IP、TCP校验和

在网上看了半天,没看明白,现在总算明白了。


下面是一条最简单的指令,没有数据


45 0 0 34 4D C5 40 0 72 6 20 E1 D3 93 4 CC C0 A8 1 16  


4E 23 6 8F 36 CA 45 A3 EC 73 CB FB 80 10 1E E8 D0 2A 0 0  


1 1 8 A 15 F AC FE 0 0 A1 EF


第一行是IP包头,


(2-3)字节0 34 表示包总长hex(34)=52


计算校验和时,先把(10-11)16位IP首部校验和置0(如果不置0,算出的校验和是0,这就相当于检测原来的校验和是否正确),在去用网上流传的checksum 函数就可算出来了。(20 E1)和指令中的一致。


4500+0034+4DC5+4000+7206+0(20E1置0)+D393+4CC+c0A8+116=2DF1C


2+DF1C=DF1E


~DF1E=20E1


第二行是TCP包头,


(12)80 表示TCP包头长hex(80/4)=32,后面的12个字节是TCP包头的可选项(可怜我一直以为是TCP的伪包头,实际上TCP的伪包头是不发的,根本就不存在)。


计算TCP的校验和时,有三部分:TCP伪包头+TCP包头+数据。


这条指令没有数据,就只用算两部分,


伪包头自己写,


源IP地址        目的IP地址       置空(0)         协议类型         TCP包的总长度


D3 93 4 CC   C0 A8 1 16      0                   6                      0       20


源IP地址,目的IP地址,协议类型在IP包头中有,直接移过来, TCP包的总长度用IP包中的总长度0x34-IP包的长度0x14(定长20)=0x20。


然后把TCP伪包头+TCP包头+数据三部分合起来(TCP包头的(16-17)校验和置0),再用鼎鼎大名的checksum函数,就可算出校验和 D0 2A .


_________________________________________________________________________________


 


unsigned short checksum(unsigned short *buf, int nword)
{
    unsigned long sum;


    for(sum = 0; nword > 0; nword--)
        sum += *buf++;


    sum = (sum>>16) + (sum&0xffff);
    sum += (sum>>16);


    return ~sum;
}


 

猜你喜欢

转载自blog.csdn.net/wangyanchao151/article/details/32405297
今日推荐