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小时内删除。
发表评论