zoukankan      html  css  js  c++  java
  • ip首部校验和计算

     IP首部校验和的计算方法:
      1.把校验和字段清零。
      2.然后对每16位(2字节)进行二进制反码求和,反码求和的意思是先对每16位求和,再将得到的和转为反码
      接下来详细描述反码求和的步骤:看下面的代码
      算法:

    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); 
        cksum += (cksum>>16); 
        return (USHORT)(~cksum);
    }

      参数buffer是指向16位整数的指针,刚开始指向的是IP首部的起始地址,参数size是IP首部的大小。while循环是将IP首部的内容以16位为单元加在一起,如果没有整除(即size还有余下的不足16位的部分),则加上余下的部分,此时的cksum就是相加后的结果,这个结果往往超出了16位,因为校验和是16位的,所以要将高16位和计算得到的cksum再加工。
      再加工第一步:cksum = (cksum>>16) + (cksum&0xffff); sum>>16是将高16位移位到低16位,sum&0xffff是取出低16位,相加得到新的cksum。
      再加工第二步:cksum += (cksum>>16); 第一步相加时很可能会产生进位,因此要再次把进位移到低16位进行相加。  
      这样就加工好了,接下来就是取反,并强制转换为16位,这样就得到了最终的校验和。
      校验和计算出来了,接下来就是该如何校验:
      接收方进行校验时,也是对每16位进行二进制反码求和。接收方计算校验和时的首部与发送方计算校验和时的首部相比,多了一个发送方计算出来的校验和。因此,如果首部在传输过程中没有发生差错,那么接收方计算的结果应该为全一,因为接收方计算除校验和以外的部分得到值是校验和的反码,再加多出来的校验和当然是全一了。
      最后对上述过程举个例子:
      IP头:
      45 00    00 31
      89 F5    00 00
      6E 06    00 00(校验字段)
      DE B7   45 5D       ->    222.183.69.93
      C0 A8   00 DC     ->    192.168.0.220
      计算:  
      4500 + 0031 +89F5 + 0000 + 6e06+ 0000 + DEB7 + 455D + C0A8 + 00DC =3 22C4
      0003 + 22C4 = 22C7
      ~22C7 = DD38      ->即为应填充的校验和
      当接受到IP数据包时,要检查IP头是否正确,则对IP头进行检验,方法同上:
      计算:
      4500 + 0031 +89F5 + 0000 + 6E06+ DD38 + DEB7 + 455D + C0A8 + 00DC =3 FFFC
      0003 + FFFC = FFFF
      得到的结果是全一,正确。
  • 相关阅读:
    CF763C Timofey and Remoduling
    CF762E Radio Stations
    CF762D Maximum Path
    CF763B Timofey and Rectangles
    URAL1696 Salary for Robots
    uva10884 Persephone
    LA4273 Post Offices
    SCU3037 Painting the Balls
    poj3375 Network Connection
    Golang zip压缩文件读写操作
  • 原文地址:https://www.cnblogs.com/hushaojun/p/6491392.html
Copyright © 2011-2022 走看看