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