ip_address.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. // Copyright (c) 2015 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef NET_BASE_IP_ADDRESS_H_
  5. #define NET_BASE_IP_ADDRESS_H_
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <array>
  9. #include <string>
  10. #include <vector>
  11. #include "base/check_op.h"
  12. #include "base/strings/string_piece.h"
  13. #include "net/base/net_export.h"
  14. namespace net {
  15. // Helper class to represent the sequence of bytes in an IP address.
  16. // A vector<uint8_t> would be simpler but incurs heap allocation, so
  17. // IPAddressBytes uses a fixed size array.
  18. class NET_EXPORT IPAddressBytes {
  19. public:
  20. IPAddressBytes();
  21. IPAddressBytes(const uint8_t* data, size_t data_len);
  22. IPAddressBytes(const IPAddressBytes& other);
  23. ~IPAddressBytes();
  24. // Copies |data_len| elements from |data| into this object.
  25. void Assign(const uint8_t* data, size_t data_len);
  26. // Returns the number of elements in the underlying array.
  27. size_t size() const { return size_; }
  28. // Sets the size to be |size|. Does not actually change the size
  29. // of the underlying array or zero-initialize the bytes.
  30. void Resize(size_t size) {
  31. DCHECK_LE(size, 16u);
  32. size_ = static_cast<uint8_t>(size);
  33. }
  34. // Returns true if the underlying array is empty.
  35. bool empty() const { return size_ == 0; }
  36. // Returns a pointer to the underlying array of bytes.
  37. const uint8_t* data() const { return bytes_.data(); }
  38. uint8_t* data() { return bytes_.data(); }
  39. // Returns a pointer to the first element.
  40. const uint8_t* begin() const { return data(); }
  41. uint8_t* begin() { return data(); }
  42. // Returns a pointer past the last element.
  43. const uint8_t* end() const { return data() + size_; }
  44. uint8_t* end() { return data() + size_; }
  45. // Returns a reference to the last element.
  46. uint8_t& back() {
  47. DCHECK(!empty());
  48. return bytes_[size_ - 1];
  49. }
  50. const uint8_t& back() const {
  51. DCHECK(!empty());
  52. return bytes_[size_ - 1];
  53. }
  54. // Appends |val| to the end and increments the size.
  55. void push_back(uint8_t val) {
  56. DCHECK_GT(16, size_);
  57. bytes_[size_++] = val;
  58. }
  59. // Returns a reference to the byte at index |pos|.
  60. uint8_t& operator[](size_t pos) {
  61. DCHECK_LT(pos, size_);
  62. return bytes_[pos];
  63. }
  64. const uint8_t& operator[](size_t pos) const {
  65. DCHECK_LT(pos, size_);
  66. return bytes_[pos];
  67. }
  68. bool operator<(const IPAddressBytes& other) const;
  69. bool operator!=(const IPAddressBytes& other) const;
  70. bool operator==(const IPAddressBytes& other) const;
  71. private:
  72. // Underlying sequence of bytes
  73. std::array<uint8_t, 16> bytes_;
  74. // Number of elements in |bytes_|. Should be either kIPv4AddressSize
  75. // or kIPv6AddressSize or 0.
  76. uint8_t size_;
  77. };
  78. class NET_EXPORT IPAddress {
  79. public:
  80. enum : size_t { kIPv4AddressSize = 4, kIPv6AddressSize = 16 };
  81. // Creates a zero-sized, invalid address.
  82. IPAddress();
  83. IPAddress(const IPAddress& other);
  84. // Copies the input address to |ip_address_|.
  85. explicit IPAddress(const IPAddressBytes& address);
  86. // Copies the input address to |ip_address_|. The input is expected to be in
  87. // network byte order.
  88. template <size_t N>
  89. explicit IPAddress(const uint8_t (&address)[N]) : IPAddress(address, N) {}
  90. // Copies the input address to |ip_address_| taking an additional length
  91. // parameter. The input is expected to be in network byte order.
  92. IPAddress(const uint8_t* address, size_t address_len);
  93. // Initializes |ip_address_| from the 4 bX bytes to form an IPv4 address.
  94. // The bytes are expected to be in network byte order.
  95. IPAddress(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3);
  96. // Initializes |ip_address_| from the 16 bX bytes to form an IPv6 address.
  97. // The bytes are expected to be in network byte order.
  98. IPAddress(uint8_t b0,
  99. uint8_t b1,
  100. uint8_t b2,
  101. uint8_t b3,
  102. uint8_t b4,
  103. uint8_t b5,
  104. uint8_t b6,
  105. uint8_t b7,
  106. uint8_t b8,
  107. uint8_t b9,
  108. uint8_t b10,
  109. uint8_t b11,
  110. uint8_t b12,
  111. uint8_t b13,
  112. uint8_t b14,
  113. uint8_t b15);
  114. ~IPAddress();
  115. // Returns true if the IP has |kIPv4AddressSize| elements.
  116. bool IsIPv4() const;
  117. // Returns true if the IP has |kIPv6AddressSize| elements.
  118. bool IsIPv6() const;
  119. // Returns true if the IP is either an IPv4 or IPv6 address. This function
  120. // only checks the address length.
  121. bool IsValid() const;
  122. // Returns true if the IP is not in a range reserved by the IANA for
  123. // local networks. Works with both IPv4 and IPv6 addresses.
  124. // IPv4-mapped-to-IPv6 addresses are considered publicly routable.
  125. bool IsPubliclyRoutable() const;
  126. // Returns true if the IP is "zero" (e.g. the 0.0.0.0 IPv4 address).
  127. bool IsZero() const;
  128. // Returns true if |ip_address_| is an IPv4-mapped IPv6 address.
  129. bool IsIPv4MappedIPv6() const;
  130. // Returns true if |ip_address_| is 127.0.0.1/8 or ::1/128
  131. bool IsLoopback() const;
  132. // Returns true if |ip_address_| is 169.254.0.0/16 or fe80::/10, or
  133. // ::ffff:169.254.0.0/112 (IPv4 mapped IPv6 link-local).
  134. bool IsLinkLocal() const;
  135. // The size in bytes of |ip_address_|.
  136. size_t size() const { return ip_address_.size(); }
  137. // Returns true if the IP is an empty, zero-sized (invalid) address.
  138. bool empty() const { return ip_address_.empty(); }
  139. // Returns the canonical string representation of an IP address.
  140. // For example: "192.168.0.1" or "::1". Returns the empty string when
  141. // |ip_address_| is invalid.
  142. std::string ToString() const;
  143. // Parses an IP address literal (either IPv4 or IPv6) to its numeric value.
  144. // Returns true on success and fills |ip_address_| with the numeric value.
  145. //
  146. // When parsing fails, the original value of |this| will be overwritten such
  147. // that |this->empty()| and |!this->IsValid()|.
  148. [[nodiscard]] bool AssignFromIPLiteral(const base::StringPiece& ip_literal);
  149. // Returns the underlying bytes.
  150. const IPAddressBytes& bytes() const { return ip_address_; }
  151. // Copies the bytes to a new vector. Generally callers should be using
  152. // |bytes()| and the IPAddressBytes abstraction. This method is provided as a
  153. // convenience for call sites that existed prior to the introduction of
  154. // IPAddressBytes.
  155. std::vector<uint8_t> CopyBytesToVector() const;
  156. // Returns an IPAddress instance representing the 127.0.0.1 address.
  157. static IPAddress IPv4Localhost();
  158. // Returns an IPAddress instance representing the ::1 address.
  159. static IPAddress IPv6Localhost();
  160. // Returns an IPAddress made up of |num_zero_bytes| zeros.
  161. static IPAddress AllZeros(size_t num_zero_bytes);
  162. // Returns an IPAddress instance representing the 0.0.0.0 address.
  163. static IPAddress IPv4AllZeros();
  164. // Returns an IPAddress instance representing the :: address.
  165. static IPAddress IPv6AllZeros();
  166. bool operator==(const IPAddress& that) const;
  167. bool operator!=(const IPAddress& that) const;
  168. bool operator<(const IPAddress& that) const;
  169. private:
  170. IPAddressBytes ip_address_;
  171. // This class is copyable and assignable.
  172. };
  173. using IPAddressList = std::vector<IPAddress>;
  174. // Returns the canonical string representation of an IP address along with its
  175. // port. For example: "192.168.0.1:99" or "[::1]:80".
  176. NET_EXPORT std::string IPAddressToStringWithPort(const IPAddress& address,
  177. uint16_t port);
  178. // Returns the address as a sequence of bytes in network-byte-order.
  179. NET_EXPORT std::string IPAddressToPackedString(const IPAddress& address);
  180. // Converts an IPv4 address to an IPv4-mapped IPv6 address.
  181. // For example 192.168.0.1 would be converted to ::ffff:192.168.0.1.
  182. NET_EXPORT IPAddress ConvertIPv4ToIPv4MappedIPv6(const IPAddress& address);
  183. // Converts an IPv4-mapped IPv6 address to IPv4 address. Should only be called
  184. // on IPv4-mapped IPv6 addresses.
  185. NET_EXPORT IPAddress ConvertIPv4MappedIPv6ToIPv4(const IPAddress& address);
  186. // Compares an IP address to see if it falls within the specified IP block.
  187. // Returns true if it does, false otherwise.
  188. //
  189. // The IP block is given by (|ip_prefix|, |prefix_length_in_bits|) -- any
  190. // IP address whose |prefix_length_in_bits| most significant bits match
  191. // |ip_prefix| will be matched.
  192. //
  193. // In cases when an IPv4 address is being compared to an IPv6 address prefix
  194. // and vice versa, the IPv4 addresses will be converted to IPv4-mapped
  195. // (IPv6) addresses.
  196. NET_EXPORT bool IPAddressMatchesPrefix(const IPAddress& ip_address,
  197. const IPAddress& ip_prefix,
  198. size_t prefix_length_in_bits);
  199. // Parses an IP block specifier from CIDR notation to an
  200. // (IP address, prefix length) pair. Returns true on success and fills
  201. // |*ip_address| with the numeric value of the IP address and sets
  202. // |*prefix_length_in_bits| with the length of the prefix. On failure,
  203. // |ip_address| will be cleared to an empty value.
  204. //
  205. // CIDR notation literals can use either IPv4 or IPv6 literals. Some examples:
  206. //
  207. // 10.10.3.1/20
  208. // a:b:c::/46
  209. // ::1/128
  210. NET_EXPORT bool ParseCIDRBlock(base::StringPiece cidr_literal,
  211. IPAddress* ip_address,
  212. size_t* prefix_length_in_bits);
  213. // Parses a URL-safe IP literal (see RFC 3986, Sec 3.2.2) to its numeric value.
  214. // Returns true on success, and fills |ip_address| with the numeric value.
  215. // In other words, |hostname| must be an IPv4 literal, or an IPv6 literal
  216. // surrounded by brackets as in [::1]. On failure |ip_address| may have been
  217. // overwritten and could contain an invalid IPAddress.
  218. [[nodiscard]] NET_EXPORT bool ParseURLHostnameToAddress(
  219. const base::StringPiece& hostname,
  220. IPAddress* ip_address);
  221. // Returns number of matching initial bits between the addresses |a1| and |a2|.
  222. NET_EXPORT size_t CommonPrefixLength(const IPAddress& a1, const IPAddress& a2);
  223. // Computes the number of leading 1-bits in |mask|.
  224. NET_EXPORT size_t MaskPrefixLength(const IPAddress& mask);
  225. // Checks whether |address| starts with |prefix|. This provides similar
  226. // functionality as IPAddressMatchesPrefix() but doesn't perform automatic IPv4
  227. // to IPv4MappedIPv6 conversions and only checks against full bytes.
  228. template <size_t N>
  229. bool IPAddressStartsWith(const IPAddress& address, const uint8_t (&prefix)[N]) {
  230. if (address.size() < N)
  231. return false;
  232. return std::equal(prefix, prefix + N, address.bytes().begin());
  233. }
  234. } // namespace net
  235. #endif // NET_BASE_IP_ADDRESS_H_