Netlink 是 Linux 内核提供的一种用于内核与用户空间进程之间通信的机制。它允许用户空间程序与内核模块进行双向数据交换,常用于网络配置、路由表管理、防火墙规则等场景。
CAP_NET_ADMIN
权限,允许其执行网络管理操作。以下是一个简单的 Netlink 客户端示例,用于查询网络接口信息:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
void die(const char *s) {
perror(s);
exit(1);
}
int main() {
int sockfd;
struct sockaddr_nl src_addr, dest_addr;
struct nlmsghdr *nlh = NULL;
struct iovec iov;
int ret;
sockfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (sockfd < 0) die("socket");
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(sockfd, (struct sockaddr*)&src_addr, sizeof(src_addr)) < 0) die("bind");
memset(&dest_addr, 0, sizeof(dest_addr));
dest_addr.nl_family = AF_NETLINK;
dest_addr.nl_pid = 0; // For Linux Kernel
dest_addr.nl_groups = 0;
nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(sizeof(struct rtmsg)));
memset(nlh, 0, NLMSG_SPACE(sizeof(struct rtmsg)));
nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
nlh->nlmsg_pid = getpid();
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
nlh->nlmsg_type = RTM_GETLINK;
iov.iov_base = (void *)nlh;
iov.iov_len = nlh->nlmsg_len;
ret = sendto(sockfd, &iov, 2, 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr));
if (ret < 0) die("sendto");
while (1) {
ret = recvmsg(sockfd, &msg, 0);
if (ret < 0) die("recvmsg");
for (nlh = (struct nlmsghdr *)msg.msg_iov->iov_base; NLMSG_OK(nlh, ret); nlh = NLMSG_NEXT(nlh, ret)) {
if (nlh->nlmsg_type == NLMSG_DONE) {
return 0;
}
if (nlh->nlmsg_type == RTM_NEWLINK) {
struct ifinfomsg *ifi = (struct ifinfomsg *)NLMSG_DATA(nlh);
printf("Interface: %s\n", if_indextoname(ifi->ifi_index, ifi_name));
}
}
}
close(sockfd);
return 0;
}
这个示例展示了如何使用 Netlink 查询网络接口信息。通过这种方式,可以实现更复杂的网络管理和监控功能。
没有搜到相关的文章