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