[Midnightbsd-cvs] src [11467] trunk/usr.bin/netstat: sync netstat with freebsd

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sat Jul 7 12:54:33 EDT 2018


Revision: 11467
          http://svnweb.midnightbsd.org/src/?rev=11467
Author:   laffer1
Date:     2018-07-07 12:54:32 -0400 (Sat, 07 Jul 2018)
Log Message:
-----------
sync netstat with freebsd

Modified Paths:
--------------
    trunk/usr.bin/netstat/Makefile
    trunk/usr.bin/netstat/atalk.c
    trunk/usr.bin/netstat/bpf.c
    trunk/usr.bin/netstat/if.c
    trunk/usr.bin/netstat/inet.c
    trunk/usr.bin/netstat/inet6.c
    trunk/usr.bin/netstat/ipsec.c
    trunk/usr.bin/netstat/ipx.c
    trunk/usr.bin/netstat/main.c
    trunk/usr.bin/netstat/mbuf.c
    trunk/usr.bin/netstat/mroute.c
    trunk/usr.bin/netstat/mroute6.c
    trunk/usr.bin/netstat/netgraph.c
    trunk/usr.bin/netstat/netisr.c
    trunk/usr.bin/netstat/netstat.1
    trunk/usr.bin/netstat/netstat.h
    trunk/usr.bin/netstat/pfkey.c
    trunk/usr.bin/netstat/route.c
    trunk/usr.bin/netstat/sctp.c
    trunk/usr.bin/netstat/unix.c

Added Paths:
-----------
    trunk/usr.bin/netstat/flowtable.c

Property Changed:
----------------
    trunk/usr.bin/netstat/netstat.1

Modified: trunk/usr.bin/netstat/Makefile
===================================================================
--- trunk/usr.bin/netstat/Makefile	2018-07-07 16:54:14 UTC (rev 11466)
+++ trunk/usr.bin/netstat/Makefile	2018-07-07 16:54:32 UTC (rev 11467)
@@ -1,11 +1,13 @@
+# $MidnightBSD$
 #	@(#)Makefile	8.1 (Berkeley) 6/12/93
-# $MidnightBSD$
+# $FreeBSD: stable/10/usr.bin/netstat/Makefile 291824 2015-12-04 21:11:17Z bdrewery $
 
 .include <bsd.own.mk>
 
 PROG=	netstat
 SRCS=	if.c inet.c main.c mbuf.c mroute.c netisr.c route.c \
-	unix.c atalk.c mroute6.c ipsec.c bpf.c pfkey.c sctp.c
+	unix.c atalk.c mroute6.c ipsec.c bpf.c pfkey.c sctp.c \
+	flowtable.c
 
 WARNS?=	3
 CFLAGS+=-fno-strict-aliasing
@@ -26,6 +28,10 @@
 CFLAGS+=-DSDP
 .endif
 
+.if ${MK_PF} != "no"
+CFLAGS+=-DPF
+.endif
+
 BINGRP=	kmem
 BINMODE=2555
 DPADD=	${LIBKVM} ${LIBMEMSTAT} ${LIBUTIL}

Modified: trunk/usr.bin/netstat/atalk.c
===================================================================
--- trunk/usr.bin/netstat/atalk.c	2018-07-07 16:54:14 UTC (rev 11466)
+++ trunk/usr.bin/netstat/atalk.c	2018-07-07 16:54:32 UTC (rev 11467)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1983, 1988, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -34,7 +35,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/usr.bin/netstat/atalk.c 228668 2011-12-17 22:32:00Z dim $");
 
 #include <sys/param.h>
 #include <sys/queue.h>

Modified: trunk/usr.bin/netstat/bpf.c
===================================================================
--- trunk/usr.bin/netstat/bpf.c	2018-07-07 16:54:14 UTC (rev 11466)
+++ trunk/usr.bin/netstat/bpf.c	2018-07-07 16:54:32 UTC (rev 11467)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2005 Christian S.J. Peron
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/usr.bin/netstat/bpf.c 200462 2009-12-13 03:14:06Z delphij $");
 
 #include <sys/types.h>
 #include <sys/protosw.h>

Added: trunk/usr.bin/netstat/flowtable.c
===================================================================
--- trunk/usr.bin/netstat/flowtable.c	                        (rev 0)
+++ trunk/usr.bin/netstat/flowtable.c	2018-07-07 16:54:32 UTC (rev 11467)
@@ -0,0 +1,88 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Gleb Smirnoff <glebius at FreeBSD.org>
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/usr.bin/netstat/flowtable.c 293307 2016-01-07 07:21:37Z markj $");
+
+#include <sys/param.h>
+
+#include <net/flowtable.h>
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include "netstat.h"
+
+/*
+ * Print flowtable statistics.
+ */
+
+static void
+print_stats(struct flowtable_stat *stat)
+{
+
+#define	p(f, m) if (stat->f || sflag <= 1) \
+	printf(m, (uintmax_t)stat->f, plural(stat->f))
+#define	p2(f, m) if (stat->f || sflag <= 1) \
+	printf(m, (uintmax_t)stat->f, plurales(stat->f))
+
+	p(ft_lookups, "\t%ju lookup%s\n");
+	p(ft_hits, "\t%ju hit%s\n");
+	p2(ft_misses, "\t%ju miss%s\n");
+	p(ft_inserts, "\t%ju insert%s\n");
+	p(ft_collisions, "\t%ju collision%s\n");
+	p(ft_free_checks, "\t%ju free check%s\n");
+	p(ft_frees, "\t%ju free%s\n");
+	p(ft_fail_lle_invalid,
+	    "\t%ju lookup%s with not resolved Layer 2 address\n");
+
+#undef	p2
+#undef	p
+}
+
+void
+flowtable_stats(void)
+{
+	struct flowtable_stat stat;
+
+	if (!live)
+		return;
+
+	if (fetch_stats("net.flowtable.ip4.stat", 0, &stat,
+	    sizeof(stat), NULL) == 0) {
+		printf("flowtable for IPv4:\n");
+		print_stats(&stat);
+	}
+
+	if (fetch_stats("net.flowtable.ip6.stat", 0, &stat,
+	    sizeof(stat), NULL) == 0) {
+		printf("flowtable for IPv6:\n");
+		print_stats(&stat);
+	}
+}


Property changes on: trunk/usr.bin/netstat/flowtable.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/usr.bin/netstat/if.c
===================================================================
--- trunk/usr.bin/netstat/if.c	2018-07-07 16:54:14 UTC (rev 11466)
+++ trunk/usr.bin/netstat/if.c	2018-07-07 16:54:32 UTC (rev 11467)
@@ -1,4 +1,6 @@
+/* $MidnightBSD$ */
 /*-
+ * Copyright (c) 2013 Gleb Smirnoff <glebius at FreeBSD.org>
  * Copyright (c) 1983, 1988, 1993
  *	The Regents of the University of California.  All rights reserved.
  *
@@ -34,53 +36,81 @@
 #endif
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/usr.bin/netstat/if.c 293307 2016-01-07 07:21:37Z markj $");
 
-#include <sys/types.h>
+#include <sys/param.h>
 #include <sys/protosw.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
-#include <sys/sysctl.h>
 #include <sys/time.h>
 
+#define	_IFI_OQDROPS
 #include <net/if.h>
 #include <net/if_var.h>
 #include <net/if_dl.h>
 #include <net/if_types.h>
 #include <net/ethernet.h>
-#include <net/pfvar.h>
-#include <net/if_pfsync.h>
 #include <netinet/in.h>
 #include <netinet/in_var.h>
 #include <netipx/ipx.h>
 #include <netipx/ipx_if.h>
 #include <arpa/inet.h>
+#ifdef PF
+#include <net/pfvar.h>
+#include <net/if_pfsync.h>
+#endif
 
 #include <err.h>
 #include <errno.h>
+#include <ifaddrs.h>
 #include <libutil.h>
 #ifdef INET6
 #include <netdb.h>
 #endif
 #include <signal.h>
+#include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sysexits.h>
 #include <unistd.h>
 
 #include "netstat.h"
 
-#define	YES	1
-#define	NO	0
+static void sidewaysintpr(int);
 
-static void sidewaysintpr(int, u_long);
-static void catchalarm(int);
-
 #ifdef INET6
 static char addr_buf[NI_MAXHOST];		/* for getnameinfo() */
 #endif
 
+#ifdef PF
+static const char* pfsyncacts[] = {
+	/* PFSYNC_ACT_CLR */		"clear all request",
+	/* PFSYNC_ACT_INS */		"state insert",
+	/* PFSYNC_ACT_INS_ACK */	"state inserted ack",
+	/* PFSYNC_ACT_UPD */		"state update",
+	/* PFSYNC_ACT_UPD_C */		"compressed state update",
+	/* PFSYNC_ACT_UPD_REQ */	"uncompressed state request",
+	/* PFSYNC_ACT_DEL */		"state delete",
+	/* PFSYNC_ACT_DEL_C */		"compressed state delete",
+	/* PFSYNC_ACT_INS_F */		"fragment insert",
+	/* PFSYNC_ACT_DEL_F */		"fragment delete",
+	/* PFSYNC_ACT_BUS */		"bulk update mark",
+	/* PFSYNC_ACT_TDB */		"TDB replay counter update",
+	/* PFSYNC_ACT_EOF */		"end of frame mark",
+};
+
+static void
+pfsync_acts_stats(const char *fmt, uint64_t *a)
+{
+	int i;
+
+	for (i = 0; i < PFSYNC_ACT_MAX; i++, a++)
+		if (*a || sflag <= 1)
+			printf(fmt, *a, pfsyncacts[i], plural(*a));
+}
+
 /*
  * Dump pfsync statistics structure.
  */
@@ -87,30 +117,21 @@
 void
 pfsync_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
 {
-	struct pfsyncstats pfsyncstat, zerostat;
-	size_t len = sizeof(struct pfsyncstats);
+	struct pfsyncstats pfsyncstat;
 
-	if (live) {
-		if (zflag)
-			memset(&zerostat, 0, len);
-		if (sysctlbyname("net.inet.pfsync.stats", &pfsyncstat, &len,
-		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
-			if (errno != ENOENT)
-				warn("sysctl: net.inet.pfsync.stats");
-			return;
-		}
-	} else
-		kread(off, &pfsyncstat, len);
+	if (fetch_stats("net.pfsync.stats", off, &pfsyncstat,
+	    sizeof(pfsyncstat), kread) != 0)
+		return;
 
 	printf("%s:\n", name);
 
 #define	p(f, m) if (pfsyncstat.f || sflag <= 1) \
 	printf(m, (uintmax_t)pfsyncstat.f, plural(pfsyncstat.f))
-#define	p2(f, m) if (pfsyncstat.f || sflag <= 1) \
-	printf(m, (uintmax_t)pfsyncstat.f)
 
 	p(pfsyncs_ipackets, "\t%ju packet%s received (IPv4)\n");
 	p(pfsyncs_ipackets6, "\t%ju packet%s received (IPv6)\n");
+	pfsync_acts_stats("\t    %ju %s%s received\n",
+	    &pfsyncstat.pfsyncs_iacts[0]);
 	p(pfsyncs_badif, "\t\t%ju packet%s discarded for bad interface\n");
 	p(pfsyncs_badttl, "\t\t%ju packet%s discarded for bad ttl\n");
 	p(pfsyncs_hdrops, "\t\t%ju packet%s shorter than header\n");
@@ -123,17 +144,20 @@
 	p(pfsyncs_badstate, "\t\t%ju failed state lookup/insert%s\n");
 	p(pfsyncs_opackets, "\t%ju packet%s sent (IPv4)\n");
 	p(pfsyncs_opackets6, "\t%ju packet%s sent (IPv6)\n");
-	p2(pfsyncs_onomem, "\t\t%ju send failed due to mbuf memory error\n");
-	p2(pfsyncs_oerrors, "\t\t%ju send error\n");
+	pfsync_acts_stats("\t    %ju %s%s sent\n",
+	    &pfsyncstat.pfsyncs_oacts[0]);
+	p(pfsyncs_onomem, "\t\t%ju failure%s due to mbuf memory error\n");
+	p(pfsyncs_oerrors, "\t\t%ju send error%s\n");
 #undef p
-#undef p2
 }
+#endif /* PF */
 
 /*
  * Display a formatted value, or a '-' in the same space.
  */
 static void
-show_stat(const char *fmt, int width, u_long value, short showvalue)
+show_stat(const char *fmt, int width, u_long value, short showvalue,
+    int div1000)
 {
 	const char *lsep, *rsep;
 	char newfmt[32];
@@ -160,7 +184,8 @@
 
 		/* Format in human readable form. */
 		humanize_number(buf, sizeof(buf), (int64_t)value, "",
-		    HN_AUTOSCALE, HN_NOSPACE | HN_DECIMAL);
+		    HN_AUTOSCALE, HN_NOSPACE | HN_DECIMAL | \
+		    ((div1000) ? HN_DIVISOR_1000 : 0));
 		sprintf(newfmt, "%s%%%ds%s", lsep, width, rsep);
 		printf(newfmt, buf);
 	} else {
@@ -171,58 +196,55 @@
 }
 
 /*
+ * Find next multiaddr for a given interface name.
+ */
+static struct ifmaddrs *
+next_ifma(struct ifmaddrs *ifma, const char *name, const sa_family_t family)
+{
+
+	for(; ifma != NULL; ifma = ifma->ifma_next) {
+		struct sockaddr_dl *sdl;
+
+		sdl = (struct sockaddr_dl *)ifma->ifma_name;
+		if (ifma->ifma_addr->sa_family == family &&
+		    strcmp(sdl->sdl_data, name) == 0)
+			break;
+	}
+
+	return (ifma);
+}
+
+/*
  * Print a description of the network interfaces.
  */
 void
-intpr(int interval1, u_long ifnetaddr, void (*pfunc)(char *))
+intpr(int interval, void (*pfunc)(char *), int af)
 {
-	struct ifnet ifnet;
-	struct ifnethead ifnethead;
-	union {
-		struct ifaddr ifa;
-		struct in_ifaddr in;
-#ifdef INET6
-		struct in6_ifaddr in6;
-#endif
-		struct ipx_ifaddr ipx;
-	} ifaddr;
-	u_long ifaddraddr;
-	u_long ifaddrfound;
-	u_long opackets;
-	u_long ipackets;
-	u_long obytes;
-	u_long ibytes;
-	u_long omcasts;
-	u_long imcasts;
-	u_long oerrors;
-	u_long ierrors;
-	u_long idrops;
-	u_long collisions;
-	int drops;
-	struct sockaddr *sa = NULL;
-	char name[IFNAMSIZ];
-	short network_layer;
-	short link_layer;
+	struct ifaddrs *ifap, *ifa;
+	struct ifmaddrs *ifmap, *ifma;
+	u_int ifn_len_max = 5;
 
-	if (ifnetaddr == 0) {
-		printf("ifnet: symbol not defined\n");
-		return;
+	if (interval)
+		return sidewaysintpr(interval);
+
+	if (getifaddrs(&ifap) != 0)
+		err(EX_OSERR, "getifaddrs");
+	if (aflag && getifmaddrs(&ifmap) != 0)
+		err(EX_OSERR, "getifmaddrs");
+
+	if (Wflag) {
+		for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+			if (interface != NULL &&
+			    strcmp(ifa->ifa_name, interface) != 0)
+				continue;
+			if (af != AF_UNSPEC && ifa->ifa_addr->sa_family != af)
+				continue;
+			ifn_len_max = MAX(ifn_len_max, strlen(ifa->ifa_name));
+		}
 	}
-	if (interval1) {
-		sidewaysintpr(interval1, ifnetaddr);
-		return;
-	}
-	if (kread(ifnetaddr, (char *)&ifnethead, sizeof ifnethead) != 0)
-		return;
-	ifnetaddr = (u_long)TAILQ_FIRST(&ifnethead);
-	if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) != 0)
-		return;
 
 	if (!pfunc) {
-		if (Wflag)
-			printf("%-7.7s", "Name");
-		else
-			printf("%-5.5s", "Name");
+		printf("%-*.*s", ifn_len_max, ifn_len_max, "Name");
 		printf(" %5.5s %-13.13s %-17.17s %8.8s %5.5s %5.5s",
 		    "Mtu", "Network", "Address", "Ipkts", "Ierrs", "Idrop");
 		if (bflag)
@@ -232,367 +254,298 @@
 			printf(" %10.10s","Obytes");
 		printf(" %5s", "Coll");
 		if (dflag)
-			printf(" %s", "Drop");
+			printf("  %s", "Drop");
 		putchar('\n');
 	}
-	ifaddraddr = 0;
-	while (ifnetaddr || ifaddraddr) {
-		struct sockaddr_in *sockin;
-#ifdef INET6
-		struct sockaddr_in6 *sockin6;
-#endif
-		char *cp;
-		int n, m;
 
-		network_layer = 0;
-		link_layer = 0;
+	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+		bool network = false, link = false;
 
-		if (ifaddraddr == 0) {
-			if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) != 0)
-				return;
-			strlcpy(name, ifnet.if_xname, sizeof(name));
-			ifnetaddr = (u_long)TAILQ_NEXT(&ifnet, if_link);
-			if (interface != 0 && strcmp(name, interface) != 0)
-				continue;
-			cp = index(name, '\0');
+		if (interface != NULL && strcmp(ifa->ifa_name, interface) != 0)
+			continue;
 
-			if (pfunc) {
-				(*pfunc)(name);
-				continue;
+		if (pfunc) {
+			char *name;
+
+			name = ifa->ifa_name;
+			(*pfunc)(name);
+
+			/*
+			 * Skip all ifaddrs belonging to same interface.
+			 */
+			while(ifa->ifa_next != NULL &&
+			    (strcmp(ifa->ifa_next->ifa_name, name) == 0)) {
+				ifa = ifa->ifa_next;
 			}
-
-			if ((ifnet.if_flags&IFF_UP) == 0)
-				*cp++ = '*';
-			*cp = '\0';
-			ifaddraddr = (u_long)TAILQ_FIRST(&ifnet.if_addrhead);
+			continue;
 		}
-		ifaddrfound = ifaddraddr;
 
-		/*
-		 * Get the interface stats.  These may get
-		 * overriden below on a per-interface basis.
-		 */
-		opackets = ifnet.if_opackets;
-		ipackets = ifnet.if_ipackets;
-		obytes = ifnet.if_obytes;
-		ibytes = ifnet.if_ibytes;
-		omcasts = ifnet.if_omcasts;
-		imcasts = ifnet.if_imcasts;
-		oerrors = ifnet.if_oerrors;
-		ierrors = ifnet.if_ierrors;
-		idrops = ifnet.if_iqdrops;
-		collisions = ifnet.if_collisions;
-		drops = ifnet.if_snd.ifq_drops;
+		if (af != AF_UNSPEC && ifa->ifa_addr->sa_family != af)
+			continue;
 
-		if (ifaddraddr == 0) {
-			if (Wflag)
-				printf("%-7.7s", name);
-			else
-				printf("%-5.5s", name);
-			printf(" %5lu ", ifnet.if_mtu);
+		printf("%-*.*s", ifn_len_max, ifn_len_max, ifa->ifa_name);
+
+#define IFA_MTU(ifa)	(((struct if_data *)(ifa)->ifa_data)->ifi_mtu)
+		show_stat("lu", 6, IFA_MTU(ifa), IFA_MTU(ifa), 0);
+#undef IFA_MTU
+
+		switch (ifa->ifa_addr->sa_family) {
+		case AF_UNSPEC:
 			printf("%-13.13s ", "none");
-			printf("%-17.17s ", "none");
-		} else {
-			if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr)
-			    != 0) {
-				ifaddraddr = 0;
-				continue;
-			}
-#define	CP(x) ((char *)(x))
-			cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) +
-				CP(&ifaddr);
-			sa = (struct sockaddr *)cp;
-			if (af != AF_UNSPEC && sa->sa_family != af) {
-				ifaddraddr =
-				    (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link);
-				continue;
-			}
-			if (Wflag)
-				printf("%-7.7s", name);
-			else
-				printf("%-5.5s", name);
-			printf(" %5lu ", ifnet.if_mtu);
-			switch (sa->sa_family) {
-			case AF_UNSPEC:
-				printf("%-13.13s ", "none");
-				printf("%-15.15s ", "none");
-				break;
-			case AF_INET:
-				sockin = (struct sockaddr_in *)sa;
-#ifdef notdef
-				/* can't use inet_makeaddr because kernel
-				 * keeps nets unshifted.
-				 */
-				in = inet_makeaddr(ifaddr.in.ia_subnet,
-					INADDR_ANY);
-				printf("%-13.13s ", netname(in.s_addr,
-				    ifaddr.in.ia_subnetmask));
-#else
-				printf("%-13.13s ",
-				    netname(htonl(ifaddr.in.ia_subnet),
-				    ifaddr.in.ia_subnetmask));
-#endif
-				printf("%-17.17s ",
-				    routename(sockin->sin_addr.s_addr));
+			printf("%-15.15s ", "none");
+			break;
+		case AF_INET:
+		    {
+			struct sockaddr_in *sin, *mask;
 
-				network_layer = 1;
-				break;
+			sin = (struct sockaddr_in *)ifa->ifa_addr;
+			mask = (struct sockaddr_in *)ifa->ifa_netmask;
+			printf("%-13.13s ", netname(sin->sin_addr.s_addr,
+			    mask->sin_addr.s_addr));
+			printf("%-17.17s ",
+			    routename(sin->sin_addr.s_addr));
+
+			network = true;
+			break;
+		    }
 #ifdef INET6
-			case AF_INET6:
-				sockin6 = (struct sockaddr_in6 *)sa;
-				in6_fillscopeid(&ifaddr.in6.ia_addr);
-				printf("%-13.13s ",
-				       netname6(&ifaddr.in6.ia_addr,
-						&ifaddr.in6.ia_prefixmask.sin6_addr));
-				in6_fillscopeid(sockin6);
-				getnameinfo(sa, sa->sa_len, addr_buf,
-				    sizeof(addr_buf), 0, 0, NI_NUMERICHOST);
-				printf("%-17.17s ", addr_buf);
+		case AF_INET6:
+		    {
+			struct sockaddr_in6 *sin6, *mask;
 
-				network_layer = 1;
-				break;
-#endif /*INET6*/
-			case AF_IPX:
-				{
-				struct sockaddr_ipx *sipx =
-					(struct sockaddr_ipx *)sa;
-				u_long net;
-				char netnum[10];
+			sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
+			mask = (struct sockaddr_in6 *)ifa->ifa_netmask;
 
-				*(union ipx_net *) &net = sipx->sipx_addr.x_net;
-				sprintf(netnum, "%lx", (u_long)ntohl(net));
-				printf("ipx:%-8s  ", netnum);
-/*				printf("ipx:%-8s ", netname(net, 0L)); */
-				printf("%-17s ",
-				    ipx_phost((struct sockaddr *)sipx));
-				}
+			printf("%-13.13s ", netname6(sin6, &mask->sin6_addr));
+			getnameinfo(ifa->ifa_addr, ifa->ifa_addr->sa_len,
+			    addr_buf, sizeof(addr_buf), 0, 0, NI_NUMERICHOST);
+			printf("%-17.17s ", addr_buf);
 
-				network_layer = 1;
-				break;
+			network = 1;
+			break;
+	            }
+#endif /* INET6 */
+		case AF_IPX:
+		    {
+			struct sockaddr_ipx *sipx;
+			u_long net;
+			char netnum[10];
 
-			case AF_APPLETALK:
-				printf("atalk:%-12.12s ",atalk_print(sa,0x10) );
-				printf("%-11.11s  ",atalk_print(sa,0x0b) );
-				break;
-			case AF_LINK:
-				{
-				struct sockaddr_dl *sdl =
-					(struct sockaddr_dl *)sa;
-				char linknum[10];
-				cp = (char *)LLADDR(sdl);
-				n = sdl->sdl_alen;
-				sprintf(linknum, "<Link#%d>", sdl->sdl_index);
-				m = printf("%-13.13s ", linknum);
-				}
-				goto hexprint;
-			default:
-				m = printf("(%d)", sa->sa_family);
-				for (cp = sa->sa_len + (char *)sa;
-					--cp > sa->sa_data && (*cp == 0);) {}
-				n = cp - sa->sa_data + 1;
-				cp = sa->sa_data;
-			hexprint:
-				while ((--n >= 0) && (m < 30))
-					m += printf("%02x%c", *cp++ & 0xff,
-						    n > 0 ? ':' : ' ');
-				m = 32 - m;
-				while (m-- > 0)
-					putchar(' ');
+			sipx = (struct sockaddr_ipx *)ifa->ifa_addr;
+			*(union ipx_net *) &net = sipx->sipx_addr.x_net;
 
-				link_layer = 1;
-				break;
-			}
+			sprintf(netnum, "%lx", (u_long)ntohl(net));
+			printf("ipx:%-8s  ", netnum);
+			printf("%-17s ", ipx_phost((struct sockaddr *)sipx));
 
-			/*
-			 * Fixup the statistics for interfaces that
-			 * update stats for their network addresses
-			 */
-			if (network_layer) {
-				opackets = ifaddr.in.ia_ifa.if_opackets;
-				ipackets = ifaddr.in.ia_ifa.if_ipackets;
-				obytes = ifaddr.in.ia_ifa.if_obytes;
-				ibytes = ifaddr.in.ia_ifa.if_ibytes;
-			}
+			network = 1;
+			break;
+		    }
+		case AF_APPLETALK:
+			printf("atalk:%-12.12s ",
+			    atalk_print(ifa->ifa_addr, 0x10));
+			printf("%-11.11s  ",
+			    atalk_print(ifa->ifa_addr, 0x0b));
+			break;
+		case AF_LINK:
+		    {
+			struct sockaddr_dl *sdl;
+			char *cp, linknum[10];
+			int n, m;
 
-			ifaddraddr = (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link);
+			sdl = (struct sockaddr_dl *)ifa->ifa_addr;
+			cp = (char *)LLADDR(sdl);
+			n = sdl->sdl_alen;
+			sprintf(linknum, "<Link#%d>", sdl->sdl_index);
+			m = printf("%-13.13s ", linknum);
+
+			while ((--n >= 0) && (m < 30))
+				m += printf("%02x%c", *cp++ & 0xff,
+					    n > 0 ? ':' : ' ');
+			m = 32 - m;
+			while (m-- > 0)
+				putchar(' ');
+
+			link = 1;
+			break;
+		    }
 		}
 
-		show_stat("lu", 8, ipackets, link_layer|network_layer);
-		show_stat("lu", 5, ierrors, link_layer);
-		show_stat("lu", 5, idrops, link_layer);
+#define	IFA_STAT(s)	(((struct if_data *)ifa->ifa_data)->ifi_ ## s)
+		show_stat("lu", 8, IFA_STAT(ipackets), link|network, 1);
+		show_stat("lu", 5, IFA_STAT(ierrors), link, 1);
+		show_stat("lu", 5, IFA_STAT(iqdrops), link, 1);
 		if (bflag)
-			show_stat("lu", 10, ibytes, link_layer|network_layer);
-
-		show_stat("lu", 8, opackets, link_layer|network_layer);
-		show_stat("lu", 5, oerrors, link_layer);
+			show_stat("lu", 10, IFA_STAT(ibytes), link|network, 0);
+		show_stat("lu", 8, IFA_STAT(opackets), link|network, 1);
+		show_stat("lu", 5, IFA_STAT(oerrors), link, 1);
 		if (bflag)
-			show_stat("lu", 10, obytes, link_layer|network_layer);
-
-		show_stat("NRSlu", 5, collisions, link_layer);
+			show_stat("lu", 10, IFA_STAT(obytes), link|network, 0);
+		show_stat("NRSlu", 5, IFA_STAT(collisions), link, 1);
 		if (dflag)
-			show_stat("LSd", 4, drops, link_layer);
+			show_stat("LSlu", 5, IFA_STAT(oqdrops), link, 1);
 		putchar('\n');
 
-		if (aflag && ifaddrfound) {
-			/*
-			 * Print family's multicast addresses
-			 */
-			struct ifmultiaddr *multiaddr;
-			struct ifmultiaddr ifma;
-			union {
-				struct sockaddr sa;
-				struct sockaddr_in in;
-#ifdef INET6
-				struct sockaddr_in6 in6;
-#endif /* INET6 */
-				struct sockaddr_dl dl;
-			} msa;
-			const char *fmt;
+		if (!aflag)
+			continue;
 
-			TAILQ_FOREACH(multiaddr, &ifnet.if_multiaddrs, ifma_link) {
-				if (kread((u_long)multiaddr, (char *)&ifma,
-					  sizeof ifma) != 0)
-					break;
-				multiaddr = &ifma;
-				if (kread((u_long)ifma.ifma_addr, (char *)&msa,
-					  sizeof msa) != 0)
-					break;
-				if (msa.sa.sa_family != sa->sa_family)
-					continue;
+		/*
+		 * Print family's multicast addresses.
+		 */
+		for (ifma = next_ifma(ifmap, ifa->ifa_name,
+		     ifa->ifa_addr->sa_family);
+		     ifma != NULL;
+		     ifma = next_ifma(ifma, ifa->ifa_name,
+		     ifa->ifa_addr->sa_family)) {
+			const char *fmt = NULL;
 
-				fmt = 0;
-				switch (msa.sa.sa_family) {
-				case AF_INET:
-					fmt = routename(msa.in.sin_addr.s_addr);
-					break;
+			switch (ifma->ifma_addr->sa_family) {
+			case AF_INET:
+			    {
+				struct sockaddr_in *sin;
+
+				sin = (struct sockaddr_in *)ifma->ifma_addr;
+				fmt = routename(sin->sin_addr.s_addr);
+				break;
+			    }
 #ifdef INET6
-				case AF_INET6:
-					in6_fillscopeid(&msa.in6);
-					getnameinfo(&msa.sa, msa.sa.sa_len,
-					    addr_buf, sizeof(addr_buf), 0, 0,
-					    NI_NUMERICHOST);
-					printf("%*s %-19.19s(refs: %d)\n",
-					       Wflag ? 27 : 25, "",
-					       addr_buf, ifma.ifma_refcount);
-					break;
+			case AF_INET6:
+
+				/* in6_fillscopeid(&msa.in6); */
+				getnameinfo(ifma->ifma_addr,
+				    ifma->ifma_addr->sa_len, addr_buf,
+				    sizeof(addr_buf), 0, 0, NI_NUMERICHOST);
+				printf("%*s %s\n",
+				    Wflag ? 27 : 25, "", addr_buf);
+				break;
 #endif /* INET6 */
-				case AF_LINK:
-					switch (msa.dl.sdl_type) {
-					case IFT_ETHER:
-					case IFT_FDDI:
-						fmt = ether_ntoa(
-							(struct ether_addr *)
-							LLADDR(&msa.dl));
-						break;
-					}
+			case AF_LINK:
+			    {
+				struct sockaddr_dl *sdl;
+
+				sdl = (struct sockaddr_dl *)ifma->ifma_addr;
+				switch (sdl->sdl_type) {
+				case IFT_ETHER:
+				case IFT_FDDI:
+					fmt = ether_ntoa(
+					    (struct ether_addr *)LLADDR(sdl));
 					break;
 				}
-				if (fmt) {
-					printf("%*s %-17.17s",
-					    Wflag ? 27 : 25, "", fmt);
-					if (msa.sa.sa_family == AF_LINK) {
-						printf(" %8lu", imcasts);
-						printf("%*s",
-						    bflag ? 17 : 6, "");
-						printf(" %8lu", omcasts);
-					}
-					putchar('\n');
+				break;
+			    }
+			}
+
+			if (fmt) {
+				printf("%*s %-17.17s",
+				    Wflag ? 27 : 25, "", fmt);
+				if (ifma->ifma_addr->sa_family == AF_LINK) {
+					printf(" %8lu", IFA_STAT(imcasts));
+					printf("%*s", bflag ? 17 : 6, "");
+					printf(" %8lu", IFA_STAT(omcasts));
 				}
+				putchar('\n');
 			}
+
+			ifma = ifma->ifma_next;
 		}
 	}
+
+	freeifaddrs(ifap);
+	if (aflag)
+		freeifmaddrs(ifmap);
 }
 
-struct	iftot {
-	SLIST_ENTRY(iftot) chain;
-	char	ift_name[IFNAMSIZ];	/* interface name */
+struct iftot {
 	u_long	ift_ip;			/* input packets */
 	u_long	ift_ie;			/* input errors */
 	u_long	ift_id;			/* input drops */
 	u_long	ift_op;			/* output packets */
 	u_long	ift_oe;			/* output errors */
+	u_long	ift_od;			/* output drops */
 	u_long	ift_co;			/* collisions */
-	u_int	ift_dr;			/* drops */
 	u_long	ift_ib;			/* input bytes */
 	u_long	ift_ob;			/* output bytes */
 };
 
-u_char	signalled;			/* set if alarm goes off "early" */
+/*
+ * Obtain stats for interface(s).
+ */
+static void
+fill_iftot(struct iftot *st)
+{
+	struct ifaddrs *ifap, *ifa;
+	bool found = false;
 
+	if (getifaddrs(&ifap) != 0)
+		err(EX_OSERR, "getifaddrs");
+
+	bzero(st, sizeof(*st));
+
+	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+		if (ifa->ifa_addr->sa_family != AF_LINK)
+			continue;
+		if (interface) {
+			if (strcmp(ifa->ifa_name, interface) == 0)
+				found = true;
+			else
+				continue;
+		}
+
+		st->ift_ip += IFA_STAT(ipackets);
+		st->ift_ie += IFA_STAT(ierrors);
+		st->ift_id += IFA_STAT(iqdrops);
+		st->ift_ib += IFA_STAT(ibytes);
+		st->ift_op += IFA_STAT(opackets);
+		st->ift_oe += IFA_STAT(oerrors);
+		st->ift_od += IFA_STAT(oqdrops);
+		st->ift_ob += IFA_STAT(obytes);
+ 		st->ift_co += IFA_STAT(collisions);
+	}
+
+	if (interface && found == false)
+		err(EX_DATAERR, "interface %s not found", interface);
+
+	freeifaddrs(ifap);
+}
+
 /*
+ * Set a flag to indicate that a signal from the periodic itimer has been
+ * caught.
+ */
+static sig_atomic_t signalled;
+static void
+catchalarm(int signo __unused)
+{
+	signalled = true;
+}
+
+/*
  * Print a running summary of interface statistics.
- * Repeat display every interval1 seconds, showing statistics
- * collected over that interval.  Assumes that interval1 is non-zero.
+ * Repeat display every interval seconds, showing statistics
+ * collected over that interval.  Assumes that interval is non-zero.
  * First line printed at top of screen is always cumulative.
- * XXX - should be rewritten to use ifmib(4).
  */
 static void
-sidewaysintpr(int interval1, u_long off)
+sidewaysintpr(int interval)
 {
-	struct ifnet ifnet;
-	u_long firstifnet;
-	struct ifnethead ifnethead;
+	struct iftot ift[2], *new, *old;
 	struct itimerval interval_it;
-	struct iftot *iftot, *ip, *ipn, *total, *sum, *interesting;
-	int line;
-	int oldmask, first;
-	u_long interesting_off;
+	int oldmask, line;
 
-	if (kread(off, (char *)&ifnethead, sizeof ifnethead) != 0)
-		return;
-	firstifnet = (u_long)TAILQ_FIRST(&ifnethead);
+	new = &ift[0];
+	old = &ift[1];
+	fill_iftot(old);
 
-	if ((iftot = malloc(sizeof(struct iftot))) == NULL) {
-		printf("malloc failed\n");
-		exit(1);
-	}
-	memset(iftot, 0, sizeof(struct iftot));
-
-	interesting = NULL;
-	interesting_off = 0;
-	for (off = firstifnet, ip = iftot; off;) {
-		char name[IFNAMSIZ];
-
-		if (kread(off, (char *)&ifnet, sizeof ifnet) != 0)
-			break;
-		strlcpy(name, ifnet.if_xname, sizeof(name));
-		if (interface && strcmp(name, interface) == 0) {
-			interesting = ip;
-			interesting_off = off;
-		}
-		snprintf(ip->ift_name, sizeof(ip->ift_name), "(%s)", name);
-		if ((ipn = malloc(sizeof(struct iftot))) == NULL) {
-			printf("malloc failed\n");
-			exit(1);
-		}
-		memset(ipn, 0, sizeof(struct iftot));
-		SLIST_NEXT(ip, chain) = ipn;
-		ip = ipn;
-		off = (u_long)TAILQ_NEXT(&ifnet, if_link);
-	}
-	if (interface && interesting == NULL)
-		errx(1, "%s: unknown interface", interface);
-	if ((total = malloc(sizeof(struct iftot))) == NULL) {
-		printf("malloc failed\n");
-		exit(1);
-	}
-	memset(total, 0, sizeof(struct iftot));
-	if ((sum = malloc(sizeof(struct iftot))) == NULL) {
-		printf("malloc failed\n");
-		exit(1);
-	}
-	memset(sum, 0, sizeof(struct iftot));
-
 	(void)signal(SIGALRM, catchalarm);
-	signalled = NO;
-	interval_it.it_interval.tv_sec = interval1;
+	signalled = false;
+	interval_it.it_interval.tv_sec = interval;
 	interval_it.it_interval.tv_usec = 0;
 	interval_it.it_value = interval_it.it_interval;
 	setitimer(ITIMER_REAL, &interval_it, NULL);
-	first = 1;
+
 banner:
 	printf("%17s %14s %16s", "input",
-	    interesting ? interesting->ift_name : "(Total)", "output");
+	    interface != NULL ? interface : "(Total)", "output");
 	putchar('\n');
 	printf("%10s %5s %5s %10s %10s %5s %10s %5s",
 	    "packets", "errs", "idrops", "bytes", "packets", "errs", "bytes",
@@ -602,104 +555,44 @@
 	putchar('\n');
 	fflush(stdout);
 	line = 0;
+
 loop:
-	if (interesting != NULL) {
-		ip = interesting;
-		if (kread(interesting_off, (char *)&ifnet, sizeof ifnet) != 0) {
-			printf("???\n");
-			exit(1);
-		};
-		if (!first) {
-			show_stat("lu", 10, ifnet.if_ipackets - ip->ift_ip, 1);
-			show_stat("lu", 5, ifnet.if_ierrors - ip->ift_ie, 1);
-			show_stat("lu", 5, ifnet.if_iqdrops - ip->ift_id, 1);
-			show_stat("lu", 10, ifnet.if_ibytes - ip->ift_ib, 1);
-			show_stat("lu", 10, ifnet.if_opackets - ip->ift_op, 1);
-			show_stat("lu", 5, ifnet.if_oerrors - ip->ift_oe, 1);
-			show_stat("lu", 10, ifnet.if_obytes - ip->ift_ob, 1);
-			show_stat("NRSlu", 5,
-			    ifnet.if_collisions - ip->ift_co, 1);
-			if (dflag)
-				show_stat("LSu", 5,
-				    ifnet.if_snd.ifq_drops - ip->ift_dr, 1);
-		}
-		ip->ift_ip = ifnet.if_ipackets;
-		ip->ift_ie = ifnet.if_ierrors;
-		ip->ift_id = ifnet.if_iqdrops;
-		ip->ift_ib = ifnet.if_ibytes;
-		ip->ift_op = ifnet.if_opackets;
-		ip->ift_oe = ifnet.if_oerrors;
-		ip->ift_ob = ifnet.if_obytes;
-		ip->ift_co = ifnet.if_collisions;
-		ip->ift_dr = ifnet.if_snd.ifq_drops;
-	} else {
-		sum->ift_ip = 0;
-		sum->ift_ie = 0;
-		sum->ift_id = 0;
-		sum->ift_ib = 0;
-		sum->ift_op = 0;
-		sum->ift_oe = 0;
-		sum->ift_ob = 0;
-		sum->ift_co = 0;
-		sum->ift_dr = 0;
-		for (off = firstifnet, ip = iftot;
-		     off && SLIST_NEXT(ip, chain) != NULL;
-		     ip = SLIST_NEXT(ip, chain)) {
-			if (kread(off, (char *)&ifnet, sizeof ifnet) != 0) {
-				off = 0;
-				continue;
-			}
-			sum->ift_ip += ifnet.if_ipackets;
-			sum->ift_ie += ifnet.if_ierrors;
-			sum->ift_id += ifnet.if_iqdrops;
-			sum->ift_ib += ifnet.if_ibytes;
-			sum->ift_op += ifnet.if_opackets;
-			sum->ift_oe += ifnet.if_oerrors;
-			sum->ift_ob += ifnet.if_obytes;
-			sum->ift_co += ifnet.if_collisions;
-			sum->ift_dr += ifnet.if_snd.ifq_drops;
-			off = (u_long)TAILQ_NEXT(&ifnet, if_link);
-		}
-		if (!first) {
-			show_stat("lu", 10, sum->ift_ip - total->ift_ip, 1);
-			show_stat("lu", 5, sum->ift_ie - total->ift_ie, 1);
-			show_stat("lu", 5, sum->ift_id - total->ift_id, 1);
-			show_stat("lu", 10, sum->ift_ib - total->ift_ib, 1);
-			show_stat("lu", 10, sum->ift_op - total->ift_op, 1);
-			show_stat("lu", 5, sum->ift_oe - total->ift_oe, 1);
-			show_stat("lu", 10, sum->ift_ob - total->ift_ob, 1);
-			show_stat("NRSlu", 5, sum->ift_co - total->ift_co, 1);
-			if (dflag)
-				show_stat("LSu", 5,
-				    sum->ift_dr - total->ift_dr, 1);
-		}
-		*total = *sum;
-	}
-	if (!first)
-		putchar('\n');
-	fflush(stdout);
 	if ((noutputs != 0) && (--noutputs == 0))
 		exit(0);
 	oldmask = sigblock(sigmask(SIGALRM));
 	while (!signalled)
 		sigpause(0);
-	signalled = NO;
+	signalled = false;
 	sigsetmask(oldmask);
 	line++;
-	first = 0;
+
+	fill_iftot(new);
+
+	show_stat("lu", 10, new->ift_ip - old->ift_ip, 1, 1);
+	show_stat("lu", 5, new->ift_ie - old->ift_ie, 1, 1);
+	show_stat("lu", 5, new->ift_id - old->ift_id, 1, 1);
+	show_stat("lu", 10, new->ift_ib - old->ift_ib, 1, 0);
+	show_stat("lu", 10, new->ift_op - old->ift_op, 1, 1);
+	show_stat("lu", 5, new->ift_oe - old->ift_oe, 1, 1);
+	show_stat("lu", 10, new->ift_ob - old->ift_ob, 1, 0);
+	show_stat("NRSlu", 5, new->ift_co - old->ift_co, 1, 1);
+	if (dflag)
+		show_stat("LSlu", 5, new->ift_od - old->ift_od, 1, 1);
+	putchar('\n');
+	fflush(stdout);
+
+	if (new == &ift[0]) {
+		new = &ift[1];
+		old = &ift[0];
+	} else {
+		new = &ift[0];
+		old = &ift[1];
+	}
+
 	if (line == 21)
 		goto banner;
 	else
 		goto loop;
-	/*NOTREACHED*/
-}
 
-/*
- * Set a flag to indicate that a signal from the periodic itimer has been
- * caught.
- */
-static void
-catchalarm(int signo __unused)
-{
-	signalled = YES;
+	/* NOTREACHED */
 }

Modified: trunk/usr.bin/netstat/inet.c
===================================================================
--- trunk/usr.bin/netstat/inet.c	2018-07-07 16:54:14 UTC (rev 11466)
+++ trunk/usr.bin/netstat/inet.c	2018-07-07 16:54:32 UTC (rev 11467)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1983, 1988, 1993, 1995
  *	The Regents of the University of California.  All rights reserved.
@@ -34,7 +35,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/usr.bin/netstat/inet.c 293637 2016-01-10 17:39:49Z ngie $");
 
 #include <sys/param.h>
 #include <sys/queue.h>
@@ -89,7 +90,7 @@
 #endif /* INET6 */
 
 static int
-pcblist_sysctl(int proto, const char *name, char **bufp, int istcp)
+pcblist_sysctl(int proto, const char *name, char **bufp, int istcp __unused)
 {
 	const char *mibvar;
 	char *buf;
@@ -429,7 +430,7 @@
 				       "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s",
 				       "Proto", "Recv-Q", "Send-Q",
 				       "Local Address", "Foreign Address");
-				if (!xflag)
+				if (!xflag && !Rflag)
 					printf(" (state)");
 			}
 			if (xflag) {
@@ -441,6 +442,9 @@
 				printf(" %7.7s %7.7s %7.7s %7.7s %7.7s %7.7s",
 				       "rexmt", "persist", "keep",
 				       "2msl", "delack", "rcvtime");
+			} else if (Rflag) {
+				printf ("  %8.8s %5.5s",
+				    "flowid", "ftype");
 			}
 			putchar('\n');
 			first = 0;
@@ -549,7 +553,7 @@
 				    timer->tt_delack / 1000, (timer->tt_delack % 1000) / 10,
 				    timer->t_rcvtime / 1000, (timer->t_rcvtime % 1000) / 10);
 		}
-		if (istcp && !Lflag && !xflag && !Tflag) {
+		if (istcp && !Lflag && !xflag && !Tflag && !Rflag) {
 			if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES)
 				printf("%d", tp->t_state);
 			else {
@@ -560,7 +564,12 @@
 					putchar('*');
 #endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */
 			}
-		} 		
+		}
+		if (Rflag) {
+			printf(" %08x %5d",
+			    inp->inp_flowid,
+			    inp->inp_flowtype);
+		}
 		putchar('\n');
 	}
 	if (xig != oxig && xig->xig_gen != oxig->xig_gen) {
@@ -585,8 +594,7 @@
 void
 tcp_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
 {
-	struct tcpstat tcpstat, zerostat;
-	size_t len = sizeof tcpstat;
+	struct tcpstat tcpstat;
 
 #ifdef INET6
 	if (tcp_done != 0)
@@ -595,128 +603,138 @@
 		tcp_done = 1;
 #endif
 
-	if (live) {
-		if (zflag)
-			memset(&zerostat, 0, len);
-		if (sysctlbyname("net.inet.tcp.stats", &tcpstat, &len,
-		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
-			warn("sysctl: net.inet.tcp.stats");
-			return;
-		}
-	} else
-		kread(off, &tcpstat, len);
+	if (fetch_stats("net.inet.tcp.stats", off, &tcpstat,
+	    sizeof(tcpstat), kread_counters) != 0)
+		return;
 
 	printf ("%s:\n", name);
 
-#define	p(f, m) if (tcpstat.f || sflag <= 1) \
-    printf(m, tcpstat.f, plural(tcpstat.f))
-#define	p1a(f, m) if (tcpstat.f || sflag <= 1) \
-    printf(m, tcpstat.f)
-#define	p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
-    printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2))
-#define	p2a(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
-    printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2)
-#define	p3(f, m) if (tcpstat.f || sflag <= 1) \
-    printf(m, tcpstat.f, pluralies(tcpstat.f))
+#define	p(f, m) if (tcpstat.f || sflag <= 1)				\
+	printf(m, (uintmax_t )tcpstat.f, plural(tcpstat.f))
 
-	p(tcps_sndtotal, "\t%lu packet%s sent\n");
-	p2(tcps_sndpack,tcps_sndbyte, "\t\t%lu data packet%s (%lu byte%s)\n");
+#define	p1a(f, m) if (tcpstat.f || sflag <= 1)				\
+	printf(m, (uintmax_t )tcpstat.f)
+
+#define	p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1)	\
+	printf(m, (uintmax_t )tcpstat.f1, plural(tcpstat.f1),		\
+	    (uintmax_t )tcpstat.f2, plural(tcpstat.f2))
+
+#define	p2a(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1)	\
+	printf(m, (uintmax_t )tcpstat.f1, plural(tcpstat.f1),		\
+	    (uintmax_t )tcpstat.f2)
+
+#define	p3(f, m) if (tcpstat.f || sflag <= 1)				\
+	printf(m, (uintmax_t )tcpstat.f, pluralies(tcpstat.f))
+
+	p(tcps_sndtotal, "\t%ju packet%s sent\n");
+	p2(tcps_sndpack,tcps_sndbyte, "\t\t%ju data packet%s (%ju byte%s)\n");
 	p2(tcps_sndrexmitpack, tcps_sndrexmitbyte,
-	    "\t\t%lu data packet%s (%lu byte%s) retransmitted\n");
+	    "\t\t%ju data packet%s (%ju byte%s) retransmitted\n");
 	p(tcps_sndrexmitbad,
-	    "\t\t%lu data packet%s unnecessarily retransmitted\n");
-	p(tcps_mturesent, "\t\t%lu resend%s initiated by MTU discovery\n");
+	    "\t\t%ju data packet%s unnecessarily retransmitted\n");
+	p(tcps_mturesent, "\t\t%ju resend%s initiated by MTU discovery\n");
 	p2a(tcps_sndacks, tcps_delack,
-	    "\t\t%lu ack-only packet%s (%lu delayed)\n");
-	p(tcps_sndurg, "\t\t%lu URG only packet%s\n");
-	p(tcps_sndprobe, "\t\t%lu window probe packet%s\n");
-	p(tcps_sndwinup, "\t\t%lu window update packet%s\n");
-	p(tcps_sndctrl, "\t\t%lu control packet%s\n");
-	p(tcps_rcvtotal, "\t%lu packet%s received\n");
+	    "\t\t%ju ack-only packet%s (%ju delayed)\n");
+	p(tcps_sndurg, "\t\t%ju URG only packet%s\n");
+	p(tcps_sndprobe, "\t\t%ju window probe packet%s\n");
+	p(tcps_sndwinup, "\t\t%ju window update packet%s\n");
+	p(tcps_sndctrl, "\t\t%ju control packet%s\n");
+	p(tcps_rcvtotal, "\t%ju packet%s received\n");
 	p2(tcps_rcvackpack, tcps_rcvackbyte,
-	    "\t\t%lu ack%s (for %lu byte%s)\n");
-	p(tcps_rcvdupack, "\t\t%lu duplicate ack%s\n");
-	p(tcps_rcvacktoomuch, "\t\t%lu ack%s for unsent data\n");
+	    "\t\t%ju ack%s (for %ju byte%s)\n");
+	p(tcps_rcvdupack, "\t\t%ju duplicate ack%s\n");
+	p(tcps_rcvacktoomuch, "\t\t%ju ack%s for unsent data\n");
 	p2(tcps_rcvpack, tcps_rcvbyte,
-	    "\t\t%lu packet%s (%lu byte%s) received in-sequence\n");
+	    "\t\t%ju packet%s (%ju byte%s) received in-sequence\n");
 	p2(tcps_rcvduppack, tcps_rcvdupbyte,
-	    "\t\t%lu completely duplicate packet%s (%lu byte%s)\n");
-	p(tcps_pawsdrop, "\t\t%lu old duplicate packet%s\n");
+	    "\t\t%ju completely duplicate packet%s (%ju byte%s)\n");
+	p(tcps_pawsdrop, "\t\t%ju old duplicate packet%s\n");
 	p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte,
-	    "\t\t%lu packet%s with some dup. data (%lu byte%s duped)\n");
+	    "\t\t%ju packet%s with some dup. data (%ju byte%s duped)\n");
 	p2(tcps_rcvoopack, tcps_rcvoobyte,
-	    "\t\t%lu out-of-order packet%s (%lu byte%s)\n");
+	    "\t\t%ju out-of-order packet%s (%ju byte%s)\n");
 	p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin,
-	    "\t\t%lu packet%s (%lu byte%s) of data after window\n");
-	p(tcps_rcvwinprobe, "\t\t%lu window probe%s\n");
-	p(tcps_rcvwinupd, "\t\t%lu window update packet%s\n");
-	p(tcps_rcvafterclose, "\t\t%lu packet%s received after close\n");
-	p(tcps_rcvbadsum, "\t\t%lu discarded for bad checksum%s\n");
-	p(tcps_rcvbadoff, "\t\t%lu discarded for bad header offset field%s\n");
-	p1a(tcps_rcvshort, "\t\t%lu discarded because packet too short\n");
-	p1a(tcps_rcvmemdrop, "\t\t%lu discarded due to memory problems\n");
-	p(tcps_connattempt, "\t%lu connection request%s\n");
-	p(tcps_accepts, "\t%lu connection accept%s\n");
-	p(tcps_badsyn, "\t%lu bad connection attempt%s\n");
-	p(tcps_listendrop, "\t%lu listen queue overflow%s\n");
-	p(tcps_badrst, "\t%lu ignored RSTs in the window%s\n");
-	p(tcps_connects, "\t%lu connection%s established (including accepts)\n");
+	    "\t\t%ju packet%s (%ju byte%s) of data after window\n");
+	p(tcps_rcvwinprobe, "\t\t%ju window probe%s\n");
+	p(tcps_rcvwinupd, "\t\t%ju window update packet%s\n");
+	p(tcps_rcvafterclose, "\t\t%ju packet%s received after close\n");
+	p(tcps_rcvbadsum, "\t\t%ju discarded for bad checksum%s\n");
+	p(tcps_rcvbadoff, "\t\t%ju discarded for bad header offset field%s\n");
+	p1a(tcps_rcvshort, "\t\t%ju discarded because packet too short\n");
+	p1a(tcps_rcvmemdrop, "\t\t%ju discarded due to memory problems\n");
+	p(tcps_connattempt, "\t%ju connection request%s\n");
+	p(tcps_accepts, "\t%ju connection accept%s\n");
+	p(tcps_badsyn, "\t%ju bad connection attempt%s\n");
+	p(tcps_listendrop, "\t%ju listen queue overflow%s\n");
+	p(tcps_badrst, "\t%ju ignored RSTs in the window%s\n");
+	p(tcps_connects, "\t%ju connection%s established (including accepts)\n");
 	p2(tcps_closed, tcps_drops,
-	    "\t%lu connection%s closed (including %lu drop%s)\n");
-	p(tcps_cachedrtt, "\t\t%lu connection%s updated cached RTT on close\n");
+	    "\t%ju connection%s closed (including %ju drop%s)\n");
+	p(tcps_cachedrtt, "\t\t%ju connection%s updated cached RTT on close\n");
 	p(tcps_cachedrttvar,
-	    "\t\t%lu connection%s updated cached RTT variance on close\n");
+	    "\t\t%ju connection%s updated cached RTT variance on close\n");
 	p(tcps_cachedssthresh,
-	    "\t\t%lu connection%s updated cached ssthresh on close\n");
-	p(tcps_conndrops, "\t%lu embryonic connection%s dropped\n");
+	    "\t\t%ju connection%s updated cached ssthresh on close\n");
+	p(tcps_conndrops, "\t%ju embryonic connection%s dropped\n");
 	p2(tcps_rttupdated, tcps_segstimed,
-	    "\t%lu segment%s updated rtt (of %lu attempt%s)\n");
-	p(tcps_rexmttimeo, "\t%lu retransmit timeout%s\n");
-	p(tcps_timeoutdrop, "\t\t%lu connection%s dropped by rexmit timeout\n");
-	p(tcps_persisttimeo, "\t%lu persist timeout%s\n");
-	p(tcps_persistdrop, "\t\t%lu connection%s dropped by persist timeout\n");
+	    "\t%ju segment%s updated rtt (of %ju attempt%s)\n");
+	p(tcps_rexmttimeo, "\t%ju retransmit timeout%s\n");
+	p(tcps_timeoutdrop, "\t\t%ju connection%s dropped by rexmit timeout\n");
+	p(tcps_persisttimeo, "\t%ju persist timeout%s\n");
+	p(tcps_persistdrop, "\t\t%ju connection%s dropped by persist timeout\n");
 	p(tcps_finwait2_drops,
-	    "\t%lu Connection%s (fin_wait_2) dropped because of timeout\n");
-	p(tcps_keeptimeo, "\t%lu keepalive timeout%s\n");
-	p(tcps_keepprobe, "\t\t%lu keepalive probe%s sent\n");
-	p(tcps_keepdrops, "\t\t%lu connection%s dropped by keepalive\n");
-	p(tcps_predack, "\t%lu correct ACK header prediction%s\n");
-	p(tcps_preddat, "\t%lu correct data packet header prediction%s\n");
+	    "\t%ju Connection%s (fin_wait_2) dropped because of timeout\n");
+	p(tcps_keeptimeo, "\t%ju keepalive timeout%s\n");
+	p(tcps_keepprobe, "\t\t%ju keepalive probe%s sent\n");
+	p(tcps_keepdrops, "\t\t%ju connection%s dropped by keepalive\n");
+	p(tcps_predack, "\t%ju correct ACK header prediction%s\n");
+	p(tcps_preddat, "\t%ju correct data packet header prediction%s\n");
 
-	p3(tcps_sc_added, "\t%lu syncache entr%s added\n");
-	p1a(tcps_sc_retransmitted, "\t\t%lu retransmitted\n");
-	p1a(tcps_sc_dupsyn, "\t\t%lu dupsyn\n");
-	p1a(tcps_sc_dropped, "\t\t%lu dropped\n");
-	p1a(tcps_sc_completed, "\t\t%lu completed\n");
-	p1a(tcps_sc_bucketoverflow, "\t\t%lu bucket overflow\n");
-	p1a(tcps_sc_cacheoverflow, "\t\t%lu cache overflow\n");
-	p1a(tcps_sc_reset, "\t\t%lu reset\n");
-	p1a(tcps_sc_stale, "\t\t%lu stale\n");
-	p1a(tcps_sc_aborted, "\t\t%lu aborted\n");
-	p1a(tcps_sc_badack, "\t\t%lu badack\n");
-	p1a(tcps_sc_unreach, "\t\t%lu unreach\n");
-	p(tcps_sc_zonefail, "\t\t%lu zone failure%s\n");
-	p(tcps_sc_sendcookie, "\t%lu cookie%s sent\n");
-	p(tcps_sc_recvcookie, "\t%lu cookie%s received\n");
+	p3(tcps_sc_added, "\t%ju syncache entr%s added\n");
+	p1a(tcps_sc_retransmitted, "\t\t%ju retransmitted\n");
+	p1a(tcps_sc_dupsyn, "\t\t%ju dupsyn\n");
+	p1a(tcps_sc_dropped, "\t\t%ju dropped\n");
+	p1a(tcps_sc_completed, "\t\t%ju completed\n");
+	p1a(tcps_sc_bucketoverflow, "\t\t%ju bucket overflow\n");
+	p1a(tcps_sc_cacheoverflow, "\t\t%ju cache overflow\n");
+	p1a(tcps_sc_reset, "\t\t%ju reset\n");
+	p1a(tcps_sc_stale, "\t\t%ju stale\n");
+	p1a(tcps_sc_aborted, "\t\t%ju aborted\n");
+	p1a(tcps_sc_badack, "\t\t%ju badack\n");
+	p1a(tcps_sc_unreach, "\t\t%ju unreach\n");
+	p(tcps_sc_zonefail, "\t\t%ju zone failure%s\n");
+	p(tcps_sc_sendcookie, "\t%ju cookie%s sent\n");
+	p(tcps_sc_recvcookie, "\t%ju cookie%s received\n");
 
-	p(tcps_hc_added, "\t%lu hostcache entrie%s added\n");
-	p1a(tcps_hc_bucketoverflow, "\t\t%lu bucket overflow\n");
+	p3(tcps_hc_added, "\t%ju hostcache entr%s added\n");
+	p1a(tcps_hc_bucketoverflow, "\t\t%ju bucket overflow\n");
 
-	p(tcps_sack_recovery_episode, "\t%lu SACK recovery episode%s\n");
+	p(tcps_sack_recovery_episode, "\t%ju SACK recovery episode%s\n");
 	p(tcps_sack_rexmits,
-	    "\t%lu segment rexmit%s in SACK recovery episodes\n");
+	    "\t%ju segment rexmit%s in SACK recovery episodes\n");
 	p(tcps_sack_rexmit_bytes,
-	    "\t%lu byte rexmit%s in SACK recovery episodes\n");
+	    "\t%ju byte rexmit%s in SACK recovery episodes\n");
 	p(tcps_sack_rcv_blocks,
-	    "\t%lu SACK option%s (SACK blocks) received\n");
-	p(tcps_sack_send_blocks, "\t%lu SACK option%s (SACK blocks) sent\n");
-	p1a(tcps_sack_sboverflow, "\t%lu SACK scoreboard overflow\n");
+	    "\t%ju SACK option%s (SACK blocks) received\n");
+	p(tcps_sack_send_blocks, "\t%ju SACK option%s (SACK blocks) sent\n");
+	p1a(tcps_sack_sboverflow, "\t%ju SACK scoreboard overflow\n");
 
-	p(tcps_ecn_ce, "\t%lu packet%s with ECN CE bit set\n");
-	p(tcps_ecn_ect0, "\t%lu packet%s with ECN ECT(0) bit set\n");
-	p(tcps_ecn_ect1, "\t%lu packet%s with ECN ECT(1) bit set\n");
-	p(tcps_ecn_shs, "\t%lu successful ECN handshake%s\n");
-	p(tcps_ecn_rcwnd, "\t%lu time%s ECN reduced the congestion window\n");
+	p(tcps_ecn_ce, "\t%ju packet%s with ECN CE bit set\n");
+	p(tcps_ecn_ect0, "\t%ju packet%s with ECN ECT(0) bit set\n");
+	p(tcps_ecn_ect1, "\t%ju packet%s with ECN ECT(1) bit set\n");
+	p(tcps_ecn_shs, "\t%ju successful ECN handshake%s\n");
+	p(tcps_ecn_rcwnd, "\t%ju time%s ECN reduced the congestion window\n");
+
+	p(tcps_sig_rcvgoodsig,
+	     "\t%ju packet%s with valid tcp-md5 signature received\n");
+	p(tcps_sig_rcvbadsig,
+	     "\t%ju packet%s with invalid tcp-md5 signature received\n");
+	p(tcps_sig_err_buildsig,
+	     "\t%ju packet%s with tcp-md5 signature mismatch\n");
+	p(tcps_sig_err_sigopt,
+	     "\t%ju packet%s with unexpected tcp-md5 signature received\n");
+	p(tcps_sig_err_nosigopt,
+	     "\t%ju packet%s without expected tcp-md5 signature received\n");
 #undef p
 #undef p1a
 #undef p2
@@ -730,9 +748,8 @@
 void
 udp_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
 {
-	struct udpstat udpstat, zerostat;
-	size_t len = sizeof udpstat;
-	u_long delivered;
+	struct udpstat udpstat;
+	uint64_t delivered;
 
 #ifdef INET6
 	if (udp_done != 0)
@@ -741,32 +758,25 @@
 		udp_done = 1;
 #endif
 
-	if (live) {
-		if (zflag)
-			memset(&zerostat, 0, len);
-		if (sysctlbyname("net.inet.udp.stats", &udpstat, &len,
-		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
-			warn("sysctl: net.inet.udp.stats");
-			return;
-		}
-	} else
-		kread(off, &udpstat, len);
+	if (fetch_stats("net.inet.udp.stats", off, &udpstat,
+	    sizeof(udpstat), kread_counters) != 0)
+		return;
 
 	printf("%s:\n", name);
 #define	p(f, m) if (udpstat.f || sflag <= 1) \
-    printf(m, udpstat.f, plural(udpstat.f))
+    printf("\t%ju " m, (uintmax_t)udpstat.f, plural(udpstat.f))
 #define	p1a(f, m) if (udpstat.f || sflag <= 1) \
-    printf(m, udpstat.f)
-	p(udps_ipackets, "\t%lu datagram%s received\n");
-	p1a(udps_hdrops, "\t%lu with incomplete header\n");
-	p1a(udps_badlen, "\t%lu with bad data length field\n");
-	p1a(udps_badsum, "\t%lu with bad checksum\n");
-	p1a(udps_nosum, "\t%lu with no checksum\n");
-	p1a(udps_noport, "\t%lu dropped due to no socket\n");
+    printf("\t%ju " m, (uintmax_t)udpstat.f)
+	p(udps_ipackets, "datagram%s received\n");
+	p1a(udps_hdrops, "with incomplete header\n");
+	p1a(udps_badlen, "with bad data length field\n");
+	p1a(udps_badsum, "with bad checksum\n");
+	p1a(udps_nosum, "with no checksum\n");
+	p1a(udps_noport, "dropped due to no socket\n");
 	p(udps_noportbcast,
-	    "\t%lu broadcast/multicast datagram%s undelivered\n");
-	p1a(udps_fullsock, "\t%lu dropped due to full socket buffers\n");
-	p1a(udpps_pcbhashmiss, "\t%lu not for hashed pcb\n");
+	    "broadcast/multicast datagram%s undelivered\n");
+	p1a(udps_fullsock, "dropped due to full socket buffers\n");
+	p1a(udpps_pcbhashmiss, "not for hashed pcb\n");
 	delivered = udpstat.udps_ipackets -
 		    udpstat.udps_hdrops -
 		    udpstat.udps_badlen -
@@ -775,11 +785,11 @@
 		    udpstat.udps_noportbcast -
 		    udpstat.udps_fullsock;
 	if (delivered || sflag <= 1)
-		printf("\t%lu delivered\n", delivered);
-	p(udps_opackets, "\t%lu datagram%s output\n");
+		printf("\t%ju delivered\n", (uint64_t)delivered);
+	p(udps_opackets, "datagram%s output\n");
 	/* the next statistic is cumulative in udps_noportbcast */
 	p(udps_filtermcast,
-	    "\t%lu time%s multicast source filter matched\n");
+	    "time%s multicast source filter matched\n");
 #undef p
 #undef p1a
 }
@@ -790,23 +800,11 @@
 void
 carp_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
 {
-	struct carpstats carpstat, zerostat;
-	size_t len = sizeof(struct carpstats);
+	struct carpstats carpstat;
 
-	if (live) {
-		if (zflag)
-			memset(&zerostat, 0, len);
-		if (sysctlbyname("net.inet.carp.stats", &carpstat, &len,
-		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
-			if (errno != ENOENT)
-				warn("sysctl: net.inet.carp.stats");
-			return;
-		}
-	} else {
-		if (off == 0)
-			return;
-		kread(off, &carpstat, len);
-	}
+	if (fetch_stats("net.inet.carp.stats", off, &carpstat,
+	    sizeof(carpstat), kread_counters) != 0)
+		return;
 
 	printf("%s:\n", name);
 
@@ -841,60 +839,52 @@
 void
 ip_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
 {
-	struct ipstat ipstat, zerostat;
-	size_t len = sizeof ipstat;
+	struct ipstat ipstat;
 
-	if (live) {
-		if (zflag)
-			memset(&zerostat, 0, len);
-		if (sysctlbyname("net.inet.ip.stats", &ipstat, &len,
-		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
-			warn("sysctl: net.inet.ip.stats");
-			return;
-		}
-	} else
-		kread(off, &ipstat, len);
+	if (fetch_stats("net.inet.ip.stats", off, &ipstat,
+	    sizeof(ipstat), kread_counters) != 0)
+		return;
 
 	printf("%s:\n", name);
 
 #define	p(f, m) if (ipstat.f || sflag <= 1) \
-    printf(m, ipstat.f, plural(ipstat.f))
+    printf(m, (uintmax_t )ipstat.f, plural(ipstat.f))
 #define	p1a(f, m) if (ipstat.f || sflag <= 1) \
-    printf(m, ipstat.f)
+    printf(m, (uintmax_t )ipstat.f)
 
-	p(ips_total, "\t%lu total packet%s received\n");
-	p(ips_badsum, "\t%lu bad header checksum%s\n");
-	p1a(ips_toosmall, "\t%lu with size smaller than minimum\n");
-	p1a(ips_tooshort, "\t%lu with data size < data length\n");
-	p1a(ips_toolong, "\t%lu with ip length > max ip packet size\n");
-	p1a(ips_badhlen, "\t%lu with header length < data size\n");
-	p1a(ips_badlen, "\t%lu with data length < header length\n");
-	p1a(ips_badoptions, "\t%lu with bad options\n");
-	p1a(ips_badvers, "\t%lu with incorrect version number\n");
-	p(ips_fragments, "\t%lu fragment%s received\n");
-	p(ips_fragdropped, "\t%lu fragment%s dropped (dup or out of space)\n");
-	p(ips_fragtimeout, "\t%lu fragment%s dropped after timeout\n");
-	p(ips_reassembled, "\t%lu packet%s reassembled ok\n");
-	p(ips_delivered, "\t%lu packet%s for this host\n");
-	p(ips_noproto, "\t%lu packet%s for unknown/unsupported protocol\n");
-	p(ips_forward, "\t%lu packet%s forwarded");
-	p(ips_fastforward, " (%lu packet%s fast forwarded)");
+	p(ips_total, "\t%ju total packet%s received\n");
+	p(ips_badsum, "\t%ju bad header checksum%s\n");
+	p1a(ips_toosmall, "\t%ju with size smaller than minimum\n");
+	p1a(ips_tooshort, "\t%ju with data size < data length\n");
+	p1a(ips_toolong, "\t%ju with ip length > max ip packet size\n");
+	p1a(ips_badhlen, "\t%ju with header length < data size\n");
+	p1a(ips_badlen, "\t%ju with data length < header length\n");
+	p1a(ips_badoptions, "\t%ju with bad options\n");
+	p1a(ips_badvers, "\t%ju with incorrect version number\n");
+	p(ips_fragments, "\t%ju fragment%s received\n");
+	p(ips_fragdropped, "\t%ju fragment%s dropped (dup or out of space)\n");
+	p(ips_fragtimeout, "\t%ju fragment%s dropped after timeout\n");
+	p(ips_reassembled, "\t%ju packet%s reassembled ok\n");
+	p(ips_delivered, "\t%ju packet%s for this host\n");
+	p(ips_noproto, "\t%ju packet%s for unknown/unsupported protocol\n");
+	p(ips_forward, "\t%ju packet%s forwarded");
+	p(ips_fastforward, " (%ju packet%s fast forwarded)");
 	if (ipstat.ips_forward || sflag <= 1)
 		putchar('\n');
-	p(ips_cantforward, "\t%lu packet%s not forwardable\n");
+	p(ips_cantforward, "\t%ju packet%s not forwardable\n");
 	p(ips_notmember,
-	    "\t%lu packet%s received for unknown multicast group\n");
-	p(ips_redirectsent, "\t%lu redirect%s sent\n");
-	p(ips_localout, "\t%lu packet%s sent from this host\n");
-	p(ips_rawout, "\t%lu packet%s sent with fabricated ip header\n");
+	    "\t%ju packet%s received for unknown multicast group\n");
+	p(ips_redirectsent, "\t%ju redirect%s sent\n");
+	p(ips_localout, "\t%ju packet%s sent from this host\n");
+	p(ips_rawout, "\t%ju packet%s sent with fabricated ip header\n");
 	p(ips_odropped,
-	    "\t%lu output packet%s dropped due to no bufs, etc.\n");
-	p(ips_noroute, "\t%lu output packet%s discarded due to no route\n");
-	p(ips_fragmented, "\t%lu output datagram%s fragmented\n");
-	p(ips_ofragments, "\t%lu fragment%s created\n");
-	p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n");
-	p(ips_nogif, "\t%lu tunneling packet%s that can't find gif\n");
-	p(ips_badaddr, "\t%lu datagram%s with bad address in header\n");
+	    "\t%ju output packet%s dropped due to no bufs, etc.\n");
+	p(ips_noroute, "\t%ju output packet%s discarded due to no route\n");
+	p(ips_fragmented, "\t%ju output datagram%s fragmented\n");
+	p(ips_ofragments, "\t%ju fragment%s created\n");
+	p(ips_cantfrag, "\t%ju datagram%s that can't be fragmented\n");
+	p(ips_nogif, "\t%ju tunneling packet%s that can't find gif\n");
+	p(ips_badaddr, "\t%ju datagram%s with bad address in header\n");
 #undef p
 #undef p1a
 }
@@ -905,35 +895,27 @@
 void
 arp_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
 {
-	struct arpstat arpstat, zerostat;
-	size_t len = sizeof(arpstat);
+	struct arpstat arpstat;
 
-	if (live) {
-		if (zflag)
-			memset(&zerostat, 0, len);
-		if (sysctlbyname("net.link.ether.arp.stats", &arpstat, &len,
-		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
-			warn("sysctl: net.link.ether.arp.stats");
-			return;
-		}
-	} else
-		kread(off, &arpstat, len);
+	if (fetch_stats("net.link.ether.arp.stats", off, &arpstat,
+	    sizeof(arpstat), kread_counters) != 0)
+		return;
 
 	printf("%s:\n", name);
 
 #define	p(f, m) if (arpstat.f || sflag <= 1) \
-    printf(m, arpstat.f, plural(arpstat.f))
+    printf("\t%ju " m, (uintmax_t)arpstat.f, plural(arpstat.f))
 #define	p2(f, m) if (arpstat.f || sflag <= 1) \
-    printf(m, arpstat.f, pluralies(arpstat.f))
+    printf("\t%ju " m, (uintmax_t)arpstat.f, pluralies(arpstat.f))
 
-	p(txrequests, "\t%lu ARP request%s sent\n");
-	p2(txreplies, "\t%lu ARP repl%s sent\n");
-	p(rxrequests, "\t%lu ARP request%s received\n");
-	p2(rxreplies, "\t%lu ARP repl%s received\n");
-	p(received, "\t%lu ARP packet%s received\n");
-	p(dropped, "\t%lu total packet%s dropped due to no ARP entry\n");
-	p(timeouts, "\t%lu ARP entry%s timed out\n");
-	p(dupips, "\t%lu Duplicate IP%s seen\n");
+	p(txrequests, "ARP request%s sent\n");
+	p2(txreplies, "ARP repl%s sent\n");
+	p(rxrequests, "ARP request%s received\n");
+	p2(rxreplies, "ARP repl%s received\n");
+	p(received, "ARP packet%s received\n");
+	p(dropped, "total packet%s dropped due to no ARP entry\n");
+	p(timeouts, "ARP entry%s timed out\n");
+	p(dupips, "Duplicate IP%s seen\n");
 #undef p
 #undef p2
 }
@@ -990,21 +972,13 @@
 void
 icmp_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
 {
-	struct icmpstat icmpstat, zerostat;
+	struct icmpstat icmpstat;
+	size_t len;
 	int i, first;
-	size_t len;
 
-	len = sizeof icmpstat;
-	if (live) {
-		if (zflag)
-			memset(&zerostat, 0, len);
-		if (sysctlbyname("net.inet.icmp.stats", &icmpstat, &len,
-		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
-			warn("sysctl: net.inet.icmp.stats");
-			return;
-		}
-	} else
-		kread(off, &icmpstat, len);
+	if (fetch_stats("net.inet.icmp.stats", off, &icmpstat,
+	    sizeof(icmpstat), kread_counters) != 0)
+		return;
 
 	printf("%s:\n", name);
 
@@ -1066,91 +1040,18 @@
 	}
 }
 
-#ifndef BURN_BRIDGES
 /*
- * Dump IGMP statistics structure (pre 8.x kernel).
- */
-static void
-igmp_stats_live_old(const char *name)
-{
-	struct oigmpstat oigmpstat, zerostat;
-	size_t len = sizeof(oigmpstat);
-
-	if (zflag)
-		memset(&zerostat, 0, len);
-	if (sysctlbyname("net.inet.igmp.stats", &oigmpstat, &len,
-	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
-		warn("sysctl: net.inet.igmp.stats");
-		return;
-	}
-
-	printf("%s:\n", name);
-
-#define	p(f, m) if (oigmpstat.f || sflag <= 1) \
-    printf(m, oigmpstat.f, plural(oigmpstat.f))
-#define	py(f, m) if (oigmpstat.f || sflag <= 1) \
-    printf(m, oigmpstat.f, oigmpstat.f != 1 ? "ies" : "y")
-	p(igps_rcv_total, "\t%u message%s received\n");
-	p(igps_rcv_tooshort, "\t%u message%s received with too few bytes\n");
-	p(igps_rcv_badsum, "\t%u message%s received with bad checksum\n");
-	py(igps_rcv_queries, "\t%u membership quer%s received\n");
-	py(igps_rcv_badqueries,
-	    "\t%u membership quer%s received with invalid field(s)\n");
-	p(igps_rcv_reports, "\t%u membership report%s received\n");
-	p(igps_rcv_badreports,
-	    "\t%u membership report%s received with invalid field(s)\n");
-	p(igps_rcv_ourreports,
-"\t%u membership report%s received for groups to which we belong\n");
-        p(igps_snd_reports, "\t%u membership report%s sent\n");
-#undef p
-#undef py
-}
-#endif /* !BURN_BRIDGES */
-
-/*
  * Dump IGMP statistics structure.
  */
 void
 igmp_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
 {
-	struct igmpstat igmpstat, zerostat;
-	size_t len;
+	struct igmpstat igmpstat;
 
-#ifndef BURN_BRIDGES
-	if (live) {
-		/*
-		 * Detect if we are being run against a pre-IGMPv3 kernel.
-		 * We cannot do this for a core file as the legacy
-		 * struct igmpstat has no size field, nor does it
-		 * export it in any readily-available symbols.
-		 */
-		len = 0;
-		if (sysctlbyname("net.inet.igmp.stats", NULL, &len, NULL,
-		    0) < 0) {
-			warn("sysctl: net.inet.igmp.stats");
-			return;
-		}
-		if (len < sizeof(igmpstat)) {
-			igmp_stats_live_old(name);
-			return;
-		}
-	}
-#endif /* !BURN_BRIDGES */
+	if (fetch_stats("net.inet.igmp.stats", 0, &igmpstat,
+	    sizeof(igmpstat), kread) != 0)
+		return;
 
-	len = sizeof(igmpstat);
-	if (live) {
-		if (zflag)
-			memset(&zerostat, 0, len);
-		if (sysctlbyname("net.inet.igmp.stats", &igmpstat, &len,
-		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
-			warn("sysctl: net.inet.igmp.stats");
-			return;
-		}
-	} else {
-		len = sizeof(igmpstat);
-		kread(off, &igmpstat, len);
-	}
-
 	if (igmpstat.igps_version != IGPS_VERSION_3) {
 		warnx("%s: version mismatch (%d != %d)", __func__,
 		    igmpstat.igps_version, IGPS_VERSION_3);
@@ -1196,23 +1097,11 @@
 pim_stats(u_long off __unused, const char *name, int af1 __unused,
     int proto __unused)
 {
-	struct pimstat pimstat, zerostat;
-	size_t len = sizeof pimstat;
+	struct pimstat pimstat;
 
-	if (live) {
-		if (zflag)
-			memset(&zerostat, 0, len);
-		if (sysctlbyname("net.inet.pim.stats", &pimstat, &len,
-		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
-			if (errno != ENOENT)
-				warn("sysctl: net.inet.pim.stats");
-			return;
-		}
-	} else {
-		if (off == 0)
-			return;
-		kread(off, &pimstat, len);
-	}
+	if (fetch_stats("net.inet.pim.stats", off, &pimstat,
+	    sizeof(pimstat), kread_counters) != 0)
+		return;
 
 	printf("%s:\n", name);
 
@@ -1250,7 +1139,7 @@
 	    sprintf(line, "%s.", inetname(in));
 	else
 	    sprintf(line, "%.*s.", (Aflag && !num_port) ? 12 : 16, inetname(in));
-	cp = index(line, '\0');
+	cp = strchr(line, '\0');
 	if (!num_port && port)
 		sp = getservbyport((int)port, proto);
 	if (sp || port == 0)

Modified: trunk/usr.bin/netstat/inet6.c
===================================================================
--- trunk/usr.bin/netstat/inet6.c	2018-07-07 16:54:14 UTC (rev 11466)
+++ trunk/usr.bin/netstat/inet6.c	2018-07-07 16:54:32 UTC (rev 11467)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp	*/
 /*-
  * Copyright (c) 1983, 1988, 1993
@@ -35,7 +36,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/usr.bin/netstat/inet6.c 319260 2017-05-30 22:35:36Z asomers $");
 
 #ifdef INET6
 #include <sys/param.h>
@@ -44,7 +45,6 @@
 #include <sys/ioctl.h>
 #include <sys/mbuf.h>
 #include <sys/protosw.h>
-#include <sys/sysctl.h>
 
 #include <net/route.h>
 #include <net/if.h>
@@ -335,7 +335,7 @@
 	"#255",
 };
 
-static char *srcrule_str[] = {
+static const char *srcrule_str[] = {
 	"first candidate",
 	"same address",
 	"appropriate scope",
@@ -345,8 +345,8 @@
 	"matching label",
 	"public/temporary address",
 	"alive interface",
-	"preferred interface",
-	"rule #10",
+	"better virtual status",
+	"preferred source",
 	"rule #11",
 	"rule #12",
 	"rule #13",
@@ -360,23 +360,12 @@
 void
 ip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
 {
-	struct ip6stat ip6stat, zerostat;
+	struct ip6stat ip6stat;
 	int first, i;
-	size_t len;
 
-	len = sizeof ip6stat;
-	if (live) {
-		memset(&ip6stat, 0, len);
-		if (zflag)
-			memset(&zerostat, 0, len);
-		if (sysctlbyname("net.inet6.ip6.stats", &ip6stat, &len,
-		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
-			if (errno != ENOENT)
-				warn("sysctl: net.inet6.ip6.stats");
-			return;
-		}
-	} else
-		kread(off, &ip6stat, len);
+	if (fetch_stats("net.inet6.ip6.stats", off, &ip6stat,
+	    sizeof(ip6stat), kread_counters) != 0)
+		return;
 
 	printf("%s:\n", name);
 
@@ -539,14 +528,14 @@
 		return;
 	}
 
-	strcpy(ifr.ifr_name, ifname);
-	printf("ip6 on %s:\n", ifr.ifr_name);
-
+	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
 	if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) {
-		perror("Warning: ioctl(SIOCGIFSTAT_IN6)");
+		if (errno != EPFNOSUPPORT)
+			perror("Warning: ioctl(SIOCGIFSTAT_IN6)");
 		goto end;
 	}
 
+	printf("ip6 on %s:\n", ifr.ifr_name);
 	p(ifs6_in_receive, "\t%ju total input datagram%s\n");
 	p(ifs6_in_hdrerr, "\t%ju datagram%s with invalid header received\n");
 	p(ifs6_in_toobig, "\t%ju datagram%s exceeded MTU received\n");
@@ -842,23 +831,12 @@
 void
 icmp6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
 {
-	struct icmp6stat icmp6stat, zerostat;
+	struct icmp6stat icmp6stat;
 	int i, first;
-	size_t len;
 
-	len = sizeof icmp6stat;
-	if (live) {
-		memset(&icmp6stat, 0, len);
-		if (zflag)
-			memset(&zerostat, 0, len);
-		if (sysctlbyname("net.inet6.icmp6.stats", &icmp6stat, &len,
-		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
-			if (errno != ENOENT)
-				warn("sysctl: net.inet6.icmp6.stats");
-			return;
-		}
-	} else
-		kread(off, &icmp6stat, len);
+	if (fetch_stats("net.inet6.icmp6.stats", off, &icmp6stat,
+	    sizeof(icmp6stat), kread_counters) != 0)
+		return;
 
 	printf("%s:\n", name);
 
@@ -944,14 +922,14 @@
 		return;
 	}
 
-	strcpy(ifr.ifr_name, ifname);
-	printf("icmp6 on %s:\n", ifr.ifr_name);
-
+	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
 	if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) {
-		perror("Warning: ioctl(SIOCGIFSTAT_ICMP6)");
+		if (errno != EPFNOSUPPORT)
+			perror("Warning: ioctl(SIOCGIFSTAT_ICMP6)");
 		goto end;
 	}
 
+	printf("icmp6 on %s:\n", ifr.ifr_name);
 	p(ifs6_in_msg, "\t%ju total input message%s\n");
 	p(ifs6_in_error, "\t%ju total input error message%s\n");
 	p(ifs6_in_dstunreach, "\t%ju input destination unreachable error%s\n");
@@ -999,23 +977,11 @@
 void
 pim6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
 {
-	struct pim6stat pim6stat, zerostat;
-	size_t len = sizeof pim6stat;
+	struct pim6stat pim6stat;
 
-	if (live) {
-		if (zflag)
-			memset(&zerostat, 0, len);
-		if (sysctlbyname("net.inet6.pim.stats", &pim6stat, &len,
-		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
-			if (errno != ENOENT)
-				warn("sysctl: net.inet6.pim.stats");
-			return;
-		}
-	} else {
-		if (off == 0)
-			return;
-		kread(off, &pim6stat, len);
-	}
+	if (fetch_stats("net.inet6.pim.stats", off, &pim6stat,
+	    sizeof(pim6stat), kread) != 0)
+		return;
 
 	printf("%s:\n", name);
 
@@ -1037,22 +1003,12 @@
 void
 rip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
 {
-	struct rip6stat rip6stat, zerostat;
+	struct rip6stat rip6stat;
 	u_quad_t delivered;
-	size_t len;
 
-	len = sizeof(rip6stat);
-	if (live) {
-		if (zflag)
-			memset(&zerostat, 0, len);
-		if (sysctlbyname("net.inet6.ip6.rip6stats", &rip6stat, &len,
-		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
-			if (errno != ENOENT)
-				warn("sysctl: net.inet6.ip6.rip6stats");
-			return;
-		}
-	} else
-		kread(off, &rip6stat, len);
+	if (fetch_stats("net.inet6.ip6.rip6stats", off, &rip6stat,
+	    sizeof(rip6stat), kread_counters) != 0)
+		return;
 
 	printf("%s:\n", name);
 
@@ -1100,7 +1056,7 @@
 
 	sprintf(line, "%.*s.", Wflag ? 39 :
 		(Aflag && !numeric) ? 12 : 16, inet6name(in6));
-	cp = index(line, '\0');
+	cp = strchr(line, '\0');
 	if (!numeric && port)
 		GETSERVBYPORT6(port, proto, sp);
 	if (sp || port == 0)
@@ -1120,38 +1076,45 @@
 char *
 inet6name(struct in6_addr *in6p)
 {
-	char *cp;
+	struct sockaddr_in6 sin6;
+	char hbuf[NI_MAXHOST], *cp;
 	static char line[50];
-	struct hostent *hp;
 	static char domain[MAXHOSTNAMELEN];
 	static int first = 1;
+	int flags, error;
 
+	if (IN6_IS_ADDR_UNSPECIFIED(in6p)) {
+		strcpy(line, "*");
+		return (line);
+	}
 	if (first && !numeric_addr) {
 		first = 0;
 		if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
-		    (cp = index(domain, '.')))
+		    (cp = strchr(domain, '.')))
 			(void) strcpy(domain, cp + 1);
 		else
 			domain[0] = 0;
 	}
-	cp = 0;
-	if (!numeric_addr && !IN6_IS_ADDR_UNSPECIFIED(in6p)) {
-		hp = gethostbyaddr((char *)in6p, sizeof(*in6p), AF_INET6);
-		if (hp) {
-			if ((cp = index(hp->h_name, '.')) &&
-			    !strcmp(cp + 1, domain))
-				*cp = 0;
-			cp = hp->h_name;
-		}
-	}
-	if (IN6_IS_ADDR_UNSPECIFIED(in6p))
-		strcpy(line, "*");
-	else if (cp)
-		strcpy(line, cp);
-	else
+	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);
+	flags = (numeric_addr) ? NI_NUMERICHOST : 0;
+	error = getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), hbuf,
+	    sizeof(hbuf), NULL, 0, flags);
+	if (error == 0) {
+		if ((flags & NI_NUMERICHOST) == 0 &&
+		    (cp = strchr(hbuf, '.')) &&
+		    !strcmp(cp + 1, domain))
+			*cp = 0;
+		strcpy(line, hbuf);
+	} else {
+		/* XXX: this should not happen. */
 		sprintf(line, "%s",
-			inet_ntop(AF_INET6, (void *)in6p, ntop_buf,
+			inet_ntop(AF_INET6, (void *)&sin6.sin6_addr, ntop_buf,
 				sizeof(ntop_buf)));
+	}
 	return (line);
 }
 #endif /*INET6*/

Modified: trunk/usr.bin/netstat/ipsec.c
===================================================================
--- trunk/usr.bin/netstat/ipsec.c	2018-07-07 16:54:14 UTC (rev 11466)
+++ trunk/usr.bin/netstat/ipsec.c	2018-07-07 16:54:32 UTC (rev 11467)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$KAME: ipsec.c,v 1.33 2003/07/25 09:54:32 itojun Exp $	*/
 
 /*-
@@ -89,7 +90,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/usr.bin/netstat/ipsec.c 293344 2016-01-07 19:52:17Z gnn $");
 
 #include <sys/param.h>
 #include <sys/queue.h>
@@ -166,84 +167,18 @@
 	{ -1, NULL },
 };
 
-static void ipsec_hist(const u_quad_t *hist, size_t histmax,
-		       const struct val2str *name, const char *title);
 static void print_ipsecstats(const struct ipsecstat *ipsecstat);
 
-
-/*
- * Dump IPSEC statistics structure.
- */
 static void
-ipsec_hist(const u_quad_t *hist, size_t histmax, const struct val2str *name,
-	   const char *title)
-{
-	int first;
-	size_t proto;
-	const struct val2str *p;
-
-	first = 1;
-	for (proto = 0; proto < histmax; proto++) {
-		if (hist[proto] <= 0)
-			continue;
-		if (first) {
-			printf("\t%s histogram:\n", title);
-			first = 0;
-		}
-		for (p = name; p && p->str; p++) {
-			if (p->val == (int)proto)
-				break;
-		}
-		if (p && p->str) {
-			printf("\t\t%s: %ju\n", p->str, (uintmax_t)hist[proto]);
-		} else {
-			printf("\t\t#%ld: %ju\n", (long)proto,
-			    (uintmax_t)hist[proto]);
-		}
-	}
-}
-
-static void
 print_ipsecstats(const struct ipsecstat *ipsecstat)
 {
 #define	p(f, m) if (ipsecstat->f || sflag <= 1) \
     printf(m, (uintmax_t)ipsecstat->f, plural(ipsecstat->f))
-#define	pes(f, m) if (ipsecstat->f || sflag <= 1) \
-    printf(m, (uintmax_t)ipsecstat->f, plurales(ipsecstat->f))
-#define	hist(f, n, t) \
-    ipsec_hist((f), sizeof(f)/sizeof(f[0]), (n), (t));
-
-	p(in_success, "\t%ju inbound packet%s processed successfully\n");
-	p(in_polvio, "\t%ju inbound packet%s violated process security "
-	    "policy\n");
-	p(in_nosa, "\t%ju inbound packet%s with no SA available\n");
-	p(in_inval, "\t%ju invalid inbound packet%s\n");
-	p(in_nomem, "\t%ju inbound packet%s failed due to insufficient memory\n");
-	p(in_badspi, "\t%ju inbound packet%s failed getting SPI\n");
-	p(in_ahreplay, "\t%ju inbound packet%s failed on AH replay check\n");
-	p(in_espreplay, "\t%ju inbound packet%s failed on ESP replay check\n");
-	p(in_ahauthsucc, "\t%ju inbound packet%s considered authentic\n");
-	p(in_ahauthfail, "\t%ju inbound packet%s failed on authentication\n");
-	hist(ipsecstat->in_ahhist, ipsec_ahnames, "AH input");
-	hist(ipsecstat->in_esphist, ipsec_espnames, "ESP input");
-	hist(ipsecstat->in_comphist, ipsec_compnames, "IPComp input");
-
-	p(out_success, "\t%ju outbound packet%s processed successfully\n");
-	p(out_polvio, "\t%ju outbound packet%s violated process security "
-	    "policy\n");
-	p(out_nosa, "\t%ju outbound packet%s with no SA available\n");
-	p(out_inval, "\t%ju invalid outbound packet%s\n");
-	p(out_nomem, "\t%ju outbound packet%s failed due to insufficient memory\n");
-	p(out_noroute, "\t%ju outbound packet%s with no route\n");
-	hist(ipsecstat->out_ahhist, ipsec_ahnames, "AH output");
-	hist(ipsecstat->out_esphist, ipsec_espnames, "ESP output");
-	hist(ipsecstat->out_comphist, ipsec_compnames, "IPComp output");
-	p(spdcachelookup, "\t%ju SPD cache lookup%s\n");
-	pes(spdcachemiss, "\t%ju SPD cache miss%s\n");
-#undef pes
-#undef hist
 	p(ips_in_polvio, "\t%ju inbound packet%s violated process "
 		"security policy\n");
+	p(ips_in_nomem, "\t%ju inbound packet%s failed due to "
+		"insufficient memory\n");
+	p(ips_in_inval, "\t%ju invalid inbound packet%s\n");
 	p(ips_out_polvio, "\t%ju outbound packet%s violated process "
 		"security policy\n");
 	p(ips_out_nosa, "\t%ju outbound packet%s with no SA available\n");
@@ -265,16 +200,23 @@
 {
 	struct ipsecstat ipsecstat;
 
-	if (off == 0)
-		return;
+	if (strcmp(name, "ipsec6") == 0) {
+		if (fetch_stats("net.inet6.ipsec6.ipsecstats", off,&ipsecstat,
+				sizeof(ipsecstat), kread_counters) != 0)
+			return;
+	} else {
+		if (fetch_stats("net.inet.ipsec.ipsecstats", off, &ipsecstat,
+				sizeof(ipsecstat), kread_counters) != 0)
+			return;
+	}
+
 	printf ("%s:\n", name);
-	kread(off, (char *)&ipsecstat, sizeof(ipsecstat));
 
 	print_ipsecstats(&ipsecstat);
 }
 
 
-static void ipsec_hist_new(const u_int32_t *hist, size_t histmax,
+static void ipsec_hist_new(const uint64_t *hist, size_t histmax,
 			   const struct val2str *name, const char *title);
 static void print_ahstats(const struct ahstat *ahstat);
 static void print_espstats(const struct espstat *espstat);
@@ -284,7 +226,7 @@
  * Dump IPSEC statistics structure.
  */
 static void
-ipsec_hist_new(const u_int32_t *hist, size_t histmax,
+ipsec_hist_new(const uint64_t *hist, size_t histmax,
 	       const struct val2str *name, const char *title)
 {
 	int first;
@@ -304,10 +246,11 @@
 				break;
 		}
 		if (p && p->str) {
-			printf("\t\t%s: %u\n", p->str, hist[proto]);
+			printf("\t\t%s: %ju\n", p->str,
+			    (uintmax_t)hist[proto]);
 		} else {
-			printf("\t\t#%lu: %u\n", (unsigned long)proto,
-			       hist[proto]);
+			printf("\t\t#%lu: %ju\n", (unsigned long)proto,
+			    (uintmax_t)hist[proto]);
 		}
 	}
 }
@@ -315,36 +258,33 @@
 static void
 print_ahstats(const struct ahstat *ahstat)
 {
-#define	p32(f, m) if (ahstat->f || sflag <= 1) \
-    printf("\t%u" m, (unsigned int)ahstat->f, plural(ahstat->f))
-#define	p64(f, m) if (ahstat->f || sflag <= 1) \
+#define	p(f, m) if (ahstat->f || sflag <= 1) \
     printf("\t%ju" m, (uintmax_t)ahstat->f, plural(ahstat->f))
 #define	hist(f, n, t) \
     ipsec_hist_new((f), sizeof(f)/sizeof(f[0]), (n), (t));
 
-	p32(ahs_hdrops, " packet%s shorter than header shows\n");
-	p32(ahs_nopf, " packet%s dropped; protocol family not supported\n");
-	p32(ahs_notdb, " packet%s dropped; no TDB\n");
-	p32(ahs_badkcr, " packet%s dropped; bad KCR\n");
-	p32(ahs_qfull, " packet%s dropped; queue full\n");
-	p32(ahs_noxform, " packet%s dropped; no transform\n");
-	p32(ahs_wrap, " replay counter wrap%s\n");
-	p32(ahs_badauth, " packet%s dropped; bad authentication detected\n");
-	p32(ahs_badauthl, " packet%s dropped; bad authentication length\n");
-	p32(ahs_replay, " possible replay packet%s detected\n");
-	p32(ahs_input, " packet%s in\n");
-	p32(ahs_output, " packet%s out\n");
-	p32(ahs_invalid, " packet%s dropped; invalid TDB\n");
-	p64(ahs_ibytes, " byte%s in\n");
-	p64(ahs_obytes, " byte%s out\n");
-	p32(ahs_toobig, " packet%s dropped; larger than IP_MAXPACKET\n");
-	p32(ahs_pdrops, " packet%s blocked due to policy\n");
-	p32(ahs_crypto, " crypto processing failure%s\n");
-	p32(ahs_tunnel, " tunnel sanity check failure%s\n");
+	p(ahs_hdrops, " packet%s shorter than header shows\n");
+	p(ahs_nopf, " packet%s dropped; protocol family not supported\n");
+	p(ahs_notdb, " packet%s dropped; no TDB\n");
+	p(ahs_badkcr, " packet%s dropped; bad KCR\n");
+	p(ahs_qfull, " packet%s dropped; queue full\n");
+	p(ahs_noxform, " packet%s dropped; no transform\n");
+	p(ahs_wrap, " replay counter wrap%s\n");
+	p(ahs_badauth, " packet%s dropped; bad authentication detected\n");
+	p(ahs_badauthl, " packet%s dropped; bad authentication length\n");
+	p(ahs_replay, " possible replay packet%s detected\n");
+	p(ahs_input, " packet%s in\n");
+	p(ahs_output, " packet%s out\n");
+	p(ahs_invalid, " packet%s dropped; invalid TDB\n");
+	p(ahs_ibytes, " byte%s in\n");
+	p(ahs_obytes, " byte%s out\n");
+	p(ahs_toobig, " packet%s dropped; larger than IP_MAXPACKET\n");
+	p(ahs_pdrops, " packet%s blocked due to policy\n");
+	p(ahs_crypto, " crypto processing failure%s\n");
+	p(ahs_tunnel, " tunnel sanity check failure%s\n");
 	hist(ahstat->ahs_hist, ipsec_ahnames, "AH output");
 
-#undef p32
-#undef p64
+#undef p
 #undef hist
 }
 
@@ -353,10 +293,10 @@
 {
 	struct ahstat ahstat;
 
-	if (off == 0)
+	if (fetch_stats("net.inet.ah.stats", off, &ahstat,
+	    sizeof(ahstat), kread_counters) != 0)
 		return;
 	printf ("%s:\n", name);
-	kread(off, (char *)&ahstat, sizeof(ahstat));
 
 	print_ahstats(&ahstat);
 }
@@ -364,37 +304,34 @@
 static void
 print_espstats(const struct espstat *espstat)
 {
-#define	p32(f, m) if (espstat->f || sflag <= 1) \
-    printf("\t%u" m, (unsigned int)espstat->f, plural(espstat->f))
-#define	p64(f, m) if (espstat->f || sflag <= 1) \
+#define	p(f, m) if (espstat->f || sflag <= 1) \
     printf("\t%ju" m, (uintmax_t)espstat->f, plural(espstat->f))
 #define	hist(f, n, t) \
     ipsec_hist_new((f), sizeof(f)/sizeof(f[0]), (n), (t));
 
-	p32(esps_hdrops, " packet%s shorter than header shows\n");
-	p32(esps_nopf, " packet%s dropped; protocol family not supported\n");
-	p32(esps_notdb, " packet%s dropped; no TDB\n");
-	p32(esps_badkcr, " packet%s dropped; bad KCR\n");
-	p32(esps_qfull, " packet%s dropped; queue full\n");
-	p32(esps_noxform, " packet%s dropped; no transform\n");
-	p32(esps_badilen, " packet%s dropped; bad ilen\n");
-	p32(esps_wrap, " replay counter wrap%s\n");
-	p32(esps_badenc, " packet%s dropped; bad encryption detected\n");
-	p32(esps_badauth, " packet%s dropped; bad authentication detected\n");
-	p32(esps_replay, " possible replay packet%s detected\n");
-	p32(esps_input, " packet%s in\n");
-	p32(esps_output, " packet%s out\n");
-	p32(esps_invalid, " packet%s dropped; invalid TDB\n");
-	p64(esps_ibytes, " byte%s in\n");
-	p64(esps_obytes, " byte%s out\n");
-	p32(esps_toobig, " packet%s dropped; larger than IP_MAXPACKET\n");
-	p32(esps_pdrops, " packet%s blocked due to policy\n");
-	p32(esps_crypto, " crypto processing failure%s\n");
-	p32(esps_tunnel, " tunnel sanity check failure%s\n");
+	p(esps_hdrops, " packet%s shorter than header shows\n");
+	p(esps_nopf, " packet%s dropped; protocol family not supported\n");
+	p(esps_notdb, " packet%s dropped; no TDB\n");
+	p(esps_badkcr, " packet%s dropped; bad KCR\n");
+	p(esps_qfull, " packet%s dropped; queue full\n");
+	p(esps_noxform, " packet%s dropped; no transform\n");
+	p(esps_badilen, " packet%s dropped; bad ilen\n");
+	p(esps_wrap, " replay counter wrap%s\n");
+	p(esps_badenc, " packet%s dropped; bad encryption detected\n");
+	p(esps_badauth, " packet%s dropped; bad authentication detected\n");
+	p(esps_replay, " possible replay packet%s detected\n");
+	p(esps_input, " packet%s in\n");
+	p(esps_output, " packet%s out\n");
+	p(esps_invalid, " packet%s dropped; invalid TDB\n");
+	p(esps_ibytes, " byte%s in\n");
+	p(esps_obytes, " byte%s out\n");
+	p(esps_toobig, " packet%s dropped; larger than IP_MAXPACKET\n");
+	p(esps_pdrops, " packet%s blocked due to policy\n");
+	p(esps_crypto, " crypto processing failure%s\n");
+	p(esps_tunnel, " tunnel sanity check failure%s\n");
 	hist(espstat->esps_hist, ipsec_espnames, "ESP output");
 
-#undef p32
-#undef p64
+#undef p
 #undef hist
 }
 
@@ -403,10 +340,10 @@
 {
 	struct espstat espstat;
 
-	if (off == 0)
+	if (fetch_stats("net.inet.esp.stats", off, &espstat,
+	    sizeof(espstat), kread_counters) != 0)
 		return;
 	printf ("%s:\n", name);
-	kread(off, (char *)&espstat, sizeof(espstat));
 
 	print_espstats(&espstat);
 }
@@ -414,42 +351,31 @@
 static void
 print_ipcompstats(const struct ipcompstat *ipcompstat)
 {
-	uint32_t version;
-#define	p32(f, m) if (ipcompstat->f || sflag <= 1) \
-    printf("\t%u" m, (unsigned int)ipcompstat->f, plural(ipcompstat->f))
-#define	p64(f, m) if (ipcompstat->f || sflag <= 1) \
+#define	p(f, m) if (ipcompstat->f || sflag <= 1) \
     printf("\t%ju" m, (uintmax_t)ipcompstat->f, plural(ipcompstat->f))
 #define	hist(f, n, t) \
     ipsec_hist_new((f), sizeof(f)/sizeof(f[0]), (n), (t));
 
-#ifndef IPCOMPSTAT_VERSION
-	version = 0;
-#else
-	version = ipcompstat->version;
-#endif
-	p32(ipcomps_hdrops, " packet%s shorter than header shows\n");
-	p32(ipcomps_nopf, " packet%s dropped; protocol family not supported\n");
-	p32(ipcomps_notdb, " packet%s dropped; no TDB\n");
-	p32(ipcomps_badkcr, " packet%s dropped; bad KCR\n");
-	p32(ipcomps_qfull, " packet%s dropped; queue full\n");
-	p32(ipcomps_noxform, " packet%s dropped; no transform\n");
-	p32(ipcomps_wrap, " replay counter wrap%s\n");
-	p32(ipcomps_input, " packet%s in\n");
-	p32(ipcomps_output, " packet%s out\n");
-	p32(ipcomps_invalid, " packet%s dropped; invalid TDB\n");
-	p64(ipcomps_ibytes, " byte%s in\n");
-	p64(ipcomps_obytes, " byte%s out\n");
-	p32(ipcomps_toobig, " packet%s dropped; larger than IP_MAXPACKET\n");
-	p32(ipcomps_pdrops, " packet%s blocked due to policy\n");
-	p32(ipcomps_crypto, " crypto processing failure%s\n");
+	p(ipcomps_hdrops, " packet%s shorter than header shows\n");
+	p(ipcomps_nopf, " packet%s dropped; protocol family not supported\n");
+	p(ipcomps_notdb, " packet%s dropped; no TDB\n");
+	p(ipcomps_badkcr, " packet%s dropped; bad KCR\n");
+	p(ipcomps_qfull, " packet%s dropped; queue full\n");
+	p(ipcomps_noxform, " packet%s dropped; no transform\n");
+	p(ipcomps_wrap, " replay counter wrap%s\n");
+	p(ipcomps_input, " packet%s in\n");
+	p(ipcomps_output, " packet%s out\n");
+	p(ipcomps_invalid, " packet%s dropped; invalid TDB\n");
+	p(ipcomps_ibytes, " byte%s in\n");
+	p(ipcomps_obytes, " byte%s out\n");
+	p(ipcomps_toobig, " packet%s dropped; larger than IP_MAXPACKET\n");
+	p(ipcomps_pdrops, " packet%s blocked due to policy\n");
+	p(ipcomps_crypto, " crypto processing failure%s\n");
 	hist(ipcompstat->ipcomps_hist, ipsec_compnames, "COMP output");
-	if (version >= 1) {
-	p32(ipcomps_threshold, " packet%s sent uncompressed; size < compr. algo. threshold\n");
-	p32(ipcomps_uncompr, " packet%s sent uncompressed; compression was useless\n");
-	}
+	p(ipcomps_threshold, " packet%s sent uncompressed; size < compr. algo. threshold\n");
+	p(ipcomps_uncompr, " packet%s sent uncompressed; compression was useless\n");
 
-#undef p32
-#undef p64
+#undef p
 #undef hist
 }
 
@@ -459,10 +385,10 @@
 {
 	struct ipcompstat ipcompstat;
 
-	if (off == 0)
+	if (fetch_stats("net.inet.ipcomp.stats", off, &ipcompstat,
+	    sizeof(ipcompstat), kread_counters) != 0)
 		return;
 	printf ("%s:\n", name);
-	kread(off, (char *)&ipcompstat, sizeof(ipcompstat));
 
 	print_ipcompstats(&ipcompstat);
 }

Modified: trunk/usr.bin/netstat/ipx.c
===================================================================
--- trunk/usr.bin/netstat/ipx.c	2018-07-07 16:54:14 UTC (rev 11466)
+++ trunk/usr.bin/netstat/ipx.c	2018-07-07 16:54:32 UTC (rev 11467)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2004, Robert N. M. Watson
  * Copyright (c) 1983, 1988, 1993
@@ -39,7 +40,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/usr.bin/netstat/ipx.c 228992 2011-12-30 11:02:40Z uqs $");
 
 #include <sys/param.h>
 #include <sys/queue.h>
@@ -201,7 +202,7 @@
 	ANYl(spxstat.spxs_sndurg, "packet", " sent with URG only");
 	ANYl(spxstat.spxs_sndwinup, "window update-only packet", " sent");
 	ANYl(spxstat.spxs_sndctrl, "control (SYN|FIN|RST) packet", " sent");
-	ANYl(spxstat.spxs_sndvoid, "request", " to send a non-existant packet");
+	ANYl(spxstat.spxs_sndvoid, "request", " to send a non-existent packet");
 	ANYl(spxstat.spxs_rcvtotal, "total packet", " received");
 	ANYl(spxstat.spxs_rcvpack, "packet", " received in sequence");
 	ANYl(spxstat.spxs_rcvbyte, "byte", " received in sequence");

Modified: trunk/usr.bin/netstat/main.c
===================================================================
--- trunk/usr.bin/netstat/main.c	2018-07-07 16:54:14 UTC (rev 11466)
+++ trunk/usr.bin/netstat/main.c	2018-07-07 16:54:32 UTC (rev 11467)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1983, 1988, 1993
  *	Regents of the University of California.  All rights reserved.
@@ -40,7 +41,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/usr.bin/netstat/main.c 312278 2017-01-16 09:12:40Z smh $");
 
 #include <sys/param.h>
 #include <sys/file.h>
@@ -47,6 +48,7 @@
 #include <sys/protosw.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
+#include <sys/sysctl.h>
 
 #include <netinet/in.h>
 
@@ -71,7 +73,7 @@
 
 static struct nlist nl[] = {
 #define	N_IFNET		0
-	{ .n_name = "_ifnet" },
+	{ .n_name = "_ifnet" },		/* XXXGL: can be deleted */
 #define	N_RTSTAT	1
 	{ .n_name = "_rtstat" },
 #define	N_RTREE		2
@@ -112,78 +114,58 @@
 	{ .n_name = "_mif6table" },
 #define	N_PFKEYSTAT	20
 	{ .n_name = "_pfkeystat" },
-#define	N_MBSTAT	21
-	{ .n_name = "_mbstat" },
-#define	N_MBTYPES	22
-	{ .n_name = "_mbtypes" },
-#define	N_NMBCLUSTERS	23
-	{ .n_name = "_nmbclusters" },
-#define	N_NMBUFS	24
-	{ .n_name = "_nmbufs" },
-#define	N_MBHI		25
-	{ .n_name = "_mbuf_hiwm" },
-#define	N_CLHI		26
-	{ .n_name = "_clust_hiwm" },
-#define	N_NCPUS		27
-	{ .n_name = "_smp_cpus" },
-#define	N_PAGESZ	28
-	{ .n_name = "_pagesize" },
-#define	N_MBPSTAT	29
-	{ .n_name = "_mb_statpcpu" },
-#define	N_RTTRASH	30
+#define	N_RTTRASH	21
 	{ .n_name = "_rttrash" },
-#define	N_MBLO		31
-	{ .n_name = "_mbuf_lowm" },
-#define	N_CLLO		32
-	{ .n_name = "_clust_lowm" },
-#define	N_CARPSTAT	33
+#define	N_CARPSTAT	22
 	{ .n_name = "_carpstats" },
-#define	N_PFSYNCSTAT	34
+#define	N_PFSYNCSTAT	23
 	{ .n_name = "_pfsyncstats" },
-#define	N_AHSTAT	35
+#define	N_AHSTAT	24
 	{ .n_name = "_ahstat" },
-#define	N_ESPSTAT	36
+#define	N_ESPSTAT	25
 	{ .n_name = "_espstat" },
-#define	N_IPCOMPSTAT	37
+#define	N_IPCOMPSTAT	26
 	{ .n_name = "_ipcompstat" },
-#define	N_TCPSTAT	38
+#define	N_TCPSTAT	27
 	{ .n_name = "_tcpstat" },
-#define	N_UDPSTAT	39
+#define	N_UDPSTAT	28
 	{ .n_name = "_udpstat" },
-#define	N_IPSTAT	40
+#define	N_IPSTAT	29
 	{ .n_name = "_ipstat" },
-#define	N_ICMPSTAT	41
+#define	N_ICMPSTAT	30
 	{ .n_name = "_icmpstat" },
-#define	N_IGMPSTAT	42
+#define	N_IGMPSTAT	31
 	{ .n_name = "_igmpstat" },
-#define	N_PIMSTAT	43
+#define	N_PIMSTAT	32
 	{ .n_name = "_pimstat" },
-#define	N_TCBINFO	44
+#define	N_TCBINFO	33
 	{ .n_name = "_tcbinfo" },
-#define	N_UDBINFO	45
+#define	N_UDBINFO	34
 	{ .n_name = "_udbinfo" },
-#define	N_DIVCBINFO	46
+#define	N_DIVCBINFO	35
 	{ .n_name = "_divcbinfo" },
-#define	N_RIPCBINFO	47
+#define	N_RIPCBINFO	36
 	{ .n_name = "_ripcbinfo" },
-#define	N_UNP_COUNT	48
+#define	N_UNP_COUNT	37
 	{ .n_name = "_unp_count" },
-#define	N_UNP_GENCNT	49
+#define	N_UNP_GENCNT	38
 	{ .n_name = "_unp_gencnt" },
-#define	N_UNP_DHEAD	50
+#define	N_UNP_DHEAD	39
 	{ .n_name = "_unp_dhead" },
-#define	N_UNP_SHEAD	51
+#define	N_UNP_SHEAD	40
 	{ .n_name = "_unp_shead" },
-#define	N_RIP6STAT	52
+#define	N_RIP6STAT	41
 	{ .n_name = "_rip6stat" },
-#define	N_SCTPSTAT	53
+#define	N_SCTPSTAT	42
 	{ .n_name = "_sctpstat" },
-#define	N_MFCTABLESIZE	54
+#define	N_MFCTABLESIZE	43
 	{ .n_name = "_mfctablesize" },
-#define N_ARPSTAT       55
+#define	N_ARPSTAT       44
 	{ .n_name = "_arpstat" },
-#define	N_UNP_SPHEAD	56
+#define	N_UNP_SPHEAD	45
 	{ .n_name = "unp_sphead" },
+#define	N_SFSTAT	46
+	{ .n_name = "_sfstat"},
 	{ .n_name = NULL },
 };
 
@@ -222,20 +204,22 @@
 	  igmp_stats,	NULL,		"igmp",	1,	IPPROTO_IGMP },
 #ifdef IPSEC
 	{ -1,		N_IPSECSTAT,	1,	NULL,	/* keep as compat */
-	  ipsec_stats,	NULL,		"ipsec", 0,	0},
+	  ipsec_stats,	NULL,		"ipsec", 1,	0},
 	{ -1,		N_AHSTAT,	1,	NULL,
-	  ah_stats,	NULL,		"ah",	0,	0},
+	  ah_stats,	NULL,		"ah",	1,	0},
 	{ -1,		N_ESPSTAT,	1,	NULL,
-	  esp_stats,	NULL,		"esp",	0,	0},
+	  esp_stats,	NULL,		"esp",	1,	0},
 	{ -1,		N_IPCOMPSTAT,	1,	NULL,
-	  ipcomp_stats,	NULL,		"ipcomp", 0,	0},
+	  ipcomp_stats,	NULL,		"ipcomp", 1,	0},
 #endif
 	{ N_RIPCBINFO,	N_PIMSTAT,	1,	protopr,
 	  pim_stats,	NULL,		"pim",	1,	IPPROTO_PIM },
 	{ -1,		N_CARPSTAT,	1,	NULL,
 	  carp_stats,	NULL,		"carp",	1,	0 },
+#ifdef PF
 	{ -1,		N_PFSYNCSTAT,	1,	NULL,
 	  pfsync_stats,	NULL,		"pfsync", 1,	0 },
+#endif
 	{ -1,		N_ARPSTAT,	1,	NULL,
 	  arp_stats,	NULL,		"arp", 1,	0 },
 	{ -1,		-1,		0,	NULL,
@@ -258,7 +242,7 @@
 #endif
 #ifdef IPSEC
 	{ -1,		N_IPSEC6STAT,	1,	NULL,
-	  ipsec_stats,	NULL,		"ipsec6", 0,	0 },
+	  ipsec_stats,	NULL,		"ipsec6", 1,	0 },
 #endif
 #ifdef notyet
 	{ -1,		N_PIM6STAT,	1,	NULL,
@@ -344,6 +328,7 @@
 static int pflag;	/* show given protocol */
 int	Qflag;		/* show netisr information */
 int	rflag;		/* show routing tables (or routing stats) */
+int	Rflag;		/* show flow / RSS statistics */
 int	sflag;		/* show protocol statistics */
 int	Wflag;		/* wide display */
 int	Tflag;		/* TCP Information */
@@ -363,12 +348,28 @@
 {
 	struct protox *tp = NULL;  /* for printing cblocks & stats */
 	int ch;
+	int fib = -1;
+	char *endptr;
 
 	af = AF_UNSPEC;
 
-	while ((ch = getopt(argc, argv, "AaBbdf:ghI:iLlM:mN:np:Qq:rSTsuWw:xz"))
+	while ((ch = getopt(argc, argv, "46AaBbdF:f:ghI:iLlM:mN:np:Qq:RrSTsuWw:xz"))
 	    != -1)
 		switch(ch) {
+		case '4':
+#ifdef INET
+			af = AF_INET;
+#else
+			errx(1, "IPv4 support is not compiled in");
+#endif
+			break;
+		case '6':
+#ifdef INET6
+			af = AF_INET6;
+#else
+			errx(1, "IPv6 support is not compiled in");
+#endif
+			break;
 		case 'A':
 			Aflag = 1;
 			break;
@@ -384,6 +385,12 @@
 		case 'd':
 			dflag = 1;
 			break;
+		case 'F':
+			fib = strtol(optarg, &endptr, 0);
+			if (*endptr != '\0' ||
+			    (fib == 0 && (errno == EINVAL || errno == ERANGE)))
+				errx(1, "%s: invalid fib", optarg);
+			break;
 		case 'f':
 			if (strcmp(optarg, "ipx") == 0)
 				af = AF_IPX;
@@ -464,6 +471,9 @@
 		case 'r':
 			rflag = 1;
 			break;
+		case 'R':
+			Rflag = 1;
+			break;
 		case 's':
 			++sflag;
 			break;
@@ -526,6 +536,9 @@
 	if (xflag && Tflag) 
 		errx(1, "-x and -T are incompatible, pick one.");
 
+	/* Load all necessary kvm symbols */
+	kresolve_list(nl);
+
 	if (Bflag) {
 		if (!live)
 			usage();
@@ -535,7 +548,7 @@
 	if (mflag) {
 		if (!live) {
 			if (kread(0, NULL, 0) == 0)
-				mbpr(kvmd, nl[N_MBSTAT].n_value);
+				mbpr(kvmd, nl[N_SFSTAT].n_value);
 		} else
 			mbpr(NULL, 0);
 		exit(0);
@@ -562,35 +575,33 @@
 	 * used for the queries, which is slower.
 	 */
 #endif
-	kread(0, NULL, 0);
 	if (iflag && !sflag) {
-		intpr(interval, nl[N_IFNET].n_value, NULL);
+		intpr(interval, NULL, af);
 		exit(0);
 	}
 	if (rflag) {
-		if (sflag)
-			rt_stats(nl[N_RTSTAT].n_value, nl[N_RTTRASH].n_value);
-		else
-			routepr(nl[N_RTREE].n_value);
+		if (sflag) {
+			rt_stats();
+			flowtable_stats();
+		} else
+			routepr(fib, af);
 		exit(0);
 	}
+
 	if (gflag) {
 		if (sflag) {
 			if (af == AF_INET || af == AF_UNSPEC)
-				mrt_stats(nl[N_MRTSTAT].n_value);
+				mrt_stats();
 #ifdef INET6
 			if (af == AF_INET6 || af == AF_UNSPEC)
-				mrt6_stats(nl[N_MRT6STAT].n_value);
+				mrt6_stats();
 #endif
 		} else {
 			if (af == AF_INET || af == AF_UNSPEC)
-				mroutepr(nl[N_MFCHASHTBL].n_value,
-					 nl[N_MFCTABLESIZE].n_value,
-					 nl[N_VIFTABLE].n_value);
+				mroutepr();
 #ifdef INET6
 			if (af == AF_INET6 || af == AF_UNSPEC)
-				mroute6pr(nl[N_MF6CTABLE].n_value,
-					  nl[N_MIF6TABLE].n_value);
+				mroute6pr();
 #endif
 		}
 		exit(0);
@@ -634,6 +645,29 @@
 	exit(0);
 }
 
+int
+fetch_stats(const char *sysctlname, u_long off, void *stats, size_t len,
+    int (*kreadfn)(u_long, void *, size_t))
+{
+	int error;
+
+	if (live) {
+		memset(stats, 0, len);
+		if (zflag)
+			error = sysctlbyname(sysctlname, NULL, NULL, stats,
+			    len);
+		else
+			error = sysctlbyname(sysctlname, stats, &len, NULL, 0);
+		if (error == -1 && errno != ENOENT)
+			warn("sysctl %s", sysctlname);
+	} else {
+		if (off == 0)
+			return (1);
+		error = kreadfn(off, stats, len);
+	}
+	return (error);
+}
+
 /*
  * Print out protocol statistics or control blocks (per sflag).
  * If the interface was not specifically requested, and the symbol
@@ -640,9 +674,7 @@
  * is not in the namelist, ignore this one.
  */
 static void
-printproto(tp, name)
-	struct protox *tp;
-	const char *name;
+printproto(struct protox *tp, const char *name)
 {
 	void (*pr)(u_long, const char *, int, int);
 	u_long off;
@@ -650,8 +682,7 @@
 	if (sflag) {
 		if (iflag) {
 			if (tp->pr_istats)
-				intpr(interval, nl[N_IFNET].n_value,
-				      tp->pr_istats);
+				intpr(interval, tp->pr_istats, af);
 			else if (pflag)
 				printf("%s: no per-interface stats routine\n",
 				    tp->pr_name);
@@ -698,37 +729,59 @@
 		(*pr)(off, name, af, tp->pr_protocol);
 }
 
+static int
+kvmd_init(void)
+{
+	char errbuf[_POSIX2_LINE_MAX];
+
+	if (kvmd != NULL)
+		return (0);
+
+	kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf);
+	setgid(getgid());
+
+	if (kvmd == NULL) {
+		warnx("kvm not available: %s", errbuf);
+		return (-1);
+	}
+
+	return (0);
+}
+
 /*
+ * Resolve symbol list, return 0 on success.
+ */
+int
+kresolve_list(struct nlist *_nl)
+{
+
+	if ((kvmd == NULL) && (kvmd_init() != 0))
+		return (-1);
+
+	if (_nl[0].n_type != 0)
+		return (0);
+
+	if (kvm_nlist(kvmd, _nl) < 0) {
+		if (nlistf)
+			errx(1, "%s: kvm_nlist: %s", nlistf,
+			     kvm_geterr(kvmd));
+		else
+			errx(1, "kvm_nlist: %s", kvm_geterr(kvmd));
+	}
+
+	return (0);
+}
+
+/*
  * Read kernel memory, return 0 on success.
  */
 int
 kread(u_long addr, void *buf, size_t size)
 {
-	char errbuf[_POSIX2_LINE_MAX];
 
-	if (kvmd == NULL) {
-		kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf);
-		setgid(getgid());
-		if (kvmd != NULL) {
-			if (kvm_nlist(kvmd, nl) < 0) {
-				if (nlistf)
-					errx(1, "%s: kvm_nlist: %s", nlistf,
-					     kvm_geterr(kvmd));
-				else
-					errx(1, "kvm_nlist: %s", kvm_geterr(kvmd));
-			}
+	if (kvmd_init() < 0)
+		return (-1);
 
-			if (nl[0].n_type == 0) {
-				if (nlistf)
-					errx(1, "%s: no namelist", nlistf);
-				else
-					errx(1, "no namelist");
-			}
-		} else {
-			warnx("kvm not available: %s", errbuf);
-			return(-1);
-		}
-	}
 	if (!buf)
 		return (0);
 	if (kvm_read(kvmd, addr, buf, size) != (ssize_t)size) {
@@ -738,6 +791,53 @@
 	return (0);
 }
 
+/*
+ * Read single counter(9).
+ */
+uint64_t
+kread_counter(u_long addr)
+{
+
+	if (kvmd_init() < 0)
+		return (-1);
+
+	return (kvm_counter_u64_fetch(kvmd, addr));
+}
+
+/*
+ * Read an array of N counters in kernel memory into array of N uint64_t's.
+ */
+int
+kread_counters(u_long addr, void *buf, size_t size)
+{
+	uint64_t *c;
+	u_long *counters;
+	size_t i, n;
+
+	if (kvmd_init() < 0)
+		return (-1);
+
+	if (size % sizeof(uint64_t) != 0) {
+		warnx("kread_counters: invalid counter set size");
+		return (-1);
+	}
+
+	n = size / sizeof(uint64_t);
+	if ((counters = malloc(n * sizeof(u_long))) == NULL)
+		err(-1, "malloc");
+	if (kread(addr, counters, n * sizeof(u_long)) < 0) {
+		free(counters);
+		return (-1);
+	}
+
+	c = buf;
+	for (i = 0; i < n; i++)
+		c[i] = kvm_counter_u64_fetch(kvmd, counters[i]);
+
+	free(counters);
+	return (0);
+}
+
 const char *
 plural(uintmax_t n)
 {
@@ -805,21 +905,21 @@
 usage(void)
 {
 	(void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
-"usage: netstat [-AaLnSTWx] [-f protocol_family | -p protocol]\n"
+"usage: netstat [-46AaLnRSTWx] [-f protocol_family | -p protocol]\n"
 "               [-M core] [-N system]",
-"       netstat -i | -I interface [-abdhnW] [-f address_family]\n"
+"       netstat -i | -I interface [-46abdhnW] [-f address_family]\n"
 "               [-M core] [-N system]",
-"       netstat -w wait [-I interface] [-d] [-M core] [-N system] [-q howmany]",
-"       netstat -s [-s] [-z] [-f protocol_family | -p protocol]\n"
+"       netstat -w wait [-I interface] [-46d] [-M core] [-N system] [-q howmany]",
+"       netstat -s [-s] [-46z] [-f protocol_family | -p protocol]\n"
 "               [-M core] [-N system]",
-"       netstat -i | -I interface -s [-f protocol_family | -p protocol]\n"
+"       netstat -i | -I interface [-46s] [-f protocol_family | -p protocol]\n"
 "               [-M core] [-N system]",
 "       netstat -m [-M core] [-N system]",
 "       netstat -B [-I interface]",
-"       netstat -r [-AanW] [-f address_family] [-M core] [-N system]",
+"       netstat -r [-46AanW] [-f address_family] [-M core] [-N system]",
 "       netstat -rs [-s] [-M core] [-N system]",
-"       netstat -g [-W] [-f address_family] [-M core] [-N system]",
-"       netstat -gs [-s] [-f address_family] [-M core] [-N system]",
+"       netstat -g [-46W] [-f address_family] [-M core] [-N system]",
+"       netstat -gs [-46s] [-f address_family] [-M core] [-N system]",
 "       netstat -Q");
 	exit(1);
 }

Modified: trunk/usr.bin/netstat/mbuf.c
===================================================================
--- trunk/usr.bin/netstat/mbuf.c	2018-07-07 16:54:14 UTC (rev 11466)
+++ trunk/usr.bin/netstat/mbuf.c	2018-07-07 16:54:32 UTC (rev 11467)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1983, 1988, 1993
  *	The Regents of the University of California.
@@ -40,11 +41,12 @@
 #endif
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/usr.bin/netstat/mbuf.c 293307 2016-01-07 07:21:37Z markj $");
 
 #include <sys/param.h>
 #include <sys/mbuf.h>
 #include <sys/protosw.h>
+#include <sys/sf_buf.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/sysctl.h>
@@ -68,20 +70,20 @@
 	struct memory_type *mtp;
 	uintmax_t mbuf_count, mbuf_bytes, mbuf_free, mbuf_failures, mbuf_size;
 	uintmax_t mbuf_sleeps;
-	uintmax_t cluster_count, cluster_bytes, cluster_limit, cluster_free;
+	uintmax_t cluster_count, cluster_limit, cluster_free;
 	uintmax_t cluster_failures, cluster_size, cluster_sleeps;
 	uintmax_t packet_count, packet_bytes, packet_free, packet_failures;
 	uintmax_t packet_sleeps;
-	uintmax_t tag_count, tag_bytes;
-	uintmax_t jumbop_count, jumbop_bytes, jumbop_limit, jumbop_free;
+	uintmax_t tag_bytes;
+	uintmax_t jumbop_count, jumbop_limit, jumbop_free;
 	uintmax_t jumbop_failures, jumbop_sleeps, jumbop_size;
-	uintmax_t jumbo9_count, jumbo9_bytes, jumbo9_limit, jumbo9_free;
+	uintmax_t jumbo9_count, jumbo9_limit, jumbo9_free;
 	uintmax_t jumbo9_failures, jumbo9_sleeps, jumbo9_size;
-	uintmax_t jumbo16_count, jumbo16_bytes, jumbo16_limit, jumbo16_free;
+	uintmax_t jumbo16_count, jumbo16_limit, jumbo16_free;
 	uintmax_t jumbo16_failures, jumbo16_sleeps, jumbo16_size;
 	uintmax_t bytes_inuse, bytes_incache, bytes_total;
 	int nsfbufs, nsfbufspeak, nsfbufsused;
-	struct mbstat mbstat;
+	struct sfstat sfstat;
 	size_t mlen;
 	int error;
 
@@ -145,7 +147,6 @@
 		goto out;
 	}
 	cluster_count = memstat_get_count(mtp);
-	cluster_bytes = memstat_get_bytes(mtp);
 	cluster_limit = memstat_get_countlimit(mtp);
 	cluster_free = memstat_get_free(mtp);
 	cluster_failures = memstat_get_failures(mtp);
@@ -158,7 +159,6 @@
 		    MBUF_TAG_MEM_NAME);
 		goto out;
 	}
-	tag_count = memstat_get_count(mtp);
 	tag_bytes = memstat_get_bytes(mtp);
 
 	mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_JUMBOP_MEM_NAME);
@@ -168,7 +168,6 @@
 		goto out;
 	}
 	jumbop_count = memstat_get_count(mtp);
-	jumbop_bytes = memstat_get_bytes(mtp);
 	jumbop_limit = memstat_get_countlimit(mtp);
 	jumbop_free = memstat_get_free(mtp);
 	jumbop_failures = memstat_get_failures(mtp);
@@ -182,7 +181,6 @@
 		goto out;
 	}
 	jumbo9_count = memstat_get_count(mtp);
-	jumbo9_bytes = memstat_get_bytes(mtp);
 	jumbo9_limit = memstat_get_countlimit(mtp);
 	jumbo9_free = memstat_get_free(mtp);
 	jumbo9_failures = memstat_get_failures(mtp);
@@ -196,7 +194,6 @@
 		goto out;
 	}
 	jumbo16_count = memstat_get_count(mtp);
-	jumbo16_bytes = memstat_get_bytes(mtp);
 	jumbo16_limit = memstat_get_countlimit(mtp);
 	jumbo16_free = memstat_get_free(mtp);
 	jumbo16_failures = memstat_get_failures(mtp);
@@ -298,30 +295,26 @@
 	    "(%juk/9k/16k)\n", jumbop_failures, jumbo9_failures,
 	    jumbo16_failures, jumbop_size / 1024);
 
-	if (live) {
-		mlen = sizeof(nsfbufs);
-		if (!sysctlbyname("kern.ipc.nsfbufs", &nsfbufs, &mlen, NULL,
-		    0) &&
-		    !sysctlbyname("kern.ipc.nsfbufsused", &nsfbufsused,
-		    &mlen, NULL, 0) &&
-		    !sysctlbyname("kern.ipc.nsfbufspeak", &nsfbufspeak,
-		    &mlen, NULL, 0))
-			printf("%d/%d/%d sfbufs in use (current/peak/max)\n",
-			    nsfbufsused, nsfbufspeak, nsfbufs);
-		mlen = sizeof(mbstat);
-		if (sysctlbyname("kern.ipc.mbstat", &mbstat, &mlen, NULL, 0)) {
-			warn("kern.ipc.mbstat");
-			goto out;
-		}
-	} else {
-		if (kread(mbaddr, (char *)&mbstat, sizeof mbstat) != 0)
-			goto out;
-	}
-	printf("%lu requests for sfbufs denied\n", mbstat.sf_allocfail);
-	printf("%lu requests for sfbufs delayed\n", mbstat.sf_allocwait);
-	printf("%lu requests for I/O initiated by sendfile\n",
-	    mbstat.sf_iocnt);
-	printf("%lu calls to protocol drain routines\n", mbstat.m_drain);
+	mlen = sizeof(nsfbufs);
+	if (live &&
+	    sysctlbyname("kern.ipc.nsfbufs", &nsfbufs, &mlen, NULL, 0) == 0 &&
+	    sysctlbyname("kern.ipc.nsfbufsused", &nsfbufsused, &mlen,
+	    NULL, 0) == 0 &&
+	    sysctlbyname("kern.ipc.nsfbufspeak", &nsfbufspeak, &mlen,
+	    NULL, 0) == 0)
+		printf("%d/%d/%d sfbufs in use (current/peak/max)\n",
+		    nsfbufsused, nsfbufspeak, nsfbufs);
+
+	if (fetch_stats("kern.ipc.sfstat", mbaddr, &sfstat, sizeof(sfstat),
+	    kread_counters) != 0)
+		goto out;
+
+	printf("%ju requests for sfbufs denied\n",
+	    (uintmax_t)sfstat.sf_allocfail);
+	printf("%ju requests for sfbufs delayed\n",
+	    (uintmax_t)sfstat.sf_allocwait);
+	printf("%ju requests for I/O initiated by sendfile\n",
+	    (uintmax_t)sfstat.sf_iocnt);
 out:
 	memstat_mtl_free(mtlp);
 }

Modified: trunk/usr.bin/netstat/mroute.c
===================================================================
--- trunk/usr.bin/netstat/mroute.c	2018-07-07 16:54:14 UTC (rev 11466)
+++ trunk/usr.bin/netstat/mroute.c	2018-07-07 16:54:32 UTC (rev 11467)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1989 Stephen Deering
  * Copyright (c) 1992, 1993
@@ -38,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/usr.bin/netstat/mroute.c 293307 2016-01-07 07:21:37Z markj $");
 
 /*
  * Print multicast routing structures and statistics.
@@ -65,11 +66,26 @@
 #undef _KERNEL
 
 #include <err.h>
+#include <nlist.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include "netstat.h"
 
+/*
+ * kvm(3) bindings for every needed symbol
+ */
+static struct nlist mrl[] = {
+#define	N_MRTSTAT	0
+	{ .n_name = "_mrtstat" },
+#define	N_MFCHASHTBL	1
+	{ .n_name = "_mfchashtbl" },
+#define	N_VIFTABLE	2
+	{ .n_name = "_viftable" },
+#define	N_MFCTABLESIZE	3
+	{ .n_name = "_mfctablesize" },
+	{ .n_name = NULL },
+};
 
 static void	print_bw_meter(struct bw_meter *, int *);
 static void	print_mfc(struct mfc *, int, int *);
@@ -193,11 +209,12 @@
 }
 
 void
-mroutepr(u_long pmfchashtbl, u_long pmfctablesize, u_long pviftbl)
+mroutepr()
 {
 	struct vif viftable[MAXVIFS];
 	struct vif *v;
 	struct mfc *m;
+	u_long pmfchashtbl, pmfctablesize, pviftbl;
 	int banner_printed;
 	int saved_numeric_addr;
 	size_t len;
@@ -220,6 +237,7 @@
 	 * functionality was deprecated, as PIM does not use it.
 	 */
 	maxvif = 0;
+	pmfchashtbl = pmfctablesize = pviftbl = 0;
 
 	len = sizeof(viftable);
 	if (live) {
@@ -228,8 +246,19 @@
 			warn("sysctl: net.inet.ip.viftable");
 			return;
 		}
-	} else
+	} else {
+		kresolve_list(mrl);
+		pmfchashtbl = mrl[N_MFCHASHTBL].n_value;
+		pmfctablesize = mrl[N_MFCTABLESIZE].n_value;
+		pviftbl = mrl[N_VIFTABLE].n_value;
+
+		if (pmfchashtbl == 0 || pmfctablesize == 0 || pviftbl == 0) {
+			fprintf(stderr, "No IPv4 MROUTING kernel support.\n");
+			return;
+		}
+
 		kread(pviftbl, (char *)viftable, sizeof(viftable));
+	}
 
 	banner_printed = 0;
 	for (vifi = 0, v = viftable; vifi < MAXVIFS; ++vifi, ++v) {
@@ -338,41 +367,44 @@
 }
 
 void
-mrt_stats(u_long mstaddr)
+mrt_stats()
 {
 	struct mrtstat mrtstat;
-	size_t len = sizeof mrtstat;
+	u_long mstaddr;
 
-	if (live) {
-		if (sysctlbyname("net.inet.ip.mrtstat", &mrtstat, &len, NULL,
-		    0) < 0) {
-			warn("sysctl: net.inet.ip.mrtstat");
-			return;
-		}
-	} else
-		kread(mstaddr, (char *)&mrtstat, sizeof(mrtstat));
+	kresolve_list(mrl);
+	mstaddr = mrl[N_MRTSTAT].n_value;
 
+	if (mstaddr == 0) {
+		fprintf(stderr, "No IPv4 MROUTING kernel support.\n");
+		return;
+	}
+
+	if (fetch_stats("net.inet.ip.mrtstat", mstaddr, &mrtstat,
+	    sizeof(mrtstat), kread_counters) != 0)
+		return;
+
 	printf("IPv4 multicast forwarding:\n");
 
 #define	p(f, m) if (mrtstat.f || sflag <= 1) \
-	printf(m, mrtstat.f, plural(mrtstat.f))
+	printf(m, (uintmax_t)mrtstat.f, plural(mrtstat.f))
 #define	p2(f, m) if (mrtstat.f || sflag <= 1) \
-	printf(m, mrtstat.f, plurales(mrtstat.f))
+	printf(m, (uintmax_t)mrtstat.f, plurales(mrtstat.f))
 
-	p(mrts_mfc_lookups, "\t%lu multicast forwarding cache lookup%s\n");
-	p2(mrts_mfc_misses, "\t%lu multicast forwarding cache miss%s\n");
-	p(mrts_upcalls, "\t%lu upcall%s to multicast routing daemon\n");
-	p(mrts_upq_ovflw, "\t%lu upcall queue overflow%s\n");
+	p(mrts_mfc_lookups, "\t%ju multicast forwarding cache lookup%s\n");
+	p2(mrts_mfc_misses, "\t%ju multicast forwarding cache miss%s\n");
+	p(mrts_upcalls, "\t%ju upcall%s to multicast routing daemon\n");
+	p(mrts_upq_ovflw, "\t%ju upcall queue overflow%s\n");
 	p(mrts_upq_sockfull,
-	    "\t%lu upcall%s dropped due to full socket buffer\n");
-	p(mrts_cache_cleanups, "\t%lu cache cleanup%s\n");
-	p(mrts_no_route, "\t%lu datagram%s with no route for origin\n");
-	p(mrts_bad_tunnel, "\t%lu datagram%s arrived with bad tunneling\n");
-	p(mrts_cant_tunnel, "\t%lu datagram%s could not be tunneled\n");
-	p(mrts_wrong_if, "\t%lu datagram%s arrived on wrong interface\n");
-	p(mrts_drop_sel, "\t%lu datagram%s selectively dropped\n");
-	p(mrts_q_overflow, "\t%lu datagram%s dropped due to queue overflow\n");
-	p(mrts_pkt2large, "\t%lu datagram%s dropped for being too large\n");
+	    "\t%ju upcall%s dropped due to full socket buffer\n");
+	p(mrts_cache_cleanups, "\t%ju cache cleanup%s\n");
+	p(mrts_no_route, "\t%ju datagram%s with no route for origin\n");
+	p(mrts_bad_tunnel, "\t%ju datagram%s arrived with bad tunneling\n");
+	p(mrts_cant_tunnel, "\t%ju datagram%s could not be tunneled\n");
+	p(mrts_wrong_if, "\t%ju datagram%s arrived on wrong interface\n");
+	p(mrts_drop_sel, "\t%ju datagram%s selectively dropped\n");
+	p(mrts_q_overflow, "\t%ju datagram%s dropped due to queue overflow\n");
+	p(mrts_pkt2large, "\t%ju datagram%s dropped for being too large\n");
 
 #undef	p2
 #undef	p

Modified: trunk/usr.bin/netstat/mroute6.c
===================================================================
--- trunk/usr.bin/netstat/mroute6.c	2018-07-07 16:54:14 UTC (rev 11466)
+++ trunk/usr.bin/netstat/mroute6.c	2018-07-07 16:54:32 UTC (rev 11467)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (C) 1998 WIDE Project.
  * All rights reserved.
@@ -66,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/usr.bin/netstat/mroute6.c 293307 2016-01-07 07:21:37Z markj $");
 
 #ifdef INET6
 #include <sys/param.h>
@@ -85,6 +86,7 @@
 #include <netinet/in.h>
 
 #include <err.h>
+#include <nlist.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -95,11 +97,25 @@
 
 #include "netstat.h"
 
+/*
+ * kvm(3) bindings for every needed symbol
+ */
+static struct nlist mrl[] = {
+#define	N_MF6CTABLE	0
+	{ .n_name = "_mf6ctable" },
+#define	N_MIF6TABLE	1
+	{ .n_name = "_mif6table" },
+#define	N_MRT6STAT	2
+	{ .n_name = "_mrt6stat" },
+	{ .n_name = NULL },
+};
+
+
 #define	WID_ORG	(Wflag ? 39 : (numeric_addr ? 29 : 18)) /* width of origin column */
 #define	WID_GRP	(Wflag ? 18 : (numeric_addr ? 16 : 18)) /* width of group column */
 
 void
-mroute6pr(u_long mfcaddr, u_long mifaddr)
+mroute6pr()
 {
 	struct mf6c *mf6ctable[MF6CTBLSIZ], *mfcp;
 	struct mif6 mif6table[MAXMIFS];
@@ -106,6 +122,7 @@
 	struct mf6c mfc;
 	struct rtdetq rte, *rtep;
 	struct mif6 *mifp;
+	u_long mfcaddr, mifaddr;
 	mifi_t mifi;
 	int i;
 	int banner_printed;
@@ -114,6 +131,15 @@
 	long int waitings;
 	size_t len;
 
+	kresolve_list(mrl);
+	mfcaddr = mrl[N_MF6CTABLE].n_value;
+	mifaddr = mrl[N_MIF6TABLE].n_value;
+
+	if (mfcaddr == 0 || mifaddr == 0) {
+		fprintf(stderr, "No IPv6 MROUTING kernel support.\n");
+		return;
+	}
+
 	len = sizeof(mif6table);
 	if (live) {
 		if (sysctlbyname("net.inet6.ip6.mif6table", mif6table, &len,
@@ -217,20 +243,22 @@
 }
 
 void
-mrt6_stats(u_long mstaddr)
+mrt6_stats()
 {
 	struct mrt6stat mrtstat;
-	size_t len = sizeof mrtstat;
+	u_long mstaddr;
 
-	if (live) {
-		if (sysctlbyname("net.inet6.ip6.mrt6stat", &mrtstat, &len,
-		    NULL, 0) < 0) {
-			warn("sysctl: net.inet6.ip6.mrt6stat");
-			return;
-		}
-	} else
-		kread(mstaddr, (char *)&mrtstat, sizeof(mrtstat));
+	kresolve_list(mrl);
+	mstaddr = mrl[N_MRT6STAT].n_value;
 
+	if (mstaddr == 0) {
+		fprintf(stderr, "No IPv6 MROUTING kernel support.\n");
+		return;
+	}
+	if (fetch_stats("net.inet6.ip6.mrt6stat", 0, &mrtstat,
+	    sizeof(mrtstat), kread_counters) != 0)
+		return;
+
 	printf("IPv6 multicast forwarding:\n");
 
 #define	p(f, m) if (mrtstat.f || sflag <= 1) \

Modified: trunk/usr.bin/netstat/netgraph.c
===================================================================
--- trunk/usr.bin/netstat/netgraph.c	2018-07-07 16:54:14 UTC (rev 11466)
+++ trunk/usr.bin/netstat/netgraph.c	2018-07-07 16:54:32 UTC (rev 11467)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1996-1999 Whistle Communications, Inc.
  * All rights reserved.
@@ -33,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/usr.bin/netstat/netgraph.c 263335 2014-03-19 09:36:29Z glebius $");
 
 #include <sys/param.h>
 #include <sys/queue.h>
@@ -67,59 +68,15 @@
 {
 	struct ngpcb *this, *next;
 	struct ngpcb ngpcb;
-	struct ngsock info;
 	struct socket sockb;
 	int debug = 1;
 
 	/* If symbol not found, try looking in the KLD module */
 	if (off == 0) {
-		const char *const modname = "ng_socket.ko";
-/* XXX We should get "mpath" from "sysctl kern.module_path" */
-		const char *mpath[] = { "/", "/boot/", "/modules/", NULL };
-		struct nlist sym[] = { { .n_name = "_ngsocklist" },
-				       { .n_name = NULL } };
-		const char **pre;
-		struct kld_file_stat ks;
-		int fileid;
-
-		/* Can't do this for core dumps. */
-		if (!live)
-			return;
-
-		/* See if module is loaded */
-		if ((fileid = kldfind(modname)) < 0) {
-			if (debug)
-				warn("kldfind(%s)", modname);
-			return;
-		}
-
-		/* Get module info */
-		memset(&ks, 0, sizeof(ks));
-		ks.version = sizeof(struct kld_file_stat);
-		if (kldstat(fileid, &ks) < 0) {
-			if (debug)
-				warn("kldstat(%d)", fileid);
-			return;
-		}
-
-		/* Get symbol table from module file */
-		for (pre = mpath; *pre; pre++) {
-			char path[MAXPATHLEN];
-
-			snprintf(path, sizeof(path), "%s%s", *pre, modname);
-			if (nlist(path, sym) == 0)
-				break;
-		}
-
-		/* Did we find it? */
-		if (sym[0].n_value == 0) {
-			if (debug)
-				warnx("%s not found", modname);
-			return;
-		}
-
-		/* Symbol found at load address plus symbol offset */
-		off = (u_long) ks.address + sym[0].n_value;
+		if (debug)
+			fprintf(stderr,
+			    "Error reading symbols from ng_socket.ko");
+		return;
 	}
 
 	/* Get pointer to first socket */
@@ -165,15 +122,10 @@
 		printf("%-5.5s %6u %6u ",
 		    name, sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc);
 
-		/* Get ngsock structure */
-		if (ngpcb.sockdata == NULL)	/* unconnected data socket */
-			goto finish;
-		kread((u_long)ngpcb.sockdata, (char *)&info, sizeof(info));
-
 		/* Get info on associated node */
-		if (info.node_id == 0 || csock == -1)
+		if (ngpcb.node_id == 0 || csock == -1)
 			goto finish;
-		snprintf(path, sizeof(path), "[%x]:", info.node_id);
+		snprintf(path, sizeof(path), "[%x]:", ngpcb.node_id);
 		if (NgSendMsg(csock, path,
 		    NGM_GENERIC_COOKIE, NGM_NODEINFO, NULL, 0) < 0)
 			goto finish;

Modified: trunk/usr.bin/netstat/netisr.c
===================================================================
--- trunk/usr.bin/netstat/netisr.c	2018-07-07 16:54:14 UTC (rev 11466)
+++ trunk/usr.bin/netstat/netisr.c	2018-07-07 16:54:32 UTC (rev 11467)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2010-2011 Juniper Networks, Inc.
  * All rights reserved.
@@ -29,7 +30,7 @@
 
 #include <sys/cdefs.h>
 
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/usr.bin/netstat/netisr.c 246988 2013-02-19 13:17:16Z charnier $");
 
 #include <sys/param.h>
 #include <sys/sysctl.h>
@@ -76,12 +77,12 @@
 static u_int				 maxprot;
 
 static void
-netisr_dispatch_policy_to_string(u_int dispatch_policy, char *buf,
+netisr_dispatch_policy_to_string(u_int policy, char *buf,
     size_t buflen)
 {
 	const char *str;
 
-	switch (dispatch_policy) {
+	switch (policy) {
 	case NETISR_DISPATCH_DEFAULT:
 		str = "default";
 		break;
@@ -102,7 +103,7 @@
 }
 
 static void
-netisr_load_kvm_uint(kvm_t *kd, char *name, u_int *p)
+netisr_load_kvm_uint(kvm_t *kd, const char *name, u_int *p)
 {
 	struct nlist nl[] = {
 		{ .n_name = name },

Modified: trunk/usr.bin/netstat/netstat.1
===================================================================
--- trunk/usr.bin/netstat/netstat.1	2018-07-07 16:54:14 UTC (rev 11466)
+++ trunk/usr.bin/netstat/netstat.1	2018-07-07 16:54:32 UTC (rev 11467)
@@ -1,3 +1,4 @@
+.\" $MidnightBSD$
 .\" Copyright (c) 1983, 1990, 1992, 1993
 .\"	The Regents of the University of California.  All rights reserved.
 .\"
@@ -26,9 +27,9 @@
 .\" SUCH DAMAGE.
 .\"
 .\"	@(#)netstat.1	8.8 (Berkeley) 4/18/94
-.\" $MidnightBSD$
+.\" $FreeBSD: stable/10/usr.bin/netstat/netstat.1 265701 2014-05-08 19:35:12Z melifaro $
 .\"
-.Dd March 10, 2013
+.Dd January 11, 2014
 .Dt NETSTAT 1
 .Os
 .Sh NAME
@@ -45,7 +46,7 @@
 .It Xo
 .Bk -words
 .Nm
-.Op Fl AaLnSTWx
+.Op Fl 46AaLnSTWx
 .Op Fl f Ar protocol_family | Fl p Ar protocol
 .Op Fl M Ar core
 .Op Fl N Ar system
@@ -92,10 +93,8 @@
 .Bk -words
 .Nm
 .Fl i | I Ar interface
-.Op Fl abdhnW
+.Op Fl 46abdhnW
 .Op Fl f Ar address_family
-.Op Fl M Ar core
-.Op Fl N Ar system
 .Ek
 .Xc
 Show the state of all network interfaces or a single
@@ -155,7 +154,7 @@
 .Bk -words
 .Nm
 .Fl s Op Fl s
-.Op Fl z
+.Op Fl 46z
 .Op Fl f Ar protocol_family | Fl p Ar protocol
 .Op Fl M Ar core
 .Op Fl N Ar system
@@ -176,6 +175,7 @@
 .Bk -words
 .Nm
 .Fl i | I Ar interface Fl s
+.Op Fl 46
 .Op Fl f Ar protocol_family | Fl p Ar protocol
 .Op Fl M Ar core
 .Op Fl N Ar system
@@ -216,28 +216,35 @@
 .Bk -words
 .Nm
 .Fl r
-.Op Fl AanW
+.Op Fl 46AanW
+.Op Fl F Ar fibnum
 .Op Fl f Ar address_family
 .Op Fl M Ar core
 .Op Fl N Ar system
 .Ek
 .Xc
-Display the contents of all routing tables,
-or a routing table for a particular
-.Ar address_family .
+Display the contents of routing tables.
+When
+.Fl f
+is specified, a routing table for a particular
+.Ar address_family
+is displayed.
+When
+.Fl F
+is specified, a routing table with the number
+.Ar fibnum
+is displayed.
+If the specified
+.Ar fibnum
+is -1 or
+.Fl F
+is not specified,
+the default routing table is displayed.
 If
 .Fl A
 is also present,
 show the contents of the internal Patricia tree
 structures; used for debugging.
-If
-.Fl a
-is also present,
-show protocol-cloned routes
-(routes generated by an
-.Dv RTF_PRCLONING
-parent route);
-normally these routes are not shown.
 When
 .Fl W
 is also present,
@@ -263,7 +270,7 @@
 .Bk -words
 .Nm
 .Fl g
-.Op Fl W
+.Op Fl 46W
 .Op Fl f Ar address_family
 .Op Fl M Ar core
 .Op Fl N Ar system
@@ -282,7 +289,7 @@
 .Bk -words
 .Nm
 .Fl gs
-.Op Fl s
+.Op Fl 46s
 .Op Fl f Ar address_family
 .Op Fl M Ar core
 .Op Fl N Ar system
@@ -307,9 +314,18 @@
 .It Li D Ta Dv NETISR_SNP_FLAGS_DRAINEDCPU  Ta "Has queue drain handler"
 .It Li F Ta Dv NETISR_SNP_FLAGS_M2FLOW Ta "Able to map mbuf to flow id"
 .El
+.El
 .Pp
 Some options have the general meaning:
 .Bl -tag -width flag
+.It Fl 4
+Is shorthand for
+.Fl f
+.Ar inet
+.It Fl 6
+Is shorthand for
+.Fl f
+.Ar inet6
 .It Fl f Ar address_family , Fl p Ar protocol
 Limit display to those records
 of the specified
@@ -416,8 +432,6 @@
 .It Li 3 Ta Dv RTF_PROTO3 Ta "Protocol specific routing flag #3"
 .It Li B Ta Dv RTF_BLACKHOLE Ta "Just discard pkts (during updates)"
 .It Li b Ta Dv RTF_BROADCAST Ta "The route represents a broadcast address"
-.It Li C Ta Dv RTF_CLONING Ta "Generate new routes on use"
-.It Li c Ta Dv RTF_PRCLONING Ta "Protocol-specified generate new routes on use"
 .It Li D Ta Dv RTF_DYNAMIC Ta "Created dynamically (by redirect)"
 .It Li G Ta Dv RTF_GATEWAY Ta "Destination requires forwarding by intermediary"
 .It Li H Ta Dv RTF_HOST Ta "Host entry (net otherwise)"
@@ -426,7 +440,6 @@
 .It Li R Ta Dv RTF_REJECT Ta "Host or net unreachable"
 .It Li S Ta Dv RTF_STATIC Ta "Manually added"
 .It Li U Ta Dv RTF_UP Ta "Route usable"
-.It Li W Ta Dv RTF_WASCLONED Ta "Route was generated as a result of cloning"
 .It Li X Ta Dv RTF_XRESOLVE Ta "External daemon translates proto to link address"
 .El
 .Pp


Property changes on: trunk/usr.bin/netstat/netstat.1
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Modified: trunk/usr.bin/netstat/netstat.h
===================================================================
--- trunk/usr.bin/netstat/netstat.h	2018-07-07 16:54:14 UTC (rev 11466)
+++ trunk/usr.bin/netstat/netstat.h	2018-07-07 16:54:32 UTC (rev 11467)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1992, 1993
  *	Regents of the University of California.  All rights reserved.
@@ -27,7 +28,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)netstat.h	8.2 (Berkeley) 1/4/94
- * $MidnightBSD$
+ * $FreeBSD: stable/10/usr.bin/netstat/netstat.h 293307 2016-01-07 07:21:37Z markj $
  */
 
 #include <sys/cdefs.h>
@@ -45,6 +46,7 @@
 extern int	numeric_addr;	/* show addresses numerically */
 extern int	numeric_port;	/* show ports numerically */
 extern int	rflag;	/* show routing tables (or routing stats) */
+extern int	Rflag;	/* show flowid / RSS information */
 extern int	sflag;	/* show protocol statistics */
 extern int	Tflag;  /* show TCP control block info */
 extern int	Wflag;	/* wide display */
@@ -56,10 +58,15 @@
 extern char	*interface; /* desired i/f for stats, or NULL for all i/fs */
 extern int	unit;	/* unit number for above */
 
-extern int	af;	/* address family */
 extern int	live;	/* true if we are examining a live system */
 
+struct nlist;
+int	fetch_stats(const char *sysctlname, u_long addr, void *stats,
+	    size_t len, int (*kreadfn)(u_long, void *, size_t));
 int	kread(u_long addr, void *buf, size_t size);
+uint64_t kread_counter(u_long addr);
+int	kread_counters(u_long addr, void *buf, size_t size);
+int	kresolve_list(struct nlist *);
 const char *plural(uintmax_t);
 const char *plurales(uintmax_t);
 const char *pluralies(uintmax_t);
@@ -96,8 +103,8 @@
 void	icmp6_ifstats(char *);
 void	pim6_stats(u_long, const char *, int, int);
 void	rip6_stats(u_long, const char *, int, int);
-void	mroute6pr(u_long, u_long);
-void	mrt6_stats(u_long);
+void	mroute6pr(void);
+void	mrt6_stats(void);
 
 struct sockaddr_in6;
 struct in6_addr;
@@ -118,11 +125,12 @@
 void	hostpr(u_long, u_long);
 void	impstats(u_long, u_long);
 
-void	intpr(int, u_long, void (*)(char *));
+void	intpr(int, void (*)(char *), int);
 
 void	pr_rthdr(int);
 void	pr_family(int);
-void	rt_stats(u_long, u_long);
+void	rt_stats(void);
+void	flowtable_stats(void);
 char	*ipx_pnet(struct sockaddr *);
 char	*ipx_phost(struct sockaddr *);
 char	*ns_phost(struct sockaddr *);
@@ -129,12 +137,12 @@
 void	upHex(char *);
 
 char	*routename(in_addr_t);
-char	*netname(in_addr_t, u_long);
+char	*netname(in_addr_t, in_addr_t);
 char	*atalk_print(struct sockaddr *, int);
 char	*atalk_print2(struct sockaddr *, struct sockaddr *, int);
 char	*ipx_print(struct sockaddr *);
 char	*ns_print(struct sockaddr *);
-void	routepr(u_long);
+void	routepr(int, int);
 
 void	ipxprotopr(u_long, const char *, int, int);
 void	spx_stats(u_long, const char *, int, int);
@@ -164,6 +172,6 @@
 void	tp_inproto(u_long);
 void	tp_stats(caddr_t, caddr_t);
 
-void	mroutepr(u_long, u_long, u_long);
-void	mrt_stats(u_long);
+void	mroutepr(void);
+void	mrt_stats(void);
 void	bpf_stats(char *);

Modified: trunk/usr.bin/netstat/pfkey.c
===================================================================
--- trunk/usr.bin/netstat/pfkey.c	2018-07-07 16:54:14 UTC (rev 11466)
+++ trunk/usr.bin/netstat/pfkey.c	2018-07-07 16:54:32 UTC (rev 11467)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*	$NetBSD: inet.c,v 1.35.2.1 1999/04/29 14:57:08 perry Exp $	*/
 /*	$KAME: ipsec.c,v 1.25 2001/03/12 09:04:39 itojun Exp $	*/
 /*-
@@ -64,7 +65,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/usr.bin/netstat/pfkey.c 253088 2013-07-09 10:08:13Z ae $");
 
 #include <sys/param.h>
 #include <sys/queue.h>
@@ -119,7 +120,7 @@
 	if (off == 0)
 		return;
 	printf ("%s:\n", name);
-	kread(off, (char *)&pfkeystat, sizeof(pfkeystat));
+	kread_counters(off, (char *)&pfkeystat, sizeof(pfkeystat));
 
 #define	p(f, m) if (pfkeystat.f || sflag <= 1) \
     printf(m, (uintmax_t)pfkeystat.f, plural(pfkeystat.f))

Modified: trunk/usr.bin/netstat/route.c
===================================================================
--- trunk/usr.bin/netstat/route.c	2018-07-07 16:54:14 UTC (rev 11466)
+++ trunk/usr.bin/netstat/route.c	2018-07-07 16:54:32 UTC (rev 11467)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1983, 1988, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -34,7 +35,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/usr.bin/netstat/route.c 291381 2015-11-27 03:48:02Z ume $");
 
 #include <sys/param.h>
 #include <sys/protosw.h>
@@ -48,6 +49,7 @@
 #include <net/if_dl.h>
 #include <net/if_types.h>
 #include <net/radix.h>
+#define	_WANT_RTENTRY
 #include <net/route.h>
 
 #include <netinet/in.h>
@@ -58,8 +60,10 @@
 #include <sys/sysctl.h>
 
 #include <arpa/inet.h>
+#include <ifaddrs.h>
 #include <libutil.h>
 #include <netdb.h>
+#include <nlist.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -89,7 +93,6 @@
 	{ RTF_STATIC,	'S' },
 	{ RTF_PROTO1,	'1' },
 	{ RTF_PROTO2,	'2' },
-	{ RTF_PRCLONING,'c' },
 	{ RTF_PROTO3,	'3' },
 	{ RTF_BLACKHOLE,'B' },
 	{ RTF_BROADCAST,'b' },
@@ -96,15 +99,22 @@
 #ifdef RTF_LLINFO
 	{ RTF_LLINFO,	'L' },
 #endif
-#ifdef RTF_WASCLONED
-	{ RTF_WASCLONED,'W' },
-#endif
-#ifdef RTF_CLONING
-	{ RTF_CLONING,	'C' },
-#endif
 	{ 0 , 0 }
 };
 
+/*
+ * kvm(3) bindings for every needed symbol
+ */
+static struct nlist rl[] = {
+#define	N_RTSTAT	0
+	{ .n_name = "_rtstat" },
+#define	N_RTREE		1
+	{ .n_name = "_rt_tables"},
+#define	N_RTTRASH	2
+	{ .n_name = "_rttrash" },
+	{ .n_name = NULL },
+};
+
 typedef union {
 	long	dummy;		/* Helps align structure. */
 	struct	sockaddr u_sa;
@@ -113,13 +123,19 @@
 
 static sa_u pt_u;
 
+struct ifmap_entry {
+	char ifname[IFNAMSIZ];
+};
+
+static struct ifmap_entry *ifmap;
+static int ifmap_size;
+
 int	do_rtent = 0;
 struct	rtentry rtentry;
 struct	radix_node rnode;
 struct	radix_mask rmask;
-struct	radix_node_head **rt_tables;
 
-int	NewTree = 0;
+int	NewTree = 1;
 
 struct	timespec uptime;
 
@@ -127,16 +143,17 @@
 static void size_cols(int ef, struct radix_node *rn);
 static void size_cols_tree(struct radix_node *rn);
 static void size_cols_rtentry(struct rtentry *rt);
-static void p_tree(struct radix_node *);
-static void p_rtnode(void);
-static void ntreestuff(void);
-static void np_rtentry(struct rt_msghdr *);
+static void p_rtnode_kvm(void);
+static void p_rtable_sysctl(int, int);
+static void p_rtable_kvm(int, int );
+static void p_rtree_kvm(struct radix_node *);
+static void p_rtentry_sysctl(struct rt_msghdr *);
 static void p_sockaddr(struct sockaddr *, struct sockaddr *, int, int);
 static const char *fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask,
     int flags);
 static void p_flags(int, const char *);
 static const char *fmt_flags(int f);
-static void p_rtentry(struct rtentry *);
+static void p_rtentry_kvm(struct rtentry *);
 static void domask(char *, in_addr_t, u_long);
 
 /*
@@ -143,80 +160,39 @@
  * Print routing tables.
  */
 void
-routepr(u_long rtree)
+routepr(int fibnum, int af)
 {
-	struct radix_node_head **rnhp, *rnh, head;
 	size_t intsize;
-	int fam, fibnum, numfibs;
+	int numfibs;
 
 	intsize = sizeof(int);
-	if (sysctlbyname("net.my_fibnum", &fibnum, &intsize, NULL, 0) == -1)
+	if (fibnum == -1 &&
+	    sysctlbyname("net.my_fibnum", &fibnum, &intsize, NULL, 0) == -1)
 		fibnum = 0;
 	if (sysctlbyname("net.fibs", &numfibs, &intsize, NULL, 0) == -1)
 		numfibs = 1;
-	rt_tables = calloc(numfibs * (AF_MAX+1),
-	    sizeof(struct radix_node_head *));
-	if (rt_tables == NULL)
-		err(EX_OSERR, "memory allocation failed");
+	if (fibnum < 0 || fibnum > numfibs - 1)
+		errx(EX_USAGE, "%d: invalid fib", fibnum);
 	/*
 	 * Since kernel & userland use different timebase
 	 * (time_uptime vs time_second) and we are reading kernel memory
-	 * directly we should do rt_rmx.rmx_expire --> expire_time conversion.
+	 * directly we should do rt_expire --> expire_time conversion.
 	 */
 	if (clock_gettime(CLOCK_UPTIME, &uptime) < 0)
 		err(EX_OSERR, "clock_gettime() failed");
 
-	printf("Routing tables\n");
+	printf("Routing tables");
+	if (fibnum)
+		printf(" (fib: %d)", fibnum);
+	printf("\n");
 
-	if (Aflag == 0 && NewTree)
-		ntreestuff();
-	else {
-		if (rtree == 0) {
-			printf("rt_tables: symbol not in namelist\n");
-			return;
-		}
+	if (Aflag == 0 && live != 0 && NewTree)
+		p_rtable_sysctl(fibnum, af);
+	else
+		p_rtable_kvm(fibnum, af);
+}
 
-		if (kread((u_long)(rtree), (char *)(rt_tables), (numfibs *
-		    (AF_MAX+1) * sizeof(struct radix_node_head *))) != 0)
-			return;
-		for (fam = 0; fam <= AF_MAX; fam++) {
-			int tmpfib;
 
-			switch (fam) {
-			case AF_INET6:
-			case AF_INET:
-				tmpfib = fibnum;
-				break;
-			default:
-				tmpfib = 0;
-			}
-			rnhp = (struct radix_node_head **)*rt_tables;
-			/* Calculate the in-kernel address. */
-			rnhp += tmpfib * (AF_MAX+1) + fam;
-			/* Read the in kernel rhn pointer. */
-			if (kget(rnhp, rnh) != 0)
-				continue;
-			if (rnh == NULL)
-				continue;
-			/* Read the rnh data. */
-			if (kget(rnh, head) != 0)
-				continue;
-			if (fam == AF_UNSPEC) {
-				if (Aflag && af == 0) {
-					printf("Netmasks:\n");
-					p_tree(head.rnh_treetop);
-				}
-			} else if (af == AF_UNSPEC || af == fam) {
-				size_cols(fam, head.rnh_treetop);
-				pr_family(fam);
-				do_rtent = 1;
-				pr_rthdr(fam);
-				p_tree(head.rnh_treetop);
-			}
-		}
-	}
-}
-
 /*
  * Print address family header before a section of the routing table.
  */
@@ -263,37 +239,35 @@
 #ifndef INET6
 #define	WID_DST_DEFAULT(af) 	18	/* width of destination column */
 #define	WID_GW_DEFAULT(af)	18	/* width of gateway column */
-#define	WID_IF_DEFAULT(af)	(Wflag ? 8 : 6)	/* width of netif column */
+#define	WID_IF_DEFAULT(af)	(Wflag ? 10 : 8) /* width of netif column */
 #else
 #define	WID_DST_DEFAULT(af) \
 	((af) == AF_INET6 ? (numeric_addr ? 33: 18) : 18)
 #define	WID_GW_DEFAULT(af) \
 	((af) == AF_INET6 ? (numeric_addr ? 29 : 18) : 18)
-#define	WID_IF_DEFAULT(af)	((af) == AF_INET6 ? 8 : (Wflag ? 8 : 6))
+#define	WID_IF_DEFAULT(af)	((af) == AF_INET6 ? 8 : (Wflag ? 10 : 8))
 #endif /*INET6*/
 
 static int wid_dst;
 static int wid_gw;
 static int wid_flags;
-static int wid_refs;
-static int wid_use;
+static int wid_pksent;
 static int wid_mtu;
 static int wid_if;
 static int wid_expire;
 
 static void
-size_cols(int ef __unused, struct radix_node *rn)
+size_cols(int ef, struct radix_node *rn)
 {
 	wid_dst = WID_DST_DEFAULT(ef);
 	wid_gw = WID_GW_DEFAULT(ef);
 	wid_flags = 6;
-	wid_refs = 6;
-	wid_use = 8;
+	wid_pksent = 8;
 	wid_mtu = 6;
 	wid_if = WID_IF_DEFAULT(ef);
 	wid_expire = 6;
 
-	if (Wflag)
+	if (Wflag && rn != NULL)
 		size_cols_tree(rn);
 }
 
@@ -348,16 +322,10 @@
 	len = strlen(bp);
 	wid_flags = MAX(len, wid_flags);
 
-	if (addr.u_sa.sa_family == AF_INET || Wflag) {
-		len = snprintf(buffer, sizeof(buffer), "%d", rt->rt_refcnt);
-		wid_refs = MAX(len, wid_refs);
-		len = snprintf(buffer, sizeof(buffer), "%lu", rt->rt_use);
-		wid_use = MAX(len, wid_use);
-		if (Wflag && rt->rt_rmx.rmx_mtu != 0) {
-			len = snprintf(buffer, sizeof(buffer),
-				       "%lu", rt->rt_rmx.rmx_mtu);
-			wid_mtu = MAX(len, wid_mtu);
-		}
+	if (Wflag) {
+		len = snprintf(buffer, sizeof(buffer), "%ju",
+		    (uintmax_t )kread_counter((u_long )rt->rt_pksent));
+		wid_pksent = MAX(len, wid_pksent);
 	}
 	if (rt->rt_ifp) {
 		if (rt->rt_ifp != lastif) {
@@ -368,11 +336,11 @@
 			lastif = rt->rt_ifp;
 			wid_if = MAX(len, wid_if);
 		}
-		if (rt->rt_rmx.rmx_expire) {
+		if (rt->rt_expire) {
 			time_t expire_time;
 
 			if ((expire_time =
-			    rt->rt_rmx.rmx_expire - uptime.tv_sec) > 0) {
+			    rt->rt_expire - uptime.tv_sec) > 0) {
 				len = snprintf(buffer, sizeof(buffer), "%d",
 					       (int)expire_time);
 				wid_expire = MAX(len, wid_expire);
@@ -391,27 +359,15 @@
 
 	if (Aflag)
 		printf("%-8.8s ","Address");
-	if (af1 == AF_INET || Wflag) {
-		if (Wflag) {
-			printf("%-*.*s %-*.*s %-*.*s %*.*s %*.*s %*.*s %*.*s %*s\n",
-				wid_dst,	wid_dst,	"Destination",
-				wid_gw,		wid_gw,		"Gateway",
-				wid_flags,	wid_flags,	"Flags",
-				wid_refs,	wid_refs,	"Refs",
-				wid_use,	wid_use,	"Use",
-				wid_mtu,	wid_mtu,	"Mtu",
-				wid_if,		wid_if,		"Netif",
-				wid_expire,			"Expire");
-		} else {
-			printf("%-*.*s %-*.*s %-*.*s %*.*s %*.*s %*.*s %*s\n",
-				wid_dst,	wid_dst,	"Destination",
-				wid_gw,		wid_gw,		"Gateway",
-				wid_flags,	wid_flags,	"Flags",
-				wid_refs,	wid_refs,	"Refs",
-				wid_use,	wid_use,	"Use",
-				wid_if,		wid_if,		"Netif",
-				wid_expire,			"Expire");
-		}
+	if (Wflag) {
+		printf("%-*.*s %-*.*s %-*.*s %*.*s %*.*s %*.*s %*s\n",
+			wid_dst,	wid_dst,	"Destination",
+			wid_gw,		wid_gw,		"Gateway",
+			wid_flags,	wid_flags,	"Flags",
+			wid_pksent,	wid_pksent,	"Use",
+			wid_mtu,	wid_mtu,	"Mtu",
+			wid_if,		wid_if,		"Netif",
+			wid_expire,			"Expire");
 	} else {
 		printf("%-*.*s %-*.*s %-*.*s  %*.*s %*s\n",
 			wid_dst,	wid_dst,	"Destination",
@@ -433,10 +389,79 @@
 	return (&pt_u.u_sa);
 }
 
+/*
+ * Print kernel routing tables for given fib
+ * using debugging kvm(3) interface.
+ */
 static void
-p_tree(struct radix_node *rn)
+p_rtable_kvm(int fibnum, int af)
 {
+	struct radix_node_head **rnhp, *rnh, head;
+	struct radix_node_head **rt_tables;
+	u_long rtree;
+	int fam, af_size;
 
+	kresolve_list(rl);
+	if ((rtree = rl[N_RTREE].n_value) == 0) {
+		printf("rt_tables: symbol not in namelist\n");
+		return;
+	}
+
+	af_size = (AF_MAX + 1) * sizeof(struct radix_node_head *);
+	rt_tables = calloc(1, af_size);
+	if (rt_tables == NULL)
+		err(EX_OSERR, "memory allocation failed");
+
+	if (kread((u_long)(rtree), (char *)(rt_tables) + fibnum * af_size,
+	    af_size) != 0)
+		err(EX_OSERR, "error retrieving radix pointers");
+	for (fam = 0; fam <= AF_MAX; fam++) {
+		int tmpfib;
+
+		switch (fam) {
+		case AF_INET6:
+		case AF_INET:
+			tmpfib = fibnum;
+			break;
+		default:
+			tmpfib = 0;
+		}
+		rnhp = (struct radix_node_head **)*rt_tables;
+		/* Calculate the in-kernel address. */
+		rnhp += tmpfib * (AF_MAX + 1) + fam;
+		/* Read the in kernel rhn pointer. */
+		if (kget(rnhp, rnh) != 0)
+			continue;
+		if (rnh == NULL)
+			continue;
+		/* Read the rnh data. */
+		if (kget(rnh, head) != 0)
+			continue;
+		if (fam == AF_UNSPEC) {
+			if (Aflag && af == 0) {
+				printf("Netmasks:\n");
+				p_rtree_kvm(head.rnh_treetop);
+			}
+		} else if (af == AF_UNSPEC || af == fam) {
+			size_cols(fam, head.rnh_treetop);
+			pr_family(fam);
+			do_rtent = 1;
+			pr_rthdr(fam);
+			p_rtree_kvm(head.rnh_treetop);
+		}
+	}
+
+	free(rt_tables);
+}
+
+/*
+ * Print given kernel radix tree using
+ * debugging kvm(3) interface.
+ */
+static void
+p_rtree_kvm(struct radix_node *rn)
+{
+
 again:
 	if (kget(rn, rnode) != 0)
 		return;
@@ -451,9 +476,9 @@
 				    rnode.rn_dupedkey ? " =>\n" : "\n");
 		} else if (do_rtent) {
 			if (kget(rn, rtentry) == 0) {
-				p_rtentry(&rtentry);
+				p_rtentry_kvm(&rtentry);
 				if (Aflag)
-					p_rtnode();
+					p_rtnode_kvm();
 			}
 		} else {
 			p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_key),
@@ -465,11 +490,11 @@
 	} else {
 		if (Aflag && do_rtent) {
 			printf("%-8.8lx ", (u_long)rn);
-			p_rtnode();
+			p_rtnode_kvm();
 		}
 		rn = rnode.rn_right;
-		p_tree(rnode.rn_left);
-		p_tree(rn);
+		p_rtree_kvm(rnode.rn_left);
+		p_rtree_kvm(rn);
 	}
 }
 
@@ -476,7 +501,7 @@
 char	nbuf[20];
 
 static void
-p_rtnode(void)
+p_rtnode_kvm(void)
 {
 	struct radix_mask *rm = rnode.rn_mklist;
 
@@ -516,72 +541,142 @@
 }
 
 static void
-ntreestuff(void)
+p_rtable_sysctl(int fibnum, int af)
 {
 	size_t needed;
-	int mib[6];
+	int mib[7];
 	char *buf, *next, *lim;
 	struct rt_msghdr *rtm;
+	struct sockaddr *sa;
+	int fam = 0, ifindex = 0, size;
 
+	struct ifaddrs *ifap, *ifa;
+	struct sockaddr_dl *sdl;
+
+	/*
+	 * Retrieve interface list at first
+	 * since we need #ifindex -> if_xname match
+	 */
+	if (getifaddrs(&ifap) != 0)
+		err(EX_OSERR, "getifaddrs");
+
+	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+		
+		if (ifa->ifa_addr->sa_family != AF_LINK)
+			continue;
+
+		sdl = (struct sockaddr_dl *)ifa->ifa_addr;
+		ifindex = sdl->sdl_index;
+
+		if (ifindex >= ifmap_size) {
+			size = roundup(ifindex + 1, 32) *
+			    sizeof(struct ifmap_entry);
+			if ((ifmap = realloc(ifmap, size)) == NULL)
+				errx(2, "realloc(%d) failed", size);
+			memset(&ifmap[ifmap_size], 0,
+			    size - ifmap_size *
+			     sizeof(struct ifmap_entry));
+
+			ifmap_size = roundup(ifindex + 1, 32);
+		}
+
+		if (*ifmap[ifindex].ifname != '\0')
+			continue;
+
+		strlcpy(ifmap[ifindex].ifname, ifa->ifa_name, IFNAMSIZ);
+	}
+
+	freeifaddrs(ifap);
+
 	mib[0] = CTL_NET;
 	mib[1] = PF_ROUTE;
 	mib[2] = 0;
-	mib[3] = 0;
+	mib[3] = af;
 	mib[4] = NET_RT_DUMP;
 	mib[5] = 0;
-	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) {
-		err(1, "sysctl: net.route.0.0.dump estimate");
-	}
-
-	if ((buf = malloc(needed)) == 0) {
+	mib[6] = fibnum;
+	if (sysctl(mib, nitems(mib), NULL, &needed, NULL, 0) < 0)
+		err(EX_OSERR, "sysctl: net.route.0.%d.dump.%d estimate", af,
+		    fibnum);
+	if ((buf = malloc(needed)) == NULL)
 		errx(2, "malloc(%lu)", (unsigned long)needed);
-	}
-	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
-		err(1, "sysctl: net.route.0.0.dump");
-	}
+	if (sysctl(mib, nitems(mib), buf, &needed, NULL, 0) < 0)
+		err(1, "sysctl: net.route.0.%d.dump.%d", af, fibnum);
 	lim  = buf + needed;
 	for (next = buf; next < lim; next += rtm->rtm_msglen) {
 		rtm = (struct rt_msghdr *)next;
-		np_rtentry(rtm);
+		if (rtm->rtm_version != RTM_VERSION)
+			continue;
+		/*
+		 * Peek inside header to determine AF
+		 */
+		sa = (struct sockaddr *)(rtm + 1);
+		if (fam != sa->sa_family) {
+			fam = sa->sa_family;
+			size_cols(fam, NULL);
+			pr_family(fam);
+			pr_rthdr(fam);
+		}
+		p_rtentry_sysctl(rtm);
 	}
+	free(buf);
 }
 
 static void
-np_rtentry(struct rt_msghdr *rtm)
+p_rtentry_sysctl(struct rt_msghdr *rtm)
 {
 	struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
-#ifdef notdef
-	static int masks_done, banner_printed;
-#endif
-	static int old_af;
-	int af1 = 0, interesting = RTF_UP | RTF_GATEWAY | RTF_HOST;
+	char buffer[128];
+	char prettyname[128];
+	sa_u addr, mask, gw;
+	unsigned int l;
 
-#ifdef notdef
-	/* for the moment, netmasks are skipped over */
-	if (!banner_printed) {
-		printf("Netmasks:\n");
-		banner_printed = 1;
+#define	GETSA(_s, _f)	{ \
+	bzero(&(_s), sizeof(_s)); \
+	if (rtm->rtm_addrs & _f) { \
+		l = roundup(sa->sa_len, sizeof(long)); \
+		memcpy(&(_s), sa, (l > sizeof(_s)) ? sizeof(_s) : l); \
+		sa = (struct sockaddr *)((char *)sa + l); \
+	} \
+}
+
+	GETSA(addr, RTA_DST);
+	GETSA(gw, RTA_GATEWAY);
+	GETSA(mask, RTA_NETMASK);
+	p_sockaddr(&addr.u_sa, &mask.u_sa, rtm->rtm_flags, wid_dst);
+	p_sockaddr(&gw.u_sa, NULL, RTF_HOST, wid_gw);
+
+	snprintf(buffer, sizeof(buffer), "%%-%d.%ds ", wid_flags, wid_flags);
+	p_flags(rtm->rtm_flags, buffer);
+	if (Wflag) {
+		printf("%*lu ", wid_pksent, rtm->rtm_rmx.rmx_pksent);
+
+		if (rtm->rtm_rmx.rmx_mtu != 0)
+			printf("%*lu ", wid_mtu, rtm->rtm_rmx.rmx_mtu);
+		else
+			printf("%*s ", wid_mtu, "");
 	}
-	if (masks_done == 0) {
-		if (rtm->rtm_addrs != RTA_DST ) {
-			masks_done = 1;
-			af1 = sa->sa_family;
-		}
-	} else
-#endif
-		af1 = sa->sa_family;
-	if (af1 != old_af) {
-		pr_family(af1);
-		old_af = af1;
+
+	memset(prettyname, 0, sizeof(prettyname));
+	if (rtm->rtm_index < ifmap_size) {
+		strlcpy(prettyname, ifmap[rtm->rtm_index].ifname,
+		    sizeof(prettyname));
+		if (*prettyname == '\0')
+			strlcpy(prettyname, "---", sizeof(prettyname));
 	}
-	if (rtm->rtm_addrs == RTA_DST)
-		p_sockaddr(sa, NULL, 0, 36);
-	else {
-		p_sockaddr(sa, NULL, rtm->rtm_flags, 16);
-		sa = (struct sockaddr *)(SA_SIZE(sa) + (char *)sa);
-		p_sockaddr(sa, NULL, 0, 18);
+
+	if (Wflag)
+		printf("%*s", wid_if, prettyname);
+	else
+		printf("%*.*s", wid_if, wid_if, prettyname);
+	if (rtm->rtm_rmx.rmx_expire) {
+		time_t expire_time;
+
+		if ((expire_time =
+		    rtm->rtm_rmx.rmx_expire - uptime.tv_sec) > 0)
+			printf(" %*d", wid_expire, (int)expire_time);
 	}
-	p_flags(rtm->rtm_flags & interesting, "%-6.6s ");
+
 	putchar('\n');
 }
 
@@ -625,10 +720,9 @@
 			cp = routename(sockin->sin_addr.s_addr);
 		else if (mask)
 			cp = netname(sockin->sin_addr.s_addr,
-				     ntohl(((struct sockaddr_in *)mask)
-					   ->sin_addr.s_addr));
+			    ((struct sockaddr_in *)mask)->sin_addr.s_addr);
 		else
-			cp = netname(sockin->sin_addr.s_addr, 0L);
+			cp = netname(sockin->sin_addr.s_addr, INADDR_ANY);
 		break;
 	    }
 
@@ -751,7 +845,7 @@
 }
 
 static void
-p_rtentry(struct rtentry *rt)
+p_rtentry_kvm(struct rtentry *rt)
 {
 	static struct ifnet ifnet, *lastif;
 	static char buffer[128];
@@ -769,15 +863,14 @@
 	p_sockaddr(kgetsa(rt->rt_gateway), NULL, RTF_HOST, wid_gw);
 	snprintf(buffer, sizeof(buffer), "%%-%d.%ds ", wid_flags, wid_flags);
 	p_flags(rt->rt_flags, buffer);
-	if (addr.u_sa.sa_family == AF_INET || Wflag) {
-		printf("%*d %*lu ", wid_refs, rt->rt_refcnt,
-				     wid_use, rt->rt_use);
-		if (Wflag) {
-			if (rt->rt_rmx.rmx_mtu != 0)
-				printf("%*lu ", wid_mtu, rt->rt_rmx.rmx_mtu);
-			else
-				printf("%*s ", wid_mtu, "");
-		}
+	if (Wflag) {
+		printf("%*ju ", wid_pksent,
+		    (uintmax_t )kread_counter((u_long )rt->rt_pksent));
+
+		if (rt->rt_mtu != 0)
+			printf("%*lu ", wid_mtu, rt->rt_mtu);
+		else
+			printf("%*s ", wid_mtu, "");
 	}
 	if (rt->rt_ifp) {
 		if (rt->rt_ifp != lastif) {
@@ -789,11 +882,11 @@
 			lastif = rt->rt_ifp;
 		}
 		printf("%*.*s", wid_if, wid_if, prettyname);
-		if (rt->rt_rmx.rmx_expire) {
+		if (rt->rt_expire) {
 			time_t expire_time;
 
 			if ((expire_time =
-			    rt->rt_rmx.rmx_expire - uptime.tv_sec) > 0)
+			    rt->rt_expire - uptime.tv_sec) > 0)
 				printf(" %*d", wid_expire, (int)expire_time);
 		}
 		if (rt->rt_nodes[0].rn_dupedkey)
@@ -864,10 +957,9 @@
 
 /*
  * Return the name of the network whose address is given.
- * The address is assumed to be that of a net or subnet, not a host.
  */
 char *
-netname(in_addr_t in, u_long mask)
+netname(in_addr_t in, in_addr_t mask)
 {
 	char *cp = 0;
 	static char line[MAXHOSTNAMELEN];
@@ -874,9 +966,12 @@
 	struct netent *np = 0;
 	in_addr_t i;
 
+	/* It is ok to supply host address. */
+	in &= mask;
+
 	i = ntohl(in);
 	if (!numeric_addr && i) {
-		np = getnetbyaddr(i >> NSHIFT(mask), AF_INET);
+		np = getnetbyaddr(i >> NSHIFT(ntohl(mask)), AF_INET);
 		if (np != NULL) {
 			cp = np->n_name;
 			trimdomain(cp, strlen(cp));
@@ -887,7 +982,7 @@
 	} else {
 		inet_ntop(AF_INET, &in, line, sizeof(line) - 1);
 	}
-	domask(line + strlen(line), i, mask);
+	domask(line + strlen(line), i, ntohl(mask));
 	return (line);
 }
 
@@ -905,9 +1000,9 @@
 	if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr) ||
 	    IN6_IS_ADDR_MC_NODELOCAL(&sa6->sin6_addr) ||
 	    IN6_IS_ADDR_MC_LINKLOCAL(&sa6->sin6_addr)) {
-		/* XXX: override is ok? */
-		sa6->sin6_scope_id =
-		    ntohs(*(u_int16_t *)&sa6->sin6_addr.s6_addr[2]);
+		if (sa6->sin6_scope_id == 0)
+			sa6->sin6_scope_id =
+			    ntohs(*(u_int16_t *)&sa6->sin6_addr.s6_addr[2]);
 		sa6->sin6_addr.s6_addr[2] = sa6->sin6_addr.s6_addr[3] = 0;
 	}
 #endif
@@ -1002,16 +1097,19 @@
  * Print routing statistics
  */
 void
-rt_stats(u_long rtsaddr, u_long rttaddr)
+rt_stats(void)
 {
 	struct rtstat rtstat;
+	u_long rtsaddr, rttaddr;
 	int rttrash;
 
-	if (rtsaddr == 0) {
+	kresolve_list(rl);
+
+	if ((rtsaddr = rl[N_RTSTAT].n_value) == 0) {
 		printf("rtstat: symbol not in namelist\n");
 		return;
 	}
-	if (rttaddr == 0) {
+	if ((rttaddr = rl[N_RTTRASH].n_value) == 0) {
 		printf("rttrash: symbol not in namelist\n");
 		return;
 	}

Modified: trunk/usr.bin/netstat/sctp.c
===================================================================
--- trunk/usr.bin/netstat/sctp.c	2018-07-07 16:54:14 UTC (rev 11466)
+++ trunk/usr.bin/netstat/sctp.c	2018-07-07 16:54:32 UTC (rev 11467)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2001-2007, by Weongyo Jeong. All rights reserved.
  * Copyright (c) 2011, by Michael Tuexen. All rights reserved.
@@ -36,7 +37,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/usr.bin/netstat/sctp.c 294150 2016-01-16 14:43:27Z tuexen $");
 
 #include <sys/param.h>
 #include <sys/queue.h>
@@ -77,7 +78,7 @@
 #define	NETSTAT_SCTP_STATES_SHUTDOWN_ACK_SENT	0x8
 #define	NETSTAT_SCTP_STATES_SHUTDOWN_PENDING	0x9
 
-char *sctpstates[] = {
+const char *sctpstates[] = {
 	"CLOSED",
 	"BOUND",
 	"LISTEN",
@@ -164,7 +165,7 @@
 	if (first && !numeric_addr) {
 		first = 0;
 		if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
-		    (cp = index(domain, '.')))
+		    (cp = strchr(domain, '.')))
 			(void) strcpy(domain, cp + 1);
 		else
 			domain[0] = 0;
@@ -173,7 +174,7 @@
 	if (!numeric_addr && !IN6_IS_ADDR_UNSPECIFIED(in6p)) {
 		hp = gethostbyaddr((char *)in6p, sizeof(*in6p), AF_INET6);
 		if (hp) {
-			if ((cp = index(hp->h_name, '.')) &&
+			if ((cp = strchr(hp->h_name, '.')) &&
 			    !strcmp(cp + 1, domain))
 				*cp = 0;
 			cp = hp->h_name;
@@ -213,7 +214,7 @@
 		sprintf(line, "%.*s.", Wflag ? 39 : 16, "");
 		break;
 	}
-	cp = index(line, '\0');
+	cp = strchr(line, '\0');
 	if (!num_port && port)
 		sp = getservbyport((int)port, "sctp");
 	if (sp || port == 0)
@@ -393,7 +394,7 @@
 {
 	int indent = 0, xladdr_total = 0, is_listening = 0;
 	static int first = 1;
-	char *tname, *pname;
+	const char *tname, *pname;
 	struct xsctp_tcb *xstcb;
 	struct xsctp_laddr *xladdr;
 	size_t offset_laddr;
@@ -527,7 +528,7 @@
  */
 void
 sctp_protopr(u_long off __unused,
-    const char *name, int af1, int proto)
+    const char *name __unused, int af1 __unused, int proto)
 {
 	char *buf;
 	const char *mibvar = "net.inet.sctp.assoclist";
@@ -572,25 +573,34 @@
 	int idx;
 
 	switch (state) {
-	case SCTP_STATE_COOKIE_WAIT:
+	case SCTP_CLOSED:
+		idx = NETSTAT_SCTP_STATES_CLOSED;
+		break;
+	case SCTP_BOUND:
+		idx = NETSTAT_SCTP_STATES_BOUND;
+		break;
+	case SCTP_LISTEN:
+		idx = NETSTAT_SCTP_STATES_LISTEN;
+		break;
+	case SCTP_COOKIE_WAIT:
 		idx = NETSTAT_SCTP_STATES_COOKIE_WAIT;
 		break;
-	case SCTP_STATE_COOKIE_ECHOED:
+	case SCTP_COOKIE_ECHOED:
 		idx = NETSTAT_SCTP_STATES_COOKIE_ECHOED;
 		break;
-	case SCTP_STATE_OPEN:
+	case SCTP_ESTABLISHED:
 		idx = NETSTAT_SCTP_STATES_ESTABLISHED;
 		break;
-	case SCTP_STATE_SHUTDOWN_SENT:
+	case SCTP_SHUTDOWN_SENT:
 		idx = NETSTAT_SCTP_STATES_SHUTDOWN_SENT;
 		break;
-	case SCTP_STATE_SHUTDOWN_RECEIVED:
+	case SCTP_SHUTDOWN_RECEIVED:
 		idx = NETSTAT_SCTP_STATES_SHUTDOWN_RECEIVED;
 		break;
-	case SCTP_STATE_SHUTDOWN_ACK_SENT:
+	case SCTP_SHUTDOWN_ACK_SENT:
 		idx = NETSTAT_SCTP_STATES_SHUTDOWN_ACK_SENT;
 		break;
-	case SCTP_STATE_SHUTDOWN_PENDING:
+	case SCTP_SHUTDOWN_PENDING:
 		idx = NETSTAT_SCTP_STATES_SHUTDOWN_PENDING;
 		break;
 	default:
@@ -607,20 +617,11 @@
 void
 sctp_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
 {
-	struct sctpstat sctpstat, zerostat;
-	size_t len = sizeof(sctpstat);
+	struct sctpstat sctpstat;
 
-	if (live) {
-		if (zflag)
-			memset(&zerostat, 0, len);
-		if (sysctlbyname("net.inet.sctp.stats", &sctpstat, &len,
-		    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
-			if (errno != ENOENT)
-				warn("sysctl: net.inet.sctp.stats");
-			return;
-		}
-	} else
-		kread(off, &sctpstat, len);
+	if (fetch_stats("net.inet.sctp.stats", off, &sctpstat,
+	    sizeof(sctpstat), kread) != 0)
+		return;
 
 	printf ("%s:\n", name);
 

Modified: trunk/usr.bin/netstat/unix.c
===================================================================
--- trunk/usr.bin/netstat/unix.c	2018-07-07 16:54:14 UTC (rev 11466)
+++ trunk/usr.bin/netstat/unix.c	2018-07-07 16:54:32 UTC (rev 11467)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1983, 1988, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -34,7 +35,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/usr.bin/netstat/unix.c 246988 2013-02-19 13:17:16Z charnier $");
 
 /*
  * Display protocol blocks in the unix domain.
@@ -199,6 +200,7 @@
 	struct	xunpcb *xunp;
 	u_long	head_off;
 
+	buf = NULL;
 	for (type = SOCK_STREAM; type <= SOCK_SEQPACKET; type++) {
 		if (live)
 			ret = pcblist_sysctl(type, &buf);



More information about the Midnightbsd-cvs mailing list