source: rtems/c/src/lib/libnetworking/netinet/in_cksum.c @ 5d5f23b

4.104.114.84.9
Last change on this file since 5d5f23b was 5d5f23b, checked in by Joel Sherrill <joel.sherrill@…>, on Feb 2, 1999 at 9:15:02 PM

Added PowerPC specific in_cksum file.

  • Property mode set to 100644
File size: 4.6 KB
Line 
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 * $Id$
35 */
36
37#include <sys/param.h>
38#include <sys/mbuf.h>
39
40/*
41 *  Try to use a CPU specific version, then punt to the portable C one.
42 */
43
44#if (defined(__GNUC__) && (defined(__mc68000__) || defined(__m68k__)))
45
46#include "in_cksum_m68k.c"
47
48#elif (defined(__GNUC__) && defined(__i386__))
49
50#include "in_cksum_i386.c"
51
52#elif (defined(__GNUC__) && defined(__PPC__))
53
54#include "in_cksum_powerpc.c"
55
56#else
57
58/*
59 * Checksum routine for Internet Protocol family headers (Portable Version).
60 *
61 * This routine is very heavily used in the network
62 * code and should be modified for each CPU to be as fast as possible.
63 */
64
65#define ADDCARRY(x)  (x > 65535 ? x -= 65535 : x)
66#define REDUCE \
67  {l_util.l = sum; sum = l_util.s[0] + l_util.s[1];  ADDCARRY(sum);}
68
69int
70in_cksum(m, len)
71        register struct mbuf *m;
72        register int len;
73{
74        register u_short *w;
75        register int sum = 0;
76        register int mlen = 0;
77        int byte_swapped = 0;
78
79        union {
80                char    c[2];
81                u_short s;
82        } s_util;
83        union {
84                u_short s[2];
85                long    l;
86        } l_util;
87
88        for (;m && len; m = m->m_next) {
89                if (m->m_len == 0)
90                        continue;
91                w = mtod(m, u_short *);
92                if (mlen == -1) {
93                        /*
94                         * The first byte of this mbuf is the continuation
95                         * of a word spanning between this mbuf and the
96                         * last mbuf.
97                         *
98                         * s_util.c[0] is already saved when scanning previous
99                         * mbuf.
100                         */
101                        s_util.c[1] = *(char *)w;
102                        sum += s_util.s;
103                        w = (u_short *)((char *)w + 1);
104                        mlen = m->m_len - 1;
105                        len--;
106                } else
107                        mlen = m->m_len;
108                if (len < mlen)
109                        mlen = len;
110                len -= mlen;
111                /*
112                 * Force to even boundary.
113                 */
114                if ((1 & (int) w) && (mlen > 0)) {
115                        REDUCE;
116                        sum <<= 8;
117                        s_util.c[0] = *(u_char *)w;
118                        w = (u_short *)((char *)w + 1);
119                        mlen--;
120                        byte_swapped = 1;
121                }
122                /*
123                 * Unroll the loop to make overhead from
124                 * branches &c small.
125                 */
126                while ((mlen -= 32) >= 0) {
127                        sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
128                        sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
129                        sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
130                        sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
131                        w += 16;
132                }
133                mlen += 32;
134                while ((mlen -= 8) >= 0) {
135                        sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
136                        w += 4;
137                }
138                mlen += 8;
139                if (mlen == 0 && byte_swapped == 0)
140                        continue;
141                REDUCE;
142                while ((mlen -= 2) >= 0) {
143                        sum += *w++;
144                }
145                if (byte_swapped) {
146                        REDUCE;
147                        sum <<= 8;
148                        byte_swapped = 0;
149                        if (mlen == -1) {
150                                s_util.c[1] = *(char *)w;
151                                sum += s_util.s;
152                                mlen = 0;
153                        } else
154                                mlen = -1;
155                } else if (mlen == -1)
156                        s_util.c[0] = *(char *)w;
157        }
158        if (len)
159                puts("cksum: out of data");
160        if (mlen == -1) {
161                /* The last mbuf has odd # of bytes. Follow the
162                   standard (the odd byte may be shifted left by 8 bits
163                   or not as determined by endian-ness of the machine) */
164                s_util.c[1] = 0;
165                sum += s_util.s;
166        }
167        REDUCE;
168        return (~sum & 0xffff);
169}
170#endif
Note: See TracBrowser for help on using the repository browser.