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