xref: /openwifi/doc/app_notes/inject_80211.md (revision 90a961823175e3903613a8254a4efa9dd13da633)
1a6085186SLina Ceballos<!--
2a2a0d4bdSXianjun JiaoAuthor: Michael Mehari, Xianjun Jiao
3ea75aaf6SJiao XianjunSPDX-FileCopyrightText: 2019 UGent
4a6085186SLina CeballosSPDX-License-Identifier: AGPL-3.0-or-later
5a6085186SLina Ceballos-->
67273ec43Smmehari
7a2a0d4bdSXianjun Jiao## 802.11 packet injection and fuzzing
87273ec43Smmehari
9a2a0d4bdSXianjun JiaoThe 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).
107273ec43Smmehari
117273ec43SmmehariPing 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.
127273ec43Smmehari
13a2a0d4bdSXianjun JiaoLuckily, 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.
147273ec43Smmehari
15a2a0d4bdSXianjun JiaoBesides 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.
167273ec43Smmehari
17fdbf6a5aSJiao Xianjun### Build inject_80211 on board
187273ec43SmmehariUserspace program to inject 802.11 packets through mac80211 supported (softmac) wireless devices.
197273ec43Smmehari
204ec04889SJiao XianjunLogin/ssh to the board and setup internet connection according to the Quick Start. Then
21fdbf6a5aSJiao Xianjun```
22fdbf6a5aSJiao Xianjuncd openwifi/inject_80211
23fdbf6a5aSJiao Xianjunmake
24fdbf6a5aSJiao Xianjun```
25a2a0d4bdSXianjun Jiao### Customize the packet content
26a2a0d4bdSXianjun JiaoTo customize the packet, following piece of the inject_80211.c needs to be changed:
27a2a0d4bdSXianjun Jiao```
28a2a0d4bdSXianjun Jiao/* IEEE80211 header */
29*90a96182SXianjun Jiaostatic u8 ieee_hdr_data[] =
30a2a0d4bdSXianjun Jiao{
31*90a96182SXianjun Jiao	0x08, 0x02, 0x00, 0x00,
32*90a96182SXianjun Jiao	0x66, 0x55, 0x44, 0x33, 0x22, 0x11,
33*90a96182SXianjun Jiao	0x66, 0x55, 0x44, 0x33, 0x22, 0x22,
34*90a96182SXianjun Jiao	0x66, 0x55, 0x44, 0x33, 0x22, 0x33,
35*90a96182SXianjun Jiao	0x10, 0x86,
36*90a96182SXianjun Jiao};
37*90a96182SXianjun Jiao
38*90a96182SXianjun Jiaostatic u8 ieee_hdr_mgmt[] =
39*90a96182SXianjun Jiao{
40*90a96182SXianjun Jiao	0x00, 0x00, 0x00, 0x00,
41*90a96182SXianjun Jiao	0x66, 0x55, 0x44, 0x33, 0x22, 0x11,
42*90a96182SXianjun Jiao	0x66, 0x55, 0x44, 0x33, 0x22, 0x22,
43*90a96182SXianjun Jiao	0x66, 0x55, 0x44, 0x33, 0x22, 0x33,
44*90a96182SXianjun Jiao	0x10, 0x86,
45*90a96182SXianjun Jiao};
46*90a96182SXianjun Jiao
47*90a96182SXianjun Jiaostatic u8 ieee_hdr_ack_cts[] =
48*90a96182SXianjun Jiao{
49*90a96182SXianjun Jiao	0xd4, 0x00, 0x00, 0x00,
50*90a96182SXianjun Jiao	0x66, 0x55, 0x44, 0x33, 0x22, 0x11,
51*90a96182SXianjun Jiao};
52*90a96182SXianjun Jiao
53*90a96182SXianjun Jiaostatic u8 ieee_hdr_rts[] =
54*90a96182SXianjun Jiao{
55*90a96182SXianjun Jiao	0xb4, 0x00, 0x00, 0x00,
56*90a96182SXianjun Jiao	0x66, 0x55, 0x44, 0x33, 0x22, 0x11,
57*90a96182SXianjun Jiao	0x66, 0x55, 0x44, 0x33, 0x22, 0x22,
58a2a0d4bdSXianjun Jiao};
59a2a0d4bdSXianjun Jiao```
60a2a0d4bdSXianjun JiaoNote: The byte/bit order might not be intuitive when comparing with the standard.
61a2a0d4bdSXianjun Jiao
62a2a0d4bdSXianjun Jiao### FPGA behavior control
63a2a0d4bdSXianjun Jiao- ACK and retransmission after FPGA sends packet
64a2a0d4bdSXianjun Jiao
65a2a0d4bdSXianjun JiaoIn 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)
66a2a0d4bdSXianjun Jiao
67a2a0d4bdSXianjun JiaoIf 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)
68a2a0d4bdSXianjun Jiao
69a2a0d4bdSXianjun JiaoThe 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.
70a2a0d4bdSXianjun Jiao
71a2a0d4bdSXianjun Jiao- ACK after FPGA receives packet in monitor mode
72a2a0d4bdSXianjun Jiao
73a2a0d4bdSXianjun JiaoEven 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:
74a2a0d4bdSXianjun Jiao```
75a2a0d4bdSXianjun Jiaosdrctl dev sdr0 set reg xpu 11 16
76a2a0d4bdSXianjun Jiao```
77fdbf6a5aSJiao Xianjun
7810ae6518SJiao Xianjun### Options of program inject_80211
797273ec43Smmehari```
807273ec43Smmehari-m/--hw_mode <hardware operation mode> (a,g,n)
817273ec43Smmehari-r/--rate_index <rate/MCS index> (0,1,2,3,4,5,6,7)
82*90a96182SXianjun Jiao-t/--packet_type (m/c/d/r for management/control/data/reserved)
83*90a96182SXianjun Jiao-e/--sub_type (hex value. example:
84*90a96182SXianjun Jiao     8/A/B/C for Beacon/Disassociation/Authentication/Deauth, when packet_type m
85*90a96182SXianjun Jiao     A/B/C/D for PS-Poll/RTS/CTS/ACK, when packet_type c
86*90a96182SXianjun Jiao     0/1/2/8 for Data/Data+CF-Ack/Data+CF-Poll/QoS-Data, when packet_type d)
87*90a96182SXianjun Jiao-a/--addr1 <the last byte of addr1 in hex>
88*90a96182SXianjun Jiao-b/--addr2 <the last byte of addr2 in hex>
897273ec43Smmehari-i/--sgi_flag (0,1)
907273ec43Smmehari-n/--num_packets <number of packets>
917273ec43Smmehari-s/--payload_size <payload size in bytes>
927273ec43Smmehari-d/--delay <delay between packets in usec>
937273ec43Smmehari-h   this menu
947273ec43Smmehari```
957273ec43Smmehari
967273ec43Smmehari### Example:
9764ce2ec9SJiao XianjunLogin/ssh to the board, Then
987273ec43Smmehari```
9964ce2ec9SJiao Xianjuncd openwifi
10064ce2ec9SJiao Xianjun./wgd.sh
10164ce2ec9SJiao Xianjun./monitor_ch.sh sdr0 11
102e42aed84SJiao Xianjun(Above will turn sdr0 into the monitor mode and monitor on channel 11)
1036681d84fSXianjun Jiao./inject_80211/inject_80211 -m n -r 0 -n 10 -s 64 sdr0
104e42aed84SJiao Xianjun(Above will inject 10 802.11n packets at 6.5Mbps bitrate and 64bytes size via NIC sdr0)
10564ce2ec9SJiao Xianjun```
106e42aed84SJiao XianjunWhen above injection command is running, you could see the injected packets with wireshark (or other packet sniffer) on another WiFi device monitoring channel 11.
107e42aed84SJiao Xianjun
10864ce2ec9SJiao XianjunOr add extra virtual monitor interface on top of sdr0, and inject packets:
10964ce2ec9SJiao Xianjun```
11064ce2ec9SJiao Xianjuniw dev sdr0 interface add mon0 type monitor && ifconfig mon0 up
1116681d84fSXianjun Jiao./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
1127273ec43Smmehari```
1137273ec43Smmehari
1147273ec43Smmehari### Link performance test
1157273ec43Smmehari
1167273ec43SmmehariTo make a profound experimental analysis on the physical layer performance, we can rely on automation scripts.
1177273ec43Smmehari
1187273ec43SmmehariThe following script will inject 100 802.11n packets at different bitrates and payload sizes.
1197273ec43Smmehari
1207273ec43Smmehari```
1217273ec43Smmehari#!/bin/bash
1227273ec43Smmehari
1237273ec43SmmehariHW_MODE='n'
1247273ec43SmmehariCOUNT=100
1257273ec43SmmehariDELAY=1000
1267273ec43SmmehariRATE=( 0 1 2 3 4 5 6 7 )
1277273ec43SmmehariSIZE=( $(seq -s' ' 50 100 1450) ) # paload size in bytes
1287273ec43SmmehariIF="mon0"
1297273ec43Smmehari
1307273ec43Smmeharifor (( i = 0 ; i < ${#PAYLOAD[@]} ; i++ )) do
1317273ec43Smmehari	for (( j = 0 ; j < ${#RATE[@]} ; j++ )) do
1327273ec43Smmehari		inject_80211 -m $HW_MODE -n $COUNT -d $DELAY -r ${RATE[$j]} -s ${SIZE[$i]} $IF
1337273ec43Smmehari		sleep 1
1347273ec43Smmehari	done
1357273ec43Smmeharidone
1367273ec43Smmehari
1377273ec43Smmehari```
1387273ec43Smmehari
1397273ec43SmmehariOn the receiver side, we can use tcpdump to collect the pcap traces.
1407273ec43Smmehari
1417273ec43Smmehari```
142a2a0d4bdSXianjun Jiaoiw dev sdr0 interface add mon0 type monitor && ifconfig mon0 up
1437273ec43Smmeharitcpdump -i mon0 -w trace.pcap 'wlan addr1 ff:ff:ff:ff:ff:ff and wlan addr2 66:55:44:33:22:11'
1447273ec43Smmehari```
1457273ec43Smmehari
1467273ec43SmmehariWlan addresses *ff:ff:ff:ff:ff:ff* and *66:55:44:33:22:11* are specific to our injector application.
1477273ec43Smmehari
1487273ec43SmmehariNext, we analyze the collected pcap traces using the analysis tool provided.
1497273ec43Smmehari
1507273ec43Smmehari```
1517273ec43Smmeharianalyze_80211 trace.pcap
1527273ec43Smmehari```
1537273ec43Smmehari
1547273ec43SmmehariAn excerpt from a sample analysis looks the following
1557273ec43Smmehari
1567273ec43Smmehari```
1577273ec43SmmehariHW MODE	RATE(Mbps)	SGI	SIZE(bytes)	COUNT	Duration(sec)
1587273ec43Smmehari=======	==========	===	===========	=====	=============
1597273ec43Smmehari802.11n	6.5           	OFF	54		100	0.11159
1607273ec43Smmehari802.11n	13.0		OFF	54		100	0.11264
1617273ec43Smmehari802.11n	19.5		OFF	54		100	0.11156
1627273ec43Smmehari802.11n	26.0		OFF	54	    	100	0.11268
1637273ec43Smmehari802.11n	39.0		OFF	54	    	100	0.11333
1647273ec43Smmehari802.11n	52.0		OFF	54	    	100	0.11149
1657273ec43Smmehari802.11n	58.5		OFF	54	    	100	0.11469
1667273ec43Smmehari802.11n	65.0		OFF	54	    	100	0.11408
1677273ec43Smmehari```
1687273ec43Smmehari
169