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