C 使用netlink API设置无线通道

C 使用netlink API设置无线通道,c,linux,wifi,netlink,C,Linux,Wifi,Netlink,我正在Ubuntu Linux 12.04环境中开发WiFi工具,我需要在不同频道之间切换WiFi接口 目前,我在Wireshark源代码ws80211_utils.c中找到了名为ws80211_set_freq的函数中的解决方案,但我不知道如何将其实现到我的源代码中,包括哪些库以及如何编译,以便对其进行测试 问题是您必须使用太多的参数和标志。此外,这是我第一次开发netlink wifi工具 如果有任何好的手册可以从哪里开始以及如何使用netlink呼叫WiFi,请向我提供链接 非常感谢我的进

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

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

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

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


非常感谢我的进步

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

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

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

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

$ 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-]
…
$iw--帮助
用法:iw[options]命令
选项:
--调试启用netlink调试
--版本显示版本(3.2)
命令:
…
开发设置通道[HT20 | HT40+| HT40-]
…
iw
的第91ff行。您可以在执行
iw wlan0 set channel
时找到调用的代码。然而,这段代码绝对不容易阅读。看起来像是
NL80211_CMD_SET_WIPHY
命令与
NL80211_ATTR_WIPHY_FREQ
属性结合使用是一种方法


在中,您可以找到一个使用nl80211的框架程序。另外,Aircrack ng的代码(,function
linux\u set\u channel\u nl80211
)可以作为一个蓝图。

目前公认的答案是正确的,但还没有发布示例代码来解决OP的问题(即使晚了近4年),所以我想我会在这里为任何未来的搜索引擎用户添加此代码。它改编自此文件和前面提到的特定Aircrack ng文件(,第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;
}
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
/*设备名称和我们希望设置的频率*/
char*device=“wlan1”;
int-frequencyMhz=2442;
/*创建套接字并连接到它*/
结构nl_sock*sckt=nl_socket_alloc();
genl_connect(sckt);
/*分配一条新消息*/
结构nl_msg*mesg=nlmsg_alloc();
/*检查/usr/include/linux/nl80211.h以获得命令和属性的列表*/
enum nl80211_commands command=nl80211_CMD_SET_WIPHY;
/*创建消息,以便将命令发送到nl80211接口*/
genlmsg_put(mesg,0,0,genl_ctrl_resolve(sckt,“nl80211”),0,0,command,0);
/*添加特定属性以更改设备的频率*/
NLA_PUT_U32(mesg,NL80211_ATTR_iIndex,如果名称为索引(设备));
NLA输出32(mesg、NL80211、ATTR、WIPHY、frequencyMhz);
/*最后发送并接收发送的字节数*/
int ret=nl发送自动完成(sckt,mesg);
printf(“%d字节已发送\n”,ret);
无nlmsg_(mesg);
返回退出成功;
nla_put_故障:
无nlmsg_(mesg);
printf(“放置失败\n”);
返回退出失败;
}
使用gcc main.c$(pkg config--cflags--libs libnl-3.0 libnl-genl-3.0)编译此文件。。
执行后,使用例如
iw wlan1 info
iwconfig
检查设备的频率/频道。这里没有严重的错误检查,因此您将注意到消息是否已发送。希望这能帮助像我这样的人从无线扩展过渡到cfg80211和nl80211。

谢谢!你是对的,我应该将操作模式设置为监视模式,以便能够更改通道,并且我使用了wireshark API中的示例代码。已安装libnl dev并使用-lnl netlink library标志编译。但我有时会遇到“设备或资源忙(-16)”的错误,我不知道是什么原因造成的。您使用哪个无线驱动程序?您可以查找cfg80211的源代码和/或正在使用的驱动程序,以查看哪些情况可能导致出现
-EBUSY
情况。如果我的答案解决了你的问题,请投票并/或选择它作为接受答案。看来我的司机还可以。解决方案是:sudo iwconfig wlan0 mode monitor&&ifconfig wlan0 down。您可以在@Phidelux中找到一个好的方法。这是libnl和netlink套接字的一般文档。这里没有描述nl80211。这就像UDP的描述不解释DNS;-)我不知道有nl80211文档,但我真的希望有一个。
nl\u send\u auto\u complete
不推荐使用。使用
nl\u发送\u自动
NL80211\u命令集\u WIPHY
也可以使用
NL80211\u命令集\u频道