Wireless・のおと
サイレックスの無線LAN 開発者が語る、無線技術についてや製品開発の秘話、技術者向け情報、新しく興味深い話題、サイレックスが提供するサービスや現状などの話題などを配信していきます。
WiFiの接続手続きのはなし
EAPについての話が一段落したところで、そもそも「WiFiネットワークに接続する」という動作が具体的に何をやっているのかを説明したいと思います。
ビーコンとスキャン
WiFi ネットワークに接続したいステーション(STA)は、まず接続先のアクセスポイント(AP)を探すことから始めます。通常は SSID (Service Set ID) と呼ばれる文字列でネットワークを識別しますが、WiFi の仕様上 AP を識別するのは BSSID (Basic Service Set ID, 実質的には MAC アドレス)で SSID はオプションであり、SSID を持たない AP を運用することも可能です。このモードを俗に「ステルス AP」と呼んだりしますが、「ステルス AP」という用語には幾つか異なる定義がありますので(※註)必ずしも一般的に通用する用語ではないことに注意してください。
(※註) 「ステルス AP」と呼ばれる形態には長さ0のSSIDを用いる場合と、文字コード0x00のみで構成されたSSIDを用いる場合の2種類があります。またかなり特殊な形態ですが、AP からビーコンを送信せず Probe request (後述) にのみ応答するものを「ステルス AP」と呼ぶ場合もあります。
WiFi の AP は通常、「ビーコン」と呼ばれるパケットを恒常的に(通常は 100msec 間隔=秒間約10回)その AP が動作しているチャネル上に送信しています。ビーコンには様々な情報が含まれますが、代表的なものを挙げると
・BSSID, SSID
・ビーコン送信間隔
・チャネル(周波数)情報
・サポートする転送速度の一覧
・セキュリティ情報
などが含まれます。
silex SX-AP-4800N によるビーコンの例を図1に示します。WiFi 規格が段階的に発展してきた経緯を反映して、情報があちこちに分散していることに注意してください。例えばセキュリティに関して、WEP についての情報は「Capabilities Bit」のなかに、WPA については「Vendor Specific: Microsoft WPA Information Element」のなかに、WPA2/802.11i については「RSN Information」のなかにあります。また通信レートについては 1~18Mbps が「Supported Rates」に、24~54Mbps が「Extended Supported Rates」に入り、802.11n の拡張モードについては「HT Capabilities」に入るといった具合になっています。
注意ぶかく見ると、Capability Bits の 32bit を使いきって HT Capability IE を増築した様子が伺えるかと思います。Capability Bits の中には 802.11/b 混在用の Short Preamble, 802.11b/g 混在用の Short Slot Time や DSSS-OFDM など今では殆ど意味を持たない情報も多いのですが、こういった盲腸のような古い仕様の残滓と、後付け拡張された情報が複数のフィールドに散らばっているのが WiFi 無線 LAN 仕様の特徴です。
STA はビーコンを受信することによって AP の一覧を得ることができ、この動作を「静的スキャン(Passive scan)」と呼びます。また、AP に対して積極的に「誰かいますか?」という呼びかけ(Probe request)を行うこともでき、この動作を「動的スキャン(Active scan)」と呼びます。AP は Probe request に対し Probe response というパケットで応答しますが、Probe response の内容はビーコンとほぼ同じです。
AP, STA に限らず、無線ノードは原則として同時に1つの周波数(チャネル)しか送受信できません。従って接続したい AP を探す STA は「通信するかもしれないチャネル」全てを渡り歩きながら静的ないし動的スキャンを行って AP の一覧を作成する必要があります。一般的に「スキャン」と呼ぶ場合、この「チャネルを渡り歩きながらの動的スキャン」を行う動作を指す場合が多いです。
環境によっては、同じ SSID で動作する AP が(異なるチャネルに)複数存在する場合もあります。企業ネットワークではビル1軒やフロア1つを単一の SSID でカバーするため、同じ SSID の AP を異なるチャネルで交互に配置して運用することが多いです(ローミング環境)。この場合、ステーションは作成した AP 一覧から「最も接続しやすそうな AP」 を選択しなければなりません。この選択アルゴリズムはメーカーや設定によって異なりますが、最も電波強度(RSSI:Received Signal Strength Indicator)の強い AP を選択するのが一般的です。
アソシエーション手続き
さて接続先の AP を選択したら、いよいよ接続手続きを開始します。これは
STA→AP Authentication
AP→STA Authentication
STA→AP Association Request
AP→STA Association Response
というパケットの交換によって実行されます。
「Authentication」は WEP 時代の "Shared" 認証でパスワード確認を行うために使われていた手続きですが、現在ではほぼ形骸化しています。Shared 認証は安全性を増すどころか逆にセキュリティホールになるため(※註)、現在では使用しないことが強く推奨されています。一方、WPA 以降で拡張された認証方式(WPA-PSK や WPA-EAP)は Authentication の枠組みを用いませんので、現在の WiFi では Authentication は実質的な機能を持っていません。
(※註)Authentication に失敗すれば「そのパスワードは違う」ことが判るので、攻撃者は「ありそうなパスワードの組み合わせ」を手当たり次第に乱発することで「正しい」パスワードを探ることができてしまいます。
Association Request は STA からの接続要求、Association Response は AP からの接続許可(あるいは拒否)応答です。ここで交換される情報もおおむねビーコンや Probe-request / Probe-response と同様ですが、レギュレトリ情報や WMM/QOS がらみの情報など、より詳しい情報がオプションで相乗りすることも多いです。特定メーカーの特定アクセスポイント機種にだけつながらないといった「相性」問題はこの Association 手続きで起こることが多く、我々ネットワークエンジニアが真っ先に疑う部分でもあります。
認証手続き(4-way handshake)
Association 手続きの完了をもって、オープンシステム認証(暗号化なし、あるいは WEP)の場合はステーションと AP の接続は完了しますが、WPA セキュリティを用いる場合はこの後に認証手続きが始まります。PSK 認証の場合、Association Response に続いて AP 側から 4-way handshake と呼ばれる手続きが開始されます。
STA→AP Association Request
AP→STA Association Response
AP→STA Key message 1/4
STA→AP Key message 2/4
AP→STA Key message 3/4
STA→AP Key message 4/4
Key message の詳細については触れませんが、Nonce, IV, MIC などと呼ばれる一連の情報を交換するとで、第三者にはわからない方法で秘密鍵を交換しています。
WPA2-PSK を使った接続手続きの例を図2に示します。フレーム番号 1~6 がスキャン手続き、7~12 がアソシエーション手続き、17~23 が 4-way handshake 手続きです。
WiFi の接続失敗...いわゆる「つながらない」問題はこの中の何処かで起こり、たとえば AP が見つからない(SSID 違い)、見つかった AP が接続条件に合致しない(セキュリティ設定違い)、Association Request が拒絶された(国コード違い、要求ビットレート不一致、Listen Interval 範囲逸脱など)、4-way handshake に失敗した(パスワード間違い)などです。
このように、接続失敗原因の殆どは設定ミスですが、稀にバグも含めた「相性問題」が起こることもあります。例えば AP 側の設定で 802.11N を禁止して 802.11b/g モードにしたとき、本来なら載ってはいけない HT Capabilities Information が半ば壊れた状態で(例えば length=0 のヘッダのみ、中身なしフィールドとして)ビーコンに入ってしまうバグ持ちの AP があるとして、ある実装(たとえば Windows PC)は壊れた情報を無視するので接続できるけれど、別の実装(たとえば iPhone)は壊れた情報をエラー扱いするのでつながらない、などという現象として発現します。
この場合は AP 側の設定で 802.11N を許可すると HT Capabilities Information が正しく載るので、「互換性を高めようと思って b/g モードにすると何故か iPhone だけつながらず、11n モードに設定したほうが互換性が高い」という謎現象となり、素人さんには何がなんだかわからないと思います。しかも市販のコンシューマ AP は同じメーカー・同じ型番の製品でも製造ロットによって搭載されているチップセットが異なることがあり、こういった微妙なバグの発現もロットによって変わったりします。
別に脅すわけではなく、コンシューマ AP でも殆どの場合は問題なくつながるのですが、たまにこういう問題が出るとパケットを捕まえて中身を見てみないと何が起こっているのかわかりません。こんな仕事をやっていると「うちの無線 LAN の調子が悪いんだけど、何が悪いか教えてくれない?」みたいな質問を気軽にされたりしますが、無線 LAN について知れば知るほど、症状だけ聞かされたって何が悪いかなんて判るわけがないと思います。
認証手続き(EAPoL)
さて EAP 認証の場合、Association Response に続いて AP 側から EAPoL 手続きが開始されます。
STA→AP Association Request
AP→STA Association Response
AP→STA EAPoL Identity Request
STA→AP EAPoL Identity Response
AP→STA EAPoL Request
STA→AP EAPoL Response
.
.
.
AP→STA EAPoL Success
EAPoL の Request/Response 交換は AP から Success あるいは Failure が返ってくるまで何度も繰り返されます。EAPoL の中身は設定されている EAP タイプ(LEAP, TLS, PEAP など)によって異なり、単純な EAP-MD5 であれば Challenge request / Challenge response の一回で終わりますが、EAP-TLS や PEAP では TLS プロトコルの手続き(Server Hello, Client Hello, Cipher Spec...)をコマ切れに分割して通信するため、通常は 20~30 回のパケット交換が必要となります。
EAP の完了後、通常は 4-way handshake が実行されて暗号鍵の交換が行われます。WiFi の仕様上「認証」と「暗号化」は別規格になっているので、「EAP-PEAP + 暗号なし」や「EAP-TLS + WEP 暗号」という組み合わせで動作させることも可能ではありますが、強力な EAP 認証にわざわざ弱い暗号を組み合わせて使う実用上の意味は殆どありません。
接続後の処理
スキャン・アソシエーション・認証が終わると STA は AP と接続された状態となり、パケットの送受信ができるようになります。しかし接続完了後も、まだやるべき仕事が幾つか残っています。
WPA(WPA/WPA2) を使用している場合、AP は一定期間毎にマルチキャスト鍵(GTK)の更新を行います。GTK 更新に伴い、AP は接続配下にある STA に対し鍵更新通知(EAPoL Group Key Message, 1/2)を送信します。これを受信した STA は適切な鍵更新処理を行い、鍵更新受理(EAPoL Group Key Message, 2/2)を返送しなければなりません。通常、この処理はドライバ上位で動作するサプリカントに実装されます。
AP の実装や設定によっては、一定時間通信が無い STA を自動的に切断してしまうもの(タイムアウト機能)もあります。このとき切断通知(Deauthentication)を出してくれれば STA 側から再接続処理を行うことが可能ですが、通知を出さずに黙って切ってしまう AP もありますし、出したつもりの切断通知が電波状況の一時的悪化によって届かないこともあります。こうなると「時々切れることがある」「一旦切れると再接続しない」という、あまり遭遇したくないタイプの不具合を招くことになります。
こういった「知らない間に切れていた」事態を避けるため、ドライバの実装や設定によっては、上位層の通信がなくとも定期的に通信を行う場合があり、これをキープアライブ(Keepalive)と呼びます。キープアライブで送信するデータはデータを持たないヌルフレーム(Null frame)だったり、自身の IP アドレスを通知する ARP パケット(Gratituous ARP)だったり、これも実装や設定によって異なります。
前述したローミング環境...同じ SSID を持つ AP が複数動作している環境では、STA には「現在接続している AP の電波状況」と「他の AP の電波状況」を把握し、電波状況が悪化した場合は他の AP に接続し直す(ローミング)動作が求められます。ローミング動作は接続完了後に行うドライバの仕事しては最も重要なもので、GTK 更新やキープアライブ以上にトラブルの元になりやすい機能でもあります。
とりあえず「現在接続している AP の電波状況」はビーコンの RSSI から把握できますが、多くの実装ではビーコンだけではなく通信パケットのデータレートや再送回数もローミング計算に含めるようになっています。ビーコンは最も伝達性の高い最低データレート(2.4GHz では 1Mbps DSSS + BPSK、5GHz では 6Mbps OFDM + BPSK + 符号化率 1/2)で送信されるので、必ずしもビーコン RSSI は実際のデータ通信レートでの電波状況を反映しないからです。
「現在接続している AP」よりも厄介なのが「ローミング先候補の AP」の把握です。既に述べたように「無線ノードは原則として同時に1つの周波数(チャネル)しか送受信できない」ので、接続中の AP と通信しながら他チャネル AP のスキャンを行うことはできません。ここは各メーカー毎に工夫されているところで、データ通信が一定時間途絶えたことを検出してスキャンを行ったり、電波状況が一定以上悪化したときにはデータ通信を中断してでもスキャンを行ってローミング先 AP を探すなどの実装がなされています。
WiFi ドライバが複雑な理由
以上、WiFi の接続と通信手続きについて「ごく基本的なところ」を「ばっさり簡略化して」解説してみました。こういった機能の殆どは「WiFi ドライバ」に実装されています(※註)。「Association-Response フレームに含まれる HT Information IE の Rx Supported MCS Scheme フィールドを調べて設定可能な HT 送信レートのビットマップを PHY ドライバに設定する」などという機能も WiFi ドライバの一部なのです。
(※註)一部の機能は「サプリカント」にありますが、広義にはサプリカントも含めて「ドライバ」と呼ぶ場合が多いです。
通常「デバイスドライバ」というのは、データの塊を A 地点(メモリ上)から B 地点(デバイスの接続先)に移す機能しかありません。例えば有線の Ethernet ドライバであれば、上位層から指定されたデータに MAC ヘッダを付けて DMA 経由で MAC コントローラに渡すだけ(あるいはその逆)です。Ethernet にも回線ビジー状態制御程度の簡単なプロトコル(CSMA/CD)はありますが、それは基本的に Ethernet チップのハードウェアで処理され、ドライバソフトウェアがいちいち気にする必要はありません。
ところが WiFi においては、「アクセスポイントに接続する」という動作ひとつを取っても「スキャン」「アソシエーション」「認証」「ローミング監視」「KeepAlive, GTK 監視」という一連の機能を必要とし、その機能一つ一つがまた複数のパケット送受信を必要とするのです。WiFi の規格が段階的に発展してきた事情(WEP, WPA, WPA2 や 11b, 11a/g, 11n など)や、メーカー・実装・設定によってパケット構造やフィールド値が微妙に異なる(仕様上そうなっている場合もあれば、バグでそうなっている場合もある)事情が更にドライバの仕事を面倒にします。「WiFiドライバ」が他のドライバ(例えば有線LANのドライバ)にくらべて桁違いに複雑なのはそういう理由があります。
WiFi の接続手続きなんて標準規格で決まったプロトコルなんだから、ベンダーごと・チップごと・ドライバごとに実装するなんて馬鹿な真似はやめて OS の方に標準機能として実装し、ドライバには「周波数を設定する」「パケットを送信する」「パケットを受信する」程度の機能だけ実装すれば良いのに、と思う方もいるかもしれません(※註)。実際 Windows や MacOS, Linux ではこのようなアプローチも取られてはいます。しかし iTRON などの工業組み込み RTOS にはそんな機能は無いので結局ドライバで全部受け持たなければならないとか、インテリジェント型の WiFi チップではオンチップで接続手続き(の一部)をオフロードするので逆に OS 側の WiFi 機能をバイパスしなければならないとか、いろいろと「大人の事情」があって一本化できません。結局ドライバが様々な矛盾や事情を吸収する「必要悪」として存在し続けることになってしまっています。
(※註)Bluetoothはこれに近い構成になっており、Bluetoothのチップを駆動する「HCIドライバ」と、プロトコルやプロファイルを実装するサービス層はかなり綺麗に分かれています。何でWiFiがそうなっていないかというと...歴史上の経緯や大人の事情というところでしょうか。
Looking Back
1980 年代中頃にエンジニアリングワークステーション(EWS)が流行りはじめたころ、TCP/IPプロトコルは「仕様が重すぎて PC 向きではない」と言われていました。その頃の PC といえば 640KByte のメモリ制限を背負ったシングルタスクの DOS でしたから仕方ありません。DOS PC から Unix 上のファイルを共有する PC-NFS というシステムもありましたが、実装に癖やバグが多くて運用互換性に苦労させられました。
DOS のメモリ制限は intel 80286 という CPU のアーキテクチャに由来しており(※註)、これが事実上撤廃されるのは Windows95 が爆発的に売れた 95 年以降のことになります。しかし初期の Microsoft 製 TCP/IP スタックには Winsock にバグがあったり 95 系と NT 系で動きが違ったりして、2000 年頃になるまで落ち付きませんでした。Unix の世界では 4.3BSD(1986) でほぼ仕様が固まった TCP/IP も、コンシューマ市場に普及して仕様が落ち着くまで 15 年ほどかかったわけです。
(※註)286 の Protected Virtual Address Mode については個人的に恨みがあり、これについて書きだすと長くなり過ぎるので割愛します。今後このブログで取り上げる気もありません。
無線 LAN を取り巻く状況もかつての TCP/IP と似ているような気がします。1999 年 10 月に IEEE802.11b-1999 がリリースされてからちょうど 14 年ほど経つわけですが、まだ落ち着く気配がないのは数年に一度の高速化で後付け拡張が繰り返されたこと( 802.11a/g/n/ac/ad)、セキュリティ規格の WPA2(802.11i) 制定に手間取ったこと(WPA/TKIP という中途半端な過渡規格が出来てしまった)、前回述べた EAP 認証プロトコルの混迷がまだ片付いていないからでしょう。
企業としては仕様が混迷して適度にトラブルが出てくれたほうが仕事が増えて有り難いのかもしれませんが、一介のエンジニアとしては「いいかげんにしてくれ」と思います。
WiFi ネットワークに接続したいステーション(STA)は、まず接続先のアクセスポイント(AP)を探すことから始めます。通常は SSID (Service Set ID) と呼ばれる文字列でネットワークを識別しますが、WiFi の仕様上 AP を識別するのは BSSID (Basic Service Set ID, 実質的には MAC アドレス)で SSID はオプションであり、SSID を持たない AP を運用することも可能です。このモードを俗に「ステルス AP」と呼んだりしますが、「ステルス AP」という用語には幾つか異なる定義がありますので(※註)必ずしも一般的に通用する用語ではないことに注意してください。
(※註) 「ステルス AP」と呼ばれる形態には長さ0のSSIDを用いる場合と、文字コード0x00のみで構成されたSSIDを用いる場合の2種類があります。またかなり特殊な形態ですが、AP からビーコンを送信せず Probe request (後述) にのみ応答するものを「ステルス AP」と呼ぶ場合もあります。
WiFi の AP は通常、「ビーコン」と呼ばれるパケットを恒常的に(通常は 100msec 間隔=秒間約10回)その AP が動作しているチャネル上に送信しています。ビーコンには様々な情報が含まれますが、代表的なものを挙げると
・BSSID, SSID
・ビーコン送信間隔
・チャネル(周波数)情報
・サポートする転送速度の一覧
・セキュリティ情報
などが含まれます。
silex SX-AP-4800N によるビーコンの例を図1に示します。WiFi 規格が段階的に発展してきた経緯を反映して、情報があちこちに分散していることに注意してください。例えばセキュリティに関して、WEP についての情報は「Capabilities Bit」のなかに、WPA については「Vendor Specific: Microsoft WPA Information Element」のなかに、WPA2/802.11i については「RSN Information」のなかにあります。また通信レートについては 1~18Mbps が「Supported Rates」に、24~54Mbps が「Extended Supported Rates」に入り、802.11n の拡張モードについては「HT Capabilities」に入るといった具合になっています。
注意ぶかく見ると、Capability Bits の 32bit を使いきって HT Capability IE を増築した様子が伺えるかと思います。Capability Bits の中には 802.11/b 混在用の Short Preamble, 802.11b/g 混在用の Short Slot Time や DSSS-OFDM など今では殆ど意味を持たない情報も多いのですが、こういった盲腸のような古い仕様の残滓と、後付け拡張された情報が複数のフィールドに散らばっているのが WiFi 無線 LAN 仕様の特徴です。
STA はビーコンを受信することによって AP の一覧を得ることができ、この動作を「静的スキャン(Passive scan)」と呼びます。また、AP に対して積極的に「誰かいますか?」という呼びかけ(Probe request)を行うこともでき、この動作を「動的スキャン(Active scan)」と呼びます。AP は Probe request に対し Probe response というパケットで応答しますが、Probe response の内容はビーコンとほぼ同じです。
AP, STA に限らず、無線ノードは原則として同時に1つの周波数(チャネル)しか送受信できません。従って接続したい AP を探す STA は「通信するかもしれないチャネル」全てを渡り歩きながら静的ないし動的スキャンを行って AP の一覧を作成する必要があります。一般的に「スキャン」と呼ぶ場合、この「チャネルを渡り歩きながらの動的スキャン」を行う動作を指す場合が多いです。
環境によっては、同じ SSID で動作する AP が(異なるチャネルに)複数存在する場合もあります。企業ネットワークではビル1軒やフロア1つを単一の SSID でカバーするため、同じ SSID の AP を異なるチャネルで交互に配置して運用することが多いです(ローミング環境)。この場合、ステーションは作成した AP 一覧から「最も接続しやすそうな AP」 を選択しなければなりません。この選択アルゴリズムはメーカーや設定によって異なりますが、最も電波強度(RSSI:Received Signal Strength Indicator)の強い AP を選択するのが一般的です。
アソシエーション手続き
さて接続先の AP を選択したら、いよいよ接続手続きを開始します。これは
STA→AP Authentication
AP→STA Authentication
STA→AP Association Request
AP→STA Association Response
というパケットの交換によって実行されます。
「Authentication」は WEP 時代の "Shared" 認証でパスワード確認を行うために使われていた手続きですが、現在ではほぼ形骸化しています。Shared 認証は安全性を増すどころか逆にセキュリティホールになるため(※註)、現在では使用しないことが強く推奨されています。一方、WPA 以降で拡張された認証方式(WPA-PSK や WPA-EAP)は Authentication の枠組みを用いませんので、現在の WiFi では Authentication は実質的な機能を持っていません。
(※註)Authentication に失敗すれば「そのパスワードは違う」ことが判るので、攻撃者は「ありそうなパスワードの組み合わせ」を手当たり次第に乱発することで「正しい」パスワードを探ることができてしまいます。
Association Request は STA からの接続要求、Association Response は AP からの接続許可(あるいは拒否)応答です。ここで交換される情報もおおむねビーコンや Probe-request / Probe-response と同様ですが、レギュレトリ情報や WMM/QOS がらみの情報など、より詳しい情報がオプションで相乗りすることも多いです。特定メーカーの特定アクセスポイント機種にだけつながらないといった「相性」問題はこの Association 手続きで起こることが多く、我々ネットワークエンジニアが真っ先に疑う部分でもあります。
認証手続き(4-way handshake)
Association 手続きの完了をもって、オープンシステム認証(暗号化なし、あるいは WEP)の場合はステーションと AP の接続は完了しますが、WPA セキュリティを用いる場合はこの後に認証手続きが始まります。PSK 認証の場合、Association Response に続いて AP 側から 4-way handshake と呼ばれる手続きが開始されます。
STA→AP Association Request
AP→STA Association Response
AP→STA Key message 1/4
STA→AP Key message 2/4
AP→STA Key message 3/4
STA→AP Key message 4/4
Key message の詳細については触れませんが、Nonce, IV, MIC などと呼ばれる一連の情報を交換するとで、第三者にはわからない方法で秘密鍵を交換しています。
WPA2-PSK を使った接続手続きの例を図2に示します。フレーム番号 1~6 がスキャン手続き、7~12 がアソシエーション手続き、17~23 が 4-way handshake 手続きです。
WiFi の接続失敗...いわゆる「つながらない」問題はこの中の何処かで起こり、たとえば AP が見つからない(SSID 違い)、見つかった AP が接続条件に合致しない(セキュリティ設定違い)、Association Request が拒絶された(国コード違い、要求ビットレート不一致、Listen Interval 範囲逸脱など)、4-way handshake に失敗した(パスワード間違い)などです。
このように、接続失敗原因の殆どは設定ミスですが、稀にバグも含めた「相性問題」が起こることもあります。例えば AP 側の設定で 802.11N を禁止して 802.11b/g モードにしたとき、本来なら載ってはいけない HT Capabilities Information が半ば壊れた状態で(例えば length=0 のヘッダのみ、中身なしフィールドとして)ビーコンに入ってしまうバグ持ちの AP があるとして、ある実装(たとえば Windows PC)は壊れた情報を無視するので接続できるけれど、別の実装(たとえば iPhone)は壊れた情報をエラー扱いするのでつながらない、などという現象として発現します。
この場合は AP 側の設定で 802.11N を許可すると HT Capabilities Information が正しく載るので、「互換性を高めようと思って b/g モードにすると何故か iPhone だけつながらず、11n モードに設定したほうが互換性が高い」という謎現象となり、素人さんには何がなんだかわからないと思います。しかも市販のコンシューマ AP は同じメーカー・同じ型番の製品でも製造ロットによって搭載されているチップセットが異なることがあり、こういった微妙なバグの発現もロットによって変わったりします。
別に脅すわけではなく、コンシューマ AP でも殆どの場合は問題なくつながるのですが、たまにこういう問題が出るとパケットを捕まえて中身を見てみないと何が起こっているのかわかりません。こんな仕事をやっていると「うちの無線 LAN の調子が悪いんだけど、何が悪いか教えてくれない?」みたいな質問を気軽にされたりしますが、無線 LAN について知れば知るほど、症状だけ聞かされたって何が悪いかなんて判るわけがないと思います。
認証手続き(EAPoL)
さて EAP 認証の場合、Association Response に続いて AP 側から EAPoL 手続きが開始されます。
STA→AP Association Request
AP→STA Association Response
AP→STA EAPoL Identity Request
STA→AP EAPoL Identity Response
AP→STA EAPoL Request
STA→AP EAPoL Response
.
.
.
AP→STA EAPoL Success
EAPoL の Request/Response 交換は AP から Success あるいは Failure が返ってくるまで何度も繰り返されます。EAPoL の中身は設定されている EAP タイプ(LEAP, TLS, PEAP など)によって異なり、単純な EAP-MD5 であれば Challenge request / Challenge response の一回で終わりますが、EAP-TLS や PEAP では TLS プロトコルの手続き(Server Hello, Client Hello, Cipher Spec...)をコマ切れに分割して通信するため、通常は 20~30 回のパケット交換が必要となります。
EAP の完了後、通常は 4-way handshake が実行されて暗号鍵の交換が行われます。WiFi の仕様上「認証」と「暗号化」は別規格になっているので、「EAP-PEAP + 暗号なし」や「EAP-TLS + WEP 暗号」という組み合わせで動作させることも可能ではありますが、強力な EAP 認証にわざわざ弱い暗号を組み合わせて使う実用上の意味は殆どありません。
接続後の処理
スキャン・アソシエーション・認証が終わると STA は AP と接続された状態となり、パケットの送受信ができるようになります。しかし接続完了後も、まだやるべき仕事が幾つか残っています。
WPA(WPA/WPA2) を使用している場合、AP は一定期間毎にマルチキャスト鍵(GTK)の更新を行います。GTK 更新に伴い、AP は接続配下にある STA に対し鍵更新通知(EAPoL Group Key Message, 1/2)を送信します。これを受信した STA は適切な鍵更新処理を行い、鍵更新受理(EAPoL Group Key Message, 2/2)を返送しなければなりません。通常、この処理はドライバ上位で動作するサプリカントに実装されます。
AP の実装や設定によっては、一定時間通信が無い STA を自動的に切断してしまうもの(タイムアウト機能)もあります。このとき切断通知(Deauthentication)を出してくれれば STA 側から再接続処理を行うことが可能ですが、通知を出さずに黙って切ってしまう AP もありますし、出したつもりの切断通知が電波状況の一時的悪化によって届かないこともあります。こうなると「時々切れることがある」「一旦切れると再接続しない」という、あまり遭遇したくないタイプの不具合を招くことになります。
こういった「知らない間に切れていた」事態を避けるため、ドライバの実装や設定によっては、上位層の通信がなくとも定期的に通信を行う場合があり、これをキープアライブ(Keepalive)と呼びます。キープアライブで送信するデータはデータを持たないヌルフレーム(Null frame)だったり、自身の IP アドレスを通知する ARP パケット(Gratituous ARP)だったり、これも実装や設定によって異なります。
前述したローミング環境...同じ SSID を持つ AP が複数動作している環境では、STA には「現在接続している AP の電波状況」と「他の AP の電波状況」を把握し、電波状況が悪化した場合は他の AP に接続し直す(ローミング)動作が求められます。ローミング動作は接続完了後に行うドライバの仕事しては最も重要なもので、GTK 更新やキープアライブ以上にトラブルの元になりやすい機能でもあります。
とりあえず「現在接続している AP の電波状況」はビーコンの RSSI から把握できますが、多くの実装ではビーコンだけではなく通信パケットのデータレートや再送回数もローミング計算に含めるようになっています。ビーコンは最も伝達性の高い最低データレート(2.4GHz では 1Mbps DSSS + BPSK、5GHz では 6Mbps OFDM + BPSK + 符号化率 1/2)で送信されるので、必ずしもビーコン RSSI は実際のデータ通信レートでの電波状況を反映しないからです。
「現在接続している AP」よりも厄介なのが「ローミング先候補の AP」の把握です。既に述べたように「無線ノードは原則として同時に1つの周波数(チャネル)しか送受信できない」ので、接続中の AP と通信しながら他チャネル AP のスキャンを行うことはできません。ここは各メーカー毎に工夫されているところで、データ通信が一定時間途絶えたことを検出してスキャンを行ったり、電波状況が一定以上悪化したときにはデータ通信を中断してでもスキャンを行ってローミング先 AP を探すなどの実装がなされています。
WiFi ドライバが複雑な理由
以上、WiFi の接続と通信手続きについて「ごく基本的なところ」を「ばっさり簡略化して」解説してみました。こういった機能の殆どは「WiFi ドライバ」に実装されています(※註)。「Association-Response フレームに含まれる HT Information IE の Rx Supported MCS Scheme フィールドを調べて設定可能な HT 送信レートのビットマップを PHY ドライバに設定する」などという機能も WiFi ドライバの一部なのです。
(※註)一部の機能は「サプリカント」にありますが、広義にはサプリカントも含めて「ドライバ」と呼ぶ場合が多いです。
通常「デバイスドライバ」というのは、データの塊を A 地点(メモリ上)から B 地点(デバイスの接続先)に移す機能しかありません。例えば有線の Ethernet ドライバであれば、上位層から指定されたデータに MAC ヘッダを付けて DMA 経由で MAC コントローラに渡すだけ(あるいはその逆)です。Ethernet にも回線ビジー状態制御程度の簡単なプロトコル(CSMA/CD)はありますが、それは基本的に Ethernet チップのハードウェアで処理され、ドライバソフトウェアがいちいち気にする必要はありません。
ところが WiFi においては、「アクセスポイントに接続する」という動作ひとつを取っても「スキャン」「アソシエーション」「認証」「ローミング監視」「KeepAlive, GTK 監視」という一連の機能を必要とし、その機能一つ一つがまた複数のパケット送受信を必要とするのです。WiFi の規格が段階的に発展してきた事情(WEP, WPA, WPA2 や 11b, 11a/g, 11n など)や、メーカー・実装・設定によってパケット構造やフィールド値が微妙に異なる(仕様上そうなっている場合もあれば、バグでそうなっている場合もある)事情が更にドライバの仕事を面倒にします。「WiFiドライバ」が他のドライバ(例えば有線LANのドライバ)にくらべて桁違いに複雑なのはそういう理由があります。
WiFi の接続手続きなんて標準規格で決まったプロトコルなんだから、ベンダーごと・チップごと・ドライバごとに実装するなんて馬鹿な真似はやめて OS の方に標準機能として実装し、ドライバには「周波数を設定する」「パケットを送信する」「パケットを受信する」程度の機能だけ実装すれば良いのに、と思う方もいるかもしれません(※註)。実際 Windows や MacOS, Linux ではこのようなアプローチも取られてはいます。しかし iTRON などの工業組み込み RTOS にはそんな機能は無いので結局ドライバで全部受け持たなければならないとか、インテリジェント型の WiFi チップではオンチップで接続手続き(の一部)をオフロードするので逆に OS 側の WiFi 機能をバイパスしなければならないとか、いろいろと「大人の事情」があって一本化できません。結局ドライバが様々な矛盾や事情を吸収する「必要悪」として存在し続けることになってしまっています。
(※註)Bluetoothはこれに近い構成になっており、Bluetoothのチップを駆動する「HCIドライバ」と、プロトコルやプロファイルを実装するサービス層はかなり綺麗に分かれています。何でWiFiがそうなっていないかというと...歴史上の経緯や大人の事情というところでしょうか。
Looking Back
1980 年代中頃にエンジニアリングワークステーション(EWS)が流行りはじめたころ、TCP/IPプロトコルは「仕様が重すぎて PC 向きではない」と言われていました。その頃の PC といえば 640KByte のメモリ制限を背負ったシングルタスクの DOS でしたから仕方ありません。DOS PC から Unix 上のファイルを共有する PC-NFS というシステムもありましたが、実装に癖やバグが多くて運用互換性に苦労させられました。
DOS のメモリ制限は intel 80286 という CPU のアーキテクチャに由来しており(※註)、これが事実上撤廃されるのは Windows95 が爆発的に売れた 95 年以降のことになります。しかし初期の Microsoft 製 TCP/IP スタックには Winsock にバグがあったり 95 系と NT 系で動きが違ったりして、2000 年頃になるまで落ち付きませんでした。Unix の世界では 4.3BSD(1986) でほぼ仕様が固まった TCP/IP も、コンシューマ市場に普及して仕様が落ち着くまで 15 年ほどかかったわけです。
(※註)286 の Protected Virtual Address Mode については個人的に恨みがあり、これについて書きだすと長くなり過ぎるので割愛します。今後このブログで取り上げる気もありません。
無線 LAN を取り巻く状況もかつての TCP/IP と似ているような気がします。1999 年 10 月に IEEE802.11b-1999 がリリースされてからちょうど 14 年ほど経つわけですが、まだ落ち着く気配がないのは数年に一度の高速化で後付け拡張が繰り返されたこと( 802.11a/g/n/ac/ad)、セキュリティ規格の WPA2(802.11i) 制定に手間取ったこと(WPA/TKIP という中途半端な過渡規格が出来てしまった)、前回述べた EAP 認証プロトコルの混迷がまだ片付いていないからでしょう。
企業としては仕様が混迷して適度にトラブルが出てくれたほうが仕事が増えて有り難いのかもしれませんが、一介のエンジニアとしては「いいかげんにしてくれ」と思います。