proxygen
IPAddressV6.h
Go to the documentation of this file.
1 /*
2  * Copyright 2014-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <cstring>
20 
21 #include <array>
22 #include <functional>
23 #include <iosfwd>
24 #include <map>
25 #include <stdexcept>
26 
27 #include <folly/Expected.h>
28 #include <folly/FBString.h>
30 #include <folly/Optional.h>
31 #include <folly/Range.h>
32 #include <folly/detail/IPAddress.h>
33 #include <folly/hash/Hash.h>
34 
35 namespace folly {
36 
37 class IPAddress;
38 class IPAddressV4;
39 class IPAddressV6;
40 class MacAddress;
41 
45 typedef std::pair<IPAddressV6, uint8_t> CIDRNetworkV6;
46 
50 typedef std::array<uint8_t, 16> ByteArray16;
51 
71 class IPAddressV6 {
72  public:
73  // V6 Address Type
74  enum Type {
78  };
79  // A constructor parameter to indicate that we should create a link-local
80  // IPAddressV6.
81  enum LinkLocalTag {
83  };
84  // Thrown when a type assertion fails
85  typedef std::runtime_error TypeError;
86 
87  // Binary prefix for teredo networks
88  static const uint32_t PREFIX_TEREDO;
89  // Binary prefix for 6to4 networks
90  static const uint32_t PREFIX_6TO4;
91 
92  // Size of std::string returned by toFullyQualified.
93  static constexpr size_t kToFullyQualifiedSize =
94  8 /*words*/ * 4 /*hex chars per word*/ + 7 /*separators*/;
95 
96  // returns true iff the input string can be parsed as an ipv6-address
97  static bool validate(StringPiece ip) noexcept;
98 
104 
111 
118 
124  static IPAddressV6 fromInverseArpaName(const std::string& arpaname);
125 
129  ByteRange toBinary() const {
130  return ByteRange((const unsigned char*)&addr_.in6Addr_.s6_addr, 16);
131  }
132 
138  IPAddressV6();
139 
140  // Create an IPAddressV6 from a string
141  // @throws IPAddressFormatException
142  //
143  explicit IPAddressV6(StringPiece ip);
144 
145  // ByteArray16 constructor
146  explicit IPAddressV6(const ByteArray16& src) noexcept;
147 
148  // in6_addr constructor
149  explicit IPAddressV6(const in6_addr& src) noexcept;
150 
151  // sockaddr_in6 constructor
152  explicit IPAddressV6(const sockaddr_in6& src) noexcept;
153 
158 
159  // return the mapped V4 address
160  // @throws IPAddressFormatException if !isIPv4Mapped
161  IPAddressV4 createIPv4() const;
162 
167  IPAddressV4 getIPv4For6To4() const;
168 
169  // Return true if a 6TO4 address
170  bool is6To4() const {
171  return type() == IPAddressV6::Type::T6TO4;
172  }
173 
174  // Return true if a TEREDO address
175  bool isTeredo() const {
176  return type() == IPAddressV6::Type::TEREDO;
177  }
178 
179  // return true if this is v4-to-v6-mapped
180  bool isIPv4Mapped() const;
181 
182  // Return the V6 address type
183  Type type() const;
184 
189  static constexpr size_t bitCount() {
190  return 128;
191  }
192 
196  std::string toJson() const;
197 
198  size_t hash() const;
199 
200  // @see IPAddress#inSubnet
201  // @throws IPAddressFormatException if string doesn't contain a V6 address
202  bool inSubnet(StringPiece cidrNetwork) const;
203 
204  // return true if address is in subnet
205  bool inSubnet(const IPAddressV6& subnet, uint8_t cidr) const {
206  return inSubnetWithMask(subnet, fetchMask(cidr));
207  }
208  bool inSubnetWithMask(const IPAddressV6& subnet, const ByteArray16& mask)
209  const;
210 
211  // @see IPAddress#isLoopback
212  bool isLoopback() const;
213 
214  // @see IPAddress#isNonroutable
215  bool isNonroutable() const {
216  return !isRoutable();
217  }
218 
222  bool isRoutable() const;
223 
224  // @see IPAddress#isPrivate
225  bool isPrivate() const;
226 
235  bool isLinkLocal() const;
236 
246 
256 
260  bool isMulticast() const;
261 
266  uint8_t getMulticastFlags() const;
267 
272  uint8_t getMulticastScope() const;
273 
274  // @see IPAddress#isZero
275  bool isZero() const {
276  constexpr auto zero = ByteArray16{{}};
277  return 0 == std::memcmp(bytes(), zero.data(), zero.size());
278  }
279 
280  bool isLinkLocalBroadcast() const;
281 
282  // @see IPAddress#mask
283  IPAddressV6 mask(size_t numBits) const;
284 
285  // return underlying in6_addr structure
286  in6_addr toAddr() const {
287  return addr_.in6Addr_;
288  }
289 
291  return scope_;
292  }
293  void setScopeId(uint16_t scope) {
294  scope_ = scope;
295  }
296 
297  sockaddr_in6 toSockAddr() const {
298  sockaddr_in6 addr;
299  memset(&addr, 0, sizeof(sockaddr_in6));
300  addr.sin6_family = AF_INET6;
301  addr.sin6_scope_id = scope_;
302  memcpy(&addr.sin6_addr, &addr_.in6Addr_, sizeof(in6_addr));
303  return addr;
304  }
305 
306  ByteArray16 toByteArray() const {
307  ByteArray16 ba{{0}};
308  std::memcpy(ba.data(), bytes(), 16);
309  return ba;
310  }
311 
312  // @see IPAddress#toFullyQualified
314 
315  // @see IPAddress#toFullyQualifiedAppend
316  void toFullyQualifiedAppend(std::string& out) const;
317 
319 
320  // @see IPAddress#str
321  std::string str() const;
322 
323  // @see IPAddress#version
324  uint8_t version() const {
325  return 6;
326  }
327 
332 
341  static const ByteArray16 fetchMask(size_t numBits);
342  // Given 2 IPAddressV6,mask pairs extract the longest common IPAddress,
343  // mask pair
344  static CIDRNetworkV6 longestCommonPrefix(
345  const CIDRNetworkV6& one,
346  const CIDRNetworkV6& two);
347  // Number of bytes in the address representation.
348  static constexpr size_t byteCount() {
349  return 16;
350  }
351 
352  // get nth most significant bit - 0 indexed
353  bool getNthMSBit(size_t bitIndex) const {
354  return detail::getNthMSBitImpl(*this, bitIndex, AF_INET6);
355  }
356  // get nth most significant byte - 0 indexed
357  uint8_t getNthMSByte(size_t byteIndex) const;
358  // get nth bit - 0 indexed
359  bool getNthLSBit(size_t bitIndex) const {
360  return getNthMSBit(bitCount() - bitIndex - 1);
361  }
362  // get nth byte - 0 indexed
363  uint8_t getNthLSByte(size_t byteIndex) const {
364  return getNthMSByte(byteCount() - byteIndex - 1);
365  }
366 
367  const unsigned char* bytes() const {
368  return addr_.in6Addr_.s6_addr;
369  }
370 
371  protected:
376  bool inBinarySubnet(const std::array<uint8_t, 2> addr, size_t numBits) const;
377 
378  private:
379  auto tie() const {
380  return std::tie(addr_.bytes_, scope_);
381  }
382 
383  public:
384  friend inline bool operator==(const IPAddressV6& a, const IPAddressV6& b) {
385  return a.tie() == b.tie();
386  }
387  friend inline bool operator!=(const IPAddressV6& a, const IPAddressV6& b) {
388  return a.tie() != b.tie();
389  }
390  friend inline bool operator<(const IPAddressV6& a, const IPAddressV6& b) {
391  return a.tie() < b.tie();
392  }
393  friend inline bool operator>(const IPAddressV6& a, const IPAddressV6& b) {
394  return a.tie() > b.tie();
395  }
396  friend inline bool operator<=(const IPAddressV6& a, const IPAddressV6& b) {
397  return a.tie() <= b.tie();
398  }
399  friend inline bool operator>=(const IPAddressV6& a, const IPAddressV6& b) {
400  return a.tie() >= b.tie();
401  }
402 
403  private:
405  in6_addr in6Addr_;
406  ByteArray16 bytes_;
408  std::memset(this, 0, sizeof(AddressStorage));
409  }
410  explicit AddressStorage(const ByteArray16& bytes) : bytes_(bytes) {}
411  explicit AddressStorage(const in6_addr& addr) : in6Addr_(addr) {}
412  explicit AddressStorage(MacAddress mac);
413  } addr_;
414 
415  // Link-local scope id. This should always be 0 for IPAddresses that
416  // are *not* link-local.
418 
425 };
426 
427 // boost::hash uses hash_value() so this allows boost::hash to work
428 // automatically for IPAddressV6
429 std::size_t hash_value(const IPAddressV6& addr);
430 std::ostream& operator<<(std::ostream& os, const IPAddressV6& addr);
431 // Define toAppend() to allow IPAddressV6 to be used with to<string>
432 void toAppend(IPAddressV6 addr, std::string* result);
433 void toAppend(IPAddressV6 addr, fbstring* result);
434 
435 } // namespace folly
436 
437 namespace std {
438 template <>
440  size_t operator()(const folly::IPAddressV6& addr) const {
441  return addr.hash();
442  }
443 };
444 } // namespace std
static CIDRNetworkV6 longestCommonPrefix(const CIDRNetworkV6 &one, const CIDRNetworkV6 &two)
IPAddressV4 createIPv4() const
bool getNthMSBitImpl(const IPAddrType &ip, size_t bitIndex, sa_family_t family)
Definition: IPAddress.h:49
ByteArray16 toByteArray() const
Definition: IPAddressV6.h:306
std::string toInverseArpaName() const
bool inSubnetWithMask(const IPAddressV6 &subnet, const ByteArray16 &mask) const
AddressStorage(const in6_addr &addr)
Definition: IPAddressV6.h:411
AddressStorage(const ByteArray16 &bytes)
Definition: IPAddressV6.h:410
bool inBinarySubnet(const std::array< uint8_t, 2 > addr, size_t numBits) const
static const uint32_t PREFIX_6TO4
Definition: IPAddressV6.h:90
bool getNthLSBit(size_t bitIndex) const
Definition: IPAddressV6.h:359
char b
uint8_t getNthMSByte(size_t byteIndex) const
bool isLinkLocalBroadcast() const
Optional< MacAddress > getMacAddressFromLinkLocal() const
const unsigned char * bytes() const
Definition: IPAddressV6.h:367
friend bool operator<(const IPAddressV6 &a, const IPAddressV6 &b)
Definition: IPAddressV6.h:390
static IPAddressV6 fromBinary(ByteRange bytes)
static constexpr size_t bitCount()
Definition: IPAddressV6.h:189
IPAddressV6 mask(size_t numBits) const
STL namespace.
IPAddressV4 getIPv4For6To4() const
friend bool operator==(const IPAddressV6 &a, const IPAddressV6 &b)
Definition: IPAddressV6.h:384
uint16_t getScopeId() const
Definition: IPAddressV6.h:290
Expected< Unit, IPAddressFormatError > trySetFromBinary(ByteRange bytes) noexcept
bool isTeredo() const
Definition: IPAddressV6.h:175
bool isLinkLocal() const
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
uint8_t getMulticastFlags() const
requires E e noexcept(noexcept(s.error(std::move(e))))
sockaddr_in6 toSockAddr() const
Definition: IPAddressV6.h:297
std::string toFullyQualified() const
void setScopeId(uint16_t scope)
Definition: IPAddressV6.h:293
std::pair< IPAddressV6, uint8_t > CIDRNetworkV6
Definition: IPAddressV6.h:40
static constexpr size_t byteCount()
Definition: IPAddressV6.h:348
bool isLoopback() const
static Expected< IPAddressV6, IPAddressFormatError > tryFromBinary(ByteRange bytes) noexcept
friend bool operator!=(const IPAddressV6 &a, const IPAddressV6 &b)
Definition: IPAddressV6.h:387
bool isZero() const
Definition: IPAddressV6.h:275
static constexpr size_t kToFullyQualifiedSize
Definition: IPAddressV6.h:93
void toFullyQualifiedAppend(std::string &out) const
static const ByteArray16 fetchMask(size_t numBits)
static bool validate(StringPiece ip) noexcept
Definition: IPAddressV6.cpp:65
uint8_t version() const
Definition: IPAddressV6.h:324
IPAddressV6 getSolicitedNodeAddress() const
static Expected< IPAddressV6, IPAddressFormatError > tryFromString(StringPiece str) noexcept
Definition: IPAddressV6.cpp:82
std::array< uint8_t, 16 > ByteArray16
Definition: IPAddressV6.h:50
size_t hash_value(const IPAddress &addr)
Definition: IPAddress.cpp:34
auto tie() const
Definition: IPAddressV6.h:379
char a
static const uint32_t PREFIX_TEREDO
Definition: IPAddressV6.h:88
bool inSubnet(const IPAddressV6 &subnet, uint8_t cidr) const
Definition: IPAddressV6.h:205
void toAppend(char value, Tgt *result)
Definition: Conv.h:406
std::string str() const
size_t operator()(const folly::IPAddressV6 &addr) const
Definition: IPAddressV6.h:440
Optional< MacAddress > getMacAddressFromEUI64() const
bool getNthMSBit(size_t bitIndex) const
Definition: IPAddressV6.h:353
friend bool operator>(const IPAddressV6 &a, const IPAddressV6 &b)
Definition: IPAddressV6.h:393
bool isMulticast() const
std::runtime_error TypeError
Definition: IPAddressV6.h:85
size_t hash() const
const char * string
Definition: Conv.cpp:212
friend bool operator<=(const IPAddressV6 &a, const IPAddressV6 &b)
Definition: IPAddressV6.h:396
Range< const unsigned char * > ByteRange
Definition: Range.h:1163
std::string toJson() const
friend bool operator>=(const IPAddressV6 &a, const IPAddressV6 &b)
Definition: IPAddressV6.h:399
uint8_t getMulticastScope() const
static IPAddressV6 fromInverseArpaName(const std::string &arpaname)
bool inSubnet(StringPiece cidrNetwork) const
uint8_t getNthLSByte(size_t byteIndex) const
Definition: IPAddressV6.h:363
bool isNonroutable() const
Definition: IPAddressV6.h:215
bool isRoutable() const
bool isPrivate() const
ThreadPoolListHook * addr
union folly::IPAddressV6::AddressStorage addr_
bool is6To4() const
Definition: IPAddressV6.h:170
Type type() const
in6_addr toAddr() const
Definition: IPAddressV6.h:286
bool isIPv4Mapped() const
ByteRange toBinary() const
Definition: IPAddressV6.h:129
std::ostream & operator<<(std::ostream &out, dynamic const &d)
Definition: dynamic-inl.h:1158