OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/base/net_util.h" | 5 #include "net/base/net_util.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <sys/types.h> | 8 #include <sys/types.h> |
9 | 9 |
10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 #include "net/android/network_library.h" | 34 #include "net/android/network_library.h" |
35 #endif | 35 #endif |
36 | 36 |
37 namespace net { | 37 namespace net { |
38 | 38 |
39 namespace { | 39 namespace { |
40 | 40 |
41 #if !defined(OS_ANDROID) | 41 #if !defined(OS_ANDROID) |
42 | 42 |
43 struct NetworkInterfaceInfo { | 43 struct NetworkInterfaceInfo { |
44 NetworkInterfaceInfo() : permanent(true) { } | 44 NetworkInterfaceInfo() : permanent(true) {} |
45 | 45 |
46 bool permanent; // IPv6 has notion of temporary address. If the address is | 46 bool permanent; // IPv6 has notion of temporary address. If the address is |
47 // IPv6 and it's temporary this field will be false. | 47 // IPv6 and it's temporary this field will be false. |
48 NetworkInterface interface; | 48 NetworkInterface interface; |
49 }; | 49 }; |
50 | 50 |
51 // This method will remove permanent IPv6 addresses if a temporary address | 51 // This method will remove permanent IPv6 addresses if a temporary address |
52 // is available for same network interface. | 52 // is available for same network interface. |
53 void RemovePermanentIPv6AddressesWhereTemporaryExists( | 53 void RemovePermanentIPv6AddressesWhereTemporaryExists( |
54 std::vector<NetworkInterfaceInfo>* infos) { | 54 std::vector<NetworkInterfaceInfo>* infos) { |
55 if (!infos || infos->empty()) | 55 if (!infos || infos->empty()) |
56 return; | 56 return; |
57 | 57 |
58 // Build a set containing the names of interfaces with a temp IPv6 address | 58 // Build a set containing the names of interfaces with a temp IPv6 address |
59 std::set<std::string> ifaces_with_temp_addrs; | 59 std::set<std::string> ifaces_with_temp_addrs; |
60 std::vector<NetworkInterfaceInfo>::iterator i; | 60 std::vector<NetworkInterfaceInfo>::iterator i; |
61 for (i = infos->begin(); i != infos->end(); ++i) { | 61 for (i = infos->begin(); i != infos->end(); ++i) { |
62 if (!i->permanent && i->interface.address.size() == kIPv6AddressSize) { | 62 if (!i->permanent && i->interface.address.size() == kIPv6AddressSize) { |
63 ifaces_with_temp_addrs.insert(i->interface.name); | 63 ifaces_with_temp_addrs.insert(i->interface.name); |
64 } | 64 } |
65 } | 65 } |
66 | 66 |
67 // If there are no such interfaces then there's no further work. | 67 // If there are no such interfaces then there's no further work. |
68 if (ifaces_with_temp_addrs.empty()) | 68 if (ifaces_with_temp_addrs.empty()) |
69 return; | 69 return; |
70 | 70 |
71 // Search for permenent addresses belonging to same network interface. | 71 // Search for permenent addresses belonging to same network interface. |
72 for (i = infos->begin(); i != infos->end(); ) { | 72 for (i = infos->begin(); i != infos->end();) { |
73 // If the address is IPv6 and it's permanent and there is temporary | 73 // If the address is IPv6 and it's permanent and there is temporary |
74 // address for it, then we can remove this address. | 74 // address for it, then we can remove this address. |
75 if ((i->interface.address.size() == kIPv6AddressSize) && i->permanent && | 75 if ((i->interface.address.size() == kIPv6AddressSize) && i->permanent && |
76 (ifaces_with_temp_addrs.find(i->interface.name) != | 76 (ifaces_with_temp_addrs.find(i->interface.name) != |
77 ifaces_with_temp_addrs.end())) { | 77 ifaces_with_temp_addrs.end())) { |
78 i = infos->erase(i); | 78 i = infos->erase(i); |
79 } else { | 79 } else { |
80 ++i; | 80 ++i; |
81 } | 81 } |
82 } | 82 } |
83 } | 83 } |
84 | 84 |
85 #endif | 85 #endif |
86 | 86 |
87 #if defined(OS_MACOSX) && !defined(OS_IOS) | 87 #if defined(OS_MACOSX) && !defined(OS_IOS) |
88 | 88 |
89 NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType( | 89 NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType( |
90 int addr_family, const std::string& interface_name) { | 90 int addr_family, |
| 91 const std::string& interface_name) { |
91 NetworkChangeNotifier::ConnectionType type = | 92 NetworkChangeNotifier::ConnectionType type = |
92 NetworkChangeNotifier::CONNECTION_UNKNOWN; | 93 NetworkChangeNotifier::CONNECTION_UNKNOWN; |
93 | 94 |
94 struct ifmediareq ifmr = {}; | 95 struct ifmediareq ifmr = {}; |
95 strncpy(ifmr.ifm_name, interface_name.c_str(), sizeof(ifmr.ifm_name) - 1); | 96 strncpy(ifmr.ifm_name, interface_name.c_str(), sizeof(ifmr.ifm_name) - 1); |
96 | 97 |
97 int s = socket(addr_family, SOCK_DGRAM, 0); | 98 int s = socket(addr_family, SOCK_DGRAM, 0); |
98 if (s == -1) { | 99 if (s == -1) { |
99 return type; | 100 return type; |
100 } | 101 } |
(...skipping 23 matching lines...) Expand all Loading... |
124 while (network_interfaces.GetNext()) { | 125 while (network_interfaces.GetNext()) { |
125 std::string network_item = network_interfaces.token(); | 126 std::string network_item = network_interfaces.token(); |
126 base::StringTokenizer network_tokenizer(network_item, "\t"); | 127 base::StringTokenizer network_tokenizer(network_item, "\t"); |
127 CHECK(network_tokenizer.GetNext()); | 128 CHECK(network_tokenizer.GetNext()); |
128 std::string name = network_tokenizer.token(); | 129 std::string name = network_tokenizer.token(); |
129 | 130 |
130 CHECK(network_tokenizer.GetNext()); | 131 CHECK(network_tokenizer.GetNext()); |
131 std::string interface_address = network_tokenizer.token(); | 132 std::string interface_address = network_tokenizer.token(); |
132 IPAddressNumber address; | 133 IPAddressNumber address; |
133 size_t network_prefix = 0; | 134 size_t network_prefix = 0; |
134 CHECK(ParseCIDRBlock(network_tokenizer.token(), | 135 CHECK(ParseCIDRBlock(network_tokenizer.token(), &address, &network_prefix)); |
135 &address, | |
136 &network_prefix)); | |
137 | 136 |
138 CHECK(network_tokenizer.GetNext()); | 137 CHECK(network_tokenizer.GetNext()); |
139 uint32 index = 0; | 138 uint32 index = 0; |
140 CHECK(base::StringToUint(network_tokenizer.token(), &index)); | 139 CHECK(base::StringToUint(network_tokenizer.token(), &index)); |
141 | 140 |
142 networks->push_back( | 141 networks->push_back( |
143 NetworkInterface(name, name, index, | 142 NetworkInterface(name, |
| 143 name, |
| 144 index, |
144 NetworkChangeNotifier::CONNECTION_UNKNOWN, | 145 NetworkChangeNotifier::CONNECTION_UNKNOWN, |
145 address, network_prefix)); | 146 address, |
| 147 network_prefix)); |
146 } | 148 } |
147 return true; | 149 return true; |
148 #else | 150 #else |
149 // getifaddrs() may require IO operations. | 151 // getifaddrs() may require IO operations. |
150 base::ThreadRestrictions::AssertIOAllowed(); | 152 base::ThreadRestrictions::AssertIOAllowed(); |
151 | 153 |
152 int ioctl_socket = -1; | 154 int ioctl_socket = -1; |
153 if (policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) { | 155 if (policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) { |
154 // we need a socket to query information about temporary address. | 156 // we need a socket to query information about temporary address. |
155 ioctl_socket = socket(AF_INET6, SOCK_DGRAM, 0); | 157 ioctl_socket = socket(AF_INET6, SOCK_DGRAM, 0); |
156 DCHECK_GT(ioctl_socket, 0); | 158 DCHECK_GT(ioctl_socket, 0); |
157 } | 159 } |
158 | 160 |
159 ifaddrs *interfaces; | 161 ifaddrs* interfaces; |
160 if (getifaddrs(&interfaces) < 0) { | 162 if (getifaddrs(&interfaces) < 0) { |
161 PLOG(ERROR) << "getifaddrs"; | 163 PLOG(ERROR) << "getifaddrs"; |
162 return false; | 164 return false; |
163 } | 165 } |
164 | 166 |
165 std::vector<NetworkInterfaceInfo> network_infos; | 167 std::vector<NetworkInterfaceInfo> network_infos; |
166 | 168 |
167 // Enumerate the addresses assigned to network interfaces which are up. | 169 // Enumerate the addresses assigned to network interfaces which are up. |
168 for (ifaddrs *interface = interfaces; | 170 for (ifaddrs* interface = interfaces; interface != NULL; |
169 interface != NULL; | |
170 interface = interface->ifa_next) { | 171 interface = interface->ifa_next) { |
171 // Skip loopback interfaces, and ones which are down. | 172 // Skip loopback interfaces, and ones which are down. |
172 if (!(IFF_UP & interface->ifa_flags)) | 173 if (!(IFF_UP & interface->ifa_flags)) |
173 continue; | 174 continue; |
174 if (IFF_LOOPBACK & interface->ifa_flags) | 175 if (IFF_LOOPBACK & interface->ifa_flags) |
175 continue; | 176 continue; |
176 // Skip interfaces with no address configured. | 177 // Skip interfaces with no address configured. |
177 struct sockaddr* addr = interface->ifa_addr; | 178 struct sockaddr* addr = interface->ifa_addr; |
178 if (!addr) | 179 if (!addr) |
179 continue; | 180 continue; |
180 | 181 |
181 // Skip unspecified addresses (i.e. made of zeroes) and loopback addresses | 182 // Skip unspecified addresses (i.e. made of zeroes) and loopback addresses |
182 // configured on non-loopback interfaces. | 183 // configured on non-loopback interfaces. |
183 int addr_size = 0; | 184 int addr_size = 0; |
184 if (addr->sa_family == AF_INET6) { | 185 if (addr->sa_family == AF_INET6) { |
185 struct sockaddr_in6* addr_in6 = | 186 struct sockaddr_in6* addr_in6 = |
186 reinterpret_cast<struct sockaddr_in6*>(addr); | 187 reinterpret_cast<struct sockaddr_in6*>(addr); |
187 struct in6_addr* sin6_addr = &addr_in6->sin6_addr; | 188 struct in6_addr* sin6_addr = &addr_in6->sin6_addr; |
188 addr_size = sizeof(*addr_in6); | 189 addr_size = sizeof(*addr_in6); |
189 if (IN6_IS_ADDR_LOOPBACK(sin6_addr) || | 190 if (IN6_IS_ADDR_LOOPBACK(sin6_addr) || |
190 IN6_IS_ADDR_UNSPECIFIED(sin6_addr)) { | 191 IN6_IS_ADDR_UNSPECIFIED(sin6_addr)) { |
191 continue; | 192 continue; |
192 } | 193 } |
193 } else if (addr->sa_family == AF_INET) { | 194 } else if (addr->sa_family == AF_INET) { |
194 struct sockaddr_in* addr_in = | 195 struct sockaddr_in* addr_in = reinterpret_cast<struct sockaddr_in*>(addr); |
195 reinterpret_cast<struct sockaddr_in*>(addr); | |
196 addr_size = sizeof(*addr_in); | 196 addr_size = sizeof(*addr_in); |
197 if (addr_in->sin_addr.s_addr == INADDR_LOOPBACK || | 197 if (addr_in->sin_addr.s_addr == INADDR_LOOPBACK || |
198 addr_in->sin_addr.s_addr == 0) { | 198 addr_in->sin_addr.s_addr == 0) { |
199 continue; | 199 continue; |
200 } | 200 } |
201 } else { | 201 } else { |
202 // Skip non-IP addresses. | 202 // Skip non-IP addresses. |
203 continue; | 203 continue; |
204 } | 204 } |
205 | 205 |
206 const std::string& name = interface->ifa_name; | 206 const std::string& name = interface->ifa_name; |
207 // Filter out VMware interfaces, typically named vmnet1 and vmnet8. | 207 // Filter out VMware interfaces, typically named vmnet1 and vmnet8. |
208 if ((policy & EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES) && | 208 if ((policy & EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES) && |
209 ((name.find("vmnet") != std::string::npos) || | 209 ((name.find("vmnet") != std::string::npos) || |
210 (name.find("vnic") != std::string::npos))) { | 210 (name.find("vnic") != std::string::npos))) { |
211 continue; | 211 continue; |
212 } | 212 } |
213 | 213 |
214 NetworkInterfaceInfo network_info; | 214 NetworkInterfaceInfo network_info; |
215 NetworkChangeNotifier::ConnectionType connection_type = | 215 NetworkChangeNotifier::ConnectionType connection_type = |
216 NetworkChangeNotifier::CONNECTION_UNKNOWN; | 216 NetworkChangeNotifier::CONNECTION_UNKNOWN; |
217 #if defined(OS_MACOSX) && !defined(OS_IOS) | 217 #if defined(OS_MACOSX) && !defined(OS_IOS) |
218 // Check if this is a temporary address. Currently this is only supported | 218 // Check if this is a temporary address. Currently this is only supported |
219 // on Mac. | 219 // on Mac. |
220 if ((policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) && | 220 if ((policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) && |
221 ioctl_socket >= 0 && addr->sa_family == AF_INET6) { | 221 ioctl_socket >= 0 && addr->sa_family == AF_INET6) { |
222 struct in6_ifreq ifr = {}; | 222 struct in6_ifreq ifr = {}; |
223 strncpy(ifr.ifr_name, interface->ifa_name, sizeof(ifr.ifr_name) - 1); | 223 strncpy(ifr.ifr_name, interface->ifa_name, sizeof(ifr.ifr_name) - 1); |
224 memcpy(&ifr.ifr_ifru.ifru_addr, interface->ifa_addr, | 224 memcpy(&ifr.ifr_ifru.ifru_addr, |
| 225 interface->ifa_addr, |
225 interface->ifa_addr->sa_len); | 226 interface->ifa_addr->sa_len); |
226 int rv = ioctl(ioctl_socket, SIOCGIFAFLAG_IN6, &ifr); | 227 int rv = ioctl(ioctl_socket, SIOCGIFAFLAG_IN6, &ifr); |
227 if (rv >= 0) { | 228 if (rv >= 0) { |
228 network_info.permanent = !(ifr.ifr_ifru.ifru_flags & IN6_IFF_TEMPORARY); | 229 network_info.permanent = !(ifr.ifr_ifru.ifru_flags & IN6_IFF_TEMPORARY); |
229 } | 230 } |
230 } | 231 } |
231 | 232 |
232 connection_type = GetNetworkInterfaceType(addr->sa_family, name); | 233 connection_type = GetNetworkInterfaceType(addr->sa_family, name); |
233 #endif | 234 #endif |
234 | 235 |
235 IPEndPoint address; | 236 IPEndPoint address; |
236 if (address.FromSockAddr(addr, addr_size)) { | 237 if (address.FromSockAddr(addr, addr_size)) { |
237 uint8 net_mask = 0; | 238 uint8 net_mask = 0; |
238 if (interface->ifa_netmask) { | 239 if (interface->ifa_netmask) { |
239 // If not otherwise set, assume the same sa_family as ifa_addr. | 240 // If not otherwise set, assume the same sa_family as ifa_addr. |
240 if (interface->ifa_netmask->sa_family == 0) { | 241 if (interface->ifa_netmask->sa_family == 0) { |
241 interface->ifa_netmask->sa_family = addr->sa_family; | 242 interface->ifa_netmask->sa_family = addr->sa_family; |
242 } | 243 } |
243 IPEndPoint netmask; | 244 IPEndPoint netmask; |
244 if (netmask.FromSockAddr(interface->ifa_netmask, addr_size)) { | 245 if (netmask.FromSockAddr(interface->ifa_netmask, addr_size)) { |
245 net_mask = MaskPrefixLength(netmask.address()); | 246 net_mask = MaskPrefixLength(netmask.address()); |
246 } | 247 } |
247 } | 248 } |
248 network_info.interface = NetworkInterface( | 249 network_info.interface = NetworkInterface(name, |
249 name, name, if_nametoindex(name.c_str()), | 250 name, |
250 connection_type, address.address(), net_mask); | 251 if_nametoindex(name.c_str()), |
| 252 connection_type, |
| 253 address.address(), |
| 254 net_mask); |
251 | 255 |
252 network_infos.push_back(NetworkInterfaceInfo(network_info)); | 256 network_infos.push_back(NetworkInterfaceInfo(network_info)); |
253 } | 257 } |
254 } | 258 } |
255 freeifaddrs(interfaces); | 259 freeifaddrs(interfaces); |
256 if (ioctl_socket >= 0) { | 260 if (ioctl_socket >= 0) { |
257 close(ioctl_socket); | 261 close(ioctl_socket); |
258 } | 262 } |
259 | 263 |
260 if (policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) { | 264 if (policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) { |
261 RemovePermanentIPv6AddressesWhereTemporaryExists(&network_infos); | 265 RemovePermanentIPv6AddressesWhereTemporaryExists(&network_infos); |
262 } | 266 } |
263 | 267 |
264 for (size_t i = 0; i < network_infos.size(); ++i) { | 268 for (size_t i = 0; i < network_infos.size(); ++i) { |
265 networks->push_back(network_infos[i].interface); | 269 networks->push_back(network_infos[i].interface); |
266 } | 270 } |
267 return true; | 271 return true; |
268 #endif | 272 #endif |
269 } | 273 } |
270 | 274 |
271 WifiPHYLayerProtocol GetWifiPHYLayerProtocol() { | 275 WifiPHYLayerProtocol GetWifiPHYLayerProtocol() { |
272 return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN; | 276 return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN; |
273 } | 277 } |
274 | 278 |
275 } // namespace net | 279 } // namespace net |
OLD | NEW |