• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/strings/string_number_conversions.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 
FileURLToFilePath(const GURL & url,base::FilePath * path)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 
GetNetworkList(NetworkInterfaceList * networks)66 bool GetNetworkList(NetworkInterfaceList* networks) {
67 #if defined(OS_ANDROID)
68   std::string network_list = android::GetNetworkList();
69   base::StringTokenizer network_interfaces(network_list, "\n");
70   while (network_interfaces.GetNext()) {
71     std::string network_item = network_interfaces.token();
72     base::StringTokenizer network_tokenizer(network_item, "\t");
73     CHECK(network_tokenizer.GetNext());
74     std::string name = network_tokenizer.token();
75 
76     CHECK(network_tokenizer.GetNext());
77     std::string interface_address = network_tokenizer.token();
78     IPAddressNumber address;
79     size_t network_prefix = 0;
80     CHECK(ParseCIDRBlock(network_tokenizer.token(),
81                          &address,
82                          &network_prefix));
83 
84     CHECK(network_tokenizer.GetNext());
85     uint32 index = 0;
86     CHECK(base::StringToUint(network_tokenizer.token(), &index));
87 
88     networks->push_back(
89         NetworkInterface(name, index, address, network_prefix));
90   }
91   return true;
92 #else
93   // getifaddrs() may require IO operations.
94   base::ThreadRestrictions::AssertIOAllowed();
95 
96   ifaddrs *interfaces;
97   if (getifaddrs(&interfaces) < 0) {
98     PLOG(ERROR) << "getifaddrs";
99     return false;
100   }
101 
102   // Enumerate the addresses assigned to network interfaces which are up.
103   for (ifaddrs *interface = interfaces;
104        interface != NULL;
105        interface = interface->ifa_next) {
106     // Skip loopback interfaces, and ones which are down.
107     if (!(IFF_UP & interface->ifa_flags))
108       continue;
109     if (IFF_LOOPBACK & interface->ifa_flags)
110       continue;
111     // Skip interfaces with no address configured.
112     struct sockaddr* addr = interface->ifa_addr;
113     if (!addr)
114       continue;
115 
116     // Skip unspecified addresses (i.e. made of zeroes) and loopback addresses
117     // configured on non-loopback interfaces.
118     int addr_size = 0;
119     if (addr->sa_family == AF_INET6) {
120       struct sockaddr_in6* addr_in6 =
121           reinterpret_cast<struct sockaddr_in6*>(addr);
122       struct in6_addr* sin6_addr = &addr_in6->sin6_addr;
123       addr_size = sizeof(*addr_in6);
124       if (IN6_IS_ADDR_LOOPBACK(sin6_addr) ||
125           IN6_IS_ADDR_UNSPECIFIED(sin6_addr)) {
126         continue;
127       }
128     } else if (addr->sa_family == AF_INET) {
129       struct sockaddr_in* addr_in =
130           reinterpret_cast<struct sockaddr_in*>(addr);
131       addr_size = sizeof(*addr_in);
132       if (addr_in->sin_addr.s_addr == INADDR_LOOPBACK ||
133           addr_in->sin_addr.s_addr == 0) {
134         continue;
135       }
136     } else {
137       // Skip non-IP addresses.
138       continue;
139     }
140 
141     IPEndPoint address;
142     std::string name = interface->ifa_name;
143     if (address.FromSockAddr(addr, addr_size)) {
144       uint8 net_mask = 0;
145       if (interface->ifa_netmask) {
146         IPEndPoint netmask;
147         if (netmask.FromSockAddr(interface->ifa_netmask, addr_size)) {
148           net_mask = MaskPrefixLength(netmask.address());
149         }
150       }
151 
152       networks->push_back(
153           NetworkInterface(name, if_nametoindex(name.c_str()),
154                            address.address(), net_mask));
155     }
156   }
157 
158   freeifaddrs(interfaces);
159 
160   return true;
161 #endif
162 }
163 
GetWifiPHYLayerProtocol()164 WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
165   return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN;
166 }
167 
168 }  // namespace net
169