netwerk/wifi/nsWifiScannerFreeBSD.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 // Developed by J.R. Oldroyd <fbsd@opal.com>, December 2012.
michael@0 6
michael@0 7 // For FreeBSD we use the getifaddrs(3) to obtain the list of interfaces
michael@0 8 // and then check for those with an 802.11 media type and able to return
michael@0 9 // a list of stations. This is similar to ifconfig(8).
michael@0 10
michael@0 11 #include <sys/types.h>
michael@0 12 #include <sys/ioctl.h>
michael@0 13 #include <sys/socket.h>
michael@0 14 #include <net/if.h>
michael@0 15 #include <net/if_media.h>
michael@0 16 #include <net80211/ieee80211_ioctl.h>
michael@0 17
michael@0 18 #include <ifaddrs.h>
michael@0 19 #include <string.h>
michael@0 20 #include <unistd.h>
michael@0 21
michael@0 22 #include "nsWifiAccessPoint.h"
michael@0 23
michael@0 24 using namespace mozilla;
michael@0 25
michael@0 26 static nsresult
michael@0 27 FreeBSDGetAccessPointData(nsCOMArray<nsWifiAccessPoint> &accessPoints)
michael@0 28 {
michael@0 29 // get list of interfaces
michael@0 30 struct ifaddrs *ifal;
michael@0 31 if (getifaddrs(&ifal) < 0) {
michael@0 32 return NS_ERROR_FAILURE;
michael@0 33 }
michael@0 34
michael@0 35 accessPoints.Clear();
michael@0 36
michael@0 37 // loop through the interfaces
michael@0 38 nsresult rv = NS_ERROR_FAILURE;
michael@0 39 struct ifaddrs *ifa;
michael@0 40 for (ifa = ifal; ifa; ifa = ifa->ifa_next) {
michael@0 41 // limit to one interface per address
michael@0 42 if (ifa->ifa_addr->sa_family != AF_LINK) {
michael@0 43 continue;
michael@0 44 }
michael@0 45
michael@0 46 // store interface name in socket structure
michael@0 47 struct ifreq ifr;
michael@0 48 memset(&ifr, 0, sizeof(ifr));
michael@0 49 strncpy(ifr.ifr_name, ifa->ifa_name, sizeof(ifr.ifr_name));
michael@0 50 ifr.ifr_addr.sa_family = AF_LOCAL;
michael@0 51
michael@0 52 // open socket to interface
michael@0 53 int s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0);
michael@0 54 if (s < 0) {
michael@0 55 continue;
michael@0 56 }
michael@0 57
michael@0 58 // clear interface media structure
michael@0 59 struct ifmediareq ifmr;
michael@0 60 memset(&ifmr, 0, sizeof(ifmr));
michael@0 61 strncpy(ifmr.ifm_name, ifa->ifa_name, sizeof(ifmr.ifm_name));
michael@0 62
michael@0 63 // get interface media information
michael@0 64 if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
michael@0 65 close(s);
michael@0 66 continue;
michael@0 67 }
michael@0 68
michael@0 69 // check interface is a WiFi interface
michael@0 70 if (IFM_TYPE(ifmr.ifm_active) != IFM_IEEE80211) {
michael@0 71 close(s);
michael@0 72 continue;
michael@0 73 }
michael@0 74
michael@0 75 // perform WiFi scan
michael@0 76 struct ieee80211req i802r;
michael@0 77 char iscanbuf[32*1024];
michael@0 78 memset(&i802r, 0, sizeof(i802r));
michael@0 79 strncpy(i802r.i_name, ifa->ifa_name, sizeof(i802r.i_name));
michael@0 80 i802r.i_type = IEEE80211_IOC_SCAN_RESULTS;
michael@0 81 i802r.i_data = iscanbuf;
michael@0 82 i802r.i_len = sizeof(iscanbuf);
michael@0 83 if (ioctl(s, SIOCG80211, &i802r) < 0) {
michael@0 84 close(s);
michael@0 85 continue;
michael@0 86 }
michael@0 87
michael@0 88 // close socket
michael@0 89 close(s);
michael@0 90
michael@0 91 // loop through WiFi networks and build geoloc-lookup structure
michael@0 92 char *vsr = (char *) i802r.i_data;
michael@0 93 unsigned len = i802r.i_len;
michael@0 94 while (len >= sizeof(struct ieee80211req_scan_result)) {
michael@0 95 struct ieee80211req_scan_result *isr =
michael@0 96 (struct ieee80211req_scan_result *) vsr;
michael@0 97
michael@0 98 // determine size of this entry
michael@0 99 char *id;
michael@0 100 int idlen;
michael@0 101 if (isr->isr_meshid_len) {
michael@0 102 id = vsr + isr->isr_ie_off + isr->isr_ssid_len;
michael@0 103 idlen = isr->isr_meshid_len;
michael@0 104 } else {
michael@0 105 id = vsr + isr->isr_ie_off;
michael@0 106 idlen = isr->isr_ssid_len;
michael@0 107 }
michael@0 108
michael@0 109 // copy network data
michael@0 110 char ssid[IEEE80211_NWID_LEN+1];
michael@0 111 strncpy(ssid, id, idlen);
michael@0 112 ssid[idlen] = '\0';
michael@0 113 nsWifiAccessPoint *ap = new nsWifiAccessPoint();
michael@0 114 ap->setSSID(ssid, strlen(ssid));
michael@0 115 ap->setMac(isr->isr_bssid);
michael@0 116 ap->setSignal(isr->isr_rssi);
michael@0 117 accessPoints.AppendObject(ap);
michael@0 118 rv = NS_OK;
michael@0 119
michael@0 120 // log the data
michael@0 121 LOG(( "FreeBSD access point: "
michael@0 122 "SSID: %s, MAC: %02x-%02x-%02x-%02x-%02x-%02x, "
michael@0 123 "Strength: %d, Channel: %dMHz\n",
michael@0 124 ssid, isr->isr_bssid[0], isr->isr_bssid[1], isr->isr_bssid[2],
michael@0 125 isr->isr_bssid[3], isr->isr_bssid[4], isr->isr_bssid[5],
michael@0 126 isr->isr_rssi, isr->isr_freq));
michael@0 127
michael@0 128 // increment pointers
michael@0 129 len -= isr->isr_len;
michael@0 130 vsr += isr->isr_len;
michael@0 131 }
michael@0 132 }
michael@0 133
michael@0 134 freeifaddrs(ifal);
michael@0 135
michael@0 136 return rv;
michael@0 137 }
michael@0 138
michael@0 139 nsresult
michael@0 140 nsWifiMonitor::DoScan()
michael@0 141 {
michael@0 142 // Regularly get the access point data.
michael@0 143
michael@0 144 nsCOMArray<nsWifiAccessPoint> lastAccessPoints;
michael@0 145 nsCOMArray<nsWifiAccessPoint> accessPoints;
michael@0 146
michael@0 147 do {
michael@0 148 nsresult rv = FreeBSDGetAccessPointData(accessPoints);
michael@0 149 if (NS_FAILED(rv))
michael@0 150 return rv;
michael@0 151
michael@0 152 bool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints);
michael@0 153 ReplaceArray(lastAccessPoints, accessPoints);
michael@0 154
michael@0 155 rv = CallWifiListeners(lastAccessPoints, accessPointsChanged);
michael@0 156 NS_ENSURE_SUCCESS(rv, rv);
michael@0 157
michael@0 158 // wait for some reasonable amount of time. pref?
michael@0 159 LOG(("waiting on monitor\n"));
michael@0 160
michael@0 161 ReentrantMonitorAutoEnter mon(mReentrantMonitor);
michael@0 162 mon.Wait(PR_SecondsToInterval(60));
michael@0 163 }
michael@0 164 while (mKeepGoing);
michael@0 165
michael@0 166 return NS_OK;
michael@0 167 }

mercurial