在网络层封装时要求需要对头部数据进行保护,IPv6与IPv4对头部校验和(CheckSum)的计算方法不同,下文主要针对IPv4的头部校验和进行计算过程介绍。
1. IPv4中的可选字段是否参与校验和计算
在IPv4的头部中会有可选的数据段,那么可选数据要参与IP头部的检验和计算吗?答案是可选字段不需要参与头部校验和的计算。主要原因是一般IP报文中不包含可选字段,另外有一些小型商业公司生产的路由器会选择丢弃IP报文中的可选字段,为了IP校验和在收/发方及网络中参与计算的设备一致,因此IPv4的头部校验和计算不包含可选字段。
-
哪些设备需要参与校验和计算
IPv4的校验和需要哪些设备参与计算呢?首先是收/发双方的主机需要校验和计算,发方计算校验和用于填充校验和字段,收发用于检查接收的IPv4的IP报文的头部是否正确,如果发现错误接收主机直接丢弃IP数据包。其次是网络中对数据包进行重新分片或重新组包的设备需要重新计算校验和,并修改校验和。再者是网络中的路由器会重新计算校验和,由于在路由过程中,IP数据包每一跳(hop),TTL(Time to live)都会减1,因此会引起校验和的变化。
-
校验和填充计算
IPv4的头部结构如图1所示,由于可选字段不参与校验和的计算,因此参与计算的部分总共5个32-bit。
图1
IPv4校验和计算采用16位数据求和的过程,校验和的结果也是16位的二进制数。计算过程如下:
(1)将首部校验和部分清零,将校验和变量清零,即checksum=0;
(2)将首部其它部分填充完毕,示例如表2
表2
04 | 05 | 0 |
0073(115) |
|
0000 | 4000(表示不能分片) | |||
40 | 11 |
0000 |
||
c0a8 0001 (192.168.0.1) | ||||
c0a8 00c7(192.168.0.199) |
(3)将表2按照16位数据的方式排列如下:
4500 0073 0000 4000 4011 0000 c0a8 0001 c0a8 00c7
(4)计算校验和,并设Cy为进位位
{Cy, checksum}=0x4500 +0x0073+ 0x0000+ 0x4000+ 0x4011+ 0x0000+0x c0a8+ 0x0001+0xc0a8 +0x00c7=0x2479C
其中Cy=16’H0002(0x0002), checksum=16’h479c(0x479c)
(5)进位位参与求和
{Cy, checksum}=checksum+Cy=0x479c+0x0002=0x479e
其中Cy=0x0, checksum=0x479e
(6)检查进位位是否为零,不为零重复(5)的计算过程
(7)将计算的校验和求反(求1的补码),checksum=~checksum=0xb861
(8)将计算结果填充到表2中的校验和字段,如表3所示
表3
04 | 05 | 0 | 0073115) | |
c0a8 00c7(192.168.0.199) |
-
接收端校验计算
接收端的校验计算与发送端计算过程类似,过程如下,
(1)将校验和变量清零,checksum=0;
(2)将接收的IPv4头部数据按照16位数据的方式排列如下(继续采用上面的例子):
www.ica123.com
(3)计算校验和,并设Cy为进位位
(4)进位位参与求和
{Cy, checksum}=checksum+Cy=0xFFFD+0x0002=0xFFFF
其中Cy=0, checksum=0xFFFF
(5)检查进位位是否为零,不为零重复(4)的计算过程
(6)检验结果判定,如果计算结果为0xFFFF判定接收正确,否则判定接收错误并丢弃接收的数据包。
练习题:
- 利用Verilog描述IPv4 header checksum的计算,并用testbench验证
- 利用C语言编写IPv4 header checksum的计算程序,并验证结果。