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