summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/base/ip_endpoint.cc3
-rw-r--r--net/base/net_util.cc13
-rw-r--r--net/base/net_util.h25
-rw-r--r--net/base/net_util_posix.cc38
-rw-r--r--net/base/net_util_unittest.cc27
-rw-r--r--net/base/net_util_win.cc60
6 files changed, 156 insertions, 10 deletions
diff --git a/net/base/ip_endpoint.cc b/net/base/ip_endpoint.cc
index df90f1a..3d776b1 100644
--- a/net/base/ip_endpoint.cc
+++ b/net/base/ip_endpoint.cc
@@ -14,9 +14,6 @@
namespace net {
-const size_t kIPv4AddressSize = 4;
-const size_t kIPv6AddressSize = 16;
-
IPEndPoint::IPEndPoint() : port_(0) {}
IPEndPoint::~IPEndPoint() {}
diff --git a/net/base/net_util.cc b/net/base/net_util.cc
index f3b0127..1a8aa89 100644
--- a/net/base/net_util.cc
+++ b/net/base/net_util.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -2111,4 +2111,15 @@ int GetPortFromSockaddr(const struct sockaddr* address, socklen_t address_len) {
return ntohs(*port_field);
}
+NetworkInterface::NetworkInterface() {
+}
+
+NetworkInterface::NetworkInterface(const std::string& name,
+ const IPAddressNumber& address)
+ : name(name), address(address) {
+}
+
+NetworkInterface::~NetworkInterface() {
+}
+
} // namespace net
diff --git a/net/base/net_util.h b/net/base/net_util.h
index 935eab6..9e30d2b 100644
--- a/net/base/net_util.h
+++ b/net/base/net_util.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -15,6 +15,7 @@
#include <sys/socket.h>
#endif
+#include <list>
#include <string>
#include <set>
#include <vector>
@@ -372,6 +373,9 @@ bool HaveOnlyLoopbackAddresses();
// IPv4 addresses will have length 4, whereas IPv6 address will have length 16.
typedef std::vector<unsigned char> IPAddressNumber;
+static const size_t kIPv4AddressSize = 4;
+static const size_t kIPv6AddressSize = 16;
+
// Parses an IP address literal (either IPv4 or IPv6) to its numeric value.
// Returns true on success and fills |ip_number| with the numeric value.
bool ParseIPLiteralToNumber(const std::string& ip_literal,
@@ -423,6 +427,25 @@ const uint16* GetPortFieldFromSockaddr(const struct sockaddr* address,
int GetPortFromSockaddr(const struct sockaddr* address,
socklen_t address_len);
+// struct that is used by GetNetworkList() to represent a network
+// interface.
+struct NetworkInterface {
+ NetworkInterface();
+ NetworkInterface(const std::string& name, const IPAddressNumber& address);
+ ~NetworkInterface();
+
+ std::string name;
+ IPAddressNumber address;
+};
+
+typedef std::list<NetworkInterface> NetworkInterfaceList;
+
+// Returns list of network interfaces except loopback interface. If an
+// interface has more than one address, a separate entry is added to
+// the list for each address.
+// Can be called only on a thread that allows IO.
+bool GetNetworkList(NetworkInterfaceList* networks);
+
} // namespace net
#endif // NET_BASE_NET_UTIL_H_
diff --git a/net/base/net_util_posix.cc b/net/base/net_util_posix.cc
index 651be1b..af3d5d1 100644
--- a/net/base/net_util_posix.cc
+++ b/net/base/net_util_posix.cc
@@ -1,13 +1,21 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/base/net_util.h"
+#include <ifaddrs.h>
+#include <sys/types.h>
+
+#include "base/eintr_wrapper.h"
#include "base/file_path.h"
+#include "base/logging.h"
#include "base/string_util.h"
+#include "base/threading/thread_restrictions.h"
#include "googleurl/src/gurl.h"
#include "net/base/escape.h"
+#include "net/base/ip_endpoint.h"
+#include "net/base/net_errors.h"
namespace net {
@@ -45,4 +53,32 @@ bool FileURLToFilePath(const GURL& url, FilePath* path) {
return !file_path_str.empty();
}
+bool GetNetworkList(NetworkInterfaceList* networks) {
+ // getifaddrs() may require IO operations.
+ base::ThreadRestrictions::AssertIOAllowed();
+
+ ifaddrs *ifaddr;
+ if (getifaddrs(&ifaddr) < 0) {
+ PLOG(ERROR) << "getifaddrs";
+ return false;
+ }
+
+ for (ifaddrs *ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+ int family = ifa->ifa_addr->sa_family;
+ if (family == AF_INET || family == AF_INET6) {
+ IPEndPoint address;
+ std::string name = ifa->ifa_name;
+ if (address.FromSockAddr(ifa->ifa_addr,
+ sizeof(ifa->ifa_addr)) &&
+ name.substr(0, 2) != "lo") {
+ networks->push_back(NetworkInterface(name, address.address()));
+ }
+ }
+ }
+
+ freeifaddrs(ifaddr);
+
+ return true;
+}
+
} // namespace net
diff --git a/net/base/net_util_unittest.cc b/net/base/net_util_unittest.cc
index 46293a3..8f05c20 100644
--- a/net/base/net_util_unittest.cc
+++ b/net/base/net_util_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -2166,3 +2166,28 @@ TEST(NetUtilTest, IPNumberMatchesPrefix) {
prefix_length_in_bits));
}
}
+
+// Verify GetNetworkList().
+TEST(NetUtilTest, GetNetworkList) {
+ net::NetworkInterfaceList list;
+ ASSERT_TRUE(net::GetNetworkList(&list));
+
+ for (net::NetworkInterfaceList::iterator it = list.begin();
+ it != list.end(); ++it) {
+ // Verify that the name is not empty.
+ EXPECT_FALSE(it->name.empty());
+
+ // Verify that the address is correct.
+ EXPECT_TRUE(it->address.size() == net::kIPv4AddressSize ||
+ it->address.size() == net::kIPv6AddressSize)
+ << "Invalid address of size " << it->address.size();
+ bool all_zeroes = true;
+ for (size_t i = 0; i < it->address.size(); ++i) {
+ if (it->address[i] != 0) {
+ all_zeroes = false;
+ break;
+ }
+ }
+ EXPECT_FALSE(all_zeroes);
+ }
+}
diff --git a/net/base/net_util_win.cc b/net/base/net_util_win.cc
index dac93a9..ee6a5af 100644
--- a/net/base/net_util_win.cc
+++ b/net/base/net_util_win.cc
@@ -1,18 +1,24 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <algorithm>
-
#include "net/base/net_util.h"
+#include <iphlpapi.h>
+
+#include <algorithm>
+
#include "base/file_path.h"
+#include "base/scoped_ptr.h"
#include "base/string_piece.h"
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
+#include "base/threading/thread_restrictions.h"
#include "base/utf_string_conversions.h"
#include "googleurl/src/gurl.h"
#include "net/base/escape.h"
+#include "net/base/ip_endpoint.h"
+#include "net/base/net_errors.h"
namespace net {
@@ -69,4 +75,52 @@ bool FileURLToFilePath(const GURL& url, FilePath* file_path) {
return true;
}
+bool GetNetworkList(NetworkInterfaceList* networks) {
+ // GetAdaptersAddresses() may require IO operations.
+ base::ThreadRestrictions::AssertIOAllowed();
+
+ IP_ADAPTER_ADDRESSES info_temp;
+ ULONG len = 0;
+
+ // First get number of networks.
+ ULONG result = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, &info_temp, &len);
+ if (result != ERROR_BUFFER_OVERFLOW) {
+ // There are 0 networks.
+ return true;
+ }
+
+ scoped_array<char> buf(new char[len]);
+ IP_ADAPTER_ADDRESSES *adapters =
+ reinterpret_cast<IP_ADAPTER_ADDRESSES *>(buf.get());
+ result = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, adapters, &len);
+ if (result != NO_ERROR) {
+ LOG(ERROR) << "GetAdaptersAddresses failed: " << result;
+ return false;
+ }
+
+ for (IP_ADAPTER_ADDRESSES *adapter = adapters; adapter != NULL;
+ adapter = adapter->Next) {
+ // Ignore the loopback device.
+ if (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK) {
+ continue;
+ }
+
+ IP_ADAPTER_UNICAST_ADDRESS* address;
+ for (address = adapter->FirstUnicastAddress; address != NULL;
+ address = address->Next) {
+ int family = address->Address.lpSockaddr->sa_family;
+ if (family == AF_INET || family == AF_INET6) {
+ IPEndPoint endpoint;
+ if (endpoint.FromSockAddr(address->Address.lpSockaddr,
+ address->Address.iSockaddrLength)) {
+ std::string name = adapter->AdapterName;
+ networks->push_back(NetworkInterface(name, endpoint.address()));
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
} // namespace net