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