IP首部检验和详细计算步骤

前言

前段时间自己在做计算机网络的期末课设,题目就是关于IP首部检验和的计算程序的实现,要实现这个程序的首要步骤就是要搞明白相关的计算原理。可是我翻来找去,发现课本上对这部分的描述十分的.......干净利索。

IP首部的检验和不采用复杂的CRC检验码而采用下面的简单计算方法:

在发送方,先把IP数据报首部划分为许多16位字的序列,并把检验和字段置零。用反码算术运算把所有16位字相加后,将得到的和的反码写入检验和字段。

接收方收到数据报后,将首部的所有16位字再使用反码算术运算相加一次。将得到的和取反码,即得出接收方检验和的计算结果。

若首部未发生任何变化,则此结果必为0,于是就保留这个数据报。否则即认为出差错。

 说句实话,当时我看完这段话之后,本来只有一个问题在阻碍着我,然后一个问题就变成了很多的问题。

既然课本看不懂那我就去网上找找,没想到找到的结果也和课本上差不多,基本没啥用。给的例子看着好像很详细,实际上知识点非常的混乱,东说一句,西说一句,在完全不了解原理之前这些东西简直就是天书(至少在当时的我看来是这样的)。不过好在最后还是通过为数不多的高质量文章知道了如何计算IP首部检验和及其具体计算步骤,所以在这做一个详细的计算方法的总结与说明,以尽可能的帮助那些有类似经历的朋友 。

“什么是IP数据报”,“IP首部检验和是干什么用”,类似的理论叙述就不在这里详细阐述了,直接上方法。

详细计算步骤

要计算IP首部检验和,我们得先知道在IP数据报的固定部分里有什么字段(这个不是套话,很重要),以下12个字段是我们待会在计算过程中使用到的数据。

①版本(Version)   ②首部长度(Header Length)   ③区分服务(Differentiated Service Field) 

④总长度(Total Length)         ⑤标识 (Identification)            ⑥标志 (Flags)

⑦片偏移(Fragment Offset)   ⑧生存时间 (Time to Live)     ⑨协议(Protocol)

⑩首部检验和(Header CheckSum)        ⑩①源地址(Source Address) 

⑩②目的地址 (Destination Address)

上面这张图是我在WireShark中随机抓取的一个IP数据报的报头部分的数据。

通过分析这个数据报,结合上面说的12个字段,我们可以得到以下信息:

(1)版本 = 4            (2)首部长度 = 5     (3)区分服务 = 0x00      (4)总长度 = 40

(5)标识 = 5386 (0x150a)               (6)标志 = 0x40                 (7)片偏移 = 0

(8)生存时间 = 128                            (9)协议 = 6                      (10)首部检验和 = 0x72e3

(11)源地址 = 192.168.1.176            (12)目的地址 = 39.106.137.32

这里稍微介绍一下“协议”字段,课本上对协议的字段值是这么说明的:

协议名ICMPIGMPIPTCPEGPIGPUDPIPv6ESPOSPF
协议字段值12468917415089

 即什么协议就取其对应的值,上面的数据报里的协议是TCP,所以取的值是6。

在了解了上述知识点后,现在我们可以开始计算了。为了更为直观的说明计算过程,接下来均采用二进制数据作为计算数据。实际上,采用二进制数据进行计算与采用十六进制数据进行计算并无区别,读者可根据自身情况进行选择。 

将上述11个字段(除了首部检验和)转为二进制这里提一嘴,在实际的程序中,包内的首部检验和是要置零然后要参与计算的,但是因为“将首部检验和置零参与计算”和“将首部检验和排除在外然后计算”,这两者在计算结果上没有任何区别。所以,遵循怎么简单怎么来的原则,在下面的计算步骤中就不再涉及首部检验和,大家心里有个数就好,并进行字段拼接。

要注意的是,每个拼接的字段长度均为 16 位(拼接规则:每个字段括号内的数字为该字段转为二进制的最长位数,若该字段转为二进制后小于所规定的最长位数,则在该二进制首位添零,直至达到最长位数)。(“+”表示拼接)

① 版本(4) + 首部长度(4) + 区分服务(8)

② 总长度(16)

③ 标识(16)

④ 标志(8) + 片偏移(8)

⑤ 生存时间(8) + 协议(8)

⑥ 源地址第一部分(8) + 源地址第二部分(8)

⑦ 源地址第三部分(8) + 源地址第四部分(8)

⑧ 目的地址第一部分(8) + 目的地址第二部分(8)

⑨ 目的地址第三部分(8) + 目的地址第四部分(8)


由此,将得到的11个字段通过上述转换,我们可以得到如下数据(“+”表示拼接):

0100 0101 0000 0000(4 + 5 + 00)

0000 0000 0010 1000(40)

0001 0101 0000 1010(5386)

0100 0000 0000 0000(0x40 + 0)

1000 0000 0000 0110(128 + 6)

1100 0000 1010 1000(192 + 168)

0000 0001 1011 0000(1 + 176)

0010 0111 0110 1010(39 + 106)

1000 1001 0010 0000(137 + 32)

将这 9 个二进制数据相加,我们可以得到 0010 1000 1101 0001 10100x2 8d1a

可以看出,累加后的数据发生了进位,即 0b0010(0x0002)部分。

是否发生了进位可以通过位数进行判断,以二进制为例,从最后一位开始向前数 16 位,超出的位数即进位部分(0010),若该二进制数刚好为16 位,则说明未发生进位。

若发生了进位情况,只需要将进位部分(0010)与剩余部分(1000 1101 0001 1010)重新累加,直至得到的二进制数据位数等于 16 位,然后对该二进制数据取反码,即可得到首部检验和。此处可以用递归的思想实现,长度 > 16 继续递归,else return 当前计算结果

0010(进位部分) + 1000 1101 0001 1010(剩余部分) = 1000 1101 0001 1100,此时位数为 16 位,未发生进位,则无需累加。对该二进制取反码,可以得到 0111 0010 1110 00110x72e3,该计算结果与包内IP首部检验和相同,计算完成。 

结语

以上就是IP首部检验和的计算步骤,都是较为详尽的步骤。对刚接触该方法的读者来说,个人建议采用二进制的计算模式,二进制在字段拼接上比较直观易懂,能使读者尽快的了解字段拼接规则。但二进制在计算方面较为冗长,容易在累加的过程中出现错误;如果读者对该计算思想有了较为清晰的认识,可以改为采用十六进制数据进行计算,这样在计算方面会比二进制简短不少,同时也不容易出错。

IP数据报的传输中,首部检验和是一种重要的验证机制,用于确保数据包在从发送端到接收端的过程中未发生损坏。要准确计算IP数据报首部检验和,你需要遵循以下步骤: 参考资源链接:[IP首部检验和原理详解与计算方法](https://wenku.csdn.net/doc/1054f6jz6a?spm=1055.2569.3001.10343) 1. 首先,发送端会将校验和字段初始化为0。 2. 然后,将IP首部的16位字进行二进制反码求和,这意味着在求和过程中如果某一位发生进位,则进位会加到该位上,而不是向左边的高位进位(与普通的二进制求和不同,这是一种特殊的求和方式)。 3. 计算完所有16位字的和后,将得到的结果再次取反,即得到首部检验和的值,将其填充到校验和字段中。 4. 在接收端,接收到数据包后,同样对IP首部进行上述求和计算,然后检查计算结果是否为全1(即二进制的16个1),如果是,则表示数据包在传输过程中保持了完整性,没有发生错误;如果不是全1,则表示数据包受损。 为了更详细地理解整个过程,可以参考《IP首部检验和原理详解与计算方法》这份资料。该资料详细讲解了首部检验和的原理、算法以及计算方法,涵盖了从概念到具体计算步骤的各个方面,非常适合希望深入学习网络协议验证机制的专业人士。 在数据包处理过程中,首部检验和的校验不仅简化了路由器的处理工作,还提高了网络通信的传输效率。通过这种校验方式,可以在不深入分析数据报具体内容的前提下,快速检测到数据报可能存在的错误,从而保证了数据传输的可靠性。 参考资源链接:[IP首部检验和原理详解与计算方法](https://wenku.csdn.net/doc/1054f6jz6a?spm=1055.2569.3001.10343)
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值