IEEE 802.11acフレームキャプチャ with Raspberry Pi

Raspberry Piでパケットキャプチャできるようにする

自身の研究で、802.11acで規定されてるCSI(Channel State Information)を取得する必要があったのだけど、Raspberry Piでパケットキャプチャできるようにするまでの流れがかなりしんどかったので、まとめておきます。まとめるつもりが、まとめても大ボリュームなのでめちゃくちゃ暇と興味のある人向け。使用するのはNexmonという、Broadcom製のWifiチップ向けのファームウェアパッチです。

[!注意!]

この記事は内容の検証が十分ではありません。後日加筆修正を加える可能性がありますので、下記の作業は、作業者の責任において実行してください。特にWifiチップのファームウェアパッチを適用するという作業は、ハードウェアのサポートが受けられなくなる可能性がありますので注意してください。

必要なもの

  • Raspberry Pi 3B+/4
    • 重要なのはBroadcom製のBCM434355c0というWifiチップを積んでること
    • Raspbianが動作しているものに限る、liteでもdesktopでも大丈夫
    • SDの容量は8GBあれば十分っぽいけど余裕がある方が良い

手順

基本的にはNexmon公式のインストラクションに従いますが、一部記述のないパッケージを入れないと先に進まないところがあったので、その補足も書いておきます。「パケットキャプチャできるようにする」過程と「CSIを取得する」過程に分けて説明します。

パケットキャプチャの準備

無線をキャプチャするためには、デバイスのNIC(Network Interface Card)をモニターモードに変更しなければなりませんが、現状Raspberry Piにはモニターモードに移行させるオプションが実装されていません。そのため、以下の手順を踏んで、モニターモードに移行できるようにしていきます。
特に補足のないところはコマンドを上から順に実行すればOK。
1. sudo su
2. apt update && apt upgrade
3. apt install raspberrypi-kernel-headers git libgmp3-dev gawk qpdf bison flex make
4. apt install libtool-bin automake texinfo1
5. git clone https://github.com/seemoo-lab/nexmon.git
6. cd nexmonで5.でクローンしたディレクトリに入る
7. cd buildtools/isl-0.10, autoreconf -f -i, ./configure, make, make install, ln -s /usr/local/lib/libisl.so /usr/lib/arm-linux-gnueabihf/libisl.so.10を順に実行し2、親ディレクトリ/nexmonに戻る
8. cd buildtools/mpfr-3.1.4, autoreconf -f -i, ./configure, make, make install, ln -s /usr/local/lib/libmpfr.so /usr/lib/arm-linux-gnueabihf/libmpfr.so.4を順に実行し3、親ディレクトリ/nexmonに戻る
9. source setup_env.sh, makeを順に実行
10. cd patches/bcm43455c0/7_45_189/nexmon/, make, make backup-firmware, make install-firmwareを順に実行4

ここまでうまくいっていれば、モニターモードのインターフェースを追加できるようになっているはず。sudo権限で
iw phy `iw dev wlan0 info | gawk '/wiphy/ {printf "phy" $2}'` interface add mon0 type monitor
と実行して、モニターモードのインターフェースmon0が追加されていたら成功。

再起動後も動かすために

Nexmonは既存のファームウェアを上書きしてるわけじゃないので、このままだとラズパイを再起動すると元のWifiドライバが読み込まれて使えなくなってしまう。ので、以下の手順を踏んで、再起動後もNexmon経由にできるようにする。

  1. modinfo brcmfmacを実行し、冒頭のfilename:以降に記述されているパス(.../brcmfmac.ko)をコピーする
  2. mv "<PATH>/brcmfmac.ko" "<PATH>/brcmfmac.ko.orig"
  3. cp /home/pi/nexmon/patches/bcm43455c0/7_45_189/nexmon/brcmfmac_4.19.y-nexmon/brcmfmac.ko "<PATH>/"
  4. depmod -a

ここまでできたら再起動して、上述のインターフェース追加のコマンドが動くかどうか確かめる。もしも再起動後にコマンドが通らなくなったら、「パケットキャプチャの準備」の2, 3, 4, 5を飛ばしてやり直せば戻せる。はず。

CSIの取得

ここからの説明におけるCSIは、厳密にはCompressed Beamforming Reportと呼ばれるバイナリで、例えば802.11n CSI Toolで取得できるような生のCSIとは異なるものです。いわゆるrawなCSIの取得方法については調査中。Compressed Beamforming Reportについて詳しく知りたい方は、IEEE公式のドキュメントを参照してください。

基本的にはtcpdumpやwiresharkなどを使って無線をキャプチャするだけ...なのですが、キャプチャ後の処理がかなり複雑なので、その処理についてまとめておきます。ちなみに後述の理由で環境によって得られる結果が違うので、サンプルコードなどを載せるのではなくキャプチャした中身の解析手順についてのみ書くことにします。

Compressed Beamforming Report

802.11acでは、MIMO通信におけるビーム形成のためにチャネルの情報をAPとSTAでやりとりしていて、これをBeamforming Reportと言います。MIMOのストリームごとに生の情報をやり取りするのはオーバーヘッドがかかるので、チャネルの情報を数学的処理5で圧縮して、いくつかの「角度の情報」に変換して送信しているようです。

今回はキャプチャした中身をWiresharkを使って取り出していきます。
ちなみに下の例では、aa:bb:cc:dd:ee:ffというMACアドレスのデバイスからAPに向かってBeamforming Reportを送っている状況を想定します。

pcap → json

tcpdumpでもwiresharkでも、パケット時にその内容をpcapファイルに出力することができます。このpcapファイルを、jsonファイルに書き下します。絶対jsonに直さないといけないというわけではないと思いますが、後々の作業を簡単にする意味で変換しておきます。
手順は簡単で、例えばtest.pcapというファイルをtest.jsonに変換するにはターミナル等で

tshark -nr test.pcap -Y 'wlan.fc.type_subtype == 0x000e' -T json > test.json

を実行するだけです。ちなみにsubtype 0x000eというのは、Compressed Beamforming ReportやSNRの情報が入っているAction No Ackというフレームのサブタイプを指しているみたいです。

json → アンテナ数/Beamforming Report

前の段階で得たjsonを解析して、通信しているAPとデバイスのアンテナ数を取得し、角度情報のビット数を調べて、Beamforming Reportを取り出します。jsonの構造において必要な値がどのキーに含まれているかも書きますが、なんとpcapからjsonへの変換を行った環境によって、jsonの構造が必ずしも同じじゃないことがあるみたいです(めんどくせぇ...)。なので、以降で括弧書きしているところは自分の環境にどちらかが合うと信じて、どちらかで使ってください。

アンテナ数を確認するのは、アンテナ数の組み合わせによって、Beamforming Reportで送信される内容に変化があるからです。
スクリーンショット 2020-03-29 19.34.22.jpg
上の表はIEEE公式のドキュメントから持ってきたものですが、NrNcがデバイスのアンテナ数を表しています。表の通り、アンテナ数の組み合わせによって得られる角度情報の数量が変わってきます。
Ncはjsonの_source → layers → wlan_mgt (wlan_1) → Fixed parameters → wlan.vht.mimo_control.control_tree → wlan.vht.mimo_control.ncindexに、Nr_source → layers → wlan_mgt (wlan_1) → Fixed parameters → wlan.vht.mimo_control.control_tree → wlan.vht.mimo_control.nrindexに値があります。

2020/03/29 : 続きを執筆中


  1. 公式の説明には書いてなかったけど、おそらく必須のパッケージ。 

  2. ここで/usr/lib/arm-linux-gnueabihf/libisl.so.10なるファイルの存在確認するよう書いてあるが、大抵存在しないのでいきなりこの手順を踏む。 

  3. 脚注2に同じ。/usr/lib/arm-linux-gnueabihf/libmpfr.so.4というファイルの存在確認をするよう指示してるけど、こいつも大抵ない。 

  4. make系のコマンドがMakefile:3: /firmwares/bcm43455c0/7_45_189/definitions.mk: No such file or directoryというエラーで動かない時がある。その時は、/nexmonまで戻ってもう一回source setup_env.shすれば良い 

  5. 特異値分解とギブンス回転 

24601_cold
某大学生。 面識のない人や、ビジネス売りの強い人は怖いので、コメント欄以外では関わりません。悪しからず。
ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
コメント
この記事にコメントはありません。
あなたもコメントしてみませんか :)
すでにアカウントを持っている方は
ユーザーは見つかりませんでした