
電波版htop — ターミナルで動作するライブ802.11(Wi-Fi)RFダッシュボード
電波のためのhtop — ターミナルで動くライブな802.11(Wi-Fi)RFダッシュボード。
airtopは、あなたの周囲のWi-Fiトラフィックをライブなターミナルダッシュボードに変えます — 近隣のアクセスポイントの周波数スペクトラム、ステーションごとのシグナルトレース、フレームタイプ別のアクティビティフィード、RSSIヒストグラム、発見されたネットワークのスクロールリスト — これらをeBPF上で点字とブロック文字のグラフィックスで描画します。
[!TIP] モニターモードもrawソケットも不要。 airtopはeBPFプログラムを
mac80211/cfg80211にアタッチし、カーネルのWi-Fiスタックを流れる802.11フレームを読み取ります。通常の接続済みインターフェースで動作し、リンクを切断することはありません。
curl -fsSL https://yeet.cx | sh
yeet run https://github.com/yeet-src/airtop
共有可能なスクリーンショットを撮るには、SSIDとMACを匿名化します(自分のネットワークも隣人のネットワークも、network-01、station-02、…のようにラベルが付け替えられます):
yeet run https://github.com/yeet-src/airtop -- --anonymize
Ctrl-Cが押されるまで実行し続けます。ターミナルをリサイズするとレイアウトが自動で再構成されます。最小サイズは80×24です。
近隣のネットワークを表示するには、カーネルがスキャン結果を必要とします。OSは定期的に自動でスキャンを行います。手動でスキャンを実行することもできます:
nmcli dev wifi rescan # or: iw dev <iface> scan
Wi-FiはIEEE 802.11標準規格ファミリーです。基本的な考え方:
すべてはフレームである。 ラップトップ、スマートフォン、ルーターは、フレームと呼ばれる短い無線パケットを交換します。すべてのフレームはMACアドレスを保持しており、そのうちの1つ(BSSID)が、そのフレームが属するアクセスポイントを識別します。
フレームの3つのクラス:
| クラス | 例 | 目的 |
|---|---|---|
| Management | Beacon、Probe、Auth、Assoc、Deauth | ネットワークの通知、参加、離脱 |
| Control | ACK、RTS/CTS | 誰が送信するかを調整 |
| Data | 実際のトラフィック | ペイロードを運搬 |
アクセスポイントはビーコンを送信する。 APは毎秒約10回、ネットワーク名(SSID)とBSSIDを載せたビーコンフレームで自身を通知します。これがスマートフォンのWi-Fiリストが作られる仕組みであり、airtopがAPを発見する仕組みでもあります。
チャンネルと周波数。 Wi-Fiは帯域(2.4 GHz、5 GHz、6 GHz)に存在し、各帯域はチャンネルに分割されます。各チャンネルはMHz単位の中心周波数を持ちます(チャンネル6 ≈ 2437 MHz、チャンネル161 ≈ 5805 MHz)。無線機は一度に1つのチャンネルしか受信できないため、主に自分のチャンネルのトラフィックが見えるのです。
**シグナル強度(RSSI)**はdBmで測定されます。値は常に負で、0に近いほど強いことを示します:
| RSSI | 品質 |
|---|---|
| −30 … −50 dBm | 非常に良い(すぐそば) |
| −50 … −67 dBm | 良好 |
| −67 … −80 dBm | 使用可能 |
| −80 … −90 dBm | 弱い / ぎりぎり |
主な対象は、不安定なWi-Fiを調査する一般ユーザーと、イベント前にチャンネルを選定するネットワーク管理者です。
各パネルは上記の概念に対応しています:
ヘッダー — 稼働時間、総フレーム数、アクティブなステーション数、発見されたAP数、ビーコン数、deauth数(0以外の場合は赤表示)、現在のチャンネル。注目すべきはdeauthカウンターです。正常なネットワークではゼロのままです。
周波数スペクトラム — 発見されたすべてのAPが、MHz軸上の実際の中心周波数に配置されたシグナルの「こぶ」として描画されます。高さと色がRSSIを示し、ラベルはSSID + dBmです。こぶの重なりは同一チャンネル混雑を表します — 定番のWi-Fiアナライザービューであり、「なぜWi-Fiが遅いのか」への答えです。
RSSI × 時間 — アクティブなステーションごとの点字折れ線グラフで、直近数秒間のシグナルをプロットします。デバイスがAPから離れていくにつれてリンクが弱まる様子や、誰かがラップトップを動かした瞬間にシグナルが跳ねる様子を確認できます。
フレームフィード — 時間経過に伴うフレームタイプのヒートマップ。セルの色 = 各スライスに到着したそのタイプの数。deauthの洪水はその行を即座に照らし出します。これが実際に必要なアラートパターンです。
シグナルヒストグラム — RSSI別の受信フレーム分布。RF環境の「形状」を示します: −50 dBm付近の鋭いピークは強力なAPのすぐ近くにいることを意味し、−60〜−80にかけて広がる分布は混雑した環境を意味します。
アクセスポイント — 発見されたSSIDを、チャンネル、シグナルゲージ、dBmとともに、強い順に並べて表示します。
単一のBPFオブジェクト(airtop.bpf.c)が2つのfentryプログラムをアタッチし、リングバッファ経由でイベントをユーザースペースへストリーム配信します:
| フック | 取得される内容 |
|---|---|
fentry/ieee80211_rx_list | 受信したすべての802.11フレーム: タイプ/サブタイプ、アドレス、ieee80211_rx_statusからのRSSI |
fentry/cfg80211_inform_bss_frame_data | カーネルのスキャンが発見したすべてのAP: SSID、チャンネル、シグナル |
ダッシュボードはyeetのV8ランタイム上で動作し、それらのリングバッファを購読してターミナルUIを描画します:
main.js entry: tty size, render loop, BPF bind/subscribe
state.js live data + frame/scan ingest
render.js ANSI, color ramps, braille canvas/charts (pure)
dashboard.js panels + layout (renderDashboard)
[!IMPORTANT] BTF対応のLinux:
CONFIG_DEBUG_INFO_BTF=yとCONFIG_DEBUG_INFO_BTF_MODULES=y。現在のArch、Fedora、Ubuntu、Debian 12+ではデフォルトで有効です。CO-REによりカーネルごとの再コンパイルは不要です。
cfg80211/mac80211スタックを使用するWi-Fiインターフェース(Linux上の一般的なWi-Fiカードならどれでも可)。curl -fsSL https://yeet.cx | shでインストールされます。[!NOTE] airtopができないこと:
tx_statusフックの対象です。fentryのターゲットは実際には安定していますが、カーネルABIではありません。取得できる正確なデータはWi-Fiドライバーに依存します。モニターモードは必要ですか? いいえ。それがこのツールの要点です。airtopはカーネルのWi-Fiスタックを内部からフックするため、通常の接続済みインターフェースで動作します。
接続が切断されることはありますか? いいえ。モード切り替えは発生しません。インターフェースは接続先に接続されたままです。airtopはカーネルがすでに行っている処理を観察しているだけです。
ネットワークが1つか2つしか表示されないのはなぜですか?
無線機はほとんどの時間、1つのチャンネル(自分のチャンネル)だけを受信しているからです。近隣のネットワークは、OSが定期的なスキャンを実行したときか、nmcli dev wifi rescan / iw dev <iface> scanで手動スキャンを実行したときに表示されます。全帯域の調査にはモニターモードとチャンネルホッピングが必要で、それは別のツールの役割です。
これは合法ですか? 周囲の電波にある802.11フレームを受動的に観測することは、ほとんどの法域で合法です。無線機はすでにそれらを受信しており、airtopはそこにあるものを表示しているだけです。能動的な妨害(deauthパネルは攻撃を検出するものであり、実行するものではありません)は別の話です。社内ネットワークを使用している場合は、利用規定(AUP)を確認してください。
Kismet、airodump-ng、Wiresharkとは何が違うのですか? それらのツールはモニターモードでさらに多くのことを実現します: フレーム単位の完全キャプチャ、PCAPエクスポート、復号など。airtopは通常のインターフェースで動作し、ひと目で把握できるダッシュボードを提供します。ペネトレーションテストにはairodump-ngを使用してください。通話が途切れた原因を知りたいなら、こちらを使用してください。
make # generates include/vmlinux.h, builds bin/airtop.bpf.o
make vmlinux # force-refresh the kernel type header
make clean
clang(BPFターゲット)とbpftoolが必要です。ヘッダーにはディストリビューションのlibbpf / libbpf-devを使用します。生成されるinclude/vmlinux.hとbin/はgitignoreされています。
GIFはassets/airtop.tapeからVHSを使って生成されます:
vhs assets/airtop.tape # -> assets/airtop.gif
カメラの外でairtopを起動するため、GIFはライブダッシュボードの状態で始まります。録画中に別のシェルでWi-Fiスキャンを実行すると、スペクトラムとAPリストが埋まります。
BPFプログラムはGPLです(SEC("license") = "GPL")。これは、使用するカーネルヘルパーによって要求されています。
yeetによって作られました。yeetは、JavaScriptでeBPFプログラムとライブなシステムダッシュボードを記述するためのLinuxランタイムです。