xref: /openbsd-src/usr.bin/netstat/inet.c (revision 43003dfe3ad45d1698bed8a37f2b0f5b14f20d4f)
1 /*	$OpenBSD: inet.c,v 1.111 2009/10/04 16:08:37 michele 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/param.h>
34 #include <sys/queue.h>
35 #include <sys/socket.h>
36 #include <sys/socketvar.h>
37 #include <sys/mbuf.h>
38 #include <sys/protosw.h>
39 #include <sys/sysctl.h>
40 
41 #include <net/route.h>
42 #include <netinet/in.h>
43 #include <netinet/in_systm.h>
44 #include <netinet/ip.h>
45 #include <netinet/in_pcb.h>
46 #include <netinet/ip_icmp.h>
47 #include <netinet/icmp_var.h>
48 #include <netinet/igmp_var.h>
49 #include <netinet/ip_var.h>
50 #include <netinet/pim_var.h>
51 #include <netinet/tcp.h>
52 #include <netinet/tcpip.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/tcp_debug.h>
59 #include <netinet/udp.h>
60 #include <netinet/udp_var.h>
61 #include <netinet/ip_ipsp.h>
62 #include <netinet/ip_ah.h>
63 #include <netinet/ip_esp.h>
64 #include <netinet/ip_ipip.h>
65 #include <netinet/ip_ipcomp.h>
66 #include <netinet/ip_ether.h>
67 #include <netinet/ip_carp.h>
68 #include <netinet/ip_divert.h>
69 #include <net/if.h>
70 #include <net/pfvar.h>
71 #include <net/if_pfsync.h>
72 #include <net/if_pflow.h>
73 
74 #include <rpc/rpc.h>
75 #include <rpc/pmap_prot.h>
76 #include <rpc/pmap_clnt.h>
77 
78 #include <arpa/inet.h>
79 #include <err.h>
80 #include <limits.h>
81 #include <netdb.h>
82 #include <stdio.h>
83 #include <string.h>
84 #include <unistd.h>
85 #include <stdlib.h>
86 #include <errno.h>
87 #include "netstat.h"
88 
89 struct	inpcb inpcb;
90 struct	tcpcb tcpcb;
91 struct	socket sockb;
92 
93 static void protopr0(u_long, char *, int);
94 
95 char	*inetname(struct in_addr *);
96 void	inetprint(struct in_addr *, in_port_t, char *, int);
97 char	*inet6name(struct in6_addr *);
98 void	inet6print(struct in6_addr *, int, char *);
99 
100 /*
101  * Print a summary of connections related to an Internet
102  * protocol.  For TCP, also give state of connection.
103  * Listening processes (aflag) are suppressed unless the
104  * -a (all) flag is specified.
105  */
106 void
107 protopr(u_long off, char *name)
108 {
109 	protopr0(off, name, AF_INET);
110 }
111 
112 void
113 ip6protopr(u_long off, char *name)
114 {
115 	protopr0(off, name, AF_INET6);
116 }
117 
118 static void
119 protopr0(u_long off, char *name, int af)
120 {
121 	struct inpcbtable table;
122 	struct inpcb *head, *next, *prev;
123 	struct inpcb inpcb;
124 	int istcp, israw, isany;
125 	int first = 1;
126 	char *name0;
127 	char namebuf[20];
128 
129 	name0 = name;
130 	if (off == 0)
131 		return;
132 	istcp = strcmp(name, "tcp") == 0;
133 	israw = strncmp(name, "ip", 2) == 0;
134 	kread(off, &table, sizeof table);
135 	prev = head =
136 	    (struct inpcb *)&CIRCLEQ_FIRST(&((struct inpcbtable *)off)->inpt_queue);
137 	next = CIRCLEQ_FIRST(&table.inpt_queue);
138 
139 	while (next != head) {
140 		kread((u_long)next, &inpcb, sizeof inpcb);
141 		if (CIRCLEQ_PREV(&inpcb, inp_queue) != prev) {
142 			printf("???\n");
143 			break;
144 		}
145 		prev = next;
146 		next = CIRCLEQ_NEXT(&inpcb, inp_queue);
147 
148 		switch (af) {
149 		case AF_INET:
150 			if ((inpcb.inp_flags & INP_IPV6) != 0)
151 				continue;
152 			isany = inet_lnaof(inpcb.inp_faddr) == INADDR_ANY;
153 			break;
154 		case AF_INET6:
155 			if ((inpcb.inp_flags & INP_IPV6) == 0)
156 				continue;
157 			isany = IN6_IS_ADDR_UNSPECIFIED(&inpcb.inp_faddr6);
158 			break;
159 		default:
160 			isany = 0;
161 			break;
162 		}
163 
164 		kread((u_long)inpcb.inp_socket, &sockb, sizeof (sockb));
165 		if (istcp) {
166 			kread((u_long)inpcb.inp_ppcb, &tcpcb, sizeof (tcpcb));
167 			if (!aflag && tcpcb.t_state <= TCPS_LISTEN)
168 				continue;
169 		} else if (!aflag && isany)
170 			continue;
171 		if (first) {
172 			printf("Active Internet connections");
173 			if (aflag)
174 				printf(" (including servers)");
175 			putchar('\n');
176 			if (Aflag)
177 				printf("%-*.*s %-6.6s %-6.6s %-6.6s  %-18.18s %-18.18s %s\n",
178 				    PLEN, PLEN, "PCB", "Proto", "Recv-Q",
179 				    "Send-Q", "Local Address",
180 				    "Foreign Address", "(state)");
181 			else
182 				printf("%-6.6s %-6.6s %-6.6s  %-22.22s %-22.22s %s\n",
183 				    "Proto", "Recv-Q", "Send-Q",
184 				    "Local Address", "Foreign Address",
185 				    "(state)");
186 			first = 0;
187 		}
188 		if (Aflag) {
189 			if (istcp)
190 				printf("%*p ", PLEN, inpcb.inp_ppcb);
191 			else
192 				printf("%*p ", PLEN, prev);
193 		}
194 		if (inpcb.inp_flags & INP_IPV6 && !israw) {
195 			strlcpy(namebuf, name0, sizeof namebuf);
196 			strlcat(namebuf, "6", sizeof namebuf);
197 			name = namebuf;
198 		} else
199 			name = name0;
200 		printf("%-6.6s %6ld %6ld ", name, sockb.so_rcv.sb_cc,
201 		    sockb.so_snd.sb_cc);
202 		if (inpcb.inp_flags & INP_IPV6) {
203 			inet6print(&inpcb.inp_laddr6, (int)inpcb.inp_lport,
204 			    name);
205 			inet6print(&inpcb.inp_faddr6, (int)inpcb.inp_fport,
206 			    name);
207 		} else {
208 			inetprint(&inpcb.inp_laddr, (int)inpcb.inp_lport,
209 			    name, 1);
210 			inetprint(&inpcb.inp_faddr, (int)inpcb.inp_fport,
211 			    name, 0);
212 		}
213 		if (istcp) {
214 			if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES)
215 				printf(" %d", tcpcb.t_state);
216 			else
217 				printf(" %s", tcpstates[tcpcb.t_state]);
218 		} else if (israw) {
219 			u_int8_t proto;
220 
221 			if (inpcb.inp_flags & INP_IPV6)
222 				proto = inpcb.inp_ipv6.ip6_nxt;
223 			else
224 				proto = inpcb.inp_ip.ip_p;
225 			printf(" %u", proto);
226 		}
227 		putchar('\n');
228 	}
229 }
230 
231 /*
232  * Dump TCP statistics structure.
233  */
234 void
235 tcp_stats(char *name)
236 {
237 	struct tcpstat tcpstat;
238 	int mib[] = { CTL_NET, AF_INET, IPPROTO_TCP, TCPCTL_STATS };
239 	size_t len = sizeof(tcpstat);
240 
241 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
242 	    &tcpstat, &len, NULL, 0) == -1) {
243 		if (errno != ENOPROTOOPT)
244 			warn(name);
245 		return;
246 	}
247 
248 	printf("%s:\n", name);
249 #define	p(f, m) if (tcpstat.f || sflag <= 1) \
250 	printf(m, tcpstat.f, plural(tcpstat.f))
251 #define	p1(f, m) if (tcpstat.f || sflag <= 1) \
252 	printf(m, tcpstat.f)
253 #define	p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
254 	printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2))
255 #define	p2a(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
256 	printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2)
257 #define	p3(f, m) if (tcpstat.f || sflag <= 1) \
258 	printf(m, tcpstat.f, plurales(tcpstat.f))
259 
260 	p(tcps_sndtotal, "\t%u packet%s sent\n");
261 	p2(tcps_sndpack,tcps_sndbyte,
262 	    "\t\t%u data packet%s (%qd byte%s)\n");
263 	p2(tcps_sndrexmitpack, tcps_sndrexmitbyte,
264 	    "\t\t%u data packet%s (%qd byte%s) retransmitted\n");
265 	p(tcps_sndrexmitfast, "\t\t%qd fast retransmitted packet%s\n");
266 	p2a(tcps_sndacks, tcps_delack,
267 	    "\t\t%u ack-only packet%s (%u delayed)\n");
268 	p(tcps_sndurg, "\t\t%u URG only packet%s\n");
269 	p(tcps_sndprobe, "\t\t%u window probe packet%s\n");
270 	p(tcps_sndwinup, "\t\t%u window update packet%s\n");
271 	p(tcps_sndctrl, "\t\t%u control packet%s\n");
272 	p(tcps_outhwcsum, "\t\t%u packet%s hardware-checksummed\n");
273 	p(tcps_rcvtotal, "\t%u packet%s received\n");
274 	p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%u ack%s (for %qd byte%s)\n");
275 	p(tcps_rcvdupack, "\t\t%u duplicate ack%s\n");
276 	p(tcps_rcvacktoomuch, "\t\t%u ack%s for unsent data\n");
277 	p(tcps_rcvacktooold, "\t\t%u ack%s for old data\n");
278 	p2(tcps_rcvpack, tcps_rcvbyte,
279 	    "\t\t%u packet%s (%qu byte%s) received in-sequence\n");
280 	p2(tcps_rcvduppack, tcps_rcvdupbyte,
281 	    "\t\t%u completely duplicate packet%s (%qd byte%s)\n");
282 	p(tcps_pawsdrop, "\t\t%u old duplicate packet%s\n");
283 	p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte,
284 	    "\t\t%u packet%s with some duplicate data (%qd byte%s duplicated)\n");
285 	p2(tcps_rcvoopack, tcps_rcvoobyte,
286 	    "\t\t%u out-of-order packet%s (%qd byte%s)\n");
287 	p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin,
288 	    "\t\t%u packet%s (%qd byte%s) of data after window\n");
289 	p(tcps_rcvwinprobe, "\t\t%u window probe%s\n");
290 	p(tcps_rcvwinupd, "\t\t%u window update packet%s\n");
291 	p(tcps_rcvafterclose, "\t\t%u packet%s received after close\n");
292 	p(tcps_rcvbadsum, "\t\t%u discarded for bad checksum%s\n");
293 	p(tcps_rcvbadoff, "\t\t%u discarded for bad header offset field%s\n");
294 	p1(tcps_rcvshort, "\t\t%u discarded because packet too short\n");
295 	p1(tcps_rcvnosec, "\t\t%u discarded for missing IPsec protection\n");
296 	p1(tcps_rcvmemdrop, "\t\t%u discarded due to memory shortage\n");
297 	p(tcps_inhwcsum, "\t\t%u packet%s hardware-checksummed\n");
298 	p(tcps_rcvbadsig, "\t\t%u bad/missing md5 checksum%s\n");
299 	p(tcps_rcvgoodsig, "\t\t%qd good md5 checksum%s\n");
300 	p(tcps_connattempt, "\t%u connection request%s\n");
301 	p(tcps_accepts, "\t%u connection accept%s\n");
302 	p(tcps_connects, "\t%u connection%s established (including accepts)\n");
303 	p2(tcps_closed, tcps_drops,
304 	    "\t%u connection%s closed (including %u drop%s)\n");
305 	p(tcps_conndrained, "\t%qd connection%s drained\n");
306 	p(tcps_conndrops, "\t%u embryonic connection%s dropped\n");
307 	p2(tcps_rttupdated, tcps_segstimed,
308 	    "\t%u segment%s updated rtt (of %u attempt%s)\n");
309 	p(tcps_rexmttimeo, "\t%u retransmit timeout%s\n");
310 	p(tcps_timeoutdrop, "\t\t%u connection%s dropped by rexmit timeout\n");
311 	p(tcps_persisttimeo, "\t%u persist timeout%s\n");
312 	p(tcps_keeptimeo, "\t%u keepalive timeout%s\n");
313 	p(tcps_keepprobe, "\t\t%u keepalive probe%s sent\n");
314 	p(tcps_keepdrops, "\t\t%u connection%s dropped by keepalive\n");
315 	p(tcps_predack, "\t%u correct ACK header prediction%s\n");
316 	p(tcps_preddat, "\t%u correct data packet header prediction%s\n");
317 	p3(tcps_pcbhashmiss, "\t%u PCB cache miss%s\n");
318 
319 	p(tcps_ecn_accepts, "\t%u ECN connection%s accepted\n");
320 	p(tcps_ecn_rcvece, "\t\t%u ECE packet%s received\n");
321 	p(tcps_ecn_rcvcwr, "\t\t%u CWR packet%s received\n");
322 	p(tcps_ecn_rcvce, "\t\t%u CE packet%s received\n");
323 	p(tcps_ecn_sndect, "\t\t%u ECT packet%s sent\n");
324 	p(tcps_ecn_sndece, "\t\t%u ECE packet%s sent\n");
325 	p(tcps_ecn_sndcwr, "\t\t%u CWR packet%s sent\n");
326 	p1(tcps_cwr_frecovery, "\t\t\tcwr by fastrecovery: %u\n");
327 	p1(tcps_cwr_timeout, "\t\t\tcwr by timeout: %u\n");
328 	p1(tcps_cwr_ecn, "\t\t\tcwr by ecn: %u\n");
329 
330 	p(tcps_badsyn, "\t%u bad connection attempt%s\n");
331 	p1(tcps_sc_added, "\t%qd SYN cache entries added\n");
332 	p(tcps_sc_collisions, "\t\t%qd hash collision%s\n");
333 	p1(tcps_sc_completed, "\t\t%qd completed\n");
334 	p1(tcps_sc_aborted, "\t\t%qd aborted (no space to build PCB)\n");
335 	p1(tcps_sc_timed_out, "\t\t%qd timed out\n");
336 	p1(tcps_sc_overflowed, "\t\t%qd dropped due to overflow\n");
337 	p1(tcps_sc_bucketoverflow, "\t\t%qd dropped due to bucket overflow\n");
338 	p1(tcps_sc_reset, "\t\t%qd dropped due to RST\n");
339 	p1(tcps_sc_unreach, "\t\t%qd dropped due to ICMP unreachable\n");
340 	p(tcps_sc_retransmitted, "\t%qd SYN,ACK%s retransmitted\n");
341 	p(tcps_sc_dupesyn, "\t%qd duplicate SYN%s received for entries "
342 		"already in the cache\n");
343 	p(tcps_sc_dropped, "\t%qd SYN%s dropped (no route or no space)\n");
344 
345 	p(tcps_sack_recovery_episode, "\t%qd SACK recovery episode%s\n");
346 	p(tcps_sack_rexmits,
347 		"\t\t%qd segment rexmit%s in SACK recovery episodes\n");
348 	p(tcps_sack_rexmit_bytes,
349 		"\t\t%qd byte rexmit%s in SACK recovery episodes\n");
350 	p(tcps_sack_rcv_opts,
351 		"\t%qd SACK option%s received\n");
352 	p(tcps_sack_snd_opts, "\t%qd SACK option%s sent\n");
353 
354 #undef p
355 #undef p1
356 #undef p2
357 #undef p2a
358 #undef p3
359 }
360 
361 /*
362  * Dump UDP statistics structure.
363  */
364 void
365 udp_stats(char *name)
366 {
367 	struct udpstat udpstat;
368 	u_long delivered;
369 	int mib[] = { CTL_NET, AF_INET, IPPROTO_UDP, UDPCTL_STATS };
370 	size_t len = sizeof(udpstat);
371 
372 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
373 	    &udpstat, &len, NULL, 0) == -1) {
374 		if (errno != ENOPROTOOPT)
375 			warn(name);
376 		return;
377 	}
378 
379 	printf("%s:\n", name);
380 #define	p(f, m) if (udpstat.f || sflag <= 1) \
381 	printf(m, udpstat.f, plural(udpstat.f))
382 #define	p1(f, m) if (udpstat.f || sflag <= 1) \
383 	printf(m, udpstat.f)
384 
385 	p(udps_ipackets, "\t%lu datagram%s received\n");
386 	p1(udps_hdrops, "\t%lu with incomplete header\n");
387 	p1(udps_badlen, "\t%lu with bad data length field\n");
388 	p1(udps_badsum, "\t%lu with bad checksum\n");
389 	p1(udps_nosum, "\t%lu with no checksum\n");
390 	p(udps_inhwcsum, "\t%lu input packet%s hardware-checksummed\n");
391 	p(udps_outhwcsum, "\t%lu output packet%s hardware-checksummed\n");
392 	p1(udps_noport, "\t%lu dropped due to no socket\n");
393 	p(udps_noportbcast, "\t%lu broadcast/multicast datagram%s dropped due to no socket\n");
394 	p1(udps_nosec, "\t%lu dropped due to missing IPsec protection\n");
395 	p1(udps_fullsock, "\t%lu dropped due to full socket buffers\n");
396 	delivered = udpstat.udps_ipackets - udpstat.udps_hdrops -
397 	    udpstat.udps_badlen - udpstat.udps_badsum -
398 	    udpstat.udps_noport - udpstat.udps_noportbcast -
399 	    udpstat.udps_fullsock;
400 	if (delivered || sflag <= 1)
401 		printf("\t%lu delivered\n", delivered);
402 	p(udps_opackets, "\t%lu datagram%s output\n");
403 	p1(udps_pcbhashmiss, "\t%lu missed PCB cache\n");
404 #undef p
405 #undef p1
406 }
407 
408 /*
409  * Dump IP statistics structure.
410  */
411 void
412 ip_stats(char *name)
413 {
414 	struct ipstat ipstat;
415 	int mib[] = { CTL_NET, AF_INET, IPPROTO_IP, IPCTL_STATS };
416 	size_t len = sizeof(ipstat);
417 
418 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
419 	    &ipstat, &len, NULL, 0) == -1) {
420 		if (errno != ENOPROTOOPT)
421 			warn(name);
422 		return;
423 	}
424 
425 	printf("%s:\n", name);
426 #define	p(f, m) if (ipstat.f || sflag <= 1) \
427 	printf(m, ipstat.f, plural(ipstat.f))
428 #define	p1(f, m) if (ipstat.f || sflag <= 1) \
429 	printf(m, ipstat.f)
430 
431 	p(ips_total, "\t%lu total packet%s received\n");
432 	p(ips_badsum, "\t%lu bad header checksum%s\n");
433 	p1(ips_toosmall, "\t%lu with size smaller than minimum\n");
434 	p1(ips_tooshort, "\t%lu with data size < data length\n");
435 	p1(ips_badhlen, "\t%lu with header length < data size\n");
436 	p1(ips_badlen, "\t%lu with data length < header length\n");
437 	p1(ips_badoptions, "\t%lu with bad options\n");
438 	p1(ips_badvers, "\t%lu with incorrect version number\n");
439 	p(ips_fragments, "\t%lu fragment%s received\n");
440 	p(ips_fragdropped, "\t%lu fragment%s dropped (duplicates or out of space)\n");
441 	p(ips_badfrags, "\t%lu malformed fragment%s dropped\n");
442 	p(ips_fragtimeout, "\t%lu fragment%s dropped after timeout\n");
443 	p(ips_reassembled, "\t%lu packet%s reassembled ok\n");
444 	p(ips_delivered, "\t%lu packet%s for this host\n");
445 	p(ips_noproto, "\t%lu packet%s for unknown/unsupported protocol\n");
446 	p(ips_forward, "\t%lu packet%s forwarded\n");
447 	p(ips_cantforward, "\t%lu packet%s not forwardable\n");
448 	p(ips_redirectsent, "\t%lu redirect%s sent\n");
449 	p(ips_localout, "\t%lu packet%s sent from this host\n");
450 	p(ips_rawout, "\t%lu packet%s sent with fabricated ip header\n");
451 	p(ips_odropped, "\t%lu output packet%s dropped due to no bufs, etc.\n");
452 	p(ips_noroute, "\t%lu output packet%s discarded due to no route\n");
453 	p(ips_fragmented, "\t%lu output datagram%s fragmented\n");
454 	p(ips_ofragments, "\t%lu fragment%s created\n");
455 	p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n");
456 	p1(ips_rcvmemdrop, "\t%lu fragment floods\n");
457 	p(ips_toolong, "\t%lu packet%s with ip length > max ip packet size\n");
458 	p(ips_nogif, "\t%lu tunneling packet%s that can't find gif\n");
459 	p(ips_badaddr, "\t%lu datagram%s with bad address in header\n");
460 	p(ips_inhwcsum, "\t%lu input datagram%s checksum-processed by hardware\n");
461 	p(ips_outhwcsum, "\t%lu output datagram%s checksum-processed by hardware\n");
462 	p(ips_notmember, "\t%lu multicast packet%s which we don't join\n");
463 #undef p
464 #undef p1
465 }
466 
467 /*
468  * Dump DIVERT statistics structure.
469  */
470 void
471 div_stats(char *name)
472 {
473 	struct divstat divstat;
474 	int mib[] = { CTL_NET, AF_INET, IPPROTO_DIVERT, DIVERTCTL_STATS };
475 	size_t len = sizeof(divstat);
476 
477 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
478 	    &divstat, &len, NULL, 0) == -1) {
479 		if (errno != ENOPROTOOPT)
480 			warn(name);
481 		return;
482 	}
483 
484 	printf("%s:\n", name);
485 #define	p(f, m) if (divstat.f || sflag <= 1) \
486 	printf(m, divstat.f, plural(divstat.f))
487 #define	p1(f, m) if (divstat.f || sflag <= 1) \
488 	printf(m, divstat.f)
489 	p(divs_ipackets, "\t%lu total packet%s received\n");
490 	p1(divs_noport, "\t%lu dropped due to no socket\n");
491 	p1(divs_fullsock, "\t%lu dropped due to full socket buffers\n");
492 	p(divs_opackets, "\t%lu packet%s output\n");
493 	p1(divs_errors, "\t%lu errors\n");
494 #undef p
495 #undef p1
496 }
497 
498 static	char *icmpnames[ICMP_MAXTYPE + 1] = {
499 	"echo reply",
500 	"#1",
501 	"#2",
502 	"destination unreachable",
503 	"source quench",
504 	"routing redirect",
505 	"#6",
506 	"#7",
507 	"echo",
508 	"router advertisement",
509 	"router solicitation",
510 	"time exceeded",
511 	"parameter problem",
512 	"time stamp",
513 	"time stamp reply",
514 	"information request",
515 	"information request reply",
516 	"address mask request",
517 	"address mask reply",
518 	"#19",
519 	"#20",
520 	"#21",
521 	"#22",
522 	"#23",
523 	"#24",
524 	"#25",
525 	"#26",
526 	"#27",
527 	"#28",
528 	"#29",
529 	"traceroute",
530 	"data conversion error",
531 	"mobile host redirect",
532 	"IPv6 where-are-you",
533 	"IPv6 i-am-here",
534 	"mobile registration request",
535 	"mobile registration reply",
536 	"#37",
537 	"#38",
538 	"SKIP",
539 	"Photuris",
540 };
541 
542 /*
543  * Dump ICMP statistics.
544  */
545 void
546 icmp_stats(char *name)
547 {
548 	struct icmpstat icmpstat;
549 	int i, first;
550 	int mib[] = { CTL_NET, AF_INET, IPPROTO_ICMP, ICMPCTL_STATS };
551 	size_t len = sizeof(icmpstat);
552 
553 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
554 	    &icmpstat, &len, NULL, 0) == -1) {
555 		if (errno != ENOPROTOOPT)
556 			warn(name);
557 		return;
558 	}
559 
560 	printf("%s:\n", name);
561 #define	p(f, m) if (icmpstat.f || sflag <= 1) \
562 	printf(m, icmpstat.f, plural(icmpstat.f))
563 
564 	p(icps_error, "\t%lu call%s to icmp_error\n");
565 	p(icps_oldicmp,
566 	    "\t%lu error%s not generated because old message was icmp\n");
567 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
568 		if (icmpstat.icps_outhist[i] != 0) {
569 			if (first) {
570 				printf("\tOutput packet histogram:\n");
571 				first = 0;
572 			}
573 			if (icmpnames[i])
574 				printf("\t\t%s:", icmpnames[i]);
575 			else
576 				printf("\t\t#%d:", i);
577 			printf(" %lu\n", icmpstat.icps_outhist[i]);
578 		}
579 	p(icps_badcode, "\t%lu message%s with bad code fields\n");
580 	p(icps_tooshort, "\t%lu message%s < minimum length\n");
581 	p(icps_checksum, "\t%lu bad checksum%s\n");
582 	p(icps_badlen, "\t%lu message%s with bad length\n");
583 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
584 		if (icmpstat.icps_inhist[i] != 0) {
585 			if (first) {
586 				printf("\tInput packet histogram:\n");
587 				first = 0;
588 			}
589 			if (icmpnames[i])
590 				printf("\t\t%s:", icmpnames[i]);
591 			else
592 				printf("\t\t#%d:", i);
593 			printf(" %lu\n", icmpstat.icps_inhist[i]);
594 		}
595 	p(icps_reflect, "\t%lu message response%s generated\n");
596 #undef p
597 }
598 
599 /*
600  * Dump IGMP statistics structure.
601  */
602 void
603 igmp_stats(char *name)
604 {
605 	struct igmpstat igmpstat;
606 	int mib[] = { CTL_NET, AF_INET, IPPROTO_IGMP, IGMPCTL_STATS };
607 	size_t len = sizeof(igmpstat);
608 
609 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
610 	    &igmpstat, &len, NULL, 0) == -1) {
611 		if (errno != ENOPROTOOPT)
612 			warn(name);
613 		return;
614 	}
615 
616 	printf("%s:\n", name);
617 #define	p(f, m) if (igmpstat.f || sflag <= 1) \
618 	printf(m, igmpstat.f, plural(igmpstat.f))
619 #define	py(f, m) if (igmpstat.f || sflag <= 1) \
620 	printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y")
621 
622 	p(igps_rcv_total, "\t%lu message%s received\n");
623 	p(igps_rcv_tooshort, "\t%lu message%s received with too few bytes\n");
624 	p(igps_rcv_badsum, "\t%lu message%s received with bad checksum\n");
625 	py(igps_rcv_queries, "\t%lu membership quer%s received\n");
626 	py(igps_rcv_badqueries, "\t%lu membership quer%s received with invalid field(s)\n");
627 	p(igps_rcv_reports, "\t%lu membership report%s received\n");
628 	p(igps_rcv_badreports, "\t%lu membership report%s received with invalid field(s)\n");
629 	p(igps_rcv_ourreports, "\t%lu membership report%s received for groups to which we belong\n");
630 	p(igps_snd_reports, "\t%lu membership report%s sent\n");
631 #undef p
632 #undef py
633 }
634 
635 /*
636  * Dump PIM statistics structure.
637  */
638 void
639 pim_stats(char *name)
640 {
641 	struct pimstat pimstat;
642 	int mib[] = { CTL_NET, AF_INET, IPPROTO_PIM, PIMCTL_STATS };
643 	size_t len = sizeof(pimstat);
644 
645 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
646 	    &pimstat, &len, NULL, 0) == -1) {
647 		if (errno != ENOPROTOOPT)
648 			warn(name);
649 		return;
650 	}
651 
652 	printf("%s:\n", name);
653 #define	p(f, m) if (pimstat.f || sflag <= 1) \
654 	printf(m, pimstat.f, plural(pimstat.f))
655 #define	py(f, m) if (pimstat.f || sflag <= 1) \
656 	printf(m, pimstat.f, pimstat.f != 1 ? "ies" : "y")
657 
658 	p(pims_rcv_total_msgs, "\t%llu message%s received\n");
659 	p(pims_rcv_total_bytes, "\t%llu byte%s received\n");
660 	p(pims_rcv_tooshort, "\t%llu message%s received with too few bytes\n");
661 	p(pims_rcv_badsum, "\t%llu message%s received with bad checksum\n");
662 	p(pims_rcv_badversion, "\t%llu message%s received with bad version\n");
663 	p(pims_rcv_registers_msgs, "\t%llu data register message%s received\n");
664 	p(pims_rcv_registers_bytes, "\t%llu data register byte%s received\n");
665 	p(pims_rcv_registers_wrongiif, "\t%llu data register message%s received on wrong iif\n");
666 	p(pims_rcv_badregisters, "\t%llu bad register%s received\n");
667 	p(pims_snd_registers_msgs, "\t%llu data register message%s sent\n");
668 	p(pims_snd_registers_bytes, "\t%llu data register byte%s sent\n");
669 #undef p
670 #undef py
671 }
672 
673 struct rpcnams {
674 	struct rpcnams *next;
675 	in_port_t port;
676 	int	  proto;
677 	char	*rpcname;
678 };
679 
680 static char *
681 getrpcportnam(in_port_t port, int proto)
682 {
683 	struct sockaddr_in server_addr;
684 	struct hostent *hp;
685 	static struct pmaplist *head;
686 	int socket = RPC_ANYSOCK;
687 	struct timeval minutetimeout;
688 	CLIENT *client;
689 	struct rpcent *rpc;
690 	static int first;
691 	static struct rpcnams *rpcn;
692 	struct rpcnams *n;
693 	char num[20];
694 
695 	if (first == 0) {
696 		first = 1;
697 		memset(&server_addr, 0, sizeof server_addr);
698 		server_addr.sin_family = AF_INET;
699 		if ((hp = gethostbyname("localhost")) != NULL)
700 			memmove((caddr_t)&server_addr.sin_addr, hp->h_addr,
701 			    hp->h_length);
702 		else
703 			(void) inet_aton("0.0.0.0", &server_addr.sin_addr);
704 
705 		minutetimeout.tv_sec = 60;
706 		minutetimeout.tv_usec = 0;
707 		server_addr.sin_port = htons(PMAPPORT);
708 		if ((client = clnttcp_create(&server_addr, PMAPPROG,
709 		    PMAPVERS, &socket, 50, 500)) == NULL)
710 			return (NULL);
711 		if (clnt_call(client, PMAPPROC_DUMP, xdr_void, NULL,
712 		    xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) {
713 			clnt_destroy(client);
714 			return (NULL);
715 		}
716 		for (; head != NULL; head = head->pml_next) {
717 			n = (struct rpcnams *)malloc(sizeof(struct rpcnams));
718 			if (n == NULL)
719 				continue;
720 			n->next = rpcn;
721 			rpcn = n;
722 			n->port = head->pml_map.pm_port;
723 			n->proto = head->pml_map.pm_prot;
724 
725 			rpc = getrpcbynumber(head->pml_map.pm_prog);
726 			if (rpc)
727 				n->rpcname = strdup(rpc->r_name);
728 			else {
729 				snprintf(num, sizeof num, "%ld",
730 				    head->pml_map.pm_prog);
731 				n->rpcname = strdup(num);
732 			}
733 		}
734 		clnt_destroy(client);
735 	}
736 
737 	for (n = rpcn; n; n = n->next)
738 		if (n->port == port && n->proto == proto)
739 			return (n->rpcname);
740 	return (NULL);
741 }
742 
743 /*
744  * Pretty print an Internet address (net address + port).
745  * If the nflag was specified, use numbers instead of names.
746  */
747 void
748 inetprint(struct in_addr *in, in_port_t port, char *proto, int local)
749 {
750 	struct servent *sp = 0;
751 	char line[80], *cp, *nam;
752 	int width;
753 
754 	snprintf(line, sizeof line, "%.*s.", (Aflag && !nflag) ? 12 : 16,
755 	    inetname(in));
756 	cp = strchr(line, '\0');
757 	if (!nflag && port)
758 		sp = getservbyport((int)port, proto);
759 	if (sp || port == 0)
760 		snprintf(cp, line + sizeof line - cp, "%.8s",
761 		    sp ? sp->s_name : "*");
762 	else if (local && !nflag && (nam = getrpcportnam(ntohs(port),
763 	    (strcmp(proto, "tcp") == 0 ? IPPROTO_TCP : IPPROTO_UDP))))
764 		snprintf(cp, line + sizeof line - cp, "%d[%.8s]",
765 		    ntohs(port), nam);
766 	else
767 		snprintf(cp, line + sizeof line - cp, "%d", ntohs(port));
768 	width = Aflag ? 18 : 22;
769 	printf(" %-*.*s", width, width, line);
770 }
771 
772 /*
773  * Construct an Internet address representation.
774  * If the nflag has been supplied, give
775  * numeric value, otherwise try for symbolic name.
776  */
777 char *
778 inetname(struct in_addr *inp)
779 {
780 	char *cp;
781 	static char line[50];
782 	struct hostent *hp;
783 	struct netent *np;
784 	static char domain[MAXHOSTNAMELEN];
785 	static int first = 1;
786 
787 	if (first && !nflag) {
788 		first = 0;
789 		if (gethostname(domain, sizeof(domain)) == 0 &&
790 		    (cp = strchr(domain, '.')))
791 			(void) strlcpy(domain, cp + 1, sizeof domain);
792 		else
793 			domain[0] = '\0';
794 	}
795 	cp = NULL;
796 	if (!nflag && inp->s_addr != INADDR_ANY) {
797 		int net = inet_netof(*inp);
798 		int lna = inet_lnaof(*inp);
799 
800 		if (lna == INADDR_ANY) {
801 			np = getnetbyaddr(net, AF_INET);
802 			if (np)
803 				cp = np->n_name;
804 		}
805 		if (cp == NULL) {
806 			hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET);
807 			if (hp) {
808 				if ((cp = strchr(hp->h_name, '.')) &&
809 				    !strcmp(cp + 1, domain))
810 					*cp = '\0';
811 				cp = hp->h_name;
812 			}
813 		}
814 	}
815 	if (inp->s_addr == INADDR_ANY)
816 		snprintf(line, sizeof line, "*");
817 	else if (cp)
818 		snprintf(line, sizeof line, "%s", cp);
819 	else {
820 		inp->s_addr = ntohl(inp->s_addr);
821 #define C(x)	((x) & 0xff)
822 		snprintf(line, sizeof line, "%u.%u.%u.%u",
823 		    C(inp->s_addr >> 24), C(inp->s_addr >> 16),
824 		    C(inp->s_addr >> 8), C(inp->s_addr));
825 	}
826 	return (line);
827 }
828 
829 /*
830  * Dump AH statistics structure.
831  */
832 void
833 ah_stats(char *name)
834 {
835 	struct ahstat ahstat;
836 	int mib[] = { CTL_NET, AF_INET, IPPROTO_AH, AHCTL_STATS };
837 	size_t len = sizeof(ahstat);
838 
839 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
840 	    &ahstat, &len, NULL, 0) == -1) {
841 		if (errno != ENOPROTOOPT)
842 			warn(name);
843 		return;
844 	}
845 
846 	printf("%s:\n", name);
847 #define p(f, m) if (ahstat.f || sflag <= 1) \
848 	printf(m, ahstat.f, plural(ahstat.f))
849 #define p1(f, m) if (ahstat.f || sflag <= 1) \
850 	printf(m, ahstat.f)
851 
852 	p1(ahs_input, "\t%u input AH packets\n");
853 	p1(ahs_output, "\t%u output AH packets\n");
854 	p(ahs_nopf, "\t%u packet%s from unsupported protocol families\n");
855 	p(ahs_hdrops, "\t%u packet%s shorter than header shows\n");
856 	p(ahs_pdrops, "\t%u packet%s dropped due to policy\n");
857 	p(ahs_notdb, "\t%u packet%s for which no TDB was found\n");
858 	p(ahs_badkcr, "\t%u input packet%s that failed to be processed\n");
859 	p(ahs_badauth, "\t%u packet%s that failed verification received\n");
860 	p(ahs_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n");
861 	p(ahs_qfull, "\t%u packet%s were dropped due to full output queue\n");
862 	p(ahs_wrap, "\t%u packet%s where counter wrapping was detected\n");
863 	p(ahs_replay, "\t%u possibly replayed packet%s received\n");
864 	p(ahs_badauthl, "\t%u packet%s with bad authenticator length received\n");
865 	p(ahs_invalid, "\t%u packet%s attempted to use an invalid TDB\n");
866 	p(ahs_toobig, "\t%u packet%s got larger than max IP packet size\n");
867 	p(ahs_crypto, "\t%u packet%s that failed crypto processing\n");
868 	p(ahs_ibytes, "\t%qu input byte%s\n");
869 	p(ahs_obytes, "\t%qu output byte%s\n");
870 
871 #undef p
872 #undef p1
873 }
874 
875 /*
876  * Dump etherip statistics structure.
877  */
878 void
879 etherip_stats(char *name)
880 {
881 	struct etheripstat etheripstat;
882 	int mib[] = { CTL_NET, AF_INET, IPPROTO_ETHERIP, ETHERIPCTL_STATS };
883 	size_t len = sizeof(etheripstat);
884 
885 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
886 	    &etheripstat, &len, NULL, 0) == -1) {
887 		if (errno != ENOPROTOOPT)
888 			warn(name);
889 		return;
890 	}
891 
892 	printf("%s:\n", name);
893 #define p(f, m) if (etheripstat.f || sflag <= 1) \
894 	printf(m, etheripstat.f, plural(etheripstat.f))
895 
896 	p(etherip_hdrops, "\t%u packet%s shorter than header shows\n");
897 	p(etherip_qfull, "\t%u packet%s were dropped due to full output queue\n");
898 	p(etherip_noifdrops, "\t%u packet%s were dropped because of no interface/bridge information\n");
899 	p(etherip_pdrops, "\t%u packet%s dropped due to policy\n");
900 	p(etherip_adrops, "\t%u packet%s dropped for other reasons\n");
901 	p(etherip_ipackets, "\t%u input ethernet-in-IP packet%s\n");
902 	p(etherip_opackets, "\t%u output ethernet-in-IP packet%s\n");
903 	p(etherip_ibytes, "\t%qu input byte%s\n");
904 	p(etherip_obytes, "\t%qu output byte%s\n");
905 #undef p
906 }
907 
908 /*
909  * Dump ESP statistics structure.
910  */
911 void
912 esp_stats(char *name)
913 {
914 	struct espstat espstat;
915 	int mib[] = { CTL_NET, AF_INET, IPPROTO_ESP, ESPCTL_STATS };
916 	size_t len = sizeof(espstat);
917 
918 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
919 	    &espstat, &len, NULL, 0) == -1) {
920 		if (errno != ENOPROTOOPT)
921 			warn(name);
922 		return;
923 	}
924 
925 	printf("%s:\n", name);
926 #define p(f, m) if (espstat.f || sflag <= 1) \
927 	printf(m, espstat.f, plural(espstat.f))
928 
929 	p(esps_input, "\t%u input ESP packet%s\n");
930 	p(esps_output, "\t%u output ESP packet%s\n");
931 	p(esps_nopf, "\t%u packet%s from unsupported protocol families\n");
932 	p(esps_hdrops, "\t%u packet%s shorter than header shows\n");
933 	p(esps_pdrops, "\t%u packet%s dropped due to policy\n");
934 	p(esps_notdb, "\t%u packet%s for which no TDB was found\n");
935 	p(esps_badkcr, "\t%u input packet%s that failed to be processed\n");
936 	p(esps_badenc, "\t%u packet%s with bad encryption received\n");
937 	p(esps_badauth, "\t%u packet%s that failed verification received\n");
938 	p(esps_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n");
939 	p(esps_qfull, "\t%u packet%s were dropped due to full output queue\n");
940 	p(esps_wrap, "\t%u packet%s where counter wrapping was detected\n");
941 	p(esps_replay, "\t%u possibly replayed packet%s received\n");
942 	p(esps_badilen, "\t%u packet%s with bad payload size or padding received\n");
943 	p(esps_invalid, "\t%u packet%s attempted to use an invalid TDB\n");
944 	p(esps_toobig, "\t%u packet%s got larger than max IP packet size\n");
945 	p(esps_crypto, "\t%u packet%s that failed crypto processing\n");
946 	p(esps_udpencin, "\t%u input UDP encapsulated ESP packet%s\n");
947 	p(esps_udpencout, "\t%u output UDP encapsulated ESP packet%s\n");
948 	p(esps_udpinval, "\t%u UDP packet%s for non-encapsulating TDB received\n");
949 	p(esps_ibytes, "\t%qu input byte%s\n");
950 	p(esps_obytes, "\t%qu output byte%s\n");
951 
952 #undef p
953 }
954 
955 /*
956  * Dump IP-in-IP statistics structure.
957  */
958 void
959 ipip_stats(char *name)
960 {
961 	struct ipipstat ipipstat;
962 	int mib[] = { CTL_NET, AF_INET, IPPROTO_IPIP, IPIPCTL_STATS };
963 	size_t len = sizeof(ipipstat);
964 
965 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
966 	    &ipipstat, &len, NULL, 0) == -1) {
967 		if (errno != ENOPROTOOPT)
968 			warn(name);
969 		return;
970 	}
971 
972 	printf("%s:\n", name);
973 #define p(f, m) if (ipipstat.f || sflag <= 1) \
974 	printf(m, ipipstat.f, plural(ipipstat.f))
975 
976 	p(ipips_ipackets, "\t%u total input packet%s\n");
977 	p(ipips_opackets, "\t%u total output packet%s\n");
978 	p(ipips_hdrops, "\t%u packet%s shorter than header shows\n");
979 	p(ipips_pdrops, "\t%u packet%s dropped due to policy\n");
980 	p(ipips_spoof, "\t%u packet%s with possibly spoofed local addresses\n");
981 	p(ipips_qfull, "\t%u packet%s were dropped due to full output queue\n");
982 	p(ipips_ibytes, "\t%qu input byte%s\n");
983 	p(ipips_obytes, "\t%qu output byte%s\n");
984 	p(ipips_family, "\t%u protocol family mismatche%s\n");
985 	p(ipips_unspec, "\t%u attempt%s to use tunnel with unspecified endpoint(s)\n");
986 #undef p
987 }
988 
989 /*
990  * Dump CARP statistics structure.
991  */
992 void
993 carp_stats(char *name)
994 {
995 	struct carpstats carpstat;
996 	int mib[] = { CTL_NET, AF_INET, IPPROTO_CARP, CARPCTL_STATS };
997 	size_t len = sizeof(carpstat);
998 
999 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
1000 	    &carpstat, &len, NULL, 0) == -1) {
1001 		if (errno != ENOPROTOOPT)
1002 			warn(name);
1003 		return;
1004 	}
1005 
1006 	printf("%s:\n", name);
1007 #define p(f, m) if (carpstat.f || sflag <= 1) \
1008 	printf(m, carpstat.f, plural(carpstat.f))
1009 #define p2(f, m) if (carpstat.f || sflag <= 1) \
1010 	printf(m, carpstat.f)
1011 
1012 	p(carps_ipackets, "\t%llu packet%s received (IPv4)\n");
1013 	p(carps_ipackets6, "\t%llu packet%s received (IPv6)\n");
1014 	p(carps_badif, "\t\t%llu packet%s discarded for bad interface\n");
1015 	p(carps_badttl, "\t\t%llu packet%s discarded for wrong TTL\n");
1016 	p(carps_hdrops, "\t\t%llu packet%s shorter than header\n");
1017 	p(carps_badsum, "\t\t%llu discarded for bad checksum%s\n");
1018 	p(carps_badver,	"\t\t%llu discarded packet%s with a bad version\n");
1019 	p2(carps_badlen, "\t\t%llu discarded because packet too short\n");
1020 	p2(carps_badauth, "\t\t%llu discarded for bad authentication\n");
1021 	p2(carps_badvhid, "\t\t%llu discarded for unknown vhid\n");
1022 	p2(carps_badaddrs, "\t\t%llu discarded because of a bad address list\n");
1023 	p(carps_opackets, "\t%llu packet%s sent (IPv4)\n");
1024 	p(carps_opackets6, "\t%llu packet%s sent (IPv6)\n");
1025 	p2(carps_onomem, "\t\t%llu send failed due to mbuf memory error\n");
1026 	p(carps_preempt, "\t%llu transition%s to master\n");
1027 #undef p
1028 #undef p2
1029 }
1030 
1031 /*
1032  * Dump pfsync statistics structure.
1033  */
1034 void
1035 pfsync_stats(char *name)
1036 {
1037 	struct pfsyncstats pfsyncstat;
1038 	int mib[] = { CTL_NET, AF_INET, IPPROTO_PFSYNC, PFSYNCCTL_STATS };
1039 	size_t len = sizeof(pfsyncstat);
1040 
1041 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
1042 	    &pfsyncstat, &len, NULL, 0) == -1) {
1043 		if (errno != ENOPROTOOPT)
1044 			warn(name);
1045 		return;
1046 	}
1047 
1048 	printf("%s:\n", name);
1049 #define p(f, m) if (pfsyncstat.f || sflag <= 1) \
1050 	printf(m, pfsyncstat.f, plural(pfsyncstat.f))
1051 #define p2(f, m) if (pfsyncstat.f || sflag <= 1) \
1052 	printf(m, pfsyncstat.f)
1053 
1054 	p(pfsyncs_ipackets, "\t%llu packet%s received (IPv4)\n");
1055 	p(pfsyncs_ipackets6, "\t%llu packet%s received (IPv6)\n");
1056 	p(pfsyncs_badif, "\t\t%llu packet%s discarded for bad interface\n");
1057 	p(pfsyncs_badttl, "\t\t%llu packet%s discarded for bad ttl\n");
1058 	p(pfsyncs_hdrops, "\t\t%llu packet%s shorter than header\n");
1059 	p(pfsyncs_badver, "\t\t%llu packet%s discarded for bad version\n");
1060 	p(pfsyncs_badauth, "\t\t%llu packet%s discarded for bad HMAC\n");
1061 	p(pfsyncs_badact,"\t\t%llu packet%s discarded for bad action\n");
1062 	p(pfsyncs_badlen, "\t\t%llu packet%s discarded for short packet\n");
1063 	p(pfsyncs_badval, "\t\t%llu state%s discarded for bad values\n");
1064 	p(pfsyncs_stale, "\t\t%llu stale state%s\n");
1065 	p(pfsyncs_badstate, "\t\t%llu failed state lookup/insert%s\n");
1066 	p(pfsyncs_opackets, "\t%llu packet%s sent (IPv4)\n");
1067 	p(pfsyncs_opackets6, "\t%llu packet%s sent (IPv6)\n");
1068 	p2(pfsyncs_onomem, "\t\t%llu send failed due to mbuf memory error\n");
1069 	p2(pfsyncs_oerrors, "\t\t%llu send error\n");
1070 #undef p
1071 #undef p2
1072 }
1073 
1074 /*
1075  * Dump pflow statistics structure.
1076  */
1077 void
1078 pflow_stats(char *name)
1079 {
1080 	struct pflowstats flowstats;
1081 	int mib[] = { CTL_NET, PF_PFLOW, NET_PFLOW_STATS };
1082 	size_t len = sizeof(struct pflowstats);
1083 
1084 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &flowstats, &len,
1085 	    NULL, 0) == -1) {
1086 		if (errno != ENOPROTOOPT)
1087 			warn(name);
1088 		return;
1089 	}
1090 
1091 	printf("%s:\n", name);
1092 #define p(f, m) if (flowstats.f || sflag <= 1) \
1093 	printf(m, flowstats.f, plural(flowstats.f))
1094 #define p2(f, m) if (flowstats.f || sflag <= 1) \
1095 	printf(m, flowstats.f)
1096 
1097 	p(pflow_flows, "\t%llu flow%s sent\n");
1098 	p(pflow_packets, "\t%llu packet%s sent\n");
1099 	p2(pflow_onomem, "\t\t%llu send failed due to mbuf memory error\n");
1100 	p2(pflow_oerrors, "\t\t%llu send error\n");
1101 #undef p
1102 #undef p2
1103 }
1104 
1105 /*
1106  * Dump IPCOMP statistics structure.
1107  */
1108 void
1109 ipcomp_stats(char *name)
1110 {
1111 	struct ipcompstat ipcompstat;
1112 	int mib[] = { CTL_NET, AF_INET, IPPROTO_IPCOMP, IPCOMPCTL_STATS };
1113 	size_t len = sizeof(ipcompstat);
1114 
1115 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
1116 	    &ipcompstat, &len, NULL, 0) == -1) {
1117 		if (errno != ENOPROTOOPT)
1118 			warn(name);
1119 		return;
1120 	}
1121 
1122 	printf("%s:\n", name);
1123 #define p(f, m) if (ipcompstat.f || sflag <= 1) \
1124 	printf(m, ipcompstat.f, plural(ipcompstat.f))
1125 
1126 	p(ipcomps_input, "\t%u input IPCOMP packet%s\n");
1127 	p(ipcomps_output, "\t%u output IPCOMP packet%s\n");
1128 	p(ipcomps_nopf, "\t%u packet%s from unsupported protocol families\n");
1129 	p(ipcomps_hdrops, "\t%u packet%s shorter than header shows\n");
1130 	p(ipcomps_pdrops, "\t%u packet%s dropped due to policy\n");
1131 	p(ipcomps_notdb, "\t%u packet%s for which no TDB was found\n");
1132 	p(ipcomps_badkcr, "\t%u input packet%s that failed to be processed\n");
1133 	p(ipcomps_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n");
1134 	p(ipcomps_qfull, "\t%u packet%s were dropped due to full output queue\n");
1135 	p(ipcomps_wrap, "\t%u packet%s where counter wrapping was detected\n");
1136 	p(ipcomps_invalid, "\t%u packet%s attempted to use an invalid TDB\n");
1137 	p(ipcomps_toobig, "\t%u packet%s got larger than max IP packet size\n");
1138 	p(ipcomps_crypto, "\t%u packet%s that failed (de)compression processing\n");
1139 	p(ipcomps_minlen, "\t%u packet%s less than minimum compression length\n");
1140 	p(ipcomps_ibytes, "\t%qu input byte%s\n");
1141 	p(ipcomps_obytes, "\t%qu output byte%s\n");
1142 
1143 #undef p
1144 }
1145 
1146 /*
1147  * Dump the contents of a TCPCB
1148  */
1149 void
1150 tcp_dump(u_long off)
1151 {
1152 	struct tcpcb tcpcb;
1153 
1154 	if (off == 0)
1155 		return;
1156 	kread(off, (char *)&tcpcb, sizeof (tcpcb));
1157 
1158 #define	p(fmt, v, sep) printf(#v " " fmt sep, tcpcb.v);
1159 	printf("pcb %#lx, ", off);
1160 	p("%p", t_inpcb, "\n");
1161 	p("%d", t_state, "");
1162         if (tcpcb.t_state >= 0 && tcpcb.t_state < TCP_NSTATES)
1163 		printf(" (%s)", tcpstates[tcpcb.t_state]);
1164 	printf("\n");
1165 	p("%d", t_rxtshift, ", ");
1166 	p("%d", t_rxtcur, ", ");
1167 	p("%d", t_dupacks, "\n");
1168 	p("%u", t_maxseg, ", ");
1169 	p("%u", t_maxopd, ", ");
1170 	p("%u", t_peermss, "\n");
1171 	p("0x%x", t_flags, ", ");
1172 	p("%u", t_force, "\n");
1173 	p("%u", iss, "\n");
1174 	p("%u", snd_una, ", ");
1175 	p("%u", snd_nxt, ", ");
1176 	p("%u", snd_up, "\n");
1177 	p("%u", snd_wl1, ", ");
1178 	p("%u", snd_wl2, ", ");
1179 	p("%lu", snd_wnd, "\n");
1180 	p("%d", sack_enable, ", ");
1181 	p("%d", snd_numholes, ", ");
1182 	p("%u", snd_fack, ", ");
1183 	p("%lu",snd_awnd, "\n");
1184 	p("%u", retran_data, ", ");
1185 	p("%u", snd_last, "\n");
1186 	p("%u", irs, "\n");
1187 	p("%u", rcv_nxt, ", ");
1188 	p("%u", rcv_up, ", ");
1189 	p("%lu", rcv_wnd, "\n");
1190 	p("%u", rcv_lastsack, "\n");
1191 	p("%d", rcv_numsacks, "\n");
1192 	p("%u", rcv_adv, ", ");
1193 	p("%u", snd_max, "\n");
1194 	p("%lu", snd_cwnd, ", ");
1195 	p("%lu", snd_ssthresh, ", ");
1196 	p("%lu", max_sndwnd, "\n");
1197 	p("%u", t_rcvtime, ", ");
1198 	p("%u", t_rtttime, ", ");
1199 	p("%u", t_rtseq, "\n");
1200 	p("%u", t_srtt, ", ");
1201 	p("%u", t_rttvar, ", ");
1202 	p("%u", t_rttmin, "\n");
1203 	p("%u", t_oobflags, ", ");
1204 	p("%u", t_iobc, "\n");
1205 	p("%u", t_softerror, "\n");
1206 	p("%u", snd_scale, ", ");
1207 	p("%u", rcv_scale, ", ");
1208 	p("%u", request_r_scale, ", ");
1209 	p("%u", requested_s_scale, "\n");
1210 	p("%u", ts_recent, ", ");
1211 	p("%u", ts_recent_age, "\n");
1212 	p("%u", last_ack_sent, "\n");
1213 	HTONS(tcpcb.t_pmtud_ip_len);
1214 	HTONS(tcpcb.t_pmtud_nextmtu);
1215 	p("%u", t_pmtud_mss_acked, ", ");
1216 	p("%u", t_pmtud_mtu_sent, "\n");
1217 	p("%u", t_pmtud_nextmtu, ", ");
1218 	p("%u", t_pmtud_ip_len, ", ");
1219 	p("%u", t_pmtud_ip_hl, "\n");
1220 	p("%u", t_pmtud_th_seq, "\n");
1221 	p("%u", pf, "\n");
1222 #undef	p
1223 }
1224