[BACK]Return to in4_cksum.c CVS log [TXT][DIR] Up to [local] / sys / arch / vax / vax

Annotation of sys/arch/vax/vax/in4_cksum.c, Revision 1.1.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