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.
5 #include "net/base/net_util.h"
9 #include "base/files/file_path.h"
10 #include "base/logging.h"
11 #include "base/posix/eintr_wrapper.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_tokenizer.h"
14 #include "base/strings/string_util.h"
15 #include "base/threading/thread_restrictions.h"
16 #include "net/base/escape.h"
17 #include "net/base/ip_endpoint.h"
18 #include "net/base/net_errors.h"
21 #if !defined(OS_ANDROID)
25 #include <netinet/in.h>
27 #if defined(OS_ANDROID)
28 #include "net/android/network_library.h"
33 bool FileURLToFilePath(const GURL& url, base::FilePath* path) {
34 *path = base::FilePath();
35 std::string& file_path_str = const_cast<std::string&>(path->value());
36 file_path_str.clear();
41 // Firefox seems to ignore the "host" of a file url if there is one. That is,
42 // file://foo/bar.txt maps to /bar.txt.
43 // TODO(dhg): This should probably take into account UNCs which could
44 // include a hostname other than localhost or blank
45 std::string old_path = url.path();
50 // GURL stores strings as percent-encoded 8-bit, this will undo if possible.
51 old_path = UnescapeURLComponent(old_path,
52 UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS);
54 // Collapse multiple path slashes into a single path slash.
58 ReplaceSubstringsAfterOffset(&new_path, 0, "//", "/");
59 old_path.swap(new_path);
60 } while (new_path != old_path);
62 file_path_str.assign(old_path);
64 return !file_path_str.empty();
67 bool GetNetworkList(NetworkInterfaceList* networks) {
68 #if defined(OS_ANDROID)
69 std::string network_list = android::GetNetworkList();
70 base::StringTokenizer network_interfaces(network_list, "\n");
71 while (network_interfaces.GetNext()) {
72 std::string network_item = network_interfaces.token();
73 base::StringTokenizer network_tokenizer(network_item, "\t");
74 CHECK(network_tokenizer.GetNext());
75 std::string name = network_tokenizer.token();
77 CHECK(network_tokenizer.GetNext());
78 std::string interface_address = network_tokenizer.token();
79 IPAddressNumber address;
80 size_t network_prefix = 0;
81 CHECK(ParseCIDRBlock(network_tokenizer.token(),
86 NetworkInterface(name, address, network_prefix));
90 // getifaddrs() may require IO operations.
91 base::ThreadRestrictions::AssertIOAllowed();
94 if (getifaddrs(&interfaces) < 0) {
95 PLOG(ERROR) << "getifaddrs";
99 // Enumerate the addresses assigned to network interfaces which are up.
100 for (ifaddrs *interface = interfaces;
102 interface = interface->ifa_next) {
103 // Skip loopback interfaces, and ones which are down.
104 if (!(IFF_UP & interface->ifa_flags))
106 if (IFF_LOOPBACK & interface->ifa_flags)
108 // Skip interfaces with no address configured.
109 struct sockaddr* addr = interface->ifa_addr;
112 // Skip unspecified addresses (i.e. made of zeroes) and loopback addresses
113 // configured on non-loopback interfaces.
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)) {
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) {
133 // Skip non-IP addresses.
138 std::string name = interface->ifa_name;
139 if (address.FromSockAddr(addr, addr_size)) {
141 if (interface->ifa_netmask) {
143 if (netmask.FromSockAddr(interface->ifa_netmask, addr_size)) {
144 net_mask = MaskPrefixLength(netmask.address());
148 networks->push_back(NetworkInterface(name, address.address(), net_mask));
152 freeifaddrs(interfaces);
158 WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
159 return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN;