16b463eedSChristian S.J. Peron /*- 2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 31de7b4b8SPedro F. Giffuni * 46b463eedSChristian S.J. Peron * Copyright (c) 2005 Christian S.J. Peron 56b463eedSChristian S.J. Peron * All rights reserved. 66b463eedSChristian S.J. Peron * 76b463eedSChristian S.J. Peron * Redistribution and use in source and binary forms, with or without 86b463eedSChristian S.J. Peron * modification, are permitted provided that the following conditions 96b463eedSChristian S.J. Peron * are met: 106b463eedSChristian S.J. Peron * 1. Redistributions of source code must retain the above copyright 116b463eedSChristian S.J. Peron * notice, this list of conditions and the following disclaimer. 126b463eedSChristian S.J. Peron * 2. Redistributions in binary form must reproduce the above copyright 136b463eedSChristian S.J. Peron * notice, this list of conditions and the following disclaimer in the 146b463eedSChristian S.J. Peron * documentation and/or other materials provided with the distribution. 156b463eedSChristian S.J. Peron * 166b463eedSChristian S.J. Peron * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 176b463eedSChristian S.J. Peron * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 186b463eedSChristian S.J. Peron * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 196b463eedSChristian S.J. Peron * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 206b463eedSChristian S.J. Peron * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 216b463eedSChristian S.J. Peron * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 226b463eedSChristian S.J. Peron * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 236b463eedSChristian S.J. Peron * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 246b463eedSChristian S.J. Peron * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 256b463eedSChristian S.J. Peron * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 266b463eedSChristian S.J. Peron * SUCH DAMAGE. 276b463eedSChristian S.J. Peron */ 2865475bc8SDavid E. O'Brien 2965475bc8SDavid E. O'Brien #include <sys/cdefs.h> 3065475bc8SDavid E. O'Brien __FBSDID("$FreeBSD$"); 3165475bc8SDavid E. O'Brien 326b463eedSChristian S.J. Peron #include <sys/types.h> 336b463eedSChristian S.J. Peron #include <sys/protosw.h> 346b463eedSChristian S.J. Peron #include <sys/socket.h> 35feda1a43SJohn Baldwin #include <sys/socketvar.h> 366b463eedSChristian S.J. Peron #include <sys/sysctl.h> 376b463eedSChristian S.J. Peron #include <sys/param.h> 386b463eedSChristian S.J. Peron #include <sys/user.h> 396b463eedSChristian S.J. Peron 406b463eedSChristian S.J. Peron #include <net/if.h> 41560a54e1SJung-uk Kim #include <net/bpf.h> 426b463eedSChristian S.J. Peron #include <net/bpfdesc.h> 436b463eedSChristian S.J. Peron #include <arpa/inet.h> 446b463eedSChristian S.J. Peron 456b463eedSChristian S.J. Peron #include <err.h> 466b463eedSChristian S.J. Peron #include <errno.h> 477b95a1ebSYaroslav Tykhiy #include <stdint.h> 486b463eedSChristian S.J. Peron #include <stdio.h> 496b463eedSChristian S.J. Peron #include <stdlib.h> 50ade9ccfeSMarcel Moolenaar #include <stdbool.h> 516b463eedSChristian S.J. Peron #include <string.h> 52821df508SXin LI #include <unistd.h> 53ade9ccfeSMarcel Moolenaar #include <libxo/xo.h> 546b463eedSChristian S.J. Peron 556b463eedSChristian S.J. Peron #include "netstat.h" 566b463eedSChristian S.J. Peron 576b463eedSChristian S.J. Peron /* print bpf stats */ 586b463eedSChristian S.J. Peron 596b463eedSChristian S.J. Peron static char * 606b463eedSChristian S.J. Peron bpf_pidname(pid_t pid) 616b463eedSChristian S.J. Peron { 626b463eedSChristian S.J. Peron struct kinfo_proc newkp; 636b463eedSChristian S.J. Peron int error, mib[4]; 646b463eedSChristian S.J. Peron size_t size; 656b463eedSChristian S.J. Peron 666b463eedSChristian S.J. Peron mib[0] = CTL_KERN; 676b463eedSChristian S.J. Peron mib[1] = KERN_PROC; 686b463eedSChristian S.J. Peron mib[2] = KERN_PROC_PID; 696b463eedSChristian S.J. Peron mib[3] = pid; 706b463eedSChristian S.J. Peron size = sizeof(newkp); 716b463eedSChristian S.J. Peron error = sysctl(mib, 4, &newkp, &size, NULL, 0); 726f798df5SChristian S.J. Peron if (error < 0) { 73ade9ccfeSMarcel Moolenaar xo_warn("kern.proc.pid failed"); 746b463eedSChristian S.J. Peron return (strdup("??????")); 756f798df5SChristian S.J. Peron } 766b463eedSChristian S.J. Peron return (strdup(newkp.ki_comm)); 776b463eedSChristian S.J. Peron } 786b463eedSChristian S.J. Peron 796b463eedSChristian S.J. Peron static void 806b463eedSChristian S.J. Peron bpf_flags(struct xbpf_d *bd, char *flagbuf) 816b463eedSChristian S.J. Peron { 826b463eedSChristian S.J. Peron 836b463eedSChristian S.J. Peron *flagbuf++ = bd->bd_promisc ? 'p' : '-'; 846b463eedSChristian S.J. Peron *flagbuf++ = bd->bd_immediate ? 'i' : '-'; 856b463eedSChristian S.J. Peron *flagbuf++ = bd->bd_hdrcmplt ? '-' : 'f'; 86560a54e1SJung-uk Kim *flagbuf++ = (bd->bd_direction == BPF_D_IN) ? '-' : 87560a54e1SJung-uk Kim ((bd->bd_direction == BPF_D_OUT) ? 'o' : 's'); 88560a54e1SJung-uk Kim *flagbuf++ = bd->bd_feedback ? 'b' : '-'; 896b463eedSChristian S.J. Peron *flagbuf++ = bd->bd_async ? 'a' : '-'; 906b463eedSChristian S.J. Peron *flagbuf++ = bd->bd_locked ? 'l' : '-'; 916b463eedSChristian S.J. Peron *flagbuf++ = '\0'; 92ade9ccfeSMarcel Moolenaar 93ade9ccfeSMarcel Moolenaar if (bd->bd_promisc) 94ade9ccfeSMarcel Moolenaar xo_emit("{e:promiscuous/}"); 95ade9ccfeSMarcel Moolenaar if (bd->bd_immediate) 96ade9ccfeSMarcel Moolenaar xo_emit("{e:immediate/}"); 97ade9ccfeSMarcel Moolenaar if (bd->bd_hdrcmplt) 98ade9ccfeSMarcel Moolenaar xo_emit("{e:header-complete/}"); 99ade9ccfeSMarcel Moolenaar xo_emit("{e:direction}", (bd->bd_direction == BPF_D_IN) ? "input" : 100ade9ccfeSMarcel Moolenaar (bd->bd_direction == BPF_D_OUT) ? "output" : "bidirectional"); 101ade9ccfeSMarcel Moolenaar if (bd->bd_feedback) 102ade9ccfeSMarcel Moolenaar xo_emit("{e:feedback/}"); 103ade9ccfeSMarcel Moolenaar if (bd->bd_async) 104ade9ccfeSMarcel Moolenaar xo_emit("{e:async/}"); 105ade9ccfeSMarcel Moolenaar if (bd->bd_locked) 106ade9ccfeSMarcel Moolenaar xo_emit("{e:locked/}"); 1076b463eedSChristian S.J. Peron } 1086b463eedSChristian S.J. Peron 1096b463eedSChristian S.J. Peron void 11004f7f23bSYaroslav Tykhiy bpf_stats(char *ifname) 1116b463eedSChristian S.J. Peron { 1120e37f3e1SChristian S.J. Peron struct xbpf_d *d, *bd, zerostat; 1136b463eedSChristian S.J. Peron char *pname, flagbuf[12]; 1146b463eedSChristian S.J. Peron size_t size; 1156b463eedSChristian S.J. Peron 1160e37f3e1SChristian S.J. Peron if (zflag) { 1170e37f3e1SChristian S.J. Peron bzero(&zerostat, sizeof(zerostat)); 1180e37f3e1SChristian S.J. Peron if (sysctlbyname("net.bpf.stats", NULL, NULL, 1190e37f3e1SChristian S.J. Peron &zerostat, sizeof(zerostat)) < 0) 120ade9ccfeSMarcel Moolenaar xo_warn("failed to zero bpf counters"); 1210e37f3e1SChristian S.J. Peron return; 1220e37f3e1SChristian S.J. Peron } 1236b463eedSChristian S.J. Peron if (sysctlbyname("net.bpf.stats", NULL, &size, 1246b463eedSChristian S.J. Peron NULL, 0) < 0) { 125ade9ccfeSMarcel Moolenaar xo_warn("net.bpf.stats"); 1266b463eedSChristian S.J. Peron return; 1276b463eedSChristian S.J. Peron } 12815f3d81fSChristian S.J. Peron if (size == 0) 12915f3d81fSChristian S.J. Peron return; 1306b463eedSChristian S.J. Peron bd = malloc(size); 1316b463eedSChristian S.J. Peron if (bd == NULL) { 132ade9ccfeSMarcel Moolenaar xo_warn("malloc failed"); 1336b463eedSChristian S.J. Peron return; 1346b463eedSChristian S.J. Peron } 1356b463eedSChristian S.J. Peron if (sysctlbyname("net.bpf.stats", bd, &size, 1366b463eedSChristian S.J. Peron NULL, 0) < 0) { 137ade9ccfeSMarcel Moolenaar xo_warn("net.bpf.stats"); 1386b463eedSChristian S.J. Peron free(bd); 1396b463eedSChristian S.J. Peron return; 1406b463eedSChristian S.J. Peron } 141ade9ccfeSMarcel Moolenaar xo_emit("{T:/%5s} {T:/%6s} {T:/%7s} {T:/%9s} {T:/%9s} {T:/%9s} " 142ade9ccfeSMarcel Moolenaar "{T:/%5s} {T:/%5s} {T:/%s}\n", 143ade9ccfeSMarcel Moolenaar "Pid", "Netif", "Flags", "Recv", "Drop", "Match", 144ade9ccfeSMarcel Moolenaar "Sblen", "Hblen", "Command"); 145ade9ccfeSMarcel Moolenaar xo_open_container("bpf-statistics"); 146ade9ccfeSMarcel Moolenaar xo_open_list("bpf-entry"); 1476b463eedSChristian S.J. Peron for (d = &bd[0]; d < &bd[size / sizeof(*d)]; d++) { 148582908b3SChristian S.J. Peron if (d->bd_structsize != sizeof(*d)) { 149ade9ccfeSMarcel Moolenaar xo_warnx("bpf_stats_extended: version mismatch"); 150582908b3SChristian S.J. Peron return; 151582908b3SChristian S.J. Peron } 15204f7f23bSYaroslav Tykhiy if (ifname && strcmp(ifname, d->bd_ifname) != 0) 1536b463eedSChristian S.J. Peron continue; 154ade9ccfeSMarcel Moolenaar xo_open_instance("bpf-entry"); 1556b463eedSChristian S.J. Peron pname = bpf_pidname(d->bd_pid); 156ade9ccfeSMarcel Moolenaar xo_emit("{k:pid/%5d} {k:interface-name/%6s} ", 157ade9ccfeSMarcel Moolenaar d->bd_pid, d->bd_ifname); 158ade9ccfeSMarcel Moolenaar bpf_flags(d, flagbuf); 159ade9ccfeSMarcel Moolenaar xo_emit("{d:flags/%7s} {:received-packets/%9ju} " 160ade9ccfeSMarcel Moolenaar "{:dropped-packets/%9ju} {:filter-packets/%9ju} " 161ade9ccfeSMarcel Moolenaar "{:store-buffer-length/%5d} {:hold-buffer-length/%5d} " 162ade9ccfeSMarcel Moolenaar "{:process/%s}\n", 163ade9ccfeSMarcel Moolenaar flagbuf, (uintmax_t)d->bd_rcount, (uintmax_t)d->bd_dcount, 164ade9ccfeSMarcel Moolenaar (uintmax_t)d->bd_fcount, d->bd_slen, d->bd_hlen, pname); 1656b463eedSChristian S.J. Peron free(pname); 166ade9ccfeSMarcel Moolenaar xo_close_instance("bpf-entry"); 1676b463eedSChristian S.J. Peron } 168ade9ccfeSMarcel Moolenaar xo_close_list("bpf-entry"); 169ade9ccfeSMarcel Moolenaar xo_close_container("bpf-statistics"); 17048d91509SChristian S.J. Peron free(bd); 1716b463eedSChristian S.J. Peron } 172