[AP]
# ./hostapd /etc/hostapd/hostapd.conf
ただし、hostapd.conf には、下記を記載。
wpa = 1(WPA) or 2(WPA2) or 3(WPA/WPA2 mixed)
wpa_passphrase = my_passphrase
[STA]
# wpa_passphrase my_ssid my_passphrase
# wpa_supplicant -i wlan1 /etc/wpa_supplicant/wpa_supplicant.conf
(これで、iw connect を実行しなくても自動的に接続される)
2012年3月1日木曜日
WLAN 接続メモ
[AP]
# ./hostapd hostapd.conf
[STA]
# iw -i wlan1 scan
# iw -i wlan1 connect my_ssid
# iw -i wlan1 disconnect
[capture(1024Byte までダンプする)]
# tcpdump -i hwsim0 -w dump.pcap -s 1024
# ./hostapd hostapd.conf
[STA]
# iw -i wlan1 scan
# iw -i wlan1 connect my_ssid
# iw -i wlan1 disconnect
[capture(1024Byte までダンプする)]
# tcpdump -i hwsim0 -w dump.pcap -s 1024
2012年2月25日土曜日
Linux で WPS を使う方法
STA(wext/nl80211) が Enrollee、AP(nl80211) が Registrar の場合、
■ STA 側
■ AP 側 (hostapd)
# cat hostapd.conf
wpa=2
wpa_passphrase=xxxxxxxx
wps_state=2 (configured)
eap_server=1
hostapd 起動後
# hostapd_cli wps_pbc (PBC の場合)
# hostapd_cli wps_pin any 12345678 (PIN の場合)
WPS の実行と、configure 後の WPA2 による再接続は続けて行われる。
また、WPS 実行後、wpa_supplicant.conf が更新される。
(update_config=1 を書かなければ更新されない。)
# cat wpa_supplicant.conf
ctrl_interface=/var/run/wpa_supplicant
update_config=1
network={
ssid="myssid"
psk="xxxxxxxx" # PSK ではなく、パスフレーズが書かれている
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP
auth_alg=OPEN
}
■ STA 側
# cat wpa_supplicant.conf
ctrl_interface=/var/run/wpa_supplicant
update_config=1
ctrl_interface=/var/run/wpa_supplicant
update_config=1
wpa_supplicant 起動後
# wpa_cli wps_pbc (PBC の場合)
# wpa_cli wps_pin any 12345678 (PIN の場合)
# wpa_cli wps_pin any 12345678 (PIN の場合)
■ AP 側 (hostapd)
# cat hostapd.conf
wpa=2
wpa_passphrase=xxxxxxxx
wps_state=2 (configured)
eap_server=1
hostapd 起動後
# hostapd_cli wps_pbc (PBC の場合)
# hostapd_cli wps_pin any 12345678 (PIN の場合)
WPS の実行と、configure 後の WPA2 による再接続は続けて行われる。
また、WPS 実行後、wpa_supplicant.conf が更新される。
(update_config=1 を書かなければ更新されない。)
# cat wpa_supplicant.conf
ctrl_interface=/var/run/wpa_supplicant
update_config=1
network={
ssid="myssid"
psk="xxxxxxxx" # PSK ではなく、パスフレーズが書かれている
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP
auth_alg=OPEN
}
2012年2月23日木曜日
カーネルモジュールのデバッグ
カーネルモジュールのデバッグ方法として、
printk + dmesg があるが、多くの文字列を出力するには適さない。
一つの方法として、proc ファイルシステムを使う方法がある。
■使い方
cat /proc/myprocentry
とすると、情報が読み出せる。
■ハンドラの登録
struct proc_dir_entry *dirp;
dirp = (struct proc_dir_entry *) create_proc_entry("/proc/myprocentry", 0444, (struct proc_dir_entry *) 0);
dirp->read_proc = myproc_read;
printk + dmesg があるが、多くの文字列を出力するには適さない。
一つの方法として、proc ファイルシステムを使う方法がある。
■使い方
cat /proc/myprocentry
とすると、情報が読み出せる。
■ハンドラの登録
struct proc_dir_entry *dirp;
dirp = (struct proc_dir_entry *) create_proc_entry("/proc/myprocentry", 0444, (struct proc_dir_entry *) 0);
dirp->read_proc = myproc_read;
これで、/proc/myprocentry に読み出しを行った際に、myproc_read が呼び出されるようになる。
wireless extensions
iwconfig などのコマンドは、内部で wireless extensions のインタフェースを使っている。
その先で、さらに呼ばれるのが、wireless_handlers である。
■wireless_handlers の登録
mynet_dev = alloc_netdev(PRIV_SIZE, MYDEV_NAME, ether_setup);
mynet_dev->netdev_ops = &mynet_dev_ops;
mynet_dev->wireless_handlers = &mynet_wext_handlers;
register_netdev(mynet_dev);
net_device の wireless_handlers に適切な関数を登録しておけば、
iwconfig から(ioctl 経由で)呼ばれる。
登録の仕方は、
static const iw_handler cfg80211_handlers[] = {
[IW_IOCTL_IDX(SIOCGIWNAME)] = (iw_handler) cfg80211_wext_giwname,
[IW_IOCTL_IDX(SIOCSIWFREQ)] = (iw_handler) cfg80211_wext_siwfreq,
[IW_IOCTL_IDX(SIOCGIWFREQ)] = (iw_handler) cfg80211_wext_giwfreq,
[IW_IOCTL_IDX(SIOCSIWMODE)] = (iw_handler) cfg80211_wext_siwmode,
[IW_IOCTL_IDX(SIOCGIWMODE)] = (iw_handler) cfg80211_wext_giwmode,
[IW_IOCTL_IDX(SIOCGIWRANGE)] = (iw_handler) cfg80211_wext_giwrange,
[IW_IOCTL_IDX(SIOCSIWAP)] = (iw_handler) cfg80211_wext_siwap,
[IW_IOCTL_IDX(SIOCGIWAP)] = (iw_handler) cfg80211_wext_giwap,
[IW_IOCTL_IDX(SIOCSIWMLME)] = (iw_handler) cfg80211_wext_siwmlme,
[IW_IOCTL_IDX(SIOCSIWSCAN)] = (iw_handler) cfg80211_wext_siwscan,
[IW_IOCTL_IDX(SIOCGIWSCAN)] = (iw_handler) cfg80211_wext_giwscan,
}
const struct iw_handler_def cfg80211_wext_handler = {
.num_standard = ARRAY_SIZE(cfg80211_handlers),
.standard = cfg80211_handlers,
};
など。詳しくは、/usr/src/linux/net/wireless/wext-compat.c を参照。
iwconfig を引数なしで実行するためには、少なくとも SIOCGIWNAME に対するハンドラの登録が必要。それ以外の iwconfig のコマンドを実行するためには、他の SIOC*IW ハンドラを実装する必要あり。
ifconfig
ネットワークインタフェースを追加し、ifconfig できるところまで行います。
■ネットワークインタフェースの確保
struct net_device *mynet_dev;
mynet_dev = alloc_netdev(PRIV_SIZE, NDEV_NAME, ether_setup);
// PRIV_SIZE にプライベートデータを保存する領域のサイズ(int。特になければ 0)
// NDEV_NAME にネットワークインタフェースの名前 (char *)
■ネットワークインタフェースの登録
mynet_dev->netdev_ops = &mynet_dev_ops;
register_netdev(mynet_dev);
これで、カーネルにネットワークインタフェースの登録が完了する。
ただし、最低限、下記の netdev_ops を定義しておかなければならない。
static struct net_device_ops mynet_dev_ops = {
.ndo_init = mynet_init,
.ndo_open = mynet_open,
.ndo_start_xmit = mynet_xmit,
};
.ndo_open が ifconfig を実行したとき呼ばれる関数である。
また、.ndo_init は reigster_netdev() 実行時に呼ばれる関数、
ndo_start_xmit は、パケット送信時に呼ばれる関数である。
ndo_start_xmit は、パケット送信時に呼ばれる関数である。
カーネルモジュールの書き方
モジュール名 moduletest のモジュールを作ります。
■使い方
(モジュールの読み込み)
# insmod moduletest.ko
(モジュールの取り外し)
# rmmod moduletest
■C コード
#include <linux/module.h>
#include <linux/kernel.h> // for printk
#include <linux/sched.h> // for jiffies
// insmod 時に呼ばれる
int init_module()
{
printk("module being installed at %lu\n", jiffies);
return 0; // 0 以外の値を返すと、insmod は成功しない
}
// rmmod 時に呼ばれる
void cleanup_module()
{
printk("module being removed at %lu\n", jiffies);
}
■注3
■使い方
(モジュールの読み込み)
# insmod moduletest.ko
(モジュールの取り外し)
# rmmod moduletest
■C コード
#include <linux/module.h>
#include <linux/kernel.h> // for printk
#include <linux/sched.h> // for jiffies
// insmod 時に呼ばれる
int init_module()
{
printk("module being installed at %lu\n", jiffies);
return 0; // 0 以外の値を返すと、insmod は成功しない
}
// rmmod 時に呼ばれる
void cleanup_module()
{
printk("module being removed at %lu\n", jiffies);
}
■Makefile
KERNEL_SRCDIR = /usr/src/linux
BUILD_DIR = $(shell pwd)
TARGET = moduletest
obj-m := $(TARGET).o
all:
make -C $(KERNEL_SRCDIR) M=$(BUILD_DIR) modules
■注1
カーネルのシンボルを使うので、カーネルのヘッダファイルが必要。
apt-get install linux-headers などを行う。
■注2
init_module, cleanup_module という名前を変えるためには、
module_init, module_exit などのマクロを使う。
static int __init modtest_module_init( void )
{
printk( KERN_INFO "modtest is loaded\n" );
return 0;
}
static void __exit modtest_module_exit( void )
{
printk( KERN_INFO "modtest is removed\n" );
}
module_init( modtest_module_init );
module_exit( modtest_module_exit );
デバッグ出力したいときは、printk を使う。出力は dmesg で確認する。
■注4
モジュールが insmod できたかどうかは lsmod で確認する。
■注4
モジュールが insmod できたかどうかは lsmod で確認する。
登録:
投稿 (Atom)