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

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

Issue 1886043002: Update IPAddress::IsReserved() ranges. (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
« no previous file with comments | « no previous file | net/base/ip_address_unittest.cc » ('j') | net/base/ip_address_unittest.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. 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 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.h" 5 #include "net/base/ip_address.h"
6 6
7 #include "base/strings/string_piece.h" 7 #include "base/strings/string_piece.h"
8 #include "base/strings/string_split.h" 8 #include "base/strings/string_split.h"
9 #include "net/base/ip_address_number.h" 9 #include "net/base/ip_address_number.h"
10 #include "net/base/parse_number.h" 10 #include "net/base/parse_number.h"
11 #include "url/gurl.h" 11 #include "url/gurl.h"
12 #include "url/url_canon_ip.h" 12 #include "url/url_canon_ip.h"
13 13
14 namespace { 14 namespace {
15 15
16 bool IPAddressPrefixCheck(const std::vector<uint8_t>& ip_address, 16 bool IPAddressPrefixCheck(const std::vector<uint8_t>& ip_address,
eroman 2016/04/18 22:52:39 While you are here, do you mind documenting the im
martijnc 2016/04/19 18:30:41 Done.
17 const unsigned char* ip_prefix, 17 const uint8_t* ip_prefix,
18 size_t prefix_length_in_bits) { 18 size_t prefix_length_in_bits) {
19 // Compare all the bytes that fall entirely within the prefix. 19 // Compare all the bytes that fall entirely within the prefix.
20 int num_entire_bytes_in_prefix = prefix_length_in_bits / 8; 20 int num_entire_bytes_in_prefix = prefix_length_in_bits / 8;
eroman 2016/04/18 18:13:15 side-comment: This existing function is a bit of a
martijnc 2016/04/18 21:39:54 Changed to size_t for consistency (think that's th
eroman 2016/04/18 22:52:38 Correct -- truncation in that case is working as i
21 for (int i = 0; i < num_entire_bytes_in_prefix; ++i) { 21 for (int i = 0; i < num_entire_bytes_in_prefix; ++i) {
22 if (ip_address[i] != ip_prefix[i]) 22 if (ip_address[i] != ip_prefix[i])
23 return false; 23 return false;
24 } 24 }
25 25
26 // In case the prefix was not a multiple of 8, there will be 1 byte 26 // In case the prefix was not a multiple of 8, there will be 1 byte
27 // which is only partially masked. 27 // which is only partially masked.
28 int remaining_bits = prefix_length_in_bits % 8; 28 int remaining_bits = prefix_length_in_bits % 8;
29 if (remaining_bits != 0) { 29 if (remaining_bits != 0) {
30 unsigned char mask = 0xFF << (8 - remaining_bits); 30 unsigned char mask = 0xFF << (8 - remaining_bits);
31 int i = num_entire_bytes_in_prefix; 31 int i = num_entire_bytes_in_prefix;
32 if ((ip_address[i] & mask) != (ip_prefix[i] & mask)) 32 if ((ip_address[i] & mask) != (ip_prefix[i] & mask))
33 return false; 33 return false;
34 } 34 }
35 return true; 35 return true;
36 } 36 }
37 37
38 // Returns true if |ip_address| matches any of the reserved IPv4 ranges. This
39 // method operates on a blacklist of reserved IPv4 ranges. Some ranges are
40 // consolidated.
41 // Sources for info:
42 // www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xhtml
43 // www.iana.org/assignments/iana-ipv4-special-registry/
44 // iana-ipv4-special-registry.xhtml
45 bool IsReservedIPv4(const std::vector<uint8_t>& ip_address) {
46 // Different IP versions have different range reservations.
47 DCHECK(ip_address.size() == net::IPAddress::kIPv4AddressSize);
eroman 2016/04/18 18:13:15 DCHECK_EQ
martijnc 2016/04/18 21:39:54 Done.
48 struct {
49 const uint8_t address[4];
50 size_t prefix_length;
51 } static const kReservedIPv4Ranges[] = {
eroman 2016/04/18 18:13:15 For the IPv4 ranges here, I confirmed that these c
52 {{0, 0, 0, 0}, 8}, {{10, 0, 0, 0}, 8}, {{100, 64, 0, 0}, 10},
53 {{127, 0, 0, 0}, 8}, {{169, 254, 0, 0}, 16}, {{172, 16, 0, 0}, 12},
54 {{192, 0, 2, 0}, 24}, {{192, 88, 99, 0}, 24}, {{192, 168, 0, 0}, 16},
55 {{198, 18, 0, 0}, 15}, {{198, 51, 100, 0}, 24}, {{203, 0, 113, 0}, 24},
56 {{224, 0, 0, 0}, 3}};
57
58 for (const auto& range : kReservedIPv4Ranges)
59 if (IPAddressPrefixCheck(ip_address, range.address, range.prefix_length))
60 return true;
61
62 return false;
63 }
64
65 // Returns true if |ip_address| matches any of the reserved IPv6 ranges. This
66 // method operates on a whitelist of non-reserved IPv6 ranges. All IPv6
67 // addresses outside these ranges are reserved.
68 // Sources for info:
69 // www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml
70 bool IsReservedIPv6(const std::vector<uint8_t>& ip_address) {
71 // Different IP versions have different range reservations.
72 DCHECK(ip_address.size() == net::IPAddress::kIPv6AddressSize);
eroman 2016/04/18 18:13:15 DCHECK_EQ.
martijnc 2016/04/18 21:39:54 Done.
73 struct {
74 const uint8_t address[16];
eroman 2016/04/18 18:13:15 The largest prefix length we need for the ranges b
martijnc 2016/04/18 21:39:54 Done & done.
75 size_t prefix_length;
76 } static const kPublicIPv6Ranges[] = {
77 {{0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 3},
eroman 2016/04/18 18:13:15 Please add comments to these that identify what th
martijnc 2016/04/18 21:39:54 Done.
78 {{0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 8},
79 };
80
81 bool matched = false;
82 for (const auto& range : kPublicIPv6Ranges)
83 if (IPAddressPrefixCheck(ip_address, range.address, range.prefix_length))
84 matched = true;
eroman 2016/04/18 18:13:15 Can you early return here instead? return false
martijnc 2016/04/18 21:39:54 Done.
85
86 return !matched;
87 }
88
38 } // namespace 89 } // namespace
39 90
40 namespace net { 91 namespace net {
41 92
42 IPAddress::IPAddress() {} 93 IPAddress::IPAddress() {}
43 94
44 IPAddress::IPAddress(const IPAddressNumber& address) : ip_address_(address) {} 95 IPAddress::IPAddress(const IPAddressNumber& address) : ip_address_(address) {}
45 96
46 IPAddress::IPAddress(const IPAddress& other) = default; 97 IPAddress::IPAddress(const IPAddress& other) = default;
47 98
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 } 135 }
85 136
86 bool IPAddress::IsIPv6() const { 137 bool IPAddress::IsIPv6() const {
87 return ip_address_.size() == kIPv6AddressSize; 138 return ip_address_.size() == kIPv6AddressSize;
88 } 139 }
89 140
90 bool IPAddress::IsValid() const { 141 bool IPAddress::IsValid() const {
91 return IsIPv4() || IsIPv6(); 142 return IsIPv4() || IsIPv6();
92 } 143 }
93 144
94 // Don't compare IPv4 and IPv6 addresses (they have different range
95 // reservations). Keep separate reservation arrays for each IP type, and
96 // consolidate adjacent reserved ranges within a reservation array when
97 // possible.
98 // Sources for info:
99 // www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xhtml
100 // www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml
101 // They're formatted here with the prefix as the last element. For example:
102 // 10.0.0.0/8 becomes 10,0,0,0,8 and fec0::/10 becomes 0xfe,0xc0,0,0,0...,10.
103 bool IPAddress::IsReserved() const { 145 bool IPAddress::IsReserved() const {
104 static const unsigned char kReservedIPv4[][5] = { 146 if (IsIPv4()) {
105 {0, 0, 0, 0, 8}, {10, 0, 0, 0, 8}, {100, 64, 0, 0, 10}, 147 return IsReservedIPv4(ip_address_);
106 {127, 0, 0, 0, 8}, {169, 254, 0, 0, 16}, {172, 16, 0, 0, 12}, 148 } else if (IsIPv6()) {
107 {192, 0, 2, 0, 24}, {192, 88, 99, 0, 24}, {192, 168, 0, 0, 16}, 149 return IsReservedIPv6(ip_address_);
108 {198, 18, 0, 0, 15}, {198, 51, 100, 0, 24}, {203, 0, 113, 0, 24},
109 {224, 0, 0, 0, 3}};
110 static const unsigned char kReservedIPv6[][17] = {
111 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8},
112 {0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2},
113 {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2},
114 {0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
115 {0xe0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4},
116 {0xf0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5},
117 {0xf8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
118 {0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7},
119 {0xfe, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9},
120 {0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10},
121 {0xfe, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10},
122 };
123 size_t array_size = 0;
124 const unsigned char* array = nullptr;
125 switch (ip_address_.size()) {
126 case kIPv4AddressSize:
127 array_size = arraysize(kReservedIPv4);
128 array = kReservedIPv4[0];
129 break;
130 case kIPv6AddressSize:
131 array_size = arraysize(kReservedIPv6);
132 array = kReservedIPv6[0];
133 break;
134 }
135 if (!array)
136 return false;
137 size_t width = ip_address_.size() + 1;
138 for (size_t i = 0; i < array_size; ++i, array += width) {
139 if (IPAddressPrefixCheck(ip_address_, array, array[width - 1]))
140 return true;
141 } 150 }
142 return false; 151 return false;
143 } 152 }
144 153
145 bool IPAddress::IsZero() const { 154 bool IPAddress::IsZero() const {
146 for (auto x : ip_address_) { 155 for (auto x : ip_address_) {
147 if (x != 0) 156 if (x != 0)
148 return false; 157 return false;
149 } 158 }
150 159
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 308
300 unsigned CommonPrefixLength(const IPAddress& a1, const IPAddress& a2) { 309 unsigned CommonPrefixLength(const IPAddress& a1, const IPAddress& a2) {
301 return CommonPrefixLength(a1.bytes(), a2.bytes()); 310 return CommonPrefixLength(a1.bytes(), a2.bytes());
302 } 311 }
303 312
304 unsigned MaskPrefixLength(const IPAddress& mask) { 313 unsigned MaskPrefixLength(const IPAddress& mask) {
305 return MaskPrefixLength(mask.bytes()); 314 return MaskPrefixLength(mask.bytes());
306 } 315 }
307 316
308 } // namespace net 317 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/base/ip_address_unittest.cc » ('j') | net/base/ip_address_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698