home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NETKIT-B.05 / NETKIT-B / NetKit-B-0.05 / arp / arp.c,v < prev    next >
Encoding:
Text File  |  1994-05-23  |  9.7 KB  |  435 lines

  1. head    1.1;
  2. access;
  3. symbols;
  4. locks
  5.     rzsfl:1.1; strict;
  6. comment    @ * @;
  7.  
  8.  
  9. 1.1
  10. date    94.05.23.08.58.37;    author rzsfl;    state Exp;
  11. branches;
  12. next    ;
  13.  
  14.  
  15. desc
  16. @Original
  17. @
  18.  
  19.  
  20. 1.1
  21. log
  22. @Initial revision
  23. @
  24. text
  25. @/*
  26.  * Copyright (c) 1984 Regents of the University of California.
  27.  * All rights reserved.
  28.  *
  29.  * This code is derived from software contributed to Berkeley by
  30.  * Sun Microsystems, Inc.
  31.  *
  32.  * Redistribution and use in source and binary forms, with or without
  33.  * modification, are permitted provided that the following conditions
  34.  * are met:
  35.  * 1. Redistributions of source code must retain the above copyright
  36.  *    notice, this list of conditions and the following disclaimer.
  37.  * 2. Redistributions in binary form must reproduce the above copyright
  38.  *    notice, this list of conditions and the following disclaimer in the
  39.  *    documentation and/or other materials provided with the distribution.
  40.  * 3. All advertising materials mentioning features or use of this software
  41.  *    must display the following acknowledgement:
  42.  *    This product includes software developed by the University of
  43.  *    California, Berkeley and its contributors.
  44.  * 4. Neither the name of the University nor the names of its contributors
  45.  *    may be used to endorse or promote products derived from this software
  46.  *    without specific prior written permission.
  47.  *
  48.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  49.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  50.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  51.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  52.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  53.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  54.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  55.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  56.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  57.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  58.  * SUCH DAMAGE.
  59.  */
  60.  
  61. #ifndef lint
  62. char copyright[] =
  63. "@@(#) Copyright (c) 1984 Regents of the University of California.\n\
  64.  All rights reserved.\n";
  65. #endif /* not lint */
  66.  
  67. #ifndef lint
  68. /*static char sccsid[] = "from: @@(#)arp.c    5.11.1.1 (Berkeley) 7/22/91";*/
  69. static char rcsid[] = "$Id: arp.c,v 1.4 1993/12/25 02:28:46 deraadt Exp $";
  70. #endif /* not lint */
  71.  
  72. /*
  73.  * arp - display, set, and delete arp table entries
  74.  */
  75.  
  76. #include <sys/param.h>
  77. #include <sys/file.h>
  78. #include <sys/socket.h>
  79. #include <sys/ioctl.h>
  80.  
  81. #include <netdb.h>
  82. #include <netinet/in.h>
  83. #include <net/if.h>
  84. #include <netinet/if_ether.h>
  85. #include <arpa/inet.h>
  86.  
  87. #include <errno.h>
  88. #include <nlist.h>
  89. #include <kvm.h>
  90. #include <stdio.h>
  91. #include <paths.h>
  92.  
  93. extern int errno;
  94.  
  95. main(argc, argv)
  96.     int argc;
  97.     char **argv;
  98. {
  99.     int ch;
  100.  
  101.     while ((ch = getopt(argc, argv, "adsf")) != EOF)
  102.         switch((char)ch) {
  103.         case 'a': {
  104.             char *mem = 0;
  105.  
  106.             if (argc > 4)
  107.                 usage();
  108.             if (argc == 4) {
  109.                 mem = argv[3];
  110.             }
  111.             dump((argc >= 3) ? argv[2] : _PATH_UNIX, mem);
  112.             exit(0);
  113.         }
  114.         case 'd':
  115.             if (argc != 3)
  116.                 usage();
  117.             delete(argv[2]);
  118.             exit(0);
  119.         case 's':
  120.             if (argc < 4 || argc > 7)
  121.                 usage();
  122.             exit(set(argc-2, &argv[2]) ? 1 : 0);
  123.         case 'f':
  124.             if (argc != 3)
  125.                 usage();
  126.             exit (file(argv[2]) ? 1 : 0);
  127.         case '?':
  128.         default:
  129.             usage();
  130.         }
  131.     if (argc != 2)
  132.         usage();
  133.     get(argv[1]);
  134.     exit(0);
  135. }
  136.  
  137. /*
  138.  * Process a file to set standard arp entries
  139.  */
  140. file(name)
  141.     char *name;
  142. {
  143.     FILE *fp;
  144.     int i, retval;
  145.     char line[100], arg[5][50], *args[5];
  146.  
  147.     setregid(getegid(), getgid());
  148.     if ((fp = fopen(name, "r")) == NULL) {
  149.         fprintf(stderr, "arp: cannot open %s\n", name);
  150.         exit(1);
  151.     }
  152.     setregid(getegid(), getgid());
  153.     args[0] = &arg[0][0];
  154.     args[1] = &arg[1][0];
  155.     args[2] = &arg[2][0];
  156.     args[3] = &arg[3][0];
  157.     args[4] = &arg[4][0];
  158.     retval = 0;
  159.     while(fgets(line, 100, fp) != NULL) {
  160.         i = sscanf(line, "%s %s %s %s %s", arg[0], arg[1], arg[2],
  161.             arg[3], arg[4]);
  162.         if (i < 2) {
  163.             fprintf(stderr, "arp: bad line: %s\n", line);
  164.             retval = 1;
  165.             continue;
  166.         }
  167.         if (set(i, args))
  168.             retval = 1;
  169.     }
  170.     fclose(fp);
  171.     return (retval);
  172. }
  173.  
  174. /*
  175.  * Set an individual arp entry 
  176.  */
  177. set(argc, argv)
  178.     int argc;
  179.     char **argv;
  180. {
  181.     struct arpreq ar;
  182.     struct hostent *hp;
  183.     struct sockaddr_in *sin;
  184.     u_char *ea;
  185.     int s;
  186.     char *host = argv[0], *eaddr = argv[1];
  187.  
  188.     argc -= 2;
  189.     argv += 2;
  190.     bzero((caddr_t)&ar, sizeof ar);
  191.     sin = (struct sockaddr_in *)&ar.arp_pa;
  192.     sin->sin_family = AF_INET;
  193.     sin->sin_addr.s_addr = inet_addr(host);
  194.     if (sin->sin_addr.s_addr == -1) {
  195.         if (!(hp = gethostbyname(host))) {
  196.             fprintf(stderr, "arp: %s: ", host);
  197.             herror((char *)NULL);
  198.             return (1);
  199.         }
  200.         bcopy((char *)hp->h_addr, (char *)&sin->sin_addr,
  201.             sizeof sin->sin_addr);
  202.     }
  203.     ea = (u_char *)ar.arp_ha.sa_data;
  204.     if (ether_aton(eaddr, ea))
  205.         return (1);
  206.     ar.arp_flags = ATF_PERM;
  207.     while (argc-- > 0) {
  208.         if (strncmp(argv[0], "temp", 4) == 0)
  209.             ar.arp_flags &= ~ATF_PERM;
  210.         else if (strncmp(argv[0], "pub", 3) == 0)
  211.             ar.arp_flags |= ATF_PUBL;
  212.         else if (strncmp(argv[0], "trail", 5) == 0)
  213.             ar.arp_flags |= ATF_USETRAILERS;
  214.         argv++;
  215.     }
  216.     
  217.     s = socket(AF_INET, SOCK_DGRAM, 0);
  218.     if (s < 0) {
  219.         perror("arp: socket");
  220.         exit(1);
  221.     }
  222.     if (ioctl(s, SIOCSARP, (caddr_t)&ar) < 0) {
  223.         perror(host);
  224.         exit(1);
  225.     }
  226.     close(s);
  227.     return (0);
  228. }
  229.  
  230. /*
  231.  * Display an individual arp entry
  232.  */
  233. get(host)
  234.     char *host;
  235. {
  236.     struct arpreq ar;
  237.     struct hostent *hp;
  238.     struct sockaddr_in *sin;
  239.     u_char *ea;
  240.     int s;
  241.  
  242.     bzero((caddr_t)&ar, sizeof ar);
  243.     ar.arp_pa.sa_family = AF_INET;
  244.     sin = (struct sockaddr_in *)&ar.arp_pa;
  245.     sin->sin_family = AF_INET;
  246.     sin->sin_addr.s_addr = inet_addr(host);
  247.     if (sin->sin_addr.s_addr == -1) {
  248.         if (!(hp = gethostbyname(host))) {
  249.             fprintf(stderr, "arp: %s: ", host);
  250.             herror((char *)NULL);
  251.             exit(1);
  252.         }
  253.         bcopy((char *)hp->h_addr, (char *)&sin->sin_addr,
  254.             sizeof sin->sin_addr);
  255.     }
  256.     s = socket(AF_INET, SOCK_DGRAM, 0);
  257.     if (s < 0) {
  258.         perror("arp: socket");
  259.         exit(1);
  260.     }
  261.     if (ioctl(s, SIOCGARP, (caddr_t)&ar) < 0) {
  262.         if (errno == ENXIO)
  263.             printf("%s (%s) -- no entry\n",
  264.                 host, inet_ntoa(sin->sin_addr));
  265.         else
  266.             perror("SIOCGARP");
  267.         exit(1);
  268.     }
  269.     close(s);
  270.     ea = (u_char *)ar.arp_ha.sa_data;
  271.     printf("%s (%s) at ", host, inet_ntoa(sin->sin_addr));
  272.     if (ar.arp_flags & ATF_COM)
  273.         ether_print(ea);
  274.     else
  275.         printf("(incomplete)");
  276.     if (ar.arp_flags & ATF_PERM)
  277.         printf(" permanent");
  278.     if (ar.arp_flags & ATF_PUBL)
  279.         printf(" published");
  280.     if (ar.arp_flags & ATF_USETRAILERS)
  281.         printf(" trailers");
  282.     printf("\n");
  283. }
  284.  
  285. /*
  286.  * Delete an arp entry 
  287.  */
  288. delete(host)
  289.     char *host;
  290. {
  291.     struct arpreq ar;
  292.     struct hostent *hp;
  293.     struct sockaddr_in *sin;
  294.     int s;
  295.  
  296.     bzero((caddr_t)&ar, sizeof ar);
  297.     ar.arp_pa.sa_family = AF_INET;
  298.     sin = (struct sockaddr_in *)&ar.arp_pa;
  299.     sin->sin_family = AF_INET;
  300.     sin->sin_addr.s_addr = inet_addr(host);
  301.     if (sin->sin_addr.s_addr == -1) {
  302.         if (!(hp = gethostbyname(host))) {
  303.             fprintf(stderr, "arp: %s: ", host);
  304.             herror((char *)NULL);
  305.             exit(1);
  306.         }
  307.         bcopy((char *)hp->h_addr, (char *)&sin->sin_addr,
  308.             sizeof sin->sin_addr);
  309.     }
  310.     s = socket(AF_INET, SOCK_DGRAM, 0);
  311.     if (s < 0) {
  312.         perror("arp: socket");
  313.         exit(1);
  314.     }
  315.     if (ioctl(s, SIOCDARP, (caddr_t)&ar) < 0) {
  316.         if (errno == ENXIO)
  317.             printf("%s (%s) -- no entry\n",
  318.                 host, inet_ntoa(sin->sin_addr));
  319.         else
  320.             perror("SIOCDARP");
  321.         exit(1);
  322.     }
  323.     close(s);
  324.     printf("%s (%s) deleted\n", host, inet_ntoa(sin->sin_addr));
  325. }
  326.  
  327. struct nlist nl[] = {
  328. #define    X_ARPTAB    0
  329.     { "_arptab" },
  330. #define    X_ARPTAB_SIZE    1
  331.     { "_arptab_size" },
  332.     { "" },
  333. };
  334.  
  335. /*
  336.  * Dump the entire arp table
  337.  */
  338. dump(kernel, mem)
  339.     char *kernel, *mem;
  340. {
  341.     extern int h_errno;
  342.     struct arptab *at;
  343.     struct hostent *hp;
  344.     int bynumber, mf, arptab_size, sz;
  345.     char *host, *malloc();
  346.     off_t lseek();
  347.  
  348.     if (kvm_openfiles(kernel, mem, NULL) == -1) {
  349.         fprintf(stderr, "arp: kvm_openfiles: %s\n", kvm_geterr());
  350.         exit(1);
  351.     }
  352.     if (kvm_nlist(nl) < 0 || nl[X_ARPTAB_SIZE].n_type == 0) {
  353.         fprintf(stderr, "arp: %s: bad namelist\n", kernel);
  354.         exit(1);
  355.     }
  356.     if (kvm_read((void *)(nl[X_ARPTAB_SIZE].n_value),
  357.              &arptab_size, sizeof arptab_size) == -1 ||
  358.         arptab_size <= 0 || arptab_size > 1000) {
  359.         fprintf(stderr, "arp: %s: namelist wrong\n", kernel);
  360.         exit(1);
  361.     }
  362.     sz = arptab_size * sizeof (struct arptab);
  363.     at = (struct arptab *)malloc((u_int)sz);
  364.     if (at == NULL) {
  365.         fputs("arp: can't get memory for arptab.\n", stderr);
  366.         exit(1);
  367.     }
  368.     if (kvm_read((void *)(nl[X_ARPTAB].n_value), (char *)at, sz) == -1) {
  369.         perror("arp: error reading arptab");
  370.         exit(1);
  371.     }
  372.     for (bynumber = 0; arptab_size-- > 0; at++) {
  373.         if (at->at_iaddr.s_addr == 0 || at->at_flags == 0)
  374.             continue;
  375.         if (bynumber == 0)
  376.             hp = gethostbyaddr((caddr_t)&at->at_iaddr,
  377.                 sizeof at->at_iaddr, AF_INET);
  378.         else
  379.             hp = 0;
  380.         if (hp)
  381.             host = hp->h_name;
  382.         else {
  383.             host = "?";
  384.             if (h_errno == TRY_AGAIN)
  385.                 bynumber = 1;
  386.         }
  387.         printf("%s (%s) at ", host, inet_ntoa(at->at_iaddr));
  388.         if (at->at_flags & ATF_COM)
  389.             ether_print(at->at_enaddr);
  390.         else
  391.             printf("(incomplete)");
  392.         if (at->at_flags & ATF_PERM)
  393.             printf(" permanent");
  394.         if (at->at_flags & ATF_PUBL)
  395.             printf(" published");
  396.         if (at->at_flags & ATF_USETRAILERS)
  397.             printf(" trailers");
  398.         printf("\n");
  399.     }
  400. }
  401.  
  402. ether_print(cp)
  403.     u_char *cp;
  404. {
  405.     printf("%x:%x:%x:%x:%x:%x", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]);
  406. }
  407.  
  408. ether_aton(a, n)
  409.     char *a;
  410.     u_char *n;
  411. {
  412.     int i, o[6];
  413.  
  414.     i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o[0], &o[1], &o[2],
  415.                        &o[3], &o[4], &o[5]);
  416.     if (i != 6) {
  417.         fprintf(stderr, "arp: invalid Ethernet address '%s'\n", a);
  418.         return (1);
  419.     }
  420.     for (i=0; i<6; i++)
  421.         n[i] = o[i];
  422.     return (0);
  423. }
  424.  
  425. usage()
  426. {
  427.     printf("usage: arp hostname\n");
  428.     printf("       arp -a [kernel] [kernel_memory]\n");
  429.     printf("       arp -d hostname\n");
  430.     printf("       arp -s hostname ether_addr [temp] [pub] [trail]\n");
  431.     printf("       arp -f filename\n");
  432.     exit(1);
  433. }
  434. @
  435.