blob: 3f1b83ed1c3b60a192c3ecc538c829e25357f549 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <netinet/in.h>
#ifndef __Fuchsia__
#include <sys/un.h>
#endif
#include <iosfwd>
#include "src/connectivity/overnet/lib/vocabulary/optional.h"
namespace overnet {
union IpAddr {
sockaddr_in ipv4;
sockaddr_in6 ipv6;
sockaddr addr;
#ifndef __Fuchsia__
sockaddr_un unix;
static Optional<IpAddr> Unix(const std::string& name);
#endif
Optional<IpAddr> WithPort(uint16_t port) const;
static IpAddr AnyIpv4();
static IpAddr AnyIpv6();
const sockaddr* get() const { return &addr; }
socklen_t length() const;
Optional<IpAddr> AsIpv6() const;
uint16_t port() const {
switch (addr.sa_family) {
case AF_INET:
return htons(ipv4.sin_port);
case AF_INET6:
return htons(ipv6.sin6_port);
default:
return 0;
}
}
IpAddr() {}
constexpr IpAddr(uint16_t a, uint16_t b, uint16_t c, uint16_t d, uint16_t e,
uint16_t f, uint16_t g, uint16_t h, uint16_t port)
: ipv6{.sin6_family = AF_INET6,
.sin6_addr = {{{
static_cast<unsigned char>(a >> 8),
static_cast<unsigned char>(a & 0xff),
static_cast<unsigned char>(b >> 8),
static_cast<unsigned char>(b & 0xff),
static_cast<unsigned char>(c >> 8),
static_cast<unsigned char>(c & 0xff),
static_cast<unsigned char>(d >> 8),
static_cast<unsigned char>(d & 0xff),
static_cast<unsigned char>(e >> 8),
static_cast<unsigned char>(e & 0xff),
static_cast<unsigned char>(f >> 8),
static_cast<unsigned char>(f & 0xff),
static_cast<unsigned char>(g >> 8),
static_cast<unsigned char>(g & 0xff),
static_cast<unsigned char>(h >> 8),
static_cast<unsigned char>(h & 0xff),
}}},
.sin6_port = uint16_t((port >> 8) | (port << 8))} {}
constexpr IpAddr(uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint16_t port)
: ipv4{.sin_family = AF_INET,
.sin_addr = {(uint32_t(d) << 24) | (uint32_t(c) << 16) |
(uint32_t(b) << 8) | uint32_t(a)},
.sin_port = uint16_t((port >> 8) | (port << 8))} {}
};
std::ostream& operator<<(std::ostream& out, IpAddr addr);
class HashIpAddr {
public:
size_t operator()(const IpAddr& addr) const;
};
class EqIpAddr {
public:
bool operator()(const IpAddr& a, const IpAddr& b) const;
};
inline bool operator==(const IpAddr& a, const IpAddr& b) {
return EqIpAddr()(a, b);
}
} // namespace overnet