3

我正在Ubuntu Linux 12.04环境下开发WiFi工具,需要在不同通道之间切换WiFi接口。

目前我在名为 ws80211_set_freq 的函数中的 Wireshark 源代码 ws80211_utils.c 中找到了解决方案,但我不知道如何将它实现到我的源代码中,以及要包含哪些库以及如何编译,以便我可以测试它。

问题是您必须使用的参数和标志太多。另外,这是我第一次开发netlink wifi工具。

如果有任何好的手册可以从哪里开始以及如何使用 netlink 呼叫 WiFi,请提供链接。

非常感谢我提前!

4

2 回答 2

8

在当前的 Linux 版本中,nl80211是与无线子系统“对话”的正确方式。请注意,您不能为每个驱动程序和每个操作模式(主、客户端、监视器等)任意设置通道。某些驱动程序仅在相应接口“关闭”时才允许更改通道。在客户端(“托管”)等模式下,根本无法设置通道,因为它是由接入点定义的。

另请注意,并非所有无线设备驱动程序都使用 mac80211/cfg80211。对于那些不使用它的驱动程序,您要么必须使用旧的无线扩展 API,要么(甚至更糟)特定于驱动程序的专有 API。

遗憾的是,似乎没有关于 nl80211 接口的最新完整文档。如果我错了,请纠正我!

您查看其他程序源代码的方法似乎是一种合理的方法。您还可以使用命令行实用程序源代码。有一个设置频道的选项:iwiw

$ iw --help
Usage:  iw [options] command
Options:
    --debug     enable netlink debugging
    --version   show version (3.2)
Commands:
…
dev <devname> set channel <channel> [HT20|HT40+|HT40-]
…

在phy.ciw的第91ff行。你可以找到iw wlan0 set channel执行时调用的代码。但是,这段代码绝对不容易阅读。看起来 NL80211_CMD_SET_WIPHY命令与NL80211_ATTR_WIPHY_FREQ属性结合是要走的路。

这个 SO 答案中,您可以找到使用 nl80211 的框架程序。此外,Aircrack-ng ( src/osdep/linux.c, function linux_set_channel_nl80211) 的代码可以作为蓝图。

于 2014-03-02T16:55:34.773 回答
4

接受的答案目前是正确的,但是还没有发布示例代码来解决 OP 的问题(即使晚了将近 4 年),所以我想我会在这里为任何未来的搜索引擎用户添加这个。它改编自这个SO question和前面提到的特定 Aircrack-ng 文件(/src/aircrack-osdep/linux.c ,第 1050 行)。

#include <net/if.h>
#include <netlink/netlink.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h>
#include <linux/nl80211.h>

int main(int argc, char *argv[])
{
    /* The device's name and the frequency we wish to set it to. */
    char *device = "wlan1";
    int frequencyMhz = 2442;

    /* Create the socket and connect to it. */
    struct nl_sock *sckt = nl_socket_alloc();
    genl_connect(sckt);

    /* Allocate a new message. */
    struct nl_msg *mesg = nlmsg_alloc();

    /* Check /usr/include/linux/nl80211.h for a list of commands and attributes. */
    enum nl80211_commands command = NL80211_CMD_SET_WIPHY;

    /* Create the message so it will send a command to the nl80211 interface. */
    genlmsg_put(mesg, 0, 0, genl_ctrl_resolve(sckt, "nl80211"), 0, 0, command, 0);

    /* Add specific attributes to change the frequency of the device. */
    NLA_PUT_U32(mesg, NL80211_ATTR_IFINDEX, if_nametoindex(device));
    NLA_PUT_U32(mesg, NL80211_ATTR_WIPHY_FREQ, frequencyMhz);

    /* Finally send it and receive the amount of bytes sent. */
    int ret = nl_send_auto_complete(sckt, mesg);
    printf("%d Bytes Sent\n", ret);

    nlmsg_free(mesg);
    return EXIT_SUCCESS;

    nla_put_failure:
        nlmsg_free(mesg);
        printf("PUT Failure\n");
        return EXIT_FAILURE;
}

gcc main.c $(pkg-config --cflags --libs libnl-3.0 libnl-genl-3.0). iw wlan1 info执行后,使用例如或检查设备的频率/频道iwconfig。这里没有严重的错误检查,所以您只会注意到消息是否已发送。希望这可以帮助像我这样的人从无线扩展过渡到 cfg80211 和 nl80211。

于 2018-12-03T21:46:20.160 回答