Chromium Code Reviews| 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 |