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