3 --- chrome/browser/geolocation/gateway_data_provider_bsd.cc.orig 2011-04-26 05:17:13.000000000 +0000
4 +++ chrome/browser/geolocation/gateway_data_provider_bsd.cc
6 +// Copyright (c) 2010 The Chromium Authors. All rights reserved.
7 +// Use of this source code is governed by a BSD-style license that can be
8 +// found in the LICENSE file.
10 +// Provides MAC addresses of connected routers by using the /proc/net/
11 +// directory which contains files with network information.
12 +// This directory is used in most BSD based operating systems.
14 +#include "chrome/browser/geolocation/gateway_data_provider_bsd.h"
16 +#include <sys/types.h>
17 +#include <sys/param.h>
18 +#include <sys/sysctl.h>
20 +#include <sys/time.h>
21 +#include <sys/socket.h>
23 +#include <net/if_dl.h>
24 +#include <net/route.h>
25 +#include <net/ethernet.h>
26 +#include <netinet/in.h>
27 +#include <netinet/if_ether.h>
28 +#include <arpa/inet.h>
38 +#include "base/command_line.h"
39 +#include "base/utf_string_conversions.h"
40 +#include "chrome/browser/geolocation/empty_device_data_provider.h"
41 +#include "chrome/browser/geolocation/gateway_data_provider_common.h"
42 +#include "chrome/common/chrome_switches.h"
45 +#define SA_SIZE(sa) \
46 + ((!(sa) || ((struct sockaddr *)(sa))->sa_len == 0) ? \
48 + 1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(long) - 1)))
53 +// TODO(joth): Cache the sets of gateways and MAC addresses to avoid reading
54 +// through the arp table when the routing table hasn't changed.
55 +class BSDGatewayApi : public GatewayDataProviderCommon::GatewayApiInterface {
58 + virtual ~BSDGatewayApi() {}
60 + static BSDGatewayApi* Create() {
61 + return new BSDGatewayApi();
64 + // GatewayApiInterface
65 + virtual bool GetRouterData(GatewayData::RouterDataSet* data);
68 + DISALLOW_COPY_AND_ASSIGN(BSDGatewayApi);
71 +bool GetGateways(std::set<std::string>* gateways) {
72 + struct rt_msghdr *rtm;
75 + char *buf, *next, *lim;
77 + struct sockaddr *dst;
78 + struct sockaddr_inarp *gw;
84 + mib[4] = NET_RT_DUMP;
87 + if (sysctl(mib, 6, NULL, &needed, NULL, 0) > 0)
90 + if ((buf = (char *)malloc(needed)) == 0)
93 + if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
97 + for (next = buf; next < lim; next += rtm->rtm_msglen) {
98 + rtm = (struct rt_msghdr *) next;
99 + if (!(rtm->rtm_flags & RTF_GATEWAY))
102 + dst = (struct sockaddr *)(rtm + 1);
103 + gw = (struct sockaddr_inarp *)(dst->sa_len + (char *)dst);
105 + gateways->insert(inet_ntoa(gw->sin_addr));
112 +// Gets a RouterDataSet containing MAC addresses related to any connected
113 +// routers. Returns false if we cannot read the arp file.
114 +// The /proc/net/arp file contains arp data in the following format
115 +// Note: "|" represents a delimeter.
116 +// IP address|HW type|Flags|HW address|Mask|Device
117 +// The delimiter for this table is " ".
118 +bool GetMacAddresses(GatewayData::RouterDataSet* data,
119 + std::set<std::string>* gateways) {
120 + struct rt_msghdr *rtm;
123 + char *buf, *next, *lim;
125 + struct sockaddr_inarp *sin;
126 + struct sockaddr_dl *sdl;
132 + mib[4] = NET_RT_FLAGS;
135 + if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
138 + if ((buf = (char *)malloc(needed)) == 0)
141 + if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
144 + lim = buf + needed;
145 + for (next = buf; next < lim; next += rtm->rtm_msglen) {
146 + rtm = (struct rt_msghdr *)next;
147 + sin = (struct sockaddr_inarp *)(rtm + 1);
149 + std::string ip_addr = inet_ntoa(sin->sin_addr);
150 + if (gateways->find(ip_addr) == gateways->end())
153 + sdl = (struct sockaddr_dl *)((char *)sin + SA_SIZE(sin));
154 + std::string mac_addr = ether_ntoa((struct ether_addr *)LLADDR(sdl));
156 + std::replace(mac_addr.begin(), mac_addr.end(), ':', '-');
158 + router.mac_address = UTF8ToUTF16(mac_addr);
159 + data->insert(router);
165 +bool BSDGatewayApi::GetRouterData(GatewayData::RouterDataSet* data) {
166 + std::set<std::string> gateways;
167 + if (!GetGateways(&gateways))
169 + if (gateways.empty())
171 + return GetMacAddresses(data, &gateways);
177 +GatewayDataProviderImplBase* GatewayDataProvider::DefaultFactoryFunction() {
178 + if (!CommandLine::ForCurrentProcess()
179 + ->HasSwitch(switches::kExperimentalLocationFeatures))
180 + return new EmptyDeviceDataProvider<GatewayData>();
181 + return new GatewayDataProviderBSD();
184 +GatewayDataProviderBSD::GatewayDataProviderBSD() {
187 +GatewayDataProviderBSD::~GatewayDataProviderBSD() {
190 +GatewayDataProviderCommon::GatewayApiInterface*
191 + GatewayDataProviderBSD::NewGatewayApi() {
192 + return BSDGatewayApi::Create();