Migrate net/dns/* to net::IPAddress.

BUG=496258

Review URL: https://codereview.chromium.org/1755513003

Cr-Commit-Position: refs/heads/master@{#379314}
diff --git a/net/base/ip_address.cc b/net/base/ip_address.cc
index 170be40..82e250aa 100644
--- a/net/base/ip_address.cc
+++ b/net/base/ip_address.cc
@@ -74,6 +74,19 @@
   return true;
 }
 
+// static
+IPAddress IPAddress::IPv4Localhost() {
+  static const uint8_t kLocalhostIPv4[] = {127, 0, 0, 1};
+  return IPAddress(kLocalhostIPv4);
+}
+
+// static
+IPAddress IPAddress::IPv6Localhost() {
+  static const uint8_t kLocalhostIPv6[] = {0, 0, 0, 0, 0, 0, 0, 0,
+                                           0, 0, 0, 0, 0, 0, 0, 1};
+  return IPAddress(kLocalhostIPv6);
+}
+
 bool IPAddress::operator==(const IPAddress& that) const {
   return ip_address_ == that.ip_address_;
 }
diff --git a/net/base/ip_address.h b/net/base/ip_address.h
index f1f7480..2fb54b4 100644
--- a/net/base/ip_address.h
+++ b/net/base/ip_address.h
@@ -87,6 +87,12 @@
   // Returns the underlying byte vector.
   const std::vector<uint8_t>& bytes() const { return ip_address_; };
 
+  // Returns an IPAddress instance representing the 127.0.0.1 address.
+  static IPAddress IPv4Localhost();
+
+  // Returns an IPAddress instance representing the ::1 address.
+  static IPAddress IPv6Localhost();
+
   bool operator==(const IPAddress& that) const;
   bool operator!=(const IPAddress& that) const;
   bool operator<(const IPAddress& that) const;
@@ -133,6 +139,16 @@
                                        const IPAddress& ip_prefix,
                                        size_t prefix_length_in_bits);
 
+// Checks whether |address| starts with |prefix|. This provides similar
+// functionality as IPAddressMatchesPrefix() but doesn't perform automatic IPv4
+// to IPv4MappedIPv6 conversions and only checks against full bytes.
+template <size_t N>
+bool IPAddressStartsWith(const IPAddress& address, const uint8_t (&prefix)[N]) {
+  if (address.size() < N)
+    return false;
+  return std::equal(prefix, prefix + N, address.bytes().begin());
+}
+
 }  // namespace net
 
 #endif  // NET_BASE_IP_ADDRESS_NET_H_
diff --git a/net/base/ip_address_unittest.cc b/net/base/ip_address_unittest.cc
index b08d10a..dffb905 100644
--- a/net/base/ip_address_unittest.cc
+++ b/net/base/ip_address_unittest.cc
@@ -228,6 +228,46 @@
   EXPECT_EQ(expected, result);
 }
 
+TEST(IPAddressTest, IPAddressStartsWith) {
+  IPAddress ipv4_address(192, 168, 10, 5);
+
+  uint8_t ipv4_prefix1[] = {192, 168, 10};
+  EXPECT_TRUE(IPAddressStartsWith(ipv4_address, ipv4_prefix1));
+
+  uint8_t ipv4_prefix3[] = {192, 168, 10, 5};
+  EXPECT_TRUE(IPAddressStartsWith(ipv4_address, ipv4_prefix3));
+
+  uint8_t ipv4_prefix2[] = {192, 168, 10, 10};
+  EXPECT_FALSE(IPAddressStartsWith(ipv4_address, ipv4_prefix2));
+
+  // Prefix is longer than the address.
+  uint8_t ipv4_prefix4[] = {192, 168, 10, 10, 0};
+  EXPECT_FALSE(IPAddressStartsWith(ipv4_address, ipv4_prefix4));
+
+  IPAddress ipv6_address;
+  EXPECT_TRUE(ipv6_address.AssignFromIPLiteral("2a00:1450:400c:c09::64"));
+
+  uint8_t ipv6_prefix1[] = {42, 0, 20, 80, 64, 12, 12, 9};
+  EXPECT_TRUE(IPAddressStartsWith(ipv6_address, ipv6_prefix1));
+
+  uint8_t ipv6_prefix2[] = {41, 0, 20, 80, 64, 12, 12, 9,
+                            0,  0, 0,  0,  0,  0,  100};
+  EXPECT_FALSE(IPAddressStartsWith(ipv6_address, ipv6_prefix2));
+
+  uint8_t ipv6_prefix3[] = {42, 0, 20, 80, 64, 12, 12, 9,
+                            0,  0, 0,  0,  0,  0,  0,  100};
+  EXPECT_TRUE(IPAddressStartsWith(ipv6_address, ipv6_prefix3));
+
+  uint8_t ipv6_prefix4[] = {42, 0, 20, 80, 64, 12, 12, 9,
+                            0,  0, 0,  0,  0,  0,  0,  0};
+  EXPECT_FALSE(IPAddressStartsWith(ipv6_address, ipv6_prefix4));
+
+  // Prefix is longer than the address.
+  uint8_t ipv6_prefix5[] = {42, 0, 20, 80, 64, 12, 12, 9, 0,
+                            0,  0, 0,  0,  0,  0,  0,  10};
+  EXPECT_FALSE(IPAddressStartsWith(ipv6_address, ipv6_prefix5));
+}
+
 }  // anonymous namespace
 
 }  // namespace net
diff --git a/net/dns/dns_config_service_posix.cc b/net/dns/dns_config_service_posix.cc
index ab84b22..aaa12b0 100644
--- a/net/dns/dns_config_service_posix.cc
+++ b/net/dns/dns_config_service_posix.cc
@@ -18,6 +18,7 @@
 #include "base/single_thread_task_runner.h"
 #include "base/thread_task_runner_handle.h"
 #include "base/time/time.h"
+#include "net/base/ip_address.h"
 #include "net/base/ip_endpoint.h"
 #include "net/dns/dns_hosts.h"
 #include "net/dns/dns_protocol.h"
@@ -172,18 +173,18 @@
   if (dns1_string.length() == 0 && dns2_string.length() == 0)
     return CONFIG_PARSE_POSIX_NO_NAMESERVERS;
 
-  IPAddressNumber dns1_number, dns2_number;
-  bool parsed1 = ParseIPLiteralToNumber(dns1_string, &dns1_number);
-  bool parsed2 = ParseIPLiteralToNumber(dns2_string, &dns2_number);
+  IPAddress dns1_address, dns2_address;
+  bool parsed1 = dns1_address.AssignFromIPLiteral(dns1_string);
+  bool parsed2 = dns2_address.AssignFromIPLiteral(dns2_string);
   if (!parsed1 && !parsed2)
     return CONFIG_PARSE_POSIX_BAD_ADDRESS;
 
   if (parsed1) {
-    IPEndPoint dns1(dns1_number, dns_protocol::kDefaultPort);
+    IPEndPoint dns1(dns1_address, dns_protocol::kDefaultPort);
     dns_config->nameservers.push_back(dns1);
   }
   if (parsed2) {
-    IPEndPoint dns2(dns2_number, dns_protocol::kDefaultPort);
+    IPEndPoint dns2(dns2_address, dns_protocol::kDefaultPort);
     dns_config->nameservers.push_back(dns2);
   }
 
@@ -541,9 +542,8 @@
 
   // If any name server is 0.0.0.0, assume the configuration is invalid.
   // TODO(szym): Measure how often this happens. http://crbug.com/125599
-  const IPAddressNumber kEmptyAddress(kIPv4AddressSize);
   for (unsigned i = 0; i < dns_config->nameservers.size(); ++i) {
-    if (dns_config->nameservers[i].address().bytes() == kEmptyAddress)
+    if (dns_config->nameservers[i].address().IsZero())
       return CONFIG_PARSE_POSIX_NULL_ADDRESS;
   }
   return CONFIG_PARSE_POSIX_OK;
diff --git a/net/dns/dns_config_service_posix_unittest.cc b/net/dns/dns_config_service_posix_unittest.cc
index 04384d4..38c5cb6 100644
--- a/net/dns/dns_config_service_posix_unittest.cc
+++ b/net/dns/dns_config_service_posix_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/sys_byteorder.h"
 #include "base/test/test_timeouts.h"
 #include "base/threading/platform_thread.h"
+#include "net/base/ip_address.h"
 #include "net/dns/dns_config_service_posix.h"
 #include "net/dns/dns_protocol.h"
 
@@ -117,8 +118,8 @@
 
   config->nameservers.clear();
   for (unsigned i = 0; i < arraysize(kNameserversIPv4) && i < MAXNS; ++i) {
-    IPAddressNumber ip;
-    ParseIPLiteralToNumber(kNameserversIPv4[i], &ip);
+    IPAddress ip;
+    EXPECT_TRUE(ip.AssignFromIPLiteral(kNameserversIPv4[i]));
     config->nameservers.push_back(IPEndPoint(ip, NS_DEFAULTPORT + i));
   }
 
@@ -126,8 +127,8 @@
   for (unsigned i = 0; i < arraysize(kNameserversIPv6) && i < MAXNS; ++i) {
     if (!kNameserversIPv6[i])
       continue;
-    IPAddressNumber ip;
-    ParseIPLiteralToNumber(kNameserversIPv6[i], &ip);
+    IPAddress ip;
+    EXPECT_TRUE(ip.AssignFromIPLiteral(kNameserversIPv6[i]));
     config->nameservers[i] = IPEndPoint(ip, NS_DEFAULTPORT - i);
   }
 #endif
@@ -211,11 +212,11 @@
   }
 
   void MockDNSConfig(const char* dns_server) {
-    IPAddressNumber dns_number;
-    ASSERT_TRUE(ParseIPLiteralToNumber(dns_server, &dns_number));
+    IPAddress dns_address;
+    ASSERT_TRUE(dns_address.AssignFromIPLiteral(dns_server));
     test_config_.nameservers.clear();
     test_config_.nameservers.push_back(
-        IPEndPoint(dns_number, dns_protocol::kDefaultPort));
+        IPEndPoint(dns_address, dns_protocol::kDefaultPort));
     service_->SetDnsConfigForTesting(&test_config_);
   }
 
diff --git a/net/dns/dns_config_service_unittest.cc b/net/dns/dns_config_service_unittest.cc
index aa4b3c8..16d1c896 100644
--- a/net/dns/dns_config_service_unittest.cc
+++ b/net/dns/dns_config_service_unittest.cc
@@ -42,9 +42,8 @@
       if (server_str.empty())
         continue;
 
-      IPAddressNumber address;
-      bool parsed = ParseIPLiteralToNumber(server_str, &address);
-      EXPECT_TRUE(parsed);
+      IPAddress address;
+      EXPECT_TRUE(address.AssignFromIPLiteral(server_str));
       servers.push_back(IPEndPoint(address, dns_protocol::kDefaultPort));
     }
 
@@ -157,9 +156,8 @@
   // Generate a config using the given seed..
   DnsConfig MakeConfig(unsigned seed) {
     DnsConfig config;
-    IPAddressNumber ip;
-    CHECK(ParseIPLiteralToNumber("1.2.3.4", &ip));
-    config.nameservers.push_back(IPEndPoint(ip, seed & 0xFFFF));
+    config.nameservers.push_back(
+        IPEndPoint(IPAddress(1, 2, 3, 4), seed & 0xFFFF));
     EXPECT_TRUE(config.IsValid());
     return config;
   }
diff --git a/net/dns/dns_config_service_win.cc b/net/dns/dns_config_service_win.cc
index 0f085f4..35358f41 100644
--- a/net/dns/dns_config_service_win.cc
+++ b/net/dns/dns_config_service_win.cc
@@ -26,6 +26,7 @@
 #include "base/win/registry.h"
 #include "base/win/scoped_handle.h"
 #include "base/win/windows_version.h"
+#include "net/base/ip_address.h"
 #include "net/base/network_change_notifier.h"
 #include "net/dns/dns_hosts.h"
 #include "net/dns/dns_protocol.h"
@@ -220,13 +221,8 @@
 // Default address of "localhost" and local computer name can be overridden
 // by the HOSTS file, but if it's not there, then we need to fill it in.
 HostsParseWinResult AddLocalhostEntries(DnsHosts* hosts) {
-  const unsigned char kIPv4Localhost[] = { 127, 0, 0, 1 };
-  const unsigned char kIPv6Localhost[] = { 0, 0, 0, 0, 0, 0, 0, 0,
-                                           0, 0, 0, 0, 0, 0, 0, 1 };
-  IPAddressNumber loopback_ipv4(kIPv4Localhost,
-                                kIPv4Localhost + arraysize(kIPv4Localhost));
-  IPAddressNumber loopback_ipv6(kIPv6Localhost,
-                                kIPv6Localhost + arraysize(kIPv6Localhost));
+  IPAddress loopback_ipv4 = IPAddress::IPv4Localhost();
+  IPAddress loopback_ipv6 = IPAddress::IPv6Localhost();
 
   // This does not override any pre-existing entries from the HOSTS file.
   hosts->insert(std::make_pair(DnsHostsKey("localhost", ADDRESS_FAMILY_IPV4),
@@ -280,12 +276,10 @@
       }
       if (!have_ipv4 && (ipe.GetFamily() == ADDRESS_FAMILY_IPV4)) {
         have_ipv4 = true;
-        (*hosts)[DnsHostsKey(localname, ADDRESS_FAMILY_IPV4)] =
-            ipe.address().bytes();
+        (*hosts)[DnsHostsKey(localname, ADDRESS_FAMILY_IPV4)] = ipe.address();
       } else if (!have_ipv6 && (ipe.GetFamily() == ADDRESS_FAMILY_IPV6)) {
         have_ipv6 = true;
-        (*hosts)[DnsHostsKey(localname, ADDRESS_FAMILY_IPV6)] =
-            ipe.address().bytes();
+        (*hosts)[DnsHostsKey(localname, ADDRESS_FAMILY_IPV6)] = ipe.address();
       }
     }
   }
@@ -332,15 +326,12 @@
 // Returns true iff |address| is DNS address from IPv6 stateless discovery,
 // i.e., matches fec0:0:0:ffff::{1,2,3}.
 // http://tools.ietf.org/html/draft-ietf-ipngwg-dns-discovery
-bool IsStatelessDiscoveryAddress(const IPAddressNumber& address) {
-  if (address.size() != kIPv6AddressSize)
+bool IsStatelessDiscoveryAddress(const IPAddress& address) {
+  if (!address.IsIPv6())
     return false;
-  const uint8_t kPrefix[] = {
-      0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  };
-  return std::equal(kPrefix, kPrefix + arraysize(kPrefix),
-                    address.begin()) && (address.back() < 4);
+  const uint8_t kPrefix[] = {0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+  return IPAddressStartsWith(address, kPrefix) && (address.bytes().back() < 4);
 }
 
 // Returns the path to the HOSTS file.
@@ -514,7 +505,7 @@
       IPEndPoint ipe;
       if (ipe.FromSockAddr(address->Address.lpSockaddr,
                            address->Address.iSockaddrLength)) {
-        if (IsStatelessDiscoveryAddress(ipe.address().bytes()))
+        if (IsStatelessDiscoveryAddress(ipe.address()))
           continue;
         // Override unset port.
         if (!ipe.port())
diff --git a/net/dns/dns_config_service_win_unittest.cc b/net/dns/dns_config_service_win_unittest.cc
index 4568db4..87be751 100644
--- a/net/dns/dns_config_service_win_unittest.cc
+++ b/net/dns/dns_config_service_win_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "base/logging.h"
 #include "base/win/windows_version.h"
+#include "net/base/ip_address.h"
 #include "net/dns/dns_protocol.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -96,8 +97,8 @@
         // Note that |address| is moving backwards.
         address = address->Next = address - 1;
       }
-      IPAddressNumber ip;
-      CHECK(ParseIPLiteralToNumber(info.dns_server_addresses[j], &ip));
+      IPAddress ip;
+      CHECK(ip.AssignFromIPLiteral(info.dns_server_addresses[j]));
       IPEndPoint ipe = IPEndPoint(ip, info.ports[j]);
       address->Address.lpSockaddr =
           reinterpret_cast<LPSOCKADDR>(storage + num_addresses);
@@ -173,8 +174,8 @@
     // Default settings for the rest.
     std::vector<IPEndPoint> expected_nameservers;
     for (size_t j = 0; !t.expected_nameservers[j].empty(); ++j) {
-      IPAddressNumber ip;
-      ASSERT_TRUE(ParseIPLiteralToNumber(t.expected_nameservers[j], &ip));
+      IPAddress ip;
+      ASSERT_TRUE(ip.AssignFromIPLiteral(t.expected_nameservers[j]));
       uint16_t port = t.expected_ports[j];
       if (!port)
         port = dns_protocol::kDefaultPort;
diff --git a/net/dns/dns_hosts.cc b/net/dns/dns_hosts.cc
index a4f293f6..098c617 100644
--- a/net/dns/dns_hosts.cc
+++ b/net/dns/dns_hosts.cc
@@ -134,7 +134,7 @@
   CHECK(dns_hosts);
 
   StringPiece ip_text;
-  IPAddressNumber ip;
+  IPAddress ip;
   AddressFamily family = ADDRESS_FAMILY_IPV4;
   HostsParser parser(contents, comma_mode);
   while (parser.Advance()) {
@@ -144,11 +144,11 @@
       // the same IP address (usually 127.0.0.1).  Don't bother parsing the IP
       // again if it's the same as the one above it.
       if (new_ip_text != ip_text) {
-        IPAddressNumber new_ip;
-        if (ParseIPLiteralToNumber(parser.token().as_string(), &new_ip)) {
+        IPAddress new_ip;
+        if (new_ip.AssignFromIPLiteral(parser.token())) {
           ip_text = new_ip_text;
-          ip.swap(new_ip);
-          family = (ip.size() == 4) ? ADDRESS_FAMILY_IPV4 : ADDRESS_FAMILY_IPV6;
+          ip = new_ip;
+          family = (ip.IsIPv4()) ? ADDRESS_FAMILY_IPV4 : ADDRESS_FAMILY_IPV6;
         } else {
           parser.SkipRestOfLine();
         }
@@ -156,7 +156,7 @@
     } else {
       DnsHostsKey key(parser.token().as_string(), family);
       key.first = base::ToLowerASCII(key.first);
-      IPAddressNumber* mapped_ip = &(*dns_hosts)[key];
+      IPAddress* mapped_ip = &(*dns_hosts)[key];
       if (mapped_ip->empty())
         *mapped_ip = ip;
       // else ignore this entry (first hit counts)
diff --git a/net/dns/dns_hosts.h b/net/dns/dns_hosts.h
index 0b9edc2..2ce7c52 100644
--- a/net/dns/dns_hosts.h
+++ b/net/dns/dns_hosts.h
@@ -15,7 +15,7 @@
 #include "base/containers/hash_tables.h"
 #include "base/files/file_path.h"
 #include "net/base/address_family.h"
-#include "net/base/ip_address_number.h"
+#include "net/base/ip_address.h"
 #include "net/base/net_export.h"
 
 namespace net {
@@ -57,11 +57,11 @@
 // 10.0.0.1 localhost
 // The expected resolution of localhost is 127.0.0.1.
 #if !defined(OS_ANDROID)
-typedef base::hash_map<DnsHostsKey, IPAddressNumber> DnsHosts;
+typedef base::hash_map<DnsHostsKey, IPAddress> DnsHosts;
 #else
 // Android's hash_map doesn't support ==, so fall back to map.  (Chromium on
 // Android doesn't use the built-in DNS resolver anyway, so it's irrelevant.)
-typedef std::map<DnsHostsKey, IPAddressNumber> DnsHosts;
+typedef std::map<DnsHostsKey, IPAddress> DnsHosts;
 #endif
 
 // Parses |contents| (as read from /etc/hosts or equivalent) and stores results
diff --git a/net/dns/dns_hosts_unittest.cc b/net/dns/dns_hosts_unittest.cc
index 1bce190..9e52f0e2 100644
--- a/net/dns/dns_hosts_unittest.cc
+++ b/net/dns/dns_hosts_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "net/dns/dns_hosts.h"
 
+#include "net/base/ip_address.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace net {
@@ -21,9 +22,9 @@
                            DnsHosts* expected_hosts_out) {
   for (size_t i = 0; i < num_entries; ++i) {
     DnsHostsKey key(entries[i].host, entries[i].family);
-    IPAddressNumber& ip_ref = (*expected_hosts_out)[key];
+    IPAddress& ip_ref = (*expected_hosts_out)[key];
     ASSERT_TRUE(ip_ref.empty());
-    ASSERT_TRUE(ParseIPLiteralToNumber(entries[i].ip, &ip_ref));
+    ASSERT_TRUE(ip_ref.AssignFromIPLiteral(entries[i].ip));
     ASSERT_EQ(ip_ref.size(),
         (entries[i].family == ADDRESS_FAMILY_IPV4) ? 4u : 16u);
   }
diff --git a/net/dns/dns_session_unittest.cc b/net/dns/dns_session_unittest.cc
index b2a09f1..1c65c67 100644
--- a/net/dns/dns_session_unittest.cc
+++ b/net/dns/dns_session_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/rand_util.h"
 #include "base/stl_util.h"
+#include "net/base/ip_address.h"
 #include "net/dns/dns_protocol.h"
 #include "net/dns/dns_socket_pool.h"
 #include "net/log/net_log.h"
@@ -113,12 +114,9 @@
 void DnsSessionTest::Initialize(unsigned num_servers) {
   CHECK(num_servers < 256u);
   config_.nameservers.clear();
-  IPAddressNumber dns_ip;
-  bool rv = ParseIPLiteralToNumber("192.168.1.0", &dns_ip);
-  EXPECT_TRUE(rv);
   for (unsigned char i = 0; i < num_servers; ++i) {
-    dns_ip[3] = i;
-    IPEndPoint dns_endpoint(dns_ip, dns_protocol::kDefaultPort);
+    IPEndPoint dns_endpoint(IPAddress(192, 168, 1, i),
+                            dns_protocol::kDefaultPort);
     config_.nameservers.push_back(dns_endpoint);
   }
 
diff --git a/net/dns/dns_transaction.cc b/net/dns/dns_transaction.cc
index 8eebb8c6..f726bd2 100644
--- a/net/dns/dns_transaction.cc
+++ b/net/dns/dns_transaction.cc
@@ -28,6 +28,7 @@
 #include "base/values.h"
 #include "net/base/completion_callback.h"
 #include "net/base/io_buffer.h"
+#include "net/base/ip_address.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_errors.h"
 #include "net/dns/dns_protocol.h"
@@ -57,8 +58,8 @@
 }
 
 bool IsIPLiteral(const std::string& hostname) {
-  IPAddressNumber ip;
-  return ParseIPLiteralToNumber(hostname, &ip);
+  IPAddress ip;
+  return ip.AssignFromIPLiteral(hostname);
 }
 
 scoped_ptr<base::Value> NetLogStartCallback(
diff --git a/net/dns/dns_transaction_unittest.cc b/net/dns/dns_transaction_unittest.cc
index 7b906ba..2f8e6755 100644
--- a/net/dns/dns_transaction_unittest.cc
+++ b/net/dns/dns_transaction_unittest.cc
@@ -14,6 +14,7 @@
 #include "base/rand_util.h"
 #include "base/sys_byteorder.h"
 #include "base/test/test_timeouts.h"
+#include "net/base/ip_address.h"
 #include "net/dns/dns_protocol.h"
 #include "net/dns/dns_query.h"
 #include "net/dns/dns_response.h"
@@ -333,15 +334,9 @@
   void ConfigureNumServers(unsigned num_servers) {
     CHECK_LE(num_servers, 255u);
     config_.nameservers.clear();
-    IPAddressNumber dns_ip;
-    {
-      bool rv = ParseIPLiteralToNumber("192.168.1.0", &dns_ip);
-      EXPECT_TRUE(rv);
-    }
     for (unsigned i = 0; i < num_servers; ++i) {
-      dns_ip[3] = i;
-      config_.nameservers.push_back(IPEndPoint(dns_ip,
-                                               dns_protocol::kDefaultPort));
+      config_.nameservers.push_back(
+          IPEndPoint(IPAddress(192, 168, 1, i), dns_protocol::kDefaultPort));
     }
   }
 
diff --git a/net/dns/host_resolver_impl.cc b/net/dns/host_resolver_impl.cc
index af91b09..de32c90 100644
--- a/net/dns/host_resolver_impl.cc
+++ b/net/dns/host_resolver_impl.cc
@@ -39,6 +39,7 @@
 #include "net/base/address_family.h"
 #include "net/base/address_list.h"
 #include "net/base/host_port_pair.h"
+#include "net/base/ip_address.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_errors.h"
 #include "net/base/url_util.h"
@@ -167,7 +168,7 @@
 // possible to navigate to http://127.0.53.53/ directly.
 //
 // For more details: https://www.icann.org/news/announcement-2-2014-08-01-en
-const unsigned char kIcanNameCollisionIp[] = {127, 0, 53, 53};
+const uint8_t kIcanNameCollisionIp[] = {127, 0, 53, 53};
 
 void UmaAsyncDnsResolveStatus(DnsResolveStatus result) {
   UMA_HISTOGRAM_ENUMERATION("AsyncDNS.ResolveStatus",
@@ -195,8 +196,7 @@
 }
 
 // Attempts to connect a UDP socket to |dest|:53.
-bool IsGloballyReachable(const IPAddressNumber& dest,
-                         const BoundNetLog& net_log) {
+bool IsGloballyReachable(const IPAddress& dest, const BoundNetLog& net_log) {
   // TODO(eroman): Remove ScopedTracker below once crbug.com/455942 is fixed.
   tracked_objects::ScopedTracker tracking_profile_1(
       FROM_HERE_WITH_EXPLICIT_FUNCTION("455942 IsGloballyReachable"));
@@ -215,16 +215,17 @@
   if (rv != OK)
     return false;
   DCHECK_EQ(ADDRESS_FAMILY_IPV6, endpoint.GetFamily());
-  const IPAddressNumber& address = endpoint.address().bytes();
-  bool is_link_local = (address[0] == 0xFE) && ((address[1] & 0xC0) == 0x80);
+  const IPAddress& address = endpoint.address();
+
+  bool is_link_local =
+      (address.bytes()[0] == 0xFE) && ((address.bytes()[1] & 0xC0) == 0x80);
   if (is_link_local)
     return false;
+
   const uint8_t kTeredoPrefix[] = {0x20, 0x01, 0, 0};
-  bool is_teredo = std::equal(kTeredoPrefix,
-                              kTeredoPrefix + arraysize(kTeredoPrefix),
-                              address.begin());
-  if (is_teredo)
+  if (IPAddressStartsWith(address, kTeredoPrefix))
     return false;
+
   return true;
 }
 
@@ -299,10 +300,10 @@
 // Returns true if |addresses| contains only IPv4 loopback addresses.
 bool IsAllIPv4Loopback(const AddressList& addresses) {
   for (unsigned i = 0; i < addresses.size(); ++i) {
-    const IPAddressNumber& address = addresses[i].address().bytes();
+    const IPAddress& address = addresses[i].address();
     switch (addresses[i].GetFamily()) {
       case ADDRESS_FAMILY_IPV4:
-        if (address[0] != 127)
+        if (address.bytes()[0] != 127)
           return false;
         break;
       case ADDRESS_FAMILY_IPV6:
@@ -493,25 +494,15 @@
 bool ResolveLocalHostname(base::StringPiece host,
                           uint16_t port,
                           AddressList* address_list) {
-  static const unsigned char kLocalhostIPv4[] = {127, 0, 0, 1};
-  static const unsigned char kLocalhostIPv6[] = {
-      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
-
   address_list->clear();
 
   bool is_local6;
   if (!IsLocalHostname(host, &is_local6))
     return false;
 
-  address_list->push_back(
-      IPEndPoint(IPAddressNumber(kLocalhostIPv6,
-                                 kLocalhostIPv6 + arraysize(kLocalhostIPv6)),
-                 port));
+  address_list->push_back(IPEndPoint(IPAddress::IPv6Localhost(), port));
   if (!is_local6) {
-    address_list->push_back(
-        IPEndPoint(IPAddressNumber(kLocalhostIPv4,
-                                   kLocalhostIPv4 + arraysize(kLocalhostIPv4)),
-                   port));
+    address_list->push_back(IPEndPoint(IPAddress::IPv4Localhost(), port));
   }
 
   return true;
@@ -738,9 +729,8 @@
     // Fail the resolution if the result contains 127.0.53.53. See the comment
     // block of kIcanNameCollisionIp for details on why.
     for (const auto& it : results) {
-      const IPAddressNumber& cur = it.address().bytes();
-      if (cur.size() == arraysize(kIcanNameCollisionIp) &&
-          0 == memcmp(&cur.front(), kIcanNameCollisionIp, cur.size())) {
+      const IPAddress& cur = it.address();
+      if (cur.IsIPv4() && IPAddressStartsWith(cur, kIcanNameCollisionIp)) {
         error = ERR_ICANN_NAME_COLLISION;
         break;
       }
@@ -1939,16 +1929,16 @@
 
   LogStartRequest(source_net_log, info);
 
-  IPAddressNumber ip_number;
-  IPAddressNumber* ip_number_ptr = nullptr;
-  if (ParseIPLiteralToNumber(info.hostname(), &ip_number))
-    ip_number_ptr = &ip_number;
+  IPAddress ip_address;
+  IPAddress* ip_address_ptr = nullptr;
+  if (ip_address.AssignFromIPLiteral(info.hostname()))
+    ip_address_ptr = &ip_address;
 
   // Build a key that identifies the request in the cache and in the
   // outstanding jobs map.
-  Key key = GetEffectiveKeyForRequest(info, ip_number_ptr, source_net_log);
+  Key key = GetEffectiveKeyForRequest(info, ip_address_ptr, source_net_log);
 
-  int rv = ResolveHelper(key, info, ip_number_ptr, addresses, source_net_log);
+  int rv = ResolveHelper(key, info, ip_address_ptr, addresses, source_net_log);
   if (rv != ERR_DNS_CACHE_MISS) {
     LogFinishRequest(source_net_log, info, rv);
     RecordTotalTime(HaveDnsConfig(), info.is_speculative(), base::TimeDelta());
@@ -1994,7 +1984,7 @@
 
 int HostResolverImpl::ResolveHelper(const Key& key,
                                     const RequestInfo& info,
-                                    const IPAddressNumber* ip_number,
+                                    const IPAddress* ip_address,
                                     AddressList* addresses,
                                     const BoundNetLog& source_net_log) {
   // The result of |getaddrinfo| for empty hosts is inconsistent across systems.
@@ -2004,7 +1994,7 @@
     return ERR_NAME_NOT_RESOLVED;
 
   int net_error = ERR_UNEXPECTED;
-  if (ResolveAsIP(key, info, ip_number, &net_error, addresses))
+  if (ResolveAsIP(key, info, ip_address, &net_error, addresses))
     return net_error;
   if (ServeFromCache(key, info, &net_error, addresses)) {
     source_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT);
@@ -2032,14 +2022,14 @@
   // Update the net log and notify registered observers.
   LogStartRequest(source_net_log, info);
 
-  IPAddressNumber ip_number;
-  IPAddressNumber* ip_number_ptr = nullptr;
-  if (ParseIPLiteralToNumber(info.hostname(), &ip_number))
-    ip_number_ptr = &ip_number;
+  IPAddress ip_address;
+  IPAddress* ip_address_ptr = nullptr;
+  if (ip_address.AssignFromIPLiteral(info.hostname()))
+    ip_address_ptr = &ip_address;
 
-  Key key = GetEffectiveKeyForRequest(info, ip_number_ptr, source_net_log);
+  Key key = GetEffectiveKeyForRequest(info, ip_address_ptr, source_net_log);
 
-  int rv = ResolveHelper(key, info, ip_number_ptr, addresses, source_net_log);
+  int rv = ResolveHelper(key, info, ip_address_ptr, addresses, source_net_log);
   LogFinishRequest(source_net_log, info, rv);
   return rv;
 }
@@ -2084,12 +2074,12 @@
 
 bool HostResolverImpl::ResolveAsIP(const Key& key,
                                    const RequestInfo& info,
-                                   const IPAddressNumber* ip_number,
+                                   const IPAddress* ip_address,
                                    int* net_error,
                                    AddressList* addresses) {
   DCHECK(addresses);
   DCHECK(net_error);
-  if (ip_number == nullptr)
+  if (ip_address == nullptr)
     return false;
 
   DCHECK_EQ(key.host_resolver_flags &
@@ -2098,13 +2088,13 @@
             0) << " Unhandled flag";
 
   *net_error = OK;
-  AddressFamily family = GetAddressFamily(*ip_number);
+  AddressFamily family = GetAddressFamily(*ip_address);
   if (key.address_family != ADDRESS_FAMILY_UNSPECIFIED &&
       key.address_family != family) {
     // Don't return IPv6 addresses for IPv4 queries, and vice versa.
     *net_error = ERR_NAME_NOT_RESOLVED;
   } else {
-    *addresses = AddressList::CreateFromIPAddress(*ip_number, info.port());
+    *addresses = AddressList::CreateFromIPAddress(*ip_address, info.port());
     if (key.host_resolver_flags & HOST_RESOLVER_CANONNAME)
       addresses->SetDefaultCanonicalName();
   }
@@ -2235,7 +2225,7 @@
 
 HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest(
     const RequestInfo& info,
-    const IPAddressNumber* ip_number,
+    const IPAddress* ip_address,
     const BoundNetLog& net_log) {
   HostResolverFlags effective_flags =
       info.host_resolver_flags() | additional_resolver_flags_;
@@ -2249,7 +2239,7 @@
         // that this query is UNSPECIFIED (see info.address_family()
         // check above) so the code requesting the resolution should be amenable
         // to receiving a IPv6 resolution.
-        ip_number == nullptr) {
+        ip_address == nullptr) {
       if (!IsIPv6Reachable(net_log)) {
         effective_address_family = ADDRESS_FAMILY_IPV4;
         effective_flags |= HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
@@ -2264,9 +2254,8 @@
   base::TimeTicks now = base::TimeTicks::Now();
   bool cached = true;
   if ((now - last_ipv6_probe_time_).InMilliseconds() > kIPv6ProbePeriodMs) {
-    IPAddressNumber address(kIPv6ProbeAddress,
-                            kIPv6ProbeAddress + arraysize(kIPv6ProbeAddress));
-    last_ipv6_probe_result_ = IsGloballyReachable(address, net_log);
+    last_ipv6_probe_result_ =
+        IsGloballyReachable(IPAddress(kIPv6ProbeAddress), net_log);
     last_ipv6_probe_time_ = now;
     cached = false;
   }
diff --git a/net/dns/host_resolver_impl.h b/net/dns/host_resolver_impl.h
index aa76363..fc3835d 100644
--- a/net/dns/host_resolver_impl.h
+++ b/net/dns/host_resolver_impl.h
@@ -16,7 +16,6 @@
 #include "base/strings/string_piece.h"
 #include "base/threading/non_thread_safe.h"
 #include "base/time/time.h"
-#include "net/base/ip_address_number.h"
 #include "net/base/net_export.h"
 #include "net/base/network_change_notifier.h"
 #include "net/dns/host_cache.h"
@@ -28,6 +27,7 @@
 class AddressList;
 class BoundNetLog;
 class DnsClient;
+class IPAddress;
 class NetLog;
 
 // For each hostname that is requested, HostResolver creates a
@@ -169,7 +169,7 @@
   // HOSTS and is not localhost.
   int ResolveHelper(const Key& key,
                     const RequestInfo& info,
-                    const IPAddressNumber* ip_address,
+                    const IPAddress* ip_address,
                     AddressList* addresses,
                     const BoundNetLog& request_net_log);
 
@@ -177,7 +177,7 @@
   // succeeds, returns false otherwise.
   bool ResolveAsIP(const Key& key,
                    const RequestInfo& info,
-                   const IPAddressNumber* ip_address,
+                   const IPAddress* ip_address,
                    int* net_error,
                    AddressList* addresses);
 
@@ -208,7 +208,7 @@
   // "effective" address family by inheriting the resolver's default address
   // family when the request leaves it unspecified.
   Key GetEffectiveKeyForRequest(const RequestInfo& info,
-                                const IPAddressNumber* ip_number,
+                                const IPAddress* ip_address,
                                 const BoundNetLog& net_log);
 
   // Probes IPv6 support and returns true if IPv6 support is enabled.
diff --git a/net/dns/host_resolver_impl_unittest.cc b/net/dns/host_resolver_impl_unittest.cc
index 3d30dbe..2f02d21 100644
--- a/net/dns/host_resolver_impl_unittest.cc
+++ b/net/dns/host_resolver_impl_unittest.cc
@@ -26,6 +26,7 @@
 #include "base/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "net/base/address_list.h"
+#include "net/base/ip_address.h"
 #include "net/base/net_errors.h"
 #include "net/dns/dns_client.h"
 #include "net/dns/dns_test_util.h"
@@ -189,8 +190,8 @@
 bool AddressListContains(const AddressList& list,
                          const std::string& address,
                          uint16_t port) {
-  IPAddressNumber ip;
-  bool rv = ParseIPLiteralToNumber(address, &ip);
+  IPAddress ip;
+  bool rv = ip.AssignFromIPLiteral(address);
   DCHECK(rv);
   return std::find(list.begin(),
                    list.end(),
@@ -446,9 +447,6 @@
   }
 };
 
-const unsigned char kLocalhostIPv4[] = {127, 0, 0, 1};
-const unsigned char kLocalhostIPv6[] =
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
 const uint16_t kLocalhostLookupPort = 80;
 
 bool HasEndpoint(const IPEndPoint& endpoint, const AddressList& addresses) {
@@ -460,14 +458,8 @@
 }
 
 void TestBothLoopbackIPs(const std::string& host) {
-  IPEndPoint localhost_ipv4(
-      IPAddressNumber(kLocalhostIPv4,
-                      kLocalhostIPv4 + arraysize(kLocalhostIPv4)),
-      kLocalhostLookupPort);
-  IPEndPoint localhost_ipv6(
-      IPAddressNumber(kLocalhostIPv6,
-                      kLocalhostIPv6 + arraysize(kLocalhostIPv6)),
-      kLocalhostLookupPort);
+  IPEndPoint localhost_ipv4(IPAddress::IPv4Localhost(), kLocalhostLookupPort);
+  IPEndPoint localhost_ipv6(IPAddress::IPv6Localhost(), kLocalhostLookupPort);
 
   AddressList addresses;
   EXPECT_TRUE(ResolveLocalHostname(host, kLocalhostLookupPort, &addresses));
@@ -477,10 +469,7 @@
 }
 
 void TestIPv6LoopbackOnly(const std::string& host) {
-  IPEndPoint localhost_ipv6(
-      IPAddressNumber(kLocalhostIPv6,
-                      kLocalhostIPv6 + arraysize(kLocalhostIPv6)),
-      kLocalhostLookupPort);
+  IPEndPoint localhost_ipv6(IPAddress::IPv6Localhost(), kLocalhostLookupPort);
 
   AddressList addresses;
   EXPECT_TRUE(ResolveLocalHostname(host, kLocalhostLookupPort, &addresses));
@@ -1447,10 +1436,7 @@
 }
 
 DnsConfig CreateValidDnsConfig() {
-  IPAddressNumber dns_ip;
-  bool rv = ParseIPLiteralToNumber("192.168.1.0", &dns_ip);
-  EXPECT_TRUE(rv);
-
+  IPAddress dns_ip(192, 168, 1, 0);
   DnsConfig config;
   config.nameservers.push_back(IPEndPoint(dns_ip, dns_protocol::kDefaultPort));
   EXPECT_TRUE(config.IsValid());
@@ -1687,9 +1673,8 @@
   EXPECT_EQ(ERR_IO_PENDING, req0->Resolve());
   EXPECT_EQ(ERR_NAME_NOT_RESOLVED, req0->WaitForResult());
 
-  IPAddressNumber local_ipv4, local_ipv6;
-  ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &local_ipv4));
-  ASSERT_TRUE(ParseIPLiteralToNumber("::1", &local_ipv6));
+  IPAddress local_ipv4 = IPAddress::IPv4Localhost();
+  IPAddress local_ipv6 = IPAddress::IPv6Localhost();
 
   DnsHosts hosts;
   hosts[DnsHostsKey("nx_ipv4", ADDRESS_FAMILY_IPV4)] = local_ipv4;
@@ -1878,9 +1863,8 @@
   // Configure DnsClient with dual-host HOSTS file.
   DnsConfig config_hosts = CreateValidDnsConfig();
   DnsHosts hosts;
-  IPAddressNumber local_ipv4, local_ipv6;
-  ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &local_ipv4));
-  ASSERT_TRUE(ParseIPLiteralToNumber("::1", &local_ipv6));
+  IPAddress local_ipv4 = IPAddress::IPv4Localhost();
+  IPAddress local_ipv6 = IPAddress::IPv6Localhost();
   if (saw_ipv4)
     hosts[DnsHostsKey("localhost", ADDRESS_FAMILY_IPV4)] = local_ipv4;
   if (saw_ipv6)
diff --git a/net/dns/host_resolver_mojo_unittest.cc b/net/dns/host_resolver_mojo_unittest.cc
index c0d05a7..a210d78 100644
--- a/net/dns/host_resolver_mojo_unittest.cc
+++ b/net/dns/host_resolver_mojo_unittest.cc
@@ -9,6 +9,7 @@
 
 #include "mojo/public/cpp/bindings/binding.h"
 #include "net/base/address_list.h"
+#include "net/base/ip_address.h"
 #include "net/base/net_errors.h"
 #include "net/base/request_priority.h"
 #include "net/base/test_completion_callback.h"
@@ -174,11 +175,10 @@
 
 TEST_F(HostResolverMojoTest, Basic) {
   AddressList address_list;
-  IPAddressNumber address_number;
-  ASSERT_TRUE(ParseIPLiteralToNumber("1.2.3.4", &address_number));
-  address_list.push_back(IPEndPoint(address_number, 12345));
+  IPAddress address(1, 2, 3, 4);
+  address_list.push_back(IPEndPoint(address, 12345));
   address_list.push_back(
-      IPEndPoint(ConvertIPv4NumberToIPv6Number(address_number), 12345));
+      IPEndPoint(ConvertIPv4ToIPv4MappedIPv6(address), 12345));
   mock_resolver_->AddAction(HostResolverAction::ReturnResult(address_list));
   HostResolver::RequestInfo request_info(
       HostPortPair::FromString("example.com:12345"));
@@ -198,11 +198,10 @@
 
 TEST_F(HostResolverMojoTest, ResolveCachedResult) {
   AddressList address_list;
-  IPAddressNumber address_number;
-  ASSERT_TRUE(ParseIPLiteralToNumber("1.2.3.4", &address_number));
-  address_list.push_back(IPEndPoint(address_number, 12345));
+  IPAddress address(1, 2, 3, 4);
+  address_list.push_back(IPEndPoint(address, 12345));
   address_list.push_back(
-      IPEndPoint(ConvertIPv4NumberToIPv6Number(address_number), 12345));
+      IPEndPoint(ConvertIPv4ToIPv4MappedIPv6(address), 12345));
   mock_resolver_->AddAction(HostResolverAction::ReturnResult(address_list));
   HostResolver::RequestInfo request_info(
       HostPortPair::FromString("example.com:12345"));
@@ -215,9 +214,9 @@
   EXPECT_EQ(OK, Resolve(request_info, &result));
   ASSERT_EQ(2u, result.size());
   address_list.clear();
-  address_list.push_back(IPEndPoint(address_number, 6789));
+  address_list.push_back(IPEndPoint(address, 6789));
   address_list.push_back(
-      IPEndPoint(ConvertIPv4NumberToIPv6Number(address_number), 6789));
+      IPEndPoint(ConvertIPv4ToIPv4MappedIPv6(address), 6789));
   EXPECT_EQ(address_list[0], result[0]);
   EXPECT_EQ(address_list[1], result[1]);
   EXPECT_EQ(1u, mock_resolver_->requests().size());
@@ -234,9 +233,8 @@
 
 TEST_F(HostResolverMojoTest, Multiple) {
   AddressList address_list;
-  IPAddressNumber address_number;
-  ASSERT_TRUE(ParseIPLiteralToNumber("1.2.3.4", &address_number));
-  address_list.push_back(IPEndPoint(address_number, 12345));
+  IPAddress address(1, 2, 3, 4);
+  address_list.push_back(IPEndPoint(address, 12345));
   mock_resolver_->AddAction(HostResolverAction::ReturnResult(address_list));
   mock_resolver_->AddAction(
       HostResolverAction::ReturnError(ERR_NAME_NOT_RESOLVED));
@@ -359,11 +357,10 @@
 
 TEST_F(HostResolverMojoTest, ResolveFromCache_Hit) {
   AddressList address_list;
-  IPAddressNumber address_number;
-  ASSERT_TRUE(ParseIPLiteralToNumber("1.2.3.4", &address_number));
-  address_list.push_back(IPEndPoint(address_number, 12345));
+  IPAddress address(1, 2, 3, 4);
+  address_list.push_back(IPEndPoint(address, 12345));
   address_list.push_back(
-      IPEndPoint(ConvertIPv4NumberToIPv6Number(address_number), 12345));
+      IPEndPoint(ConvertIPv4ToIPv4MappedIPv6(address), 12345));
   mock_resolver_->AddAction(HostResolverAction::ReturnResult(address_list));
   HostResolver::RequestInfo request_info(
       HostPortPair::FromString("example.com:12345"));
@@ -382,11 +379,10 @@
 
 TEST_F(HostResolverMojoTest, ResolveFromCache_CacheNotAllowed) {
   AddressList address_list;
-  IPAddressNumber address_number;
-  ASSERT_TRUE(ParseIPLiteralToNumber("1.2.3.4", &address_number));
-  address_list.push_back(IPEndPoint(address_number, 12345));
+  IPAddress address(1, 2, 3, 4);
+  address_list.push_back(IPEndPoint(address, 12345));
   address_list.push_back(
-      IPEndPoint(ConvertIPv4NumberToIPv6Number(address_number), 12345));
+      IPEndPoint(ConvertIPv4ToIPv4MappedIPv6(address), 12345));
   mock_resolver_->AddAction(HostResolverAction::ReturnResult(address_list));
   HostResolver::RequestInfo request_info(
       HostPortPair::FromString("example.com:12345"));
diff --git a/net/dns/mdns_client.cc b/net/dns/mdns_client.cc
index 109a836..64e0d75 100644
--- a/net/dns/mdns_client.cc
+++ b/net/dns/mdns_client.cc
@@ -4,6 +4,7 @@
 
 #include "net/dns/mdns_client.h"
 
+#include "net/base/ip_address.h"
 #include "net/base/net_errors.h"
 #include "net/base/network_interfaces.h"
 #include "net/dns/dns_protocol.h"
@@ -17,9 +18,8 @@
 const char kMDnsMulticastGroupIPv6[] = "FF02::FB";
 
 IPEndPoint GetMDnsIPEndPoint(const char* address) {
-  IPAddressNumber multicast_group_number;
-  bool success = ParseIPLiteralToNumber(address,
-                                        &multicast_group_number);
+  IPAddress multicast_group_number;
+  bool success = multicast_group_number.AssignFromIPLiteral(address);
   DCHECK(success);
   return IPEndPoint(multicast_group_number,
                     dns_protocol::kDefaultPortMulticast);
@@ -28,7 +28,7 @@
 int Bind(const IPEndPoint& multicast_addr,
          uint32_t interface_index,
          DatagramServerSocket* socket) {
-  IPAddressNumber address_any(multicast_addr.address().size());
+  IPAddress address_any(std::vector<uint8_t>(multicast_addr.address().size()));
   IPEndPoint bind_endpoint(address_any, multicast_addr.port());
 
   socket->AllowAddressReuse();
diff --git a/net/dns/mdns_client_unittest.cc b/net/dns/mdns_client_unittest.cc
index ae1a8d91..b8f38cf 100644
--- a/net/dns/mdns_client_unittest.cc
+++ b/net/dns/mdns_client_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/time/clock.h"
 #include "base/time/default_clock.h"
 #include "base/timer/mock_timer.h"
+#include "net/base/ip_address.h"
 #include "net/base/rand_callback.h"
 #include "net/base/test_completion_callback.h"
 #include "net/dns/mdns_client_impl.h"
@@ -930,13 +931,13 @@
 
 ACTION_P(SaveIPAddress, ip_container) {
   ::testing::StaticAssertTypeEq<const RecordParsed*, arg1_type>();
-  ::testing::StaticAssertTypeEq<IPAddressNumber*, ip_container_type>();
+  ::testing::StaticAssertTypeEq<IPAddress*, ip_container_type>();
 
   *ip_container = arg1->template rdata<ARecordRdata>()->address();
 }
 
 TEST_F(MDnsTest, DoubleRecordDisagreeing) {
-  IPAddressNumber address;
+  IPAddress address;
   StrictMock<MockListenerDelegate> delegate_privet;
 
   scoped_ptr<MDnsListener> listener_privet = test_client_->CreateListener(
@@ -951,7 +952,7 @@
   SimulatePacketReceive(kCorruptedPacketDoubleRecord,
                         sizeof(kCorruptedPacketDoubleRecord));
 
-  EXPECT_EQ("2.3.4.5", IPAddressToString(address));
+  EXPECT_EQ("2.3.4.5", address.ToString());
 }
 
 TEST_F(MDnsTest, NsecWithListener) {
diff --git a/net/dns/mock_host_resolver.cc b/net/dns/mock_host_resolver.cc
index b97c51b..b734cd3 100644
--- a/net/dns/mock_host_resolver.cc
+++ b/net/dns/mock_host_resolver.cc
@@ -17,6 +17,7 @@
 #include "base/strings/string_util.h"
 #include "base/thread_task_runner_handle.h"
 #include "base/threading/platform_thread.h"
+#include "net/base/ip_address.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_errors.h"
 #include "net/base/test_completion_callback.h"
@@ -44,12 +45,12 @@
   addrlist->set_canonical_name(canonical_name);
   for (const base::StringPiece& address : base::SplitStringPiece(
            host_list, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
-    IPAddressNumber ip_number;
-    if (!ParseIPLiteralToNumber(address, &ip_number)) {
+    IPAddress ip_address;
+    if (!ip_address.AssignFromIPLiteral(address)) {
       LOG(WARNING) << "Not a supported IP literal: " << address.as_string();
       return ERR_UNEXPECTED;
     }
-    addrlist->push_back(IPEndPoint(ip_number, 0));
+    addrlist->push_back(IPEndPoint(ip_address, 0));
   }
   return OK;
 }
@@ -154,15 +155,15 @@
 
 int MockHostResolverBase::ResolveFromIPLiteralOrCache(const RequestInfo& info,
                                                       AddressList* addresses) {
-  IPAddressNumber ip;
-  if (ParseIPLiteralToNumber(info.hostname(), &ip)) {
+  IPAddress ip_address;
+  if (ip_address.AssignFromIPLiteral(info.hostname())) {
     // This matches the behavior HostResolverImpl.
     if (info.address_family() != ADDRESS_FAMILY_UNSPECIFIED &&
-        info.address_family() != GetAddressFamily(ip)) {
+        info.address_family() != GetAddressFamily(ip_address)) {
       return ERR_NAME_NOT_RESOLVED;
     }
 
-    *addresses = AddressList::CreateFromIPAddress(ip, info.port());
+    *addresses = AddressList::CreateFromIPAddress(ip_address, info.port());
     if (info.host_resolver_flags() & HOST_RESOLVER_CANONNAME)
       addresses->SetDefaultCanonicalName();
     return OK;
@@ -284,8 +285,8 @@
     const std::string& canonical_name) {
   // Literals are always resolved to themselves by HostResolverImpl,
   // consequently we do not support remapping them.
-  IPAddressNumber ip_number;
-  DCHECK(!ParseIPLiteralToNumber(host_pattern, &ip_number));
+  IPAddress ip_address;
+  DCHECK(!ip_address.AssignFromIPLiteral(host_pattern));
   HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
       HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
   if (!canonical_name.empty())
diff --git a/net/dns/record_rdata.cc b/net/dns/record_rdata.cc
index 2213473..be9d387f 100644
--- a/net/dns/record_rdata.cc
+++ b/net/dns/record_rdata.cc
@@ -65,16 +65,12 @@
 scoped_ptr<ARecordRdata> ARecordRdata::Create(
     const base::StringPiece& data,
     const DnsRecordParser& parser) {
-  if (data.size() != kIPv4AddressSize)
+  if (data.size() != IPAddress::kIPv4AddressSize)
     return scoped_ptr<ARecordRdata>();
 
   scoped_ptr<ARecordRdata> rdata(new ARecordRdata);
-
-  rdata->address_.resize(kIPv4AddressSize);
-  for (unsigned i = 0; i < kIPv4AddressSize; ++i) {
-    rdata->address_[i] = data[i];
-  }
-
+  rdata->address_ =
+      IPAddress(reinterpret_cast<const uint8_t*>(data.data()), data.length());
   return rdata;
 }
 
@@ -98,16 +94,12 @@
 scoped_ptr<AAAARecordRdata> AAAARecordRdata::Create(
     const base::StringPiece& data,
     const DnsRecordParser& parser) {
-  if (data.size() != kIPv6AddressSize)
+  if (data.size() != IPAddress::kIPv6AddressSize)
     return scoped_ptr<AAAARecordRdata>();
 
   scoped_ptr<AAAARecordRdata> rdata(new AAAARecordRdata);
-
-  rdata->address_.resize(kIPv6AddressSize);
-  for (unsigned i = 0; i < kIPv6AddressSize; ++i) {
-    rdata->address_[i] = data[i];
-  }
-
+  rdata->address_ =
+      IPAddress(reinterpret_cast<const uint8_t*>(data.data()), data.length());
   return rdata;
 }
 
diff --git a/net/dns/record_rdata.h b/net/dns/record_rdata.h
index 8184edd..fea1f6b 100644
--- a/net/dns/record_rdata.h
+++ b/net/dns/record_rdata.h
@@ -14,7 +14,7 @@
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/string_piece.h"
-#include "net/base/ip_address_number.h"
+#include "net/base/ip_address.h"
 #include "net/base/net_export.h"
 #include "net/dns/dns_protocol.h"
 
@@ -83,12 +83,12 @@
   bool IsEqual(const RecordRdata* other) const override;
   uint16_t Type() const override;
 
-  const IPAddressNumber& address() const { return address_; }
+  const IPAddress& address() const { return address_; }
 
  private:
   ARecordRdata();
 
-  IPAddressNumber address_;
+  IPAddress address_;
 
   DISALLOW_COPY_AND_ASSIGN(ARecordRdata);
 };
@@ -105,12 +105,12 @@
   bool IsEqual(const RecordRdata* other) const override;
   uint16_t Type() const override;
 
-  const IPAddressNumber& address() const { return address_; }
+  const IPAddress& address() const { return address_; }
 
  private:
   AAAARecordRdata();
 
-  IPAddressNumber address_;
+  IPAddress address_;
 
   DISALLOW_COPY_AND_ASSIGN(AAAARecordRdata);
 };
diff --git a/net/dns/record_rdata_unittest.cc b/net/dns/record_rdata_unittest.cc
index d83f497c..5db22e6 100644
--- a/net/dns/record_rdata_unittest.cc
+++ b/net/dns/record_rdata_unittest.cc
@@ -5,7 +5,6 @@
 #include "net/dns/record_rdata.h"
 
 #include "base/memory/scoped_ptr.h"
-#include "net/base/ip_address_number.h"
 #include "net/dns/dns_response.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -76,7 +75,7 @@
   record_obj = ARecordRdata::Create(record_strpiece, parser);
   ASSERT_TRUE(record_obj != NULL);
 
-  ASSERT_EQ("127.0.0.1", IPAddressToString(record_obj->address()));
+  ASSERT_EQ("127.0.0.1", record_obj->address().ToString());
 
   ASSERT_TRUE(record_obj->IsEqual(record_obj.get()));
 }
@@ -98,8 +97,7 @@
   record_obj = AAAARecordRdata::Create(record_strpiece, parser);
   ASSERT_TRUE(record_obj != NULL);
 
-  ASSERT_EQ("1234:5678::9",
-            IPAddressToString(record_obj->address()));
+  ASSERT_EQ("1234:5678::9", record_obj->address().ToString());
 
   ASSERT_TRUE(record_obj->IsEqual(record_obj.get()));
 }