简体   繁体   English

如何使用Netlink库将命令发送到网络接口

[英]How to send command to network interface with netlink library

I'm starting wifi related project and i've completed one with linux ioctl calls. 我正在开始与wifi相关的项目,并且已经用linux ioctl调用完成了一个项目。 Now i must do the same with help of libnl as ioctl is now deprecated, i've already read all the core documentation but still don't understand how to send command on specific interface. 现在我必须在libnl的帮助下做同样的事情,因为ioctl现在已被弃用,我已经阅读了所有核心文档,但是仍然不了解如何在特定接口上发送命令。 How can i send command to network interface? 如何将命令发送到网络接口? say i want send NL80211_CMD_TRIGGER_SCAN, how can i do this? 说我要发送NL80211_CMD_TRIGGER_SCAN,我该怎么做? any example code is greatly appreciated as it will be the start of my journey. 任何示例代码都将不胜感激,因为这将是我旅程的开始。 As i understand for now i must create libnl socket, something like: 据我了解,我现在必须创建libnl套接字,例如:

struct nl_sock *socket;
sock = nl_socket_alloc();

and then compose nl_msg message with my command and send it, but how? 然后用我的命令编写nl_msg消息并发送,但是如何?

PS suppose with nl_send(), but i hope you understand that i stuck at point of no-understanding the idea of how this lib works PS假设使用nl_send(),但我希望您了解我一直不了解该lib的工作原理

I am also working on something that involves netlink. 我也在从事涉及netlink的工作。 I pieced together a program that seems to work on my system (debian 3.2.0.4). 我拼凑了一个似乎可以在我的系统上运行的程序(debian 3.2.0.4)。 It is a simple program that sends a msg first and starts listening updates coming from kernel. 这是一个简单的程序,它首先发送msg并开始监听来自内核的更新。 I believe you would have to change the send part and set necessary flags etc. 我相信您将不得不更改发送部分并设置必要的标志等。

One rather important difference: I don't call nl_socket_alloc, instead, I create a regular socket. 一个相当重要的区别:我不调用nl_socket_alloc,而是创建一个常规套接字。 I am sure I have some mistake in there, you can be straightforward. 我敢肯定,我那里有些错误,您可以直白。 I hope it helps: 希望对您有所帮助:

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM