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

Defined functions

delete defined in line 209; used 1 times
  • in line 50
dump defined in line 269; used 1 times
  • in line 37
ether_aton defined in line 357; used 1 times
ether_print defined in line 351; used 2 times
file defined in line 65; used 1 times
  • in line 54
get defined in line 157; used 1 times
  • in line 41
main defined in line 23; never used
set defined in line 101; used 2 times
usage defined in line 374; used 1 times
  • in line 58

Defined variables

base2_10 defined in line 258; used 4 times
kl defined in line 259; used 3 times
nl defined in line 248; used 6 times
sccsid defined in line 2; never used
unix2_10 defined in line 257; used 2 times

Defined macros

X_ARPTAB defined in line 249; used 2 times
X_ARPTAB_SIZE defined in line 251; used 3 times
X_NETDATA defined in line 260; used 2 times
Last modified: 1994-01-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5052
Valid CSS Valid XHTML 1.0 Strict