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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陌上花开缓缓归以

你的鼓励将是我创作的最大动力,

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值