Annotation of 43BSD/etc/arp.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char *sccsid = "@(#)arp.c       5.2 (Berkeley) 2/21/86";
                      3: #endif
                      4: 
                      5: /*
                      6:  * arp - display, set, and delete arp table entries
                      7:  */
                      8: 
                      9: #include <stdio.h>
                     10: #include <sys/types.h>
                     11: #include <sys/socket.h>
                     12: #include <netinet/in.h>
                     13: #include <sys/ioctl.h>
                     14: #include <errno.h>
                     15: #include <netdb.h>
                     16: #include <nlist.h>
                     17: #include <net/if.h>
                     18: #include <netinet/if_ether.h>
                     19: 
                     20: extern int errno;
                     21: 
                     22: main(argc, argv)
                     23:        char **argv;
                     24: {
                     25:        if (argc >= 2 && strcmp(argv[1], "-a") == 0) {
                     26:                char *kernel = "/vmunix", *mem = "/dev/kmem";
                     27: 
                     28:                if (argc >= 3)
                     29:                        kernel = argv[2];
                     30:                if (argc >= 4)
                     31:                        mem = argv[3];
                     32:                dump(kernel, mem);
                     33:                exit(0);
                     34:        }
                     35:        if (argc == 2) {
                     36:                get(argv[1]);
                     37:                exit(0);
                     38:        }
                     39:        if (argc >= 4 && strcmp(argv[1], "-s") == 0) {
                     40:                set(argc-2, &argv[2]);
                     41:                exit(0);
                     42:        }
                     43:        if (argc == 3 && strcmp(argv[1], "-d") == 0) {
                     44:                delete(argv[2]);
                     45:                exit(0);
                     46:        }
                     47:        if (argc == 3 && strcmp(argv[1], "-f") == 0) {
                     48:                file(argv[2]);
                     49:                exit(0);
                     50:        }
                     51:        usage();
                     52:        exit(1);
                     53: }
                     54: 
                     55: /*
                     56:  * Process a file to set standard arp entries
                     57:  */
                     58: file(name)
                     59:        char *name;
                     60: {
                     61:        FILE *fp;
                     62:        int i;
                     63:        char line[100], arg[5][50], *args[5];
                     64: 
                     65:        if ((fp = fopen(name, "r")) == NULL) {
                     66:                fprintf(stderr, "arp: cannot open %s\n", name);
                     67:                exit(1);
                     68:        }
                     69:        args[0] = &arg[0][0];
                     70:        args[1] = &arg[1][0];
                     71:        args[2] = &arg[2][0];
                     72:        args[3] = &arg[3][0];
                     73:        args[4] = &arg[4][0];
                     74:        while(fgets(line, 100, fp) != NULL) {
                     75:                i = sscanf(line, "%s %s %s %s", arg[0], arg[1], arg[2], arg[3],
                     76:                        arg[4]);
                     77:                if (i < 2) {
                     78:                        fprintf(stderr, "arp: bad line: %s\n", line);
                     79:                        continue;
                     80:                }
                     81:                set(i, args);
                     82:        }
                     83:        fclose(fp);
                     84: }
                     85: 
                     86: /*
                     87:  * Set an individual arp entry 
                     88:  */
                     89: set(argc, argv)
                     90:        char **argv;
                     91: {
                     92:        struct arpreq ar;
                     93:        struct hostent *hp;
                     94:        struct sockaddr_in *sin;
                     95:        u_char *ea;
                     96:        int s;
                     97:        char *host = argv[0], *eaddr = argv[1];
                     98: 
                     99:        argc -= 2;
                    100:        argv += 2;
                    101:        bzero((caddr_t)&ar, sizeof ar);
                    102:        sin = (struct sockaddr_in *)&ar.arp_pa;
                    103:        sin->sin_family = AF_INET;
                    104:        sin->sin_addr.s_addr = inet_addr(host);
                    105:        if (sin->sin_addr.s_addr == -1) {
                    106:                hp = gethostbyname(host);
                    107:                if (hp == NULL) {
                    108:                        fprintf(stderr, "arp: %s: unknown host\n", host);
                    109:                        return;
                    110:                }
                    111:                bcopy((char *)hp->h_addr, (char *)&sin->sin_addr,
                    112:                    sizeof sin->sin_addr);
                    113:        }
                    114:        ea = (u_char *)ar.arp_ha.sa_data;
                    115:        if (ether_aton(eaddr, ea))
                    116:                return;
                    117:        ar.arp_flags = ATF_PERM;
                    118:        while (argc-- > 0) {
                    119:                if (strncmp(argv[0], "temp", 4) == 0)
                    120:                        ar.arp_flags &= ~ATF_PERM;
                    121:                if (strncmp(argv[0], "pub", 3) == 0)
                    122:                        ar.arp_flags |= ATF_PUBL;
                    123:                if (strncmp(argv[0], "trail", 5) == 0)
                    124:                        ar.arp_flags |= ATF_USETRAILERS;
                    125:                argv++;
                    126:        }
                    127:        
                    128:        s = socket(AF_INET, SOCK_DGRAM, 0);
                    129:        if (s < 0) {
                    130:                 perror("arp: socket");
                    131:                 exit(1);
                    132:         }
                    133:        if (ioctl(s, SIOCSARP, (caddr_t)&ar) < 0) {
                    134:                perror(host);
                    135:                exit(1);
                    136:        }
                    137:        close(s);
                    138: }
                    139: 
                    140: 
                    141: /*
                    142:  * Display an individual arp entry
                    143:  */
                    144: get(host)
                    145:        char *host;
                    146: {
                    147:        struct arpreq ar;
                    148:        struct hostent *hp;
                    149:        struct sockaddr_in *sin;
                    150:        u_char *ea;
                    151:        int s;
                    152: 
                    153:        bzero((caddr_t)&ar, sizeof ar);
                    154:        ar.arp_pa.sa_family = AF_INET;
                    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:                hp = gethostbyname(host);
                    160:                if (hp == NULL) {
                    161:                        fprintf(stderr, "arp: %s: unknown host\n", host);
                    162:                        exit(1);
                    163:                }
                    164:                bcopy((char *)hp->h_addr, (char *)&sin->sin_addr,
                    165:                    sizeof sin->sin_addr);
                    166:        }
                    167:        s = socket(AF_INET, SOCK_DGRAM, 0);
                    168:        if (s < 0) {
                    169:                 perror("arp: socket");
                    170:                 exit(1);
                    171:         }
                    172:        if (ioctl(s, SIOCGARP, (caddr_t)&ar) < 0) {
                    173:                if (errno == ENXIO)
                    174:                        printf("%s (%s) -- no entry\n",
                    175:                            host, inet_ntoa(sin->sin_addr));
                    176:                else
                    177:                        perror("SIOCGARP");
                    178:                exit(1);
                    179:        }
                    180:        close(s);
                    181:        ea = (u_char *)ar.arp_ha.sa_data;
                    182:        printf("%s (%s) at ", host, inet_ntoa(sin->sin_addr));
                    183:        if (ar.arp_flags & ATF_COM)
                    184:                ether_print(ea);
                    185:        else
                    186:                printf("(incomplete)");
                    187:        if (ar.arp_flags & ATF_PERM) printf(" permanent");
                    188:        if (ar.arp_flags & ATF_PUBL) printf(" published");
                    189:        if (ar.arp_flags & ATF_USETRAILERS) printf(" trailers");
                    190:        printf("\n");
                    191: }
                    192: 
                    193: /*
                    194:  * Delete an arp entry 
                    195:  */
                    196: delete(host)
                    197:        char *host;
                    198: {
                    199:        struct arpreq ar;
                    200:        struct hostent *hp;
                    201:        struct sockaddr_in *sin;
                    202:        int s;
                    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, SIOCDARP, (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("SIOCDARP");
                    229:                exit(1);
                    230:        }
                    231:        close(s);
                    232:        printf("%s (%s) deleted\n", host, inet_ntoa(sin->sin_addr));
                    233: }
                    234: 
                    235: struct nlist nl[] = {
                    236: #define        X_ARPTAB        0
                    237:        { "_arptab" },
                    238: #define        X_ARPTAB_SIZE   1
                    239:        { "_arptab_size" },
                    240:        { "" },
                    241: };
                    242: 
                    243: /*
                    244:  * Dump the entire arp table
                    245:  */
                    246: dump(kernel, mem)
                    247:        char *kernel, *mem;
                    248: {
                    249:        int mf, arptab_size, sz;
                    250:        struct arptab *at;
                    251:        struct hostent *hp;
                    252:        char *host;
                    253:        int bynumber = 0;
                    254: 
                    255:        nlist(kernel, nl);
                    256:        if(nl[X_ARPTAB_SIZE].n_type == 0) {
                    257:                fprintf(stderr, "arp: %s: bad namelist\n", kernel);
                    258:                exit(1);
                    259:        }
                    260:        mf = open(mem, 0);
                    261:        if(mf < 0) {
                    262:                fprintf(fprintf, "arp: cannot open %s\n", mem);
                    263:                exit(1);
                    264:        }
                    265:        lseek(mf, (long)nl[X_ARPTAB_SIZE].n_value, 0);
                    266:        read(mf, &arptab_size, sizeof arptab_size);
                    267:        if (arptab_size <=0 || arptab_size > 1000) {
                    268:                fprintf(stderr, "arp: %s: namelist wrong\n", kernel);
                    269:                exit(1);
                    270:        }
                    271:        sz = arptab_size * sizeof (struct arptab);
                    272:        at = (struct arptab *)malloc(sz);
                    273:        if (at == NULL) {
                    274:                fprintf(stderr, "arp: can't get memory for arptab\n");
                    275:                exit(1);
                    276:        }
                    277:        lseek(mf, (long)nl[X_ARPTAB].n_value, 0);
                    278:        if (read(mf, (char *)at, sz) != sz) {
                    279:                perror("arp: error reading arptab");
                    280:                exit(1);
                    281:        }
                    282:        close(mf);
                    283:        for (; arptab_size-- > 0; at++) {
                    284:                if (at->at_iaddr.s_addr == 0 || at->at_flags == 0)
                    285:                        continue;
                    286:                if (bynumber == 0)
                    287:                        hp = gethostbyaddr((caddr_t)&at->at_iaddr,
                    288:                            sizeof at->at_iaddr, AF_INET);
                    289:                else
                    290:                        hp = 0;
                    291:                if (hp)
                    292:                        host = hp->h_name;
                    293:                else {
                    294:                        host = "?";
                    295:                        if (h_errno == TRY_AGAIN)
                    296:                                bynumber = 1;
                    297:                }
                    298:                printf("%s (%s) at ", host, inet_ntoa(at->at_iaddr));
                    299:                if (at->at_flags & ATF_COM)
                    300:                        ether_print(at->at_enaddr);
                    301:                else
                    302:                        printf("(incomplete)");
                    303:                if (at->at_flags & ATF_PERM) printf(" permanent");
                    304:                if (at->at_flags & ATF_PUBL) printf(" published");
                    305:                if (at->at_flags & ATF_USETRAILERS) printf(" trailers");
                    306:                printf("\n");
                    307:        }
                    308: }
                    309: 
                    310: ether_print(cp)
                    311:        u_char *cp;
                    312: {
                    313:        printf("%x:%x:%x:%x:%x:%x", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]);
                    314: }
                    315: 
                    316: ether_aton(a, n)
                    317:        char *a;
                    318:        u_char *n;
                    319: {
                    320:        int i, o[6];
                    321: 
                    322:        i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o[0], &o[1], &o[2],
                    323:                                           &o[3], &o[4], &o[5]);
                    324:        if (i != 6) {
                    325:                fprintf(stderr, "arp: invalid Ethernet address '%s'\n", a);
                    326:                return (1);
                    327:        }
                    328:        for (i=0; i<6; i++)
                    329:                n[i] = o[i];
                    330:        return (0);
                    331: }
                    332: 
                    333: usage()
                    334: {
                    335:        printf("Usage: arp hostname\n");
                    336:        printf("       arp -a [/vmunix] [/dev/kmem]\n");
                    337:        printf("       arp -d hostname\n");
                    338:        printf("       arp -s hostname ether_addr [temp] [pub]\n");
                    339:        printf("       arp -f filename\n");
                    340: }

unix.superglobalmegacorp.com

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