svn commit: r324227 - in head: lib/libprocstat sys/kern sys/netinet6 sys/sys usr.bin/bluetooth/btsockstat usr.bin/netstat usr.bin/sockstat usr.bin/systat

Gleb Smirnoff glebius at FreeBSD.org
Mon Oct 2 23:29:59 UTC 2017


Author: glebius
Date: Mon Oct  2 23:29:56 2017
New Revision: 324227
URL: https://svnweb.freebsd.org/changeset/base/324227

Log:
  Hide struct socket and struct unpcb from the userland.
  
  Violators may define _WANT_SOCKET and _WANT_UNPCB respectively and
  are not guaranteed for stability of the structures.  The violators
  list is the the usual one: libprocstat(3) and netstat(1) internally
  and lsof in ports.
  
  In struct xunpcb remove the inclusion of kernel structure and add
  a bunch of spare fields.  The xsocket already has socket not included,
  but add there spares as well.  Embed xsockbuf into xsocket.
  
  Sort declarations in sys/socketvar.h to separate kernel only from
  userland available ones.
  
  PR:		221820 (exp-run)

Deleted:
  head/sys/sys/sockstate.h
Modified:
  head/lib/libprocstat/libprocstat.c
  head/sys/kern/uipc_usrreq.c
  head/sys/netinet6/send.c
  head/sys/sys/param.h
  head/sys/sys/sockbuf.h
  head/sys/sys/socketvar.h
  head/sys/sys/unpcb.h
  head/usr.bin/bluetooth/btsockstat/btsockstat.c
  head/usr.bin/netstat/inet.c
  head/usr.bin/netstat/netgraph.c
  head/usr.bin/netstat/unix.c
  head/usr.bin/sockstat/sockstat.c
  head/usr.bin/systat/netstat.c

Modified: head/lib/libprocstat/libprocstat.c
==============================================================================
--- head/lib/libprocstat/libprocstat.c	Mon Oct  2 23:23:12 2017	(r324226)
+++ head/lib/libprocstat/libprocstat.c	Mon Oct  2 23:29:56 2017	(r324227)
@@ -48,10 +48,12 @@ __FBSDID("$FreeBSD$");
 #include <sys/stat.h>
 #include <sys/vnode.h>
 #include <sys/socket.h>
+#define	_WANT_SOCKET
 #include <sys/socketvar.h>
 #include <sys/domain.h>
 #include <sys/protosw.h>
 #include <sys/un.h>
+#define	_WANT_UNPCB
 #include <sys/unpcb.h>
 #include <sys/sysctl.h>
 #include <sys/tty.h>

Modified: head/sys/kern/uipc_usrreq.c
==============================================================================
--- head/sys/kern/uipc_usrreq.c	Mon Oct  2 23:23:12 2017	(r324226)
+++ head/sys/kern/uipc_usrreq.c	Mon Oct  2 23:29:56 2017	(r324227)
@@ -1646,12 +1646,20 @@ unp_pcblist(SYSCTL_HANDLER_ARGS)
 			if (unp->unp_addr != NULL)
 				bcopy(unp->unp_addr, &xu->xu_addr,
 				      unp->unp_addr->sun_len);
+			else
+				bzero(&xu->xu_addr, sizeof(xu->xu_addr));
 			if (unp->unp_conn != NULL &&
 			    unp->unp_conn->unp_addr != NULL)
 				bcopy(unp->unp_conn->unp_addr,
 				      &xu->xu_caddr,
 				      unp->unp_conn->unp_addr->sun_len);
-			bcopy(unp, &xu->xu_unp, sizeof *unp);
+			else
+				bzero(&xu->xu_caddr, sizeof(xu->xu_caddr));
+			xu->unp_vnode = unp->unp_vnode;
+			xu->unp_conn = unp->unp_conn;
+			xu->xu_firstref = LIST_FIRST(&unp->unp_refs);
+			xu->xu_nextref = LIST_NEXT(unp, unp_reflink);
+			xu->unp_gencnt = unp->unp_gencnt;
 			sotoxsocket(unp->unp_socket, &xu->xu_socket);
 			UNP_PCB_UNLOCK(unp);
 			error = SYSCTL_OUT(req, xu, sizeof *xu);

Modified: head/sys/netinet6/send.c
==============================================================================
--- head/sys/netinet6/send.c	Mon Oct  2 23:23:12 2017	(r324226)
+++ head/sys/netinet6/send.c	Mon Oct  2 23:29:56 2017	(r324227)
@@ -37,7 +37,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/sdt.h>
 #include <sys/systm.h>
 #include <sys/socket.h>
-#include <sys/sockstate.h>
 #include <sys/sockbuf.h>
 #include <sys/socketvar.h>
 #include <sys/types.h>

Modified: head/sys/sys/param.h
==============================================================================
--- head/sys/sys/param.h	Mon Oct  2 23:23:12 2017	(r324226)
+++ head/sys/sys/param.h	Mon Oct  2 23:29:56 2017	(r324227)
@@ -58,7 +58,7 @@
  *		in the range 5 to 9.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 1200047	/* Master, propagated to newvers */
+#define __FreeBSD_version 1200048	/* Master, propagated to newvers */
 
 /*
  * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,

Modified: head/sys/sys/sockbuf.h
==============================================================================
--- head/sys/sys/sockbuf.h	Mon Oct  2 23:23:12 2017	(r324226)
+++ head/sys/sys/sockbuf.h	Mon Oct  2 23:29:56 2017	(r324227)
@@ -65,18 +65,6 @@ struct socket;
 struct thread;
 struct selinfo;
 
-struct	xsockbuf {
-	u_int	sb_cc;
-	u_int	sb_hiwat;
-	u_int	sb_mbcnt;
-	u_int   sb_mcnt;
-	u_int   sb_ccnt;
-	u_int	sb_mbmax;
-	int	sb_lowat;
-	int	sb_timeo;
-	short	sb_flags;
-};
-
 /*
  * Variables for socket buffering.
  *
@@ -174,7 +162,6 @@ struct mbuf *
 	sbsndptr(struct sockbuf *sb, u_int off, u_int len, u_int *moff);
 struct mbuf *
 	sbsndmbuf(struct sockbuf *sb, u_int off, u_int *moff);
-void	sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb);
 int	sbwait(struct sockbuf *sb);
 int	sblock(struct sockbuf *sb, int flags);
 void	sbunlock(struct sockbuf *sb);

Modified: head/sys/sys/socketvar.h
==============================================================================
--- head/sys/sys/socketvar.h	Mon Oct  2 23:23:12 2017	(r324226)
+++ head/sys/sys/socketvar.h	Mon Oct  2 23:29:56 2017	(r324227)
@@ -34,6 +34,12 @@
 #ifndef _SYS_SOCKETVAR_H_
 #define _SYS_SOCKETVAR_H_
 
+/*
+ * Socket generation count type.  Also used in xinpcb, xtcpcb, xunpcb.
+ */
+typedef uint64_t so_gen_t;
+
+#if defined(_KERNEL) || defined(_WANT_SOCKET)
 #include <sys/queue.h>			/* for TAILQ macros */
 #include <sys/selinfo.h>		/* for struct selinfo */
 #include <sys/_lock.h>
@@ -41,7 +47,6 @@
 #include <sys/osd.h>
 #include <sys/_sx.h>
 #include <sys/sockbuf.h>
-#include <sys/sockstate.h>
 #ifdef _KERNEL
 #include <sys/caprights.h>
 #include <sys/sockopt.h>
@@ -55,7 +60,6 @@ struct vnet;
  * handle on protocol and pointer to protocol
  * private data and error information.
  */
-typedef	uint64_t so_gen_t;
 typedef	int so_upcall_t(struct socket *, void *, int);
 
 struct socket;
@@ -167,7 +171,40 @@ struct socket {
 		};
 	};
 };
+#endif	/* defined(_KERNEL) || defined(_WANT_SOCKET) */
 
+/*
+ * Socket state bits.
+ *
+ * Historically, this bits were all kept in the so_state field.  For
+ * locking reasons, they are now in multiple fields, as they are
+ * locked differently.  so_state maintains basic socket state protected
+ * by the socket lock.  so_qstate holds information about the socket
+ * accept queues.  Each socket buffer also has a state field holding
+ * information relevant to that socket buffer (can't send, rcv).  Many
+ * fields will be read without locks to improve performance and avoid
+ * lock order issues.  However, this approach must be used with caution.
+ */
+#define	SS_NOFDREF		0x0001	/* no file table ref any more */
+#define	SS_ISCONNECTED		0x0002	/* socket connected to a peer */
+#define	SS_ISCONNECTING		0x0004	/* in process of connecting to peer */
+#define	SS_ISDISCONNECTING	0x0008	/* in process of disconnecting */
+#define	SS_NBIO			0x0100	/* non-blocking ops */
+#define	SS_ASYNC		0x0200	/* async i/o notify */
+#define	SS_ISCONFIRMING		0x0400	/* deciding to accept connection req */
+#define	SS_ISDISCONNECTED	0x2000	/* socket disconnected from peer */
+
+/*
+ * Protocols can mark a socket as SS_PROTOREF to indicate that, following
+ * pru_detach, they still want the socket to persist, and will free it
+ * themselves when they are done.  Protocols should only ever call sofree()
+ * following setting this flag in pru_detach(), and never otherwise, as
+ * sofree() bypasses socket reference counting.
+ */
+#define	SS_PROTOREF		0x4000	/* strong protocol reference */
+
+#ifdef _KERNEL
+
 #define	SOCK_MTX(so)		&(so)->so_lock
 #define	SOCK_LOCK(so)		mtx_lock(&(so)->so_lock)
 #define	SOCK_OWNED(so)		mtx_owned(&(so)->so_lock)
@@ -194,32 +231,6 @@ struct socket {
 } while (0)
 
 /*
- * Externalized form of struct socket used by the sysctl(3) interface.
- */
-struct xsocket {
-	size_t	xso_len;	/* length of this structure */
-	struct	socket *xso_so;	/* makes a convenient handle sometimes */
-	short	so_type;
-	short	so_options;
-	short	so_linger;
-	short	so_state;
-	caddr_t	so_pcb;		/* another convenient handle */
-	int	xso_protocol;
-	int	xso_family;
-	u_int	so_qlen;
-	u_int	so_incqlen;
-	u_int	so_qlimit;
-	short	so_timeo;
-	u_short	so_error;
-	pid_t	so_pgid;
-	u_long	so_oobmark;
-	struct xsockbuf so_rcv, so_snd;
-	uid_t	so_uid;		/* XXX */
-};
-
-#ifdef _KERNEL
-
-/*
  * Macros for sockets and socket buffering.
  */
 
@@ -422,7 +433,6 @@ int	sosend_generic(struct socket *so, struct sockaddr 
 	    struct uio *uio, struct mbuf *top, struct mbuf *control,
 	    int flags, struct thread *td);
 int	soshutdown(struct socket *so, int how);
-void	sotoxsocket(struct socket *so, struct xsocket *xso);
 void	soupcall_clear(struct socket *, int);
 void	soupcall_set(struct socket *, int, so_upcall_t, void *);
 void	solisten_upcall_set(struct socket *, so_upcall_t, void *);
@@ -431,6 +441,14 @@ void	sowakeup_aio(struct socket *so, struct sockbuf *s
 void	solisten_wakeup(struct socket *);
 int	selsocket(struct socket *so, int events, struct timeval *tv,
 	    struct thread *td);
+void	soisconnected(struct socket *so);
+void	soisconnecting(struct socket *so);
+void	soisdisconnected(struct socket *so);
+void	soisdisconnecting(struct socket *so);
+void	socantrcvmore(struct socket *so);
+void	socantrcvmore_locked(struct socket *so);
+void	socantsendmore(struct socket *so);
+void	socantsendmore_locked(struct socket *so);
 
 /*
  * Accept filter functions (duh).
@@ -446,5 +464,59 @@ int	accept_filt_generic_mod_event(module_t mod, int ev
 #endif
 
 #endif /* _KERNEL */
+
+/*
+ * Structure to export socket from kernel to utilities, via sysctl(3).
+ */
+struct xsocket {
+	size_t		xso_len;	/* length of this structure */
+	union {
+		void	*xso_so;	/* kernel address of struct socket */
+		int64_t ph_so;
+	};
+	union {
+		void 	*so_pcb;	/* kernel address of struct inpcb */
+		int64_t ph_pcb;
+	};
+	uint64_t	so_oobmark;
+	int64_t		so_spare64[8];
+	int32_t		xso_protocol;
+	int32_t		xso_family;
+	uint32_t	so_qlen;
+	uint32_t	so_incqlen;
+	uint32_t	so_qlimit;
+	pid_t		so_pgid;
+	uid_t		so_uid;
+	int32_t		so_spare32[8];
+	int16_t		so_type;
+	int16_t		so_options;
+	int16_t		so_linger;
+	int16_t		so_state;
+	int16_t		so_timeo;
+	uint16_t	so_error;
+	struct xsockbuf {
+		uint32_t	sb_cc;
+		uint32_t	sb_hiwat;
+		uint32_t	sb_mbcnt;
+		uint32_t	sb_mcnt;
+		uint32_t	sb_ccnt;
+		uint32_t	sb_mbmax;
+		int32_t		sb_lowat;
+		int32_t		sb_timeo;
+		int16_t		sb_flags;
+	} so_rcv, so_snd;
+};
+
+#ifdef _KERNEL
+void	sotoxsocket(struct socket *so, struct xsocket *xso);
+void	sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb);
+#endif
+
+/*
+ * Socket buffer state bits.  Exported via libprocstat(3).
+ */
+#define	SBS_CANTSENDMORE	0x0010	/* can't send more data to peer */
+#define	SBS_CANTRCVMORE		0x0020	/* can't receive more data from peer */
+#define	SBS_RCVATMARK		0x0040	/* at mark on input */
 
 #endif /* !_SYS_SOCKETVAR_H_ */

Modified: head/sys/sys/unpcb.h
==============================================================================
--- head/sys/sys/unpcb.h	Mon Oct  2 23:23:12 2017	(r324226)
+++ head/sys/sys/unpcb.h	Mon Oct  2 23:29:56 2017	(r324227)
@@ -33,6 +33,9 @@
 #ifndef _SYS_UNPCB_H_
 #define _SYS_UNPCB_H_
 
+typedef uint64_t unp_gen_t;
+
+#if defined(_KERNEL) || defined(_WANT_UNPCB)
 #include <sys/queue.h>
 #include <sys/ucred.h>
 
@@ -61,7 +64,6 @@
  * so that changes in the sockbuf may be computed to modify
  * back pressure on the sender accordingly.
  */
-typedef	u_quad_t	unp_gen_t;
 LIST_HEAD(unp_head, unpcb);
 
 struct unpcb {
@@ -74,8 +76,6 @@ struct unpcb {
 	struct	unp_head unp_refs;	/* referencing socket linked list */
 	LIST_ENTRY(unpcb) unp_reflink;	/* link in unp_refs list */
 	struct	sockaddr_un *unp_addr;	/* bound address of socket */
-	int	reserved1;
-	int	reserved2;
 	unp_gen_t unp_gencnt;		/* generation count of this instance */
 	short	unp_flags;		/* flags */
 	short	unp_gcflag;		/* Garbage collector flags. */
@@ -116,32 +116,50 @@ struct unpcb {
 
 #define	sotounpcb(so)	((struct unpcb *)((so)->so_pcb))
 
-/* Hack alert -- this structure depends on <sys/socketvar.h>. */
+#endif	/* _KERNEL || _WANT_UNPCB */
+
+/*
+ * UNPCB structure exported to user-land via sysctl(3).
+ *
+ * Fields prefixed with "xu_" are unique to the export structure, and fields
+ * with "unp_" or other prefixes match corresponding fields of 'struct unpcb'.
+ *
+ * Legend:
+ * (s) - used by userland utilities in src
+ * (p) - used by utilities in ports
+ * (3) - is known to be used by third party software not in ports
+ * (n) - no known usage
+ *
+ * Evil hack: declare only if sys/socketvar.h have been included.
+ */
 #ifdef	_SYS_SOCKETVAR_H_
 struct xunpcb {
-	size_t	xu_len;			/* length of this structure */
-	struct	unpcb *xu_unpp;		/* to help netstat, fstat */
-	struct	unpcb xu_unp;		/* our information */
+	size_t		xu_len;			/* length of this structure */
+	void		*xu_unpp;		/* to help netstat, fstat */
+	void		*unp_vnode;		/* (s) */
+	void		*unp_conn;		/* (s) */
+	void		*xu_firstref;		/* (s) */
+	void		*xu_nextref;		/* (s) */
+	unp_gen_t	unp_gencnt;		/* (s) */
+	int64_t		xu_spare64[8];
+	int32_t		xu_spare32[8];
 	union {
-		struct	sockaddr_un xuu_addr;	/* our bound address */
+		struct	sockaddr_un xu_addr;	/* our bound address */
 		char	xu_dummy1[256];
-	} xu_au;
-#define	xu_addr	xu_au.xuu_addr
+	};
 	union {
-		struct	sockaddr_un xuu_caddr; /* their bound address */
+		struct	sockaddr_un xu_caddr;	/* their bound address */
 		char	xu_dummy2[256];
-	} xu_cau;
-#define	xu_caddr xu_cau.xuu_caddr
-	struct	xsocket	xu_socket;
-	u_quad_t	xu_alignment_hack;
-};
+	};
+	struct xsocket	xu_socket;
+} __aligned(8);
 
 struct xunpgen {
 	size_t	xug_len;
 	u_int	xug_count;
 	unp_gen_t xug_gen;
 	so_gen_t xug_sogen;
-};
+} __aligned(8);;
 #endif /* _SYS_SOCKETVAR_H_ */
 
 #endif /* _SYS_UNPCB_H_ */

Modified: head/usr.bin/bluetooth/btsockstat/btsockstat.c
==============================================================================
--- head/usr.bin/bluetooth/btsockstat/btsockstat.c	Mon Oct  2 23:23:12 2017	(r324226)
+++ head/usr.bin/bluetooth/btsockstat/btsockstat.c	Mon Oct  2 23:29:56 2017	(r324227)
@@ -35,6 +35,7 @@
 #include <sys/protosw.h>
 #include <sys/queue.h>
 #include <sys/socket.h>
+#define	_WANT_SOCKET
 #include <sys/socketvar.h>
 
 #include <net/if.h>

Modified: head/usr.bin/netstat/inet.c
==============================================================================
--- head/usr.bin/netstat/inet.c	Mon Oct  2 23:23:12 2017	(r324226)
+++ head/usr.bin/netstat/inet.c	Mon Oct  2 23:29:56 2017	(r324227)
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/domain.h>
 #include <sys/protosw.h>
 #include <sys/socket.h>
+#define	_WANT_SOCKET
 #include <sys/socketvar.h>
 #include <sys/sysctl.h>
 
@@ -172,7 +173,7 @@ sotoxsocket(struct socket *so, struct xsocket *xso)
 	xso->xso_family = domain.dom_family;
 	xso->so_timeo = so->so_timeo;
 	xso->so_error = so->so_error;
-	if (SOLISTENING(so)) {
+	if ((so->so_options & SO_ACCEPTCONN) != 0) {
 		xso->so_qlen = so->sol_qlen;
 		xso->so_incqlen = so->sol_incqlen;
 		xso->so_qlimit = so->sol_qlimit;

Modified: head/usr.bin/netstat/netgraph.c
==============================================================================
--- head/usr.bin/netstat/netgraph.c	Mon Oct  2 23:23:12 2017	(r324226)
+++ head/usr.bin/netstat/netgraph.c	Mon Oct  2 23:29:56 2017	(r324227)
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/queue.h>
 #include <sys/socket.h>
+#define	_WANT_SOCKET
 #include <sys/socketvar.h>
 #include <sys/protosw.h>
 #include <sys/linker.h>

Modified: head/usr.bin/netstat/unix.c
==============================================================================
--- head/usr.bin/netstat/unix.c	Mon Oct  2 23:23:12 2017	(r324226)
+++ head/usr.bin/netstat/unix.c	Mon Oct  2 23:29:56 2017	(r324227)
@@ -43,10 +43,12 @@ __FBSDID("$FreeBSD$");
 #include <sys/queue.h>
 #include <sys/protosw.h>
 #include <sys/socket.h>
+#define	_WANT_SOCKET
 #include <sys/socketvar.h>
 #include <sys/mbuf.h>
 #include <sys/sysctl.h>
 #include <sys/un.h>
+#define	_WANT_UNPCB
 #include <sys/unpcb.h>
 
 #include <netinet/in.h>
@@ -100,7 +102,7 @@ static int
 pcblist_kvm(u_long count_off, u_long gencnt_off, u_long head_off, char **bufp)
 {
 	struct unp_head head;
-	struct unpcb *unp, unp_conn;
+	struct unpcb *unp, unp0, unp_conn;
 	u_char sun_len;
 	struct socket so;
 	struct xunpgen xug;
@@ -150,8 +152,8 @@ pcblist_kvm(u_long count_off, u_long gencnt_off, u_lon
 	KREAD(head_off, &head, sizeof(head));
 	LIST_FOREACH(unp, &head, unp_link) {
 		xu.xu_unpp = unp;
-		KREAD(unp, &xu.xu_unp, sizeof (*unp));
-		unp = &xu.xu_unp;
+		KREAD(unp, &unp0, sizeof (*unp));
+		unp = &unp0;
 
 		if (unp->unp_gencnt > unp_gencnt)
 			continue;
@@ -236,7 +238,7 @@ unixpr(u_long count_off, u_long gencnt_off, u_long dhe
 			so = &xunp->xu_socket;
 
 			/* Ignore PCBs which were freed during copyout. */
-			if (xunp->xu_unp.unp_gencnt > oxug->xug_gen)
+			if (xunp->unp_gencnt > oxug->xug_gen)
 				continue;
 			if (*first) {
 				xo_open_list("socket");
@@ -268,7 +270,6 @@ unixpr(u_long count_off, u_long gencnt_off, u_long dhe
 static void
 unixdomainpr(struct xunpcb *xunp, struct xsocket *so)
 {
-	struct unpcb *unp;
 	struct sockaddr_un *sa;
 	static int first = 1;
 	char buf1[33];
@@ -292,11 +293,7 @@ unixdomainpr(struct xunpcb *xunp, struct xsocket *so)
 	};
 	int fmt = (sizeof(void *) == 8) ? 1 : 0;
 
-	unp = &xunp->xu_unp;
-	if (unp->unp_addr)
-		sa = &xunp->xu_addr;
-	else
-		sa = (struct sockaddr_un *)0;
+	sa = (xunp->xu_addr.sun_family == AF_UNIX) ? &xunp->xu_addr : NULL;
 
 	if (first && !Lflag) {
 		xo_emit("{T:Active UNIX domain sockets}\n");
@@ -318,10 +315,9 @@ unixdomainpr(struct xunpcb *xunp, struct xsocket *so)
 	} else {
 		xo_emit(format[fmt],
 		    (long)so->so_pcb, socktype[so->so_type], so->so_rcv.sb_cc,
-		    so->so_snd.sb_cc, (long)unp->unp_vnode,
-		    (long)unp->unp_conn,
-		    (long)LIST_FIRST(&unp->unp_refs),
-		    (long)LIST_NEXT(unp, unp_reflink));
+		    so->so_snd.sb_cc, (long)xunp->unp_vnode,
+		    (long)xunp->unp_conn, (long)xunp->xu_firstref,
+		    (long)xunp->xu_nextref);
 	}
 	if (sa)
 		xo_emit(" {:path/%.*s}",

Modified: head/usr.bin/sockstat/sockstat.c
==============================================================================
--- head/usr.bin/sockstat/sockstat.c	Mon Oct  2 23:23:12 2017	(r324226)
+++ head/usr.bin/sockstat/sockstat.c	Mon Oct  2 23:29:56 2017	(r324227)
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/user.h>
 
 #include <sys/un.h>
+#define	_WANT_UNPCB
 #include <sys/unpcb.h>
 
 #include <net/route.h>
@@ -784,8 +785,8 @@ gather_unix(int proto)
 			warnx("struct xunpcb size mismatch");
 			goto out;
 		}
-		if ((xup->xu_unp.unp_conn == NULL && !opt_l) ||
-		    (xup->xu_unp.unp_conn != NULL && !opt_c))
+		if ((xup->unp_conn == NULL && !opt_l) ||
+		    (xup->unp_conn != NULL && !opt_c))
 			continue;
 		if ((sock = calloc(1, sizeof(*sock))) == NULL)
 			err(1, "malloc()");
@@ -798,11 +799,11 @@ gather_unix(int proto)
 		sock->proto = proto;
 		sock->family = AF_UNIX;
 		sock->protoname = protoname;
-		if (xup->xu_unp.unp_addr != NULL)
+		if (xup->xu_addr.sun_family == AF_UNIX)
 			laddr->address =
 			    *(struct sockaddr_storage *)(void *)&xup->xu_addr;
-		else if (xup->xu_unp.unp_conn != NULL)
-			*(void **)&(faddr->address) = xup->xu_unp.unp_conn;
+		else if (xup->unp_conn != NULL)
+			*(void **)&(faddr->address) = xup->unp_conn;
 		laddr->next = NULL;
 		faddr->next = NULL;
 		sock->laddr = laddr;

Modified: head/usr.bin/systat/netstat.c
==============================================================================
--- head/usr.bin/systat/netstat.c	Mon Oct  2 23:23:12 2017	(r324226)
+++ head/usr.bin/systat/netstat.c	Mon Oct  2 23:29:56 2017	(r324227)
@@ -41,6 +41,7 @@ static const char sccsid[] = "@(#)netstat.c	8.1 (Berke
 #include <sys/param.h>
 #include <sys/queue.h>
 #include <sys/socket.h>
+#define	_WANT_SOCKET
 #include <sys/socketvar.h>
 #include <sys/protosw.h>
 


More information about the svn-src-all mailing list