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