/// <summary> /// Converts a pointer to a BSS list (header + entries) to an array of BSS entries. /// </summary> /// <returns>An array of BSS entries.</returns> private NdisWlanBssidEx[] ConvertBssidListPtr(IntPtr bssidListPtr) { // // Marshal the bssid list structure to get the number of items plus // the first bssid entry. // Ndis802Dot11BssidListEx bssidList = (Ndis802Dot11BssidListEx)Marshal.PtrToStructure(bssidListPtr, typeof(Ndis802Dot11BssidListEx)); // // Iterate through memory and marshal each bssid entry. We have // to marshal the individual structures one at a time, since they // vary in size. // NdisWlanBssidEx[] bssidEntries = null; if (bssidList.NumberOfItems > 0) { bssidEntries = new NdisWlanBssidEx[bssidList.NumberOfItems]; long bssidAddress = bssidListPtr.ToInt64() + Marshal.SizeOf(bssidList.NumberOfItems) + bssidList.Bssid[0].Length; bssidEntries[0] = bssidList.Bssid[0]; // // Starting from the second array entry, iterate and marshal each of the // existing bssid entries. // for (int i = 1; i < bssidList.NumberOfItems; ++i) { // // Marshal the currently referenced bssid item and add it to the // array. // NdisWlanBssidEx bssidEntry = (NdisWlanBssidEx)Marshal.PtrToStructure( new IntPtr(bssidAddress), typeof(NdisWlanBssidEx)); bssidEntries[i] = bssidEntry; // // Move the pointer to the next bssid entry. // bssidAddress += bssidEntry.Length; } // Patch from cborn: // We can receive either NDIS_WLAN_BSSID (104 bytes) or NDIS_WLAN_BSSID_EX (>=120 bytes) here // More of its devices send the obsolete 104 byte one than the new one // We should handle it properly, but for now I'll just set the IELength field to 0, // and clear out the additional 8 supported rate fields // DAV 20AUG08 for (int i = 0; i < bssidList.NumberOfItems; ++i) { if (bssidEntries[i].Length < 120) { bssidEntries[i].IELength = 0; for (int j = 8; j < 16; ++j) { bssidEntries[i].SupportedRates[j] = 0; } } } } return(bssidEntries); }
/// <summary> /// Converts a pointer to a BSS list (header + entries) to an array of BSS entries. /// </summary> /// <returns>An array of BSS entries.</returns> private NdisWlanBssidEx[] ConvertBssidListPtr(IntPtr bssidListPtr) { // // Marshal the bssid list structure to get the number of items plus // the first bssid entry. // Ndis802Dot11BssidListEx bssidList = (Ndis802Dot11BssidListEx)Marshal.PtrToStructure(bssidListPtr, typeof(Ndis802Dot11BssidListEx)); // // Iterate through memory and marshal each bssid entry. We have // to marshal the individual structures one at a time, since they // vary in size. // NdisWlanBssidEx[] bssidEntries = null; if (bssidList.NumberOfItems > 0) { bssidEntries = new NdisWlanBssidEx[bssidList.NumberOfItems]; long bssidAddress = bssidListPtr.ToInt64() + Marshal.SizeOf(bssidList.NumberOfItems) + bssidList.Bssid[0].Length; bssidEntries[0] = bssidList.Bssid[0]; // // Starting from the second array entry, iterate and marshal each of the // existing bssid entries. // for (int i = 1; i < bssidList.NumberOfItems; ++i) { // // Marshal the currently referenced bssid item and add it to the // array. // NdisWlanBssidEx bssidEntry = (NdisWlanBssidEx)Marshal.PtrToStructure( new IntPtr(bssidAddress), typeof(NdisWlanBssidEx)); bssidEntries[i] = bssidEntry; // // Move the pointer to the next bssid entry. // bssidAddress += bssidEntry.Length; } // Patch from cborn: // We can receive either NDIS_WLAN_BSSID (104 bytes) or NDIS_WLAN_BSSID_EX (>=120 bytes) here // More of its devices send the obsolete 104 byte one than the new one // We should handle it properly, but for now I'll just set the IELength field to 0, // and clear out the additional 8 supported rate fields // DAV 20AUG08 for (int i = 0; i < bssidList.NumberOfItems; ++i) { if (bssidEntries[i].Length < 120) { bssidEntries[i].IELength = 0; for (int j = 8; j < 16; ++j) bssidEntries[i].SupportedRates[j] = 0; } } } return bssidEntries; }
/// <summary> /// Returns the string representation of the privacy mode /// for the specified bssid. /// </summary> /// <param name="bssidItem">bssid from which to read the privacy mode</param> /// <returns>a string representing the privacy mode</returns> public string GetSecurityString(NdisWlanBssidEx bssidItem) { string privacyMode = "Open"; if (bssidItem.Privacy != 0) { privacyMode = "WEP"; // // To get the privacy information, the variable length // information elements must be inspected. Thereore, we // skip past the fixed information elements. // int index = Marshal.SizeOf(typeof(Ndis802Dot11FixedIes)); // // Iterate through the variable information elements. // int length = (int)bssidItem.IELength - 2; while ((index >= 0) && (index <= length)) { // // Get the element id and the length of the // element. // // TODO: Should index be incremented here, since // it is incremented again down below? byte elementId = bssidItem.IEs[index++]; byte elementLength = bssidItem.IEs[index++]; // // Determine the required privacy mode. // if (WlanEidRsn == elementId) { // Parse the RSN cipher suite value if (elementLength >= 6 && bssidItem.IEs[index + 0] == 0x01 && // version msb bssidItem.IEs[index + 1] == 0x00 && // version lsb bssidItem.IEs[index + 2] == 0x00 && // cipher suite id b1 bssidItem.IEs[index + 3] == 0x0F && // cipher suite id b2 bssidItem.IEs[index + 4] == 0xAC) // cipher suite id b3 // Dispatch on the cipher suite selector { switch (bssidItem.IEs[index + 5]) { case 1: // WEP-40 privacyMode = "WEP-40"; break; case 5: // WEP-104 privacyMode = "WEP-104"; break; case 2: // TKIP -> Personal privacyMode = "WPA2-Personal"; break; case 4: // CCMP -> Enterprise privacyMode = "WPA2-Enterprise"; break; default: privacyMode = "Unknown"; break; } } //Debug.WriteLine("WLAN_EID_RSN : length = " + elementLength); break; } if (WlanEidVendorSpecific == elementId) { //Debug.WriteLine("WLAN_EID_VENDOR_SPECIFIC"); // BEGIN FM // Parse the Microsoft OUI if (elementLength >= 3 && bssidItem.IEs[index + 0] == 0x00 && bssidItem.IEs[index + 1] == 0x50 && bssidItem.IEs[index + 2] == 0xF2 && bssidItem.IEs[index + 3] == 0x01) // 1 == WPA, 2 == WMM ??? { privacyMode = "WPA-Personal"; } // END FM } // // Move to the next information element. // // TODO: We incremented index twice before this call. Is it valid // to increment by element length again? index += elementLength; } } return(privacyMode); }
/// <summary> /// Returns the string representation of the privacy mode /// for the specified bssid. /// </summary> /// <param name="bssidItem">bssid from which to read the privacy mode</param> /// <returns>a string representing the privacy mode</returns> public string GetSecurityString(NdisWlanBssidEx bssidItem) { string privacyMode = "Open"; if (bssidItem.Privacy != 0) { privacyMode = "WEP"; // // To get the privacy information, the variable length // information elements must be inspected. Thereore, we // skip past the fixed information elements. // int index = Marshal.SizeOf(typeof(Ndis802Dot11FixedIes)); // // Iterate through the variable information elements. // int length = (int)bssidItem.IELength - 2; while ((index >= 0) && (index <= length)) { // // Get the element id and the length of the // element. // // TODO: Should index be incremented here, since // it is incremented again down below? byte elementId = bssidItem.IEs[index++]; byte elementLength = bssidItem.IEs[index++]; // // Determine the required privacy mode. // if (WlanEidRsn == elementId) { // Parse the RSN cipher suite value if (elementLength >= 6 && bssidItem.IEs[index + 0] == 0x01 && // version msb bssidItem.IEs[index + 1] == 0x00 && // version lsb bssidItem.IEs[index + 2] == 0x00 && // cipher suite id b1 bssidItem.IEs[index + 3] == 0x0F && // cipher suite id b2 bssidItem.IEs[index + 4] == 0xAC) { // cipher suite id b3 // Dispatch on the cipher suite selector switch (bssidItem.IEs[index + 5]) { case 1: // WEP-40 privacyMode = "WEP-40"; break; case 5: // WEP-104 privacyMode = "WEP-104"; break; case 2: // TKIP -> Personal privacyMode = "WPA2-Personal"; break; case 4: // CCMP -> Enterprise privacyMode = "WPA2-Enterprise"; break; default: privacyMode = "Unknown"; break; } } //Debug.WriteLine("WLAN_EID_RSN : length = " + elementLength); break; } if (WlanEidVendorSpecific == elementId) { //Debug.WriteLine("WLAN_EID_VENDOR_SPECIFIC"); // BEGIN FM // Parse the Microsoft OUI if (elementLength >= 3 && bssidItem.IEs[index + 0] == 0x00 && bssidItem.IEs[index + 1] == 0x50 && bssidItem.IEs[index + 2] == 0xF2 && bssidItem.IEs[index + 3] == 0x01) { // 1 == WPA, 2 == WMM ??? privacyMode = "WPA-Personal"; } // END FM } // // Move to the next information element. // // TODO: We incremented index twice before this call. Is it valid // to increment by element length again? index += elementLength; } } return (privacyMode); }