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