{"id":51002123,"url":"https://github.com/yeet-src/airtop","last_synced_at":"2026-06-20T15:33:14.931Z","repository":{"id":360585706,"uuid":"1250830715","full_name":"yeet-src/airtop","owner":"yeet-src","description":"htop for the airwaves — a live 802.11 (Wi-Fi) RF dashboard in your terminal, powered by yeet + eBPF. No monitor mode.","archived":false,"fork":false,"pushed_at":"2026-05-27T02:51:07.000Z","size":2694,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-27T04:23:39.109Z","etag":null,"topics":["802-11","bpf","ebpf","network-monitoring","rf","terminal","tui","wifi"],"latest_commit_sha":null,"homepage":"https://yeet.cx","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yeet-src.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-27T02:22:08.000Z","updated_at":"2026-05-27T03:08:37.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/yeet-src/airtop","commit_stats":null,"previous_names":["yeet-src/airtop"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/yeet-src/airtop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yeet-src%2Fairtop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yeet-src%2Fairtop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yeet-src%2Fairtop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yeet-src%2Fairtop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yeet-src","download_url":"https://codeload.github.com/yeet-src/airtop/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yeet-src%2Fairtop/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34576043,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-20T02:00:06.407Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["802-11","bpf","ebpf","network-monitoring","rf","terminal","tui","wifi"],"created_at":"2026-06-20T15:33:14.862Z","updated_at":"2026-06-20T15:33:14.926Z","avatar_url":"https://github.com/yeet-src.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# airtop\n\n**htop for the airwaves** — a live 802.11 (Wi-Fi) RF dashboard in your terminal.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/platform-Linux-1793D1\" alt=\"Linux\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/built%20with-yeet%20%2B%20eBPF-8A2BE2\" alt=\"yeet + eBPF\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/license-GPL-3DA639\" alt=\"GPL\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/airtop.gif\" alt=\"airtop running in anonymize mode\" width=\"820\"\u003e\n\u003c/p\u003e\n\n**airtop turns the Wi-Fi traffic around you into a live terminal dashboard** — a frequency spectrum of nearby access points, per-station signal traces, a frame-type activity feed, an RSSI histogram, and a rolling list of discovered networks — drawn with braille and block graphics over eBPF.\n\n\u003e [!TIP]\n\u003e **No monitor mode, no raw sockets.** airtop attaches eBPF programs to `mac80211`/`cfg80211` and reads 802.11 frames as they flow through the kernel's Wi-Fi stack, so it runs on your normal, connected interface without dropping your link.\n\n## Quick start\n\n```sh\ncurl -fsSL https://yeet.cx | sh\nyeet run https://github.com/yeet-src/airtop\n```\n\nFor a shareable screenshot, anonymize SSIDs and MACs (your network and your neighbors' get relabeled `network-01`, `station-02`, …):\n\n```sh\nyeet run https://github.com/yeet-src/airtop -- --anonymize\n```\n\nRuns until `Ctrl-C`. Resize the terminal and the layout reflows; minimum 80×24.\n\nTo surface neighboring networks the kernel needs scan results. Your OS scans periodically on its own, or force one:\n\n```sh\nnmcli dev wifi rescan        # or: iw dev \u003ciface\u003e scan\n```\n\n## A 60-second 802.11 primer\n\nWi-Fi is the IEEE 802.11 family of standards. The mental model:\n\n**Everything is a frame.** Your laptop, phone, and router exchange short radio packets called frames. Every frame carries MAC addresses, and one of them (the **BSSID**) identifies the access point it belongs to.\n\n**Three classes of frame:**\n\n| Class | Examples | Purpose |\n|---|---|---|\n| Management | Beacon, Probe, Auth, Assoc, Deauth | advertise, join, and leave networks |\n| Control | ACK, RTS/CTS | coordinate who gets to talk |\n| Data | your actual traffic | carry payloads |\n\n**Access points beacon.** An AP announces itself ~10 times a second with a beacon frame carrying its network name (SSID) and BSSID. That's how your phone's Wi-Fi list gets populated, and how airtop discovers APs.\n\n**Channels \u0026 frequency.** Wi-Fi lives in bands (2.4 GHz, 5 GHz, 6 GHz), each split into channels, and every channel is a center frequency in MHz (channel 6 ≈ 2437 MHz, channel 161 ≈ 5805 MHz). A radio listens to one channel at a time, which is why you mostly see traffic on your channel.\n\n**Signal strength (RSSI)** is measured in dBm. Values are always negative, and closer to zero is stronger:\n\n| RSSI | quality |\n|---|---|\n| −30 … −50 dBm | excellent (right next to it) |\n| −50 … −67 dBm | good |\n| −67 … −80 dBm | usable |\n| −80 … −90 dBm | weak / marginal |\n\n## Common use cases\n\nMostly home users debugging flaky Wi-Fi, and netadmins picking channels before an event.\n\n- Your video call stutters. Is your channel congested?\n- A guest can't connect. Is the AP even beaconing?\n- Picking a channel for a demo. What's the RF environment look like?\n- Deauth frames spike. Attack, or misbehaving router?\n\n## What you're looking at\n\nEach panel maps onto the concepts above:\n\n**Header** — uptime, total frames seen, live stations, discovered APs, beacon count, deauth count (red if any non-zero), and your current channel. The deauth counter is the one to keep an eye on; healthy networks have zero.\n\n**Frequency spectrum** — every discovered AP drawn as a signal \"hump\" positioned at its real center frequency on a MHz axis. Height and color show RSSI; the label is the SSID + dBm. **Overlapping humps reveal co-channel congestion** — the classic Wi-Fi-analyzer view, and the answer to \"why is my Wi-Fi slow.\"\n\n**RSSI × time** — a braille line graph per live station plotting its signal over the last several seconds. Watch a link fade as a device walks away from the AP, or jump when someone moves their laptop.\n\n**Frame feed** — a heatmap of frame types over time; cell color = how many of that type arrived per slice. **A deauth flood lights up that row instantly**, which is the alert pattern you actually want.\n\n**Signal histogram** — distribution of received frames by RSSI. The \"shape\" of your RF environment: a tight peak around −50 dBm means you're close to one strong AP, a smear across −60 to −80 means a crowded environment.\n\n**Access points** — discovered SSIDs with channel, signal gauge, and dBm, sorted strongest-first.\n\n## How it works\n\nA single BPF object (`airtop.bpf.c`) attaches two `fentry` programs and streams events to userspace over ring buffers:\n\n| Hook | What it captures |\n|---|---|\n| `fentry/ieee80211_rx_list` | every received 802.11 frame: type/subtype, addresses, RSSI from `ieee80211_rx_status` |\n| `fentry/cfg80211_inform_bss_frame_data` | every AP the kernel's scans discover: SSID, channel, signal |\n\nThe dashboard runs in yeet's V8 runtime, subscribing to those ring buffers and rendering the terminal UI:\n\n```\nmain.js       entry: tty size, render loop, BPF bind/subscribe\nstate.js      live data + frame/scan ingest\nrender.js     ANSI, color ramps, braille canvas/charts (pure)\ndashboard.js  panels + layout (renderDashboard)\n```\n\n## Requirements\n\n\u003e [!IMPORTANT]\n\u003e Linux with BTF: `CONFIG_DEBUG_INFO_BTF=y` and `CONFIG_DEBUG_INFO_BTF_MODULES=y`. Default on current Arch, Fedora, Ubuntu, and Debian 12+. CO-RE means no per-kernel recompile.\n\n- A Wi-Fi interface using the standard `cfg80211`/`mac80211` stack (any normal Wi-Fi card on Linux).\n- The yeet daemon, which handles the privileged BPF load. `curl -fsSL https://yeet.cx | sh` installs it.\n\n## Honest caveats\n\n\u003e [!NOTE]\n\u003e What airtop doesn't do:\n\n- A connected interface only hears its own channel plus whatever brief scans touch, so the spectrum and AP list fill in as scans run, and live per-frame traffic is mostly your channel. A full-band survey would need monitor mode + channel hopping.\n- It counts frames, not bytes. \"Activity\" is frame count, not airtime.\n- TX rate and retries aren't captured. That's a separate `tx_status` hook.\n- The `fentry` targets are stable in practice but not a kernel ABI; exact data depends on your Wi-Fi driver.\n\n## Community questions\n\n**Does this need monitor mode?**\nNo. That's the whole point. airtop hooks the kernel's Wi-Fi stack from inside, so it works on your normal connected interface.\n\n**Will it drop my connection?**\nNo. There's no mode switch; your interface stays associated to whatever it's associated to. airtop is observing what the kernel is already doing.\n\n**Why do I only see one or two networks?**\nBecause your radio is listening to one channel (its own) most of the time. Neighboring networks show up when your OS does periodic scans, or when you force one with `nmcli dev wifi rescan` / `iw dev \u003ciface\u003e scan`. A full-band survey needs monitor mode + channel hopping, which is a different tool.\n\n**Is this legal?**\nPassively observing 802.11 frames in the air around you is legal in most jurisdictions; your radio is already receiving them, and airtop just shows you what's there. Active interference (the deauth panel *detects* attacks, it doesn't perform them) is a different story. If you're on a corporate network, check your AUP.\n\n**How is this different from Kismet, airodump-ng, or Wireshark?**\nThose tools do more with monitor mode: full per-frame capture, PCAP export, decryption. airtop runs on your normal interface and gives you an at-a-glance dashboard. For pen-testing, use airodump-ng. To find out why your call dropped, use this.\n\n## Building from source\n\n```sh\nmake          # generates include/vmlinux.h, builds bin/airtop.bpf.o\nmake vmlinux  # force-refresh the kernel type header\nmake clean\n```\n\nNeeds `clang` (BPF target) and `bpftool`; your distro's `libbpf` / `libbpf-dev` for headers. The generated `include/vmlinux.h` and `bin/` are gitignored.\n\n## Recording the demo\n\nThe GIF is produced with [VHS](https://github.com/charmbracelet/vhs) from `assets/airtop.tape`:\n\n```sh\nvhs assets/airtop.tape    # -\u003e assets/airtop.gif\n```\n\nIt launches airtop off-camera so the GIF opens on the live dashboard. Kick off Wi-Fi scans in another shell while recording to fill the spectrum and AP list.\n\n## License\n\nThe BPF program is GPL (`SEC(\"license\") = \"GPL\"`), as required by the kernel helpers it uses.\n\n---\n\nBuilt by [yeet](https://yeet.cx). yeet is a Linux runtime for writing eBPF programs and live system dashboards in JavaScript.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyeet-src%2Fairtop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyeet-src%2Fairtop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyeet-src%2Fairtop/lists"}