オフィシャルサイト: MADWiFi-Project.org, Atheros Communications

MADWiFi
AtherosワイヤレスLANドライバ

RedHat系ディストリビューションで AtherosチップのワイヤレスLANを動作させる。Atheros社は Linux版ドライバをオープンソースにしており、それが MADWiFi だ。筆者の検証環境は、Red Hat Enterprise Linux 4 ES (RHEL4 Update 5)。ワイヤレスハードウェアは、PC (やや古め) に標準搭載されていた 802.11a/b MiniPCIカードで、Atheros AR5211 チップを搭載している。

Table of Contents

インストール

必要なソフトウェア

madwifi ドライバ(カーネルモジュール) と付属ツールを含む。当解説では、ソースを入手し RPMを作成して使う
wireless-tools RHEL や Fedora Core 標準の RPMパッケージ。iwconfig, iwprv といったチップコントロールユーティリティが含まれる
wpa_supplicant RHEL や Fedora Core 標準の RPMパッケージ。WPA や WPA2 で接続したい場合に必要。なんのセキュリティも掛けないか WEP でしか接続しないなら不要

なお、madwifi は各所からバイナリパッケージもダウンロードできる。URL を挙げておこう;

madwifiソースの入手

安定版を入手する方法と、最新の開発版を subversion コマンドでダウンロードする方法、スナップショットアーカイブを入手する方法がある。安定版は確かに手堅いが、MADWiFi はまだどんどん開発されている最中なので、それでは充分に機能しないことが多い。筆者の経験から最もお勧めなのはスナップショットアーカイブをダウンロードする方法で、これならば既存のいろいろなリビジョンのスナップショットが試せる。(スナップショットは、各時点毎の subversion ディレクトリをアーカイブしたもの)。開発版は madwifi-ng-* という名称になっている。

スナップショットアーカイブの場合

下記リンクから適当なバージョンのソースをダウンロードする。 2007/8/5 現在、筆者の環境では今のところリビジョン 2598 が最適のようで、26xx だとカーネルモジュールのロード時点でカーネルパニックとなってしまった。

http://snapshots.madwifi-project.org/

最新開発版の場合

subversion ユーティリティ (パッケージ名: subversion) がインストールされているか確認し、なければインストールする。サブバージョンは CVS の改良版のようなバージョニングユーティリティだ。ソースを /home/hoge/madwifi_svn/ にダウンロードするものとして例を挙げる。

hoge$ cd ~hoge
hoge$ svn checkout http://madwifi-project.org/svn/madwifi/trunk \
       madwifi_svn
hoge$ cd madwifi_svn
hoge$ svn info

後日、最新のレポジトリと同期するには、下記のようにコマンドするだけ;

hoge$ cd ~hoge/madwifi_svn
hoge$ svn update

安定版の場合

http://sourceforge.net/projects/madwifi/ からダウンロードできる。

RPMforgeから

RPMforge で、当該ディストリビューション下の source/ ディレクトリからダウンロード。

RPMビルドとインストール

実は SPECファイルのひな形がソースの contrib ディレクトリに収録されているが、 RedHat系の kernel-2.6.x 系ディストリビューションではウマくないので、それを元にして修正した SPECファイルおよびパッチを用意した。以下のパーツをまずダウンロードしていただきたい;

ファイル 説明
madwifi.spec スナップショット版およびSVN版用のSPECファイル
madwifi-release.spec 安定版用のSPECファイル。0.9.4 用
madwifi-release-0.9.3.spec 安定版用のSPECファイル。0.9.3 の時代のもの
madwifi-rhlize.patch カーネルモジュールやmanのパスをRedHatの使用に合わせて変更するパッチ
madwifi-include-redhat.patch 0.9.4 のソースコードでは、カーネルが 2.6.22 より古いと skb_* 関数を定義するようになっているが、RedHat系では 2.6.18-x でもそれらファンクションを持っているのでコンパイルに失敗する。それを避けるためのパッチ

SPECファイルの調整

下記の赤字部分を修正する。 revisionsnapshotmadwifi ソースアーカイブファイルのバージョンに合わせ、Release: は自分のディストリビューションに合わせる。

# スナップショットアーカイブの場合。ターボールが madwifi-ng-r2598-20070725.tar.gz の時の例
%define       revision       2598
%define       snapshot       20070725
Release: 6.el4
 
# 安定版の場合。ターボールが madwifi-0.9.3.1.tar.gz の時の例
%define       revision       9
%define       snapshot       3.1
Release: 6.el4

コンポーネントの配置

RPMビルドツリー (よく分からない人は当サイトの RPM解説のページを見ていただくといいかもしれない) の SPECS/ ディレクトリにどちらか必要な方の SPECファイルをコピー。(安定版用を使う場合は madwifi.spec へとリネームしてコピー)。 madwifi のソースアーカイブと上記パッチ類を SOURCES/ ディレクトリへコピーする。パッチの適用は我が SPECファイルの中に記述済みなので、ビルド時に自動的に適用される。

ビルドとインストール

user$ rpmbuild -bb --clean --define "kernel $(uname -r)" /PATH/TO/SPEC_FILE

`--define "kernel ..."' は、カーネルバージョンの判定が上手く行われない時に指定するとよい。RPMビルドツリーの /RPM/YOUR_ARCH/ に完成するパッケージファイルは以下;

パッケージファイル 説明
madwifi-*.rpm athchans, athstats, 80211stats などのユーティリティとその man
madwifi-module-*.rpm カーネルモジュール群(ドライバ)。当方の SPECファイルでは /lib/modules/KVER/kernel/net/ath/ にインストールされるようになっている
madwifi-debuginfo-*.rpm 通常は要らない

設定

WEP接続の場合とWPA/WPA2接続の場合とで設定項目が一部異なる。セキュリティなしでの接続は推奨されないので割愛する。

関係ファイル一覧

/etc/
   \_ modprobe.conf    athドライバのロード定義を書き加える
      wpa_supplicant/
           \_ wpa_supplicant.conf  WPA/WPA2接続のキーネゴシエーション設定ファイル

   \_ init.d/
           \_ wpa_supplicant       WPA/WPA2のキーネゴシエータデーモン起動スクリプト。少々手直しする

   \_ sysconfig/
           \_ wpa_supplicant       wpa_supplicantの起動オプション設定ファイル
              network-scripts/
                       \_ ifcfg-ath0  ネットワークインターフェイス定義ファイル
                          keys-ath0   WEP接続用のパスフレーズを定義。ifupスクリプトによってifcfg-ath0と一緒にインクルードされる

ドライバのロード (WPA/WEP共通)

modprobe.confMADWiFi ドライバのロード定義を書く。設定例;

alias ath0 ath_pci
options ath_pci countrycode=392 autocreate=sta

ネットワークインターフェイスの作成 (WPA/WEP共通)

/etc/sysconfig/network-scripts/ifcfg-ath0 ファイルを作成する。

基本部分。重要な部分を赤で示す。それ以外の汎用的な設定項目については、例えば Red Hat Enterprise Linux 4: リファレンスガイド を参照のこと。

DEVICE=ath0
TYPE=Wireless
ONBOOT=no
BOOTPROTO=none
IPADDR=192.168.1.8
NETMASK=255.255.255.0
GATEWAY=192.168.1.254
USERCTL=yes
IPV6INIT=no

MADWiFi 特有の部分。これらは `ifup ath0' をコールした時に ifup-wireless スクリプトによって iwconfigiwpriv コマンドなどを使って設定されることになる。

ESSID=straypenguin
MODE=Managed
#CHANNEL=1
RATE=Auto
RTS=2346
FRAG=2346
#IWCONFIG="ap 00:FF:FF:FF:FF:FF"
IWPRIV="mode 2 bgscan 0"

特有パラメータの解説。この他にもたくさんあるが、通常使うものだけ述べる。詳しくは MADWiFi ユーザーガイドで述べられている。

変数名 使用される
コマンド
実行時
内部名
説明
ESSID iwconfig essid WLAN親機に設定してあるESSID
MODE iwconfig mode VAPの動作モード。主なモードは、
 Managed: インフラストラクチャ・ステーションモード
 Master: アクセスポイントモード
 Auto: 自動選択
CHANNEL iwconfig channel 接続するチャンネル。ただし MODE=Managed の時は使用されない。999以下の時はチャンネル番号だと解釈される。1000以上の時には周波数だと解釈され、2.412G2412M のように単位文字で指定することもできる。周波数の時は CHANNEL でなく FREQ を使うのが通例
FREQ iwconfig freq 同上。MODE=Managed の時は使用されない
RATE iwconfig rate 通信速度(ビットレート)。例えば 802.11b では 1M, 2M, 5.5M, 11M ... といったようにレートリストは決められており、宙ぶらりんなレートは指定できない (例えば `10M' はダメ)。 Auto は自動選択。 "12M Auto" のように速度値の後に Auto を併記して「12Mを上限として自動選択」という指示をすることもできる
RTS iwconfig rts RTS/CTSネゴシエーション発動最小値(バイト)。ここで指定したサイズ以上のパケットに対しては RTS/CTS制御信号が親機との間で取り交わされる。必須パラメータではないが、パフォーマンスが出ない時には設定してみる。省略時のデフォルトはおそらく "off" つまり機能無効
FRAG iwconfig frag パケットフラグメント最大サイズ(バイト)。ここで指定したサイズを超えるパケットはこのサイズにフラグメントしてから送信される。これもオプション的なパフォーマンスチューニングのひとつ。省略時はおそらく "off" つまり機能無効
IWCONFIG iwconfig * ifup-wireless スクリプトで変数定義されているもの以外に、 iwconfig を使用して設定したいパラメータがあればこの変数に指定する。うまくいかない時には親機のハードウェアアドレスをここで指定 (ap <MAC>) してみるとよい。例でコメントアウトしてあることからも分かるように、通常は必要ない
IWPRIV iwpriv * iwpriv を使って設定したいプライベートパラメータを指定。代表的な個々のコマンドを以下に挙げる;
mode
ドライバのワイヤレスモード指定。主なものは以下。数字(左端)で指定するのが通例のようだが、カッコ内の名称で指定することも可能らしい;
 0 (auto): 自動選択
 1 (11a): 802.11a
 2 (11b): 802.11b
 3 (11g): 802.11g
authmode
認証モード。
 1: オープンシステム
 2: 共有鍵認証(Shared Key)
 3: 802.1x認証
bgscan
ローミングのために「他に使用可能な親機はないか」と常にバックグラウンドスキャンを行うかどうか。単一のアクセスポイントだけ使用していればいい環境では、これを 0 (無効) にすることでパフォーマンスが改善する可能性が高い。MADWiFi ではバックグラウンドスキャンの実行時に一時的に通常トラフィックが停止するからだそうだ
burst, ar, compression
SuperA/Gを有効にするものらしいが、筆者のカードにはその機能がないので未検証

WEPパスフレーズファイル

/etc/sysconfig/network-scripts/keys-ath0 には WEP接続時のパスフレーズを定義しておく。ただし、WPA/WPA2 接続の場合にも、パスフレーズ (ダミーの文字列でも構わない) を書いておく必要がある。というのは、ifup-wireless スクリプトの構造上、KEY が空文字になっていると `iwconfig ath0 key off' が実行されてしまうからだ。このファイルの内容は ifup-wireless スクリプトによって ifcfg-ath0 の内容と合成パースされるわけであり、KEY=.. を ifcfg-ath0 内に書いておくことも可能。ただし、 RedHat がキーだけを別ファイルにしているのには理由がある。このファイルだけパーミションを絞り込んでおく (root:root 0600) ことができるようにというちょっとしたセキュリティだ。

WEPキーには幾つかの書き方がある。

16進値で書く場合はハイフォンで区切っても区切らなくてもよい;
KEY="12AB-CDEF-89"
平文で書く場合は頭に s: を添え、スペースを含む場合は必ずクォートする;
KEY="s:my passWord"
これは DEFAULTKEY="s:my passWord" と同義。
4つまで定義しておくこともできる;
KEY1=12ABCDEF89
KEY2=ABCDEF1234
KEY3=F123456790
KEY4=987654321F
これらは結果的に ifup-wireless スクリプトによって;
iwconfig ath0 key [1] 12ABCDEF89
iwconfig ath0 key [2] ABCDEF1234
iwconfig ath0 key [3] F123456790
iwconfig ath0 key [4] 987654321F
とコールされることになる。

WEP の場合はもうやるべきことはないので 「起動」 の項へジャンプすべし。

WPA/WPA2 キーネゴシエータの設定 (WPA/WPA2接続の場合のみ)

wpa_supplicant は、ドライバと協調して、定期的に変更/交換される WPA および WAP2 キーの面倒を見てくれるデーモン。

wpa_supplicant起動スクリプトのちょっとしたカスタマイズ

設定ファイルで幾つか追加のパラメータを制御したいので、/etc/init.d/wpa_supplicant ファイルを少しいじる。 diff を採っておいたので下記ファイルをご覧いただきたい。追加した設定変数は $SCAN$WAIT だが詳しくは後述する。

wpa_supplicant.diff

wpa_supplicant.conf の設定

ファイルの土台を作る。親機の ESSID が "straypenguin"、平文パスフレーズが "my Secret!" だと仮定する。シェルのメタキャラクタやスペースを含む場合はシングルクォートで囲むのを忘れずに。

root# cd /etc/wpa_supplicant
root# /usr/sbin/wpa_passphrase straypenguin 'my Secret!' \
  >> wpa_supplicant.conf

こうしてできた wpa_supplicant.conf を編集して仕上げる;

ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=wheel
#ap_scan=2
 
network={
	ssid="straypenguin"
	proto=WPA
	#proto=RSN
	key_mgmt=WPA-PSK
	pairwise=CCMP TKIP
	group=CCMP TKIP
	#psk="my Secret!"
	psk=1b221e0ca810fffe9299738de2c674a529eddcbf9b1da6b130c83c554c21411c
}

主なパラメータの解説:

パラメータ 説明
ctrl_interface 外部プログラムの使用できる UNIXドメインソケットファイルを作成するディレクトリ。本稿の例では /var/run/wpa_supplicant/ath0 というソケットファイルができる
ctrl_interface_group 上記ソケットディレクトリおよびソケットファイルの所有グループ。指定しなければ root グループの所有となり root しかアクセスできない
ap_scan (お勧めではない)。APの検索を wpa_supplicant が行うかドライバが行うかの指定。デフォルトは 0 のようで、0 では AP検索も 802.11 関連パラメータの推測もドライバに任せる。 1 では wpa_supplicant が受け持つ。 2 にすると「0 に似ているが、SSIDとセキュリティポリシーに基づいて AP と インターフェイスの結び付けを行う。 ステルスAP に接続する時に使用するとよい」というようなことが述べられているが、これ (2) をやると筆者の環境ではマシンが固まる。そもそも、親機をステルスにすると、筆者の環境ではこれまで一度もつながった試しがない
proto WPA か WPA2 か。 WPA2 の時は RSN と指定しても WPA2 (RSN のエイリアス) と指定してもいい
pairwise ユニキャスト用の、受け入れ可能なサイファースート
group ブロードキャストおよびマルチキャスト用の、受け入れ可能なサイファースート
psk プリシェアードキー (Pre-Shared-Key)。先ほど wpa_passphrase を行った結果、ASCII文字の平文 "this Is my Secret!" と、それを SSID を使ってハッシュした16進数の両方が書かれている。ASCII 平文では 8文字以上 63文字以内、16進の時はきっかり 64文字でなくてはならない。どちらを使っても構わないが、(おそらく) 平文だと wpa_supplicant がいちいちハッシュしなくてはならないので後者のほうがよさそう

キーネゴシエータの起動パラメータ設定

RedHat系の場合、wpa_supplicant の起動パラメータは /etc/sysconfig/wpa_supplicant ファイルで指定することができる。

INTERFACES="-iath0"
DRIVERS="-Dmadwifi"
SCAN=yes
#WAIT=yes

解説:

パラメータ 説明
INTERFACES wpa_supplicant 起動ファイルの仕様から、頭に必ず -i が要る。ベースデバイスである wifi0 でなく VAP である ath* を指定する
DRIVERS カーネル 2.6.14 以降なら -Dwext とするべきらしい。頭に必ず -D が要る
SCAN 当方の起動スクリプトパッチによってのみ使用可能となる変数。 yes, Yes, 1 のいずれかにすると、wpa_supplicant デーモン開始直後に `iwlist ath0 scan' が行われる。検証してみて、そのほうが確実に AP が検出されて wlan_tkip などの追加ドライバがきちんとロードされるようだったからだ
WAIT これも当方の起動スクリプトパッチによってのみ使用可能となる変数。 `ifup ath0' よりも先に wpa_supplicant を起動した場合に、ath0 がアップするまで wpa_supplicant が待機するようにさせる

起動

  1. ath0 インターフェイスをマシン起動と同時に活性化させたいなら、 /etc/sysconfig/network-scripts/ifcfg-ath0ONBOOTyes にしておく。GATEWAY の書いてあるインターフェイスが他にも (例えば ifcfg-eth0) あるのなら、それの GATEWAY=.. をコメントアウトするか、その ONBOOTno にしておく必要もあるだろう。
  2. 同上、且つ、WPA/WPA2 接続の場合は、wpa_supplicant デーモンも自動起動にする。
    root# chkconfig wpa_supplicant on
  3. ath_pci ドライバをロードさせるためにマシンを再起動する。
  4. 自動起動にした場合には、もう接続が成り立っているはずだ。そうしなかった人は ath0 インターフェイスと wpa_supplicant を立ち上げる。他のLANインターフェイスを殺すかどうかは環境による;
  5. root# ifdown eth0
    root# ifup ath0
  6. 自動起動でなく WPA/WPA2 接続の場合は、wpa_supplicant デーモンを起動する;
    root# service wpa_supplicant start

動作確認コマンド

root# lsmod
root# iwconfig
root# ifconfig -a
root# ip link show
root# ping <GATEWAY>
root# iwlist ath0 scan
root# iwlist ath0 channel
root# athstats
root# 80211stats