- 论坛徽章:
- 0
|
要重新计算tcp校验和时,把google和cu翻了遍!!!
结果就是,一半一半吧!
现总结如下:
ms有两种方法,一种是从头开始,整个重新计算校验和;还有一种呢就是,修改不超过连续16个字节,就在原来的基础上修改。为什么说一半一半呢,是第一种方法,我怎么都没有成功,但我的需求后一种方法也可以满足,就没有再深究了。(浅尝辄止,明明知道,就是改不了啊!!!sharememory的问题也是一样,这个下一篇在写)
先说我会的吧:
u_int16_t diffs[2];
diffs[0] = ((htons(th->urg) 5) + (htons(th->ack) 4) + (htons(th->psh) 3) + (htons(th->rst) 2) + (htons(th->syn) 1) + htons(th->fin)) ^ 0xFFFF;
diffs[1] = (htons(th->urg) 5) + (htons(th->ack) 4) + (htons(th->psh) 3) + (htons(th->rst) 2) + (htons(th->syn) 1) + htons(th->fin);
th->check = csum_fold(csum_partial((char *)diffs,
sizeof(diffs),
th->check^0xFFFF));
用一个diff[0]记下改之前的(要^0xFFFF),diff[1]记下改之后的。我改的是tcp的标志位,要移位之类的,看起来有点长啊。然后用csum_fold算一下就好了,简单吧。
接下来是我没成功的:
只需要调用tcp_v4_check函数即可,当然,也可以调用更低层的函数,例如csum_tcpudp_magic()函数。计算tcp头部的checksum,csum_tcpudp_magic()的参数为源地址(网络字序),目的地址(网络字序)、skb->len、skbuff的校验和。skubuff的校验和是skb->csum,当然也需要自己计算,这其实是个中间值,用来计算出最终的tcp头部checksum。skb->csum为报文数据(除去mac头部,ip头部,tcp头部)的校验和,可以使用csum_partial函数计算,参数为数据指针,长度,0。
下面的代码,一搜就找到了:
iph->check = 0;
iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
size = ntohs( nskb->nh.iph->tot_len ) - ( nskb->nh.iph->ihl * 4 );
nskb->csum = 0;
nskb->csum = csum_partial( nskb->h.raw + doff, size - doff, 0 );
th->check = tcp_v4_check(th, size,
iph->saddr,
iph->daddr,
csum_partial((char *)th , doff , nskb->csum));
疑惑的是doff的值,后来找到了一般是
doff = th->doff 2; //tcp头长度
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/48851/showart_386854.html |
|