2008年8月25日月曜日

mac80211 の Master mode

2.6.27-rc にて mac80211_hwsim なる WLAN デバイスのシミュレータが入ったとのお話。Documentation/networking/mac80211_hwsim/README を眺めると
Please note that the current Linux kernel does not enable AP mode, so a
simple patch is needed to enable AP mode selection:
http://johannes.sipsolutions.net/patches/kernel/all/LATEST/006-allow-ap-vlan-modes.patch
ここにある###-allow-ap-vlan-modes.patch がソレなのだが、コメントが...
Don't allow doing it with wext because then
people will just attempt to do it manually (without hostapd) and
complain that it doesn't work.
あー...オレオレ。該当。文句言う言う。なんて話はさておき。

とは言え mac80211 なデバイス全てで hostapd が動くわけではなさげ。と言うか IEEE80211_IF_TYPE_AP が有効なわけではなさげ。手元にあるデバイス...zd1211rw, ath5k, rtl8187, rt2x00 内 2.6.27-rc にて動作するのは rt2x00 のみ。また ath5k は近々 という感じ。で rt2x00 の何を使っているかと言えば
$ lsusb
...
Bus 003 Device 003: ID 0411:0067 MelCo., Inc. WLI-U2-KG54-AI WLAN
...
バッファローの製品。他は?
fgrep "USB_DEVICE(" /usr/src/testing/drivers/net/wireless/rt2x00/*.c
なんてたたくと山ほど。USB_DEVICE の中、例えば rt73usb.c に、こんな行
        /* Buffalo */
{ USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) },
があったら、Google 様に "0411:00f4"と尋ねると、ヒントが見付かることもアリ。

ところで WPA や RSN ではない Master mode とするために、こんな抜粋してみたけど...最初のドキュメント通り、Master mode になるも ip link set 〜 up あるいは ifconfig 〜 up なんてしてもリンクアップしているように見えますが、動きませんっ。ええ、理解してませんっ。
#include <stdio.h>
#include <linux/nl80211.h>

#include <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h>
#include <netlink/genl/mngt.h>
#include <netlink/route/link.h>

int name2ifindex(char *ifname)
{
struct nl_handle *nlh;
struct nl_cache *link_cache;
int ifindex = -1;

if (!ifname)
return -1;

nlh = nl_handle_alloc();
if (!nlh)
return -1;

if (nl_connect(nlh, NETLINK_ROUTE) < 0)
goto errout;

link_cache = rtnl_link_alloc_cache(nlh);
if (!link_cache)
goto errout;

ifindex = rtnl_link_name2i(link_cache, ifname);

nl_cache_free(link_cache);
errout:
nl_close(nlh);
nl_handle_destroy(nlh);

return ifindex;
}

int main(int argc, char *argv[])
{
struct nl_handle *h;
struct nl_msg *msg;
struct nl_cache *cache;
struct genl_family *family;
int ifindex = name2ifindex(argv[1]);

if (ifindex < 0) {
fprintf(stderr, "could not get ifindex: %s\n", argv[1]);
return -1;
}

h = nl_handle_alloc();
if (!h) {
nl_perror("nl_handle_alloc");
return -1;
}

if (genl_connect(h) < 0) {
nl_perror("genl_connect");
goto nla_handle_failure_2;
}

cache = genl_ctrl_alloc_cache(h);
if (!cache) {
nl_perror("genl_ctrl_alloc_cache");
goto nla_handle_failure_1;
}

family = genl_ctrl_search_by_name(cache, "nl80211");
if (!family) {
nl_perror("search nl80211 family");
goto nla_cache_failure;
}

msg = nlmsg_alloc();
if (!msg) {
nl_perror("nlmsg_alloc");
goto nla_cache_failure;
}

genlmsg_put(msg, 0, 0, genl_family_get_id(family), 0,
0, NL80211_CMD_SET_INTERFACE, 0);
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_AP);


if (nl_send_auto_complete(h, msg) < 0 || nl_wait_for_ack(h) < 0)
nl_perror("Failed to set interface to master mode");

nla_put_failure:
nlmsg_free(msg);
nla_cache_failure:
nl_cache_free(cache);
nla_handle_failure_1:
nl_close(h);
nla_handle_failure_2:
nl_handle_destroy(h);

return 0;
}

0 件のコメント: