Jump to content

WlanGetNetworkBssList enumerate entries


Andreik
 Share

Go to solution Solved by TheXman,

Recommended Posts

I am a little bit confused about MSDN documentation regarding how you should enumerate entries from WLAN_BSS_LIST. After the call of WlanGetNetworkBssList I get the pointer to WLAN_BSS_LIST which contains an array of WLAN_BSS_ENTRY structures. Now things get weird. WLAN_BSS_LIST have two members dwTotalSize and dwNumberOfItems followed by the array of WLAN_BSS_ENTRY structures. Usually dwNumberOfItems=1 but dwTotalSize is quite variable which is not necessarily strange since there padding might be needed but the strange part is that dwTotalSize is around 700 bytes when I expect to be around 351 bytes for each WLAN_BSS_ENTRY structure + 8 more bytes (dwTotalSize, dwNumberOfItems). If I have more than one item how do I find where the next WLAN_BSS_ENTRY structure starts? Looks like there is something more data in each WLAN_BSS_ENTRY...

Quote

typedef struct _WLAN_BSS_LIST {
  DWORD          dwTotalSize;                // 4
  DWORD          dwNumberOfItems;            // 4
  WLAN_BSS_ENTRY wlanBssEntries[1];            // 351 * dwNumberOfItems
} WLAN_BSS_LIST, *PWLAN_BSS_LIST;

typedef struct _WLAN_BSS_ENTRY {
  DOT11_SSID        dot11Ssid;            // 4 + 32 = 36
  ULONG             uPhyId;                // 4
  DOT11_MAC_ADDRESS dot11Bssid;            // 6
  DOT11_BSS_TYPE    dot11BssType;            // 4
  DOT11_PHY_TYPE    dot11BssPhyType;        // 4
  LONG              lRssi;                // 4
  ULONG             uLinkQuality;            // 4
  BOOLEAN           bInRegDomain;            // 1
  USHORT            usBeaconPeriod;            // 2
  ULONGLONG         ullTimestamp;            // 8
  ULONGLONG         ullHostTimestamp;        // 8
  USHORT            usCapabilityInformation;    // 2
  ULONG             ulChCenterFrequency;        // 4
  WLAN_RATE_SET     wlanRateSet;            // 4 + (2 * 126) = 256
  ULONG             ulIeOffset;            // 4
  ULONG             ulIeSize;                // 4
} WLAN_BSS_ENTRY, *PWLAN_BSS_ENTRY;

My results

Quote

dwTotalSize, dwNumberOfItems

704, 1
696, 1
624, 1
1632, 2
696, 1
704, 1

 

Some sample code for testing:

$hWlanapi = DllOpen('Wlanapi.dll')

$aRet = DllCall($hWlanapi, 'dword', 'WlanOpenHandle', 'dword', 2, 'ptr', Null, 'dword*', Null, 'ptr*', Null)
If $aRet[0] = 0 Then
    $hWlan = $aRet[4]
Else
    ConsoleWrite('WlanOpenHandle error' & @CRLF)
    Exit
EndIf

$aRet = DllCall($hWlanapi, 'dword', 'WlanEnumInterfaces', 'handle', $hWlan, 'ptr', Null, 'ptr*', Null)
If $aRet[0] = 0 Then
    $tWLAN_INTERFACE_INFO_LIST = DllStructCreate('dword dwNumberOfItems; dword dwIndex', $aRet[3])
    $dwNumberOfItems = DllStructGetData($tWLAN_INTERFACE_INFO_LIST, 'dwNumberOfItems')
    If $dwNumberOfItems > 0 Then
        $tGUID = DllStructCreate('byte GUID[16]', $aRet[3] + 8) ; Get GUID of first Wlan interface
        ConsoleWrite('Interface: ' & DllStructGetData(DllStructCreate('wchar strInterfaceDescription[256]', $aRet[3] + 24), 'strInterfaceDescription') & @CRLF)
    Else
        ConsoleWrite('WlanEnumInterfaces error' & @CRLF)
        Exit
    EndIf
EndIf

$aRet = DllCall($hWlanapi, 'dword', 'WlanGetAvailableNetworkList', 'handle', $hWlan, 'struct*', $tGUID, 'dword', 0, 'ptr', Null, 'ptr*', Null)
If $aRet[0] = 0 Then
    $tWLAN_AVAILABLE_NETWORK_LIST = DllStructCreate('dword dwNumberOfItems; dword dwIndex', $aRet[5])
    $dwNumberOfItems = DllStructGetData($tWLAN_AVAILABLE_NETWORK_LIST, 'dwNumberOfItems')
    $tWLAN_AVAILABLE_NETWORK = DllStructCreate('wchar strProfileName[256];ulong uSSIDLength; char ucSSID[32]; dword DOT11_BSS_TYPE; ulong uNumberOfBssids; bool bNetworkConnectable; dword wlanNotConnectableReason;' & _
            'ulong uNumberOfPhyTypes; dword dot11PhyTypes[8]; bool bMorePhyTypes; ulong wlanSignalQuality; bool bSecurityEnabled; dword dot11DefaultAuthAlgorithm; dword dot11DefaultCipherAlgorithm; dword dwFlags; ' & _
            'dword dwReserved', $aRet[5] + 8)   ; Get first available network
    ConsoleWrite('Network SSID: ' & DllStructGetData($tWLAN_AVAILABLE_NETWORK, 'ucSSID') & @CRLF)
Else
    ConsoleWrite('WlanGetAvailableNetworkList error' & @CRLF)
    Exit
EndIf

$tDot11Ssid = DllStructCreate('ulong uSSIDLength; char ucSSID[32]', DllStructGetPtr($tWLAN_AVAILABLE_NETWORK) + 512)
$BSSType = DllStructGetData($tWLAN_AVAILABLE_NETWORK, 'DOT11_BSS_TYPE')
$SecurityEnable = DllStructGetData($tWLAN_AVAILABLE_NETWORK, 'bSecurityEnabled')
$aRet = DllCall($hWlanapi, 'dword', 'WlanGetNetworkBssList', 'handle', $hWlan, 'struct*', $tGUID, 'struct*', $tDot11Ssid, 'dword', $BSSType, 'bool', $SecurityEnable, 'ptr', Null, 'ptr*', Null)
If $aRet[0] = 0 Then
    Local $tWLAN_BSS_LIST = DllStructCreate('dword dwTotalSize; dword dwNumberOfItems', $aRet[7])
    Local $dwNumberOfItems = DllStructGetData($tWLAN_BSS_LIST, 'dwNumberOfItems')
    Local $dwTotalSize = DllStructGetData($tWLAN_BSS_LIST, 'dwTotalSize')
    ConsoleWrite('dwTotalSize: ' & $dwTotalSize & ', dwNumberOfItems: ' & $dwNumberOfItems & @CRLF)
Else
    ConsoleWrite('WlanGetNetworkBssList error' & @CRLF)
    Exit
EndIf

DllCall($hWlanapi, 'dword', 'WlanCloseHandle', 'handle', $hWlan, 'ptr', Null)
DllClose($hWlanapi)

 

Edited by Andreik

When the words fail... music speaks.

Link to comment
Share on other sites

1 hour ago, Andreik said:

how do I find where the next LAN_BSS_ENTRY structure starts? Looks like there is something more data in each WLAN_BSS_ENTRY...

 

 

LAN_BSS_ENTRY structure Are Static Structure's According to MSDN documentation,Else if you want you want to create your own Structure's.

iam ِAutoit programmer.

best thing in life is to use your Brain to

Achieve

everything you want.

Link to comment
Share on other sites

 you say's how do I find where the next WLAN_BSS_ENTRY structure starts you mean pointer???

the strange part is that dwTotalSize is around 700 bytes........when I expect to be around 351 bytes for each WLAN_BSS_ENTRY

$aRet[5] + 636) 
$aRet[5] + 635)

between [635]|[636]:

635 = 635;;first network
-7 = 635 + 635 - 7;;;;2.. network
-7*2 = 635+ 635 + 635 - 14;;;3.. network
-7*3 = 635+ 635 + 635 + 635 - 21;;;4.. network

636 = 636;;first network
-8 = 636 + 636 - 8;;;;2.. network
-8*2 = 636+ 636 + 636 - 16;;;3.. network
-8*3 = 636+ 636 + 636 + 636 - 24;;;4.. network

 

 

Edited by ad777

iam ِAutoit programmer.

best thing in life is to use your Brain to

Achieve

everything you want.

Link to comment
Share on other sites

I tried to follow the raw bytes of WLAN_BSS_LIST and I manage to obtain the size of WLAN_BSS_ENTRY as 360 Bytes but I am not sure if this calculation is consistent.

image.thumb.png.8c54ff49ee110b25b028cafbe5da626a.png

The only way I can see to get the size of an entry is to read the ulIeOffset of the first entry(720) [assuming that first IE data blob starts right after the end of the last entry] and then divide by dwNumberOfItems(2).

Edited by Andreik

When the words fail... music speaks.

Link to comment
Share on other sites

  • Solution
1 hour ago, Andreik said:

I tried to follow the raw bytes of WLAN_BSS_LIST and I manage to obtain the size of WLAN_BSS_ENTRY as 360 Bytes

You are correct that the size of a WLAN_BSS_ENTRY is 360 bytes.  However, your parsing of the information is off for a couple of reasons:

  1. You are not properly taking into account the alignment bytes within the structure.
  2. There is a difference between BOOL and BOOLEAN.  BOOL is 4 bytes and BOOLEAN is one.

If you run the script below, it will display the structure (including the alignment bytes or padding as you call it).  The displaying of the structure should help you correctly parse your data.  Looking at the image you posted, I think my definition of the structures are correct.

Of course if you use the _WinAPI_DisplayStruct() function in your script, with valid BSS ENTRY data , it should show you your correctly parsed data.

 

#include <WinAPIDiag.au3>

Global $gtag_DOT11_SSID = _
    "struct;" & _
    "ulong uSSIDLength;" & _
    "byte  ucSSID[32];" & _
    "endstruct;"

Global $gtag_WLAN_RATE_SET = _
    "struct;" & _
    "ulong  uRateSetLength;" & _
    "ushort usRateSet[126];" & _
    "endstruct;"

Global $gtag_WLAN_BSS_ENTRY = _
    "struct;" & _
    $gtag_DOT11_SSID & _
    "ulong     uPhyId;" & _
    "byte      dot11Bssid[6];" & _
    "int       dot11BssType;" & _
    "int       dot11BssPhyType;" & _
    "long      lRssi;" & _
    "ulong     uLinkQuality;" & _
    "boolean   bInRegDomain;" & _
    "ushort    usBeaconPeriod;" & _
    "uint64    ullTimestamp;" & _
    "uint64    ullHostTimestamp;" & _
    "ushort    usCapabilityInformation;" & _
    "ulong     ulChCenterFrequency;" & _
    $gtag_WLAN_RATE_SET & _
    "ulong     ulIeOffset;" & _
    "ulong     ulIeSize;" & _
    "endstruct;"

;Create an empty WLAN_BSS_ENTRY and display it
Global $t_WLAN_BSS_ENTRY = DllStructCreate($gtag_WLAN_BSS_ENTRY)
_WinAPI_DisplayStruct($t_WLAN_BSS_ENTRY, $gtag_WLAN_BSS_ENTRY, "WLAN_BSS_ENTRY")

Partial Struct Display

image.png.2153fd6c80d3130a7a6891911d6bd136.png

image.png.d18e2c910419713a5c9c3c685886ceb4.png

 

 

Edited by TheXman
Link to comment
Share on other sites

I know BOOL BOOLEAN is only one byte and I thought it might have one more byte as padding but I couldn't figure out the 6 bytes later in the structure also used as padding. Now it makes sense. Many thanks.

Edited by Andreik

When the words fail... music speaks.

Link to comment
Share on other sites

1 minute ago, Andreik said:

I know BOOL is only one byte

I'm sure you meant to say that you know BOOLEAN is one byte.  😉

2 minutes ago, Andreik said:

Many thanks.

You're welcome!  :thumbsup:

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...