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