c-如何使用netlink库将命令发送到网络接口



我正在启动与wifi相关的项目,我已经用linux ioctl调用完成了一个项目。现在我必须在libnl的帮助下做同样的事情,因为ioctl现在已经被弃用了,我已经阅读了所有的核心文档,但仍然不明白如何在特定的接口上发送命令。如何将命令发送到网络接口?说我想发送NL80211_CMD_TRIGGER_SCAN,我该怎么做?非常感谢任何示例代码,因为这将是我旅程的开始。正如我现在所理解的,我必须创建libnl套接字,类似于:

struct nl_sock *socket;
sock = nl_socket_alloc();

然后用我的命令编写nlmsg消息并发送,但是如何发送呢?

附言:假设使用nl_send(),但我希望你能理解,我一直不理解这个库是如何工作的。

我也在做一些涉及netlink的事情。我拼凑了一个似乎能在我的系统上运行的程序(debian 3.2.0.4)。这是一个简单的程序,它首先发送一条消息,然后开始监听来自内核的更新。我相信你必须更改发送部分并设置必要的标志等

一个相当重要的区别是:我不调用nl_socket_alloc,而是创建一个常规套接字。我确信我有一些错误,你可以直截了当。我希望它能有所帮助:

#include <iostream>
#include <unistd.h>
#include <sys/socket.h>
#include <netlink/netlink.h>
#include <netlink/socket.h>
#include <netlink/cache.h>
#include <netlink/route/link.h>
//#include <>
#define NETLINK_USER 31
#define MAX_PAYLOAD 1024
using std::cout;
using std::endl;
int sequence_number = 0;
void sendNetLinkMsg(int fd) {
    struct nlmsghdr *nh = 0;
    struct sockaddr_nl sa;
    struct iovec iov = { nh, nh->nlmsg_len };
    struct msghdr msg;
    msg = {&sa, sizeof(sa), &iov, 1, NULL, 0, 0};
    memset(&sa, 0, sizeof(sa));
    sa.nl_family = AF_NETLINK;
    nh->nlmsg_pid = getpid();
    nh->nlmsg_seq = ++sequence_number;
    nh->nlmsg_flags |= NLM_F_ACK;
    sendmsg(fd, &msg, 0);
}
void recvNetLinkMsg(int fd, struct msghdr* msg, char* buf) {
    int len;
    struct nlmsghdr *nh;
    len = recvmsg(fd, msg, 0);
    for (nh = (struct nlmsghdr *) buf; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len)) {
        if (nh->nlmsg_type == NLMSG_DONE)
            break;
        if (nh->nlmsg_type == NLMSG_ERROR) {
            cout << "Error" << endl;
        }
        if (nh->nlmsg_type == RTM_DELROUTE)
            cout << "Delete route" << endl;
        else if (nh->nlmsg_type == RTM_NEWROUTE)
            cout << "New route" << endl;
        else {
            cout << "Unknown msg: " << nh->nlmsg_type << endl;
        }
    }
}
int main() {
    struct sockaddr_nl sockAddr;
    memset(&sockAddr, 0, sizeof(sockAddr));
    sockAddr.nl_family = AF_NETLINK;
    sockAddr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE;
    int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
    bind(fd, (struct sockaddr *) &sockAddr, sizeof(sockAddr));
    char buf[4096];
    struct iovec iov = { buf, sizeof(buf) };
    struct msghdr msg;
    msg = {&sockAddr, sizeof(sockAddr), &iov, 1, NULL, 0, 0};
    sendNetLinkMsg(fd);
    while (true) {
        recvNetLinkMsg(fd, &msg, buf);
    }
    return 0;
}

最新更新