zoukankan      html  css  js  c++  java
  • IP首部之首部校验和

    首先介绍一下1的补码,2的补码:(摘自http://blog.csdn.net/cradmin/article/details/3092559

    过1的补码,2的补码,到网上搜了下找到这个:

    It is the 1’s complement of the 1’s complement sum of all the 16-bit words in the TCP header and data       这是关于TCP头部校验和字段(checksum field)的说明。
    补码:补码是计算机中二进制数表达负数的办法,这样可以在计算机中把两个数的减法变成加法。补码形式有1的补码和2的补码,其中1的补码用在IP、TCP的校验和中;
    The checksum algorithm is simply to add up all the 16-bit words in one's complement and then to take the one's complement of the sum.
    1's Complement Arithmetic
    The Formula
    ~N = (2^n -1) - N
    where: n is the number of bits per word
    N is a positive integer
    ~N is -N in 1's complement notation
    For example with an 8-bit word and N = 6, we have:
    ~N = (2^8 -1) - 6 = 255 - 6 = 249 = 11111001

    In Binary
    An alternate way to find the 1's complement is to simply
    take the bit by bit complement of the binary number.
    For example: N = +6 = 00000110
    N = -6 = 11111001
    Conversely, given the 1's complement we can find the
    magnitude of the number by taking it's 1's complement.
    The largest number that can be represented in 8-bit 1's
    complement is 01111111 = 127 = 0x7F. The smallest is
    10000000 = -127. Note that the values 00000000 and
    11111111 both represent zero.
    Addition
    End-around Carry. When the addition of two values
    results in a carry, the carry bit is added to the sum in the
    rightmost position. There is no overflow as long as the
    magnitude of the result is not greater than 2^n-1.
    2's Complement Arithmetic
    The Formula
    N* = 2^n - N
    where: n is the number of bits per word
    N is a positive integer
    N* is -N in 2's complement notation
    For example with an 8-bit word and N = 6, we have:
    N* = 2^8 - 6 = 256 - 6 = 250 = 11111010

    In Binary
    An alternate way to find the 2's complement is to start at
    the right and complement each bit to the left of the first
    "1".
    For example: N = +6 = 00000110
    N* = -6 = 11111010
    Conversely, given the 2's complement we can find the
    magnitude of the number by taking it's 2's complement.
    The largest number that can be represented in 8-bit 2s
    complement is 01111111 = 127. The smallest is
    10000000 = -128.
    Addition
    When the addition of two values results in a carry, the
    carry bit is ignored. There is no overflow as long as the
    is not greater than 2^n-1 nor less than -2^n.

    我们之前学的是2的补码:正数补码是自己,负数补码=反码+1

    而1的补码:正数补码是自己,负数的补码=各位取反(也就是反码)

    IP/TCP首部校验规则:(摘自:http://www.cnblogs.com/fhefh/archive/2011/10/18/2216885.html,这篇讲解非常棒,有例子)

    P/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 unsigned short checksum(unsigned short *buf, int nword)
     2 {
     3     // short是16位(俩字节),即把报表首部按16bit分开  
     4    // 先求和 
     5     unsigned long sum = 0;
     6     for(int i=0; i<nword; i++)
     7     {
     8         sum += *buf++;
     9     }
    10     //高位溢出加到低位
    11     sum = (sum >> 16) + (sum & 0xffff);
    12     //防止上次操作引起的新溢出
    13     sum += (sum >> 16);
    14     //long(32 bit) 截取低位部分转换为short(16位)
    15     return (unsigned short)~sum;
    16 }
  • 相关阅读:
    数组的一些经典案例(循环)(max=score[0])(冒泡)(flag标志)(杨辉三角)
    冒泡排序
    C语言之数组
    循环结构的一些案例:倒等腰三角形、菱形、暴力破解
    break和contine关键字
    循环嵌套(打印*** ***)
    循环的经典案例(李白买酒)
    C语言循环结构-while/do...while/for--逢3过,阶乘,九九乘法表
    WordPress部署踩坑记
    Symbol
  • 原文地址:https://www.cnblogs.com/fkissx/p/4626811.html
Copyright © 2011-2022 走看看