summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorallanwoj@chromium.org <allanwoj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-24 14:17:34 +0000
committerallanwoj@chromium.org <allanwoj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-24 14:17:34 +0000
commit899fbcf0206bc07548cc1a4e9f33745571977961 (patch)
tree15eb523e544cd103ab998c443c1cb0f903d1fc18
parentd1eb9488278abb41cdea240162aec3daae50cecd (diff)
downloadchromium_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.cc4
-rw-r--r--chrome/browser/geolocation/gateway_data_provider_win.cc116
-rw-r--r--chrome/browser/geolocation/gateway_data_provider_win.h24
-rw-r--r--chrome/browser/geolocation/network_location_provider.cc2
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/common/chrome_switches.cc3
-rw-r--r--chrome/common/chrome_switches.h1
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[];