Annotation of researchv10no/ipc/internet/ipconfig.c, revision 1.1

1.1     ! root        1: #include <sys/param.h>
        !             2: #include <stdio.h>
        !             3: #include <errno.h>
        !             4: #include <signal.h>
        !             5: #include <sys/filio.h>
        !             6: #include <sys/inio.h>
        !             7: #include <sys/enio.h>
        !             8: #include <sys/inet/ethernet.h>
        !             9: #include <sys/inet/in.h>
        !            10: #include "config.h"
        !            11: 
        !            12: extern errno;
        !            13: extern unsigned short htons();
        !            14: extern int ip_ld;
        !            15: extern char *optarg;
        !            16: extern int optind;
        !            17: char *enpr();
        !            18: 
        !            19: /*
        !            20:  *  global because we're too lazy to pass them as args
        !            21:  */
        !            22: int debug, fool;
        !            23: in_addr myinaddr, hisinaddr, mask, broadcast;
        !            24: int superarp;
        !            25: u_char myenaddr[6];
        !            26: u_char noether[6];
        !            27: 
        !            28: usage(name)
        !            29:        char *name;
        !            30: {
        !            31:        fprint(2,
        !            32:           "Usage: %s [-m subnet-mask] [-s] device myinaddr hisinaddr [arp-device]\n",
        !            33:           name);
        !            34:        fprint(2,
        !            35:           "       %s [-m subnet-mask] [-s] myinaddr hisinaddr\n",
        !            36:           name);
        !            37:        fprint(2,
        !            38:           "       %s [-m subnet-mask] [-s] myinaddr\n",
        !            39:           name);
        !            40:        exit(1);
        !            41: }
        !            42: 
        !            43: main(argc, argv)
        !            44: char *argv[];
        !            45: {
        !            46:        char *dev, *me, *it, *arp;
        !            47:        int ipfd, enfd, x, ld;
        !            48:        int c, mtu;
        !            49: 
        !            50:        /*
        !            51:         *  process arguments
        !            52:         */
        !            53:        while((c = getopt(argc, argv, "dfm:s")) != -1)
        !            54:                switch(c){
        !            55:                case 'd':
        !            56:                        /*
        !            57:                         *  debugging
        !            58:                         */
        !            59:                        debug = 1;
        !            60:                        break;
        !            61:                case 'f':
        !            62:                        /*
        !            63:                         *  fool people not understanding the
        !            64:                         *  broadcast IP address to shut them up
        !            65:                         */
        !            66:                        fool = 1;
        !            67:                        break;
        !            68:                case 'm':
        !            69:                        /*
        !            70:                         *  subnet mask
        !            71:                         */
        !            72:                        if(strchr(optarg, '.'))
        !            73:                                mask = in_aton(optarg);
        !            74:                        else
        !            75:                                sscanf(optarg, "%x", &mask);
        !            76:                        break;
        !            77:                case 's':
        !            78:                        /*
        !            79:                         *  answer all arp requests for this net ignoring mask
        !            80:                         */
        !            81:                        superarp = 1;
        !            82:                        break;
        !            83:                default:
        !            84:                        usage(argv[0]);
        !            85:                        break;
        !            86:                }
        !            87: 
        !            88:        switch(argc-optind){
        !            89:        case 1:
        !            90:                dev = 0;
        !            91:                me = argv[optind++];
        !            92:                it = me;
        !            93:                arp = 0;
        !            94:                break;
        !            95:        case 2:
        !            96:                dev = 0;
        !            97:                me = argv[optind++];
        !            98:                it = argv[optind++];
        !            99:                arp = 0;
        !           100:                break;
        !           101:        case 3:
        !           102:                dev = argv[optind++];
        !           103:                me = argv[optind++];
        !           104:                it = argv[optind++];
        !           105:                arp = 0;
        !           106:                break;
        !           107:        case 4:
        !           108:                dev = argv[optind++];
        !           109:                me = argv[optind++];
        !           110:                it = argv[optind++];
        !           111:                arp = argv[optind++];
        !           112:                break;
        !           113:        default:
        !           114:                usage(argv[0]);
        !           115:                break;
        !           116:        }
        !           117: 
        !           118:        /*
        !           119:         *  look up the addresses
        !           120:         */
        !           121:        hisinaddr = in_address(it);
        !           122:        if(hisinaddr == 0){
        !           123:                logevent("ipconfig: unknown host/net %s\n", it);
        !           124:                exit(1);
        !           125:        }
        !           126:        myinaddr = in_addronnet(me, hisinaddr, mask);
        !           127:        if(myinaddr == 0){
        !           128:                logevent("ipconfig: no host %s on same net as %s\n", me,it);
        !           129:                exit(1);
        !           130:        }
        !           131: 
        !           132:        /*
        !           133:         *  push disciplines onto the right device
        !           134:         */
        !           135:        signal(SIGHUP, SIG_IGN);
        !           136:        if(dev) {
        !           137:                ipfd = open(dev, 2);
        !           138:                if(ipfd < 0){
        !           139:                        perror(dev);
        !           140:                        exit(1);
        !           141:                }
        !           142:                if(arp){
        !           143:                        x = htons((unsigned short)ETHERPUP_IPTYPE);
        !           144:                        if(ioctl(ipfd, ENIOTYPE, &x) < 0){
        !           145:                                logevent("ENIOTYPE\n");
        !           146:                                exit(1);
        !           147:                        }
        !           148:                }
        !           149:                flavor(ipfd, myinaddr, hisinaddr, mtu);
        !           150:        } else {
        !           151:                int pfd[2];
        !           152:                if(pipe(pfd)<0){
        !           153:                        logevent("pipe\n");
        !           154:                        exit(1);
        !           155:                }
        !           156:                flavor(pfd[0], myinaddr, hisinaddr, mtu);
        !           157:                flavor(pfd[1], hisinaddr, myinaddr, mtu);
        !           158:        }
        !           159: 
        !           160:        /*
        !           161:         *  wait for ever or do arping
        !           162:         */
        !           163:        if(arp == 0){
        !           164:                if(!debug)
        !           165:                        detach("ipconfig");
        !           166:                pause();        /* forever, hopefully */
        !           167:                exit(0);
        !           168:        }
        !           169:        if(ioctl(ipfd, IPIOARP, 0) < 0){
        !           170:                logevent("IPIOARP\n");
        !           171:                exit(1);
        !           172:        }
        !           173:        enfd = open(arp, 2);
        !           174:        if(enfd < 0){
        !           175:                logevent("can't open arp device %s\n", arp);
        !           176:                exit(1);
        !           177:        }
        !           178:        if(!debug)
        !           179:                detach("ipconfig");
        !           180:        doarp(ipfd, enfd);
        !           181: }
        !           182: 
        !           183: flavor(ipfd, myinaddr, hisinaddr, mtu)
        !           184:        int ipfd;
        !           185:        in_addr myinaddr, hisinaddr;
        !           186:        int mtu;
        !           187: {
        !           188:        if(ioctl(ipfd, FIOPUSHLD, &ip_ld) < 0){
        !           189:                logevent("PUSHLD\n");
        !           190:                exit(1);
        !           191:        }
        !           192: 
        !           193:        /*
        !           194:         *  tell the line disciplines the identity of the ends
        !           195:         */
        !           196:        if(ioctl(ipfd, IPIOLOCAL, &myinaddr) < 0){
        !           197:                logevent("IPIOLOCAL\n");
        !           198:                exit(1);
        !           199:        }
        !           200:        if(hisinaddr!=in_netof(hisinaddr) && !mask){
        !           201:                /*
        !           202:                 *  host to host connection
        !           203:                 */
        !           204:                ioctl(ipfd, IPIOHOST, &hisinaddr);
        !           205:                broadcast = hisinaddr;
        !           206:        } else {
        !           207:                /*
        !           208:                 *  host to network connection
        !           209:                 */
        !           210:                mtu = 1500;
        !           211:                ioctl(ipfd, IPIOMTU, &mtu);
        !           212:                ioctl(ipfd, IPIONET, &hisinaddr);
        !           213:                if(mask) {
        !           214:                        ioctl(ipfd, IPIOMASK, &mask);
        !           215:                        broadcast = hisinaddr | ~mask;
        !           216:                } else {
        !           217:                        broadcast = hisinaddr |
        !           218:                                    (IN_CLASSA(hisinaddr) ? IN_CLASSA_HOST :
        !           219:                                     (IN_CLASSB(hisinaddr) ? IN_CLASSB_HOST :
        !           220:                                      (IN_CLASSC(hisinaddr) ? IN_CLASSC_HOST :
        !           221:                                       0)));
        !           222:                }
        !           223:        }
        !           224: }
        !           225: 
        !           226: /*
        !           227:  * Address resolution
        !           228:  */
        !           229: 
        !           230: struct ether_arp{
        !           231:        /* driver goo */
        !           232:        struct etherpup arp_ether;
        !           233: 
        !           234:        /* arp stuff */
        !           235:        u_short arp_hrd;
        !           236: #define ARPHRD_ETHER   1
        !           237:        u_short arp_pro;
        !           238:        u_char  arp_hln;
        !           239:        u_char  arp_pln;
        !           240:        u_short arp_op;
        !           241: #define ARPOP_REQUEST  1
        !           242: #define ARPOP_REPLY    2
        !           243:        u_char  arp_sha[6];     /* sender ether addr */
        !           244:        u_char  arp_spa[4];     /* sender internet addr */
        !           245:        u_char  arp_tha[6];     /* target ether addr */
        !           246:        u_char  arp_tpa[4];     /* target internet addr */
        !           247: };
        !           248: 
        !           249: u_char broadaddr[6] = {
        !           250:        0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        !           251: };
        !           252: 
        !           253: /* wait for ARP requests and answers */
        !           254: doarp(ipfd, enfd)
        !           255:        int ipfd;
        !           256:        int enfd;
        !           257: {
        !           258:        fd_set rdfds;
        !           259:        int x;
        !           260:        char buf[2000];
        !           261:        struct goo{
        !           262:                in_addr inaddr;
        !           263:                u_char enaddr[6];
        !           264:        } goo;
        !           265:        in_addr tpa;
        !           266: 
        !           267:        x = htons((u_short)ETHERPUP_ARPTYPE);
        !           268:        if(ioctl(enfd, ENIOTYPE, &x) < 0){
        !           269:                perror("ipconfig: ENIOTYPE");
        !           270:                exit(1);
        !           271:        }
        !           272:        if(ioctl(enfd, ENIOADDR, myenaddr) < 0){
        !           273:                perror("ipconfig: ENIOADDR");
        !           274:                exit(1);
        !           275:        }
        !           276: 
        !           277:        FD_ZERO(rdfds);
        !           278:        while(1){
        !           279:                FD_SET(ipfd, rdfds);
        !           280:                FD_SET(enfd, rdfds);
        !           281: 
        !           282:                errno = 0;      /* just in case */
        !           283:                if(select(20, &rdfds, 0, 2000) < 0){
        !           284:                        if(errno == EINTR)
        !           285:                                continue;
        !           286:                        logevent("ipconfig: select error\n");
        !           287:                        exit(1);
        !           288:                }
        !           289:                if(FD_ISSET(ipfd, rdfds)){
        !           290:                        if(read(ipfd, &tpa, sizeof(tpa)) != sizeof(tpa))
        !           291:                                logevent("ipconfig: in read\n");
        !           292:                        arpwhohas(enfd, ipfd, tpa);
        !           293:                }
        !           294:                if(FD_ISSET(enfd, rdfds)){
        !           295:                        if(read(enfd, buf, sizeof(buf)) <= 0)
        !           296:                                logevent("ipconfig: en read\n");
        !           297:                        arpinput(ipfd, enfd, buf);
        !           298:                }
        !           299:        }
        !           300: }
        !           301: 
        !           302: /* broadcast an arp request */
        !           303: arpwhohas(enfd, ipfd, addr)
        !           304:        in_addr addr;
        !           305: {
        !           306:        struct goo{
        !           307:                in_addr inaddr;
        !           308:                u_char enaddr[6];
        !           309:        } goo;
        !           310:        struct ether_arp a;
        !           311:        in_addr rddaniym;
        !           312: 
        !           313:        if(addr == myinaddr){
        !           314:                goo.inaddr = addr;
        !           315:                bcopy(myenaddr, goo.enaddr, sizeof(goo.enaddr));
        !           316:                ioctl(ipfd, IPIORESOLVE, &goo);
        !           317:                return;
        !           318:        }
        !           319:        if(addr == hisinaddr || addr == broadcast){
        !           320:                goo.inaddr = addr;
        !           321:                bcopy(broadaddr, goo.enaddr, sizeof(goo.enaddr));
        !           322:                ioctl(ipfd, IPIORESOLVE, &goo);
        !           323:                return;
        !           324:        }
        !           325:        bcopy(broadaddr, a.arp_ether.dhost, sizeof(a.arp_ether.dhost));
        !           326:        a.arp_ether.type = htons(ETHERPUP_ARPTYPE);
        !           327: 
        !           328:        a.arp_hrd = htons(ARPHRD_ETHER);
        !           329:        a.arp_pro = htons(ETHERPUP_IPTYPE);
        !           330:        a.arp_hln = sizeof(goo.enaddr);
        !           331:        a.arp_pln = sizeof(in_addr);
        !           332:        a.arp_op = htons(ARPOP_REQUEST);
        !           333: 
        !           334:        bcopy(myenaddr, a.arp_sha, sizeof(a.arp_sha));
        !           335:        rddaniym = htonl(myinaddr);
        !           336:        bcopy(&rddaniym, a.arp_spa, sizeof(a.arp_spa));
        !           337:        addr = htonl(addr);
        !           338:        bcopy(&addr, a.arp_tpa, sizeof(a.arp_tpa));
        !           339: 
        !           340:        write(enfd, &a, sizeof(a));
        !           341: }
        !           342: 
        !           343: /* process an arp request */
        !           344: arpinput(ipfd, enfd, ap)
        !           345:        struct ether_arp *ap;
        !           346: {
        !           347:        struct goo{
        !           348:                in_addr inaddr;
        !           349:                u_char enaddr[6];
        !           350:        } goo;
        !           351:        in_addr spa, tpa;
        !           352:        in_addr rddaniym;
        !           353:        int forgery = 0;
        !           354: 
        !           355:        bcopy(ap->arp_spa, &spa, sizeof(spa));
        !           356:        bcopy(ap->arp_tpa, &tpa, sizeof(tpa));
        !           357:        spa = ntohl(spa);
        !           358:        tpa = ntohl(tpa);
        !           359: 
        !           360:        if(debug){
        !           361:                print("%s from %s", 
        !           362:                        ap->arp_op == ntohs(ARPOP_REQUEST) ? "request" : "answer",
        !           363:                        in_ntoa(spa));
        !           364:                print(" for %s\n", in_ntoa(tpa));
        !           365:        }
        !           366: 
        !           367:        if(ntohs(ap->arp_pro) != ETHERPUP_IPTYPE)
        !           368:                return;
        !           369: 
        !           370:        /* make sure noone's trying to be me */
        !           371:        if(memcmp(ap->arp_sha, myenaddr, sizeof(myenaddr)) != 0){
        !           372:                if(spa == myinaddr){
        !           373:                        /*
        !           374:                         *  scream on the console and send out an
        !           375:                         *  arp packet with my correct ether addrss
        !           376:                         */
        !           377:                        logconsole("ipconfig: machine at ether address %s is forging my IP address\n", enpr(ap->arp_ether.shost));
        !           378:                        tpa = spa;
        !           379:                        bcopy(myenaddr, ap->arp_sha, sizeof(myenaddr));
        !           380:                        forgery = 1;
        !           381:                }
        !           382:        }
        !           383: 
        !           384:        if(!forgery){
        !           385:                /* incorporate sender's address */
        !           386:                goo.inaddr = spa;
        !           387:                bcopy(ap->arp_sha, goo.enaddr, sizeof(goo.enaddr));
        !           388:                if(ioctl(ipfd, IPIORESOLVE, &goo) < 0)
        !           389:                        logevent("ipconfig: IPIORESOLVE");
        !           390: 
        !           391:                /* send reply only to a request */
        !           392:                if(ap->arp_op != ntohs(ARPOP_REQUEST))
        !           393:                        return;
        !           394:        }
        !           395: 
        !           396:        /*  accept the request if
        !           397:         *  (1) the target is me or
        !           398:         *  (2) superarp==1 and (  the target is not on my subnet &&
        !           399:         *                         the target is on my net  )
        !           400:         */
        !           401:        if(tpa==myinaddr || (superarp && in_netof(tpa)==in_netof(myinaddr) &&
        !           402:                             in_subnetof(tpa, mask)!=in_subnetof(myinaddr, mask))){
        !           403:                if(debug)
        !           404:                        print("answering %s\n", enpr(ap->arp_sha));
        !           405:                ap->arp_hrd = htons(ARPHRD_ETHER);
        !           406:                ap->arp_pro = htons(ETHERPUP_IPTYPE);
        !           407:                ap->arp_op = htons(ARPOP_REPLY);
        !           408:                rddaniym = htonl(tpa);
        !           409:                tpa = htonl(spa);
        !           410:                spa = rddaniym;
        !           411:                bcopy(&tpa, ap->arp_tpa, sizeof(ap->arp_tpa));
        !           412:                bcopy(&spa, ap->arp_spa, sizeof(ap->arp_spa));
        !           413:                bcopy(ap->arp_sha, ap->arp_tha, sizeof(ap->arp_tha));
        !           414:                bcopy(myenaddr, ap->arp_sha, sizeof(ap->arp_sha));
        !           415:                bcopy(broadaddr, ap->arp_ether.dhost, sizeof(ap->arp_ether.dhost));
        !           416:                ap->arp_ether.type = htons(ETHERPUP_ARPTYPE);
        !           417:                write(enfd, ap, sizeof(struct ether_arp));
        !           418:        } else if((tpa==hisinaddr || tpa==broadcast)){
        !           419:                /*
        !           420:                 *  For various reasons, some systems to not understand
        !           421:                 *  the correct IP address to use for broadcast.  This
        !           422:                 *  causes them to send there future arp requests (for that
        !           423:                 *  address) to a non-existant ether address.
        !           424:                 */
        !           425:                logevent("bozo request from %s", in_ntoa(spa));
        !           426:                fprint(2, " for %s\n", in_ntoa(tpa));
        !           427:                if(fool){
        !           428:                        logevent("giving him bozoid arp response\n");
        !           429:                        ap->arp_hrd = htons(ARPHRD_ETHER);
        !           430:                        ap->arp_pro = htons(ETHERPUP_IPTYPE);
        !           431:                        ap->arp_op = htons(ARPOP_REPLY);
        !           432:                        rddaniym = htonl(tpa);
        !           433:                        tpa = htonl(spa);
        !           434:                        spa = rddaniym;
        !           435:                        bcopy(&tpa, ap->arp_tpa, sizeof(ap->arp_tpa));
        !           436:                        bcopy(&spa, ap->arp_spa, sizeof(ap->arp_spa));
        !           437:                        bcopy(ap->arp_sha, ap->arp_tha, sizeof(ap->arp_tha));
        !           438:                        bcopy(noether, ap->arp_sha, sizeof(ap->arp_sha));
        !           439:                        bcopy(ap->arp_ether.shost, ap->arp_ether.dhost,sizeof(ap->arp_ether.dhost));
        !           440:                        ap->arp_ether.type = htons(ETHERPUP_ARPTYPE);
        !           441: 
        !           442:                        write(enfd, ap, sizeof(struct ether_arp));
        !           443:                }
        !           444:        }
        !           445: }
        !           446: 
        !           447: arppr(a)
        !           448: struct ether_arp a;
        !           449: {
        !           450:        in_addr spa, tpa;
        !           451: 
        !           452:        print("dhost %s\n", enpr(a.arp_ether.dhost));
        !           453:        print("shost %s\n", enpr(a.arp_ether.shost));
        !           454:        print("type  %x\n", ntohs(a.arp_ether.type));
        !           455:        a.arp_hrd = ntohs(a.arp_hrd);
        !           456:        a.arp_pro = ntohs(a.arp_pro);
        !           457:        a.arp_op = ntohs(a.arp_op);
        !           458: 
        !           459:        bcopy(a.arp_spa, &spa, sizeof(spa));
        !           460:        bcopy(a.arp_tpa, &tpa, sizeof(tpa));
        !           461:        tpa = ntohl(tpa);
        !           462:        spa = ntohl(spa);
        !           463: 
        !           464:        print("hrd %d pro %x op %d spa %x tpa %x\n",
        !           465:                a.arp_hrd, a.arp_pro, a.arp_op, spa, tpa);
        !           466:        print("sha %s\n", enpr(a.arp_sha));
        !           467:        print("tha %s\n", enpr(a.arp_tha));
        !           468: }
        !           469: 
        !           470: char *
        !           471: enpr(en)
        !           472: u_char *en;
        !           473: {
        !           474:        static char a[128];
        !           475: 
        !           476:        sprint(a, "%02x %02x %02x %02x %02x %02x", en[0], en[1], en[2],
        !           477:                en[3], en[4], en[5]);
        !           478:        return a;
        !           479: }

unix.superglobalmegacorp.com

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