打印

uip0.9TCP校验和 计算代码不符合 TCP协议吗?

[复制链接]
3058|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 kaly_liu 于 2013-6-6 16:39 编辑

uip0.9中我找到uip_buf[]的定义是这样的 :u8_t Uip_buf[ ]  (是8位的)
在进行TCP校验和计算的时候是:TCP首部以及数据都划分成16位的一个个16进制数再进行的,一开始我以为是这样的(https://bbs.21ic.com/icview-561044-1-1.html),后来看看感觉还是不对。
当进行TCP校验和计算的时候是如下代码所示的,代码中现将 uip_buf 类型转换为 u16_t;这样子 uip_buf的高8位不是就是0了?那么uip_buf中的数据如果原来是:01 02 03 01 04 05 那么现在的存储格式应该变为了:0001 0002 0003 0001 0004 0005了,如果按照下面的校验和计算不是只计算了0、2、4、三个数据而把1、3、5、数据给漏掉了?
本来按照校验和的计算应该是将数据组合成 : 0102 0301 0405 这样子进行的,按照这个程序有点乱了····我不懂了现在啊·············
/***************************************************************/
/* Compute the checksum of the TCP header. */
  hsum = uip_chksum((u16_t *)&uip_buf[20 + UIP_LLH_LEN], 20);
/***************************************************************/
/***************************************************************/
u16_t uip_chksum(u16_t *sdata, u16_t len)
{
  u16_t acc;
  
  for(acc = 0; len > 1; len -= 2) {
    acc += *sdata;
    if(acc < *sdata) {
      /* Overflow, so we add the carry to acc (i.e., increase by
         one). */
      ++acc;
    }
    ++sdata;
  }

  /* add up any odd byte */
  if(len == 1) {
    acc += htons(((u16_t)(*(u8_t *)sdata)) << 8);
    if(acc < htons(((u16_t)(*(u8_t *)sdata)) << 8)) {
      ++acc;
    }
  }

  return acc;
}
/*-----------------------------------------------------------------------------------*/
/***************************************************************/

相关帖子

沙发
758044068| | 2013-6-6 10:31 | 只看该作者
打酱油啊:sleepy:

使用特权

评论回复
板凳
开发者_test| | 2013-6-6 10:34 | 只看该作者
我也是。。。。

使用特权

评论回复
地板
kaly_liu|  楼主 | 2013-6-6 10:36 | 只看该作者
我不是卖酱油的~~

使用特权

评论回复
5
kaly_liu|  楼主 | 2013-6-6 15:45 | 只看该作者
我直接将上面的程序代码 弄到keil里面进行测试,发现那个程序代码运行完毕后,加入的数据只有前面的一半的数据,就是说,运行后的数据 acc 结果其实是 uip_buf[0]+uip_buf[1]+...+uip_buf[len/2](假设正好是偶数个的话)
如下是我的测试程序和结果:

#include <REG_MPC82G516.H>
#define u8_t unsigned char;
#define u16_t unsigned int;

u8_t uip_buf[]={0x01,0x02,0x01,0X02,0x01,0X02,0x01,0X02,0x01,0X02,0x01,0X02,0x01,0X02,0x01,0X02,0x01,0X02,0x01,0X02,0x01,0X02,0x01,0X02,0x01,0X02};

u16_t uip_chksum(unsigned int *sdata, unsigned int len)
{
  unsigned int acc;
  
  for(acc = 0; len > 1; len -= 2) {
    acc += *sdata;
    if(acc < *sdata) {
      /* Overflow, so we add the carry to acc (i.e., increase by
         one). */
      ++acc;
    }
    ++sdata;
  }

  return acc;
}

void main()
{
/***************************************************************/
/* Compute the checksum of the TCP header. */
  unsigned int hsum;
  hsum = uip_chksum((unsigned int *)&uip_buf[0], 20);
/***************************************************************/
}
我调试后结果发现:acc 的最后结果是:0X000F ;其结果就是数组的前面len/2个数的和而已;并没有像想象中的 进行两两组合后再加的···

使用特权

评论回复
6
kaly_liu|  楼主 | 2013-6-6 16:56 | 只看该作者
不好意思,我自己弄错了,不知道为什么那个 数组定义成 u8_t不行啊,我定义成unsigned char uip_buf。。。就可以了·····
但是这样一来我觉得,C里面是不是有时候容易出错了,比如我们定义一个char数组,当我们要用到某一个的时候,把它转成int类型,那高位不就会变成这一位的前面一位了? 就是我将char buf[3]转为 int后,那 int buf[3]实际上就是 char buf[2] char buf[3]了,如果我将int buf[3] = 0;那后面我再使用到 char buf[2]的时候,那char buf[2]不就变为0了额······

使用特权

评论回复
7
758044068| | 2013-6-6 17:23 | 只看该作者

使用特权

评论回复
评分
参与人数 1威望 +3 收起 理由
kaly_liu + 3 很给力!
8
jerkoh| | 2013-6-8 21:30 | 只看该作者
本帖最后由 jerkoh 于 2013-6-8 21:41 编辑

对于uip, Little Endian 和 Big Endian  针对CPU 也要注意

使用特权

评论回复
9
kaly_liu|  楼主 | 2013-6-9 08:48 | 只看该作者
jerkoh 发表于 2013-6-8 21:30
对于uip, Little Endian 和 Big Endian  针对CPU 也要注意

恩,好的!多谢啦!

使用特权

评论回复
10
原野之狼| | 2013-6-9 10:52 | 只看该作者
这么多天了  楼主还没有把问题解决么?


首先要知道是如何计算checksum的。看权威文档吧:http://tools.ietf.org/html/rfc793   
摘录一下关键段落:
Checksum:  16 bits
    The checksum field is the 16 bit one's complement of the one's
    complement sum
of all 16 bit words in the header and text.  If a
    segment contains an odd number of header and text octets to be
    checksummed, the last octet is padded on the right with zeros to
    form a 16 bit word for checksum purposes.  The pad is not
    transmitted as part of the segment.  While computing the checksum,
    the checksum field itself is replaced with zeros.

    The checksum also covers a 96 bit pseudo header conceptually

标红处我也没看懂,不过没关系,继续找资料:http://mathforum.org/library/drmath/view/54379.html
摘录关键段落:
What that means is:

1. Add the 16-bit values up. Each time a carry-out (17th bit) is
produced, swing that bit around and add it back into the LSb (one's
digit). This is somewhat erroneously referred to as "one's complement
addition."

2. Once all the values are added in this manner, invert all the bits
in the result. A binary value that has all the bits of another binary
value inverted is called its "one's complement," or simply its
"complement."

这下该明白了吧?


另外一个重要问题,就是要搞明白主机字节序与网络字节序的问题,这个留给你自己去研究吧。


剩下的就是c语言的问题了,我没啥好说的,你自己慢慢玩吧~

使用特权

评论回复
评分
参与人数 1威望 +3 收起 理由
kaly_liu + 3 很给力!
11
kaly_liu|  楼主 | 2013-6-9 16:13 | 只看该作者
问题已经解决了。多谢提供的经典资料啊,看了更加明白了。呵呵

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

23

主题

344

帖子

3

粉丝