|
|
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: /* ! 63: * $Header: iso_chksum.c,v 4.7 88/07/29 15:31:26 nhall Exp $ ! 64: * $Source: /usr/argo/sys/netiso/RCS/iso_chksum.c,v $ ! 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.