Windows wlan简单操作

因为是基于windows平台的开发,第一手的参考资料肯定是msdn的https://docs.microsoft.com/zh-cn/windows/desktop/NativeWiFi/portal

第一天我们的需求很简单,扫描当前无线网卡扫到的AP,并获取当前连接的BSSID。

先做一下科普,了解一下wlan网络结构。https://blog.csdn.net/zwl1584671413/article/details/77936950。分上下两篇,基本入门了。

先普及几个概念。

站点,可以理解为一切连接到wifi热点的设备。比如手机,笔记本电脑,平板等。

接入点,又叫AP,或者叫热点。可以理解为一切向外广播wifi信号的设备,具备报文收发、转播,好像还要有网络拓扑结构的设备。比如路由器,装备了无线网卡的电脑(需要开启对应的服务)。

站点加AP或者多个AP可以组成一个服务单元,叫基本服务集(BSS)。站点和AP组网的叫基础结构型基本服务集(infrastructure BSS)。多个AP组网独立型基本服务集(Independent BSS,简称IBSS),也叫Ad - hoc 网络,这种网络最早是为了军事需要而架设的特殊网络。战争题材的电视剧里,通信要发报包括战地电话,都是拉的专线,基本就是Ad-hoc这种网络。通过一根网线连接两个电脑,通过设置一样的网关,在同一网段,这两台电脑就相当于组网了,然后可以互相通信,比如通过FileZilla组成Ftp服务端和客户端,可以互相上传文件,都属于Ad-hoc网络。

现在实际网络环境都是BSS+IBSS混合使用,一起发挥各自的优点。比如基站作为远距离的中继,有一定的覆盖范围,不同区域的BSS和IBSS需要通信时,需要通过分布式系统,路由到合理的基站,再通过蜂窝网络覆盖到服务单元,如果小区内BSS末端的用户,由于距离相对较远,信号会衰减,一些实时的信息传输就回有延迟了,所以小区里一般都是Ad-hoc网络入户(因为各个结点都是平级的)。

以上可能不太专业,就是个人对无线网络的肤浅认识,难免有错误。

然后回来解决我们自己的问题。站点扫描在AP广播范围内的信号(SSID)。然后获取当前链接的AP的BSSID。

主要四个函数

WlanOpenHandle();// 获取本地无线网卡的句柄

WlanEnumInterfaces(); // 遍历网卡,可能有多块 

WlanGetAvailableNetworkList(); // 获取某块网卡扫描到的AP;  

pIfInfo->isState == wlan_interface_state_connected; // 用来判断某个信号是否为当前链接的AP 

            PWLAN_CONNECTION_ATTRIBUTES pConnectInfo = NULL;
            DWORD connectInfoSize = sizeof(WLAN_CONNECTION_ATTRIBUTES);
            WLAN_OPCODE_VALUE_TYPE opCode = wlan_opcode_value_type_invalid;

            dwResult = WlanQueryInterface(hClient,
                &pIfInfo->InterfaceGuid,
                wlan_intf_opcode_current_connection,
                NULL,
                &connectInfoSize,
                (PVOID *)&pConnectInfo,
                &opCode);  ; // 如果是,查询端口,返回当前AP的接口信息,然后就可以做后续操作

获取AP信息,参考如下链接 https://docs.microsoft.com/zh-cn/windows/desktop/api/wlanapi/nf-wlanapi-wlanqueryinterface

#include<windows.h>  
#include<wlanapi.h>  
#include<stdio.h> 
#include "include/cef_parser.h" // json func

#pragma comment(lib, "wlanapi.lib")
#pragma comment(lib, "ole32.lib")

int GetWlanListEx()
{
	int iState(200);
	// construct wlan list
	CefRefPtr<CefDictionaryValue> pDictRt = CefDictionaryValue::Create();

	// Declare and initialize variables.

	HANDLE hClient = NULL;
	DWORD dwMaxClient = 2;      //    
	DWORD dwCurVersion = 0;
	DWORD dwResult = 0;
	DWORD dwRetVal = 0;
	int iRet = 0;

	WCHAR GuidString[39] = { 0 };

	unsigned int i, j, k;

	/* variables used for WlanEnumInterfaces  */

	PWLAN_INTERFACE_INFO_LIST pIfList = NULL;
	PWLAN_INTERFACE_INFO pIfInfo = NULL;

	PWLAN_AVAILABLE_NETWORK_LIST pBssList = NULL;
	PWLAN_AVAILABLE_NETWORK pBssEntry = NULL;

	int iRSSI = 0;

	dwResult = WlanOpenHandle(dwMaxClient, NULL, &dwCurVersion, &hClient);
	if (dwResult != ERROR_SUCCESS) {
		wprintf(L"WlanOpenHandle failed with error: %u\n", dwResult);
		iState = 251;
		return 1;
		// You can use FormatMessage here to find out why the function failed
	}

	dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList);
	if (dwResult != ERROR_SUCCESS) {
		wprintf(L"WlanEnumInterfaces failed with error: %u\n", dwResult);
		iState = 252;
		return 1;
		// You can use FormatMessage here to find out why the function failed
	}
	else {
		wprintf(L"Num Entries: %lu\n", pIfList->dwNumberOfItems);
		wprintf(L"Current Index: %lu\n", pIfList->dwIndex);
		for (i = 0; i < (int)pIfList->dwNumberOfItems; i++) 
		{
			pIfInfo = (WLAN_INTERFACE_INFO *)&pIfList->InterfaceInfo[i];
			wprintf(L"  Interface Index[%u]:\t %lu\n", i, i);
			iRet = StringFromGUID2(pIfInfo->InterfaceGuid, (LPOLESTR)&GuidString,
				sizeof(GuidString) / sizeof(*GuidString));
			// For c rather than C++ source code, the above line needs to be
			// iRet = StringFromGUID2(&pIfInfo->InterfaceGuid, (LPOLESTR) &GuidString, 
			//     sizeof(GuidString)/sizeof(*GuidString)); 
			if (iRet == 0)
				wprintf(L"StringFromGUID2 failed\n");
			else {
				wprintf(L"  InterfaceGUID[%d]: %ws\n", i, GuidString);
			}
			wprintf(L"  Interface Description[%d]: %ws", i,
				pIfInfo->strInterfaceDescription);
			wprintf(L"\n");
			wprintf(L"  Interface State[%d]:\t ", i);
			switch (pIfInfo->isState) {
			case wlan_interface_state_not_ready:
				wprintf(L"Not ready\n");
				break;
			case wlan_interface_state_connected:
				wprintf(L"Connected\n");
				break;
			case wlan_interface_state_ad_hoc_network_formed:
				wprintf(L"First node in a ad hoc network\n");
				break;
			case wlan_interface_state_disconnecting:
				wprintf(L"Disconnecting\n");
				break;
			case wlan_interface_state_disconnected:
				wprintf(L"Not connected\n");
				break;
			case wlan_interface_state_associating:
				wprintf(L"Attempting to associate with a network\n");
				break;
			case wlan_interface_state_discovering:
				wprintf(L"Auto configuration is discovering settings for the network\n");
				break;
			case wlan_interface_state_authenticating:
				wprintf(L"In process of authenticating\n");
				break;
			default:
				wprintf(L"Unknown state %ld\n", pIfInfo->isState);
				break;
			}
			wprintf(L"\n");

			dwResult = WlanGetAvailableNetworkList(hClient,
				&pIfInfo->InterfaceGuid,
				0,
				NULL,
				&pBssList);

			// variables used for WlanQueryInterfaces for opcode = wlan_intf_opcode_current_connection
			PWLAN_CONNECTION_ATTRIBUTES pConnectInfo = NULL;
			DWORD connectInfoSize = sizeof(WLAN_CONNECTION_ATTRIBUTES);
			WLAN_OPCODE_VALUE_TYPE opCode = wlan_opcode_value_type_invalid;

			// If interface state is connected, call WlanQueryInterface
			// to get current connection attributes
			if (pIfInfo->isState == wlan_interface_state_connected)
			{
				dwResult = WlanQueryInterface(hClient,
					&pIfInfo->InterfaceGuid,
					wlan_intf_opcode_current_connection,
					NULL,
					&connectInfoSize,
					(PVOID *)&pConnectInfo,
					&opCode);

				if (dwResult != ERROR_SUCCESS) {
					wprintf(L"WlanQueryInterface failed with error: %u\n", dwResult);
					dwRetVal = 1;
					// You can use FormatMessage to find out why the function failed
				}
				else {
					wprintf(L"  WLAN_CONNECTION_ATTRIBUTES for this interface\n");

					wprintf(L"  Interface State:\t ");
					switch (pConnectInfo->isState) {
					case wlan_interface_state_not_ready:
						wprintf(L"Not ready\n");
						break;
					case wlan_interface_state_connected:
						wprintf(L"Connected\n");
						break;
					case wlan_interface_state_ad_hoc_network_formed:
						wprintf(L"First node in a ad hoc network\n");
						break;
					case wlan_interface_state_disconnecting:
						wprintf(L"Disconnecting\n");
						break;
					case wlan_interface_state_disconnected:
						wprintf(L"Not connected\n");
						break;
					case wlan_interface_state_associating:
						wprintf(L"Attempting to associate with a network\n");
						break;
					case wlan_interface_state_discovering:
						wprintf
							(L"Auto configuration is discovering settings for the network\n");
						break;
					case wlan_interface_state_authenticating:
						wprintf(L"In process of authenticating\n");
						break;
					default:
						wprintf(L"Unknown state %ld\n", pIfInfo->isState);
						break;
					}

					wprintf(L"  Connection Mode:\t ");
					switch (pConnectInfo->wlanConnectionMode) {
					case wlan_connection_mode_profile:
						wprintf(L"A profile is used to make the connection\n");
						break;
					case wlan_connection_mode_temporary_profile:
						wprintf(L"A temporary profile is used to make the connection\n");
						break;
					case wlan_connection_mode_discovery_secure:
						wprintf(L"Secure discovery is used to make the connection\n");
						break;
					case wlan_connection_mode_discovery_unsecure:
						wprintf(L"Unsecure discovery is used to make the connection\n");
						break;
					case wlan_connection_mode_auto:
						wprintf
							(L"connection initiated by wireless service automatically using a persistent profile\n");
						break;
					case wlan_connection_mode_invalid:
						wprintf(L"Invalid connection mode\n");
						break;
					default:
						wprintf(L"Unknown connection mode %ld\n",
							pConnectInfo->wlanConnectionMode);
						break;
					}

					wprintf(L"  Profile name used:\t %ws\n", pConnectInfo->strProfileName);

					wprintf(L"  Association Attributes for this connection\n");
					wprintf(L"    SSID:\t\t ");
					if (pConnectInfo->wlanAssociationAttributes.dot11Ssid.uSSIDLength == 0)
						wprintf(L"\n");
					else {
						for (k = 0;
							k < pConnectInfo->wlanAssociationAttributes.dot11Ssid.uSSIDLength;
							k++) {
							wprintf(L"%c",
								(int)pConnectInfo->wlanAssociationAttributes.dot11Ssid.
								ucSSID[k]);
						}
						wprintf(L"\n");
					}

					wprintf(L"    BSS Network type:\t ");
					switch (pConnectInfo->wlanAssociationAttributes.dot11BssType) {
					case dot11_BSS_type_infrastructure:
						wprintf(L"Infrastructure\n");
						break;
					case dot11_BSS_type_independent:
						wprintf(L"Infrastructure\n");
						break;
					default:
						wprintf(L"Other = %lu\n",
							pConnectInfo->wlanAssociationAttributes.dot11BssType);
						break;
					}

					wprintf(L"    MAC address:\t ");
					for (k = 0; k < sizeof(pConnectInfo->wlanAssociationAttributes.dot11Bssid);
						k++) {
						if (k == 5)
							wprintf(L"%.2X\n",
							pConnectInfo->wlanAssociationAttributes.dot11Bssid[k]);
						else
							wprintf(L"%.2X-",
							pConnectInfo->wlanAssociationAttributes.dot11Bssid[k]);
					}

					wprintf(L"    PHY network type:\t ");
					switch (pConnectInfo->wlanAssociationAttributes.dot11PhyType) {
					case dot11_phy_type_fhss:
						wprintf(L"Frequency-hopping spread-spectrum (FHSS)\n");
						break;
					case dot11_phy_type_dsss:
						wprintf(L"Direct sequence spread spectrum (DSSS)\n");
						break;
					case dot11_phy_type_irbaseband:
						wprintf(L"Infrared (IR) baseband\n");
						break;
					case dot11_phy_type_ofdm:
						wprintf(L"Orthogonal frequency division multiplexing (OFDM)\n");
						break;
					case dot11_phy_type_hrdsss:
						wprintf(L"High-rate DSSS (HRDSSS) = \n");
						break;
					case dot11_phy_type_erp:
						wprintf(L"Extended rate PHY type\n");
						break;
					case dot11_phy_type_ht:
						wprintf(L"802.11n PHY type\n");
						break;
					default:
						wprintf(L"Unknown = %lu\n",
							pConnectInfo->wlanAssociationAttributes.dot11PhyType);
						break;
					}

					wprintf(L"    PHY index:\t\t %u\n",
						pConnectInfo->wlanAssociationAttributes.uDot11PhyIndex);

					wprintf(L"    Signal Quality:\t %d\n",
						pConnectInfo->wlanAssociationAttributes.wlanSignalQuality);

					wprintf(L"    Receiving Rate:\t %ld\n",
						pConnectInfo->wlanAssociationAttributes.ulRxRate);

					wprintf(L"    Transmission Rate:\t %ld\n",
						pConnectInfo->wlanAssociationAttributes.ulTxRate);
					wprintf(L"\n");

					wprintf(L"  Security Attributes for this connection\n");

					wprintf(L"    Security enabled:\t ");
					if (pConnectInfo->wlanSecurityAttributes.bSecurityEnabled == 0)
						wprintf(L"No\n");
					else
						wprintf(L"Yes\n");

					wprintf(L"    802.1X enabled:\t ");
					if (pConnectInfo->wlanSecurityAttributes.bOneXEnabled == 0)
						wprintf(L"No\n");
					else
						wprintf(L"Yes\n");

					wprintf(L"    Authentication Algorithm: ");
					switch (pConnectInfo->wlanSecurityAttributes.dot11AuthAlgorithm) {
					case DOT11_AUTH_ALGO_80211_OPEN:
						wprintf(L"802.11 Open\n");
						break;
					case DOT11_AUTH_ALGO_80211_SHARED_KEY:
						wprintf(L"802.11 Shared\n");
						break;
					case DOT11_AUTH_ALGO_WPA:
						wprintf(L"WPA\n");
						break;
					case DOT11_AUTH_ALGO_WPA_PSK:
						wprintf(L"WPA-PSK\n");
						break;
					case DOT11_AUTH_ALGO_WPA_NONE:
						wprintf(L"WPA-None\n");
						break;
					case DOT11_AUTH_ALGO_RSNA:
						wprintf(L"RSNA\n");
						break;
					case DOT11_AUTH_ALGO_RSNA_PSK:
						wprintf(L"RSNA with PSK\n");
						break;
					default:
						wprintf(L"Other (%lu)\n", pConnectInfo->wlanSecurityAttributes.dot11AuthAlgorithm);
						break;
					}

					wprintf(L"    Cipher Algorithm:\t ");
					switch (pConnectInfo->wlanSecurityAttributes.dot11CipherAlgorithm) {
					case DOT11_CIPHER_ALGO_NONE:
						wprintf(L"None\n");
						break;
					case DOT11_CIPHER_ALGO_WEP40:
						wprintf(L"WEP-40\n");
						break;
					case DOT11_CIPHER_ALGO_TKIP:
						wprintf(L"TKIP\n");
						break;
					case DOT11_CIPHER_ALGO_CCMP:
						wprintf(L"CCMP\n");
						break;
					case DOT11_CIPHER_ALGO_WEP104:
						wprintf(L"WEP-104\n");
						break;
					case DOT11_CIPHER_ALGO_WEP:
						wprintf(L"WEP\n");
						break;
					default:
						wprintf(L"Other (0x%x)\n", pConnectInfo->wlanSecurityAttributes.dot11CipherAlgorithm);
						break;
					}
					wprintf(L"\n");
				}
			} // WlanQueryInterface

			if (dwResult != ERROR_SUCCESS) {
				wprintf(L"WlanGetAvailableNetworkList failed with error: %u\n",
					dwResult);
				iState = 253;
				dwRetVal = 1;
				// You can use FormatMessage to find out why the function failed
			}
			else {
				wprintf(L"WLAN_AVAILABLE_NETWORK_LIST for this interface\n");

				wprintf(L"  Num Entries: %lu\n\n", pBssList->dwNumberOfItems);

				for (j = 0; j < pBssList->dwNumberOfItems; j++) {
					pBssEntry =
						(WLAN_AVAILABLE_NETWORK *)& pBssList->Network[j];

					wprintf(L"  Profile Name[%u]:  %ws\n", j, pBssEntry->strProfileName);

					wprintf(L"  SSID[%u]:\t\t ", j);
					if (pBssEntry->dot11Ssid.uSSIDLength == 0)
						wprintf(L"\n");
					else {
						for (k = 0; k < pBssEntry->dot11Ssid.uSSIDLength; k++) {
							wprintf(L"%c", (int)pBssEntry->dot11Ssid.ucSSID[k]);
						}
						wprintf(L"\n");
					}

					wprintf(L"  BSS Network type[%u]:\t ", j);
					switch (pBssEntry->dot11BssType) {
					case dot11_BSS_type_infrastructure:
						wprintf(L"Infrastructure (%u)\n", pBssEntry->dot11BssType);
						break;
					case dot11_BSS_type_independent:
						wprintf(L"Infrastructure (%u)\n", pBssEntry->dot11BssType);
						break;
					default:
						wprintf(L"Other (%lu)\n", pBssEntry->dot11BssType);
						break;
					}

					wprintf(L"  Number of BSSIDs[%u]:\t %u\n", j, pBssEntry->uNumberOfBssids);

					wprintf(L"  Connectable[%u]:\t ", j);
					if (pBssEntry->bNetworkConnectable)
						wprintf(L"Yes\n");
					else {
						wprintf(L"No\n");
						wprintf(L"  Not connectable WLAN_REASON_CODE value[%u]:\t %u\n", j,
							pBssEntry->wlanNotConnectableReason);
					}

					wprintf(L"  Number of PHY types supported[%u]:\t %u\n", j, pBssEntry->uNumberOfPhyTypes);

					if (pBssEntry->wlanSignalQuality == 0)
						iRSSI = -100;
					else if (pBssEntry->wlanSignalQuality == 100)
						iRSSI = -50;
					else
						iRSSI = -100 + (pBssEntry->wlanSignalQuality / 2);

					wprintf(L"  Signal Quality[%u]:\t %u (RSSI: %i dBm)\n", j,
						pBssEntry->wlanSignalQuality, iRSSI);

					wprintf(L"  Security Enabled[%u]:\t ", j);
					if (pBssEntry->bSecurityEnabled)
						wprintf(L"Yes\n");
					else
						wprintf(L"No\n");

					wprintf(L"  Default AuthAlgorithm[%u]: ", j);
					switch (pBssEntry->dot11DefaultAuthAlgorithm) {
					case DOT11_AUTH_ALGO_80211_OPEN:
						wprintf(L"802.11 Open (%u)\n", pBssEntry->dot11DefaultAuthAlgorithm);
						break;
					case DOT11_AUTH_ALGO_80211_SHARED_KEY:
						wprintf(L"802.11 Shared (%u)\n", pBssEntry->dot11DefaultAuthAlgorithm);
						break;
					case DOT11_AUTH_ALGO_WPA:
						wprintf(L"WPA (%u)\n", pBssEntry->dot11DefaultAuthAlgorithm);
						break;
					case DOT11_AUTH_ALGO_WPA_PSK:
						wprintf(L"WPA-PSK (%u)\n", pBssEntry->dot11DefaultAuthAlgorithm);
						break;
					case DOT11_AUTH_ALGO_WPA_NONE:
						wprintf(L"WPA-None (%u)\n", pBssEntry->dot11DefaultAuthAlgorithm);
						break;
					case DOT11_AUTH_ALGO_RSNA:
						wprintf(L"RSNA (%u)\n", pBssEntry->dot11DefaultAuthAlgorithm);
						break;
					case DOT11_AUTH_ALGO_RSNA_PSK:
						wprintf(L"RSNA with PSK(%u)\n", pBssEntry->dot11DefaultAuthAlgorithm);
						break;
					default:
						wprintf(L"Other (%lu)\n", pBssEntry->dot11DefaultAuthAlgorithm);
						break;
					}

					wprintf(L"  Default CipherAlgorithm[%u]: ", j);
					switch (pBssEntry->dot11DefaultCipherAlgorithm) {
					case DOT11_CIPHER_ALGO_NONE:
						wprintf(L"None (0x%x)\n", pBssEntry->dot11DefaultCipherAlgorithm);
						break;
					case DOT11_CIPHER_ALGO_WEP40:
						wprintf(L"WEP-40 (0x%x)\n", pBssEntry->dot11DefaultCipherAlgorithm);
						break;
					case DOT11_CIPHER_ALGO_TKIP:
						wprintf(L"TKIP (0x%x)\n", pBssEntry->dot11DefaultCipherAlgorithm);
						break;
					case DOT11_CIPHER_ALGO_CCMP:
						wprintf(L"CCMP (0x%x)\n", pBssEntry->dot11DefaultCipherAlgorithm);
						break;
					case DOT11_CIPHER_ALGO_WEP104:
						wprintf(L"WEP-104 (0x%x)\n", pBssEntry->dot11DefaultCipherAlgorithm);
						break;
					case DOT11_CIPHER_ALGO_WEP:
						wprintf(L"WEP (0x%x)\n", pBssEntry->dot11DefaultCipherAlgorithm);
						break;
					default:
						wprintf(L"Other (0x%x)\n", pBssEntry->dot11DefaultCipherAlgorithm);
						break;
					}

					wprintf(L"  Flags[%u]:\t 0x%x", j, pBssEntry->dwFlags);
					if (pBssEntry->dwFlags) {
						if (pBssEntry->dwFlags & WLAN_AVAILABLE_NETWORK_CONNECTED)
							wprintf(L" - Currently connected");
						if (pBssEntry->dwFlags & WLAN_AVAILABLE_NETWORK_CONNECTED)
							wprintf(L" - Has profile");
					}
					wprintf(L"\n");

					wprintf(L"\n");
				}
			}
		}

	}
	if (pBssList != NULL) {
		WlanFreeMemory(pBssList);
		pBssList = NULL;
	}

	if (pIfList != NULL) {
		WlanFreeMemory(pIfList);
		pIfList = NULL;
	}

	return dwRetVal;
}

为了对比AP信息是否准确,参考链接google, 关键字“Determining which AP a client is associated with”。

windows

cmd

netsh wlan show interfaces

 其他平台

祝愉快。

猜你喜欢

转载自blog.csdn.net/moyebaobei1/article/details/82494331