xref: /netbsd-src/usr.bin/netstat/inet.c (revision 88fcb00c0357f2d7c1774f86a352637bfda96184)
1 /*	$NetBSD: inet.c,v 1.99 2011/05/11 22:21:59 dyoung Exp $	*/
2 
3 /*
4  * Copyright (c) 1983, 1988, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "from: @(#)inet.c	8.4 (Berkeley) 4/20/94";
36 #else
37 __RCSID("$NetBSD: inet.c,v 1.99 2011/05/11 22:21:59 dyoung Exp $");
38 #endif
39 #endif /* not lint */
40 
41 #define	_CALLOUT_PRIVATE	/* for defs in sys/callout.h */
42 
43 #include <sys/param.h>
44 #include <sys/queue.h>
45 #include <sys/socket.h>
46 #include <sys/socketvar.h>
47 #include <sys/mbuf.h>
48 #include <sys/protosw.h>
49 #include <sys/sysctl.h>
50 
51 #include <net/if_arp.h>
52 #include <net/route.h>
53 #include <netinet/in.h>
54 #include <netinet/in_systm.h>
55 #include <netinet/ip.h>
56 #include <netinet/in_pcb.h>
57 #include <netinet/ip_icmp.h>
58 
59 #ifdef INET6
60 #include <netinet/ip6.h>
61 #endif
62 
63 #include <netinet/icmp_var.h>
64 #include <netinet/igmp_var.h>
65 #include <netinet/ip_var.h>
66 #include <netinet/pim_var.h>
67 #include <netinet/tcp.h>
68 #include <netinet/tcpip.h>
69 #include <netinet/tcp_seq.h>
70 #define TCPSTATES
71 #include <netinet/tcp_fsm.h>
72 #define	TCPTIMERS
73 #include <netinet/tcp_timer.h>
74 #include <netinet/tcp_var.h>
75 #include <netinet/tcp_debug.h>
76 #include <netinet/udp.h>
77 #include <netinet/ip_carp.h>
78 #include <netinet/udp_var.h>
79 #include <netinet/tcp_vtw.h>
80 
81 #include <arpa/inet.h>
82 #include <kvm.h>
83 #include <netdb.h>
84 #include <stdio.h>
85 #include <string.h>
86 #include <unistd.h>
87 #include <stdlib.h>
88 #include <err.h>
89 #include "netstat.h"
90 #include "vtw.h"
91 #include "prog_ops.h"
92 
93 char	*inetname(struct in_addr *);
94 void	inetprint(struct in_addr *, u_int16_t, const char *, int);
95 
96 void	print_vtw_v4(const vtw_t *);
97 
98 /*
99  * Print a summary of connections related to an Internet
100  * protocol.  For TCP, also give state of connection.
101  * Listening processes (aflag) are suppressed unless the
102  * -a (all) flag is specified.
103  */
104 static int width;
105 static int compact;
106 
107 /* VTW-related variables. */
108 static struct timeval now;
109 
110 static void
111 protoprhdr(void)
112 {
113 	printf("Active Internet connections");
114 	if (aflag)
115 		printf(" (including servers)");
116 	putchar('\n');
117 	if (Aflag)
118 		printf("%-8.8s ", "PCB");
119 	printf(
120 	    Vflag ? "%-5.5s %-6.6s %-6.6s %s%-*.*s %-*.*s %-13.13s Expires\n"
121 	          : "%-5.5s %-6.6s %-6.6s %s%-*.*s %-*.*s %s\n",
122 		"Proto", "Recv-Q", "Send-Q", compact ? "" : " ",
123 		width, width, "Local Address",
124 		width, width, "Foreign Address",
125 		"State");
126 }
127 
128 static void
129 protopr0(intptr_t ppcb, u_long rcv_sb_cc, u_long snd_sb_cc,
130 	 struct in_addr *laddr, u_int16_t lport,
131 	 struct in_addr *faddr, u_int16_t fport,
132 	 short t_state, const char *name, int inp_flags,
133 	 const struct timeval *expires)
134 {
135 	static const char *shorttcpstates[] = {
136 		"CLOSED",	"LISTEN",	"SYNSEN",	"SYSRCV",
137 		"ESTABL",	"CLWAIT",	"FWAIT1",	"CLOSNG",
138 		"LASTAK",	"FWAIT2",	"TMWAIT",
139 	};
140 	int istcp;
141 
142 	istcp = strcmp(name, "tcp") == 0;
143 
144 	if (Aflag) {
145 		printf("%8" PRIxPTR " ", ppcb);
146 	}
147 	printf("%-5.5s %6ld %6ld%s", name, rcv_sb_cc, snd_sb_cc,
148 	       compact ? "" : " ");
149 	if (numeric_port) {
150 		inetprint(laddr, lport, name, 1);
151 		inetprint(faddr, fport, name, 1);
152 	} else if (inp_flags & INP_ANONPORT) {
153 		inetprint(laddr, lport, name, 1);
154 		inetprint(faddr, fport, name, 0);
155 	} else {
156 		inetprint(laddr, lport, name, 0);
157 		inetprint(faddr, fport, name, 0);
158 	}
159 	if (istcp) {
160 		if (t_state < 0 || t_state >= TCP_NSTATES)
161 			printf(" %d", t_state);
162 		else
163 			printf(" %s", compact ? shorttcpstates[t_state] :
164 			       tcpstates[t_state]);
165 	}
166 	if (Vflag && expires != NULL) {
167 		if (expires->tv_sec == 0 && expires->tv_usec == -1)
168 			printf(" reclaimed");
169 		else {
170 			struct timeval delta;
171 
172 			timersub(expires, &now, &delta);
173 			printf(" %.3fms",
174 			    delta.tv_sec * 1000.0 + delta.tv_usec / 1000.0);
175 		}
176 	}
177 	putchar('\n');
178 }
179 
180 static void
181 dbg_printf(const char *fmt, ...)
182 {
183 	return;
184 }
185 
186 void
187 print_vtw_v4(const vtw_t *vtw)
188 {
189 	const vtw_v4_t *v4 = (const vtw_v4_t *)vtw;
190 	struct timeval delta;
191 	struct in_addr la, fa;
192 	char buf[2][32];
193 	static const struct timeval zero = {.tv_sec = 0, .tv_usec = 0};
194 
195 	la.s_addr = v4->laddr;
196 	fa.s_addr = v4->faddr;
197 
198 	snprintf(&buf[0][0], 32, "%s", inet_ntoa(la));
199 	snprintf(&buf[1][0], 32, "%s", inet_ntoa(fa));
200 
201 	timersub(&vtw->expire, &now, &delta);
202 
203 	if (vtw->expire.tv_sec == 0 && vtw->expire.tv_usec == -1) {
204 		dbg_printf("%15.15s:%d %15.15s:%d reclaimed\n"
205 		    ,buf[0], ntohs(v4->lport)
206 		    ,buf[1], ntohs(v4->fport));
207 		if (!(Vflag && vflag))
208 			return;
209 	} else if (vtw->expire.tv_sec == 0)
210 		return;
211 	else if (timercmp(&delta, &zero, <) && !(Vflag && vflag)) {
212 		dbg_printf("%15.15s:%d %15.15s:%d expired\n"
213 		    ,buf[0], ntohs(v4->lport)
214 		    ,buf[1], ntohs(v4->fport));
215 		return;
216 	} else {
217 		dbg_printf("%15.15s:%d %15.15s:%d expires in %.3fms\n"
218 		    ,buf[0], ntohs(v4->lport)
219 		    ,buf[1], ntohs(v4->fport)
220 		    ,delta.tv_sec * 1000.0 + delta.tv_usec / 1000.0);
221 	}
222 	protopr0(0, 0, 0,
223 		 &la, v4->lport,
224 		 &fa, v4->fport,
225 		 TCPS_TIME_WAIT, "tcp", 0, &vtw->expire);
226 }
227 
228 void
229 protopr(u_long off, const char *name)
230 {
231 	struct inpcbtable table;
232 	struct inpcb *head, *next, *prev;
233 	struct inpcb inpcb;
234 	struct tcpcb tcpcb;
235 	struct socket sockb;
236 	int istcp = strcmp(name, "tcp") == 0;
237 	static int first = 1;
238 
239 	compact = 0;
240 	if (Aflag) {
241 		if (!numeric_addr)
242 			width = 18;
243 		else {
244 			width = 21;
245 			compact = 1;
246 		}
247 	} else
248 		width = 22;
249 
250 	if (use_sysctl) {
251 		struct kinfo_pcb *pcblist;
252 		int mib[8];
253 		size_t namelen = 0, size = 0, i;
254 		char *mibname = NULL;
255 
256 		memset(mib, 0, sizeof(mib));
257 
258 		if (asprintf(&mibname, "net.inet.%s.pcblist", name) == -1)
259 			err(1, "asprintf");
260 
261 		/* get dynamic pcblist node */
262 		if (sysctlnametomib(mibname, mib, &namelen) == -1)
263 			err(1, "sysctlnametomib: %s", mibname);
264 
265 		if (prog_sysctl(mib, __arraycount(mib),
266 		    NULL, &size, NULL, 0) == -1)
267 			err(1, "sysctl (query)");
268 
269 		if ((pcblist = malloc(size)) == NULL)
270 			err(1, "malloc");
271 		memset(pcblist, 0, size);
272 
273 	        mib[6] = sizeof(*pcblist);
274         	mib[7] = size / sizeof(*pcblist);
275 
276 		if (prog_sysctl(mib, __arraycount(mib),
277 		    pcblist, &size, NULL, 0) == -1)
278 			err(1, "sysctl (copy)");
279 
280 		for (i = 0; i < size / sizeof(*pcblist); i++) {
281 			struct sockaddr_in src, dst;
282 
283 			memcpy(&src, &pcblist[i].ki_s, sizeof(src));
284 			memcpy(&dst, &pcblist[i].ki_d, sizeof(dst));
285 
286 			if (!aflag &&
287 			    inet_lnaof(dst.sin_addr) == INADDR_ANY)
288 				continue;
289 
290 			if (first) {
291 				protoprhdr();
292 				first = 0;
293 			}
294 
295 	                protopr0((intptr_t) pcblist[i].ki_ppcbaddr,
296 				 pcblist[i].ki_rcvq, pcblist[i].ki_sndq,
297 				 &src.sin_addr, src.sin_port,
298 				 &dst.sin_addr, dst.sin_port,
299 				 pcblist[i].ki_tstate, name,
300 				 pcblist[i].ki_pflags, NULL);
301 		}
302 
303 		free(pcblist);
304 		goto end;
305 	}
306 
307 	if (off == 0)
308 		return;
309 	kread(off, (char *)&table, sizeof table);
310 	prev = head =
311 	    (struct inpcb *)&((struct inpcbtable *)off)->inpt_queue.cqh_first;
312 	next = (struct inpcb *)table.inpt_queue.cqh_first;
313 
314 	while (next != head) {
315 		kread((u_long)next, (char *)&inpcb, sizeof inpcb);
316 		if ((struct inpcb *)inpcb.inp_queue.cqe_prev != prev) {
317 			printf("???\n");
318 			break;
319 		}
320 		prev = next;
321 		next = (struct inpcb *)inpcb.inp_queue.cqe_next;
322 
323 		if (inpcb.inp_af != AF_INET)
324 			continue;
325 
326 		if (!aflag &&
327 		    inet_lnaof(inpcb.inp_faddr) == INADDR_ANY)
328 			continue;
329 		kread((u_long)inpcb.inp_socket, (char *)&sockb, sizeof (sockb));
330 		if (istcp) {
331 			kread((u_long)inpcb.inp_ppcb,
332 			    (char *)&tcpcb, sizeof (tcpcb));
333 		}
334 
335 		if (first) {
336 			protoprhdr();
337 			first = 0;
338 		}
339 
340 		protopr0(istcp ? (intptr_t) inpcb.inp_ppcb : (intptr_t) prev,
341 			 sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc,
342 			 &inpcb.inp_laddr, inpcb.inp_lport,
343 			 &inpcb.inp_faddr, inpcb.inp_fport,
344 			 tcpcb.t_state, name, inpcb.inp_flags, NULL);
345 	}
346 end:
347 	if (istcp) {
348 		struct timeval t;
349 		timebase(&t);
350 		gettimeofday(&now, NULL);
351 		timersub(&now, &t, &now);
352 		show_vtw_v4(print_vtw_v4);
353 	}
354 }
355 
356 /*
357  * Dump TCP statistics structure.
358  */
359 void
360 tcp_stats(u_long off, const char *name)
361 {
362 	uint64_t tcpstat[TCP_NSTATS];
363 
364 	if (use_sysctl) {
365 		size_t size = sizeof(tcpstat);
366 
367 		if (sysctlbyname("net.inet.tcp.stats", tcpstat, &size,
368 				 NULL, 0) == -1)
369 			return;
370 	} else {
371 		warnx("%s stats not available via KVM.", name);
372 		return;
373 	}
374 
375 	printf ("%s:\n", name);
376 
377 #define	ps(f, m) if (tcpstat[f] || sflag <= 1) \
378     printf(m, tcpstat[f])
379 #define	p(f, m) if (tcpstat[f] || sflag <= 1) \
380     printf(m, tcpstat[f], plural(tcpstat[f]))
381 #define	p2(f1, f2, m) if (tcpstat[f1] || tcpstat[f2] || sflag <= 1) \
382     printf(m, tcpstat[f1], plural(tcpstat[f1]), \
383     tcpstat[f2], plural(tcpstat[f2]))
384 #define	p2s(f1, f2, m) if (tcpstat[f1] || tcpstat[f2] || sflag <= 1) \
385     printf(m, tcpstat[f1], plural(tcpstat[f1]), \
386     tcpstat[f2])
387 #define	p3(f, m) if (tcpstat[f] || sflag <= 1) \
388     printf(m, tcpstat[f], plurales(tcpstat[f]))
389 
390 	p(TCP_STAT_SNDTOTAL, "\t%" PRIu64 " packet%s sent\n");
391 	p2(TCP_STAT_SNDPACK,TCP_STAT_SNDBYTE,
392 		"\t\t%" PRIu64 " data packet%s (%" PRIu64 " byte%s)\n");
393 	p2(TCP_STAT_SNDREXMITPACK, TCP_STAT_SNDREXMITBYTE,
394 		"\t\t%" PRIu64 " data packet%s (%" PRIu64 " byte%s) retransmitted\n");
395 	p2s(TCP_STAT_SNDACKS, TCP_STAT_DELACK,
396 		"\t\t%" PRIu64 " ack-only packet%s (%" PRIu64 " delayed)\n");
397 	p(TCP_STAT_SNDURG, "\t\t%" PRIu64 " URG only packet%s\n");
398 	p(TCP_STAT_SNDPROBE, "\t\t%" PRIu64 " window probe packet%s\n");
399 	p(TCP_STAT_SNDWINUP, "\t\t%" PRIu64 " window update packet%s\n");
400 	p(TCP_STAT_SNDCTRL, "\t\t%" PRIu64 " control packet%s\n");
401 	p(TCP_STAT_SELFQUENCH,
402 	    "\t\t%" PRIu64 " send attempt%s resulted in self-quench\n");
403 	p(TCP_STAT_RCVTOTAL, "\t%" PRIu64 " packet%s received\n");
404 	p2(TCP_STAT_RCVACKPACK, TCP_STAT_RCVACKBYTE,
405 		"\t\t%" PRIu64 " ack%s (for %" PRIu64 " byte%s)\n");
406 	p(TCP_STAT_RCVDUPACK, "\t\t%" PRIu64 " duplicate ack%s\n");
407 	p(TCP_STAT_RCVACKTOOMUCH, "\t\t%" PRIu64 " ack%s for unsent data\n");
408 	p2(TCP_STAT_RCVPACK, TCP_STAT_RCVBYTE,
409 		"\t\t%" PRIu64 " packet%s (%" PRIu64 " byte%s) received in-sequence\n");
410 	p2(TCP_STAT_RCVDUPPACK, TCP_STAT_RCVDUPBYTE,
411 		"\t\t%" PRIu64 " completely duplicate packet%s (%" PRIu64 " byte%s)\n");
412 	p(TCP_STAT_PAWSDROP, "\t\t%" PRIu64 " old duplicate packet%s\n");
413 	p2(TCP_STAT_RCVPARTDUPPACK, TCP_STAT_RCVPARTDUPBYTE,
414 		"\t\t%" PRIu64 " packet%s with some dup. data (%" PRIu64 " byte%s duped)\n");
415 	p2(TCP_STAT_RCVOOPACK, TCP_STAT_RCVOOBYTE,
416 		"\t\t%" PRIu64 " out-of-order packet%s (%" PRIu64 " byte%s)\n");
417 	p2(TCP_STAT_RCVPACKAFTERWIN, TCP_STAT_RCVBYTEAFTERWIN,
418 		"\t\t%" PRIu64 " packet%s (%" PRIu64 " byte%s) of data after window\n");
419 	p(TCP_STAT_RCVWINPROBE, "\t\t%" PRIu64 " window probe%s\n");
420 	p(TCP_STAT_RCVWINUPD, "\t\t%" PRIu64 " window update packet%s\n");
421 	p(TCP_STAT_RCVAFTERCLOSE, "\t\t%" PRIu64 " packet%s received after close\n");
422 	p(TCP_STAT_RCVBADSUM, "\t\t%" PRIu64 " discarded for bad checksum%s\n");
423 	p(TCP_STAT_RCVBADOFF, "\t\t%" PRIu64 " discarded for bad header offset field%s\n");
424 	ps(TCP_STAT_RCVSHORT, "\t\t%" PRIu64 " discarded because packet too short\n");
425 	p(TCP_STAT_CONNATTEMPT, "\t%" PRIu64 " connection request%s\n");
426 	p(TCP_STAT_ACCEPTS, "\t%" PRIu64 " connection accept%s\n");
427 	p(TCP_STAT_CONNECTS,
428 		"\t%" PRIu64 " connection%s established (including accepts)\n");
429 	p2(TCP_STAT_CLOSED, TCP_STAT_DROPS,
430 		"\t%" PRIu64 " connection%s closed (including %" PRIu64 " drop%s)\n");
431 	p(TCP_STAT_CONNDROPS, "\t%" PRIu64 " embryonic connection%s dropped\n");
432 	p(TCP_STAT_DELAYED_FREE, "\t%" PRIu64 " delayed free%s of tcpcb\n");
433 	p2(TCP_STAT_RTTUPDATED, TCP_STAT_SEGSTIMED,
434 		"\t%" PRIu64 " segment%s updated rtt (of %" PRIu64 " attempt%s)\n");
435 	p(TCP_STAT_REXMTTIMEO, "\t%" PRIu64 " retransmit timeout%s\n");
436 	p(TCP_STAT_TIMEOUTDROP,
437 		"\t\t%" PRIu64 " connection%s dropped by rexmit timeout\n");
438 	p2(TCP_STAT_PERSISTTIMEO, TCP_STAT_PERSISTDROPS,
439 	   "\t%" PRIu64 " persist timeout%s (resulting in %" PRIu64 " dropped "
440 		"connection%s)\n");
441 	p(TCP_STAT_KEEPTIMEO, "\t%" PRIu64 " keepalive timeout%s\n");
442 	p(TCP_STAT_KEEPPROBE, "\t\t%" PRIu64 " keepalive probe%s sent\n");
443 	p(TCP_STAT_KEEPDROPS, "\t\t%" PRIu64 " connection%s dropped by keepalive\n");
444 	p(TCP_STAT_PREDACK, "\t%" PRIu64 " correct ACK header prediction%s\n");
445 	p(TCP_STAT_PREDDAT, "\t%" PRIu64 " correct data packet header prediction%s\n");
446 	p3(TCP_STAT_PCBHASHMISS, "\t%" PRIu64 " PCB hash miss%s\n");
447 	ps(TCP_STAT_NOPORT, "\t%" PRIu64 " dropped due to no socket\n");
448 	p(TCP_STAT_CONNSDRAINED, "\t%" PRIu64 " connection%s drained due to memory "
449 		"shortage\n");
450 	p(TCP_STAT_PMTUBLACKHOLE, "\t%" PRIu64 " PMTUD blackhole%s detected\n");
451 
452 	p(TCP_STAT_BADSYN, "\t%" PRIu64 " bad connection attempt%s\n");
453 	ps(TCP_STAT_SC_ADDED, "\t%" PRIu64 " SYN cache entries added\n");
454 	p(TCP_STAT_SC_COLLISIONS, "\t\t%" PRIu64 " hash collision%s\n");
455 	ps(TCP_STAT_SC_COMPLETED, "\t\t%" PRIu64 " completed\n");
456 	ps(TCP_STAT_SC_ABORTED, "\t\t%" PRIu64 " aborted (no space to build PCB)\n");
457 	ps(TCP_STAT_SC_TIMED_OUT, "\t\t%" PRIu64 " timed out\n");
458 	ps(TCP_STAT_SC_OVERFLOWED, "\t\t%" PRIu64 " dropped due to overflow\n");
459 	ps(TCP_STAT_SC_BUCKETOVERFLOW, "\t\t%" PRIu64 " dropped due to bucket overflow\n");
460 	ps(TCP_STAT_SC_RESET, "\t\t%" PRIu64 " dropped due to RST\n");
461 	ps(TCP_STAT_SC_UNREACH, "\t\t%" PRIu64 " dropped due to ICMP unreachable\n");
462 	ps(TCP_STAT_SC_DELAYED_FREE, "\t\t%" PRIu64 " delayed free of SYN cache "
463 		"entries\n");
464 	p(TCP_STAT_SC_RETRANSMITTED, "\t%" PRIu64 " SYN,ACK%s retransmitted\n");
465 	p(TCP_STAT_SC_DUPESYN, "\t%" PRIu64 " duplicate SYN%s received for entries "
466 		"already in the cache\n");
467 	p(TCP_STAT_SC_DROPPED, "\t%" PRIu64 " SYN%s dropped (no route or no space)\n");
468 	p(TCP_STAT_BADSIG, "\t%" PRIu64 " packet%s with bad signature\n");
469 	p(TCP_STAT_GOODSIG, "\t%" PRIu64 " packet%s with good signature\n");
470 
471 	p(TCP_STAT_ECN_SHS, "\t%" PRIu64 " successful ECN handshake%s\n");
472 	p(TCP_STAT_ECN_CE, "\t%" PRIu64 " packet%s with ECN CE bit\n");
473 	p(TCP_STAT_ECN_ECT, "\t%" PRIu64 " packet%s ECN ECT(0) bit\n");
474 #undef p
475 #undef ps
476 #undef p2
477 #undef p2s
478 #undef p3
479 	show_vtw_stats();
480 }
481 
482 /*
483  * Dump UDP statistics structure.
484  */
485 void
486 udp_stats(u_long off, const char *name)
487 {
488 	uint64_t udpstat[UDP_NSTATS];
489 	u_quad_t delivered;
490 
491 	if (use_sysctl) {
492 		size_t size = sizeof(udpstat);
493 
494 		if (sysctlbyname("net.inet.udp.stats", udpstat, &size,
495 				 NULL, 0) == -1)
496 			return;
497 	} else {
498 		warnx("%s stats not available via KVM.", name);
499 		return;
500 	}
501 
502 	printf ("%s:\n", name);
503 
504 #define	ps(f, m) if (udpstat[f] || sflag <= 1) \
505     printf(m, udpstat[f])
506 #define	p(f, m) if (udpstat[f] || sflag <= 1) \
507     printf(m, udpstat[f], plural(udpstat[f]))
508 #define	p3(f, m) if (udpstat[f] || sflag <= 1) \
509     printf(m, udpstat[f], plurales(udpstat[f]))
510 
511 	p(UDP_STAT_IPACKETS, "\t%" PRIu64 " datagram%s received\n");
512 	ps(UDP_STAT_HDROPS, "\t%" PRIu64 " with incomplete header\n");
513 	ps(UDP_STAT_BADLEN, "\t%" PRIu64 " with bad data length field\n");
514 	ps(UDP_STAT_BADSUM, "\t%" PRIu64 " with bad checksum\n");
515 	ps(UDP_STAT_NOPORT, "\t%" PRIu64 " dropped due to no socket\n");
516 	p(UDP_STAT_NOPORTBCAST,
517 	  "\t%" PRIu64 " broadcast/multicast datagram%s dropped due to no socket\n");
518 	ps(UDP_STAT_FULLSOCK, "\t%" PRIu64 " dropped due to full socket buffers\n");
519 	delivered = udpstat[UDP_STAT_IPACKETS] -
520 		    udpstat[UDP_STAT_HDROPS] -
521 		    udpstat[UDP_STAT_BADLEN] -
522 		    udpstat[UDP_STAT_BADSUM] -
523 		    udpstat[UDP_STAT_NOPORT] -
524 		    udpstat[UDP_STAT_NOPORTBCAST] -
525 		    udpstat[UDP_STAT_FULLSOCK];
526 	if (delivered || sflag <= 1)
527 		printf("\t%" PRIu64 " delivered\n", delivered);
528 	p3(UDP_STAT_PCBHASHMISS, "\t%" PRIu64 " PCB hash miss%s\n");
529 	p(UDP_STAT_OPACKETS, "\t%" PRIu64 " datagram%s output\n");
530 
531 #undef ps
532 #undef p
533 #undef p3
534 }
535 
536 /*
537  * Dump IP statistics structure.
538  */
539 void
540 ip_stats(u_long off, const char *name)
541 {
542 	uint64_t ipstat[IP_NSTATS];
543 
544 	if (use_sysctl) {
545 		size_t size = sizeof(ipstat);
546 
547 		if (sysctlbyname("net.inet.ip.stats", ipstat, &size,
548 				 NULL, 0) == -1)
549 			return;
550 	} else {
551 		warnx("%s stats not available via KVM.", name);
552 		return;
553 	}
554 
555 	printf("%s:\n", name);
556 
557 #define	ps(f, m) if (ipstat[f] || sflag <= 1) \
558     printf(m, ipstat[f])
559 #define	p(f, m) if (ipstat[f] || sflag <= 1) \
560     printf(m, ipstat[f], plural(ipstat[f]))
561 
562 	p(IP_STAT_TOTAL, "\t%" PRIu64 " total packet%s received\n");
563 	p(IP_STAT_BADSUM, "\t%" PRIu64 " bad header checksum%s\n");
564 	ps(IP_STAT_TOOSMALL, "\t%" PRIu64 " with size smaller than minimum\n");
565 	ps(IP_STAT_TOOSHORT, "\t%" PRIu64 " with data size < data length\n");
566 	ps(IP_STAT_TOOLONG, "\t%" PRIu64 " with length > max ip packet size\n");
567 	ps(IP_STAT_BADHLEN, "\t%" PRIu64 " with header length < data size\n");
568 	ps(IP_STAT_BADLEN, "\t%" PRIu64 " with data length < header length\n");
569 	ps(IP_STAT_BADOPTIONS, "\t%" PRIu64 " with bad options\n");
570 	ps(IP_STAT_BADVERS, "\t%" PRIu64 " with incorrect version number\n");
571 	p(IP_STAT_FRAGMENTS, "\t%" PRIu64 " fragment%s received\n");
572 	p(IP_STAT_FRAGDROPPED, "\t%" PRIu64 " fragment%s dropped (dup or out of space)\n");
573 	p(IP_STAT_RCVMEMDROP, "\t%" PRIu64 " fragment%s dropped (out of ipqent)\n");
574 	p(IP_STAT_BADFRAGS, "\t%" PRIu64 " malformed fragment%s dropped\n");
575 	p(IP_STAT_FRAGTIMEOUT, "\t%" PRIu64 " fragment%s dropped after timeout\n");
576 	p(IP_STAT_REASSEMBLED, "\t%" PRIu64 " packet%s reassembled ok\n");
577 	p(IP_STAT_DELIVERED, "\t%" PRIu64 " packet%s for this host\n");
578 	p(IP_STAT_NOPROTO, "\t%" PRIu64 " packet%s for unknown/unsupported protocol\n");
579 	p(IP_STAT_FORWARD, "\t%" PRIu64 " packet%s forwarded");
580 	p(IP_STAT_FASTFORWARD, " (%" PRIu64 " packet%s fast forwarded)");
581 	if (ipstat[IP_STAT_FORWARD] || sflag <= 1)
582 		putchar('\n');
583 	p(IP_STAT_CANTFORWARD, "\t%" PRIu64 " packet%s not forwardable\n");
584 	p(IP_STAT_REDIRECTSENT, "\t%" PRIu64 " redirect%s sent\n");
585 	p(IP_STAT_NOGIF, "\t%" PRIu64 " packet%s no matching gif found\n");
586 	p(IP_STAT_LOCALOUT, "\t%" PRIu64 " packet%s sent from this host\n");
587 	p(IP_STAT_RAWOUT, "\t%" PRIu64 " packet%s sent with fabricated ip header\n");
588 	p(IP_STAT_ODROPPED, "\t%" PRIu64 " output packet%s dropped due to no bufs, etc.\n");
589 	p(IP_STAT_NOROUTE, "\t%" PRIu64 " output packet%s discarded due to no route\n");
590 	p(IP_STAT_FRAGMENTED, "\t%" PRIu64 " output datagram%s fragmented\n");
591 	p(IP_STAT_OFRAGMENTS, "\t%" PRIu64 " fragment%s created\n");
592 	p(IP_STAT_CANTFRAG, "\t%" PRIu64 " datagram%s that can't be fragmented\n");
593 	p(IP_STAT_BADADDR, "\t%" PRIu64 " datagram%s with bad address in header\n");
594 #undef ps
595 #undef p
596 }
597 
598 static	const char *icmpnames[] = {
599 	"echo reply",
600 	"#1",
601 	"#2",
602 	"destination unreachable",
603 	"source quench",
604 	"routing redirect",
605 	"alternate host address",
606 	"#7",
607 	"echo",
608 	"router advertisement",
609 	"router solicitation",
610 	"time exceeded",
611 	"parameter problem",
612 	"time stamp",
613 	"time stamp reply",
614 	"information request",
615 	"information request reply",
616 	"address mask request",
617 	"address mask reply",
618 };
619 
620 /*
621  * Dump ICMP statistics.
622  */
623 void
624 icmp_stats(u_long off, const char *name)
625 {
626 	uint64_t icmpstat[ICMP_NSTATS];
627 	int i, first;
628 
629 	if (use_sysctl) {
630 		size_t size = sizeof(icmpstat);
631 
632 		if (sysctlbyname("net.inet.icmp.stats", icmpstat, &size,
633 				 NULL, 0) == -1)
634 			return;
635 	} else {
636 		warnx("%s stats not available via KVM.", name);
637 		return;
638 	}
639 
640 	printf("%s:\n", name);
641 
642 #define	p(f, m) if (icmpstat[f] || sflag <= 1) \
643     printf(m, icmpstat[f], plural(icmpstat[f]))
644 
645 	p(ICMP_STAT_ERROR, "\t%" PRIu64 " call%s to icmp_error\n");
646 	p(ICMP_STAT_OLDICMP,
647 	    "\t%" PRIu64 " error%s not generated because old message was icmp\n");
648 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
649 		if (icmpstat[ICMP_STAT_OUTHIST + i] != 0) {
650 			if (first) {
651 				printf("\tOutput histogram:\n");
652 				first = 0;
653 			}
654 			printf("\t\t%s: %" PRIu64 "\n", icmpnames[i],
655 			   icmpstat[ICMP_STAT_OUTHIST + i]);
656 		}
657 	p(ICMP_STAT_BADCODE, "\t%" PRIu64 " message%s with bad code fields\n");
658 	p(ICMP_STAT_TOOSHORT, "\t%" PRIu64 " message%s < minimum length\n");
659 	p(ICMP_STAT_CHECKSUM, "\t%" PRIu64 " bad checksum%s\n");
660 	p(ICMP_STAT_BADLEN, "\t%" PRIu64 " message%s with bad length\n");
661 	p(ICMP_STAT_BMCASTECHO, "\t%" PRIu64 " multicast echo request%s ignored\n");
662 	p(ICMP_STAT_BMCASTTSTAMP, "\t%" PRIu64 " multicast timestamp request%s ignored\n");
663 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
664 		if (icmpstat[ICMP_STAT_INHIST + i] != 0) {
665 			if (first) {
666 				printf("\tInput histogram:\n");
667 				first = 0;
668 			}
669 			printf("\t\t%s: %" PRIu64 "\n", icmpnames[i],
670 			    icmpstat[ICMP_STAT_INHIST + i]);
671 		}
672 	p(ICMP_STAT_REFLECT, "\t%" PRIu64 " message response%s generated\n");
673 	p(ICMP_STAT_PMTUCHG, "\t%" PRIu64 " path MTU change%s\n");
674 #undef p
675 }
676 
677 /*
678  * Dump IGMP statistics structure.
679  */
680 void
681 igmp_stats(u_long off, const char *name)
682 {
683 	uint64_t igmpstat[IGMP_NSTATS];
684 
685 	if (use_sysctl) {
686 		size_t size = sizeof(igmpstat);
687 
688 		if (sysctlbyname("net.inet.igmp.stats", igmpstat, &size,
689 				 NULL, 0) == -1)
690 			return;
691 	} else {
692 		warnx("%s stats not available via KVM.", name);
693 		return;
694 	}
695 
696 	printf("%s:\n", name);
697 
698 #define	p(f, m) if (igmpstat[f] || sflag <= 1) \
699     printf(m, igmpstat[f], plural(igmpstat[f]))
700 #define	py(f, m) if (igmpstat[f] || sflag <= 1) \
701     printf(m, igmpstat[f], igmpstat[f] != 1 ? "ies" : "y")
702 	p(IGMP_STAT_RCV_TOTAL, "\t%" PRIu64 " message%s received\n");
703         p(IGMP_STAT_RCV_TOOSHORT, "\t%" PRIu64 " message%s received with too few bytes\n");
704         p(IGMP_STAT_RCV_BADSUM, "\t%" PRIu64 " message%s received with bad checksum\n");
705         py(IGMP_STAT_RCV_QUERIES, "\t%" PRIu64 " membership quer%s received\n");
706         py(IGMP_STAT_RCV_BADQUERIES, "\t%" PRIu64 " membership quer%s received with invalid field(s)\n");
707         p(IGMP_STAT_RCV_REPORTS, "\t%" PRIu64 " membership report%s received\n");
708         p(IGMP_STAT_RCV_BADREPORTS, "\t%" PRIu64 " membership report%s received with invalid field(s)\n");
709         p(IGMP_STAT_RCV_OURREPORTS, "\t%" PRIu64 " membership report%s received for groups to which we belong\n");
710         p(IGMP_STAT_SND_REPORTS, "\t%" PRIu64 " membership report%s sent\n");
711 #undef p
712 #undef py
713 }
714 
715 /*
716  * Dump CARP statistics structure.
717  */
718 void
719 carp_stats(u_long off, const char *name)
720 {
721 	uint64_t carpstat[CARP_NSTATS];
722 
723 	if (use_sysctl) {
724 		size_t size = sizeof(carpstat);
725 
726 		if (sysctlbyname("net.inet.carp.stats", carpstat, &size,
727 				 NULL, 0) == -1)
728 			return;
729 	} else {
730 		warnx("%s stats not available via KVM.", name);
731 		return;
732 	}
733 
734 	printf("%s:\n", name);
735 
736 #define p(f, m) if (carpstat[f] || sflag <= 1) \
737 	printf(m, carpstat[f], plural(carpstat[f]))
738 #define p2(f, m) if (carpstat[f] || sflag <= 1) \
739 	printf(m, carpstat[f])
740 
741 	p(CARP_STAT_IPACKETS, "\t%" PRIu64 " packet%s received (IPv4)\n");
742 	p(CARP_STAT_IPACKETS6, "\t%" PRIu64 " packet%s received (IPv6)\n");
743 	p(CARP_STAT_BADIF,
744 	    "\t\t%" PRIu64 " packet%s discarded for bad interface\n");
745 	p(CARP_STAT_BADTTL,
746 	    "\t\t%" PRIu64 " packet%s discarded for wrong TTL\n");
747 	p(CARP_STAT_HDROPS, "\t\t%" PRIu64 " packet%s shorter than header\n");
748 	p(CARP_STAT_BADSUM, "\t\t%" PRIu64
749 		" packet%s discarded for bad checksum\n");
750 	p(CARP_STAT_BADVER,
751 	    "\t\t%" PRIu64 " packet%s discarded with a bad version\n");
752 	p2(CARP_STAT_BADLEN,
753 	    "\t\t%" PRIu64 " discarded because packet was too short\n");
754 	p(CARP_STAT_BADAUTH,
755 	    "\t\t%" PRIu64 " packet%s discarded for bad authentication\n");
756 	p(CARP_STAT_BADVHID, "\t\t%" PRIu64 " packet%s discarded for bad vhid\n");
757 	p(CARP_STAT_BADADDRS, "\t\t%" PRIu64
758 		" packet%s discarded because of a bad address list\n");
759 	p(CARP_STAT_OPACKETS, "\t%" PRIu64 " packet%s sent (IPv4)\n");
760 	p(CARP_STAT_OPACKETS6, "\t%" PRIu64 " packet%s sent (IPv6)\n");
761 	p2(CARP_STAT_ONOMEM,
762 	    "\t\t%" PRIu64 " send failed due to mbuf memory error\n");
763 #undef p
764 #undef p2
765 }
766 
767 /*
768  * Dump PIM statistics structure.
769  */
770 void
771 pim_stats(u_long off, const char *name)
772 {
773 	struct pimstat pimstat;
774 
775 	if (off == 0)
776 		return;
777 	if (kread(off, (char *)&pimstat, sizeof (pimstat)) != 0) {
778 		/* XXX: PIM is probably not enabled in the kernel */
779 		return;
780 	}
781 
782 	printf("%s:\n", name);
783 
784 #define	p(f, m) if (pimstat.f || sflag <= 1) \
785 	printf(m, pimstat.f, plural(pimstat.f))
786 
787 	p(pims_rcv_total_msgs, "\t%" PRIu64 " message%s received\n");
788 	p(pims_rcv_total_bytes, "\t%" PRIu64 " byte%s received\n");
789 	p(pims_rcv_tooshort, "\t%" PRIu64 " message%s received with too few bytes\n");
790         p(pims_rcv_badsum, "\t%" PRIu64 " message%s received with bad checksum\n");
791 	p(pims_rcv_badversion, "\t%" PRIu64 " message%s received with bad version\n");
792 	p(pims_rcv_registers_msgs, "\t%" PRIu64 " data register message%s received\n");
793 	p(pims_rcv_registers_bytes, "\t%" PRIu64 " data register byte%s received\n");
794 	p(pims_rcv_registers_wrongiif, "\t%" PRIu64 " data register message%s received on wrong iif\n");
795 	p(pims_rcv_badregisters, "\t%" PRIu64 " bad register%s received\n");
796 	p(pims_snd_registers_msgs, "\t%" PRIu64 " data register message%s sent\n");
797 	p(pims_snd_registers_bytes, "\t%" PRIu64 " data register byte%s sent\n");
798 #undef p
799 }
800 
801 /*
802  * Dump the ARP statistics structure.
803  */
804 void
805 arp_stats(u_long off, const char *name)
806 {
807 	uint64_t arpstat[ARP_NSTATS];
808 
809 	if (use_sysctl) {
810 		size_t size = sizeof(arpstat);
811 
812 		if (sysctlbyname("net.inet.arp.stats", arpstat, &size,
813 				 NULL, 0) == -1)
814 			return;
815 	} else {
816 		warnx("%s stats not available via KVM.", name);
817 		return;
818 	}
819 
820 	printf("%s:\n", name);
821 
822 #define	ps(f, m) if (arpstat[f] || sflag <= 1) \
823     printf(m, arpstat[f])
824 #define	p(f, m) if (arpstat[f] || sflag <= 1) \
825     printf(m, arpstat[f], plural(arpstat[f]))
826 
827 	p(ARP_STAT_SNDTOTAL, "\t%" PRIu64 " packet%s sent\n");
828 	p(ARP_STAT_SNDREPLY, "\t\t%" PRIu64 " reply packet%s\n");
829 	p(ARP_STAT_SENDREQUEST, "\t\t%" PRIu64 " request packet%s\n");
830 
831 	p(ARP_STAT_RCVTOTAL, "\t%" PRIu64 " packet%s received\n");
832 	p(ARP_STAT_RCVREPLY, "\t\t%" PRIu64 " reply packet%s\n");
833 	p(ARP_STAT_RCVREQUEST, "\t\t%" PRIu64 " valid request packet%s\n");
834 	p(ARP_STAT_RCVMCAST, "\t\t%" PRIu64 " broadcast/multicast packet%s\n");
835 	p(ARP_STAT_RCVBADPROTO, "\t\t%" PRIu64 " packet%s with unknown protocol type\n");
836 	p(ARP_STAT_RCVBADLEN, "\t\t%" PRIu64 " packet%s with bad (short) length\n");
837 	p(ARP_STAT_RCVZEROTPA, "\t\t%" PRIu64 " packet%s with null target IP address\n");
838 	p(ARP_STAT_RCVZEROSPA, "\t\t%" PRIu64 " packet%s with null source IP address\n");
839 	ps(ARP_STAT_RCVNOINT, "\t\t%" PRIu64 " could not be mapped to an interface\n");
840 	p(ARP_STAT_RCVLOCALSHA, "\t\t%" PRIu64 " packet%s sourced from a local hardware "
841 	    "address\n");
842 	p(ARP_STAT_RCVBCASTSHA, "\t\t%" PRIu64 " packet%s with a broadcast "
843 	    "source hardware address\n");
844 	p(ARP_STAT_RCVLOCALSPA, "\t\t%" PRIu64 " duplicate%s for a local IP address\n");
845 	p(ARP_STAT_RCVOVERPERM, "\t\t%" PRIu64 " attempt%s to overwrite a static entry\n");
846 	p(ARP_STAT_RCVOVERINT, "\t\t%" PRIu64 " packet%s received on wrong interface\n");
847 	p(ARP_STAT_RCVOVER, "\t\t%" PRIu64 " entry%s overwritten\n");
848 	p(ARP_STAT_RCVLENCHG, "\t\t%" PRIu64 " change%s in hardware address length\n");
849 
850 	p(ARP_STAT_DFRTOTAL, "\t%" PRIu64 " packet%s deferred pending ARP resolution\n");
851 	ps(ARP_STAT_DFRSENT, "\t\t%" PRIu64 " sent\n");
852 	ps(ARP_STAT_DFRDROPPED, "\t\t%" PRIu64 " dropped\n");
853 
854 	p(ARP_STAT_ALLOCFAIL, "\t%" PRIu64 " failure%s to allocate llinfo\n");
855 
856 #undef ps
857 #undef p
858 }
859 
860 /*
861  * Pretty print an Internet address (net address + port).
862  * Take numeric_addr and numeric_port into consideration.
863  */
864 void
865 inetprint(struct in_addr *in, uint16_t port, const char *proto,
866 	  int port_numeric)
867 {
868 	struct servent *sp = 0;
869 	char line[80], *cp;
870 	size_t space;
871 
872 	(void)snprintf(line, sizeof line, "%.*s.",
873 	    (Aflag && !numeric_addr) ? 12 : 16, inetname(in));
874 	cp = strchr(line, '\0');
875 	if (!port_numeric && port)
876 		sp = getservbyport((int)port, proto);
877 	space = sizeof line - (cp-line);
878 	if (sp || port == 0)
879 		(void)snprintf(cp, space, "%s", sp ? sp->s_name : "*");
880 	else
881 		(void)snprintf(cp, space, "%u", ntohs(port));
882 	(void)printf(" %-*.*s", width, width, line);
883 }
884 
885 /*
886  * Construct an Internet address representation.
887  * If numeric_addr has been supplied, give
888  * numeric value, otherwise try for symbolic name.
889  */
890 char *
891 inetname(struct in_addr *inp)
892 {
893 	char *cp;
894 	static char line[50];
895 	struct hostent *hp;
896 	struct netent *np;
897 	static char domain[MAXHOSTNAMELEN + 1];
898 	static int first = 1;
899 
900 	if (first && !numeric_addr) {
901 		first = 0;
902 		if (gethostname(domain, sizeof domain) == 0) {
903 			domain[sizeof(domain) - 1] = '\0';
904 			if ((cp = strchr(domain, '.')))
905 				(void) strlcpy(domain, cp + 1, sizeof(domain));
906 			else
907 				domain[0] = 0;
908 		} else
909 			domain[0] = 0;
910 	}
911 	cp = 0;
912 	if (!numeric_addr && inp->s_addr != INADDR_ANY) {
913 		int net = inet_netof(*inp);
914 		int lna = inet_lnaof(*inp);
915 
916 		if (lna == INADDR_ANY) {
917 			np = getnetbyaddr(net, AF_INET);
918 			if (np)
919 				cp = np->n_name;
920 		}
921 		if (cp == 0) {
922 			hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET);
923 			if (hp) {
924 				if ((cp = strchr(hp->h_name, '.')) &&
925 				    !strcmp(cp + 1, domain))
926 					*cp = 0;
927 				cp = hp->h_name;
928 			}
929 		}
930 	}
931 	if (inp->s_addr == INADDR_ANY)
932 		strlcpy(line, "*", sizeof line);
933 	else if (cp)
934 		strlcpy(line, cp, sizeof line);
935 	else {
936 		inp->s_addr = ntohl(inp->s_addr);
937 #define C(x)	((x) & 0xff)
938 		(void)snprintf(line, sizeof line, "%u.%u.%u.%u",
939 		    C(inp->s_addr >> 24), C(inp->s_addr >> 16),
940 		    C(inp->s_addr >> 8), C(inp->s_addr));
941 #undef C
942 	}
943 	return (line);
944 }
945 
946 /*
947  * Dump the contents of a TCP PCB.
948  */
949 void
950 tcp_dump(u_long pcbaddr)
951 {
952 	callout_impl_t *ci;
953 	struct tcpcb tcpcb;
954 	int i, hardticks;
955 
956 	kread(pcbaddr, (char *)&tcpcb, sizeof(tcpcb));
957 	hardticks = get_hardticks();
958 
959 	printf("TCP Protocol Control Block at 0x%08lx:\n\n", pcbaddr);
960 
961 	printf("Timers:\n");
962 	for (i = 0; i < TCPT_NTIMERS; i++) {
963 		ci = (callout_impl_t *)&tcpcb.t_timer[i];
964 		printf("\t%s: %d", tcptimers[i],
965 		    (ci->c_flags & CALLOUT_PENDING) ?
966 		    ci->c_time - hardticks : 0);
967 	}
968 	printf("\n\n");
969 
970 	if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES)
971 		printf("State: %d", tcpcb.t_state);
972 	else
973 		printf("State: %s", tcpstates[tcpcb.t_state]);
974 	printf(", flags 0x%x, inpcb 0x%lx, in6pcb 0x%lx\n\n", tcpcb.t_flags,
975 	    (u_long)tcpcb.t_inpcb, (u_long)tcpcb.t_in6pcb);
976 
977 	printf("rxtshift %d, rxtcur %d, dupacks %d\n", tcpcb.t_rxtshift,
978 	    tcpcb.t_rxtcur, tcpcb.t_dupacks);
979 	printf("peermss %u, ourmss %u, segsz %u\n\n", tcpcb.t_peermss,
980 	    tcpcb.t_ourmss, tcpcb.t_segsz);
981 
982 	printf("snd_una %u, snd_nxt %u, snd_up %u\n",
983 	    tcpcb.snd_una, tcpcb.snd_nxt, tcpcb.snd_up);
984 	printf("snd_wl1 %u, snd_wl2 %u, iss %u, snd_wnd %lu\n\n",
985 	    tcpcb.snd_wl1, tcpcb.snd_wl2, tcpcb.iss, tcpcb.snd_wnd);
986 
987 	printf("rcv_wnd %lu, rcv_nxt %u, rcv_up %u, irs %u\n\n",
988 	    tcpcb.rcv_wnd, tcpcb.rcv_nxt, tcpcb.rcv_up, tcpcb.irs);
989 
990 	printf("rcv_adv %u, snd_max %u, snd_cwnd %lu, snd_ssthresh %lu\n",
991 	    tcpcb.rcv_adv, tcpcb.snd_max, tcpcb.snd_cwnd, tcpcb.snd_ssthresh);
992 
993 	printf("rcvtime %u, rtttime %u, rtseq %u, srtt %d, rttvar %d, "
994 	    "rttmin %d, max_sndwnd %lu\n\n", tcpcb.t_rcvtime, tcpcb.t_rtttime,
995 	    tcpcb.t_rtseq, tcpcb.t_srtt, tcpcb.t_rttvar, tcpcb.t_rttmin,
996 	    tcpcb.max_sndwnd);
997 
998 	printf("oobflags %d, iobc %d, softerror %d\n\n", tcpcb.t_oobflags,
999 	    tcpcb.t_iobc, tcpcb.t_softerror);
1000 
1001 	printf("snd_scale %d, rcv_scale %d, req_r_scale %d, req_s_scale %d\n",
1002 	    tcpcb.snd_scale, tcpcb.rcv_scale, tcpcb.request_r_scale,
1003 	    tcpcb.requested_s_scale);
1004 	printf("ts_recent %u, ts_regent_age %d, last_ack_sent %u\n",
1005 	    tcpcb.ts_recent, tcpcb.ts_recent_age, tcpcb.last_ack_sent);
1006 }
1007