利用netfilter机制,实现内核防火墙把http请求和回应的数据包截获后,解释出其中的http层数据
#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");
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。