zoukankan      html  css  js  c++  java
  • IP数据报首部校验和算法

     

    当用google搜索IP数据报首部校验和算法的时候,总是看到的是代码,没有看到其过程,于是就有了此文,如有错误请指正。文章省略一点,呵呵
     
    IP/ICMP/IGMP/TCP/UDP等协议的校验和算法都是相同的,算法如下:
    在发送数据时,为了计算数IP据报的校验和。应该按如下步骤:
    (1)把IP数据报的首部都置为0,包括校验和字段。
    (2)把首部看成以16位为单位的数字组成,依次进行二进制反码求和。
    (3)把得到的结果存入校验和字段中。
    在接收数据时,计算数据报的校验和相对简单,按如下步骤:
     
    (1)当接收IP包时,需要对报头进行确认,检查IP头是否有误,算法同上2、3步,然后判断取反的结果是否为0,是则正确,否则有错。

      

    1、发送方
      i)将校验和字段置为0,然后将IP包头按16比特分成多个单元,如包头长度不是16比特的倍数,则用0比特填充到16比特的倍数;
     
      ii)对各个单元采用反码加法运算(即高位溢出位会加到低位,通常的补码运算是直接丢掉溢出的高位),将得到的和的反码填入校验和字段;
     
      iii)发送数据包。
     
    2、接收方
      i)将IP包头按16比特分成多个单元,如包头长度不是16比特的倍数,则用0比特填充到16比特的倍数;
     
      ii)对各个单元采用反码加法运算,检查得到的和是否符合是全1(有的实现可能对得到的和会取反码,然后判断最终值是不是全0);
     
    iii)如果是全1则进行下步处理,否则意味着包已变化从而丢弃之。需要强调的是反码和是采用高位溢出加到低位的,如3比特的反码和运算:100b+101b=010b(因为100b+101b=1001b,高位溢出1,其应该加到低位,即001b+1b(高位溢出位)=010b)。

     1.实例

    请看我用ominipeek的抓包

    I.将校验和字段置为0,然后将IP包头按16比特分成多个

     

    校验和Header Checksum:0x618D将其重置为0X0000

    将IP包头分段:

            1.  0x4500

            2.  0x0029

            3.  0x44F1

            4.  0x4000

            5.  0x8006

            6.  0x0000 ------->这个为Header Checksum的值,我们前面将其重置为0了

            7.  0xC0A8

            8.  0x01AE

            9.  0x4A7D

    +       10.  0x477D

    -------------------------------------------------------

    将1至10相加求出来的和为:0x29E70

    II.对各个单元采用反码加法运算(即高位溢出位会加到低位,通常的补码运算是直接丢掉溢出的高位),将得到的和的反码填入校验和字段

    0x0002+0x9E70=0x9E72

    0x9E72二进制为:1001 1110 0111 0010

    反码为:0110 0001 1000 1101

    0110 0001 1000 1101的16进制为:0x618D

    看看这个 是否与IP包头中的Checksum相同

    ==========================================================

    当接收到IP对其进行检测

    III.对各个单元采用反码加法运算,检查得到的和是否符合是全1(有的实现可能对得到的和会取反码,然后判断最终值是不是全0)

    当收到IP数据局包的时候,要验证IP头是否正确,则可以这样进行

            1.  0x4500

            2.  0x0029

            3.  0x44F1

            4.  0x4000

            5.  0x8006

            6.  0x618D ------->这个为Header Checksum的值

            7.  0xC0A8

            8.  0x01AE

            9.  0x4A7D

    +       10.  0x477D

    -------------------------------------------------------

    将1至10相加求出来的和为:0x2FFD

    对各个单元采用反码加法运算(即高位溢出位会加到低位,通常的补码运算是直接丢掉溢出的高位),将得到的和的反码填入校验和字段:

    0x0002+0x0FFD=0xFFFF

    0xFFFF二进制为:1111 1111 1111 1111

    1111 1111 1111 1111反码为:0

    ====================================================

    关于这一部的补充说明,

    将IP包头分段:
     
            1.  0x4500
     
            2.  0x0029
     
            3.  0x44F1
     
            4.  0x4000
     
            5.  0x8006
     
            6.  0x0000 ------->这个为Header Checksum的值,我们前面将其重置为0了
     
            7.  0xC0A8
     
            8.  0x01AE
     
            9.  0x4A7D
     
    +       10.  0x477D
    ----------------------------------------------------------------------------------------------------------

  • 相关阅读:
    fail to start File System Check
    qemu:///system 没有连接驱动器可用;读取数据时进入文件终点: 输入/输出错误
    [转载]libvirt(virsh命令总结)
    【转载】CentOS 7自动以root身份登录gnome桌面 操作系统开机后自动登录到桌面 跳过GDM
    Linux查看PCIe版本及速率# lspci -vvv |grep Width -i
    JAVA的线程能够在多个CPU上执行么?
    给定字典做分词
    POJ 3130 & ZOJ 2820 How I Mathematician Wonder What You Are!(半平面相交 多边形是否有核)
    高仿一元云购IOS应用源代码项目
    增加收藏兼容主流浏览器代码
  • 原文地址:https://www.cnblogs.com/furenjian/p/5022103.html
Copyright © 2011-2022 走看看