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

相关推荐
HideF4 小时前
Linux
linux·服务器·网络
吠品4 小时前
智谱开源 ZCode 之后,真正的考试才开始
单片机·嵌入式硬件·1024程序员节
Ruiery6 小时前
Linux 6.6内核内存管理深度解析(十三):slab/slub 分配器
linux·运维·服务器
丰锋ff8 小时前
压缩命令笔记
linux
小李不想当小白8 小时前
SPI通信外设与W25Q64 (硬件SPI)(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·嵌入式
LCG米9 小时前
STM32驱动W5500以太网模块实测:TCP吞吐瓶颈定位、TX指针回绕陷阱与断线重连保活落地
stm32·单片机·嵌入式硬件·tcp/ip
GeW9 小时前
产业新优势基础软件的人才底盘,从Linux与数据库开始
linux·数据库
by2099910 小时前
Linux GCC/G++ 编译与 Makefile 构建
linux·运维·服务器·经验分享
创界工坊工作室10 小时前
63-基于STC89C52霍尔传感器的智能化电能表设计
stm32·单片机·嵌入式硬件·51单片机·proteus
cq林志炫10 小时前
两个Linux服务器之间同步文件
linux·运维·服务器