| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "content/browser/geolocation/gateway_data_provider_win.h" | |
| 6 | |
| 7 #include <iphlpapi.h> | |
| 8 #include <winsock2.h> | |
| 9 | |
| 10 #include <set> | |
| 11 | |
| 12 #include "base/command_line.h" | |
| 13 #include "base/utf_string_conversions.h" | |
| 14 #include "chrome/common/chrome_switches.h" | |
| 15 #include "content/browser/geolocation/empty_device_data_provider.h" | |
| 16 | |
| 17 namespace { | |
| 18 | |
| 19 string16 MacAsString16(const uint8 mac_as_int[6]) { | |
| 20 // mac_as_int is big-endian. Write in byte chunks. | |
| 21 // Format is XX-XX-XX-XX-XX-XX. | |
| 22 static const wchar_t* const kMacFormatString = | |
| 23 L"%02x-%02x-%02x-%02x-%02x-%02x"; | |
| 24 return WideToUTF16(StringPrintf(kMacFormatString, | |
| 25 mac_as_int[0], mac_as_int[1], | |
| 26 mac_as_int[2], mac_as_int[3], | |
| 27 mac_as_int[4], mac_as_int[5])); | |
| 28 } | |
| 29 | |
| 30 void FetchGatewayIps(std::set<IPAddr>* gateway_ips) { | |
| 31 ULONG out_buf_len = 0; | |
| 32 if (GetAdaptersInfo(NULL, &out_buf_len) != ERROR_BUFFER_OVERFLOW) | |
| 33 return; | |
| 34 scoped_ptr_malloc<IP_ADAPTER_INFO> adapter_list( | |
| 35 static_cast<IP_ADAPTER_INFO*>(malloc(out_buf_len))); | |
| 36 if (adapter_list == NULL) | |
| 37 return; | |
| 38 if (GetAdaptersInfo(adapter_list.get(), &out_buf_len) == NO_ERROR) { | |
| 39 for (const IP_ADAPTER_INFO* adapter = adapter_list.get(); adapter != NULL; | |
| 40 adapter = adapter->Next) { | |
| 41 if (adapter->Type == IF_TYPE_ETHERNET_CSMACD) { | |
| 42 // If we have multiple gateways with conflicting IPs we'll disregard | |
| 43 // the duplicates. | |
| 44 for (const IP_ADDR_STRING* gw = &adapter->GatewayList; | |
| 45 gw != NULL; gw = gw->Next) | |
| 46 gateway_ips->insert(inet_addr(gw->IpAddress.String)); | |
| 47 } | |
| 48 } | |
| 49 } | |
| 50 } | |
| 51 | |
| 52 // Sends an ARP request to determine the MAC address of the destination. | |
| 53 bool GetMacFromIp(IPAddr dest_ip, ULONG* mac_addr, size_t mac_addr_size) { | |
| 54 memset(mac_addr, 0xff, mac_addr_size); | |
| 55 DWORD arp_result = 0; | |
| 56 ULONG phys_addr_len = 6; | |
| 57 IPAddr src_ip = 0; | |
| 58 arp_result = SendARP(dest_ip, src_ip, mac_addr, &phys_addr_len); | |
| 59 return arp_result == NO_ERROR && phys_addr_len == 6; | |
| 60 } | |
| 61 | |
| 62 } // namespace | |
| 63 | |
| 64 class WinGatewayApi : public GatewayDataProviderCommon::GatewayApiInterface { | |
| 65 public: | |
| 66 WinGatewayApi(); | |
| 67 virtual ~WinGatewayApi(); | |
| 68 | |
| 69 // GatewayApiInterface | |
| 70 virtual bool GetRouterData(GatewayData::RouterDataSet* data); | |
| 71 }; | |
| 72 | |
| 73 GatewayDataProviderCommon::GatewayApiInterface* | |
| 74 WinGatewayDataProvider::NewGatewayApi() { | |
| 75 return new WinGatewayApi(); | |
| 76 } | |
| 77 | |
| 78 WinGatewayApi::WinGatewayApi() { | |
| 79 } | |
| 80 | |
| 81 WinGatewayApi::~WinGatewayApi() { | |
| 82 } | |
| 83 | |
| 84 bool WinGatewayApi::GetRouterData(GatewayData::RouterDataSet* data) { | |
| 85 std::set<IPAddr> gateway_ips; | |
| 86 FetchGatewayIps(&gateway_ips); | |
| 87 if (gateway_ips.empty()) | |
| 88 return false; | |
| 89 const size_t kMacAddrLength = 2; | |
| 90 for (std::set<IPAddr>::const_iterator gateway_it = | |
| 91 gateway_ips.begin(); gateway_it != gateway_ips.end(); ++gateway_it) { | |
| 92 IPAddr adapter_gateway_ip = *gateway_it; | |
| 93 ULONG mac_addr[kMacAddrLength]; | |
| 94 if (GetMacFromIp(adapter_gateway_ip, mac_addr, sizeof(mac_addr))) { | |
| 95 RouterData router; | |
| 96 uint8* phys_addr = reinterpret_cast<uint8*>(&mac_addr); | |
| 97 router.mac_address = MacAsString16(phys_addr); | |
| 98 data->insert(router); | |
| 99 } | |
| 100 } | |
| 101 return true; | |
| 102 } | |
| 103 | |
| 104 WinGatewayDataProvider::WinGatewayDataProvider() { | |
| 105 } | |
| 106 | |
| 107 WinGatewayDataProvider::~WinGatewayDataProvider() { | |
| 108 } | |
| 109 | |
| 110 template<> | |
| 111 GatewayDataProviderImplBase* GatewayDataProvider::DefaultFactoryFunction() { | |
| 112 if (!CommandLine::ForCurrentProcess() | |
| 113 ->HasSwitch(switches::kExperimentalLocationFeatures)) | |
| 114 return new EmptyDeviceDataProvider<GatewayData>(); | |
| 115 return new WinGatewayDataProvider(); | |
| 116 } | |
| OLD | NEW |