|
|
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: /*-
26: * Copyright (c) 1991, 1993
27: * The Regents of the University of California. All rights reserved.
28: *
29: * Redistribution and use in source and binary forms, with or without
30: * modification, are permitted provided that the following conditions
31: * are met:
32: * 1. Redistributions of source code must retain the above copyright
33: * notice, this list of conditions and the following disclaimer.
34: * 2. Redistributions in binary form must reproduce the above copyright
35: * notice, this list of conditions and the following disclaimer in the
36: * documentation and/or other materials provided with the distribution.
37: * 3. All advertising materials mentioning features or use of this software
38: * must display the following acknowledgement:
39: * This product includes software developed by the University of
40: * California, Berkeley and its contributors.
41: * 4. Neither the name of the University nor the names of its contributors
42: * may be used to endorse or promote products derived from this software
43: * without specific prior written permission.
44: *
45: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55: * SUCH DAMAGE.
56: *
57: * @(#)iso_chksum.c 8.1 (Berkeley) 6/10/93
58: */
59:
60: /***********************************************************
61: Copyright IBM Corporation 1987
62:
63: All Rights Reserved
64:
65: Permission to use, copy, modify, and distribute this software and its
66: documentation for any purpose and without fee is hereby granted,
67: provided that the above copyright notice appear in all copies and that
68: both that copyright notice and this permission notice appear in
69: supporting documentation, and that the name of IBM not be
70: used in advertising or publicity pertaining to distribution of the
71: software without specific, written prior permission.
72:
73: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
74: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
75: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
76: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
77: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
78: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
79: SOFTWARE.
80:
81: ******************************************************************/
82:
83: /*
84: * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
85: */
86: /*
87: * ISO CHECKSUM
88: *
89: * The checksum generation and check routines are here.
90: * The checksum is 2 bytes such that the sum of all the bytes b(i) == 0
91: * and the sum of i * b(i) == 0.
92: * The whole thing is complicated by the fact that the data are in mbuf
93: * chains.
94: * Furthermore, there is the possibility of wraparound in the running
95: * sums after adding up 4102 octets. In order to avoid doing a mod
96: * operation after EACH add, we have restricted this implementation to
97: * negotiating a maximum of 4096-octets per TPDU (for the transport layer).
98: * The routine iso_check_csum doesn't need to know where the checksum
99: * octets are.
100: * The routine iso_gen_csum takes a pointer to an mbuf chain (logically
101: * a chunk of data), an offset into the chunk at which the 2 octets are to
102: * be stuffed, and the length of the chunk. The 2 octets have to be
103: * logically adjacent, but may be physically located in separate mbufs.
104: */
105:
106: #include <sys/param.h>
107: #include <sys/systm.h>
108:
109: #if ISO
110: #include <netiso/argo_debug.h>
111: #include <sys/mbuf.h>
112: #endif /* ISO */
113:
114: #ifndef MNULL
115: #define MNULL (struct mbuf *)0
116: #endif /* MNULL */
117:
118: /*
119: * FUNCTION: iso_check_csum
120: *
121: * PURPOSE: To check the checksum of the packet in the mbuf chain (m).
122: * The total length of the packet is (len).
123: * Called from tp_input() and clnp_intr()
124: *
125: * RETURNS: TRUE (something non-zero) if there is a checksum error,
126: * FALSE if there was NO checksum error.
127: *
128: * SIDE EFFECTS: none
129: *
130: * NOTES: It might be possible to gain something by optimizing
131: * this routine (unrolling loops, etc). But it is such
132: * a horrible thing to fiddle with anyway, it probably
133: * isn't worth it.
134: */
135: int
136: iso_check_csum(m, len)
137: struct mbuf *m;
138: int len;
139: {
140: register u_char *p = mtod(m, u_char *);
141: register u_long c0=0, c1=0;
142: register int i=0;
143: int cum = 0; /* cumulative length */
144: int l;
145:
146: l = len;
147: len = min(m->m_len, len);
148: i = 0;
149:
150: IFDEBUG(D_CHKSUM)
151: printf("iso_check_csum: m x%x, l x%x, m->m_len x%x\n", m, l, m->m_len);
152: ENDDEBUG
153:
154: while( i<l ) {
155: cum += len;
156: while (i<cum) {
157: c0 = c0 + *(p++);
158: c1 += c0;
159: i++;
160: }
161: if(i < l) {
162: m = m->m_next;
163: IFDEBUG(D_CHKSUM)
164: printf("iso_check_csum: new mbuf\n");
165: if(l-i < m->m_len)
166: printf(
167: "bad mbuf chain in check csum l 0x%x i 0x%x m_data 0x%x",
168: l,i,m->m_data);
169: ENDDEBUG
170: ASSERT( m != MNULL);
171: len = min( m->m_len, l-i);
172: p = mtod(m, u_char *);
173: }
174: }
175: if ( ((int)c0 % 255) || ((int)c1 % 255) ) {
176: IFDEBUG(D_CHKSUM)
177: printf("BAD iso_check_csum l 0x%x cum 0x%x len 0x%x, i 0x%x",
178: l, cum, len, i);
179: ENDDEBUG
180: return ((int)c0 % 255)<<8 | ((int)c1 % 255);
181: }
182: return 0;
183: }
184:
185: /*
186: * FUNCTION: iso_gen_csum
187: *
188: * PURPOSE: To generate the checksum of the packet in the mbuf chain (m).
189: * The first of the 2 (logically) adjacent checksum bytes
190: * (x and y) go at offset (n).
191: * (n) is an offset relative to the beginning of the data,
192: * not the beginning of the mbuf.
193: * (l) is the length of the total mbuf chain's data.
194: * Called from tp_emit(), tp_error_emit()
195: * clnp_emit_er(), clnp_forward(), clnp_output().
196: *
197: * RETURNS: Rien
198: *
199: * SIDE EFFECTS: Puts the 2 checksum bytes into the packet.
200: *
201: * NOTES: Ditto the note for iso_check_csum().
202: */
203:
204: void
205: iso_gen_csum(m,n,l)
206: struct mbuf *m;
207: int n; /* offset of 2 checksum bytes */
208: int l;
209: {
210: register u_char *p = mtod(m, u_char *);
211: register int c0=0, c1=0;
212: register int i=0;
213: int loc = n++, len=0; /* n is position, loc is offset */
214: u_char *xloc;
215: u_char *yloc;
216: int cum=0; /* cum == cumulative length */
217:
218: IFDEBUG(D_CHKSUM)
219: printf("enter gen csum m 0x%x n 0x%x l 0x%x\n",m, n-1 ,l );
220: ENDDEBUG
221:
222: while(i < l) {
223: len = min(m->m_len, CLBYTES);
224: /* RAH: don't cksum more than l bytes */
225: len = min(len, l - i);
226:
227: cum +=len;
228: p = mtod(m, u_char *);
229:
230: if(loc>=0) {
231: if (loc < len) {
232: xloc = loc + mtod(m, u_char *);
233: IFDEBUG(D_CHKSUM)
234: printf("1: zeroing xloc 0x%x loc 0x%x\n",xloc, loc );
235: ENDDEBUG
236: *xloc = (u_char)0;
237: if (loc+1 < len) {
238: /* both xloc and yloc are in same mbuf */
239: yloc = 1 + xloc;
240: IFDEBUG(D_CHKSUM)
241: printf("2: zeroing yloc 0x%x loc 0x%x\n",yloc, loc );
242: ENDDEBUG
243: *yloc = (u_char)0;
244: } else {
245: /* crosses boundary of mbufs */
246: yloc = mtod(m->m_next, u_char *);
247: IFDEBUG(D_CHKSUM)
248: printf("3: zeroing yloc 0x%x \n",yloc );
249: ENDDEBUG
250: *yloc = (u_char)0;
251: }
252: }
253: loc -= len;
254: }
255:
256: while(i < cum) {
257: c0 = (c0 + *p);
258: c1 += c0 ;
259: i++;
260: p++;
261: }
262: m = m->m_next;
263: }
264: IFDEBUG(D_CHKSUM)
265: printf("gen csum final xloc 0x%x yloc 0x%x\n",xloc, yloc );
266: ENDDEBUG
267:
268: c1 = (((c0 * (l-n))-c1)%255) ;
269: *xloc = (u_char) ((c1 < 0)? c1+255 : c1);
270:
271: c1 = (-(int)(c1+c0))%255;
272: *yloc = (u_char) (c1 < 0? c1 + 255 : c1);
273:
274: IFDEBUG(D_CHKSUM)
275: printf("gen csum end \n");
276: ENDDEBUG
277: }
278:
279: /*
280: * FUNCTION: m_datalen
281: *
282: * PURPOSE: returns length of the mbuf chain.
283: * used all over the iso code.
284: *
285: * RETURNS: integer
286: *
287: * SIDE EFFECTS: none
288: *
289: * NOTES:
290: */
291:
292: int
293: m_datalen (m)
294: register struct mbuf *m;
295: {
296: register int datalen;
297:
298: for (datalen = 0; m; m = m->m_next)
299: datalen += m->m_len;
300: return datalen;
301: }
302:
303: int
304: m_compress(in, out)
305: register struct mbuf *in, **out;
306: {
307: register int datalen = 0;
308: int s = splimp();
309:
310: if( in->m_next == MNULL ) {
311: *out = in;
312: IFDEBUG(D_REQUEST)
313: printf("m_compress returning 0x%x: A\n", in->m_len);
314: ENDDEBUG
315: splx(s);
316: return in->m_len;
317: }
318: MGET((*out), M_DONTWAIT, MT_DATA);
319: if((*out) == MNULL) {
320: *out = in;
321: IFDEBUG(D_REQUEST)
322: printf("m_compress returning -1: B\n");
323: ENDDEBUG
324: splx(s);
325: return -1;
326: }
327: (*out)->m_len = 0;
328: (*out)->m_act = MNULL;
329:
330: while (in) {
331: IFDEBUG(D_REQUEST)
332: printf("m_compress in 0x%x *out 0x%x\n", in, *out);
333: printf("m_compress in: len 0x%x, off 0x%x\n", in->m_len, in->m_data);
334: printf("m_compress *out: len 0x%x, off 0x%x\n", (*out)->m_len,
335: (*out)->m_data);
336: ENDDEBUG
337: if (in->m_flags & M_EXT) {
338: ASSERT(in->m_len == 0);
339: }
340: if ( in->m_len == 0) {
341: in = in->m_next;
342: continue;
343: }
344: if (((*out)->m_flags & M_EXT) == 0) {
345: int len;
346:
347: len = M_TRAILINGSPACE(*out);
348: len = min(len, in->m_len);
349: datalen += len;
350:
351: IFDEBUG(D_REQUEST)
352: printf("m_compress copying len %d\n", len);
353: ENDDEBUG
354: bcopy(mtod(in, caddr_t), mtod((*out), caddr_t) + (*out)->m_len,
355: (unsigned)len);
356:
357: (*out)->m_len += len;
358: in->m_len -= len;
359: continue;
360: } else {
361: /* (*out) is full */
362: if(( (*out)->m_next = m_get(M_DONTWAIT, MT_DATA) ) == MNULL) {
363: m_freem(*out);
364: *out = in;
365: IFDEBUG(D_REQUEST)
366: printf("m_compress returning -1: B\n");
367: ENDDEBUG
368: splx(s);
369: return -1;
370: }
371: (*out)->m_len = 0;
372: (*out)->m_act = MNULL;
373: *out = (*out)->m_next;
374: }
375: }
376: m_freem(in);
377: IFDEBUG(D_REQUEST)
378: printf("m_compress returning 0x%x: A\n", datalen);
379: ENDDEBUG
380: splx(s);
381: return datalen;
382: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.