diff options
author | wez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-16 18:47:07 +0000 |
---|---|---|
committer | wez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-16 18:47:07 +0000 |
commit | 7fc22b1dd0141d4dc52129a2b78611a2b77522c3 (patch) | |
tree | 8b217731f0791999876fc09c6d2bebf9330fc264 /net/base/net_util_posix.cc | |
parent | 254ed74c6520bbe191d47730b90414798ca2c0df (diff) | |
download | chromium_src-7fc22b1dd0141d4dc52129a2b78611a2b77522c3.zip chromium_src-7fc22b1dd0141d4dc52129a2b78611a2b77522c3.tar.gz chromium_src-7fc22b1dd0141d4dc52129a2b78611a2b77522c3.tar.bz2 |
Cleanup GetNetworkList.
BUG=
TEST=
Review URL: http://codereview.chromium.org/7612012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96993 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/net_util_posix.cc')
-rw-r--r-- | net/base/net_util_posix.cc | 56 |
1 files changed, 41 insertions, 15 deletions
diff --git a/net/base/net_util_posix.cc b/net/base/net_util_posix.cc index 9257989..8ff720f 100644 --- a/net/base/net_util_posix.cc +++ b/net/base/net_util_posix.cc @@ -19,6 +19,8 @@ #if !defined(OS_ANDROID) #include <ifaddrs.h> #endif +#include <net/if.h> +#include <netinet/in.h> namespace net { @@ -68,28 +70,52 @@ bool GetNetworkList(NetworkInterfaceList* networks) { // getifaddrs() may require IO operations. base::ThreadRestrictions::AssertIOAllowed(); - ifaddrs *ifaddr; - if (getifaddrs(&ifaddr) < 0) { + ifaddrs *interfaces; + if (getifaddrs(&interfaces) < 0) { PLOG(ERROR) << "getifaddrs"; return false; } - for (ifaddrs *ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { - if (!ifa->ifa_addr) - continue; // Interface has no IP addresses, so skip it. - 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())); - } + // Enumerate the addresses assigned to network interfaces which are up. + for (ifaddrs *interface = interfaces; + interface != NULL; + interface = interface->ifa_next) { + // Skip loopback interfaces, and ones which are down. + if (!(IFF_UP & interface->ifa_flags)) + continue; + if (IFF_LOOPBACK & interface->ifa_flags) + continue; + // Skip interfaces with no address configured. + struct sockaddr* addr = interface->ifa_addr; + if (!addr) + continue; + // Skip loopback addresses configured on non-loopback interfaces. + int addr_size = 0; + if (addr->sa_family == AF_INET6) { + struct sockaddr_in6* addr_in6 = + reinterpret_cast<struct sockaddr_in6*>(addr); + struct in6_addr* sin6_addr = &addr_in6->sin6_addr; + addr_size = sizeof(*addr_in6); + if (IN6_IS_ADDR_LOOPBACK(sin6_addr)) + continue; + } else if (addr->sa_family == AF_INET) { + struct sockaddr_in* addr_in = + reinterpret_cast<struct sockaddr_in*>(addr); + addr_size = sizeof(*addr_in); + if (addr_in->sin_addr.s_addr == INADDR_LOOPBACK) + continue; + } else { + // Skip non-IP addresses. + continue; + } + IPEndPoint address; + std::string name = interface->ifa_name; + if (address.FromSockAddr(addr, addr_size)) { + networks->push_back(NetworkInterface(name, address.address())); } } - freeifaddrs(ifaddr); + freeifaddrs(interfaces); return true; #endif |