#include <cdev.h>
#include <export.h>
#include <gfp.h>
#include <kobject.h>
#include <netdevice.h>
#include <page_types.h>
#include <page-flags.h>
#include <semaphore.h>
#include <skbuff.h>
#include <socket.h>
#include <types.h>
#include <fs/char_dev.c>
//#include <wait.h>
#include <linux/gfp.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include "../arch/arm/include/asm/memory.h"
#include "../include/uapi/asm-generic/ioctl.h"
#include "../include/uapi/asm-generic/poll.h"
#include "../include/uapi/linux/if_ether.h"
#include "../include/uapi/linux/netfilter.h"
#include "../tools/testing/radix-tree/linux/types.h"
#include "../drivers/staging/lustre/lustre/include/lustre_compat.h"
#ifndef GFP_KERNEL
#define GFP_KERNEL 0
#ifndef _LUSTRE_COMPAT_H
#define _LUSTRE_COMPAT_H
#endif
/*
#include <linux/slab.h>
#include <linux/fs.h>
#include <stdio.h>
#include <linux/netfilter.h>
#include <linux/netfilter_bridge.h>
#include <linux/netfilter_ipv4.h>
#include <linux/ip.h>
#include <linux/poll.h>
#include “linux/include/linux/wait.h”
#include <mm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <linux/module.h>
#include <linux/mm_types.h>
#include <linux/kernel.h>
//與用戶的同步通知相應用信號量或者等待隊列
//定義信號量用於用戶端selet輪旋操作與讀寫操作同步(readop writeop)
*/
struct semaphore sing;
//定義等待隊列頭
static wait_queue_head_t quehead;
//定義條件變量
static int condition=0;
//定義poll函數用於客戶查詢
unsigned int hellpoll(struct filp *p,struct poll_table_struct *wait){
if(down_interruptible(&sing)){ //獲取信號量
unsigned int mask=0;
poll_wait(p,&quehead,wait);
//返回狀態碼
if( condition==0 ){
mask |=POLLIN | POLLRDNORM;
}//在讀取中
if(condition==1){
mask |=POLLOUT | POLLWRNORM ;
}//再寫
up(&sing);//釋放
return mask;
}
};
//设备文件中写入信息集合属性信息 入出ip地址 端口 源 IP 物理地址 特殊过
struct shebzt{
int ydun; //原 目的端口
int mdun;
int yip[4];//ip
int mip[4];
char ywaddr[50];//物理地址 0保存字符字数
char maddr[50];
int liux; //数据包流向 0路由 1pc 2网络
};
//内存虚拟镜像vm与用户层传递数据包信息
static char *buffer;//定义映射内核缓存
static void mapopen(struct vm_area_struct * area){};
static void mapclos(struct vm_area_struct * area){};//定义调用函数集中的函数
static struct vm_operations_struct maops={.open=mapopen, .close=mapclos};
int vmmap (struct file *flip,struct vm_area_struct *vma){
//赋予函数集
vma->vm_ops=maops;
//得到申请内存大小
unsigned long size0=vma->vm_end-vma->vm_start;
//分配buff大小
buffer=kmalloc(size0,GFP_KERNEL);
int size =getpagesize();//获取页大小
//计算首物理地址
unsigned long pysics=virt_to_phys(buffer);
unsigned long pysics1=virt_to_phys(buffer+size0);
//得到页首号
unsigned long yehao=pysics>>PAGE_SHIFT;
unsigned long yehao1=pysics1>>PAGE_SHIFT;
//对每一页设置不许内存分配标准
unsigned long page;
for(page=yehao;page<yehao1;page++){
SetPageReserved(page);
};
//调用open函数
//内存映射
remap_pfn_range(vma,vma->vm_start,yehao,size0,vma->vm_page_prot);
}
//注册用户交互的itcol函数
//定义命令常量用于状态设定
#define NETXNG1 ‘js’ //结束程序
#define NETXNG2 ‘zt’ //暂停数据包分析过滤
#define NETXNG3 ‘fz’//复制模式配置
#define NETXNG4 ‘gl’ //过滤模式配置
//等一处理函数
//定义保存用户命令状态
char ycomd[1];//
int *ioctlnet( struct file *filp, unsigned int cmd, unsigned long arg){
switch(_IOC_TYPE(cmd)){
case 'js' :
;
break;
case 'zt':
;
break;
case 'fz':
;
break;
case 'gl':
;
break;
}
return 0;
};
//内核分析部分
//数据包分析后信息结构
//数据包集目录与用户层交互的
int *array;
int number;
struct sjbml{
int number1; //数据数量
array=(int*)calloc(number,sizeof(int)) ; //插入位置数组
int tim; //需要的延迟时间
int zd;//中断更新号
int moshi;//客户端当前模式
};
//注册到operations结构中
//数据结构包含用户端传递信息
//提供截留数据包定义函数
//定义地址范围
//定义协议类型
//定义端口
//定义操作类型
//执行操作分类
// 分析内核部分用来选择接下去操作流程
//定义设备文件读写函数并注册 处理客户端配置的分析的数据包流信息
int readop(struct file *file,char *buf,size_t len,loff_t *offset){ //调用读取函数
if(down_interruptible(&sing)){ //獲取信號 等待poll完成
//讀寫分開同步
wait_event_interruptible(quehead,condition==1); //等待寫完成
//進行真實讀寫操作
//設置condition
condition=0;
}
return 0;
};
int writeop(struct file *file, char *buf,size_t len,loff_t *offset){ //调用写幻术
if(down_interruptible(&sing)){ //獲取信號 等待poll完成
wait_event_interruptible(quehead,condition==0);
//進行真實讀寫操作
//設置condition
condition=1;
}
return 0;
};
extern struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,int flags, int node);
//定义协议处理函数
int ipnet(){
return 0;
};
struct file_operations fops;
struct cdev inetdev;
void cdev_init(){
sema_init(&sing,1);
//初始等待頭
init_waitqueue_head(&quehead);
//内存虚拟镜像vm与用户层
fops->mmap=vmmap;
//設置poll函數
fops->poll=hellpoll;
//注册读写函数
fops->read=readop;
fops->write=writeop;
//fuyu itol
fops->unlocked_ioctl=ioctlnet;
//初始设备各个成员
menset(inetdev,0,sizeof *inetdev);
//初始话首尾指针
INIT_LIST_HEAD(&inetdev->list);
//初始化设备文件
kobject_init(&inetdev->kobj,&ktype_cdev_default);
//关联operationws
inetdev->ops=fops;
inetdev->owner=THIS_MODULE;
}
///struct cdev{ //设备
int size;
static struct packet_type inetpack;
struct sk_buff *skglu;//包含的的skbuff网络数据包
int main(){
inetpack.func=ipnet;//处理所有数据
inetpack.type=ETH_P_ALL;
cdev_init();
skglu=_alloc_skb(size,GFP_KERNEL,1,-1);//申请skbuff 空间 克隆skbuff
//激活设备
cdev_add(inetdev,inetdev->dev,inetdev->count);
dev_add_pack(inetpack); //加入协议注册到内核
}
static struct nf_hook_ops *hookob;
//hook 函数处理
int usrnumber; //用户端调用功能吗
unsigned int hookcl (void *priv,struct sk_buff *skb,const struct nf_hook_state *state){
unsigned int rtn;
rtn=NF_ACCEPT;
//进行功能 处理流程选择
switch(usrnumber){
case 0: rtn=NF_ACCEPT ;
;//继续正常传输
break ;
case 1:rtn=NF_DROP;
; //丢球
break;
case 2:rtn=NF_STOLEN;
; //模块接管
break;
case 3:rtn=NF_QUEUE;
; //数据包进行排队 转给进陈处理
break;
case 4:rtn= NF_REPEAT;
; //在回调一次处理
break;
} ;
return rtn;
// NF_ACCEPT继续正常传输数据报 NF_DROP丢弃该数据报,不再传输 NF_STOLEN模块接管该数据报,告诉Netfilter“忘掉”该数据报
//NF_QUEUE对该数据报进行排队(通常用于将数据报给用户空间的进程进行处理) NF_REPEAT 再次调用该回调函数,应当谨慎使用这个值,以免造成死循环。
};
//初始化
int hook(){
//定义结构变量
hookob->hook=hookcl;
hookob->pf=PF_INET;
nf_register_hook(hookob);//注册hook函数
return 0;
}
int unmain(){
_dev_remove_pack(inetpack); //移除协议
kfree_skb(); //释放内存
//注销hook
nf_unregister_hook(hookob);
return 0;
}
module_init(main);
module_exit(unmain);