⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netlink.c

📁 Linux kernel - user space IPC - Netlink example
💻 C
字号:
#define LINUX#define __KERNEL__#define MODULE#include <linux/kernel.h>#include <linux/module.h>#include <linux/string.h>#include <linux/init.h>#include <linux/types.h>#include <linux/netdevice.h>#include <linux/skbuff.h>#include <linux/inet.h>#include <linux/in.h>#include <linux/ip.h>#include <linux/netlink.h>#include <linux/spinlock.h>#include <asm/semaphore.h>#include <net/sock.h>#include <linux/timer.h>#include <linux/time.h>/* public define */#define IMP_U_PID        0#define IMP_K_MSG        1#define IMP_CLOSE        2#define NL_IMP            31static struct timer_list t_timer;/* Kernel defines */DECLARE_MUTEX(receive_sem);    static struct sock *nlfd;struct {	__u32         pid;	rwlock_t     lock;} user_proc;static void kernel_receive(struct sock *sk,int len){	do {		struct sk_buff *skb;		printk("kernel_receive: somebody call this function. \n");		if(down_trylock(&receive_sem))			return;		while((skb = skb_dequeue(&sk->receive_queue)) != NULL) {			struct nlmsghdr *nlh = NULL;			if(skb->len >= sizeof(struct nlmsghdr)) {				nlh = (struct nlmsghdr *)skb->data;				printk("kernel_receive: type:0x%x pid:%x.\n", nlh->nlmsg_type, nlh->nlmsg_pid);				if((nlh->nlmsg_len >= sizeof(struct nlmsghdr)) && (skb->len >= nlh->nlmsg_len)) {					if(nlh->nlmsg_type == IMP_U_PID) {						write_lock_bh(&user_proc.pid);						user_proc.pid = nlh->nlmsg_pid;						write_unlock_bh(&user_proc.pid);					} else if(nlh->nlmsg_type == IMP_CLOSE) {						write_lock_bh(&user_proc.pid);						if(nlh->nlmsg_pid == user_proc.pid) {							user_proc.pid = 0;						}						write_unlock_bh(&user_proc.pid);					}				}			}			kfree_skb(skb);		}		up(&receive_sem);    	}while(nlfd && nlfd->receive_queue.qlen);}static int send_to_user(unsigned char *message){	int ret;	int size;	unsigned char *old_tail;	struct sk_buff         *skb;	struct nlmsghdr     *nlh;	printk("send_to_user: Start to send message to user.msg:%s, user_proc.pid:%d\n", message, user_proc.pid);	if(!user_proc.pid) 		return 0;	size = NLMSG_SPACE(strlen(message));	skb = alloc_skb(size,GFP_ATOMIC);	old_tail = skb->tail;	nlh = NLMSG_PUT(skb,0,0,IMP_K_MSG,size - sizeof(*nlh));	strcpy(NLMSG_DATA(nlh), message);	nlh->nlmsg_len = skb->tail - old_tail;	NETLINK_CB(skb).dst_groups = 0;	read_lock_bh(&user_proc.lock);	ret = netlink_unicast(nlfd,skb,user_proc.pid,MSG_DONTWAIT);	read_unlock_bh(&user_proc.lock);	/* In netlink_unicast, it will release skb buffer. There is no need to free ourself. */	printk("send_to_user: ret value:%d \n", ret);	return ret;nlmsg_failure:	if(skb) {		kfree_skb(skb);	}	return -1;}void hello(unsigned long data){	char buf[32];	sprintf(buf, "Hello. jiffies:%d\n", jiffies);	send_to_user(buf);	mod_timer(&t_timer, jiffies+5*HZ);}int init_module(){	printk("Perry :Enter\n");	rwlock_init(&user_proc.lock);	nlfd = netlink_kernel_create(NL_IMP, kernel_receive);	if(!nlfd) {		printk("can't create a netlink socket \n");		return -1;	}	init_timer(&t_timer);		t_timer.expires = jiffies + 100;	t_timer.function = hello;	add_timer(&t_timer);	return 0;}void cleanup_module(void){	del_timer_sync(&t_timer);	if(nlfd) {		sock_release(nlfd->socket);	}	printk("Perry:leave\n");}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -