飞翔灬吾爱的Blog
华为网络基础 | IP包校验和算法实例抓包验证
2018-8-17 fishyoung

上一篇已经说明了TCP为什么这么复杂,因为既要保证可靠性, 同时又要尽可能提高性能。在保证可靠性的机制中,讲解了序列号(按序到达)确认应答机制,今天继续讲解校验和机制,讲解TCP校验和机制之前,先来学学IP包的校验和,为什么呢?????因为TCP 首部检验和与 IP 首部校验和的计算方法相同,在程序中使用同一个函数来计算。

关于IP报文头部结构及字段说明,在之前的RS | IP报文头部篇章已将将结果了,这儿不再过多赘述,具体的知识点请点击超链接查看学习。

这次的重点是IP包的校验和计算原理和实际验证

一、IP包的校验和原理

当发送IP包时,需要计算IP报头的校验和,原理及过程如下:

1、把校验和字段置为0

2、对IP头部中的每16bit进行二进制求和;

3、如果和的高16bit不为0,则将和的高16bit和低16bit反复相加,直到和的高16bit0,从而获得一个16bit的值;

4、将该16bit的值取反,存入校验和字段中。

当接收 IP 包时,需要对报头进行确认,检查 IP 头是否有误,算法同上23步,然后判断取反的结果是否为0,是则正确,否则有错。

二、算法

SHORT checksum(USHORT* buffer, int size)
{
unsigned long cksum = 0;
while(size>1)
{
    cksum += *buffer++;
    size -= sizeof(USHORT);
}
if(size)
{
    cksum += *(UCHAR*)buffer;
}
cksum = (cksum>>16) + (cksum&0xffff);           // 将高 16bit 与低 16bit 相加
cksum += (cksum>>16);                                     // 将进位到高位的 16bit 与低 16bit 再相加
return (USHORT)(~cksum);
}

算法是不是感觉不太好理解,好吧,下面通过实际抓包验证。认真看哟!!!

三、实例验证

从下图的WireShark抓包分析可以得出IP头部的一些信息

把以上所抓取的信息划到表格中如下:[hide]

再把表格里的信息转换成二进制如下:

按照过程进行:

1、首先将检验和置零;

2、然后将IP头,都化为二进制数;

3、如果和的高16bit不为0,则将和的高16bit和低16bit反复相加,直到和的高16bit0,从而获得一个16bit的值;

4、最后将该16bit的值取反,存入校验和字段0x64b6

如下是计算步骤:

我们将计算出来的74e1和第一张图中的数值对比一下,是否一样?

即:通过某种的算法,得出了最终的值,这个值即为应填充的校验和。

当接收到IP数据包时,要检查IP头是否正确,则对IP头进行校验,方法同上,只是把头部校验和的“0000 0000 0000 0000”换成正式的头部校验和,最终求和为FFFF,取反为0000,表示数据在传输过程中没问题,正确的。

[/hide]开篇已经说过,TCP 首部检验和与 IP 首部校验和的计算方法相同,在程序中使用同一个函数来计算。

需要注意的是,由于 TCP 首部中不包含源地址与目标地址等信息,为了保证 TCP 校验的有效性,在进行 TCP 校验和的计算时,需要增加一个 TCP 伪首部的校验和,具体的我们将在下一篇博文中继续讲述。

评论:
顾涛
2020-03-03 10:01 回复
复习一下,查看隐藏内容
顾涛
2020-03-03 09:46 回复
隐藏内容
顾涛
2019-12-25 16:08 回复
查看隐藏内容