Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/netstat netstat: strengthen against kernel changes



details:   https://anonhg.NetBSD.org/src/rev/99ef331aa9cb
branches:  trunk
changeset: 943179:99ef331aa9cb
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Fri Aug 28 07:23:48 2020 +0000

description:
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.

diffstat:

 usr.bin/netstat/atalk.c  |   6 +++---
 usr.bin/netstat/bpf.c    |   5 +++--
 usr.bin/netstat/inet.c   |  18 +++++++++---------
 usr.bin/netstat/inet6.c  |  16 ++++++++--------
 usr.bin/netstat/pfkey.c  |   7 ++++---
 usr.bin/netstat/pfsync.c |   7 ++++---
 6 files changed, 31 insertions(+), 28 deletions(-)

diffs (269 lines):

diff -r c8e22008478a -r 99ef331aa9cb usr.bin/netstat/atalk.c
--- a/usr.bin/netstat/atalk.c   Fri Aug 28 07:03:41 2020 +0000
+++ b/usr.bin/netstat/atalk.c   Fri Aug 28 07:23:48 2020 +0000
@@ -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 @@
                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);
diff -r c8e22008478a -r 99ef331aa9cb usr.bin/netstat/bpf.c
--- a/usr.bin/netstat/bpf.c     Fri Aug 28 07:03:41 2020 +0000
+++ b/usr.bin/netstat/bpf.c     Fri Aug 28 07:23:48 2020 +0000
@@ -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 @@
        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");
diff -r c8e22008478a -r 99ef331aa9cb usr.bin/netstat/inet.c
--- a/usr.bin/netstat/inet.c    Fri Aug 28 07:03:41 2020 +0000
+++ b/usr.bin/netstat/inet.c    Fri Aug 28 07:23:48 2020 +0000
@@ -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 @@
                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 @@
                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 @@
                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 @@
                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 @@
                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 @@
                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 @@
                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);
diff -r c8e22008478a -r 99ef331aa9cb usr.bin/netstat/inet6.c
--- a/usr.bin/netstat/inet6.c   Fri Aug 28 07:03:41 2020 +0000
+++ b/usr.bin/netstat/inet6.c   Fri Aug 28 07:23:48 2020 +0000
@@ -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 @@
                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 @@
                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 @@
                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 @@
                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 @@
                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 @@
                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);
diff -r c8e22008478a -r 99ef331aa9cb usr.bin/netstat/pfkey.c
--- a/usr.bin/netstat/pfkey.c   Fri Aug 28 07:03:41 2020 +0000
+++ b/usr.bin/netstat/pfkey.c   Fri Aug 28 07:23:48 2020 +0000
@@ -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 @@
 #endif
 
 #include <err.h>
+#include <errno.h>
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
@@ -121,7 +122,7 @@
                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);
diff -r c8e22008478a -r 99ef331aa9cb usr.bin/netstat/pfsync.c
--- a/usr.bin/netstat/pfsync.c  Fri Aug 28 07:03:41 2020 +0000
+++ b/usr.bin/netstat/pfsync.c  Fri Aug 28 07:23:48 2020 +0000
@@ -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 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <err.h>
+#include <errno.h>
 #include "netstat.h"
 #include "prog_ops.h"
 
@@ -82,7 +83,7 @@
                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);



Home | Main Index | Thread Index | Old Index