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: }

Defined functions

delete defined in line 196; used 1 times
  • in line 44
dump defined in line 246; used 1 times
  • in line 32
ether_aton defined in line 316; used 1 times
ether_print defined in line 310; used 2 times
file defined in line 58; used 1 times
  • in line 48
get defined in line 144; used 1 times
  • in line 36
main defined in line 22; never used
set defined in line 89; used 2 times
usage defined in line 333; used 1 times
  • in line 51

Defined variables

nl defined in line 235; used 4 times
sccsid defined in line 2; never used

Defined macros

X_ARPTAB defined in line 236; used 1 times
X_ARPTAB_SIZE defined in line 238; used 2 times
Last modified: 1986-02-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1748
Valid CSS Valid XHTML 1.0 Strict