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