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