summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/base/net_util.cc3
-rw-r--r--net/base/net_util.h22
-rw-r--r--net/base/net_util_posix.cc6
-rw-r--r--net/base/net_util_unittest.cc109
-rw-r--r--net/base/net_util_win.cc184
-rw-r--r--net/base/net_util_win.h85
6 files changed, 322 insertions, 87 deletions
diff --git a/net/base/net_util.cc b/net/base/net_util.cc
index 559f887..704add2 100644
--- a/net/base/net_util.cc
+++ b/net/base/net_util.cc
@@ -1040,4 +1040,7 @@ unsigned MaskPrefixLength(const IPAddressNumber& mask) {
return CommonPrefixLength(mask, all_ones);
}
+ScopedWifiOptions::~ScopedWifiOptions() {
+}
+
} // namespace net
diff --git a/net/base/net_util.h b/net/base/net_util.h
index 5999ad2..49780e8 100644
--- a/net/base/net_util.h
+++ b/net/base/net_util.h
@@ -518,6 +518,28 @@ enum WifiPHYLayerProtocol {
// Currently only available on OS_WIN.
NET_EXPORT WifiPHYLayerProtocol GetWifiPHYLayerProtocol();
+enum WifiOptions {
+ // Disables background SSID scans.
+ WIFI_OPTIONS_DISABLE_SCAN = 1 << 0,
+ // Enables media streaming mode.
+ WIFI_OPTIONS_MEDIA_STREAMING_MODE = 1 << 1
+};
+
+class NET_EXPORT ScopedWifiOptions {
+ public:
+ ScopedWifiOptions() {}
+ virtual ~ScopedWifiOptions();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ScopedWifiOptions);
+};
+
+// Set temporary options on all wifi interfaces.
+// |options| is an ORed bitfield of WifiOptions.
+// Options are automatically disabled when the scoped pointer
+// is freed. Currently only available on OS_WIN.
+NET_EXPORT scoped_ptr<ScopedWifiOptions> SetWifiOptions(int options);
+
// Returns number of matching initial bits between the addresses |a1| and |a2|.
unsigned CommonPrefixLength(const IPAddressNumber& a1,
const IPAddressNumber& a2);
diff --git a/net/base/net_util_posix.cc b/net/base/net_util_posix.cc
index 7f88ef6..73704cd 100644
--- a/net/base/net_util_posix.cc
+++ b/net/base/net_util_posix.cc
@@ -9,6 +9,7 @@
#include "base/files/file_path.h"
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
@@ -284,4 +285,9 @@ WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN;
}
+scoped_ptr<ScopedWifiOptions> SetWifiOptions(int options) {
+ return scoped_ptr<ScopedWifiOptions>();
+}
+
+
} // namespace net
diff --git a/net/base/net_util_unittest.cc b/net/base/net_util_unittest.cc
index 8306db5..3bb518f 100644
--- a/net/base/net_util_unittest.cc
+++ b/net/base/net_util_unittest.cc
@@ -24,6 +24,7 @@
#include <iphlpapi.h>
#include <objbase.h>
#include "base/win/windows_version.h"
+#include "net/base/net_util_win.h"
#elif !defined(OS_ANDROID)
#include <net/if.h>
#endif // OS_WIN
@@ -790,6 +791,114 @@ TEST(NetUtilTest, GetNetworkList) {
}
}
+namespace {
+
+#if defined(OS_WIN)
+bool read_int_or_bool(DWORD data_size,
+ PVOID data) {
+ switch (data_size) {
+ case 1:
+ return !!*reinterpret_cast<uint8*>(data);
+ case 4:
+ return !!*reinterpret_cast<uint32*>(data);
+ default:
+ LOG(FATAL) << "That is not a type I know!";
+ return false;
+ }
+}
+
+int GetWifiOptions() {
+ const internal::WlanApi& wlanapi = internal::WlanApi::GetInstance();
+ if (!wlanapi.initialized)
+ return -1;
+
+ internal::WlanHandle client;
+ DWORD cur_version = 0;
+ const DWORD kMaxClientVersion = 2;
+ DWORD result = wlanapi.OpenHandle(
+ kMaxClientVersion, &cur_version, &client);
+ if (result != ERROR_SUCCESS)
+ return -1;
+
+ WLAN_INTERFACE_INFO_LIST* interface_list_ptr = NULL;
+ result = wlanapi.enum_interfaces_func(client, NULL, &interface_list_ptr);
+ if (result != ERROR_SUCCESS)
+ return -1;
+ scoped_ptr<WLAN_INTERFACE_INFO_LIST, internal::WlanApiDeleter> interface_list(
+ interface_list_ptr);
+
+ for (unsigned i = 0; i < interface_list->dwNumberOfItems; ++i) {
+ WLAN_INTERFACE_INFO* info = &interface_list->InterfaceInfo[i];
+ DWORD data_size;
+ PVOID data;
+ int options = 0;
+ result = wlanapi.query_interface_func(
+ client,
+ &info->InterfaceGuid,
+ wlan_intf_opcode_background_scan_enabled,
+ NULL,
+ &data_size,
+ &data,
+ NULL);
+ if (result != ERROR_SUCCESS)
+ continue;
+ if (!read_int_or_bool(data_size, data)) {
+ options |= WIFI_OPTIONS_DISABLE_SCAN;
+ }
+ internal::WlanApi::GetInstance().free_memory_func(data);
+
+ result = wlanapi.query_interface_func(
+ client,
+ &info->InterfaceGuid,
+ wlan_intf_opcode_media_streaming_mode,
+ NULL,
+ &data_size,
+ &data,
+ NULL);
+ if (result != ERROR_SUCCESS)
+ continue;
+ if (read_int_or_bool(data_size, data)) {
+ options |= WIFI_OPTIONS_MEDIA_STREAMING_MODE;
+ }
+ internal::WlanApi::GetInstance().free_memory_func(data);
+
+ // Just the the options from the first succesful
+ // interface.
+ return options;
+ }
+
+ // No wifi interface found.
+ return -1;
+}
+
+#else // OS_WIN
+
+int GetWifiOptions() {
+ // Not supported.
+ return -1;
+}
+
+#endif // OS_WIN
+
+void TryChangeWifiOptions(int options) {
+ int previous_options = GetWifiOptions();
+ scoped_ptr<ScopedWifiOptions> scoped_options = SetWifiOptions(options);
+ EXPECT_EQ(previous_options | options, GetWifiOptions());
+ scoped_options.reset();
+ EXPECT_EQ(previous_options, GetWifiOptions());
+}
+
+}; // namespace
+
+// Test SetWifiOptions().
+TEST(NetUtilTest, SetWifiOptionsTest) {
+ TryChangeWifiOptions(0);
+ TryChangeWifiOptions(WIFI_OPTIONS_DISABLE_SCAN);
+ TryChangeWifiOptions(WIFI_OPTIONS_MEDIA_STREAMING_MODE);
+ TryChangeWifiOptions(WIFI_OPTIONS_DISABLE_SCAN |
+ WIFI_OPTIONS_MEDIA_STREAMING_MODE);
+}
+
struct NonUniqueNameTestData {
bool is_unique;
const char* hostname;
diff --git a/net/base/net_util_win.cc b/net/base/net_util_win.cc
index 6f331ec..4f59d6d 100644
--- a/net/base/net_util_win.cc
+++ b/net/base/net_util_win.cc
@@ -22,67 +22,13 @@
#include "net/base/escape.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
+#include "net/base/net_util_win.h"
#include "url/gurl.h"
namespace net {
namespace {
-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;
- }
-
- template <typename T>
- DWORD OpenHandle(DWORD client_version, DWORD* cur_version, T* handle) const {
- HANDLE temp_handle;
- DWORD result = open_handle_func(client_version, NULL, cur_version,
- &temp_handle);
- if (result != ERROR_SUCCESS)
- return result;
- handle->Set(temp_handle);
- return ERROR_SUCCESS;
- }
-
- HMODULE module;
- WlanOpenHandleFunc open_handle_func;
- WlanEnumInterfacesFunc enum_interfaces_func;
- WlanQueryInterfaceFunc query_interface_func;
- WlanFreeMemoryFunc free_memory_func;
- WlanCloseHandleFunc close_handle_func;
- bool initialized;
-};
-
// Converts Windows defined types to NetworkInterfaceType.
NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(DWORD ifType) {
// Bail out for pre-Vista versions of Windows which are documented to give
@@ -104,6 +50,43 @@ NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(DWORD ifType) {
} // namespace
+namespace internal {
+
+base::LazyInstance<WlanApi>::Leaky lazy_wlanapi =
+ LAZY_INSTANCE_INITIALIZER;
+
+WlanApi& WlanApi::GetInstance() {
+ return lazy_wlanapi.Get();
+}
+
+WlanApi::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"));
+ set_interface_func = reinterpret_cast<WlanSetInterfaceFunc>(
+ ::GetProcAddress(module, "WlanSetInterface"));
+ 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 && set_interface_func &&
+ free_memory_func && close_handle_func;
+}
+
+} // namespace internal
+
bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
// GetAdaptersAddresses() may require IO operations.
base::ThreadRestrictions::AssertIOAllowed();
@@ -221,39 +204,11 @@ bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
}
WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
- 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::DummyVerifierTraits> WlanHandle;
-
- struct WlanApiDeleter {
- inline void operator()(void* ptr) const {
- lazy_wlanapi.Get().free_memory_func(ptr);
- }
- };
-
- const WlanApi& wlanapi = lazy_wlanapi.Get();
+ const internal::WlanApi& wlanapi = internal::WlanApi::GetInstance();
if (!wlanapi.initialized)
return WIFI_PHY_LAYER_PROTOCOL_NONE;
- WlanHandle client;
+ internal::WlanHandle client;
DWORD cur_version = 0;
const DWORD kMaxClientVersion = 2;
DWORD result = wlanapi.OpenHandle(kMaxClientVersion, &cur_version, &client);
@@ -264,7 +219,7 @@ WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
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(
+ scoped_ptr<WLAN_INTERFACE_INFO_LIST, internal::WlanApiDeleter> interface_list(
interface_list_ptr);
// Assume at most one connected wifi interface.
@@ -288,7 +243,7 @@ WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
&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(
+ scoped_ptr<WLAN_CONNECTION_ATTRIBUTES, internal::WlanApiDeleter> conn_info(
conn_info_ptr);
switch (conn_info->wlanAssociationAttributes.dot11PhyType) {
@@ -311,4 +266,59 @@ WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
}
}
+// Note: There is no need to explicitly set the options back
+// as the OS will automatically set them back when the WlanHandle
+// is closed.
+class WifiOptionSetter : public ScopedWifiOptions {
+ public:
+ WifiOptionSetter(int options) {
+ const internal::WlanApi& wlanapi = internal::WlanApi::GetInstance();
+ if (!wlanapi.initialized)
+ return;
+
+ DWORD cur_version = 0;
+ const DWORD kMaxClientVersion = 2;
+ DWORD result = wlanapi.OpenHandle(
+ kMaxClientVersion, &cur_version, &client_);
+ if (result != ERROR_SUCCESS)
+ return;
+
+ WLAN_INTERFACE_INFO_LIST* interface_list_ptr = NULL;
+ result = wlanapi.enum_interfaces_func(client_, NULL, &interface_list_ptr);
+ if (result != ERROR_SUCCESS)
+ return;
+ scoped_ptr<WLAN_INTERFACE_INFO_LIST, internal::WlanApiDeleter>
+ interface_list(interface_list_ptr);
+
+ for (unsigned i = 0; i < interface_list->dwNumberOfItems; ++i) {
+ WLAN_INTERFACE_INFO* info = &interface_list->InterfaceInfo[i];
+ if (options & WIFI_OPTIONS_DISABLE_SCAN) {
+ BOOL data = false;
+ wlanapi.set_interface_func(client_,
+ &info->InterfaceGuid,
+ wlan_intf_opcode_background_scan_enabled,
+ sizeof(data),
+ &data,
+ NULL);
+ }
+ if (options & WIFI_OPTIONS_MEDIA_STREAMING_MODE) {
+ BOOL data = true;
+ wlanapi.set_interface_func(client_,
+ &info->InterfaceGuid,
+ wlan_intf_opcode_media_streaming_mode,
+ sizeof(data),
+ &data,
+ NULL);
+ }
+ }
+ }
+
+ private:
+ internal::WlanHandle client_;
+};
+
+scoped_ptr<ScopedWifiOptions> SetWifiOptions(int options) {
+ return scoped_ptr<ScopedWifiOptions>(new WifiOptionSetter(options));
+}
+
} // namespace net
diff --git a/net/base/net_util_win.h b/net/base/net_util_win.h
new file mode 100644
index 0000000..afa888b
--- /dev/null
+++ b/net/base/net_util_win.h
@@ -0,0 +1,85 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_BASE_NET_UTIL_WIN_H_
+#define NET_BASE_NET_UTIL_WIN_H_
+
+// This file is only used to expose some of the internals
+// of net_util_win.cc to tests.
+
+#include <wlanapi.h>
+
+#include "base/win/scoped_handle.h"
+#include "net/base/net_export.h"
+
+namespace net {
+namespace internal {
+
+struct NET_EXPORT 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 DWORD (WINAPI *WlanSetInterfaceFunc)(
+ HANDLE, const GUID*, WLAN_INTF_OPCODE, DWORD, const VOID*, VOID*);
+ typedef VOID (WINAPI *WlanFreeMemoryFunc)(VOID*);
+ typedef DWORD (WINAPI *WlanCloseHandleFunc)(HANDLE, VOID*);
+
+ WlanApi();
+ static WlanApi& GetInstance();
+
+ template <typename T>
+ DWORD OpenHandle(DWORD client_version, DWORD* cur_version, T* handle) const {
+ HANDLE temp_handle;
+ DWORD result = open_handle_func(client_version, NULL, cur_version,
+ &temp_handle);
+ if (result != ERROR_SUCCESS)
+ return result;
+ handle->Set(temp_handle);
+ return ERROR_SUCCESS;
+ }
+
+ HMODULE module;
+ WlanOpenHandleFunc open_handle_func;
+ WlanEnumInterfacesFunc enum_interfaces_func;
+ WlanQueryInterfaceFunc query_interface_func;
+ WlanSetInterfaceFunc set_interface_func;
+ WlanFreeMemoryFunc free_memory_func;
+ WlanCloseHandleFunc close_handle_func;
+ bool initialized;
+};
+
+struct WlanApiHandleTraits {
+ typedef HANDLE Handle;
+
+ static bool CloseHandle(HANDLE handle) {
+ return WlanApi::GetInstance().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::DummyVerifierTraits> WlanHandle;
+
+struct WlanApiDeleter {
+ inline void operator()(void* ptr) const {
+ WlanApi::GetInstance().free_memory_func(ptr);
+ }
+};
+
+} // namespace internal
+
+} // namespace net
+
+#endif // NET_BASE_NET_UTIL_WIN_H_