计算机网络-ipv4首部校验原理
一、 核心目标:是什么与为什么
是什么? IPv4 首部校验和是一个 16 比特(2 字节) 的字段,位于 IPv4 数据包的首部。
为什么? 它的唯一目的是检测 IPv4 数据包首部在传输过程中是否发生了错误。这些错误可能由路由器、交换机等网络设备的物理链路问题、信号干扰、内存故障等原因引起。
重要特点:
只校验首部,不校验数据: 校验和的计算范围仅限于 IP 首部(通常 20 字节,不含选项)。传输层(如 TCP、UDP)有它们自己的校验和,用于保护数据。
逐跳计算: 由于 IP 首部中的 TTL(生存时间) 字段在每一跳路由器都会减 1,所以每一台处理该数据包的路由器都必须重新计算校验和。
错误处理简单: 如果校验失败,接收方(通常是路由器或目的主机)会直接、静默地丢弃该数据包。它不会请求重传,因为 IP 协议本身是无连接、不可靠的。重传的责任由上层协议(如 TCP)负责。
二、 校验原理:核心思想
校验和的核心思想是 “反码算术和” 的冗余校验。
可以把它理解为一个 “一致性检查”:
发送方: 在发送数据包之前,它将整个 IP 首部视为一系列 16 位的字(word)。对这些字进行一种特殊的加法运算,得到一个 16 位的结果,这个结果就是校验和,并将其填入首部的校验和字段。
接收方: 收到数据包后,它对整个 IP 首部(包括发送方填入的校验和字段本身)进行完全相同的加法运算。
结果判定:
如果传输过程中没有发生任何错误,接收方计算出的结果应该是一个固定值:全 1(即 0xFFFF)。
如果结果不是全 1,则说明首部在传输中发生了比特错误,数据包被丢弃。
为什么结果是全 1 就代表正确? 这正是“反码算术”的精妙之处,我们将在计算步骤中详细解释。
三、 详细计算步骤
我们通过一个具体的例子来演示。假设有一个非常简单的 IP 首部(为了计算方便,我们使用极简的例子,实际首部为 20 字节)。
步骤 1:发送方计算校验和
将首部划分为 16 位字:
将 IP 首部(不包括数据)从头开始,每 16 位(2 字节)作为一个单元。如果首部长度不是 16 位的整数倍(比如有选项字段),则在末尾补零到 16 位。在我们的例子中,假设首部有 4 个 16 位字(共 8 字节):Word 1:
0x4500
Word 2:
0x0030
Word 3:
0x8a11
Word 4:
0x0000
<-- 注意:这个位置就是校验和字段,在计算前先置为 0。
计算反码算术和:
这是一个特殊的加法过程,包含“回卷”。第一次加法:
0x4500 + 0x0030 = 0x4530
第二次加法:
0x4530 + 0x8a11 = 0xCF41
(因为0x4530 + 0x8A11 = 0xCF41
)第三次加法:
0xCF41 + 0x0000 = 0xCF41
(因为校验和字段是 0,加和不变)检查回卷: 现在看结果
0xCF41
,最高位没有产生进位(它是 16 位数),所以不需要回卷。如果相加过程中产生了超出 16 位的进位(比如结果是0x1CF41
),需要将这个进位(0x1
)加回到结果的低位,这步操作称为“回卷”。回卷示例: 假设某次加和结果是
0x1CF41
。将高 16 位(进位
0x1
)与低 16 位(0xCF41
)相加:0x0001 + 0xCF41 = 0xCF42
。这个
0xCF42
就是回卷后的新和。
取反码得到校验和:
对上一步得到的最终和
0xCF41
进行按位取反操作(1 变 0,0 变 1)。0xCF41
的二进制是1100 1111 0100 0001
。按位取反后是
0011 0000 1011 1110
,即0x30BE
。这个
0x30BE
就是最终的校验和。
填入首部:
将计算出的校验和0x30BE
填入 IP 首部的第 11-12 字节(校验和字段)。现在首部的第 4 个字不再是0x0000
,而是0x30BE
。
步骤 2:接收方验证校验和
接收方进行几乎相同的操作,但关键区别是:它把发送方填好的整个首部(包括校验和字段)拿来进行计算。
将首部划分为 16 位字:
Word 1:
0x4500
Word 2:
0x0030
Word 3:
0x8a11
Word 4:
0x30BE
<-- 这次,这个字段是发送方填好的校验和!
计算反码算术和:
0x4500 + 0x0030 = 0x4530
0x4530 + 0x8a11 = 0xCF41
0xCF41 + 0x30BE = 0xFFFF
(因为0xCF41 + 0x30BE = 0xFFFF
)
检查结果:
最终结果是
0xFFFF
(二进制全 1)。不需要回卷,也不需要取反。
因为结果是全 1,所以接收方判定 IP 首部没有错误。
原理揭秘:为什么结果是全 1?
发送方计算校验和的公式本质是:
校验和 = ~(Word1 + Word2 + Word3 + 0)
接收方验证时计算的公式是:
总和 = Word1 + Word2 + Word3 + 校验和
我们把发送方的公式代入接收方的公式:
总和 = Word1 + Word2 + Word3 + ~(Word1 + Word2 + Word3)
在反码算术中,一个数加上它的反码,结果必然是全 1。
例如:
1010 + 0101 = 1111
。
因此,只要数据没有错误,接收方计算的总和就一定是全 1(0xFFFF
)。
四、 特点与局限性
强度: 校验和能检测出所有奇数个比特错误和大多数偶数个比特错误。它是一种轻量级的错误检测机制。
局限性:
强度不如CRC: 它的错误检测能力不如循环冗余校验(CRC)强。例如,在特定位置发生两个比特交换的错误,可能检测不到。这就是为什么在更注重可靠性的链路层(如以太网)和数据链路层(如 PPP)普遍使用 CRC,而 IPv6 甚至直接取消了首部校验和(将可靠性完全交由数据链路层和传输层保证)。
计算开销: 由于 TTL 字段变化,每一跳都需要重新计算,对路由器 CPU 有一定的开销。
总结
步骤 | 发送方 | 接收方 |
---|---|---|
1. 准备 | 将校验和字段置零。 | 接收整个 IP 首部。 |
2. 划分 | 将首部按 16 位分组。 | 将首部按 16 位分组。 |
3. 求和 | 计算所有字的反码算术和(有进位则回卷)。 | 计算所有字(包括校验和字段)的反码算术和(有进位则回卷)。 |
4. 取反 | 对最终和进行按位取反,得到校验和。 | 不取反。 |
5. 动作 | 将校验和填入首部,发送数据包。 | 检查最终结果:如果为 0xFFFF,通过;否则,丢弃 |