diff options
author | allanwoj@chromium.org <allanwoj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-24 14:17:34 +0000 |
---|---|---|
committer | allanwoj@chromium.org <allanwoj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-24 14:17:34 +0000 |
commit | 899fbcf0206bc07548cc1a4e9f33745571977961 (patch) | |
tree | 15eb523e544cd103ab998c443c1cb0f903d1fc18 | |
parent | d1eb9488278abb41cdea240162aec3daae50cecd (diff) | |
download | chromium_src-899fbcf0206bc07548cc1a4e9f33745571977961.zip chromium_src-899fbcf0206bc07548cc1a4e9f33745571977961.tar.gz chromium_src-899fbcf0206bc07548cc1a4e9f33745571977961.tar.bz2 |
Windows Gateway Data Provider.
Provides the MAC address of any routers connected via Ethernet. Also added in a command line flag to enable it.
BUG=None
TEST=None
Review URL: http://codereview.chromium.org/3368014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@60463 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/geolocation/empty_device_data_provider.cc | 4 | ||||
-rw-r--r-- | chrome/browser/geolocation/gateway_data_provider_win.cc | 116 | ||||
-rw-r--r-- | chrome/browser/geolocation/gateway_data_provider_win.h | 24 | ||||
-rw-r--r-- | chrome/browser/geolocation/network_location_provider.cc | 2 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | chrome/common/chrome_switches.cc | 3 | ||||
-rw-r--r-- | chrome/common/chrome_switches.h | 1 |
7 files changed, 150 insertions, 2 deletions
diff --git a/chrome/browser/geolocation/empty_device_data_provider.cc b/chrome/browser/geolocation/empty_device_data_provider.cc index 7a7cbe0..b11dd79 100644 --- a/chrome/browser/geolocation/empty_device_data_provider.cc +++ b/chrome/browser/geolocation/empty_device_data_provider.cc @@ -20,9 +20,11 @@ WifiDataProviderImplBase* WifiDataProvider::DefaultFactoryFunction() { } #endif -// No platform has a gateway data provider yet. +// Only define for platforms that lack a real gateway data provider. +#if !defined(OS_WIN) // static template<> GatewayDataProviderImplBase* GatewayDataProvider::DefaultFactoryFunction() { return new EmptyDeviceDataProvider<GatewayData>(); } +#endif diff --git a/chrome/browser/geolocation/gateway_data_provider_win.cc b/chrome/browser/geolocation/gateway_data_provider_win.cc new file mode 100644 index 0000000..acc3b02 --- /dev/null +++ b/chrome/browser/geolocation/gateway_data_provider_win.cc @@ -0,0 +1,116 @@ +// Copyright (c) 2010 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. + +#include "chrome/browser/geolocation/gateway_data_provider_win.h" + +#include <iphlpapi.h> +#include <winsock2.h> + +#include <set> + +#include "base/command_line.h" +#include "base/utf_string_conversions.h" +#include "chrome/browser/geolocation/empty_device_data_provider.h" +#include "chrome/common/chrome_switches.h" + +namespace { + +string16 MacAsString16(const uint8 mac_as_int[6]) { + // mac_as_int is big-endian. Write in byte chunks. + // Format is XX-XX-XX-XX-XX-XX. + static const wchar_t* const kMacFormatString = + L"%02x-%02x-%02x-%02x-%02x-%02x"; + return WideToUTF16(StringPrintf(kMacFormatString, + mac_as_int[0], mac_as_int[1], + mac_as_int[2], mac_as_int[3], + mac_as_int[4], mac_as_int[5])); +} + +void FetchGatewayIps(std::set<IPAddr>* gateway_ips) { + ULONG out_buf_len = 0; + if (GetAdaptersInfo(NULL, &out_buf_len) != ERROR_BUFFER_OVERFLOW) + return; + scoped_ptr_malloc<IP_ADAPTER_INFO> adapter_list( + static_cast<IP_ADAPTER_INFO*>(malloc(out_buf_len))); + if (adapter_list == NULL) + return; + if (GetAdaptersInfo(adapter_list.get(), &out_buf_len) == NO_ERROR) { + for (const IP_ADAPTER_INFO* adapter = adapter_list.get(); adapter != NULL; + adapter = adapter->Next) { + if (adapter->Type == IF_TYPE_ETHERNET_CSMACD) { + // If we have multiple gateways with conflicting IPs we'll disregard + // the duplicates. + for (const IP_ADDR_STRING* gw = &adapter->GatewayList; + gw != NULL; gw = gw->Next) + gateway_ips->insert(inet_addr(gw->IpAddress.String)); + } + } + } +} + +// Sends an ARP request to determine the MAC address of the destination. +bool GetMacFromIp(IPAddr dest_ip, ULONG* mac_addr, size_t mac_addr_size) { + memset(mac_addr, 0xff, mac_addr_size); + DWORD arp_result = 0; + ULONG phys_addr_len = 6; + IPAddr src_ip = 0; + arp_result = SendARP(dest_ip, src_ip, mac_addr, &phys_addr_len); + return arp_result == NO_ERROR && phys_addr_len == 6; +} + +} // namespace + +class WinGatewayApi : public GatewayDataProviderCommon::GatewayApiInterface { + public: + WinGatewayApi(); + virtual ~WinGatewayApi(); + + // GatewayApiInterface + virtual bool GetRouterData(GatewayData::RouterDataSet* data); +}; + +GatewayDataProviderCommon::GatewayApiInterface* +WinGatewayDataProvider::NewGatewayApi() { + return new WinGatewayApi(); +} + +WinGatewayApi::WinGatewayApi() { +} + +WinGatewayApi::~WinGatewayApi() { +} + +bool WinGatewayApi::GetRouterData(GatewayData::RouterDataSet* data) { + std::set<IPAddr> gateway_ips; + FetchGatewayIps(&gateway_ips); + if (gateway_ips.empty()) + return false; + const size_t kMacAddrLength = 2; + for (std::set<IPAddr>::const_iterator gateway_it = + gateway_ips.begin(); gateway_it != gateway_ips.end(); ++gateway_it) { + IPAddr adapter_gateway_ip = *gateway_it; + ULONG mac_addr[kMacAddrLength]; + if (GetMacFromIp(adapter_gateway_ip, mac_addr, sizeof(mac_addr))) { + RouterData router; + uint8* phys_addr = reinterpret_cast<uint8*>(&mac_addr); + router.mac_address = MacAsString16(phys_addr); + data->insert(router); + } + } + return true; +} + +WinGatewayDataProvider::WinGatewayDataProvider() { +} + +WinGatewayDataProvider::~WinGatewayDataProvider() { +} + +template<> +GatewayDataProviderImplBase* GatewayDataProvider::DefaultFactoryFunction() { + if (!CommandLine::ForCurrentProcess() + ->HasSwitch(switches::kExperimentalLocationFeatures)) + return new EmptyDeviceDataProvider<GatewayData>(); + return new WinGatewayDataProvider(); +} diff --git a/chrome/browser/geolocation/gateway_data_provider_win.h b/chrome/browser/geolocation/gateway_data_provider_win.h new file mode 100644 index 0000000..265b524 --- /dev/null +++ b/chrome/browser/geolocation/gateway_data_provider_win.h @@ -0,0 +1,24 @@ +// Copyright (c) 2010 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 CHROME_BROWSER_GEOLOCATION_GATEWAY_DATA_PROVIDER_WIN_H_ +#define CHROME_BROWSER_GEOLOCATION_GATEWAY_DATA_PROVIDER_WIN_H_ +#pragma once + +#include "chrome/browser/geolocation/gateway_data_provider_common.h" + +class WinGatewayDataProvider : public GatewayDataProviderCommon { + public: + WinGatewayDataProvider(); + + private: + virtual ~WinGatewayDataProvider(); + + // GatewayDataProviderCommon + virtual GatewayApiInterface* NewGatewayApi(); + + DISALLOW_COPY_AND_ASSIGN(WinGatewayDataProvider); +}; + +#endif //CHROME_BROWSER_GEOLOCATION_GATEWAY_DATA_PROVIDER_WIN_H_ diff --git a/chrome/browser/geolocation/network_location_provider.cc b/chrome/browser/geolocation/network_location_provider.cc index f90cc9f..1f77fbc 100644 --- a/chrome/browser/geolocation/network_location_provider.cc +++ b/chrome/browser/geolocation/network_location_provider.cc @@ -321,7 +321,7 @@ void NetworkLocationProvider::OnDeviceDataUpdated() { } bool NetworkLocationProvider::IsStarted() const { - DCHECK_EQ(!!gateway_data_provider_, !!radio_data_provider_); + DCHECK_EQ(!!gateway_data_provider_, !!wifi_data_provider_); DCHECK_EQ(!!radio_data_provider_, !!wifi_data_provider_); return wifi_data_provider_ != NULL; } diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index b564fe4..f21eae4 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1572,6 +1572,8 @@ 'browser/geolocation/empty_device_data_provider.h', 'browser/geolocation/gateway_data_provider_common.cc', 'browser/geolocation/gateway_data_provider_common.h', + 'browser/geolocation/gateway_data_provider_win.cc', + 'browser/geolocation/gateway_data_provider_win.h', 'browser/geolocation/geolocation_dispatcher_host.cc', 'browser/geolocation/geolocation_dispatcher_host.h', 'browser/geolocation/geolocation_permission_context.cc', diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 1db5e90..f93210c 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -556,6 +556,9 @@ const char kEnableWin7Location[] = "enable-win7-location"; // Disable WebKit's XSSAuditor. The XSSAuditor mitigates reflective XSS. const char kEnableXSSAuditor[] = "enable-xss-auditor"; +// Enables experimental features for the geolocation API. +const char kExperimentalLocationFeatures[] = "experimental-location-features"; + // Enables experimental features for Spellchecker. Right now, the first // experimental feature is auto spell correct, which corrects words which are // misppelled by typing the word with two consecutive letters swapped. The diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 59bb88f..f6c1c27 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -171,6 +171,7 @@ extern const char kEnableWatchdog[]; extern const char kEnableWin7Location[]; extern const char kEnableXSSAuditor[]; // Experimental features. +extern const char kExperimentalLocationFeatures[]; extern const char kExperimentalSpellcheckerFeatures[]; // End experimental features. extern const char kExplicitlyAllowedPorts[]; |