ICMP, IP,UDP,TCP 报头部分都有checksum(检验和)字段
ICMP 和 IP 报头校验和的计算都很简单,使用RFC1071 中给出的方法即可完成(如下)
//计算校验和 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; 这个过程是一个很繁琐的过程,计算过几次后再也忍受不了做这样重复的工作,于是写了一个通用的计算函数
这个函数使用起来我感觉非常方便:先封装好你的数据包(完整的,包括以太头),然后将数据包的首地址作为参数,调用该函数即可
函数将帮你完成IP 报头以及UDP