xref: /openbsd-src/usr.bin/netstat/inet.c (revision 89c96e90242a81edf0d9a0550930a11563268b9d)
1 /*	$OpenBSD: inet.c,v 1.153 2016/12/22 11:04:44 rzalamena 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/tcp.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/udp.h>
59 #include <netinet/udp_var.h>
60 #include <netinet/ip_ipsp.h>
61 #include <netinet/ip_ah.h>
62 #include <netinet/ip_esp.h>
63 #include <netinet/ip_ipip.h>
64 #include <netinet/ip_ipcomp.h>
65 #include <netinet/ip_ether.h>
66 #include <netinet/ip_carp.h>
67 #include <netinet/ip_divert.h>
68 #include <net/if.h>
69 #include <net/pfvar.h>
70 #include <net/if_pfsync.h>
71 #include <net/if_pflow.h>
72 
73 #include <rpc/rpc.h>
74 #include <rpc/pmap_prot.h>
75 #include <rpc/pmap_clnt.h>
76 
77 #include <arpa/inet.h>
78 #include <err.h>
79 #include <limits.h>
80 #include <netdb.h>
81 #include <stdio.h>
82 #include <string.h>
83 #include <unistd.h>
84 #include <stdlib.h>
85 #include <errno.h>
86 #include "netstat.h"
87 
88 struct	inpcb inpcb;
89 struct	tcpcb tcpcb;
90 struct	socket sockb;
91 
92 char	*inetname(struct in_addr *);
93 void	inetprint(struct in_addr *, in_port_t, const char *, int);
94 char	*inet6name(struct in6_addr *);
95 void	sosplice_dump(u_long);
96 void	sockbuf_dump(struct sockbuf *, const char *);
97 void	protosw_dump(u_long, u_long);
98 void	domain_dump(u_long, u_long, short);
99 void	inpcb_dump(u_long, short, int);
100 void	tcpcb_dump(u_long);
101 int	kf_comp(const void *, const void *);
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 struct rpcnams {
774 	struct rpcnams *next;
775 	in_port_t port;
776 	int	  proto;
777 	char	*rpcname;
778 };
779 
780 static char *
781 getrpcportnam(in_port_t port, int proto)
782 {
783 	struct sockaddr_in server_addr;
784 	struct hostent *hp;
785 	static struct pmaplist *head;
786 	int socket = RPC_ANYSOCK;
787 	struct timeval minutetimeout;
788 	CLIENT *client;
789 	struct rpcent *rpc;
790 	static int first;
791 	static struct rpcnams *rpcn;
792 	struct rpcnams *n;
793 	char num[20];
794 
795 	if (first == 0) {
796 		first = 1;
797 		memset(&server_addr, 0, sizeof server_addr);
798 		server_addr.sin_family = AF_INET;
799 		if ((hp = gethostbyname("localhost")) != NULL)
800 			memmove((caddr_t)&server_addr.sin_addr, hp->h_addr,
801 			    hp->h_length);
802 		else
803 			(void) inet_aton("0.0.0.0", &server_addr.sin_addr);
804 
805 		minutetimeout.tv_sec = 60;
806 		minutetimeout.tv_usec = 0;
807 		server_addr.sin_port = htons(PMAPPORT);
808 		if ((client = clnttcp_create(&server_addr, PMAPPROG,
809 		    PMAPVERS, &socket, 50, 500)) == NULL)
810 			return (NULL);
811 		if (clnt_call(client, PMAPPROC_DUMP, xdr_void, NULL,
812 		    xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) {
813 			clnt_destroy(client);
814 			return (NULL);
815 		}
816 		for (; head != NULL; head = head->pml_next) {
817 			n = malloc(sizeof(struct rpcnams));
818 			if (n == NULL)
819 				continue;
820 			n->next = rpcn;
821 			rpcn = n;
822 			n->port = head->pml_map.pm_port;
823 			n->proto = head->pml_map.pm_prot;
824 
825 			rpc = getrpcbynumber(head->pml_map.pm_prog);
826 			if (rpc)
827 				n->rpcname = strdup(rpc->r_name);
828 			else {
829 				snprintf(num, sizeof num, "%ld",
830 				    head->pml_map.pm_prog);
831 				n->rpcname = strdup(num);
832 			}
833 		}
834 		clnt_destroy(client);
835 	}
836 
837 	for (n = rpcn; n; n = n->next)
838 		if (n->port == port && n->proto == proto)
839 			return (n->rpcname);
840 	return (NULL);
841 }
842 
843 /*
844  * Pretty print an Internet address (net address + port).
845  * If the nflag was specified, use numbers instead of names.
846  */
847 void
848 inetprint(struct in_addr *in, in_port_t port, const char *proto, int local)
849 {
850 	struct servent *sp = 0;
851 	char line[80], *cp, *nam;
852 	int width;
853 
854 	snprintf(line, sizeof line, "%.*s.", (Aflag && !nflag) ? 12 : 16,
855 	    inetname(in));
856 	cp = strchr(line, '\0');
857 	if (!nflag && port)
858 		sp = getservbyport((int)port, proto);
859 	if (sp || port == 0)
860 		snprintf(cp, line + sizeof line - cp, "%.8s",
861 		    sp ? sp->s_name : "*");
862 	else if (local && !nflag && (nam = getrpcportnam(ntohs(port),
863 	    (strcmp(proto, "tcp") == 0 ? IPPROTO_TCP : IPPROTO_UDP))))
864 		snprintf(cp, line + sizeof line - cp, "%d[%.8s]",
865 		    ntohs(port), nam);
866 	else
867 		snprintf(cp, line + sizeof line - cp, "%d", ntohs(port));
868 	width = Aflag ? 18 : 22;
869 	printf(" %-*.*s", width, width, line);
870 }
871 
872 /*
873  * Construct an Internet address representation.
874  * If the nflag has been supplied, give
875  * numeric value, otherwise try for symbolic name.
876  */
877 char *
878 inetname(struct in_addr *inp)
879 {
880 	char *cp;
881 	static char line[50];
882 	struct hostent *hp;
883 	static char domain[HOST_NAME_MAX+1];
884 	static int first = 1;
885 
886 	if (first && !nflag) {
887 		first = 0;
888 		if (gethostname(domain, sizeof(domain)) == 0 &&
889 		    (cp = strchr(domain, '.')))
890 			(void) strlcpy(domain, cp + 1, sizeof domain);
891 		else
892 			domain[0] = '\0';
893 	}
894 	cp = NULL;
895 	if (!nflag && inp->s_addr != INADDR_ANY) {
896 		hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET);
897 		if (hp) {
898 			if ((cp = strchr(hp->h_name, '.')) &&
899 			    !strcmp(cp + 1, domain))
900 				*cp = '\0';
901 			cp = hp->h_name;
902 		}
903 	}
904 	if (inp->s_addr == INADDR_ANY)
905 		snprintf(line, sizeof line, "*");
906 	else if (cp)
907 		snprintf(line, sizeof line, "%s", cp);
908 	else {
909 		inp->s_addr = ntohl(inp->s_addr);
910 #define C(x)	((x) & 0xff)
911 		snprintf(line, sizeof line, "%u.%u.%u.%u",
912 		    C(inp->s_addr >> 24), C(inp->s_addr >> 16),
913 		    C(inp->s_addr >> 8), C(inp->s_addr));
914 	}
915 	return (line);
916 }
917 
918 /*
919  * Dump AH statistics structure.
920  */
921 void
922 ah_stats(char *name)
923 {
924 	struct ahstat ahstat;
925 	int mib[] = { CTL_NET, PF_INET, IPPROTO_AH, AHCTL_STATS };
926 	size_t len = sizeof(ahstat);
927 
928 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
929 	    &ahstat, &len, NULL, 0) == -1) {
930 		if (errno != ENOPROTOOPT)
931 			warn("%s", name);
932 		return;
933 	}
934 
935 	printf("%s:\n", name);
936 #define p(f, m) if (ahstat.f || sflag <= 1) \
937 	printf(m, ahstat.f, plural(ahstat.f))
938 #define p1(f, m) if (ahstat.f || sflag <= 1) \
939 	printf(m, ahstat.f)
940 
941 	p1(ahs_input, "\t%u input AH packets\n");
942 	p1(ahs_output, "\t%u output AH packets\n");
943 	p(ahs_nopf, "\t%u packet%s from unsupported protocol families\n");
944 	p(ahs_hdrops, "\t%u packet%s shorter than header shows\n");
945 	p(ahs_pdrops, "\t%u packet%s dropped due to policy\n");
946 	p(ahs_notdb, "\t%u packet%s for which no TDB was found\n");
947 	p(ahs_badkcr, "\t%u input packet%s that failed to be processed\n");
948 	p(ahs_badauth, "\t%u packet%s that failed verification received\n");
949 	p(ahs_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n");
950 	p(ahs_qfull, "\t%u packet%s were dropped due to full output queue\n");
951 	p(ahs_wrap, "\t%u packet%s where counter wrapping was detected\n");
952 	p(ahs_replay, "\t%u possibly replayed packet%s received\n");
953 	p(ahs_badauthl, "\t%u packet%s with bad authenticator length received\n");
954 	p(ahs_invalid, "\t%u packet%s attempted to use an invalid TDB\n");
955 	p(ahs_toobig, "\t%u packet%s got larger than max IP packet size\n");
956 	p(ahs_crypto, "\t%u packet%s that failed crypto processing\n");
957 	p(ahs_ibytes, "\t%llu input byte%s\n");
958 	p(ahs_obytes, "\t%llu output byte%s\n");
959 
960 #undef p
961 #undef p1
962 }
963 
964 /*
965  * Dump etherip statistics structure.
966  */
967 void
968 etherip_stats(char *name)
969 {
970 	struct etheripstat etheripstat;
971 	int mib[] = { CTL_NET, PF_INET, IPPROTO_ETHERIP, ETHERIPCTL_STATS };
972 	size_t len = sizeof(etheripstat);
973 
974 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
975 	    &etheripstat, &len, NULL, 0) == -1) {
976 		if (errno != ENOPROTOOPT)
977 			warn("%s", name);
978 		return;
979 	}
980 
981 	printf("%s:\n", name);
982 #define p(f, m) if (etheripstat.f || sflag <= 1) \
983 	printf(m, etheripstat.f, plural(etheripstat.f))
984 
985 	p(etherip_hdrops, "\t%u packet%s shorter than header shows\n");
986 	p(etherip_qfull, "\t%u packet%s were dropped due to full output queue\n");
987 	p(etherip_noifdrops, "\t%u packet%s were dropped because of no interface/bridge information\n");
988 	p(etherip_pdrops, "\t%u packet%s dropped due to policy\n");
989 	p(etherip_adrops, "\t%u packet%s dropped for other reasons\n");
990 	p(etherip_ipackets, "\t%u input ethernet-in-IP packet%s\n");
991 	p(etherip_opackets, "\t%u output ethernet-in-IP packet%s\n");
992 	p(etherip_ibytes, "\t%llu input byte%s\n");
993 	p(etherip_obytes, "\t%llu output byte%s\n");
994 #undef p
995 }
996 
997 /*
998  * Dump ESP statistics structure.
999  */
1000 void
1001 esp_stats(char *name)
1002 {
1003 	struct espstat espstat;
1004 	int mib[] = { CTL_NET, PF_INET, IPPROTO_ESP, ESPCTL_STATS };
1005 	size_t len = sizeof(espstat);
1006 
1007 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
1008 	    &espstat, &len, NULL, 0) == -1) {
1009 		if (errno != ENOPROTOOPT)
1010 			warn("%s", name);
1011 		return;
1012 	}
1013 
1014 	printf("%s:\n", name);
1015 #define p(f, m) if (espstat.f || sflag <= 1) \
1016 	printf(m, espstat.f, plural(espstat.f))
1017 
1018 	p(esps_input, "\t%u input ESP packet%s\n");
1019 	p(esps_output, "\t%u output ESP packet%s\n");
1020 	p(esps_nopf, "\t%u packet%s from unsupported protocol families\n");
1021 	p(esps_hdrops, "\t%u packet%s shorter than header shows\n");
1022 	p(esps_pdrops, "\t%u packet%s dropped due to policy\n");
1023 	p(esps_notdb, "\t%u packet%s for which no TDB was found\n");
1024 	p(esps_badkcr, "\t%u input packet%s that failed to be processed\n");
1025 	p(esps_badenc, "\t%u packet%s with bad encryption received\n");
1026 	p(esps_badauth, "\t%u packet%s that failed verification received\n");
1027 	p(esps_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n");
1028 	p(esps_qfull, "\t%u packet%s were dropped due to full output queue\n");
1029 	p(esps_wrap, "\t%u packet%s where counter wrapping was detected\n");
1030 	p(esps_replay, "\t%u possibly replayed packet%s received\n");
1031 	p(esps_badilen, "\t%u packet%s with bad payload size or padding received\n");
1032 	p(esps_invalid, "\t%u packet%s attempted to use an invalid TDB\n");
1033 	p(esps_toobig, "\t%u packet%s got larger than max IP packet size\n");
1034 	p(esps_crypto, "\t%u packet%s that failed crypto processing\n");
1035 	p(esps_udpencin, "\t%u input UDP encapsulated ESP packet%s\n");
1036 	p(esps_udpencout, "\t%u output UDP encapsulated ESP packet%s\n");
1037 	p(esps_udpinval, "\t%u UDP packet%s for non-encapsulating TDB received\n");
1038 	p(esps_udpneeded, "\t%u raw ESP packet%s for encapsulating TDB received\n");
1039 	p(esps_ibytes, "\t%llu input byte%s\n");
1040 	p(esps_obytes, "\t%llu output byte%s\n");
1041 
1042 #undef p
1043 }
1044 
1045 /*
1046  * Dump IP-in-IP statistics structure.
1047  */
1048 void
1049 ipip_stats(char *name)
1050 {
1051 	struct ipipstat ipipstat;
1052 	int mib[] = { CTL_NET, PF_INET, IPPROTO_IPIP, IPIPCTL_STATS };
1053 	size_t len = sizeof(ipipstat);
1054 
1055 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
1056 	    &ipipstat, &len, NULL, 0) == -1) {
1057 		if (errno != ENOPROTOOPT)
1058 			warn("%s", name);
1059 		return;
1060 	}
1061 
1062 	printf("%s:\n", name);
1063 #define p(f, m) if (ipipstat.f || sflag <= 1) \
1064 	printf(m, ipipstat.f, plural(ipipstat.f))
1065 
1066 	p(ipips_ipackets, "\t%u total input packet%s\n");
1067 	p(ipips_opackets, "\t%u total output packet%s\n");
1068 	p(ipips_hdrops, "\t%u packet%s shorter than header shows\n");
1069 	p(ipips_pdrops, "\t%u packet%s dropped due to policy\n");
1070 	p(ipips_spoof, "\t%u packet%s with possibly spoofed local addresses\n");
1071 	p(ipips_qfull, "\t%u packet%s were dropped due to full output queue\n");
1072 	p(ipips_ibytes, "\t%llu input byte%s\n");
1073 	p(ipips_obytes, "\t%llu output byte%s\n");
1074 	p(ipips_family, "\t%u protocol family mismatche%s\n");
1075 	p(ipips_unspec, "\t%u attempt%s to use tunnel with unspecified endpoint(s)\n");
1076 #undef p
1077 }
1078 
1079 /*
1080  * Dump CARP statistics structure.
1081  */
1082 void
1083 carp_stats(char *name)
1084 {
1085 	struct carpstats carpstat;
1086 	int mib[] = { CTL_NET, PF_INET, IPPROTO_CARP, CARPCTL_STATS };
1087 	size_t len = sizeof(carpstat);
1088 
1089 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
1090 	    &carpstat, &len, NULL, 0) == -1) {
1091 		if (errno != ENOPROTOOPT)
1092 			warn("%s", name);
1093 		return;
1094 	}
1095 
1096 	printf("%s:\n", name);
1097 #define p(f, m) if (carpstat.f || sflag <= 1) \
1098 	printf(m, carpstat.f, plural(carpstat.f))
1099 #define p2(f, m) if (carpstat.f || sflag <= 1) \
1100 	printf(m, carpstat.f)
1101 
1102 	p(carps_ipackets, "\t%llu packet%s received (IPv4)\n");
1103 	p(carps_ipackets6, "\t%llu packet%s received (IPv6)\n");
1104 	p(carps_badif, "\t\t%llu packet%s discarded for bad interface\n");
1105 	p(carps_badttl, "\t\t%llu packet%s discarded for wrong TTL\n");
1106 	p(carps_hdrops, "\t\t%llu packet%s shorter than header\n");
1107 	p(carps_badsum, "\t\t%llu discarded for bad checksum%s\n");
1108 	p(carps_badver,	"\t\t%llu discarded packet%s with a bad version\n");
1109 	p2(carps_badlen, "\t\t%llu discarded because packet too short\n");
1110 	p2(carps_badauth, "\t\t%llu discarded for bad authentication\n");
1111 	p2(carps_badvhid, "\t\t%llu discarded for unknown vhid\n");
1112 	p2(carps_badaddrs, "\t\t%llu discarded because of a bad address list\n");
1113 	p(carps_opackets, "\t%llu packet%s sent (IPv4)\n");
1114 	p(carps_opackets6, "\t%llu packet%s sent (IPv6)\n");
1115 	p2(carps_onomem, "\t\t%llu send failed due to mbuf memory error\n");
1116 	p(carps_preempt, "\t%llu transition%s to master\n");
1117 #undef p
1118 #undef p2
1119 }
1120 
1121 /*
1122  * Dump pfsync statistics structure.
1123  */
1124 void
1125 pfsync_stats(char *name)
1126 {
1127 	struct pfsyncstats pfsyncstat;
1128 	int mib[] = { CTL_NET, PF_INET, IPPROTO_PFSYNC, PFSYNCCTL_STATS };
1129 	size_t len = sizeof(pfsyncstat);
1130 
1131 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
1132 	    &pfsyncstat, &len, NULL, 0) == -1) {
1133 		if (errno != ENOPROTOOPT)
1134 			warn("%s", name);
1135 		return;
1136 	}
1137 
1138 	printf("%s:\n", name);
1139 #define p(f, m) if (pfsyncstat.f || sflag <= 1) \
1140 	printf(m, pfsyncstat.f, plural(pfsyncstat.f))
1141 #define p2(f, m) if (pfsyncstat.f || sflag <= 1) \
1142 	printf(m, pfsyncstat.f)
1143 
1144 	p(pfsyncs_ipackets, "\t%llu packet%s received (IPv4)\n");
1145 	p(pfsyncs_ipackets6, "\t%llu packet%s received (IPv6)\n");
1146 	p(pfsyncs_badif, "\t\t%llu packet%s discarded for bad interface\n");
1147 	p(pfsyncs_badttl, "\t\t%llu packet%s discarded for bad ttl\n");
1148 	p(pfsyncs_hdrops, "\t\t%llu packet%s shorter than header\n");
1149 	p(pfsyncs_badver, "\t\t%llu packet%s discarded for bad version\n");
1150 	p(pfsyncs_badauth, "\t\t%llu packet%s discarded for bad HMAC\n");
1151 	p(pfsyncs_badact,"\t\t%llu packet%s discarded for bad action\n");
1152 	p(pfsyncs_badlen, "\t\t%llu packet%s discarded for short packet\n");
1153 	p(pfsyncs_badval, "\t\t%llu state%s discarded for bad values\n");
1154 	p(pfsyncs_stale, "\t\t%llu stale state%s\n");
1155 	p(pfsyncs_badstate, "\t\t%llu failed state lookup/insert%s\n");
1156 	p(pfsyncs_opackets, "\t%llu packet%s sent (IPv4)\n");
1157 	p(pfsyncs_opackets6, "\t%llu packet%s sent (IPv6)\n");
1158 	p2(pfsyncs_onomem, "\t\t%llu send failed due to mbuf memory error\n");
1159 	p2(pfsyncs_oerrors, "\t\t%llu send error\n");
1160 #undef p
1161 #undef p2
1162 }
1163 
1164 /*
1165  * Dump pflow statistics structure.
1166  */
1167 void
1168 pflow_stats(char *name)
1169 {
1170 	struct pflowstats flowstats;
1171 	int mib[] = { CTL_NET, PF_PFLOW, NET_PFLOW_STATS };
1172 	size_t len = sizeof(struct pflowstats);
1173 
1174 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &flowstats, &len,
1175 	    NULL, 0) == -1) {
1176 		if (errno != ENOPROTOOPT)
1177 			warn("%s", name);
1178 		return;
1179 	}
1180 
1181 	printf("%s:\n", name);
1182 #define p(f, m) if (flowstats.f || sflag <= 1) \
1183 	printf(m, flowstats.f, plural(flowstats.f))
1184 #define p2(f, m) if (flowstats.f || sflag <= 1) \
1185 	printf(m, flowstats.f)
1186 
1187 	p(pflow_flows, "\t%llu flow%s sent\n");
1188 	p(pflow_packets, "\t%llu packet%s sent\n");
1189 	p2(pflow_onomem, "\t\t%llu send failed due to mbuf memory error\n");
1190 	p2(pflow_oerrors, "\t\t%llu send error\n");
1191 #undef p
1192 #undef p2
1193 }
1194 
1195 /*
1196  * Dump IPCOMP statistics structure.
1197  */
1198 void
1199 ipcomp_stats(char *name)
1200 {
1201 	struct ipcompstat ipcompstat;
1202 	int mib[] = { CTL_NET, PF_INET, IPPROTO_IPCOMP, IPCOMPCTL_STATS };
1203 	size_t len = sizeof(ipcompstat);
1204 
1205 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
1206 	    &ipcompstat, &len, NULL, 0) == -1) {
1207 		if (errno != ENOPROTOOPT)
1208 			warn("%s", name);
1209 		return;
1210 	}
1211 
1212 	printf("%s:\n", name);
1213 #define p(f, m) if (ipcompstat.f || sflag <= 1) \
1214 	printf(m, ipcompstat.f, plural(ipcompstat.f))
1215 
1216 	p(ipcomps_input, "\t%u input IPCOMP packet%s\n");
1217 	p(ipcomps_output, "\t%u output IPCOMP packet%s\n");
1218 	p(ipcomps_nopf, "\t%u packet%s from unsupported protocol families\n");
1219 	p(ipcomps_hdrops, "\t%u packet%s shorter than header shows\n");
1220 	p(ipcomps_pdrops, "\t%u packet%s dropped due to policy\n");
1221 	p(ipcomps_notdb, "\t%u packet%s for which no TDB was found\n");
1222 	p(ipcomps_badkcr, "\t%u input packet%s that failed to be processed\n");
1223 	p(ipcomps_noxform, "\t%u packet%s for which no XFORM was set in TDB received\n");
1224 	p(ipcomps_qfull, "\t%u packet%s were dropped due to full output queue\n");
1225 	p(ipcomps_wrap, "\t%u packet%s where counter wrapping was detected\n");
1226 	p(ipcomps_invalid, "\t%u packet%s attempted to use an invalid TDB\n");
1227 	p(ipcomps_toobig, "\t%u packet%s got larger than max IP packet size\n");
1228 	p(ipcomps_crypto, "\t%u packet%s that failed (de)compression processing\n");
1229 	p(ipcomps_minlen, "\t%u packet%s less than minimum compression length\n");
1230 	p(ipcomps_ibytes, "\t%llu input byte%s\n");
1231 	p(ipcomps_obytes, "\t%llu output byte%s\n");
1232 
1233 #undef p
1234 }
1235 
1236 /*
1237  * Dump the contents of a socket structure
1238  */
1239 void
1240 socket_dump(u_long off)
1241 {
1242 	struct socket so;
1243 
1244 	if (off == 0)
1245 		return;
1246 	kread(off, &so, sizeof(so));
1247 
1248 #define	p(fmt, v, sep) printf(#v " " fmt sep, so.v);
1249 #define	pp(fmt, v, sep) printf(#v " " fmt sep, so.v);
1250 	printf("socket %#lx\n ", off);
1251 	p("%#.4x", so_type, "\n ");
1252 	p("%#.4x", so_options, "\n ");
1253 	p("%d", so_linger, "\n ");
1254 	p("%#.4x", so_state, "\n ");
1255 	pp("%p", so_pcb, ", ");
1256 	pp("%p", so_proto, ", ");
1257 	pp("%p", so_head, "\n ");
1258 	p("%d", so_q0len, ", ");
1259 	p("%d", so_qlen, ", ");
1260 	p("%d", so_qlimit, "\n ");
1261 	p("%d", so_timeo, "\n ");
1262 	p("%u", so_error, "\n ");
1263 	p("%d", so_pgid, ", ");
1264 	p("%u", so_siguid, ", ");
1265 	p("%u", so_sigeuid, "\n ");
1266 	p("%lu", so_oobmark, "\n ");
1267 	if (so.so_sp)
1268 		sosplice_dump((u_long)so.so_sp);
1269 	sockbuf_dump(&so.so_rcv, "so_rcv");
1270 	sockbuf_dump(&so.so_snd, "so_snd");
1271 	p("%u", so_euid, ", ");
1272 	p("%u", so_ruid, ", ");
1273 	p("%u", so_egid, ", ");
1274 	p("%u", so_rgid, "\n ");
1275 	p("%d", so_cpid, "\n");
1276 #undef	p
1277 #undef	pp
1278 
1279 	protosw_dump((u_long)so.so_proto, (u_long)so.so_pcb);
1280 }
1281 
1282 /*
1283  * Dump the contents of a struct sosplice
1284  */
1285 void
1286 sosplice_dump(u_long off)
1287 {
1288 	struct sosplice ssp;
1289 
1290 	if (off == 0)
1291 		return;
1292 	kread(off, &ssp, sizeof(ssp));
1293 
1294 #define	p(fmt, v, sep) printf(#v " " fmt sep, ssp.v);
1295 #define	pll(fmt, v, sep) printf(#v " " fmt sep, (long long) ssp.v);
1296 #define	pp(fmt, v, sep) printf(#v " " fmt sep, ssp.v);
1297 	pp("%p", ssp_socket, ", ");
1298 	pp("%p", ssp_soback, "\n ");
1299 	p("%lld", ssp_len, ", ");
1300 	p("%lld", ssp_max, ", ");
1301 	pll("%lld", ssp_idletv.tv_sec, ", ");
1302 	p("%ld", ssp_idletv.tv_usec, "\n ");
1303 #undef	p
1304 #undef	pll
1305 #undef	pp
1306 }
1307 
1308 /*
1309  * Dump the contents of a socket buffer
1310  */
1311 void
1312 sockbuf_dump(struct sockbuf *sb, const char *name)
1313 {
1314 #define	p(fmt, v, sep) printf(#v " " fmt sep, sb->v);
1315 	printf("%s ", name);
1316 	p("%lu", sb_cc, ", ");
1317 	p("%lu", sb_datacc, ", ");
1318 	p("%lu", sb_hiwat, ", ");
1319 	p("%lu", sb_wat, "\n ");
1320 	printf("%s ", name);
1321 	p("%lu", sb_mbcnt, ", ");
1322 	p("%lu", sb_mbmax, ", ");
1323 	p("%ld", sb_lowat, "\n ");
1324 	printf("%s ", name);
1325 	p("%#.8x", sb_flagsintr, ", ");
1326 	p("%#.4x", sb_flags, ", ");
1327 	p("%u", sb_timeo, "\n ");
1328 #undef	p
1329 }
1330 
1331 /*
1332  * Dump the contents of a protosw structure
1333  */
1334 void
1335 protosw_dump(u_long off, u_long pcb)
1336 {
1337 	struct protosw proto;
1338 
1339 	if (off == 0)
1340 		return;
1341 	kread(off, &proto, sizeof(proto));
1342 
1343 #define	p(fmt, v, sep) printf(#v " " fmt sep, proto.v);
1344 #define	pp(fmt, v, sep) printf(#v " " fmt sep, proto.v);
1345 	printf("protosw %#lx\n ", off);
1346 	p("%#.4x", pr_type, "\n ");
1347 	pp("%p", pr_domain, "\n ");
1348 	p("%d", pr_protocol, "\n ");
1349 	p("%#.4x", pr_flags, "\n");
1350 #undef	p
1351 #undef	pp
1352 
1353 	domain_dump((u_long)proto.pr_domain, pcb, proto.pr_protocol);
1354 }
1355 
1356 /*
1357  * Dump the contents of a domain structure
1358  */
1359 void
1360 domain_dump(u_long off, u_long pcb, short protocol)
1361 {
1362 	struct domain dom;
1363 	char name[256];
1364 
1365 	if (off == 0)
1366 		return;
1367 	kread(off, &dom, sizeof(dom));
1368 	kread((u_long)dom.dom_name, name, sizeof(name));
1369 
1370 #define	p(fmt, v, sep) printf(#v " " fmt sep, dom.v);
1371 	printf("domain %#lx\n ", off);
1372 	p("%d", dom_family, "\n ");
1373 	printf("dom_name %.*s\n", (int)sizeof(name), name);
1374 #undef	p
1375 }
1376 
1377 /*
1378  * Dump the contents of a internet PCB
1379  */
1380 void
1381 inpcb_dump(u_long off, short protocol, int af)
1382 {
1383 	struct inpcb inp;
1384 	char faddr[256], laddr[256], raddr[256];
1385 
1386 	if (off == 0)
1387 		return;
1388 	kread(off, &inp, sizeof(inp));
1389 
1390 	if (vflag)
1391 		socket_dump((u_long)inp.inp_socket);
1392 
1393 	switch (af) {
1394 	case AF_INET:
1395 		inet_ntop(af, &inp.inp_faddr, faddr, sizeof(faddr));
1396 		inet_ntop(af, &inp.inp_laddr, laddr, sizeof(laddr));
1397 		inet_ntop(af, &((struct sockaddr_in *)
1398 		    (&inp.inp_route.ro_dst))->sin_addr, raddr, sizeof(raddr));
1399 		break;
1400 	case AF_INET6:
1401 		inet_ntop(af, &inp.inp_faddr6, faddr, sizeof(faddr));
1402 		inet_ntop(af, &inp.inp_laddr6, laddr, sizeof(laddr));
1403 		inet_ntop(af, &inp.inp_route6.ro_dst.sin6_addr,
1404 		    raddr, sizeof(raddr));
1405 		break;
1406 	default:
1407 		faddr[0] = laddr[0] = '\0';
1408 	}
1409 
1410 #define	p(fmt, v, sep) printf(#v " " fmt sep, inp.v);
1411 #define	pp(fmt, v, sep) printf(#v " " fmt sep, inp.v);
1412 	printf("inpcb %#lx\n ", off);
1413 	pp("%p", inp_table, "\n ");
1414 	printf("inp_faddru %s, inp_laddru %s\n ", faddr, laddr);
1415 	HTONS(inp.inp_fport);
1416 	HTONS(inp.inp_lport);
1417 	p("%u", inp_fport, ", ");
1418 	p("%u", inp_lport, "\n ");
1419 	pp("%p", inp_socket, ", ");
1420 	pp("%p", inp_ppcb, "\n ");
1421 	pp("%p", inp_route.ro_rt, ", ");
1422 	printf("ro_dst %s\n ", raddr);
1423 	p("%#.8x", inp_flags, "\n ");
1424 	p("%d", inp_hops, "\n ");
1425 	p("%u", inp_seclevel[0], ", ");
1426 	p("%u", inp_seclevel[1], ", ");
1427 	p("%u", inp_seclevel[2], ", ");
1428 	p("%u", inp_seclevel[3], "\n ");
1429 	p("%u", inp_ip_minttl, "\n ");
1430 	p("%d", inp_cksum6, "\n ");
1431 	pp("%p", inp_icmp6filt, "\n ");
1432 	pp("%p", inp_pf_sk, "\n ");
1433 	p("%u", inp_rtableid, "\n ");
1434 	p("%d", inp_pipex, "\n");
1435 #undef	p
1436 #undef	pp
1437 
1438 	switch (protocol) {
1439 	case IPPROTO_TCP:
1440 		tcpcb_dump((u_long)inp.inp_ppcb);
1441 		break;
1442 	}
1443 }
1444 
1445 /*
1446  * Dump the contents of a TCP PCB
1447  */
1448 void
1449 tcpcb_dump(u_long off)
1450 {
1451 	struct tcpcb tcpcb;
1452 
1453 	if (off == 0)
1454 		return;
1455 	kread(off, (char *)&tcpcb, sizeof (tcpcb));
1456 
1457 #define	p(fmt, v, sep) printf(#v " " fmt sep, tcpcb.v);
1458 #define	pp(fmt, v, sep) printf(#v " " fmt sep, tcpcb.v);
1459 	printf("tcpcb %#lx\n ", off);
1460 	pp("%p", t_inpcb, "\n ");
1461 	p("%d", t_state, "");
1462 	if (tcpcb.t_state >= 0 && tcpcb.t_state < TCP_NSTATES)
1463 		printf(" (%s)", tcpstates[tcpcb.t_state]);
1464 	printf("\n ");
1465 	p("%d", t_rxtshift, ", ");
1466 	p("%d", t_rxtcur, ", ");
1467 	p("%d", t_dupacks, "\n ");
1468 	p("%u", t_maxseg, ", ");
1469 	p("%u", t_maxopd, ", ");
1470 	p("%u", t_peermss, "\n ");
1471 	p("0x%x", t_flags, ", ");
1472 	p("%u", t_force, "\n ");
1473 	p("%u", iss, "\n ");
1474 	p("%u", snd_una, ", ");
1475 	p("%u", snd_nxt, ", ");
1476 	p("%u", snd_up, "\n ");
1477 	p("%u", snd_wl1, ", ");
1478 	p("%u", snd_wl2, ", ");
1479 	p("%lu", snd_wnd, "\n ");
1480 	p("%d", sack_enable, ", ");
1481 	p("%d", snd_numholes, ", ");
1482 	p("%u", snd_fack, ", ");
1483 	p("%lu",snd_awnd, "\n ");
1484 	p("%u", retran_data, ", ");
1485 	p("%u", snd_last, "\n ");
1486 	p("%u", irs, "\n ");
1487 	p("%u", rcv_nxt, ", ");
1488 	p("%u", rcv_up, ", ");
1489 	p("%lu", rcv_wnd, "\n ");
1490 	p("%u", rcv_lastsack, "\n ");
1491 	p("%d", rcv_numsacks, "\n ");
1492 	p("%u", rcv_adv, ", ");
1493 	p("%u", snd_max, "\n ");
1494 	p("%lu", snd_cwnd, ", ");
1495 	p("%lu", snd_ssthresh, ", ");
1496 	p("%lu", max_sndwnd, "\n ");
1497 	p("%u", t_rcvtime, ", ");
1498 	p("%u", t_rtttime, ", ");
1499 	p("%u", t_rtseq, "\n ");
1500 	p("%u", t_srtt, ", ");
1501 	p("%u", t_rttvar, ", ");
1502 	p("%u", t_rttmin, "\n ");
1503 	p("%u", t_oobflags, ", ");
1504 	p("%u", t_iobc, "\n ");
1505 	p("%u", t_softerror, "\n ");
1506 	p("%u", snd_scale, ", ");
1507 	p("%u", rcv_scale, ", ");
1508 	p("%u", request_r_scale, ", ");
1509 	p("%u", requested_s_scale, "\n ");
1510 	p("%u", ts_recent, ", ");
1511 	p("%u", ts_recent_age, "\n ");
1512 	p("%u", last_ack_sent, "\n ");
1513 	HTONS(tcpcb.t_pmtud_ip_len);
1514 	HTONS(tcpcb.t_pmtud_nextmtu);
1515 	p("%u", t_pmtud_mss_acked, ", ");
1516 	p("%u", t_pmtud_mtu_sent, "\n ");
1517 	p("%u", t_pmtud_nextmtu, ", ");
1518 	p("%u", t_pmtud_ip_len, ", ");
1519 	p("%u", t_pmtud_ip_hl, "\n ");
1520 	p("%u", t_pmtud_th_seq, "\n ");
1521 	p("%u", pf, "\n");
1522 #undef	p
1523 #undef	pp
1524 }
1525