summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorreyk <reyk@openbsd.org>2007-12-13 20:00:53 +0000
committerreyk <reyk@openbsd.org>2007-12-13 20:00:53 +0000
commit5000ee89c8e051880c2651e17fd3b27aeb0c4917 (patch)
treee22d43093e0cb4920671131fd4e71aa5515b8201
parentSync with the mvme188 codebase, various tweaks from the last 18 months which (diff)
downloadwireguard-openbsd-5000ee89c8e051880c2651e17fd3b27aeb0c4917.tar.xz
wireguard-openbsd-5000ee89c8e051880c2651e17fd3b27aeb0c4917.zip
implement sysctls to report IP, TCP, UDP, and ICMP statistics and
change netstat to use them instead of accessing kvm for it. more protocols will be added later. discussed with deraadt@ claudio@ gilles@ ok deraadt@
-rw-r--r--lib/libc/gen/sysctl.316
-rw-r--r--sbin/sysctl/sysctl.c16
-rw-r--r--sys/netinet/icmp_var.h7
-rw-r--r--sys/netinet/in.h11
-rw-r--r--sys/netinet/ip_icmp.c7
-rw-r--r--sys/netinet/ip_input.c7
-rw-r--r--sys/netinet/tcp_usrreq.c9
-rw-r--r--sys/netinet/tcp_var.h7
-rw-r--r--sys/netinet/udp_usrreq.c9
-rw-r--r--sys/netinet/udp_var.h7
-rw-r--r--usr.bin/netstat/inet.c52
11 files changed, 121 insertions, 27 deletions
diff --git a/lib/libc/gen/sysctl.3 b/lib/libc/gen/sysctl.3
index 73f7efe7888..125814d387a 100644
--- a/lib/libc/gen/sysctl.3
+++ b/lib/libc/gen/sysctl.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sysctl.3,v 1.175 2007/09/25 16:12:27 jmc Exp $
+.\" $OpenBSD: sysctl.3,v 1.176 2007/12/13 20:00:53 reyk Exp $
.\"
.\" Copyright (c) 1993
.\" The Regents of the University of California. All rights reserved.
@@ -27,7 +27,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd $Mdocdate: September 25 2007 $
+.Dd $Mdocdate: December 13 2007 $
.Dt SYSCTL 3
.Os
.Sh NAME
@@ -1095,6 +1095,7 @@ The currently defined protocols and names are:
.It icmp maskrepl integer yes
.It icmp rediraccept integer yes
.It icmp redirtimeout integer yes
+.It icmp stats structure no
.It icmp tstamprepl integer yes
.It ip directed-broadcast integer yes
.It ip encdebug integer yes
@@ -1124,6 +1125,7 @@ The currently defined protocols and names are:
.It ip portlast integer yes
.It ip redirect integer yes
.It ip sourceroute integer yes
+.It ip stats structure no
.It ip ttl integer yes
.It ipcomp enable integer yes
.It ipip allow integer yes
@@ -1144,12 +1146,14 @@ The currently defined protocols and names are:
.It tcp sack integer yes
.It tcp sendspace integer yes
.It tcp slowhz integer no
+.It tcp stats structure no
.It tcp synbucketlimit integer yes
.It tcp syncachelimit integer yes
.It udp baddynamic array yes
.It udp checksum integer yes
.It udp recvspace integer yes
.It udp sendspace integer yes
+.It udp stats structure no
.El
.Pp
The variables are as follows:
@@ -1248,6 +1252,8 @@ and the variable is meaningful on IP hosts only.
This variable specifies the lifetime of routing entries generated by incoming
ICMP redirects.
The default timeout is 10 minutes.
+.It Li icmp.stats
+Returns the ICMP statistics in a struct icmpstat.
.It Li icmp.tstamprepl
If set to 1, reply to ICMP timestamp requests.
If set to 0, ignore timestamp requests.
@@ -1434,6 +1440,8 @@ the host.
As detailed in
.Xr securelevel 7 ,
this variable may not be changed if the securelevel is \*(Gt 0.
+.It Li ip.stats
+Returns the IP statistics in a struct ipstat.
.It Li ip.ttl
The maximum time-to-live (hop count) value for an
.Tn IP
@@ -1527,6 +1535,8 @@ The units for tcp.keepidle and tcp.keepintvl; those variables are in ticks
of a clock that ticks tcp.slowhz times per second.
(That is, their values must be divided by the tcp.slowhz value to get times
in seconds.)
+.It Li tcp.stats
+Returns the TCP statistics in a struct tcpstat.
.It Li tcp.synbucketlimit
The maximum number of entries allowed per hash bucket in the TCP SYN cache.
.It Li tcp.syncachelimit
@@ -1552,6 +1562,8 @@ receive buffer size.
Returns the default
.Tn UDP
send buffer size.
+.It Li udp.stats
+Returns the UDP statistics in a struct udpstat.
.El
.It Dv PF_INET6
Get or set various global information about IPv6
diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c
index 62892805803..a3864058fc5 100644
--- a/sbin/sysctl/sysctl.c
+++ b/sbin/sysctl/sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysctl.c,v 1.151 2007/11/26 13:36:33 deraadt Exp $ */
+/* $OpenBSD: sysctl.c,v 1.152 2007/12/13 20:00:53 reyk Exp $ */
/* $NetBSD: sysctl.c,v 1.9 1995/09/30 07:12:50 thorpej Exp $ */
/*
@@ -40,7 +40,7 @@ static const char copyright[] =
#if 0
static const char sccsid[] = "@(#)sysctl.c 8.5 (Berkeley) 5/9/95";
#else
-static const char rcsid[] = "$OpenBSD: sysctl.c,v 1.151 2007/11/26 13:36:33 deraadt Exp $";
+static const char rcsid[] = "$OpenBSD: sysctl.c,v 1.152 2007/12/13 20:00:53 reyk Exp $";
#endif
#endif /* not lint */
@@ -514,6 +514,18 @@ parse(char *string, int flags)
break;
case CTL_NET:
+ if (mib[1] == PF_INET &&
+ ((mib[2] == IPPROTO_IP && mib[3] == IPCTL_STATS) ||
+ (mib[2] == IPPROTO_TCP && mib[3] == TCPCTL_STATS) ||
+ (mib[2] == IPPROTO_UDP && mib[3] == UDPCTL_STATS) ||
+ (mib[2] == IPPROTO_ICMP && mib[3] == ICMPCTL_STATS))) {
+ if (flags == 0)
+ return;
+ warnx("use netstat to view %s information",
+ string);
+ return;
+ }
+
if (mib[1] == PF_INET) {
len = sysctl_inet(string, &bufp, mib, flags, &type);
if (len < 0)
diff --git a/sys/netinet/icmp_var.h b/sys/netinet/icmp_var.h
index b759744656a..c94acb94503 100644
--- a/sys/netinet/icmp_var.h
+++ b/sys/netinet/icmp_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: icmp_var.h,v 1.12 2004/02/15 11:16:08 markus Exp $ */
+/* $OpenBSD: icmp_var.h,v 1.13 2007/12/13 20:00:53 reyk Exp $ */
/* $NetBSD: icmp_var.h,v 1.8 1995/03/26 20:32:19 jtc Exp $ */
/*
@@ -64,7 +64,8 @@ struct icmpstat {
#define ICMPCTL_REDIRACCEPT 4 /* Accept redirects from routers */
#define ICMPCTL_REDIRTIMEOUT 5 /* Remove routes added via redirects */
#define ICMPCTL_TSTAMPREPL 6 /* allow replies to timestamp requests */
-#define ICMPCTL_MAXID 7
+#define ICMPCTL_STATS 7 /* ICMP statistics */
+#define ICMPCTL_MAXID 8
#define ICMPCTL_NAMES { \
{ 0, 0 }, \
@@ -74,6 +75,7 @@ struct icmpstat {
{ "rediraccept", CTLTYPE_INT }, \
{ "redirtimeout", CTLTYPE_INT }, \
{ "tstamprepl", CTLTYPE_INT }, \
+ { "stats", CTLTYPE_STRUCT } \
}
#define ICMPCTL_VARS { \
@@ -84,6 +86,7 @@ struct icmpstat {
&icmp_rediraccept, \
NULL, \
&icmptstamprepl, \
+ NULL \
}
#ifdef _KERNEL
diff --git a/sys/netinet/in.h b/sys/netinet/in.h
index 5cfdf0e66c2..1a2e3a98897 100644
--- a/sys/netinet/in.h
+++ b/sys/netinet/in.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: in.h,v 1.74 2007/09/18 18:56:02 markus Exp $ */
+/* $OpenBSD: in.h,v 1.75 2007/12/13 20:00:53 reyk Exp $ */
/* $NetBSD: in.h,v 1.20 1996/02/13 23:41:47 christos Exp $ */
/*
@@ -482,7 +482,8 @@ struct ip_mreq {
#define IPCTL_IFQUEUE 30
#define IPCTL_MFORWARDING 31
#define IPCTL_MULTIPATH 32
-#define IPCTL_MAXID 33
+#define IPCTL_STATS 33 /* IP statistics */
+#define IPCTL_MAXID 34
#define IPCTL_NAMES { \
{ 0, 0 }, \
@@ -517,7 +518,8 @@ struct ip_mreq {
{ "ipsec-comp-alg", CTLTYPE_STRING }, \
{ "ifq", CTLTYPE_NODE }, \
{ "mforwarding", CTLTYPE_INT }, \
- { "multipath", CTLTYPE_INT } \
+ { "multipath", CTLTYPE_INT }, \
+ { "stats", CTLTYPE_STRUCT } \
}
#define IPCTL_VARS { \
NULL, \
@@ -552,7 +554,8 @@ struct ip_mreq {
NULL, \
NULL, \
&ipmforwarding, \
- &ipmultipath \
+ &ipmultipath, \
+ NULL \
}
/* INET6 stuff */
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index f838357521d..bd727af3b58 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_icmp.c,v 1.77 2007/11/24 12:59:28 jmc Exp $ */
+/* $OpenBSD: ip_icmp.c,v 1.78 2007/12/13 20:00:53 reyk Exp $ */
/* $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $ */
/*
@@ -842,6 +842,11 @@ icmp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
break;
}
+ case ICMPCTL_STATS:
+ if (newp != NULL)
+ return (EPERM);
+ return (sysctl_struct(oldp, oldlenp, newp, newlen,
+ &icmpstat, sizeof(icmpstat)));
default:
if (name[0] < ICMPCTL_MAXID)
return (sysctl_int_arr(icmpctl_vars, name, namelen,
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index c36cd44fe0e..8bbe357c553 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_input.c,v 1.154 2007/10/29 16:19:23 chl Exp $ */
+/* $OpenBSD: ip_input.c,v 1.155 2007/12/13 20:00:53 reyk Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
@@ -1622,6 +1622,11 @@ ip_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
case IPCTL_IFQUEUE:
return (sysctl_ifq(name + 1, namelen - 1,
oldp, oldlenp, newp, newlen, &ipintrq));
+ case IPCTL_STATS:
+ if (newp != NULL)
+ return (EPERM);
+ return (sysctl_struct(oldp, oldlenp, newp, newlen,
+ &ipstat, sizeof(ipstat)));
default:
if (name[0] < IPCTL_MAXID)
return (sysctl_int_arr(ipctl_vars, name, namelen,
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 13dd15cbc67..2e1750e00af 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_usrreq.c,v 1.94 2007/11/27 17:23:23 deraadt Exp $ */
+/* $OpenBSD: tcp_usrreq.c,v 1.95 2007/12/13 20:00:53 reyk Exp $ */
/* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */
/*
@@ -954,6 +954,13 @@ tcp_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
}
return (0);
#endif
+
+ case TCPCTL_STATS:
+ if (newp != NULL)
+ return (EPERM);
+ return (sysctl_struct(oldp, oldlenp, newp, newlen,
+ &tcpstat, sizeof(tcpstat)));
+
default:
if (name[0] < TCPCTL_MAXID)
return (sysctl_int_arr(tcpctl_vars, name, namelen,
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index ca90b1b8c5b..cf2859b19d2 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_var.h,v 1.83 2007/06/25 12:17:43 markus Exp $ */
+/* $OpenBSD: tcp_var.h,v 1.84 2007/12/13 20:00:53 reyk Exp $ */
/* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */
/*
@@ -494,7 +494,8 @@ struct tcpstat {
#define TCPCTL_REASS_LIMIT 18 /* max entries for tcp reass queues */
#define TCPCTL_DROP 19 /* drop tcp connection */
#define TCPCTL_SACKHOLE_LIMIT 20 /* max entries for tcp sack queues */
-#define TCPCTL_MAXID 21
+#define TCPCTL_STATS 21 /* TCP statistics */
+#define TCPCTL_MAXID 22
#define TCPCTL_NAMES { \
{ 0, 0 }, \
@@ -518,6 +519,7 @@ struct tcpstat {
{ "reasslimit", CTLTYPE_INT }, \
{ "drop", CTLTYPE_STRUCT }, \
{ "sackholelimit", CTLTYPE_INT }, \
+ { "stats", CTLTYPE_STRUCT } \
}
#define TCPCTL_VARS { \
@@ -541,6 +543,7 @@ struct tcpstat {
&tcp_do_rfc3390, \
NULL, \
NULL, \
+ NULL, \
NULL \
}
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 05ec0e1fe6f..7f4370c04b1 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: udp_usrreq.c,v 1.114 2007/06/11 11:29:35 henning Exp $ */
+/* $OpenBSD: udp_usrreq.c,v 1.115 2007/12/13 20:00:53 reyk Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
/*
@@ -1236,6 +1236,13 @@ udp_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
case UDPCTL_BADDYNAMIC:
return (sysctl_struct(oldp, oldlenp, newp, newlen,
baddynamicports.udp, sizeof(baddynamicports.udp)));
+
+ case UDPCTL_STATS:
+ if (newp != NULL)
+ return (EPERM);
+ return (sysctl_struct(oldp, oldlenp, newp, newlen,
+ &udpstat, sizeof(udpstat)));
+
default:
if (name[0] < UDPCTL_MAXID)
return (sysctl_int_arr(udpctl_vars, name, namelen,
diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h
index 8c385683949..943711bf1e6 100644
--- a/sys/netinet/udp_var.h
+++ b/sys/netinet/udp_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: udp_var.h,v 1.16 2004/02/17 12:07:45 markus Exp $ */
+/* $OpenBSD: udp_var.h,v 1.17 2007/12/13 20:00:53 reyk Exp $ */
/* $NetBSD: udp_var.h,v 1.12 1996/02/13 23:44:41 christos Exp $ */
/*
@@ -77,7 +77,8 @@ struct udpstat {
#define UDPCTL_BADDYNAMIC 2 /* return bad dynamic port bitmap */
#define UDPCTL_RECVSPACE 3 /* receive buffer space */
#define UDPCTL_SENDSPACE 4 /* send buffer space */
-#define UDPCTL_MAXID 5
+#define UDPCTL_STATS 5 /* UDP statistics */
+#define UDPCTL_MAXID 6
#define UDPCTL_NAMES { \
{ 0, 0 }, \
@@ -85,6 +86,7 @@ struct udpstat {
{ "baddynamic", CTLTYPE_STRUCT }, \
{ "recvspace", CTLTYPE_INT }, \
{ "sendspace", CTLTYPE_INT }, \
+ { "stats", CTLTYPE_STRUCT } \
}
#define UDPCTL_VARS { \
@@ -93,6 +95,7 @@ struct udpstat {
NULL, \
&udp_recvspace, \
&udp_sendspace, \
+ NULL \
}
#ifdef _KERNEL
diff --git a/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c
index 2ef4ac59c02..f3db9d55909 100644
--- a/usr.bin/netstat/inet.c
+++ b/usr.bin/netstat/inet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: inet.c,v 1.101 2007/09/03 06:10:54 joel Exp $ */
+/* $OpenBSD: inet.c,v 1.102 2007/12/13 20:00:53 reyk Exp $ */
/* $NetBSD: inet.c,v 1.14 1995/10/03 21:42:37 thorpej Exp $ */
/*
@@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "from: @(#)inet.c 8.4 (Berkeley) 4/20/94";
#else
-static const char *rcsid = "$OpenBSD: inet.c,v 1.101 2007/09/03 06:10:54 joel Exp $";
+static const char *rcsid = "$OpenBSD: inet.c,v 1.102 2007/12/13 20:00:53 reyk Exp $";
#endif
#endif /* not lint */
@@ -44,6 +44,7 @@ static const char *rcsid = "$OpenBSD: inet.c,v 1.101 2007/09/03 06:10:54 joel Ex
#include <sys/socketvar.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
+#include <sys/sysctl.h>
#include <net/route.h>
#include <netinet/in.h>
@@ -245,12 +246,20 @@ void
tcp_stats(u_long off, char *name)
{
struct tcpstat tcpstat;
+ size_t len;
+ int mib[] = { CTL_NET, AF_INET, IPPROTO_TCP, TCPCTL_STATS };
if (off == 0)
return;
- printf("%s:\n", name);
- kread(off, &tcpstat, sizeof (tcpstat));
+ len = sizeof(tcpstat);
+ if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
+ &tcpstat, &len, NULL, 0) == -1) {
+ warn(name);
+ return;
+ }
+
+ printf("%s:\n", name);
#define p(f, m) if (tcpstat.f || sflag <= 1) \
printf(m, tcpstat.f, plural(tcpstat.f))
#define p1(f, m) if (tcpstat.f || sflag <= 1) \
@@ -371,10 +380,19 @@ udp_stats(u_long off, char *name)
{
struct udpstat udpstat;
u_long delivered;
+ size_t len;
+ int mib[] = { CTL_NET, AF_INET, IPPROTO_UDP, UDPCTL_STATS };
if (off == 0)
return;
- kread(off, &udpstat, sizeof (udpstat));
+
+ len = sizeof(udpstat);
+ if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
+ &udpstat, &len, NULL, 0) == -1) {
+ warn(name);
+ return;
+ }
+
printf("%s:\n", name);
#define p(f, m) if (udpstat.f || sflag <= 1) \
printf(m, udpstat.f, plural(udpstat.f))
@@ -411,12 +429,20 @@ void
ip_stats(u_long off, char *name)
{
struct ipstat ipstat;
+ size_t len;
+ int mib[] = { CTL_NET, AF_INET, IPPROTO_IP, IPCTL_STATS };
if (off == 0)
return;
- kread(off, &ipstat, sizeof (ipstat));
- printf("%s:\n", name);
+ len = sizeof(ipstat);
+ if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
+ &ipstat, &len, NULL, 0) == -1) {
+ warn(name);
+ return;
+ }
+
+ printf("%s:\n", name);
#define p(f, m) if (ipstat.f || sflag <= 1) \
printf(m, ipstat.f, plural(ipstat.f))
#define p1(f, m) if (ipstat.f || sflag <= 1) \
@@ -510,12 +536,20 @@ icmp_stats(u_long off, char *name)
{
struct icmpstat icmpstat;
int i, first;
+ int mib[] = { CTL_NET, AF_INET, IPPROTO_ICMP, ICMPCTL_STATS };
+ size_t len;
if (off == 0)
return;
- kread(off, &icmpstat, sizeof (icmpstat));
- printf("%s:\n", name);
+ len = sizeof(icmpstat);
+ if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
+ &icmpstat, &len, NULL, 0) == -1) {
+ warn(name);
+ return;
+ }
+
+ printf("%s:\n", name);
#define p(f, m) if (icmpstat.f || sflag <= 1) \
printf(m, icmpstat.f, plural(icmpstat.f))