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