网络协议栈实现分析8--ICMP校验和计算

 

校验和计算:

   为了计算一份数据报的校验和码。首先把校验和字段置为0。然后,对首部中每一个16bit进行二进制反码求和,结果存在校验和字段中。当受到到一份ip数据报后,同样对首部中每个16bit进行二进制反码的求和。由于接收方在计算过程中包含了发送方存在首部中的检验和,因此,如果首部在传输过程中没有任何差错,那么接收方计算的结果应该为全1.

Icmp 校验和的计算:

TCP/ip协议对校验和计算方法:对16位的数据进行累加计算,并返回求反的计算结果。

需要注意的是对奇数个字节数据的计算。是将最后的有效数据作为最高位的字节,低字节填充为0.

 /* CRC16校验和计算icmp_cksum

参数:

data:数据

len:数据长度

返回值:

计算结果,short类型

*/

static unsigned short icmp_cksum(unsigned char *data,  int len)

{

       int sum=0;/* 计算结果 */

int odd = len & 0x01;/*是否为奇数*/

unsigned short *value = (unsigned short*)data;

/*将数据按照2字节为单位累加起来*/

       while( len & 0xfffe)  {

              sum += *(unsigned short*)data;

data += 2;

len -=2;

       }

/*判断是否为奇数个数据,若ICMP报头为奇数个字节,会剩下最后一字节。*/

       if( odd) {

unsigned short tmp = ((*data)<<8)&0xff00;

              sum += tmp;

       }

       sum = (sum >>16) + (sum & 0xffff);  //16位与低16位相加

       sum += (sum >>16) ;               //如果逸出则再相加

       

       return ~sum;

}

经过对ping程序的改良后,发现该函数的len值的设置并不影响icmp的使用。具体原因尚待分析。

 

<基于www.hacktao.com上的作品创作,转载请注明!>

你可能感兴趣的:(网络协议栈实现分析8--ICMP校验和计算)