From c84854ee3b4d6efea69362446e6ff1779cd158d1 Mon Sep 17 00:00:00 2001
From: root <jfb8856606@163.com>
Date: Mon, 15 Jul 2019 21:04:09 +0800
Subject: [PATCH] IPv6: `netstat` tool support ipv6.

---
 lib/ff_msg.h                               |   2 -
 tools/README.md                            |   1 -
 tools/compat/include/netinet6/in6.h        | 252 ++++++++++++
 tools/compat/include/netinet6/in6_pcb.h    | 119 ++++++
 tools/compat/include/netinet6/ip6_mroute.h | 279 +++++++++++++
 tools/compat/include/netinet6/ip6_var.h    | 433 +++++++++++++++++++++
 tools/compat/include/netinet6/pim6_var.h   |  63 +++
 tools/compat/include/netinet6/raw_ip6.h    |  59 +++
 tools/netstat/inet6.c                      |  22 +-
 9 files changed, 1226 insertions(+), 4 deletions(-)
 create mode 100644 tools/compat/include/netinet6/in6_pcb.h
 create mode 100644 tools/compat/include/netinet6/ip6_mroute.h
 create mode 100644 tools/compat/include/netinet6/ip6_var.h
 create mode 100644 tools/compat/include/netinet6/pim6_var.h
 create mode 100644 tools/compat/include/netinet6/raw_ip6.h

diff --git a/lib/ff_msg.h b/lib/ff_msg.h
index 0a8d38c2c..715e2b585 100644
--- a/lib/ff_msg.h
+++ b/lib/ff_msg.h
@@ -38,9 +38,7 @@ enum FF_MSG_TYPE {
     FF_UNKNOWN = 0,
     FF_SYSCTL,
     FF_IOCTL,
-//#ifdef INET6
     FF_IOCTL6,
-//#endif
     FF_ROUTE,
     FF_TOP,
     FF_NGCTL,
diff --git a/tools/README.md b/tools/README.md
index f59eaa78b..d1192e80f 100644
--- a/tools/README.md
+++ b/tools/README.md
@@ -146,7 +146,6 @@ Unsupported commands or features:
 -M
 -N
 -m
-ipv6
 netgraph
 ipsec
 ```
diff --git a/tools/compat/include/netinet6/in6.h b/tools/compat/include/netinet6/in6.h
index c83a1f453..c84881e40 100644
--- a/tools/compat/include/netinet6/in6.h
+++ b/tools/compat/include/netinet6/in6.h
@@ -101,6 +101,11 @@ struct in6_addr {
 };
 
 #define s6_addr   __u6_addr.__u6_addr8
+#ifdef _KERNEL	/* XXX nonstandard */
+#define s6_addr8  __u6_addr.__u6_addr8
+#define s6_addr16 __u6_addr.__u6_addr16
+#define s6_addr32 __u6_addr.__u6_addr32
+#endif
 
 #define INET6_ADDRSTRLEN	46
 
@@ -124,6 +129,56 @@ struct sockaddr_in6 {
 	uint32_t	sin6_scope_id;	/* scope zone index */
 };
 
+/*
+ * Local definition for masks
+ */
+#ifdef _KERNEL	/* XXX nonstandard */
+#define IN6MASK0	{{{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}}
+#define IN6MASK32	{{{ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, \
+			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}}
+#define IN6MASK64	{{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
+			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}}
+#define IN6MASK96	{{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
+			    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }}}
+#define IN6MASK128	{{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
+			    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }}}
+#endif
+
+#ifdef _KERNEL
+extern const struct sockaddr_in6 sa6_any;
+
+extern const struct in6_addr in6mask0;
+extern const struct in6_addr in6mask32;
+extern const struct in6_addr in6mask64;
+extern const struct in6_addr in6mask96;
+extern const struct in6_addr in6mask128;
+#endif /* _KERNEL */
+
+/*
+ * Macros started with IPV6_ADDR is KAME local
+ */
+#ifdef _KERNEL	/* XXX nonstandard */
+#if _BYTE_ORDER == _BIG_ENDIAN
+#define IPV6_ADDR_INT32_ONE	1
+#define IPV6_ADDR_INT32_TWO	2
+#define IPV6_ADDR_INT32_MNL	0xff010000
+#define IPV6_ADDR_INT32_MLL	0xff020000
+#define IPV6_ADDR_INT32_SMP	0x0000ffff
+#define IPV6_ADDR_INT16_ULL	0xfe80
+#define IPV6_ADDR_INT16_USL	0xfec0
+#define IPV6_ADDR_INT16_MLL	0xff02
+#elif _BYTE_ORDER == _LITTLE_ENDIAN
+#define IPV6_ADDR_INT32_ONE	0x01000000
+#define IPV6_ADDR_INT32_TWO	0x02000000
+#define IPV6_ADDR_INT32_MNL	0x000001ff
+#define IPV6_ADDR_INT32_MLL	0x000002ff
+#define IPV6_ADDR_INT32_SMP	0xffff0000
+#define IPV6_ADDR_INT16_ULL	0x80fe
+#define IPV6_ADDR_INT16_USL	0xc0fe
+#define IPV6_ADDR_INT16_MLL	0x02ff
+#endif
+#endif
+
 /*
  * Definition of some useful macros to handle IP6 addresses
  */
@@ -160,6 +215,22 @@ extern const struct in6_addr in6addr_linklocal_allrouters;
 extern const struct in6_addr in6addr_linklocal_allv2routers;
 #endif
 
+/*
+ * Equality
+ * NOTE: Some of kernel programming environment (for example, openbsd/sparc)
+ * does not supply memcmp().  For userland memcmp() is preferred as it is
+ * in ANSI standard.
+ */
+#ifdef _KERNEL
+#define IN6_ARE_ADDR_EQUAL(a, b)			\
+    (bcmp(&(a)->s6_addr[0], &(b)->s6_addr[0], sizeof(struct in6_addr)) == 0)
+#else
+#if __BSD_VISIBLE
+#define IN6_ARE_ADDR_EQUAL(a, b)			\
+    (memcmp(&(a)->s6_addr[0], &(b)->s6_addr[0], sizeof(struct in6_addr)) == 0)
+#endif
+#endif
+
 /*
  * Unspecified
  */
@@ -196,6 +267,26 @@ extern const struct in6_addr in6addr_linklocal_allv2routers;
 	 (a)->__u6_addr.__u6_addr32[1] == 0 &&	\
 	 (a)->__u6_addr.__u6_addr32[2] == ntohl(0x0000ffff))
 
+/*
+ * KAME Scope Values
+ */
+
+#ifdef _KERNEL	/* XXX nonstandard */
+#define IPV6_ADDR_SCOPE_NODELOCAL	0x01
+#define IPV6_ADDR_SCOPE_INTFACELOCAL	0x01
+#define IPV6_ADDR_SCOPE_LINKLOCAL	0x02
+#define IPV6_ADDR_SCOPE_SITELOCAL	0x05
+#define IPV6_ADDR_SCOPE_ORGLOCAL	0x08	/* just used in this file */
+#define IPV6_ADDR_SCOPE_GLOBAL		0x0e
+#else
+#define __IPV6_ADDR_SCOPE_NODELOCAL	0x01
+#define __IPV6_ADDR_SCOPE_INTFACELOCAL	0x01
+#define __IPV6_ADDR_SCOPE_LINKLOCAL	0x02
+#define __IPV6_ADDR_SCOPE_SITELOCAL	0x05
+#define __IPV6_ADDR_SCOPE_ORGLOCAL	0x08	/* just used in this file */
+#define __IPV6_ADDR_SCOPE_GLOBAL	0x0e
+#endif
+
 /*
  * Unicast Scope
  * Note that we must check topmost 10 bits only, not 16 bits (see RFC2373).
@@ -210,8 +301,35 @@ extern const struct in6_addr in6addr_linklocal_allv2routers;
  */
 #define IN6_IS_ADDR_MULTICAST(a)	((a)->s6_addr[0] == 0xff)
 
+#ifdef _KERNEL	/* XXX nonstandard */
+#define IPV6_ADDR_MC_SCOPE(a)		((a)->s6_addr[1] & 0x0f)
+#else
 #define __IPV6_ADDR_MC_SCOPE(a)		((a)->s6_addr[1] & 0x0f)
+#endif
 
+/*
+ * Multicast Scope
+ */
+#ifdef _KERNEL	/* refers nonstandard items */
+#define IN6_IS_ADDR_MC_NODELOCAL(a)	\
+	(IN6_IS_ADDR_MULTICAST(a) &&	\
+	 (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_NODELOCAL))
+#define IN6_IS_ADDR_MC_INTFACELOCAL(a)	\
+	(IN6_IS_ADDR_MULTICAST(a) &&	\
+	 (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_INTFACELOCAL))
+#define IN6_IS_ADDR_MC_LINKLOCAL(a)	\
+	(IN6_IS_ADDR_MULTICAST(a) &&	\
+	 (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_LINKLOCAL))
+#define IN6_IS_ADDR_MC_SITELOCAL(a)	\
+	(IN6_IS_ADDR_MULTICAST(a) &&	\
+	 (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_SITELOCAL))
+#define IN6_IS_ADDR_MC_ORGLOCAL(a)	\
+	(IN6_IS_ADDR_MULTICAST(a) &&	\
+	 (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_ORGLOCAL))
+#define IN6_IS_ADDR_MC_GLOBAL(a)	\
+	(IN6_IS_ADDR_MULTICAST(a) &&	\
+	 (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_GLOBAL))
+#else
 #define IN6_IS_ADDR_MC_NODELOCAL(a)	\
 	(IN6_IS_ADDR_MULTICAST(a) &&	\
 	 (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL))
@@ -227,6 +345,29 @@ extern const struct in6_addr in6addr_linklocal_allv2routers;
 #define IN6_IS_ADDR_MC_GLOBAL(a)	\
 	(IN6_IS_ADDR_MULTICAST(a) &&	\
 	 (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL))
+#endif
+
+#ifdef _KERNEL	/* nonstandard */
+/*
+ * KAME Scope
+ */
+#define IN6_IS_SCOPE_LINKLOCAL(a)	\
+	((IN6_IS_ADDR_LINKLOCAL(a)) ||	\
+	 (IN6_IS_ADDR_MC_LINKLOCAL(a)))
+#define	IN6_IS_SCOPE_EMBED(a)			\
+	((IN6_IS_ADDR_LINKLOCAL(a)) ||		\
+	 (IN6_IS_ADDR_MC_LINKLOCAL(a)) ||	\
+	 (IN6_IS_ADDR_MC_INTFACELOCAL(a)))
+
+#define IFA6_IS_DEPRECATED(a) \
+	((a)->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME && \
+	 (u_int32_t)((time_uptime - (a)->ia6_updatetime)) > \
+	 (a)->ia6_lifetime.ia6t_pltime)
+#define IFA6_IS_INVALID(a) \
+	((a)->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME && \
+	 (u_int32_t)((time_uptime - (a)->ia6_updatetime)) > \
+	 (a)->ia6_lifetime.ia6t_vltime)
+#endif /* _KERNEL */
 
 /*
  * IP6 route structure
@@ -248,6 +389,23 @@ struct route_in6 {
 };
 #endif
 
+#ifdef _KERNEL
+#define MTAG_ABI_IPV6		1444287380	/* IPv6 ABI */
+#define IPV6_TAG_DIRECT		0		/* direct-dispatch IPv6 */
+#endif /* _KERNEL */
+
+/*
+ * Options for use with [gs]etsockopt at the IPV6 level.
+ * First word of comment is data type; bool is stored in int.
+ */
+/* no hdrincl */
+#if 0 /* the followings are relic in IPv4 and hence are disabled */
+#define IPV6_OPTIONS		1  /* buf/ip6_opts; set/get IP6 options */
+#define IPV6_RECVOPTS		5  /* bool; receive all IP6 opts w/dgram */
+#define IPV6_RECVRETOPTS	6  /* bool; receive IP6 opts for response */
+#define IPV6_RECVDSTADDR	7  /* bool; receive IP6 dst addr w/dgram */
+#define IPV6_RETOPTS		8  /* ip6_opts; set/get IP6 options */
+#endif
 #define IPV6_SOCKOPT_RESERVED1	3  /* reserved for future use */
 #define IPV6_UNICAST_HOPS	4  /* int; IP6 hops */
 #define IPV6_MULTICAST_IF	9  /* u_int; set/get IP6 multicast i/f  */
@@ -257,10 +415,22 @@ struct route_in6 {
 #define IPV6_LEAVE_GROUP	13 /* ipv6_mreq; leave a group membership */
 #define IPV6_PORTRANGE		14 /* int; range to choose for unspec port */
 #define ICMP6_FILTER		18 /* icmp6_filter; icmp6 filter */
+/* RFC2292 options */
+#ifdef _KERNEL
+#define IPV6_2292PKTINFO	19 /* bool; send/recv if, src/dst addr */
+#define IPV6_2292HOPLIMIT	20 /* bool; hop limit */
+#define IPV6_2292NEXTHOP	21 /* bool; next hop addr */
+#define IPV6_2292HOPOPTS	22 /* bool; hop-by-hop option */
+#define IPV6_2292DSTOPTS	23 /* bool; destinaion option */
+#define IPV6_2292RTHDR		24 /* bool; routing header */
+#define IPV6_2292PKTOPTIONS	25 /* buf/cmsghdr; set/get IPv6 options */
+#endif
 
 #define IPV6_CHECKSUM		26 /* int; checksum offset for raw socket */
 #define IPV6_V6ONLY		27 /* bool; make AF_INET6 sockets v6 only */
+#ifndef _KERNEL
 #define IPV6_BINDV6ONLY		IPV6_V6ONLY
+#endif
 
 #if 1 /* IPSEC */
 #define IPV6_IPSEC_POLICY	28 /* struct; get/set security policy */
@@ -283,6 +453,9 @@ struct route_in6 {
 #define IPV6_RECVRTHDR		38 /* bool; recv routing header */
 #define IPV6_RECVHOPOPTS	39 /* bool; recv hop-by-hop option */
 #define IPV6_RECVDSTOPTS	40 /* bool; recv dst option after rthdr */
+#ifdef _KERNEL
+#define IPV6_RECVRTHDRDSTOPTS	41 /* bool; recv dst option before rthdr */
+#endif
 
 #define IPV6_USE_MIN_MTU	42 /* bool; send packets at the minimum MTU */
 #define IPV6_RECVPATHMTU	43 /* bool; notify an according MTU */
@@ -480,6 +653,39 @@ struct ip6_mtuinfo {
 #define	M_LOOP			M_PROTO6
 #define	M_AUTHIPDGM		M_PROTO7
 #define	M_RTALERT_MLD		M_PROTO8
+
+#ifdef _KERNEL
+struct cmsghdr;
+struct ip6_hdr;
+
+int	in6_cksum_pseudo(struct ip6_hdr *, uint32_t, uint8_t, uint16_t);
+int	in6_cksum(struct mbuf *, u_int8_t, u_int32_t, u_int32_t);
+int	in6_cksum_partial(struct mbuf *, u_int8_t, u_int32_t, u_int32_t,
+			  u_int32_t);
+int	in6_localaddr(struct in6_addr *);
+int	in6_localip(struct in6_addr *);
+int	in6_ifhasaddr(struct ifnet *, struct in6_addr *);
+int	in6_addrscope(const struct in6_addr *);
+char	*ip6_sprintf(char *, const struct in6_addr *);
+struct	in6_ifaddr *in6_ifawithifp(struct ifnet *, struct in6_addr *);
+extern void in6_if_up(struct ifnet *);
+struct sockaddr;
+extern	u_char	ip6_protox[];
+
+void	in6_sin6_2_sin(struct sockaddr_in *sin,
+			    struct sockaddr_in6 *sin6);
+void	in6_sin_2_v4mapsin6(struct sockaddr_in *sin,
+				 struct sockaddr_in6 *sin6);
+void	in6_sin6_2_sin_in_sock(struct sockaddr *nam);
+void	in6_sin_2_v4mapsin6_in_sock(struct sockaddr **nam);
+extern void addrsel_policy_init(void);
+
+#define	satosin6(sa)	((struct sockaddr_in6 *)(sa))
+#define	sin6tosa(sin6)	((struct sockaddr *)(sin6))
+#define	ifatoia6(ifa)	((struct in6_ifaddr *)(ifa))
+
+#endif /* _KERNEL */
+
 #ifndef _SIZE_T_DECLARED
 typedef	__size_t	size_t;
 #define	_SIZE_T_DECLARED
@@ -490,4 +696,50 @@ typedef	__socklen_t	socklen_t;
 #define	_SOCKLEN_T_DECLARED
 #endif
 
+#if __BSD_VISIBLE
+
+__BEGIN_DECLS
+struct cmsghdr;
+
+extern int inet6_option_space(int);
+extern int inet6_option_init(void *, struct cmsghdr **, int);
+extern int inet6_option_append(struct cmsghdr *, const uint8_t *,
+	int, int);
+extern uint8_t *inet6_option_alloc(struct cmsghdr *, int, int, int);
+extern int inet6_option_next(const struct cmsghdr *, uint8_t **);
+extern int inet6_option_find(const struct cmsghdr *, uint8_t **, int);
+
+extern size_t inet6_rthdr_space(int, int);
+extern struct cmsghdr *inet6_rthdr_init(void *, int);
+extern int inet6_rthdr_add(struct cmsghdr *, const struct in6_addr *,
+	unsigned int);
+extern int inet6_rthdr_lasthop(struct cmsghdr *, unsigned int);
+#if 0 /* not implemented yet */
+extern int inet6_rthdr_reverse(const struct cmsghdr *, struct cmsghdr *);
+#endif
+extern int inet6_rthdr_segments(const struct cmsghdr *);
+extern struct in6_addr *inet6_rthdr_getaddr(struct cmsghdr *, int);
+extern int inet6_rthdr_getflags(const struct cmsghdr *, int);
+
+extern int inet6_opt_init(void *, socklen_t);
+extern int inet6_opt_append(void *, socklen_t, int, uint8_t, socklen_t,
+	uint8_t, void **);
+extern int inet6_opt_finish(void *, socklen_t, int);
+extern int inet6_opt_set_val(void *, int, void *, socklen_t);
+
+extern int inet6_opt_next(void *, socklen_t, int, uint8_t *, socklen_t *,
+	void **);
+extern int inet6_opt_find(void *, socklen_t, int, uint8_t, socklen_t *,
+	void **);
+extern int inet6_opt_get_val(void *, int, void *, socklen_t);
+extern socklen_t inet6_rth_space(int, int);
+extern void *inet6_rth_init(void *, socklen_t, int, int);
+extern int inet6_rth_add(void *, const struct in6_addr *);
+extern int inet6_rth_reverse(const void *, void *);
+extern int inet6_rth_segments(const void *);
+extern struct in6_addr *inet6_rth_getaddr(const void *, int);
+__END_DECLS
+
+#endif /* __BSD_VISIBLE */
+
 #endif /* !_NETINET6_IN6_H_ */
diff --git a/tools/compat/include/netinet6/in6_pcb.h b/tools/compat/include/netinet6/in6_pcb.h
new file mode 100644
index 000000000..e758dacea
--- /dev/null
+++ b/tools/compat/include/netinet6/in6_pcb.h
@@ -0,0 +1,119 @@
+/*-
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	$KAME: in6_pcb.h,v 1.13 2001/02/06 09:16:53 itojun Exp $
+ */
+
+/*-
+ * Copyright (c) 1982, 1986, 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)in_pcb.h	8.1 (Berkeley) 6/10/93
+ * $FreeBSD$
+ */
+
+#ifndef _NETINET6_IN6_PCB_H_
+#define	_NETINET6_IN6_PCB_H_
+
+#ifdef _KERNEL
+#define	satosin6(sa)	((struct sockaddr_in6 *)(sa))
+#define	sin6tosa(sin6)	((struct sockaddr *)(sin6))
+#define	ifatoia6(ifa)	((struct in6_ifaddr *)(ifa))
+
+struct	inpcbgroup *
+	in6_pcbgroup_byhash(struct inpcbinfo *, u_int, uint32_t);
+struct	inpcbgroup *
+	in6_pcbgroup_byinpcb(struct inpcb *);
+struct inpcbgroup *
+	in6_pcbgroup_bymbuf(struct inpcbinfo *, struct mbuf *);
+struct	inpcbgroup *
+	in6_pcbgroup_bytuple(struct inpcbinfo *, const struct in6_addr *,
+	    u_short, const struct in6_addr *, u_short);
+
+void	in6_pcbpurgeif0(struct inpcbinfo *, struct ifnet *);
+void	in6_losing(struct inpcb *);
+int	in6_pcbbind(struct inpcb *, struct sockaddr *, struct ucred *);
+int	in6_pcbconnect(struct inpcb *, struct sockaddr *, struct ucred *);
+int	in6_pcbconnect_mbuf(struct inpcb *, struct sockaddr *,
+	    struct ucred *, struct mbuf *);
+void	in6_pcbdisconnect(struct inpcb *);
+struct	inpcb *
+	in6_pcblookup_local(struct inpcbinfo *,
+				 struct in6_addr *, u_short, int,
+				 struct ucred *);
+struct	inpcb *
+	in6_pcblookup(struct inpcbinfo *, struct in6_addr *,
+			   u_int, struct in6_addr *, u_int, int,
+			   struct ifnet *);
+struct	inpcb *
+	in6_pcblookup_mbuf(struct inpcbinfo *, struct in6_addr *,
+			   u_int, struct in6_addr *, u_int, int,
+			   struct ifnet *ifp, struct mbuf *);
+void	in6_pcbnotify(struct inpcbinfo *, struct sockaddr *,
+			   u_int, const struct sockaddr *, u_int, int, void *,
+			   struct inpcb *(*)(struct inpcb *, int));
+struct inpcb *
+	in6_rtchange(struct inpcb *, int);
+struct sockaddr *
+	in6_sockaddr(in_port_t port, struct in6_addr *addr_p);
+struct sockaddr *
+	in6_v4mapsin6_sockaddr(in_port_t port, struct in_addr *addr_p);
+int	in6_getpeeraddr(struct socket *so, struct sockaddr **nam);
+int	in6_getsockaddr(struct socket *so, struct sockaddr **nam);
+int	in6_mapped_sockaddr(struct socket *so, struct sockaddr **nam);
+int	in6_mapped_peeraddr(struct socket *so, struct sockaddr **nam);
+int	in6_selecthlim(struct in6pcb *, struct ifnet *);
+int	in6_pcbsetport(struct in6_addr *, struct inpcb *, struct ucred *);
+void	init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m);
+#endif /* _KERNEL */
+
+#endif /* !_NETINET6_IN6_PCB_H_ */
diff --git a/tools/compat/include/netinet6/ip6_mroute.h b/tools/compat/include/netinet6/ip6_mroute.h
new file mode 100644
index 000000000..51e1d496a
--- /dev/null
+++ b/tools/compat/include/netinet6/ip6_mroute.h
@@ -0,0 +1,279 @@
+/*-
+ * Copyright (C) 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	$KAME: ip6_mroute.h,v 1.19 2001/06/14 06:12:55 suz Exp $
+ * $FreeBSD$
+ */
+
+/*	BSDI ip_mroute.h,v 2.5 1996/10/11 16:01:48 pjd Exp	*/
+
+/*
+ * Definitions for IP multicast forwarding.
+ *
+ * Written by David Waitzman, BBN Labs, August 1988.
+ * Modified by Steve Deering, Stanford, February 1989.
+ * Modified by Ajit Thyagarajan, PARC, August 1993.
+ * Modified by Ajit Thyagarajan, PARC, August 1994.
+ * Modified by Ahmed Helmy, USC, September 1996.
+ *
+ * MROUTING Revision: 1.2
+ */
+
+#ifndef _NETINET6_IP6_MROUTE_H_
+#define _NETINET6_IP6_MROUTE_H_
+
+/*
+ * Multicast Routing set/getsockopt commands.
+ */
+#ifdef _KERNEL
+#define MRT6_OINIT		100	/* initialize forwarder (omrt6msg) */
+#endif
+#define MRT6_DONE		101	/* shut down forwarder */
+#define MRT6_ADD_MIF		102	/* add multicast interface */
+#define MRT6_DEL_MIF		103	/* delete multicast interface */
+#define MRT6_ADD_MFC		104	/* insert forwarding cache entry */
+#define MRT6_DEL_MFC		105	/* delete forwarding cache entry */
+#define MRT6_PIM                107     /* enable pim code */
+#define MRT6_INIT		108	/* initialize forwarder (mrt6msg) */
+
+#if BSD >= 199103
+#define GET_TIME(t)	microtime(&t)
+#elif defined(sun)
+#define GET_TIME(t)	uniqtime(&t)
+#else
+#define GET_TIME(t)	((t) = time)
+#endif
+
+/*
+ * Types and macros for handling bitmaps with one bit per multicast interface.
+ */
+typedef u_short mifi_t;		/* type of a mif index */
+#define MAXMIFS		64
+
+#ifndef	IF_SETSIZE
+#define	IF_SETSIZE	256
+#endif
+
+typedef	u_int32_t	if_mask;
+#define	NIFBITS	(sizeof(if_mask) * NBBY)	/* bits per mask */
+
+#ifndef howmany
+#define	howmany(x, y)	(((x) + ((y) - 1)) / (y))
+#endif
+
+typedef	struct if_set {
+	if_mask	ifs_bits[howmany(IF_SETSIZE, NIFBITS)];
+} if_set;
+
+#define	IF_SET(n, p)	((p)->ifs_bits[(n)/NIFBITS] |= (1 << ((n) % NIFBITS)))
+#define	IF_CLR(n, p)	((p)->ifs_bits[(n)/NIFBITS] &= ~(1 << ((n) % NIFBITS)))
+#define	IF_ISSET(n, p)	((p)->ifs_bits[(n)/NIFBITS] & (1 << ((n) % NIFBITS)))
+#define	IF_COPY(f, t)	bcopy(f, t, sizeof(*(f)))
+#define	IF_ZERO(p)	bzero(p, sizeof(*(p)))
+
+/*
+ * Argument structure for MRT6_ADD_IF.
+ */
+struct mif6ctl {
+	mifi_t	    mif6c_mifi;		/* the index of the mif to be added  */
+	u_char	    mif6c_flags;	/* MIFF_ flags defined below         */
+	u_short	    mif6c_pifi;		/* the index of the physical IF */
+};
+
+#define	MIFF_REGISTER	0x1	/* mif represents a register end-point */
+
+/*
+ * Argument structure for MRT6_ADD_MFC and MRT6_DEL_MFC
+ */
+struct mf6cctl {
+	struct sockaddr_in6 mf6cc_origin;	/* IPv6 origin of mcasts */
+	struct sockaddr_in6 mf6cc_mcastgrp; /* multicast group associated */
+	mifi_t		mf6cc_parent;	/* incoming ifindex */
+	struct if_set	mf6cc_ifset;	/* set of forwarding ifs */
+};
+
+/*
+ * The kernel's multicast routing statistics.
+ */
+struct mrt6stat {
+	uint64_t mrt6s_mfc_lookups;	/* # forw. cache hash table hits   */
+	uint64_t mrt6s_mfc_misses;	/* # forw. cache hash table misses */
+	uint64_t mrt6s_upcalls;		/* # calls to multicast routing daemon */
+	uint64_t mrt6s_no_route;	/* no route for packet's origin    */
+	uint64_t mrt6s_bad_tunnel;	/* malformed tunnel options        */
+	uint64_t mrt6s_cant_tunnel;	/* no room for tunnel options      */
+	uint64_t mrt6s_wrong_if;	/* arrived on wrong interface	   */
+	uint64_t mrt6s_upq_ovflw;	/* upcall Q overflow		   */
+	uint64_t mrt6s_cache_cleanups;	/* # entries with no upcalls	   */
+	uint64_t mrt6s_drop_sel;	/* pkts dropped selectively        */
+	uint64_t mrt6s_q_overflow;	/* pkts dropped - Q overflow       */
+	uint64_t mrt6s_pkt2large;	/* pkts dropped - size > BKT SIZE  */
+	uint64_t mrt6s_upq_sockfull;	/* upcalls dropped - socket full   */
+};
+
+#ifdef MRT6_OINIT
+/*
+ * Struct used to communicate from kernel to multicast router
+ * note the convenient similarity to an IPv6 header.
+ * XXX old version, superseded by mrt6msg.
+ */
+struct omrt6msg {
+	u_long	    unused1;
+	u_char	    im6_msgtype;		/* what type of message	    */
+	u_char	    im6_mbz;			/* must be zero		    */
+	u_char	    im6_mif;			/* mif rec'd on		    */
+	u_char	    unused2;
+	struct in6_addr  im6_src, im6_dst;
+};
+#endif
+
+/*
+ * Structure used to communicate from kernel to multicast router.
+ * We'll overlay the structure onto an MLD header (not an IPv6 header
+ * like igmpmsg{} used for IPv4 implementation). This is because this
+ * structure will be passed via an IPv6 raw socket, on which an application
+ * will only receive the payload i.e. the data after the IPv6 header and all
+ * the extension headers. (see Section 3 of RFC3542)
+ */
+struct mrt6msg {
+#define MRT6MSG_NOCACHE		1
+#define MRT6MSG_WRONGMIF	2
+#define MRT6MSG_WHOLEPKT	3		/* used for user level encap*/
+	u_char	    im6_mbz;			/* must be zero		    */
+	u_char	    im6_msgtype;		/* what type of message	    */
+	u_int16_t   im6_mif;			/* mif rec'd on		    */
+	u_int32_t   im6_pad;			/* padding for 64bit arch   */
+	struct in6_addr  im6_src, im6_dst;
+};
+
+/*
+ * Argument structure used by multicast routing daemon to get src-grp
+ * packet counts
+ */
+struct sioc_sg_req6 {
+	struct sockaddr_in6 src;
+	struct sockaddr_in6 grp;
+	u_quad_t pktcnt;
+	u_quad_t bytecnt;
+	u_quad_t wrong_if;
+};
+
+/*
+ * Argument structure used by mrouted to get mif pkt counts
+ */
+struct sioc_mif_req6 {
+	mifi_t mifi;		/* mif number				*/
+	u_quad_t icount;	/* Input packet count on mif		*/
+	u_quad_t ocount;	/* Output packet count on mif		*/
+	u_quad_t ibytes;	/* Input byte count on mif		*/
+	u_quad_t obytes;	/* Output byte count on mif		*/
+};
+
+/*
+ * Structure to export 'struct mif6' to userland via sysctl.
+ */
+struct mif6_sctl {
+	u_char		m6_flags;	/* MIFF_ flags defined above         */
+	u_int		m6_rate_limit;	/* max rate			     */
+	struct in6_addr	m6_lcl_addr;	/* local interface address           */
+	uint32_t	m6_ifp;		/* interface index	             */
+	u_quad_t	m6_pkt_in;	/* # pkts in on interface            */
+	u_quad_t	m6_pkt_out;	/* # pkts out on interface           */
+	u_quad_t	m6_bytes_in;	/* # bytes in on interface	     */
+	u_quad_t	m6_bytes_out;	/* # bytes out on interface	     */
+};
+
+#if defined(_KERNEL) || defined(KERNEL)
+/*
+ * The kernel's multicast-interface structure.
+ */
+struct mif6 {
+        u_char		m6_flags;	/* MIFF_ flags defined above         */
+	u_int		m6_rate_limit;	/* max rate			     */
+	struct in6_addr	m6_lcl_addr;	/* local interface address           */
+	struct ifnet    *m6_ifp;	/* pointer to interface              */
+	u_quad_t	m6_pkt_in;	/* # pkts in on interface            */
+	u_quad_t	m6_pkt_out;	/* # pkts out on interface           */
+	u_quad_t	m6_bytes_in;	/* # bytes in on interface	     */
+	u_quad_t	m6_bytes_out;	/* # bytes out on interface	     */
+#ifdef notyet
+	u_int		m6_rsvp_on;	/* RSVP listening on this vif */
+	struct socket   *m6_rsvpd;	/* RSVP daemon socket */
+#endif
+};
+
+/*
+ * The kernel's multicast forwarding cache entry structure
+ */
+struct mf6c {
+	struct sockaddr_in6  mf6c_origin;	/* IPv6 origin of mcasts     */
+	struct sockaddr_in6  mf6c_mcastgrp;	/* multicast group associated*/
+	mifi_t		 mf6c_parent;		/* incoming IF               */
+	struct if_set	 mf6c_ifset;		/* set of outgoing IFs */
+
+	u_quad_t	mf6c_pkt_cnt;		/* pkt count for src-grp     */
+	u_quad_t	mf6c_byte_cnt;		/* byte count for src-grp    */
+	u_quad_t	mf6c_wrong_if;		/* wrong if for src-grp	     */
+	int		mf6c_expire;		/* time to clean entry up    */
+	struct timeval  mf6c_last_assert;	/* last time I sent an assert*/
+	struct rtdetq  *mf6c_stall;		/* pkts waiting for route */
+	struct mf6c    *mf6c_next;		/* hash table linkage */
+};
+
+#define MF6C_INCOMPLETE_PARENT ((mifi_t)-1)
+
+/*
+ * Argument structure used for pkt info. while upcall is made
+ */
+#ifndef _NETINET_IP_MROUTE_H_
+struct rtdetq {		/* XXX: rtdetq is also defined in ip_mroute.h */
+    struct mbuf		*m;		/* A copy of the packet		    */
+    struct ifnet	*ifp;		/* Interface pkt came in on	    */
+#ifdef UPCALL_TIMING
+    struct timeval	t;		/* Timestamp */
+#endif /* UPCALL_TIMING */
+    struct rtdetq	*next;
+};
+#endif /* _NETINET_IP_MROUTE_H_ */
+
+#define MF6CTBLSIZ	256
+#if (MF6CTBLSIZ & (MF6CTBLSIZ - 1)) == 0	  /* from sys:route.h */
+#define MF6CHASHMOD(h)	((h) & (MF6CTBLSIZ - 1))
+#else
+#define MF6CHASHMOD(h)	((h) % MF6CTBLSIZ)
+#endif
+
+#define MAX_UPQ6	4		/* max. no of pkts in upcall Q */
+
+extern int	(*ip6_mrouter_set)(struct socket *so, struct sockopt *sopt);
+extern int	(*ip6_mrouter_get)(struct socket *so, struct sockopt *sopt);
+extern int	(*ip6_mrouter_done)(void);
+extern int	(*mrt6_ioctl)(u_long, caddr_t);
+#endif /* _KERNEL */
+
+#endif /* !_NETINET6_IP6_MROUTE_H_ */
diff --git a/tools/compat/include/netinet6/ip6_var.h b/tools/compat/include/netinet6/ip6_var.h
new file mode 100644
index 000000000..e52a32068
--- /dev/null
+++ b/tools/compat/include/netinet6/ip6_var.h
@@ -0,0 +1,433 @@
+/*-
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	$KAME: ip6_var.h,v 1.62 2001/05/03 14:51:48 itojun Exp $
+ */
+
+/*-
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ip_var.h	8.1 (Berkeley) 6/10/93
+ * $FreeBSD$
+ */
+
+#ifndef _NETINET6_IP6_VAR_H_
+#define _NETINET6_IP6_VAR_H_
+
+/*
+ * IP6 reassembly queue structure.  Each fragment
+ * being reassembled is attached to one of these structures.
+ */
+struct	ip6q {
+	struct ip6asfrag *ip6q_down;
+	struct ip6asfrag *ip6q_up;
+	u_int32_t	ip6q_ident;
+	u_int8_t	ip6q_nxt;
+	u_int8_t	ip6q_ecn;
+	u_int8_t	ip6q_ttl;
+	struct in6_addr ip6q_src, ip6q_dst;
+	struct ip6q	*ip6q_next;
+	struct ip6q	*ip6q_prev;
+	int		ip6q_unfrglen;	/* len of unfragmentable part */
+#ifdef notyet
+	u_char		*ip6q_nxtp;
+#endif
+	int		ip6q_nfrag;	/* # of fragments */
+	struct label	*ip6q_label;
+};
+
+struct	ip6asfrag {
+	struct ip6asfrag *ip6af_down;
+	struct ip6asfrag *ip6af_up;
+	struct mbuf	*ip6af_m;
+	int		ip6af_offset;	/* offset in ip6af_m to next header */
+	int		ip6af_frglen;	/* fragmentable part length */
+	int		ip6af_off;	/* fragment offset */
+	u_int16_t	ip6af_mff;	/* more fragment bit in frag off */
+};
+
+#define IP6_REASS_MBUF(ip6af) (*(struct mbuf **)&((ip6af)->ip6af_m))
+
+/*
+ * IP6 reinjecting structure.
+ */
+struct ip6_direct_ctx {
+	uint32_t	ip6dc_nxt;	/* next header to process */
+	uint32_t	ip6dc_off;	/* offset to next header */
+};
+
+/*
+ * Structure attached to inpcb.in6p_moptions and
+ * passed to ip6_output when IPv6 multicast options are in use.
+ * This structure is lazy-allocated.
+ */
+struct ip6_moptions {
+	struct	ifnet *im6o_multicast_ifp; /* ifp for outgoing multicasts */
+	u_char	im6o_multicast_hlim;	/* hoplimit for outgoing multicasts */
+	u_char	im6o_multicast_loop;	/* 1 >= hear sends if a member */
+	u_short	im6o_num_memberships;	/* no. memberships this socket */
+	u_short	im6o_max_memberships;	/* max memberships this socket */
+	struct	in6_multi **im6o_membership;	/* group memberships */
+	struct	in6_mfilter *im6o_mfilters;	/* source filters */
+};
+
+/*
+ * Control options for outgoing packets
+ */
+
+/* Routing header related info */
+struct	ip6po_rhinfo {
+	struct	ip6_rthdr *ip6po_rhi_rthdr; /* Routing header */
+	struct	route_in6 ip6po_rhi_route; /* Route to the 1st hop */
+};
+#define ip6po_rthdr	ip6po_rhinfo.ip6po_rhi_rthdr
+#define ip6po_route	ip6po_rhinfo.ip6po_rhi_route
+
+/* Nexthop related info */
+struct	ip6po_nhinfo {
+	struct	sockaddr *ip6po_nhi_nexthop;
+	struct	route_in6 ip6po_nhi_route; /* Route to the nexthop */
+};
+#define ip6po_nexthop	ip6po_nhinfo.ip6po_nhi_nexthop
+#define ip6po_nextroute	ip6po_nhinfo.ip6po_nhi_route
+
+struct	ip6_pktopts {
+	struct	mbuf *ip6po_m;	/* Pointer to mbuf storing the data */
+	int	ip6po_hlim;	/* Hoplimit for outgoing packets */
+
+	/* Outgoing IF/address information */
+	struct	in6_pktinfo *ip6po_pktinfo;
+
+	/* Next-hop address information */
+	struct	ip6po_nhinfo ip6po_nhinfo;
+
+	struct	ip6_hbh *ip6po_hbh; /* Hop-by-Hop options header */
+
+	/* Destination options header (before a routing header) */
+	struct	ip6_dest *ip6po_dest1;
+
+	/* Routing header related info. */
+	struct	ip6po_rhinfo ip6po_rhinfo;
+
+	/* Destination options header (after a routing header) */
+	struct	ip6_dest *ip6po_dest2;
+
+	int	ip6po_tclass;	/* traffic class */
+
+	int	ip6po_minmtu;  /* fragment vs PMTU discovery policy */
+#define IP6PO_MINMTU_MCASTONLY	-1 /* default; send at min MTU for multicast*/
+#define IP6PO_MINMTU_DISABLE	 0 /* always perform pmtu disc */
+#define IP6PO_MINMTU_ALL	 1 /* always send at min MTU */
+
+	int	ip6po_prefer_tempaddr;  /* whether temporary addresses are
+					   preferred as source address */
+#define IP6PO_TEMPADDR_SYSTEM	-1 /* follow the system default */
+#define IP6PO_TEMPADDR_NOTPREFER 0 /* not prefer temporary address */
+#define IP6PO_TEMPADDR_PREFER	 1 /* prefer temporary address */
+
+	int ip6po_flags;
+#if 0	/* parameters in this block is obsolete. do not reuse the values. */
+#define IP6PO_REACHCONF	0x01	/* upper-layer reachability confirmation. */
+#define IP6PO_MINMTU	0x02	/* use minimum MTU (IPV6_USE_MIN_MTU) */
+#endif
+#define IP6PO_DONTFRAG	0x04	/* disable fragmentation (IPV6_DONTFRAG) */
+#define IP6PO_USECOA	0x08	/* use care of address */
+};
+
+/*
+ * Control options for incoming packets
+ */
+
+struct	ip6stat {
+	uint64_t ip6s_total;		/* total packets received */
+	uint64_t ip6s_tooshort;		/* packet too short */
+	uint64_t ip6s_toosmall;		/* not enough data */
+	uint64_t ip6s_fragments;	/* fragments received */
+	uint64_t ip6s_fragdropped;	/* frags dropped(dups, out of space) */
+	uint64_t ip6s_fragtimeout;	/* fragments timed out */
+	uint64_t ip6s_fragoverflow;	/* fragments that exceeded limit */
+	uint64_t ip6s_forward;		/* packets forwarded */
+	uint64_t ip6s_cantforward;	/* packets rcvd for unreachable dest */
+	uint64_t ip6s_redirectsent;	/* packets forwarded on same net */
+	uint64_t ip6s_delivered;	/* datagrams delivered to upper level*/
+	uint64_t ip6s_localout;		/* total ip packets generated here */
+	uint64_t ip6s_odropped;		/* lost packets due to nobufs, etc. */
+	uint64_t ip6s_reassembled;	/* total packets reassembled ok */
+	uint64_t ip6s_fragmented;	/* datagrams successfully fragmented */
+	uint64_t ip6s_ofragments;	/* output fragments created */
+	uint64_t ip6s_cantfrag;		/* don't fragment flag was set, etc. */
+	uint64_t ip6s_badoptions;	/* error in option processing */
+	uint64_t ip6s_noroute;		/* packets discarded due to no route */
+	uint64_t ip6s_badvers;		/* ip6 version != 6 */
+	uint64_t ip6s_rawout;		/* total raw ip packets generated */
+	uint64_t ip6s_badscope;		/* scope error */
+	uint64_t ip6s_notmember;	/* don't join this multicast group */
+#define	IP6S_HDRCNT		256	/* headers count */
+	uint64_t ip6s_nxthist[IP6S_HDRCNT]; /* next header history */
+	uint64_t ip6s_m1;		/* one mbuf */
+#define	IP6S_M2MMAX		32
+	uint64_t ip6s_m2m[IP6S_M2MMAX];	/* two or more mbuf */
+	uint64_t ip6s_mext1;		/* one ext mbuf */
+	uint64_t ip6s_mext2m;		/* two or more ext mbuf */
+	uint64_t ip6s_exthdrtoolong;	/* ext hdr are not contiguous */
+	uint64_t ip6s_nogif;		/* no match gif found */
+	uint64_t ip6s_toomanyhdr;	/* discarded due to too many headers */
+
+	/*
+	 * statistics for improvement of the source address selection
+	 * algorithm:
+	 * XXX: hardcoded 16 = # of ip6 multicast scope types + 1
+	 */
+#define	IP6S_RULESMAX		16
+#define	IP6S_SCOPECNT		16
+	/* number of times that address selection fails */
+	uint64_t ip6s_sources_none;
+	/* number of times that an address on the outgoing I/F is chosen */
+	uint64_t ip6s_sources_sameif[IP6S_SCOPECNT];
+	/* number of times that an address on a non-outgoing I/F is chosen */
+	uint64_t ip6s_sources_otherif[IP6S_SCOPECNT];
+	/*
+	 * number of times that an address that has the same scope
+	 * from the destination is chosen.
+	 */
+	uint64_t ip6s_sources_samescope[IP6S_SCOPECNT];
+	/*
+	 * number of times that an address that has a different scope
+	 * from the destination is chosen.
+	 */
+	uint64_t ip6s_sources_otherscope[IP6S_SCOPECNT];
+	/* number of times that a deprecated address is chosen */
+	uint64_t ip6s_sources_deprecated[IP6S_SCOPECNT];
+
+	/* number of times that each rule of source selection is applied. */
+	uint64_t ip6s_sources_rule[IP6S_RULESMAX];
+};
+
+#ifdef _KERNEL
+#include <sys/counter.h>
+
+VNET_PCPUSTAT_DECLARE(struct ip6stat, ip6stat);
+#define	IP6STAT_ADD(name, val)	\
+    VNET_PCPUSTAT_ADD(struct ip6stat, ip6stat, name, (val))
+#define	IP6STAT_SUB(name, val)	IP6STAT_ADD(name, -(val))
+#define	IP6STAT_INC(name)	IP6STAT_ADD(name, 1)
+#define	IP6STAT_DEC(name)	IP6STAT_SUB(name, 1)
+#endif
+
+#ifdef _KERNEL
+/* flags passed to ip6_output as last parameter */
+#define	IPV6_UNSPECSRC		0x01	/* allow :: as the source address */
+#define	IPV6_FORWARDING		0x02	/* most of IPv6 header exists */
+#define	IPV6_MINMTU		0x04	/* use minimum MTU (IPV6_USE_MIN_MTU) */
+
+#ifdef __NO_STRICT_ALIGNMENT
+#define IP6_HDR_ALIGNED_P(ip)	1
+#else
+#define IP6_HDR_ALIGNED_P(ip)	((((intptr_t) (ip)) & 3) == 0)
+#endif
+
+VNET_DECLARE(int, ip6_defhlim);		/* default hop limit */
+VNET_DECLARE(int, ip6_defmcasthlim);	/* default multicast hop limit */
+VNET_DECLARE(int, ip6_forwarding);	/* act as router? */
+VNET_DECLARE(int, ip6_use_deprecated);	/* allow deprecated addr as source */
+VNET_DECLARE(int, ip6_rr_prune);	/* router renumbering prefix
+					 * walk list every 5 sec.    */
+VNET_DECLARE(int, ip6_mcast_pmtu);	/* enable pMTU discovery for multicast? */
+VNET_DECLARE(int, ip6_v6only);
+#define	V_ip6_defhlim			VNET(ip6_defhlim)
+#define	V_ip6_defmcasthlim		VNET(ip6_defmcasthlim)
+#define	V_ip6_forwarding		VNET(ip6_forwarding)
+#define	V_ip6_use_deprecated		VNET(ip6_use_deprecated)
+#define	V_ip6_rr_prune			VNET(ip6_rr_prune)
+#define	V_ip6_mcast_pmtu		VNET(ip6_mcast_pmtu)
+#define	V_ip6_v6only			VNET(ip6_v6only)
+
+VNET_DECLARE(struct socket *, ip6_mrouter);	/* multicast routing daemon */
+VNET_DECLARE(int, ip6_sendredirects);	/* send IP redirects when forwarding? */
+VNET_DECLARE(int, ip6_maxfragpackets);	/* Maximum packets in reassembly
+					 * queue */
+VNET_DECLARE(int, ip6_maxfrags);	/* Maximum fragments in reassembly
+					 * queue */
+VNET_DECLARE(int, ip6_accept_rtadv);	/* Acts as a host not a router */
+VNET_DECLARE(int, ip6_no_radr);		/* No defroute from RA */
+VNET_DECLARE(int, ip6_norbit_raif);	/* Disable R-bit in NA on RA
+					 * receiving IF. */
+VNET_DECLARE(int, ip6_rfc6204w3);	/* Accept defroute from RA even when
+					   forwarding enabled */
+VNET_DECLARE(int, ip6_log_interval);
+VNET_DECLARE(time_t, ip6_log_time);
+VNET_DECLARE(int, ip6_hdrnestlimit);	/* upper limit of # of extension
+					 * headers */
+VNET_DECLARE(int, ip6_dad_count);	/* DupAddrDetectionTransmits */
+#define	V_ip6_mrouter			VNET(ip6_mrouter)
+#define	V_ip6_sendredirects		VNET(ip6_sendredirects)
+#define	V_ip6_maxfragpackets		VNET(ip6_maxfragpackets)
+#define	V_ip6_maxfrags			VNET(ip6_maxfrags)
+#define	V_ip6_accept_rtadv		VNET(ip6_accept_rtadv)
+#define	V_ip6_no_radr			VNET(ip6_no_radr)
+#define	V_ip6_norbit_raif		VNET(ip6_norbit_raif)
+#define	V_ip6_rfc6204w3			VNET(ip6_rfc6204w3)
+#define	V_ip6_log_interval		VNET(ip6_log_interval)
+#define	V_ip6_log_time			VNET(ip6_log_time)
+#define	V_ip6_hdrnestlimit		VNET(ip6_hdrnestlimit)
+#define	V_ip6_dad_count			VNET(ip6_dad_count)
+
+VNET_DECLARE(int, ip6_auto_flowlabel);
+VNET_DECLARE(int, ip6_auto_linklocal);
+#define	V_ip6_auto_flowlabel		VNET(ip6_auto_flowlabel)
+#define	V_ip6_auto_linklocal		VNET(ip6_auto_linklocal)
+
+VNET_DECLARE(int, ip6_use_tempaddr);	/* Whether to use temporary addresses */
+VNET_DECLARE(int, ip6_prefer_tempaddr);	/* Whether to prefer temporary
+					 * addresses in the source address
+					 * selection */
+#define	V_ip6_use_tempaddr		VNET(ip6_use_tempaddr)
+#define	V_ip6_prefer_tempaddr		VNET(ip6_prefer_tempaddr)
+
+VNET_DECLARE(int, ip6_use_defzone);	/* Whether to use the default scope
+					 * zone when unspecified */
+#define	V_ip6_use_defzone		VNET(ip6_use_defzone)
+
+VNET_DECLARE (struct pfil_head, inet6_pfil_hook);	/* packet filter hooks */
+#define	V_inet6_pfil_hook	VNET(inet6_pfil_hook)
+#ifdef IPSTEALTH
+VNET_DECLARE(int, ip6stealth);
+#define	V_ip6stealth			VNET(ip6stealth)
+#endif
+
+extern struct	pr_usrreqs rip6_usrreqs;
+struct sockopt;
+
+struct inpcb;
+
+int	icmp6_ctloutput(struct socket *, struct sockopt *sopt);
+
+struct in6_ifaddr;
+void	ip6_init(void);
+int	ip6proto_register(short);
+int	ip6proto_unregister(short);
+
+void	ip6_input(struct mbuf *);
+void	ip6_direct_input(struct mbuf *);
+void	ip6_freepcbopts(struct ip6_pktopts *);
+
+int	ip6_unknown_opt(u_int8_t *, struct mbuf *, int);
+char *	ip6_get_prevhdr(const struct mbuf *, int);
+int	ip6_nexthdr(const struct mbuf *, int, int, int *);
+int	ip6_lasthdr(const struct mbuf *, int, int, int *);
+
+extern int	(*ip6_mforward)(struct ip6_hdr *, struct ifnet *,
+    struct mbuf *);
+
+int	ip6_process_hopopts(struct mbuf *, u_int8_t *, int, u_int32_t *,
+				 u_int32_t *);
+struct mbuf	**ip6_savecontrol_v4(struct inpcb *, struct mbuf *,
+	    struct mbuf **, int *);
+void	ip6_savecontrol(struct inpcb *, struct mbuf *, struct mbuf **);
+void	ip6_notify_pmtu(struct inpcb *, struct sockaddr_in6 *, u_int32_t);
+int	ip6_sysctl(int *, u_int, void *, size_t *, void *, size_t);
+
+void	ip6_forward(struct mbuf *, int);
+
+void	ip6_mloopback(struct ifnet *, struct mbuf *);
+int	ip6_output(struct mbuf *, struct ip6_pktopts *,
+			struct route_in6 *,
+			int,
+			struct ip6_moptions *, struct ifnet **,
+			struct inpcb *);
+int	ip6_ctloutput(struct socket *, struct sockopt *);
+int	ip6_raw_ctloutput(struct socket *, struct sockopt *);
+void	ip6_initpktopts(struct ip6_pktopts *);
+int	ip6_setpktopts(struct mbuf *, struct ip6_pktopts *,
+	struct ip6_pktopts *, struct ucred *, int);
+void	ip6_clearpktopts(struct ip6_pktopts *, int);
+struct ip6_pktopts *ip6_copypktopts(struct ip6_pktopts *, int);
+int	ip6_optlen(struct inpcb *);
+int	ip6_deletefraghdr(struct mbuf *, int, int);
+int	ip6_fragment(struct ifnet *, struct mbuf *, int, u_char, int,
+			uint32_t);
+
+int	route6_input(struct mbuf **, int *, int);
+
+void	frag6_init(void);
+int	frag6_input(struct mbuf **, int *, int);
+void	frag6_slowtimo(void);
+void	frag6_drain(void);
+
+void	rip6_init(void);
+int	rip6_input(struct mbuf **, int *, int);
+void	rip6_ctlinput(int, struct sockaddr *, void *);
+int	rip6_ctloutput(struct socket *, struct sockopt *);
+int	rip6_output(struct mbuf *, struct socket *, ...);
+int	rip6_usrreq(struct socket *,
+	    int, struct mbuf *, struct mbuf *, struct mbuf *, struct thread *);
+
+int	dest6_input(struct mbuf **, int *, int);
+int	none_input(struct mbuf **, int *, int);
+
+int	in6_selectsrc_socket(struct sockaddr_in6 *, struct ip6_pktopts *,
+    struct inpcb *, struct ucred *, int, struct in6_addr *, int *);
+int	in6_selectsrc_addr(uint32_t, const struct in6_addr *,
+    uint32_t, struct ifnet *, struct in6_addr *, int *);
+int in6_selectroute(struct sockaddr_in6 *, struct ip6_pktopts *,
+	struct ip6_moptions *, struct route_in6 *, struct ifnet **,
+	struct rtentry **);
+int	in6_selectroute_fib(struct sockaddr_in6 *, struct ip6_pktopts *,
+	    struct ip6_moptions *, struct route_in6 *, struct ifnet **,
+	    struct rtentry **, u_int);
+u_int32_t ip6_randomid(void);
+u_int32_t ip6_randomflowlabel(void);
+void in6_delayed_cksum(struct mbuf *m, uint32_t plen, u_short offset);
+#endif /* _KERNEL */
+
+#endif /* !_NETINET6_IP6_VAR_H_ */
diff --git a/tools/compat/include/netinet6/pim6_var.h b/tools/compat/include/netinet6/pim6_var.h
new file mode 100644
index 000000000..7f9262bbc
--- /dev/null
+++ b/tools/compat/include/netinet6/pim6_var.h
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (C) 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	$KAME: pim6_var.h,v 1.8 2000/06/06 08:07:43 jinmei Exp $
+ * $FreeBSD$
+ */
+
+/*
+ * Protocol Independent Multicast (PIM),
+ * implementation-specific definitions.
+ *
+ * Written by George Edmond Eddy (Rusty), ISI, February 1998
+ * Modified by Pavlin Ivanov Radoslavov, USC/ISI, May 1998
+ */
+
+#ifndef _NETINET6_PIM6_VAR_H_
+#define _NETINET6_PIM6_VAR_H_
+
+struct pim6stat {
+	uint64_t pim6s_rcv_total;	/* total PIM messages received	*/
+	uint64_t pim6s_rcv_tooshort;	/* received with too few bytes	*/
+	uint64_t pim6s_rcv_badsum;	/* received with bad checksum	*/
+	uint64_t pim6s_rcv_badversion;	/* received bad PIM version	*/
+	uint64_t pim6s_rcv_registers;	/* received registers		*/
+	uint64_t pim6s_rcv_badregisters; /* received invalid registers	*/
+	uint64_t pim6s_snd_registers;	/* sent registers		*/
+};
+
+#if (defined(KERNEL)) || (defined(_KERNEL))
+int pim6_input(struct mbuf **, int*, int);
+#endif /* KERNEL */
+
+/*
+ * Identifiers for PIM sysctl nodes
+ */
+#define PIM6CTL_STATS		1	/* statistics (read-only) */
+
+#endif /* _NETINET6_PIM6_VAR_H_ */
diff --git a/tools/compat/include/netinet6/raw_ip6.h b/tools/compat/include/netinet6/raw_ip6.h
new file mode 100644
index 000000000..5eec5fffd
--- /dev/null
+++ b/tools/compat/include/netinet6/raw_ip6.h
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (C) 2001 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	$KAME: raw_ip6.h,v 1.2 2001/05/27 13:28:35 itojun Exp $
+ * $FreeBSD$
+ */
+
+#ifndef _NETINET6_RAW_IP6_H_
+#define _NETINET6_RAW_IP6_H_
+
+/*
+ * ICMPv6 stat is counted separately.  see netinet/icmp6.h
+ */
+struct rip6stat {
+	uint64_t rip6s_ipackets;	/* total input packets */
+	uint64_t rip6s_isum;		/* input checksum computations */
+	uint64_t rip6s_badsum;		/* of above, checksum error */
+	uint64_t rip6s_nosock;		/* no matching socket */
+	uint64_t rip6s_nosockmcast;	/* of above, arrived as multicast */
+	uint64_t rip6s_fullsock;	/* not delivered, input socket full */
+
+	uint64_t rip6s_opackets;	/* total output packets */
+};
+
+#ifdef _KERNEL
+#include <sys/counter.h>
+
+VNET_PCPUSTAT_DECLARE(struct rip6stat, rip6stat);
+#define	RIP6STAT_ADD(name, val)	\
+    VNET_PCPUSTAT_ADD(struct rip6stat, rip6stat, name, (val))
+#define	RIP6STAT_INC(name)	RIP6STAT_ADD(name, 1)
+#endif /* _KERNEL */
+
+#endif
diff --git a/tools/netstat/inet6.c b/tools/netstat/inet6.c
index d01f690ec..d3866d29f 100644
--- a/tools/netstat/inet6.c
+++ b/tools/netstat/inet6.c
@@ -621,7 +621,11 @@ ip6_ifstats(char *ifname)
 	}
 
 	strcpy(ifr.ifr_name, ifname);
+#ifndef FSTACK
 	if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) {
+#else
+	if (ioctl_va(s, SIOCGIFSTAT_IN6, (char *)&ifr, 1, AF_INET6) < 0) {
+#endif
 		if (errno != EPFNOSUPPORT)
 			xo_warn("Warning: ioctl(SIOCGIFSTAT_IN6)");
 		goto end;
@@ -1082,7 +1086,11 @@ icmp6_ifstats(char *ifname)
 	}
 
 	strcpy(ifr.ifr_name, ifname);
+#ifndef FSTACK
 	if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) {
+#else
+	if (ioctl_va(s, SIOCGIFSTAT_ICMP6, (char *)&ifr, 1, AF_INET6) < 0) {
+#endif
 		if (errno != EPFNOSUPPORT)
 			xo_warn("Warning: ioctl(SIOCGIFSTAT_ICMP6)");
 		goto end;
@@ -1315,6 +1323,8 @@ inet6name(struct in6_addr *in6p)
 		strcpy(line, "*");
 		return (line);
 	}
+
+#ifndef FSTACK
 	if (first && !numeric_addr) {
 		first = 0;
 		if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
@@ -1323,11 +1333,15 @@ inet6name(struct in6_addr *in6p)
 		else
 			domain[0] = 0;
 	}
+#endif
+
 	memset(&sin6, 0, sizeof(sin6));
 	memcpy(&sin6.sin6_addr, in6p, sizeof(*in6p));
 	sin6.sin6_family = AF_INET6;
 	/* XXX: in6p.s6_addr[2] can contain scopeid. */
 	in6_fillscopeid(&sin6);
+
+#ifndef FSTACK
 	flags = (numeric_addr) ? NI_NUMERICHOST : 0;
 	error = getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), hbuf,
 	    sizeof(hbuf), NULL, 0, flags);
@@ -1337,10 +1351,16 @@ inet6name(struct in6_addr *in6p)
 		    !strcmp(cp + 1, domain))
 			*cp = 0;
 		strcpy(line, hbuf);
-	} else {
+	} else
+#endif
+	{
 		/* XXX: this should not happen. */
 		sprintf(line, "%s",
+#ifndef FSTACK
 			inet_ntop(AF_INET6, (void *)&sin6.sin6_addr, ntop_buf,
+#else
+			inet_ntop(AF_INET6_LINUX, (void *)&sin6.sin6_addr, ntop_buf,
+#endif
 				sizeof(ntop_buf)));
 	}
 	return (line);