Annotation of researchv9/ipc/src/internet/ipconfig.c, revision 1.1.1.1

1.1       root        1: #include <stdio.h>
                      2: #include <errno.h>
                      3: #include <signal.h>
                      4: #include <sys/param.h>
                      5: #include <sys/types.h>
                      6: #include <sgtty.h>
                      7: #include <sys/ethernet.h>
                      8: #include <sys/inet/in.h>
                      9: #include "config.h"
                     10: 
                     11: extern errno;
                     12: 
                     13: #if vax
                     14: extern unsigned short htons();
                     15: #endif
                     16: extern int ip_ld;
                     17: 
                     18: main(argc, argv)
                     19: char *argv[];
                     20: {
                     21:        char *dev, *me, *it, *arp;
                     22:        unsigned long myaddr, hisaddr, inaddr;
                     23:        int ipfd, enfd, x, ld;
                     24: 
                     25:        if(argc < 4){
                     26:                fprintf(stderr, "Usage: %s device my-addr his-addr [arp-device]\n",
                     27:                        argv[0]);
                     28:                exit(1);
                     29:        }
                     30:        dev = argv[1];
                     31:        me = argv[2];
                     32:        it = argv[3];
                     33:        if(argc > 4)
                     34:                arp = argv[4];
                     35:        else
                     36:                arp = 0;
                     37: 
                     38:        myaddr = in_address(me);
                     39:        if(myaddr == 0){
                     40:                fprintf(stderr, "ipconfig: unknown host %s\n", me);
                     41:                exit(1);
                     42:        }
                     43:        hisaddr = in_address(it);
                     44:        if(hisaddr == 0){
                     45:                fprintf(stderr, "ipconfig: unknown host/net %s\n", it);
                     46:                exit(1);
                     47:        }
                     48:        signal(SIGHUP, SIG_IGN);
                     49:        ipfd = open(dev, 2);
                     50:        if(ipfd < 0){
                     51:                perror(dev);
                     52:                exit(1);
                     53:        }
                     54: 
                     55:        if(arp){
                     56:                x = htons((unsigned short)ETHERPUP_IPTYPE);
                     57:                if(ioctl(ipfd, ENIOTYPE, &x) < 0){
                     58:                        perror("ENIOTYPE");
                     59:                        exit(1);
                     60:                }
                     61:        }
                     62:        if(ioctl(ipfd, FIOPUSHLD, &ip_ld) < 0){
                     63:                perror("PUSHLD");
                     64:                exit(1);
                     65:        }
                     66:        if(ioctl(ipfd, IPIOLOCAL, &myaddr) < 0){
                     67:                perror("IPIOLOCAL");
                     68:                exit(1);
                     69:        }
                     70:        if(hisaddr & 0xff){
                     71:                ioctl(ipfd, IPIOHOST, &hisaddr);
                     72:        } else {
                     73:                ioctl(ipfd, IPIONET, &hisaddr);
                     74:        }
                     75:        if(arp == 0){
                     76:                pause();        /* forever, hopefully */
                     77:                exit(0);
                     78:        }
                     79: 
                     80:        if(ioctl(ipfd, IPIOARP, 0) < 0){
                     81:                perror("IPIOARP");
                     82:                exit(1);
                     83:        }
                     84:        enfd = open(arp, 2);
                     85:        if(enfd < 0){
                     86:                perror(arp);
                     87:                exit(1);
                     88:        }
                     89:        doarp(ipfd, enfd, myaddr);
                     90: }
                     91: 
                     92: 
                     93: /*
                     94:  * Address resolution
                     95:  */
                     96: 
                     97: struct ether_arp{
                     98:        /* driver goo */
                     99:        struct etherpup arp_ether;
                    100: 
                    101:        /* arp stuff */
                    102:        u_short arp_hrd;
                    103: #define ARPHRD_ETHER   1
                    104:        u_short arp_pro;
                    105:        u_char  arp_hln;
                    106:        u_char  arp_pln;
                    107:        u_short arp_op;
                    108: #define ARPOP_REQUEST  1
                    109: #define ARPOP_REPLY    2
                    110:        u_char  arp_sha[6];     /* sender ether addr */
                    111:        u_char  arp_spa[4];     /* sender internet addr */
                    112:        u_char  arp_tha[6];     /* target ether addr */
                    113:        u_char  arp_tpa[4];     /* target internet addr */
                    114: };
                    115: 
                    116: u_char broadaddr[6] = {
                    117:        0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                    118: };
                    119: 
                    120: /* wait for ARP requests and answers */
                    121: doarp(ipfd, enfd, myinaddr)
                    122: int ipfd;
                    123: int enfd;
                    124: in_addr myinaddr;
                    125: {
                    126:        u_char myenaddr[6];
                    127:        fd_set rdfds;
                    128:        int x;
                    129:        char buf[2000];
                    130:        struct goo{
                    131:                in_addr inaddr;
                    132:                u_char enaddr[6];
                    133:        } goo;
                    134:        in_addr tpa;
                    135: 
                    136:        x = htons((u_short)ETHERPUP_ARPTYPE);
                    137:        if(ioctl(enfd, ENIOTYPE, &x) < 0){
                    138:                perror("ENIOTYPE");
                    139:                exit(1);
                    140:        }
                    141:        if(ioctl(enfd, ENIOADDR, myenaddr) < 0){
                    142:                perror("ENIOADDR");
                    143:                exit(1);
                    144:        }
                    145: 
                    146:        FD_ZERO(rdfds);
                    147:        while(1){
                    148:                FD_SET(ipfd, rdfds);
                    149:                FD_SET(enfd, rdfds);
                    150: 
                    151:                if(select(20, &rdfds, 0, 2000) < 0){
                    152:                        if(errno == EINTR)
                    153:                                continue;
                    154:                        perror("select");
                    155:                        exit(1);
                    156:                }
                    157:                if(FD_ISSET(ipfd, rdfds)){
                    158:                        if(read(ipfd, &tpa, sizeof(tpa)) != sizeof(tpa))
                    159:                                perror("in read");
                    160:                        arpwhohas(enfd, ipfd, myenaddr, myinaddr, tpa);
                    161:                }
                    162:                if(FD_ISSET(enfd, rdfds)){
                    163:                        if(read(enfd, buf, sizeof(buf)) <= 0)
                    164:                                perror("en read");
                    165:                        arpinput(ipfd, enfd, myenaddr, myinaddr, buf);
                    166:                }
                    167:        }
                    168: }
                    169: 
                    170: /* broadcast an arp request */
                    171: arpwhohas(enfd, ipfd, myenaddr, myinaddr, addr)
                    172: u_char myenaddr[6];
                    173: in_addr addr, myinaddr;
                    174: {
                    175:        struct goo{
                    176:                in_addr inaddr;
                    177:                u_char enaddr[6];
                    178:        } goo;
                    179:        struct ether_arp a;
                    180: 
                    181:        if(addr == (myinaddr & 0xffffff00)){
                    182:                goo.inaddr = addr;
                    183:                bcopy(broadaddr, goo.enaddr, sizeof(goo.enaddr));
                    184:                ioctl(ipfd, IPIORESOLVE, &goo);
                    185:                return;
                    186:        }
                    187:        if(addr == myinaddr){
                    188:                goo.inaddr = addr;
                    189:                bcopy(myenaddr, goo.enaddr, sizeof(goo.enaddr));
                    190:                ioctl(ipfd, IPIORESOLVE, &goo);
                    191:                return;
                    192:        }
                    193:        bcopy(broadaddr, a.arp_ether.dhost, sizeof(a.arp_ether.dhost));
                    194:        a.arp_ether.type = htons(ETHERPUP_ARPTYPE);
                    195: 
                    196:        a.arp_hrd = htons(ARPHRD_ETHER);
                    197:        a.arp_pro = htons(ETHERPUP_IPTYPE);
                    198:        a.arp_hln = sizeof(goo.enaddr);
                    199:        a.arp_pln = sizeof(in_addr);
                    200:        a.arp_op = htons(ARPOP_REQUEST);
                    201: 
                    202:        bcopy(myenaddr, a.arp_sha, sizeof(a.arp_sha));
                    203:        myinaddr = htonl(myinaddr);
                    204:        bcopy(&myinaddr, a.arp_spa, sizeof(a.arp_spa));
                    205:        addr = htonl(addr);
                    206:        bcopy(&addr, a.arp_tpa, sizeof(a.arp_tpa));
                    207: 
                    208:        write(enfd, &a, sizeof(a));
                    209: }
                    210: 
                    211: /* process an arp request */
                    212: arpinput(ipfd, enfd, myenaddr, myinaddr, ap)
                    213: u_char myenaddr[6];
                    214: in_addr myinaddr;
                    215: struct ether_arp *ap;
                    216: {
                    217:        struct goo{
                    218:                in_addr inaddr;
                    219:                u_char enaddr[6];
                    220:        } goo;
                    221:        in_addr spa, tpa;
                    222: 
                    223:        bcopy(ap->arp_spa, &spa, sizeof(spa));
                    224:        bcopy(ap->arp_tpa, &tpa, sizeof(tpa));
                    225:        spa = ntohl(spa);
                    226:        tpa = ntohl(tpa);
                    227: 
                    228:        if(ntohs(ap->arp_pro) != ETHERPUP_IPTYPE)
                    229:                return;
                    230: 
                    231:        /* make sure noone's trying to be me */
                    232:        if(memcmp(ap->arp_sha, myenaddr, sizeof(myenaddr)) != 0){
                    233:                if(spa == myinaddr){
                    234:                        printf("ipconfig: forgery from me!!!\n");
                    235:                        printf("ipconfig: enaddr = ");
                    236:                        enpr(ap->arp_ether.shost);
                    237:                        return;
                    238:                }
                    239:        }
                    240: 
                    241:        /* incorporate sender's address */
                    242:        goo.inaddr = spa;
                    243:        bcopy(ap->arp_sha, goo.enaddr, sizeof(goo.enaddr));
                    244:        if(ioctl(ipfd, IPIORESOLVE, &goo) < 0)
                    245:                perror("IPIORESOLVE");
                    246: 
                    247:        /* send reply to a request */
                    248:        if(ap->arp_op != ntohs(ARPOP_REQUEST))
                    249:                return;
                    250:        if(tpa != myinaddr) 
                    251:                return;
                    252:        ap->arp_hrd = htons(ARPHRD_ETHER);
                    253:        ap->arp_pro = htons(ETHERPUP_IPTYPE);
                    254:        ap->arp_op = htons(ARPOP_REPLY);
                    255:        tpa = htonl(spa);
                    256:        spa = htonl(myinaddr);
                    257:        bcopy(&tpa, ap->arp_tpa, sizeof(ap->arp_tpa));
                    258:        bcopy(&spa, ap->arp_spa, sizeof(ap->arp_spa));
                    259:        bcopy(ap->arp_sha, ap->arp_tha, sizeof(ap->arp_tha));
                    260:        bcopy(myenaddr, ap->arp_sha, sizeof(ap->arp_sha));
                    261:        bcopy(broadaddr, ap->arp_ether.dhost, sizeof(ap->arp_ether.dhost));
                    262:        ap->arp_ether.type = htons(ETHERPUP_ARPTYPE);
                    263: 
                    264:        write(enfd, ap, sizeof(struct ether_arp));
                    265: }
                    266: 
                    267: arppr(a)
                    268: struct ether_arp a;
                    269: {
                    270:        in_addr spa, tpa;
                    271: 
                    272:        printf("dhost "); enpr(a.arp_ether.dhost);
                    273:        printf("shost "); enpr(a.arp_ether.shost);
                    274:        printf("type  %x\n", ntohs(a.arp_ether.type));
                    275:        a.arp_hrd = ntohs(a.arp_hrd);
                    276:        a.arp_pro = ntohs(a.arp_pro);
                    277:        a.arp_op = ntohs(a.arp_op);
                    278: 
                    279:        bcopy(a.arp_spa, &spa, sizeof(spa));
                    280:        bcopy(a.arp_tpa, &tpa, sizeof(tpa));
                    281:        tpa = ntohl(tpa);
                    282:        spa = ntohl(spa);
                    283: 
                    284:        printf("hrd %d pro %x op %d spa %x tpa %x\n",
                    285:                a.arp_hrd, a.arp_pro, a.arp_op, spa, tpa);
                    286:        printf("sha "); enpr(a.arp_sha);
                    287:        printf("tha "); enpr(a.arp_tha);
                    288: }
                    289: 
                    290: enpr(en)
                    291: u_char *en;
                    292: {
                    293:        int i;
                    294: 
                    295:        for(i = 0; i < 6; i++)
                    296:                printf("%02x ", (en[i])&0xff);
                    297:        printf("\n");
                    298: }

unix.superglobalmegacorp.com

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