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