LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 3115|回复: 3

求助:IP数据报首部中16位首部检验和的计算问题?

[复制链接]
发表于 2004-12-26 14:24:41 | 显示全部楼层 |阅读模式
菜鸟提问各位大侠:
   读TCP/IP详解第一卷 第三章 IP:网际协议中一段关于IP首部的问题,原书描述如下:
   ......
    为了计算一份数据报的IP检验和,首先把检验和字段置为0。然后,对首部中每个16bit进行二进制反码求和(整个首部看成是由一串16bit的字组成),结果存在检验和字段中。当收到一份IP数据报后,同样对首部中每个16bit进行二进制反码的求和。由于接受方在计算过程中包含了发送方存在首部中的校验和。因此,如果首部在传输过程中没有发生任何差错,那么接受方计算的结果应该为全1。如果结果不是全1(即检验和错误),那么IP就丢弃收到的数据报。
  。。。。
  请问:1。对于每个16bit进行二进制反码求和(整个首部看成是由一串16bit的字组成),是怎么样取反求和的?
2。既然校验和属于IP首部,那么言下之意他应该也被看作是某一串16bit的字吧,那么接受方是不是也把校验和字段也取反求和了呢?
3。结果全是1,我怎么老算不出来啊?难于理解这段话!

请高手指点迷津啊!最好,能用例子计算一下,让我彻底醒悟啊!在此叩谢!
发表于 2004-12-26 18:44:37 | 显示全部楼层
1.没有学过二进制吧。最好去看书,建立基本概念。不然我下面的回答你也看不懂。
2.接受方的计算包括校验和字段。
3.你可以算算一个二进制数加上自己的反码,结果会是多少?
发表于 2004-12-27 09:55:22 | 显示全部楼层
IP checksum的定义在RFC1071中,可以参考原文来理解
源代码:
来自http://www.netfor2.com/ipsum.htm



  1. The IP Header Checksum is computed on the header fields only.
  2. Before starting the calculation, the checksum fields (octets 11 and 12)
  3. are made equal to zero.

  4. In the example code,
  5. u16 buff[] is an array containing all octets in the header with octets 11 and 12 equal to zero.
  6. u16 len_ip_header is the length (number of octets) of the header.


  7. /*
  8. **************************************************************************
  9. Function: ip_sum_calc
  10. Description: Calculate the 16 bit IP sum.
  11. ***************************************************************************
  12. */
  13. typedef unsigned short u16;
  14. typedef unsigned long u32;

  15. u16 ip_sum_calc(u16 len_ip_header, u16 buff[])
  16. {
  17.         u16 word16;
  18.         u32 sum=0;
  19.         u16 i;
  20.    
  21.         // make 16 bit words out of every two adjacent 8 bit words in the packet
  22.         // and add them up
  23.         for (i=0;i<len_ip_header;i=i+2){
  24.                 word16 =((buff[i]<<8)&0xFF00)+(buff[i+1]&0xFF);
  25.                 sum = sum + (u32) word16;
  26.         }

  27.         // take only 16 bits out of the 32 bit sum and add up the carries
  28.         while (sum>>16)
  29.                 sum = (sum & 0xFFFF)+(sum >> 16);

  30.         // one's complement the result
  31.         sum = ~sum;

  32.         return ((u16) sum);
  33. }
复制代码
 楼主| 发表于 2004-12-27 13:16:36 | 显示全部楼层
多谢回答菜鸟的问题!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表