网站建设属于前端还是后台,wordpress建站访问提示不安全,百度收录查询方法,wordpress社交帐号登录Netlink 套接字 是 Linux 特有的一种 IPC#xff08;进程间通信#xff09;机制#xff0c;用于用户态进程和内核模块之间的通信。它可以用来完成路由管理、设备通知、网络状态更新等任务。 1. Netlink 的基本工作原理
Netlink 是一种双向通信机制。Netlink 消息分为请求和…Netlink 套接字 是 Linux 特有的一种 IPC进程间通信机制用于用户态进程和内核模块之间的通信。它可以用来完成路由管理、设备通知、网络状态更新等任务。 1. Netlink 的基本工作原理
Netlink 是一种双向通信机制。Netlink 消息分为请求和响应 用户态进程发送请求消息到内核。内核处理请求并返回响应消息到用户态进程。也可以由内核主动向用户态进程发送事件通知。
Netlink 的消息通常通过结构体 struct nlmsghdr 包装消息正文是可选的数据内容。 2. Netlink 的常用 API
Netlink 通信使用的是普通的 BSD 套接字接口 创建套接字 int socket(int domain, int type, int protocol);domain 使用 AF_NETLINK。type 通常为 SOCK_RAW 或 SOCK_DGRAM。protocol 指定 Netlink 子系统编号例如 NETLINK_ROUTE。 绑定套接字 int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);使用 struct sockaddr_nl 作为地址。 发送消息 ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);接收消息 ssize_t recv(int sockfd, void *buf, size_t len, int flags);3. Netlink 示例代码
以下示例演示了如何使用 Netlink 套接字与内核进行简单的通信。
完整代码用户态程序
#include iostream
#include cstring
#include cstdlib
#include sys/socket.h
#include linux/netlink.h
#include unistd.h#define NETLINK_USER 31 // 自定义 Netlink 协议号大于 31 时需内核支持
#define MSG_LEN 1024 // 消息缓冲区大小int main() {// 创建 Netlink 套接字int sock_fd socket(AF_NETLINK, SOCK_RAW, NETLINK_USER);if (sock_fd 0) {std::cerr Error creating Netlink socket\n;return -1;}// 本地地址配置struct sockaddr_nl src_addr;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) {std::cerr Error binding Netlink socket\n;close(sock_fd);return -1;}// 目标地址配置内核struct sockaddr_nl dest_addr;memset(dest_addr, 0, sizeof(dest_addr));dest_addr.nl_family AF_NETLINK;dest_addr.nl_pid 0; // 发送到内核dest_addr.nl_groups 0; // 不订阅多播// 构造发送消息struct nlmsghdr *nlh (struct nlmsghdr *)malloc(NLMSG_SPACE(MSG_LEN));memset(nlh, 0, NLMSG_SPACE(MSG_LEN));nlh-nlmsg_len NLMSG_SPACE(MSG_LEN); // 消息长度nlh-nlmsg_pid getpid(); // 发送者 PIDnlh-nlmsg_flags 0; // 无特殊标志位strcpy((char *)NLMSG_DATA(nlh), Hello from user space!); // 消息内容// 发送消息到内核if (sendto(sock_fd, nlh, nlh-nlmsg_len, 0, (struct sockaddr *)dest_addr, sizeof(dest_addr)) 0) {std::cerr Error sending message\n;free(nlh);close(sock_fd);return -1;}std::cout Message sent to kernel: (char *)NLMSG_DATA(nlh) \n;// 接收内核响应memset(nlh, 0, NLMSG_SPACE(MSG_LEN));if (recv(sock_fd, nlh, NLMSG_SPACE(MSG_LEN), 0) 0) {std::cerr Error receiving message\n;free(nlh);close(sock_fd);return -1;}std::cout Message received from kernel: (char *)NLMSG_DATA(nlh) \n;// 清理资源free(nlh);close(sock_fd);return 0;
}4. 编写内核模块以响应 Netlink 消息
内核模块代码
#include linux/module.h
#include linux/kernel.h
#include linux/netlink.h
#include linux/skbuff.h
#include net/sock.h#define NETLINK_USER 31struct sock *nl_sk NULL;static void netlink_recv_msg(struct sk_buff *skb) {struct nlmsghdr *nlh;int pid;struct sk_buff *skb_out;char *msg Hello from kernel!;int msg_size strlen(msg);int res;// 获取 Netlink 消息头部nlh (struct nlmsghdr *)skb-data;printk(KERN_INFO Kernel received message: %s\n, (char *)NLMSG_DATA(nlh));pid nlh-nlmsg_pid; // 获取用户进程 PID// 构造响应消息skb_out nlmsg_new(msg_size, 0);if (!skb_out) {printk(KERN_ERR Failed to allocate new skb\n);return;}nlh nlmsg_put(skb_out, 0, 0, NLMSG_DONE, msg_size, 0);strncpy(NLMSG_DATA(nlh), msg, msg_size);res nlmsg_unicast(nl_sk, skb_out, pid); // 发送响应if (res 0) {printk(KERN_INFO Error sending message to user\n);}
}static int __init netlink_init(void) {struct netlink_kernel_cfg cfg {.input netlink_recv_msg, // 注册消息接收回调};nl_sk netlink_kernel_create(init_net, NETLINK_USER, cfg);if (!nl_sk) {printk(KERN_ALERT Error creating Netlink socket\n);return -10;}printk(KERN_INFO Netlink module loaded\n);return 0;
}static void __exit netlink_exit(void) {netlink_kernel_release(nl_sk);printk(KERN_INFO Netlink module unloaded\n);
}module_init(netlink_init);
module_exit(netlink_exit);MODULE_LICENSE(GPL);5. 编译和测试
编译内核模块
make -C /lib/modules/$(uname -r)/build M$(pwd) modules加载模块
sudo insmod netlink_test.ko运行用户态程序
./user_netlink6. 输出示例 用户态程序 Message sent to kernel: Hello from user space!
Message received from kernel: Hello from kernel!内核日志dmesg [INFO] Kernel received message: Hello from user space!总结
通过以上代码用户态程序和内核模块实现了简单的双向 Netlink 通信。根据实际需求可以扩展消息内容和通信逻辑。