|
|
1.1 ! root 1: /*********************************************************** ! 2: Copyright IBM Corporation 1987 ! 3: ! 4: All Rights Reserved ! 5: ! 6: Permission to use, copy, modify, and distribute this software and its ! 7: documentation for any purpose and without fee is hereby granted, ! 8: provided that the above copyright notice appear in all copies and that ! 9: both that copyright notice and this permission notice appear in ! 10: supporting documentation, and that the name of IBM not be ! 11: used in advertising or publicity pertaining to distribution of the ! 12: software without specific, written prior permission. ! 13: ! 14: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 15: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 16: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 17: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 18: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 19: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 20: SOFTWARE. ! 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 $ ! 30: * @(#)iso_chksum.c 7.4 (Berkeley) 9/26/89 * ! 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: ! 51: #ifdef ISO ! 52: #ifndef lint ! 53: static char *rcsid = "$Header: iso_chksum.c,v 4.7 88/07/29 15:31:26 nhall Exp $"; ! 54: #endif ! 55: ! 56: #include "argo_debug.h" ! 57: #include "param.h" ! 58: #include "mbuf.h" ! 59: #endif ISO ! 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: */ ! 82: int ! 83: iso_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( ! 114: "bad mbuf chain in check csum l 0x%x i 0x%x m_data 0x%x", ! 115: l,i,m->m_data); ! 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: ! 151: void ! 152: iso_gen_csum(m,n,l) ! 153: struct mbuf *m; ! 154: int n; /* offset of 2 checksum bytes */ ! 155: int l; ! 156: { ! 157: register u_char *p = mtod(m, u_char *); ! 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 - i); ! 173: ! 174: cum +=len; ! 175: p = mtod(m, u_char *); ! 176: ! 177: if(loc>=0) { ! 178: if (loc < len) { ! 179: xloc = loc + mtod(m, u_char *); ! 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 */ ! 186: yloc = 1 + xloc; ! 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 */ ! 193: yloc = mtod(m->m_next, u_char *); ! 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: ! 226: struct mbuf * ! 227: m_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: ! 255: int ! 256: m_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: ! 276: int ! 277: m_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); ! 306: printf("m_compress in: len 0x%x, off 0x%x\n", in->m_len, in->m_data); ! 307: printf("m_compress *out: len 0x%x, off 0x%x\n", (*out)->m_len, ! 308: (*out)->m_data); ! 309: ENDDEBUG ! 310: if (in->m_flags & M_EXT) { ! 311: ASSERT(in->m_len == 0); ! 312: } ! 313: if ( in->m_len == 0) { ! 314: in = in->m_next; ! 315: continue; ! 316: } ! 317: if (((*out)->m_flags & M_EXT) == 0) { ! 318: int len; ! 319: ! 320: len = M_TRAILINGSPACE(*out); ! 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 ! 327: bcopy(mtod(in, caddr_t), mtod((*out), caddr_t) + (*out)->m_len, ! 328: (unsigned)len); ! 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.