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

unix.superglobalmegacorp.com

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