|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.