分类:
2011-12-06 18:32:48
原文地址:网络中校验和比较 作者:asweisun_shan
本文说明了网卡, IP层,TCP层,UDP层的校验和功能,以及异同点。
网卡校验和
高级的网卡(e1000e等千M网卡)的接收,发送的校验和的计算方法是CRC32。
Refs:
http://www.intel.com/content/dam/doc/manual/pci-pci-x-family-gbe-controllers-software-dev-manual.pdf
可以使用ethtool查看网卡的校验功能,rx-checksumming是接收端的校验功能,tx-checksumming是发送端的校验功能:
# ethtool -k eth0
Offload parameters for eth0:
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp-segmentation-offload: on
udp-fragmentation-offload: off
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off
IP校验和
校验和只对头部进行,不包括数据部分。
发送IP包, 计算checksum:
(1)把IP数据报的首部校验和字段设置为0。
(2)把首部看成以16位为单位的数字组成,依次进行二进制反码求和。
(3)把得到的结果存入校验和字段中。
接收IP包,验证checksum:
(1)把首部看成以16位为单位的数字组成,依次进行二进制反码求和,包括校验和字段。
(2)检查计算出的校验和的结果是否为全1。
(3)如果全1,校验是和正确。否则,校验和就是错误的,协议栈要抛弃这个数据包。但不生成差错报文,由上层去发现丢失的数据报并进行重传。
Refs:
UDP校验和
校验和即覆盖头部,也覆盖数据部分。UDP校验和是可选的,而TCP校验和是必须的。
发送包, 计算checksum:
算法和IP头部的校验和计算方法类似:二进制反码求和。但有下面两个区别:
1) 总长度如果是奇数,则自动补齐,并自动填充为0. 填充的部分不发送出去。
2)添加12个字节的伪头部。源地址(4个字节),目的地址(4个字节),0(1个字节),udp协议号(1个字节),udp头部中长度字段值(2个字节)。
如果校验和字段是0,表示不需要计算校验和。
接收包, 验证checksum:
验证checksum是根据udp头部中的length字段值所指向的数据长度进行校验,如果length字段值大于实际的数据长度,那么包在校验前会被丢弃。如果length字段值小于实际的数据长度,则需要裁减数据,并校验。
TCP校验和
校验和即覆盖头部,也覆盖数据部分。TCP校验和是必须的。也包含了12个字节的伪头部。