• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 4896
  • Last Modified:

How to get other bss information from ndisuio?

Hello expert,

I meet a tricky problem to get the multiple AP's information detected by local 802.11 NIC.  When I prase the data which is returned from kernel, only the information of first AP is correct.  I miss the address of other AP.

The data sturctures defined in "Ntddndis.h" are here:

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;

typedef struct _NDIS_802_11_BSSID_LIST
{
    ULONG           NumberOfItems;      // in list below, at least 1
    NDIS_WLAN_BSSID Bssid[1];
} NDIS_802_11_BSSID_LIST, *PNDIS_802_11_BSSID_LIST;


The code to access NDIS_802_11_BSSID_LIST:

NDIS_STATUS            Dot11_GetAPList(
      HANDLE      handle,
      DOT11_BSS_LIST *pBssList )
{
      UCHAR                                    buf[4096];
      PNDISUIO_QUERY_OID                  pQueryOid;
      PNDISUIO_SET_OID                  pSetOid;
      PNDIS_802_11_BSSID_LIST            pBssid_List;
      ULONG                                    i = 0;
      int                                          j = 0;
      NDIS_STATUS                              status = S_OK;
      DWORD                                    dwBytesReturned = 0;
      DWORD                                    dwErrorCode = 0;
      int                                          bufSize;
      AP_DATA                                    *pTempApData = NULL;
      NDIS_WLAN_BSSID                  *pBssId = NULL;
      

      if (!pBssList )
      {
            status = E_POINTER;
      }

      else
      {
            pSetOid = (PNDISUIO_SET_OID) &buf[0];
            pSetOid->Oid = OID_802_11_BSSID_LIST_SCAN;
            
      
            if (!DeviceIoControl(
                              handle,
                              IOCTL_NDISUIO_SET_OID_VALUE,
                              (LPVOID) &buf[0],
                              sizeof(buf),                  // BUGBUG: ??
                              (LPVOID) &buf[0],
                              0,
                              &dwBytesReturned,
                              NULL))
            {
                  dwErrorCode = GetLastError();
                  DEBUGP(("IOCTL SET BSSID_LIST_SCAN failed: %d\n", dwErrorCode));
                  status = E_FAIL;
            }

            pQueryOid = (PNDISUIO_QUERY_OID) &buf[0];
            pQueryOid->Oid = OID_802_11_BSSID_LIST;

            if (DeviceIoControl(
                              handle,
                              IOCTL_NDISUIO_QUERY_OID_VALUE,
                              (LPVOID) &buf[0],
                              sizeof(buf),                  // BUGBUG: ??
                              (LPVOID) &buf[0],
                              sizeof(buf),
                              &dwBytesReturned,
                              NULL))
            {
                  DEBUGP(("IOCTL BSSID_LIST succeeded\n"));

                  pBssid_List = (PNDIS_802_11_BSSID_LIST)pQueryOid->Data;

                  pBssList->size = pBssid_List->NumberOfItems;
                  pBssList->pAP_Data = calloc( pBssid_List->NumberOfItems, sizeof(AP_DATA));

                  PRINTF(("\n\n===========  802.11 BSS List ==============\n"));
                  PRINTF(( "ID\tMAC\t\t\tRSSI(dBm)\tBSSID\n" ));      


                  for ( i = 0; i < pBssid_List->NumberOfItems; i++ )
                  {                        
                        pTempApData = &pBssList->pAP_Data[i] ;
                  
                        for ( j = 0; j < MAC_ADDR_LEN; j++ )
                        {
                              pTempApData->mac_addr[j] = (pBssid_List->Bssid[i]).MacAddress[j];
                        }

                        pTempApData->Rssi = (pBssid_List->Bssid[i]).Rssi;

                        PRINTF(( "%2u\t", i ));

                        PRINTF(("%02X-%02X-%02X-%02X-%02X-%02X",
                              (pBssid_List->Bssid[i]).MacAddress[0],
                              (pBssid_List->Bssid[i]).MacAddress[1],
                              (pBssid_List->Bssid[i]).MacAddress[2],
                              (pBssid_List->Bssid[i]).MacAddress[3],
                              (pBssid_List->Bssid[i]).MacAddress[4],
                              (pBssid_List->Bssid[i]).MacAddress[5] ));

                        PRINTF(( "\t%d", (pBssid_List->Bssid[i]).Rssi));

                        PRINTF(( "\t\t%s\n", (pBssid_List->Bssid[i]).Ssid.Ssid));

                  }                  
            }
            else
            {
                  status = E_FAIL;
                  dwErrorCode = GetLastError();
                  DEBUGP(("IOCTL BSSID_LIST failed: %d\n", dwErrorCode));
            }            
      }

      return status;

} //Dot11_GetAPList


Here is the output reslut:
===========  802.11 BSS List ==============
ID      MAC                            RSSI(dBm)  BSSID
 0      00-02-2D-B4-32-C2       -55             My Wireless Network A
 1      00-00-00-00-2C-00       33620758                v
 2      A5-FF-FF-FF-01-00       0               P
 3      28-40-00-00-04-00       3


According to the output, the first item in NDIS_802_11_BSSID_LIST struct, i.e, Bssid[0], is correct.  Unfortunately, I can not get the right address for Bssid[1] and Bssid[2].  How to get the right address?  Or the kernel only return the first AP's information indeed?

Thank you!

-Liang

typedef struct _NDIS_802_11_BSSID_LIST
{
    ULONG           NumberOfItems;      // in list below, at least 1
    NDIS_WLAN_BSSID Bssid[1];
} NDIS_802_11_BSSID_LIST, *PNDIS_802_11_BSSID_LIST;
0
overlook
Asked:
overlook
2 Solutions
 
jhanceCommented:
The NDIS_802_11_BSSID_LIST_EX (you should use the _EX version as the original NDIS_802_11_BSSID_LIST is obsolete) is a VARIABLE length struct.  You are indexing it as:

for ( i = 0; i < pBssid_List->NumberOfItems; i++ )

This is an error since not all of the elements are the same length. Use the Length data member of each item in the list to find the beginning of the next element.
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now