Print this page
OS-4807 arp(1M) and ndp(1M) should use zone_get_nroot()


  23 #include <time.h>
  24 #include <err.h>
  25 #include <errno.h>
  26 #include <stdlib.h>
  27 #include <strings.h>
  28 #include <unistd.h>
  29 #include <libgen.h>
  30 #include <sys/ioctl.h>
  31 #include <sys/types.h>
  32 #include <wait.h>
  33 #include <sys/mac.h>
  34 #include <sys/socket.h>
  35 #include <sys/sockio.h>
  36 #include <netdb.h>
  37 #include <net/if_types.h>
  38 #include <netinet/in.h>
  39 #include <arpa/inet.h>
  40 #include <inet/ip.h>
  41 #include <net/if_dl.h>
  42 #include <net/route.h>

  43 
  44 typedef struct  sockaddr_in6    sin6_t;
  45 
  46 #define BUF_SIZE 2048
  47 typedef struct rtmsg_pkt {
  48         struct  rt_msghdr m_rtm;
  49         char    m_space[BUF_SIZE];
  50 } rtmsg_pkt_t;
  51 
  52 enum ndp_action {
  53         NDP_A_DEFAULT,
  54         NDP_A_GET,              /* Show a single NDP entry */
  55         NDP_A_GET_ALL,          /* Show NDP entries */
  56         NDP_A_GET_FOREVER,      /* Repeatedly show entries */
  57         NDP_A_DELETE,           /* Delete an NDP entry */
  58         NDP_A_SET_NCE,          /* Set NDP entry */
  59         NDP_A_SET_FILE          /* Read in & set NDP entries */
  60 };
  61 
  62 typedef int     (ndp_addr_f)(int, struct lifreq *, void *);


  78                     struct sockaddr **, struct sockaddr **, struct sockaddr **,
  79                     struct sockaddr_dl **);
  80 static  int     ndp_rtmsg_get(int, rtmsg_pkt_t *, struct sockaddr *);
  81 static  int     ndp_find_interface(int, struct sockaddr *, char *, int);
  82 
  83 static  int     ndp_initialize_lifreq(int, struct lifreq *, struct sockaddr *);
  84 static  int     ndp_host_enumerate(char *, ndp_addr_f *, void *);
  85 
  86 static  int     ndp_display(struct lifreq *);
  87 static  int     ndp_display_missing(struct lifreq *);
  88 static  void    ndp_lifr2ip(struct lifreq *, char *, int);
  89 
  90 static  int     ndp_get(int, struct lifreq *, void *);
  91 static  void    ndp_get_all(void);
  92 static  int     ndp_delete(int, struct lifreq *, void *);
  93 static  int     ndp_set(int, struct lifreq *, void *);
  94 static  int     ndp_set_nce(char *, char *, char *[], int);
  95 static  int     ndp_set_file(char *);
  96 
  97 static  char            *ndp_iface = NULL;
  98 static  char            *netstat_path = "/usr/bin/netstat";
  99 static  pid_t           ndp_pid;
 100 static  boolean_t       ndp_noresolve = B_FALSE; /* Don't lookup addresses */
 101 static  boolean_t       ndp_run = B_TRUE;
 102 
 103 #define MAX_ATTEMPTS 5
 104 #define MAX_OPTS 5
 105 #define WORDSEPS " \t\r\n"

 106 
 107 /*
 108  * Macros borrowed from route(1M) for working with PF_ROUTE messages
 109  */
 110 #define RT_ADVANCE(x, n) ((x) += ndp_salen(n))
 111 #define RT_NEXTADDR(cp, w, u) \
 112         l = ndp_salen(u); \
 113         (void) memmove(cp, u, l); \
 114         cp += l;
 115 
 116 /*
 117  * Print an error to stderr and then exit non-zero.
 118  */
 119 static void
 120 ndp_fatal(const char *format, ...)
 121 {
 122         va_list ap;
 123 
 124         va_start(ap, format);
 125         vwarnx(format, ap);


 750         if (ioctl(fd, SIOCLIFGETND, lifrp) < 0) {
 751                 if (errno == ESRCH) {
 752                         return (ndp_display_missing(lifrp));
 753                 } else {
 754                         ndp_lifr2ip(lifrp, ipaddr, sizeof (ipaddr));
 755                         warnx("Couldn't lookup %s: %s",
 756                             ipaddr, strerror(errno));
 757                         return (-1);
 758                 }
 759         }
 760 
 761         return (ndp_display(lifrp));
 762 }
 763 
 764 /*
 765  * Print out all NDP entries
 766  */
 767 static void
 768 ndp_get_all(void)
 769 {






 770         (void) execl(netstat_path, "netstat",
 771             (ndp_noresolve ? "-np" : "-p"),
 772             "-f", "inet6", (char *)0);
 773         ndp_fatal("Coudn't exec %s: %s", netstat_path, strerror(errno));
 774 }
 775 
 776 /*
 777  * Perform a SIOCLIFDELND ioctl
 778  */
 779 /*ARGSUSED*/
 780 static int
 781 ndp_delete(int fd, struct lifreq *lifrp, void *unused)
 782 {
 783         char ipaddr[INET6_ADDRSTRLEN];
 784 
 785         if (ioctl(fd, SIOCLIFDELND, lifrp) < 0) {
 786                 ndp_lifr2ip(lifrp, ipaddr, sizeof (ipaddr));
 787                 if (errno == ESRCH) {
 788                         warnx("No entry for %s", ipaddr);
 789                         return (-1);




  23 #include <time.h>
  24 #include <err.h>
  25 #include <errno.h>
  26 #include <stdlib.h>
  27 #include <strings.h>
  28 #include <unistd.h>
  29 #include <libgen.h>
  30 #include <sys/ioctl.h>
  31 #include <sys/types.h>
  32 #include <wait.h>
  33 #include <sys/mac.h>
  34 #include <sys/socket.h>
  35 #include <sys/sockio.h>
  36 #include <netdb.h>
  37 #include <net/if_types.h>
  38 #include <netinet/in.h>
  39 #include <arpa/inet.h>
  40 #include <inet/ip.h>
  41 #include <net/if_dl.h>
  42 #include <net/route.h>
  43 #include <zone.h>
  44 
  45 typedef struct  sockaddr_in6    sin6_t;
  46 
  47 #define BUF_SIZE 2048
  48 typedef struct rtmsg_pkt {
  49         struct  rt_msghdr m_rtm;
  50         char    m_space[BUF_SIZE];
  51 } rtmsg_pkt_t;
  52 
  53 enum ndp_action {
  54         NDP_A_DEFAULT,
  55         NDP_A_GET,              /* Show a single NDP entry */
  56         NDP_A_GET_ALL,          /* Show NDP entries */
  57         NDP_A_GET_FOREVER,      /* Repeatedly show entries */
  58         NDP_A_DELETE,           /* Delete an NDP entry */
  59         NDP_A_SET_NCE,          /* Set NDP entry */
  60         NDP_A_SET_FILE          /* Read in & set NDP entries */
  61 };
  62 
  63 typedef int     (ndp_addr_f)(int, struct lifreq *, void *);


  79                     struct sockaddr **, struct sockaddr **, struct sockaddr **,
  80                     struct sockaddr_dl **);
  81 static  int     ndp_rtmsg_get(int, rtmsg_pkt_t *, struct sockaddr *);
  82 static  int     ndp_find_interface(int, struct sockaddr *, char *, int);
  83 
  84 static  int     ndp_initialize_lifreq(int, struct lifreq *, struct sockaddr *);
  85 static  int     ndp_host_enumerate(char *, ndp_addr_f *, void *);
  86 
  87 static  int     ndp_display(struct lifreq *);
  88 static  int     ndp_display_missing(struct lifreq *);
  89 static  void    ndp_lifr2ip(struct lifreq *, char *, int);
  90 
  91 static  int     ndp_get(int, struct lifreq *, void *);
  92 static  void    ndp_get_all(void);
  93 static  int     ndp_delete(int, struct lifreq *, void *);
  94 static  int     ndp_set(int, struct lifreq *, void *);
  95 static  int     ndp_set_nce(char *, char *, char *[], int);
  96 static  int     ndp_set_file(char *);
  97 
  98 static  char            *ndp_iface = NULL;

  99 static  pid_t           ndp_pid;
 100 static  boolean_t       ndp_noresolve = B_FALSE; /* Don't lookup addresses */
 101 static  boolean_t       ndp_run = B_TRUE;
 102 
 103 #define MAX_ATTEMPTS 5
 104 #define MAX_OPTS 5
 105 #define WORDSEPS " \t\r\n"
 106 #define NETSTAT_PATH    "/usr/bin/netstat"
 107 
 108 /*
 109  * Macros borrowed from route(1M) for working with PF_ROUTE messages
 110  */
 111 #define RT_ADVANCE(x, n) ((x) += ndp_salen(n))
 112 #define RT_NEXTADDR(cp, w, u) \
 113         l = ndp_salen(u); \
 114         (void) memmove(cp, u, l); \
 115         cp += l;
 116 
 117 /*
 118  * Print an error to stderr and then exit non-zero.
 119  */
 120 static void
 121 ndp_fatal(const char *format, ...)
 122 {
 123         va_list ap;
 124 
 125         va_start(ap, format);
 126         vwarnx(format, ap);


 751         if (ioctl(fd, SIOCLIFGETND, lifrp) < 0) {
 752                 if (errno == ESRCH) {
 753                         return (ndp_display_missing(lifrp));
 754                 } else {
 755                         ndp_lifr2ip(lifrp, ipaddr, sizeof (ipaddr));
 756                         warnx("Couldn't lookup %s: %s",
 757                             ipaddr, strerror(errno));
 758                         return (-1);
 759                 }
 760         }
 761 
 762         return (ndp_display(lifrp));
 763 }
 764 
 765 /*
 766  * Print out all NDP entries
 767  */
 768 static void
 769 ndp_get_all(void)
 770 {
 771         char netstat_path[MAXPATHLEN];
 772         const char *zroot = zone_get_nroot();
 773 
 774         (void) snprintf(netstat_path, sizeof (netstat_path), "%s%s", zroot != NULL ?
 775             zroot : "", NETSTAT_PATH);
 776 
 777         (void) execl(netstat_path, "netstat",
 778             (ndp_noresolve ? "-np" : "-p"),
 779             "-f", "inet6", (char *)0);
 780         ndp_fatal("Coudn't exec %s: %s", netstat_path, strerror(errno));
 781 }
 782 
 783 /*
 784  * Perform a SIOCLIFDELND ioctl
 785  */
 786 /*ARGSUSED*/
 787 static int
 788 ndp_delete(int fd, struct lifreq *lifrp, void *unused)
 789 {
 790         char ipaddr[INET6_ADDRSTRLEN];
 791 
 792         if (ioctl(fd, SIOCLIFDELND, lifrp) < 0) {
 793                 ndp_lifr2ip(lifrp, ipaddr, sizeof (ipaddr));
 794                 if (errno == ESRCH) {
 795                         warnx("No entry for %s", ipaddr);
 796                         return (-1);