Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/base/net_util.h"
      6 
      7 #include <sys/types.h>
      8 
      9 #include "base/files/file_path.h"
     10 #include "base/logging.h"
     11 #include "base/posix/eintr_wrapper.h"
     12 #include "base/strings/string_tokenizer.h"
     13 #include "base/strings/string_util.h"
     14 #include "base/threading/thread_restrictions.h"
     15 #include "net/base/escape.h"
     16 #include "net/base/ip_endpoint.h"
     17 #include "net/base/net_errors.h"
     18 #include "url/gurl.h"
     19 
     20 #if !defined(OS_ANDROID)
     21 #include <ifaddrs.h>
     22 #endif
     23 #include <net/if.h>
     24 #include <netinet/in.h>
     25 
     26 #if defined(OS_ANDROID)
     27 #include "net/android/network_library.h"
     28 #endif
     29 
     30 namespace net {
     31 
     32 bool FileURLToFilePath(const GURL& url, base::FilePath* path) {
     33   *path = base::FilePath();
     34   std::string& file_path_str = const_cast<std::string&>(path->value());
     35   file_path_str.clear();
     36 
     37   if (!url.is_valid())
     38     return false;
     39 
     40   // Firefox seems to ignore the "host" of a file url if there is one. That is,
     41   // file://foo/bar.txt maps to /bar.txt.
     42   // TODO(dhg): This should probably take into account UNCs which could
     43   // include a hostname other than localhost or blank
     44   std::string old_path = url.path();
     45 
     46   if (old_path.empty())
     47     return false;
     48 
     49   // GURL stores strings as percent-encoded 8-bit, this will undo if possible.
     50   old_path = UnescapeURLComponent(old_path,
     51       UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS);
     52 
     53   // Collapse multiple path slashes into a single path slash.
     54   std::string new_path;
     55   do {
     56     new_path = old_path;
     57     ReplaceSubstringsAfterOffset(&new_path, 0, "//", "/");
     58     old_path.swap(new_path);
     59   } while (new_path != old_path);
     60 
     61   file_path_str.assign(old_path);
     62 
     63   return !file_path_str.empty();
     64 }
     65 
     66 bool GetNetworkList(NetworkInterfaceList* networks) {
     67 #if defined(OS_ANDROID)
     68   std::string network_list = android::GetNetworkList();
     69   base::StringTokenizer network_interfaces(network_list, ";");
     70   while (network_interfaces.GetNext()) {
     71     std::string network_item = network_interfaces.token();
     72     base::StringTokenizer network_tokenizer(network_item, ",");
     73     std::string name;
     74     if (!network_tokenizer.GetNext())
     75       continue;
     76     name = network_tokenizer.token();
     77 
     78     std::string literal_address;
     79     if (!network_tokenizer.GetNext())
     80       continue;
     81     literal_address = network_tokenizer.token();
     82 
     83     IPAddressNumber address;
     84     if (!ParseIPLiteralToNumber(literal_address, &address))
     85       continue;
     86     networks->push_back(NetworkInterface(name, address));
     87   }
     88   return true;
     89 #else
     90   // getifaddrs() may require IO operations.
     91   base::ThreadRestrictions::AssertIOAllowed();
     92 
     93   ifaddrs *interfaces;
     94   if (getifaddrs(&interfaces) < 0) {
     95     PLOG(ERROR) << "getifaddrs";
     96     return false;
     97   }
     98 
     99   // Enumerate the addresses assigned to network interfaces which are up.
    100   for (ifaddrs *interface = interfaces;
    101        interface != NULL;
    102        interface = interface->ifa_next) {
    103     // Skip loopback interfaces, and ones which are down.
    104     if (!(IFF_UP & interface->ifa_flags))
    105       continue;
    106     if (IFF_LOOPBACK & interface->ifa_flags)
    107       continue;
    108     // Skip interfaces with no address configured.
    109     struct sockaddr* addr = interface->ifa_addr;
    110     if (!addr)
    111       continue;
    112     // Skip unspecified addresses (i.e. made of zeroes) and loopback addresses
    113     // configured on non-loopback interfaces.
    114     int addr_size = 0;
    115     if (addr->sa_family == AF_INET6) {
    116       struct sockaddr_in6* addr_in6 =
    117           reinterpret_cast<struct sockaddr_in6*>(addr);
    118       struct in6_addr* sin6_addr = &addr_in6->sin6_addr;
    119       addr_size = sizeof(*addr_in6);
    120       if (IN6_IS_ADDR_LOOPBACK(sin6_addr) ||
    121           IN6_IS_ADDR_UNSPECIFIED(sin6_addr)) {
    122         continue;
    123       }
    124     } else if (addr->sa_family == AF_INET) {
    125       struct sockaddr_in* addr_in =
    126           reinterpret_cast<struct sockaddr_in*>(addr);
    127       addr_size = sizeof(*addr_in);
    128       if (addr_in->sin_addr.s_addr == INADDR_LOOPBACK ||
    129           addr_in->sin_addr.s_addr == 0) {
    130         continue;
    131       }
    132     } else {
    133       // Skip non-IP addresses.
    134       continue;
    135     }
    136     IPEndPoint address;
    137     std::string name = interface->ifa_name;
    138     if (address.FromSockAddr(addr, addr_size)) {
    139       networks->push_back(NetworkInterface(name, address.address()));
    140     }
    141   }
    142 
    143   freeifaddrs(interfaces);
    144 
    145   return true;
    146 #endif
    147 }
    148 
    149 WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
    150   return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN;
    151 }
    152 
    153 }  // namespace net
    154