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