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