您的位置:首页 > 理论基础 > 计算机网络

利用netfilter机制,实现内核防火墙把http请求和回应的数据包截获后,解释出其中的http层数据

2014-11-04 12:44 344 查看
#include<linux/init.h>

#include<linux/kernel.h>

#include<linux/module.h>

#include<linux/netfilter_ipv4.h>

#include<linux/skbuff.h>

#include<linux/ip.h>

#include<linux/tcp.h>

#include<linux/if_ether.h>

#include<linux/if_packet.h>

unsigned int change(int aChar,int hex)

{

int ch;

ch = aChar - hex;

return ch;

}

unsigned char HexToAsc(int aChar)

{

/*if(aChar>=0x20&&aChar<=0x7E)

{

return ' '+(aChar-0x20);

}*/

/*if((aChar>=0x0)&&(aChar<=0x9))

return 0+change(aChar,0x0);

if((aChar>=0xA)&&(aChar<=0xF))

return 0+change(aChar,0xA);

if((aChar>=0x10)&&(aChar<=0x19))

return 16+change(aChar,0x10);

if((aChar>=0x1A)&&(aChar<=0x1F))

return 26+change(aChar,0x1A);*/

if(aChar == 0x20)

return 32;

/*if(aChar == 0x7F)

return 127;*/

if(aChar == 0xA)

return 10;

if(aChar == 0xD)

return 13;

if((aChar>=0x21)&&(aChar<=0x2F))

{

int ch = change(aChar,0x21);

return '!'+ch;

}

if((aChar>=0x30)&&(aChar<=0x39))

{

int ch = change(aChar,0x30);

return '0'+ch;

}

if((aChar>=0x3A)&&(aChar<=0x40))

{

int ch = change(aChar,0x3A);

return ':'+ch;

}

if((aChar>=0x41)&&(aChar<=0x5A))

{

int ch = change(aChar,0x41);

return 'A'+ch;

}

if((aChar>=0x5B)&&(aChar<=0x60))

{

int ch = change(aChar,0x5B);

return '['+change;

}

if((aChar>=0x61)&&(aChar<=0x7A))

{

int ch = change(aChar,0x61);

return 'a'+ch;

}

if((aChar>=0x7B)&&(aChar<=0x7E))

{

int ch = change(aChar,0x7B);

return '{'+ch;

}

return NULL;

}

//nf_in钩子执行函数hf_hook_in

static unsigned int nf_hook_in(unsigned int hooknum,struct sk_buff **skb,const struct net_device *in,const struct net_device *out,int (*okfn)(struct sk_buff*))

{

int i;

struct sk_buff *sk = NULL;

sk = skb_copy(skb,GFP_ATOMIC);

struct iphdr *iph = ip_hdr(sk);//获取ip头指针

struct tcphdr *tcph;//tcp头指针

tcph = (void*)iph + iph->ihl*4;//获取tcp开始位置

//int char_int1,char_int2;

//char c1 = NULL;

//char c2 = NULL;

if(iph->protocol == IPPROTO_TCP)//截获的是TCP类型的包

{

if((tcph->source == htons(8080)||tcph->source == htons(80))&&(sk->len > 40))//接收的包源地址端口是8080或80端口的并且包长度大于40个字节

{

if(tcph->source == htons(8080))//源地址端口号是8080,接收的8080端口的包

{

printk("receive package starting:this is a http 8080 package!\n");

for(i=40;i<sk->len;i++)//从第40个字节以后开始获取数据data部分

{

printk("%x ",*(sk->data+i));

}

printk("\n");

for(i=40;i<sk->len;i++)//从第40个字节以后开始获取数据data部分

{

printk("%c",HexToAsc(*(sk->data+i)));

}

printk("\nreceive ended!\n");

}

else//源地址端口号是80,接收的是80端口的包

{

printk("receive package starting:this is a http 80 package!\n");

for(i=40;i<sk->len;i++)//从第40个字节以后开始获取数据data部分

{

printk("%x ",*(sk->data+i));

}

printk("\n");

for(i=40;i<sk->len;i++)//从第40个字节以后开始获取数据data部分

{

printk("%c",HexToAsc(*(sk->data+i)));

}

printk("\nreceive ended!\n");

}

}

}

return NF_ACCEPT;

}

//nf_out钩子执行函数hf_hook_out

static unsigned int nf_hook_out(unsigned int hooknum,struct sk_buff **skb,const struct net_device *in,const struct net_device *out,int (*okfn)(struct sk_buff*))

{

int i;

struct sk_buff *sk = NULL;

sk = skb_copy(skb,GFP_ATOMIC);

struct iphdr *iph = ip_hdr(sk);//获取ip头指针

struct tcphdr *tcph;//tcp头指针

tcph = (void*)iph + iph->ihl*4;//获取tcp开始位置

//int char_int1,char_int2;

//char c1 = NULL;

//char c2 = NULL;

if(iph->protocol == IPPROTO_TCP)//发送的是TCP类型的包

{

if((tcph->dest == htons(8080)||tcph->dest == htons(80))&&(sk->len > 40))//发送的包目的地址端口是8080或80端口的并且包长度大于40个字节

{

if(tcph->dest == htons(8080))//目的地址端口号是8080,发送的是前往8080端口的包

{

printk("send package starting:this is a http 8080 package!\n");

for(i=40;i<sk->len;i++)//从第40个字节以后开始获取数据data部分

{

printk("%x ",*(sk->data+i));

}

printk("\n");

for(i=40;i<sk->len;i++)//从第40个字节以后开始获取数据data部分

{

printk("%c",HexToAsc(*(sk->data+i)));

}

printk("\nsend ended!\n");

}

else//目的地址端口号是80,发送的是前往80端口的包

{

printk("send package starting:this is a http 80 package!\n");

for(i=40;i<sk->len;i++)//从第40个字节以后开始获取数据data部分

{

printk("%x ",*(sk->data+i));

}

printk("\n");

for(i=40;i<sk->len;i++)//从第40个字节以后开始获取数据data部分

{

printk("%c",HexToAsc(*(sk->data+i)));

}

printk("\nsend ended!\n");

}

}

}

return NF_ACCEPT;

}

//初始化nf_in钩子,在钩子LOCAL_IN上

static struct nf_hook_ops nf_in =

{

.hook = nf_hook_in,//绑定执行函数nf_hook_in()

.hooknum = NF_INET_LOCAL_IN,//钩子类型

.pf = PF_INET,//指定IPv4协议族

.priority = 0//指定在执行的顺序中,这个hook函数应当在被放在什么地方

};

//初始化nf_out钩子,在钩子LOCAL_OUT上

static struct nf_hook_ops nf_out =

{

.hook = nf_hook_out,//绑定执行函数nf_hook_out()

.hooknum = NF_INET_LOCAL_OUT,//钩子类型

.pf = PF_INET,//指定IPv4协议族

.priority = 0//指定在执行的顺序中,这个hook函数应当在被放在什么地方

};

static int __init nf_init(void){//模块入口

nf_register_hook(&nf_in);//注册nf_in钩子函数

nf_register_hook(&nf_out);//注册nf_out钩子函数

return 0;

}

static void __exit//模块退出

nf_exit(void){

nf_unregister_hook(&nf_in);//注销nf_in钩子函数

nf_unregister_hook(&nf_out);//注销nf_out钩子函数

}

module_init(nf_init);

module_exit(nf_exit);

MODULE_LICENSE("GPL");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: