校验和计算函数(很精彩)

2009-05-13 09:01:05来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

int
in_cksum(m, len)
register struct mbuf *m;
register int len;
{
register u_short *w;
register int sum = 0;
register int mlen = 0;
int byte_swapped = 0;
union {
  char c[2];
  u_short s;
} s_util;
union {
  u_short s[2];
  long l;
} l_util;
for (;m && len; m = m->m_next) {
  if (m->m_len == 0)
   continue;
  w = mtod(m, u_short *);
  if (mlen == -1) {
   /*
    * The first byte of this mbuf is the continuation
    * of a word spanning between this mbuf and the
    * last mbuf.
    *
    * s_util.c[0] is already saved when scanning previous
    * mbuf.
    */
   s_util.c[1] = *(char *)w;
   sum += s_util.s;
   w = (u_short *)((char *)w + 1);
   mlen = m->m_len - 1;
   len--;
  } else
   mlen = m->m_len;
  if (len  0)) {
   REDUCE;
   sum = 0) {
   sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
   sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
   sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
   sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
   w += 16;
  }
  mlen += 32;
  while ((mlen -= 8) >= 0) {
   sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
   w += 4;
  }
  mlen += 8;
  if (mlen == 0 && byte_swapped == 0)
   continue;
  REDUCE;
  while ((mlen -= 2) >= 0) {
   sum += *w++;
  }
  if (byte_swapped) {
   REDUCE;
   sum

//摘自BSD4.4-lite,这个函数在ip层接收包的处理流程中消耗了大量的时间,因此可以看到这个函数是非常注重效率的提高的,补码的运算可以简单地看作是两个无符号整型加后再加上其进位的部分,至于为什么采用这样的一种校验方式,应该是它的检错能力与运算效率两方面的权衡后的结果。具体为什么还需要进一步的查看相关的资料
//还要注意unsigned short加法,以及计算是从mbuf的低地址不部分开始的
//这里被计算的是网卡或传输层直接放到ip packet中的数据,忽略了内容,把所有要计算的东西都看看成了一个unsigned short的数组
//还有一点,就是字节序的问题,在BSD4.4-lite中每一种特定的硬件结构都使用了专门的in_cksum()
这一方面是为了能在具体的机器上充分地提供函数的计算效率,另一方面我向也考虑到了字节序的问题。上面的这个函数是在大端机器上运行的
//sum

//对于网络中传输的数据包的内容在接受的时候统一的假设是使用大端字节序(网络字节序)来进行操作,如果使用的接收(发送)端的机器使用的是另外的一种字节序的话,那么就需要在输入(输出)中进行调整。

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:OpenBSD 树

下一篇:vmstat