Annotation of 43BSDTahoe/etc/arp.c, revision 1.1.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.