16b463eedSChristian S.J. Peron /*- 26b463eedSChristian S.J. Peron * Copyright (c) 2005 Christian S.J. Peron 36b463eedSChristian S.J. Peron * All rights reserved. 46b463eedSChristian S.J. Peron * 56b463eedSChristian S.J. Peron * Redistribution and use in source and binary forms, with or without 66b463eedSChristian S.J. Peron * modification, are permitted provided that the following conditions 76b463eedSChristian S.J. Peron * are met: 86b463eedSChristian S.J. Peron * 1. Redistributions of source code must retain the above copyright 96b463eedSChristian S.J. Peron * notice, this list of conditions and the following disclaimer. 106b463eedSChristian S.J. Peron * 2. Redistributions in binary form must reproduce the above copyright 116b463eedSChristian S.J. Peron * notice, this list of conditions and the following disclaimer in the 126b463eedSChristian S.J. Peron * documentation and/or other materials provided with the distribution. 136b463eedSChristian S.J. Peron * 146b463eedSChristian S.J. Peron * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 156b463eedSChristian S.J. Peron * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 166b463eedSChristian S.J. Peron * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 176b463eedSChristian S.J. Peron * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 186b463eedSChristian S.J. Peron * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 196b463eedSChristian S.J. Peron * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 206b463eedSChristian S.J. Peron * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 216b463eedSChristian S.J. Peron * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 226b463eedSChristian S.J. Peron * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 236b463eedSChristian S.J. Peron * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 246b463eedSChristian S.J. Peron * SUCH DAMAGE. 256b463eedSChristian S.J. Peron */ 2665475bc8SDavid E. O'Brien 2765475bc8SDavid E. O'Brien #include <sys/cdefs.h> 2865475bc8SDavid E. O'Brien __FBSDID("$FreeBSD$"); 2965475bc8SDavid E. O'Brien 306b463eedSChristian S.J. Peron #include <sys/types.h> 316b463eedSChristian S.J. Peron #include <sys/protosw.h> 326b463eedSChristian S.J. Peron #include <sys/socket.h> 33feda1a43SJohn Baldwin #include <sys/socketvar.h> 346b463eedSChristian S.J. Peron #include <sys/sysctl.h> 356b463eedSChristian S.J. Peron #include <sys/param.h> 366b463eedSChristian S.J. Peron #include <sys/user.h> 376b463eedSChristian S.J. Peron 386b463eedSChristian S.J. Peron #include <net/if.h> 396b463eedSChristian S.J. Peron #include <net/if_var.h> 40560a54e1SJung-uk Kim #include <net/bpf.h> 416b463eedSChristian S.J. Peron #include <net/bpfdesc.h> 426b463eedSChristian S.J. Peron #include <arpa/inet.h> 436b463eedSChristian S.J. Peron 446b463eedSChristian S.J. Peron #include <err.h> 456b463eedSChristian S.J. Peron #include <errno.h> 467b95a1ebSYaroslav Tykhiy #include <stdint.h> 476b463eedSChristian S.J. Peron #include <stdio.h> 486b463eedSChristian S.J. Peron #include <stdlib.h> 496b463eedSChristian S.J. Peron #include <string.h> 506b463eedSChristian S.J. Peron #include <unistd.h> 516b463eedSChristian S.J. Peron 526b463eedSChristian S.J. Peron #include "netstat.h" 536b463eedSChristian S.J. Peron 546b463eedSChristian S.J. Peron /* print bpf stats */ 556b463eedSChristian S.J. Peron 566b463eedSChristian S.J. Peron static char * 576b463eedSChristian S.J. Peron bpf_pidname(pid_t pid) 586b463eedSChristian S.J. Peron { 596b463eedSChristian S.J. Peron struct kinfo_proc newkp; 606b463eedSChristian S.J. Peron int error, mib[4]; 616b463eedSChristian S.J. Peron size_t size; 626b463eedSChristian S.J. Peron 636b463eedSChristian S.J. Peron mib[0] = CTL_KERN; 646b463eedSChristian S.J. Peron mib[1] = KERN_PROC; 656b463eedSChristian S.J. Peron mib[2] = KERN_PROC_PID; 666b463eedSChristian S.J. Peron mib[3] = pid; 676b463eedSChristian S.J. Peron size = sizeof(newkp); 686b463eedSChristian S.J. Peron error = sysctl(mib, 4, &newkp, &size, NULL, 0); 696f798df5SChristian S.J. Peron if (error < 0) { 706f798df5SChristian S.J. Peron warn("kern.proc.pid failed"); 716b463eedSChristian S.J. Peron return (strdup("??????")); 726f798df5SChristian S.J. Peron } 736b463eedSChristian S.J. Peron return (strdup(newkp.ki_comm)); 746b463eedSChristian S.J. Peron } 756b463eedSChristian S.J. Peron 766b463eedSChristian S.J. Peron static void 776b463eedSChristian S.J. Peron bpf_flags(struct xbpf_d *bd, char *flagbuf) 786b463eedSChristian S.J. Peron { 796b463eedSChristian S.J. Peron 806b463eedSChristian S.J. Peron *flagbuf++ = bd->bd_promisc ? 'p' : '-'; 816b463eedSChristian S.J. Peron *flagbuf++ = bd->bd_immediate ? 'i' : '-'; 826b463eedSChristian S.J. Peron *flagbuf++ = bd->bd_hdrcmplt ? '-' : 'f'; 83560a54e1SJung-uk Kim *flagbuf++ = (bd->bd_direction == BPF_D_IN) ? '-' : 84560a54e1SJung-uk Kim ((bd->bd_direction == BPF_D_OUT) ? 'o' : 's'); 85560a54e1SJung-uk Kim *flagbuf++ = bd->bd_feedback ? 'b' : '-'; 866b463eedSChristian S.J. Peron *flagbuf++ = bd->bd_async ? 'a' : '-'; 876b463eedSChristian S.J. Peron *flagbuf++ = bd->bd_locked ? 'l' : '-'; 886b463eedSChristian S.J. Peron *flagbuf++ = '\0'; 896b463eedSChristian S.J. Peron } 906b463eedSChristian S.J. Peron 916b463eedSChristian S.J. Peron void 9204f7f23bSYaroslav Tykhiy bpf_stats(char *ifname) 936b463eedSChristian S.J. Peron { 946b463eedSChristian S.J. Peron struct xbpf_d *d, *bd; 956b463eedSChristian S.J. Peron char *pname, flagbuf[12]; 966b463eedSChristian S.J. Peron size_t size; 976b463eedSChristian S.J. Peron 986b463eedSChristian S.J. Peron if (sysctlbyname("net.bpf.stats", NULL, &size, 996b463eedSChristian S.J. Peron NULL, 0) < 0) { 1006b463eedSChristian S.J. Peron warn("net.bpf.stats"); 1016b463eedSChristian S.J. Peron return; 1026b463eedSChristian S.J. Peron } 10315f3d81fSChristian S.J. Peron if (size == 0) 10415f3d81fSChristian S.J. Peron return; 1056b463eedSChristian S.J. Peron bd = malloc(size); 1066b463eedSChristian S.J. Peron if (bd == NULL) { 1076b463eedSChristian S.J. Peron warn("malloc failed"); 1086b463eedSChristian S.J. Peron return; 1096b463eedSChristian S.J. Peron } 1106b463eedSChristian S.J. Peron if (sysctlbyname("net.bpf.stats", bd, &size, 1116b463eedSChristian S.J. Peron NULL, 0) < 0) { 1126b463eedSChristian S.J. Peron warn("net.bpf.stats"); 1136b463eedSChristian S.J. Peron free(bd); 1146b463eedSChristian S.J. Peron return; 1156b463eedSChristian S.J. Peron } 116582908b3SChristian S.J. Peron (void) printf("%5s %6s %7s %9s %9s %9s %5s %5s %s\n", 1176b463eedSChristian S.J. Peron "Pid", "Netif", "Flags", "Recv", "Drop", "Match", "Sblen", 1186b463eedSChristian S.J. Peron "Hblen", "Command"); 1196b463eedSChristian S.J. Peron for (d = &bd[0]; d < &bd[size / sizeof(*d)]; d++) { 120582908b3SChristian S.J. Peron if (d->bd_structsize != sizeof(*d)) { 121582908b3SChristian S.J. Peron warnx("bpf_stats_extended: version mismatch"); 122582908b3SChristian S.J. Peron return; 123582908b3SChristian S.J. Peron } 12404f7f23bSYaroslav Tykhiy if (ifname && strcmp(ifname, d->bd_ifname) != 0) 1256b463eedSChristian S.J. Peron continue; 1266b463eedSChristian S.J. Peron bpf_flags(d, flagbuf); 1276b463eedSChristian S.J. Peron pname = bpf_pidname(d->bd_pid); 128582908b3SChristian S.J. Peron (void) printf("%5d %6s %7s %9ju %9ju %9ju %5d %5d %s\n", 1296b463eedSChristian S.J. Peron d->bd_pid, d->bd_ifname, flagbuf, 1306b463eedSChristian S.J. Peron d->bd_rcount, d->bd_dcount, d->bd_fcount, 1316b463eedSChristian S.J. Peron d->bd_slen, d->bd_hlen, pname); 1326b463eedSChristian S.J. Peron free(pname); 1336b463eedSChristian S.J. Peron } 13448d91509SChristian S.J. Peron free(bd); 1356b463eedSChristian S.J. Peron } 136