| 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 24 matching lines...) Expand all Loading... |
| 35 #include "net/android/network_library.h" | 35 #include "net/android/network_library.h" |
| 36 #endif | 36 #endif |
| 37 | 37 |
| 38 namespace net { | 38 namespace net { |
| 39 | 39 |
| 40 namespace { | 40 namespace { |
| 41 | 41 |
| 42 #if !defined(OS_ANDROID) | 42 #if !defined(OS_ANDROID) |
| 43 | 43 |
| 44 struct NetworkInterfaceInfo { | 44 struct NetworkInterfaceInfo { |
| 45 NetworkInterfaceInfo() : permanent(true) { } | 45 NetworkInterfaceInfo() : permanent(true) {} |
| 46 | 46 |
| 47 bool permanent; // IPv6 has notion of temporary address. If the address is | 47 bool permanent; // IPv6 has notion of temporary address. If the address is |
| 48 // IPv6 and it's temporary this field will be false. | 48 // IPv6 and it's temporary this field will be false. |
| 49 NetworkInterface interface; | 49 NetworkInterface interface; |
| 50 }; | 50 }; |
| 51 | 51 |
| 52 // This method will remove permanent IPv6 addresses if a temporary address | 52 // This method will remove permanent IPv6 addresses if a temporary address |
| 53 // is available for same network interface. | 53 // is available for same network interface. |
| 54 void RemovePermanentIPv6AddressesWhereTemporaryExists( | 54 void RemovePermanentIPv6AddressesWhereTemporaryExists( |
| 55 std::vector<NetworkInterfaceInfo>* infos) { | 55 std::vector<NetworkInterfaceInfo>* infos) { |
| 56 if (!infos || infos->empty()) | 56 if (!infos || infos->empty()) |
| 57 return; | 57 return; |
| 58 | 58 |
| 59 // Build a set containing the names of interfaces with a temp IPv6 address | 59 // Build a set containing the names of interfaces with a temp IPv6 address |
| 60 std::set<std::string> ifaces_with_temp_addrs; | 60 std::set<std::string> ifaces_with_temp_addrs; |
| 61 std::vector<NetworkInterfaceInfo>::iterator i; | 61 std::vector<NetworkInterfaceInfo>::iterator i; |
| 62 for (i = infos->begin(); i != infos->end(); ++i) { | 62 for (i = infos->begin(); i != infos->end(); ++i) { |
| 63 if (!i->permanent && i->interface.address.size() == kIPv6AddressSize) { | 63 if (!i->permanent && i->interface.address.size() == kIPv6AddressSize) { |
| 64 ifaces_with_temp_addrs.insert(i->interface.name); | 64 ifaces_with_temp_addrs.insert(i->interface.name); |
| 65 } | 65 } |
| 66 } | 66 } |
| 67 | 67 |
| 68 // If there are no such interfaces then there's no further work. | 68 // If there are no such interfaces then there's no further work. |
| 69 if (ifaces_with_temp_addrs.empty()) | 69 if (ifaces_with_temp_addrs.empty()) |
| 70 return; | 70 return; |
| 71 | 71 |
| 72 // Search for permenent addresses belonging to same network interface. | 72 // Search for permenent addresses belonging to same network interface. |
| 73 for (i = infos->begin(); i != infos->end(); ) { | 73 for (i = infos->begin(); i != infos->end();) { |
| 74 // If the address is IPv6 and it's permanent and there is temporary | 74 // If the address is IPv6 and it's permanent and there is temporary |
| 75 // address for it, then we can remove this address. | 75 // address for it, then we can remove this address. |
| 76 if ((i->interface.address.size() == kIPv6AddressSize) && i->permanent && | 76 if ((i->interface.address.size() == kIPv6AddressSize) && i->permanent && |
| 77 (ifaces_with_temp_addrs.find(i->interface.name) != | 77 (ifaces_with_temp_addrs.find(i->interface.name) != |
| 78 ifaces_with_temp_addrs.end())) { | 78 ifaces_with_temp_addrs.end())) { |
| 79 i = infos->erase(i); | 79 i = infos->erase(i); |
| 80 } else { | 80 } else { |
| 81 ++i; | 81 ++i; |
| 82 } | 82 } |
| 83 } | 83 } |
| 84 } | 84 } |
| 85 | 85 |
| 86 #endif | 86 #endif |
| 87 | 87 |
| 88 #if defined(OS_MACOSX) && !defined(OS_IOS) | 88 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 89 | 89 |
| 90 NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType( | 90 NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType( |
| 91 int addr_family, const std::string& interface_name) { | 91 int addr_family, |
| 92 const std::string& interface_name) { |
| 92 NetworkChangeNotifier::ConnectionType type = | 93 NetworkChangeNotifier::ConnectionType type = |
| 93 NetworkChangeNotifier::CONNECTION_UNKNOWN; | 94 NetworkChangeNotifier::CONNECTION_UNKNOWN; |
| 94 | 95 |
| 95 struct ifmediareq ifmr = {}; | 96 struct ifmediareq ifmr = {}; |
| 96 strncpy(ifmr.ifm_name, interface_name.c_str(), sizeof(ifmr.ifm_name) - 1); | 97 strncpy(ifmr.ifm_name, interface_name.c_str(), sizeof(ifmr.ifm_name) - 1); |
| 97 | 98 |
| 98 int s = socket(addr_family, SOCK_DGRAM, 0); | 99 int s = socket(addr_family, SOCK_DGRAM, 0); |
| 99 if (s == -1) { | 100 if (s == -1) { |
| 100 return type; | 101 return type; |
| 101 } | 102 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 125 while (network_interfaces.GetNext()) { | 126 while (network_interfaces.GetNext()) { |
| 126 std::string network_item = network_interfaces.token(); | 127 std::string network_item = network_interfaces.token(); |
| 127 base::StringTokenizer network_tokenizer(network_item, "\t"); | 128 base::StringTokenizer network_tokenizer(network_item, "\t"); |
| 128 CHECK(network_tokenizer.GetNext()); | 129 CHECK(network_tokenizer.GetNext()); |
| 129 std::string name = network_tokenizer.token(); | 130 std::string name = network_tokenizer.token(); |
| 130 | 131 |
| 131 CHECK(network_tokenizer.GetNext()); | 132 CHECK(network_tokenizer.GetNext()); |
| 132 std::string interface_address = network_tokenizer.token(); | 133 std::string interface_address = network_tokenizer.token(); |
| 133 IPAddressNumber address; | 134 IPAddressNumber address; |
| 134 size_t network_prefix = 0; | 135 size_t network_prefix = 0; |
| 135 CHECK(ParseCIDRBlock(network_tokenizer.token(), | 136 CHECK(ParseCIDRBlock(network_tokenizer.token(), &address, &network_prefix)); |
| 136 &address, | |
| 137 &network_prefix)); | |
| 138 | 137 |
| 139 CHECK(network_tokenizer.GetNext()); | 138 CHECK(network_tokenizer.GetNext()); |
| 140 uint32 index = 0; | 139 uint32 index = 0; |
| 141 CHECK(base::StringToUint(network_tokenizer.token(), &index)); | 140 CHECK(base::StringToUint(network_tokenizer.token(), &index)); |
| 142 | 141 |
| 143 networks->push_back( | 142 networks->push_back( |
| 144 NetworkInterface(name, | 143 NetworkInterface(name, |
| 145 name, | 144 name, |
| 146 index, | 145 index, |
| 147 NetworkChangeNotifier::CONNECTION_UNKNOWN, | 146 NetworkChangeNotifier::CONNECTION_UNKNOWN, |
| 148 address, | 147 address, |
| 149 network_prefix, | 148 network_prefix, |
| 150 IP_ADDRESS_ATTRIBUTE_NONE)); | 149 IP_ADDRESS_ATTRIBUTE_NONE)); |
| 151 } | 150 } |
| 152 return true; | 151 return true; |
| 153 #else | 152 #else |
| 154 // getifaddrs() may require IO operations. | 153 // getifaddrs() may require IO operations. |
| 155 base::ThreadRestrictions::AssertIOAllowed(); | 154 base::ThreadRestrictions::AssertIOAllowed(); |
| 156 | 155 |
| 157 #if defined(OS_MACOSX) && !defined(OS_IOS) | 156 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 158 int ioctl_socket = -1; | 157 int ioctl_socket = -1; |
| 159 if (policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) { | 158 if (policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) { |
| 160 // we need a socket to query information about temporary address. | 159 // we need a socket to query information about temporary address. |
| 161 ioctl_socket = socket(AF_INET6, SOCK_DGRAM, 0); | 160 ioctl_socket = socket(AF_INET6, SOCK_DGRAM, 0); |
| 162 DCHECK_GT(ioctl_socket, 0); | 161 DCHECK_GT(ioctl_socket, 0); |
| 163 } | 162 } |
| 164 #endif | 163 #endif |
| 165 | 164 |
| 166 ifaddrs *interfaces; | 165 ifaddrs* interfaces; |
| 167 if (getifaddrs(&interfaces) < 0) { | 166 if (getifaddrs(&interfaces) < 0) { |
| 168 PLOG(ERROR) << "getifaddrs"; | 167 PLOG(ERROR) << "getifaddrs"; |
| 169 return false; | 168 return false; |
| 170 } | 169 } |
| 171 | 170 |
| 172 std::vector<NetworkInterfaceInfo> network_infos; | 171 std::vector<NetworkInterfaceInfo> network_infos; |
| 173 | 172 |
| 174 // Enumerate the addresses assigned to network interfaces which are up. | 173 // Enumerate the addresses assigned to network interfaces which are up. |
| 175 for (ifaddrs *interface = interfaces; | 174 for (ifaddrs* interface = interfaces; interface != NULL; |
| 176 interface != NULL; | |
| 177 interface = interface->ifa_next) { | 175 interface = interface->ifa_next) { |
| 178 // Skip loopback interfaces, and ones which are down. | 176 // Skip loopback interfaces, and ones which are down. |
| 179 if (!(IFF_UP & interface->ifa_flags)) | 177 if (!(IFF_UP & interface->ifa_flags)) |
| 180 continue; | 178 continue; |
| 181 if (IFF_LOOPBACK & interface->ifa_flags) | 179 if (IFF_LOOPBACK & interface->ifa_flags) |
| 182 continue; | 180 continue; |
| 183 // Skip interfaces with no address configured. | 181 // Skip interfaces with no address configured. |
| 184 struct sockaddr* addr = interface->ifa_addr; | 182 struct sockaddr* addr = interface->ifa_addr; |
| 185 if (!addr) | 183 if (!addr) |
| 186 continue; | 184 continue; |
| 187 | 185 |
| 188 // Skip unspecified addresses (i.e. made of zeroes) and loopback addresses | 186 // Skip unspecified addresses (i.e. made of zeroes) and loopback addresses |
| 189 // configured on non-loopback interfaces. | 187 // configured on non-loopback interfaces. |
| 190 int addr_size = 0; | 188 int addr_size = 0; |
| 191 if (addr->sa_family == AF_INET6) { | 189 if (addr->sa_family == AF_INET6) { |
| 192 struct sockaddr_in6* addr_in6 = | 190 struct sockaddr_in6* addr_in6 = |
| 193 reinterpret_cast<struct sockaddr_in6*>(addr); | 191 reinterpret_cast<struct sockaddr_in6*>(addr); |
| 194 struct in6_addr* sin6_addr = &addr_in6->sin6_addr; | 192 struct in6_addr* sin6_addr = &addr_in6->sin6_addr; |
| 195 addr_size = sizeof(*addr_in6); | 193 addr_size = sizeof(*addr_in6); |
| 196 if (IN6_IS_ADDR_LOOPBACK(sin6_addr) || | 194 if (IN6_IS_ADDR_LOOPBACK(sin6_addr) || |
| 197 IN6_IS_ADDR_UNSPECIFIED(sin6_addr)) { | 195 IN6_IS_ADDR_UNSPECIFIED(sin6_addr)) { |
| 198 continue; | 196 continue; |
| 199 } | 197 } |
| 200 } else if (addr->sa_family == AF_INET) { | 198 } else if (addr->sa_family == AF_INET) { |
| 201 struct sockaddr_in* addr_in = | 199 struct sockaddr_in* addr_in = reinterpret_cast<struct sockaddr_in*>(addr); |
| 202 reinterpret_cast<struct sockaddr_in*>(addr); | |
| 203 addr_size = sizeof(*addr_in); | 200 addr_size = sizeof(*addr_in); |
| 204 if (addr_in->sin_addr.s_addr == INADDR_LOOPBACK || | 201 if (addr_in->sin_addr.s_addr == INADDR_LOOPBACK || |
| 205 addr_in->sin_addr.s_addr == 0) { | 202 addr_in->sin_addr.s_addr == 0) { |
| 206 continue; | 203 continue; |
| 207 } | 204 } |
| 208 } else { | 205 } else { |
| 209 // Skip non-IP addresses. | 206 // Skip non-IP addresses. |
| 210 continue; | 207 continue; |
| 211 } | 208 } |
| 212 | 209 |
| 213 const std::string& name = interface->ifa_name; | 210 const std::string& name = interface->ifa_name; |
| 214 // Filter out VMware interfaces, typically named vmnet1 and vmnet8. | 211 // Filter out VMware interfaces, typically named vmnet1 and vmnet8. |
| 215 if ((policy & EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES) && | 212 if ((policy & EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES) && |
| 216 ((name.find("vmnet") != std::string::npos) || | 213 ((name.find("vmnet") != std::string::npos) || |
| 217 (name.find("vnic") != std::string::npos))) { | 214 (name.find("vnic") != std::string::npos))) { |
| 218 continue; | 215 continue; |
| 219 } | 216 } |
| 220 | 217 |
| 221 NetworkInterfaceInfo network_info; | 218 NetworkInterfaceInfo network_info; |
| 222 NetworkChangeNotifier::ConnectionType connection_type = | 219 NetworkChangeNotifier::ConnectionType connection_type = |
| 223 NetworkChangeNotifier::CONNECTION_UNKNOWN; | 220 NetworkChangeNotifier::CONNECTION_UNKNOWN; |
| 224 #if defined(OS_MACOSX) && !defined(OS_IOS) | 221 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 225 // Check if this is a temporary address. Currently this is only supported | 222 // Check if this is a temporary address. Currently this is only supported |
| 226 // on Mac. | 223 // on Mac. |
| 227 if ((policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) && | 224 if ((policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) && |
| 228 ioctl_socket >= 0 && addr->sa_family == AF_INET6) { | 225 ioctl_socket >= 0 && addr->sa_family == AF_INET6) { |
| 229 struct in6_ifreq ifr = {}; | 226 struct in6_ifreq ifr = {}; |
| 230 strncpy(ifr.ifr_name, interface->ifa_name, sizeof(ifr.ifr_name) - 1); | 227 strncpy(ifr.ifr_name, interface->ifa_name, sizeof(ifr.ifr_name) - 1); |
| 231 memcpy(&ifr.ifr_ifru.ifru_addr, interface->ifa_addr, | 228 memcpy(&ifr.ifr_ifru.ifru_addr, |
| 229 interface->ifa_addr, |
| 232 interface->ifa_addr->sa_len); | 230 interface->ifa_addr->sa_len); |
| 233 int rv = ioctl(ioctl_socket, SIOCGIFAFLAG_IN6, &ifr); | 231 int rv = ioctl(ioctl_socket, SIOCGIFAFLAG_IN6, &ifr); |
| 234 if (rv >= 0) { | 232 if (rv >= 0) { |
| 235 network_info.permanent = !(ifr.ifr_ifru.ifru_flags & IN6_IFF_TEMPORARY); | 233 network_info.permanent = !(ifr.ifr_ifru.ifru_flags & IN6_IFF_TEMPORARY); |
| 236 } | 234 } |
| 237 } | 235 } |
| 238 | 236 |
| 239 connection_type = GetNetworkInterfaceType(addr->sa_family, name); | 237 connection_type = GetNetworkInterfaceType(addr->sa_family, name); |
| 240 #endif | 238 #endif |
| 241 | 239 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 } | 280 } |
| 283 | 281 |
| 284 WifiPHYLayerProtocol GetWifiPHYLayerProtocol() { | 282 WifiPHYLayerProtocol GetWifiPHYLayerProtocol() { |
| 285 return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN; | 283 return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN; |
| 286 } | 284 } |
| 287 | 285 |
| 288 scoped_ptr<ScopedWifiOptions> SetWifiOptions(int options) { | 286 scoped_ptr<ScopedWifiOptions> SetWifiOptions(int options) { |
| 289 return scoped_ptr<ScopedWifiOptions>(); | 287 return scoped_ptr<ScopedWifiOptions>(); |
| 290 } | 288 } |
| 291 | 289 |
| 292 | |
| 293 } // namespace net | 290 } // namespace net |
| OLD | NEW |