smallbarrow
驱动小牛
驱动小牛
  • 注册日期2002-06-05
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分3分
  • 威望20点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:2309回复:10

为什么ip包的包头20个字节相加的结果不是0xffff?

楼主#
更多 发布于:2002-07-10 14:20
passthru mpsend函数中,如果packet有ip包,将包头每2个字节相加,结果应当是0xffff。但我测试的结果是:对tcp来说和为0xfffd,udp为0xb6d5?
很困惑,哪位大虾能指点迷津?
嗒嗒的,是那马蹄 是我的心声 别了 一瞬间的花朵
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2002-07-10 15:32
passthru mpsend函数中,如果packet有ip包,将包头每2个字节相加,结果应当是0xffff。但我测试的结果是:对tcp来说和为0xfffd,udp为0xb6d5?
很困惑,哪位大虾能指点迷津?


ip chksum计算的时候需要把一些会被router修改的字段
设置为0。chksum的计算你在任何一本书里面都找得到,
很多地方也有source------不过大多数是汇编写的:-)。
不再回忆从前,我已经生活在幸福当中。
smallbarrow
驱动小牛
驱动小牛
  • 注册日期2002-06-05
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分3分
  • 威望20点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2002-07-10 16:18
老胡,俺搞不懂唉。

ip checksum的计算规则不是:先清零校验和字段,然后对ip header数据每16位求和,然后结果取反 吗?
如果按这个规则来说的话,ip header每16位的和(包含校验和)应当为0xffff才对呀。

按照你上一个帖子的说法,ip checksum 可能不是ip层做的,如果不在ip层做,ip checksum域可能为一个随机数或一个常数,(由于ip头不同)按照验证算法得到的值应该是不一样的。但是对所有tcp包我得到的验证值总是0xfffd。

请老胡指点。
嗒嗒的,是那马蹄 是我的心声 别了 一瞬间的花朵
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
地板#
发布于:2002-07-10 16:34
老胡,俺搞不懂唉。

ip checksum的计算规则不是:先清零校验和字段,然后对ip header数据每16位求和,然后结果取反 吗?
如果按这个规则来说的话,ip header每16位的和(包含校验和)应当为0xffff才对呀。

按照你上一个帖子的说法,ip checksum 可能不是ip层做的,如果不在ip层做,ip checksum域可能为一个随机数或一个常数,(由于ip头不同)按照验证算法得到的值应该是不一样的。但是对所有tcp包我得到的验证值总是0xfffd。

请老胡指点。


你这个0xfffd是怎么得到的?

在imd里?(这有可能是一样的,因为imd得到的是一个没有计算
过ipchksum的数据包)

还是你用sniffer抓了个包看了看?(这不可能总是一样,除非
你的tcp包长度都一样,目的地址也一样)

不再回忆从前,我已经生活在幸福当中。
smallbarrow
驱动小牛
驱动小牛
  • 注册日期2002-06-05
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分3分
  • 威望20点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
地下室#
发布于:2002-07-10 16:58
 
你这个0xfffd是怎么得到的?

在imd里?(这有可能是一样的,因为imd得到的是一个没有计算
过ipchksum的数据包)

还是你用sniffer抓了个包看了看?(这不可能总是一样,除非
你的tcp包长度都一样,目的地址也一样)
 


老胡,我的0xfffd是ip header中每16位数据的和(包含校验和),不是校验和――checksum。
如果按照ip header的验证算法――ip header中每16位数据的和(包含校验和),它应当是0xffff才对。

我在imd中得到的这个值。

即使ip层随便填一个值或什么都不填,ip header的其他部分是不尽相同的,那么它们由验证算法得到的值也应该是不同的。
嗒嗒的,是那马蹄 是我的心声 别了 一瞬间的花朵
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
5楼#
发布于:2002-07-10 17:15
[quote]你这个0xfffd是怎么得到的?

在imd里?(这有可能是一样的,因为imd得到的是一个没有计算
过ipchksum的数据包)

还是你用sniffer抓了个包看了看?(这不可能总是一样,除非
你的tcp包长度都一样,目的地址也一样)
 


老胡,我的0xfffd是ip header中每16位数据的和(包含校验和),不是校验和――checksum。
如果按照ip header的验证算法――ip header中每16位数据的和(包含校验和),它应当是0xffff才对。

我在imd中得到的这个值。

即使ip层随便填一个值或什么都不填,ip header的其他部分是不尽相同的,那么它们由验证算法得到的值也应该是不同的。 [/quote]


既然你在imd中得到的这个值...
我理解为你在imd中作了一个循环,自己把ipheader加了一遍。

可能性如下:
1、你算错了。
2、这个值是正常的,因为ip层交下来的数据中并不包括ipchksum,
所以出现任何值都是有可能的。请注意,ip层的动作很奇怪,并
不是一个包不算就所有的包都不算,这个似乎取决于某个隐藏在
某处的一个状态,我找了很久也没有找到,只是发现当ip发现
网卡有taskoffload功能的时候,ip自己算还是不算,完全取决
于ip自己,ip如果算了的话,会在oob上告诉网卡,如果不算,
也会在oob中告诉网卡。在这里做出任何假设都会导致错误。
(除非真正搞清楚了ip背后的策略,但是似乎是undocument的)

我的建议:你用sniffer抓一个数据包,注意这个sniffer最好在
目标主机上,或者在另外一个主机上,不要在发送主机上。
看看抓到的包的ip头和你imd中的ip头的区别。



不再回忆从前,我已经生活在幸福当中。
smallbarrow
驱动小牛
驱动小牛
  • 注册日期2002-06-05
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分3分
  • 威望20点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
6楼#
发布于:2002-07-10 17:21
谢谢老胡!!!!!
嗒嗒的,是那马蹄 是我的心声 别了 一瞬间的花朵
fenger_li
驱动老牛
驱动老牛
  • 注册日期2002-03-26
  • 最后登录2005-04-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-07-10 18:16
刚拜读两位的讨论。

很有收获,在此我问个可能很低级的问题,望两位赐教。

对于ipchksum的算法,有的书上是这样讲的:对ip首部每个16bit进行二进制反码求和。也有的书上是这样讲的:对ip首部每个16bit进行求和的反码。最可气的是清华的tcp/ip那本书上是:异或的反吗(肯定不对)。
另外看见的算法是:SHORT iphdr_cksum(USHORT *iph)
{
    USHORT i;
    ULONG sum;

    i = 0;
    sum = 0;

    while(i++ < (sizeof(IP_HEADER)/2))
        sum += *iph++;

    sum = (sum >> 16) + (sum & 0xffff);
    sum += (sum >> 16);
    sum = ~sum;

    return (USHORT)sum;
}
感觉这可能是标准算法。

不过,这样检查校验的算法就不是:每16bit的和就不是0xffff了。
高不太明白。

还是留给明白的人解释吧。

嗬嗬!

有点意思。。。 呵呵!
fenger_li
驱动老牛
驱动老牛
  • 注册日期2002-03-26
  • 最后登录2005-04-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-07-11 18:08
果真是这个算法。

 另还有已优化的算法,写得不错。

 看样,有病不能乱投医呀!


呵呵!
有点意思。。。 呵呵!
guardee
驱动巨牛
驱动巨牛
  • 注册日期2002-11-08
  • 最后登录2010-05-29
  • 粉丝2
  • 关注1
  • 积分2分
  • 威望34点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-07-11 22:47
呵呵!你的程序的算法得到的结果是对的!和什么详解上面的说法不一样!
gjpland
驱动小牛
驱动小牛
  • 注册日期2001-09-13
  • 最后登录2011-03-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-07-12 22:43
[quote] [quote]你这个0xfffd是怎么得到的?

在imd里?(这有可能是一样的,因为imd得到的是一个没有计算
过ipchksum的数据包)

还是你用sniffer抓了个包看了看?(这不可能总是一样,除非
你的tcp包长度都一样,目的地址也一样)
 


老胡,我的0xfffd是ip header中每16位数据的和(包含校验和),不是校验和――checksum。
如果按照ip header的验证算法――ip header中每16位数据的和(包含校验和),它应当是0xffff才对。

我在imd中得到的这个值。

即使ip层随便填一个值或什么都不填,ip header的其他部分是不尽相同的,那么它们由验证算法得到的值也应该是不同的。 [/quote]


既然你在imd中得到的这个值...
我理解为你在imd中作了一个循环,自己把ipheader加了一遍。

可能性如下:
1、你算错了。
2、这个值是正常的,因为ip层交下来的数据中并不包括ipchksum,
所以出现任何值都是有可能的。请注意,ip层的动作很奇怪,并
不是一个包不算就所有的包都不算,这个似乎取决于某个隐藏在
某处的一个状态,我找了很久也没有找到,只是发现当ip发现
网卡有taskoffload功能的时候,ip自己算还是不算,完全取决
于ip自己,ip如果算了的话,会在oob上告诉网卡,如果不算,
也会在oob中告诉网卡。在这里做出任何假设都会导致错误。
(除非真正搞清楚了ip背后的策略,但是似乎是undocument的)

我的建议:你用sniffer抓一个数据包,注意这个sniffer最好在
目标主机上,或者在另外一个主机上,不要在发送主机上。
看看抓到的包的ip头和你imd中的ip头的区别。



 [/quote]
是由网卡来计算CHECKSUM还是由PROTOCOL来计算CHECKSUM可以通过
对NIC的发送OID查询来获得
OID_TCP_TASK_OFFLOAD
task = NDIS_TASK_TCP_IP_CHECKSUM
我思故我在,脑袋不会坏.
游客

返回顶部