# 2.11BSD#431 - /usr/src/usr.sbin/arp/arp.c

##### Functions

    delete            X
    dump              X
    ether_aton        X
    ether_print       X
    file              X
    get               X
    main              X
    set               X
    usage             X

##### Variables

    base2_10          X
    kl                X
    nl                X
    unix2_10          X

##### Macros

    X_ARPTAB          X
    X_ARPTAB_SIZE     X
    X_NETDATA         X

       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

- in line 127

ether_print defined in line 351; used 2 times

- in line 197, 341

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

- in line 45, 91

usage defined in line 374; used 1 times

- in line 58

#### Defined variables

base2_10 defined in line 258; used 4 times

- in line 298-299(3), 315

kl defined in line 259; used 3 times

- in line 281-282(2), 297

nl defined in line 248; used 6 times

- in line 279, 287, 299-301(2), 315-317(2)

sccsid defined in line 2; never used
unix2_10 defined in line 257; used 2 times

- in line 281-283(2)

#### Defined macros

X_ARPTAB defined in line 249; used 2 times

- in line 315-317(2)

X_ARPTAB_SIZE defined in line 251; used 3 times

- in line 287, 299-301(2)

X_NETDATA defined in line 260; used 2 times

- in line 282, 297

Last modified: 1994-01-11 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2075 |