MasaのITC Life

夢は起業家!全てにおいて凡人だけど頑張ることだけはいっちょ前!

プログラミング

【C言語】Wi-Fiビーコン(IEEE802.11)を送信して、疑似APを作ってみた!

投稿日:2019年9月13日 更新日:


普段私たちが使っているWi-Fiは、"IEEE802.11" という規格に基づいて通信が行われます。 そして、AP (アクセスポイント) を認識させるには、ビーコンフレームを使います。

ビーコンフレームは、ネットワークの存在を通知します。私たちが普段Wi-Fi接続するときに、SSID (ネットワーク名) を確認しますが、これはビーコンフレームの中に含まれています。端末がビーコンフレームをキャッチすれば、そのAPが展開するネットワークに参加するチャンスがあるわけです。しかし厳密には、APが指定する機能を全て、端末は実装している必要があります。今回はどの端末でも参加できるような、とても簡易的なAPを作成します。あくまで疑似なので、ビーコンを送信して、疑似APの存在を端末側で確認するのみとします。実際に作成した疑似APに接続して、通信を行えるようにする(実装)には、時間がかかりそうだったので折れました。



IEEE802.11のビーコンフレームも、他の無線規格同様に、フォーマットが定められています。実際は、Wi-Fiを含め、IEEE802.11規格を使った通信には、ビーコンフレーム以外にも、たくさんの種類があります。IEEE802.11通信にはデータの種類に応じて、大きく3種類のフレームタイプに区別することが出来ます。

  • マネジメントフレーム (ビーコン / プローブ要求 / プローブ応答 など)
  • コントロールフレーム (RTS / CTS/ ACK など)
  • データフレーム (レイヤ3以上のデータを運ぶ)



3つのフレームタイプの中でも、さらに細かく分けることが出来ます。全てを理解するには、IEEE802.11の通信が実際にどのように動いているかを勉強する必要があります。今回はマネジメントフレームの中のビーコンフレームを実装していきます。


IEEE802.11 MAC層はフレームタイプによって、フォーマットも少し変わります。とはいえど、基本的な構造は同じです。


IEEE802.11 MAC層の最初にあるフィールド "フレームコントロール" によって、このパケットはどのフレームタイプなのかを識別します。そして、フレームタイプによって、MACヘッダーが少し変わります。MAC層ペイロードのところで、各フレームに応じたデータが入ります。


マネジメントフレームのフォーマットは以下になっています。



他のフレームタイプも、MAC層基本フォーマットをもとに、少しフォーマットが変わります。今回はビーコンを送信するので、このマネジメントフレームのフォーマットに基づいて実装します。 そして、ビーコンフレームに限ったことではありませんが、マネジメントフレームのペイロード部分には、固定フィールド (Fixed Field)情報エレメント (Infromation Element) と呼ばれる2種類のデータが入ります。例えば以下のものがあります。

  • ビーコン間隔 (Beacon Interval)
  • タイムスタンプ (Timestamp)
  • ケーパビリティ情報 (Capability Information)
  • SSID
  • サポートレート (Supported Rates)
  • DSパラメータセット (DS Parameter Set)


今あげたものは、ビーコンフレームでよく使われるデータですが、これはペイロードに入るデータ種類の一部に過ぎません。

上の3つは、固定フィールドと呼ばれるあらかじめデータ長が決まっているデータです。一方で下3つは、情報エレメントと呼ばれる、データ値によってデータ長が変わる可変フィールドです。情報エレメントのイメージはオプションみたいなもので、種類がたくさんあり、その種類に応じて、エレメントIDが割り振られています。





それでは各データについて、簡単に説明します。

ビーコン間隔 (Beacon Interval)は、2バイトのフィールドで指定します。伝送間隔は "タイムユニット" と呼ばれる単位で指定され、1タイムユニットは1,024 μ秒を表しています (約1ミリ秒) 。一般的にはこのビーコン間隔に、100タイムユニットがセットされ、約0.1秒ごとビーコンが送信されます。


タイムスタンプ (Timestamp)は、同期を実現するためのもので、4バイトのフィールドです。APが立ち上がってから、カウントが始ります。64ビットなので、 フルカウントになるまで、最低580,000年以上必要です。なので実際のところは、無限にカウントできると思っても良いかと思います。プログラム上では、最初に0を指定して、時間を取得しなければいけませんが、簡素化のためそこまでは行っていません。


ケーパビリティ情報 (Capability Information)は、2バイトにビット単位フィールドで、各ビットがネットワークの特定の機能を通知するフラグとして使われます。ビーコンだけでなく、プローブ要求やプローブ応答でも使用されます。APが指定したケーパビリティ情報を実装していない端末は、そのAPに接続することが出来ません。今回は簡易的なAPなので、ほぼ全てのビットに0をセットしますが、APはケーパビリティ情報の1ビット目 (ESSフィールド) は、1をセットする必要があります。


サポートレート (Supported Rates)は、データレートのことです。データレートはサポート必須のものと必須でないものがあります。APが飛ばしたビーコンに、データレートを指定し、端末はそのAPが展開するネットワークに入りたければ、必須となっているデータレートはサポートしている必要があります。APが必須といっているデータレートをサポートしていない端末は、ネットワークに参加できません。サポートレートのエレメントIDは1です。データレート対応表に一部を併せて載せておきます。サポートするデータレートの数だけ、"サポートレート"全体のデータ長は増えます。ソースでは、IEEE802.11bのデータレートをサポートしてあります。


SSIDは、ネットワーク名を示します。最大で32文字まで、名前を決めることが出来ます。指定したSSIDの文字数の数だけ、データ長が増えます。エレメントIDは0です。以下のソースではSSID名を "Hello World!" としました。

DSパラメータセット (DS Parameter Set)は、ネットワーク使うチャネル番号を入れます。エレメントIDは3です。


引用:
英語で書かれていますが、IEEE802.11フレームの各フィールドについて説明されているので、良かったら参考にしてみて下さい。
https://www.oreilly.com/library/view/80211-wireless-networks/0596100523/ch04.html


ソースは以下のようになっています。

IEEE802.11フレームをCで送信するためのコード



ieee80211.hは標準では定義されていませんので、自分で用意します。有志が作ったものがありますが、量が少し多いので、ビーコンを送信するにあたって、必要な箇所だけ抜粋しました。



あと、ieee80211_radiotap.hも使います。"IEEE802.11 Radiotap" とググれば、Radiotapヘッダーについて出てきますが、日本語のサイトはあまりありません。私自身も詳しくは理解しておりません。なので有志が作ったieee80211_radiotap.hは、ほとんど丸ごと使っております。

ここからが、本体のcソースになります。

まずは、ライブラリのインクルードと各種定義をします。

IEEE80211_RATE_BASICは、サポートレートを指定したときに、必須レートにする値とビット和をとるためのものです。こうすることで、データレートの必須フラグを立てます。

Beacon_Intervalは102400を指定します。実際のビーコンフレームに入れるときは、タイムユニットという単位(1,024μ秒)です。代入時にBeacon_Intervalを1,024で割ってあげることで、100タイムユニット(約0.1秒)をセットすることが出来ます。

あとは、ビーコンフレームのペイロード部分を、固定フィールドと情報エレメントに分けて定義します。APの情報に関してもここで、定義しておきます。

次は、ソケットを作成する関数です。




ビーコンフレームを実際に作成するための関数です。radiotap、MACヘッダーなどのフィールドを順番にセットしていきます。




main関数です。

実行時に、インタフェース名とチャネル番号を一緒に指定します。まずは、ソケットを開いて、ビーコンフレームを組み立てて、送信するといった、シンプルな流れです。


実行するときの注意ですが、無線LANアダプターを別に用意する必要があります。PC内蔵の無線LANアダプターでは機能が限られているので、外付け無線LANアダプターでないと動作しません。内蔵の無線LANアダプターは、Managedモードというモードで動作しています。


しかし今回のようにAPとして動作させるには、無線LANアダプターをMonitorモードにしてあげる必要があります。また外付けの無線LANアダプターなら、どれでもよいというわけではありません。ここは少し難しい話になってしまいますが、無線LANアダプターの中にあるチップセットというものが関係してきます。


どれを買っらたよいか分からない、という方もいると思いますので、私も参考になったサイトを載せておきますね。




それでは実際に実行してみます。

偽のAPをスマホに認識させる



まずは、モニターモードにします。

外付け無線LANアダプターをPCに、単に接続しただけでの状態で、iwconfigで確認してみます。Managedモードになっています。いわば、通常のモードです。



以下のコマンドを叩いて、monitorモードに切り替えます。

  • ifconfig wlan0 down
  • iwconfig wlan0 mode monitor
  • ifconfig wlan0 up

再度、iwconfigで確認してみると、Monitorモードになっているのが分かります。これで下準備は完了です。あとはこのインタフェースに、ビーコンフレームを送信するのみです。



実行するとこのようになります。



それでは、スマホの方で確認してみます。



Hello Worldと名付けたSSIDで、APの存在が確認できました!

最後まで読んでいただきありがとうございました。

-プログラミング

Copyright© MasaのITC Life , 2023 All Rights Reserved Powered by STINGER.