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