Annotation of researchv10no/ipc/mgrs/nonetmgr/main.c, revision 1.1.1.1

1.1       root        1: #include <sys/param.h>
                      2: #include <sys/enio.h>
                      3: #include <sys/filio.h>
                      4: #include <errno.h>
                      5: #include <ipc.h>
                      6: #include <signal.h>
                      7: 
                      8: typedef unsigned char uchar;
                      9: 
                     10: /*
                     11:  *  one structure per fd to decide what to do with
                     12:  *  input on the fd.
                     13:  */
                     14: typedef struct {
                     15:        void (*func)();         /* function to call */
                     16:        void *ptr;
                     17: } Fdesc;
                     18: Fdesc f[NOFILE];
                     19: 
                     20: /*
                     21:  *  bit mask of fds to listen on
                     22:  */
                     23: fd_set master;
                     24: int etherfd;
                     25: 
                     26: /*
                     27:  *  name to address translation
                     28:  */
                     29: typedef struct Address {
                     30:        char *name;
                     31:        uchar addr[6];
                     32:        int ack;
                     33: } Address;
                     34: Address addr[] = {
                     35:        { "ross",       0x02, 0x07, 0x01, 0x00, 0x5e, 0xff,     0 },
                     36:        { "research",   0x02, 0x07, 0x01, 0x00, 0x62, 0x8a,     1 },
                     37:        { "ara",        0x08, 0x00, 0x47, 0x00, 0x09, 0xfa,     1 },
                     38:        { "shamash",    0x08, 0x00, 0x20, 0x01, 0x37, 0x78,     1 },
                     39:        { "ra",         0x08, 0x00, 0x20, 0x01, 0x34, 0x13,     1 },
                     40:        { "aten",       0x08, 0x00, 0x20, 0x01, 0x3b, 0x74,     1 },
                     41:        { "pipe",       0x08, 0x00, 0x2b, 0x09, 0x57, 0x94,     1 },
                     42:        { "sol",        0x08, 0x00, 0x20, 0x01, 0x64, 0xab,     1 },
                     43:        { "bowell",     0x08, 0x00, 0x2b, 0x0b, 0xce, 0xda,     1 },
                     44:        { "pyxis",      0x08, 0x00, 0x69, 0x02, 0x01, 0x4e,     1 },
                     45:        { "r70",        0x08, 0x00, 0x2b, 0x04, 0x26, 0x5d,     1 },
                     46:        { "nun",        0x08, 0x00, 0x20, 0x00, 0x24, 0xc4,     1 },
                     47:        { "wild",       0x02, 0x07, 0x01, 0x00, 0x4e, 0x05,     1 },
                     48:        { "coma",       0x08, 0x00, 0x2b, 0x0b, 0x1d, 0x9b,     1 },
                     49:        { "tempel",     0x02, 0xcf, 0x1f, 0x11, 0x73, 0x13,     1 },
                     50:        { "bootes",     0x08, 0x00, 0x69, 0x02, 0x02, 0x05,     0 },
                     51:        { "helix",      0x08, 0x00, 0x69, 0x02, 0x04, 0x27,     1 },
                     52:        { "spindle",    0x08, 0x00, 0x69, 0x02, 0x01, 0x9e,     1 },
                     53:        { "hr4784",     0x00, 0x00, 0xa7, 0x00, 0x08, 0x28,     1 },
                     54:        { 0 }
                     55: };
                     56: 
                     57: /*
                     58:  *  ethernet header
                     59:  */
                     60: typedef struct Etherhdr {
                     61:        uchar   d[6];
                     62:        uchar   s[6];
                     63:        uchar   type[2];
                     64:        uchar   circuit[3];     /* circuit number */
                     65:        uchar   flag;
                     66:        uchar   mid;            /* message id */
                     67:        uchar   ack;            /* piggy back ack */
                     68:        uchar   remain[2];      /* count of remaing bytes of data */
                     69:        uchar   sum[2];         /* checksum (0 means none) */
                     70: } Etherhdr;
                     71: 
                     72: /*
                     73:  *  ethernet packet
                     74:  */
                     75: typedef struct Ethermsg {
                     76:        uchar   d[6];
                     77:        uchar   s[6];
                     78:        uchar   type[2];
                     79:        uchar   circuit[3];     /* circuit number */
                     80:        uchar   flag;
                     81:        uchar   mid;            /* message id */
                     82:        uchar   ack;            /* piggy back ack */
                     83:        uchar   remain[2];      /* count of remaing bytes of data */
                     84:        uchar   sum[2];         /* checksum (0 means none) */
                     85:        uchar   data[1500 - 10];
                     86: } Ethermsg;
                     87: #define HDRSIZE 24
                     88: #define NEWCALL        0x1             /* flag bit marking a new circuit */
                     89: #define HANGUP 0x2             /* flag bit requesting hangup */
                     90: #define ACKME 0x4              /* acknowledge this message */
                     91: #define ETHER_TYPE 0x9         /* most significant byte last */
                     92: 
                     93: char *dev[] = {
                     94:        "/dev/qe02",
                     95:        "/dev/il02",
                     96:        "/dev/bna02",
                     97:        0,
                     98: };
                     99: 
                    100: /*
                    101:  *  nonet conversations
                    102:  */
                    103: #define NCIRC (NOFILE/2)
                    104: #define MAXMSG (8*1024+100)
                    105: typedef struct Circuit {
                    106:        Fdesc   *f;
                    107:        int     hangingup;
                    108:        int     hungup;
                    109:        int     version;
                    110: 
                    111:        uchar   rcved;          /* last msg rcved */
                    112:        int     mid;            /* id of current input message */
                    113:        int     rem;            /* remaining bytes for input current message */
                    114:        int     rcvcircuit;     /* circuit number of incoming packets */
                    115:        uchar   ibuf[MAXMSG];
                    116:        int     ibi;
                    117:        int     eofs;
                    118: 
                    119:        uchar   sent;           /* last msg sent */
                    120:        uchar   ackrcved;       /* last ack received */
                    121:        int     resent;         /* number of times a message is transmitted */
                    122:        Etherhdr eh;            /* prototype ethernet header */
                    123:        uchar   obuf[MAXMSG];
                    124:        int     obi;
                    125: } Circuit;
                    126: Circuit circ[NCIRC];
                    127: 
                    128: void announce();
                    129: void openether();
                    130: void newcall();
                    131: void fromclient();
                    132: void fromether();
                    133: void timeout();
                    134: void fillhdr();
                    135: void send();
                    136: void hangup();
                    137: void ack();
                    138: void resend();
                    139: void ackdead();
                    140: 
                    141: int debug;
                    142: 
                    143: main(ac, av)
                    144:        int ac;
                    145:        char *av[];
                    146: {
                    147:        fd_set set;
                    148:        int fds;
                    149:        int i;
                    150: 
                    151:        debug = 0;
                    152:        if(ac > 1 && strcmp(av[1], "-d")==0)
                    153:                debug = 1;
                    154:        chdir("/cs");
                    155:        FD_ZERO(master);
                    156:        if(!debug)
                    157:                detach("nonet");
                    158:        announce();
                    159:        openether();
                    160:        signal(SIGPIPE, SIG_IGN);
                    161:        for(;;){
                    162:                /*
                    163:                 *  keep polling the fds for input.  call an
                    164:                 *  fd's input routine whenever it has any input.
                    165:                 */
                    166:                set = master;
                    167:                switch(fds = select(NOFILE, &set, 0, 1000)){
                    168:                case -1:
                    169:                        logevent("switch returned -1");
                    170:                        exit(1);
                    171:                case 0:
                    172:                        timeout();
                    173:                        continue;
                    174:                }
                    175:                for(i = 0; fds && i < NOFILE; i++){
                    176:                        if(FD_ISSET(i, set)) {
                    177:                                fds--;
                    178:                                if(f[i].func != 0)
                    179:                                        (*f[i].func)(i);
                    180:                                else {
                    181:                                        logevent("io on bad fd %d\n", i);
                    182:                                        FD_CLR(i, master);
                    183:                                        close(i);
                    184:                                }
                    185:                        }
                    186:                }
                    187:        }
                    188: }
                    189: 
                    190: /*
                    191:  *  set up a connected pair of fd's to listen on.
                    192:  *  if fd2 < 0, then there is only 1 fd.
                    193:  */
                    194: newf(fd, func)
                    195:        int fd;
                    196:        void (*func)();
                    197: {
                    198:        f[fd].func = func;
                    199:        FD_SET(fd, master);
                    200: }
                    201: 
                    202: /*
                    203:  *  close an fd, stop listening to it, and close off it's related fd.
                    204:  */
                    205: delf(fd)
                    206:        int fd;
                    207: {
                    208:        if(fd < 0)
                    209:                return;
                    210:        if(f[fd].func == 0)
                    211:                return;
                    212:        f[fd].func = 0;
                    213:        close(fd);
                    214:        FD_CLR(fd, master);
                    215: }
                    216: 
                    217: /*
                    218:  *  plug into the name space
                    219:  */
                    220: void
                    221: announce()
                    222: {
                    223:        int fd;
                    224: 
                    225:        fd = ipccreat("/cs/nonet", "");
                    226:        if(fd<0){
                    227:                logconsole("error announcing /cs/nonet\n");
                    228:                exit(1);
                    229:        }
                    230:        newf(fd, newcall);
                    231:        logconsole("/cs/nonet announced\n");
                    232: }
                    233: 
                    234: /*
                    235:  *  listen to the nonet ether type
                    236:  */
                    237: void
                    238: openether()
                    239: {
                    240:        int fd;
                    241:        int i;
                    242:        extern int buf_ld;
                    243: 
                    244:        for(i = 0; dev[i]; i++){
                    245:                fd = open(dev[i], 2);
                    246:                if(fd >= 0)
                    247:                        break;
                    248:        }
                    249:        if(fd < 0){
                    250:                logevent("opening ethernet device\n");
                    251:                exit(1);
                    252:        }
                    253:        i = ETHER_TYPE;
                    254:        if(ioctl(fd, ENIOTYPE, &i) < 0){
                    255:                perror("ENIOTYPE");
                    256:                exit(1);
                    257:        }
                    258:        newf(fd, fromether);
                    259:        etherfd = fd;
                    260:        if(ioctl(etherfd, FIOPUSHLD, &buf_ld)<0){
                    261:                perror("pushing buf_ld");
                    262:        }
                    263:        if(ioctl(etherfd, FIOPUSHLD, &buf_ld)<0){
                    264:                perror("pushing buf_ld");
                    265:        }
                    266: }
                    267: 
                    268: /*
                    269:  *  there is input on the announcement channel.  see if a
                    270:  *  new call has come in.
                    271:  */
                    272: void
                    273: newcall(fd)
                    274:        int fd;
                    275: {
                    276:        ipcinfo *ipc;
                    277:        Circuit *cp;
                    278:        Address *a;
                    279:        int circuit;
                    280:        int nfd;
                    281:        char *service;
                    282:        char *strchr();
                    283: 
                    284:        logevent("newcall\n");
                    285:        ipc = ipclisten(fd);
                    286:        if(ipc == 0){
                    287:                logevent("listening %s\n", errstr);
                    288:                return;
                    289:        }
                    290: 
                    291:        /*
                    292:         *  Find a new circuit for the call.
                    293:         */
                    294:        for(cp = circ; cp < &circ[NCIRC]; cp++){
                    295:                if(cp->f == 0)
                    296:                        break;
                    297:        }
                    298:        if(cp == &circ[NCIRC]){
                    299:                logevent("call from %s!%s busy\n", ipc->machine, ipc->user);
                    300:                ipcreject(ipc, EBUSY, "out of output channels");
                    301:                return;
                    302:        }
                    303:        logevent("call from %s!%s on %d\n", ipc->machine, ipc->user, cp - circ);
                    304: 
                    305:        /*
                    306:         * separate name and service
                    307:         */
                    308:        service = strchr(ipc->name, '.');
                    309:        if(service)
                    310:                *service++ = 0;
                    311:        else{
                    312:                service = strchr(ipc->name, '!');
                    313:                if(service)
                    314:                        *service++ = 0;
                    315:        }
                    316:        if(service==0)
                    317:                service = "";
                    318: 
                    319:        /*
                    320:         *  see if we know the destination
                    321:         */
                    322:        for(a = addr; a->name; a++){
                    323:                if(strcmp(a->name, ipc->name) == 0)
                    324:                        break;
                    325:        }
                    326:        if(a->name == 0){
                    327:                logevent("call from %s!%s, %s!%s unknown dest\n", ipc->machine, ipc->user,
                    328:                        ipc->name, service);
                    329:                ipcreject(ipc, EEXIST, "unknown destination");
                    330:                return;
                    331:        }
                    332:        nfd = ipcaccept(ipc);
                    333:        if(nfd < 0){
                    334:                logevent("call from %s!%s error accepting\n", ipc->machine, ipc->user);
                    335:                return;
                    336:        }
                    337:        logevent("call from %s!%s to %s!%s accepted\n", ipc->machine, ipc->user, ipc->name,
                    338:                service);
                    339: 
                    340:        /*
                    341:         *  init the circuit
                    342:         */
                    343:        f[nfd].ptr = (void *)cp;
                    344:        cp->f = &f[nfd];
                    345:        cp->hangingup = 0;
                    346:        cp->hungup = 0;
                    347:        cp->eofs = 0;
                    348:        cp->ackrcved = 0;
                    349:        cp->sent = 0;
                    350:        cp->ibi = 0;
                    351:        cp->obi = 0;
                    352:        cp->rcved = 0;
                    353:        cp->mid = 0;
                    354:        circuit = 2*((cp - circ)+cp->version*NCIRC);
                    355:        cp->rcvcircuit = circuit+1;
                    356:        cp->version++;
                    357:        if(a->ack)
                    358:                cp->eh.flag = NEWCALL|ACKME;
                    359:        else
                    360:                cp->eh.flag = NEWCALL;
                    361:        cp->eh.circuit[2] = circuit>>16;
                    362:        cp->eh.circuit[1] = circuit>>8;
                    363:        cp->eh.circuit[0] = circuit;
                    364:        memcpy(cp->eh.d, a->addr, sizeof(a->addr));
                    365:        cp->eh.type[1] = ETHER_TYPE>>8;
                    366:        cp->eh.type[0] = ETHER_TYPE;
                    367:        newf(nfd, fromclient);
                    368: 
                    369:        if(strcmp(service, "bootfs") == 0){
                    370:                /*
                    371:                 *  send ok to the caller
                    372:                 */
                    373:                write(nfd, "OK", 2);
                    374:        } else  if(strcmp(service, "fs") != 0){
                    375:                /*
                    376:                 *  send user id
                    377:                 */
                    378:                sprint(cp->obuf, "%s %s", ipc->user, service);
                    379:                cp->obi += strlen(cp->obuf);
                    380:                send(cp);
                    381:        }
                    382: }
                    383: 
                    384: /*
                    385:  *  input from the ethernet
                    386:  */
                    387: void
                    388: fromether(fd)
                    389:        int fd;
                    390: {
                    391:        int len;
                    392:        short r;
                    393:        int c;
                    394:        Circuit *cp;
                    395:        Ethermsg em;
                    396:        int hungup;
                    397: 
                    398:        /*
                    399:         *  read/parse an ethernet message
                    400:         */
                    401:        len = read(fd, &em, sizeof(Ethermsg));
                    402:        if(len <= 0){
                    403:                logevent("error reading from ether\n");
                    404:                return;
                    405:        }
                    406:        if(debug)
                    407:                printpacket("in", &em);
                    408:        r = (em.remain[1]<<8) | em.remain[0];
                    409:        c = (em.circuit[2]<<16) | (em.circuit[1]<<8) | em.circuit[0];
                    410:        hungup = em.flag & HANGUP;
                    411:        
                    412:        /*
                    413:         *  look for an existing client
                    414:         */
                    415:        for(cp = circ; cp < &circ[NCIRC]; cp++){
                    416:                if(cp->f && c == cp->rcvcircuit
                    417:                && memcmp(cp->eh.d, em.s, sizeof(em.s)) == 0)
                    418:                        break;
                    419:        }
                    420:        if(cp == &circ[NCIRC]) {
                    421:                logevent("no client found\n");
                    422:                ackdead(&em);
                    423:                return;
                    424:        }
                    425: 
                    426:        len -= HDRSIZE;
                    427:        if(r>=0){
                    428:                /*
                    429:                 *  a new message, forget any old messages
                    430:                 */
                    431:                cp->ibi = 0;
                    432:                cp->mid = em.mid;
                    433:                cp->rem = r;
                    434:        } else {
                    435:                /*
                    436:                 *  a continuation
                    437:                 */
                    438:                if(cp->mid != em.mid || -r != cp->rem) {
                    439:                        /* bad fragment -- drop anything ibuffered */
                    440:                        logevent("cp->mid %d em.mid %d r %d cp->rem %d\n", cp->mid, em.mid,
                    441:                                r, cp->rem);
                    442:                        cp->ibi = 0;
                    443:                        return;
                    444:                }
                    445:        }
                    446:        cp->rem -= len;
                    447: 
                    448:        /*
                    449:         *  last packet may be ``padded out''.  adjust size if it is.
                    450:         */
                    451:        if(cp->rem < 0){
                    452:                if(-cp->rem <= len){
                    453:                        len += cp->rem;
                    454:                        cp->rem = 0;
                    455:                } else {
                    456:                        logevent("short packet\n");
                    457:                        return;
                    458:                }
                    459:        }
                    460: 
                    461:        /*
                    462:         *  copy the packet into the buffer
                    463:         */
                    464:        memcpy(&(cp->ibuf[cp->ibi]), em.data, len);
                    465:        cp->ibi += len;
                    466: 
                    467:        /*
                    468:         *  if last packet of a message...
                    469:         */
                    470:        if(cp->rem == 0){
                    471:                /*
                    472:                 * ... is it what we expected?
                    473:                 */
                    474:                if(((cp->rcved+1)&0xff) != cp->mid){
                    475:                        if(cp->rcved == cp->mid){
                    476:                                cp->ackrcved = em.ack;
                    477:                                if(cp->ibi)
                    478:                                        ack(cp);                /* retransmission */
                    479:                                fd = cp->f - f;
                    480:                                if(cp->ackrcved == cp->sent && f[fd].func)
                    481:                                        FD_SET(fd, master);
                    482:                                return;
                    483:                        }
                    484:                        logevent("expected %d got %d\n", (cp->rcved+1)&0xff,  cp->mid);
                    485:                        cp->ibi = 0;
                    486:                        return;
                    487:                }
                    488:                /*
                    489:                 *  ... update state and send packet to client
                    490:                 */
                    491:                cp->eh.flag &= ~NEWCALL;
                    492:                cp->rcved = cp->mid;
                    493:                cp->ackrcved = em.ack;
                    494:                fd = cp->f - f;
                    495:                if(cp->ackrcved == cp->sent && f[fd].func)
                    496:                        FD_SET(fd, master);
                    497:                if(cp->ibi && write(fd, cp->ibuf, cp->ibi) != cp->ibi){
                    498:                        logevent("error writing to client %d %d\n", fd, cp->ibi);
                    499:                        hangup(cp);
                    500:                }
                    501:                if(hungup){
                    502:                        cp->hungup = 1;
                    503:                        hangup(cp);
                    504:                }
                    505:                if(cp->eh.flag & ACKME)
                    506:                        ack(cp);
                    507:        }
                    508: }
                    509: 
                    510: /*
                    511:  *  collect a message from a client.  4 eofs in a row mean the connection
                    512:  *  is closed.
                    513:  */
                    514: void
                    515: fromclient(fd)
                    516:        int fd;
                    517: {
                    518:        int len;
                    519:        Circuit *cp;
                    520: 
                    521:        cp = (Circuit *)(f[fd].ptr);
                    522: 
                    523:        /*
                    524:         *  read in the message
                    525:         */
                    526:        len = read(fd, cp->obuf, sizeof(cp->obuf));
                    527:        if(len < 0){
                    528:                hangup(cp);
                    529:                return;
                    530:        }
                    531:        if(len == 0){
                    532:                if(++(cp->eofs) == 4){
                    533:                        hangup(cp);
                    534:                        return;
                    535:                }
                    536:        } else
                    537:                cp->eofs = 0;
                    538:        cp->obi = len;
                    539: 
                    540:        /*
                    541:         *  send message
                    542:         */
                    543:        send(cp);
                    544: }
                    545: 
                    546: /*
                    547:  *  send a message on a circuit
                    548:  */
                    549: void
                    550: send(cp)
                    551:        Circuit *cp;
                    552: {
                    553:        cp->sent++;
                    554:        cp->resent = 0;
                    555:        FD_CLR(cp->f - f, master);
                    556:        resend(cp);
                    557: }
                    558: 
                    559: /*
                    560:  *  resend a message on a circuit
                    561:  */
                    562: void
                    563: resend(cp)
                    564:        Circuit *cp;
                    565: {
                    566:        Ethermsg em;
                    567:        int rem, len, first;
                    568: 
                    569:        /*
                    570:         *  break up the message into some number of
                    571:         *  ethernet packets and send them.
                    572:         */
                    573:        first = 1;
                    574:        for (rem = cp->obi; first || rem > 0; rem -= len){
                    575:                first = 0;
                    576:                fillhdr(cp, &em, rem == cp->obi ? rem : -rem);
                    577:                len = rem > sizeof(em.data) ? sizeof(em.data) : rem;
                    578:                memcpy(em.data, &(cp->obuf[cp->obi - rem]), len);
                    579:                if(len < 128-HDRSIZE)
                    580:                        len = 128-HDRSIZE;
                    581:                if(debug)
                    582:                        printpacket("out", &em);
                    583:                if(write(etherfd, &em, len + HDRSIZE) != len + HDRSIZE){
                    584:                        logevent("error writing to ether\n");
                    585:                        return;
                    586:                }
                    587:        }
                    588: }
                    589: 
                    590: /*
                    591:  *  ack a dead client
                    592:  */
                    593: void
                    594: ackdead(e)
                    595:        Ethermsg *e;
                    596: {
                    597:        Ethermsg em;
                    598: 
                    599:        memcpy(em.d, e->s, sizeof(em.d));
                    600:        memcpy(em.s, e->d, sizeof(em.s));
                    601:        em.mid = e->ack;
                    602:        em.ack = e->mid;
                    603:        em.flag = HANGUP;
                    604:        e->remain[1] = 0;
                    605:        e->remain[0] = 0;
                    606:        e->sum[0] = e->sum[1] = 0;
                    607: 
                    608:        if(write(etherfd, &em, HDRSIZE) != HDRSIZE){
                    609:                logevent("error writing to ether\n");
                    610:                return;
                    611:        }
                    612: }
                    613: 
                    614: /*
                    615:  *  fill in an ethernet/nonet header
                    616:  */
                    617: void
                    618: fillhdr(cp, e, rem)
                    619:        Circuit *cp;
                    620:        Ethermsg *e;
                    621:        int rem;
                    622: {
                    623:        memcpy(e, &cp->eh, HDRSIZE);
                    624:        e->mid = cp->sent;
                    625:        e->ack = cp->rcved;
                    626:        e->remain[1] = rem>>8;
                    627:        e->remain[0] = rem;
                    628:        e->sum[0] = e->sum[1] = 0;
                    629: }
                    630: 
                    631: /*
                    632:  *  retransmit any unacknowledged messages
                    633:  */
                    634: void
                    635: timeout(sig)
                    636:        int sig;
                    637: {
                    638:        Circuit *cp;
                    639: 
                    640:        for(cp = circ; cp < &circ[NCIRC]; cp++){
                    641:                if(cp->f && cp->sent != cp->ackrcved){
                    642:                        if(++(cp->resent) > 15) {
                    643:                                logevent("too many rexmits, giving up %d\n", cp - circ);
                    644:                                delf(cp->f - f);
                    645:                                cp->f = 0;
                    646:                        } else
                    647:                                resend(cp);
                    648:                }
                    649:                if(cp->f && cp->hungup && cp->hangingup && cp->sent == cp->ackrcved)
                    650:                        cp->f = 0;
                    651:        }
                    652: }
                    653: 
                    654: /*
                    655:  *  hangup a connection
                    656:  */
                    657: void
                    658: hangup(cp)
                    659:        Circuit *cp;
                    660: {
                    661:        Ethermsg em;
                    662: 
                    663:        logevent("hanging up %d\n", cp - circ);
                    664:        if(cp->hangingup)
                    665:                return;
                    666:        cp->hangingup = 1;
                    667:        cp->eh.flag |= HANGUP;
                    668:        cp->obi = 0;
                    669:        delf(cp->f - f);
                    670:        send(cp);
                    671:        cp->f = 0;
                    672: }
                    673: 
                    674: /*
                    675:  *  ack a message
                    676:  */
                    677: void
                    678: ack(cp)
                    679:        Circuit *cp;
                    680: {
                    681:        Ethermsg em;
                    682: 
                    683:        fillhdr(cp, &em, 0);
                    684:        if(write(etherfd, &em, HDRSIZE) != HDRSIZE){
                    685:                logevent("error writing to ether\n");
                    686:                return;
                    687:        }
                    688: }
                    689: 
                    690: printpacket(tag, p)
                    691:        char *tag;
                    692:        Ethermsg *p;
                    693: {
                    694:        uchar *cp;
                    695:        cp = p->circuit;
                    696:   fprint(2, "%s: d(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)s(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)t(%ux %ux)d(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)\n",
                    697:        tag,
                    698:        p->d[0], p->d[1], p->d[2], p->d[3], p->d[4], p->d[5],
                    699:        p->s[0], p->s[1], p->s[2], p->s[3], p->s[4], p->s[5], p->type[0], p->type[1],
                    700:        cp[0], cp[1], cp[2], cp[3], cp[4], cp[5],
                    701:        cp[6], cp[7], cp[8], cp[9], cp[10], cp[11]);
                    702: }
                    703: 

unix.superglobalmegacorp.com

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