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