linux的nlmsghdr用法
    在Linux系统中,nlmsghdr结构体用于表示Netlink消息头。Netlink是一种进程间通信协议,旨在为内核和用户空间提供一种可靠的数据传输机制。Netlink提供了多种协议族,其中之一是NETLINK_GENERIC协议族,它可以用来实现自定义通信协议。
    nlmsghdr结构体的定义如下:
    ```c
    struct nlmsghdr {
        __u32 nlmsg_len;
        __u16 nlmsg_type;
        __u16 nlmsg_flags;
        __u32 nlmsg_seq;
        __u32 nlmsg_pid;
    };
    ```
    其中,各成员变量的含义如下:
    - nlmsg_len 表示Netlink消息的总长度,包括消息头和消息体。
    - nlmsg_type 表示Netlink消息的类型。
    - nlmsg_flags 表示Netlink消息的标记,可以包括NLM_F_REQUEST、NLM_F_ACK、NLM_F_DUMP等,具体含义请参考官方文档。
    - nlmsg_seq 表示Netlink消息的序列号,用于标识消息的顺序。
    - nlmsg_pid 表示发送或接收Netlink消息的进程ID。
    下面是一个简单的使用例子,展示如何创建一个Netlink消息并向内核发送:
    ```c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
memset结构体初始化
    #include <linux/netlink.h>
    #define NETLINK_TEST 25
    #define MAX_PAYLOAD 1024
    //创建Netlink socket
        sockfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_TEST);
        if (sockfd < 0) {
            perror("socket");
            return -1;
        }
    //绑定源地址
        memset(&src_addr, 0, sizeof(src_addr));
        src_addr.nl_family = AF_NETLINK;
        src_addr.nl_pid = getpid();
        src_addr.nl_groups = 0;
        ret = bind(sockfd, (struct sockaddr *)&src_addr, sizeof(src_addr));
        if (ret < 0) {
            perror("bind");
            return -1;
        }
    //构造Netlink消息头
        nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
        memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
        nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
        nlh->nlmsg_type = 1;  //自定义消息类型
        nlh->nlmsg_flags = NLM_F_REQUEST;
        nlh->nlmsg_seq = 0;
        nlh->nlmsg_pid = getpid();
    //设置消息体
        strcpy(NLMSG_DATA(nlh), "Hello, kernel!");
    //设置iovec结构体
        iov.iov_base = (void *)nlh;
        iov.iov_len = nlh->nlmsg_len;
    //解析Netlink消息头
        nlh = (struct nlmsghdr *)msg.msg_iov->iov_base;
        printf("Received message: %s\n", (char *)NLMSG_DATA(nlh));
    //释放资源
        free(nlh);
        close(sockfd);
    return 0;
    }
    ```
    在这个例子中,我们创建了一个Netlink socket,并设置了源地址和目的地址。然后构造了一个消息头,设置了消息类型为1,也就是自定义消息类型,并且设置了消息体为“Hello, kernel!”。最后通过sendmsg函数将消息发送到内核,并通过recvmsg函数从内核接收消息。在接收到消息后,我们可以通过解析消息头获取消息体的内容,并输出到控制台上。
    需要注意的是,Netlink消息中的数据传递方式是二进制的,因此消息体的内容应该按照二进制格式进行打包和解包。使用NLMSG_DATA宏可以方便地获取消息体的指针,但在将消息体转换为具体的数据类型时需要格外注意字节序(例如小端序和大端序)的问题。
    除了上面的例子外,还可以使用Netlink协议完成其他诸如路由配置、网络监视等功能。需要的话读者可以参考官方文档进行深入了解。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。