- add sources.
[platform/framework/web/crosswalk.git] / src / net / base / net_util_posix.cc
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_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"
19 #include "url/gurl.h"
20
21 #if !defined(OS_ANDROID)
22 #include <ifaddrs.h>
23 #endif
24 #include <net/if.h>
25 #include <netinet/in.h>
26
27 #if defined(OS_ANDROID)
28 #include "net/android/network_library.h"
29 #endif
30
31 namespace net {
32
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();
37
38   if (!url.is_valid())
39     return false;
40
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();
46
47   if (old_path.empty())
48     return false;
49
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);
53
54   // Collapse multiple path slashes into a single path slash.
55   std::string new_path;
56   do {
57     new_path = old_path;
58     ReplaceSubstringsAfterOffset(&new_path, 0, "//", "/");
59     old_path.swap(new_path);
60   } while (new_path != old_path);
61
62   file_path_str.assign(old_path);
63
64   return !file_path_str.empty();
65 }
66
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();
76
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(),
82                          &address,
83                          &network_prefix));
84
85     networks->push_back(
86         NetworkInterface(name, address, network_prefix));
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
137     IPEndPoint address;
138     std::string name = interface->ifa_name;
139     if (address.FromSockAddr(addr, addr_size)) {
140       uint8 net_mask = 0;
141       if (interface->ifa_netmask) {
142         IPEndPoint netmask;
143         if (netmask.FromSockAddr(interface->ifa_netmask, addr_size)) {
144           net_mask = MaskPrefixLength(netmask.address());
145         }
146       }
147
148       networks->push_back(NetworkInterface(name, address.address(), net_mask));
149     }
150   }
151
152   freeifaddrs(interfaces);
153
154   return true;
155 #endif
156 }
157
158 WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
159   return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN;
160 }
161
162 }  // namespace net