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

📄 kernelspace.c

📁 NETLINK是LINUX环境下一种新型的用户空间与内核空间的交互方法
💻 C
字号:
#include <linux/kernel.h>#include <linux/module.h>#include <linux/types.h>#include <linux/sched.h>#include <net/sock.h>#include <net/netlink.h>#include <linux/skbuff.h>extern char *dpi_skbpool_addr; #define DPI_NETLINK 21#define CONTROL_MSG 0x10#define NOT_MIRROR 0#define DO_MIRROR 0x01#define DATA_MSG 0x11extern int packet_transmit(struct sk_buff *); struct sock *nl_sk = NULL;volatile u32 pid;struct _data_from_user{	unsigned char * pskb_ptr;	char flag;}data_from_user;   struct _data_to_user{	int skb_offset;		//数据包相对内存区域首地址的偏移	int skb_len;			//数据包长度	unsigned char * pskb_ptr;		//skb结构体的地址 }data_to_user;//回调函数void data_process(struct sock * sk){    struct sk_buff * skb;    struct sk_buff * kskb;    struct nlmsghdr * nlh;     //printk("enter the function data_process!\n");    skb = skb_dequeue(&sk->sk_receive_queue);        nlh = nlmsg_hdr(skb);    if (nlh->nlmsg_len >= NLMSG_SPACE(0))  //CHECK nlmsghdr is or not complete	 {    //data from user space is treated as payload in skb struct (skb->data)    //define in <netlink.h>          memset(&data_from_user,0,sizeof(data_from_user));     memcpy(&data_from_user,NLMSG_DATA(nlh), sizeof(data_from_user));    if(nlh->nlmsg_type==CONTROL_MSG)   {   	pid = nlh->nlmsg_pid;     printk("******test******\n");		   }   else if(nlh->nlmsg_type==DATA_MSG)	 {  			kskb=(struct sk_buff *)data_from_user.pskb_ptr;		kskb->cb[0]=data_from_user.flag;		packet_transmit(kskb);   }		kfree_skb(skb); 		    }	  return 0;	 }void dpi_netlink_rcv(struct sock *sk, int len){	data_process(sk);}int send_user(struct sk_buff *skb){  struct sk_buff *nl_skb;  struct nlmsghdr *nlh;    int ret;  int len = NLMSG_SPACE(sizeof(data_to_user)); //NOTICE   //printk("enter the function send_user!\n");  memset(&data_to_user,0,sizeof(data_to_user));  data_to_user.pskb_ptr=(unsigned char *)skb;  data_to_user.skb_len=skb->len;  //memcpy(data_to_user.packet,skb->data,skb->len); //NOTICE  data_to_user.skb_offset=(int)skb->data-(int)dpi_skbpool_addr;  //alloc a new skb struct nl_skb nl_skb->data = nl_skb->tail  nl_skb= alloc_skb(len, GFP_ATOMIC); //NOTICE where to free!!  if (!nl_skb){      printk(KERN_ERR "net_link: allocate failed.\n");      return 0;  } //创建一个nlmsghdr结构体,将传入的参数填充到结构体中,返回一个指针nlh   //nlh = nlmsg_put(nl_skb,0,0,DPI_NETLINK,2000,0);  NOTICE  nlh = nlmsg_put(nl_skb,0,0,0,sizeof(data_to_user),0);    //设置源地址0: from kernel  NETLINK_CB(nl_skb).pid = 0;  	//将data2user数据结构中的内容拷贝到消息的数据段中		memcpy(NLMSG_DATA(nlh), &data_to_user, sizeof(data_to_user));   //发送消息到ID为pid的用户进程  ret= netlink_unicast(nl_sk, nl_skb, pid, 1); //MSG_DONTWAIT    if (ret< 0) {      printk(KERN_ERR "net_link: can not unicast skb (%d)\n", ret);      if(nl_skb)      kfree_skb(nl_skb);    }  printk("send data success!\n");  return 0; }//创建netlink在内核段的socket static int test_netlink(void) {   nl_sk = netlink_kernel_create(DPI_NETLINK, 0, dpi_netlink_rcv, NULL, THIS_MODULE); /*netlink_kernel_create函数在不同的内核版本中参数不同    DPI_NETLINK netlink 协议类型    dpi_netlink_rcv回调函数 */  if (!nl_sk) {    printk(KERN_ERR "net_link: Cannot create netlink socket.\n");    return -EIO;  }  printk("create the netlink socket successed!\n");  return 0;}static int __init init_dpi_netlink(void){    printk("init dpi_netlink!\n");  test_netlink();  return 0;}static void __exit cleanup_dpi_netlink(void){  if (nl_sk != NULL){    sock_release(nl_sk->sk_socket);  }  printk("exit the netlink module\n");}module_init(init_dpi_netlink);module_exit(cleanup_dpi_netlink);MODULE_LICENSE("GPL");MODULE_AUTHOR("ljp");EXPORT_SYMBOL(send_user);

⌨️ 快捷键说明

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