• Stars
    star
    201
  • Rank 194,491 (Top 4 %)
  • Language
    C
  • License
    MIT License
  • Created about 3 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A virtual wireless device driver for Linux

vwifi: A Simple Virtual Wireless Driver for Linux

vwifi implements a minimal interface to achieve basic functionalities, such as scanning dummy Wi-Fi networks, connecting, and disconnecting from them. It is based on the cfg80211 subsystem, which works together with FullMAC drivers. Currently, vwifi supports both Station Mode and Host AP Mode, and is well-equipped with WPA/WPA2 security facilities. This enables users to set up a wireless environment using vwifi, hostapd (in HostAP mode interface), and wpa_supplicant (in station mode interface).

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

logo image

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.

To test the network environment, we can utilize the Linux network namespace. Linux network namespace allows us to isolate a network environment from the host system, providing its own routes, firewall rules, and network devices. Essentially, it creates a separate instance of the network stack.

Without network namespace, when virtual interfaces are created that share the same network namespace and start transmitting/receiving packets between them, the kernel will use the loopback device for packet transmission/reception. This behavior occurs because the kernel identifies that the sender and receiver are on the same host.

In conclusion, all the interfaces created by vwifi in the testing environment will be added to an isolated network namespace.

Build and Run

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=3

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 owl0, owl1, and owl2, 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#2
	Interface owl2
		ifindex 5
		wdev 0x200000001
		addr 00:6f:77:6c:32:00
		type managed
phy#1
	Interface owl1
		ifindex 4
		wdev 0x100000001
		addr 00:6f:77:6c:31:00
		type managed
phy#0
	Interface owl0
		ifindex 3
		wdev 0x1
		addr 00:6f:77:6c:30:00
		type managed

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 phy2
(... omit)
Wiphy phy1
(... omit)
Wiphy 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

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 phy0 set netns name ns0
$ sudo iw phy phy1 set netns name ns1
$ sudo iw phy 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 owl0
$ sudo ip netns exec ns1 ip addr add 10.0.0.2/24 dev owl1
$ sudo ip netns exec ns2 ip addr add 10.0.0.3/24 dev owl2

Running hostapd on the HostAP Mode Interface

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

interface=owl0
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 owl0:

$ sudo ip netns exec ns0 hostapd -i owl0 -B 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 owl1 -B -c wpa_supplicant.conf
sudo ip netns exec ns2 \
wpa_supplicant -i owl2 -B -c wpa_supplicant.conf 

Validating the Connection

To validate the connection, use the following command:

$ sudo ip netns exec ns1 iw dev owl1 link

The output might seem like this:

Connected to 00:6f:77:6c:30:00 (on owl1)
	SSID: test
	freq: 2437
	RX: 282 bytes (2 packets)
	TX: 248 bytes (2 packets)
	signal: -84 dBm

It shows that owl1 has connected to the BSS with BSSID 00:6f:77:6c:30:00, which is the MAC address of owl0.

You may also check the connection of owl2 by slightly changing the command above.

On the other hand, we can validate all the stations connected to owl0 by the following commands:

sudo ip netns exec ns0 iw dev owl0 station dump

The output may seem like this:

Station 00:6f:77:6c:31:00 (on owl0)
	inactive time:	5588 ms
	rx bytes:	5366
	rx packets:	65
	tx bytes:	1772
	tx packets:	18
	tx failed:	74
	signal:  	-57 dBm
	current time:	1689679337171 ms
Station 00:6f:77:6c:32:00 (on owl0)
	inactive time:	5588 ms
	rx bytes:	5366
	rx packets:	65
	tx bytes:	1772
	tx packets:	18
	tx failed:	74
	signal:  	-57 dBm
	current time:	1689679337171 ms

Transmission/Receivement test

Finally, we can do the ping test:

  1. To perform a ping test between two STAs (owl1 and owl2), use the following command:
$ sudo ip netns exec ns1 ping -c 4 10.0.0.3

You should see output similar to the following:

PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
64 bytes from 10.0.0.3: icmp_seq=1 ttl=64 time=0.188 ms
64 bytes from 10.0.0.3: icmp_seq=2 ttl=64 time=0.147 ms
64 bytes from 10.0.0.3: icmp_seq=3 ttl=64 time=0.082 ms
64 bytes from 10.0.0.3: icmp_seq=4 ttl=64 time=0.136 ms

--- 10.0.0.3 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3036ms
rtt min/avg/max/mdev = 0.082/0.138/0.188/0.037 ms
  1. To perform a ping test between the AP (owl0) and a STA (owl2), execute the following command:
$ sudo ip netns exec ns2 ping -c 4 10.0.0.1

You should see output similar to the following:

PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.342 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.054 ms
64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=0.106 ms
64 bytes from 10.0.0.1: icmp_seq=4 ttl=64 time=0.063 ms

--- 10.0.0.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3058ms
rtt min/avg/max/mdev = 0.054/0.141/0.342/0.117 ms

Optional: Monitoring Wireless Device

If desired, you can use wireless device monitoring applications such as wavemon to observe signal and noise levels, packet statistics, device configuration, and network parameters of vwifi.

$ sudo apt install wavemon

logo image

License

vwifi is released under the MIT license. Use of this source code is governed by a MIT-style license that can be found in the LICENSE file.

Reference

More Repositories

1

lkmpg

The Linux Kernel Module Programming Guide (updated for 5.0+ kernels)
TeX
7,496
star
2

shecc

A self-hosting and educational C optimizing compiler
C
1,119
star
3

lab0-c

C Programming Lab: Assessing Your C Programming Skills
C
407
star
4

rv32emu

Compact and Efficient RISC-V RV32I[MAFC] emulator
C
393
star
5

simplefs

A simple native file system for Linux kernel
C
372
star
6

concurrent-programs

Complementary Concurrency Programs for course "Linux Kernel Internals"
C
301
star
7

jitboy

A Game Boy emulator with dynamic recompilation (JIT)
C
299
star
8

semu

A minimalist RISC-V system emulator capable of running Linux kernel
C
252
star
9

cpumemory-zhtw

Traditional Chinese translation of "What Every Programmer Should Know About Memory"
CSS
216
star
10

kvm-host

A minimalist type 2 hypervisor using Linux Kernel Virtual Machine (KVM)
C
152
star
11

pitifulvm

A shabby implementation of Java virtual machine in C
C
138
star
12

vcam

Virtual camera device driver for Linux
C
89
star
13

sehttpd

A small and efficient web server with 1K lines of C code
C
82
star
14

concurrency-primer

Concurrency Primer
TeX
75
star
15

cserv

An event-driven and non-blocking web server
C
70
star
16

concurrent-ll

concurrent linked list implementation
C
68
star
17

khttpd

An experimental HTTP server implemented as Linux kernel module
C
60
star
18

rv32emu-legacy

RISC-V RV32I[MA] emulator with ELF support
C
47
star
19

raycaster

Wolfenstein 3D-style raycasting implementation
C
44
star
20

linux-list

Linux-like doubly-linked list
C
39
star
21

fibdrv

Linux kernel module that calculates Fibonacci numbers
Shell
37
star
22

gameboy-emu

An efficient and portable Game Boy emulator
C
36
star
23

mado

A window system for resource-constrained devices
C
34
star
24

lkm-hidden

A Linux kernel module which hides itself
C
29
star
25

kecho

A lightweight echo server implementation in Linux kernel mode
C
27
star
26

rubi

Ruby-like high-performance script programming language with JIT compilation
C
25
star
27

threaded-logger

Threaded Logger
C
21
star
28

threadkit

A collection of lightweight threading utilities
C
20
star
29

vinput

A collection of virtual input device drivers for Linux
C
20
star
30

linux-cfs-sim

Simulate Linux Completely Fair Scheduler (CFS) using POSIX Threads
C
18
star
31

rnnoise

A noise suppression library based on a recurrent neural network
C
17
star
32

kcalc

Math expression evaluation as Linux kernel module
C
17
star
33

dict

Ternary Search Tree + Bloom filter
C
15
star
34

jitcalc

A simple integer calculator using JIT compilation
C
15
star
35

y86_64-tools

Y86-64 Tools: assembler, simulator, Verilog designs
C
14
star
36

fastcat

A faster "cat" implementation using splice and sendfile system calls
C
13
star
37

neocon

A simple serial console utility
C
13
star
38

bignum

An incomplete arbitrary-precision integer arithmetic library
C
13
star
39

fiber

A User Space Threading Library
C
13
star
40

compute-pi

Leibniz formula for π
C
12
star
41

ca2023-lab3

Lab3: Construct a single-cycle CPU with Chisel
Scala
12
star
42

mapreduce

A simple C Thread pool implementation
C
12
star
43

prefix-search

Implement prefix search using ternary search tree
C
12
star
44

jit-construct

JIT compiler from scratch, derived from Nick Desaulniers' great work
Lua
11
star
45

datalab

Improved CS:APP Data Lab
C
9
star
46

buddy

Buddy Memory Allocator
C
8
star
47

moxiebox

A secure, sandboxed execution mechanism that enables deterministic input, processing and output
C
8
star
48

phonebook

sample phonebook program to illustrate the impact of cache miss
Shell
8
star
49

raytracing

Small ray tracing program for performance evaluation
C
8
star
50

intrusive-ds

A collection of intrusive data-structures for C
C
8
star
51

kilo

A text editor in less than 1000 LoC with syntax highlight and search
C
8
star
52

gecos

GECOS: A lock-free synchronization mechanism
C
7
star
53

nyancat

Nyancat rendered in your terminal
C
6
star
54

matrix_oo

Sample matrix implementation illustrating object-oriented techniques in C99
Shell
6
star
55

dont-trace

A simple Linux kernel module that kills ptrace tracer and its tracees
C
6
star
56

kfifo-examples

Linux kernel module examples about kfifo
C
5
star
57

mergesort-concurrent

merge sort on singly-linked list utilzing POSIX Thread
C
5
star
58

tinymembench

Measure peak bandwidth of sequential memory accesses and the latency of random memory accesses
C
5
star
59

cirbuf

Circular Buffer implementation with mmap(2) *incomplete*
C
4
star
60

align-bench

Microbenchmark for unaligned memory access
C
4
star
61

kcalc-fixed

Math expression evaluation as Linux kernel module, fixed-point implementation
C
4
star
62

malloc-test-concurrent

concurrent malloc benchmark
C
3
star
63

prefetcher

Evaluate the effects of prefetching
Shell
3
star
64

sched-plugin

A Linux kernel module to allow user processes being handed out with LKM based scheduler
C
3
star
65

phonebook-concurrent

build a phonebook program by concurrent linked list
C
3
star
66

simrupt

A Linux device driver that simulates interrupts
C
3
star
67

tco-test

Test the ability of C compilers performing Tail Call Optimization
C
2
star
68

vsnd

Virtual Linux soundcard driver
C
2
star
69

rv32emu-demo

HTML
2
star
70

balanced-ternary

Ilustrate how balanced ternary works
Shell
2
star
71

bf-runtime

Brainf*ck runtime engine
C
1
star
72

quotient-filter

(Incomplete) in-memory quotient filter
C
1
star
73

ksort

Linux kernel module that implements and validates sorting algorithms
C
1
star
74

arm-assembler-latex-listings

Arm Assembler language definition for the LaTeX listings package
TeX
1
star
75

clz-tests

Evaluate implementations of count leading zero
C
1
star