xref: /openwifi/doc/app_notes/inject_80211.md (revision 261bb9eef73c3da1bda8d992c145e07cdacfaaac)
1<!--
2Author: Michael Mehari, Xianjun Jiao
3SPDX-FileCopyrightText: 2019 UGent
4SPDX-License-Identifier: AGPL-3.0-or-later
5-->
6
7## 802.11 packet injection and fuzzing
8
9The Linux wireless networking stack (i.e. driver, mac80211, cfg80211, net_dev, user app) is a robust implementation supporting a plethora of wireless devices. As robust as it is, it also has a drawback when it comes to single-layer testing and manual/total control mode (fuzzing).
10
11Ping and Iperf are well established performance measurement tools. However, using such tools to measure 802.11 PHY performance can be misleading, simply because they touch multiple layers in the network stack.
12
13Luckily, the mac80211 Linux subsystem provides packet injection functionality when the NIC is in the monitor mode and it allows us to have finer control for physical layer testing and/or fuzzing.
14
15Besides the traditional fuzzing tool (like scapy), we have adapted a [packetspammer](https://github.com/gnychis/packetspammer) application, which is originally written by Andy Green <[email protected]> and maintained by George Nychis <[email protected]>, to show how to inject packets and control the FPGA behavior.
16
17### Build inject_80211 on board
18Userspace program to inject 802.11 packets through mac80211 supported (softmac) wireless devices.
19
20Login/ssh to the board and setup internet connection according to the Quick Start. Then
21```
22cd openwifi/inject_80211
23make
24```
25### Customize the packet content
26To customize the packet, following piece of the inject_80211.c needs to be changed:
27```
28/* IEEE80211 header */
29static const u8 ieee_hdr[] =
30{
31	0x08, 0x01, 0x00, 0x00,             // FC 0x0801. 0--subtype; 8--type&version; 01--toDS1 fromDS0 (data packet to DS)
32	0x66, 0x55, 0x44, 0x33, 0x22, 0x11, // BSSID/MAC of AP
33	0x66, 0x55, 0x44, 0x33, 0x22, 0x22, // Source address (STA)
34	0x66, 0x55, 0x44, 0x33, 0x22, 0x33, // Destination address (another STA under the same AP)
35	0x10, 0x86,                         // 0--fragment number; 0x861=2145--sequence number
36};
37```
38Note: The byte/bit order might not be intuitive when comparing with the standard.
39
40### FPGA behavior control
41- ACK and retransmission after FPGA sends packet
42
43In openwifi_tx of sdr.c, many FPGA behaviors can be controled. Generally they are controled by the information from upper layer (Linux mac80211), but you can override them in driver (sdr.c)
44
45If 802.11 ACK is expected from the peer after the packet is sent by FPGA, variable **pkt_need_ack** should be overridden to 1. In this case, the FPGA will try to receive ACK, and report the sending status (ACK is received or not) to upper layer (Linux mac80211)
46
47The maximum times of transmission for the packet can be controled by variable **retry_limit_raw**. If no ACK is received after the packet is sent, FPGA will try retransmissions automatically if retry_limit_raw>1.
48
49- ACK after FPGA receives packet in monitor mode
50
51Even in monitor mode, openwifi FPGA still sends ACK after the packet is received, if the conditions are met: MAC address is matched, it is a data frame, etc. To disable this automatic ACK generation, the register 11 of xpu should be set to 16:
52```
53sdrctl dev sdr0 set reg xpu 11 16
54```
55
56### Options of program inject_80211
57```
58-m/--hw_mode <hardware operation mode> (a,g,n)
59-r/--rate_index <rate/MCS index> (0,1,2,3,4,5,6,7)
60-i/--sgi_flag (0,1)
61-n/--num_packets <number of packets>
62-s/--payload_size <payload size in bytes>
63-d/--delay <delay between packets in usec>
64-h   this menu
65```
66
67### Example:
68Login/ssh to the board, Then
69```
70cd openwifi
71./wgd.sh
72./monitor_ch.sh sdr0 11
73(Above will turn sdr0 into the monitor mode and monitor on channel 11)
74./inject_80211/inject_80211 -m n -r 0 -n 10 -s 64 sdr0
75(Above will inject 10 802.11n packets at 6.5Mbps bitrate and 64bytes size via NIC sdr0)
76```
77When above injection command is running, you could see the injected packets with wireshark (or other packet sniffer) on another WiFi device monitoring channel 11.
78
79Or add extra virtual monitor interface on top of sdr0, and inject packets:
80```
81iw dev sdr0 interface add mon0 type monitor && ifconfig mon0 up
82./inject_80211/inject_80211 -m n -r 0 -n 10 -s 64 mon0     # Inject 10 802.11n packets at 6.5Mbps bitrate and 64bytes size
83```
84
85### Link performance test
86
87To make a profound experimental analysis on the physical layer performance, we can rely on automation scripts.
88
89The following script will inject 100 802.11n packets at different bitrates and payload sizes.
90
91```
92#!/bin/bash
93
94HW_MODE='n'
95COUNT=100
96DELAY=1000
97RATE=( 0 1 2 3 4 5 6 7 )
98SIZE=( $(seq -s' ' 50 100 1450) ) # paload size in bytes
99IF="mon0"
100
101for (( i = 0 ; i < ${#PAYLOAD[@]} ; i++ )) do
102	for (( j = 0 ; j < ${#RATE[@]} ; j++ )) do
103		inject_80211 -m $HW_MODE -n $COUNT -d $DELAY -r ${RATE[$j]} -s ${SIZE[$i]} $IF
104		sleep 1
105	done
106done
107
108```
109
110On the receiver side, we can use tcpdump to collect the pcap traces.
111
112```
113iw dev sdr0 interface add mon0 type monitor && ifconfig mon0 up
114tcpdump -i mon0 -w trace.pcap 'wlan addr1 ff:ff:ff:ff:ff:ff and wlan addr2 66:55:44:33:22:11'
115```
116
117Wlan addresses *ff:ff:ff:ff:ff:ff* and *66:55:44:33:22:11* are specific to our injector application.
118
119Next, we analyze the collected pcap traces using the analysis tool provided.
120
121```
122analyze_80211 trace.pcap
123```
124
125An excerpt from a sample analysis looks the following
126
127```
128HW MODE	RATE(Mbps)	SGI	SIZE(bytes)	COUNT	Duration(sec)
129=======	==========	===	===========	=====	=============
130802.11n	6.5           	OFF	54		100	0.11159
131802.11n	13.0		OFF	54		100	0.11264
132802.11n	19.5		OFF	54		100	0.11156
133802.11n	26.0		OFF	54	    	100	0.11268
134802.11n	39.0		OFF	54	    	100	0.11333
135802.11n	52.0		OFF	54	    	100	0.11149
136802.11n	58.5		OFF	54	    	100	0.11469
137802.11n	65.0		OFF	54	    	100	0.11408
138```
139
140