|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.