home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / netinet / in_cksum.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-08  |  4.3 KB  |  149 lines

  1. /*
  2.  * Copyright (c) 1988 Regents of the University of California.
  3.  * 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    7.3 (Berkeley) 6/28/90
  34.  */
  35.  
  36. #include "../h/types.h"
  37. #include "../h/mbuf.h"
  38.  
  39. /*
  40.  * Checksum routine for Internet Protocol family headers (Portable Version).
  41.  *
  42.  * This routine is very heavily used in the network
  43.  * code and should be modified for each CPU to be as fast as possible.
  44.  */
  45.  
  46. #define ADDCARRY(x)  (x > 65535 ? x -= 65535 : x)
  47. #define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
  48.  
  49. in_cksum_c(m, len)
  50.     register struct mbuf *m;
  51.     register int len;
  52. {
  53.     register u_short *w;
  54.     register int sum = 0;
  55.     register int mlen = 0;
  56.     int byte_swapped = 0;
  57.  
  58.     union {
  59.         char    c[2];
  60.         u_short    s;
  61.     } s_util;
  62.     union {
  63.         u_short s[2];
  64.         long    l;
  65.     } l_util;
  66.  
  67.     for (;m && len; m = m->m_next) {
  68.         if (m->m_len == 0)
  69.             continue;
  70.         w = mtod(m, u_short *);
  71.         if (mlen == -1) {
  72.             /*
  73.              * The first byte of this mbuf is the continuation
  74.              * of a word spanning between this mbuf and the
  75.              * last mbuf.
  76.              *
  77.              * s_util.c[0] is already saved when scanning previous 
  78.              * mbuf.
  79.              */
  80.             s_util.c[1] = *(char *)w;
  81.             sum += s_util.s;
  82.             w = (u_short *)((char *)w + 1);
  83.             mlen = m->m_len - 1;
  84.             len--;
  85.         } else
  86.             mlen = m->m_len;
  87.         if (len < mlen)
  88.             mlen = len;
  89.         len -= mlen;
  90.         /*
  91.          * Force to even boundary.
  92.          */
  93.         if ((1 & (int) w) && (mlen > 0)) {
  94.             REDUCE;
  95.             sum <<= 8;
  96.             s_util.c[0] = *(u_char *)w;
  97.             w = (u_short *)((char *)w + 1);
  98.             mlen--;
  99.             byte_swapped = 1;
  100.         }
  101.         /*
  102.          * Unroll the loop to make overhead from
  103.          * branches &c small.
  104.          */
  105.         while ((mlen -= 32) >= 0) {
  106.             sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
  107.             sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
  108.             sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
  109.             sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
  110.             w += 16;
  111.         }
  112.         mlen += 32;
  113.         while ((mlen -= 8) >= 0) {
  114.             sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
  115.             w += 4;
  116.         }
  117.         mlen += 8;
  118.         if (mlen == 0 && byte_swapped == 0)
  119.             continue;
  120.         REDUCE;
  121.         while ((mlen -= 2) >= 0) {
  122.             sum += *w++;
  123.         }
  124.         if (byte_swapped) {
  125.             REDUCE;
  126.             sum <<= 8;
  127.             byte_swapped = 0;
  128.             if (mlen == -1) {
  129.                 s_util.c[1] = *(char *)w;
  130.                 sum += s_util.s;
  131.                 mlen = 0;
  132.             } else
  133.                 mlen = -1;
  134.         } else if (mlen == -1)
  135.             s_util.c[0] = *(char *)w;
  136.     }
  137.     if (len)
  138.         printf("cksum: out of data\n");
  139.     if (mlen == -1) {
  140.         /* The last mbuf has odd # of bytes. Follow the
  141.            standard (the odd byte may be shifted left by 8 bits
  142.            or not as determined by endian-ness of the machine) */
  143.         s_util.c[1] = 0;
  144.         sum += s_util.s;
  145.     }
  146.     REDUCE;
  147.     return (~sum & 0xffff);
  148. }
  149.