在IP协议中有"首部校验和"字段用来校验在传输过程中首部是否正确;在UDP协议中有"校验和"字段用来校验首部和数据;在TCP协议中有"校验和"字段用来校验首部和数据;校验和也称为Internet校验和,其计算方式与采取二进制补码和运算不同,其计算方式见《TCP IP详解卷1:协议 原书第2版》5.2.2节及《计算机网络(第7版)-谢希仁》5.2.2节。其计算方式为:取2个16位(2字节)数据进行二进制补码求和,若最高位还有进位则进位的1加到和的最低位,此时的和为S1,再取2个16位数据与S1进行二进制补码求和,若最高位还有进位则进位的1加到和的最低位,如此反复直到所有数据计算完毕,最后对和取反即得校验和。

说明:(1)若不足16位的需要补0够16位,计算开始时校验和位置置0。

(2)从概述中可以看出UDP和TCP中有校验和,IP层中也有校验和显得IP层中的校验和有点多余,因为上层UDP和TCP会校验,加之现在网络采用光纤传输质量有保证,所以IPv6中取消了校验和,其校验交给了上层协议。

下面以《TCP IP详解卷1:协议 原书第2版》5.2.2节的例子看如何计算

数据为:E3 4F 23 96 44 27 99 F3 00 00 (最后00 00为校验和字段)




wireshark 怎么查看头部校验_IP


计算的和为E500,对其取反~E500=1AFF

故最终传输数据为E3 4F 23 96 44 27 99 F3 1A FF(1A FF为校验和)

接收者收到后校验过程与计算校验和类似


wireshark 怎么查看头部校验_IP_02


计算的和为FFFF,对其取反~FFFF=0

故校验和为0则说明传输无问题,否则有问题,路由器会丢弃此包。

如何在C程序中进行校验和的计算呢?下面给出示例程序


wireshark 怎么查看头部校验_校验和_03


wireshark 怎么查看头部校验_校验和_04


因为程序中数据是按char数组组织的,而checksum函数是按short进行读取的,即按1个字节组织但按每次2个字节读取,所以要注意大小端模式。

对于要验证的IP头数据,如果在wireshark中可以很方便的提取出来,方法是在IP数据上右击选择show packet bytes,在弹出的对话框中选择C Array就可以方便的得到IP数据了。


wireshark 怎么查看头部校验_数据_05


wireshark 怎么查看头部校验_校验程序_06