Fix inet_addr/inet_aton/inet_network.

Rewrite inet_addr and inet_network in terms of inet_aton, and reimplement
that to include all the missing error checks.

Bug: http://b/24754503
Change-Id: I5dfa971c87201968985a0894df419f0fbf54768a
diff --git a/tests/arpa_inet_test.cpp b/tests/arpa_inet_test.cpp
index 5e53337..8ba0d7a 100644
--- a/tests/arpa_inet_test.cpp
+++ b/tests/arpa_inet_test.cpp
@@ -24,8 +24,81 @@
 
 TEST(arpa_inet, inet_aton) {
   in_addr a;
-  ASSERT_EQ(1, inet_aton("127.0.0.1", &a));
+
+  // a.b.c.d
+  a.s_addr = 0;
+  ASSERT_EQ(1, inet_aton("127.1.2.3", &a));
+  ASSERT_EQ((htonl)(0x7f010203), a.s_addr);
+
+  // a.b.c
+  a.s_addr = 0;
+  ASSERT_EQ(1, inet_aton("127.1.2", &a));
+  ASSERT_EQ((htonl)(0x7f010002), a.s_addr);
+
+  // a.b
+  a.s_addr = 0;
+  ASSERT_EQ(1, inet_aton("127.1", &a));
   ASSERT_EQ((htonl)(0x7f000001), a.s_addr);
+
+  // a
+  a.s_addr = 0;
+  ASSERT_EQ(1, inet_aton("0x7f000001", &a));
+  ASSERT_EQ((htonl)(0x7f000001), a.s_addr);
+
+  // Hex (0x) and mixed-case hex digits.
+  a.s_addr = 0;
+  ASSERT_EQ(1, inet_aton("0xFf.0.0.1", &a));
+  ASSERT_EQ((htonl)(0xff000001), a.s_addr);
+
+  // Hex (0X) and mixed-case hex digits.
+  a.s_addr = 0;
+  ASSERT_EQ(1, inet_aton("0XfF.0.0.1", &a));
+  ASSERT_EQ((htonl)(0xff000001), a.s_addr);
+
+  // Octal.
+  a.s_addr = 0;
+  ASSERT_EQ(1, inet_aton("0177.0.0.1", &a));
+  ASSERT_EQ((htonl)(0x7f000001), a.s_addr);
+
+  a.s_addr = 0;
+  ASSERT_EQ(1, inet_aton("036", &a));
+  ASSERT_EQ((htonl)(036U), a.s_addr);
+}
+
+TEST(arpa_inet, inet_aton_nullptr) {
+  ASSERT_EQ(0, inet_aton("", nullptr));
+  ASSERT_EQ(1, inet_aton("127.0.0.1", nullptr));
+}
+
+TEST(arpa_inet, inet_aton_invalid) {
+  ASSERT_EQ(0, inet_aton("", nullptr)); // Empty.
+  ASSERT_EQ(0, inet_aton("x", nullptr)); // Leading junk.
+  ASSERT_EQ(0, inet_aton("127.0.0.1x", nullptr)); // Trailing junk.
+  ASSERT_EQ(0, inet_aton("09.0.0.1", nullptr)); // Invalid octal.
+  ASSERT_EQ(0, inet_aton("0xg.0.0.1", nullptr)); // Invalid hex.
+
+  ASSERT_EQ(0, inet_aton("1.2.3.4.5", nullptr)); // Too many dots.
+  ASSERT_EQ(0, inet_aton("1.2.3.4.", nullptr)); // Trailing dot.
+
+  // Out of range a.b.c.d form.
+  ASSERT_EQ(0, inet_aton("999.0.0.1", nullptr));
+  ASSERT_EQ(0, inet_aton("0.999.0.1", nullptr));
+  ASSERT_EQ(0, inet_aton("0.0.999.1", nullptr));
+  ASSERT_EQ(0, inet_aton("0.0.0.999", nullptr));
+
+  // Out of range a.b.c form.
+  ASSERT_EQ(0, inet_aton("256.0.0", nullptr));
+  ASSERT_EQ(0, inet_aton("0.256.0", nullptr));
+  ASSERT_EQ(0, inet_aton("0.0.0x10000", nullptr));
+
+  // Out of range a.b form.
+  ASSERT_EQ(0, inet_aton("256.0", nullptr));
+  ASSERT_EQ(0, inet_aton("0.0x1000000", nullptr));
+
+  // Out of range a form.
+  ASSERT_EQ(0, inet_aton("0x100000000", nullptr));
+
+  ASSERT_EQ(0, inet_aton("0400.0.0.1", nullptr)); // Out of range octal.
 }
 
 TEST(arpa_inet, inet_lnaof) {
@@ -45,6 +118,8 @@
 
 TEST(arpa_inet, inet_network) {
   ASSERT_EQ(0x7f000001U, inet_network("127.0.0.1"));
+  ASSERT_EQ(0x7fU, inet_network("0x7f"));
+  ASSERT_EQ(~0U, inet_network(""));
 }
 
 TEST(arpa_inet, inet_ntoa) {