Home | History | Annotate | Line # | Download | only in netstat
inet.c revision 1.99
      1  1.99    dyoung /*	$NetBSD: inet.c,v 1.99 2011/05/11 22:21:59 dyoung Exp $	*/
      2  1.14   thorpej 
      3   1.1       cgd /*
      4   1.9   mycroft  * Copyright (c) 1983, 1988, 1993
      5   1.9   mycroft  *	The Regents of the University of California.  All rights reserved.
      6   1.1       cgd  *
      7   1.1       cgd  * Redistribution and use in source and binary forms, with or without
      8   1.1       cgd  * modification, are permitted provided that the following conditions
      9   1.1       cgd  * are met:
     10   1.1       cgd  * 1. Redistributions of source code must retain the above copyright
     11   1.1       cgd  *    notice, this list of conditions and the following disclaimer.
     12   1.1       cgd  * 2. Redistributions in binary form must reproduce the above copyright
     13   1.1       cgd  *    notice, this list of conditions and the following disclaimer in the
     14   1.1       cgd  *    documentation and/or other materials provided with the distribution.
     15  1.58       agc  * 3. Neither the name of the University nor the names of its contributors
     16   1.1       cgd  *    may be used to endorse or promote products derived from this software
     17   1.1       cgd  *    without specific prior written permission.
     18   1.1       cgd  *
     19   1.1       cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20   1.1       cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21   1.1       cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22   1.1       cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23   1.1       cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24   1.1       cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25   1.1       cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26   1.1       cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27   1.1       cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28   1.1       cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29   1.1       cgd  * SUCH DAMAGE.
     30   1.1       cgd  */
     31   1.1       cgd 
     32  1.23     lukem #include <sys/cdefs.h>
     33   1.1       cgd #ifndef lint
     34  1.14   thorpej #if 0
     35  1.14   thorpej static char sccsid[] = "from: @(#)inet.c	8.4 (Berkeley) 4/20/94";
     36  1.14   thorpej #else
     37  1.99    dyoung __RCSID("$NetBSD: inet.c,v 1.99 2011/05/11 22:21:59 dyoung Exp $");
     38  1.14   thorpej #endif
     39   1.1       cgd #endif /* not lint */
     40   1.1       cgd 
     41  1.78        ad #define	_CALLOUT_PRIVATE	/* for defs in sys/callout.h */
     42  1.78        ad 
     43   1.1       cgd #include <sys/param.h>
     44  1.10       cgd #include <sys/queue.h>
     45   1.1       cgd #include <sys/socket.h>
     46   1.1       cgd #include <sys/socketvar.h>
     47   1.1       cgd #include <sys/mbuf.h>
     48   1.1       cgd #include <sys/protosw.h>
     49  1.65      elad #include <sys/sysctl.h>
     50   1.1       cgd 
     51  1.41     jhawk #include <net/if_arp.h>
     52   1.1       cgd #include <net/route.h>
     53   1.1       cgd #include <netinet/in.h>
     54   1.1       cgd #include <netinet/in_systm.h>
     55   1.1       cgd #include <netinet/ip.h>
     56   1.1       cgd #include <netinet/in_pcb.h>
     57   1.1       cgd #include <netinet/ip_icmp.h>
     58  1.37    itojun 
     59  1.37    itojun #ifdef INET6
     60  1.37    itojun #include <netinet/ip6.h>
     61  1.37    itojun #endif
     62  1.37    itojun 
     63   1.1       cgd #include <netinet/icmp_var.h>
     64   1.6    brezak #include <netinet/igmp_var.h>
     65   1.1       cgd #include <netinet/ip_var.h>
     66  1.62      manu #include <netinet/pim_var.h>
     67   1.1       cgd #include <netinet/tcp.h>
     68   1.1       cgd #include <netinet/tcpip.h>
     69   1.1       cgd #include <netinet/tcp_seq.h>
     70   1.1       cgd #define TCPSTATES
     71   1.1       cgd #include <netinet/tcp_fsm.h>
     72  1.30   thorpej #define	TCPTIMERS
     73   1.1       cgd #include <netinet/tcp_timer.h>
     74   1.1       cgd #include <netinet/tcp_var.h>
     75   1.1       cgd #include <netinet/tcp_debug.h>
     76   1.1       cgd #include <netinet/udp.h>
     77  1.69  liamjfoy #include <netinet/ip_carp.h>
     78   1.1       cgd #include <netinet/udp_var.h>
     79  1.96    dyoung #include <netinet/tcp_vtw.h>
     80   1.1       cgd 
     81   1.9   mycroft #include <arpa/inet.h>
     82  1.64    rpaulo #include <kvm.h>
     83   1.1       cgd #include <netdb.h>
     84   1.1       cgd #include <stdio.h>
     85   1.1       cgd #include <string.h>
     86   1.9   mycroft #include <unistd.h>
     87  1.66      elad #include <stdlib.h>
     88  1.65      elad #include <err.h>
     89   1.9   mycroft #include "netstat.h"
     90  1.96    dyoung #include "vtw.h"
     91  1.93     pooka #include "prog_ops.h"
     92   1.1       cgd 
     93  1.84   thorpej char	*inetname(struct in_addr *);
     94  1.84   thorpej void	inetprint(struct in_addr *, u_int16_t, const char *, int);
     95   1.1       cgd 
     96  1.96    dyoung void	print_vtw_v4(const vtw_t *);
     97  1.96    dyoung 
     98   1.1       cgd /*
     99   1.1       cgd  * Print a summary of connections related to an Internet
    100   1.1       cgd  * protocol.  For TCP, also give state of connection.
    101   1.1       cgd  * Listening processes (aflag) are suppressed unless the
    102   1.1       cgd  * -a (all) flag is specified.
    103   1.1       cgd  */
    104  1.35     lukem static int width;
    105  1.66      elad static int compact;
    106  1.66      elad 
    107  1.96    dyoung /* VTW-related variables. */
    108  1.96    dyoung static struct timeval now;
    109  1.96    dyoung 
    110  1.66      elad static void
    111  1.66      elad protoprhdr(void)
    112  1.66      elad {
    113  1.66      elad 	printf("Active Internet connections");
    114  1.66      elad 	if (aflag)
    115  1.66      elad 		printf(" (including servers)");
    116  1.66      elad 	putchar('\n');
    117  1.66      elad 	if (Aflag)
    118  1.66      elad 		printf("%-8.8s ", "PCB");
    119  1.99    dyoung 	printf(
    120  1.99    dyoung 	    Vflag ? "%-5.5s %-6.6s %-6.6s %s%-*.*s %-*.*s %-13.13s Expires\n"
    121  1.99    dyoung 	          : "%-5.5s %-6.6s %-6.6s %s%-*.*s %-*.*s %s\n",
    122  1.66      elad 		"Proto", "Recv-Q", "Send-Q", compact ? "" : " ",
    123  1.66      elad 		width, width, "Local Address",
    124  1.66      elad 		width, width, "Foreign Address",
    125  1.99    dyoung 		"State");
    126  1.66      elad }
    127  1.66      elad 
    128  1.66      elad static void
    129  1.67        he protopr0(intptr_t ppcb, u_long rcv_sb_cc, u_long snd_sb_cc,
    130  1.66      elad 	 struct in_addr *laddr, u_int16_t lport,
    131  1.66      elad 	 struct in_addr *faddr, u_int16_t fport,
    132  1.96    dyoung 	 short t_state, const char *name, int inp_flags,
    133  1.96    dyoung 	 const struct timeval *expires)
    134  1.66      elad {
    135  1.83   thorpej 	static const char *shorttcpstates[] = {
    136  1.66      elad 		"CLOSED",	"LISTEN",	"SYNSEN",	"SYSRCV",
    137  1.66      elad 		"ESTABL",	"CLWAIT",	"FWAIT1",	"CLOSNG",
    138  1.66      elad 		"LASTAK",	"FWAIT2",	"TMWAIT",
    139  1.66      elad 	};
    140  1.66      elad 	int istcp;
    141  1.66      elad 
    142  1.66      elad 	istcp = strcmp(name, "tcp") == 0;
    143  1.66      elad 
    144  1.66      elad 	if (Aflag) {
    145  1.68      elad 		printf("%8" PRIxPTR " ", ppcb);
    146  1.66      elad 	}
    147  1.66      elad 	printf("%-5.5s %6ld %6ld%s", name, rcv_sb_cc, snd_sb_cc,
    148  1.66      elad 	       compact ? "" : " ");
    149  1.66      elad 	if (numeric_port) {
    150  1.66      elad 		inetprint(laddr, lport, name, 1);
    151  1.66      elad 		inetprint(faddr, fport, name, 1);
    152  1.90     lukem 	} else if (inp_flags & INP_ANONPORT) {
    153  1.66      elad 		inetprint(laddr, lport, name, 1);
    154  1.66      elad 		inetprint(faddr, fport, name, 0);
    155  1.66      elad 	} else {
    156  1.66      elad 		inetprint(laddr, lport, name, 0);
    157  1.66      elad 		inetprint(faddr, fport, name, 0);
    158  1.66      elad 	}
    159  1.66      elad 	if (istcp) {
    160  1.66      elad 		if (t_state < 0 || t_state >= TCP_NSTATES)
    161  1.66      elad 			printf(" %d", t_state);
    162  1.66      elad 		else
    163  1.66      elad 			printf(" %s", compact ? shorttcpstates[t_state] :
    164  1.66      elad 			       tcpstates[t_state]);
    165  1.66      elad 	}
    166  1.96    dyoung 	if (Vflag && expires != NULL) {
    167  1.97    dyoung 		if (expires->tv_sec == 0 && expires->tv_usec == -1)
    168  1.97    dyoung 			printf(" reclaimed");
    169  1.97    dyoung 		else {
    170  1.96    dyoung 			struct timeval delta;
    171  1.96    dyoung 
    172  1.96    dyoung 			timersub(expires, &now, &delta);
    173  1.96    dyoung 			printf(" %.3fms",
    174  1.96    dyoung 			    delta.tv_sec * 1000.0 + delta.tv_usec / 1000.0);
    175  1.97    dyoung 		}
    176  1.96    dyoung 	}
    177  1.66      elad 	putchar('\n');
    178  1.66      elad }
    179  1.35     lukem 
    180  1.96    dyoung static void
    181  1.96    dyoung dbg_printf(const char *fmt, ...)
    182  1.96    dyoung {
    183  1.96    dyoung 	return;
    184  1.96    dyoung }
    185  1.96    dyoung 
    186  1.96    dyoung void
    187  1.96    dyoung print_vtw_v4(const vtw_t *vtw)
    188  1.96    dyoung {
    189  1.96    dyoung 	const vtw_v4_t *v4 = (const vtw_v4_t *)vtw;
    190  1.96    dyoung 	struct timeval delta;
    191  1.96    dyoung 	struct in_addr la, fa;
    192  1.96    dyoung 	char buf[2][32];
    193  1.97    dyoung 	static const struct timeval zero = {.tv_sec = 0, .tv_usec = 0};
    194  1.96    dyoung 
    195  1.96    dyoung 	la.s_addr = v4->laddr;
    196  1.96    dyoung 	fa.s_addr = v4->faddr;
    197  1.96    dyoung 
    198  1.96    dyoung 	snprintf(&buf[0][0], 32, "%s", inet_ntoa(la));
    199  1.96    dyoung 	snprintf(&buf[1][0], 32, "%s", inet_ntoa(fa));
    200  1.96    dyoung 
    201  1.96    dyoung 	timersub(&vtw->expire, &now, &delta);
    202  1.96    dyoung 
    203  1.96    dyoung 	if (vtw->expire.tv_sec == 0 && vtw->expire.tv_usec == -1) {
    204  1.97    dyoung 		dbg_printf("%15.15s:%d %15.15s:%d reclaimed\n"
    205  1.96    dyoung 		    ,buf[0], ntohs(v4->lport)
    206  1.96    dyoung 		    ,buf[1], ntohs(v4->fport));
    207  1.96    dyoung 		if (!(Vflag && vflag))
    208  1.96    dyoung 			return;
    209  1.96    dyoung 	} else if (vtw->expire.tv_sec == 0)
    210  1.96    dyoung 		return;
    211  1.97    dyoung 	else if (timercmp(&delta, &zero, <) && !(Vflag && vflag)) {
    212  1.97    dyoung 		dbg_printf("%15.15s:%d %15.15s:%d expired\n"
    213  1.97    dyoung 		    ,buf[0], ntohs(v4->lport)
    214  1.97    dyoung 		    ,buf[1], ntohs(v4->fport));
    215  1.97    dyoung 		return;
    216  1.97    dyoung 	} else {
    217  1.96    dyoung 		dbg_printf("%15.15s:%d %15.15s:%d expires in %.3fms\n"
    218  1.96    dyoung 		    ,buf[0], ntohs(v4->lport)
    219  1.96    dyoung 		    ,buf[1], ntohs(v4->fport)
    220  1.96    dyoung 		    ,delta.tv_sec * 1000.0 + delta.tv_usec / 1000.0);
    221  1.96    dyoung 	}
    222  1.96    dyoung 	protopr0(0, 0, 0,
    223  1.96    dyoung 		 &la, v4->lport,
    224  1.96    dyoung 		 &fa, v4->fport,
    225  1.96    dyoung 		 TCPS_TIME_WAIT, "tcp", 0, &vtw->expire);
    226  1.96    dyoung }
    227  1.96    dyoung 
    228   1.9   mycroft void
    229  1.90     lukem protopr(u_long off, const char *name)
    230   1.1       cgd {
    231  1.12   mycroft 	struct inpcbtable table;
    232  1.23     lukem 	struct inpcb *head, *next, *prev;
    233  1.13       cgd 	struct inpcb inpcb;
    234  1.90     lukem 	struct tcpcb tcpcb;
    235  1.90     lukem 	struct socket sockb;
    236  1.96    dyoung 	int istcp = strcmp(name, "tcp") == 0;
    237   1.1       cgd 	static int first = 1;
    238   1.1       cgd 
    239  1.35     lukem 	compact = 0;
    240  1.35     lukem 	if (Aflag) {
    241  1.46     assar 		if (!numeric_addr)
    242  1.35     lukem 			width = 18;
    243  1.35     lukem 		else {
    244  1.35     lukem 			width = 21;
    245  1.35     lukem 			compact = 1;
    246  1.35     lukem 		}
    247  1.35     lukem 	} else
    248  1.35     lukem 		width = 22;
    249  1.66      elad 
    250  1.66      elad 	if (use_sysctl) {
    251  1.66      elad 		struct kinfo_pcb *pcblist;
    252  1.66      elad 		int mib[8];
    253  1.66      elad 		size_t namelen = 0, size = 0, i;
    254  1.66      elad 		char *mibname = NULL;
    255  1.66      elad 
    256  1.66      elad 		memset(mib, 0, sizeof(mib));
    257  1.66      elad 
    258  1.66      elad 		if (asprintf(&mibname, "net.inet.%s.pcblist", name) == -1)
    259  1.66      elad 			err(1, "asprintf");
    260  1.66      elad 
    261  1.66      elad 		/* get dynamic pcblist node */
    262  1.66      elad 		if (sysctlnametomib(mibname, mib, &namelen) == -1)
    263  1.77      elad 			err(1, "sysctlnametomib: %s", mibname);
    264  1.66      elad 
    265  1.95    dyoung 		if (prog_sysctl(mib, __arraycount(mib),
    266  1.93     pooka 		    NULL, &size, NULL, 0) == -1)
    267  1.66      elad 			err(1, "sysctl (query)");
    268  1.66      elad 
    269  1.71  liamjfoy 		if ((pcblist = malloc(size)) == NULL)
    270  1.71  liamjfoy 			err(1, "malloc");
    271  1.66      elad 		memset(pcblist, 0, size);
    272  1.66      elad 
    273  1.66      elad 	        mib[6] = sizeof(*pcblist);
    274  1.66      elad         	mib[7] = size / sizeof(*pcblist);
    275  1.66      elad 
    276  1.95    dyoung 		if (prog_sysctl(mib, __arraycount(mib),
    277  1.93     pooka 		    pcblist, &size, NULL, 0) == -1)
    278  1.66      elad 			err(1, "sysctl (copy)");
    279  1.66      elad 
    280  1.66      elad 		for (i = 0; i < size / sizeof(*pcblist); i++) {
    281  1.66      elad 			struct sockaddr_in src, dst;
    282  1.66      elad 
    283  1.66      elad 			memcpy(&src, &pcblist[i].ki_s, sizeof(src));
    284  1.66      elad 			memcpy(&dst, &pcblist[i].ki_d, sizeof(dst));
    285  1.66      elad 
    286  1.89  dholland 			if (!aflag &&
    287  1.89  dholland 			    inet_lnaof(dst.sin_addr) == INADDR_ANY)
    288  1.89  dholland 				continue;
    289  1.89  dholland 
    290  1.66      elad 			if (first) {
    291  1.66      elad 				protoprhdr();
    292  1.66      elad 				first = 0;
    293  1.66      elad 			}
    294  1.66      elad 
    295  1.67        he 	                protopr0((intptr_t) pcblist[i].ki_ppcbaddr,
    296  1.66      elad 				 pcblist[i].ki_rcvq, pcblist[i].ki_sndq,
    297  1.66      elad 				 &src.sin_addr, src.sin_port,
    298  1.66      elad 				 &dst.sin_addr, dst.sin_port,
    299  1.90     lukem 				 pcblist[i].ki_tstate, name,
    300  1.96    dyoung 				 pcblist[i].ki_pflags, NULL);
    301  1.66      elad 		}
    302  1.66      elad 
    303  1.66      elad 		free(pcblist);
    304  1.96    dyoung 		goto end;
    305  1.66      elad 	}
    306  1.66      elad 
    307  1.72      elad 	if (off == 0)
    308  1.72      elad 		return;
    309  1.72      elad 	kread(off, (char *)&table, sizeof table);
    310  1.72      elad 	prev = head =
    311  1.72      elad 	    (struct inpcb *)&((struct inpcbtable *)off)->inpt_queue.cqh_first;
    312  1.72      elad 	next = (struct inpcb *)table.inpt_queue.cqh_first;
    313  1.72      elad 
    314  1.13       cgd 	while (next != head) {
    315  1.12   mycroft 		kread((u_long)next, (char *)&inpcb, sizeof inpcb);
    316  1.59    itojun 		if ((struct inpcb *)inpcb.inp_queue.cqe_prev != prev) {
    317   1.1       cgd 			printf("???\n");
    318   1.1       cgd 			break;
    319   1.1       cgd 		}
    320  1.13       cgd 		prev = next;
    321  1.59    itojun 		next = (struct inpcb *)inpcb.inp_queue.cqe_next;
    322  1.59    itojun 
    323  1.59    itojun 		if (inpcb.inp_af != AF_INET)
    324  1.59    itojun 			continue;
    325  1.13       cgd 
    326   1.1       cgd 		if (!aflag &&
    327  1.89  dholland 		    inet_lnaof(inpcb.inp_faddr) == INADDR_ANY)
    328   1.1       cgd 			continue;
    329   1.9   mycroft 		kread((u_long)inpcb.inp_socket, (char *)&sockb, sizeof (sockb));
    330   1.1       cgd 		if (istcp) {
    331   1.9   mycroft 			kread((u_long)inpcb.inp_ppcb,
    332   1.9   mycroft 			    (char *)&tcpcb, sizeof (tcpcb));
    333   1.1       cgd 		}
    334  1.66      elad 
    335   1.1       cgd 		if (first) {
    336  1.66      elad 			protoprhdr();
    337   1.1       cgd 			first = 0;
    338   1.1       cgd 		}
    339  1.66      elad 
    340  1.67        he 		protopr0(istcp ? (intptr_t) inpcb.inp_ppcb : (intptr_t) prev,
    341  1.66      elad 			 sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc,
    342  1.66      elad 			 &inpcb.inp_laddr, inpcb.inp_lport,
    343  1.66      elad 			 &inpcb.inp_faddr, inpcb.inp_fport,
    344  1.96    dyoung 			 tcpcb.t_state, name, inpcb.inp_flags, NULL);
    345  1.96    dyoung 	}
    346  1.96    dyoung end:
    347  1.96    dyoung 	if (istcp) {
    348  1.98  drochner 		struct timeval t;
    349  1.98  drochner 		timebase(&t);
    350  1.96    dyoung 		gettimeofday(&now, NULL);
    351  1.98  drochner 		timersub(&now, &t, &now);
    352  1.96    dyoung 		show_vtw_v4(print_vtw_v4);
    353   1.1       cgd 	}
    354   1.1       cgd }
    355   1.1       cgd 
    356   1.1       cgd /*
    357   1.1       cgd  * Dump TCP statistics structure.
    358   1.1       cgd  */
    359   1.9   mycroft void
    360  1.90     lukem tcp_stats(u_long off, const char *name)
    361   1.1       cgd {
    362  1.83   thorpej 	uint64_t tcpstat[TCP_NSTATS];
    363   1.1       cgd 
    364  1.65      elad 	if (use_sysctl) {
    365  1.65      elad 		size_t size = sizeof(tcpstat);
    366  1.65      elad 
    367  1.83   thorpej 		if (sysctlbyname("net.inet.tcp.stats", tcpstat, &size,
    368  1.65      elad 				 NULL, 0) == -1)
    369  1.88   thorpej 			return;
    370  1.65      elad 	} else {
    371  1.88   thorpej 		warnx("%s stats not available via KVM.", name);
    372  1.88   thorpej 		return;
    373  1.65      elad 	}
    374  1.65      elad 
    375   1.1       cgd 	printf ("%s:\n", name);
    376   1.9   mycroft 
    377  1.83   thorpej #define	ps(f, m) if (tcpstat[f] || sflag <= 1) \
    378  1.95    dyoung     printf(m, tcpstat[f])
    379  1.83   thorpej #define	p(f, m) if (tcpstat[f] || sflag <= 1) \
    380  1.95    dyoung     printf(m, tcpstat[f], plural(tcpstat[f]))
    381  1.83   thorpej #define	p2(f1, f2, m) if (tcpstat[f1] || tcpstat[f2] || sflag <= 1) \
    382  1.95    dyoung     printf(m, tcpstat[f1], plural(tcpstat[f1]), \
    383  1.95    dyoung     tcpstat[f2], plural(tcpstat[f2]))
    384  1.83   thorpej #define	p2s(f1, f2, m) if (tcpstat[f1] || tcpstat[f2] || sflag <= 1) \
    385  1.95    dyoung     printf(m, tcpstat[f1], plural(tcpstat[f1]), \
    386  1.95    dyoung     tcpstat[f2])
    387  1.83   thorpej #define	p3(f, m) if (tcpstat[f] || sflag <= 1) \
    388  1.95    dyoung     printf(m, tcpstat[f], plurales(tcpstat[f]))
    389   1.1       cgd 
    390  1.95    dyoung 	p(TCP_STAT_SNDTOTAL, "\t%" PRIu64 " packet%s sent\n");
    391  1.83   thorpej 	p2(TCP_STAT_SNDPACK,TCP_STAT_SNDBYTE,
    392  1.95    dyoung 		"\t\t%" PRIu64 " data packet%s (%" PRIu64 " byte%s)\n");
    393  1.83   thorpej 	p2(TCP_STAT_SNDREXMITPACK, TCP_STAT_SNDREXMITBYTE,
    394  1.95    dyoung 		"\t\t%" PRIu64 " data packet%s (%" PRIu64 " byte%s) retransmitted\n");
    395  1.83   thorpej 	p2s(TCP_STAT_SNDACKS, TCP_STAT_DELACK,
    396  1.95    dyoung 		"\t\t%" PRIu64 " ack-only packet%s (%" PRIu64 " delayed)\n");
    397  1.95    dyoung 	p(TCP_STAT_SNDURG, "\t\t%" PRIu64 " URG only packet%s\n");
    398  1.95    dyoung 	p(TCP_STAT_SNDPROBE, "\t\t%" PRIu64 " window probe packet%s\n");
    399  1.95    dyoung 	p(TCP_STAT_SNDWINUP, "\t\t%" PRIu64 " window update packet%s\n");
    400  1.95    dyoung 	p(TCP_STAT_SNDCTRL, "\t\t%" PRIu64 " control packet%s\n");
    401  1.83   thorpej 	p(TCP_STAT_SELFQUENCH,
    402  1.95    dyoung 	    "\t\t%" PRIu64 " send attempt%s resulted in self-quench\n");
    403  1.95    dyoung 	p(TCP_STAT_RCVTOTAL, "\t%" PRIu64 " packet%s received\n");
    404  1.83   thorpej 	p2(TCP_STAT_RCVACKPACK, TCP_STAT_RCVACKBYTE,
    405  1.95    dyoung 		"\t\t%" PRIu64 " ack%s (for %" PRIu64 " byte%s)\n");
    406  1.95    dyoung 	p(TCP_STAT_RCVDUPACK, "\t\t%" PRIu64 " duplicate ack%s\n");
    407  1.95    dyoung 	p(TCP_STAT_RCVACKTOOMUCH, "\t\t%" PRIu64 " ack%s for unsent data\n");
    408  1.83   thorpej 	p2(TCP_STAT_RCVPACK, TCP_STAT_RCVBYTE,
    409  1.95    dyoung 		"\t\t%" PRIu64 " packet%s (%" PRIu64 " byte%s) received in-sequence\n");
    410  1.83   thorpej 	p2(TCP_STAT_RCVDUPPACK, TCP_STAT_RCVDUPBYTE,
    411  1.95    dyoung 		"\t\t%" PRIu64 " completely duplicate packet%s (%" PRIu64 " byte%s)\n");
    412  1.95    dyoung 	p(TCP_STAT_PAWSDROP, "\t\t%" PRIu64 " old duplicate packet%s\n");
    413  1.83   thorpej 	p2(TCP_STAT_RCVPARTDUPPACK, TCP_STAT_RCVPARTDUPBYTE,
    414  1.95    dyoung 		"\t\t%" PRIu64 " packet%s with some dup. data (%" PRIu64 " byte%s duped)\n");
    415  1.83   thorpej 	p2(TCP_STAT_RCVOOPACK, TCP_STAT_RCVOOBYTE,
    416  1.95    dyoung 		"\t\t%" PRIu64 " out-of-order packet%s (%" PRIu64 " byte%s)\n");
    417  1.83   thorpej 	p2(TCP_STAT_RCVPACKAFTERWIN, TCP_STAT_RCVBYTEAFTERWIN,
    418  1.95    dyoung 		"\t\t%" PRIu64 " packet%s (%" PRIu64 " byte%s) of data after window\n");
    419  1.95    dyoung 	p(TCP_STAT_RCVWINPROBE, "\t\t%" PRIu64 " window probe%s\n");
    420  1.95    dyoung 	p(TCP_STAT_RCVWINUPD, "\t\t%" PRIu64 " window update packet%s\n");
    421  1.95    dyoung 	p(TCP_STAT_RCVAFTERCLOSE, "\t\t%" PRIu64 " packet%s received after close\n");
    422  1.95    dyoung 	p(TCP_STAT_RCVBADSUM, "\t\t%" PRIu64 " discarded for bad checksum%s\n");
    423  1.95    dyoung 	p(TCP_STAT_RCVBADOFF, "\t\t%" PRIu64 " discarded for bad header offset field%s\n");
    424  1.95    dyoung 	ps(TCP_STAT_RCVSHORT, "\t\t%" PRIu64 " discarded because packet too short\n");
    425  1.95    dyoung 	p(TCP_STAT_CONNATTEMPT, "\t%" PRIu64 " connection request%s\n");
    426  1.95    dyoung 	p(TCP_STAT_ACCEPTS, "\t%" PRIu64 " connection accept%s\n");
    427  1.83   thorpej 	p(TCP_STAT_CONNECTS,
    428  1.95    dyoung 		"\t%" PRIu64 " connection%s established (including accepts)\n");
    429  1.83   thorpej 	p2(TCP_STAT_CLOSED, TCP_STAT_DROPS,
    430  1.95    dyoung 		"\t%" PRIu64 " connection%s closed (including %" PRIu64 " drop%s)\n");
    431  1.95    dyoung 	p(TCP_STAT_CONNDROPS, "\t%" PRIu64 " embryonic connection%s dropped\n");
    432  1.95    dyoung 	p(TCP_STAT_DELAYED_FREE, "\t%" PRIu64 " delayed free%s of tcpcb\n");
    433  1.83   thorpej 	p2(TCP_STAT_RTTUPDATED, TCP_STAT_SEGSTIMED,
    434  1.95    dyoung 		"\t%" PRIu64 " segment%s updated rtt (of %" PRIu64 " attempt%s)\n");
    435  1.95    dyoung 	p(TCP_STAT_REXMTTIMEO, "\t%" PRIu64 " retransmit timeout%s\n");
    436  1.83   thorpej 	p(TCP_STAT_TIMEOUTDROP,
    437  1.95    dyoung 		"\t\t%" PRIu64 " connection%s dropped by rexmit timeout\n");
    438  1.83   thorpej 	p2(TCP_STAT_PERSISTTIMEO, TCP_STAT_PERSISTDROPS,
    439  1.95    dyoung 	   "\t%" PRIu64 " persist timeout%s (resulting in %" PRIu64 " dropped "
    440  1.38    bouyer 		"connection%s)\n");
    441  1.95    dyoung 	p(TCP_STAT_KEEPTIMEO, "\t%" PRIu64 " keepalive timeout%s\n");
    442  1.95    dyoung 	p(TCP_STAT_KEEPPROBE, "\t\t%" PRIu64 " keepalive probe%s sent\n");
    443  1.95    dyoung 	p(TCP_STAT_KEEPDROPS, "\t\t%" PRIu64 " connection%s dropped by keepalive\n");
    444  1.95    dyoung 	p(TCP_STAT_PREDACK, "\t%" PRIu64 " correct ACK header prediction%s\n");
    445  1.95    dyoung 	p(TCP_STAT_PREDDAT, "\t%" PRIu64 " correct data packet header prediction%s\n");
    446  1.95    dyoung 	p3(TCP_STAT_PCBHASHMISS, "\t%" PRIu64 " PCB hash miss%s\n");
    447  1.95    dyoung 	ps(TCP_STAT_NOPORT, "\t%" PRIu64 " dropped due to no socket\n");
    448  1.95    dyoung 	p(TCP_STAT_CONNSDRAINED, "\t%" PRIu64 " connection%s drained due to memory "
    449  1.38    bouyer 		"shortage\n");
    450  1.95    dyoung 	p(TCP_STAT_PMTUBLACKHOLE, "\t%" PRIu64 " PMTUD blackhole%s detected\n");
    451  1.38    bouyer 
    452  1.95    dyoung 	p(TCP_STAT_BADSYN, "\t%" PRIu64 " bad connection attempt%s\n");
    453  1.95    dyoung 	ps(TCP_STAT_SC_ADDED, "\t%" PRIu64 " SYN cache entries added\n");
    454  1.95    dyoung 	p(TCP_STAT_SC_COLLISIONS, "\t\t%" PRIu64 " hash collision%s\n");
    455  1.95    dyoung 	ps(TCP_STAT_SC_COMPLETED, "\t\t%" PRIu64 " completed\n");
    456  1.95    dyoung 	ps(TCP_STAT_SC_ABORTED, "\t\t%" PRIu64 " aborted (no space to build PCB)\n");
    457  1.95    dyoung 	ps(TCP_STAT_SC_TIMED_OUT, "\t\t%" PRIu64 " timed out\n");
    458  1.95    dyoung 	ps(TCP_STAT_SC_OVERFLOWED, "\t\t%" PRIu64 " dropped due to overflow\n");
    459  1.95    dyoung 	ps(TCP_STAT_SC_BUCKETOVERFLOW, "\t\t%" PRIu64 " dropped due to bucket overflow\n");
    460  1.95    dyoung 	ps(TCP_STAT_SC_RESET, "\t\t%" PRIu64 " dropped due to RST\n");
    461  1.95    dyoung 	ps(TCP_STAT_SC_UNREACH, "\t\t%" PRIu64 " dropped due to ICMP unreachable\n");
    462  1.95    dyoung 	ps(TCP_STAT_SC_DELAYED_FREE, "\t\t%" PRIu64 " delayed free of SYN cache "
    463  1.57        he 		"entries\n");
    464  1.95    dyoung 	p(TCP_STAT_SC_RETRANSMITTED, "\t%" PRIu64 " SYN,ACK%s retransmitted\n");
    465  1.95    dyoung 	p(TCP_STAT_SC_DUPESYN, "\t%" PRIu64 " duplicate SYN%s received for entries "
    466  1.38    bouyer 		"already in the cache\n");
    467  1.95    dyoung 	p(TCP_STAT_SC_DROPPED, "\t%" PRIu64 " SYN%s dropped (no route or no space)\n");
    468  1.95    dyoung 	p(TCP_STAT_BADSIG, "\t%" PRIu64 " packet%s with bad signature\n");
    469  1.95    dyoung 	p(TCP_STAT_GOODSIG, "\t%" PRIu64 " packet%s with good signature\n");
    470  1.95    dyoung 
    471  1.95    dyoung 	p(TCP_STAT_ECN_SHS, "\t%" PRIu64 " successful ECN handshake%s\n");
    472  1.95    dyoung 	p(TCP_STAT_ECN_CE, "\t%" PRIu64 " packet%s with ECN CE bit\n");
    473  1.95    dyoung 	p(TCP_STAT_ECN_ECT, "\t%" PRIu64 " packet%s ECN ECT(0) bit\n");
    474   1.1       cgd #undef p
    475  1.20  christos #undef ps
    476   1.1       cgd #undef p2
    477  1.20  christos #undef p2s
    478   1.9   mycroft #undef p3
    479  1.96    dyoung 	show_vtw_stats();
    480   1.1       cgd }
    481   1.1       cgd 
    482   1.1       cgd /*
    483   1.1       cgd  * Dump UDP statistics structure.
    484   1.1       cgd  */
    485   1.9   mycroft void
    486  1.90     lukem udp_stats(u_long off, const char *name)
    487   1.1       cgd {
    488  1.80   thorpej 	uint64_t udpstat[UDP_NSTATS];
    489  1.38    bouyer 	u_quad_t delivered;
    490   1.1       cgd 
    491  1.65      elad 	if (use_sysctl) {
    492  1.65      elad 		size_t size = sizeof(udpstat);
    493  1.65      elad 
    494  1.80   thorpej 		if (sysctlbyname("net.inet.udp.stats", udpstat, &size,
    495  1.65      elad 				 NULL, 0) == -1)
    496  1.88   thorpej 			return;
    497  1.65      elad 	} else {
    498  1.88   thorpej 		warnx("%s stats not available via KVM.", name);
    499  1.88   thorpej 		return;
    500  1.65      elad 	}
    501  1.65      elad 
    502  1.65      elad 	printf ("%s:\n", name);
    503  1.15   mycroft 
    504  1.80   thorpej #define	ps(f, m) if (udpstat[f] || sflag <= 1) \
    505  1.95    dyoung     printf(m, udpstat[f])
    506  1.80   thorpej #define	p(f, m) if (udpstat[f] || sflag <= 1) \
    507  1.95    dyoung     printf(m, udpstat[f], plural(udpstat[f]))
    508  1.80   thorpej #define	p3(f, m) if (udpstat[f] || sflag <= 1) \
    509  1.95    dyoung     printf(m, udpstat[f], plurales(udpstat[f]))
    510  1.80   thorpej 
    511  1.95    dyoung 	p(UDP_STAT_IPACKETS, "\t%" PRIu64 " datagram%s received\n");
    512  1.95    dyoung 	ps(UDP_STAT_HDROPS, "\t%" PRIu64 " with incomplete header\n");
    513  1.95    dyoung 	ps(UDP_STAT_BADLEN, "\t%" PRIu64 " with bad data length field\n");
    514  1.95    dyoung 	ps(UDP_STAT_BADSUM, "\t%" PRIu64 " with bad checksum\n");
    515  1.95    dyoung 	ps(UDP_STAT_NOPORT, "\t%" PRIu64 " dropped due to no socket\n");
    516  1.80   thorpej 	p(UDP_STAT_NOPORTBCAST,
    517  1.95    dyoung 	  "\t%" PRIu64 " broadcast/multicast datagram%s dropped due to no socket\n");
    518  1.95    dyoung 	ps(UDP_STAT_FULLSOCK, "\t%" PRIu64 " dropped due to full socket buffers\n");
    519  1.80   thorpej 	delivered = udpstat[UDP_STAT_IPACKETS] -
    520  1.80   thorpej 		    udpstat[UDP_STAT_HDROPS] -
    521  1.80   thorpej 		    udpstat[UDP_STAT_BADLEN] -
    522  1.80   thorpej 		    udpstat[UDP_STAT_BADSUM] -
    523  1.80   thorpej 		    udpstat[UDP_STAT_NOPORT] -
    524  1.80   thorpej 		    udpstat[UDP_STAT_NOPORTBCAST] -
    525  1.80   thorpej 		    udpstat[UDP_STAT_FULLSOCK];
    526   1.9   mycroft 	if (delivered || sflag <= 1)
    527  1.95    dyoung 		printf("\t%" PRIu64 " delivered\n", delivered);
    528  1.95    dyoung 	p3(UDP_STAT_PCBHASHMISS, "\t%" PRIu64 " PCB hash miss%s\n");
    529  1.95    dyoung 	p(UDP_STAT_OPACKETS, "\t%" PRIu64 " datagram%s output\n");
    530  1.15   mycroft 
    531  1.20  christos #undef ps
    532   1.9   mycroft #undef p
    533  1.15   mycroft #undef p3
    534   1.1       cgd }
    535   1.1       cgd 
    536   1.1       cgd /*
    537   1.1       cgd  * Dump IP statistics structure.
    538   1.1       cgd  */
    539   1.9   mycroft void
    540  1.90     lukem ip_stats(u_long off, const char *name)
    541   1.1       cgd {
    542  1.82   thorpej 	uint64_t ipstat[IP_NSTATS];
    543   1.1       cgd 
    544  1.65      elad 	if (use_sysctl) {
    545  1.65      elad 		size_t size = sizeof(ipstat);
    546  1.65      elad 
    547  1.82   thorpej 		if (sysctlbyname("net.inet.ip.stats", ipstat, &size,
    548  1.65      elad 				 NULL, 0) == -1)
    549  1.88   thorpej 			return;
    550  1.65      elad 	} else {
    551  1.88   thorpej 		warnx("%s stats not available via KVM.", name);
    552  1.88   thorpej 		return;
    553  1.65      elad 	}
    554  1.65      elad 
    555   1.9   mycroft 	printf("%s:\n", name);
    556   1.9   mycroft 
    557  1.82   thorpej #define	ps(f, m) if (ipstat[f] || sflag <= 1) \
    558  1.95    dyoung     printf(m, ipstat[f])
    559  1.82   thorpej #define	p(f, m) if (ipstat[f] || sflag <= 1) \
    560  1.95    dyoung     printf(m, ipstat[f], plural(ipstat[f]))
    561  1.82   thorpej 
    562  1.95    dyoung 	p(IP_STAT_TOTAL, "\t%" PRIu64 " total packet%s received\n");
    563  1.95    dyoung 	p(IP_STAT_BADSUM, "\t%" PRIu64 " bad header checksum%s\n");
    564  1.95    dyoung 	ps(IP_STAT_TOOSMALL, "\t%" PRIu64 " with size smaller than minimum\n");
    565  1.95    dyoung 	ps(IP_STAT_TOOSHORT, "\t%" PRIu64 " with data size < data length\n");
    566  1.95    dyoung 	ps(IP_STAT_TOOLONG, "\t%" PRIu64 " with length > max ip packet size\n");
    567  1.95    dyoung 	ps(IP_STAT_BADHLEN, "\t%" PRIu64 " with header length < data size\n");
    568  1.95    dyoung 	ps(IP_STAT_BADLEN, "\t%" PRIu64 " with data length < header length\n");
    569  1.95    dyoung 	ps(IP_STAT_BADOPTIONS, "\t%" PRIu64 " with bad options\n");
    570  1.95    dyoung 	ps(IP_STAT_BADVERS, "\t%" PRIu64 " with incorrect version number\n");
    571  1.95    dyoung 	p(IP_STAT_FRAGMENTS, "\t%" PRIu64 " fragment%s received\n");
    572  1.95    dyoung 	p(IP_STAT_FRAGDROPPED, "\t%" PRIu64 " fragment%s dropped (dup or out of space)\n");
    573  1.95    dyoung 	p(IP_STAT_RCVMEMDROP, "\t%" PRIu64 " fragment%s dropped (out of ipqent)\n");
    574  1.95    dyoung 	p(IP_STAT_BADFRAGS, "\t%" PRIu64 " malformed fragment%s dropped\n");
    575  1.95    dyoung 	p(IP_STAT_FRAGTIMEOUT, "\t%" PRIu64 " fragment%s dropped after timeout\n");
    576  1.95    dyoung 	p(IP_STAT_REASSEMBLED, "\t%" PRIu64 " packet%s reassembled ok\n");
    577  1.95    dyoung 	p(IP_STAT_DELIVERED, "\t%" PRIu64 " packet%s for this host\n");
    578  1.95    dyoung 	p(IP_STAT_NOPROTO, "\t%" PRIu64 " packet%s for unknown/unsupported protocol\n");
    579  1.95    dyoung 	p(IP_STAT_FORWARD, "\t%" PRIu64 " packet%s forwarded");
    580  1.95    dyoung 	p(IP_STAT_FASTFORWARD, " (%" PRIu64 " packet%s fast forwarded)");
    581  1.82   thorpej 	if (ipstat[IP_STAT_FORWARD] || sflag <= 1)
    582  1.29      matt 		putchar('\n');
    583  1.95    dyoung 	p(IP_STAT_CANTFORWARD, "\t%" PRIu64 " packet%s not forwardable\n");
    584  1.95    dyoung 	p(IP_STAT_REDIRECTSENT, "\t%" PRIu64 " redirect%s sent\n");
    585  1.95    dyoung 	p(IP_STAT_NOGIF, "\t%" PRIu64 " packet%s no matching gif found\n");
    586  1.95    dyoung 	p(IP_STAT_LOCALOUT, "\t%" PRIu64 " packet%s sent from this host\n");
    587  1.95    dyoung 	p(IP_STAT_RAWOUT, "\t%" PRIu64 " packet%s sent with fabricated ip header\n");
    588  1.95    dyoung 	p(IP_STAT_ODROPPED, "\t%" PRIu64 " output packet%s dropped due to no bufs, etc.\n");
    589  1.95    dyoung 	p(IP_STAT_NOROUTE, "\t%" PRIu64 " output packet%s discarded due to no route\n");
    590  1.95    dyoung 	p(IP_STAT_FRAGMENTED, "\t%" PRIu64 " output datagram%s fragmented\n");
    591  1.95    dyoung 	p(IP_STAT_OFRAGMENTS, "\t%" PRIu64 " fragment%s created\n");
    592  1.95    dyoung 	p(IP_STAT_CANTFRAG, "\t%" PRIu64 " datagram%s that can't be fragmented\n");
    593  1.95    dyoung 	p(IP_STAT_BADADDR, "\t%" PRIu64 " datagram%s with bad address in header\n");
    594  1.20  christos #undef ps
    595   1.9   mycroft #undef p
    596   1.1       cgd }
    597   1.1       cgd 
    598  1.79   thorpej static	const char *icmpnames[] = {
    599   1.1       cgd 	"echo reply",
    600   1.1       cgd 	"#1",
    601   1.1       cgd 	"#2",
    602   1.1       cgd 	"destination unreachable",
    603   1.1       cgd 	"source quench",
    604   1.1       cgd 	"routing redirect",
    605  1.44    itojun 	"alternate host address",
    606   1.1       cgd 	"#7",
    607   1.1       cgd 	"echo",
    608  1.44    itojun 	"router advertisement",
    609  1.44    itojun 	"router solicitation",
    610   1.1       cgd 	"time exceeded",
    611   1.1       cgd 	"parameter problem",
    612   1.1       cgd 	"time stamp",
    613   1.1       cgd 	"time stamp reply",
    614   1.1       cgd 	"information request",
    615   1.1       cgd 	"information request reply",
    616   1.1       cgd 	"address mask request",
    617   1.1       cgd 	"address mask reply",
    618   1.1       cgd };
    619   1.1       cgd 
    620   1.1       cgd /*
    621   1.1       cgd  * Dump ICMP statistics.
    622   1.1       cgd  */
    623   1.9   mycroft void
    624  1.90     lukem icmp_stats(u_long off, const char *name)
    625   1.1       cgd {
    626  1.79   thorpej 	uint64_t icmpstat[ICMP_NSTATS];
    627  1.23     lukem 	int i, first;
    628   1.1       cgd 
    629  1.65      elad 	if (use_sysctl) {
    630  1.65      elad 		size_t size = sizeof(icmpstat);
    631  1.65      elad 
    632  1.79   thorpej 		if (sysctlbyname("net.inet.icmp.stats", icmpstat, &size,
    633  1.65      elad 				 NULL, 0) == -1)
    634  1.88   thorpej 			return;
    635  1.65      elad 	} else {
    636  1.88   thorpej 		warnx("%s stats not available via KVM.", name);
    637  1.88   thorpej 		return;
    638  1.65      elad 	}
    639  1.65      elad 
    640   1.9   mycroft 	printf("%s:\n", name);
    641   1.9   mycroft 
    642  1.79   thorpej #define	p(f, m) if (icmpstat[f] || sflag <= 1) \
    643  1.95    dyoung     printf(m, icmpstat[f], plural(icmpstat[f]))
    644   1.9   mycroft 
    645  1.95    dyoung 	p(ICMP_STAT_ERROR, "\t%" PRIu64 " call%s to icmp_error\n");
    646  1.79   thorpej 	p(ICMP_STAT_OLDICMP,
    647  1.95    dyoung 	    "\t%" PRIu64 " error%s not generated because old message was icmp\n");
    648   1.1       cgd 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
    649  1.79   thorpej 		if (icmpstat[ICMP_STAT_OUTHIST + i] != 0) {
    650   1.1       cgd 			if (first) {
    651   1.1       cgd 				printf("\tOutput histogram:\n");
    652   1.1       cgd 				first = 0;
    653   1.1       cgd 			}
    654  1.95    dyoung 			printf("\t\t%s: %" PRIu64 "\n", icmpnames[i],
    655  1.95    dyoung 			   icmpstat[ICMP_STAT_OUTHIST + i]);
    656   1.1       cgd 		}
    657  1.95    dyoung 	p(ICMP_STAT_BADCODE, "\t%" PRIu64 " message%s with bad code fields\n");
    658  1.95    dyoung 	p(ICMP_STAT_TOOSHORT, "\t%" PRIu64 " message%s < minimum length\n");
    659  1.95    dyoung 	p(ICMP_STAT_CHECKSUM, "\t%" PRIu64 " bad checksum%s\n");
    660  1.95    dyoung 	p(ICMP_STAT_BADLEN, "\t%" PRIu64 " message%s with bad length\n");
    661  1.95    dyoung 	p(ICMP_STAT_BMCASTECHO, "\t%" PRIu64 " multicast echo request%s ignored\n");
    662  1.95    dyoung 	p(ICMP_STAT_BMCASTTSTAMP, "\t%" PRIu64 " multicast timestamp request%s ignored\n");
    663   1.1       cgd 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
    664  1.79   thorpej 		if (icmpstat[ICMP_STAT_INHIST + i] != 0) {
    665   1.1       cgd 			if (first) {
    666   1.1       cgd 				printf("\tInput histogram:\n");
    667   1.1       cgd 				first = 0;
    668   1.1       cgd 			}
    669  1.95    dyoung 			printf("\t\t%s: %" PRIu64 "\n", icmpnames[i],
    670  1.95    dyoung 			    icmpstat[ICMP_STAT_INHIST + i]);
    671   1.1       cgd 		}
    672  1.95    dyoung 	p(ICMP_STAT_REFLECT, "\t%" PRIu64 " message response%s generated\n");
    673  1.95    dyoung 	p(ICMP_STAT_PMTUCHG, "\t%" PRIu64 " path MTU change%s\n");
    674   1.9   mycroft #undef p
    675   1.6    brezak }
    676   1.6    brezak 
    677   1.6    brezak /*
    678   1.9   mycroft  * Dump IGMP statistics structure.
    679   1.6    brezak  */
    680   1.6    brezak void
    681  1.90     lukem igmp_stats(u_long off, const char *name)
    682   1.6    brezak {
    683  1.87   thorpej 	uint64_t igmpstat[IGMP_NSTATS];
    684  1.87   thorpej 
    685  1.87   thorpej 	if (use_sysctl) {
    686  1.87   thorpej 		size_t size = sizeof(igmpstat);
    687  1.87   thorpej 
    688  1.87   thorpej 		if (sysctlbyname("net.inet.igmp.stats", igmpstat, &size,
    689  1.87   thorpej 				 NULL, 0) == -1)
    690  1.88   thorpej 			return;
    691  1.87   thorpej 	} else {
    692  1.88   thorpej 		warnx("%s stats not available via KVM.", name);
    693  1.88   thorpej 		return;
    694  1.87   thorpej 	}
    695   1.6    brezak 
    696   1.9   mycroft 	printf("%s:\n", name);
    697   1.9   mycroft 
    698  1.87   thorpej #define	p(f, m) if (igmpstat[f] || sflag <= 1) \
    699  1.95    dyoung     printf(m, igmpstat[f], plural(igmpstat[f]))
    700  1.87   thorpej #define	py(f, m) if (igmpstat[f] || sflag <= 1) \
    701  1.95    dyoung     printf(m, igmpstat[f], igmpstat[f] != 1 ? "ies" : "y")
    702  1.95    dyoung 	p(IGMP_STAT_RCV_TOTAL, "\t%" PRIu64 " message%s received\n");
    703  1.95    dyoung         p(IGMP_STAT_RCV_TOOSHORT, "\t%" PRIu64 " message%s received with too few bytes\n");
    704  1.95    dyoung         p(IGMP_STAT_RCV_BADSUM, "\t%" PRIu64 " message%s received with bad checksum\n");
    705  1.95    dyoung         py(IGMP_STAT_RCV_QUERIES, "\t%" PRIu64 " membership quer%s received\n");
    706  1.95    dyoung         py(IGMP_STAT_RCV_BADQUERIES, "\t%" PRIu64 " membership quer%s received with invalid field(s)\n");
    707  1.95    dyoung         p(IGMP_STAT_RCV_REPORTS, "\t%" PRIu64 " membership report%s received\n");
    708  1.95    dyoung         p(IGMP_STAT_RCV_BADREPORTS, "\t%" PRIu64 " membership report%s received with invalid field(s)\n");
    709  1.95    dyoung         p(IGMP_STAT_RCV_OURREPORTS, "\t%" PRIu64 " membership report%s received for groups to which we belong\n");
    710  1.95    dyoung         p(IGMP_STAT_SND_REPORTS, "\t%" PRIu64 " membership report%s sent\n");
    711   1.9   mycroft #undef p
    712   1.9   mycroft #undef py
    713  1.41     jhawk }
    714  1.41     jhawk 
    715  1.41     jhawk /*
    716  1.69  liamjfoy  * Dump CARP statistics structure.
    717  1.69  liamjfoy  */
    718  1.69  liamjfoy void
    719  1.90     lukem carp_stats(u_long off, const char *name)
    720  1.69  liamjfoy {
    721  1.85   thorpej 	uint64_t carpstat[CARP_NSTATS];
    722  1.69  liamjfoy 
    723  1.69  liamjfoy 	if (use_sysctl) {
    724  1.69  liamjfoy 		size_t size = sizeof(carpstat);
    725  1.69  liamjfoy 
    726  1.85   thorpej 		if (sysctlbyname("net.inet.carp.stats", carpstat, &size,
    727  1.88   thorpej 				 NULL, 0) == -1)
    728  1.73    rpaulo 			return;
    729  1.69  liamjfoy 	} else {
    730  1.88   thorpej 		warnx("%s stats not available via KVM.", name);
    731  1.88   thorpej 		return;
    732  1.69  liamjfoy 	}
    733  1.69  liamjfoy 
    734  1.69  liamjfoy 	printf("%s:\n", name);
    735  1.69  liamjfoy 
    736  1.85   thorpej #define p(f, m) if (carpstat[f] || sflag <= 1) \
    737  1.85   thorpej 	printf(m, carpstat[f], plural(carpstat[f]))
    738  1.85   thorpej #define p2(f, m) if (carpstat[f] || sflag <= 1) \
    739  1.85   thorpej 	printf(m, carpstat[f])
    740  1.85   thorpej 
    741  1.85   thorpej 	p(CARP_STAT_IPACKETS, "\t%" PRIu64 " packet%s received (IPv4)\n");
    742  1.85   thorpej 	p(CARP_STAT_IPACKETS6, "\t%" PRIu64 " packet%s received (IPv6)\n");
    743  1.85   thorpej 	p(CARP_STAT_BADIF,
    744  1.70       riz 	    "\t\t%" PRIu64 " packet%s discarded for bad interface\n");
    745  1.85   thorpej 	p(CARP_STAT_BADTTL,
    746  1.70       riz 	    "\t\t%" PRIu64 " packet%s discarded for wrong TTL\n");
    747  1.85   thorpej 	p(CARP_STAT_HDROPS, "\t\t%" PRIu64 " packet%s shorter than header\n");
    748  1.85   thorpej 	p(CARP_STAT_BADSUM, "\t\t%" PRIu64
    749  1.70       riz 		" packet%s discarded for bad checksum\n");
    750  1.85   thorpej 	p(CARP_STAT_BADVER,
    751  1.70       riz 	    "\t\t%" PRIu64 " packet%s discarded with a bad version\n");
    752  1.85   thorpej 	p2(CARP_STAT_BADLEN,
    753  1.70       riz 	    "\t\t%" PRIu64 " discarded because packet was too short\n");
    754  1.85   thorpej 	p(CARP_STAT_BADAUTH,
    755  1.70       riz 	    "\t\t%" PRIu64 " packet%s discarded for bad authentication\n");
    756  1.85   thorpej 	p(CARP_STAT_BADVHID, "\t\t%" PRIu64 " packet%s discarded for bad vhid\n");
    757  1.85   thorpej 	p(CARP_STAT_BADADDRS, "\t\t%" PRIu64
    758  1.70       riz 		" packet%s discarded because of a bad address list\n");
    759  1.85   thorpej 	p(CARP_STAT_OPACKETS, "\t%" PRIu64 " packet%s sent (IPv4)\n");
    760  1.85   thorpej 	p(CARP_STAT_OPACKETS6, "\t%" PRIu64 " packet%s sent (IPv6)\n");
    761  1.85   thorpej 	p2(CARP_STAT_ONOMEM,
    762  1.70       riz 	    "\t\t%" PRIu64 " send failed due to mbuf memory error\n");
    763  1.69  liamjfoy #undef p
    764  1.69  liamjfoy #undef p2
    765  1.69  liamjfoy }
    766  1.69  liamjfoy 
    767  1.69  liamjfoy /*
    768  1.62      manu  * Dump PIM statistics structure.
    769  1.62      manu  */
    770  1.62      manu void
    771  1.90     lukem pim_stats(u_long off, const char *name)
    772  1.62      manu {
    773  1.62      manu 	struct pimstat pimstat;
    774  1.62      manu 
    775  1.62      manu 	if (off == 0)
    776  1.62      manu 		return;
    777  1.62      manu 	if (kread(off, (char *)&pimstat, sizeof (pimstat)) != 0) {
    778  1.62      manu 		/* XXX: PIM is probably not enabled in the kernel */
    779  1.62      manu 		return;
    780  1.62      manu 	}
    781  1.62      manu 
    782  1.62      manu 	printf("%s:\n", name);
    783  1.62      manu 
    784  1.62      manu #define	p(f, m) if (pimstat.f || sflag <= 1) \
    785  1.95    dyoung 	printf(m, pimstat.f, plural(pimstat.f))
    786  1.62      manu 
    787  1.95    dyoung 	p(pims_rcv_total_msgs, "\t%" PRIu64 " message%s received\n");
    788  1.95    dyoung 	p(pims_rcv_total_bytes, "\t%" PRIu64 " byte%s received\n");
    789  1.95    dyoung 	p(pims_rcv_tooshort, "\t%" PRIu64 " message%s received with too few bytes\n");
    790  1.95    dyoung         p(pims_rcv_badsum, "\t%" PRIu64 " message%s received with bad checksum\n");
    791  1.95    dyoung 	p(pims_rcv_badversion, "\t%" PRIu64 " message%s received with bad version\n");
    792  1.95    dyoung 	p(pims_rcv_registers_msgs, "\t%" PRIu64 " data register message%s received\n");
    793  1.95    dyoung 	p(pims_rcv_registers_bytes, "\t%" PRIu64 " data register byte%s received\n");
    794  1.95    dyoung 	p(pims_rcv_registers_wrongiif, "\t%" PRIu64 " data register message%s received on wrong iif\n");
    795  1.95    dyoung 	p(pims_rcv_badregisters, "\t%" PRIu64 " bad register%s received\n");
    796  1.95    dyoung 	p(pims_snd_registers_msgs, "\t%" PRIu64 " data register message%s sent\n");
    797  1.95    dyoung 	p(pims_snd_registers_bytes, "\t%" PRIu64 " data register byte%s sent\n");
    798  1.62      manu #undef p
    799  1.62      manu }
    800  1.62      manu 
    801  1.62      manu /*
    802  1.41     jhawk  * Dump the ARP statistics structure.
    803  1.41     jhawk  */
    804  1.41     jhawk void
    805  1.90     lukem arp_stats(u_long off, const char *name)
    806  1.41     jhawk {
    807  1.86   thorpej 	uint64_t arpstat[ARP_NSTATS];
    808  1.86   thorpej 
    809  1.86   thorpej 	if (use_sysctl) {
    810  1.86   thorpej 		size_t size = sizeof(arpstat);
    811  1.86   thorpej 
    812  1.86   thorpej 		if (sysctlbyname("net.inet.arp.stats", arpstat, &size,
    813  1.88   thorpej 				 NULL, 0) == -1)
    814  1.86   thorpej 			return;
    815  1.86   thorpej 	} else {
    816  1.88   thorpej 		warnx("%s stats not available via KVM.", name);
    817  1.88   thorpej 		return;
    818  1.86   thorpej 	}
    819  1.41     jhawk 
    820  1.41     jhawk 	printf("%s:\n", name);
    821  1.41     jhawk 
    822  1.86   thorpej #define	ps(f, m) if (arpstat[f] || sflag <= 1) \
    823  1.95    dyoung     printf(m, arpstat[f])
    824  1.86   thorpej #define	p(f, m) if (arpstat[f] || sflag <= 1) \
    825  1.95    dyoung     printf(m, arpstat[f], plural(arpstat[f]))
    826  1.86   thorpej 
    827  1.95    dyoung 	p(ARP_STAT_SNDTOTAL, "\t%" PRIu64 " packet%s sent\n");
    828  1.95    dyoung 	p(ARP_STAT_SNDREPLY, "\t\t%" PRIu64 " reply packet%s\n");
    829  1.95    dyoung 	p(ARP_STAT_SENDREQUEST, "\t\t%" PRIu64 " request packet%s\n");
    830  1.95    dyoung 
    831  1.95    dyoung 	p(ARP_STAT_RCVTOTAL, "\t%" PRIu64 " packet%s received\n");
    832  1.95    dyoung 	p(ARP_STAT_RCVREPLY, "\t\t%" PRIu64 " reply packet%s\n");
    833  1.95    dyoung 	p(ARP_STAT_RCVREQUEST, "\t\t%" PRIu64 " valid request packet%s\n");
    834  1.95    dyoung 	p(ARP_STAT_RCVMCAST, "\t\t%" PRIu64 " broadcast/multicast packet%s\n");
    835  1.95    dyoung 	p(ARP_STAT_RCVBADPROTO, "\t\t%" PRIu64 " packet%s with unknown protocol type\n");
    836  1.95    dyoung 	p(ARP_STAT_RCVBADLEN, "\t\t%" PRIu64 " packet%s with bad (short) length\n");
    837  1.95    dyoung 	p(ARP_STAT_RCVZEROTPA, "\t\t%" PRIu64 " packet%s with null target IP address\n");
    838  1.95    dyoung 	p(ARP_STAT_RCVZEROSPA, "\t\t%" PRIu64 " packet%s with null source IP address\n");
    839  1.95    dyoung 	ps(ARP_STAT_RCVNOINT, "\t\t%" PRIu64 " could not be mapped to an interface\n");
    840  1.95    dyoung 	p(ARP_STAT_RCVLOCALSHA, "\t\t%" PRIu64 " packet%s sourced from a local hardware "
    841  1.41     jhawk 	    "address\n");
    842  1.95    dyoung 	p(ARP_STAT_RCVBCASTSHA, "\t\t%" PRIu64 " packet%s with a broadcast "
    843  1.41     jhawk 	    "source hardware address\n");
    844  1.95    dyoung 	p(ARP_STAT_RCVLOCALSPA, "\t\t%" PRIu64 " duplicate%s for a local IP address\n");
    845  1.95    dyoung 	p(ARP_STAT_RCVOVERPERM, "\t\t%" PRIu64 " attempt%s to overwrite a static entry\n");
    846  1.95    dyoung 	p(ARP_STAT_RCVOVERINT, "\t\t%" PRIu64 " packet%s received on wrong interface\n");
    847  1.95    dyoung 	p(ARP_STAT_RCVOVER, "\t\t%" PRIu64 " entry%s overwritten\n");
    848  1.95    dyoung 	p(ARP_STAT_RCVLENCHG, "\t\t%" PRIu64 " change%s in hardware address length\n");
    849  1.95    dyoung 
    850  1.95    dyoung 	p(ARP_STAT_DFRTOTAL, "\t%" PRIu64 " packet%s deferred pending ARP resolution\n");
    851  1.95    dyoung 	ps(ARP_STAT_DFRSENT, "\t\t%" PRIu64 " sent\n");
    852  1.95    dyoung 	ps(ARP_STAT_DFRDROPPED, "\t\t%" PRIu64 " dropped\n");
    853  1.41     jhawk 
    854  1.95    dyoung 	p(ARP_STAT_ALLOCFAIL, "\t%" PRIu64 " failure%s to allocate llinfo\n");
    855  1.41     jhawk 
    856  1.41     jhawk #undef ps
    857  1.41     jhawk #undef p
    858   1.1       cgd }
    859   1.1       cgd 
    860   1.1       cgd /*
    861   1.1       cgd  * Pretty print an Internet address (net address + port).
    862  1.46     assar  * Take numeric_addr and numeric_port into consideration.
    863   1.1       cgd  */
    864   1.9   mycroft void
    865  1.84   thorpej inetprint(struct in_addr *in, uint16_t port, const char *proto,
    866  1.90     lukem 	  int port_numeric)
    867   1.1       cgd {
    868   1.1       cgd 	struct servent *sp = 0;
    869   1.9   mycroft 	char line[80], *cp;
    870  1.33  sommerfe 	size_t space;
    871   1.1       cgd 
    872  1.32       mrg 	(void)snprintf(line, sizeof line, "%.*s.",
    873  1.46     assar 	    (Aflag && !numeric_addr) ? 12 : 16, inetname(in));
    874  1.23     lukem 	cp = strchr(line, '\0');
    875  1.90     lukem 	if (!port_numeric && port)
    876   1.1       cgd 		sp = getservbyport((int)port, proto);
    877  1.33  sommerfe 	space = sizeof line - (cp-line);
    878   1.1       cgd 	if (sp || port == 0)
    879  1.55  jdolecek 		(void)snprintf(cp, space, "%s", sp ? sp->s_name : "*");
    880   1.1       cgd 	else
    881  1.33  sommerfe 		(void)snprintf(cp, space, "%u", ntohs(port));
    882  1.32       mrg 	(void)printf(" %-*.*s", width, width, line);
    883   1.1       cgd }
    884   1.1       cgd 
    885   1.1       cgd /*
    886   1.1       cgd  * Construct an Internet address representation.
    887  1.46     assar  * If numeric_addr has been supplied, give
    888   1.1       cgd  * numeric value, otherwise try for symbolic name.
    889   1.1       cgd  */
    890   1.1       cgd char *
    891  1.84   thorpej inetname(struct in_addr *inp)
    892   1.1       cgd {
    893  1.23     lukem 	char *cp;
    894   1.1       cgd 	static char line[50];
    895   1.1       cgd 	struct hostent *hp;
    896   1.1       cgd 	struct netent *np;
    897   1.1       cgd 	static char domain[MAXHOSTNAMELEN + 1];
    898   1.1       cgd 	static int first = 1;
    899   1.1       cgd 
    900  1.46     assar 	if (first && !numeric_addr) {
    901   1.1       cgd 		first = 0;
    902  1.31       mrg 		if (gethostname(domain, sizeof domain) == 0) {
    903  1.31       mrg 			domain[sizeof(domain) - 1] = '\0';
    904  1.31       mrg 			if ((cp = strchr(domain, '.')))
    905  1.45    itojun 				(void) strlcpy(domain, cp + 1, sizeof(domain));
    906  1.31       mrg 			else
    907  1.31       mrg 				domain[0] = 0;
    908  1.31       mrg 		} else
    909   1.1       cgd 			domain[0] = 0;
    910   1.1       cgd 	}
    911   1.1       cgd 	cp = 0;
    912  1.46     assar 	if (!numeric_addr && inp->s_addr != INADDR_ANY) {
    913   1.9   mycroft 		int net = inet_netof(*inp);
    914   1.9   mycroft 		int lna = inet_lnaof(*inp);
    915   1.1       cgd 
    916   1.1       cgd 		if (lna == INADDR_ANY) {
    917   1.1       cgd 			np = getnetbyaddr(net, AF_INET);
    918   1.1       cgd 			if (np)
    919   1.1       cgd 				cp = np->n_name;
    920   1.1       cgd 		}
    921   1.1       cgd 		if (cp == 0) {
    922   1.9   mycroft 			hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET);
    923   1.1       cgd 			if (hp) {
    924  1.23     lukem 				if ((cp = strchr(hp->h_name, '.')) &&
    925   1.1       cgd 				    !strcmp(cp + 1, domain))
    926   1.1       cgd 					*cp = 0;
    927   1.1       cgd 				cp = hp->h_name;
    928   1.1       cgd 			}
    929   1.1       cgd 		}
    930   1.1       cgd 	}
    931   1.9   mycroft 	if (inp->s_addr == INADDR_ANY)
    932  1.56    itojun 		strlcpy(line, "*", sizeof line);
    933   1.1       cgd 	else if (cp)
    934  1.56    itojun 		strlcpy(line, cp, sizeof line);
    935   1.1       cgd 	else {
    936   1.9   mycroft 		inp->s_addr = ntohl(inp->s_addr);
    937   1.1       cgd #define C(x)	((x) & 0xff)
    938  1.32       mrg 		(void)snprintf(line, sizeof line, "%u.%u.%u.%u",
    939  1.32       mrg 		    C(inp->s_addr >> 24), C(inp->s_addr >> 16),
    940  1.32       mrg 		    C(inp->s_addr >> 8), C(inp->s_addr));
    941  1.32       mrg #undef C
    942   1.1       cgd 	}
    943   1.1       cgd 	return (line);
    944  1.30   thorpej }
    945  1.30   thorpej 
    946  1.30   thorpej /*
    947  1.30   thorpej  * Dump the contents of a TCP PCB.
    948  1.30   thorpej  */
    949  1.30   thorpej void
    950  1.84   thorpej tcp_dump(u_long pcbaddr)
    951  1.30   thorpej {
    952  1.78        ad 	callout_impl_t *ci;
    953  1.30   thorpej 	struct tcpcb tcpcb;
    954  1.54   thorpej 	int i, hardticks;
    955  1.30   thorpej 
    956  1.30   thorpej 	kread(pcbaddr, (char *)&tcpcb, sizeof(tcpcb));
    957  1.54   thorpej 	hardticks = get_hardticks();
    958  1.30   thorpej 
    959  1.30   thorpej 	printf("TCP Protocol Control Block at 0x%08lx:\n\n", pcbaddr);
    960  1.30   thorpej 
    961  1.30   thorpej 	printf("Timers:\n");
    962  1.48   thorpej 	for (i = 0; i < TCPT_NTIMERS; i++) {
    963  1.78        ad 		ci = (callout_impl_t *)&tcpcb.t_timer[i];
    964  1.54   thorpej 		printf("\t%s: %d", tcptimers[i],
    965  1.78        ad 		    (ci->c_flags & CALLOUT_PENDING) ?
    966  1.78        ad 		    ci->c_time - hardticks : 0);
    967  1.48   thorpej 	}
    968  1.30   thorpej 	printf("\n\n");
    969  1.30   thorpej 
    970  1.30   thorpej 	if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES)
    971  1.30   thorpej 		printf("State: %d", tcpcb.t_state);
    972  1.30   thorpej 	else
    973  1.30   thorpej 		printf("State: %s", tcpstates[tcpcb.t_state]);
    974  1.49   thorpej 	printf(", flags 0x%x, inpcb 0x%lx, in6pcb 0x%lx\n\n", tcpcb.t_flags,
    975  1.49   thorpej 	    (u_long)tcpcb.t_inpcb, (u_long)tcpcb.t_in6pcb);
    976  1.30   thorpej 
    977  1.30   thorpej 	printf("rxtshift %d, rxtcur %d, dupacks %d\n", tcpcb.t_rxtshift,
    978  1.30   thorpej 	    tcpcb.t_rxtcur, tcpcb.t_dupacks);
    979  1.30   thorpej 	printf("peermss %u, ourmss %u, segsz %u\n\n", tcpcb.t_peermss,
    980  1.30   thorpej 	    tcpcb.t_ourmss, tcpcb.t_segsz);
    981  1.30   thorpej 
    982  1.30   thorpej 	printf("snd_una %u, snd_nxt %u, snd_up %u\n",
    983  1.30   thorpej 	    tcpcb.snd_una, tcpcb.snd_nxt, tcpcb.snd_up);
    984  1.30   thorpej 	printf("snd_wl1 %u, snd_wl2 %u, iss %u, snd_wnd %lu\n\n",
    985  1.30   thorpej 	    tcpcb.snd_wl1, tcpcb.snd_wl2, tcpcb.iss, tcpcb.snd_wnd);
    986  1.30   thorpej 
    987  1.30   thorpej 	printf("rcv_wnd %lu, rcv_nxt %u, rcv_up %u, irs %u\n\n",
    988  1.30   thorpej 	    tcpcb.rcv_wnd, tcpcb.rcv_nxt, tcpcb.rcv_up, tcpcb.irs);
    989  1.30   thorpej 
    990  1.30   thorpej 	printf("rcv_adv %u, snd_max %u, snd_cwnd %lu, snd_ssthresh %lu\n",
    991  1.30   thorpej 	    tcpcb.rcv_adv, tcpcb.snd_max, tcpcb.snd_cwnd, tcpcb.snd_ssthresh);
    992  1.30   thorpej 
    993  1.47   thorpej 	printf("rcvtime %u, rtttime %u, rtseq %u, srtt %d, rttvar %d, "
    994  1.47   thorpej 	    "rttmin %d, max_sndwnd %lu\n\n", tcpcb.t_rcvtime, tcpcb.t_rtttime,
    995  1.47   thorpej 	    tcpcb.t_rtseq, tcpcb.t_srtt, tcpcb.t_rttvar, tcpcb.t_rttmin,
    996  1.47   thorpej 	    tcpcb.max_sndwnd);
    997  1.30   thorpej 
    998  1.30   thorpej 	printf("oobflags %d, iobc %d, softerror %d\n\n", tcpcb.t_oobflags,
    999  1.30   thorpej 	    tcpcb.t_iobc, tcpcb.t_softerror);
   1000  1.30   thorpej 
   1001  1.30   thorpej 	printf("snd_scale %d, rcv_scale %d, req_r_scale %d, req_s_scale %d\n",
   1002  1.30   thorpej 	    tcpcb.snd_scale, tcpcb.rcv_scale, tcpcb.request_r_scale,
   1003  1.30   thorpej 	    tcpcb.requested_s_scale);
   1004  1.30   thorpej 	printf("ts_recent %u, ts_regent_age %d, last_ack_sent %u\n",
   1005  1.30   thorpej 	    tcpcb.ts_recent, tcpcb.ts_recent_age, tcpcb.last_ack_sent);
   1006   1.1       cgd }
   1007