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