#!/usr/bin/env python3 """airodump-ng CSV parser for the wifi deauth tool (+ a hardware-free selftest).""" import os import sys import tempfile def parse_airodump_csv(path): try: with open(path, encoding="utf-8", errors="replace") as f: text = f.read() except OSError: return [], [] aps, stations, section = [], [], None for line in text.splitlines(): s = line.strip() if not s: continue if s.startswith("BSSID,"): section = "ap" continue if s.startswith("Station MAC,"): section = "sta" continue # naive comma split; an ESSID containing a comma will skew fields. parts = [c.strip() for c in line.split(",")] if section == "ap" and len(parts) >= 14: aps.append({ "bssid": parts[0], "channel": parts[3], "power": parts[8], "privacy": parts[5], "essid": parts[13], }) elif section == "sta" and len(parts) >= 6: stations.append({ "station": parts[0], "power": parts[3], "packets": parts[4], "bssid": parts[5], }) return aps, stations def _selftest(): sample = ( "BSSID, First time seen, Last time seen, channel, Speed, Privacy, Cipher, " "Authentication, Power, # beacons, # IV, LAN IP, ID-length, ESSID, Key\r\n" "\r\n" "AA:BB:CC:DD:EE:FF, 2024-01-01 00:00:00, 2024-01-01 00:01:00, 6, 130, " "WPA2, CCMP, PSK, -40, 10, 0, 0.0.0.0, 6, MyWiFi, \r\n" "\r\n" "Station MAC, First time seen, Last time seen, Power, # packets, BSSID, " "Probed ESSIDs\r\n" "\r\n" "11:22:33:44:55:66, 2024-01-01 00:00:10, 2024-01-01 00:01:00, -50, 25, " "AA:BB:CC:DD:EE:FF, MyWiFi\r\n" "99:88:77:66:55:44, 2024-01-01 00:00:10, 2024-01-01 00:01:00, -60, 5, " "(not associated), Other\r\n" ) p = os.path.join(tempfile.gettempdir(), "wd_selftest.csv") with open(p, "w") as f: f.write(sample) aps, sts = parse_airodump_csv(p) os.remove(p) assert len(aps) == 1, aps assert aps[0]["essid"] == "MyWiFi" and aps[0]["channel"] == "6", aps assert len(sts) == 2, sts assoc = [s for s in sts if s["bssid"].lower() == "aa:bb:cc:dd:ee:ff"] assert len(assoc) == 1 and assoc[0]["station"] == "11:22:33:44:55:66", sts print("selftest ok") if __name__ == "__main__": if "--selftest" in sys.argv: _selftest() sys.exit(0)