SkillAgentSearch skills...

Vwifi

A virtual wireless device driver for Linux

Install / Use

/learn @sysprog21/Vwifi
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

vwifi: A Simple Virtual Wireless Driver for Linux

vwifi implements a minimal interface to provide essential functionalities, such as scanning for dummy Wi-Fi networks, establishing connections, and disconnecting from them.

It is built upon the cfg80211 subsystem, which collaborates with FullMAC drivers. Currently, vwifi supports both Station Mode and Host AP Mode and is equipped with robust WPA/WPA2 security features. This enables users to configure a wireless environment using vwifi, hostapd (in HostAP mode interface), and wpa_supplicant (in station mode interface).

Moreover, when running on hypervisors like QEMU, vwifi functions as a virtio-net driver, allowing for inter-guest communication.

Prerequisite

The following packages must be installed before building vwifi.

To compile the kernel driver successfully, the package versions of the currently used kernel, kernel-devel, and kernel-headers need to be matched. Run the following command to install the required kernel headers:

$ sudo apt install linux-headers-$(uname -r)

Since vwifi relies on the Linux wireless (IEEE-802.11) subsystem, iw is necessary for retrieving more information and configuring. Install it using the following command:

$ sudo apt install iw

If running the test script (scripts/verify.sh), Python 3, hostapd, and some additional packages are necessary.

$ sudo apt install python3 python3-pip hostapd
$ pip3 install numpy matplotlib

Testing environment (non-virtio)

To test the network environment effectively, we utilize Linux network namespaces. These namespaces isolate network environments from the host system, providing distinct instances of network stacks with independent routes, firewall rules, and network devices.

Without network namespaces, virtual interfaces created within the same namespace use the loopback device for packet transmission between them, as the kernel recognizes them as residing on the same host.

In our testing setup, all interfaces created by vwifi are placed within an isolated network namespace. This approach ensures that each virtual interface operates independently, facilitating comprehensive testing of networking functionalities without interference from the host's network configuration.

Below, we will conduct two separate tests: Infrastructure BSS and Independent BSS.

Infrastructure BSS

<p align="center"><img src="assets/vwifi.png" alt="logo image" width=60%></p>

The testing environment consists of one AP and two STAs.

The testing environment operates in IEEE 802.11 infrastructure BSS, which imposes a constraint: STAs cannot directly communicate with each other. When an STA wants to communicate with other devices, it must send packets to the AP. The AP then performs the following actions based on the packet type:

  1. Unicast: If the packet is intended for another STA, the AP forwards it directly to the destination STA without passing it to the protocol stack. If the packet is intended for the AP itself, it is passed to the protocol stack.
  2. Broadcast: The AP forwards the packet to all other STAs in the network, except for the source STA, and then passes it to the protocol stack.
  3. Multicast: The AP treats multicast packets the same way as broadcast packets.

Independent BSS

<p align="center"><img src="assets/ibss.png" alt="logo image" width=75%></p>

The testing environment consists of two IBSS devices.

The testing environment operates in IEEE 802.11 independent BSS. IBSS devices can communicate with any device in the same IBSS network without the need to establish a connection beforehand. However, devices in different IBSS networks cannot communicate with each other.

Build and Run (non-virtio)

To build the kernel module, execute the following command:

$ make

Load the cfg80211 kernel module by running the following command:

$ sudo modprobe cfg80211

Insert the vwifi driver. This will create three interfaces (the "station" parameter can be modified according to preference):

$ sudo insmod vwifi.ko station=5

Please note that interfaces can only be created in station mode during the initialization phase. However, they can be switched to Host AP mode later using hostapd.

Checking Network Interfaces

To check the network interfaces, run the following command:

$ ip link

There should be entries starting with vw0, vw1, vw2, vw3, and vw4, which correspond to the interfaces created by vwifi.

To view the available wireless interfaces, execute the following command:

$ sudo iw dev

You should see something similar to the following output:

phy#5
	Interface vw4
		ifindex 7
		wdev 0x500000001
		addr 00:76:77:34:00:00
		type managed
		txpower 0.00 dBm
phy#4
	Interface vw3
		ifindex 6
		wdev 0x400000001
		addr 00:76:77:33:00:00
		type managed
		txpower 0.00 dBm
phy#3
	Interface vw2
		ifindex 5
		wdev 0x300000001
		addr 00:76:77:32:00:00
		type managed
		txpower 0.00 dBm
phy#2
	Interface vw1
		ifindex 4
		wdev 0x200000001
		addr 00:76:77:31:00:00
		type managed
		txpower 0.00 dBm
phy#1
	Interface vw0
		ifindex 3
		wdev 0x100000001
		addr 00:76:77:30:00:00
		type managed
		txpower 0.00 dBm

As observed, each interface has its own phy (struct wiphy), allowing them to be placed into separate network namespaces.

Dumping Wireless Information

To obtain wireless information, execute the following command:

$ sudo iw list

Reference output:

Wiphy vw_phy4
(... omit)
Wiphy vw_phy3
(... omit)
Wiphy vw_phy2
(... omit)
Wiphy vw_phy1
(... omit)
Wiphy vw_phy0
	wiphy index: 0
	max # scan SSIDs: 69
	max scan IEs length: 0 bytes
	max # sched scan SSIDs: 0
	max # match sets: 0
	Retry short limit: 7
	Retry long limit: 4
	Coverage class: 0 (up to 0m)
	Supported Ciphers:
		* WEP40 (00-0f-ac:1)
		* WEP104 (00-0f-ac:5)
		* TKIP (00-0f-ac:2)
		* CCMP-128 (00-0f-ac:4)
	Available Antennas: TX 0 RX 0
	Supported interface modes:
		 * managed
		 * AP
	Band 1:
		Bitrates (non-HT):
			* 1.0 Mbps
			* 2.0 Mbps
			* 5.5 Mbps
			* 11.0 Mbps
			* 6.0 Mbps
			* 9.0 Mbps
			* 12.0 Mbps
			* 18.0 Mbps
			* 24.0 Mbps
			* 36.0 Mbps
			* 48.0 Mbps
			* 54.0 Mbps
		Frequencies:
			* 2412 MHz [1] (20.0 dBm)
			* 2417 MHz [2] (20.0 dBm)
			* 2422 MHz [3] (20.0 dBm)
			* 2427 MHz [4] (20.0 dBm)
			* 2432 MHz [5] (20.0 dBm)
			* 2437 MHz [6] (20.0 dBm)
			* 2442 MHz [7] (20.0 dBm)
			* 2447 MHz [8] (20.0 dBm)
			* 2452 MHz [9] (20.0 dBm)
			* 2457 MHz [10] (20.0 dBm)
			* 2462 MHz [11] (20.0 dBm)
			* 2467 MHz [12] (20.0 dBm) (no IR)
			* 2472 MHz [13] (20.0 dBm) (no IR)
			* 2484 MHz [14] (20.0 dBm) (no IR)
	Supported commands:
		 * set_interface
		 * new_key
		 * start_ap
		 * set_wiphy_netns
		 * set_channel
		 * connect
		 * disconnect
	software interface modes (can always be added):
	interface combinations are not supported
	Device supports scan flush.
	max # scan plans: 1
	max scan plan interval: -1
	max scan plan iterations: 0
	Supported extended features:

You can see the supported operating modes, supported ciphers, channels, bitrates, and supported commands in the output.

The "managed mode" in the Supported interface modes is identical to station mode.

Creating Network Namespaces

Next, create three network namespaces using the following commands:

$ sudo ip netns add ns0
$ sudo ip netns add ns1
$ sudo ip netns add ns2

Find the wiphy name for the three interfaces. The index number for the wiphy name postfix might be different each time. Please use the following command for the ease of memorizing different index number everytime.

$ vw0_phy=$(sudo iw dev vw0 info | grep wiphy | awk '{print $2}')
$ vw0_phy=$(sudo iw list | grep "wiphy index: $vw0_phy" -B 1 | grep Wiphy | awk '{print $2}')
$ vw1_phy=$(sudo iw dev vw1 info | grep wiphy | awk '{print $2}')
$ vw1_phy=$(sudo iw list | grep "wiphy index: $vw1_phy" -B 1 | grep Wiphy | awk '{print $2}')
$ vw2_phy=$(sudo iw dev vw2 info | grep wiphy | awk '{print $2}')
$ vw2_phy=$(sudo iw list | grep "wiphy index: $vw2_phy" -B 1 | grep Wiphy | awk '{print $2}')

Check whether the name of each wiphy is the same as the name listing under the command sudo iw list

$ echo $vw0_phy
vw_phy0
$ echo $vw1_phy
vw_phy1
$ echo $vw2_phy
vw_phy2

Assign the three interfaces to separate network namespaces. Please note that the wiphy is placed within the network namespace, and the interface associated with that wiphy will be contained within it.

$ sudo iw phy vw_phy0 set netns name ns0
$ sudo iw phy vw_phy1 set netns name ns1
$ sudo iw phy vw_phy2 set netns name ns2

Assigning IP Addresses to Each Interface

Now, assign an IP address to both interfaces using the following commands:

$ sudo ip netns exec ns0 ip addr add 10.0.0.1/24 dev vw0
$ sudo ip netns exec ns1 ip addr add 10.0.0.2/24 dev vw1
$ sudo ip netns exec ns2 ip addr add 10.0.0.3/24 dev vw2

Running hostapd on the HostAP Mode Interface

Prepare the following script hostapd.conf (you can modify the script based on your needs):

interface=vw0
driver=nl80211
debug=1
ctrl_interface=/var/run/hostapd
ctrl_interface_group=wheel
channel=6
ssid=test
wpa=2
wpa_passphrase=12345678
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP

Run hostapd on the interface vw0:

$ sudo ip netns exec ns0 hostapd -i vw0 -B scripts/hostapd.conf

Running wpa_supplicant on the Station Mode Interfaces

Prepare the following script wpa_supplicant.conf (you can modify the script based on your needs):

network={
    ssid="test"
    psk="12345678"
}

Then run the wpa_supplicant on the interface ns1 and ns2:

$ sudo ip netns exec ns1 \
       wpa_supplicant -i vw1 -B -c scripts/wpa_supplicant.conf
$ sudo ip netns exec ns2 \
 

Related Skills

View on GitHub
GitHub Stars246
CategoryDevelopment
Updated17d ago
Forks55

Languages

C

Security Score

100/100

Audited on Mar 11, 2026

No findings