Linux Netlink编程是一种用于内核与用户空间进程之间通信的机制。Netlink套接字提供了一种灵活且高效的方式来传递内核和用户空间之间的消息,特别是在处理网络配置和监控时非常有用。
Netlink是一种特殊的套接字协议,属于AF_NETLINK家族。它允许内核模块和用户空间应用程序之间进行双向通信。Netlink通信基于消息队列,支持多播和组播,这使得它可以同时向多个接收者发送消息。
Netlink协议家族包含多种类型,常见的有:
NETLINK_ROUTE
:用于路由信息和网络接口管理。NETLINK_USERSOCK
:用于用户空间套接字相关的通知。NETLINK_FIREWALL
:用于防火墙相关的操作。NETLINK_INET_DIAG
:用于网络诊断工具如ss
和netstat
。以下是一个简单的Netlink用户空间程序示例,用于接收内核发送的消息:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <linux/netlink.h>
#include <sys/socket.h>
#define NETLINK_USER 31
struct sockaddr_nl src_addr, dest_addr;
struct nlmsghdr *nlh = NULL;
struct iovec iov;
int sock_fd;
char buffer[65536];
void send_msg(char *msgbuf, int msg_len) {
nlh->nlmsg_len = NLMSG_LENGTH(msg_len);
memcpy(NLMSG_DATA(nlh), msgbuf, msg_len);
iov.iov_base = (void *)nlh;
iov.iov_len = nlh->nlmsg_len;
sendmsg(sock_fd, &iov, 1);
}
void recv_msg() {
int len, msg_len;
struct nlmsghdr *nlh;
len = recv(sock_fd, buffer, sizeof(buffer), 0);
if (len < 0) {
perror("recv");
return;
}
nlh = (struct nlmsghdr *)buffer;
while (NLMSG_OK(nlh, len)) {
printf("Received message payload: %s\n", NLMSG_DATA(nlh));
nlh = NLMSG_NEXT(nlh, len);
}
}
int main() {
sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USER);
if (sock_fd < 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;
if (bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr)) < 0) {
perror("bind");
close(sock_fd);
return -1;
}
memset(&dest_addr, 0, sizeof(dest_addr));
dest_addr.nl_family = AF_NETLINK;
dest_addr.nl_pid = 0; // For kernel
dest_addr.nl_groups = 0;
nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(sizeof(char)));
memset(nlh, 0, NLMSG_SPACE(sizeof(char)));
nlh->nlmsg_len = NLMSG_LENGTH(sizeof(char));
nlh->nlmsg_pid = getpid();
nlh->nlmsg_flags = 0;
iov.iov_base = (void *)nlh;
iov.iov_len = nlh->nlmsg_len;
sendmsg(sock_fd, &iov, 1);
recv_msg();
close(sock_fd);
return 0;
}
Permission denied
错误,确保程序以root权限运行。通过理解和应用Netlink编程,可以有效地进行内核与用户空间的交互,特别是在网络管理和监控方面发挥重要作用。