📄 kernelspace.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 + -