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