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 296b463eedSChristian S.J. Peron #include <sys/types.h> 306b463eedSChristian S.J. Peron #include <sys/protosw.h> 316b463eedSChristian S.J. Peron #include <sys/socket.h> 32feda1a43SJohn Baldwin #include <sys/socketvar.h> 336b463eedSChristian S.J. Peron #include <sys/sysctl.h> 346b463eedSChristian S.J. Peron #include <sys/param.h> 356b463eedSChristian S.J. Peron #include <sys/user.h> 366b463eedSChristian S.J. Peron 376b463eedSChristian S.J. Peron #include <net/if.h> 38560a54e1SJung-uk Kim #include <net/bpf.h> 396b463eedSChristian S.J. Peron #include <net/bpfdesc.h> 406b463eedSChristian S.J. Peron #include <arpa/inet.h> 416b463eedSChristian S.J. Peron 426b463eedSChristian S.J. Peron #include <errno.h> 437b95a1ebSYaroslav Tykhiy #include <stdint.h> 446b463eedSChristian S.J. Peron #include <stdio.h> 456b463eedSChristian S.J. Peron #include <stdlib.h> 46ade9ccfeSMarcel Moolenaar #include <stdbool.h> 476b463eedSChristian S.J. Peron #include <string.h> 48821df508SXin LI #include <unistd.h> 49ade9ccfeSMarcel Moolenaar #include <libxo/xo.h> 506b463eedSChristian S.J. Peron 516b463eedSChristian S.J. Peron #include "netstat.h" 526b463eedSChristian S.J. Peron 536b463eedSChristian S.J. Peron /* print bpf stats */ 546b463eedSChristian S.J. Peron 556b463eedSChristian S.J. Peron static char * 566b463eedSChristian S.J. Peron bpf_pidname(pid_t pid) 576b463eedSChristian S.J. Peron { 586b463eedSChristian S.J. Peron struct kinfo_proc newkp; 596b463eedSChristian S.J. Peron int error, mib[4]; 606b463eedSChristian S.J. Peron size_t size; 616b463eedSChristian S.J. Peron 626b463eedSChristian S.J. Peron mib[0] = CTL_KERN; 636b463eedSChristian S.J. Peron mib[1] = KERN_PROC; 646b463eedSChristian S.J. Peron mib[2] = KERN_PROC_PID; 656b463eedSChristian S.J. Peron mib[3] = pid; 666b463eedSChristian S.J. Peron size = sizeof(newkp); 676b463eedSChristian S.J. Peron error = sysctl(mib, 4, &newkp, &size, NULL, 0); 686f798df5SChristian S.J. Peron if (error < 0) { 69ade9ccfeSMarcel Moolenaar xo_warn("kern.proc.pid failed"); 706b463eedSChristian S.J. Peron return (strdup("??????")); 716f798df5SChristian S.J. Peron } 726b463eedSChristian S.J. Peron return (strdup(newkp.ki_comm)); 736b463eedSChristian S.J. Peron } 746b463eedSChristian S.J. Peron 756b463eedSChristian S.J. Peron static void 766b463eedSChristian S.J. Peron bpf_flags(struct xbpf_d *bd, char *flagbuf) 776b463eedSChristian S.J. Peron { 786b463eedSChristian S.J. Peron 796b463eedSChristian S.J. Peron *flagbuf++ = bd->bd_promisc ? 'p' : '-'; 806b463eedSChristian S.J. Peron *flagbuf++ = bd->bd_immediate ? 'i' : '-'; 816b463eedSChristian S.J. Peron *flagbuf++ = bd->bd_hdrcmplt ? '-' : 'f'; 82560a54e1SJung-uk Kim *flagbuf++ = (bd->bd_direction == BPF_D_IN) ? '-' : 83560a54e1SJung-uk Kim ((bd->bd_direction == BPF_D_OUT) ? 'o' : 's'); 84560a54e1SJung-uk Kim *flagbuf++ = bd->bd_feedback ? 'b' : '-'; 856b463eedSChristian S.J. Peron *flagbuf++ = bd->bd_async ? 'a' : '-'; 866b463eedSChristian S.J. Peron *flagbuf++ = bd->bd_locked ? 'l' : '-'; 876b463eedSChristian S.J. Peron *flagbuf++ = '\0'; 88ade9ccfeSMarcel Moolenaar 89ade9ccfeSMarcel Moolenaar if (bd->bd_promisc) 90ade9ccfeSMarcel Moolenaar xo_emit("{e:promiscuous/}"); 91ade9ccfeSMarcel Moolenaar if (bd->bd_immediate) 92ade9ccfeSMarcel Moolenaar xo_emit("{e:immediate/}"); 93ade9ccfeSMarcel Moolenaar if (bd->bd_hdrcmplt) 94ade9ccfeSMarcel Moolenaar xo_emit("{e:header-complete/}"); 95ade9ccfeSMarcel Moolenaar xo_emit("{e:direction}", (bd->bd_direction == BPF_D_IN) ? "input" : 96ade9ccfeSMarcel Moolenaar (bd->bd_direction == BPF_D_OUT) ? "output" : "bidirectional"); 97ade9ccfeSMarcel Moolenaar if (bd->bd_feedback) 98ade9ccfeSMarcel Moolenaar xo_emit("{e:feedback/}"); 99ade9ccfeSMarcel Moolenaar if (bd->bd_async) 100ade9ccfeSMarcel Moolenaar xo_emit("{e:async/}"); 101ade9ccfeSMarcel Moolenaar if (bd->bd_locked) 102ade9ccfeSMarcel Moolenaar xo_emit("{e:locked/}"); 1036b463eedSChristian S.J. Peron } 1046b463eedSChristian S.J. Peron 1056b463eedSChristian S.J. Peron void 10604f7f23bSYaroslav Tykhiy bpf_stats(char *ifname) 1076b463eedSChristian S.J. Peron { 1080e37f3e1SChristian S.J. Peron struct xbpf_d *d, *bd, zerostat; 1096b463eedSChristian S.J. Peron char *pname, flagbuf[12]; 1106b463eedSChristian S.J. Peron size_t size; 1116b463eedSChristian S.J. Peron 1120e37f3e1SChristian S.J. Peron if (zflag) { 1130e37f3e1SChristian S.J. Peron bzero(&zerostat, sizeof(zerostat)); 1140e37f3e1SChristian S.J. Peron if (sysctlbyname("net.bpf.stats", NULL, NULL, 1150e37f3e1SChristian S.J. Peron &zerostat, sizeof(zerostat)) < 0) 116ade9ccfeSMarcel Moolenaar xo_warn("failed to zero bpf counters"); 1170e37f3e1SChristian S.J. Peron return; 1180e37f3e1SChristian S.J. Peron } 1196b463eedSChristian S.J. Peron if (sysctlbyname("net.bpf.stats", NULL, &size, 1206b463eedSChristian S.J. Peron NULL, 0) < 0) { 121ade9ccfeSMarcel Moolenaar xo_warn("net.bpf.stats"); 1226b463eedSChristian S.J. Peron return; 1236b463eedSChristian S.J. Peron } 12415f3d81fSChristian S.J. Peron if (size == 0) 12515f3d81fSChristian S.J. Peron return; 1266b463eedSChristian S.J. Peron bd = malloc(size); 1276b463eedSChristian S.J. Peron if (bd == NULL) { 128ade9ccfeSMarcel Moolenaar xo_warn("malloc failed"); 1296b463eedSChristian S.J. Peron return; 1306b463eedSChristian S.J. Peron } 1316b463eedSChristian S.J. Peron if (sysctlbyname("net.bpf.stats", bd, &size, 1326b463eedSChristian S.J. Peron NULL, 0) < 0) { 133ade9ccfeSMarcel Moolenaar xo_warn("net.bpf.stats"); 1346b463eedSChristian S.J. Peron free(bd); 1356b463eedSChristian S.J. Peron return; 1366b463eedSChristian S.J. Peron } 137ade9ccfeSMarcel Moolenaar xo_emit("{T:/%5s} {T:/%6s} {T:/%7s} {T:/%9s} {T:/%9s} {T:/%9s} " 138ade9ccfeSMarcel Moolenaar "{T:/%5s} {T:/%5s} {T:/%s}\n", 139ade9ccfeSMarcel Moolenaar "Pid", "Netif", "Flags", "Recv", "Drop", "Match", 140ade9ccfeSMarcel Moolenaar "Sblen", "Hblen", "Command"); 141ade9ccfeSMarcel Moolenaar xo_open_container("bpf-statistics"); 142ade9ccfeSMarcel Moolenaar xo_open_list("bpf-entry"); 1436b463eedSChristian S.J. Peron for (d = &bd[0]; d < &bd[size / sizeof(*d)]; d++) { 144582908b3SChristian S.J. Peron if (d->bd_structsize != sizeof(*d)) { 145ade9ccfeSMarcel Moolenaar xo_warnx("bpf_stats_extended: version mismatch"); 146582908b3SChristian S.J. Peron return; 147582908b3SChristian S.J. Peron } 14804f7f23bSYaroslav Tykhiy if (ifname && strcmp(ifname, d->bd_ifname) != 0) 1496b463eedSChristian S.J. Peron continue; 150ade9ccfeSMarcel Moolenaar xo_open_instance("bpf-entry"); 1516b463eedSChristian S.J. Peron pname = bpf_pidname(d->bd_pid); 152ade9ccfeSMarcel Moolenaar xo_emit("{k:pid/%5d} {k:interface-name/%6s} ", 153ade9ccfeSMarcel Moolenaar d->bd_pid, d->bd_ifname); 154ade9ccfeSMarcel Moolenaar bpf_flags(d, flagbuf); 155ade9ccfeSMarcel Moolenaar xo_emit("{d:flags/%7s} {:received-packets/%9ju} " 156ade9ccfeSMarcel Moolenaar "{:dropped-packets/%9ju} {:filter-packets/%9ju} " 157ade9ccfeSMarcel Moolenaar "{:store-buffer-length/%5d} {:hold-buffer-length/%5d} " 158ade9ccfeSMarcel Moolenaar "{:process/%s}\n", 159ade9ccfeSMarcel Moolenaar flagbuf, (uintmax_t)d->bd_rcount, (uintmax_t)d->bd_dcount, 160ade9ccfeSMarcel Moolenaar (uintmax_t)d->bd_fcount, d->bd_slen, d->bd_hlen, pname); 1616b463eedSChristian S.J. Peron free(pname); 162ade9ccfeSMarcel Moolenaar xo_close_instance("bpf-entry"); 1636b463eedSChristian S.J. Peron } 164ade9ccfeSMarcel Moolenaar xo_close_list("bpf-entry"); 165ade9ccfeSMarcel Moolenaar xo_close_container("bpf-statistics"); 16648d91509SChristian S.J. Peron free(bd); 1676b463eedSChristian S.J. Peron } 168