【问题标题】:Question regarding ip checksum code关于ip校验码的问题
【发布时间】:2011-02-04 13:13:58
【问题描述】:
unsigned short  /* this function generates header checksums */
csum (unsigned short *buf, int nwords)
{
  unsigned long sum;
  for (sum = 0; nwords > 0; nwords--) // add words(16bits) together
  {
      sum += *buf++;
  }
  sum = (sum >> 16) + (sum & 0xffff);  //add carry over
  sum += (sum >> 16);                  //MY question: what exactly does this step do??? add possible left-over   
                                       //byte? But hasn't it already been added in the loop (if 
                                       //any)?
  return ((unsigned short) ~sum);
}
  1. 我假设 nwords 在 16bits 字的数量,而不是 8bits 字节(如果有奇数字节,nword 舍入到下一个大),是否正确?假设 ip_hdr 总共有 27 个字节,那么 nword 将是 14 而不是 13,对吗?
  2. 这一行 sum = (sum >> 16) + (sum & 0xffff) 是加进位做 16bit 补码
  3. sum += (sum >> 16);这一步的目的是什么?添加剩余字节?但是循环中已经添加了剩余字节?

谢谢!

【问题讨论】:

  • 你能把你的代码格式化一下吗?
  • 有人需要清理它。 :(
  • ip_hdr 不能是 27 个字节,它们的长度必须是 4 个字节的倍数,并且长度必须在 20 到 60 个字节之间 - (4 * ip_hdr->ip_ihl) 因为ip_ihl 是一个四字节-位字段。

标签: header checksum ip-protocol


【解决方案1】:

你是对的。步骤 3 将 32 位长的 sum 压缩为 16 位无符号短型,即校验和的长度。这是出于性能目的,允许计算校验和而不跟踪溢出直到结束。它在第 2 步和第 3 步都这样做,因为它可能已经从第 2 步溢出。然后它只返回求和的反转低 16 位。

这更清楚一点: http://www.sysnet.ucsd.edu/~cfleizac/iptcphdr.html

【讨论】:

  • 这里假设long的长度为32位,short的长度为16位。但是有些平台两者都不是真的。
  • 是的,但这不是独立于平台的代码;它在内核中,你知道大小是多少,所以这是一个合理的假设。
  • 你可以看到 BSD 源码使用了类似的“non-portable”声明:fxr.watson.org/fxr/source/netinet/in_cksum.c
猜你喜欢
  • 1970-01-01
  • 2014-06-22
  • 2013-04-29
  • 2017-04-24
  • 2017-08-20
  • 1970-01-01
  • 2015-12-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多