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

1.1     ! root        1: /*
        !             2:  *             C H A O S  L D
        !             3:  *
        !             4:  * Chaosnet line discipline, to be pushed on an ethernet controller.
        !             5:  * Handles xmit and rcv windows, packet numbering, and connection states.
        !             6:  *
        !             7:  *
        !             8:  * (c) Copyright 1985  Nirvonics, Inc.
        !             9:  *
        !            10:  * Written by Kurt Gollhardt
        !            11:  * Last update Tue Mar 12 04:18:58 1985
        !            12:  *
        !            13:  * This software is the property of Nirvonics, Inc.
        !            14:  * All rights reserved.
        !            15:  *
        !            16:  */
        !            17: 
        !            18: #include "ch.h"
        !            19: #if NCH
        !            20: #include "../h/param.h"
        !            21: #include "../h/systm.h"
        !            22: #include "../h/stream.h"
        !            23: #include "../h/ioctl.h"
        !            24: #include "../h/ttyld.h"
        !            25: #include "../h/map.h"
        !            26: #include "../h/buf.h"
        !            27: #include "../h/conf.h"
        !            28: #include "../chaosld/types.h"
        !            29: #define CHDEFINE
        !            30: #include "../chaosld/globals.h"
        !            31: 
        !            32: 
        !            33: extern int     chrcv(), chb_put();
        !            34: int            chopen(), chclose(), chosrv(), chisrv();
        !            35: static struct qinit chrinit = { chb_put, chisrv, chopen, chclose, 512, 64 };
        !            36: static struct qinit chwinit = { putq, chosrv, chopen, chclose, 512, 64 };
        !            37: struct streamtab chinfo = { &chrinit, &chwinit };
        !            38: 
        !            39: chopen(q, dev)
        !            40:      register struct queue *q;
        !            41: {
        !            42:      if (q->ptr)
        !            43:           return(1);
        !            44:      if (ChaosQ != (struct queue *)0)   /* Already open */
        !            45:           return(0);
        !            46:      ChaosQ = q;     /* that's the RD q */
        !            47:      q->flag |= QDELIM|QNOENB;     /* chiput calls qenable() */
        !            48:      WR(q)->flag |= QDELIM;
        !            49:      return(1);
        !            50: }
        !            51: 
        !            52: chclose(q)
        !            53:      struct queue   *q;
        !            54: {
        !            55:      struct connection   **connp;
        !            56:      int       ps = spl6();
        !            57: 
        !            58:      for (connp = Chconn; connp < &Chconn[NCH]; ++connp)
        !            59:           if (*connp != NOCONN)
        !            60:               chld_close(*connp, NOPKT);
        !            61: 
        !            62:      freelist(Chlsnlist);
        !            63:      freelist(Chrfclist);
        !            64:      Chlsnlist = Chrfclist = Chrfctail = NOPKT;
        !            65:      Chmyaddr.ch_addr = 0;
        !            66: 
        !            67:      ChaosQ = (struct queue *)0;
        !            68:      splx(ps);
        !            69: }
        !            70: 
        !            71: 
        !            72: chisrv(q)
        !            73:      struct queue   *q;
        !            74: {
        !            75:      register struct block    *bp;
        !            76: 
        !            77:      chrcv(q);   /* Receive the packet */
        !            78: 
        !            79:      /* See if there's another packet on the queue */
        !            80:      for (bp = q->first; bp != NOBLOCK; bp = bp->next)
        !            81:          if (bp->type == M_DELIM) {
        !            82:               qenable(q);    /* re-enable queue for the next packet */
        !            83:               break;
        !            84:           }
        !            85: }
        !            86: 
        !            87: 
        !            88: chosrv(q)
        !            89:      register struct queue *q;
        !            90: {
        !            91:      register union stmsg *sp;
        !            92:      register struct block *bp;
        !            93: 
        !            94:      while(bp = getq(q)){
        !            95:           if(bp->type == M_IOCTL){
        !            96:                sp = (union stmsg *)bp->rptr;
        !            97:                switch(sp->ioc0.com){
        !            98:                    case CHIOCNAME:
        !            99:                         copyin(*(caddr_t *)sp->iocx.xxx, Chmyname, CHSTATNAME);
        !           100:                          bp->rptr = bp->wptr;
        !           101:                         bp->type = M_IOCACK;
        !           102:                         qreply(q, bp);
        !           103:                         break;
        !           104:                    case CHIOCADDR:
        !           105:                         Chmyaddr.ch_addr = *(int *)sp->iocx.xxx;
        !           106:                         /* fall through */
        !           107:                     default:
        !           108:                          (*q->next->qinfo->putp)(q->next, bp);
        !           109:                          break;
        !           110:                }
        !           111:           } else
        !           112:                (*q->next->qinfo->putp)(q->next, bp);
        !           113:      }
        !           114: }
        !           115: 
        !           116: chld_write(conn, pkt)
        !           117:      register struct connection    *conn;
        !           118:      register struct packet        *pkt;
        !           119: {
        !           120:      setconn(conn, pkt);
        !           121: 
        !           122:      switch (pkt->pk_op) {
        !           123:           case ANSOP:
        !           124:          case FWDOP:
        !           125:               if (conn->cn_state != CSRFCRCVD ||
        !           126:                         (conn->cn_flags & CHANSWER) == 0)
        !           127:                     goto err;
        !           128:                chld_close(conn, pkt);
        !           129:               return 0;
        !           130:           case RFCOP:
        !           131:           case BRDOP:
        !           132:               if (conn->cn_state != CSRFCSENT)
        !           133:                    goto err;
        !           134:                break;
        !           135:           case UNCOP:
        !           136:               pkt->pk_pkn = 0;
        !           137:               pkt->next = NOPKT;
        !           138:               senddata(pkt);
        !           139:               return 0;
        !           140:           default:
        !           141:               if (!ISDATA(pkt))
        !           142:                    goto err;
        !           143:           case OPNOP:
        !           144:          case EOFOP:
        !           145:               if (conn->cn_state != CSOPEN)
        !           146:                    goto err;
        !           147:                setack(conn, pkt);
        !           148:                break;
        !           149:      }
        !           150: 
        !           151:      pkt->pk_pkn = ++conn->cn_tlast;
        !           152:      senddata(pkt);
        !           153:      return 0;
        !           154: 
        !           155: err:
        !           156:      free_packet(pkt);
        !           157:      return -1;
        !           158: }
        !           159: 
        !           160: 
        !           161: chld_eof(conn)
        !           162:      struct connection   *conn;
        !           163: {
        !           164:      register struct packet   *pkt;
        !           165: 
        !           166:      if ((pkt = new_packet()) != NOPKT) {
        !           167:          setconn(conn, pkt);
        !           168:           pkt->pk_op = EOFOP;
        !           169:          return chld_write(conn, pkt);
        !           170:      }
        !           171:      return 0;
        !           172: }
        !           173: 
        !           174: 
        !           175: chld_accept(conn)
        !           176:      struct connection   *conn;
        !           177: {
        !           178:      conn->cn_state = CSOPEN;
        !           179:      sendopn(conn);
        !           180: }
        !           181: 
        !           182: 
        !           183: chld_open(conn, daddr, rwsize, pkt)
        !           184:      register struct connection    *conn;
        !           185:      register struct packet   *pkt;
        !           186: {
        !           187:      conn->cn_faddr.ch_addr = daddr;
        !           188:      conn->cn_state = CSRFCSENT;
        !           189:      conn->cn_rwsize = rwsize;
        !           190:      conn->cn_rsts = rwsize / 2;
        !           191:      conn->cn_time = Chclock;
        !           192:      pkt->pk_op = RFCOP;
        !           193:      pkt->pk_fc = pkt->pk_ackn = 0;
        !           194:      debug(DCONN,printf("Conn #%x: RFCS state\n", conn->cn_lidx.ci_idx));
        !           195:      /*
        !           196:       * By writing the RFC packet like a data packet, it will be kept
        !           197:       * around for automatic retransmission until freed by the normal
        !           198:       * receipting mechanism; xmitdone() and chrcv() facilitate this.
        !           199:       * Since new_conn() clears the connection (including cn_tlast),
        !           200:       * the packet number of the RFC will be 1 (pkn = ++cn_tlast).
        !           201:       */
        !           202:      chld_write(conn, pkt);
        !           203: }
        !           204: 
        !           205: 
        !           206: chld_listen(conn, rwsize, pkt)
        !           207:      register struct connection    *conn;
        !           208:      register struct packet   *pkt;
        !           209: {
        !           210:      register struct packet   *opkt, *pktl;
        !           211:      int       ps;
        !           212: 
        !           213:      conn->cn_state = CSLISTEN;
        !           214:      conn->cn_flags |= CHSERVER;
        !           215:      conn->cn_rwsize = rwsize;
        !           216:      pkt->pk_op = LSNOP;
        !           217:      setconn(conn, pkt);
        !           218: 
        !           219:      if (flatten(pkt)) {
        !           220:           free_packet(pkt);
        !           221:          return;
        !           222:      }
        !           223: 
        !           224:      ps = spl6();
        !           225:      opkt = NOPKT;
        !           226:      for (pktl = Chrfclist; pktl != NOPKT; pktl = (opkt = pktl)->next)
        !           227:           if (concmp(pktl, pkt->data->rptr, (int)pkt->pk_len)) {
        !           228:               if (opkt == NOPKT)
        !           229:                    Chrfclist = pktl->next;
        !           230:                else
        !           231:                    opkt->next = pktl->next;
        !           232:                if (pktl == Chrfctail)
        !           233:                    Chrfctail = opkt;
        !           234:                free_packet(pkt);
        !           235:               lsnmatch(pktl, conn);
        !           236:               chd_newstate(conn);
        !           237:               splx(ps);
        !           238:               return;
        !           239:           }
        !           240: 
        !           241:      pkt->next = Chlsnlist;
        !           242:      Chlsnlist = pkt;
        !           243:      splx(ps);
        !           244: 
        !           245:      debug(DCONN,printf("Conn #%x: LISTEN state\n", conn->cn_lidx.ci_idx));
        !           246: }
        !           247: 
        !           248: 
        !           249: chld_close(conn, pkt)
        !           250:      register struct connection    *conn;
        !           251:      register struct packet        *pkt;
        !           252: {
        !           253:      int       ps = spl6();
        !           254: 
        !           255:      ch_busy++;
        !           256:      switch (conn->cn_state) {
        !           257:           case CSOPEN:
        !           258:          case CSRFCRCVD:
        !           259:               if (pkt != NOPKT) {
        !           260:                    setconn(conn, pkt);
        !           261:                    pkt->pk_ackn = pkt->pk_pkn = 0;
        !           262:                    sendctl(pkt);
        !           263:                    pkt = NOPKT;
        !           264:                }
        !           265:               /* Fall into ... */
        !           266:           case CSRFCSENT:
        !           267:               close_conn(conn, CSCLOSED, NOPKT);
        !           268:               break;
        !           269:           case CSLISTEN:
        !           270:               rmlisten(conn);
        !           271:               break;
        !           272:      }
        !           273:      --ch_busy;
        !           274:      splx(ps);
        !           275: 
        !           276:      if (pkt != NOPKT)
        !           277:           free_packet(pkt);
        !           278: }
        !           279: 
        !           280: #endif

unix.superglobalmegacorp.com

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