| OLD | NEW | 
|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <iphlpapi.h> | 7 #include <iphlpapi.h> | 
| 8 #include <wlanapi.h> | 8 #include <wlanapi.h> | 
| 9 | 9 | 
| 10 #include <algorithm> | 10 #include <algorithm> | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 45     type = NetworkChangeNotifier::CONNECTION_WIFI; | 45     type = NetworkChangeNotifier::CONNECTION_WIFI; | 
| 46   } | 46   } | 
| 47   // TODO(mallinath) - Cellular? | 47   // TODO(mallinath) - Cellular? | 
| 48   return type; | 48   return type; | 
| 49 } | 49 } | 
| 50 | 50 | 
| 51 }  // namespace | 51 }  // namespace | 
| 52 | 52 | 
| 53 namespace internal { | 53 namespace internal { | 
| 54 | 54 | 
| 55 base::LazyInstance<WlanApi>::Leaky lazy_wlanapi = | 55 base::LazyInstance<WlanApi>::Leaky lazy_wlanapi = LAZY_INSTANCE_INITIALIZER; | 
| 56   LAZY_INSTANCE_INITIALIZER; |  | 
| 57 | 56 | 
| 58 WlanApi& WlanApi::GetInstance() { | 57 WlanApi& WlanApi::GetInstance() { | 
| 59   return lazy_wlanapi.Get(); | 58   return lazy_wlanapi.Get(); | 
| 60 } | 59 } | 
| 61 | 60 | 
| 62 WlanApi::WlanApi() : initialized(false) { | 61 WlanApi::WlanApi() : initialized(false) { | 
| 63   // Use an absolute path to load the DLL to avoid DLL preloading attacks. | 62   // Use an absolute path to load the DLL to avoid DLL preloading attacks. | 
| 64   static const wchar_t* const kDLL = L"%WINDIR%\\system32\\wlanapi.dll"; | 63   static const wchar_t* const kDLL = L"%WINDIR%\\system32\\wlanapi.dll"; | 
| 65   wchar_t path[MAX_PATH] = {0}; | 64   wchar_t path[MAX_PATH] = {0}; | 
| 66   ExpandEnvironmentStrings(kDLL, path, arraysize(path)); | 65   ExpandEnvironmentStrings(kDLL, path, arraysize(path)); | 
| 67   module = ::LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); | 66   module = ::LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); | 
| 68   if (!module) | 67   if (!module) | 
| 69     return; | 68     return; | 
| 70 | 69 | 
| 71   open_handle_func = reinterpret_cast<WlanOpenHandleFunc>( | 70   open_handle_func = reinterpret_cast<WlanOpenHandleFunc>( | 
| 72       ::GetProcAddress(module, "WlanOpenHandle")); | 71       ::GetProcAddress(module, "WlanOpenHandle")); | 
| 73   enum_interfaces_func = reinterpret_cast<WlanEnumInterfacesFunc>( | 72   enum_interfaces_func = reinterpret_cast<WlanEnumInterfacesFunc>( | 
| 74       ::GetProcAddress(module, "WlanEnumInterfaces")); | 73       ::GetProcAddress(module, "WlanEnumInterfaces")); | 
| 75   query_interface_func = reinterpret_cast<WlanQueryInterfaceFunc>( | 74   query_interface_func = reinterpret_cast<WlanQueryInterfaceFunc>( | 
| 76       ::GetProcAddress(module, "WlanQueryInterface")); | 75       ::GetProcAddress(module, "WlanQueryInterface")); | 
| 77   set_interface_func = reinterpret_cast<WlanSetInterfaceFunc>( | 76   set_interface_func = reinterpret_cast<WlanSetInterfaceFunc>( | 
| 78       ::GetProcAddress(module, "WlanSetInterface")); | 77       ::GetProcAddress(module, "WlanSetInterface")); | 
| 79   free_memory_func = reinterpret_cast<WlanFreeMemoryFunc>( | 78   free_memory_func = reinterpret_cast<WlanFreeMemoryFunc>( | 
| 80       ::GetProcAddress(module, "WlanFreeMemory")); | 79       ::GetProcAddress(module, "WlanFreeMemory")); | 
| 81   close_handle_func = reinterpret_cast<WlanCloseHandleFunc>( | 80   close_handle_func = reinterpret_cast<WlanCloseHandleFunc>( | 
| 82       ::GetProcAddress(module, "WlanCloseHandle")); | 81       ::GetProcAddress(module, "WlanCloseHandle")); | 
| 83   initialized = open_handle_func && enum_interfaces_func && | 82   initialized = open_handle_func && enum_interfaces_func && | 
| 84       query_interface_func && set_interface_func && | 83                 query_interface_func && set_interface_func && | 
| 85       free_memory_func && close_handle_func; | 84                 free_memory_func && close_handle_func; | 
| 86 } | 85 } | 
| 87 | 86 | 
| 88 }  // namespace internal | 87 }  // namespace internal | 
| 89 | 88 | 
| 90 bool GetNetworkList(NetworkInterfaceList* networks, int policy) { | 89 bool GetNetworkList(NetworkInterfaceList* networks, int policy) { | 
| 91   // GetAdaptersAddresses() may require IO operations. | 90   // GetAdaptersAddresses() may require IO operations. | 
| 92   base::ThreadRestrictions::AssertIOAllowed(); | 91   base::ThreadRestrictions::AssertIOAllowed(); | 
| 93   bool is_xp = base::win::GetVersion() < base::win::VERSION_VISTA; | 92   bool is_xp = base::win::GetVersion() < base::win::VERSION_VISTA; | 
| 94   ULONG len = 0; | 93   ULONG len = 0; | 
| 95   ULONG flags = is_xp ? GAA_FLAG_INCLUDE_PREFIX : 0; | 94   ULONG flags = is_xp ? GAA_FLAG_INCLUDE_PREFIX : 0; | 
| 96   // First get number of networks. | 95   // First get number of networks. | 
| 97   ULONG result = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, NULL, &len); | 96   ULONG result = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, NULL, &len); | 
| 98   if (result != ERROR_BUFFER_OVERFLOW) { | 97   if (result != ERROR_BUFFER_OVERFLOW) { | 
| 99     // There are 0 networks. | 98     // There are 0 networks. | 
| 100     return true; | 99     return true; | 
| 101   } | 100   } | 
| 102   scoped_ptr<char[]> buf(new char[len]); | 101   scoped_ptr<char[]> buf(new char[len]); | 
| 103   IP_ADAPTER_ADDRESSES *adapters = | 102   IP_ADAPTER_ADDRESSES* adapters = | 
| 104       reinterpret_cast<IP_ADAPTER_ADDRESSES *>(buf.get()); | 103       reinterpret_cast<IP_ADAPTER_ADDRESSES*>(buf.get()); | 
| 105   result = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapters, &len); | 104   result = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapters, &len); | 
| 106   if (result != NO_ERROR) { | 105   if (result != NO_ERROR) { | 
| 107     LOG(ERROR) << "GetAdaptersAddresses failed: " << result; | 106     LOG(ERROR) << "GetAdaptersAddresses failed: " << result; | 
| 108     return false; | 107     return false; | 
| 109   } | 108   } | 
| 110 | 109 | 
| 111   // These two variables are used below when this method is asked to pick a | 110   // These two variables are used below when this method is asked to pick a | 
| 112   // IPv6 address which has the shortest lifetime. | 111   // IPv6 address which has the shortest lifetime. | 
| 113   ULONG ipv6_valid_lifetime = 0; | 112   ULONG ipv6_valid_lifetime = 0; | 
| 114   scoped_ptr<NetworkInterface> ipv6_address; | 113   scoped_ptr<NetworkInterface> ipv6_address; | 
| 115 | 114 | 
| 116   for (IP_ADAPTER_ADDRESSES *adapter = adapters; adapter != NULL; | 115   for (IP_ADAPTER_ADDRESSES* adapter = adapters; adapter != NULL; | 
| 117        adapter = adapter->Next) { | 116        adapter = adapter->Next) { | 
| 118     // Ignore the loopback device. | 117     // Ignore the loopback device. | 
| 119     if (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK) { | 118     if (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK) { | 
| 120       continue; | 119       continue; | 
| 121     } | 120     } | 
| 122 | 121 | 
| 123     if (adapter->OperStatus != IfOperStatusUp) { | 122     if (adapter->OperStatus != IfOperStatusUp) { | 
| 124       continue; | 123       continue; | 
| 125     } | 124     } | 
| 126 | 125 | 
| 127     // Ignore any HOST side vmware adapters with a description like: | 126     // Ignore any HOST side vmware adapters with a description like: | 
| 128     // VMware Virtual Ethernet Adapter for VMnet1 | 127     // VMware Virtual Ethernet Adapter for VMnet1 | 
| 129     // but don't ignore any GUEST side adapters with a description like: | 128     // but don't ignore any GUEST side adapters with a description like: | 
| 130     // VMware Accelerated AMD PCNet Adapter #2 | 129     // VMware Accelerated AMD PCNet Adapter #2 | 
| 131     if (policy == EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES && | 130     if (policy == EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES && | 
| 132         strstr(adapter->AdapterName, "VMnet") != NULL) { | 131         strstr(adapter->AdapterName, "VMnet") != NULL) { | 
| 133       continue; | 132       continue; | 
| 134     } | 133     } | 
| 135 | 134 | 
| 136     for (IP_ADAPTER_UNICAST_ADDRESS* address = adapter->FirstUnicastAddress; | 135     for (IP_ADAPTER_UNICAST_ADDRESS* address = adapter->FirstUnicastAddress; | 
| 137          address; address = address->Next) { | 136          address; | 
|  | 137          address = address->Next) { | 
| 138       int family = address->Address.lpSockaddr->sa_family; | 138       int family = address->Address.lpSockaddr->sa_family; | 
| 139       if (family == AF_INET || family == AF_INET6) { | 139       if (family == AF_INET || family == AF_INET6) { | 
| 140         IPEndPoint endpoint; | 140         IPEndPoint endpoint; | 
| 141         if (endpoint.FromSockAddr(address->Address.lpSockaddr, | 141         if (endpoint.FromSockAddr(address->Address.lpSockaddr, | 
| 142                                   address->Address.iSockaddrLength)) { | 142                                   address->Address.iSockaddrLength)) { | 
| 143           // XP has no OnLinkPrefixLength field. | 143           // XP has no OnLinkPrefixLength field. | 
| 144           size_t net_prefix = is_xp ? 0 : address->OnLinkPrefixLength; | 144           size_t net_prefix = is_xp ? 0 : address->OnLinkPrefixLength; | 
| 145           if (is_xp) { | 145           if (is_xp) { | 
| 146             // Prior to Windows Vista the FirstPrefix pointed to the list with | 146             // Prior to Windows Vista the FirstPrefix pointed to the list with | 
| 147             // single prefix for each IP address assigned to the adapter. | 147             // single prefix for each IP address assigned to the adapter. | 
| 148             // Order of FirstPrefix does not match order of FirstUnicastAddress, | 148             // Order of FirstPrefix does not match order of FirstUnicastAddress, | 
| 149             // so we need to find corresponding prefix. | 149             // so we need to find corresponding prefix. | 
| 150             for (IP_ADAPTER_PREFIX* prefix = adapter->FirstPrefix; prefix; | 150             for (IP_ADAPTER_PREFIX* prefix = adapter->FirstPrefix; prefix; | 
| 151                  prefix = prefix->Next) { | 151                  prefix = prefix->Next) { | 
| 152               int prefix_family = prefix->Address.lpSockaddr->sa_family; | 152               int prefix_family = prefix->Address.lpSockaddr->sa_family; | 
| 153               IPEndPoint network_endpoint; | 153               IPEndPoint network_endpoint; | 
| 154               if (prefix_family == family && | 154               if (prefix_family == family && | 
| 155                   network_endpoint.FromSockAddr(prefix->Address.lpSockaddr, | 155                   network_endpoint.FromSockAddr( | 
|  | 156                       prefix->Address.lpSockaddr, | 
| 156                       prefix->Address.iSockaddrLength) && | 157                       prefix->Address.iSockaddrLength) && | 
| 157                   IPNumberMatchesPrefix(endpoint.address(), | 158                   IPNumberMatchesPrefix(endpoint.address(), | 
| 158                                         network_endpoint.address(), | 159                                         network_endpoint.address(), | 
| 159                                         prefix->PrefixLength)) { | 160                                         prefix->PrefixLength)) { | 
| 160                 net_prefix = std::max<size_t>(net_prefix, prefix->PrefixLength); | 161                 net_prefix = std::max<size_t>(net_prefix, prefix->PrefixLength); | 
| 161               } | 162               } | 
| 162             } | 163             } | 
| 163           } | 164           } | 
| 164           uint32 index = | 165           uint32 index = | 
| 165               (family == AF_INET) ? adapter->IfIndex : adapter->Ipv6IfIndex; | 166               (family == AF_INET) ? adapter->IfIndex : adapter->Ipv6IfIndex; | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 209     return WIFI_PHY_LAYER_PROTOCOL_NONE; | 210     return WIFI_PHY_LAYER_PROTOCOL_NONE; | 
| 210 | 211 | 
| 211   internal::WlanHandle client; | 212   internal::WlanHandle client; | 
| 212   DWORD cur_version = 0; | 213   DWORD cur_version = 0; | 
| 213   const DWORD kMaxClientVersion = 2; | 214   const DWORD kMaxClientVersion = 2; | 
| 214   DWORD result = wlanapi.OpenHandle(kMaxClientVersion, &cur_version, &client); | 215   DWORD result = wlanapi.OpenHandle(kMaxClientVersion, &cur_version, &client); | 
| 215   if (result != ERROR_SUCCESS) | 216   if (result != ERROR_SUCCESS) | 
| 216     return WIFI_PHY_LAYER_PROTOCOL_NONE; | 217     return WIFI_PHY_LAYER_PROTOCOL_NONE; | 
| 217 | 218 | 
| 218   WLAN_INTERFACE_INFO_LIST* interface_list_ptr = NULL; | 219   WLAN_INTERFACE_INFO_LIST* interface_list_ptr = NULL; | 
| 219   result = wlanapi.enum_interfaces_func(client.Get(), NULL, | 220   result = | 
| 220                                         &interface_list_ptr); | 221       wlanapi.enum_interfaces_func(client.Get(), NULL, &interface_list_ptr); | 
| 221   if (result != ERROR_SUCCESS) | 222   if (result != ERROR_SUCCESS) | 
| 222     return WIFI_PHY_LAYER_PROTOCOL_NONE; | 223     return WIFI_PHY_LAYER_PROTOCOL_NONE; | 
| 223   scoped_ptr<WLAN_INTERFACE_INFO_LIST, internal::WlanApiDeleter> interface_list( | 224   scoped_ptr<WLAN_INTERFACE_INFO_LIST, internal::WlanApiDeleter> interface_list( | 
| 224       interface_list_ptr); | 225       interface_list_ptr); | 
| 225 | 226 | 
| 226   // Assume at most one connected wifi interface. | 227   // Assume at most one connected wifi interface. | 
| 227   WLAN_INTERFACE_INFO* info = NULL; | 228   WLAN_INTERFACE_INFO* info = NULL; | 
| 228   for (unsigned i = 0; i < interface_list->dwNumberOfItems; ++i) { | 229   for (unsigned i = 0; i < interface_list->dwNumberOfItems; ++i) { | 
| 229     if (interface_list->InterfaceInfo[i].isState == | 230     if (interface_list->InterfaceInfo[i].isState == | 
| 230         wlan_interface_state_connected) { | 231         wlan_interface_state_connected) { | 
| 231       info = &interface_list->InterfaceInfo[i]; | 232       info = &interface_list->InterfaceInfo[i]; | 
| 232       break; | 233       break; | 
| 233     } | 234     } | 
| 234   } | 235   } | 
| 235 | 236 | 
| 236   if (info == NULL) | 237   if (info == NULL) | 
| 237     return WIFI_PHY_LAYER_PROTOCOL_NONE; | 238     return WIFI_PHY_LAYER_PROTOCOL_NONE; | 
| 238 | 239 | 
| 239   WLAN_CONNECTION_ATTRIBUTES* conn_info_ptr; | 240   WLAN_CONNECTION_ATTRIBUTES* conn_info_ptr; | 
| 240   DWORD conn_info_size = 0; | 241   DWORD conn_info_size = 0; | 
| 241   WLAN_OPCODE_VALUE_TYPE op_code; | 242   WLAN_OPCODE_VALUE_TYPE op_code; | 
| 242   result = wlanapi.query_interface_func( | 243   result = | 
| 243       client.Get(), &info->InterfaceGuid, wlan_intf_opcode_current_connection, | 244       wlanapi.query_interface_func(client.Get(), | 
| 244       NULL, &conn_info_size, reinterpret_cast<VOID**>(&conn_info_ptr), | 245                                    &info->InterfaceGuid, | 
| 245       &op_code); | 246                                    wlan_intf_opcode_current_connection, | 
|  | 247                                    NULL, | 
|  | 248                                    &conn_info_size, | 
|  | 249                                    reinterpret_cast<VOID**>(&conn_info_ptr), | 
|  | 250                                    &op_code); | 
| 246   if (result != ERROR_SUCCESS) | 251   if (result != ERROR_SUCCESS) | 
| 247     return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN; | 252     return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN; | 
| 248   scoped_ptr<WLAN_CONNECTION_ATTRIBUTES, internal::WlanApiDeleter> conn_info( | 253   scoped_ptr<WLAN_CONNECTION_ATTRIBUTES, internal::WlanApiDeleter> conn_info( | 
| 249       conn_info_ptr); | 254       conn_info_ptr); | 
| 250 | 255 | 
| 251   switch (conn_info->wlanAssociationAttributes.dot11PhyType) { | 256   switch (conn_info->wlanAssociationAttributes.dot11PhyType) { | 
| 252     case dot11_phy_type_fhss: | 257     case dot11_phy_type_fhss: | 
| 253       return WIFI_PHY_LAYER_PROTOCOL_ANCIENT; | 258       return WIFI_PHY_LAYER_PROTOCOL_ANCIENT; | 
| 254     case dot11_phy_type_dsss: | 259     case dot11_phy_type_dsss: | 
| 255       return WIFI_PHY_LAYER_PROTOCOL_B; | 260       return WIFI_PHY_LAYER_PROTOCOL_B; | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 273 // is closed. | 278 // is closed. | 
| 274 class WifiOptionSetter : public ScopedWifiOptions { | 279 class WifiOptionSetter : public ScopedWifiOptions { | 
| 275  public: | 280  public: | 
| 276   WifiOptionSetter(int options) { | 281   WifiOptionSetter(int options) { | 
| 277     const internal::WlanApi& wlanapi = internal::WlanApi::GetInstance(); | 282     const internal::WlanApi& wlanapi = internal::WlanApi::GetInstance(); | 
| 278     if (!wlanapi.initialized) | 283     if (!wlanapi.initialized) | 
| 279       return; | 284       return; | 
| 280 | 285 | 
| 281     DWORD cur_version = 0; | 286     DWORD cur_version = 0; | 
| 282     const DWORD kMaxClientVersion = 2; | 287     const DWORD kMaxClientVersion = 2; | 
| 283     DWORD result = wlanapi.OpenHandle( | 288     DWORD result = | 
| 284         kMaxClientVersion, &cur_version, &client_); | 289         wlanapi.OpenHandle(kMaxClientVersion, &cur_version, &client_); | 
| 285     if (result != ERROR_SUCCESS) | 290     if (result != ERROR_SUCCESS) | 
| 286       return; | 291       return; | 
| 287 | 292 | 
| 288     WLAN_INTERFACE_INFO_LIST* interface_list_ptr = NULL; | 293     WLAN_INTERFACE_INFO_LIST* interface_list_ptr = NULL; | 
| 289     result = wlanapi.enum_interfaces_func(client_.Get(), NULL, | 294     result = | 
| 290                                           &interface_list_ptr); | 295         wlanapi.enum_interfaces_func(client_.Get(), NULL, &interface_list_ptr); | 
| 291     if (result != ERROR_SUCCESS) | 296     if (result != ERROR_SUCCESS) | 
| 292       return; | 297       return; | 
| 293     scoped_ptr<WLAN_INTERFACE_INFO_LIST, internal::WlanApiDeleter> | 298     scoped_ptr<WLAN_INTERFACE_INFO_LIST, internal::WlanApiDeleter> | 
| 294         interface_list(interface_list_ptr); | 299         interface_list(interface_list_ptr); | 
| 295 | 300 | 
| 296     for (unsigned i = 0; i < interface_list->dwNumberOfItems; ++i) { | 301     for (unsigned i = 0; i < interface_list->dwNumberOfItems; ++i) { | 
| 297       WLAN_INTERFACE_INFO* info = &interface_list->InterfaceInfo[i]; | 302       WLAN_INTERFACE_INFO* info = &interface_list->InterfaceInfo[i]; | 
| 298       if (options & WIFI_OPTIONS_DISABLE_SCAN) { | 303       if (options & WIFI_OPTIONS_DISABLE_SCAN) { | 
| 299         BOOL data = false; | 304         BOOL data = false; | 
| 300         wlanapi.set_interface_func(client_.Get(), | 305         wlanapi.set_interface_func(client_.Get(), | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 318 | 323 | 
| 319  private: | 324  private: | 
| 320   internal::WlanHandle client_; | 325   internal::WlanHandle client_; | 
| 321 }; | 326 }; | 
| 322 | 327 | 
| 323 scoped_ptr<ScopedWifiOptions> SetWifiOptions(int options) { | 328 scoped_ptr<ScopedWifiOptions> SetWifiOptions(int options) { | 
| 324   return scoped_ptr<ScopedWifiOptions>(new WifiOptionSetter(options)); | 329   return scoped_ptr<ScopedWifiOptions>(new WifiOptionSetter(options)); | 
| 325 } | 330 } | 
| 326 | 331 | 
| 327 }  // namespace net | 332 }  // namespace net | 
| OLD | NEW | 
|---|