IP报文头checksum的校验

本文转载自: FPGA的现今未微信公众号

IP报文的头部中有一个checksum字段,一般都知道这个字段的含义,校验IP报文的头部是否正确,但是究竟是如何计算出来的呢?以前没有怎么研究过,刚好最近工作涉及到这方面的东西,记录下。

其实IP报文头部的checksum计算非常简单,我们看看RFC1071中如何定义的。

(1)  Adjacent octets to be checksummed are paired to form 16-bit integers, and the 1's complement sum of these 16-bit integers is formed.

(2)  To generate a checksum, the checksum field itself is cleared,the 16-bit 1's complement sum is computed over the octets concerned, and the 1's complement of this sum is placed in the checksum field.

(3)  To check a checksum, the 1's complement sum is computed over the same set of octets, including the checksum field.  If the result is all 1 bits (-0 in 1's complement arithmetic), the check succeeds.

简单总结下,就是将头部以16bit为单位做反码求和。具体的操作步骤用一个例子来表示。如下图所示,是一个网络报文的IP首部。

1.png

(1)以16bit为单位分成10组,分别为:0x4500、0x0040、0x0、0x4000、0x4060、0x0(这是checksum的位置)、0xc0a8、0x0109、0x0a0d、0xe78f,然后把他们相加得到0x27893;

(2)对得到的结果重复上述步骤,得到 0x2+0x7893 = 0x7895

(3)对0x7895取反,即~0x7895 = 0x876a,即该ip报文的checksum为0x876a。

0x4500+0x40+0x0+0x4000+0x4006+0x0+0xc0a8+0x0109+0x0a0d+0xe78f = 0x27893
0x2 + 0x7893 = 0x7895
~0x7895 = 0x876a

问题一:如何校验checksum?

当接收到报文后,提取IP报文头部共20byte,然后做反码求和,还是以上述报文为例:

0x4500+0x40+0x0+0x4000+0x4006+0x876a+0xc0a8+0x0109+0x0a0d+0xe78f = 0x2fffd
0x2 + 0xfffd = 0xffff
~0xffff = 0x0

通过反码求和后,得到的结果为0,即结果正确。

问题二、可以先取反再相加吗?

可以通过一个简单的例子来说明这个问题。这里假定4个数的反码求和。如下图所示:

2.JPG

无论是先取反再求和还是求和后再取反,结果都是一样的。

问题三,计算性能如何?

在FPGA的设计中,上述方法的性能如何呢?如果以16bit为单位两两相加,需要4拍才能得到计算结果。在短包场景下,性能可能就不算很友好了。这里有2种优化方法:

第一种,每次3个16bit的数相加,以xilinx 7系列芯片为例,3个16bit的数相加,在200M时钟下时序没有压力,这样只需要3拍就可以计算完;

第二种,可以以32bit为单位进行计算,还是以上述抓包的报文头为例,如下图所示,以32bit单位进行计算,得到的结果也是876a。

3.JPG

如果以32bit为单位,两两相加,也是3拍可以计算出结果,而且32bit的数相加同样对于7系列芯片来讲没有压力。

关于checksum的校验,还有其他更好的方法吗?欢迎交流。关于IP头部checksum的相关信息,可以查看:https://www.rfc-editor.org/rfc/rfc1071.txt 

最新文章

最新文章