Annotation of 43BSDTahoe/etc/arp.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1984 Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * This code is derived from software contributed to Berkeley by
        !             6:  * Sun Microsystems, Inc.
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms are permitted
        !             9:  * provided that the above copyright notice and this paragraph are
        !            10:  * duplicated in all such forms and that any documentation,
        !            11:  * advertising materials, and other materials related to such
        !            12:  * distribution and use acknowledge that the software was developed
        !            13:  * by the University of California, Berkeley.  The name of the
        !            14:  * University may not be used to endorse or promote products derived
        !            15:  * from this software without specific prior written permission.
        !            16:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
        !            17:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
        !            18:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            19:  */
        !            20: 
        !            21: #ifndef lint
        !            22: char copyright[] =
        !            23: "@(#) Copyright (c) 1984 Regents of the University of California.\n\
        !            24:  All rights reserved.\n";
        !            25: #endif /* not lint */
        !            26: 
        !            27: #ifndef lint
        !            28: static char sccsid[] = "@(#)arp.c      5.6 (Berkeley) 6/30/88";
        !            29: #endif /* not lint */
        !            30: 
        !            31: /*
        !            32:  * arp - display, set, and delete arp table entries
        !            33:  */
        !            34: 
        !            35: #include <machine/pte.h>
        !            36: 
        !            37: #include <sys/param.h>
        !            38: #include <sys/vmmac.h>
        !            39: #include <sys/file.h>
        !            40: #include <sys/socket.h>
        !            41: #include <sys/ioctl.h>
        !            42: 
        !            43: #include <netdb.h>
        !            44: #include <netinet/in.h>
        !            45: #include <net/if.h>
        !            46: #include <netinet/if_ether.h>
        !            47: 
        !            48: #include <errno.h>
        !            49: #include <nlist.h>
        !            50: #include <stdio.h>
        !            51: 
        !            52: extern int errno;
        !            53: static int kflag;
        !            54: 
        !            55: main(argc, argv)
        !            56:        int argc;
        !            57:        char **argv;
        !            58: {
        !            59:        int ch;
        !            60: 
        !            61:        while ((ch = getopt(argc, argv, "adsf")) != EOF)
        !            62:                switch((char)ch) {
        !            63:                case 'a': {
        !            64:                        char *mem;
        !            65: 
        !            66:                        if (argc > 4)
        !            67:                                usage();
        !            68:                        if (argc == 4) {
        !            69:                                kflag = 1;
        !            70:                                mem = argv[3];
        !            71:                        }
        !            72:                        else
        !            73:                                mem = "/dev/kmem";
        !            74:                        dump((argc >= 3) ? argv[2] : "/vmunix", mem);
        !            75:                        exit(0);
        !            76:                }
        !            77:                case 'd':
        !            78:                        if (argc != 3)
        !            79:                                usage();
        !            80:                        delete(argv[2]);
        !            81:                        exit(0);
        !            82:                case 's':
        !            83:                        if (argc < 4 || argc > 7)
        !            84:                                usage();
        !            85:                        exit(set(argc-2, &argv[2]) ? 1 : 0);
        !            86:                case 'f':
        !            87:                        if (argc != 3)
        !            88:                                usage();
        !            89:                        exit (file(argv[2]) ? 1 : 0);
        !            90:                case '?':
        !            91:                default:
        !            92:                        usage();
        !            93:                }
        !            94:        if (argc != 2)
        !            95:                usage();
        !            96:        get(argv[1]);
        !            97:        exit(0);
        !            98: }
        !            99: 
        !           100: /*
        !           101:  * Process a file to set standard arp entries
        !           102:  */
        !           103: file(name)
        !           104:        char *name;
        !           105: {
        !           106:        FILE *fp;
        !           107:        int i, retval;
        !           108:        char line[100], arg[5][50], *args[5];
        !           109: 
        !           110:        if ((fp = fopen(name, "r")) == NULL) {
        !           111:                fprintf(stderr, "arp: cannot open %s\n", name);
        !           112:                exit(1);
        !           113:        }
        !           114:        args[0] = &arg[0][0];
        !           115:        args[1] = &arg[1][0];
        !           116:        args[2] = &arg[2][0];
        !           117:        args[3] = &arg[3][0];
        !           118:        args[4] = &arg[4][0];
        !           119:        retval = 0;
        !           120:        while(fgets(line, 100, fp) != NULL) {
        !           121:                i = sscanf(line, "%s %s %s %s %s", arg[0], arg[1], arg[2],
        !           122:                    arg[3], arg[4]);
        !           123:                if (i < 2) {
        !           124:                        fprintf(stderr, "arp: bad line: %s\n", line);
        !           125:                        retval = 1;
        !           126:                        continue;
        !           127:                }
        !           128:                if (set(i, args))
        !           129:                        retval = 1;
        !           130:        }
        !           131:        fclose(fp);
        !           132:        return (retval);
        !           133: }
        !           134: 
        !           135: /*
        !           136:  * Set an individual arp entry 
        !           137:  */
        !           138: set(argc, argv)
        !           139:        int argc;
        !           140:        char **argv;
        !           141: {
        !           142:        struct arpreq ar;
        !           143:        struct hostent *hp;
        !           144:        struct sockaddr_in *sin;
        !           145:        u_char *ea;
        !           146:        int s;
        !           147:        char *host = argv[0], *eaddr = argv[1];
        !           148: 
        !           149:        argc -= 2;
        !           150:        argv += 2;
        !           151:        bzero((caddr_t)&ar, sizeof ar);
        !           152:        sin = (struct sockaddr_in *)&ar.arp_pa;
        !           153:        sin->sin_family = AF_INET;
        !           154:        sin->sin_addr.s_addr = inet_addr(host);
        !           155:        if (sin->sin_addr.s_addr == -1) {
        !           156:                hp = gethostbyname(host);
        !           157:                if (hp == NULL) {
        !           158:                        fprintf(stderr, "arp: %s: unknown host\n", host);
        !           159:                        return (1);
        !           160:                }
        !           161:                bcopy((char *)hp->h_addr, (char *)&sin->sin_addr,
        !           162:                    sizeof sin->sin_addr);
        !           163:        }
        !           164:        ea = (u_char *)ar.arp_ha.sa_data;
        !           165:        if (ether_aton(eaddr, ea))
        !           166:                return (1);
        !           167:        ar.arp_flags = ATF_PERM;
        !           168:        while (argc-- > 0) {
        !           169:                if (strncmp(argv[0], "temp", 4) == 0)
        !           170:                        ar.arp_flags &= ~ATF_PERM;
        !           171:                else if (strncmp(argv[0], "pub", 3) == 0)
        !           172:                        ar.arp_flags |= ATF_PUBL;
        !           173:                else if (strncmp(argv[0], "trail", 5) == 0)
        !           174:                        ar.arp_flags |= ATF_USETRAILERS;
        !           175:                argv++;
        !           176:        }
        !           177:        
        !           178:        s = socket(AF_INET, SOCK_DGRAM, 0);
        !           179:        if (s < 0) {
        !           180:                perror("arp: socket");
        !           181:                exit(1);
        !           182:        }
        !           183:        if (ioctl(s, SIOCSARP, (caddr_t)&ar) < 0) {
        !           184:                perror(host);
        !           185:                exit(1);
        !           186:        }
        !           187:        close(s);
        !           188:        return (0);
        !           189: }
        !           190: 
        !           191: /*
        !           192:  * Display an individual arp entry
        !           193:  */
        !           194: get(host)
        !           195:        char *host;
        !           196: {
        !           197:        struct arpreq ar;
        !           198:        struct hostent *hp;
        !           199:        struct sockaddr_in *sin;
        !           200:        u_char *ea;
        !           201:        int s;
        !           202:        char *inet_ntoa();
        !           203: 
        !           204:        bzero((caddr_t)&ar, sizeof ar);
        !           205:        ar.arp_pa.sa_family = AF_INET;
        !           206:        sin = (struct sockaddr_in *)&ar.arp_pa;
        !           207:        sin->sin_family = AF_INET;
        !           208:        sin->sin_addr.s_addr = inet_addr(host);
        !           209:        if (sin->sin_addr.s_addr == -1) {
        !           210:                hp = gethostbyname(host);
        !           211:                if (hp == NULL) {
        !           212:                        fprintf(stderr, "arp: %s: unknown host\n", host);
        !           213:                        exit(1);
        !           214:                }
        !           215:                bcopy((char *)hp->h_addr, (char *)&sin->sin_addr,
        !           216:                    sizeof sin->sin_addr);
        !           217:        }
        !           218:        s = socket(AF_INET, SOCK_DGRAM, 0);
        !           219:        if (s < 0) {
        !           220:                perror("arp: socket");
        !           221:                exit(1);
        !           222:        }
        !           223:        if (ioctl(s, SIOCGARP, (caddr_t)&ar) < 0) {
        !           224:                if (errno == ENXIO)
        !           225:                        printf("%s (%s) -- no entry\n",
        !           226:                            host, inet_ntoa(sin->sin_addr));
        !           227:                else
        !           228:                        perror("SIOCGARP");
        !           229:                exit(1);
        !           230:        }
        !           231:        close(s);
        !           232:        ea = (u_char *)ar.arp_ha.sa_data;
        !           233:        printf("%s (%s) at ", host, inet_ntoa(sin->sin_addr));
        !           234:        if (ar.arp_flags & ATF_COM)
        !           235:                ether_print(ea);
        !           236:        else
        !           237:                printf("(incomplete)");
        !           238:        if (ar.arp_flags & ATF_PERM)
        !           239:                printf(" permanent");
        !           240:        if (ar.arp_flags & ATF_PUBL)
        !           241:                printf(" published");
        !           242:        if (ar.arp_flags & ATF_USETRAILERS)
        !           243:                printf(" trailers");
        !           244:        printf("\n");
        !           245: }
        !           246: 
        !           247: /*
        !           248:  * Delete an arp entry 
        !           249:  */
        !           250: delete(host)
        !           251:        char *host;
        !           252: {
        !           253:        struct arpreq ar;
        !           254:        struct hostent *hp;
        !           255:        struct sockaddr_in *sin;
        !           256:        int s;
        !           257: 
        !           258:        bzero((caddr_t)&ar, sizeof ar);
        !           259:        ar.arp_pa.sa_family = AF_INET;
        !           260:        sin = (struct sockaddr_in *)&ar.arp_pa;
        !           261:        sin->sin_family = AF_INET;
        !           262:        sin->sin_addr.s_addr = inet_addr(host);
        !           263:        if (sin->sin_addr.s_addr == -1) {
        !           264:                hp = gethostbyname(host);
        !           265:                if (hp == NULL) {
        !           266:                        fprintf(stderr, "arp: %s: unknown host\n", host);
        !           267:                        exit(1);
        !           268:                }
        !           269:                bcopy((char *)hp->h_addr, (char *)&sin->sin_addr,
        !           270:                    sizeof sin->sin_addr);
        !           271:        }
        !           272:        s = socket(AF_INET, SOCK_DGRAM, 0);
        !           273:        if (s < 0) {
        !           274:                perror("arp: socket");
        !           275:                exit(1);
        !           276:        }
        !           277:        if (ioctl(s, SIOCDARP, (caddr_t)&ar) < 0) {
        !           278:                if (errno == ENXIO)
        !           279:                        printf("%s (%s) -- no entry\n",
        !           280:                            host, inet_ntoa(sin->sin_addr));
        !           281:                else
        !           282:                        perror("SIOCDARP");
        !           283:                exit(1);
        !           284:        }
        !           285:        close(s);
        !           286:        printf("%s (%s) deleted\n", host, inet_ntoa(sin->sin_addr));
        !           287: }
        !           288: 
        !           289: struct nlist nl[] = {
        !           290: #define        X_ARPTAB        0
        !           291:        { "_arptab" },
        !           292: #define        X_ARPTAB_SIZE   1
        !           293:        { "_arptab_size" },
        !           294: #define        N_SYSMAP        2
        !           295:        { "_Sysmap" },
        !           296: #define        N_SYSSIZE       3
        !           297:        { "_Syssize" },
        !           298:        { "" },
        !           299: };
        !           300: 
        !           301: static struct pte *Sysmap;
        !           302: 
        !           303: /*
        !           304:  * Dump the entire arp table
        !           305:  */
        !           306: dump(kernel, mem)
        !           307:        char *kernel, *mem;
        !           308: {
        !           309:        extern int h_errno;
        !           310:        struct arptab *at;
        !           311:        struct hostent *hp;
        !           312:        int bynumber, mf, arptab_size, sz;
        !           313:        char *host, *malloc();
        !           314:        off_t lseek();
        !           315: 
        !           316:        if (nlist(kernel, nl) < 0 || nl[X_ARPTAB_SIZE].n_type == 0) {
        !           317:                fprintf(stderr, "arp: %s: bad namelist\n", kernel);
        !           318:                exit(1);
        !           319:        }
        !           320:        mf = open(mem, O_RDONLY);
        !           321:        if (mf < 0) {
        !           322:                fprintf(fprintf, "arp: cannot open %s\n", mem);
        !           323:                exit(1);
        !           324:        }
        !           325:        if (kflag) {
        !           326:                off_t off;
        !           327: 
        !           328:                Sysmap = (struct pte *)
        !           329:                   malloc((u_int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
        !           330:                if (!Sysmap) {
        !           331:                        fputs("arp: can't get memory for Sysmap.\n", stderr);
        !           332:                        exit(1);
        !           333:                }
        !           334:                off = nl[N_SYSMAP].n_value & ~KERNBASE;
        !           335:                (void)lseek(mf, off, L_SET);
        !           336:                (void)read(mf, (char *)Sysmap,
        !           337:                    (int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
        !           338:        }
        !           339:        klseek(mf, (long)nl[X_ARPTAB_SIZE].n_value, L_SET);
        !           340:        read(mf, &arptab_size, sizeof arptab_size);
        !           341:        if (arptab_size <= 0 || arptab_size > 1000) {
        !           342:                fprintf(stderr, "arp: %s: namelist wrong\n", kernel);
        !           343:                exit(1);
        !           344:        }
        !           345:        sz = arptab_size * sizeof (struct arptab);
        !           346:        at = (struct arptab *)malloc((u_int)sz);
        !           347:        if (at == NULL) {
        !           348:                fputs("arp: can't get memory for arptab.\n", stderr);
        !           349:                exit(1);
        !           350:        }
        !           351:        klseek(mf, (long)nl[X_ARPTAB].n_value, L_SET);
        !           352:        if (read(mf, (char *)at, sz) != sz) {
        !           353:                perror("arp: error reading arptab");
        !           354:                exit(1);
        !           355:        }
        !           356:        close(mf);
        !           357:        for (bynumber = 0; arptab_size-- > 0; at++) {
        !           358:                if (at->at_iaddr.s_addr == 0 || at->at_flags == 0)
        !           359:                        continue;
        !           360:                if (bynumber == 0)
        !           361:                        hp = gethostbyaddr((caddr_t)&at->at_iaddr,
        !           362:                            sizeof at->at_iaddr, AF_INET);
        !           363:                else
        !           364:                        hp = 0;
        !           365:                if (hp)
        !           366:                        host = hp->h_name;
        !           367:                else {
        !           368:                        host = "?";
        !           369:                        if (h_errno == TRY_AGAIN)
        !           370:                                bynumber = 1;
        !           371:                }
        !           372:                printf("%s (%s) at ", host, inet_ntoa(at->at_iaddr));
        !           373:                if (at->at_flags & ATF_COM)
        !           374:                        ether_print(at->at_enaddr);
        !           375:                else
        !           376:                        printf("(incomplete)");
        !           377:                if (at->at_flags & ATF_PERM)
        !           378:                        printf(" permanent");
        !           379:                if (at->at_flags & ATF_PUBL)
        !           380:                        printf(" published");
        !           381:                if (at->at_flags & ATF_USETRAILERS)
        !           382:                        printf(" trailers");
        !           383:                printf("\n");
        !           384:        }
        !           385: }
        !           386: 
        !           387: /*
        !           388:  * Seek into the kernel for a value.
        !           389:  */
        !           390: klseek(fd, base, off)
        !           391:        int fd, off;
        !           392:        off_t base;
        !           393: {
        !           394:        off_t lseek();
        !           395: 
        !           396:        if (kflag) {    /* get kernel pte */
        !           397:                base &= ~KERNBASE;
        !           398:                base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET);
        !           399:        }
        !           400:        (void)lseek(fd, base, off);
        !           401: }
        !           402: 
        !           403: ether_print(cp)
        !           404:        u_char *cp;
        !           405: {
        !           406:        printf("%x:%x:%x:%x:%x:%x", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]);
        !           407: }
        !           408: 
        !           409: ether_aton(a, n)
        !           410:        char *a;
        !           411:        u_char *n;
        !           412: {
        !           413:        int i, o[6];
        !           414: 
        !           415:        i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o[0], &o[1], &o[2],
        !           416:                                           &o[3], &o[4], &o[5]);
        !           417:        if (i != 6) {
        !           418:                fprintf(stderr, "arp: invalid Ethernet address '%s'\n", a);
        !           419:                return (1);
        !           420:        }
        !           421:        for (i=0; i<6; i++)
        !           422:                n[i] = o[i];
        !           423:        return (0);
        !           424: }
        !           425: 
        !           426: usage()
        !           427: {
        !           428:        printf("usage: arp hostname\n");
        !           429:        printf("       arp -a [/vmunix] [/dev/kmem]\n");
        !           430:        printf("       arp -d hostname\n");
        !           431:        printf("       arp -s hostname ether_addr [temp] [pub] [trail]\n");
        !           432:        printf("       arp -f filename\n");
        !           433:        exit(1);
        !           434: }

unix.superglobalmegacorp.com

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