Annotation of researchv10no/ipc/mgrs/icmpmgr/icmpmgr.c, revision 1.1.1.1

1.1       root        1: #include <sys/param.h>
                      2: #include <sys/inet/ip.h>
                      3: #include <ipc.h>
                      4: 
                      5: int printip();
                      6: 
                      7: typedef struct {
                      8:        int code;
                      9:        char *meaning;
                     10:        int (*action)();
                     11:        int needid;
                     12: } Code;
                     13: 
                     14: typedef struct {
                     15:        int type;
                     16:        Code *c;
                     17: } Msg;
                     18: 
                     19: typedef struct {
                     20:        int type;
                     21:        int inuse;
                     22:        int id;
                     23: } Client;
                     24: 
                     25: /* Destination Unreachable Message
                     26: 
                     27:     0                   1                   2                   3
                     28:     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                     29:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     30:    |     Type      |     Code      |          Checksum             |
                     31:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     32:    |                             unused                            |
                     33:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     34:    |      Internet Header + 64 bits of Original Data Datagram      |
                     35:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     36: 
                     37: */
                     38: 
                     39: Code unreachc[] = {
                     40:        { 0, "net unreachable", printip, 0 },
                     41:        { 1, "host unreachable", printip, 0 },
                     42:        { 2, "protocol unreachable", printip, 0 },
                     43:        { 3, "port unreachable", printip, 0 },
                     44:        { 4, "fragment needed and DF set", printip, 0 },
                     45:        { 5, "source route failed", printip, 0 },
                     46:        { -1, 0, 0 }
                     47: };
                     48: 
                     49: typedef struct {
                     50:        u_char param[4];
                     51:        struct ip ip;
                     52: } IpMsg;
                     53: 
                     54: 
                     55: /* Time Exceeded Message
                     56: 
                     57:     0                   1                   2                   3
                     58:     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                     59:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     60:    |     Type      |     Code      |          Checksum             |
                     61:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     62:    |                             unused                            |
                     63:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     64:    |      Internet Header + 64 bits of Original Data Datagram      |
                     65:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     66: */
                     67: 
                     68: Code timec[] = {
                     69:        { 0, "time to live exceeded in transit", printip, 0 },
                     70:        { 1, "fragment reassembly time exceeded", printip, 0 },
                     71:        { -1, 0, 0 }
                     72: };
                     73: 
                     74: 
                     75: 
                     76: /* Parameter Problem Message
                     77: 
                     78:     0                   1                   2                   3
                     79:     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                     80:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     81:    |     Type      |     Code      |          Checksum             |
                     82:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     83:    |    Pointer    |                   unused                      |
                     84:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     85:    |      Internet Header + 64 bits of Original Data Datagram      |
                     86:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     87: */
                     88: 
                     89: Code paramc[] = {
                     90:        { 0, "parameter problem", printip, 0 },
                     91:        { -1, 0, 0 }
                     92: };
                     93: 
                     94: /* Source Quench Message
                     95: 
                     96:     0                   1                   2                   3
                     97:     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                     98:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     99:    |     Type      |     Code      |          Checksum             |
                    100:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    101:    |                             unused                            |
                    102:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    103:    |      Internet Header + 64 bits of Original Data Datagram      |
                    104:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    105: */
                    106: 
                    107: Code quenchc[] = {
                    108:        { 0, "source quench", printip, 0 },
                    109:        { -1, 0, 0 }
                    110: };
                    111: 
                    112: 
                    113: /* Redirect Message
                    114: 
                    115:     0                   1                   2                   3
                    116:     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                    117:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    118:    |     Type      |     Code      |          Checksum             |
                    119:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    120:    |                 Gateway Internet Address                      |
                    121:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    122:    |      Internet Header + 64 bits of Original Data Datagram      |
                    123:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    124: */
                    125: 
                    126: Code redirectc[] = {
                    127:        { 0, "redirect datagrams for the network", printip, 0 },
                    128:        { 1, "redirect datagrams for the host", printip, 0 },
                    129:        { 2, "redirect datagrams for the type of service and network", printip, 0},
                    130:        { 3, "redirect datagrams for the type of service and host", printip, 0 },
                    131:        { -1, 0, 0 }
                    132: };
                    133: 
                    134: 
                    135: /* Echo or Echo Reply Message
                    136: 
                    137:     0                   1                   2                   3
                    138:     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                    139:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    140:    |     Type      |     Code      |          Checksum             |
                    141:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    142:    |           Identifier          |        Sequence Number        |
                    143:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    144:    |     Data ...
                    145:    +-+-+-+-+-
                    146: */
                    147: 
                    148: int echo();
                    149: Code echoc[] = {
                    150:        { 0, "echo", echo, 1 },
                    151:        { -1, 0, 0 }
                    152: };
                    153: Code echorc[] = {
                    154:        { 0, "echo reply", 0, 1 },
                    155:        { -1, 0, 0 }
                    156: };
                    157: 
                    158: typedef struct {
                    159:        u_char id[2];
                    160:        u_char seqno[2];
                    161: } EchoMsg;
                    162: 
                    163: /* Timestamp or Timestamp Reply Message
                    164: 
                    165:     0                   1                   2                   3
                    166:     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                    167:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    168:    |     Type      |      Code     |          Checksum             |
                    169:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    170:    |           Identifier          |        Sequence Number        |
                    171:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    172:    |     Originate Timestamp                                       |
                    173:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    174:    |     Receive Timestamp                                         |
                    175:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    176:    |     Transmit Timestamp                                        |
                    177:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    178: */
                    179: 
                    180: Code timestampc[] = {
                    181:        { 0, "timestamp", 0, 1 },
                    182:        { -1, 0, 0 }
                    183: };
                    184: Code timestamprc[] = {
                    185:        { 0, "timestamp reply", 0, 1 },
                    186:        { -1, 0, 0 }
                    187: };
                    188: 
                    189: typedef struct {
                    190:        u_char id[2];
                    191:        u_char seqno[2];
                    192:        u_char orig[4];
                    193:        u_char recv[4];
                    194:        u_char xmit[4];
                    195: } TsMsg;
                    196: 
                    197: 
                    198: /* Information Request or Information Reply Message
                    199: 
                    200:     0                   1                   2                   3
                    201:     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                    202:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    203:    |     Type      |      Code     |          Checksum             |
                    204:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    205:    |           Identifier          |        Sequence Number        |
                    206:    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    207: */
                    208: 
                    209: Code infoc[] = {
                    210:        { 0, "info", 0, 1 },
                    211:        { -1, 0, 0 }
                    212: };
                    213: Code inforc[] = {
                    214:        { 0, "info reply", 0, 1 },
                    215:        { -1, 0, 0 }
                    216: };
                    217: 
                    218: Msg msgs[] = {
                    219:         { 0, echorc },
                    220:         { 3, unreachc },
                    221:         { 4, quenchc },
                    222:         { 5, redirectc },
                    223:         { 8, echoc },
                    224:         { 11, timec },
                    225:         { 12, paramc },
                    226:         { 13, timestampc },
                    227:         { 14, timestamprc },
                    228:         { 15, infoc },
                    229:         { 16, inforc },
                    230: };
                    231: 
                    232: typedef struct {
                    233:        struct ip ip;
                    234:        u_char type;
                    235:        u_char code;
                    236:        u_char cksum[2];
                    237:        union {
                    238:                IpMsg i;
                    239:                EchoMsg e;
                    240:                TsMsg t;
                    241:        } u;
                    242:        u_char buffer[4096];
                    243: } IcmpMsg;
                    244: 
                    245: /*
                    246:  *  globals
                    247:  */
                    248: char *av0;
                    249: Client clients[NOFILE];
                    250: fd_set cfds;
                    251: int debug;
                    252: 
                    253: ding()
                    254: {
                    255:        signal(SIGALRM, ding);
                    256:        alarm(10);
                    257: }
                    258: 
                    259: /*
                    260:  *  icmp mgr
                    261:  */
                    262: main(ac, av)
                    263:        int ac;
                    264:        char *av[];
                    265: {
                    266:        char *mtpt="icmp", *cp;
                    267:        int i;
                    268:        int ipfd, fsfd;
                    269:        fd_set fds;
                    270: 
                    271:        av0 = av[0];
                    272:        chdir("/cs");
                    273:        for (i=1; i<ac; i++) {
                    274:                if (av[i][0] == '-') {
                    275:                        for (cp=&av[i][1]; *cp; cp++) {
                    276:                                switch(*cp) {
                    277:                                case 'd':
                    278:                                        debug = 1;
                    279:                                        break;
                    280:                                case 'm':
                    281:                                        if (i+1>=ac)
                    282:                                                usage(av0);
                    283:                                        mtpt = av[++i];
                    284:                                        break;
                    285:                                default:
                    286:                                        usage(av0);
                    287:                                }
                    288:                        }
                    289:                }
                    290:        }
                    291: 
                    292:        /*
                    293:         * open the ip protocol
                    294:         */
                    295:        ipfd = open("/dev/ipicmp", 2);
                    296:        if(ipfd < 0){
                    297:                logevent("error opening ip device\n");
                    298:                exit(1);
                    299:        };
                    300: 
                    301:        /*
                    302:         * plug ourselves into the file system
                    303:         */
                    304:        fsfd = ipccreat(mtpt, "");
                    305:        if(ipfd < 0){
                    306:                logevent("error mounting into fs\n");
                    307:                exit(1);
                    308:        };
                    309: 
                    310:        if(!debug)
                    311:                detach(mtpt);
                    312: 
                    313:        /*
                    314:         * clear out the clients
                    315:         */
                    316:        for(i=0; i<NOFILE; i++){
                    317:                clients[i].id = i;
                    318:                clients[i].inuse = 0;
                    319:        }
                    320: 
                    321:        /*
                    322:         * spin honoring requests
                    323:         */
                    324:        FD_ZERO(fds);
                    325:        for(;;) {
                    326:                int n;
                    327: 
                    328:                fds = cfds;
                    329:                FD_SET(ipfd, fds);
                    330:                FD_SET(fsfd, fds);
                    331:                switch(n = select(NOFILE, &fds, 0, 10000)){
                    332:                case -1:
                    333:                        logevent("select failed\n");
                    334:                        exit(1);
                    335:                case 0:
                    336:                        continue;
                    337:                }
                    338:                signal(SIGALRM, ding);
                    339:                alarm(10);
                    340:                if(FD_ISSET(ipfd, fds)) {
                    341:                        readnet(ipfd);
                    342:                        n--;
                    343:                }
                    344:                if(n && FD_ISSET(fsfd, fds)) {
                    345:                        newclient(fsfd);
                    346:                        n--;
                    347:                }
                    348:                for(i = 0; n && i<NOFILE; i++){
                    349:                        if(FD_ISSET(i, fds)){
                    350:                                readclient(i, ipfd);
                    351:                                n--;
                    352:                        }
                    353:                }
                    354:                alarm(0);
                    355:        }
                    356: }
                    357: 
                    358: /*
                    359:  * read an icmp message from the network
                    360:  */
                    361: readnet(fd)
                    362: {
                    363:        Msg *mp;
                    364:        IcmpMsg m;
                    365:        int n;
                    366:        char fromsys[32], tosys[32];
                    367:        u_char c[2];
                    368:        Code *cp;
                    369: 
                    370:        if((n = read(fd, &m, sizeof(m))) > 0){
                    371:                strcpy(fromsys, in_ntoa(m.ip.ip_src));
                    372:                strcpy(tosys, in_ntoa(m.ip.ip_dst));
                    373:                logevent("in %s -> %s, type %d code %d\n", fromsys, tosys,
                    374:                        m.type, m.code);
                    375:                c[0] = m.cksum[0];
                    376:                c[1] = m.cksum[1];
                    377:                cksum(&m, n);
                    378:                if(c[0] != m.cksum[0] || c[1] != m.cksum[1]){
                    379:                        fprint(2, "checksum error %.2x%.2x/%.2x%.2x\n", c[0],
                    380:                                c[1], m.cksum[0], m.cksum[1]);
                    381:                        return;
                    382:                }
                    383:                for(mp = msgs; mp->type >= 0; mp++){
                    384:                        if(mp->type == m.type){
                    385:                                for(cp = mp->c; cp->code >= 0; cp++)
                    386:                                        if(cp->code == m.code)
                    387:                                                break;
                    388:                                if(cp->code < 0)
                    389:                                        fprint(2, "undefined code\n");
                    390:                                else if(cp->action)
                    391:                                        (*cp->action)(fd, &m, n);
                    392:                                break;
                    393:                        }
                    394:                }
                    395:                if(mp->type < 0)
                    396:                        fprint(2, "undefined type\n");
                    397:        } else {
                    398:                logevent("error reading from network %d\n", errno);
                    399:                exit(1);
                    400:        }
                    401: }
                    402: 
                    403: /*
                    404:  * a call from a new client
                    405:  */
                    406: newclient(fd)
                    407: {
                    408:        int cfd;
                    409:        ipcinfo *ipc;
                    410: 
                    411:        /*
                    412:         *  get the new call (protected by a timeout)
                    413:         */
                    414:        ipc = ipclisten(fd);
                    415:        if(fd==0)
                    416:                return;
                    417:        cfd = ipcaccept(ipc);
                    418:        if(cfd<0)
                    419:                return;
                    420: 
                    421:        /*
                    422:         *  set up a new id (for echo/timestamp/etc)
                    423:         */
                    424:        clients[cfd].id += NOFILE;
                    425:        clients[cfd].inuse = 1;
                    426:        FD_SET(cfd, cfds);
                    427:        logevent("new client %d %s!%s\n", cfd, ipc->machine, ipc->user);
                    428: }
                    429: 
                    430: /*
                    431:  * read an icmp message from a client (protected by an timeout).
                    432:  * if this is a message that requires an id, put one in.
                    433:  */
                    434: readclient(fd, ipfd)
                    435: {
                    436:        IcmpMsg m;
                    437:        int n;
                    438:        char fromsys[32], tosys[32];
                    439:        Msg *mp;
                    440:        Code *cp;
                    441: 
                    442:        if((n = read(fd, &m, sizeof(m))) > 0){
                    443:                strcpy(fromsys, in_ntoa(m.ip.ip_src));
                    444:                strcpy(tosys, in_ntoa(m.ip.ip_dst));
                    445:                logevent("out(%d) %s -> %s, type %d code %d\n", fd, fromsys,
                    446:                        tosys, m.type, m.code);
                    447:                for(mp = msgs; mp->type >= 0; mp++){
                    448:                        if(mp->type == m.type){
                    449:                                for(cp = mp->c; cp->code >= 0; cp++)
                    450:                                        if(cp->code == m.code)
                    451:                                                break;
                    452:                                if(cp->code < 0)
                    453:                                        fprint(2, "undefined code\n");
                    454:                                else {
                    455:                                        if(cp->needid){
                    456:                                                m.u.e.id[0] = clients[fd].id;
                    457:                                                m.u.e.id[1] = clients[fd].id>>8;
                    458:                                        }
                    459:                                        ipsend(ipfd, &m, n, m.ip.ip_src,
                    460:                                                m.ip.ip_dst);
                    461:                                }
                    462:                                break;
                    463:                        }
                    464:                }
                    465:                if(mp->type < 0)
                    466:                        fprint(2, "undefined type\n");
                    467:        } else {
                    468:                logevent("losing client %d\n", fd);
                    469:                FD_CLR(fd, cfds);
                    470:                close(fd);
                    471:        }
                    472: }
                    473: 
                    474: /*
                    475:  * print a message with an ip body
                    476:  */
                    477: printip(fd, mp, len)
                    478:        IcmpMsg *mp;
                    479: {
                    480: }
                    481: 
                    482: /*
                    483:  * send an ip datagram
                    484:  */
                    485: ipsend(fd, mp, len, src, dst)
                    486:        IcmpMsg *mp;
                    487:        u_long src;
                    488:        u_long dst;
                    489: {
                    490:        mp->ip.ip_dst = dst;
                    491:        mp->ip.ip_src = src;
                    492:        mp->ip.ip_len = len;
                    493:        mp->ip.ip_hl = sizeof(struct ip)>>2;
                    494:        mp->ip.ip_off = 0;
                    495:        mp->ip.ip_ttl = 255;
                    496:        mp->ip.ip_p = 1;
                    497:        cksum(mp, len);
                    498:        return write(fd, mp, len)!=len ? -1 : 0;
                    499: }
                    500: 
                    501: /*
                    502:  * echo a datagram
                    503:  */
                    504: echo(fd, mp, len)
                    505:        IcmpMsg *mp;
                    506: {
                    507:        mp->type = 0;
                    508:        if(ipsend(fd, mp, len, mp->ip.ip_dst, mp->ip.ip_src) < 0)
                    509:                perror("sending echo");
                    510: }
                    511: 
                    512: usage(name)
                    513:        char *name;
                    514: {
                    515:        fprint(2, "usage: %s [-d] [-m mount-pt]\n", name);
                    516:        exit(1);
                    517: }
                    518: 
                    519: /*
                    520:  * internet checksum routine
                    521:  */
                    522: cksum(mp, len)
                    523:        IcmpMsg *mp;
                    524: {
                    525:        u_char *cp;
                    526:        u_short *sp;
                    527:        u_long sum;
                    528: 
                    529:        sp = (u_short *)&mp->type;
                    530:        len -= sizeof(struct ip);
                    531:        mp->cksum[0] = mp->cksum[1] = 0;
                    532:        for(sum = 0; len >=2; len-=2)
                    533:                sum += *sp++;
                    534:        if(len){
                    535:                cp = (u_char *)sp;
                    536:                sum += *cp;
                    537:        }
                    538:        while(sum & 0xffff0000)
                    539:                sum = (sum & 0xffff) + (sum>>16);
                    540:        sum ^= 0xffff;
                    541:        mp->cksum[1] = sum>>8;
                    542:        mp->cksum[0] = sum;
                    543: }

unix.superglobalmegacorp.com

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