OLD | NEW |
---|---|
(Empty) | |
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 #include "net/base/ip_address.h" | |
6 | |
7 #include "net/base/ip_address_number.h" | |
8 #include "url/gurl.h" | |
9 #include "url/url_canon_ip.h" | |
10 | |
11 namespace net { | |
12 | |
13 namespace { | |
14 const unsigned char kIPv4MappedPrefix[] = {0, 0, 0, 0, 0, 0, | |
15 0, 0, 0, 0, 0xFF, 0xFF}; | |
16 } | |
17 | |
18 const size_t IPAddress::kIPv4AddressSize = 4; | |
19 const size_t IPAddress::kIPv6AddressSize = 16; | |
20 | |
21 IPAddress::IPAddress() {} | |
22 | |
23 IPAddress::~IPAddress() {} | |
24 | |
25 IPAddress::IPAddress(const uint8_t* address, size_t address_len) | |
26 : ip_address_(std::vector<uint8_t>(address, address + address_len)) {} | |
27 | |
28 bool IPAddress::IsIPv4() const { | |
29 return ip_address_.size() == kIPv4AddressSize; | |
30 } | |
31 | |
32 bool IPAddress::IsIPv6() const { | |
33 return ip_address_.size() == kIPv6AddressSize; | |
34 } | |
35 | |
36 // Don't compare IPv4 and IPv6 addresses (they have different range | |
37 // reservations). Keep separate reservation arrays for each IP type, and | |
38 // consolidate adjacent reserved ranges within a reservation array when | |
39 // possible. | |
40 // Sources for info: | |
41 // www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xhtml | |
42 // www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml | |
43 // They're formatted here with the prefix as the last element. For example: | |
44 // 10.0.0.0/8 becomes 10,0,0,0,8 and fec0::/10 becomes 0xfe,0xc0,0,0,0...,10. | |
45 bool IPAddress::IsReserved() const { | |
46 return IsIPAddressReserved(ip_address_); | |
47 } | |
48 | |
49 bool IPAddress::IsIPv4Mapped() const { | |
50 if (!IsIPv6()) | |
51 return false; | |
52 return std::equal(ip_address_.begin(), | |
53 ip_address_.begin() + arraysize(kIPv4MappedPrefix), | |
54 kIPv4MappedPrefix); | |
55 } | |
56 | |
57 std::string IPAddress::ToString() const { | |
58 std::string str; | |
59 url::StdStringCanonOutput output(&str); | |
60 | |
61 if (IsIPv4()) { | |
62 url::AppendIPv4Address(&ip_address_.front(), &output); | |
63 } else if (IsIPv6()) { | |
64 url::AppendIPv6Address(&ip_address_.front(), &output); | |
65 } else { | |
66 size_t address_len = ip_address_.size(); | |
eroman
2015/11/30 22:12:33
I suggest removing this temporary variable, and ju
martijnc
2015/12/01 22:09:34
Done.
| |
67 CHECK(false) << "Invalid IP address with length: " << address_len; | |
68 } | |
69 | |
70 output.Complete(); | |
71 return str; | |
72 } | |
73 | |
74 // static | |
75 bool IPAddress::FromIPLiteral(const base::StringPiece& ip_literal, | |
76 IPAddress* ip_address) { | |
77 std::vector<unsigned char> ip; | |
78 | |
79 // |ip_literal| could be either a IPv4 or an IPv6 literal. If it contains | |
80 // a colon however, it must be an IPv6 address. | |
81 if (ip_literal.find(':') != base::StringPiece::npos) { | |
82 // GURL expects IPv6 hostnames to be surrounded with brackets. | |
83 std::string host_brackets = "["; | |
84 ip_literal.AppendToString(&host_brackets); | |
85 host_brackets.push_back(']'); | |
86 url::Component host_comp(0, host_brackets.size()); | |
87 | |
88 // Try parsing the hostname as an IPv6 literal. | |
89 ip.resize(16); // 128 bits. | |
90 bool result = | |
91 url::IPv6AddressToNumber(host_brackets.data(), host_comp, &(ip)[0]); | |
92 ip_address->ip_address_ = ip; | |
eroman
2015/11/30 22:12:33
(1) only replace ip_address_ on success
(2) use st
martijnc
2015/12/01 22:09:34
Done.
| |
93 return result; | |
94 } | |
95 | |
96 // Otherwise the string is an IPv4 address. | |
97 ip.resize(4); // 32 bits. | |
98 url::Component host_comp(0, ip_literal.size()); | |
99 int num_components; | |
100 url::CanonHostInfo::Family family = url::IPv4AddressToNumber( | |
101 ip_literal.data(), host_comp, &(ip)[0], &num_components); | |
102 | |
103 ip_address->ip_address_ = ip; | |
eroman
2015/11/30 22:12:33
same thing here.
martijnc
2015/12/01 22:09:34
Done.
| |
104 return family == url::CanonHostInfo::IPV4; | |
105 } | |
106 | |
107 bool IPAddress::operator==(const IPAddress& that) const { | |
108 return ip_address_ == that.ip_address_; | |
109 } | |
110 | |
111 bool IPAddress::operator<(const IPAddress& that) const { | |
112 // Sort IPv4 before IPv6. | |
113 if (ip_address_.size() != that.ip_address_.size()) { | |
114 return ip_address_.size() < that.ip_address_.size(); | |
115 } | |
116 | |
117 return ip_address_ < that.ip_address_; | |
118 } | |
119 | |
120 } // namespace net | |
OLD | NEW |