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