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);
|