tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

FreeBsdWifiScanner.cpp (4160B)


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