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.
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.
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.
class airctl { HANDLE m_handle; deviceInfo* m_devices; public: airctl(void); // Frees the list of wlans void freeScanList(void); //scans for wlan and returns pointer to the list. NDIS_802_11_BSSID_LIST* scan(void); bool open( char *device_name); //lists all devices and saves them in an internal list. BOOL list_devices( void); // return the pointer to the list inline deviceInfo* getDevList( ){return m_devices;}; public: ~airctl(void); private: // adds one device to the list void AddDevice(char * desc, char * name); // clears the intern list void clearDeviceList(void); NDIS_802_11_BSSID_LIST* m_pBSSIDList; // intern used to get more informations about an interface BOOL get_device_info( int Index, char *key_name, char *device_info, char *device_description); };
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 };Look at the following piece of code. It is from the demo program.
//return me the pointer to the list deviceInfo* dv = win->m_airctl.getDevList(); if (dv == NULL) { List.AddString("No available interface found !"); }else{ while (dv != NULL)//step through the linked list { List.AddString(dv->description);// adds it to the list. dv = dv->next; } }
After the user selects a device, it will be opened.
To open the device with the aitctl
class we only need to call open()
with the device name in it.
if(m_airctl.open(dv->name)!= true) { MessageBox("Cant open selected device","fehler",0); }else { ::AfxBeginThread( threadFunc , (LPVOID) this); }
But we are curious and will take a small look into that function.
//we open the physical device with CreateFileA m_handle = CreateFileA( device_file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,// share // mode NULL, // default security attributes OPEN_EXISTING,// disposition 0,// file attributes NULL) ;// do not copy file attributes if( m_handle == INVALID_HANDLE_VALUE) { return false; } else { // ... open return true; }
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:
oidcode = OID_802_11_BSSID_LIST_SCAN ;//action to perform DeviceIoControl( m_handle, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oidcode, sizeof( oidcode), ( ULONG *) NULL, 0, &bytesreturned, NULL) ; Sleep( 2000) ;// we give him some time memset( m_pBSSIDList, 0, sizeof( NDIS_802_11_BSSID_LIST) * NUMBEROF_BSSIDS) ; oidcode = OID_802_11_BSSID_LIST ;//action to perform if( DeviceIoControl( m_handle,// device to be queried IOCTL_NDIS_QUERY_GLOBAL_STATS,// operation to // perform &oidcode, sizeof( oidcode),// input buffer ( ULONG *) m_pBSSIDList,// output buffer sizeof( NDIS_802_11_BSSID_LIST) * NUMBEROF_BSSIDS, &bytesreturned,// # bytes returned NULL) == 0)// synchronous I/O { // List failed return NULL; } else { return m_pBSSIDList; }
Now we have a pointer to the NDIS_802_11_BSSID_LIST
take a look in ntddndis.h where it's defined.
typedef struct _NDIS_802_11_BSSID_LIST { ULONG NumberOfItems; // in list below, at least 1 NDIS_WLAN_BSSID Bssid[1]; }
So far so good, but what does NDIS_WLAN_BSSID
look like?
typedef struct _NDIS_WLAN_BSSID { ULONG Length; // Length of this // structure NDIS_802_11_MAC_ADDRESS MacAddress; // BSSID UCHAR Reserved[2]; NDIS_802_11_SSID Ssid; // SSID ULONG Privacy; // WEP encryption // requirement NDIS_802_11_RSSI Rssi; // receive signal // strength in dBm NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; NDIS_802_11_CONFIGURATION Configuration; NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; NDIS_802_11_RATES SupportedRates; } NDIS_WLAN_BSSID, *PNDIS_WLAN_BSSID;
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(unsigned int 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.
You can perform a lot of more functions to the WLAN device. Just take a look into ntddndis.h under 802.11 OIDs.
First release version 0.1
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.
A list of licenses authors might use can be found here
Comments and Discussions
You must Sign In to use this message board.
FAQ
Noise Tolerance Very HighHighMediumLowVery Low Layout NormalExpand Posts onlyExpand Posts & RepliesThread ViewNo JavascriptNo JS + Preview Per page 102550
Msgs 20 to 31 of 31 (Total in Forum: 31) (Refresh) FirstPrevNext
Regarding OID_802_11_BSSID_LIST_SCAN raptor_funky 21:44 9 Mar '08
Found this article while surfing Codeproject. A small pointer regarding OID_802_11_BSSID_LIST_SCAN. If you check out the NDIS 5.1 design guide for 802.11, it states that this particular OID only supports Setting and Not Querying. The IOCTL_NDIS_QUERY_GLOBAL_STATS can just be used with DeviceIoControl to Query the Miniport driver (as can be done for OID_802_11_BSSID_LIST). There is not equivalent IOCTL to do a Set. Therefore eventhough the DeviceIoControl call returns success, with OID_802_11_BSSID_LIST_SCAN, it does not actually trigger an Explicit scan. You can verify this by checking for Probe Requests on a particular channel.
On Windows CE, the NDISUIO can be used to implement this functionality.
Do put up a post if anyone finds another way to do this.
Sign In·View Thread·PermaLink 4.50/5 (3 votes)
Re: Regarding OID_802_11_BSSID_LIST_SCAN Malcolm Hall 4:10 27 Mar '08
I'd really like to know how to do a OID_802_11_BSSID_LIST_SCAN via Ndis instead of through Ndisuio because Ndisuio requires you to bind to the driver and only one application can do it at once.
Is there any kind of IOCTL_NDIS_SET method perhaps?
Sign In·View Thread·PermaLink
Re: Regarding OID_802_11_BSSID_LIST_SCAN Malcolm Hall 4:13 27 Mar '08
Found more info here:
http://www.ndis.com/faq/QA10290101.htm#IOCTL_NDIS_QUERY_GLOBAL_STATISTICS
The IOCTL is predefined to use METHOD_OUT_DIRECT; this means that only the NDIS miniport QueryInformation handler can be called this way.
(With some creativity METHOD_OUT_DIRECT could be used to set NDIS data...)
Does anyone know what the creativity required is?
Sign In·View Thread·PermaLink
Re: Regarding OID_802_11_BSSID_LIST_SCAN Malcolm Hall 4:52 27 Mar '08
I think you need to modify the driver to get this to work. e.g.
If you have access to the source, you can define and then call a private Oid in MiniportQueryInformation, and in the driver you can call MiniportSetInformation.
http://www.experts-exchange.com/Networking/Windows_Networking/NT/Q_10002798.html
DeviceIOControl is a wrapper around MiniportQueryInformation.
Sign In·View Thread·PermaLink
Re: Regarding OID_802_11_BSSID_LIST_SCAN amitalonm 7:35 4 Oct '09
Hi there,
Did you find any answer to this question ?
Especially, please have a look at my open issues that I have in my respond few lines above (also in this link):
WLAN Scan with NDIS Miniport and Much More[^]
Thanks.
Sign In·View Thread·PermaLink
Re: Regarding OID_802_11_BSSID_LIST_SCAN fibers 22:47 17 Dec '09
I got the error code 31 which means "A device attached to the system is not functioning" in DeviceIoControl with OID LIST SCAN.
do you think this question matters with your point?
Sign In·View Thread·PermaLink
What about Windows CE? Win32nipuh 21:47 5 Nov '07
Great!
I have one question:
Is it possible to have the same utility (or classes) for using under Windows CE?
I'd like to integrate these features to my application.
Thank you.
Regards
Sign In·View Thread·PermaLink 3.00/5 (3 votes)
Scan IPs rrrado 3:09 30 Oct '07
It would be great if it would be able also to sniff packets to see IP addresses
--------------------------------------------------------------------------------
rrrado
Sign In·View Thread·PermaLink 2.00/5 (1 vote)
Re: Scan IPs sirb 22:36 5 Nov '07
well my friend. this is only possible if you are connected to the accesspoint. i have seen a pice of code that did it with the same technic. than it can be handled like a normal device. you can obtain the data via rawsocket or winpcap.
if you dont want to connect you need monitor mode. this is not so easy in windows. you need a patched driver.there are drivers available for orinoco und atheros. look into the airodump-ng for windows. there you will find everythink you need. but it the traffic is encypted you wont be able to get the data without the key
Sign In·View Thread·PermaLink
Re: Scan IPs rrrado 23:28 5 Nov '07
I have atheros, but capturing does not work in ethereal. It is working in one shareware program (I'm at different computer so I don't know it's name now, it has it's own driver) but it's not so important to me to purchase it so I'm looking for free alternative.
I don't need to capture encrypted trafic, there are some unencrypted providers
--------------------------------------------------------------------------------
rrrado
Sign In·View Thread·PermaLink 2.00/5 (1 vote)
Re: Scan IPs sirb 23:51 5 Nov '07
hi
ok.. well , i think i know the programm you are talking about, but i also fogot the name .mh well i hope the programm intalled the patched driver so try aircrack-ng for windows. if airodump-ng works, look into the source code. its freely available. if it wont work try to search the pachted driver on the internet and make ist work. i am not sure but i think i have seen them there. atheros421.zip or somethink like that.well i know this is not a great help.. but thats what i would do
or connect to the wlan and then you will be able to get all packets with etheral.
Sign In·View Thread·PermaLink
Re: Scan IPs rrrado 5:20 6 Nov '07
Thank you for information, I'll check it when I'll have a time.
As far as I remember ethereal doesn't capture anything even when I'm connected. BUt I'm not 100% sure, maybe it helps to turn off promiscous mode.
--------------------------------------------------------------------------------
rrrado
Sign In·View Thread·PermaLink 2.00/5 (1 vote)