|
|
1.1 ! root 1: /* ! 2: * C H P A C K E T ! 3: * ! 4: * Packet handling utilities for the Chaosnet line discipline. ! 5: * ! 6: * ! 7: * (c) Copyright 1985 Nirvonics, Inc. ! 8: * ! 9: * Written by Kurt Gollhardt ! 10: * Last update Thu Feb 28 14:44:14 1985 ! 11: * ! 12: * This software is the property of Nirvonics, Inc. ! 13: * All rights reserved. ! 14: * ! 15: */ ! 16: ! 17: #include "ch.h" ! 18: #if NCH > 0 ! 19: #include "../h/param.h" ! 20: #include "../h/systm.h" ! 21: #include "../h/stream.h" ! 22: #include "../h/conf.h" ! 23: #include "../chaosld/types.h" ! 24: #include "../chaosld/constants.h" ! 25: #include "../chaosld/globals.h" ! 26: ! 27: #define CAREFUL ! 28: ! 29: ! 30: /* ! 31: * Get blocks from a queue, up to the next delimiter, ! 32: * and place them into a packet structure. ! 33: */ ! 34: ! 35: struct packet *get_packet(q, wflag) ! 36: register struct queue *q; ! 37: { ! 38: register struct packet *pk; ! 39: register struct block *bp, **nextbp; ! 40: register int len; ! 41: ! 42: len = wflag? 1 : sizeof(struct pkt_header); ! 43: if ((bp = getq(q)) == NOBLOCK) ! 44: return NOPKT; ! 45: ! 46: #ifdef CAREFUL ! 47: if (bp->type != M_DATA || ! 48: bp->wptr - bp->rptr < len) { ! 49: freeb(bp); ! 50: printf("bad block in get_packet()\n"); ! 51: return NOPKT; ! 52: } ! 53: #endif CAREFUL ! 54: ! 55: if ((pk = pkalloc()) == NOPKT) { ! 56: freeb(bp); ! 57: flush_packet(q); ! 58: return NOPKT; ! 59: } ! 60: ! 61: if (wflag) ! 62: pk->pk_op = *bp->rptr++; ! 63: else { ! 64: pk->ph = *(struct pkt_header *)(bp->rptr); ! 65: bp->rptr += sizeof(struct pkt_header); ! 66: } ! 67: if (bp->rptr >= bp->wptr) { ! 68: freeb(bp); ! 69: bp = getq(q); ! 70: } ! 71: ! 72: pk->pk_lenword = 0; ! 73: nextbp = &pk->data; ! 74: while (bp != NOBLOCK && bp->type != M_DELIM) { ! 75: pk->pk_lenword += bp->wptr - bp->rptr; ! 76: *nextbp = bp; ! 77: nextbp = &bp->next; ! 78: bp = getq(q); ! 79: } ! 80: *nextbp = NOBLOCK; ! 81: if (bp != NOBLOCK) ! 82: freeb(bp); /* Throw away the delimiter */ ! 83: ! 84: pk->time = Chclock; ! 85: pk->next = NOPKT; ! 86: return pk; ! 87: } ! 88: ! 89: ! 90: /* ! 91: * Take the header and data blocks from a packet ! 92: * and put them onto the queue. ! 93: * Any storage associated with the packet is freed. ! 94: */ ! 95: ! 96: put_packet(q, pk) ! 97: struct queue *q; ! 98: struct packet *pk; ! 99: { ! 100: putcpy(q->next, &pk->ph, sizeof(struct pkt_header)); ! 101: put_pkdata(q, pk); ! 102: } ! 103: ! 104: ! 105: /* ! 106: * Take the data blocks from a packet ! 107: * and put them onto the queue. ! 108: * Any storage associated with the packet is freed. ! 109: */ ! 110: ! 111: put_pkdata(q, pk) ! 112: register struct queue *q; ! 113: register struct packet *pk; ! 114: { ! 115: register struct block *bp, *nextb; ! 116: ! 117: for (bp = pk->data; bp != NOBLOCK; bp = nextb) { ! 118: nextb = bp->next; ! 119: (*q->next->qinfo->putp) (q->next, bp); ! 120: } ! 121: ! 122: if (q->flag & QDELIM) ! 123: putctl(q->next, M_DELIM); ! 124: ! 125: pk->data = NOBLOCK; ! 126: free_packet(pk); ! 127: } ! 128: ! 129: ! 130: /* ! 131: * Copy the header and data blocks from a packet onto a queue. ! 132: */ ! 133: ! 134: copy_packet(q, pk) ! 135: struct queue *q; ! 136: struct packet *pk; ! 137: { ! 138: putcpy(q->next, &pk->ph, sizeof(struct pkt_header)); ! 139: copy_pkdata(q, pk); ! 140: } ! 141: ! 142: ! 143: /* ! 144: * Copy the data blocks from a packet onto a queue. ! 145: */ ! 146: ! 147: copy_pkdata(q, pk) ! 148: register struct queue *q; ! 149: register struct packet *pk; ! 150: { ! 151: register struct block *bp; ! 152: ! 153: for (bp = pk->data; bp != NOBLOCK; bp = bp->next) ! 154: putcpy(q->next, bp->rptr, bp->wptr - bp->rptr); ! 155: putctl(q->next, M_DELIM); ! 156: } ! 157: ! 158: ! 159: /* ! 160: * Obtain storage for a packet and perfrom minimal initialization. ! 161: */ ! 162: ! 163: struct packet * ! 164: new_packet() ! 165: { ! 166: register struct packet *pk; ! 167: ! 168: if ((pk = pkalloc()) == NOPKT) ! 169: return NOPKT; ! 170: bfill(pk, sizeof(struct packet), 0); ! 171: pk->time = Chclock; ! 172: return pk; ! 173: } ! 174: ! 175: ! 176: /* ! 177: * Release all storage associated with a packet structure. ! 178: */ ! 179: ! 180: free_packet(pk) ! 181: register struct packet *pk; ! 182: { ! 183: free_pkdata(pk); ! 184: pkfree(pk); ! 185: } ! 186: ! 187: ! 188: /* ! 189: * Release all data blocks in packet. ! 190: */ ! 191: ! 192: free_pkdata(pk) ! 193: register struct packet *pk; ! 194: { ! 195: register struct block *bp, *nextb; ! 196: ! 197: for (bp = pk->data; bp != NOBLOCK; bp = nextb) { ! 198: nextb = bp->next; ! 199: freeb(bp); ! 200: } ! 201: pk->data = NOBLOCK; ! 202: pk->pk_lenword = 0; ! 203: } ! 204: ! 205: ! 206: /* ! 207: * Collapse all of the data blocks for a packet ! 208: * into a single block if possible ! 209: */ ! 210: ! 211: flatten(pk) ! 212: register struct packet *pk; ! 213: { ! 214: register struct block *bp, *bigb, *nextb; ! 215: register int n; ! 216: int ps; ! 217: ! 218: debug(DPKT,printf("flatten packet of length %d\n", pk->pk_len)); ! 219: if (pk->data->wptr - pk->data->rptr >= pk->pk_len) ! 220: return 0; ! 221: if ((bigb = allocb(pk->pk_len)) == NOBLOCK) { ! 222: debug(DPKT|DABNOR,printf("flatten: can't alloc block\n")); ! 223: return -1; ! 224: } ! 225: bigb->next = NOBLOCK; ! 226: bp = pk->data; ! 227: ps = spl6(); ! 228: pk->data = bigb; ! 229: ! 230: while (bp != NOBLOCK) { ! 231: n = bp->wptr - bp->rptr; ! 232: if (bigb->lim - bigb->wptr < n) ! 233: n = bigb->lim - bigb->wptr; ! 234: bcopy(bp->rptr, bigb->wptr, n); ! 235: bigb->wptr += n; ! 236: bp->rptr += n; ! 237: if (bp->rptr < bp->wptr) { ! 238: bigb->next = bp; ! 239: splx(ps); ! 240: debug(DPKT|DABNOR,printf("flatten: not enough room in block\n")); ! 241: return -1; ! 242: } ! 243: nextb = bp->next; ! 244: freeb(bp); ! 245: bp = nextb; ! 246: } ! 247: ! 248: splx(ps); ! 249: return 0; ! 250: } ! 251: ! 252: ! 253: /* ! 254: * Add some bytes of data to the end of a packet. ! 255: * Allocate blocks as necessary. ! 256: */ ! 257: ! 258: append_packet(pkt, buf, n) ! 259: register struct packet *pkt; ! 260: char *buf; ! 261: int n; ! 262: { ! 263: register struct block *bp; ! 264: register int nmin; ! 265: ! 266: if (pkt->data == NOBLOCK) { ! 267: if ((bp = allocb(n)) == NOBLOCK) ! 268: return; ! 269: pkt->data = bp; ! 270: bp->next = NOBLOCK; ! 271: } else { ! 272: for (bp = pkt->data; bp->next != NOBLOCK; bp = bp->next) ! 273: ; ! 274: } ! 275: ! 276: while (n > 0) { ! 277: if (bp->wptr == bp->lim) { ! 278: if ((bp->next = allocb(n)) == NOBLOCK) ! 279: return; ! 280: bp = bp->next; ! 281: bp->next = NOBLOCK; ! 282: } ! 283: nmin = bp->lim - bp->wptr; ! 284: if (nmin > n) ! 285: nmin = n; ! 286: bcopy(buf, bp->wptr, nmin); ! 287: buf += nmin; ! 288: bp->wptr += nmin; ! 289: pkt->pk_lenword += nmin; ! 290: n -= nmin; ! 291: } ! 292: } ! 293: ! 294: ! 295: /* ! 296: * Free a list of packets ! 297: */ ! 298: freelist(pkt) ! 299: register struct packet *pkt; ! 300: { ! 301: register struct packet *opkt; ! 302: ! 303: while ((opkt = pkt) != NOPKT) { ! 304: pkt = pkt->next; ! 305: free_packet(opkt); ! 306: } ! 307: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.