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