[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