请问我在netfilter钩子LOCAL_OUT处,对TCP数据段添加了一部分内容(16个字节),我在钩子函数里只有一次memcpy()数据拷贝动作。为什么抓包显示有多次重复的插入数据出现?而且这个重复的次数不太固定,有的分组,重复了两次,有的重复了六次之多。我用skb_put扩展了字段,并更新了包校验和。数据插入点为TCP数据部分的开头处。以下为我的钩子函数和抓包截图,请不吝赐教,谢谢大家!unsigned int hook_func(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn) (struct sk_buff *))
{
struct iphdr *iph = NULL;
unsigned char *tcp_ins = NULL; //tcp插入指针
struct tcphdr *tcph = NULL; //tcp头
unsigned int tcp_len = 0; //tcp报文长度
unsigned int data_len = 0; //tcp数据部分长度
unsigned char insert[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; //插入数据
if(skb == NULL)
return NF_ACCEPT;
if(is_ign_pkt(skb)==1) //过滤需要修改的数据包,此后都是要修改的数据包
return NF_ACCEPT;
if(skb_is_nonlinear(skb)) //线性化skb
{
if(skb_linearize(skb) != 0)
return NF_ACCEPT;
}
iph = ip_hdr(skb); //skb的ip头
if(iph == NULL)
return NF_ACCEPT;
if(iph->protocol==TCP)
{
if(skb_tailroom(skb)<=16) //判断tailroom空间
{
printk("TCP NOT Enough\n");
}
else
{
printk("TCP tail: 0x%u\n",skb->tail);
skb_put(skb,16); //数据段空间扩展
printk("TCP new_tail: 0x%u\n",skb->tail);
printk("TCP------tailroom: %u------\n",skb_tailroom(skb));
tcph = tcp_hdr(skb);
tcp_ins = (unsigned char *)tcph + (tcph->doff*4); //指向数据起始处
iph->tot_len = htons(ntohs(iph->tot_len)+16);
tcp_len = ntohs(iph->tot_len) - iph->ihl*4;
data_len = tcp_len - (tcph->doff*4);
memmove(tcp_ins+16, tcp_ins, data_len); //原始数据后移留出插入空间
memcpy(tcp_ins, insert, 16); //拷贝插入数据
tcph->check = 0;
skb->csum = 0;
iph->check = 0;
skb->csum = skb_checksum(skb, iph->ihl*4,ntohs(iph->tot_len)-iph->ihl*4,0);
tcph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, tcp_len, iph->protocol, skb->csum);
iph->check = ip_fast_csum(iph, iph->ihl);
}
return NF_ACCEPT;
}
return NF_ACCEPT;
}
{
struct iphdr *iph = NULL;
unsigned char *tcp_ins = NULL; //tcp插入指针
struct tcphdr *tcph = NULL; //tcp头
unsigned int tcp_len = 0; //tcp报文长度
unsigned int data_len = 0; //tcp数据部分长度
unsigned char insert[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; //插入数据
if(skb == NULL)
return NF_ACCEPT;
if(is_ign_pkt(skb)==1) //过滤需要修改的数据包,此后都是要修改的数据包
return NF_ACCEPT;
if(skb_is_nonlinear(skb)) //线性化skb
{
if(skb_linearize(skb) != 0)
return NF_ACCEPT;
}
iph = ip_hdr(skb); //skb的ip头
if(iph == NULL)
return NF_ACCEPT;
if(iph->protocol==TCP)
{
if(skb_tailroom(skb)<=16) //判断tailroom空间
{
printk("TCP NOT Enough\n");
}
else
{
printk("TCP tail: 0x%u\n",skb->tail);
skb_put(skb,16); //数据段空间扩展
printk("TCP new_tail: 0x%u\n",skb->tail);
printk("TCP------tailroom: %u------\n",skb_tailroom(skb));
tcph = tcp_hdr(skb);
tcp_ins = (unsigned char *)tcph + (tcph->doff*4); //指向数据起始处
iph->tot_len = htons(ntohs(iph->tot_len)+16);
tcp_len = ntohs(iph->tot_len) - iph->ihl*4;
data_len = tcp_len - (tcph->doff*4);
memmove(tcp_ins+16, tcp_ins, data_len); //原始数据后移留出插入空间
memcpy(tcp_ins, insert, 16); //拷贝插入数据
tcph->check = 0;
skb->csum = 0;
iph->check = 0;
skb->csum = skb_checksum(skb, iph->ihl*4,ntohs(iph->tot_len)-iph->ihl*4,0);
tcph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, tcp_len, iph->protocol, skb->csum);
iph->check = ip_fast_csum(iph, iph->ihl);
}
return NF_ACCEPT;
}
return NF_ACCEPT;
}
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货