二进制求出的和如果大于16位时所做的操作,用和值中高16位加上低16位的值作为最终的和值,然后再做取反运算。
typedef unsigned short u16;
typedef unsigned long u32;
u16 ip_sum_calc(u16 len_ip_header, u16 buff[])
{
u16 word16;
u32 sum=0;
u16 i;
// make 16 bit words out of every two adjacent 8 bit words in the packet
// and add them up
for (i=0;i<len_ip_header;i=i+2){
word16 =((buff[i]<<8)&0xFF00)+(buff[i+1]&0xFF);
sum = sum + (u32) word16;
}
// take only 16 bits out of the 32 bit sum and add up the carries
while (sum>>16)
sum = (sum & 0xFFFF)+(sum >> 16);
// one's complement the result
sum = ~sum;
return ((u16) sum);
}
UDP校验方法:
UDP的CHECKSUM算法与IP包的HEADER CHECKSUM的计算方法基本一样,只是取样数据不同。
UDP中,参与计算CHEKCSUM的数据包括三部分:
伪头部+UDP头部+数据部分
- 伪头部包括:
2byte源IP地址+2byte目的IP地址+0x00+1byte协议类型+2byte UDP长度 - UDP包头:
2byte源端口+2byte 目的端口+2byte UDP长度+0x0000(checksum) - 数据部分:奇数时在尾部添加一个PAD。
计算方法,以2字节为一个单位,将其顺序相加,就会产生2个字节的SUM,如果超过2字节,则将高位的值再加回低位,然后取补,得到的就是UDP的校验和。