Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(96)

Side by Side Diff: net/base/ip_address_number.cc

Issue 1860823005: Move some net::IPAddressNumber implementations to net::IPAddress. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/ip_address_number.h" 5 #include "net/base/ip_address_number.h"
6 6
7 #include <limits.h> 7 #include <limits.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_piece.h" 11 #include "base/strings/string_piece.h"
12 #include "base/strings/string_split.h" 12 #include "base/strings/string_split.h"
13 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
14 #include "base/strings/stringprintf.h" 14 #include "base/strings/stringprintf.h"
15 #include "url/gurl.h" 15 #include "url/gurl.h"
16 #include "url/url_canon_ip.h" 16 #include "url/url_canon_ip.h"
17 17
18 namespace net { 18 namespace net {
19 19
20 namespace {
21
22 bool IPNumberPrefixCheck(const IPAddressNumber& ip_number,
23 const unsigned char* ip_prefix,
24 size_t prefix_length_in_bits) {
25 // Compare all the bytes that fall entirely within the prefix.
26 int num_entire_bytes_in_prefix = prefix_length_in_bits / 8;
27 for (int i = 0; i < num_entire_bytes_in_prefix; ++i) {
28 if (ip_number[i] != ip_prefix[i])
29 return false;
30 }
31
32 // In case the prefix was not a multiple of 8, there will be 1 byte
33 // which is only partially masked.
34 int remaining_bits = prefix_length_in_bits % 8;
35 if (remaining_bits != 0) {
36 unsigned char mask = 0xFF << (8 - remaining_bits);
37 int i = num_entire_bytes_in_prefix;
38 if ((ip_number[i] & mask) != (ip_prefix[i] & mask))
39 return false;
40 }
41 return true;
42 }
43
44 } // namespace
45
46 // Don't compare IPv4 and IPv6 addresses (they have different range
47 // reservations). Keep separate reservation arrays for each IP type, and
48 // consolidate adjacent reserved ranges within a reservation array when
49 // possible.
50 // Sources for info:
51 // www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xhtml
52 // www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml
53 // They're formatted here with the prefix as the last element. For example:
54 // 10.0.0.0/8 becomes 10,0,0,0,8 and fec0::/10 becomes 0xfe,0xc0,0,0,0...,10.
55 bool IsIPAddressReserved(const IPAddressNumber& host_addr) {
56 static const unsigned char kReservedIPv4[][5] = {
57 { 0,0,0,0,8 }, { 10,0,0,0,8 }, { 100,64,0,0,10 }, { 127,0,0,0,8 },
58 { 169,254,0,0,16 }, { 172,16,0,0,12 }, { 192,0,2,0,24 },
59 { 192,88,99,0,24 }, { 192,168,0,0,16 }, { 198,18,0,0,15 },
60 { 198,51,100,0,24 }, { 203,0,113,0,24 }, { 224,0,0,0,3 }
61 };
62 static const unsigned char kReservedIPv6[][17] = {
63 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8 },
64 { 0x40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2 },
65 { 0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2 },
66 { 0xc0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3 },
67 { 0xe0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4 },
68 { 0xf0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5 },
69 { 0xf8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6 },
70 { 0xfc,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7 },
71 { 0xfe,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9 },
72 { 0xfe,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10 },
73 { 0xfe,0xc0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10 },
74 };
75 size_t array_size = 0;
76 const unsigned char* array = NULL;
77 switch (host_addr.size()) {
78 case kIPv4AddressSize:
79 array_size = arraysize(kReservedIPv4);
80 array = kReservedIPv4[0];
81 break;
82 case kIPv6AddressSize:
83 array_size = arraysize(kReservedIPv6);
84 array = kReservedIPv6[0];
85 break;
86 }
87 if (!array)
88 return false;
89 size_t width = host_addr.size() + 1;
90 for (size_t i = 0; i < array_size; ++i, array += width) {
91 if (IPNumberPrefixCheck(host_addr, array, array[width-1]))
92 return true;
93 }
94 return false;
95 }
96
97 std::string IPAddressToString(const uint8_t* address, size_t address_len) { 20 std::string IPAddressToString(const uint8_t* address, size_t address_len) {
98 std::string str; 21 std::string str;
99 url::StdStringCanonOutput output(&str); 22 url::StdStringCanonOutput output(&str);
100 23
101 if (address_len == kIPv4AddressSize) { 24 if (address_len == kIPv4AddressSize) {
102 url::AppendIPv4Address(address, &output); 25 url::AppendIPv4Address(address, &output);
103 } else if (address_len == kIPv6AddressSize) { 26 } else if (address_len == kIPv6AddressSize) {
104 url::AppendIPv6Address(address, &output); 27 url::AppendIPv6Address(address, &output);
105 } 28 }
106 29
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 address.begin() + arraysize(kIPv4MappedPrefix), 112 address.begin() + arraysize(kIPv4MappedPrefix),
190 kIPv4MappedPrefix); 113 kIPv4MappedPrefix);
191 } 114 }
192 115
193 IPAddressNumber ConvertIPv4MappedToIPv4(const IPAddressNumber& address) { 116 IPAddressNumber ConvertIPv4MappedToIPv4(const IPAddressNumber& address) {
194 DCHECK(IsIPv4Mapped(address)); 117 DCHECK(IsIPv4Mapped(address));
195 return IPAddressNumber(address.begin() + arraysize(kIPv4MappedPrefix), 118 return IPAddressNumber(address.begin() + arraysize(kIPv4MappedPrefix),
196 address.end()); 119 address.end());
197 } 120 }
198 121
199 bool IPNumberMatchesPrefix(const IPAddressNumber& ip_number,
200 const IPAddressNumber& ip_prefix,
201 size_t prefix_length_in_bits) {
202 // Both the input IP address and the prefix IP address should be
203 // either IPv4 or IPv6.
204 DCHECK(ip_number.size() == 4 || ip_number.size() == 16);
205 DCHECK(ip_prefix.size() == 4 || ip_prefix.size() == 16);
206
207 DCHECK_LE(prefix_length_in_bits, ip_prefix.size() * 8);
208
209 // In case we have an IPv6 / IPv4 mismatch, convert the IPv4 addresses to
210 // IPv6 addresses in order to do the comparison.
211 if (ip_number.size() != ip_prefix.size()) {
212 if (ip_number.size() == 4) {
213 return IPNumberMatchesPrefix(ConvertIPv4NumberToIPv6Number(ip_number),
214 ip_prefix, prefix_length_in_bits);
215 }
216 return IPNumberMatchesPrefix(ip_number,
217 ConvertIPv4NumberToIPv6Number(ip_prefix),
218 96 + prefix_length_in_bits);
219 }
220
221 return IPNumberPrefixCheck(ip_number, &ip_prefix[0], prefix_length_in_bits);
222 }
223
224 unsigned CommonPrefixLength(const IPAddressNumber& a1, 122 unsigned CommonPrefixLength(const IPAddressNumber& a1,
225 const IPAddressNumber& a2) { 123 const IPAddressNumber& a2) {
226 DCHECK_EQ(a1.size(), a2.size()); 124 DCHECK_EQ(a1.size(), a2.size());
227 for (size_t i = 0; i < a1.size(); ++i) { 125 for (size_t i = 0; i < a1.size(); ++i) {
228 unsigned diff = a1[i] ^ a2[i]; 126 unsigned diff = a1[i] ^ a2[i];
229 if (!diff) 127 if (!diff)
230 continue; 128 continue;
231 for (unsigned j = 0; j < CHAR_BIT; ++j) { 129 for (unsigned j = 0; j < CHAR_BIT; ++j) {
232 if (diff & (1 << (CHAR_BIT - 1))) 130 if (diff & (1 << (CHAR_BIT - 1)))
233 return i * CHAR_BIT + j; 131 return i * CHAR_BIT + j;
234 diff <<= 1; 132 diff <<= 1;
235 } 133 }
236 NOTREACHED(); 134 NOTREACHED();
237 } 135 }
238 return a1.size() * CHAR_BIT; 136 return a1.size() * CHAR_BIT;
239 } 137 }
240 138
241 unsigned MaskPrefixLength(const IPAddressNumber& mask) { 139 unsigned MaskPrefixLength(const IPAddressNumber& mask) {
242 IPAddressNumber all_ones(mask.size(), 0xFF); 140 IPAddressNumber all_ones(mask.size(), 0xFF);
243 return CommonPrefixLength(mask, all_ones); 141 return CommonPrefixLength(mask, all_ones);
244 } 142 }
245 143
246 } // namespace net 144 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698