Index: net/base/net_util.cc |
diff --git a/net/base/net_util.cc b/net/base/net_util.cc |
index 56e779a6ae87dc2ee3095b6af6340b9042568ee3..d39d7abf7ff4889cd3518c092c968d1d43562c1a 100644 |
--- a/net/base/net_util.cc |
+++ b/net/base/net_util.cc |
@@ -2216,6 +2216,12 @@ bool ParseIPLiteralToNumber(const std::string& ip_literal, |
return family == url_canon::CanonHostInfo::IPV4; |
} |
+namespace { |
+ |
+const unsigned char kIPv4MappedPrefix[] = |
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF }; |
+} |
+ |
IPAddressNumber ConvertIPv4NumberToIPv6Number( |
const IPAddressNumber& ipv4_number) { |
DCHECK(ipv4_number.size() == 4); |
@@ -2224,13 +2230,27 @@ IPAddressNumber ConvertIPv4NumberToIPv6Number( |
// <80 bits of zeros> + <16 bits of ones> + <32-bit IPv4 address>. |
IPAddressNumber ipv6_number; |
ipv6_number.reserve(16); |
- ipv6_number.insert(ipv6_number.end(), 10, 0); |
- ipv6_number.push_back(0xFF); |
- ipv6_number.push_back(0xFF); |
+ ipv6_number.insert(ipv6_number.end(), |
+ kIPv4MappedPrefix, |
+ kIPv4MappedPrefix + arraysize(kIPv4MappedPrefix)); |
ipv6_number.insert(ipv6_number.end(), ipv4_number.begin(), ipv4_number.end()); |
return ipv6_number; |
} |
+bool IsIPv4Mapped(const IPAddressNumber& address) { |
+ if (address.size() != kIPv6AddressSize) |
+ return false; |
+ return std::equal(address.begin(), |
+ address.begin() + arraysize(kIPv4MappedPrefix), |
+ kIPv4MappedPrefix); |
+} |
+ |
+IPAddressNumber ConvertIPv4MappedToIPv4(const IPAddressNumber& address) { |
+ DCHECK(IsIPv4Mapped(address)); |
+ return IPAddressNumber(address.begin() + arraysize(kIPv4MappedPrefix), |
+ address.end()); |
+} |
+ |
bool ParseCIDRBlock(const std::string& cidr_literal, |
IPAddressNumber* ip_number, |
size_t* prefix_length_in_bits) { |