38 #define IFNAMSIZ IF_NAMESIZE 59 result->append(addr.
str());
66 return tryFromString(ip).hasValue();
75 if (maybeIp.hasError()) {
77 to<std::string>(
"Invalid IPv6 address '", addr,
"'"));
90 if (ip.front() ==
'[' && ip.back() ==
']') {
91 ip = ip.substr(1, ip.size() - 2);
94 struct addrinfo* result;
95 struct addrinfo hints;
96 memset(&hints, 0,
sizeof(hints));
97 hints.ai_family = AF_INET6;
98 hints.ai_socktype = SOCK_STREAM;
99 hints.ai_flags = AI_NUMERICHOST;
100 if (::getaddrinfo(ip.c_str(),
nullptr, &hints, &result) == 0) {
102 ::freeaddrinfo(result);
104 const struct sockaddr_in6* sa =
105 reinterpret_cast<struct sockaddr_in6*
>(result->ai_addr);
127 const auto* macBytes = mac.
bytes();
128 memcpy(&bytes_.front(),
"\xfe\x80\x00\x00\x00\x00\x00\x00", 8);
129 bytes_[8] =
uint8_t(macBytes[0] ^ 0x02);
130 bytes_[9] = macBytes[1];
131 bytes_[10] = macBytes[2];
134 bytes_[13] = macBytes[3];
135 bytes_[14] = macBytes[4];
136 bytes_[15] = macBytes[5];
153 std::array<uint8_t, MacAddress::SIZE>
bytes;
170 if (maybeIp.hasError()) {
172 "Invalid IPv6 binary data: length must be 16 bytes, got ",
175 return maybeIp.value();
182 if (setResult.hasError()) {
190 if (
bytes.size() != 16) {
201 if (!piece.removeSuffix(
".ip6.arpa")) {
203 "Invalid input. Should end with 'ip6.arpa'. Got '{}'", arpaname));
205 std::vector<StringPiece> pieces;
206 split(
".", piece, pieces);
207 if (pieces.size() != 32) {
210 std::array<char, IPAddressV6::kToFullyQualifiedSize> ip;
213 for (
size_t i = 1;
i <= pieces.size();
i++) {
214 ip[pos] = pieces[pieces.size() -
i][0];
218 if (count == 4 && pos < ip.size()) {
231 const unsigned char* by =
bytes();
244 for (
size_t i = 0, hi = 1, lo = 0;
i <
count;
i++) {
245 dest[
i] =
unpack(src[hi], src[lo]);
255 sformat(
"Invalid IP '{}': not a 6to4 address",
str()));
262 unsigned char bytes[4];
265 ipv4.bytes[0] = (
uint8_t)((ints[1] & 0xFF00) >> 8);
266 ipv4.bytes[1] = (
uint8_t)(ints[1] & 0x00FF);
267 ipv4.bytes[2] = (
uint8_t)((ints[2] & 0xFF00) >> 8);
268 ipv4.bytes[3] = (
uint8_t)(ints[2] & 0x00FF);
276 const unsigned char* by =
bytes();
279 for (
int i = 0;
i < 10;
i++) {
285 if (by[10] == 0xff && by[11] == 0xff) {
297 if ((((
uint32_t)ints[0] << 16) | ints[1]) == IPAddressV6::PREFIX_TEREDO) {
301 if ((
uint32_t)ints[0] == IPAddressV6::PREFIX_6TO4) {
310 return sformat(
"{{family:'AF_INET6', addr:'{}', hash:{}}}",
str(),
hash());
319 return IPAddress::createIPv4(*this).hash();
330 auto subnetInfo = IPAddress::createNetwork(cidrNetwork);
331 auto addr = subnetInfo.first;
334 sformat(
"Address '{}' is not a V6 address",
addr.toJson()));
345 return (
mask == subMask);
355 return IN6_IS_ADDR_LOOPBACK(&socka.sin6_addr);
368 static const IPAddressV6 kLinkLocalBroadcast(
"ff02::1");
369 return *
this == kLinkLocalBroadcast;
428 static const auto bits =
bitCount();
429 if (numBits > bits) {
431 sformat(
"numBits({}) > bitCount({})", numBits, bits));
439 char buffer[INET6_ADDRSTRLEN + IFNAMSIZ + 1];
441 if (!inet_ntop(AF_INET6,
toAddr().s6_addr, buffer, INET6_ADDRSTRLEN)) {
443 "Invalid address with hex '{}' with error {}",
450 auto len = strlen(buffer);
454 if (!if_indextoname(scopeId, buffer + len + 1)) {
457 snprintf(buffer + len + 1, IFNAMSIZ,
"%u", scopeId);
478 std::array<char, 32>
a;
480 for (
int i = 15;
i >= 0;
i--) {
481 a[j] = (lut[
bytes()[
i] & 0xf]);
482 a[j + 1] = (lut[
bytes()[
i] >> 4]);
490 const auto highestIndex =
byteCount() - 1;
491 if (byteIndex > highestIndex) {
492 throw std::invalid_argument(
sformat(
493 "Byte index must be <= {} for addresses of type: {}",
497 return bytes()[byteIndex];
502 static const size_t bits =
bitCount();
503 if (numBits > bits) {
510 constexpr
auto _1s = ~_0s;
511 auto const fragment =
Endian::big(_1s << ((128 - numBits) % 64));
512 auto const hi = numBits <= 64 ? fragment : _1s;
513 auto const lo = numBits <= 64 ? _0s : fragment;
516 std::memcpy(arr.data(), parts,
sizeof(parts));
525 one.first.addr_.bytes_, one.second, two.first.addr_.bytes_, two.second);
531 const std::array<uint8_t, 2>
addr,
532 size_t numBits)
const {
533 auto masked =
mask(numBits);
534 return (std::memcmp(addr.data(), masked.bytes(), 2) == 0);
static CIDRNetworkV6 longestCommonPrefix(const CIDRNetworkV6 &one, const CIDRNetworkV6 &two)
IPAddressV4 createIPv4() const
ByteArray16 toByteArray() const
std::vector< uint8_t > buffer(kBufferSize+16)
std::string toInverseArpaName() const
bool inSubnetWithMask(const IPAddressV6 &subnet, const ByteArray16 &mask) const
bool inBinarySubnet(const std::array< uint8_t, 2 > addr, size_t numBits) const
static const uint32_t PREFIX_6TO4
uint8_t getNthMSByte(size_t byteIndex) const
bool isLinkLocalBroadcast() const
Optional< MacAddress > getMacAddressFromLinkLocal() const
const unsigned char * bytes() const
std::string sformat(StringPiece fmt, Args &&...args)
static IPAddressV6 fromBinary(ByteRange bytes)
static constexpr size_t bitCount()
constexpr detail::Map< Move > move
static std::array< uint8_t, N > mask(const std::array< uint8_t, N > &a, const std::array< uint8_t, N > &b)
IPAddressV6 mask(size_t numBits) const
constexpr size_type size() const
IPAddressV4 getIPv4For6To4() const
uint16_t getScopeId() const
static void unpackInto(const unsigned char *src, uint16_t *dest, size_t count)
Expected< Unit, IPAddressFormatError > trySetFromBinary(ByteRange bytes) noexcept
—— Concurrent Priority Queue Implementation ——
uint8_t getMulticastFlags() const
requires E e noexcept(noexcept(s.error(std::move(e))))
bool prefix(Cursor &c, uint32_t expected)
sockaddr_in6 toSockAddr() const
std::string toFullyQualified() const
void split(const Delim &delimiter, const String &input, std::vector< OutputType > &out, bool ignoreEmpty)
std::pair< IPAddressV6, uint8_t > CIDRNetworkV6
static constexpr size_t byteCount()
const uint8_t * bytes() const
static Expected< IPAddressV6, IPAddressFormatError > tryFromBinary(ByteRange bytes) noexcept
static void Hash128(const void *message, size_t length, uint64_t *hash1, uint64_t *hash2)
static uint16_t unpack(uint8_t lobyte, uint8_t hibyte)
size_t hash_combine(const T &t, const Ts &...ts) noexcept(noexcept(hash_combine_generic(StdHasher{}, t, ts...)))
constexpr Unexpected< typename std::decay< Error >::type > makeUnexpected(Error &&)
void toFullyQualifiedAppend(std::string &out) const
static const ByteArray16 fetchMask(size_t numBits)
static bool validate(StringPiece ip) noexcept
IPAddressV6 getSolicitedNodeAddress() const
static Expected< IPAddressV6, IPAddressFormatError > tryFromString(StringPiece str) noexcept
std::array< uint8_t, 16 > ByteArray16
size_t hash_value(const IPAddress &addr)
constexpr Range< Iter > range(Iter first, Iter last)
static const uint32_t PREFIX_TEREDO
static std::pair< std::array< uint8_t, N >, uint8_t > longestCommonPrefix(const std::array< uint8_t, N > &one, uint8_t oneMask, const std::array< uint8_t, N > &two, uint8_t twoMask)
void fastIpv6AppendToString(const in6_addr &in6Addr, std::string &out)
void toAppend(char value, Tgt *result)
Optional< MacAddress > getMacAddressFromEUI64() const
static MacAddress fromBinary(ByteRange value)
fbstring errnoStr(int err)
std::runtime_error TypeError
static in_addr mkAddress4(const uint8_t *src)
Range< const unsigned char * > ByteRange
std::string toJson() const
void join(const Delim &delimiter, Iterator begin, Iterator end, String &output)
uint8_t getMulticastScope() const
static IPAddressV6 fromInverseArpaName(const std::string &arpaname)
bool inSubnet(StringPiece cidrNetwork) const
basic_fbstring & append(const basic_fbstring &str)
Range< const char * > StringPiece
static std::string toHex(const uint8_t *src, std::size_t len)
std::string fastIpv6ToString(const in6_addr &in6Addr)
std::string familyNameStr(sa_family_t family)
ThreadPoolListHook * addr
union folly::IPAddressV6::AddressStorage addr_
bool isIPv4Mapped() const
std::ostream & operator<<(std::ostream &out, dynamic const &d)