shill: Add IPv6 address support in SocketInfoReader.

BUG=chromium:225907
TEST=Build and run unit tests.

Change-Id: I53fc90e29870fad44ae739a720ebc8dba5e4f563
Reviewed-on: https://gerrit.chromium.org/gerrit/47703
Commit-Queue: Ben Chan <benchan@chromium.org>
Reviewed-by: Ben Chan <benchan@chromium.org>
Tested-by: Ben Chan <benchan@chromium.org>
diff --git a/socket_info_reader.cc b/socket_info_reader.cc
index 26f7db7..2155096 100644
--- a/socket_info_reader.cc
+++ b/socket_info_reader.cc
@@ -7,7 +7,6 @@
 #include <algorithm>
 #include <limits>
 
-#include <base/file_path.h>
 #include <base/string_number_conversions.h>
 #include <base/string_split.h>
 
@@ -22,7 +21,8 @@
 
 namespace {
 
-const char kTcpSocketInfoFilePath[] = "/proc/net/tcp";
+const char kTcpv4SocketInfoFilePath[] = "/proc/net/tcp";
+const char kTcpv6SocketInfoFilePath[] = "/proc/net/tcp6";
 
 }  // namespace
 
@@ -30,12 +30,25 @@
 
 SocketInfoReader::~SocketInfoReader() {}
 
-bool SocketInfoReader::LoadTcpSocketInfo(vector<SocketInfo> *info_list) {
-  return LoadSocketInfo(FilePath(kTcpSocketInfoFilePath), info_list);
+FilePath SocketInfoReader::GetTcpv4SocketInfoFilePath() const {
+  return FilePath(kTcpv4SocketInfoFilePath);
 }
 
-bool SocketInfoReader::LoadSocketInfo(const FilePath &info_file_path,
-                                      vector<SocketInfo> *info_list) {
+FilePath SocketInfoReader::GetTcpv6SocketInfoFilePath() const {
+  return FilePath(kTcpv6SocketInfoFilePath);
+}
+
+bool SocketInfoReader::LoadTcpSocketInfo(vector<SocketInfo> *info_list) {
+  info_list->clear();
+  bool v4_loaded = AppendSocketInfo(GetTcpv4SocketInfoFilePath(), info_list);
+  bool v6_loaded = AppendSocketInfo(GetTcpv6SocketInfoFilePath(), info_list);
+  // Return true if we can load either /proc/net/tcp or /proc/net/tcp6
+  // successfully.
+  return v4_loaded || v6_loaded;
+}
+
+bool SocketInfoReader::AppendSocketInfo(const FilePath &info_file_path,
+                                        vector<SocketInfo> *info_list) {
   FileReader file_reader;
   if (!file_reader.Open(info_file_path)) {
     SLOG(Link, 2) << __func__ << ": Failed to open '"
@@ -43,7 +56,6 @@
     return false;
   }
 
-  info_list->clear();
   string line;
   while (file_reader.ReadLine(&line)) {
     SocketInfo socket_info;
@@ -116,24 +128,26 @@
 
 bool SocketInfoReader::ParseIPAddress(const string &input,
                                       IPAddress *ip_address) {
-  vector<uint8> bytes;
-  if (!base::HexStringToBytes(input, &bytes))
+  ByteString byte_string = ByteString::CreateFromHexString(input);
+  if (byte_string.IsEmpty())
     return false;
 
   IPAddress::Family family;
-  if (bytes.size() == 4)
+  if (byte_string.GetLength() ==
+      IPAddress::GetAddressLength(IPAddress::kFamilyIPv4)) {
     family = IPAddress::kFamilyIPv4;
-  else if (bytes.size() == 6)
+  } else if (byte_string.GetLength() ==
+             IPAddress::GetAddressLength(IPAddress::kFamilyIPv6)) {
     family = IPAddress::kFamilyIPv6;
-  else
+  } else {
     return false;
+  }
 
-  // TODO(benchan): This doesn't work with IPv6 addresses. Fix it
-  // by introducing a proper method in ByteString to handle byte order
-  // conversion.
-  std::reverse(bytes.begin(), bytes.end());
+  // Linux kernel prints out IP addresses in network order via
+  // /proc/net/tcp{,6}.
+  byte_string.ConvertFromNetToCPUUInt32Array();
 
-  *ip_address = IPAddress(family, ByteString(&bytes[0], bytes.size()));
+  *ip_address = IPAddress(family, byte_string);
   return true;
 }
 
diff --git a/socket_info_reader.h b/socket_info_reader.h
index af32525..f8ccea5 100644
--- a/socket_info_reader.h
+++ b/socket_info_reader.h
@@ -9,16 +9,11 @@
 #include <vector>
 
 #include <base/basictypes.h>
+#include <base/file_path.h>
 #include <gtest/gtest_prod.h>
 
 #include "shill/socket_info.h"
 
-namespace base {
-
-class FilePath;
-
-}  // namespace base
-
 namespace shill {
 
 class SocketInfoReader {
@@ -26,10 +21,23 @@
   SocketInfoReader();
   virtual ~SocketInfoReader();
 
+  // Returns the file path (/proc/net/tcp by default) from where TCP/IPv4
+  // socket information are read. Overloadded by unit tests to return a
+  // different file path.
+  virtual base::FilePath GetTcpv4SocketInfoFilePath() const;
+
+  // Returns the file path (/proc/net/tcp6 by default) from where TCP/IPv6
+  // socket information are read. Overloadded by unit tests to return a
+  // different file path.
+  virtual base::FilePath GetTcpv6SocketInfoFilePath() const;
+
+  // Loads TCP socket information from /proc/net/tcp and /proc/net/tcp6.
+  // Existing entries in |info_list| are always discarded. Returns false
+  // if when neither /proc/net/tcp nor /proc/net/tcp6 can be read.
   virtual bool LoadTcpSocketInfo(std::vector<SocketInfo> *info_list);
 
  private:
-  FRIEND_TEST(SocketInfoReaderTest, LoadSocketInfo);
+  FRIEND_TEST(SocketInfoReaderTest, AppendSocketInfo);
   FRIEND_TEST(SocketInfoReaderTest, ParseConnectionState);
   FRIEND_TEST(SocketInfoReaderTest, ParseIPAddress);
   FRIEND_TEST(SocketInfoReaderTest, ParseIPAddressAndPort);
@@ -38,8 +46,8 @@
   FRIEND_TEST(SocketInfoReaderTest, ParseTimerState);
   FRIEND_TEST(SocketInfoReaderTest, ParseTransimitAndReceiveQueueValues);
 
-  bool LoadSocketInfo(const base::FilePath &info_file_path,
-                      std::vector<SocketInfo> *info_list);
+  bool AppendSocketInfo(const base::FilePath &info_file_path,
+                        std::vector<SocketInfo> *info_list);
   bool ParseSocketInfo(const std::string &input, SocketInfo *socket_info);
   bool ParseIPAddressAndPort(
       const std::string &input, IPAddress *ip_address, uint16 *port);
diff --git a/socket_info_reader_unittest.cc b/socket_info_reader_unittest.cc
index 1fda67b..7dff7dc 100644
--- a/socket_info_reader_unittest.cc
+++ b/socket_info_reader_unittest.cc
@@ -7,24 +7,28 @@
 #include <base/file_util.h>
 #include <base/files/scoped_temp_dir.h>
 #include <base/stringprintf.h>
+#include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
 using base::FilePath;
 using base::ScopedTempDir;
 using std::string;
 using std::vector;
-
-// TODO(benchan): Test IPv6 addresses.
+using testing::Return;
 
 namespace shill {
 
 namespace {
 
-const char kIPAddress_0_0_0_0[] = "0.0.0.0";
-const char kIPAddress_127_0_0_1[] = "127.0.0.1";
-const char kIPAddress_192_168_1_10[] = "192.168.1.10";
-const char kIPAddress_255_255_255_255[] = "255.255.255.255";
-const char *kSocketInfoLines[] = {
+const char kIPv4AddressAllZeros[] = "0.0.0.0";
+const char kIPv4AddressAllOnes[] = "255.255.255.255";
+const char kIPv4Address_127_0_0_1[] = "127.0.0.1";
+const char kIPv4Address_192_168_1_10[] = "192.168.1.10";
+const char kIPv6AddressAllZeros[] = "0000:0000:0000:0000:0000:0000:0000:0000";
+const char kIPv6AddressAllOnes[] = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
+const char kIPv6AddressPattern1[] = "0123:4567:89ab:cdef:ffee:ddcc:bbaa:9988";
+
+const char *kIPv4SocketInfoLines[] = {
     "  sl  local_address rem_address   st tx_queue rx_queue tr tm->when "
     "retrnsmt   uid  timeout inode                                      ",
     "   0: 0100007F:0019 00000000:0000 0A 0000000A:00000005 00:00000000 "
@@ -32,9 +36,29 @@
     "   1: 0A01A8C0:0050 0100007F:03FC 01 00000000:00000000 00:00000000 "
     "00000000 65534        0 2787034 1 0000000000000000 100 0 0 10 -1   ",
 };
+const char *kIPv6SocketInfoLines[] = {
+    "  sl  local_address                         "
+    "remote_address                        st tx_queue rx_queue tr tm->when "
+    "retrnsmt   uid  timeout inode",
+    "   0: 67452301EFCDAB89CCDDEEFF8899AABB:0019 "
+    "00000000000000000000000000000000:0000 0A 0000000A:00000005 00:00000000 "
+    "00000000     0        0 36412 1 0000000000000000 100 0 0 2 -1",
+    "   1: 00000000000000000000000000000000:0050 "
+    "67452301EFCDAB89CCDDEEFF8899AABB:03FC 01 00000000:00000000 00:00000000 "
+    "00000000     0        0 36412 1 0000000000000000 100 0 0 2 -1",
+};
 
 }  // namespace
 
+class SocketInfoReaderUnderTest : public SocketInfoReader {
+ public:
+  // Mock out GetTcpv4SocketInfoFilePath and GetTcpv6SocketInfoFilePath to
+  // use a temporary created socket info file instead of the actual path
+  // in procfs (i.e. /proc/net/tcp and /proc/net/tcp6).
+  MOCK_CONST_METHOD0(GetTcpv4SocketInfoFilePath, FilePath ());
+  MOCK_CONST_METHOD0(GetTcpv6SocketInfoFilePath, FilePath ());
+};
+
 class SocketInfoReaderTest : public testing::Test {
  protected:
   IPAddress StringToIPv4Address(const string &address_string) {
@@ -43,6 +67,12 @@
     return ip_address;
   }
 
+  IPAddress StringToIPv6Address(const string &address_string) {
+    IPAddress ip_address(IPAddress::kFamilyIPv6);
+    EXPECT_TRUE(ip_address.SetAddressFromString(address_string));
+    return ip_address;
+  }
+
   void CreateSocketInfoFile(const char **lines, size_t num_lines,
                             const FilePath &dir_path, FilePath *file_path) {
     ASSERT_TRUE(file_util::CreateTemporaryFileInDir(dir_path, file_path));
@@ -65,58 +95,143 @@
     EXPECT_EQ(info1.timer_state(), info2.timer_state());
   }
 
-  SocketInfoReader reader_;
+  SocketInfoReaderUnderTest reader_;
 };
 
-TEST_F(SocketInfoReaderTest, LoadSocketInfo) {
+TEST_F(SocketInfoReaderTest, LoadTcpSocketInfo) {
+  FilePath invalid_path("/non-existent-file"), v4_path, v6_path;
+  ScopedTempDir temp_dir;
+  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+  CreateSocketInfoFile(kIPv4SocketInfoLines, 2, temp_dir.path(), &v4_path);
+  CreateSocketInfoFile(kIPv6SocketInfoLines, 2, temp_dir.path(), &v6_path);
+
+  SocketInfo v4_info(SocketInfo::kConnectionStateListen,
+                     StringToIPv4Address(kIPv4Address_127_0_0_1),
+                     25,
+                     StringToIPv4Address(kIPv4AddressAllZeros),
+                     0,
+                     10,
+                     5,
+                     SocketInfo::kTimerStateNoTimerPending);
+  SocketInfo v6_info(SocketInfo::kConnectionStateListen,
+                     StringToIPv6Address(kIPv6AddressPattern1),
+                     25,
+                     StringToIPv6Address(kIPv6AddressAllZeros),
+                     0,
+                     10,
+                     5,
+                     SocketInfo::kTimerStateNoTimerPending);
+
+  vector<SocketInfo> info_list;
+  EXPECT_CALL(reader_, GetTcpv4SocketInfoFilePath())
+      .WillOnce(Return(invalid_path));
+  EXPECT_CALL(reader_, GetTcpv6SocketInfoFilePath())
+      .WillOnce(Return(invalid_path));
+  EXPECT_FALSE(reader_.LoadTcpSocketInfo(&info_list));
+
+  EXPECT_CALL(reader_, GetTcpv4SocketInfoFilePath())
+      .WillOnce(Return(v4_path));
+  EXPECT_CALL(reader_, GetTcpv6SocketInfoFilePath())
+      .WillOnce(Return(invalid_path));
+  EXPECT_TRUE(reader_.LoadTcpSocketInfo(&info_list));
+  EXPECT_EQ(1, info_list.size());
+  ExpectSocketInfoEqual(v4_info, info_list[0]);
+
+  EXPECT_CALL(reader_, GetTcpv4SocketInfoFilePath())
+      .WillOnce(Return(invalid_path));
+  EXPECT_CALL(reader_, GetTcpv6SocketInfoFilePath())
+      .WillOnce(Return(v6_path));
+  EXPECT_TRUE(reader_.LoadTcpSocketInfo(&info_list));
+  EXPECT_EQ(1, info_list.size());
+  ExpectSocketInfoEqual(v6_info, info_list[0]);
+
+  EXPECT_CALL(reader_, GetTcpv4SocketInfoFilePath())
+      .WillOnce(Return(v4_path));
+  EXPECT_CALL(reader_, GetTcpv6SocketInfoFilePath())
+      .WillOnce(Return(v6_path));
+  EXPECT_TRUE(reader_.LoadTcpSocketInfo(&info_list));
+  EXPECT_EQ(2, info_list.size());
+  ExpectSocketInfoEqual(v4_info, info_list[0]);
+  ExpectSocketInfoEqual(v6_info, info_list[1]);
+}
+
+TEST_F(SocketInfoReaderTest, AppendSocketInfo) {
   FilePath file_path("/non-existent-file");
   vector<SocketInfo> info_list;
 
-  EXPECT_FALSE(reader_.LoadSocketInfo(file_path, &info_list));
+  EXPECT_FALSE(reader_.AppendSocketInfo(file_path, &info_list));
   EXPECT_TRUE(info_list.empty());
 
   ScopedTempDir temp_dir;
   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
 
-  CreateSocketInfoFile(kSocketInfoLines, 1, temp_dir.path(), &file_path);
-  EXPECT_TRUE(reader_.LoadSocketInfo(file_path, &info_list));
+  CreateSocketInfoFile(kIPv4SocketInfoLines, 1, temp_dir.path(), &file_path);
+  EXPECT_TRUE(reader_.AppendSocketInfo(file_path, &info_list));
   EXPECT_TRUE(info_list.empty());
 
-  CreateSocketInfoFile(kSocketInfoLines, arraysize(kSocketInfoLines),
+  SocketInfo v4_info1(SocketInfo::kConnectionStateListen,
+                      StringToIPv4Address(kIPv4Address_127_0_0_1),
+                      25,
+                      StringToIPv4Address(kIPv4AddressAllZeros),
+                      0,
+                      10,
+                      5,
+                      SocketInfo::kTimerStateNoTimerPending);
+  SocketInfo v4_info2(SocketInfo::kConnectionStateEstablished,
+                      StringToIPv4Address(kIPv4Address_192_168_1_10),
+                      80,
+                      StringToIPv4Address(kIPv4Address_127_0_0_1),
+                      1020,
+                      0,
+                      0,
+                      SocketInfo::kTimerStateNoTimerPending);
+  SocketInfo v6_info1(SocketInfo::kConnectionStateListen,
+                      StringToIPv6Address(kIPv6AddressPattern1),
+                      25,
+                      StringToIPv6Address(kIPv6AddressAllZeros),
+                      0,
+                      10,
+                      5,
+                      SocketInfo::kTimerStateNoTimerPending);
+  SocketInfo v6_info2(SocketInfo::kConnectionStateEstablished,
+                      StringToIPv6Address(kIPv6AddressAllZeros),
+                      80,
+                      StringToIPv6Address(kIPv6AddressPattern1),
+                      1020,
+                      0,
+                      0,
+                      SocketInfo::kTimerStateNoTimerPending);
+
+  CreateSocketInfoFile(kIPv4SocketInfoLines, arraysize(kIPv4SocketInfoLines),
                        temp_dir.path(), &file_path);
-  EXPECT_TRUE(reader_.LoadSocketInfo(file_path, &info_list));
-  EXPECT_EQ(arraysize(kSocketInfoLines) - 1, info_list.size());
-  ExpectSocketInfoEqual(SocketInfo(SocketInfo::kConnectionStateListen,
-                                   StringToIPv4Address(kIPAddress_127_0_0_1),
-                                   25,
-                                   StringToIPv4Address(kIPAddress_0_0_0_0),
-                                   0,
-                                   10,
-                                   5,
-                                   SocketInfo::kTimerStateNoTimerPending),
-                        info_list[0]);
-  ExpectSocketInfoEqual(SocketInfo(SocketInfo::kConnectionStateEstablished,
-                                   StringToIPv4Address(kIPAddress_192_168_1_10),
-                                   80,
-                                   StringToIPv4Address(kIPAddress_127_0_0_1),
-                                   1020,
-                                   0,
-                                   0,
-                                   SocketInfo::kTimerStateNoTimerPending),
-                        info_list[1]);
+  EXPECT_TRUE(reader_.AppendSocketInfo(file_path, &info_list));
+  EXPECT_EQ(arraysize(kIPv4SocketInfoLines) - 1, info_list.size());
+  ExpectSocketInfoEqual(v4_info1, info_list[0]);
+  ExpectSocketInfoEqual(v4_info2, info_list[1]);
+
+  CreateSocketInfoFile(kIPv6SocketInfoLines, arraysize(kIPv6SocketInfoLines),
+                       temp_dir.path(), &file_path);
+  EXPECT_TRUE(reader_.AppendSocketInfo(file_path, &info_list));
+  EXPECT_EQ(
+      arraysize(kIPv4SocketInfoLines) + arraysize(kIPv6SocketInfoLines) - 2,
+      info_list.size());
+  ExpectSocketInfoEqual(v4_info1, info_list[0]);
+  ExpectSocketInfoEqual(v4_info2, info_list[1]);
+  ExpectSocketInfoEqual(v6_info1, info_list[2]);
+  ExpectSocketInfoEqual(v6_info2, info_list[3]);
 }
 
 TEST_F(SocketInfoReaderTest, ParseSocketInfo) {
   SocketInfo info;
 
   EXPECT_FALSE(reader_.ParseSocketInfo("", &info));
-  EXPECT_FALSE(reader_.ParseSocketInfo(kSocketInfoLines[0], &info));
+  EXPECT_FALSE(reader_.ParseSocketInfo(kIPv4SocketInfoLines[0], &info));
 
-  EXPECT_TRUE(reader_.ParseSocketInfo(kSocketInfoLines[1], &info));
+  EXPECT_TRUE(reader_.ParseSocketInfo(kIPv4SocketInfoLines[1], &info));
   ExpectSocketInfoEqual(SocketInfo(SocketInfo::kConnectionStateListen,
-                                   StringToIPv4Address(kIPAddress_127_0_0_1),
+                                   StringToIPv4Address(kIPv4Address_127_0_0_1),
                                    25,
-                                   StringToIPv4Address(kIPAddress_0_0_0_0),
+                                   StringToIPv4Address(kIPv4AddressAllZeros),
                                    0,
                                    10,
                                    5,
@@ -132,15 +247,30 @@
   EXPECT_FALSE(reader_.ParseIPAddressAndPort("00000000", &ip_address, &port));
   EXPECT_FALSE(reader_.ParseIPAddressAndPort("00000000:", &ip_address, &port));
   EXPECT_FALSE(reader_.ParseIPAddressAndPort(":0000", &ip_address, &port));
-  EXPECT_FALSE(reader_.ParseIPAddressAndPort("0000000Y:0000",
-                                             &ip_address, &port));
-  EXPECT_FALSE(reader_.ParseIPAddressAndPort("00000000:000Y", &ip_address,
-                                             &port));
+  EXPECT_FALSE(reader_.ParseIPAddressAndPort(
+      "0000000Y:0000", &ip_address, &port));
+  EXPECT_FALSE(reader_.ParseIPAddressAndPort(
+      "00000000:000Y", &ip_address, &port));
 
-  EXPECT_TRUE(reader_.ParseIPAddressAndPort("0a01A8c0:0050",
-                                            &ip_address, &port));
-  EXPECT_TRUE(ip_address.Equals(StringToIPv4Address(kIPAddress_192_168_1_10)));
+  EXPECT_FALSE(reader_.ParseIPAddressAndPort(
+      "00000000000000000000000000000000", &ip_address, &port));
+  EXPECT_FALSE(reader_.ParseIPAddressAndPort(
+      "00000000000000000000000000000000:", &ip_address, &port));
+  EXPECT_FALSE(reader_.ParseIPAddressAndPort(
+      "00000000000000000000000000000000Y:0000", &ip_address, &port));
+  EXPECT_FALSE(reader_.ParseIPAddressAndPort(
+      "000000000000000000000000000000000:000Y", &ip_address, &port));
+
+  EXPECT_TRUE(reader_.ParseIPAddressAndPort(
+      "0a01A8c0:0050", &ip_address, &port));
+  EXPECT_TRUE(ip_address.Equals(
+      StringToIPv4Address(kIPv4Address_192_168_1_10)));
   EXPECT_EQ(80, port);
+
+  EXPECT_TRUE(reader_.ParseIPAddressAndPort(
+      "67452301efcdab89CCDDEEFF8899AABB:1F90", &ip_address, &port));
+  EXPECT_TRUE(ip_address.Equals(StringToIPv6Address(kIPv6AddressPattern1)));
+  EXPECT_EQ(8080, port);
 }
 
 TEST_F(SocketInfoReaderTest, ParseIPAddress) {
@@ -150,19 +280,34 @@
   EXPECT_FALSE(reader_.ParseIPAddress("0", &ip_address));
   EXPECT_FALSE(reader_.ParseIPAddress("00", &ip_address));
   EXPECT_FALSE(reader_.ParseIPAddress("0000000Y", &ip_address));
+  EXPECT_FALSE(reader_.ParseIPAddress("0000000000000000000000000000000Y",
+                                      &ip_address));
 
   EXPECT_TRUE(reader_.ParseIPAddress("00000000", &ip_address));
-  EXPECT_TRUE(ip_address.Equals(StringToIPv4Address(kIPAddress_0_0_0_0)));
+  EXPECT_TRUE(ip_address.Equals(StringToIPv4Address(kIPv4AddressAllZeros)));
 
   EXPECT_TRUE(reader_.ParseIPAddress("0100007F", &ip_address));
-  EXPECT_TRUE(ip_address.Equals(StringToIPv4Address(kIPAddress_127_0_0_1)));
+  EXPECT_TRUE(ip_address.Equals(StringToIPv4Address(kIPv4Address_127_0_0_1)));
 
   EXPECT_TRUE(reader_.ParseIPAddress("0a01A8c0", &ip_address));
-  EXPECT_TRUE(ip_address.Equals(StringToIPv4Address(kIPAddress_192_168_1_10)));
+  EXPECT_TRUE(ip_address.Equals(
+      StringToIPv4Address(kIPv4Address_192_168_1_10)));
 
   EXPECT_TRUE(reader_.ParseIPAddress("ffffffff", &ip_address));
   EXPECT_TRUE(ip_address.Equals(
-      StringToIPv4Address(kIPAddress_255_255_255_255)));
+      StringToIPv4Address(kIPv4AddressAllOnes)));
+
+  EXPECT_TRUE(reader_.ParseIPAddress("00000000000000000000000000000000",
+                                     &ip_address));
+  EXPECT_TRUE(ip_address.Equals(StringToIPv6Address(kIPv6AddressAllZeros)));
+
+  EXPECT_TRUE(reader_.ParseIPAddress("67452301efcdab89CCDDEEFF8899AABB",
+                                     &ip_address));
+  EXPECT_TRUE(ip_address.Equals(StringToIPv6Address(kIPv6AddressPattern1)));
+
+  EXPECT_TRUE(reader_.ParseIPAddress("ffffffffffffffffffffffffffffffff",
+                                     &ip_address));
+  EXPECT_TRUE(ip_address.Equals(StringToIPv6Address(kIPv6AddressAllOnes)));
 }
 
 TEST_F(SocketInfoReaderTest, ParsePort) {