[BAT] NetStumbler AP Scanning Methods Revealed

h1kari
Mon, 19 Nov 2001 12:56:06 -0800


--- Open Source NetStumbler-like Scanning ---


-- Introduction --
After a couple days of hacking, I've managed to figure out exactly how 
NetStumbler does it's ap scanning and partially why Marius is probably 
reluctant to let people take a look at his code. All of this information is 
normally proprietary so I'm hoping that distributing this will help encourage 
other developers to add these methods to their codebase so people in *nix can 
enjoy the same features as those in windows.


-- Scanning with Wavelan Cards
First of all. It uses a proprietary feature of the proprietary hcf library 
provided by lucent/agere to scan for aps (so pretty much no one knows how 
exactly it's done.. up until now). A similar interface is also provided in 
some of the closed source wavelan drivers for linux, but I haven't been able 
to find anything that's fully open source. This isn't documented in any 
freely available documents or specs and I had to somewhat reverse engineer 
the card's interfaces to figure this out. Here is basically how you use 
scanning mode with the card (for anyone that's working on open source wavelan 
drivers out there).

First you need to send a "scan request" to the card which is usually done by 
something similar to sending an inquire command (0x11) to the card with 
(0xF101) as the parameter. This tells the card to send out probe requests and 
store information about APs it finds.

This method is handled asynchronously, so when the card has results it sends 
an event to the interrupt handler in the driver (same handler that takes care 
of other buffer reads such as rx, tx, etc). The event is labeled as an info 
event (0x0080). Now, info events are sent in a standard ltv structure 
consisting of length, code, and a data buffer, so you will want to look for 
ltvs with the code being (0xF101) (look familiar?). These ltvs will contain 
an array of structures that contain ap information that resemble something 
like this:

struct wi_scan_res {
  u_int16_t  wi_chan;  /* dss channel */
  u_int16_t  wi_noise;  /* average noise in the air */
  u_int16_t  wi_signal;  /* signal strength */
  u_int16_t  wi_bssid[6];  /* mac address of the ap */
  u_int16_t  wi_interval;  /* beacon transmit interval */
  u_int16_t  wi_capinfo;  /* capability information (bits: 0-ess, 1-ibss, 
4-privacy [wep]) */
  u_int16_t  wi_ssid_len;  /* ssid length */
  u_int16_t  wi_ssid[32];  /* ssid (ap name) */
};

Which should give you all the information you need to create a 
netstumbler-like application fully open source. Additionally, for anyone that 
wants to do this with a prism2 card, here's how you can do it.


-- Scanning with Prism2 Cards
I personally think Prism2 has a better implementation than wavelan. It's much 
cleaner and easier to implement. Here's how you can use it:

First you have to send a "scan request" to the card. You can do this using 
the normal rid configuration interface by setting the scan request rid 
(0xFCE1) with information on how you want the card to scan. Just supply the 
information in the ltv struct's data buffer using a structure similar to:

struct wi_p2_scan_req {
  u_int16_t  wi_chans;  /* channels to scan (bits: 0-chan 1, 1-chan 2, etc) */
  u_int16_t  wi_rates;  /* rate to send the probe requests at (bits: 0-1mbit, 
1-2mbit, 2-5.5mbit, 3-11mbit) */
};

Once you've set the scan request, you have to wait about half a second for 
the card to be ready for you to request the results. To grab the results of 
the scan, just read from the scan result rid (0xFD88) for the result buffer. 
The result buffer is a little bit different from the wavelan one in that it 
has an extra header as well as extra information about the rates that the ap 
supports. Here's what the frames look like:

struct wi_scan_res_hdr {
  u_int16_t  wi_rsvd;  /* reserved for something in the future (i think) */
  u_int16_t  wi_reason;  /* reason for the response (0 - error, 1 - response 
to a request from the host) */
};

Then it's followed by an array of response frames similar to the ones used 
with wavelan cards:

struct wi_scan_res {
  u_int16_t  wi_chan;  /* dss channel */
  u_int16_t  wi_noise;  /* average noise in the air */
  u_int16_t  wi_signal;  /* signal strength */
  u_int16_t  wi_bssid[6];  /* mac address of the ap */
  u_int16_t  wi_interval;  /* beacon transmit interval */
  u_int16_t  wi_capinfo;  /* capability information (bits: 0-ess, 1-ibss, 
4-privacy [wep]) */
  u_int16_t  wi_ssid_len;  /* ssid length */
  u_int16_t  wi_ssid[32];  /* ssid (ap name) */
  u_int8_t  wi_srates[10];  /* list of rates the ap supports, null terminated 
 (you'll need to get rid of the last bit (& 0x7F) and divide by 2) */
  u_int8_t  wi_rate;  /* rate that the probe response was recieved at (0x0a - 
1mbit, 0x14 - 2mbit, 0x37 - 5.5mbit, 0x6e - 11mbit) */
  u_int8_t  wi_rsvd;  /* extra padding so it fits nicely into a 16-bit buffer 
*/
};

This should provide the same info as the wavelan struct and more, making 
prism2 compatible NetStumbler-like applications more than possible.


-- Ending Notes --
I've managed to successfully implement both of these methods into the next 
release of bsd-airtools kernel patches as well as support in dstumbler making 
it have the exact same functionality as NetStumbler (+ prism2 support). The 
next airtools release will also have some extra features added to 
wicontrol/wiconfig to list access points in the area:

# wicontrol wi0 -A
NIC serial number:              [ .......
.....
Available APs:
    foobar   [ 00:04:e2:0e:b7:cb ]  [ 10 ]  [ 51 104 53 ]  100  [ ess ]
              [ 1.0 2.0 5.5 11.0 ]  * 1.0 *
    nss       [ 00:04:5a:0e:49:50 ]  [ 9  ]  [ 52 106 54 ]  100  [ ess priv ]
              [ 1.0 2.0 5.5 11.0 ]  * 1.0 *

If you have any questions regarding implementing this with other open source 
drivers, please feel free to email me or post to the BAT mailing list.
http://lists.dachb0den.com/mailman/listinfo/bat/


-h1kari