diff options
author | szym@chromium.org <szym@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-13 15:53:42 +0000 |
---|---|---|
committer | szym@chromium.org <szym@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-13 15:53:42 +0000 |
commit | 5eae204c7d34730daa91f7c4e80f547db8ec880c (patch) | |
tree | 1812873b9d50b4edac18a388623ef8fca5060085 /net | |
parent | e3df339855151037599632e38477d80317e47bec (diff) | |
download | chromium_src-5eae204c7d34730daa91f7c4e80f547db8ec880c.zip chromium_src-5eae204c7d34730daa91f7c4e80f547db8ec880c.tar.gz chromium_src-5eae204c7d34730daa91f7c4e80f547db8ec880c.tar.bz2 |
Add WifiPHYLayerProtocol to SystemProfile.
WifiPHYLayerProtocol characterizes the physical layer (PHY) protocol
of the current association with an 802.11 access point. It uses
the common nomenclature of referring to the IEEE 802.11 standard
amendment which introduced the protocol, i.e. a/b/g/n.
TBR=sky
BUG=174414
Review URL: https://codereview.chromium.org/12082090
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@182231 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/base/net_util.h | 22 | ||||
-rw-r--r-- | net/base/net_util_posix.cc | 4 | ||||
-rw-r--r-- | net/base/net_util_win.cc | 138 |
3 files changed, 164 insertions, 0 deletions
diff --git a/net/base/net_util.h b/net/base/net_util.h index f21c1ed..9bbec55 100644 --- a/net/base/net_util.h +++ b/net/base/net_util.h @@ -516,6 +516,28 @@ typedef std::vector<NetworkInterface> NetworkInterfaceList; // Can be called only on a thread that allows IO. NET_EXPORT bool GetNetworkList(NetworkInterfaceList* networks); +// General category of the IEEE 802.11 (wifi) physical layer operating mode. +enum WifiPHYLayerProtocol { + // No wifi support or no associated AP. + WIFI_PHY_LAYER_PROTOCOL_NONE, + // An obsolete modes introduced by the original 802.11, e.g. IR, FHSS, + WIFI_PHY_LAYER_PROTOCOL_ANCIENT, + // 802.11a, OFDM-based rates. + WIFI_PHY_LAYER_PROTOCOL_A, + // 802.11b, DSSS or HR DSSS. + WIFI_PHY_LAYER_PROTOCOL_B, + // 802.11g, same rates as 802.11a but compatible with 802.11b. + WIFI_PHY_LAYER_PROTOCOL_G, + // 802.11n, HT rates. + WIFI_PHY_LAYER_PROTOCOL_N, + // Unclassified mode or failure to identify. + WIFI_PHY_LAYER_PROTOCOL_UNKNOWN +}; + +// Characterize the PHY mode of the currently associated access point. +// Currently only available on OS_WIN. +NET_EXPORT WifiPHYLayerProtocol GetWifiPHYLayerProtocol(); + } // namespace net #endif // NET_BASE_NET_UTIL_H_ diff --git a/net/base/net_util_posix.cc b/net/base/net_util_posix.cc index 0bc0de6..0579ab1 100644 --- a/net/base/net_util_posix.cc +++ b/net/base/net_util_posix.cc @@ -141,4 +141,8 @@ bool GetNetworkList(NetworkInterfaceList* networks) { #endif } +WifiPHYLayerProtocol GetWifiPHYLayerProtocol() { + return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN; +} + } // namespace net diff --git a/net/base/net_util_win.cc b/net/base/net_util_win.cc index 5b101ae..62eabcc 100644 --- a/net/base/net_util_win.cc +++ b/net/base/net_util_win.cc @@ -5,16 +5,19 @@ #include "net/base/net_util.h" #include <iphlpapi.h> +#include <wlanapi.h> #include <algorithm> #include "base/file_path.h" +#include "base/lazy_instance.h" #include "base/memory/scoped_ptr.h" #include "base/string_piece.h" #include "base/string_util.h" #include "base/sys_string_conversions.h" #include "base/threading/thread_restrictions.h" #include "base/utf_string_conversions.h" +#include "base/win/scoped_handle.h" #include "googleurl/src/gurl.h" #include "net/base/escape.h" #include "net/base/ip_endpoint.h" @@ -127,4 +130,139 @@ bool GetNetworkList(NetworkInterfaceList* networks) { return true; } +WifiPHYLayerProtocol GetWifiPHYLayerProtocol() { + struct WlanApi { + typedef DWORD (WINAPI *WlanOpenHandleFunc)( + DWORD, VOID*, DWORD*, HANDLE*); + typedef DWORD (WINAPI *WlanEnumInterfacesFunc)( + HANDLE, VOID*, WLAN_INTERFACE_INFO_LIST **); + typedef DWORD (WINAPI *WlanQueryInterfaceFunc)( + HANDLE, const GUID *, WLAN_INTF_OPCODE, VOID*, DWORD*, VOID**, + WLAN_OPCODE_VALUE_TYPE*); + typedef VOID (WINAPI *WlanFreeMemoryFunc)(VOID*); + typedef DWORD (WINAPI *WlanCloseHandleFunc)(HANDLE, VOID*); + + WlanApi() : initialized(false) { + // Use an absolute path to load the DLL to avoid DLL preloading attacks. + static const wchar_t* const kDLL = L"%WINDIR%\\system32\\wlanapi.dll"; + wchar_t path[MAX_PATH] = {0}; + ExpandEnvironmentStrings(kDLL, path, arraysize(path)); + module = ::LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); + if (!module) + return; + + open_handle_func = reinterpret_cast<WlanOpenHandleFunc>( + ::GetProcAddress(module, "WlanOpenHandle")); + enum_interfaces_func = reinterpret_cast<WlanEnumInterfacesFunc>( + ::GetProcAddress(module, "WlanEnumInterfaces")); + query_interface_func = reinterpret_cast<WlanQueryInterfaceFunc>( + ::GetProcAddress(module, "WlanQueryInterface")); + free_memory_func = reinterpret_cast<WlanFreeMemoryFunc>( + ::GetProcAddress(module, "WlanFreeMemory")); + close_handle_func = reinterpret_cast<WlanCloseHandleFunc>( + ::GetProcAddress(module, "WlanCloseHandle")); + initialized = open_handle_func && enum_interfaces_func && + query_interface_func && free_memory_func && + close_handle_func; + } + + HMODULE module; + WlanOpenHandleFunc open_handle_func; + WlanEnumInterfacesFunc enum_interfaces_func; + WlanQueryInterfaceFunc query_interface_func; + WlanFreeMemoryFunc free_memory_func; + WlanCloseHandleFunc close_handle_func; + bool initialized; + }; + + static base::LazyInstance<WlanApi>::Leaky lazy_wlanapi = + LAZY_INSTANCE_INITIALIZER; + + struct WlanApiHandleTraits { + typedef HANDLE Handle; + + static bool CloseHandle(HANDLE handle) { + return lazy_wlanapi.Get().close_handle_func(handle, NULL) == + ERROR_SUCCESS; + } + static bool IsHandleValid(HANDLE handle) { + return base::win::HandleTraits::IsHandleValid(handle); + } + static HANDLE NullHandle() { + return base::win::HandleTraits::NullHandle(); + } + }; + + typedef base::win::GenericScopedHandle<WlanApiHandleTraits, + base::win::VerifierTraits> WlanHandle; + + struct WlanApiDeleter { + inline void operator()(void* ptr) const { + lazy_wlanapi.Get().free_memory_func(ptr); + } + }; + + const WlanApi& wlanapi = lazy_wlanapi.Get(); + if (!wlanapi.initialized) + return WIFI_PHY_LAYER_PROTOCOL_NONE; + + WlanHandle client; + DWORD cur_version = 0; + const DWORD kMaxClientVersion = 2; + DWORD result = wlanapi.open_handle_func(kMaxClientVersion, NULL, &cur_version, + client.Receive()); + if (result != ERROR_SUCCESS) + return WIFI_PHY_LAYER_PROTOCOL_NONE; + + WLAN_INTERFACE_INFO_LIST* interface_list_ptr = NULL; + result = wlanapi.enum_interfaces_func(client, NULL, &interface_list_ptr); + if (result != ERROR_SUCCESS) + return WIFI_PHY_LAYER_PROTOCOL_NONE; + scoped_ptr<WLAN_INTERFACE_INFO_LIST, WlanApiDeleter> interface_list( + interface_list_ptr); + + // Assume at most one connected wifi interface. + WLAN_INTERFACE_INFO* info = NULL; + for (unsigned i = 0; i < interface_list->dwNumberOfItems; ++i) { + if (interface_list->InterfaceInfo[i].isState == + wlan_interface_state_connected) { + info = &interface_list->InterfaceInfo[i]; + break; + } + } + + if (info == NULL) + return WIFI_PHY_LAYER_PROTOCOL_NONE; + + WLAN_CONNECTION_ATTRIBUTES* conn_info_ptr; + DWORD conn_info_size = 0; + WLAN_OPCODE_VALUE_TYPE op_code; + result = wlanapi.query_interface_func( + client, &info->InterfaceGuid, wlan_intf_opcode_current_connection, NULL, + &conn_info_size, reinterpret_cast<VOID**>(&conn_info_ptr), &op_code); + if (result != ERROR_SUCCESS) + return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN; + scoped_ptr<WLAN_CONNECTION_ATTRIBUTES, WlanApiDeleter> conn_info( + conn_info_ptr); + + switch (conn_info->wlanAssociationAttributes.dot11PhyType) { + case dot11_phy_type_fhss: + return WIFI_PHY_LAYER_PROTOCOL_ANCIENT; + case dot11_phy_type_dsss: + return WIFI_PHY_LAYER_PROTOCOL_B; + case dot11_phy_type_irbaseband: + return WIFI_PHY_LAYER_PROTOCOL_ANCIENT; + case dot11_phy_type_ofdm: + return WIFI_PHY_LAYER_PROTOCOL_A; + case dot11_phy_type_hrdsss: + return WIFI_PHY_LAYER_PROTOCOL_B; + case dot11_phy_type_erp: + return WIFI_PHY_LAYER_PROTOCOL_G; + case dot11_phy_type_ht: + return WIFI_PHY_LAYER_PROTOCOL_N; + default: + return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN; + } +} + } // namespace net |