Annotation of researchv8dc/sys/chaosld/chpacket.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.