如果要自己填充IP数据报,那么计算Checksum是必不可少的一步,算法如下。
按16位一组,取补码相加,然后对和取补码 USHORT Checksum(USHORT *buffer, int size) { unsigned long cksum=0;
while(size >1) { cksum+=*buffer++; size -=sizeof(USHORT); } if(size) cksum += *(UCHAR*)buffer; cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >>16); return (USHORT)(~cksum); }
checksum的计算:除去checksum以外的所有ip头数据,以16-bit的形式,计算其1‘s component和,即溢出位加在最小位上(any overflows from the most significant bits are added into the least significant bits.),再将其和的反码(1‘s component查了半天,英语真是差=.=)放入checksum field 校验的过程:头部的数据,包括checksum,计算其和,取反,如果结果为全1,则succeed(原文见ftp://ftp.rfc-editor.org/in-notes/rfc1071.txt"; target="_blank" >ftp://ftp.rfc-editor.org/in-notes/rfc1071.txt<;/A>) 当其中的数据发生了改变,如何进行计算呢?如ttl,每过一个网关,ttl减一,而checksum当然也得相应发生改变,重新计算? 当然是离不开数学滴,于是有了 Incremental Updating of the Internet Checksum(原文见ftp://ftp.rfc-editor.org/in-notes/rfc1141.txt"; target="_blank" >ftp://ftp.rfc-editor.org/in-notes/rfc1141.txt<;/A>),于是就以下一个checksum的计算式子: HC'' = ~(C + (-m) + m'')= HC + m + ~m'' 当然,也不能离开计算机的特性滴:+0,-0(溢出吧,算),于是又出来了一个Computation of the Internet Checksum via Incremental Update(原文见ftp://ftp.rfc-editor.org/in-notes/rfc1624.txt"; target="_blank" >ftp://ftp.rfc-editor.org/in-notes/rfc1624.txt<;/A>)于是就有了以下一个计算式子,消除特殊情况下的副作用的: HC'' = ~(C + (-m) + m'') = ~(~HC + ~m + m'')
HC - old checksum in header C - one''s complement sum of old header HC'' - new checksum in header C'' - one''s complement sum of new header m - old value of a 16-bit field m'' - new value of a 16-bit field
就这样.
(iwgh) |