802.11 SIMULATION · MEASURED

Virtual OpenWrt Wi-Fi Lab — Reading a Simulated Capture Honestly

A full OpenWrt router in QEMU with radios from mac80211_hwsim gives you a real MAC-layer network you can capture, with no wireless hardware. Association, the 4-way handshake and deauthentication are byte-for-byte what real gear produces. But a simulated capture is not real air, and the differences are measurable. This page is the analyst's companion, not another setup how-to: the minimal setup, then the measured artifacts that decide what a hwsim capture can and cannot tell you, so you never draw a wrong conclusion from simulated frames.

tested on 24.10.8 + 25.12.5 mac80211_hwsim

The minimal setup

Setup itself is covered thoroughly by the Linux kernel mac80211_hwsim docs and the OpenWrt package, so this is the condensed path. Boot the x86-64 generic squashfs-combined image under QEMU user-mode networking, note the loopback bind on the forwards, OpenWrt's root has no password at first boot:

qemu-system-x86_64 -enable-kvm -m 1024 -smp 2 -drive file=openwrt.img,format=raw,if=virtio -netdev user,id=n1,hostfwd=tcp:127.0.0.1:2222-10.0.2.15:22,hostfwd=tcp:127.0.0.1:8080-10.0.2.15:80 -device virtio-net-pci,netdev=n1 -nographic

Switch the LAN to DHCP, then install, and here is the first thing other guides miss, the package manager changed. OpenWrt 24.10 reaches end of life in September 2026; 25.12 replaced opkg with apk:

OpenWrt 24.10.x · opkg · EoL Sept 2026
opkg update && opkg install luci iw-full kmod-mac80211-hwsim wpad-openssl
OpenWrt 25.12.x · apk
apk update && apk add luci iw-full kmod-mac80211-hwsim wpad-openssl

What's real, what isn't

REAL — everything MAC and up
  • Association and the 4-way handshake (EAPOL M1-M4)
  • Beacons, probe requests/responses, the full IE set
  • Deauthentication / disassociation with reason codes
  • WPA2, WPA3-SAE, PMF, the uci → netifd → hostapd chain
  • VLANs, the firewall, DHCP, everything MAC-layer and up
NOT REAL — the radio
  • RSSI / SNR — absent on the monitor, not a constant (measured: 0 of 470 frames carry a signal field)
  • Path loss, fading, noise, interference
  • EDCA contention, CCA, collisions, retry and aggregation behaviour
  • Real PHY rates, OFDMA / MU, offload-firmware behaviour

hwsim copies frames between radios on the same channel, nothing more. For frame loss and delay simulation, the standard tool is wmediumd, which replaces hwsim's in-kernel forwarding.

The measured artifacts (and the wrong conclusion each causes)

These are the things that separate a simulated capture from real air. Every one is measured from a running 24.10.8 lab, and every one will mislead an analyst who doesn't know it.

The monitor radiotap has no antenna-signal field
Measured: 0 of 470 frames on the hwsim0 global monitor carry a signal field — only TSFT, flags, rate and channel are present.
Wrong conclusion it causes: You cannot read RSSI, SNR, or coverage from a hwsim capture. The signal is absent, not constant. Any tool that keys on radiotap.dbm_antsignal gets nothing.
The radio advertises the sub-1 GHz (802.11ah) band
A scanning client sweeps 902-927 MHz plus 2.4 and 5 GHz — dozens of channels a real 2.4/5 GHz client would never scan.
Wrong conclusion it causes: Reconnect and scan timing is inflated by spectrum no real client touches. Never draw roaming or scan-duration conclusions from a hwsim capture.
phys renumber after a module reload
After rmmod/insmod the phys move (phy0/phy1 → phy2/phy3/phy4) and interfaces follow (phyN-ap0). UCI survives because it keys on the device path, not the phy name.
Wrong conclusion it causes: Any script or check that hardcodes phy0/phy1 breaks until reboot. Key on iw dev interface names, never a fixed phyN.
wifi config defaults to 6 GHz / EHT80
Radios come out band '6g', htmode 'EHT80', channel 'auto'. Setting only disabled=0 gives you 6 GHz EHT80 APs.
Wrong conclusion it causes: You may be capturing a different band and width than you intended. Set band, channel, country and htmode explicitly before you trust the capture.
The kmod autoloads — a bare insmod fails
The package install autoloads mac80211_hwsim with 2 radios. A manual `insmod` then returns rc=255, “module is already loaded”. The /etc/modules.d file is package-owned.
Wrong conclusion it causes: To change the radio count you must `wifi down; rmmod mac80211_hwsim` first, then insmod with the new count. Skipping rmmod silently keeps the old count.

The MAC layer is faithful — captured proof

Add a third radio as a WPA2 station, capture on hwsim0, and force a reconnect. The full exchange appears, dissectable with the eapol and wlan.fc.type_subtype filters. This is byte-for-byte what a real client produces, only the PHY beneath it is simulated:

Deauth (reason 3) Auth Auth Assoc Req Assoc Resp EAPOL M1 EAPOL M2 EAPOL M3 EAPOL M4

Frame sequence only; absolute timings are omitted because the lab was measured under emulation without KVM, which inflates them. Counts and ordering hold; wall-clock does not.

Reading a hwsim capture honestly

Security posture (WPA2 / WPA3 / PMF / SAE) Yes
4-way handshake, EAPOL, MIC, KRACK-style sequences Yes
Deauth / disassoc behaviour + reason codes Yes
Association / roaming decision logic Logic only
RSSI, SNR, coverage No
Airtime, throughput, retries, contention No
OFDMA / MU, real PHY rates No

The rule of thumb: hwsim is faithful for protocol and security analysis and useless for anything RF, airtime, or PHY-rate related. Use it to study the handshake, not the medium.

// keep going
tshark for Wi-Fi → WLAN Pi PCAP Guide → Frame Types → The Sniffer Vantage Trap →

References: the Linux kernel mac80211_hwsim documentation, the OpenWrt 25.12 release notes (opkg → apk), and wmediumd for medium simulation. Lab measured on OpenWrt 24.10.8; 25.12.5 package availability verified, runtime not re-measured.