xref: /openbsd-src/usr.bin/netstat/inet.c (revision cb39b41371628601fbe4c618205356d538b9d08a)
1 /*	$OpenBSD: inet.c,v 1.142 2015/04/16 19:24:13 markus Exp $	*/
2 /*	$NetBSD: inet.c,v 1.14 1995/10/03 21:42:37 thorpej Exp $	*/
3 
4 /*
5  * Copyright (c) 1983, 1988, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 #include <sys/queue.h>
34 #include <sys/socket.h>
35 #include <sys/socketvar.h>
36 #include <sys/domain.h>
37 #include <sys/protosw.h>
38 #include <sys/sysctl.h>
39 #define _KERNEL
40 #include <sys/ucred.h>
41 #include <sys/file.h>
42 #undef _KERNEL
43 
44 #include <net/route.h>
45 #include <netinet/in.h>
46 #include <netinet/ip.h>
47 #include <netinet/in_pcb.h>
48 #include <netinet/ip_icmp.h>
49 #include <netinet/icmp_var.h>
50 #include <netinet/igmp_var.h>
51 #include <netinet/ip_var.h>
52 #include <netinet/pim_var.h>
53 #include <netinet/tcp.h>
54 #include <netinet/tcp_seq.h>
55 #define TCPSTATES
56 #include <netinet/tcp_fsm.h>
57 #include <netinet/tcp_timer.h>
58 #include <netinet/tcp_var.h>
59 #include <netinet/udp.h>
60 #include <netinet/udp_var.h>
61 #include <netinet/ip_ipsp.h>
62 #include <netinet/ip_ah.h>
63 #include <netinet/ip_esp.h>
64 #include <netinet/ip_ipip.h>
65 #include <netinet/ip_ipcomp.h>
66 #include <netinet/ip_ether.h>
67 #include <netinet/ip_carp.h>
68 #include <netinet/ip_divert.h>
69 #include <net/if.h>
70 #include <net/pfvar.h>
71 #include <net/if_pfsync.h>
72 #include <net/if_pflow.h>
73 
74 #include <rpc/rpc.h>
75 #include <rpc/pmap_prot.h>
76 #include <rpc/pmap_clnt.h>
77 
78 #include <arpa/inet.h>
79 #include <err.h>
80 #include <limits.h>
81 #include <netdb.h>
82 #include <stdio.h>
83 #include <string.h>
84 #include <unistd.h>
85 #include <stdlib.h>
86 #include <errno.h>
87 #include "netstat.h"
88 
89 struct	inpcb inpcb;
90 struct	tcpcb tcpcb;
91 struct	socket sockb;
92 
93 char	*inetname(struct in_addr *);
94 void	inetprint(struct in_addr *, in_port_t, const char *, int);
95 char	*inet6name(struct in6_addr *);
96 void	sosplice_dump(u_long);
97 void	sockbuf_dump(struct sockbuf *, const char *);
98 void	protosw_dump(u_long, u_long);
99 void	domain_dump(u_long, u_long, short);
100 void	inpcb_dump(u_long, short, int);
101 void	tcpcb_dump(u_long);
102 
103 int type_map[] = { -1, 2, 3, 1, 4, 5 };
104 
105 int
106 kf_comp(const void *a, const void *b)
107 {
108 	const struct kinfo_file *ka = a, *kb = b;
109 
110 	if (ka->so_family != kb->so_family) {
111 		/* AF_INET < AF_INET6 < AF_LOCAL */
112 		if (ka->so_family == AF_INET)
113 			return (-1);
114 		if (ka->so_family == AF_LOCAL)
115 			return (1);
116 		if (kb->so_family == AF_LOCAL)
117 			return (-1);
118 		return (1);
119 	}
120 	if (ka->so_family == AF_LOCAL) {
121 		if (type_map[ka->so_type] < type_map[kb->so_type])
122 			return (-1);
123 		if (type_map[ka->so_type] > type_map[kb->so_type])
124 			return (1);
125 	} else if (ka->so_family == AF_INET || ka->so_family == AF_INET6) {
126 		if (ka->so_protocol < kb->so_protocol)
127 			return (-1);
128 		if (ka->so_protocol > kb->so_protocol)
129 			return (1);
130 		if (ka->so_type == SOCK_DGRAM || ka->so_type == SOCK_STREAM) {
131 			/* order sockets by remote port desc */
132 			if (ka->inp_fport > kb->inp_fport)
133 				return (-1);
134 			if (ka->inp_fport < kb->inp_fport)
135 				return (1);
136 		} else if (ka->so_type == SOCK_RAW) {
137 			if (ka->inp_proto > kb->inp_proto)
138 				return (-1);
139 			if (ka->inp_proto < kb->inp_proto)
140 				return (1);
141 		}
142 	}
143 	return (0);
144 }
145 
146 void
147 protopr(kvm_t *kvmd, u_long pcbaddr, u_int tableid, int proto)
148 {
149 	struct kinfo_file *kf;
150 	int i, fcnt;
151 
152 	kf = kvm_getfiles(kvmd, KERN_FILE_BYFILE, DTYPE_SOCKET,
153 	    sizeof(*kf), &fcnt);
154 	if (kf == NULL) {
155 		printf("Out of memory (file table).\n");
156 		return;
157 	}
158 
159 	/* sort sockets by AF and type */
160 	qsort(kf, fcnt, sizeof(*kf), kf_comp);
161 
162 	for (i = 0; i < fcnt; i++) {
163 		if (Pflag) {
164 			switch (kf[i].so_family) {
165 			case AF_INET:
166 			case AF_INET6:
167 				/*
168 				 * XXX at the moment fstat returns the pointer
169 				 * to the so_pcb or for tcp sockets the tcpcb
170 				 * pointer (inp_ppcb) so check both.
171 				 */
172 				if (pcbaddr == kf[i].so_pcb) {
173 					inpcb_dump(pcbaddr, kf[i].so_protocol,
174 					    kf[i].so_family);
175 					return;
176 				} else if (pcbaddr == kf[i].inp_ppcb &&
177 				    kf[i].so_protocol == IPPROTO_TCP) {
178 					tcpcb_dump(pcbaddr);
179 					return;
180 				}
181 				break;
182 			case AF_UNIX:
183 				if (pcbaddr == kf[i].so_pcb) {
184 					unpcb_dump(pcbaddr);
185 					return;
186 				}
187 				break;
188 			}
189 			continue;
190 		}
191 		if (kf[i].so_family == AF_LOCAL && (kf[i].so_pcb != 0 ||
192 		    kf[i].unp_path[0] != '\0'))
193 			if ((af == AF_LOCAL || af == AF_UNSPEC) && !proto)
194 				unixdomainpr(&kf[i]);
195 		if (kf[i].so_family == AF_INET && kf[i].so_pcb != 0 &&
196 		    kf[i].inp_rtableid == tableid)
197 			if (af == AF_INET || af == AF_UNSPEC)
198 				netdomainpr(&kf[i], proto);
199 		if (kf[i].so_family == AF_INET6 && kf[i].so_pcb != 0 &&
200 		    kf[i].inp_rtableid == tableid)
201 			if (af == AF_INET6 || af == AF_UNSPEC)
202 				netdomainpr(&kf[i], proto);
203 	}
204 }
205 
206 /*
207  * Print a summary of connections related to an Internet
208  * protocol.  For TCP, also give state of connection.
209  * Listening processes (aflag) are suppressed unless the
210  * -a (all) flag is specified.
211  */
212 void
213 netdomainpr(struct kinfo_file *kf, int proto)
214 {
215 	static int af = 0, type = 0;
216 	struct in_addr laddr, faddr;
217 	struct in6_addr laddr6, faddr6;
218 	const char *name, *name6;
219 	int addrlen = 22;
220 	int isany = 0;
221 	int istcp = 0;
222 	int isip6 = 0;
223 
224 	/* XXX should fix kinfo_file instead but not now */
225 	if (kf->so_pcb == -1)
226 		kf->so_pcb = 0;
227 
228 	switch (proto) {
229 	case IPPROTO_TCP:
230 	case IPPROTO_UDP:
231 	case IPPROTO_DIVERT:
232 		if (kf->so_protocol != proto)
233 			return;
234 		break;
235 	case IPPROTO_IPV4:
236 		if (kf->so_type != SOCK_RAW || kf->so_family != AF_INET)
237 			return;
238 		break;
239 	case IPPROTO_IPV6:
240 		if (kf->so_type != SOCK_RAW || kf->so_family != AF_INET6)
241 			return;
242 		break;
243 	}
244 
245 	/* make in_addr6 access a bit easier */
246 #define s6_addr32 __u6_addr.__u6_addr32
247 	laddr.s_addr = kf->inp_laddru[0];
248 	laddr6.s6_addr32[0] = kf->inp_laddru[0];
249 	laddr6.s6_addr32[1] = kf->inp_laddru[1];
250 	laddr6.s6_addr32[2] = kf->inp_laddru[2];
251 	laddr6.s6_addr32[3] = kf->inp_laddru[3];
252 
253 	faddr.s_addr = kf->inp_faddru[0];
254 	faddr6.s6_addr32[0] = kf->inp_faddru[0];
255 	faddr6.s6_addr32[1] = kf->inp_faddru[1];
256 	faddr6.s6_addr32[2] = kf->inp_faddru[2];
257 	faddr6.s6_addr32[3] = kf->inp_faddru[3];
258 #undef s6_addr32
259 
260 	switch (kf->so_family) {
261 	case AF_INET:
262 		isany = faddr.s_addr == INADDR_ANY;
263 		break;
264 	case AF_INET6:
265 		isany = IN6_IS_ADDR_UNSPECIFIED(&faddr6);
266 		isip6 = 1;
267 		break;
268 	}
269 
270 	switch (kf->so_protocol) {
271 	case IPPROTO_TCP:
272 		name = "tcp";
273 		name6 = "tcp6";
274 		istcp = 1;
275 		break;
276 	case IPPROTO_UDP:
277 		name = "udp";
278 		name6 = "udp6";
279 		break;
280 	case IPPROTO_DIVERT:
281 		name = "divert";
282 		name6 = "divert6";
283 		break;
284 	default:
285 		name = "ip";
286 		name6 = "ip6";
287 		break;
288 	}
289 
290 	/* filter listening sockets out unless -a is set */
291 	if (!aflag && istcp && kf->t_state <= TCPS_LISTEN)
292 		return;
293 	else if (!aflag && isany)
294 		return;
295 
296 	if (af != kf->so_family || type != kf->so_type) {
297 		af = kf->so_family;
298 		type = kf->so_type;
299 		printf("Active Internet connections");
300 		if (aflag)
301 			printf(" (including servers)");
302 		putchar('\n');
303 		if (Aflag) {
304 			addrlen = 18;
305 			printf("%-*.*s ", PLEN, PLEN, "PCB");
306 		}
307 		printf("%-7.7s %-6.6s %-6.6s ",
308 		    "Proto", "Recv-Q", "Send-Q");
309 		if (Bflag && istcp)
310 			printf("%-6.6s %-6.6s %-6.6s ",
311 			    "Recv-W", "Send-W", "Cgst-W");
312 		printf(" %-*.*s %-*.*s %s\n",
313 		    addrlen, addrlen, "Local Address",
314 		    addrlen, addrlen, "Foreign Address", "(state)");
315 	}
316 
317 	if (Aflag)
318 		printf("%#*llx%s ", FAKE_PTR(kf->so_pcb));
319 
320 	printf("%-7.7s %6llu %6llu ",
321 	    isip6 ? name6: name, kf->so_rcv_cc, kf->so_snd_cc);
322 	if (Bflag && istcp)
323 		printf("%6llu %6llu %6llu ", kf->t_rcv_wnd, kf->t_snd_wnd,
324 		    (kf->t_state == TCPS_ESTABLISHED) ?
325 		    kf->t_snd_cwnd : 0);
326 
327 	if (isip6) {
328 		inet6print(&laddr6, kf->inp_lport, name);
329 		inet6print(&faddr6, kf->inp_fport, name);
330 	} else {
331 		inetprint(&laddr, kf->inp_lport, name, 1);
332 		inetprint(&faddr, kf->inp_fport, name, 0);
333 	}
334 	if (istcp) {
335 		if (kf->t_state < 0 || kf->t_state >= TCP_NSTATES)
336 			printf(" %d", kf->t_state);
337 		else
338 			printf(" %s", tcpstates[kf->t_state]);
339 	} else if (kf->so_type == SOCK_RAW) {
340 		printf(" %u", kf->inp_proto);
341 	}
342 	putchar('\n');
343 }
344 
345 /*
346  * Dump TCP statistics structure.
347  */
348 void
349 tcp_stats(char *name)
350 {
351 	struct tcpstat tcpstat;
352 	int mib[] = { CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_STATS };
353 	size_t len = sizeof(tcpstat);
354 
355 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
356 	    &tcpstat, &len, NULL, 0) == -1) {
357 		if (errno != ENOPROTOOPT)
358 			warn("%s", name);
359 		return;
360 	}
361 
362 	printf("%s:\n", name);
363 #define	p(f, m) if (tcpstat.f || sflag <= 1) \
364 	printf(m, tcpstat.f, plural(tcpstat.f))
365 #define	p1(f, m) if (tcpstat.f || sflag <= 1) \
366 	printf(m, tcpstat.f)
367 #define	p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
368 	printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2))
369 #define	p2a(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
370 	printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2)
371 #define	p3(f, m) if (tcpstat.f || sflag <= 1) \
372 	printf(m, tcpstat.f, plurales(tcpstat.f))
373 
374 	p(tcps_sndtotal, "\t%u packet%s sent\n");
375 	p2(tcps_sndpack,tcps_sndbyte,
376 	    "\t\t%u data packet%s (%qd byte%s)\n");
377 	p2(tcps_sndrexmitpack, tcps_sndrexmitbyte,
378 	    "\t\t%u data packet%s (%qd byte%s) retransmitted\n");
379 	p(tcps_sndrexmitfast, "\t\t%qd fast retransmitted packet%s\n");
380 	p2a(tcps_sndacks, tcps_delack,
381 	    "\t\t%u ack-only packet%s (%u delayed)\n");
382 	p(tcps_sndurg, "\t\t%u URG only packet%s\n");
383 	p(tcps_sndprobe, "\t\t%u window probe packet%s\n");
384 	p(tcps_sndwinup, "\t\t%u window update packet%s\n");
385 	p(tcps_sndctrl, "\t\t%u control packet%s\n");
386 	p(tcps_outswcsum, "\t\t%u packet%s software-checksummed\n");
387 	p(tcps_rcvtotal, "\t%u packet%s received\n");
388 	p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%u ack%s (for %qd byte%s)\n");
389 	p(tcps_rcvdupack, "\t\t%u duplicate ack%s\n");
390 	p(tcps_rcvacktoomuch, "\t\t%u ack%s for unsent data\n");
391 	p(tcps_rcvacktooold, "\t\t%u ack%s for old data\n");
392 	p2(tcps_rcvpack, tcps_rcvbyte,
393 	    "\t\t%u packet%s (%qu byte%s) received in-sequence\n");
394 	p2(tcps_rcvduppack, tcps_rcvdupbyte,
395 	    "\t\t%u completely duplicate packet%s (%qd byte%s)\n");
396 	p(tcps_pawsdrop, "\t\t%u old duplicate packet%s\n");
397 	p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte,
398 	    "\t\t%u packet%s with some duplicate data (%qd byte%s duplicated)\n");
399 	p2(tcps_rcvoopack, tcps_rcvoobyte,
400 	    "\t\t%u out-of-order packet%s (%qd byte%s)\n");
401 	p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin,
402 	    "\t\t%u packet%s (%qd byte%s) of data after window\n");
403 	p(tcps_rcvwinprobe, "\t\t%u window probe%s\n");
404 	p(tcps_rcvwinupd, "\t\t%u window update packet%s\n");
405 	p(tcps_rcvafterclose, "\t\t%u packet%s received after close\n");
406 	p(tcps_rcvbadsum, "\t\t%u discarded for bad checksum%s\n");
407 	p(tcps_rcvbadoff, "\t\t%u discarded for bad header offset field%s\n");
408 	p1(tcps_rcvshort, "\t\t%u discarded because packet too short\n");
409 	p1(tcps_rcvnosec, "\t\t%u discarded for missing IPsec protection\n");
410 	p1(tcps_rcvmemdrop, "\t\t%u discarded due to memory shortage\n");
411 	p(tcps_inswcsum, "\t\t%u packet%s software-checksummed\n");
412 	p(tcps_rcvbadsig, "\t\t%u bad/missing md5 checksum%s\n");
413 	p(tcps_rcvgoodsig, "\t\t%qd good md5 checksum%s\n");
414 	p(tcps_connattempt, "\t%u connection request%s\n");
415 	p(tcps_accepts, "\t%u connection accept%s\n");
416 	p(tcps_connects, "\t%u connection%s established (including accepts)\n");
417 	p2(tcps_closed, tcps_drops,
418 	    "\t%u connection%s closed (including %u drop%s)\n");
419 	p(tcps_conndrained, "\t%qd connection%s drained\n");
420 	p(tcps_conndrops, "\t%u embryonic connection%s dropped\n");
421 	p2(tcps_rttupdated, tcps_segstimed,
422 	    "\t%u segment%s updated rtt (of %u attempt%s)\n");
423 	p(tcps_rexmttimeo, "\t%u retransmit timeout%s\n");
424 	p(tcps_timeoutdrop, "\t\t%u connection%s dropped by rexmit timeout\n");
425 	p(tcps_persisttimeo, "\t%u persist timeout%s\n");
426 	p(tcps_keeptimeo, "\t%u keepalive timeout%s\n");
427 	p(tcps_keepprobe, "\t\t%u keepalive probe%s sent\n");
428 	p(tcps_keepdrops, "\t\t%u connection%s dropped by keepalive\n");
429 	p(tcps_predack, "\t%u correct ACK header prediction%s\n");
430 	p(tcps_preddat, "\t%u correct data packet header prediction%s\n");
431 	p3(tcps_pcbhashmiss, "\t%u PCB cache miss%s\n");
432 
433 	p(tcps_ecn_accepts, "\t%u ECN connection%s accepted\n");
434 	p(tcps_ecn_rcvece, "\t\t%u ECE packet%s received\n");
435 	p(tcps_ecn_rcvcwr, "\t\t%u CWR packet%s received\n");
436 	p(tcps_ecn_rcvce, "\t\t%u CE packet%s received\n");
437 	p(tcps_ecn_sndect, "\t\t%u ECT packet%s sent\n");
438 	p(tcps_ecn_sndece, "\t\t%u ECE packet%s sent\n");
439 	p(tcps_ecn_sndcwr, "\t\t%u CWR packet%s sent\n");
440 	p1(tcps_cwr_frecovery, "\t\t\tcwr by fastrecovery: %u\n");
441 	p1(tcps_cwr_timeout, "\t\t\tcwr by timeout: %u\n");
442 	p1(tcps_cwr_ecn, "\t\t\tcwr by ecn: %u\n");
443 
444 	p(tcps_badsyn, "\t%u bad connection attempt%s\n");
445 	p(tcps_dropsyn, "\t%u SYN packet%s dropped due to queue or memory full\n");
446 	p1(tcps_sc_added, "\t%qd SYN cache entries added\n");
447 	p(tcps_sc_collisions, "\t\t%qd hash collision%s\n");
448 	p1(tcps_sc_completed, "\t\t%qd completed\n");
449 	p1(tcps_sc_aborted, "\t\t%qd aborted (no space to build PCB)\n");
450 	p1(tcps_sc_timed_out, "\t\t%qd timed out\n");
451 	p1(tcps_sc_overflowed, "\t\t%qd dropped due to overflow\n");
452 	p1(tcps_sc_bucketoverflow, "\t\t%qd dropped due to bucket overflow\n");
453 	p1(tcps_sc_reset, "\t\t%qd dropped due to RST\n");
454 	p1(tcps_sc_unreach, "\t\t%qd dropped due to ICMP unreachable\n");
455 	p(tcps_sc_retransmitted, "\t%qd SYN,ACK%s retransmitted\n");
456 	p(tcps_sc_dupesyn, "\t%qd duplicate SYN%s received for entries "
457 		"already in the cache\n");
458 	p(tcps_sc_dropped, "\t%qd SYN%s dropped (no route or no space)\n");
459 
460 	p(tcps_sack_recovery_episode, "\t%qd SACK recovery episode%s\n");
461 	p(tcps_sack_rexmits,
462 		"\t\t%qd segment rexmit%s in SACK recovery episodes\n");
463 	p(tcps_sack_rexmit_bytes,
464 		"\t\t%qd byte rexmit%s in SACK recovery episodes\n");
465 	p(tcps_sack_rcv_opts,
466 		"\t%qd SACK option%s received\n");
467 	p(tcps_sack_snd_opts, "\t%qd SACK option%s sent\n");
468 
469 #undef p
470 #undef p1
471 #undef p2
472 #undef p2a
473 #undef p3
474 }
475 
476 /*
477  * Dump UDP statistics structure.
478  */
479 void
480 udp_stats(char *name)
481 {
482 	struct udpstat udpstat;
483 	u_long delivered;
484 	int mib[] = { CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_STATS };
485 	size_t len = sizeof(udpstat);
486 
487 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
488 	    &udpstat, &len, NULL, 0) == -1) {
489 		if (errno != ENOPROTOOPT)
490 			warn("%s", name);
491 		return;
492 	}
493 
494 	printf("%s:\n", name);
495 #define	p(f, m) if (udpstat.f || sflag <= 1) \
496 	printf(m, udpstat.f, plural(udpstat.f))
497 #define	p1(f, m) if (udpstat.f || sflag <= 1) \
498 	printf(m, udpstat.f)
499 
500 	p(udps_ipackets, "\t%lu datagram%s received\n");
501 	p1(udps_hdrops, "\t%lu with incomplete header\n");
502 	p1(udps_badlen, "\t%lu with bad data length field\n");
503 	p1(udps_badsum, "\t%lu with bad checksum\n");
504 	p1(udps_nosum, "\t%lu with no checksum\n");
505 	p(udps_inswcsum, "\t%lu input packet%s software-checksummed\n");
506 	p(udps_outswcsum, "\t%lu output packet%s software-checksummed\n");
507 	p1(udps_noport, "\t%lu dropped due to no socket\n");
508 	p(udps_noportbcast, "\t%lu broadcast/multicast datagram%s dropped due to no socket\n");
509 	p1(udps_nosec, "\t%lu dropped due to missing IPsec protection\n");
510 	p1(udps_fullsock, "\t%lu dropped due to full socket buffers\n");
511 	delivered = udpstat.udps_ipackets - udpstat.udps_hdrops -
512 	    udpstat.udps_badlen - udpstat.udps_badsum -
513 	    udpstat.udps_noport - udpstat.udps_noportbcast -
514 	    udpstat.udps_fullsock;
515 	if (delivered || sflag <= 1)
516 		printf("\t%lu delivered\n", delivered);
517 	p(udps_opackets, "\t%lu datagram%s output\n");
518 	p1(udps_pcbhashmiss, "\t%lu missed PCB cache\n");
519 #undef p
520 #undef p1
521 }
522 
523 /*
524  * Dump IP statistics structure.
525  */
526 void
527 ip_stats(char *name)
528 {
529 	struct ipstat ipstat;
530 	int mib[] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_STATS };
531 	size_t len = sizeof(ipstat);
532 
533 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
534 	    &ipstat, &len, NULL, 0) == -1) {
535 		if (errno != ENOPROTOOPT)
536 			warn("%s", name);
537 		return;
538 	}
539 
540 	printf("%s:\n", name);
541 #define	p(f, m) if (ipstat.f || sflag <= 1) \
542 	printf(m, ipstat.f, plural(ipstat.f))
543 #define	p1(f, m) if (ipstat.f || sflag <= 1) \
544 	printf(m, ipstat.f)
545 
546 	p(ips_total, "\t%lu total packet%s received\n");
547 	p(ips_badsum, "\t%lu bad header checksum%s\n");
548 	p1(ips_toosmall, "\t%lu with size smaller than minimum\n");
549 	p1(ips_tooshort, "\t%lu with data size < data length\n");
550 	p1(ips_badhlen, "\t%lu with header length < data size\n");
551 	p1(ips_badlen, "\t%lu with data length < header length\n");
552 	p1(ips_badoptions, "\t%lu with bad options\n");
553 	p1(ips_badvers, "\t%lu with incorrect version number\n");
554 	p(ips_fragments, "\t%lu fragment%s received\n");
555 	p(ips_fragdropped, "\t%lu fragment%s dropped (duplicates or out of space)\n");
556 	p(ips_badfrags, "\t%lu malformed fragment%s dropped\n");
557 	p(ips_fragtimeout, "\t%lu fragment%s dropped after timeout\n");
558 	p(ips_reassembled, "\t%lu packet%s reassembled ok\n");
559 	p(ips_delivered, "\t%lu packet%s for this host\n");
560 	p(ips_noproto, "\t%lu packet%s for unknown/unsupported protocol\n");
561 	p(ips_forward, "\t%lu packet%s forwarded\n");
562 	p(ips_cantforward, "\t%lu packet%s not forwardable\n");
563 	p(ips_redirectsent, "\t%lu redirect%s sent\n");
564 	p(ips_localout, "\t%lu packet%s sent from this host\n");
565 	p(ips_rawout, "\t%lu packet%s sent with fabricated ip header\n");
566 	p(ips_odropped, "\t%lu output packet%s dropped due to no bufs, etc.\n");
567 	p(ips_noroute, "\t%lu output packet%s discarded due to no route\n");
568 	p(ips_fragmented, "\t%lu output datagram%s fragmented\n");
569 	p(ips_ofragments, "\t%lu fragment%s created\n");
570 	p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n");
571 	p1(ips_rcvmemdrop, "\t%lu fragment floods\n");
572 	p(ips_toolong, "\t%lu packet%s with ip length > max ip packet size\n");
573 	p(ips_nogif, "\t%lu tunneling packet%s that can't find gif\n");
574 	p(ips_badaddr, "\t%lu datagram%s with bad address in header\n");
575 	p(ips_inswcsum, "\t%lu input datagram%s software-checksummed\n");
576 	p(ips_outswcsum, "\t%lu output datagram%s software-checksummed\n");
577 	p(ips_notmember, "\t%lu multicast packet%s which we don't join\n");
578 #undef p
579 #undef p1
580 }
581 
582 /*
583  * Dump DIVERT statistics structure.
584  */
585 void
586 div_stats(char *name)
587 {
588 	struct divstat divstat;
589 	int mib[] = { CTL_NET, PF_INET, IPPROTO_DIVERT, DIVERTCTL_STATS };
590 	size_t len = sizeof(divstat);
591 
592 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
593 	    &divstat, &len, NULL, 0) == -1) {
594 		if (errno != ENOPROTOOPT)
595 			warn("%s", name);
596 		return;
597 	}
598 
599 	printf("%s:\n", name);
600 #define	p(f, m) if (divstat.f || sflag <= 1) \
601 	printf(m, divstat.f, plural(divstat.f))
602 #define	p1(f, m) if (divstat.f || sflag <= 1) \
603 	printf(m, divstat.f)
604 	p(divs_ipackets, "\t%lu total packet%s received\n");
605 	p1(divs_noport, "\t%lu dropped due to no socket\n");
606 	p1(divs_fullsock, "\t%lu dropped due to full socket buffers\n");
607 	p(divs_opackets, "\t%lu packet%s output\n");
608 	p1(divs_errors, "\t%lu errors\n");
609 #undef p
610 #undef p1
611 }
612 
613 static	char *icmpnames[ICMP_MAXTYPE + 1] = {
614 	"echo reply",
615 	"#1",
616 	"#2",
617 	"destination unreachable",
618 	"source quench",
619 	"routing redirect",
620 	"#6",
621 	"#7",
622 	"echo",
623 	"router advertisement",
624 	"router solicitation",
625 	"time exceeded",
626 	"parameter problem",
627 	"time stamp",
628 	"time stamp reply",
629 	"information request",
630 	"information request reply",
631 	"address mask request",
632 	"address mask reply",
633 	"#19",
634 	"#20",
635 	"#21",
636 	"#22",
637 	"#23",
638 	"#24",
639 	"#25",
640 	"#26",
641 	"#27",
642 	"#28",
643 	"#29",
644 	"traceroute",
645 	"data conversion error",
646 	"mobile host redirect",
647 	"IPv6 where-are-you",
648 	"IPv6 i-am-here",
649 	"mobile registration request",
650 	"mobile registration reply",
651 	"#37",
652 	"#38",
653 	"SKIP",
654 	"Photuris",
655 };
656 
657 /*
658  * Dump ICMP statistics.
659  */
660 void
661 icmp_stats(char *name)
662 {
663 	struct icmpstat icmpstat;
664 	int i, first;
665 	int mib[] = { CTL_NET, PF_INET, IPPROTO_ICMP, ICMPCTL_STATS };
666 	size_t len = sizeof(icmpstat);
667 
668 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
669 	    &icmpstat, &len, NULL, 0) == -1) {
670 		if (errno != ENOPROTOOPT)
671 			warn("%s", name);
672 		return;
673 	}
674 
675 	printf("%s:\n", name);
676 #define	p(f, m) if (icmpstat.f || sflag <= 1) \
677 	printf(m, icmpstat.f, plural(icmpstat.f))
678 
679 	p(icps_error, "\t%lu call%s to icmp_error\n");
680 	p(icps_oldicmp,
681 	    "\t%lu error%s not generated because old message was icmp\n");
682 	p(icps_toofreq,
683 	    "\t%lu error%s not generated because of rate limitation\n");
684 
685 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
686 		if (icmpstat.icps_outhist[i] != 0) {
687 			if (first) {
688 				printf("\tOutput packet histogram:\n");
689 				first = 0;
690 			}
691 			if (icmpnames[i])
692 				printf("\t\t%s:", icmpnames[i]);
693 			else
694 				printf("\t\t#%d:", i);
695 			printf(" %lu\n", icmpstat.icps_outhist[i]);
696 		}
697 	p(icps_badcode, "\t%lu message%s with bad code fields\n");
698 	p(icps_tooshort, "\t%lu message%s < minimum length\n");
699 	p(icps_checksum, "\t%lu bad checksum%s\n");
700 	p(icps_badlen, "\t%lu message%s with bad length\n");
701 	p(icps_bmcastecho, "\t%lu echo request%s to broadcast/multicast "
702 	    "rejected\n");
703 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
704 		if (icmpstat.icps_inhist[i] != 0) {
705 			if (first) {
706 				printf("\tInput packet histogram:\n");
707 				first = 0;
708 			}
709 			if (icmpnames[i])
710 				printf("\t\t%s:", icmpnames[i]);
711 			else
712 				printf("\t\t#%d:", i);
713 			printf(" %lu\n", icmpstat.icps_inhist[i]);
714 		}
715 	p(icps_reflect, "\t%lu message response%s generated\n");
716 #undef p
717 }
718 
719 /*
720  * Dump IGMP statistics structure.
721  */
722 void
723 igmp_stats(char *name)
724 {
725 	struct igmpstat igmpstat;
726 	int mib[] = { CTL_NET, PF_INET, IPPROTO_IGMP, IGMPCTL_STATS };
727 	size_t len = sizeof(igmpstat);
728 
729 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
730 	    &igmpstat, &len, NULL, 0) == -1) {
731 		if (errno != ENOPROTOOPT)
732 			warn("%s", name);
733 		return;
734 	}
735 
736 	printf("%s:\n", name);
737 #define	p(f, m) if (igmpstat.f || sflag <= 1) \
738 	printf(m, igmpstat.f, plural(igmpstat.f))
739 #define	py(f, m) if (igmpstat.f || sflag <= 1) \
740 	printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y")
741 
742 	p(igps_rcv_total, "\t%lu message%s received\n");
743 	p(igps_rcv_tooshort, "\t%lu message%s received with too few bytes\n");
744 	p(igps_rcv_badsum, "\t%lu message%s received with bad checksum\n");
745 	py(igps_rcv_queries, "\t%lu membership quer%s received\n");
746 	py(igps_rcv_badqueries, "\t%lu membership quer%s received with invalid field(s)\n");
747 	p(igps_rcv_reports, "\t%lu membership report%s received\n");
748 	p(igps_rcv_badreports, "\t%lu membership report%s received with invalid field(s)\n");
749 	p(igps_rcv_ourreports, "\t%lu membership report%s received for groups to which we belong\n");
750 	p(igps_snd_reports, "\t%lu membership report%s sent\n");
751 #undef p
752 #undef py
753 }
754 
755 /*
756  * Dump PIM statistics structure.
757  */
758 void
759 pim_stats(char *name)
760 {
761 	struct pimstat pimstat;
762 	int mib[] = { CTL_NET, PF_INET, IPPROTO_PIM, PIMCTL_STATS };
763 	size_t len = sizeof(pimstat);
764 
765 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
766 	    &pimstat, &len, NULL, 0) == -1) {
767 		if (errno != ENOPROTOOPT)
768 			warn("%s", name);
769 		return;
770 	}
771 
772 	printf("%s:\n", name);
773 #define	p(f, m) if (pimstat.f || sflag <= 1) \
774 	printf(m, pimstat.f, plural(pimstat.f))
775 #define	py(f, m) if (pimstat.f || sflag <= 1) \
776 	printf(m, pimstat.f, pimstat.f != 1 ? "ies" : "y")
777 
778 	p(pims_rcv_total_msgs, "\t%llu message%s received\n");
779 	p(pims_rcv_total_bytes, "\t%llu byte%s received\n");
780 	p(pims_rcv_tooshort, "\t%llu message%s received with too few bytes\n");
781 	p(pims_rcv_badsum, "\t%llu message%s received with bad checksum\n");
782 	p(pims_rcv_badversion, "\t%llu message%s received with bad version\n");
783 	p(pims_rcv_registers_msgs, "\t%llu data register message%s received\n");
784 	p(pims_rcv_registers_bytes, "\t%llu data register byte%s received\n");
785 	p(pims_rcv_registers_wrongiif, "\t%llu data register message%s received on wrong iif\n");
786 	p(pims_rcv_badregisters, "\t%llu bad register%s received\n");
787 	p(pims_snd_registers_msgs, "\t%llu data register message%s sent\n");
788 	p(pims_snd_registers_bytes, "\t%llu data register byte%s sent\n");
789 #undef p
790 #undef py
791 }
792 
793 struct rpcnams {
794 	struct rpcnams *next;
795 	in_port_t port;
796 	int	  proto;
797 	char	*rpcname;
798 };
799 
800 static char *
801 getrpcportnam(in_port_t port, int proto)
802 {
803 	struct sockaddr_in server_addr;
804 	struct hostent *hp;
805 	static struct pmaplist *head;
806 	int socket = RPC_ANYSOCK;
807 	struct timeval minutetimeout;
808 	CLIENT *client;
809 	struct rpcent *rpc;
810 	static int first;
811 	static struct rpcnams *rpcn;
812 	struct rpcnams *n;
813 	char num[20];
814 
815 	if (first == 0) {
816 		first = 1;
817 		memset(&server_addr, 0, sizeof server_addr);
818 		server_addr.sin_family = AF_INET;
819 		if ((hp = gethostbyname("localhost")) != NULL)
820 			memmove((caddr_t)&server_addr.sin_addr, hp->h_addr,
821 			    hp->h_length);
822 		else
823 			(void) inet_aton("0.0.0.0", &server_addr.sin_addr);
824 
825 		minutetimeout.tv_sec = 60;
826 		minutetimeout.tv_usec = 0;
827 		server_addr.sin_port = htons(PMAPPORT);
828 		if ((client = clnttcp_create(&server_addr, PMAPPROG,
829 		    PMAPVERS, &socket, 50, 500)) == NULL)
830 			return (NULL);
831 		if (clnt_call(client, PMAPPROC_DUMP, xdr_void, NULL,
832 		    xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) {
833 			clnt_destroy(client);
834 			return (NULL);
835 		}
836 		for (; head != NULL; head = head->pml_next) {
837 			n = (struct rpcnams *)malloc(sizeof(struct rpcnams));
838 			if (n == NULL)
839 				continue;
840 			n->next = rpcn;
841 			rpcn = n;
842 			n->port = head->pml_map.pm_port;
843 			n->proto = head->pml_map.pm_prot;
844 
845 			rpc = getrpcbynumber(head->pml_map.pm_prog);
846 			if (rpc)
847 				n->rpcname = strdup(rpc->r_name);
848 			else {
849 				snprintf(num, sizeof num, "%ld",
850 				    head->pml_map.pm_prog);
851 				n->rpcname = strdup(num);
852 			}
853 		}
854 		clnt_destroy(client);
855 	}
856 
857 	for (n = rpcn; n; n = n->next)
858 		if (n->port == port && n->proto == proto)
859 			return (n->rpcname);
860 	return (NULL);
861 }
862 
863 /*
864  * Pretty print an Internet address (net address + port).
865  * If the nflag was specified, use numbers instead of names.
866  */
867 void
868 inetprint(struct in_addr *in, in_port_t port, const char *proto, int local)
869 {
870 	struct servent *sp = 0;
871 	char line[80], *cp, *nam;
872 	int width;
873 
874 	snprintf(line, sizeof line, "%.*s.", (Aflag && !nflag) ? 12 : 16,
875 	    inetname(in));
876 	cp = strchr(line, '\0');
877 	if (!nflag && port)
878 		sp = getservbyport((int)port, proto);
879 	if (sp || port == 0)
880 		snprintf(cp, line + sizeof line - cp, "%.8s",
881 		    sp ? sp->s_name : "*");
882 	else if (local && !nflag && (nam = getrpcportnam(ntohs(port),
883 	    (strcmp(proto, "tcp") == 0 ? IPPROTO_TCP : IPPROTO_UDP))))
884 		snprintf(cp, line + sizeof line - cp, "%d[%.8s]",
885 		    ntohs(port), nam);
886 	else
887 		snprintf(cp, line + sizeof line - cp, "%d", ntohs(port));
888 	width = Aflag ? 18 : 22;
889 	printf(" %-*.*s", width, width, line);
890 }
891 
892 /*
893  * Construct an Internet address representation.
894  * If the nflag has been supplied, give
895  * numeric value, otherwise try for symbolic name.
896  */
897 char *
898 inetname(struct in_addr *inp)
899 {
900 	char *cp;
901 	static char line[50];
902 	struct hostent *hp;
903 	static char domain[HOST_NAME_MAX+1];
904 	static int first = 1;
905 
906 	if (first && !nflag) {
907 		first = 0;
908 		if (gethostname(domain, sizeof(domain)) == 0 &&
909 		    (cp = strchr(domain, '.')))
910 			(void) strlcpy(domain, cp + 1, sizeof domain);
911 		else
912 			domain[0] = '\0';
913 	}
914 	cp = NULL;
915 	if (!nflag && inp->s_addr != INADDR_ANY) {
916 		hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET);
917 		if (hp) {
918 			if ((cp = strchr(hp->h_name, '.')) &&
919 			    !strcmp(cp + 1, domain))
920 				*cp = '\0';
921 			cp = hp->h_name;
922 		}
923 	}
924 	if (inp->s_addr == INADDR_ANY)
925 		snprintf(line, sizeof line, "*");
926 	else if (cp)
927 		snprintf(line, sizeof line, "%s", cp);
928 	else {
929 		inp->s_addr = ntohl(inp->s_addr);
930 #define C(x)	((x) & 0xff)
931 		snprintf(line, sizeof line, "%u.%u.%u.%u",
932 		    C(inp->s_addr >> 24), C(inp->s_addr >> 16),
933 		    C(inp->s_addr >> 8), C(inp->s_addr));
934 	}
935 	return (line);
936 }
937 
938 /*
939  * Dump AH statistics structure.
940  */
941 void
942 ah_stats(char *name)
943 {
944 	struct ahstat ahstat;
945 	int mib[] = { CTL_NET, PF_INET, IPPROTO_AH, AHCTL_STATS };
946 	size_t len = sizeof(ahstat);
947 
948 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
949 	    &ahstat, &len, NULL, 0) == -1) {
950 		if (errno != ENOPROTOOPT)
951 			warn("%s", name);
952 		return;
953 	}
954 
955 	printf("%s:\n", name);
956 #define p(f, m) if (ahstat.f || sflag <= 1) \
957 	printf(m, ahstat.f, plural(ahstat.f))
958 #define p1(f, m) if (ahstat.f || sflag <= 1) \
959 	printf(m, ahstat.f)
960 
961 	p1(ahs_input, "\t%u input AH packets\n");
962 	p1(ahs_output, "\t%u output AH packets\n");
963 	p(ahs_nopf, "\t%u packet%s from unsupported protocol families\n");
964 	p(ahs_hdrops, "\t%u packet%s shorter than header shows\n");
965 	p(ahs_pdrops, "\t%u packet%s dropped due to policy\n");
966 	p(ahs_notdb, "\t%u packet%s for which no TDB was found\n");
967 	p(ahs_badkcr, "\t%u input packet%s that failed to be processed\n");
968 	p(ahs_badauth, "\t%u packet%s that failed verification received\n");
969 	p(ahs_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n");
970 	p(ahs_qfull, "\t%u packet%s were dropped due to full output queue\n");
971 	p(ahs_wrap, "\t%u packet%s where counter wrapping was detected\n");
972 	p(ahs_replay, "\t%u possibly replayed packet%s received\n");
973 	p(ahs_badauthl, "\t%u packet%s with bad authenticator length received\n");
974 	p(ahs_invalid, "\t%u packet%s attempted to use an invalid TDB\n");
975 	p(ahs_toobig, "\t%u packet%s got larger than max IP packet size\n");
976 	p(ahs_crypto, "\t%u packet%s that failed crypto processing\n");
977 	p(ahs_ibytes, "\t%qu input byte%s\n");
978 	p(ahs_obytes, "\t%qu output byte%s\n");
979 
980 #undef p
981 #undef p1
982 }
983 
984 /*
985  * Dump etherip statistics structure.
986  */
987 void
988 etherip_stats(char *name)
989 {
990 	struct etheripstat etheripstat;
991 	int mib[] = { CTL_NET, PF_INET, IPPROTO_ETHERIP, ETHERIPCTL_STATS };
992 	size_t len = sizeof(etheripstat);
993 
994 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
995 	    &etheripstat, &len, NULL, 0) == -1) {
996 		if (errno != ENOPROTOOPT)
997 			warn("%s", name);
998 		return;
999 	}
1000 
1001 	printf("%s:\n", name);
1002 #define p(f, m) if (etheripstat.f || sflag <= 1) \
1003 	printf(m, etheripstat.f, plural(etheripstat.f))
1004 
1005 	p(etherip_hdrops, "\t%u packet%s shorter than header shows\n");
1006 	p(etherip_qfull, "\t%u packet%s were dropped due to full output queue\n");
1007 	p(etherip_noifdrops, "\t%u packet%s were dropped because of no interface/bridge information\n");
1008 	p(etherip_pdrops, "\t%u packet%s dropped due to policy\n");
1009 	p(etherip_adrops, "\t%u packet%s dropped for other reasons\n");
1010 	p(etherip_ipackets, "\t%u input ethernet-in-IP packet%s\n");
1011 	p(etherip_opackets, "\t%u output ethernet-in-IP packet%s\n");
1012 	p(etherip_ibytes, "\t%qu input byte%s\n");
1013 	p(etherip_obytes, "\t%qu output byte%s\n");
1014 #undef p
1015 }
1016 
1017 /*
1018  * Dump ESP statistics structure.
1019  */
1020 void
1021 esp_stats(char *name)
1022 {
1023 	struct espstat espstat;
1024 	int mib[] = { CTL_NET, PF_INET, IPPROTO_ESP, ESPCTL_STATS };
1025 	size_t len = sizeof(espstat);
1026 
1027 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
1028 	    &espstat, &len, NULL, 0) == -1) {
1029 		if (errno != ENOPROTOOPT)
1030 			warn("%s", name);
1031 		return;
1032 	}
1033 
1034 	printf("%s:\n", name);
1035 #define p(f, m) if (espstat.f || sflag <= 1) \
1036 	printf(m, espstat.f, plural(espstat.f))
1037 
1038 	p(esps_input, "\t%u input ESP packet%s\n");
1039 	p(esps_output, "\t%u output ESP packet%s\n");
1040 	p(esps_nopf, "\t%u packet%s from unsupported protocol families\n");
1041 	p(esps_hdrops, "\t%u packet%s shorter than header shows\n");
1042 	p(esps_pdrops, "\t%u packet%s dropped due to policy\n");
1043 	p(esps_notdb, "\t%u packet%s for which no TDB was found\n");
1044 	p(esps_badkcr, "\t%u input packet%s that failed to be processed\n");
1045 	p(esps_badenc, "\t%u packet%s with bad encryption received\n");
1046 	p(esps_badauth, "\t%u packet%s that failed verification received\n");
1047 	p(esps_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n");
1048 	p(esps_qfull, "\t%u packet%s were dropped due to full output queue\n");
1049 	p(esps_wrap, "\t%u packet%s where counter wrapping was detected\n");
1050 	p(esps_replay, "\t%u possibly replayed packet%s received\n");
1051 	p(esps_badilen, "\t%u packet%s with bad payload size or padding received\n");
1052 	p(esps_invalid, "\t%u packet%s attempted to use an invalid TDB\n");
1053 	p(esps_toobig, "\t%u packet%s got larger than max IP packet size\n");
1054 	p(esps_crypto, "\t%u packet%s that failed crypto processing\n");
1055 	p(esps_udpencin, "\t%u input UDP encapsulated ESP packet%s\n");
1056 	p(esps_udpencout, "\t%u output UDP encapsulated ESP packet%s\n");
1057 	p(esps_udpinval, "\t%u UDP packet%s for non-encapsulating TDB received\n");
1058 	p(esps_ibytes, "\t%qu input byte%s\n");
1059 	p(esps_obytes, "\t%qu output byte%s\n");
1060 
1061 #undef p
1062 }
1063 
1064 /*
1065  * Dump IP-in-IP statistics structure.
1066  */
1067 void
1068 ipip_stats(char *name)
1069 {
1070 	struct ipipstat ipipstat;
1071 	int mib[] = { CTL_NET, PF_INET, IPPROTO_IPIP, IPIPCTL_STATS };
1072 	size_t len = sizeof(ipipstat);
1073 
1074 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
1075 	    &ipipstat, &len, NULL, 0) == -1) {
1076 		if (errno != ENOPROTOOPT)
1077 			warn("%s", name);
1078 		return;
1079 	}
1080 
1081 	printf("%s:\n", name);
1082 #define p(f, m) if (ipipstat.f || sflag <= 1) \
1083 	printf(m, ipipstat.f, plural(ipipstat.f))
1084 
1085 	p(ipips_ipackets, "\t%u total input packet%s\n");
1086 	p(ipips_opackets, "\t%u total output packet%s\n");
1087 	p(ipips_hdrops, "\t%u packet%s shorter than header shows\n");
1088 	p(ipips_pdrops, "\t%u packet%s dropped due to policy\n");
1089 	p(ipips_spoof, "\t%u packet%s with possibly spoofed local addresses\n");
1090 	p(ipips_qfull, "\t%u packet%s were dropped due to full output queue\n");
1091 	p(ipips_ibytes, "\t%qu input byte%s\n");
1092 	p(ipips_obytes, "\t%qu output byte%s\n");
1093 	p(ipips_family, "\t%u protocol family mismatche%s\n");
1094 	p(ipips_unspec, "\t%u attempt%s to use tunnel with unspecified endpoint(s)\n");
1095 #undef p
1096 }
1097 
1098 /*
1099  * Dump CARP statistics structure.
1100  */
1101 void
1102 carp_stats(char *name)
1103 {
1104 	struct carpstats carpstat;
1105 	int mib[] = { CTL_NET, PF_INET, IPPROTO_CARP, CARPCTL_STATS };
1106 	size_t len = sizeof(carpstat);
1107 
1108 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
1109 	    &carpstat, &len, NULL, 0) == -1) {
1110 		if (errno != ENOPROTOOPT)
1111 			warn("%s", name);
1112 		return;
1113 	}
1114 
1115 	printf("%s:\n", name);
1116 #define p(f, m) if (carpstat.f || sflag <= 1) \
1117 	printf(m, carpstat.f, plural(carpstat.f))
1118 #define p2(f, m) if (carpstat.f || sflag <= 1) \
1119 	printf(m, carpstat.f)
1120 
1121 	p(carps_ipackets, "\t%llu packet%s received (IPv4)\n");
1122 	p(carps_ipackets6, "\t%llu packet%s received (IPv6)\n");
1123 	p(carps_badif, "\t\t%llu packet%s discarded for bad interface\n");
1124 	p(carps_badttl, "\t\t%llu packet%s discarded for wrong TTL\n");
1125 	p(carps_hdrops, "\t\t%llu packet%s shorter than header\n");
1126 	p(carps_badsum, "\t\t%llu discarded for bad checksum%s\n");
1127 	p(carps_badver,	"\t\t%llu discarded packet%s with a bad version\n");
1128 	p2(carps_badlen, "\t\t%llu discarded because packet too short\n");
1129 	p2(carps_badauth, "\t\t%llu discarded for bad authentication\n");
1130 	p2(carps_badvhid, "\t\t%llu discarded for unknown vhid\n");
1131 	p2(carps_badaddrs, "\t\t%llu discarded because of a bad address list\n");
1132 	p(carps_opackets, "\t%llu packet%s sent (IPv4)\n");
1133 	p(carps_opackets6, "\t%llu packet%s sent (IPv6)\n");
1134 	p2(carps_onomem, "\t\t%llu send failed due to mbuf memory error\n");
1135 	p(carps_preempt, "\t%llu transition%s to master\n");
1136 #undef p
1137 #undef p2
1138 }
1139 
1140 /*
1141  * Dump pfsync statistics structure.
1142  */
1143 void
1144 pfsync_stats(char *name)
1145 {
1146 	struct pfsyncstats pfsyncstat;
1147 	int mib[] = { CTL_NET, PF_INET, IPPROTO_PFSYNC, PFSYNCCTL_STATS };
1148 	size_t len = sizeof(pfsyncstat);
1149 
1150 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
1151 	    &pfsyncstat, &len, NULL, 0) == -1) {
1152 		if (errno != ENOPROTOOPT)
1153 			warn("%s", name);
1154 		return;
1155 	}
1156 
1157 	printf("%s:\n", name);
1158 #define p(f, m) if (pfsyncstat.f || sflag <= 1) \
1159 	printf(m, pfsyncstat.f, plural(pfsyncstat.f))
1160 #define p2(f, m) if (pfsyncstat.f || sflag <= 1) \
1161 	printf(m, pfsyncstat.f)
1162 
1163 	p(pfsyncs_ipackets, "\t%llu packet%s received (IPv4)\n");
1164 	p(pfsyncs_ipackets6, "\t%llu packet%s received (IPv6)\n");
1165 	p(pfsyncs_badif, "\t\t%llu packet%s discarded for bad interface\n");
1166 	p(pfsyncs_badttl, "\t\t%llu packet%s discarded for bad ttl\n");
1167 	p(pfsyncs_hdrops, "\t\t%llu packet%s shorter than header\n");
1168 	p(pfsyncs_badver, "\t\t%llu packet%s discarded for bad version\n");
1169 	p(pfsyncs_badauth, "\t\t%llu packet%s discarded for bad HMAC\n");
1170 	p(pfsyncs_badact,"\t\t%llu packet%s discarded for bad action\n");
1171 	p(pfsyncs_badlen, "\t\t%llu packet%s discarded for short packet\n");
1172 	p(pfsyncs_badval, "\t\t%llu state%s discarded for bad values\n");
1173 	p(pfsyncs_stale, "\t\t%llu stale state%s\n");
1174 	p(pfsyncs_badstate, "\t\t%llu failed state lookup/insert%s\n");
1175 	p(pfsyncs_opackets, "\t%llu packet%s sent (IPv4)\n");
1176 	p(pfsyncs_opackets6, "\t%llu packet%s sent (IPv6)\n");
1177 	p2(pfsyncs_onomem, "\t\t%llu send failed due to mbuf memory error\n");
1178 	p2(pfsyncs_oerrors, "\t\t%llu send error\n");
1179 #undef p
1180 #undef p2
1181 }
1182 
1183 /*
1184  * Dump pflow statistics structure.
1185  */
1186 void
1187 pflow_stats(char *name)
1188 {
1189 	struct pflowstats flowstats;
1190 	int mib[] = { CTL_NET, PF_PFLOW, NET_PFLOW_STATS };
1191 	size_t len = sizeof(struct pflowstats);
1192 
1193 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &flowstats, &len,
1194 	    NULL, 0) == -1) {
1195 		if (errno != ENOPROTOOPT)
1196 			warn("%s", name);
1197 		return;
1198 	}
1199 
1200 	printf("%s:\n", name);
1201 #define p(f, m) if (flowstats.f || sflag <= 1) \
1202 	printf(m, flowstats.f, plural(flowstats.f))
1203 #define p2(f, m) if (flowstats.f || sflag <= 1) \
1204 	printf(m, flowstats.f)
1205 
1206 	p(pflow_flows, "\t%llu flow%s sent\n");
1207 	p(pflow_packets, "\t%llu packet%s sent\n");
1208 	p2(pflow_onomem, "\t\t%llu send failed due to mbuf memory error\n");
1209 	p2(pflow_oerrors, "\t\t%llu send error\n");
1210 #undef p
1211 #undef p2
1212 }
1213 
1214 /*
1215  * Dump IPCOMP statistics structure.
1216  */
1217 void
1218 ipcomp_stats(char *name)
1219 {
1220 	struct ipcompstat ipcompstat;
1221 	int mib[] = { CTL_NET, PF_INET, IPPROTO_IPCOMP, IPCOMPCTL_STATS };
1222 	size_t len = sizeof(ipcompstat);
1223 
1224 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
1225 	    &ipcompstat, &len, NULL, 0) == -1) {
1226 		if (errno != ENOPROTOOPT)
1227 			warn("%s", name);
1228 		return;
1229 	}
1230 
1231 	printf("%s:\n", name);
1232 #define p(f, m) if (ipcompstat.f || sflag <= 1) \
1233 	printf(m, ipcompstat.f, plural(ipcompstat.f))
1234 
1235 	p(ipcomps_input, "\t%u input IPCOMP packet%s\n");
1236 	p(ipcomps_output, "\t%u output IPCOMP packet%s\n");
1237 	p(ipcomps_nopf, "\t%u packet%s from unsupported protocol families\n");
1238 	p(ipcomps_hdrops, "\t%u packet%s shorter than header shows\n");
1239 	p(ipcomps_pdrops, "\t%u packet%s dropped due to policy\n");
1240 	p(ipcomps_notdb, "\t%u packet%s for which no TDB was found\n");
1241 	p(ipcomps_badkcr, "\t%u input packet%s that failed to be processed\n");
1242 	p(ipcomps_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n");
1243 	p(ipcomps_qfull, "\t%u packet%s were dropped due to full output queue\n");
1244 	p(ipcomps_wrap, "\t%u packet%s where counter wrapping was detected\n");
1245 	p(ipcomps_invalid, "\t%u packet%s attempted to use an invalid TDB\n");
1246 	p(ipcomps_toobig, "\t%u packet%s got larger than max IP packet size\n");
1247 	p(ipcomps_crypto, "\t%u packet%s that failed (de)compression processing\n");
1248 	p(ipcomps_minlen, "\t%u packet%s less than minimum compression length\n");
1249 	p(ipcomps_ibytes, "\t%qu input byte%s\n");
1250 	p(ipcomps_obytes, "\t%qu output byte%s\n");
1251 
1252 #undef p
1253 }
1254 
1255 /*
1256  * Dump the contents of a socket structure
1257  */
1258 void
1259 socket_dump(u_long off)
1260 {
1261 	struct socket so;
1262 
1263 	if (off == 0)
1264 		return;
1265 	kread(off, &so, sizeof(so));
1266 
1267 #define	p(fmt, v, sep) printf(#v " " fmt sep, so.v);
1268 #define	pp(fmt, v, sep) printf(#v " " fmt sep, so.v);
1269 	printf("socket %#lx\n ", off);
1270 	p("%#.4x", so_type, "\n ");
1271 	p("%#.4x", so_options, "\n ");
1272 	p("%d", so_linger, "\n ");
1273 	p("%#.4x", so_state, "\n ");
1274 	pp("%p", so_pcb, ", ");
1275 	pp("%p", so_proto, ", ");
1276 	pp("%p", so_head, "\n ");
1277 	p("%d", so_q0len, ", ");
1278 	p("%d", so_qlen, ", ");
1279 	p("%d", so_qlimit, "\n ");
1280 	p("%d", so_timeo, "\n ");
1281 	p("%u", so_error, "\n ");
1282 	p("%d", so_pgid, ", ");
1283 	p("%u", so_siguid, ", ");
1284 	p("%u", so_sigeuid, "\n ");
1285 	p("%lu", so_oobmark, "\n ");
1286 	if (so.so_sp)
1287 		sosplice_dump((u_long)so.so_sp);
1288 	sockbuf_dump(&so.so_rcv, "so_rcv");
1289 	sockbuf_dump(&so.so_snd, "so_snd");
1290 	p("%u", so_euid, ", ");
1291 	p("%u", so_ruid, ", ");
1292 	p("%u", so_egid, ", ");
1293 	p("%u", so_rgid, "\n ");
1294 	p("%d", so_cpid, "\n");
1295 #undef	p
1296 #undef	pp
1297 
1298 	protosw_dump((u_long)so.so_proto, (u_long)so.so_pcb);
1299 }
1300 
1301 /*
1302  * Dump the contents of a struct sosplice
1303  */
1304 void
1305 sosplice_dump(u_long off)
1306 {
1307 	struct sosplice ssp;
1308 
1309 	if (off == 0)
1310 		return;
1311 	kread(off, &ssp, sizeof(ssp));
1312 
1313 #define	p(fmt, v, sep) printf(#v " " fmt sep, ssp.v);
1314 #define	pll(fmt, v, sep) printf(#v " " fmt sep, (long long) ssp.v);
1315 #define	pp(fmt, v, sep) printf(#v " " fmt sep, ssp.v);
1316 	pp("%p", ssp_socket, ", ");
1317 	pp("%p", ssp_soback, "\n ");
1318 	p("%lld", ssp_len, ", ");
1319 	p("%lld", ssp_max, ", ");
1320 	pll("%lld", ssp_idletv.tv_sec, ", ");
1321 	p("%ld", ssp_idletv.tv_usec, "\n ");
1322 #undef	p
1323 #undef	pll
1324 #undef	pp
1325 }
1326 
1327 /*
1328  * Dump the contents of a socket buffer
1329  */
1330 void
1331 sockbuf_dump(struct sockbuf *sb, const char *name)
1332 {
1333 #define	p(fmt, v, sep) printf(#v " " fmt sep, sb->v);
1334 	printf("%s ", name);
1335 	p("%lu", sb_cc, ", ");
1336 	p("%lu", sb_datacc, ", ");
1337 	p("%lu", sb_hiwat, ", ");
1338 	p("%lu", sb_wat, "\n ");
1339 	printf("%s ", name);
1340 	p("%lu", sb_mbcnt, ", ");
1341 	p("%lu", sb_mbmax, ", ");
1342 	p("%ld", sb_lowat, "\n ");
1343 	printf("%s ", name);
1344 	p("%#.8x", sb_flagsintr, ", ");
1345 	p("%#.4x", sb_flags, ", ");
1346 	p("%u", sb_timeo, "\n ");
1347 #undef	p
1348 }
1349 
1350 /*
1351  * Dump the contents of a protosw structure
1352  */
1353 void
1354 protosw_dump(u_long off, u_long pcb)
1355 {
1356 	struct protosw proto;
1357 
1358 	if (off == 0)
1359 		return;
1360 	kread(off, &proto, sizeof(proto));
1361 
1362 #define	p(fmt, v, sep) printf(#v " " fmt sep, proto.v);
1363 #define	pp(fmt, v, sep) printf(#v " " fmt sep, proto.v);
1364 	printf("protosw %#lx\n ", off);
1365 	p("%#.4x", pr_type, "\n ");
1366 	pp("%p", pr_domain, "\n ");
1367 	p("%d", pr_protocol, "\n ");
1368 	p("%#.4x", pr_flags, "\n");
1369 #undef	p
1370 #undef	pp
1371 
1372 	domain_dump((u_long)proto.pr_domain, pcb, proto.pr_protocol);
1373 }
1374 
1375 /*
1376  * Dump the contents of a domain structure
1377  */
1378 void
1379 domain_dump(u_long off, u_long pcb, short protocol)
1380 {
1381 	struct domain dom;
1382 	char name[256];
1383 
1384 	if (off == 0)
1385 		return;
1386 	kread(off, &dom, sizeof(dom));
1387 	kread((u_long)dom.dom_name, name, sizeof(name));
1388 
1389 #define	p(fmt, v, sep) printf(#v " " fmt sep, dom.v);
1390 	printf("domain %#lx\n ", off);
1391 	p("%d", dom_family, "\n ");
1392 	printf("dom_name %.*s\n", (int)sizeof(name), name);
1393 #undef	p
1394 }
1395 
1396 /*
1397  * Dump the contents of a internet PCB
1398  */
1399 void
1400 inpcb_dump(u_long off, short protocol, int af)
1401 {
1402 	struct inpcb inp;
1403 	char faddr[256], laddr[256];
1404 
1405 	if (off == 0)
1406 		return;
1407 	kread(off, &inp, sizeof(inp));
1408 
1409 	if (vflag)
1410 		socket_dump((u_long)inp.inp_socket);
1411 
1412 	switch (af) {
1413 	case AF_INET:
1414 		inet_ntop(af, &inp.inp_faddr, faddr, sizeof(faddr));
1415 		inet_ntop(af, &inp.inp_laddr, laddr, sizeof(laddr));
1416 		break;
1417 	case AF_INET6:
1418 		inet_ntop(af, &inp.inp_faddr6, faddr, sizeof(faddr));
1419 		inet_ntop(af, &inp.inp_laddr6, laddr, sizeof(laddr));
1420 		break;
1421 	default:
1422 		faddr[0] = laddr[0] = '\0';
1423 	}
1424 
1425 #define	p(fmt, v, sep) printf(#v " " fmt sep, inp.v);
1426 #define	pp(fmt, v, sep) printf(#v " " fmt sep, inp.v);
1427 	printf("inpcb %#lx\n ", off);
1428 	pp("%p", inp_table, "\n ");
1429 	printf("inp_faddru %s, inp_laddru %s\n ", faddr, laddr);
1430 	HTONS(inp.inp_fport);
1431 	HTONS(inp.inp_lport);
1432 	p("%u", inp_fport, ", ");
1433 	p("%u", inp_lport, "\n ");
1434 	pp("%p", inp_socket, ", ");
1435 	pp("%p", inp_ppcb, "\n ");
1436 	p("%#.8x", inp_flags, "\n ");
1437 	p("%d", inp_hops, "\n ");
1438 	p("%u", inp_seclevel[0], ", ");
1439 	p("%u", inp_seclevel[1], ", ");
1440 	p("%u", inp_seclevel[2], ", ");
1441 	p("%u", inp_seclevel[3], "\n ");
1442 	p("%u", inp_ip_minttl, "\n ");
1443 	p("%d", inp_cksum6, "\n ");
1444 	pp("%p", inp_icmp6filt, "\n ");
1445 	pp("%p", inp_pf_sk, "\n ");
1446 	p("%u", inp_rtableid, "\n ");
1447 	p("%d", inp_pipex, "\n");
1448 #undef	p
1449 #undef	pp
1450 
1451 	switch (protocol) {
1452 	case IPPROTO_TCP:
1453 		tcpcb_dump((u_long)inp.inp_ppcb);
1454 		break;
1455 	}
1456 }
1457 
1458 /*
1459  * Dump the contents of a TCP PCB
1460  */
1461 void
1462 tcpcb_dump(u_long off)
1463 {
1464 	struct tcpcb tcpcb;
1465 
1466 	if (off == 0)
1467 		return;
1468 	kread(off, (char *)&tcpcb, sizeof (tcpcb));
1469 
1470 #define	p(fmt, v, sep) printf(#v " " fmt sep, tcpcb.v);
1471 #define	pp(fmt, v, sep) printf(#v " " fmt sep, tcpcb.v);
1472 	printf("tcpcb %#lx\n ", off);
1473 	pp("%p", t_inpcb, "\n ");
1474 	p("%d", t_state, "");
1475 	if (tcpcb.t_state >= 0 && tcpcb.t_state < TCP_NSTATES)
1476 		printf(" (%s)", tcpstates[tcpcb.t_state]);
1477 	printf("\n ");
1478 	p("%d", t_rxtshift, ", ");
1479 	p("%d", t_rxtcur, ", ");
1480 	p("%d", t_dupacks, "\n ");
1481 	p("%u", t_maxseg, ", ");
1482 	p("%u", t_maxopd, ", ");
1483 	p("%u", t_peermss, "\n ");
1484 	p("0x%x", t_flags, ", ");
1485 	p("%u", t_force, "\n ");
1486 	p("%u", iss, "\n ");
1487 	p("%u", snd_una, ", ");
1488 	p("%u", snd_nxt, ", ");
1489 	p("%u", snd_up, "\n ");
1490 	p("%u", snd_wl1, ", ");
1491 	p("%u", snd_wl2, ", ");
1492 	p("%lu", snd_wnd, "\n ");
1493 	p("%d", sack_enable, ", ");
1494 	p("%d", snd_numholes, ", ");
1495 	p("%u", snd_fack, ", ");
1496 	p("%lu",snd_awnd, "\n ");
1497 	p("%u", retran_data, ", ");
1498 	p("%u", snd_last, "\n ");
1499 	p("%u", irs, "\n ");
1500 	p("%u", rcv_nxt, ", ");
1501 	p("%u", rcv_up, ", ");
1502 	p("%lu", rcv_wnd, "\n ");
1503 	p("%u", rcv_lastsack, "\n ");
1504 	p("%d", rcv_numsacks, "\n ");
1505 	p("%u", rcv_adv, ", ");
1506 	p("%u", snd_max, "\n ");
1507 	p("%lu", snd_cwnd, ", ");
1508 	p("%lu", snd_ssthresh, ", ");
1509 	p("%lu", max_sndwnd, "\n ");
1510 	p("%u", t_rcvtime, ", ");
1511 	p("%u", t_rtttime, ", ");
1512 	p("%u", t_rtseq, "\n ");
1513 	p("%u", t_srtt, ", ");
1514 	p("%u", t_rttvar, ", ");
1515 	p("%u", t_rttmin, "\n ");
1516 	p("%u", t_oobflags, ", ");
1517 	p("%u", t_iobc, "\n ");
1518 	p("%u", t_softerror, "\n ");
1519 	p("%u", snd_scale, ", ");
1520 	p("%u", rcv_scale, ", ");
1521 	p("%u", request_r_scale, ", ");
1522 	p("%u", requested_s_scale, "\n ");
1523 	p("%u", ts_recent, ", ");
1524 	p("%u", ts_recent_age, "\n ");
1525 	p("%u", last_ack_sent, "\n ");
1526 	HTONS(tcpcb.t_pmtud_ip_len);
1527 	HTONS(tcpcb.t_pmtud_nextmtu);
1528 	p("%u", t_pmtud_mss_acked, ", ");
1529 	p("%u", t_pmtud_mtu_sent, "\n ");
1530 	p("%u", t_pmtud_nextmtu, ", ");
1531 	p("%u", t_pmtud_ip_len, ", ");
1532 	p("%u", t_pmtud_ip_hl, "\n ");
1533 	p("%u", t_pmtud_th_seq, "\n ");
1534 	p("%u", pf, "\n");
1535 #undef	p
1536 #undef	pp
1537 }
1538