| 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 } else { | 73 } else { |
| 74 // Skip non-IP addresses. | 74 // Skip non-IP addresses. |
| 75 return true; | 75 return true; |
| 76 } | 76 } |
| 77 return false; | 77 return false; |
| 78 } | 78 } |
| 79 | 79 |
| 80 #if defined(OS_MACOSX) | 80 #if defined(OS_MACOSX) |
| 81 | 81 |
| 82 struct NetworkInterfaceInfo { | 82 struct NetworkInterfaceInfo { |
| 83 NetworkInterfaceInfo() : permanent(true) { } | 83 NetworkInterfaceInfo() : permanent(true) {} |
| 84 | 84 |
| 85 bool permanent; // IPv6 has notion of temporary address. If the address is | 85 bool permanent; // IPv6 has notion of temporary address. If the address is |
| 86 // IPv6 and it's temporary this field will be false. | 86 // IPv6 and it's temporary this field will be false. |
| 87 NetworkInterface interface; | 87 NetworkInterface interface; |
| 88 }; | 88 }; |
| 89 | 89 |
| 90 // This method will remove permanent IPv6 addresses if a temporary address | 90 // This method will remove permanent IPv6 addresses if a temporary address |
| 91 // is available for same network interface. | 91 // is available for same network interface. |
| 92 void RemovePermanentIPv6AddressesWhereTemporaryExists( | 92 void RemovePermanentIPv6AddressesWhereTemporaryExists( |
| 93 std::vector<NetworkInterfaceInfo>* infos) { | 93 std::vector<NetworkInterfaceInfo>* infos) { |
| 94 if (!infos || infos->empty()) | 94 if (!infos || infos->empty()) |
| 95 return; | 95 return; |
| 96 | 96 |
| 97 // Build a set containing the names of interfaces with a temp IPv6 address | 97 // Build a set containing the names of interfaces with a temp IPv6 address |
| 98 std::set<std::string> ifaces_with_temp_addrs; | 98 std::set<std::string> ifaces_with_temp_addrs; |
| 99 std::vector<NetworkInterfaceInfo>::iterator i; | 99 std::vector<NetworkInterfaceInfo>::iterator i; |
| 100 for (i = infos->begin(); i != infos->end(); ++i) { | 100 for (i = infos->begin(); i != infos->end(); ++i) { |
| 101 if (!i->permanent && i->interface.address.size() == kIPv6AddressSize) { | 101 if (!i->permanent && i->interface.address.size() == kIPv6AddressSize) { |
| 102 ifaces_with_temp_addrs.insert(i->interface.name); | 102 ifaces_with_temp_addrs.insert(i->interface.name); |
| 103 } | 103 } |
| 104 } | 104 } |
| 105 | 105 |
| 106 // If there are no such interfaces then there's no further work. | 106 // If there are no such interfaces then there's no further work. |
| 107 if (ifaces_with_temp_addrs.empty()) | 107 if (ifaces_with_temp_addrs.empty()) |
| 108 return; | 108 return; |
| 109 | 109 |
| 110 // Search for permenent addresses belonging to same network interface. | 110 // Search for permenent addresses belonging to same network interface. |
| 111 for (i = infos->begin(); i != infos->end(); ) { | 111 for (i = infos->begin(); i != infos->end();) { |
| 112 // If the address is IPv6 and it's permanent and there is temporary | 112 // If the address is IPv6 and it's permanent and there is temporary |
| 113 // address for it, then we can remove this address. | 113 // address for it, then we can remove this address. |
| 114 if ((i->interface.address.size() == kIPv6AddressSize) && i->permanent && | 114 if ((i->interface.address.size() == kIPv6AddressSize) && i->permanent && |
| 115 (ifaces_with_temp_addrs.find(i->interface.name) != | 115 (ifaces_with_temp_addrs.find(i->interface.name) != |
| 116 ifaces_with_temp_addrs.end())) { | 116 ifaces_with_temp_addrs.end())) { |
| 117 i = infos->erase(i); | 117 i = infos->erase(i); |
| 118 } else { | 118 } else { |
| 119 ++i; | 119 ++i; |
| 120 } | 120 } |
| 121 } | 121 } |
| 122 } | 122 } |
| 123 | 123 |
| 124 #if !defined(OS_IOS) | 124 #if !defined(OS_IOS) |
| 125 NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType( | 125 NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType( |
| 126 int addr_family, const std::string& interface_name) { | 126 int addr_family, |
| 127 const std::string& interface_name) { |
| 127 NetworkChangeNotifier::ConnectionType type = | 128 NetworkChangeNotifier::ConnectionType type = |
| 128 NetworkChangeNotifier::CONNECTION_UNKNOWN; | 129 NetworkChangeNotifier::CONNECTION_UNKNOWN; |
| 129 | 130 |
| 130 struct ifmediareq ifmr = {}; | 131 struct ifmediareq ifmr = {}; |
| 131 strncpy(ifmr.ifm_name, interface_name.c_str(), sizeof(ifmr.ifm_name) - 1); | 132 strncpy(ifmr.ifm_name, interface_name.c_str(), sizeof(ifmr.ifm_name) - 1); |
| 132 | 133 |
| 133 int s = socket(addr_family, SOCK_DGRAM, 0); | 134 int s = socket(addr_family, SOCK_DGRAM, 0); |
| 134 if (s == -1) { | 135 if (s == -1) { |
| 135 return type; | 136 return type; |
| 136 } | 137 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 154 // layer. | 155 // layer. |
| 155 bool TryConvertNativeToNetIPAttributes(int native_attributes, | 156 bool TryConvertNativeToNetIPAttributes(int native_attributes, |
| 156 int* net_attributes) { | 157 int* net_attributes) { |
| 157 // For Linux/ChromeOS/Android, we disallow addresses with attributes | 158 // For Linux/ChromeOS/Android, we disallow addresses with attributes |
| 158 // IFA_F_OPTIMISTIC, IFA_F_DADFAILED, and IFA_F_TENTATIVE as these | 159 // IFA_F_OPTIMISTIC, IFA_F_DADFAILED, and IFA_F_TENTATIVE as these |
| 159 // are still progressing through duplicated address detection (DAD) | 160 // are still progressing through duplicated address detection (DAD) |
| 160 // and shouldn't be used by the application layer until DAD process | 161 // and shouldn't be used by the application layer until DAD process |
| 161 // is completed. | 162 // is completed. |
| 162 if (native_attributes & ( | 163 if (native_attributes & ( |
| 163 #if !defined(OS_ANDROID) | 164 #if !defined(OS_ANDROID) |
| 164 IFA_F_OPTIMISTIC | IFA_F_DADFAILED | | 165 IFA_F_OPTIMISTIC | IFA_F_DADFAILED | |
| 165 #endif // !OS_ANDROID | 166 #endif // !OS_ANDROID |
| 166 IFA_F_TENTATIVE)) { | 167 IFA_F_TENTATIVE)) { |
| 167 return false; | 168 return false; |
| 168 } | 169 } |
| 169 | 170 |
| 170 if (native_attributes & IFA_F_TEMPORARY) { | 171 if (native_attributes & IFA_F_TEMPORARY) { |
| 171 *net_attributes |= IP_ADDRESS_ATTRIBUTE_TEMPORARY; | 172 *net_attributes |= IP_ADDRESS_ATTRIBUTE_TEMPORARY; |
| 172 } | 173 } |
| 173 | 174 |
| 174 if (native_attributes & IFA_F_DEPRECATED) { | 175 if (native_attributes & IFA_F_DEPRECATED) { |
| 175 *net_attributes |= IP_ADDRESS_ATTRIBUTE_DEPRECATED; | 176 *net_attributes |= IP_ADDRESS_ATTRIBUTE_DEPRECATED; |
| 176 } | 177 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 195 bool GetNetworkListImpl( | 196 bool GetNetworkListImpl( |
| 196 NetworkInterfaceList* networks, | 197 NetworkInterfaceList* networks, |
| 197 int policy, | 198 int policy, |
| 198 const base::hash_set<int>& online_links, | 199 const base::hash_set<int>& online_links, |
| 199 const internal::AddressTrackerLinux::AddressMap& address_map, | 200 const internal::AddressTrackerLinux::AddressMap& address_map, |
| 200 GetInterfaceNameFunction get_interface_name) { | 201 GetInterfaceNameFunction get_interface_name) { |
| 201 std::map<int, std::string> ifnames; | 202 std::map<int, std::string> ifnames; |
| 202 | 203 |
| 203 for (internal::AddressTrackerLinux::AddressMap::const_iterator it = | 204 for (internal::AddressTrackerLinux::AddressMap::const_iterator it = |
| 204 address_map.begin(); | 205 address_map.begin(); |
| 205 it != address_map.end(); | 206 it != address_map.end(); ++it) { |
| 206 ++it) { | |
| 207 // Ignore addresses whose links are not online. | 207 // Ignore addresses whose links are not online. |
| 208 if (online_links.find(it->second.ifa_index) == online_links.end()) | 208 if (online_links.find(it->second.ifa_index) == online_links.end()) |
| 209 continue; | 209 continue; |
| 210 | 210 |
| 211 sockaddr_storage sock_addr; | 211 sockaddr_storage sock_addr; |
| 212 socklen_t sock_len = sizeof(sockaddr_storage); | 212 socklen_t sock_len = sizeof(sockaddr_storage); |
| 213 | 213 |
| 214 // Convert to sockaddr for next check. | 214 // Convert to sockaddr for next check. |
| 215 if (!IPEndPoint(it->first, 0) | 215 if (!IPEndPoint(it->first, 0) |
| 216 .ToSockAddr(reinterpret_cast<sockaddr*>(&sock_addr), &sock_len)) { | 216 .ToSockAddr(reinterpret_cast<sockaddr*>(&sock_addr), &sock_len)) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 246 } else { | 246 } else { |
| 247 ifname = itname->second; | 247 ifname = itname->second; |
| 248 } | 248 } |
| 249 | 249 |
| 250 // Based on the interface name and policy, determine whether we | 250 // Based on the interface name and policy, determine whether we |
| 251 // should ignore it. | 251 // should ignore it. |
| 252 if (ShouldIgnoreInterface(ifname, policy)) | 252 if (ShouldIgnoreInterface(ifname, policy)) |
| 253 continue; | 253 continue; |
| 254 | 254 |
| 255 networks->push_back( | 255 networks->push_back( |
| 256 NetworkInterface(ifname, | 256 NetworkInterface(ifname, ifname, it->second.ifa_index, |
| 257 ifname, | 257 NetworkChangeNotifier::CONNECTION_UNKNOWN, it->first, |
| 258 it->second.ifa_index, | 258 it->second.ifa_prefixlen, ip_attributes)); |
| 259 NetworkChangeNotifier::CONNECTION_UNKNOWN, | |
| 260 it->first, | |
| 261 it->second.ifa_prefixlen, | |
| 262 ip_attributes)); | |
| 263 } | 259 } |
| 264 | 260 |
| 265 return true; | 261 return true; |
| 266 } | 262 } |
| 267 #endif | 263 #endif |
| 268 | 264 |
| 269 } // namespace internal | 265 } // namespace internal |
| 270 | 266 |
| 271 bool GetNetworkList(NetworkInterfaceList* networks, int policy) { | 267 bool GetNetworkList(NetworkInterfaceList* networks, int policy) { |
| 272 if (networks == NULL) | 268 if (networks == NULL) |
| 273 return false; | 269 return false; |
| 274 #if defined(OS_NACL) | 270 #if defined(OS_NACL) |
| 275 NOTIMPLEMENTED(); | 271 NOTIMPLEMENTED(); |
| 276 return false; | 272 return false; |
| 277 #elif !defined(OS_MACOSX) | 273 #elif !defined(OS_MACOSX) |
| 278 | 274 |
| 279 internal::AddressTrackerLinux tracker; | 275 internal::AddressTrackerLinux tracker; |
| 280 tracker.Init(); | 276 tracker.Init(); |
| 281 | 277 |
| 282 return internal::GetNetworkListImpl(networks, | 278 return internal::GetNetworkListImpl(networks, policy, |
| 283 policy, | |
| 284 tracker.GetOnlineLinks(), | 279 tracker.GetOnlineLinks(), |
| 285 tracker.GetAddressMap(), | 280 tracker.GetAddressMap(), &if_indextoname); |
| 286 &if_indextoname); | |
| 287 | 281 |
| 288 #else // Only OS_MACOSX and OS_IOS will run the code below | 282 #else // Only OS_MACOSX and OS_IOS will run the code below |
| 289 | 283 |
| 290 // getifaddrs() may require IO operations. | 284 // getifaddrs() may require IO operations. |
| 291 base::ThreadRestrictions::AssertIOAllowed(); | 285 base::ThreadRestrictions::AssertIOAllowed(); |
| 292 | 286 |
| 293 #if !defined(OS_IOS) | 287 #if !defined(OS_IOS) |
| 294 int ioctl_socket = -1; | 288 int ioctl_socket = -1; |
| 295 if (policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) { | 289 if (policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) { |
| 296 // we need a socket to query information about temporary address. | 290 // we need a socket to query information about temporary address. |
| 297 ioctl_socket = socket(AF_INET6, SOCK_DGRAM, 0); | 291 ioctl_socket = socket(AF_INET6, SOCK_DGRAM, 0); |
| 298 DCHECK_GT(ioctl_socket, 0); | 292 DCHECK_GT(ioctl_socket, 0); |
| 299 } | 293 } |
| 300 #endif | 294 #endif |
| 301 | 295 |
| 302 ifaddrs* interfaces; | 296 ifaddrs* interfaces; |
| 303 if (getifaddrs(&interfaces) < 0) { | 297 if (getifaddrs(&interfaces) < 0) { |
| 304 PLOG(ERROR) << "getifaddrs"; | 298 PLOG(ERROR) << "getifaddrs"; |
| 305 return false; | 299 return false; |
| 306 } | 300 } |
| 307 | 301 |
| 308 std::vector<NetworkInterfaceInfo> network_infos; | 302 std::vector<NetworkInterfaceInfo> network_infos; |
| 309 | 303 |
| 310 // Enumerate the addresses assigned to network interfaces which are up. | 304 // Enumerate the addresses assigned to network interfaces which are up. |
| 311 for (ifaddrs *interface = interfaces; | 305 for (ifaddrs* interface = interfaces; interface != NULL; |
| 312 interface != NULL; | |
| 313 interface = interface->ifa_next) { | 306 interface = interface->ifa_next) { |
| 314 // Skip loopback interfaces, and ones which are down. | 307 // Skip loopback interfaces, and ones which are down. |
| 315 if (!(IFF_UP & interface->ifa_flags)) | 308 if (!(IFF_UP & interface->ifa_flags)) |
| 316 continue; | 309 continue; |
| 317 if (IFF_LOOPBACK & interface->ifa_flags) | 310 if (IFF_LOOPBACK & interface->ifa_flags) |
| 318 continue; | 311 continue; |
| 319 // Skip interfaces with no address configured. | 312 // Skip interfaces with no address configured. |
| 320 struct sockaddr* addr = interface->ifa_addr; | 313 struct sockaddr* addr = interface->ifa_addr; |
| 321 if (!addr) | 314 if (!addr) |
| 322 continue; | 315 continue; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 if (interface->ifa_netmask) { | 359 if (interface->ifa_netmask) { |
| 367 // If not otherwise set, assume the same sa_family as ifa_addr. | 360 // If not otherwise set, assume the same sa_family as ifa_addr. |
| 368 if (interface->ifa_netmask->sa_family == 0) { | 361 if (interface->ifa_netmask->sa_family == 0) { |
| 369 interface->ifa_netmask->sa_family = addr->sa_family; | 362 interface->ifa_netmask->sa_family = addr->sa_family; |
| 370 } | 363 } |
| 371 IPEndPoint netmask; | 364 IPEndPoint netmask; |
| 372 if (netmask.FromSockAddr(interface->ifa_netmask, addr_size)) { | 365 if (netmask.FromSockAddr(interface->ifa_netmask, addr_size)) { |
| 373 net_mask = MaskPrefixLength(netmask.address()); | 366 net_mask = MaskPrefixLength(netmask.address()); |
| 374 } | 367 } |
| 375 } | 368 } |
| 376 network_info.interface = NetworkInterface(name, | 369 network_info.interface = NetworkInterface( |
| 377 name, | 370 name, name, if_nametoindex(name.c_str()), connection_type, |
| 378 if_nametoindex(name.c_str()), | 371 address.address(), net_mask, IP_ADDRESS_ATTRIBUTE_NONE); |
| 379 connection_type, | |
| 380 address.address(), | |
| 381 net_mask, | |
| 382 IP_ADDRESS_ATTRIBUTE_NONE); | |
| 383 | 372 |
| 384 network_infos.push_back(NetworkInterfaceInfo(network_info)); | 373 network_infos.push_back(NetworkInterfaceInfo(network_info)); |
| 385 } | 374 } |
| 386 } | 375 } |
| 387 freeifaddrs(interfaces); | 376 freeifaddrs(interfaces); |
| 388 #if !defined(OS_IOS) | 377 #if !defined(OS_IOS) |
| 389 if (ioctl_socket >= 0) { | 378 if (ioctl_socket >= 0) { |
| 390 close(ioctl_socket); | 379 close(ioctl_socket); |
| 391 } | 380 } |
| 392 #endif | 381 #endif |
| (...skipping 10 matching lines...) Expand all Loading... |
| 403 } | 392 } |
| 404 | 393 |
| 405 WifiPHYLayerProtocol GetWifiPHYLayerProtocol() { | 394 WifiPHYLayerProtocol GetWifiPHYLayerProtocol() { |
| 406 return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN; | 395 return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN; |
| 407 } | 396 } |
| 408 | 397 |
| 409 scoped_ptr<ScopedWifiOptions> SetWifiOptions(int options) { | 398 scoped_ptr<ScopedWifiOptions> SetWifiOptions(int options) { |
| 410 return scoped_ptr<ScopedWifiOptions>(); | 399 return scoped_ptr<ScopedWifiOptions>(); |
| 411 } | 400 } |
| 412 | 401 |
| 413 | |
| 414 } // namespace net | 402 } // namespace net |
| OLD | NEW |