Tuesday, September 16, 2014

Querying Wi-Fi Link Speed on Windows

Many have expressed the interest to query Wi-Fi link speeed on Windows and provided answers, such as, this, this, and this, which are the main references for this post.

On Windows 7,  we can view network link speed easily and conveniently using the Windows Task Manager, as shown in the figure below,



On Windows 8, the Task Manager has different interface and does not show the link speed any more. If we want to know the link speed, we can view it using the Windows Control Panel, which works on both Windows 7 and Windows 8. A shortcut is to right-click on the  "network" icon in the system tray, then open the "Network and Sharing Center", finally click on the Wi-Fi connection on the right. The result will be something similar to below,



which clealy shows the link speed.

The following methods may be more interesting,

netsh

Open a Windows Command Prompt window, you can issue the following command,

netsh wlan show interface 


which list all Wi-Fi interfaces and their properties.

Querying WMI with WQL

We can use Windows PowerShell to issue WMI queries. Below is an example,


C:\>powershell
Windows PowerShell
Copyright (C) 2013 Microsoft Corporation. All rights reserved.

PS C:\> $query = "SELECT Description, DeviceID, Speed FROM CIM_NetworkAdapter
WHERE Description like '%Wi-Fi%' OR Description like '%802.11%'";
PS C:\>  Get-WmiObject -Query $query


These two posts are particularly helpful for me to write WQL queries to query the WMI.

GetAdaptersAddresses API

To me, this is the most interesting one. This stackoverflow thread provides a sample program in C# that uses P/Invoke to call the GetAdaptersAddresses API.  I made some simple revisions and put all the code together,
You can create a project in Visual Studio to compile the program. However, for this simple example, I would prefer a command line approach,


C:\notes\wifistatus\windows>"c:\Program Files (x86)\Microsoft Visual 
Studio 12.0\Common7\Tools\vsvars32.bat"
C:\notes\wifistatus\windows>csc /warn:4 WifiStatus.cs IPIntertop.cs
Microsoft (R) Visual C# Compiler version 12.0.30501.0
for C# 5
Copyright (C) Microsoft Corporation. All rights reserved.

C:\notes\wifistatus\windows>WifiStatus.exe
GetAdaptersAddresses yields:
        Length of the IP_ADAPTER_ADDRESS struct: 448
        IfIndex (IPv4 interface): 4
        Adapter name: {......}
        DNS Suffix: foo.com
        Description: Broadcom 802.11n Network Adapter
        Friendly name: Wi-Fi
        Physical address: ......
        Flags: 453
        Mtu: 1500
        IfType: IF_TYPE_IEEE80211
        OperStatus: IfOperStatusUp
        Ipv6IfIndex (IPv6 interface): 4
        ZoneIndices (hex): 4 4 4 4 1 1 1 1 1 1 1 1 1 1 0 1
        Transmit link speed: 65000000
        Receive link speed: 144000000
        Number of IP Adapter Prefix entries: 5


GetAllNetworkInterfaces yields:
        Current Wi-Fi Speed on Broadcom 802.11n Network Adapter: 144000000

C:\notes\wifistatus\windows>

Alternatively, perhaps, more naturally, you can do the same in C/C++,
To compile and run it on the Windows Command Prompt command line, do,

C:\notes\wifistatus\windows>"c:\Program Files (x86)\Microsoft Visual 
Studio 12.0\Common7\Tools\vsvars32.bat"

C:\notes\wifistatus\windows>cl /W4 getwifiadapteraddress.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.30501 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

getwifiadapteraddress.cpp
Microsoft (R) Incremental Linker Version 12.00.30501.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:getwifiadapteraddress.exe
getwifiadapteraddress.obj

C:\notes\wifistatus\windows>getwifiadapteraddress.exe
       Length of the IP_ADAPTER_ADDRESS struct: 376
       IfIndex (IPv4 interface): 4
       Adapter name: {......}
       DNS Suffix: foo.com
       Description: Broadcom 802.11n Network Adapter
       Friendly name: Wi-Fi
       Physical address: ......
       Flags: 453
       Mtu: 1500
       IfType: 71
       OperStatus: 1
       Ipv6IfIndex (IPv6 interface): 4
       ZoneIndices (hex): 4 4 4 4 1 1 1 1 1 1 1 1 1 1 0 1
       Transmit link speed: 65000000
       Receive link speed: 144000000
       Number of IP Adapter Prefix entries: 8
C:\notes\wifistatus\windows>

Discussion

Be aware of the difference between the speed (or bandwidth) of the interface card, the negotiated link speed (or bandwidth), and the throughput. The speed of the interface card is the specified speed that the interface card could achieve, i.e., a part of the hardware specification. The negotiated link speed is a reflection of the signal strength. The throughput is the one that you actually achieve. NetworkInterface gives you the speed of the interface card.GetAdaptersAddresses can give you the negotiated link speed. Finally, the throughput can only be determined by a measurement based approach. IPInterfaceStatistics and IPv4InterfaceStatistics can help you estimate it.

1 comment: