您的位置:首页 > 其它

IP数据报首部检验和字段分析

2014-04-21 11:00 549 查看
说明:本文仅供学习交流,不得用于其它目的,转载请标明出处,欢迎转载!
我们知道,IP是TCP/IP协议族中最为核心的协议。所有的TCP、UDP、ICMP、IGMP都是以IP数据报的格式传输,而IP数据报首部中包含16位首部检验和字段,那么该字段是如何工作的呢?就此,我们从以下几个问题来分析:
1.发送方是如何填充该16位检验和字段的?
2.接收方式如何通过该16为检验和字段来判断数据是否在传输过程中发生错误?
下面,我们根据这两个问题,做详细的分析。
问题一:发送方与检验和字段
关于发送方如何填充检验和字段,我们应该分为以下两种情况分析:
情况一:当采用的是IP时,首部检验和字段仅根据数据报的首部计算检验和码;
情况二:当采用的是TCP、UDP、ICMP、IGMP时,首部检验和则同时根据数据报的首部和数据部分进行检验和码的计算。
对于这两种情况,计算过程是一样的,只是计算的范围不一样而已,下面我们仅以IP为例:
计算过程:
1.将数据报首部中的16为检验和字段各位全部置0;
2.将首部中的数据按16位分成若干块,每个数据块包含16位(每块包含16位的原因是检验和正好是16位,这样便于将计算结果填充到对应的16位字段);
3.将上述各个含16位的块取反再求和,值得注意的是,在求和过程中,如果发生进位,则不管。相当于我们在C语言中的异或运算(相同为0,不同为1)
4.将最终的结果取反后填入到检验和字段。
问题二:接收方与检验和字段
接收方同样根据协议的类型,在收到数据后来决定数据报的数据部分是否需要参与运算(只有IP的数据部分不需参与运算,TCP,UDP,ICMP,IGMP的数据部分均需要参与运算),此时检验和字段也需要参与计算,具体如下:
1.将收到的数据报首部中的数据按照16位分成若干块;
2.将上述各个含16位的块取反再求和,千万要记住此时检验和字段也参与计算(而在发送发,检验和字段是否参与运算对结果并不会产生影响,因为接收方该字段最终会被填充)
3.根据最终的16位反码求和结果,判断数据是否出错。若最终结果为0,则说明数据无误,将数据接收;若最终计算结果不为0(实际上,根据二进制反码的定义,存入到字段的却是16个全1),则说明数据有误,将数据抛弃,注意不会向发送方发送一个相应的ICMP报文,这件事应该由上层根据丢失的报文来发送相应的ICMP报文
注意:上面第3步中有些书上是根据结果是否为11111111 1111111,即0的反码来判断,但是都是一个意思。
问题三:为什么可以通过这种方法来验证数据是否有误?
这种方法其实很好理解,我先举个很简单的例子:
还记得C/C++中的异或运算^吗?异或运算满足:
交换律:a^b=b^a;
结合律: a^b^c=(a^b)^c=a^(b^c)
且满足性质:0^a=a, a^a=0
则必有:a^b^b=a^(b^b)=a^0=a
记得刚我们所说的反码求和的过程吗?我们提出不进位机制,这样整个求和过程就相当于是一个异或运算过程。现在假设首部中的反码求和结果(假设此时不包含检验和那16位)为X,则发送方的检验和字段被X填充。若数据在传送过程不发生错误,则接收方在收到数据报的时候同样是采用反码求和,此时首部中的其他位反码之和(不包含检验和字段)仍然是X,而数据报的检验和字段取反之和则变为-XX+(-X)=0,所以可以根据结果是否为0来判断数据在传输过程是否发生错误。
整个过程就相当于将一个数A,与其相反数-A相加是否为0。有人肯定会说,那还用说,3岁小孩都知道会为0。但是你必须得明白,数据报中可能某个16位组成的块在发送前是X1,但是若数据在传送过程中发生错误的话,接收端接到该数据的值就不一定是X1,可能变成X2了,这样X1‘+(-X1)=X2+(-X1),就不为0了。这个校验的过程就是这么一个原理!现在应该明白了吧!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: