Annotation of researchv8dc/sys/chncp/chrcv.c, revision 1.1

1.1     ! root        1: #include "../chunix/chsys.h"
        !             2: #include "../chunix/chconf.h"
        !             3: #include "../chaos/chaos.h"
        !             4: 
        !             5: /*
        !             6:  * Receive side - basically driven by an incoming packet.
        !             7:  */
        !             8: 
        !             9: #define send_los(x,y) sendlos(x,y,sizeof(y) - 1)
        !            10: 
        !            11: /*
        !            12:  * Receive a packet - called from receiver interrupt level.
        !            13:  */
        !            14: rcvpkt(pkt)
        !            15: register struct packet *pkt;
        !            16: {
        !            17:        register struct connection *conn;
        !            18:        register unsigned index;
        !            19: 
        !            20:        debug(DPKT,printf("Rcvpkt: "));
        !            21:        pkt->pk_next = NOPKT;
        !            22:        if (pkt->pk_op == RUTOP)
        !            23:                rcvrut(pkt);
        !            24:        else if (pkt->pk_op >= MAXOP && !ISDATOP(pkt))
        !            25:                ch_free((char *)pkt);
        !            26:        else if (pkt->pk_daddr != Chmyaddr)
        !            27:                if ((++pkt->pk_fc) == 0) {
        !            28:                        debug(DPKT|DABNOR,printf("Overforwarded packet\n"));
        !            29: ignore:
        !            30:                        ch_free((char *)pkt);
        !            31:                } else if (pkt->pk_saddr == Chmyaddr) {
        !            32:                        debug(DPKT|DABNOR,printf("Got my own packet back\n"));
        !            33:                        ch_free((char *)pkt);
        !            34:                } else if (Chmyaddr == -1)
        !            35:                        ch_free((char *)pkt);
        !            36:                else {
        !            37:                        debug(DPKT,printf("Forwarding pkt daddr=%x\n", pkt->pk_daddr));
        !            38:                        sendctl(pkt);
        !            39:                }
        !            40:        else if (pkt->pk_op == MNTOP)
        !            41:                goto ignore;
        !            42:        else if (pkt->pk_op == RFCOP)
        !            43:                rcvrfc(pkt);
        !            44:        /*
        !            45:         * Check for various flavors of bad indexes
        !            46:         */
        !            47:        else if ((index = pkt->pk_dtindex) >= CHNCONNS ||
        !            48:                 ((conn = Chconntab[index]) == NOCONN) ||
        !            49:                 conn->cn_lidx != pkt->pk_didx) {
        !            50:                debug(DPKT|DABNOR,printf("Packet with bad index: %x, op:%d\n",
        !            51:                        pkt->pk_didx, pkt->pk_op));
        !            52:                send_los(pkt, "Connection doesn't exist");
        !            53:        /*
        !            54:         * Handle responses to our RFC
        !            55:         */
        !            56:        } else if (conn->cn_state == CSRFCSENT)
        !            57:                switch(pkt->pk_op) {
        !            58:                case OPNOP:
        !            59:                        debug(DCONN,printf("Conn #%x: OPEN received\n", conn->cn_lidx));
        !            60:                        /*
        !            61:                         * Make the connection open, taking his index
        !            62:                         */
        !            63:                        conn->cn_state = CSOPEN;
        !            64:                        conn->cn_fidx = pkt->pk_sidx;
        !            65:                        conn->cn_active = Chclock;
        !            66:                        /*
        !            67:                         * Indicate we have received AND "read" the OPEN
        !            68:                         * Read his window size, indicate that he has
        !            69:                         * received and acked the RFC, and acknowledge the OPN
        !            70:                         */
        !            71:                        conn->cn_rread = conn->cn_rlast = pkt->pk_pkn;
        !            72:                        conn->cn_twsize = pkt->pk_rwsize;
        !            73:                        receipt(conn, pkt->pk_ackn, pkt->pk_ackn);
        !            74:                        /*
        !            75:                         * Wakeup the user waiting for the connection to open.
        !            76:                         */
        !            77:                        makests(conn, pkt);
        !            78:                        reflect(pkt);
        !            79:                        NEWSTATE(conn);
        !            80:                        break;
        !            81:                case CLSOP:
        !            82:                case ANSOP:
        !            83:                case FWDOP:
        !            84:                        debug(DCONN,printf("Conn #%x: CLOSE/ANS received for RFC\n", conn->cn_lidx));
        !            85:                        clsconn(conn, CSCLOSED, pkt);
        !            86:                        break;
        !            87:                default:
        !            88:                        debug(DPKT|DABNOR,
        !            89:                                printf("bad packet type for conn #%x in CSRFCSENT: %d\n",
        !            90:                                        conn->cn_lidx, pkt->pk_op));
        !            91:                        send_los(pkt, "Bad packet type reponse to RFC");
        !            92:                }
        !            93:        /*
        !            94:         * Process a packet for an open connection
        !            95:         */
        !            96:        else if (conn->cn_state == CSOPEN) {
        !            97:                conn->cn_active = Chclock;
        !            98:                if (ISDATOP(pkt))
        !            99:                        rcvdata(conn, pkt);
        !           100:                else switch (pkt->pk_op) {
        !           101:                case OPNOP:
        !           102:                        /*
        !           103:                         * Ignore duplicate opens.
        !           104:                         */
        !           105:                        debug(DPKT|DABNOR,printf("Duplicate open received\n"));
        !           106:                        ch_free((char *)pkt);
        !           107:                        break;
        !           108:                case SNSOP:
        !           109:                        debug(DPKT,prpkt(pkt, "SNS"));
        !           110:                        receipt(conn, pkt->pk_ackn, pkt->pk_ackn);
        !           111:                        makests(conn, pkt);
        !           112:                        reflect(pkt);
        !           113:                        break;
        !           114:                case EOFOP:
        !           115:                        rcvdata(conn, pkt);
        !           116:                        break;
        !           117:                case LOSOP:
        !           118:                case CLSOP:
        !           119:                        debug(DCONN, printf("Close rcvd on %x\n", conn->cn_lidx));
        !           120:                        clsconn(conn, pkt->pk_op == CLSOP ? CSCLOSED : CSLOST,
        !           121:                                pkt);
        !           122:                        break;
        !           123:                        /*
        !           124:                         * Uncontrolled data - que it at the head of the rlist
        !           125:                         */
        !           126:                case UNCOP:
        !           127:                        if ((pkt->pk_next = conn->cn_rhead) == NOPKT)
        !           128:                                conn->cn_rtail = pkt;
        !           129:                        conn->cn_rhead = pkt;
        !           130:                        if (pkt == conn->cn_rtail)
        !           131:                                INPUT(conn);
        !           132:                        receipt(conn, pkt->pk_ackn, pkt->pk_ackn);
        !           133:                        break;
        !           134:                case STSOP:
        !           135:                        debug(DABNOR,prpkt(pkt, "STS"));
        !           136:                        debug(DABNOR,printf("Receipt=%d, Trans Window=%d\n",(unsigned)pkt->pk_idata[0], pkt->pk_idata[1]));
        !           137:                        if (pkt->pk_rwsize > conn->cn_twsize)
        !           138:                                OUTPUT(conn);
        !           139:                        conn->cn_twsize = pkt->pk_rwsize;
        !           140:                        receipt(conn, pkt->pk_ackn, pkt->pk_receipt);
        !           141:                        ch_free((char *)pkt);
        !           142:                        /* could check for very recent packets here */
        !           143:                        if ((pkt = conn->cn_thead) != NOPKT) {
        !           144:                                conn->cn_thead = conn->cn_ttail = NOPKT;
        !           145:                                senddata(pkt);
        !           146:                        }
        !           147:                        break;
        !           148:                default:
        !           149:                        debug(DPKT|DABNOR, printf("bad opcode:%d\n", pkt->pk_op));
        !           150:                        send_los(pkt, "Bad opcode");
        !           151:                        /* should we do clsconn here? */
        !           152:                }
        !           153:        /*
        !           154:         * Connection is neither waiting for an OPEN nor OPEN.
        !           155:         */
        !           156:        } else {
        !           157:                debug(DPKT|DABNOR,printf("Packet for conn #%x (not open) state=%d, op:%d\n", conn->cn_lidx, conn->cn_state, pkt->pk_op));
        !           158:                send_los(pkt, "Connection is closed");
        !           159:        }
        !           160: }
        !           161: 
        !           162: /*
        !           163:  * Send a control packet back to its source
        !           164:  */
        !           165: reflect(pkt)
        !           166: register struct packet *pkt;
        !           167: {
        !           168:        register short temp;
        !           169: 
        !           170:        temp = pkt->pk_sidx;
        !           171:        pkt->pk_sidx = pkt->pk_didx;
        !           172:        pkt->pk_didx = temp;
        !           173:        temp = pkt->pk_saddr;
        !           174:        pkt->pk_saddr = pkt->pk_daddr;
        !           175:        pkt->pk_daddr = temp;
        !           176:        sendctl(pkt);
        !           177: }
        !           178: 
        !           179: /*
        !           180:  * Process a received data packet - or an EOF packet which is mostly treated
        !           181:  * the same.
        !           182:  */
        !           183: rcvdata(conn, pkt)
        !           184: register struct connection *conn;
        !           185: register struct packet *pkt;
        !           186: {
        !           187:        register struct packet *npkt;
        !           188: 
        !           189:        debug(DPKT,(prpkt(pkt,"DATA"),printf("\n")) );
        !           190:        if (cmp_gt(pkt->pk_pkn, conn->cn_rread + conn->cn_rwsize)) {
        !           191:                debug(DPKT|DABNOR,printf("Discarding data out of window\n"));
        !           192:                ch_free((char *)pkt);
        !           193:                return;
        !           194:        }
        !           195:        receipt(conn, pkt->pk_ackn, pkt->pk_ackn);
        !           196:        if (cmp_le(pkt->pk_pkn, conn->cn_rlast)) {
        !           197:                debug(DPKT,printf("Duplicate data packet\n"));
        !           198:                makests(conn, pkt);
        !           199:                reflect(pkt);
        !           200:                return;
        !           201:        }
        !           202: 
        !           203:        /*
        !           204:         * Link the out of order list onto the new packet in case
        !           205:         * it fills the gap between in-order and out-of-order lists
        !           206:         * and to make it easy to grab all now-in-order packets from the
        !           207:         * out-of-order list.
        !           208:         */
        !           209:        pkt->pk_next = conn->cn_routorder;
        !           210:        /*
        !           211:         * Now transfer all in-order packets to the in-order list
        !           212:         */
        !           213:        for (npkt = pkt;
        !           214:             npkt != NOPKT &&
        !           215:                npkt->pk_pkn == (unsigned short)(conn->cn_rlast + 1);
        !           216:             npkt = npkt->pk_next) {
        !           217:                if (conn->cn_rhead == NOPKT)
        !           218:                        conn->cn_rhead = npkt;
        !           219:                else
        !           220:                        conn->cn_rtail->pk_next = npkt;
        !           221:                conn->cn_rtail = npkt;
        !           222:                conn->cn_rlast++;
        !           223:        
        !           224:        }
        !           225:        /*
        !           226:         * If we queued up any in-order pkts, check if spontaneous STS is needed
        !           227:         */
        !           228:        if (pkt != npkt) {
        !           229:                debug(DPKT,printf("new ordered data packet\n"));
        !           230:                conn->cn_rtail->pk_next = NOPKT;
        !           231:                conn->cn_routorder = npkt;
        !           232:                if (conn->cn_rhead == pkt)
        !           233:                        INPUT(conn);
        !           234:                /*
        !           235:                 * If we are buffering "many" packets, keep him up to date
        !           236:                 * about the window. The second test can be flushed if it is
        !           237:                 * more important to receipt than to save sending an "extra"
        !           238:                 * STS with no new acknowledgement.
        !           239:                 * Lets do without it for a while.
        !           240:                if ((short)(conn->cn_rlast - conn->cn_racked) > conn->cn_rsts &&
        !           241:                    conn->cn_racked != conn->cn_rread)
        !           242:                        sendsts(conn);
        !           243:                 */
        !           244:        /*
        !           245:         * Here we have received an out of order packet which must be
        !           246:         * inserted into the out-of-order queue, in packet number order. 
        !           247:         */
        !           248:        } else {
        !           249:                for (npkt = pkt; (npkt = npkt->pk_next) != NOPKT &&
        !           250:                                 cmp_gt(pkt->pk_pkn, npkt->pk_pkn); )
        !           251:                        pkt->pk_next = npkt;    /* save the last pkt here */
        !           252:                if (npkt != NOPKT && pkt->pk_pkn == npkt->pk_pkn) {
        !           253:                        debug(DPKT|DABNOR,
        !           254:                                printf("Duplicate out of order packet\n"));
        !           255:                        pkt->pk_next = NOPKT;
        !           256:                        makests(conn, pkt);
        !           257:                        reflect(pkt);
        !           258:                } else {
        !           259:                        if (npkt == conn->cn_routorder)
        !           260:                                conn->cn_routorder = pkt;
        !           261:                        else
        !           262:                                pkt->pk_next->pk_next = pkt;
        !           263:                        pkt->pk_next = npkt;
        !           264:                        debug(DPKT|DABNOR,
        !           265:                                printf("New out of order packet\n"));
        !           266:                }
        !           267:        }
        !           268: }
        !           269: 
        !           270: /*
        !           271:  * Make a STS packet for a connection, reflecting its current state
        !           272:  */
        !           273: makests(conn, pkt) 
        !           274: register struct connection *conn;
        !           275: register struct packet *pkt;
        !           276: {
        !           277:        pkt->pk_op = STSOP;
        !           278:        pkt->pk_lenword = sizeof(struct sts_data);
        !           279:        pkt->pk_ackn = conn->cn_racked = conn->cn_rread;
        !           280:        pkt->pk_receipt = conn->cn_rlast;
        !           281:        pkt->pk_rwsize = conn->cn_rwsize;
        !           282: }
        !           283: 
        !           284: /*
        !           285:  * Process receipts and acknowledgements using recnum as the receipt.
        !           286:  */
        !           287: receipt(conn, acknum, recnum)
        !           288: register struct connection *conn;
        !           289: unsigned short acknum, recnum;
        !           290: {
        !           291:        register struct packet *pkt, *pktl;
        !           292: 
        !           293:        /*
        !           294:         * Process a receipt, freeing packets that we now know have been
        !           295:         * received.
        !           296:         */
        !           297:        if (cmp_gt(recnum, conn->cn_trecvd)) {
        !           298:                for (pktl = conn->cn_thead;
        !           299:                     pktl != NOPKT && cmp_le(pktl->pk_pkn, recnum);
        !           300:                     pktl = pkt) {
        !           301:                        pkt = pktl->pk_next;
        !           302:                        ch_free((char *)pktl);
        !           303:                }
        !           304:                if ((conn->cn_thead = pktl) == NOPKT)
        !           305:                        conn->cn_ttail = NOPKT;
        !           306:                conn->cn_trecvd = recnum;
        !           307:        }
        !           308:        /*
        !           309:         * If the acknowledgement is new, update our idea of the
        !           310:         * latest acknowledged packet, and wakeup output that might be blocked
        !           311:         * on a full transmit window.
        !           312:         */
        !           313:        if (cmp_gt(acknum, conn->cn_tacked))
        !           314:                if (cmp_gt(acknum, conn->cn_tlast))
        !           315:                        debug(DABNOR, (printf("Invalid acknowledgment(%d,%d)\n",
        !           316:                                acknum, conn->cn_tlast)));
        !           317:                else {
        !           318:                        conn->cn_tacked = acknum;
        !           319:                        OUTPUT(conn);
        !           320:                }
        !           321: }
        !           322: 
        !           323: /*
        !           324:  * Send a LOS in response to the given packet.
        !           325:  * Don't bother if the packet is itself a LOS or a CLS since the other
        !           326:  * end doesn't care anyway and would only return it again.
        !           327:  * Append the host name to the error message.
        !           328:  */
        !           329: sendlos(pkt, str, len)
        !           330: register struct packet *pkt;
        !           331: char *str;
        !           332: {
        !           333:        if (pkt->pk_op == LOSOP || pkt->pk_op == CLSOP)
        !           334:                ch_free((char *)pkt);
        !           335:        else {
        !           336:                register char *cp;
        !           337:                register int length;
        !           338:                
        !           339:                for (cp = Chmyname, length = 0; *cp && length < CHSTATNAME;) {
        !           340:                        length++;
        !           341:                        cp++;
        !           342:                }
        !           343:                if (pkt = pktstr(pkt, str, len + length + sizeof("(from )") - 1)) {
        !           344:                        chmove("(from ", &pkt->pk_cdata[len], 6);
        !           345:                        chmove(Chmyname, &pkt->pk_cdata[len + 6], length);
        !           346:                        chmove(")", &pkt->pk_cdata[len + 6 + length], 1);
        !           347:                        pkt->pk_op = LOSOP;
        !           348:                        reflect(pkt);
        !           349:                }
        !           350:        }
        !           351: }
        !           352: 
        !           353: /*
        !           354:  * Process a received RFC
        !           355:  */
        !           356: rcvrfc(pkt)
        !           357: register struct packet *pkt;
        !           358: {
        !           359:        register struct connection *conn, **conptr;
        !           360:        struct packet **opkt, *pktl;
        !           361: 
        !           362:        debug(DPKT,prpkt(pkt,"RFC"));
        !           363:        debug(DPKT,printf("contact = %s\n", pkt->pk_cdata));
        !           364:        /*
        !           365:         * Check if this is a duplicate RFC, and if so throw it away,
        !           366:         * and retransmit the OPEN.
        !           367:         */
        !           368:        for (conptr = &Chconntab[0]; conptr < &Chconntab[CHNCONNS];)
        !           369:                if ((conn = *conptr++) != NOCONN &&
        !           370:                    conn->cn_fidx == pkt->pk_sidx &&
        !           371:                    conn->cn_faddr == pkt->pk_saddr) {
        !           372:                        if (conn->cn_state == CSOPEN) {
        !           373:                                debug(DPKT|DABNOR,
        !           374:                                        printf("Rcvrfc: Retransmitting open chan #%x\n", (*conptr)->cn_lidx));
        !           375:                                sendopn(conn);
        !           376:                        } else {
        !           377:                                debug(DPKT|DABNOR,
        !           378:                                        printf("Rcvrfc: Duplicate RFC: %x\n",
        !           379:                                                conn->cn_lidx));
        !           380:                        }
        !           381:                        ch_free((char *)pkt);
        !           382:                        return;
        !           383:                }
        !           384:        /*
        !           385:         * Scan the listen list for a listener and if one is found
        !           386:         * open the connection and remove the listen packet from the
        !           387:         * listen list.
        !           388:         */
        !           389:        for (opkt = &Chlsnlist; (pktl = *opkt) != NOPKT; opkt = &pktl->pk_next)
        !           390:                if(concmp(pkt, pktl->pk_cdata, (int)pktl->pk_len)) {
        !           391:                        conn = Chconntab[pktl->pk_stindex];
        !           392:                        *opkt = pktl->pk_next;
        !           393:                        ch_free((char *)pktl);
        !           394:                        lsnmatch(pkt, conn);
        !           395:                        NEWSTATE(conn);
        !           396:                        return;
        !           397:                }
        !           398:        if (concmp(pkt, "STATUS", 6)) {
        !           399:                statusrfc(pkt);
        !           400:                return;
        !           401:        }
        !           402:        if (concmp(pkt, "TIME", 4)) {
        !           403:                timerfc(pkt);
        !           404:                return;
        !           405:        }
        !           406:        if (Chrfcrcv == 0) {
        !           407:                send_los(pkt, "All servers disabled");
        !           408:                return;
        !           409:        }
        !           410:        /*
        !           411:         * There was no listener, so queue the RFC on the unmatched RFC list
        !           412:         * again checking for duplicates.
        !           413:         */
        !           414:        pkt->pk_ackn = 0;       /* this is for ch_rskip, in chuser.c */
        !           415:        pkt->pk_next = NOPKT;
        !           416:        if ((pktl = Chrfclist) == NOPKT) 
        !           417:                Chrfclist = Chrfctail = pkt;
        !           418:        else {
        !           419:                do {
        !           420:                        if(pktl->pk_sidx == pkt->pk_sidx &&
        !           421:                           pktl->pk_saddr == pkt->pk_saddr) {
        !           422:                                debug(DPKT/*|DABNOR*/,printf("Rcvrfc: Discarding duplicate Rfc on Chrfclist\n"));
        !           423:                                ch_free((char *)pkt);
        !           424:                                return;
        !           425:                        }
        !           426:                } while ((pktl = pktl->pk_next) != NOPKT);
        !           427:                Chrfctail->pk_next = pkt;
        !           428:                Chrfctail = pkt;
        !           429:        }
        !           430:        debug(DCONN,printf("Rcvrfc: Queued Rfc on Chrfclist: '%c%c%c%c'\n",
        !           431:                pkt->pk_cdata[0], pkt->pk_cdata[1], pkt->pk_cdata[2],
        !           432:                pkt->pk_cdata[3]));
        !           433:        RFCINPUT;
        !           434: }
        !           435: /*
        !           436:  * An RFC has matched a listener, either by an RFC coming and finding a match
        !           437:  * on the listener list, or by a listen being done and matching an RFC on the
        !           438:  * unmatched RFC list. So we change the state of the connection to CSRFCRCVD
        !           439:  */
        !           440: lsnmatch(rfcpkt, conn)
        !           441: register struct packet *rfcpkt;
        !           442: register struct connection *conn;
        !           443: {
        !           444:        debug(DCONN,printf("Conn #%x: LISTEN matched \n", conn->cn_lidx));
        !           445:        /*
        !           446:         * Initialize the conection
        !           447:         */
        !           448:        conn->cn_active = Chclock;
        !           449:        conn->cn_state = CSRFCRCVD;
        !           450:        conn->cn_rwsize = CHDRWSIZE;
        !           451:        conn->cn_faddr = rfcpkt->pk_saddr;
        !           452:        conn->cn_fidx = rfcpkt->pk_sidx;
        !           453:        /*
        !           454:         * Queue up the RFC for the user to read if he wants it.
        !           455:         */
        !           456:        rfcpkt->pk_next = NOPKT;
        !           457:        conn->cn_rhead = conn->cn_rtail = rfcpkt;
        !           458:        /*
        !           459:         * Indicate to the other end that we have received and "read"
        !           460:         * the RFC so that the open will truly acknowledge it.
        !           461:         */
        !           462:        conn->cn_rlast = conn->cn_rread = rfcpkt->pk_pkn;
        !           463: }
        !           464: /*
        !           465:  * Remove a listener from the listener list, due to the listener bailing out.
        !           466:  * Called from top level at high priority
        !           467:  */
        !           468: rmlisten(conn)
        !           469: register struct connection *conn;
        !           470: {
        !           471:        register struct packet *opkt, *pkt;
        !           472: 
        !           473:        opkt = NOPKT;
        !           474:        for (pkt = Chlsnlist; pkt != NOPKT; opkt = pkt, pkt = pkt->pk_next)
        !           475:                if (pkt->pk_stindex == conn->cn_ltidx) {
        !           476:                        if(opkt == NOPKT)
        !           477:                                Chlsnlist = pkt->pk_next;
        !           478:                        else
        !           479:                                opkt->pk_next = pkt->pk_next;
        !           480:                        ch_free((char *)pkt);
        !           481:                        break;
        !           482:                }
        !           483: }
        !           484: /*
        !           485:  * Compare the RFC contact name with the listener name.
        !           486:  */
        !           487: concmp(rfcpkt, lsnstr, lsnlen)
        !           488: struct packet *rfcpkt;
        !           489: register char *lsnstr;
        !           490: register int lsnlen;
        !           491: {
        !           492:        register char *rfcstr = rfcpkt->pk_cdata;
        !           493:        register int rfclen;
        !           494: 
        !           495:        debug(DPKT,printf("Rcvrfc: Comparing %s and %s\n", rfcstr, lsnstr));
        !           496:        for (rfclen = rfcpkt->pk_len; rfclen; rfclen--, lsnlen--)
        !           497:                if (lsnlen <= 0)
        !           498:                        return ((*rfcstr == ' ') ? 1 : 0);
        !           499:                else if (*rfcstr++ != *lsnstr++)
        !           500:                        return(0);
        !           501:        return (lsnlen == 0);
        !           502: }
        !           503: /*
        !           504:  * Process a routing packet.
        !           505:  */
        !           506: rcvrut(pkt)
        !           507: struct packet *pkt;
        !           508: {
        !           509:        register int i;
        !           510:        register struct rut_data *rd;
        !           511:        register struct chroute *r;
        !           512: 
        !           513:        debug(DPKT, ( prpkt(pkt,"RUT"),printf("\n") ) );
        !           514:        rd = pkt->pk_rutdata;
        !           515:        if (pkt->pk_ssubnet >= CHNSUBNET)
        !           516:                printf("CHAOS: bad subnet %d in RUT pkt\n", pkt->pk_ssubnet);
        !           517:        else if (Chroutetab[pkt->pk_ssubnet].rt_type != CHDIRECT)
        !           518:                printf("CHAOS: RUT pkt from unconnected subnet %d\n",
        !           519:                        pkt->pk_ssubnet);
        !           520:        else for (i = pkt->pk_len; i; i -= sizeof(struct rut_data), rd++) {
        !           521:                if (rd->pk_subnet >= CHNSUBNET) {
        !           522:                        debug(DABNOR, printf("CHAOS: bad subnet %d in RUT pkt\n",
        !           523:                                rd->pk_subnet));
        !           524:                        continue;
        !           525:                }
        !           526:                r = &Chroutetab[rd->pk_subnet];
        !           527:                switch (r->rt_type) {
        !           528:                case 0:
        !           529:                case CHBRIDGE:
        !           530:                        if (rd->pk_cost <= r->rt_cost) {
        !           531:                                r->rt_cost = rd->pk_cost;
        !           532:                                r->rt_type = CHBRIDGE;
        !           533:                                r->rt_addr = pkt->pk_saddr;
        !           534:                        }
        !           535:                        break;
        !           536:                case CHDIRECT:
        !           537:                case CHFIXED:
        !           538:                        break;
        !           539:                default:
        !           540:                        printf("CHAOS: Illegal chaos routing table entry %d",
        !           541:                                r->rt_type);
        !           542:                }
        !           543:        }
        !           544:        ch_free((char *)pkt);
        !           545: }
        !           546: 
        !           547: /*
        !           548:  * process a RFC for contact name STATUS
        !           549:  */
        !           550: statusrfc(rpkt)
        !           551: register struct packet *rpkt;
        !           552: {
        !           553:        register struct packet *pkt;
        !           554:        register struct chroute *r;
        !           555:        register struct chxcvr *xp;
        !           556:        register struct statdata *sp;
        !           557:        register int i;
        !           558: 
        !           559:        for (i = 0, r = Chroutetab; r < &Chroutetab[CHNSUBNET]; r++)
        !           560:                if (r->rt_type == CHDIRECT)
        !           561:                        i++;
        !           562:        i *= sizeof(struct stathead) + sizeof(struct statxcvr);
        !           563:        i += CHSTNAME;
        !           564:        if ((pkt = pkalloc(i, 1)) == NOPKT) {
        !           565:                ch_free((char *)rpkt);
        !           566:                return;
        !           567:        }
        !           568:        pkt->pk_daddr = rpkt->pk_saddr;
        !           569:        pkt->pk_didx = rpkt->pk_sidx;
        !           570:        ch_free((char *)rpkt);
        !           571:        pkt->pk_type = 0;
        !           572:        pkt->pk_op = ANSOP;
        !           573:        pkt->pk_next = NOPKT;
        !           574:        pkt->pk_saddr = Chmyaddr;
        !           575:        pkt->pk_sidx = pkt->pk_pkn = pkt->pk_ackn = 0;
        !           576:        pkt->pk_lenword = i;
        !           577:        chmove(Chmyname, pkt->pk_status.sb_name, CHSTATNAME);
        !           578:        sp = &pkt->pk_status.sb_data[0];
        !           579:        for (r = Chroutetab; r < &Chroutetab[CHNSUBNET]; r++)
        !           580:                if (r->rt_type == CHDIRECT) {
        !           581:                        xp = r->rt_xcvr;
        !           582:                        sp->sb_ident = 0400 + xp->xc_subnet;
        !           583:                        sp->sb_nshorts = sizeof(struct statxcvr) / sizeof(short);
        !           584:                        sp->sb_xstat = xp->xc_xstat;
        !           585: #ifdef pdp11
        !           586:                        swaplong(&sp->sb_xstat,
        !           587:                                sizeof(struct statxcvr) / sizeof(long));
        !           588: #endif
        !           589:                        sp = (struct statdata *)((char *)sp +
        !           590:                                sizeof(struct stathead) +
        !           591:                                sizeof(struct statxcvr));
        !           592:                }
        !           593:        sendctl(pkt);
        !           594: }
        !           595: 
        !           596: /*
        !           597:  * process a RFC for contact name TIME 
        !           598:  */
        !           599: timerfc(pkt)
        !           600: register struct packet *pkt;
        !           601: {
        !           602:        long t;
        !           603: 
        !           604:        pkt->pk_op = ANSOP;
        !           605:        pkt->pk_next = NOPKT;
        !           606:        pkt->pk_pkn = pkt->pk_ackn = 0;
        !           607:        pkt->pk_lenword = sizeof(long);
        !           608:        ch_time(&t);
        !           609:        pkt->pk_ldata[0] = t;
        !           610: #ifdef pdp11
        !           611:                swaplong(&pkt->pk_ldata, 1);
        !           612: #endif pdp11
        !           613:        reflect(pkt);
        !           614: }
        !           615: #ifdef DEBUG
        !           616: prpkt(pkt, str)
        !           617: register struct packet *pkt;
        !           618: char *str;
        !           619: {
        !           620:        printf("op=%s(%o) len=%d fc=%d\ndhost=%o didx=%x\nshost=%o sidx=%x\npkn=%d ackn=%d ",
        !           621:                str, pkt->pk_op, pkt->pk_len, pkt->pk_fc, pkt->pk_dhost,
        !           622:                pkt->pk_didx, pkt->pk_shost, pkt->pk_sidx,
        !           623:                (unsigned)pkt->pk_pkn, (unsigned)pkt->pk_ackn);
        !           624: }
        !           625: #endif

unix.superglobalmegacorp.com

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