- 论坛徽章:
- 0
|
本帖最后由 zhengli85 于 2014-07-16 01:46 编辑
在CentOS 5.6 x86_64中利用Netfilter对TCP、UDP数据进行加密,但出现一点问题,还请各位帮忙看一下:
一、问题描述
1、该代码在5.2 i386环境下是正常的,所以不知道是不是64位的问题;
2、流入的数据能够正常识别并解密,但是流出的数据出现问题,打印输出后发现从skb获取的数据指向并不是真正需要数据
二、系统环境
[root@localhost ~]# lsb_release -a
LSB Version: :core-4.0-amd64:core-4.0-ia32:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-ia32:graphics-4.0-noarch:printing-4.0-
amd64:printing-4.0-ia32:printing-4.0-noarch
Distributor ID: CentOS
Description: CentOS release 5.6 (Final)
Release: 5.6
Codename: Final
[root@localhost ~]# uname -a
Linux localhost.local5.6 2.6.18-238.el5 #1 SMP Thu Jan 13 15:51:15 EST 2011 x86_64 x86_64 x86_64 GNU/Linux
三、问题代码
/*******************************************************************************************************
*根据sk_buff、加密类型、数据方向进行加密
*******************************************************************************************************/
static void crypt_ip_data_skb(struct sk_buff *skb,unsigned int crypt_type,int watch_flag)
{
char * data=NULL;
unsigned short data_len=0;
__u8 protocol_type=0;
struct tcphdr *tcphead=NULL;
struct udphdr *udphead=NULL;
int ip_head_len=0;
int tcp_udp_len=0;
#ifdef DEBUG_MODE
printk(KERN_EMERG"crypt_ip_data_skb\tcrypt_type:%d\twatch_flag:%d\n",crypt_type,watch_flag);
#endif
if (!skb )return;
if (!(skb->nh.iph)) return;
protocol_type=skb->nh.iph->protocol;
ip_head_len=(skb->nh.iph->ihl * 4);
switch(protocol_type)
{
case IPPROTO_TCP:
{
tcphead= (struct tcphdr *)(skb->data + ip_head_len);
tcp_udp_len=tcphead->doff*4;
data=(unsigned char *)tcphead+tcp_udp_len;
data_len=ntohs(skb->nh.iph->tot_len)-ip_head_len-tcp_udp_len;
break;
}
case IPPROTO_UDP:
{
udphead= (struct udphdr *)(skb->data + ip_head_len);
data=(unsigned char *)udphead+8;//sizeof(udphdr)=8
data_len=ntohs(udphead->len)-8;
break;
}
default:
{
return ;
}
}
//根据数据方向进行加减密
if(watch_flag==fliter_watch_in)
{
#ifdef DEBUG_MODE
printk(KERN_EMERG"fliter_watch_in\tdata:0x%08x\n",(int)data);
#endif
decrypt_data_raw(data,data_len,crypt_type);
}
if(watch_flag==fliter_watch_out)
{
#ifdef DEBUG_MODE
printk(KERN_EMERG"fliter_watch_out\tdata:0x%08x\n",(int)data);
#endif
#ifdef DEBUG_MODE
printk(KERN_EMERG"%02x%02x%02x%02x\n",data[0],data[1],data[2],data[3]);
#endif
encrypt_data_raw(data,data_len,crypt_type);
#ifdef DEBUG_MODE
printk(KERN_EMERG"%02x%02x%02x%02x\n",data[0],data[1],data[2],data[3]);
#endif
}
return;
}
四、hook点
pre_hook.hook = watch_in;
pre_hook.pf = PF_INET;
pre_hook.priority = NF_IP_PRI_LAST;
pre_hook.hooknum = NF_IP_LOCAL_IN;
post_hook.hook = watch_out;
post_hook.pf = PF_INET;
post_hook.priority = NF_IP_PRI_LAST;
post_hook.hooknum = NF_IP_LOCAL_OUT;
nf_register_hook(&pre_hook);
nf_register_hook(&post_hook); |
|