Annotation of sys/arch/vax/vax/in4_cksum.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: in4_cksum.c,v 1.2 2005/05/24 20:35:29 miod Exp $ */
! 2: /* $NetBSD: in4_cksum.c,v 1.8 2003/09/29 22:54:28 matt Exp $ */
! 3:
! 4: /*
! 5: * Copyright (C) 1999 WIDE Project.
! 6: * All rights reserved.
! 7: *
! 8: * Redistribution and use in source and binary forms, with or without
! 9: * modification, are permitted provided that the following conditions
! 10: * are met:
! 11: * 1. Redistributions of source code must retain the above copyright
! 12: * notice, this list of conditions and the following disclaimer.
! 13: * 2. Redistributions in binary form must reproduce the above copyright
! 14: * notice, this list of conditions and the following disclaimer in the
! 15: * documentation and/or other materials provided with the distribution.
! 16: * 3. Neither the name of the project nor the names of its contributors
! 17: * may be used to endorse or promote products derived from this software
! 18: * without specific prior written permission.
! 19: *
! 20: * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
! 21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 22: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 23: * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
! 24: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 25: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 26: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 27: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 28: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 29: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 30: * SUCH DAMAGE.
! 31: */
! 32:
! 33: /*
! 34: * Copyright (c) 1988, 1992, 1993
! 35: * The Regents of the University of California. All rights reserved.
! 36: *
! 37: * Redistribution and use in source and binary forms, with or without
! 38: * modification, are permitted provided that the following conditions
! 39: * are met:
! 40: * 1. Redistributions of source code must retain the above copyright
! 41: * notice, this list of conditions and the following disclaimer.
! 42: * 2. Redistributions in binary form must reproduce the above copyright
! 43: * notice, this list of conditions and the following disclaimer in the
! 44: * documentation and/or other materials provided with the distribution.
! 45: * 3. Neither the name of the University nor the names of its contributors
! 46: * may be used to endorse or promote products derived from this software
! 47: * without specific prior written permission.
! 48: *
! 49: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 50: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 51: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 52: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 53: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 54: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 55: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 56: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 57: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 58: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 59: * SUCH DAMAGE.
! 60: *
! 61: * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93
! 62: */
! 63:
! 64: #if 0
! 65: #include <sys/cdefs.h>
! 66: __KERNEL_RCSID(0, "$NetBSD: in4_cksum.c,v 1.8 2003/09/29 22:54:28 matt Exp $");
! 67: #endif
! 68:
! 69: #include <sys/param.h>
! 70: #include <sys/systm.h>
! 71: #include <sys/mbuf.h>
! 72: #include <sys/socketvar.h>
! 73: #include <netinet/in.h>
! 74: #include <netinet/in_systm.h>
! 75: #include <netinet/ip.h>
! 76: #include <netinet/ip_var.h>
! 77:
! 78: #ifdef CKSUMDEBUG
! 79: int in4_cksum_md_debug(struct mbuf *m, u_int8_t nxt, int off, int len);
! 80: #define in4_cksum in4_cksum_md_debug
! 81: #include <netinet/in4_cksum.c>
! 82: #undef in4_cksum
! 83: #undef ADDCARRY
! 84: #undef REDUCE
! 85: #endif
! 86:
! 87: /*
! 88: * Checksum routine for Internet Protocol family headers.
! 89: * This is only for IPv4 pseudo header checksum.
! 90: * No need to clear non-pseudo-header fields in IPv4 header.
! 91: * len is for actual payload size, and does not include IPv4 header and
! 92: * skipped header chain (off + len should be equal to the whole packet).
! 93: *
! 94: * This implementation is VAX version.
! 95: */
! 96:
! 97:
! 98: #define REDUCE {sum = (sum & 0xffff) + (sum >> 16);}
! 99: #define ADDCARRY {if (sum > 0xffff) sum -= 0xffff;}
! 100: #define ADVANCE(n) {w += n; mlen -= n;}
! 101: #define SWAP {sum <<= 8;} /* depends on recent REDUCE */
! 102:
! 103: #define Asm __asm __volatile
! 104: #define ADDL Asm("addl2 (%2)+,%0" : "=r" (sum) : "0" (sum), "r" (w))
! 105: #define ADWC Asm("adwc (%2)+,%0" : "=r" (sum) : "0" (sum), "r" (w))
! 106: #define ADDC Asm("adwc $0,%0" : "=r" (sum) : "0" (sum))
! 107: #define UNSWAP Asm("rotl $8,%0,%0" : "=r" (sum) : "0" (sum))
! 108: #define ADDBYTE {sum += *w; SWAP; byte_swapped ^= 1;}
! 109: #define ADDWORD {sum += *(u_short *)w;}
! 110:
! 111: int
! 112: in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len)
! 113: {
! 114: u_int8_t *w;
! 115: u_int32_t sum = 0;
! 116: int mlen = 0;
! 117: int byte_swapped = 0;
! 118: #ifdef CKSUMDEBUG
! 119: int debugrv = in4_cksum_md_debug(m, nxt, off, len);
! 120: #endif
! 121:
! 122: if (nxt != 0) {
! 123: #ifdef DIAGNOSTIC
! 124: if (off < sizeof(struct ipovly))
! 125: panic("in4_cksum: offset too short");
! 126: if (m->m_len < sizeof(struct ip))
! 127: panic("in4_cksum: bad mbuf chain");
! 128: #endif
! 129:
! 130: __asm __volatile(
! 131: "movzwl %3,%0;" /* mov len to sum */
! 132: "addb2 %4,%0;" /* add proto to sum */
! 133: "rotl $8,%0,%0;" /* htons, carry is preserved */
! 134: "adwc 12(%2),%0;" /* add src ip */
! 135: "adwc 16(%2),%0;" /* add dst ip */
! 136: "adwc $0,%0;" /* clean up carry */
! 137: : "=r" (sum)
! 138: : "0" (sum), "r" (mtod(m, void *)), "r" (len), "r"(nxt));
! 139: }
! 140:
! 141: /* skip unnecessary part */
! 142: while (m && off > 0) {
! 143: if (m->m_len > off)
! 144: break;
! 145: off -= m->m_len;
! 146: m = m->m_next;
! 147: }
! 148:
! 149: for (;m && len; m = m->m_next) {
! 150: if ((mlen = m->m_len) == 0)
! 151: continue;
! 152: w = mtod(m, u_int8_t *);
! 153: if (off) {
! 154: w += off;
! 155: mlen -= off;
! 156: off = 0;
! 157: }
! 158: if (len < mlen)
! 159: mlen = len;
! 160: len -= mlen;
! 161: if (mlen < 16)
! 162: goto short_mbuf;
! 163: /*
! 164: * Ensure that we're aligned on a word boundary here so
! 165: * that we can do 32 bit operations below.
! 166: */
! 167: if ((3 & (u_long) w) != 0) {
! 168: REDUCE;
! 169: if ((1 & (u_long) w) != 0) {
! 170: ADDBYTE;
! 171: ADVANCE(1);
! 172: }
! 173: if ((2 & (u_long) w) != 0) {
! 174: ADDWORD;
! 175: ADVANCE(2);
! 176: }
! 177: }
! 178: /*
! 179: * Do as much of the checksum as possible 32 bits at at time.
! 180: * In fact, this loop is unrolled to make overhead from
! 181: * branches &c small.
! 182: */
! 183: while ((mlen -= 32) >= 0) {
! 184: /*
! 185: * Add with carry 16 words and fold in the last carry
! 186: * by adding a 0 with carry.
! 187: */
! 188: ADDL; ADWC; ADWC; ADWC;
! 189: ADWC; ADWC; ADWC; ADWC;
! 190: ADDC;
! 191: }
! 192: mlen += 32;
! 193: if (mlen >= 16) {
! 194: ADDL; ADWC; ADWC; ADWC;
! 195: ADDC;
! 196: mlen -= 16;
! 197: }
! 198: short_mbuf:
! 199: if (mlen >= 8) {
! 200: ADDL; ADWC;
! 201: ADDC;
! 202: mlen -= 8;
! 203: }
! 204: if (mlen >= 4) {
! 205: ADDL;
! 206: ADDC;
! 207: mlen -= 4;
! 208: }
! 209: if (mlen > 0) {
! 210: REDUCE;
! 211: if (mlen >= 2) {
! 212: ADDWORD;
! 213: ADVANCE(2);
! 214: }
! 215: if (mlen >= 1) {
! 216: ADDBYTE;
! 217: }
! 218: }
! 219: }
! 220:
! 221: if (len)
! 222: printf("cksum4: out of data\n");
! 223: if (byte_swapped) {
! 224: UNSWAP;
! 225: }
! 226: REDUCE;
! 227: ADDCARRY;
! 228: #ifdef CKSUMDEBUG
! 229: if ((sum ^ 0xffff) != debugrv)
! 230: printf("in4_cksum: rv != debugrv (rv %x debugrv %x)\n",
! 231: (sum ^ 0xffff), debugrv);
! 232: #endif
! 233: return (sum ^ 0xffff);
! 234: }
CVSweb