AirSnitch — Repository Layout

What lives where in the upstream vanhoefm/airsnitch repo; the NDSS’26 artifact-evaluated snapshot is at zhouxinan/airsnitch / Zenodo.

Top-level

airsnitch/
├── README.md                       # primary docs (we ingest this)
├── setup.sh                        # one-shot dependency / build entry point
├── airsnitch/                      # the modified hostap source tree
│   ├── research/                   # ★ where you actually run things
│   ├── hostapd/, wpa_supplicant/, src/, ...   # patched hostap
│   └── ...
├── dependencies/
│   ├── hostap_2_9/, hostap_2_10/   # vendored hostap source
│   ├── build.sh, README.md
│   └── wpaspy.py → hostap_2_10/wpaspy/wpaspy.py
├── library/                        # AirSnitch's runtime helpers (not the modified hostap)
│   ├── daemon.py                   # spawns / wraps a wpa_supplicant instance
│   ├── station.py                  # state machine for one simulated client
│   └── testcase.py                 # Trigger/Action primitives the tests are built from
├── recon/
│   └── recon_bssid_clients.sh      # quick BSSID / client recon helper
├── server_triggered_port_restoration/
│   ├── server_pong.py
│   └── client_ping.py              # see auxiliary techniques
├── setup/
│   ├── hostapd-*.conf              # AP-side test configs (WPA2/3, with FT, with MFP, ...)
│   ├── supplicant-*.conf           # client-side test configs
│   ├── setup-br0-*.sh              # one-shot bring-up of test topologies
│   ├── setup-hwsim.sh              # simulate Wi-Fi NICs with mac80211_hwsim
│   ├── load-config.sh
│   ├── pysetup.sh
│   └── requirements.txt
├── airsnitch.png, airsnitch-large.png   # logo
├── steal-uplink.png, steal-downlink.png # diagrams referenced from README
└── hostap.py                       # small Python wrapper around hostap binaries

airsnitch/research/ — what you run

The actual test harness:

airsnitch/research/
├── airsnitch.py                ★  the CLI; see [airsnitch-cli.md]
├── airsnitch_measure.py        ★  performance measurement runner (Table V)
├── client.conf                    sample wpa_supplicant config (PSK)
├── client-simulated-AE-gatewaybouncing.conf
├── client-simulated-AE-gtkabuse.conf
├── client-simulated-AE-gtkabuse2.conf
├── client-simulated-AE-portsteal.conf
├── eap.conf                       sample WPA2-Enterprise config
├── multipsk.conf                  sample multi-PSK config
├── saepk.conf                     sample SAE-PK config
├── build.sh
├── pysetup.sh
├── run_every_2min.sh
├── requirements.txt
├── libwifi/                       vendored libwifi helpers
└── wpaspy.py                      symlink to dependencies/wpaspy

See configuration files for what each .conf is for.

library/ — the test framework

Three files describe AirSnitch’s own runtime model:

  • daemon.py — wraps one wpa_supplicant instance, including the named-pipe (wpaspy_ctrl) the harness uses to drive it. One Daemon per simulated party.
  • station.py — a per-NIC state machine (398 lines). Drives association, captures handshake state, and exposes the hooks each test plugs into.
  • testcase.py — the small declarative DSL used by the tests:
    • Trigger: NoTrigger, AfterAuth, Received, Associated, Connected, Disconnected.
    • Action: NoAction, GetIp, Reconnect, Inject, Function, Receive, Terminate.

A test in airsnitch.py typically constructs a list of (Trigger, Action) pairs that fire as the supplicant state advances.

setup/ — bring-up helpers

The setup-br0-*.sh scripts simulate a vulnerable AP on the same machine using mac80211_hwsim. Three are referenced in the artifact appendix (NDSS’26 Appendix A, README §3 implicit):

These sit alongside setup-hwsim.sh which sets up the simulated radios. They are how you reproduce the attacks without hardware. See setup scripts.

dependencies/ — the modified hostap

Two pinned versions of hostap (the upstream hostapd + wpa_supplicant source tree): 2.9 and 2.10. AirSnitch’s modifications live here; setup.sh builds them.

See also