TCP/IP校验和计算算法

来源:互联网 发布:深圳蜂窝网络 编辑:程序博客网 时间:2024/04/29 08:26

ICMP,IP,UDP,TCP报头部分都有checksum(检验和)字段。ICMP和IP报头校验和的计算都很简单,过程如下:

1.把校验和字段置为0;

2.对IP头部中的每16bit进行二进制求和;

3.如果和的高16bit不为0,则将和的高16bit和低16bit反复相加,直到和的高16bit为0,从而获得一个16bit的值;

4.将该16bit的值取反,存入校验和字段。

//计算校验和
USHORT checksum(USHORT *buffer,int size)
{
 unsigned long cksum=0;
 while(size>1)
 {
  cksum+=*buffer++;
  size-=sizeof(USHORT);
 }
 if(size)
 {
  cksum+=*(UCHAR *)buffer;
 }
 //将32位数转换成16
 while (cksum>>16)
  cksum=(cksum>>16)+(cksum & 0xffff);
 return (USHORT) (~cksum);
}

UDP/TCP报头中的校验和的计算比较复杂的,要用到 UDP/TCP伪首部:先要填充伪首部各个字段,然后再将UDP/TCP报头以后(包括报头)的数据附加到伪首部的后面,再对位首部使用上述校验和计算,所得到的值才是UDP/TCP报头部分的校验和。 位首部可以用如下的结构体表示:typedef struct{
 ULONG  sourceip;    //源IP地址
 ULONG  destip;      //目的IP地址
 BYTE mbz;           //置空(0)
 BYTE ptcl;          //协议类型
 USHORT plen;        //TCP/UDP数据包的长度(即从TCP/UDP报头算起到数据包结束的长度 单位:字节)
}Psd_Header; 注:1.对于UDP协议,如果不想计算的话,可以把校验和的两个字节置0,根据RFC的规定,这样上层UDP协议就不会计算校验和了2.sniffer查看校验和时,最好在中间节点。你在本机抓的时候,你的协议驱动在NDIS架构中层次太高,与标准协议栈是平级的,此时校验和处未被计算填充,还是垃圾填充数据。你在网络其它节点抓的时候,报文已经经过网卡的处理,校验和被正确设置了。

0 0
原创粉丝点击