| 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 |