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