Introduction

I spent some time with WLAN, and I wondered how NetStumbler performed this nice scan, but the source is not free. I programmed a lot of stuff but nothing worked. I tried to code my own driver and used WinPcap, but nothing worked very well. Then I read an article, "Scanning for Wireless Networks" in 29A magazine 8 from GriYo. My work is mainly based on this article and you can find a lot of sources on the internet that do the same thing.

Background

It's possible via NDIS Miniport (from userspace) to access a lot of functions of the WLANcard. To get access to all these nice functions you need the Windows DDK.

Take a look at ntddndis.h and you will find a lot of actions you can perform. For example, you can get or set the WEP key. I only implemeted the scanning function, but you can improve it. To build your own application, you can take my article class or write our own.

Using the Code

Well, I put a lot of comments in the code so you will be able to understand it easily. All the functions you need are in the airctl class. Take a look at the header file.

First we need a list of all devices. Call list_devices() and it will list everything in an single linked list. Then the demo program shows the user a list of all available devices. The structure for the list is as follows.

struct deviceInfo
{
char *description;//information for the user
char *name;// important to open the device
deviceInfo* next;//single linked list
};

Now it's time to search the WLANs. We will call scan() from the aitctl class.

NDIS_802_11_BSSID_LIST * pBSSIDList = pDlg->m_airctl.scan();

How is this performed? It's done via DeviceIoControl. This is for direct input and output, or for retrieving information from a physical device. For more infomration read this article. It's a really nice series of articles.

First we force the WLAN device to scan for WLANs; we wait for a moment and then we ask the device again to tell us an answer. The source code for this looks like this:

This looks much better. This is the information we would like to obtain. Now we can show them to the user.

But, we have one thing left to discuss: how to get the next item. For this we will use another pointer which points to NDIS_WLAN_BSSID. Now the variable ULONG Length tells us how long this entry is. After this a certain number of bytes the next entry "lies."

Well, the following is not a good solution, but it shows you what I mean and what it could look like.

//NumberOfItems indecates how many are now in the list
for(unsignedint i =0 ;i < pBSSIDList->NumberOfItems;i++){
int temp=i;//used to build the differens
//step to the next in list...
PNDIS_WLAN_BSSID cpSsid=pBSSIDList->Bssid;//save
//if we aren't in the first loop we have to set the pointer
//to the next
while(temp!=0 ){
// go forward
cpSsid=(PNDIS_WLAN_BSSID)((char*)cpSsid+ cpSsid->Length);
temp--;
}
//do something with your data
}

That's it man. Thank you for reading, now it's up to you.

Points of Interest

You can perform a lot of more functions to the WLAN device. Just take a look into ntddndis.h under 802.11 OIDs.

History

First release version 0.1

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

I think when this code use DeviceIoControl the driver which manages wlan card is receiving some packages, raw data, and extracting the ssid bssid and other info that all AP are retransmiting, so the driver can handle with this raw data.

The driver makes all the hard work to you, but if you want to deal with the raw data that your wlan card receives you might edit this driver (NDIS Miniport).

Thanks for the sample code. It was exactly what I was looking for on a project I'm working on.

I have found two bugs however:1. The list box on your adapter dialog has the "sort" property set. This means the order the items are displayed in the dropdown doesn't match the order in your list of devices. You select one device in the dropdown and the program tries to connect to another.

2. In the function NDIS_802_11_BSSID_LIST* airctl::scan(void) you need to add this line: oidcode |= 0x00800000; to turn the command to a set.

About Bug # 1 - the ordered list - i also found this bug and fixed it using the properties of the list - I deleted the sort checkbox of it.

About bug # 2:Can you please give me any reference to the information that brought you to the conclusion of this bug being there ?Where did you get the 0x00800000 value from ?Where did you see that it was required ?I get the same results with and without this line in the code.

Currently my problems are:1. I am not sure if scan is being done, at least not if the Wireless Network Interface Card (NIC) performs ACTIVE scan (rather then PASSIVE scan, which may be done in the background).I do not have a sniffer to see if probe requests are being sent out as a result of the scan request.

2. My even worse problem is that the wireless card returns also OLD scan results, i.e. it returns also SSIDs of APs that are no longer on air.For example, an AP that was turned off is still being "read" by the wireless NIC after the AP's power was taken off, and this goes on for several minutes.

I do not understand how to clear the old scanned data from the Wireless NIC before each new scan is performed.