IN_CKSUM.C
上传用户:tjbfgc
上传日期:2013-03-31
资源大小:140k
文件大小:4k
源码类别:

网络编程

开发平台:

C/C++

  1. /*
  2.  * Copyright (c) 1988, 1992, 1993
  3.  * The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  * This product includes software developed by the University of
  16.  * California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  *
  33.  * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93
  34.  */
  35. #include <sys/param.h>
  36. #include <sys/mbuf.h>
  37. /*
  38.  * Checksum routine for Internet Protocol family headers (Portable Version).
  39.  *
  40.  * This routine is very heavily used in the network
  41.  * code and should be modified for each CPU to be as fast as possible.
  42.  */
  43. #define ADDCARRY(x)  (x > 65535 ? x -= 65535 : x)
  44. #define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
  45. int
  46. in_cksum(m, len)
  47. register struct mbuf *m;
  48. register int len;
  49. {
  50. register u_short *w;
  51. register int sum = 0;
  52. register int mlen = 0;
  53. int byte_swapped = 0;
  54. union {
  55. char c[2];
  56. u_short s;
  57. } s_util;
  58. union {
  59. u_short s[2];
  60. long l;
  61. } l_util;
  62. for (;m && len; m = m->m_next) {
  63. if (m->m_len == 0)
  64. continue;
  65. w = mtod(m, u_short *);
  66. if (mlen == -1) {
  67. /*
  68.  * The first byte of this mbuf is the continuation
  69.  * of a word spanning between this mbuf and the
  70.  * last mbuf.
  71.  *
  72.  * s_util.c[0] is already saved when scanning previous 
  73.  * mbuf.
  74.  */
  75. s_util.c[1] = *(char *)w;
  76. sum += s_util.s;
  77. w = (u_short *)((char *)w + 1);
  78. mlen = m->m_len - 1;
  79. len--;
  80. } else
  81. mlen = m->m_len;
  82. if (len < mlen)
  83. mlen = len;
  84. len -= mlen;
  85. /*
  86.  * Force to even boundary.
  87.  */
  88. if ((1 & (int) w) && (mlen > 0)) {
  89. REDUCE;
  90. sum <<= 8;
  91. s_util.c[0] = *(u_char *)w;
  92. w = (u_short *)((char *)w + 1);
  93. mlen--;
  94. byte_swapped = 1;
  95. }
  96. /*
  97.  * Unroll the loop to make overhead from
  98.  * branches &c small.
  99.  */
  100. while ((mlen -= 32) >= 0) {
  101. sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
  102. sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
  103. sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
  104. sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
  105. w += 16;
  106. }
  107. mlen += 32;
  108. while ((mlen -= 8) >= 0) {
  109. sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
  110. w += 4;
  111. }
  112. mlen += 8;
  113. if (mlen == 0 && byte_swapped == 0)
  114. continue;
  115. REDUCE;
  116. while ((mlen -= 2) >= 0) {
  117. sum += *w++;
  118. }
  119. if (byte_swapped) {
  120. REDUCE;
  121. sum <<= 8;
  122. byte_swapped = 0;
  123. if (mlen == -1) {
  124. s_util.c[1] = *(char *)w;
  125. sum += s_util.s;
  126. mlen = 0;
  127. } else
  128. mlen = -1;
  129. } else if (mlen == -1)
  130. s_util.c[0] = *(char *)w;
  131. }
  132. if (len)
  133. printf("cksum: out of datan");
  134. if (mlen == -1) {
  135. /* The last mbuf has odd # of bytes. Follow the
  136.    standard (the odd byte may be shifted left by 8 bits
  137.    or not as determined by endian-ness of the machine) */
  138. s_util.c[1] = 0;
  139. sum += s_util.s;
  140. }
  141. REDUCE;
  142. return (~sum & 0xffff);
  143. }