Annotation of researchv8dc/sys/chaosld/chpacket.c, revision 1.1.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.