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