|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
26: /*
27: * Copyright (c) 1988, 1992, 1993
28: * The Regents of the University of California. All rights reserved.
29: *
30: * Redistribution and use in source and binary forms, with or without
31: * modification, are permitted provided that the following conditions
32: * are met:
33: * 1. Redistributions of source code must retain the above copyright
34: * notice, this list of conditions and the following disclaimer.
35: * 2. Redistributions in binary form must reproduce the above copyright
36: * notice, this list of conditions and the following disclaimer in the
37: * documentation and/or other materials provided with the distribution.
38: * 3. All advertising materials mentioning features or use of this software
39: * must display the following acknowledgement:
40: * This product includes software developed by the University of
41: * California, Berkeley and its contributors.
42: * 4. Neither the name of the University nor the names of its contributors
43: * may be used to endorse or promote products derived from this software
44: * without specific prior written permission.
45: *
46: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
47: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
50: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56: * SUCH DAMAGE.
57: *
58: * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93
59: */
60:
61: #include <sys/param.h>
62: #include <sys/mbuf.h>
63:
64: #if NEXT
65: #import <kern/kdebug.h>
66:
67: #if KDEBUG
68:
69: #define DBG_FNC_IN_CKSUM NETDBG_CODE(DBG_NETIP, (3 << 8))
70:
71: #endif
72:
73: #endif
74:
75: #if defined(ppc)
76:
77: int
78: in_cksum(m, len)
79: register struct mbuf *m;
80: register int len;
81: {
82: register u_short *w;
83: register int sum = 0;
84: register int mlen = 0;
85: int starting_on_odd = 0;
86:
87:
88: KERNEL_DEBUG(DBG_FNC_IN_CKSUM | DBG_FUNC_START, len,0,0,0,0);
89:
90: for (;m && len; m = m->m_next) {
91: if (m->m_len == 0)
92: continue;
93: mlen = m->m_len;
94: w = mtod(m, u_short *);
95:
96: if (len < mlen)
97: mlen = len;
98:
99: sum = xsum_assym(w, mlen, sum, starting_on_odd);
100: len -= mlen;
101: if (mlen & 0x1)
102: {
103: if (starting_on_odd)
104: starting_on_odd = 0;
105: else
106: starting_on_odd = 1;
107: }
108: }
109:
110: KERNEL_DEBUG(DBG_FNC_IN_CKSUM | DBG_FUNC_END, 0,0,0,0,0);
111: return (~sum & 0xffff);
112: }
113:
114: #else
115:
116:
117: /*
118: * Checksum routine for Internet Protocol family headers (Portable Version).
119: *
120: * This routine is very heavily used in the network
121: * code and should be modified for each CPU to be as fast as possible.
122: */
123:
124:
125:
126: #define ADDCARRY(x) (x > 65535 ? x -= 65535 : x)
127: #define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
128:
129:
130: int
131: in_cksum(m, len)
132: register struct mbuf *m;
133: register int len;
134: {
135: register u_short *w;
136: register int sum = 0;
137: register int mlen = 0;
138: int byte_swapped = 0;
139:
140: union {
141: char c[2];
142: u_short s;
143: } s_util;
144: union {
145: u_short s[2];
146: long l;
147: } l_util;
148:
149:
150: KERNEL_DEBUG(DBG_FNC_IN_CKSUM | DBG_FUNC_START, len,0,0,0,0);
151:
152: for (;m && len; m = m->m_next) {
153: if (m->m_len == 0)
154: continue;
155: w = mtod(m, u_short *);
156: if (mlen == -1) {
157: /*
158: * The first byte of this mbuf is the continuation
159: * of a word spanning between this mbuf and the
160: * last mbuf.
161: *
162: * s_util.c[0] is already saved when scanning previous
163: * mbuf.
164: */
165: s_util.c[1] = *(char *)w;
166: sum += s_util.s;
167: w = (u_short *)((char *)w + 1);
168: mlen = m->m_len - 1;
169: len--;
170: } else
171: mlen = m->m_len;
172: if (len < mlen)
173: mlen = len;
174: len -= mlen;
175: /*
176: * Force to even boundary.
177: */
178: if ((1 & (int) w) && (mlen > 0)) {
179: REDUCE;
180: sum <<= 8;
181: s_util.c[0] = *(u_char *)w;
182: w = (u_short *)((char *)w + 1);
183: mlen--;
184: byte_swapped = 1;
185: }
186: /*
187: * Unroll the loop to make overhead from
188: * branches &c small.
189: */
190: while ((mlen -= 32) >= 0) {
191: sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
192: sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
193: sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
194: sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
195: w += 16;
196: }
197: mlen += 32;
198: while ((mlen -= 8) >= 0) {
199: sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
200: w += 4;
201: }
202: mlen += 8;
203: if (mlen == 0 && byte_swapped == 0)
204: continue;
205: REDUCE;
206: while ((mlen -= 2) >= 0) {
207: sum += *w++;
208: }
209: if (byte_swapped) {
210: REDUCE;
211: sum <<= 8;
212: byte_swapped = 0;
213: if (mlen == -1) {
214: s_util.c[1] = *(char *)w;
215: sum += s_util.s;
216: mlen = 0;
217: } else
218: mlen = -1;
219: } else if (mlen == -1)
220: s_util.c[0] = *(char *)w;
221: }
222: if (len)
223: printf("cksum: out of data\n");
224: if (mlen == -1) {
225: /* The last mbuf has odd # of bytes. Follow the
226: standard (the odd byte may be shifted left by 8 bits
227: or not as determined by endian-ness of the machine) */
228: s_util.c[1] = 0;
229: sum += s_util.s;
230: }
231: REDUCE;
232: KERNEL_DEBUG(DBG_FNC_IN_CKSUM | DBG_FUNC_END, 0,0,0,0,0);
233: return (~sum & 0xffff);
234: }
235:
236: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.