内核与用户空间通过 网络通讯 示例代码

本文深入探讨了Linux内核中Netlink模块的通信机制,详细介绍了Netlink消息的发送与接收流程,包括如何创建Netlink套接字、处理不同类型的消息以及实现用户空间与内核空间的数据交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
 * netlink.c
 *
 *  Created on: 2014 *      Author: cr
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/netlink.h>
#include <net/sock.h>
//#include "usrlink.h"

//MODULE_LICENSE("Dual BSD/GPL");
//MODULE_AUTHOR("MDAXIA");

struct sock *netlink_fd;

static struct pin_desc *irq_pd;  
static struct input_dev *sunxi_buttons_dev;  
static struct timer_list buttons_timer;  
//static int key_state[2];


static int key_repeat_report[2];

static unsigned long timeout_0 = 0x00;
static unsigned long timer_cnt_0 = 0x00;

static unsigned long timeout_1 = 0x00;
static unsigned long timer_cnt_1 = 0x00;


static void netlink_to_user(int dest, void *buf, int len)
{
    struct nlmsghdr *nl;
    struct sk_buff *skb;
    int size;
    //printk( "dest = %d.\n", dest );
    size = NLMSG_SPACE(len);
    skb = alloc_skb(size, GFP_ATOMIC);
    if(!skb || !buf)
    {
        printk(KERN_ALERT "netlink_to_user skb of buf null!\n");
        return;
    }
    nl = nlmsg_put(skb, 0, 0, 0, NLMSG_SPACE(len) - sizeof(struct nlmsghdr), 0);
    //NETLINK_CB(skb).pid = 0;
    NETLINK_CB(skb).dst_group = 0;

    memcpy(NLMSG_DATA(nl), buf, len);
    nl->nlmsg_len = (len > 2) ? (len - 0):len;

    netlink_unicast(netlink_fd, skb, dest, MSG_DONTWAIT);
    //printk(KERN_ALERT "K send packet success\n");
}

static int process_hello_get(int dest, void *buf, int len)
{  
    printk(KERN_ALERT "In process_hello get!\n");
    memcpy(buf, "I known you !", 13);
    netlink_to_user(dest, buf, 13);
    return NET_OK;
}

static int process_hello_set(int dest, void *buf, int len)
{
    //printk( "In process_hello set! %s\n", (char *)buf);
    //memcpy(buf, "S known you !", 13);
    
    netlink_to_user(dest, buf, len);
    return NET_OK;
}


static void netlink_process_packet(struct nlmsghdr *nl)
{
    int ret;

    switch(nl->nlmsg_type)
    {
    case HELLO_GET:
        printk( "process_hello_get.\n" );
        ret = process_hello_get(nl->nlmsg_pid, NLMSG_DATA(nl), nl->nlmsg_len);
        break;
    case HELLO_SET:
        printk( "process_hello_set.\n" );
        ret = process_hello_set(nl->nlmsg_pid, NLMSG_DATA(nl), nl->nlmsg_len);
        break;
    default:break;
    }
}

static void netlink_recv_packet(struct sk_buff *__skb)
{
    struct sk_buff *skb;
    struct nlmsghdr *nlhdr;

    skb = skb_get(__skb);
    if(skb->len >= sizeof(struct nlmsghdr))
    {
        nlhdr = (struct nlmsghdr *)skb->data;
        if(nlhdr->nlmsg_len >= sizeof(struct nlmsghdr) &&
                __skb->len >= nlhdr->nlmsg_len)
        {
            netlink_process_packet(nlhdr);
        }
    }
    else
        printk(KERN_ALERT "Kernel receive msg length error!\n");
}


#if 0
static int __init netlink_init(void)
{
    netlink_fd = netlink_kernel_create(&init_net, USER_NETLINK_CMD, 0, netlink_recv_packet, NULL, THIS_MODULE);
    if(NULL == netlink_fd)
    {
        printk(KERN_ALERT "Init netlink!\n");
        return -1;
    }
    printk(KERN_ALERT "Init netlink success!\n");
    return 0;
}

static void __exit netlink_exit(void)
{
    netlink_kernel_release(netlink_fd);
    printk(KERN_ALERT "Exit netlink!\n");
}
#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值