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