2009年11月14日土曜日

(FreeBSD) DSiのために、廃物利用で無線LANアクセスポイントを作ってみた

802.11bだけ対応という、ずいぶんと古い、PCI接続の無線LANカードを手に入れました。
PCIではありますが、よく見ると、カバーで隠された中に、mini PCIなカードが入ってるようでしたが。



実家には無線LANのアクセスポイントがないので、この無線LANカードをFreeBSDなパソコンに挿して、Nintendo DSiでインターネット接続できるようにしてみました。



20091112





FreeBSDは2~3ヶ月前の7.2-STABLE。
dmesgで見ると、こんな感じで、wiドライバで認識されていました。

wi0: <Intersil Prism2.5> mem 0xee3ff000-0xee3fffff irq 22 at device 11.0 on pci1
wi0: [ITHREAD]
wi0: using RF:PRISM2.5 MAC:ISL3874A(Mini-PCI)
wi0: Intersil Firmware: Primary (1.1.1), Station (1.5.6)
wi0: Ethernet address: うんたらかんたら

よくわかってないんですが、無線LANの機器には、アクセスポイントとして使えるものと、使えないものがあるそうです。wiのマニュアルを見ると

http://www.freebsd.org/cgi/man.cgi?query=wi&manpath=FreeBSD+7.2-RELEASE

Cards based on the Intersil PRISM chips also support a host-based access point mode

と書かれていて、ラッキーなことに、これはアクセスポイントとして使えるものでした。



私は、有線LANばっかりで、無線LANってほとんど使ったことがないんですが、そういうわけで、FreeBSDでも無線LANを使ったことがありませんでした。

FreeBSD Handbookに、けっこう詳しくかかれているようです。

31.3 Wireless Networking
http://www.freebsd.org/doc/en/books/handbook/network-wireless.html


ざっと眺めてみただけですが、/etc/rc.d/netif start のような「いまどきのFreeBSDの作法」っぽいところ、なるほどと思いました。

まあ、無線LANといっても、ネットワークデバイスとしてつながってしまえば、イーサネットとそんなに違わないだろう、と思いまして、Handbookではなく、wiのマニュアルを主に参考にして、ちょこちょこやってみました。

http://www.freebsd.org/cgi/man.cgi?query=wi&manpath=FreeBSD+7.2-RELEASE

えーと、まず、

# ifconfig wi0
wi0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether うんたらかんたら
        media: IEEE 802.11 Wireless Ethernet autoselect (none)
        status: no carrier
        ssid "" channel 1 (2412 Mhz 11b)
        stationname "FreeBSD WaveLAN/IEEE node"
        authmode OPEN privacy OFF bmiss 7 scanvalid 60 bintval 0

という感じになってます。


# ifconfig wi0 up scan

とやると、どのチャンネルが使われているか一覧が見られるそうです。・・・まったく使われていませんでした。

# ifconfig wi0 list caps
wi0=10701<WEP,IBSS,PMGT,HOSTAP,MONITOR>

とやると、無線LANカードが、どんな機能をもっているのか、簡潔に表示されるそうです。WEPだけなんですね。まあ、Nintendo DSにはピッタリ、と言えなくもないですけど。




WEPで、はまった


無線LANなので、暗号化しておこうかと思ってもWEPしかないんですが、ないよりはましなので一応WEPを使うことにしました。

イーサネットと同じように、ifconfigコマンドでやればいいんですが、無線LANで特徴的なのは、ssid、media、mediaopt、wepmode、wepkeyなどのキーワードを指定することです。

それでも、あっというまにネットワークインターフェイスのセットアップができて、いざ動作確認をしてみると(tcpdump -i wi0 で眺めていた)、



  1. DSiは、DHCPでIPアドレスを取りに来て、


  2. DHCPサーバーが、IPアドレスをofferしてるんだけど


  3. DSiは、無視している


という感じ。これで、1~2時間、悩みました。

やっとわかったのは、deftxkeyというのも指定しなければいけなかった、ということ。

wepkeyは何種類か登録できることになっているんですが、送信時にどれを使うかを指定する必要があったのでした。

それから、wepkeyは、普通のテキストで指定するのか、16進数で指定するのか、うっかり間違えそうです。



DSiのほうでは、「AAAAA」のように普通のテキストで指定します。



ifconfigでも、普通のテキストで指定できるようですが、wiのマニュアルでは、「wepkey 1:0x4141414141」のように16進数で指定するのを推奨しているみたいです。

テキストを16進数への変換するには、たとえば

% echo -n "HelloWorld123" | hd
00000000  48 65 6c 6c 6f 57 6f 72  6c 64 31 32 33           |HelloWorld123|

とかやれば、0x48656c6c6f576f726c64313233 になるとわかります。







とりあえずのセットアップ結果

ネットワーク環境

有線LANが、192.168.1.0/255.255.255.0
無線LANが、192.168.10.0/255.255.255.0
ADSLルータが、192.168.1.1
FreeBSDを無線LANルータにする
FreeBSDの有線LAN側が、192.168.1.2。fxpドライバを使用。
FreeBSDの無線LAN側が、192.168.10.1。wiドライバを使用。
portsで、net/isc-dhcp31-serverをインストールした。
FreeBSDで、firewallを設定しようと思ったけど、今回はパス。


/etc/rc.confに書いた内容

ifconfig_fxp0="inet 192.168.1.2  netmask 255.255.255.0"
ifconfig_wi0="inet 192.168.10.1 netmask 255.255.255.0 ssid 適当に何か英数字 media DS/11Mbps mediaopt hostap wepmode on wepkey 1:0x48656c6c6f576f726c64313233 deftxkey 1 stationname これも適当"
gateway_enable="YES"
dhcpd_enable="YES"
dhcpd_flags="-q"
dhcpd_ifaces="wi0"


当たり前のことですが、wepkeyは秘密の呪文なので、このままコピペして使ってはいけません。

stationnameはどこで使われるのかよくわからなかったのですが、ifconfigで見ると、デフォルトでは、FreeBSD WaveLAN/IEEE nodeになるようです。気持ち悪いので、適当な文字列を指定しました。

wi0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether なんとかかんとか
        inet 192.168.10.1 netmask 0xffffff00 broadcast 192.168.10.255
        media: IEEE 802.11 Wireless Ethernet DS/11Mbps <hostap> (DS/2Mbps <hostap>)
        status: associated
        ssid 適当に何か英数字 channel 1 (2412 Mhz 11b) bssid なんとかんとか
        stationname "FreeBSD WaveLAN/IEEE node"
        authmode OPEN privacy MIXED deftxkey 1 wepkey 1:104-bit scanvalid 60
        dtimperiod 1



dhcpd.confに書いた内容

option domain-name "example.org";
option domain-name-servers 192.168.1.1;

default-lease-time 600;
max-lease-time 7200;

ddns-update-style ad-hoc;

log-facility local7;

subnet 192.168.10.0 netmask 255.255.255.0 {
  #range 192.168.10.10 192.168.10.19;
  range dynamic-bootp 192.168.10.10 192.168.10.19;
  option routers 192.168.10.1;
  option broadcast-address 192.168.10.255;
  option domain-name-servers 192.168.1.1;
  default-lease-time 600;
  max-lease-time 7200;
}


以上のような感じで、なんとか動くようになりました。







「ifconfig wi0 ~」で設定をいじくりまくってたとき、なんかおかしいなと思ったときは、ifconfig wi0 downしてから、ifconfig wi0 ~ その他で設定して、ifconfig wi0 upすると、うまくいったような・・・気のせい? おまじない?


動作確認で一番役に立ったのは、tcpdumpでした。tcpdump -i wi0で、無線LANの通信状況を常に眺めていました。

tcpdumpの出力を見てると、こっちが送信しているのに、なぜかDSiは受信してくれないな?と不思議に思っていて、wiのマニュアルを確認したところ、deftxkeyに気がついた、という次第です。

苦労すること数時間、DSiでインターネットへの接続をテストしたとき、conntest.nintendowifi.netとの間で通信している様子を見て、やっと動いた!と感動してしまいました。



DHCP周りの挙動を確認するには、dhcpdをデバッグモードで動かすのがよくて、

# ps axww | grep dhcp
50709  ??  Ss     0:00.14 /usr/local/sbin/dhcpd -q -cf /usr/local/etc/dhcpd.conf -lf /var/db/dhcpd/dhcpd.leases -pf /var/run/dhcpd/dhcpd.pid -user dhcpd -group dhcpd wi0

とやると、どういう引数でdhcpdが動いてるかわかるので、

# /usr/local/etc/rc.d/isc-dhcpd stop

で、dhcpdを止めてから、引数に「-d」を追加して、「-q」は消してもいいかな、

# /usr/local/sbin/dhcpd -d -cf /usr/local/etc/dhcpd.conf -lf /var/db/dhcpd/dhcpd.leases -pf /var/run/dhcpd/dhcpd.pid -user dhcpd -group dhcpd wi0

と実行。

これで、こんな感じで、ログメッセージが表示されます。

Internet Systems Consortium DHCP Server V3.1.3
Copyright 2004-2009 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/
Wrote 0 leases to leases file.
Listening on BPF/wi0/ほにゃらら/192.168.10/24
Sending on   BPF/wi0/ほにゃらら/192.168.10/24
Sending on   Socket/fallback/fallback-net
DHCPDISCOVER from だれか via wi0
DHCPOFFER on 192.168.10.10 to だれか (NintendoDS) via wi0
DHCPDISCOVER from だれか (NintendoDS) via wi0
DHCPOFFER on 192.168.10.10 to だれか (NintendoDS) via wi0





うまく動いていない場合、原因となる箇所は、いくつもあります。なんかもう、ロールプレイングゲームみたいですね。フラグが立った?



  • FreeBSDの無線LANデバイスは、動いているのか


  • ルーターとしての設定は正しいか


  • DHCPサーバーの設定は正しいか


  • DSiの設定は正しいか


問題を切り分けるために、すべてを一度に動かさずに、シンプルな構成で、1つずつ、機能が動いているかどうか確認していくのが肝心。



あんまりよくないんですが、私の場合、WEPを使わないようにして動作確認してみると、ちゃんと動いたので、WEPまわりに問題があるはずだ、と確証しました。



ブリッジ接続でやってみる

LAN側にADSLルーターがいるので、FreeBSD上でルーターやらDHCPサーバーを動かさずに、ADSLルーターに全部まかせてしまう、という手抜きもできます。

でも、暗号化がWEPで、あまりにも弱すぎるので、止めたほうがいいよね。絶対に。


wiのマニュアルにサンプルが載っているので、それを参考にしながら、たしか、こんな感じで動きました。

ifconfig wi0 inet up ssid 適当に何か英数字 media DS/11Mbps mediaopt hostap wepmode on wepkey 1:0x48656c6c6f576f726c64313233 deftxkey 1 stationname これも適当"

sysctl net.inet.ip.check_interface=0

ifconfig bridge0 create

ifconfig bridge0 addm wi0 addm fxp0 up



試行錯誤しているときに、wi0にIPアドレスを割り振ってしまったんですが、そうするとやっぱりブリッジとして動作しなくなるみたいです。
一度、ネットワークインターフェイスにIPアドレスを割り当ててしまったら、どうやって解除するんですかね?

結局、

ifconfig wi0 inet 192.168.10.1 -alias

のようにして目的は果たせたんですが、そういうものでしょうか。







やっぱり、ファイアーウォールの設定もしなくちゃいけないなぁ。







(2009/11/15追記)



今、無線LANルーターって、3000円台で買えちゃうんだ・・・と思った。





0 件のコメント:

コメントを投稿