Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/netstat Implemented the userland part of the BPF sta...
details: https://anonhg.NetBSD.org/src/rev/acefd05d2e72
branches: trunk
changeset: 583397:acefd05d2e72
user: rpaulo <rpaulo%NetBSD.org@localhost>
date: Thu Aug 04 19:39:40 2005 +0000
description:
Implemented the userland part of the BPF statistics and BPF peers,
net.bpf.stats and net.bpf.peers sysctls respectively. netstat(1) now
has an additional syntax:
netstat [-s] [-B] [-I Interface]
Only the super user can see a list of BPF peers with the following command:
# netstat -B
Active BPF peers
PID Int Recv Drop Capt Flags Bufsize Comm
4941 lo0 0 0 0 I--S- 262144 tcpdump
252 ex0 19668 0 5 I-RS- 32768 dhclient
And every user can see the BPF statistics with:
$ netstat -s -B
bpf:
19669 total packets received
5 total packets captured
0 total packets dropped
This idea came from FreeBSD (Christian S.J. Peron) but, currently, they
doen't have a userland utility in the base system to read the sysctls.
Reviewed by: christos@
diffstat:
usr.bin/netstat/bpf.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++
usr.bin/netstat/main.c | 19 ++++-
usr.bin/netstat/netstat.h | 6 +-
3 files changed, 179 insertions(+), 4 deletions(-)
diffs (246 lines):
diff -r 5f8cc1010ce4 -r acefd05d2e72 usr.bin/netstat/bpf.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/netstat/bpf.c Thu Aug 04 19:39:40 2005 +0000
@@ -0,0 +1,158 @@
+/* $NetBSD: bpf.c,v 1.1 2005/08/04 19:39:40 rpaulo Exp $ */
+
+/*
+ * Copyright (c) 2005 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Rui Paulo.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <kvm.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <net/if.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <net/bpfdesc.h>
+#include <net/bpf.h>
+#include "netstat.h"
+
+void
+bpf_stats(void)
+{
+ struct bpf_stat bpf_s;
+ size_t len = sizeof(bpf_s);
+
+ if (sysctlbyname("net.bpf.stats", &bpf_s, &len, NULL, 0) == -1)
+ err(1, "net.bpf.stats");
+
+ printf("bpf:\n");
+ printf("\t%lld total packets received\n", bpf_s.bs_recv);
+ printf("\t%lld total packets captured\n", bpf_s.bs_capt);
+ printf("\t%lld total packets dropped\n", bpf_s.bs_drop);
+}
+
+void
+bpf_dump(kvm_t *kd, char *interface)
+{
+ int name[CTL_MAXNAME], rc, i, cnt;
+ size_t sz;
+ u_int namelen;
+ void *v;
+ struct bpf_d_ext *dpe;
+ struct kinfo_proc *kp;
+
+ /* adapted from sockstat.c by Andrew Brown */
+
+ sz = CTL_MAXNAME;
+ if (sysctlnametomib("net.bpf.peers", &name[0], &sz) == -1)
+ err(1, "sysctlnametomib");
+ namelen = sz;
+
+ name[namelen++] = sizeof(*dpe);
+ name[namelen++] = INT_MAX;
+
+ v = NULL;
+ sz = 0;
+ do {
+ rc = sysctl(&name[0], namelen, v, &sz, NULL, 0);
+ if (rc == -1 && errno != ENOMEM)
+ err(1, "sysctl: net.bpf.peers");
+ if (rc == -1 && v != NULL) {
+ free(v);
+ v = NULL;
+ }
+ if (v == NULL) {
+ v = malloc(sz);
+ rc = -1;
+ }
+ if (v == NULL)
+ err(1, "malloc");
+ } while (rc == -1);
+
+ dpe = v;
+
+ printf("Active BPF peers\n");
+ printf("PID\tInt\tRecv Drop Capt Flags Bufsize Comm\n");
+
+#define BPFEXT(entry) dpe->entry
+
+ for (i = 0; i < (sz / sizeof(*dpe)); i++, dpe++) {
+ if (interface &&
+ strncmp(BPFEXT(bde_ifname), interface, IFNAMSIZ))
+ continue;
+
+ printf("%-7d ", BPFEXT(bde_pid));
+ printf("%-7s ",
+ (BPFEXT(bde_ifname)[0] == '\0') ? "-" :
+ BPFEXT(bde_ifname));
+
+ printf("%-8lld %-8lld %-8lld ",
+ BPFEXT(bde_rcount), BPFEXT(bde_dcount),
+ BPFEXT(bde_ccount));
+
+ switch (BPFEXT(bde_state)) {
+ case BPF_IDLE:
+ printf("I");
+ break;
+ case BPF_WAITING:
+ printf("W");
+ break;
+ case BPF_TIMED_OUT:
+ printf("T");
+ break;
+ default:
+ printf("-");
+ break;
+ }
+
+ printf("%c", BPFEXT(bde_promisc) ? 'P' : '-');
+ printf("%c", BPFEXT(bde_immediate) ? 'R' : '-');
+ printf("%c", BPFEXT(bde_seesent) ? 'S' : '-');
+ printf("%c", BPFEXT(bde_hdrcmplt) ? 'H' : '-');
+ printf(" %-8d ", BPFEXT(bde_bufsize));
+
+ kp = kvm_getprocs(kd, KERN_PROC_PID, BPFEXT(bde_pid), &cnt);
+
+ if (cnt && kd)
+ printf("%s\n", kp->kp_proc.p_comm);
+ else
+ printf("-\n");
+#undef BPFEXT
+ }
+}
diff -r 5f8cc1010ce4 -r acefd05d2e72 usr.bin/netstat/main.c
--- a/usr.bin/netstat/main.c Thu Aug 04 19:31:53 2005 +0000
+++ b/usr.bin/netstat/main.c Thu Aug 04 19:39:40 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.48 2004/10/30 20:56:20 dsl Exp $ */
+/* $NetBSD: main.c,v 1.49 2005/08/04 19:39:40 rpaulo Exp $ */
/*
* Copyright (c) 1983, 1988, 1993
@@ -39,7 +39,7 @@
#if 0
static char sccsid[] = "from: @(#)main.c 8.4 (Berkeley) 3/1/94";
#else
-__RCSID("$NetBSD: main.c,v 1.48 2004/10/30 20:56:20 dsl Exp $");
+__RCSID("$NetBSD: main.c,v 1.49 2005/08/04 19:39:40 rpaulo Exp $");
#endif
#endif /* not lint */
@@ -379,7 +379,7 @@
pcbaddr = 0;
while ((ch = getopt(argc, argv,
- "Aabdf:ghI:LliM:mN:nP:p:qrsStuvw:")) != -1)
+ "AabBdf:ghI:LliM:mN:nP:p:qrsStuvw:")) != -1)
switch (ch) {
case 'A':
Aflag = 1;
@@ -390,6 +390,9 @@
case 'b':
bflag = 1;
break;
+ case 'B':
+ Bflag = 1;
+ break;
case 'd':
dflag = 1;
break;
@@ -530,6 +533,14 @@
if (nlistf == NULL && memf == NULL)
(void)setgid(getgid());
+ if (Bflag) {
+ if (sflag)
+ bpf_stats();
+ else
+ bpf_dump(kvmd, interface);
+ exit(0);
+ }
+
if (kvm_nlist(kvmd, nl) < 0 || nl[0].n_type == 0) {
if (nlistf)
errx(1, "%s: no namelist", nlistf);
@@ -828,5 +839,7 @@
" %s [-p protocol] [-i] [-I Interface] \n", progname);
(void)fprintf(stderr,
" %s [-s] [-f address_family] [-i] [-I Interface]\n", progname);
+ (void)fprintf(stderr,
+" %s [-s] [-B] [-I interface]\n", progname);
exit(1);
}
diff -r 5f8cc1010ce4 -r acefd05d2e72 usr.bin/netstat/netstat.h
--- a/usr.bin/netstat/netstat.h Thu Aug 04 19:31:53 2005 +0000
+++ b/usr.bin/netstat/netstat.h Thu Aug 04 19:39:40 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: netstat.h,v 1.30 2004/09/04 23:35:43 manu Exp $ */
+/* $NetBSD: netstat.h,v 1.31 2005/08/04 19:39:40 rpaulo Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -35,6 +35,7 @@
int Aflag; /* show addresses of protocol control block */
int aflag; /* show all sockets (including servers) */
+int Bflag; /* show Berkeley Packet Filter information */
int bflag; /* show i/f byte stats */
int dflag; /* show i/f dropped packets */
#ifndef SMALL
@@ -152,3 +153,6 @@
void mroutepr __P((u_long, u_long, u_long, u_long));
void mrt_stats __P((u_long, u_long));
+
+void bpf_stats(void);
+void bpf_dump(kvm_t *, char *);
Home |
Main Index |
Thread Index |
Old Index