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

相关推荐
AlanBruce4 小时前
摩尔信使MThings功能综述与应用使用指南
linux·自动化·plc·mthings·摩尔信使
老当益壮梁奶奶6 小时前
51单片机DS18B20温度传感器详解:单总线时序与C51驱动实现
笔记·stm32·单片机·嵌入式硬件·51单片机
Horn Still Sounds6 小时前
ARM嵌入式基础|内核、寄存器、架构、存储、汇编移位全面梳理
arm开发·单片机·嵌入式硬件·硬件架构
星栖与芯6 小时前
LiteOS-M 切换汇编逐行图解(2):指令·异常机制·全景表
stm32·单片机·嵌入式硬件·harmonyos·鸿蒙系统
陈陈CHENCHEN9 小时前
【Linux】服务器根目录磁盘扩容操作记录
linux·运维·服务器
fhq_fn_jgd10 小时前
51单片机(串口通信)
单片机·嵌入式硬件
GeW10 小时前
RHCE快速拿证全攻略:考点拆解+实验强化+时间规划,一次通关
linux
深圳市元恩微科技开发有限公司10 小时前
兆讯恒达(北京兆讯)MH2457 系列 国产屏驱 MCU
单片机
码农小韩11 小时前
Linux应用开发(八)——TCP/IP网络编程基础
linux·嵌入式软件开发·linux操作系统·嵌入式操作系统·linux网络编程·linux应用
迷途之人不知返11 小时前
【进程】-5-进程优先级
linux