| Index: net/base/net_util_posix.cc
|
| diff --git a/net/base/net_util_posix.cc b/net/base/net_util_posix.cc
|
| index a2fa6cdf2ce7c1c871c4415911fe04c6b2d51602..b8e7195c5c53b4f97951144ee5d235032baddfc8 100644
|
| --- a/net/base/net_util_posix.cc
|
| +++ b/net/base/net_util_posix.cc
|
| @@ -7,38 +7,18 @@
|
| #include <set>
|
| #include <sys/types.h>
|
|
|
| -#include "base/files/file_path.h"
|
| -#include "base/logging.h"
|
| #include "base/memory/scoped_ptr.h"
|
| -#include "base/strings/string_number_conversions.h"
|
| -#include "base/strings/string_tokenizer.h"
|
| -#include "base/strings/string_util.h"
|
| -#include "base/threading/thread_restrictions.h"
|
| -#include "net/base/escape.h"
|
| -#include "net/base/ip_endpoint.h"
|
| -#include "net/base/net_errors.h"
|
| -#include "url/gurl.h"
|
|
|
| #if !defined(OS_NACL)
|
| -#if defined(OS_MACOSX)
|
| -#include <ifaddrs.h>
|
| -#else
|
| -#include "net/base/address_tracker_linux.h"
|
| #include "net/base/net_util_posix.h"
|
| -#endif // OS_MACOSX
|
| #include <net/if.h>
|
| #include <netinet/in.h>
|
| #endif // !defined(OS_NACL)
|
|
|
| -#if defined(OS_MACOSX) && !defined(OS_IOS)
|
| -#include <net/if_media.h>
|
| -#include <netinet/in_var.h>
|
| -#include <sys/ioctl.h>
|
| -#endif
|
| -
|
| namespace net {
|
|
|
| -namespace {
|
| +#if !defined(OS_NACL)
|
| +namespace internal {
|
|
|
| // The application layer can pass |policy| defined in net_util.h to
|
| // request filtering out certain type of interfaces.
|
| @@ -77,330 +57,13 @@ bool IsLoopbackOrUnspecifiedAddress(const sockaddr* addr) {
|
| return false;
|
| }
|
|
|
| -#if defined(OS_MACOSX)
|
| -
|
| -struct NetworkInterfaceInfo {
|
| - NetworkInterfaceInfo() : permanent(true) { }
|
| -
|
| - bool permanent; // IPv6 has notion of temporary address. If the address is
|
| - // IPv6 and it's temporary this field will be false.
|
| - NetworkInterface interface;
|
| -};
|
| -
|
| -// This method will remove permanent IPv6 addresses if a temporary address
|
| -// is available for same network interface.
|
| -void RemovePermanentIPv6AddressesWhereTemporaryExists(
|
| - std::vector<NetworkInterfaceInfo>* infos) {
|
| - if (!infos || infos->empty())
|
| - return;
|
| -
|
| - // Build a set containing the names of interfaces with a temp IPv6 address
|
| - std::set<std::string> ifaces_with_temp_addrs;
|
| - std::vector<NetworkInterfaceInfo>::iterator i;
|
| - for (i = infos->begin(); i != infos->end(); ++i) {
|
| - if (!i->permanent && i->interface.address.size() == kIPv6AddressSize) {
|
| - ifaces_with_temp_addrs.insert(i->interface.name);
|
| - }
|
| - }
|
| -
|
| - // If there are no such interfaces then there's no further work.
|
| - if (ifaces_with_temp_addrs.empty())
|
| - return;
|
| -
|
| - // Search for permenent addresses belonging to same network interface.
|
| - for (i = infos->begin(); i != infos->end(); ) {
|
| - // If the address is IPv6 and it's permanent and there is temporary
|
| - // address for it, then we can remove this address.
|
| - if ((i->interface.address.size() == kIPv6AddressSize) && i->permanent &&
|
| - (ifaces_with_temp_addrs.find(i->interface.name) !=
|
| - ifaces_with_temp_addrs.end())) {
|
| - i = infos->erase(i);
|
| - } else {
|
| - ++i;
|
| - }
|
| - }
|
| -}
|
| -
|
| -#if !defined(OS_IOS)
|
| -NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(
|
| - int addr_family, const std::string& interface_name) {
|
| - NetworkChangeNotifier::ConnectionType type =
|
| - NetworkChangeNotifier::CONNECTION_UNKNOWN;
|
| -
|
| - struct ifmediareq ifmr = {};
|
| - strncpy(ifmr.ifm_name, interface_name.c_str(), sizeof(ifmr.ifm_name) - 1);
|
| -
|
| - int s = socket(addr_family, SOCK_DGRAM, 0);
|
| - if (s == -1) {
|
| - return type;
|
| - }
|
| -
|
| - if (ioctl(s, SIOCGIFMEDIA, &ifmr) != -1) {
|
| - if (ifmr.ifm_current & IFM_IEEE80211) {
|
| - type = NetworkChangeNotifier::CONNECTION_WIFI;
|
| - } else if (ifmr.ifm_current & IFM_ETHER) {
|
| - type = NetworkChangeNotifier::CONNECTION_ETHERNET;
|
| - }
|
| - }
|
| - close(s);
|
| - return type;
|
| -}
|
| -
|
| -#endif // !defined(OS_IOS)
|
| -#elif !defined(OS_NACL) // OS_MACOSX
|
| -
|
| -// Convert platform native IPv6 address attributes to net IP address
|
| -// attributes and drop ones that can't be used by the application
|
| -// layer.
|
| -bool TryConvertNativeToNetIPAttributes(int native_attributes,
|
| - int* net_attributes) {
|
| - // For Linux/ChromeOS/Android, we disallow addresses with attributes
|
| - // IFA_F_OPTIMISTIC, IFA_F_DADFAILED, and IFA_F_TENTATIVE as these
|
| - // are still progressing through duplicated address detection (DAD)
|
| - // and shouldn't be used by the application layer until DAD process
|
| - // is completed.
|
| - if (native_attributes & (
|
| -#if !defined(OS_ANDROID)
|
| - IFA_F_OPTIMISTIC | IFA_F_DADFAILED |
|
| -#endif // !OS_ANDROID
|
| - IFA_F_TENTATIVE)) {
|
| - return false;
|
| - }
|
| -
|
| - if (native_attributes & IFA_F_TEMPORARY) {
|
| - *net_attributes |= IP_ADDRESS_ATTRIBUTE_TEMPORARY;
|
| - }
|
| -
|
| - if (native_attributes & IFA_F_DEPRECATED) {
|
| - *net_attributes |= IP_ADDRESS_ATTRIBUTE_DEPRECATED;
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -#endif // OS_MACOSX
|
| -} // namespace
|
| -
|
| -namespace internal {
|
| -
|
| -#if !defined(OS_MACOSX) && !defined(OS_NACL)
|
| -
|
| -inline const unsigned char* GetIPAddressData(const IPAddressNumber& ip) {
|
| -#if defined(OS_ANDROID)
|
| - return ip.begin();
|
| -#else
|
| - return ip.data();
|
| -#endif
|
| -}
|
| -
|
| -bool GetNetworkListImpl(
|
| - NetworkInterfaceList* networks,
|
| - int policy,
|
| - const base::hash_set<int>& online_links,
|
| - const internal::AddressTrackerLinux::AddressMap& address_map,
|
| - GetInterfaceNameFunction get_interface_name) {
|
| - std::map<int, std::string> ifnames;
|
| -
|
| - for (internal::AddressTrackerLinux::AddressMap::const_iterator it =
|
| - address_map.begin();
|
| - it != address_map.end();
|
| - ++it) {
|
| - // Ignore addresses whose links are not online.
|
| - if (online_links.find(it->second.ifa_index) == online_links.end())
|
| - continue;
|
| -
|
| - sockaddr_storage sock_addr;
|
| - socklen_t sock_len = sizeof(sockaddr_storage);
|
| -
|
| - // Convert to sockaddr for next check.
|
| - if (!IPEndPoint(it->first, 0)
|
| - .ToSockAddr(reinterpret_cast<sockaddr*>(&sock_addr), &sock_len)) {
|
| - continue;
|
| - }
|
| -
|
| - // Skip unspecified addresses (i.e. made of zeroes) and loopback addresses
|
| - if (IsLoopbackOrUnspecifiedAddress(reinterpret_cast<sockaddr*>(&sock_addr)))
|
| - continue;
|
| -
|
| - int ip_attributes = IP_ADDRESS_ATTRIBUTE_NONE;
|
| -
|
| - if (it->second.ifa_family == AF_INET6) {
|
| - // Ignore addresses whose attributes are not actionable by
|
| - // the application layer.
|
| - if (!TryConvertNativeToNetIPAttributes(it->second.ifa_flags,
|
| - &ip_attributes))
|
| - continue;
|
| - }
|
| -
|
| - // Find the name of this link.
|
| - std::map<int, std::string>::const_iterator itname =
|
| - ifnames.find(it->second.ifa_index);
|
| - std::string ifname;
|
| - if (itname == ifnames.end()) {
|
| - char buffer[IF_NAMESIZE] = {0};
|
| - if (get_interface_name(it->second.ifa_index, buffer)) {
|
| - ifname = ifnames[it->second.ifa_index] = buffer;
|
| - } else {
|
| - // Ignore addresses whose interface name can't be retrieved.
|
| - continue;
|
| - }
|
| - } else {
|
| - ifname = itname->second;
|
| - }
|
| -
|
| - // Based on the interface name and policy, determine whether we
|
| - // should ignore it.
|
| - if (ShouldIgnoreInterface(ifname, policy))
|
| - continue;
|
| -
|
| - networks->push_back(
|
| - NetworkInterface(ifname,
|
| - ifname,
|
| - it->second.ifa_index,
|
| - NetworkChangeNotifier::CONNECTION_UNKNOWN,
|
| - it->first,
|
| - it->second.ifa_prefixlen,
|
| - ip_attributes));
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -#endif
|
| -
|
| } // namespace internal
|
| -
|
| +#else // OS_NACL
|
| bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
|
| - if (networks == NULL)
|
| - return false;
|
| -#if defined(OS_NACL)
|
| NOTIMPLEMENTED();
|
| return false;
|
| -#elif !defined(OS_MACOSX)
|
| -
|
| - internal::AddressTrackerLinux tracker;
|
| - tracker.Init();
|
| -
|
| - return internal::GetNetworkListImpl(networks,
|
| - policy,
|
| - tracker.GetOnlineLinks(),
|
| - tracker.GetAddressMap(),
|
| - &if_indextoname);
|
| -
|
| -#else // Only OS_MACOSX and OS_IOS will run the code below
|
| -
|
| - // getifaddrs() may require IO operations.
|
| - base::ThreadRestrictions::AssertIOAllowed();
|
| -
|
| -#if !defined(OS_IOS)
|
| - int ioctl_socket = -1;
|
| - if (policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) {
|
| - // we need a socket to query information about temporary address.
|
| - ioctl_socket = socket(AF_INET6, SOCK_DGRAM, 0);
|
| - DCHECK_GT(ioctl_socket, 0);
|
| - }
|
| -#endif
|
| -
|
| - ifaddrs* interfaces;
|
| - if (getifaddrs(&interfaces) < 0) {
|
| - PLOG(ERROR) << "getifaddrs";
|
| - return false;
|
| - }
|
| -
|
| - std::vector<NetworkInterfaceInfo> network_infos;
|
| -
|
| - // 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 unspecified addresses (i.e. made of zeroes) and loopback addresses
|
| - // configured on non-loopback interfaces.
|
| - if (IsLoopbackOrUnspecifiedAddress(addr))
|
| - continue;
|
| -
|
| - int addr_size = 0;
|
| - if (addr->sa_family == AF_INET6) {
|
| - addr_size = sizeof(sockaddr_in6);
|
| - } else if (addr->sa_family == AF_INET) {
|
| - addr_size = sizeof(sockaddr_in);
|
| - }
|
| -
|
| - const std::string& name = interface->ifa_name;
|
| - // Filter out VMware interfaces, typically named vmnet1 and vmnet8.
|
| - if (ShouldIgnoreInterface(name, policy)) {
|
| - continue;
|
| - }
|
| -
|
| - NetworkInterfaceInfo network_info;
|
| - NetworkChangeNotifier::ConnectionType connection_type =
|
| - NetworkChangeNotifier::CONNECTION_UNKNOWN;
|
| -#if !defined(OS_IOS)
|
| - // Check if this is a temporary address. Currently this is only supported
|
| - // on Mac.
|
| - if ((policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) &&
|
| - ioctl_socket >= 0 && addr->sa_family == AF_INET6) {
|
| - struct in6_ifreq ifr = {};
|
| - strncpy(ifr.ifr_name, interface->ifa_name, sizeof(ifr.ifr_name) - 1);
|
| - memcpy(&ifr.ifr_ifru.ifru_addr, interface->ifa_addr,
|
| - interface->ifa_addr->sa_len);
|
| - int rv = ioctl(ioctl_socket, SIOCGIFAFLAG_IN6, &ifr);
|
| - if (rv >= 0) {
|
| - network_info.permanent = !(ifr.ifr_ifru.ifru_flags & IN6_IFF_TEMPORARY);
|
| - }
|
| - }
|
| -
|
| - connection_type = GetNetworkInterfaceType(addr->sa_family, name);
|
| -#endif
|
| -
|
| - IPEndPoint address;
|
| - if (address.FromSockAddr(addr, addr_size)) {
|
| - uint8 net_mask = 0;
|
| - if (interface->ifa_netmask) {
|
| - // If not otherwise set, assume the same sa_family as ifa_addr.
|
| - if (interface->ifa_netmask->sa_family == 0) {
|
| - interface->ifa_netmask->sa_family = addr->sa_family;
|
| - }
|
| - IPEndPoint netmask;
|
| - if (netmask.FromSockAddr(interface->ifa_netmask, addr_size)) {
|
| - net_mask = MaskPrefixLength(netmask.address());
|
| - }
|
| - }
|
| - network_info.interface = NetworkInterface(name,
|
| - name,
|
| - if_nametoindex(name.c_str()),
|
| - connection_type,
|
| - address.address(),
|
| - net_mask,
|
| - IP_ADDRESS_ATTRIBUTE_NONE);
|
| -
|
| - network_infos.push_back(NetworkInterfaceInfo(network_info));
|
| - }
|
| - }
|
| - freeifaddrs(interfaces);
|
| -#if !defined(OS_IOS)
|
| - if (ioctl_socket >= 0) {
|
| - close(ioctl_socket);
|
| - }
|
| -#endif
|
| -
|
| - if (policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) {
|
| - RemovePermanentIPv6AddressesWhereTemporaryExists(&network_infos);
|
| - }
|
| -
|
| - for (size_t i = 0; i < network_infos.size(); ++i) {
|
| - networks->push_back(network_infos[i].interface);
|
| - }
|
| - return true;
|
| -#endif
|
| }
|
| +#endif // OS_NACL
|
|
|
| WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
|
| return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN;
|
|
|