Module Name:    src
Committed By:   ozaki-r
Date:           Fri Aug 28 07:23:48 UTC 2020

Modified Files:
        src/usr.bin/netstat: atalk.c bpf.c inet.c inet6.c pfkey.c pfsync.c

Log Message:
netstat: strengthen against kernel changes

netstat uses sysctlbyname to get counter data from the kernel.
sysctlbyname fails with ENOMEM if actual counter data in the kernel is
larger than a passed buffer.  netstat just skips showing counters of a
category if sysctlbyname fails, so if we added new counters of the
category to the kernel, nestat shows nothing for the category.

Fortunately sysctlbyname fills data as much as possible even if a passed
buffer is short.  So we can allow netstat to show the filled data anyway
if sysctlbyname fails with ENOMEM.

Note that this backcompat mechanism works only if new counters are
appended, and doesn't work if new counters are inserted into the middle
or counters are moved.


To generate a diff of this commit:
cvs rdiff -u -r1.18 -r1.19 src/usr.bin/netstat/atalk.c
cvs rdiff -u -r1.14 -r1.15 src/usr.bin/netstat/bpf.c
cvs rdiff -u -r1.112 -r1.113 src/usr.bin/netstat/inet.c
cvs rdiff -u -r1.76 -r1.77 src/usr.bin/netstat/inet6.c
cvs rdiff -u -r1.2 -r1.3 src/usr.bin/netstat/pfkey.c \
    src/usr.bin/netstat/pfsync.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/netstat/atalk.c
diff -u src/usr.bin/netstat/atalk.c:1.18 src/usr.bin/netstat/atalk.c:1.19
--- src/usr.bin/netstat/atalk.c:1.18	Thu Apr 23 00:23:31 2020
+++ src/usr.bin/netstat/atalk.c	Fri Aug 28 07:23:48 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: atalk.c,v 1.18 2020/04/23 00:23:31 joerg Exp $	*/
+/*	$NetBSD: atalk.c,v 1.19 2020/08/28 07:23:48 ozaki-r Exp $	*/
 
 /*
  * Copyright (c) 1983, 1988, 1993
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "from @(#)atalk.c	1.1 (Whistle) 6/6/96";
 #else
-__RCSID("$NetBSD: atalk.c,v 1.18 2020/04/23 00:23:31 joerg Exp $");
+__RCSID("$NetBSD: atalk.c,v 1.19 2020/08/28 07:23:48 ozaki-r Exp $");
 #endif
 #endif /* not lint */
 
@@ -291,7 +291,7 @@ ddp_stats(u_long off, const char *name)
 		size_t size = sizeof(ddpstat);
 
 		if (prog_sysctlbyname("net.atalk.ddp.stats", ddpstat, &size,
-				 NULL, 0) == -1)
+				 NULL, 0) == -1 && errno != ENOMEM)
 			return;
 	} else {
 		warnx("%s stats not available via KVM.", name);

Index: src/usr.bin/netstat/bpf.c
diff -u src/usr.bin/netstat/bpf.c:1.14 src/usr.bin/netstat/bpf.c:1.15
--- src/usr.bin/netstat/bpf.c:1.14	Sun Aug 18 04:14:40 2019
+++ src/usr.bin/netstat/bpf.c	Fri Aug 28 07:23:48 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: bpf.c,v 1.14 2019/08/18 04:14:40 kamil Exp $	*/
+/*	$NetBSD: bpf.c,v 1.15 2020/08/28 07:23:48 ozaki-r Exp $	*/
 
 /*
  * Copyright (c) 2005 The NetBSD Foundation, Inc.
@@ -53,7 +53,8 @@ bpf_stats(void)
 	size_t len = sizeof(bpf_s);
 
 	if (use_sysctl) {
-		if (prog_sysctlbyname("net.bpf.stats", &bpf_s, &len, NULL, 0) == -1)
+		if (prog_sysctlbyname("net.bpf.stats", &bpf_s, &len, NULL, 0) == -1 &&
+		    errno != ENOMEM)
 			err(1, "net.bpf.stats");
 	
 		printf("bpf:\n");

Index: src/usr.bin/netstat/inet.c
diff -u src/usr.bin/netstat/inet.c:1.112 src/usr.bin/netstat/inet.c:1.113
--- src/usr.bin/netstat/inet.c:1.112	Fri Aug 28 06:34:17 2020
+++ src/usr.bin/netstat/inet.c	Fri Aug 28 07:23:48 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: inet.c,v 1.112 2020/08/28 06:34:17 ozaki-r Exp $	*/
+/*	$NetBSD: inet.c,v 1.113 2020/08/28 07:23:48 ozaki-r Exp $	*/
 
 /*
  * Copyright (c) 1983, 1988, 1993
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "from: @(#)inet.c	8.4 (Berkeley) 4/20/94";
 #else
-__RCSID("$NetBSD: inet.c,v 1.112 2020/08/28 06:34:17 ozaki-r Exp $");
+__RCSID("$NetBSD: inet.c,v 1.113 2020/08/28 07:23:48 ozaki-r Exp $");
 #endif
 #endif /* not lint */
 
@@ -404,7 +404,7 @@ tcp_stats(u_long off, const char *name)
 		size_t size = sizeof(tcpstat);
 
 		if (prog_sysctlbyname("net.inet.tcp.stats", tcpstat, &size,
-				 NULL, 0) == -1)
+				 NULL, 0) == -1 && errno != ENOMEM)
 			return;
 	} else {
 		warnx("%s stats not available via KVM.", name);
@@ -531,7 +531,7 @@ udp_stats(u_long off, const char *name)
 		size_t size = sizeof(udpstat);
 
 		if (prog_sysctlbyname("net.inet.udp.stats", udpstat, &size,
-				 NULL, 0) == -1)
+				 NULL, 0) == -1 && errno != ENOMEM)
 			return;
 	} else {
 		warnx("%s stats not available via KVM.", name);
@@ -584,7 +584,7 @@ ip_stats(u_long off, const char *name)
 		size_t size = sizeof(ipstat);
 
 		if (prog_sysctlbyname("net.inet.ip.stats", ipstat, &size,
-				 NULL, 0) == -1)
+				 NULL, 0) == -1 && errno != ENOMEM)
 			return;
 	} else {
 		warnx("%s stats not available via KVM.", name);
@@ -657,7 +657,7 @@ icmp_stats(u_long off, const char *name)
 		size_t size = sizeof(icmpstat);
 
 		if (prog_sysctlbyname("net.inet.icmp.stats", icmpstat, &size,
-				 NULL, 0) == -1)
+				 NULL, 0) == -1 && errno != ENOMEM)
 			return;
 	} else {
 		warnx("%s stats not available via KVM.", name);
@@ -713,7 +713,7 @@ igmp_stats(u_long off, const char *name)
 		size_t size = sizeof(igmpstat);
 
 		if (prog_sysctlbyname("net.inet.igmp.stats", igmpstat, &size,
-				 NULL, 0) == -1)
+				 NULL, 0) == -1 && errno != ENOMEM)
 			return;
 	} else {
 		warnx("%s stats not available via KVM.", name);
@@ -751,7 +751,7 @@ carp_stats(u_long off, const char *name)
 		size_t size = sizeof(carpstat);
 
 		if (prog_sysctlbyname("net.inet.carp.stats", carpstat, &size,
-				 NULL, 0) == -1)
+				 NULL, 0) == -1 && errno != ENOMEM)
 			return;
 	} else {
 		warnx("%s stats not available via KVM.", name);
@@ -837,7 +837,7 @@ arp_stats(u_long off, const char *name)
 		size_t size = sizeof(arpstat);
 
 		if (prog_sysctlbyname("net.inet.arp.stats", arpstat, &size,
-				 NULL, 0) == -1)
+				 NULL, 0) == -1 && errno != ENOMEM)
 			return;
 	} else {
 		warnx("%s stats not available via KVM.", name);

Index: src/usr.bin/netstat/inet6.c
diff -u src/usr.bin/netstat/inet6.c:1.76 src/usr.bin/netstat/inet6.c:1.77
--- src/usr.bin/netstat/inet6.c:1.76	Fri Aug 28 06:34:17 2020
+++ src/usr.bin/netstat/inet6.c	Fri Aug 28 07:23:48 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: inet6.c,v 1.76 2020/08/28 06:34:17 ozaki-r Exp $	*/
+/*	$NetBSD: inet6.c,v 1.77 2020/08/28 07:23:48 ozaki-r Exp $	*/
 /*	BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp	*/
 
 /*
@@ -64,7 +64,7 @@
 #if 0
 static char sccsid[] = "@(#)inet.c	8.4 (Berkeley) 4/20/94";
 #else
-__RCSID("$NetBSD: inet6.c,v 1.76 2020/08/28 06:34:17 ozaki-r Exp $");
+__RCSID("$NetBSD: inet6.c,v 1.77 2020/08/28 07:23:48 ozaki-r Exp $");
 #endif
 #endif /* not lint */
 
@@ -417,7 +417,7 @@ tcp6_stats(u_long off, const char *name)
 		size_t size = sizeof(tcp6stat);
 
 		if (prog_sysctlbyname("net.inet6.tcp6.stats", &tcp6stat, &size,
-		    NULL, 0) == -1)
+		    NULL, 0) == -1 && errno != ENOMEM)
 			return;
 	} else {
 		warnx("%s stats not available via KVM.", name);
@@ -503,7 +503,7 @@ udp6_stats(u_long off, const char *name)
 		size_t size = sizeof(udp6stat);
 
 		if (prog_sysctlbyname("net.inet6.udp6.stats", udp6stat, &size,
-		    NULL, 0) == -1)
+		    NULL, 0) == -1 && errno != ENOMEM)
 			return;
 	} else {
 		warnx("%s stats not available via KVM.", name);
@@ -647,7 +647,7 @@ ip6_stats(u_long off, const char *name)
 		size_t size = sizeof(ip6stat);
 
 		if (prog_sysctlbyname("net.inet6.ip6.stats", ip6stat, &size,
-		    NULL, 0) == -1)
+		    NULL, 0) == -1 && errno != ENOMEM)
 			return;
 	} else {
 		warnx("%s stats not available via KVM.", name);
@@ -1141,7 +1141,7 @@ icmp6_stats(u_long off, const char *name
 		size_t size = sizeof(icmp6stat);
 
 		if (prog_sysctlbyname("net.inet6.icmp6.stats", icmp6stat, &size,
-		    NULL, 0) == -1)
+		    NULL, 0) == -1 && errno != ENOMEM)
 			return;
 	} else {
 		warnx("%s stats not available via KVM.", name);
@@ -1289,7 +1289,7 @@ pim6_stats(u_long off, const char *name)
 		size_t size = sizeof(pim6stat);
 
 		if (prog_sysctlbyname("net.inet6.pim6.stats", pim6stat, &size,
-		    NULL, 0) == -1)
+		    NULL, 0) == -1 && errno != ENOMEM)
 			return;
         } else {
 		warnx("%s stats not available via KVM.", name);
@@ -1322,7 +1322,7 @@ rip6_stats(u_long off, const char *name)
 		size_t size = sizeof(rip6stat);
 
 		if (prog_sysctlbyname("net.inet6.raw6.stats", rip6stat, &size,
-		    NULL, 0) == -1)
+		    NULL, 0) == -1 && errno != ENOMEM)
 			return;
 	} else {
 		warnx("%s stats not available via KVM.", name);

Index: src/usr.bin/netstat/pfkey.c
diff -u src/usr.bin/netstat/pfkey.c:1.2 src/usr.bin/netstat/pfkey.c:1.3
--- src/usr.bin/netstat/pfkey.c:1.2	Sun Aug 18 04:14:40 2019
+++ src/usr.bin/netstat/pfkey.c	Fri Aug 28 07:23:48 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: pfkey.c,v 1.2 2019/08/18 04:14:40 kamil Exp $	*/
+/*	$NetBSD: pfkey.c,v 1.3 2020/08/28 07:23:48 ozaki-r Exp $	*/
 /*	$KAME: ipsec.c,v 1.33 2003/07/25 09:54:32 itojun Exp $	*/
 
 /*
@@ -65,7 +65,7 @@
 static char sccsid[] = "from: @(#)inet.c	8.4 (Berkeley) 4/20/94";
 #else
 #ifdef __NetBSD__
-__RCSID("$NetBSD: pfkey.c,v 1.2 2019/08/18 04:14:40 kamil Exp $");
+__RCSID("$NetBSD: pfkey.c,v 1.3 2020/08/28 07:23:48 ozaki-r Exp $");
 #endif
 #endif
 #endif /* not lint */
@@ -80,6 +80,7 @@ __RCSID("$NetBSD: pfkey.c,v 1.2 2019/08/
 #endif
 
 #include <err.h>
+#include <errno.h>
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
@@ -121,7 +122,7 @@ pfkey_stats(u_long off, const char *name
 		size_t size = sizeof(pfkeystat);
 
 		if (prog_sysctlbyname("net.key.stats", pfkeystat, &size,
-				 NULL, 0) == -1)
+				 NULL, 0) == -1 && errno != ENOMEM)
 			return;
 	} else {
 		warnx("%s stats not available via KVM.", name);
Index: src/usr.bin/netstat/pfsync.c
diff -u src/usr.bin/netstat/pfsync.c:1.2 src/usr.bin/netstat/pfsync.c:1.3
--- src/usr.bin/netstat/pfsync.c:1.2	Sun Aug 18 04:14:40 2019
+++ src/usr.bin/netstat/pfsync.c	Fri Aug 28 07:23:48 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: pfsync.c,v 1.2 2019/08/18 04:14:40 kamil Exp $	*/
+/*	$NetBSD: pfsync.c,v 1.3 2020/08/28 07:23:48 ozaki-r Exp $	*/
 
 /*
  * Copyright (c) 1983, 1988, 1993
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: pfsync.c,v 1.2 2019/08/18 04:14:40 kamil Exp $");
+__RCSID("$NetBSD: pfsync.c,v 1.3 2020/08/28 07:23:48 ozaki-r Exp $");
 #endif /* not lint */
 
 #define	_CALLOUT_PRIVATE	/* for defs in sys/callout.h */
@@ -67,6 +67,7 @@ __RCSID("$NetBSD: pfsync.c,v 1.2 2019/08
 #include <unistd.h>
 #include <stdlib.h>
 #include <err.h>
+#include <errno.h>
 #include "netstat.h"
 #include "prog_ops.h"
 
@@ -82,7 +83,7 @@ pfsync_stats(u_long off, const char *nam
 		size_t size = sizeof(pfsyncstat);
 
 		if (prog_sysctlbyname("net.inet.pfsync.stats", pfsyncstat, &size,
-				 NULL, 0) == -1)
+				 NULL, 0) == -1 && errno != ENOMEM)
 			return;
 	} else {
 		warnx("%s stats not available via KVM.", name);

Reply via email to