linux netlink实现用户态和内核态数据交互

1,内核态代码

#include <linux/module.h>

#include <linux/netlink.h>

#include <net/sock.h>

#define NETLINK_TEST 31

struct sock *nl_sk = NULL;

static void nl_recv_msg(struct sk_buff *skb) {

struct nlmsghdr *nlh;

int pid;

char *msg;

nlh = (struct nlmsghdr*)skb->data;

pid = nlh->nlmsg_pid; // 获取发送者的 PID

msg = nlh->nlmsg_data;

printk(KERN_INFO "Received message: %s from pid: %d\n", msg, pid);

// 回复用户空间

nlh->nlmsg_pid = 0; // 目标为用户空间

nlh->nlmsg_type = NLMSG_DONE; // 消息类型

strcpy(nlh->nlmsg_data, "Hello from Kernel");

netlink_unicast(nl_sk, skb, pid, MSG_DONTWAIT);

}

static int __init hello_init(void) {

struct netlink_kernel_cfg cfg = {

.input = nl_recv_msg,

};

nl_sk = netlink_kernel_create(&init_net, NETLINK_TEST, &cfg);

if (!nl_sk) {

printk(KERN_ALERT "Error creating netlink socket.\n");

return -ENOMEM;

}

printk(KERN_INFO "Netlink module initialized.\n");

return 0;

}

static void __exit hello_exit(void) {

netlink_kernel_release(nl_sk);

printk(KERN_INFO "Netlink module exited.\n");

}

module_init(hello_init);

module_exit(hello_exit);

MODULE_LICENSE("GPL");

运行insmod hello.ko

3,用户态代码

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <sys/socket.h>

#include <linux/netlink.h>

#define NETLINK_TEST 31

int main() {

struct sockaddr_nl src_addr, dest_addr;

struct nlmsghdr *nlh = NULL;

int sock_fd, msg_size;

char *msg = "Hello from User";

sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_TEST);

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(); // 用于识别

bind(sock_fd, (struct sockaddr *)&src_addr, sizeof(src_addr));

memset(&dest_addr, 0, sizeof(dest_addr));

dest_addr.nl_family = AF_NETLINK;

dest_addr.nl_pid = 0; // 目标为内核

dest_addr.nl_groups = 0;

nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(1024));

nlh->nlmsg_len = NLMSG_LENGTH(strlen(msg) + 1);

nlh->nlmsg_pid = getpid();

nlh->nlmsg_flags = 0;

strcpy(NLMSG_DATA(nlh), msg);

msg_size = sendto(sock_fd, nlh, nlh->nlmsg_len, 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));

if (msg_size < 0) {

perror("sendto");

return -1;

}

// 接收内核的回复

recv(sock_fd, nlh, NLMSG_BUFFER_SIZE, 0);

printf("Received from kernel: %s\n", (char *)NLMSG_DATA(nlh));

close(sock_fd);

return 0;

}

gcc main.c -o main

相关推荐
叁散4 小时前
实验项目1 RFID 标签实验
单片机·嵌入式硬件
赵民勇7 小时前
Linux/Unix中install命令全面用法解析
linux·shell
比奇堡派星星8 小时前
MCU 裸机时间片调度系统
单片机·嵌入式硬件
苏宸啊8 小时前
Linux指令篇(一)
linux·运维·服务器
我要升天!9 小时前
Linux中《网络基础》
linux·运维·网络
鸽芷咕9 小时前
【2025年度总结】时光知味,三载同行:落笔皆是沉淀,前行自有光芒
linux·c++·人工智能·2025年度总结
羑悻的小杀马特10 小时前
指尖敲代码,笔尖写成长:2025年度总结与那些没说出口的碎碎念
linux·c++·博客之星·2025年度总结
深圳市方中禾科技10 小时前
LED驱动芯片FZH02,应用开发相关数据技术手册
单片机·嵌入式硬件·led
晴天¥11 小时前
VMware+Oracle linux LVM/非LVM磁盘扩容
linux·运维·服务器
oMcLin11 小时前
如何在Oracle Linux 8.4上搭建并优化Kafka集群,确保高吞吐量的实时数据流处理与消息传递?
linux·oracle·kafka