1 1.84 ozaki /* $NetBSD: inet6.c,v 1.84 2022/10/28 05:27:17 ozaki-r Exp $ */ 2 1.7 itojun /* BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp */ 3 1.7 itojun 4 1.7 itojun /* 5 1.7 itojun * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 6 1.7 itojun * All rights reserved. 7 1.80 msaitoh * 8 1.7 itojun * Redistribution and use in source and binary forms, with or without 9 1.7 itojun * modification, are permitted provided that the following conditions 10 1.7 itojun * are met: 11 1.7 itojun * 1. Redistributions of source code must retain the above copyright 12 1.7 itojun * notice, this list of conditions and the following disclaimer. 13 1.7 itojun * 2. Redistributions in binary form must reproduce the above copyright 14 1.7 itojun * notice, this list of conditions and the following disclaimer in the 15 1.7 itojun * documentation and/or other materials provided with the distribution. 16 1.7 itojun * 3. Neither the name of the project nor the names of its contributors 17 1.7 itojun * may be used to endorse or promote products derived from this software 18 1.7 itojun * without specific prior written permission. 19 1.80 msaitoh * 20 1.7 itojun * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 1.7 itojun * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 1.7 itojun * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 1.7 itojun * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 1.7 itojun * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 1.7 itojun * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 1.7 itojun * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 1.7 itojun * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 1.7 itojun * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 1.7 itojun * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 1.7 itojun * SUCH DAMAGE. 31 1.7 itojun */ 32 1.2 itojun 33 1.1 itojun /* 34 1.1 itojun * Copyright (c) 1983, 1988, 1993 35 1.1 itojun * The Regents of the University of California. All rights reserved. 36 1.1 itojun * 37 1.1 itojun * Redistribution and use in source and binary forms, with or without 38 1.1 itojun * modification, are permitted provided that the following conditions 39 1.1 itojun * are met: 40 1.1 itojun * 1. Redistributions of source code must retain the above copyright 41 1.1 itojun * notice, this list of conditions and the following disclaimer. 42 1.1 itojun * 2. Redistributions in binary form must reproduce the above copyright 43 1.1 itojun * notice, this list of conditions and the following disclaimer in the 44 1.1 itojun * documentation and/or other materials provided with the distribution. 45 1.28 agc * 3. Neither the name of the University nor the names of its contributors 46 1.1 itojun * may be used to endorse or promote products derived from this software 47 1.1 itojun * without specific prior written permission. 48 1.1 itojun * 49 1.1 itojun * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 50 1.1 itojun * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 1.1 itojun * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 1.1 itojun * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 53 1.1 itojun * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 1.1 itojun * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 1.1 itojun * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 1.1 itojun * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 1.1 itojun * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 1.1 itojun * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 1.1 itojun * SUCH DAMAGE. 60 1.1 itojun */ 61 1.1 itojun 62 1.1 itojun #include <sys/cdefs.h> 63 1.1 itojun #ifndef lint 64 1.1 itojun #if 0 65 1.1 itojun static char sccsid[] = "@(#)inet.c 8.4 (Berkeley) 4/20/94"; 66 1.1 itojun #else 67 1.84 ozaki __RCSID("$NetBSD: inet6.c,v 1.84 2022/10/28 05:27:17 ozaki-r Exp $"); 68 1.1 itojun #endif 69 1.1 itojun #endif /* not lint */ 70 1.1 itojun 71 1.66 christos #define _CALLOUT_PRIVATE 72 1.66 christos 73 1.1 itojun #include <sys/param.h> 74 1.1 itojun #include <sys/socket.h> 75 1.1 itojun #include <sys/socketvar.h> 76 1.5 itojun #include <sys/ioctl.h> 77 1.1 itojun #include <sys/mbuf.h> 78 1.1 itojun #include <sys/protosw.h> 79 1.35 rpaulo #include <sys/sysctl.h> 80 1.1 itojun 81 1.1 itojun #include <net/route.h> 82 1.1 itojun #include <net/if.h> 83 1.1 itojun #include <netinet/in.h> 84 1.1 itojun #include <netinet/ip6.h> 85 1.1 itojun #include <netinet/icmp6.h> 86 1.1 itojun #include <netinet/in_systm.h> 87 1.1 itojun #ifndef TCP6 88 1.1 itojun #include <netinet/ip.h> 89 1.1 itojun #include <netinet/ip_var.h> 90 1.1 itojun #endif 91 1.7 itojun #include <netinet6/ip6_var.h> 92 1.1 itojun #include <netinet6/in6_pcb.h> 93 1.5 itojun #include <netinet6/in6_var.h> 94 1.1 itojun #ifdef TCP6 95 1.66 christos #include <netinet/tcp6.h> 96 1.66 christos #include <netinet/tcp6_seq.h> 97 1.1 itojun #define TCP6STATES 98 1.66 christos #include <netinet/tcp6_fsm.h> 99 1.1 itojun #define TCP6TIMERS 100 1.66 christos #include <netinet/tcp6_timer.h> 101 1.66 christos #include <netinet/tcp6_var.h> 102 1.66 christos #include <netinet/tcp6_debug.h> 103 1.1 itojun #else 104 1.66 christos #define TCP6T_NTIMERS TCPT_NTIMERS 105 1.66 christos #define tcp6timers tcptimers 106 1.66 christos #define tcp6states tcpstates 107 1.66 christos #define TCP6_NSTATES TCP_NSTATES 108 1.66 christos #define tcp6cb tcpcb 109 1.1 itojun #include <netinet/tcp.h> 110 1.1 itojun #include <netinet/tcp_seq.h> 111 1.1 itojun #include <netinet/tcp_fsm.h> 112 1.43 matt extern const char * const tcpstates[]; 113 1.66 christos extern const char * const tcptimers[]; 114 1.1 itojun #include <netinet/tcp_timer.h> 115 1.1 itojun #include <netinet/tcp_var.h> 116 1.1 itojun #include <netinet/tcp_debug.h> 117 1.1 itojun #endif /*TCP6*/ 118 1.1 itojun #include <netinet6/udp6.h> 119 1.1 itojun #include <netinet6/udp6_var.h> 120 1.1 itojun #include <netinet6/pim6_var.h> 121 1.23 itojun #include <netinet6/raw_ip6.h> 122 1.54 dyoung #include <netinet/tcp_vtw.h> 123 1.1 itojun 124 1.1 itojun #include <arpa/inet.h> 125 1.1 itojun #if 0 126 1.1 itojun #include "gethostbyname2.h" 127 1.1 itojun #endif 128 1.1 itojun #include <netdb.h> 129 1.1 itojun 130 1.35 rpaulo #include <err.h> 131 1.39 rpaulo #include <errno.h> 132 1.34 rpaulo #include <kvm.h> 133 1.1 itojun #include <stdio.h> 134 1.35 rpaulo #include <stdlib.h> 135 1.1 itojun #include <string.h> 136 1.1 itojun #include <unistd.h> 137 1.67 christos #include <util.h> 138 1.1 itojun #include "netstat.h" 139 1.54 dyoung #include "vtw.h" 140 1.53 pooka #include "prog_ops.h" 141 1.1 itojun 142 1.1 itojun #ifdef INET6 143 1.1 itojun 144 1.84 ozaki struct in6pcb in6pcb; 145 1.1 itojun #ifdef TCP6 146 1.1 itojun struct tcp6cb tcp6cb; 147 1.1 itojun #else 148 1.1 itojun struct tcpcb tcpcb; 149 1.1 itojun #endif 150 1.1 itojun 151 1.54 dyoung char *inet6name(const struct in6_addr *); 152 1.54 dyoung void inet6print(const struct in6_addr *, int, const char *); 153 1.54 dyoung void print_vtw_v6(const vtw_t *); 154 1.1 itojun 155 1.1 itojun /* 156 1.1 itojun * Print a summary of connections related to an Internet 157 1.1 itojun * protocol. For TCP, also give state of connection. 158 1.1 itojun * Listening processes (aflag) are suppressed unless the 159 1.1 itojun * -a (all) flag is specified. 160 1.1 itojun */ 161 1.35 rpaulo static int width; 162 1.35 rpaulo static int compact; 163 1.35 rpaulo 164 1.54 dyoung /* VTW-related variables. */ 165 1.54 dyoung static struct timeval now; 166 1.54 dyoung 167 1.35 rpaulo static void 168 1.35 rpaulo ip6protoprhdr(void) 169 1.35 rpaulo { 170 1.80 msaitoh 171 1.35 rpaulo printf("Active Internet6 connections"); 172 1.80 msaitoh 173 1.35 rpaulo if (aflag) 174 1.35 rpaulo printf(" (including servers)"); 175 1.35 rpaulo putchar('\n'); 176 1.80 msaitoh 177 1.35 rpaulo if (Aflag) { 178 1.35 rpaulo printf("%-8.8s ", "PCB"); 179 1.35 rpaulo width = 18; 180 1.35 rpaulo } 181 1.58 dyoung printf( 182 1.58 dyoung Vflag ? "%-5.5s %-6.6s %-6.6s %*.*s %*.*s %-13.13s Expires\n" 183 1.80 msaitoh : "%-5.5s %-6.6s %-6.6s %*.*s %*.*s %s\n", 184 1.35 rpaulo "Proto", "Recv-Q", "Send-Q", 185 1.35 rpaulo -width, width, "Local Address", 186 1.58 dyoung -width, width, "Foreign Address", "(state)"); 187 1.35 rpaulo } 188 1.35 rpaulo 189 1.35 rpaulo static void 190 1.35 rpaulo ip6protopr0(intptr_t ppcb, u_long rcv_sb_cc, u_long snd_sb_cc, 191 1.80 msaitoh const struct in6_addr *laddr, uint16_t lport, 192 1.80 msaitoh const struct in6_addr *faddr, uint16_t fport, 193 1.54 dyoung short t_state, const char *name, const struct timeval *expires) 194 1.35 rpaulo { 195 1.52 lukem static const char *shorttcpstates[] = { 196 1.35 rpaulo "CLOSED", "LISTEN", "SYNSEN", "SYSRCV", 197 1.35 rpaulo "ESTABL", "CLWAIT", "FWAIT1", "CLOSNG", 198 1.80 msaitoh "LASTAK", "FWAIT2", "TMWAIT" 199 1.35 rpaulo }; 200 1.35 rpaulo int istcp; 201 1.35 rpaulo 202 1.35 rpaulo istcp = strcmp(name, "tcp6") == 0; 203 1.35 rpaulo if (Aflag) 204 1.35 rpaulo printf("%8" PRIxPTR " ", ppcb); 205 1.35 rpaulo 206 1.35 rpaulo printf("%-5.5s %6ld %6ld%s", name, rcv_sb_cc, snd_sb_cc, 207 1.35 rpaulo compact ? "" : " "); 208 1.35 rpaulo 209 1.35 rpaulo inet6print(laddr, (int)lport, name); 210 1.35 rpaulo inet6print(faddr, (int)fport, name); 211 1.35 rpaulo if (istcp) { 212 1.35 rpaulo #ifdef TCP6 213 1.35 rpaulo if (t_state < 0 || t_state >= TCP6_NSTATES) 214 1.35 rpaulo printf(" %d", t_state); 215 1.35 rpaulo else 216 1.35 rpaulo printf(" %s", tcp6states[t_state]); 217 1.35 rpaulo #else 218 1.35 rpaulo if (t_state < 0 || t_state >= TCP_NSTATES) 219 1.35 rpaulo printf(" %d", t_state); 220 1.35 rpaulo else 221 1.35 rpaulo printf(" %s", compact ? shorttcpstates[t_state] : 222 1.35 rpaulo tcpstates[t_state]); 223 1.35 rpaulo #endif 224 1.35 rpaulo } 225 1.54 dyoung if (Vflag && expires != NULL) { 226 1.55 dyoung if (expires->tv_sec == 0 && expires->tv_usec == -1) 227 1.55 dyoung printf(" reclaimed"); 228 1.55 dyoung else { 229 1.54 dyoung struct timeval delta; 230 1.54 dyoung 231 1.54 dyoung timersub(expires, &now, &delta); 232 1.54 dyoung printf(" %.3fms", 233 1.54 dyoung delta.tv_sec * 1000.0 + delta.tv_usec / 1000.0); 234 1.55 dyoung } 235 1.54 dyoung } 236 1.35 rpaulo putchar('\n'); 237 1.35 rpaulo } 238 1.35 rpaulo 239 1.54 dyoung static void 240 1.54 dyoung dbg_printf(const char *fmt, ...) 241 1.54 dyoung { 242 1.80 msaitoh 243 1.54 dyoung return; 244 1.54 dyoung } 245 1.54 dyoung 246 1.80 msaitoh void 247 1.54 dyoung print_vtw_v6(const vtw_t *vtw) 248 1.54 dyoung { 249 1.54 dyoung const vtw_v6_t *v6 = (const vtw_v6_t *)vtw; 250 1.54 dyoung struct timeval delta; 251 1.54 dyoung char buf[2][128]; 252 1.55 dyoung static const struct timeval zero = {.tv_sec = 0, .tv_usec = 0}; 253 1.54 dyoung 254 1.54 dyoung inet_ntop(AF_INET6, &v6->laddr, buf[0], sizeof(buf[0])); 255 1.54 dyoung inet_ntop(AF_INET6, &v6->faddr, buf[1], sizeof(buf[1])); 256 1.54 dyoung 257 1.54 dyoung timersub(&vtw->expire, &now, &delta); 258 1.54 dyoung 259 1.54 dyoung if (vtw->expire.tv_sec == 0 && vtw->expire.tv_usec == -1) { 260 1.80 msaitoh dbg_printf("%15.15s:%d %15.15s:%d reclaimed\n", 261 1.80 msaitoh buf[0], ntohs(v6->lport), 262 1.80 msaitoh buf[1], ntohs(v6->fport)); 263 1.54 dyoung if (!(Vflag && vflag)) 264 1.54 dyoung return; 265 1.54 dyoung } else if (vtw->expire.tv_sec == 0) 266 1.54 dyoung return; 267 1.55 dyoung else if (timercmp(&delta, &zero, <) && !(Vflag && vflag)) { 268 1.80 msaitoh dbg_printf("%15.15s:%d %15.15s:%d expired\n", 269 1.80 msaitoh buf[0], ntohs(v6->lport), 270 1.80 msaitoh buf[1], ntohs(v6->fport)); 271 1.55 dyoung return; 272 1.55 dyoung } else { 273 1.80 msaitoh dbg_printf("%15.15s:%d %15.15s:%d expires in %.3fms\n", 274 1.80 msaitoh buf[0], ntohs(v6->lport), 275 1.80 msaitoh buf[1], ntohs(v6->fport), 276 1.80 msaitoh delta.tv_sec * 1000.0 + delta.tv_usec / 1000.0); 277 1.54 dyoung } 278 1.54 dyoung ip6protopr0(0, 0, 0, 279 1.54 dyoung &v6->laddr, v6->lport, 280 1.54 dyoung &v6->faddr, v6->fport, 281 1.54 dyoung TCPS_TIME_WAIT, "tcp6", &vtw->expire); 282 1.54 dyoung } 283 1.35 rpaulo 284 1.61 christos 285 1.61 christos static struct kinfo_pcb * 286 1.74 joerg getpcblist_kmem(u_long off, const char *name, size_t *len) 287 1.74 joerg { 288 1.74 joerg struct socket sockb; 289 1.29 itojun struct inpcbtable table; 290 1.83 ozaki struct inpcb *next, *prev; 291 1.84 ozaki struct inpcb *inp; 292 1.54 dyoung int istcp = strcmp(name, "tcp6") == 0; 293 1.61 christos struct kinfo_pcb *pcblist; 294 1.61 christos size_t size = 100, i; 295 1.61 christos struct sockaddr_in6 sin6; 296 1.66 christos struct inpcbqueue *head; 297 1.35 rpaulo 298 1.61 christos if (off == 0) { 299 1.61 christos *len = 0; 300 1.61 christos return NULL; 301 1.35 rpaulo } 302 1.38 elad kread(off, (char *)&table, sizeof (table)); 303 1.66 christos head = &table.inpt_queue; 304 1.66 christos next = TAILQ_FIRST(head); 305 1.66 christos prev = TAILQ_END(head); 306 1.38 elad 307 1.79 nia pcblist = NULL; 308 1.79 nia if (reallocarr(&pcblist, size, sizeof(*pcblist)) != 0) 309 1.79 nia err(1, "reallocarr"); 310 1.61 christos 311 1.61 christos i = 0; 312 1.66 christos while (next != TAILQ_END(head)) { 313 1.84 ozaki kread((u_long)next, (char *)&in6pcb, sizeof in6pcb); 314 1.84 ozaki inp = (struct inpcb *)&in6pcb; 315 1.84 ozaki next = TAILQ_NEXT(inp, inp_queue); 316 1.29 itojun prev = next; 317 1.29 itojun 318 1.84 ozaki if (inp->inp_af != AF_INET6) 319 1.29 itojun continue; 320 1.29 itojun 321 1.84 ozaki kread((u_long)inp->inp_socket, (char *)&sockb, 322 1.35 rpaulo sizeof (sockb)); 323 1.1 itojun if (istcp) { 324 1.1 itojun #ifdef TCP6 325 1.84 ozaki kread((u_long)inp->inp_ppcb, 326 1.1 itojun (char *)&tcp6cb, sizeof (tcp6cb)); 327 1.1 itojun #else 328 1.84 ozaki kread((u_long)inp->inp_ppcb, 329 1.1 itojun (char *)&tcpcb, sizeof (tcpcb)); 330 1.1 itojun #endif 331 1.1 itojun } 332 1.80 msaitoh pcblist[i].ki_ppcbaddr = 333 1.84 ozaki istcp ? (uintptr_t) inp->inp_ppcb : (uintptr_t) prev; 334 1.61 christos pcblist[i].ki_rcvq = (uint64_t)sockb.so_rcv.sb_cc; 335 1.61 christos pcblist[i].ki_sndq = (uint64_t)sockb.so_snd.sb_cc; 336 1.84 ozaki sin6.sin6_addr = in6p_laddr(inp); 337 1.84 ozaki sin6.sin6_port = inp->inp_lport; 338 1.61 christos memcpy(&pcblist[i].ki_s, &sin6, sizeof(sin6)); 339 1.84 ozaki sin6.sin6_addr = in6p_faddr(inp); 340 1.84 ozaki sin6.sin6_port = inp->inp_fport; 341 1.61 christos memcpy(&pcblist[i].ki_d, &sin6, sizeof(sin6)); 342 1.61 christos pcblist[i].ki_tstate = tcpcb.t_state; 343 1.61 christos if (i++ == size) { 344 1.68 christos size += 100; 345 1.79 nia if (reallocarr(&pcblist, size, sizeof(*pcblist)) != 0) 346 1.79 nia err(1, "reallocarr"); 347 1.61 christos } 348 1.61 christos } 349 1.61 christos *len = i; 350 1.61 christos return pcblist; 351 1.61 christos } 352 1.61 christos 353 1.61 christos void 354 1.61 christos ip6protopr(u_long off, const char *name) 355 1.61 christos { 356 1.61 christos struct kinfo_pcb *pcblist; 357 1.61 christos size_t i, len; 358 1.61 christos static int first = 1; 359 1.61 christos 360 1.61 christos compact = 0; 361 1.61 christos if (Aflag) { 362 1.61 christos if (!numeric_addr) 363 1.61 christos width = 18; 364 1.61 christos else { 365 1.61 christos width = 21; 366 1.61 christos compact = 1; 367 1.61 christos } 368 1.61 christos } else 369 1.61 christos width = 22; 370 1.61 christos 371 1.61 christos if (use_sysctl) 372 1.61 christos pcblist = getpcblist_sysctl(name, &len); 373 1.61 christos else 374 1.61 christos pcblist = getpcblist_kmem(off, name, &len); 375 1.61 christos 376 1.61 christos for (i = 0; i < len; i++) { 377 1.61 christos struct sockaddr_in6 src, dst; 378 1.61 christos 379 1.61 christos memcpy(&src, &pcblist[i].ki_s, sizeof(src)); 380 1.61 christos memcpy(&dst, &pcblist[i].ki_d, sizeof(dst)); 381 1.61 christos 382 1.61 christos if (!aflag && IN6_IS_ADDR_UNSPECIFIED(&dst.sin6_addr)) 383 1.61 christos continue; 384 1.61 christos 385 1.1 itojun if (first) { 386 1.35 rpaulo ip6protoprhdr(); 387 1.1 itojun first = 0; 388 1.1 itojun } 389 1.61 christos 390 1.61 christos ip6protopr0((intptr_t) pcblist[i].ki_ppcbaddr, 391 1.61 christos pcblist[i].ki_rcvq, pcblist[i].ki_sndq, 392 1.61 christos &src.sin6_addr, src.sin6_port, 393 1.61 christos &dst.sin6_addr, dst.sin6_port, 394 1.61 christos pcblist[i].ki_tstate, name, NULL); 395 1.1 itojun } 396 1.61 christos 397 1.61 christos free(pcblist); 398 1.61 christos 399 1.61 christos if (strcmp(name, "tcp6") == 0) { 400 1.57 drochner struct timeval t; 401 1.57 drochner timebase(&t); 402 1.54 dyoung gettimeofday(&now, NULL); 403 1.57 drochner timersub(&now, &t, &now); 404 1.54 dyoung show_vtw_v6(print_vtw_v6); 405 1.54 dyoung } 406 1.1 itojun } 407 1.1 itojun 408 1.1 itojun #ifdef TCP6 409 1.1 itojun /* 410 1.1 itojun * Dump TCP6 statistics structure. 411 1.1 itojun */ 412 1.1 itojun void 413 1.52 lukem tcp6_stats(u_long off, const char *name) 414 1.1 itojun { 415 1.1 itojun struct tcp6stat tcp6stat; 416 1.1 itojun 417 1.35 rpaulo if (use_sysctl) { 418 1.35 rpaulo size_t size = sizeof(tcp6stat); 419 1.35 rpaulo 420 1.73 kamil if (prog_sysctlbyname("net.inet6.tcp6.stats", &tcp6stat, &size, 421 1.77 ozaki NULL, 0) == -1 && errno != ENOMEM) 422 1.50 thorpej return; 423 1.35 rpaulo } else { 424 1.50 thorpej warnx("%s stats not available via KVM.", name); 425 1.50 thorpej return; 426 1.35 rpaulo } 427 1.35 rpaulo 428 1.1 itojun printf ("%s:\n", name); 429 1.1 itojun 430 1.80 msaitoh #define p(f, m) if (tcp6stat.f || sflag <= 1) \ 431 1.80 msaitoh printf(m, tcp6stat.f, plural(tcp6stat.f)) 432 1.80 msaitoh #define p2(f1, f2, m) if (tcp6stat.f1 || tcp6stat.f2 || sflag <= 1) \ 433 1.80 msaitoh printf(m, tcp6stat.f1, plural(tcp6stat.f1), tcp6stat.f2, \ 434 1.80 msaitoh plural(tcp6stat.f2)) 435 1.80 msaitoh #define p3(f, m) if (tcp6stat.f || sflag <= 1) \ 436 1.80 msaitoh printf(m, tcp6stat.f, plurales(tcp6stat.f)) 437 1.1 itojun 438 1.1 itojun p(tcp6s_sndtotal, "\t%ld packet%s sent\n"); 439 1.1 itojun p2(tcp6s_sndpack,tcp6s_sndbyte, 440 1.81 msaitoh "\t\t%ld data packet%s (%ld byte%s)\n"); 441 1.1 itojun p2(tcp6s_sndrexmitpack, tcp6s_sndrexmitbyte, 442 1.81 msaitoh "\t\t%ld data packet%s (%ld byte%s) retransmitted\n"); 443 1.1 itojun p2(tcp6s_sndacks, tcp6s_delack, 444 1.81 msaitoh "\t\t%ld ack-only packet%s (%ld packet%s delayed)\n"); 445 1.1 itojun p(tcp6s_sndurg, "\t\t%ld URG only packet%s\n"); 446 1.1 itojun p(tcp6s_sndprobe, "\t\t%ld window probe packet%s\n"); 447 1.1 itojun p(tcp6s_sndwinup, "\t\t%ld window update packet%s\n"); 448 1.1 itojun p(tcp6s_sndctrl, "\t\t%ld control packet%s\n"); 449 1.1 itojun p(tcp6s_rcvtotal, "\t%ld packet%s received\n"); 450 1.81 msaitoh p2(tcp6s_rcvackpack, tcp6s_rcvackbyte, 451 1.81 msaitoh "\t\t%ld ack%s (for %ld byte%s)\n"); 452 1.1 itojun p(tcp6s_rcvdupack, "\t\t%ld duplicate ack%s\n"); 453 1.1 itojun p(tcp6s_rcvacktoomuch, "\t\t%ld ack%s for unsent data\n"); 454 1.1 itojun p2(tcp6s_rcvpack, tcp6s_rcvbyte, 455 1.81 msaitoh "\t\t%ld packet%s (%ld byte%s) received in-sequence\n"); 456 1.1 itojun p2(tcp6s_rcvduppack, tcp6s_rcvdupbyte, 457 1.81 msaitoh "\t\t%ld completely duplicate packet%s (%ld byte%s)\n"); 458 1.1 itojun p(tcp6s_pawsdrop, "\t\t%ld old duplicate packet%s\n"); 459 1.1 itojun p2(tcp6s_rcvpartduppack, tcp6s_rcvpartdupbyte, 460 1.81 msaitoh "\t\t%ld packet%s with some dup. data (%ld byte%s duped)\n"); 461 1.1 itojun p2(tcp6s_rcvoopack, tcp6s_rcvoobyte, 462 1.81 msaitoh "\t\t%ld out-of-order packet%s (%ld byte%s)\n"); 463 1.1 itojun p2(tcp6s_rcvpackafterwin, tcp6s_rcvbyteafterwin, 464 1.81 msaitoh "\t\t%ld packet%s (%ld byte%s) of data after window\n"); 465 1.1 itojun p(tcp6s_rcvwinprobe, "\t\t%ld window probe%s\n"); 466 1.1 itojun p(tcp6s_rcvwinupd, "\t\t%ld window update packet%s\n"); 467 1.1 itojun p(tcp6s_rcvafterclose, "\t\t%ld packet%s received after close\n"); 468 1.1 itojun p(tcp6s_rcvbadsum, "\t\t%ld discarded for bad checksum%s\n"); 469 1.81 msaitoh p(tcp6s_rcvbadoff, 470 1.81 msaitoh "\t\t%ld discarded for bad header offset field%s\n"); 471 1.1 itojun p(tcp6s_rcvshort, "\t\t%ld discarded because packet%s too short\n"); 472 1.1 itojun p(tcp6s_connattempt, "\t%ld connection request%s\n"); 473 1.1 itojun p(tcp6s_accepts, "\t%ld connection accept%s\n"); 474 1.1 itojun p(tcp6s_badsyn, "\t%ld bad connection attempt%s\n"); 475 1.81 msaitoh p(tcp6s_connects, 476 1.81 msaitoh "\t%ld connection%s established (including accepts)\n"); 477 1.1 itojun p2(tcp6s_closed, tcp6s_drops, 478 1.81 msaitoh "\t%ld connection%s closed (including %ld drop%s)\n"); 479 1.1 itojun p(tcp6s_conndrops, "\t%ld embryonic connection%s dropped\n"); 480 1.1 itojun p2(tcp6s_rttupdated, tcp6s_segstimed, 481 1.81 msaitoh "\t%ld segment%s updated rtt (of %ld attempt%s)\n"); 482 1.1 itojun p(tcp6s_rexmttimeo, "\t%ld retransmit timeout%s\n"); 483 1.81 msaitoh p(tcp6s_timeoutdrop, 484 1.81 msaitoh "\t\t%ld connection%s dropped by rexmit timeout\n"); 485 1.1 itojun p(tcp6s_persisttimeo, "\t%ld persist timeout%s\n"); 486 1.1 itojun p(tcp6s_persistdrop, "\t%ld connection%s timed out in persist\n"); 487 1.1 itojun p(tcp6s_keeptimeo, "\t%ld keepalive timeout%s\n"); 488 1.1 itojun p(tcp6s_keepprobe, "\t\t%ld keepalive probe%s sent\n"); 489 1.1 itojun p(tcp6s_keepdrops, "\t\t%ld connection%s dropped by keepalive\n"); 490 1.1 itojun p(tcp6s_predack, "\t%ld correct ACK header prediction%s\n"); 491 1.1 itojun p(tcp6s_preddat, "\t%ld correct data packet header prediction%s\n"); 492 1.1 itojun p3(tcp6s_pcbcachemiss, "\t%ld PCB cache miss%s\n"); 493 1.1 itojun #undef p 494 1.1 itojun #undef p2 495 1.1 itojun #undef p3 496 1.1 itojun } 497 1.1 itojun #endif 498 1.1 itojun 499 1.1 itojun /* 500 1.1 itojun * Dump UDP6 statistics structure. 501 1.1 itojun */ 502 1.1 itojun void 503 1.52 lukem udp6_stats(u_long off, const char *name) 504 1.1 itojun { 505 1.46 thorpej uint64_t udp6stat[UDP6_NSTATS]; 506 1.82 msaitoh uint64_t delivered; 507 1.1 itojun 508 1.36 rpaulo if (use_sysctl) { 509 1.36 rpaulo size_t size = sizeof(udp6stat); 510 1.36 rpaulo 511 1.73 kamil if (prog_sysctlbyname("net.inet6.udp6.stats", udp6stat, &size, 512 1.77 ozaki NULL, 0) == -1 && errno != ENOMEM) 513 1.50 thorpej return; 514 1.36 rpaulo } else { 515 1.50 thorpej warnx("%s stats not available via KVM.", name); 516 1.50 thorpej return; 517 1.36 rpaulo } 518 1.1 itojun printf("%s:\n", name); 519 1.80 msaitoh #define p(f, m) if (udp6stat[f] || sflag <= 1) \ 520 1.80 msaitoh printf(m, (unsigned long long)udp6stat[f], plural(udp6stat[f])) 521 1.80 msaitoh #define p1(f, m) if (udp6stat[f] || sflag <= 1) \ 522 1.80 msaitoh printf(m, (unsigned long long)udp6stat[f]) 523 1.46 thorpej p(UDP6_STAT_IPACKETS, "\t%llu datagram%s received\n"); 524 1.46 thorpej p1(UDP6_STAT_HDROPS, "\t%llu with incomplete header\n"); 525 1.46 thorpej p1(UDP6_STAT_BADLEN, "\t%llu with bad data length field\n"); 526 1.46 thorpej p1(UDP6_STAT_BADSUM, "\t%llu with bad checksum\n"); 527 1.46 thorpej p1(UDP6_STAT_NOSUM, "\t%llu with no checksum\n"); 528 1.46 thorpej p1(UDP6_STAT_NOPORT, "\t%llu dropped due to no socket\n"); 529 1.46 thorpej p(UDP6_STAT_NOPORTMCAST, 530 1.7 itojun "\t%llu multicast datagram%s dropped due to no socket\n"); 531 1.46 thorpej p1(UDP6_STAT_FULLSOCK, "\t%llu dropped due to full socket buffers\n"); 532 1.46 thorpej delivered = udp6stat[UDP6_STAT_IPACKETS] - 533 1.46 thorpej udp6stat[UDP6_STAT_HDROPS] - 534 1.46 thorpej udp6stat[UDP6_STAT_BADLEN] - 535 1.46 thorpej udp6stat[UDP6_STAT_BADSUM] - 536 1.46 thorpej udp6stat[UDP6_STAT_NOPORT] - 537 1.46 thorpej udp6stat[UDP6_STAT_NOPORTMCAST] - 538 1.46 thorpej udp6stat[UDP6_STAT_FULLSOCK]; 539 1.1 itojun if (delivered || sflag <= 1) 540 1.4 bouyer printf("\t%llu delivered\n", (unsigned long long)delivered); 541 1.46 thorpej p(UDP6_STAT_OPACKETS, "\t%llu datagram%s output\n"); 542 1.1 itojun #undef p 543 1.1 itojun #undef p1 544 1.1 itojun } 545 1.1 itojun 546 1.45 thorpej static const char *ip6nh[] = { 547 1.16 itojun /*0*/ "hop by hop", 548 1.1 itojun "ICMP", 549 1.1 itojun "IGMP", 550 1.16 itojun NULL, 551 1.1 itojun "IP", 552 1.16 itojun /*5*/ NULL, 553 1.1 itojun "TCP", 554 1.16 itojun NULL, 555 1.16 itojun NULL, 556 1.16 itojun NULL, 557 1.16 itojun /*10*/ NULL, NULL, NULL, NULL, NULL, 558 1.16 itojun /*15*/ NULL, 559 1.16 itojun NULL, 560 1.1 itojun "UDP", 561 1.16 itojun NULL, 562 1.16 itojun NULL, 563 1.16 itojun /*20*/ NULL, 564 1.16 itojun NULL, 565 1.1 itojun "IDP", 566 1.16 itojun NULL, 567 1.16 itojun NULL, 568 1.16 itojun /*25*/ NULL, 569 1.16 itojun NULL, 570 1.16 itojun NULL, 571 1.16 itojun NULL, 572 1.60 joerg NULL, 573 1.16 itojun /*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 574 1.16 itojun /*40*/ NULL, 575 1.1 itojun "IP6", 576 1.16 itojun NULL, 577 1.1 itojun "routing", 578 1.1 itojun "fragment", 579 1.16 itojun /*45*/ NULL, NULL, NULL, NULL, NULL, 580 1.16 itojun /*50*/ "ESP", 581 1.1 itojun "AH", 582 1.16 itojun NULL, 583 1.16 itojun NULL, 584 1.16 itojun NULL, 585 1.16 itojun /*55*/ NULL, 586 1.16 itojun NULL, 587 1.16 itojun NULL, 588 1.1 itojun "ICMP6", 589 1.16 itojun "no next header", 590 1.16 itojun /*60*/ "destination option", 591 1.16 itojun NULL, 592 1.16 itojun NULL, 593 1.16 itojun NULL, 594 1.16 itojun NULL, 595 1.16 itojun /*65*/ NULL, NULL, NULL, NULL, NULL, 596 1.16 itojun /*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 597 1.60 joerg /*80*/ NULL, 598 1.16 itojun NULL, 599 1.16 itojun NULL, 600 1.16 itojun NULL, 601 1.16 itojun NULL, 602 1.16 itojun NULL, 603 1.16 itojun NULL, 604 1.16 itojun NULL, 605 1.16 itojun NULL, 606 1.16 itojun "OSPF", 607 1.16 itojun /*90*/ NULL, NULL, NULL, NULL, NULL, 608 1.16 itojun /*95*/ NULL, 609 1.16 itojun NULL, 610 1.1 itojun "Ethernet", 611 1.16 itojun NULL, 612 1.16 itojun NULL, 613 1.16 itojun /*100*/ NULL, 614 1.16 itojun NULL, 615 1.16 itojun NULL, 616 1.1 itojun "PIM", 617 1.16 itojun NULL, 618 1.16 itojun /*105*/ NULL, NULL, NULL, NULL, NULL, 619 1.16 itojun /*110*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 620 1.16 itojun /*120*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 621 1.18 itojun /*130*/ NULL, 622 1.18 itojun NULL, 623 1.18 itojun "SCTP", 624 1.18 itojun NULL, 625 1.18 itojun NULL, 626 1.18 itojun /*135*/ NULL, NULL, NULL, NULL, NULL, 627 1.16 itojun /*140*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 628 1.16 itojun NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 629 1.16 itojun /*160*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 630 1.16 itojun NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 631 1.16 itojun /*180*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 632 1.16 itojun NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 633 1.16 itojun /*200*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 634 1.16 itojun NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 635 1.16 itojun /*220*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 636 1.16 itojun NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 637 1.16 itojun /*240*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 638 1.80 msaitoh NULL, NULL, NULL, NULL, NULL, NULL 639 1.1 itojun }; 640 1.1 itojun 641 1.1 itojun /* 642 1.1 itojun * Dump IP6 statistics structure. 643 1.1 itojun */ 644 1.1 itojun void 645 1.52 lukem ip6_stats(u_long off, const char *name) 646 1.1 itojun { 647 1.45 thorpej uint64_t ip6stat[IP6_NSTATS]; 648 1.1 itojun int first, i; 649 1.16 itojun struct protoent *ep; 650 1.16 itojun const char *n; 651 1.1 itojun 652 1.36 rpaulo if (use_sysctl) { 653 1.36 rpaulo size_t size = sizeof(ip6stat); 654 1.1 itojun 655 1.73 kamil if (prog_sysctlbyname("net.inet6.ip6.stats", ip6stat, &size, 656 1.77 ozaki NULL, 0) == -1 && errno != ENOMEM) 657 1.50 thorpej return; 658 1.36 rpaulo } else { 659 1.50 thorpej warnx("%s stats not available via KVM.", name); 660 1.50 thorpej return; 661 1.36 rpaulo } 662 1.1 itojun printf("%s:\n", name); 663 1.1 itojun 664 1.80 msaitoh #define p(f, m) if (ip6stat[f] || sflag <= 1) \ 665 1.80 msaitoh printf(m, (unsigned long long)ip6stat[f], plural(ip6stat[f])) 666 1.80 msaitoh #define p1(f, m) if (ip6stat[f] || sflag <= 1) \ 667 1.80 msaitoh printf(m, (unsigned long long)ip6stat[f]) 668 1.45 thorpej 669 1.45 thorpej p(IP6_STAT_TOTAL, "\t%llu total packet%s received\n"); 670 1.45 thorpej p1(IP6_STAT_TOOSMALL, "\t%llu with size smaller than minimum\n"); 671 1.45 thorpej p1(IP6_STAT_TOOSHORT, "\t%llu with data size < data length\n"); 672 1.45 thorpej p1(IP6_STAT_BADOPTIONS, "\t%llu with bad options\n"); 673 1.45 thorpej p1(IP6_STAT_BADVERS, "\t%llu with incorrect version number\n"); 674 1.45 thorpej p(IP6_STAT_FRAGMENTS, "\t%llu fragment%s received\n"); 675 1.45 thorpej p(IP6_STAT_FRAGDROPPED, 676 1.7 itojun "\t%llu fragment%s dropped (dup or out of space)\n"); 677 1.45 thorpej p(IP6_STAT_FRAGTIMEOUT, "\t%llu fragment%s dropped after timeout\n"); 678 1.45 thorpej p(IP6_STAT_FRAGOVERFLOW, "\t%llu fragment%s that exceeded limit\n"); 679 1.45 thorpej p(IP6_STAT_REASSEMBLED, "\t%llu packet%s reassembled ok\n"); 680 1.45 thorpej p(IP6_STAT_DELIVERED, "\t%llu packet%s for this host\n"); 681 1.45 thorpej p(IP6_STAT_FORWARD, "\t%llu packet%s forwarded\n"); 682 1.45 thorpej p(IP6_STAT_FASTFORWARD, "\t%llu packet%s fast forwarded\n"); 683 1.80 msaitoh p1(IP6_STAT_FASTFORWARDFLOWS, "\t%llu fast forward flows\n"); 684 1.45 thorpej p(IP6_STAT_CANTFORWARD, "\t%llu packet%s not forwardable\n"); 685 1.45 thorpej p(IP6_STAT_REDIRECTSENT, "\t%llu redirect%s sent\n"); 686 1.45 thorpej p(IP6_STAT_LOCALOUT, "\t%llu packet%s sent from this host\n"); 687 1.45 thorpej p(IP6_STAT_RAWOUT, "\t%llu packet%s sent with fabricated ip header\n"); 688 1.45 thorpej p(IP6_STAT_ODROPPED, 689 1.7 itojun "\t%llu output packet%s dropped due to no bufs, etc.\n"); 690 1.81 msaitoh p(IP6_STAT_NOROUTE, 691 1.81 msaitoh "\t%llu output packet%s discarded due to no route\n"); 692 1.45 thorpej p(IP6_STAT_FRAGMENTED, "\t%llu output datagram%s fragmented\n"); 693 1.45 thorpej p(IP6_STAT_OFRAGMENTS, "\t%llu fragment%s created\n"); 694 1.45 thorpej p(IP6_STAT_CANTFRAG, "\t%llu datagram%s that can't be fragmented\n"); 695 1.45 thorpej p(IP6_STAT_BADSCOPE, "\t%llu packet%s that violated scope rules\n"); 696 1.45 thorpej p(IP6_STAT_NOTMEMBER, "\t%llu multicast packet%s which we don't join\n"); 697 1.1 itojun for (first = 1, i = 0; i < 256; i++) 698 1.45 thorpej if (ip6stat[IP6_STAT_NXTHIST + i] != 0) { 699 1.1 itojun if (first) { 700 1.17 itojun printf("\tInput packet histogram:\n"); 701 1.1 itojun first = 0; 702 1.1 itojun } 703 1.16 itojun n = NULL; 704 1.16 itojun if (ip6nh[i]) 705 1.16 itojun n = ip6nh[i]; 706 1.16 itojun else if ((ep = getprotobynumber(i)) != NULL) 707 1.16 itojun n = ep->p_name; 708 1.16 itojun if (n) 709 1.16 itojun printf("\t\t%s: %llu\n", n, 710 1.45 thorpej (unsigned long long)ip6stat[IP6_STAT_NXTHIST + i]); 711 1.16 itojun else 712 1.16 itojun printf("\t\t#%d: %llu\n", i, 713 1.45 thorpej (unsigned long long)ip6stat[IP6_STAT_NXTHIST + i]); 714 1.1 itojun } 715 1.12 jhawk printf("\tMbuf statistics:\n"); 716 1.45 thorpej p(IP6_STAT_M1, "\t\t%llu one mbuf%s\n"); 717 1.1 itojun for (first = 1, i = 0; i < 32; i++) { 718 1.1 itojun char ifbuf[IFNAMSIZ]; 719 1.80 msaitoh if (ip6stat[IP6_STAT_M2M + i] != 0) { 720 1.1 itojun if (first) { 721 1.1 itojun printf("\t\ttwo or more mbuf:\n"); 722 1.1 itojun first = 0; 723 1.1 itojun } 724 1.4 bouyer printf("\t\t\t%s = %llu\n", 725 1.80 msaitoh if_indextoname(i, ifbuf), 726 1.80 msaitoh (unsigned long long)ip6stat[IP6_STAT_M2M + i]); 727 1.1 itojun } 728 1.1 itojun } 729 1.45 thorpej p(IP6_STAT_MEXT1, "\t\t%llu one ext mbuf%s\n"); 730 1.45 thorpej p(IP6_STAT_MEXT2M, "\t\t%llu two or more ext mbuf%s\n"); 731 1.45 thorpej p(IP6_STAT_EXTHDRTOOLONG, 732 1.7 itojun "\t%llu packet%s whose headers are not continuous\n"); 733 1.45 thorpej p(IP6_STAT_NOGIF, "\t%llu tunneling packet%s that can't find gif\n"); 734 1.81 msaitoh p(IP6_STAT_NOIPSEC, 735 1.81 msaitoh "\t%llu tunneling packet%s that can't find ipsecif\n"); 736 1.45 thorpej p(IP6_STAT_TOOMANYHDR, 737 1.7 itojun "\t%llu packet%s discarded due to too many headers\n"); 738 1.7 itojun 739 1.7 itojun /* for debugging source address selection */ 740 1.80 msaitoh #define PRINT_SCOPESTAT(s, i) do { \ 741 1.80 msaitoh switch (i) { /* XXX hardcoding in each case */ \ 742 1.80 msaitoh case 1: \ 743 1.80 msaitoh p(s, "\t\t%llu node-local%s\n"); \ 744 1.80 msaitoh break; \ 745 1.80 msaitoh case 2: \ 746 1.80 msaitoh p(s, "\t\t%llu link-local%s\n"); \ 747 1.80 msaitoh break; \ 748 1.80 msaitoh case 5: \ 749 1.80 msaitoh p(s, "\t\t%llu site-local%s\n"); \ 750 1.80 msaitoh break; \ 751 1.80 msaitoh case 14: \ 752 1.80 msaitoh p(s, "\t\t%llu global%s\n"); \ 753 1.80 msaitoh break; \ 754 1.80 msaitoh default: \ 755 1.80 msaitoh printf("\t\t%llu addresses scope=%x\n", \ 756 1.80 msaitoh (unsigned long long)ip6stat[s], i); \ 757 1.80 msaitoh } \ 758 1.78 rillig } while(0); 759 1.7 itojun 760 1.45 thorpej p(IP6_STAT_SOURCES_NONE, 761 1.7 itojun "\t%llu failure%s of source address selection\n"); 762 1.7 itojun for (first = 1, i = 0; i < 16; i++) { 763 1.45 thorpej if (ip6stat[IP6_STAT_SOURCES_SAMEIF + i]) { 764 1.7 itojun if (first) { 765 1.7 itojun printf("\tsource addresses on an outgoing I/F\n"); 766 1.7 itojun first = 0; 767 1.7 itojun } 768 1.45 thorpej PRINT_SCOPESTAT(IP6_STAT_SOURCES_SAMEIF + i, i); 769 1.7 itojun } 770 1.7 itojun } 771 1.7 itojun for (first = 1, i = 0; i < 16; i++) { 772 1.45 thorpej if (ip6stat[IP6_STAT_SOURCES_OTHERIF + i]) { 773 1.7 itojun if (first) { 774 1.7 itojun printf("\tsource addresses on a non-outgoing I/F\n"); 775 1.7 itojun first = 0; 776 1.7 itojun } 777 1.45 thorpej PRINT_SCOPESTAT(IP6_STAT_SOURCES_OTHERIF + i, i); 778 1.7 itojun } 779 1.7 itojun } 780 1.7 itojun for (first = 1, i = 0; i < 16; i++) { 781 1.45 thorpej if (ip6stat[IP6_STAT_SOURCES_SAMESCOPE + i]) { 782 1.7 itojun if (first) { 783 1.7 itojun printf("\tsource addresses of same scope\n"); 784 1.7 itojun first = 0; 785 1.7 itojun } 786 1.45 thorpej PRINT_SCOPESTAT(IP6_STAT_SOURCES_SAMESCOPE + i, i); 787 1.7 itojun } 788 1.7 itojun } 789 1.7 itojun for (first = 1, i = 0; i < 16; i++) { 790 1.45 thorpej if (ip6stat[IP6_STAT_SOURCES_OTHERSCOPE + i]) { 791 1.7 itojun if (first) { 792 1.7 itojun printf("\tsource addresses of a different scope\n"); 793 1.7 itojun first = 0; 794 1.7 itojun } 795 1.45 thorpej PRINT_SCOPESTAT(IP6_STAT_SOURCES_OTHERSCOPE + i, i); 796 1.7 itojun } 797 1.7 itojun } 798 1.7 itojun for (first = 1, i = 0; i < 16; i++) { 799 1.45 thorpej if (ip6stat[IP6_STAT_SOURCES_DEPRECATED + i]) { 800 1.7 itojun if (first) { 801 1.7 itojun printf("\tdeprecated source addresses\n"); 802 1.7 itojun first = 0; 803 1.7 itojun } 804 1.45 thorpej PRINT_SCOPESTAT(IP6_STAT_SOURCES_DEPRECATED + i, i); 805 1.7 itojun } 806 1.5 itojun } 807 1.10 itojun 808 1.45 thorpej p1(IP6_STAT_FORWARD_CACHEHIT, "\t%llu forward cache hit\n"); 809 1.45 thorpej p1(IP6_STAT_FORWARD_CACHEMISS, "\t%llu forward cache miss\n"); 810 1.72 ozaki p(IP6_STAT_PFILDROP_IN, "\t%llu input packet%s dropped by pfil\n"); 811 1.72 ozaki p(IP6_STAT_PFILDROP_OUT, "\t%llu output packet%s dropped by pfil\n"); 812 1.76 ozaki p(IP6_STAT_IPSECDROP_IN, "\t%llu input packet%s dropped by IPsec\n"); 813 1.76 ozaki p(IP6_STAT_IPSECDROP_OUT, "\t%llu output packet%s dropped by IPsec\n"); 814 1.81 msaitoh p(IP6_STAT_IFDROP, 815 1.81 msaitoh "\t%llu input packet%s dropped due to interface state\n"); 816 1.81 msaitoh p(IP6_STAT_IDROPPED, 817 1.81 msaitoh "\t%llu input packet%s dropped due to no bufs, etc.\n"); 818 1.81 msaitoh p(IP6_STAT_TIMXCEED, 819 1.81 msaitoh "\t%llu packet%s dropped due to hop limit exceeded\n"); 820 1.76 ozaki p(IP6_STAT_TOOBIG, "\t%llu packet%s dropped (too big)\n"); 821 1.81 msaitoh p(IP6_STAT_RTREJECT, 822 1.81 msaitoh "\t%llu output packet%s discarded due to reject route\n"); 823 1.1 itojun #undef p 824 1.1 itojun #undef p1 825 1.1 itojun } 826 1.1 itojun 827 1.5 itojun /* 828 1.5 itojun * Dump IPv6 per-interface statistics based on RFC 2465. 829 1.5 itojun */ 830 1.5 itojun void 831 1.52 lukem ip6_ifstats(const char *ifname) 832 1.5 itojun { 833 1.5 itojun struct in6_ifreq ifr; 834 1.5 itojun int s; 835 1.80 msaitoh #define p(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \ 836 1.80 msaitoh printf(m, (unsigned long long)ifr.ifr_ifru.ifru_stat.f, \ 837 1.80 msaitoh plural(ifr.ifr_ifru.ifru_stat.f)) 838 1.80 msaitoh #define p_5(f, m) if (ifr.ifr_ifru.ifru_stat.f || sflag <= 1) \ 839 1.80 msaitoh printf(m, (unsigned long long)ip6stat.f) 840 1.5 itojun 841 1.5 itojun if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 842 1.5 itojun perror("Warning: socket(AF_INET6)"); 843 1.5 itojun return; 844 1.5 itojun } 845 1.5 itojun 846 1.19 itojun strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 847 1.19 itojun printf("ip6 on %s:\n", ifname); 848 1.5 itojun 849 1.5 itojun if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) { 850 1.5 itojun perror("Warning: ioctl(SIOCGIFSTAT_IN6)"); 851 1.5 itojun goto end; 852 1.5 itojun } 853 1.5 itojun 854 1.5 itojun p(ifs6_in_receive, "\t%llu total input datagram%s\n"); 855 1.5 itojun p(ifs6_in_hdrerr, "\t%llu datagram%s with invalid header received\n"); 856 1.5 itojun p(ifs6_in_toobig, "\t%llu datagram%s exceeded MTU received\n"); 857 1.5 itojun p(ifs6_in_noroute, "\t%llu datagram%s with no route received\n"); 858 1.5 itojun p(ifs6_in_addrerr, "\t%llu datagram%s with invalid dst received\n"); 859 1.5 itojun p(ifs6_in_truncated, "\t%llu truncated datagram%s received\n"); 860 1.81 msaitoh p(ifs6_in_protounknown, 861 1.81 msaitoh "\t%llu datagram%s with unknown proto received\n"); 862 1.5 itojun p(ifs6_in_discard, "\t%llu input datagram%s discarded\n"); 863 1.5 itojun p(ifs6_in_deliver, 864 1.81 msaitoh "\t%llu datagram%s delivered to an upper layer protocol\n"); 865 1.5 itojun p(ifs6_out_forward, "\t%llu datagram%s forwarded to this interface\n"); 866 1.5 itojun p(ifs6_out_request, 867 1.81 msaitoh "\t%llu datagram%s sent from an upper layer protocol\n"); 868 1.5 itojun p(ifs6_out_discard, "\t%llu total discarded output datagram%s\n"); 869 1.5 itojun p(ifs6_out_fragok, "\t%llu output datagram%s fragmented\n"); 870 1.5 itojun p(ifs6_out_fragfail, "\t%llu output datagram%s failed on fragment\n"); 871 1.81 msaitoh p(ifs6_out_fragcreat, 872 1.81 msaitoh "\t%llu output datagram%s succeeded on fragment\n"); 873 1.5 itojun p(ifs6_reass_reqd, "\t%llu incoming datagram%s fragmented\n"); 874 1.5 itojun p(ifs6_reass_ok, "\t%llu datagram%s reassembled\n"); 875 1.5 itojun p(ifs6_reass_fail, "\t%llu datagram%s failed on reassembling\n"); 876 1.5 itojun p(ifs6_in_mcast, "\t%llu multicast datagram%s received\n"); 877 1.5 itojun p(ifs6_out_mcast, "\t%llu multicast datagram%s sent\n"); 878 1.5 itojun 879 1.5 itojun end: 880 1.5 itojun close(s); 881 1.5 itojun 882 1.5 itojun #undef p 883 1.5 itojun #undef p_5 884 1.5 itojun } 885 1.5 itojun 886 1.70 kre static const char *icmp6names[256] = { 887 1.1 itojun "#0", 888 1.1 itojun "unreach", 889 1.1 itojun "packet too big", 890 1.1 itojun "time exceed", 891 1.1 itojun "parameter problem", 892 1.1 itojun "#5", 893 1.1 itojun "#6", 894 1.1 itojun "#7", 895 1.1 itojun "#8", 896 1.1 itojun "#9", 897 1.1 itojun "#10", 898 1.1 itojun "#11", 899 1.1 itojun "#12", 900 1.1 itojun "#13", 901 1.1 itojun "#14", 902 1.1 itojun "#15", 903 1.1 itojun "#16", 904 1.1 itojun "#17", 905 1.1 itojun "#18", 906 1.80 msaitoh "#19", 907 1.1 itojun "#20", 908 1.1 itojun "#21", 909 1.1 itojun "#22", 910 1.1 itojun "#23", 911 1.1 itojun "#24", 912 1.1 itojun "#25", 913 1.1 itojun "#26", 914 1.1 itojun "#27", 915 1.1 itojun "#28", 916 1.80 msaitoh "#29", 917 1.1 itojun "#30", 918 1.1 itojun "#31", 919 1.1 itojun "#32", 920 1.1 itojun "#33", 921 1.1 itojun "#34", 922 1.1 itojun "#35", 923 1.1 itojun "#36", 924 1.1 itojun "#37", 925 1.1 itojun "#38", 926 1.80 msaitoh "#39", 927 1.1 itojun "#40", 928 1.1 itojun "#41", 929 1.1 itojun "#42", 930 1.1 itojun "#43", 931 1.1 itojun "#44", 932 1.1 itojun "#45", 933 1.1 itojun "#46", 934 1.1 itojun "#47", 935 1.1 itojun "#48", 936 1.80 msaitoh "#49", 937 1.1 itojun "#50", 938 1.1 itojun "#51", 939 1.1 itojun "#52", 940 1.1 itojun "#53", 941 1.1 itojun "#54", 942 1.1 itojun "#55", 943 1.1 itojun "#56", 944 1.1 itojun "#57", 945 1.1 itojun "#58", 946 1.80 msaitoh "#59", 947 1.1 itojun "#60", 948 1.1 itojun "#61", 949 1.1 itojun "#62", 950 1.1 itojun "#63", 951 1.1 itojun "#64", 952 1.1 itojun "#65", 953 1.1 itojun "#66", 954 1.1 itojun "#67", 955 1.1 itojun "#68", 956 1.80 msaitoh "#69", 957 1.1 itojun "#70", 958 1.1 itojun "#71", 959 1.1 itojun "#72", 960 1.1 itojun "#73", 961 1.1 itojun "#74", 962 1.1 itojun "#75", 963 1.1 itojun "#76", 964 1.1 itojun "#77", 965 1.1 itojun "#78", 966 1.80 msaitoh "#79", 967 1.1 itojun "#80", 968 1.1 itojun "#81", 969 1.1 itojun "#82", 970 1.1 itojun "#83", 971 1.1 itojun "#84", 972 1.1 itojun "#85", 973 1.1 itojun "#86", 974 1.1 itojun "#87", 975 1.1 itojun "#88", 976 1.80 msaitoh "#89", 977 1.1 itojun "#80", 978 1.1 itojun "#91", 979 1.1 itojun "#92", 980 1.1 itojun "#93", 981 1.1 itojun "#94", 982 1.1 itojun "#95", 983 1.1 itojun "#96", 984 1.1 itojun "#97", 985 1.1 itojun "#98", 986 1.80 msaitoh "#99", 987 1.1 itojun "#100", 988 1.1 itojun "#101", 989 1.1 itojun "#102", 990 1.1 itojun "#103", 991 1.1 itojun "#104", 992 1.1 itojun "#105", 993 1.1 itojun "#106", 994 1.1 itojun "#107", 995 1.1 itojun "#108", 996 1.80 msaitoh "#109", 997 1.1 itojun "#110", 998 1.1 itojun "#111", 999 1.1 itojun "#112", 1000 1.1 itojun "#113", 1001 1.1 itojun "#114", 1002 1.1 itojun "#115", 1003 1.1 itojun "#116", 1004 1.1 itojun "#117", 1005 1.1 itojun "#118", 1006 1.80 msaitoh "#119", 1007 1.1 itojun "#120", 1008 1.1 itojun "#121", 1009 1.1 itojun "#122", 1010 1.1 itojun "#123", 1011 1.1 itojun "#124", 1012 1.1 itojun "#125", 1013 1.1 itojun "#126", 1014 1.1 itojun "#127", 1015 1.1 itojun "echo", 1016 1.80 msaitoh "echo reply", 1017 1.5 itojun "multicast listener query", 1018 1.5 itojun "multicast listener report", 1019 1.5 itojun "multicast listener done", 1020 1.1 itojun "router solicitation", 1021 1.21 itojun "router advertisement", 1022 1.1 itojun "neighbor solicitation", 1023 1.21 itojun "neighbor advertisement", 1024 1.1 itojun "redirect", 1025 1.1 itojun "router renumbering", 1026 1.1 itojun "node information request", 1027 1.1 itojun "node information reply", 1028 1.1 itojun "#141", 1029 1.1 itojun "#142", 1030 1.70 kre "multicast listener report (v2)", 1031 1.70 kre "home agent discovery request", 1032 1.70 kre "home agent discovery reply", 1033 1.70 kre "mobile prefix solicitation", 1034 1.70 kre "mobile prefix advertisement", 1035 1.1 itojun "#148", 1036 1.80 msaitoh "#149", 1037 1.1 itojun "#150", 1038 1.70 kre "multicast router advertisement", 1039 1.70 kre "multicast router solicitation", 1040 1.70 kre "multicast router termination", 1041 1.1 itojun "#154", 1042 1.1 itojun "#155", 1043 1.1 itojun "#156", 1044 1.1 itojun "#157", 1045 1.1 itojun "#158", 1046 1.80 msaitoh "#159", 1047 1.1 itojun "#160", 1048 1.1 itojun "#161", 1049 1.1 itojun "#162", 1050 1.1 itojun "#163", 1051 1.1 itojun "#164", 1052 1.1 itojun "#165", 1053 1.1 itojun "#166", 1054 1.1 itojun "#167", 1055 1.1 itojun "#168", 1056 1.80 msaitoh "#169", 1057 1.1 itojun "#170", 1058 1.1 itojun "#171", 1059 1.1 itojun "#172", 1060 1.1 itojun "#173", 1061 1.1 itojun "#174", 1062 1.1 itojun "#175", 1063 1.1 itojun "#176", 1064 1.1 itojun "#177", 1065 1.1 itojun "#178", 1066 1.80 msaitoh "#179", 1067 1.1 itojun "#180", 1068 1.1 itojun "#181", 1069 1.1 itojun "#182", 1070 1.1 itojun "#183", 1071 1.1 itojun "#184", 1072 1.1 itojun "#185", 1073 1.1 itojun "#186", 1074 1.1 itojun "#187", 1075 1.1 itojun "#188", 1076 1.80 msaitoh "#189", 1077 1.1 itojun "#180", 1078 1.1 itojun "#191", 1079 1.1 itojun "#192", 1080 1.1 itojun "#193", 1081 1.1 itojun "#194", 1082 1.1 itojun "#195", 1083 1.1 itojun "#196", 1084 1.1 itojun "#197", 1085 1.1 itojun "#198", 1086 1.80 msaitoh "#199", 1087 1.1 itojun "#200", 1088 1.1 itojun "#201", 1089 1.1 itojun "#202", 1090 1.1 itojun "#203", 1091 1.1 itojun "#204", 1092 1.1 itojun "#205", 1093 1.1 itojun "#206", 1094 1.1 itojun "#207", 1095 1.1 itojun "#208", 1096 1.80 msaitoh "#209", 1097 1.1 itojun "#210", 1098 1.1 itojun "#211", 1099 1.1 itojun "#212", 1100 1.1 itojun "#213", 1101 1.1 itojun "#214", 1102 1.1 itojun "#215", 1103 1.1 itojun "#216", 1104 1.1 itojun "#217", 1105 1.1 itojun "#218", 1106 1.80 msaitoh "#219", 1107 1.1 itojun "#220", 1108 1.1 itojun "#221", 1109 1.1 itojun "#222", 1110 1.1 itojun "#223", 1111 1.1 itojun "#224", 1112 1.1 itojun "#225", 1113 1.1 itojun "#226", 1114 1.1 itojun "#227", 1115 1.1 itojun "#228", 1116 1.80 msaitoh "#229", 1117 1.1 itojun "#230", 1118 1.1 itojun "#231", 1119 1.1 itojun "#232", 1120 1.1 itojun "#233", 1121 1.1 itojun "#234", 1122 1.1 itojun "#235", 1123 1.1 itojun "#236", 1124 1.1 itojun "#237", 1125 1.1 itojun "#238", 1126 1.80 msaitoh "#239", 1127 1.1 itojun "#240", 1128 1.1 itojun "#241", 1129 1.1 itojun "#242", 1130 1.1 itojun "#243", 1131 1.1 itojun "#244", 1132 1.1 itojun "#245", 1133 1.1 itojun "#246", 1134 1.1 itojun "#247", 1135 1.1 itojun "#248", 1136 1.80 msaitoh "#249", 1137 1.1 itojun "#250", 1138 1.1 itojun "#251", 1139 1.1 itojun "#252", 1140 1.1 itojun "#253", 1141 1.1 itojun "#254", 1142 1.80 msaitoh "#255" 1143 1.1 itojun }; 1144 1.1 itojun 1145 1.1 itojun /* 1146 1.5 itojun * Dump ICMPv6 statistics. 1147 1.1 itojun */ 1148 1.1 itojun void 1149 1.52 lukem icmp6_stats(u_long off, const char *name) 1150 1.1 itojun { 1151 1.44 thorpej uint64_t icmp6stat[ICMP6_NSTATS]; 1152 1.56 dyoung int i, first; 1153 1.1 itojun 1154 1.35 rpaulo if (use_sysctl) { 1155 1.35 rpaulo size_t size = sizeof(icmp6stat); 1156 1.35 rpaulo 1157 1.80 msaitoh if (prog_sysctlbyname("net.inet6.icmp6.stats", icmp6stat, 1158 1.80 msaitoh &size, NULL, 0) == -1 && errno != ENOMEM) 1159 1.50 thorpej return; 1160 1.35 rpaulo } else { 1161 1.50 thorpej warnx("%s stats not available via KVM.", name); 1162 1.50 thorpej return; 1163 1.35 rpaulo } 1164 1.80 msaitoh 1165 1.1 itojun printf("%s:\n", name); 1166 1.1 itojun 1167 1.80 msaitoh #define p(f, m) if (icmp6stat[f] || sflag <= 1) \ 1168 1.80 msaitoh printf(m, (unsigned long long)icmp6stat[f], \ 1169 1.80 msaitoh plural(icmp6stat[f])) 1170 1.44 thorpej #define p_oerr(f, m) if (icmp6stat[ICMP6_STAT_OUTERRHIST + f] || sflag <= 1) \ 1171 1.80 msaitoh printf(m, \ 1172 1.80 msaitoh (unsigned long long)icmp6stat[ICMP6_STAT_OUTERRHIST + f]) 1173 1.1 itojun 1174 1.44 thorpej p(ICMP6_STAT_ERROR, "\t%llu call%s to icmp6_error\n"); 1175 1.44 thorpej p(ICMP6_STAT_CANTERROR, 1176 1.8 itojun "\t%llu error%s not generated because old message was icmp6 or so\n"); 1177 1.44 thorpej p(ICMP6_STAT_TOOFREQ, 1178 1.15 itojun "\t%llu error%s not generated because of rate limitation\n"); 1179 1.1 itojun for (first = 1, i = 0; i < 256; i++) 1180 1.44 thorpej if (icmp6stat[ICMP6_STAT_OUTHIST + i] != 0) { 1181 1.1 itojun if (first) { 1182 1.17 itojun printf("\tOutput packet histogram:\n"); 1183 1.1 itojun first = 0; 1184 1.1 itojun } 1185 1.4 bouyer printf("\t\t%s: %llu\n", icmp6names[i], 1186 1.44 thorpej (unsigned long long)icmp6stat[ICMP6_STAT_OUTHIST + i]); 1187 1.1 itojun } 1188 1.44 thorpej p(ICMP6_STAT_BADCODE, "\t%llu message%s with bad code fields\n"); 1189 1.44 thorpej p(ICMP6_STAT_TOOSHORT, "\t%llu message%s < minimum length\n"); 1190 1.44 thorpej p(ICMP6_STAT_CHECKSUM, "\t%llu bad checksum%s\n"); 1191 1.44 thorpej p(ICMP6_STAT_BADLEN, "\t%llu message%s with bad length\n"); 1192 1.1 itojun for (first = 1, i = 0; i < ICMP6_MAXTYPE; i++) 1193 1.44 thorpej if (icmp6stat[ICMP6_STAT_INHIST + i] != 0) { 1194 1.1 itojun if (first) { 1195 1.17 itojun printf("\tInput packet histogram:\n"); 1196 1.1 itojun first = 0; 1197 1.1 itojun } 1198 1.4 bouyer printf("\t\t%s: %llu\n", icmp6names[i], 1199 1.44 thorpej (unsigned long long)icmp6stat[ICMP6_STAT_INHIST + i]); 1200 1.1 itojun } 1201 1.10 itojun printf("\tHistogram of error messages to be generated:\n"); 1202 1.44 thorpej p_oerr(ICMP6_ERRSTAT_DST_UNREACH_NOROUTE, "\t\t%llu no route\n"); 1203 1.81 msaitoh p_oerr(ICMP6_ERRSTAT_DST_UNREACH_ADMIN, 1204 1.81 msaitoh "\t\t%llu administratively prohibited\n"); 1205 1.81 msaitoh p_oerr(ICMP6_ERRSTAT_DST_UNREACH_BEYONDSCOPE, 1206 1.81 msaitoh "\t\t%llu beyond scope\n"); 1207 1.81 msaitoh p_oerr(ICMP6_ERRSTAT_DST_UNREACH_ADDR, 1208 1.81 msaitoh "\t\t%llu address unreachable\n"); 1209 1.81 msaitoh p_oerr(ICMP6_ERRSTAT_DST_UNREACH_NOPORT, 1210 1.81 msaitoh "\t\t%llu port unreachable\n"); 1211 1.44 thorpej p_oerr(ICMP6_ERRSTAT_PACKET_TOO_BIG, "\t\t%llu packet too big\n"); 1212 1.81 msaitoh p_oerr(ICMP6_ERRSTAT_TIME_EXCEED_TRANSIT, 1213 1.81 msaitoh "\t\t%llu time exceed transit\n"); 1214 1.81 msaitoh p_oerr(ICMP6_ERRSTAT_TIME_EXCEED_REASSEMBLY, 1215 1.81 msaitoh "\t\t%llu time exceed reassembly\n"); 1216 1.81 msaitoh p_oerr(ICMP6_ERRSTAT_PARAMPROB_HEADER, 1217 1.81 msaitoh "\t\t%llu erroneous header field\n"); 1218 1.81 msaitoh p_oerr(ICMP6_ERRSTAT_PARAMPROB_NEXTHEADER, 1219 1.81 msaitoh "\t\t%llu unrecognized next header\n"); 1220 1.81 msaitoh p_oerr(ICMP6_ERRSTAT_PARAMPROB_OPTION, 1221 1.81 msaitoh "\t\t%llu unrecognized option\n"); 1222 1.44 thorpej p_oerr(ICMP6_ERRSTAT_REDIRECT, "\t\t%llu redirect\n"); 1223 1.44 thorpej p_oerr(ICMP6_ERRSTAT_UNKNOWN, "\t\t%llu unknown\n"); 1224 1.44 thorpej 1225 1.44 thorpej p(ICMP6_STAT_REFLECT, "\t%llu message response%s generated\n"); 1226 1.81 msaitoh p(ICMP6_STAT_ND_TOOMANYOPT, 1227 1.81 msaitoh "\t%llu message%s with too many ND options\n"); 1228 1.44 thorpej p(ICMP6_STAT_ND_BADOPT, "\t%llu message%s with bad ND options\n"); 1229 1.44 thorpej p(ICMP6_STAT_BADNS, "\t%llu bad neighbor solicitation message%s\n"); 1230 1.44 thorpej p(ICMP6_STAT_BADNA, "\t%llu bad neighbor advertisement message%s\n"); 1231 1.44 thorpej p(ICMP6_STAT_BADRS, "\t%llu bad router solicitation message%s\n"); 1232 1.44 thorpej p(ICMP6_STAT_BADRA, "\t%llu bad router advertisement message%s\n"); 1233 1.81 msaitoh p(ICMP6_STAT_DROPPED_RAROUTE, 1234 1.81 msaitoh "\t%llu router advertisement route%s dropped\n"); 1235 1.44 thorpej p(ICMP6_STAT_BADREDIRECT, "\t%llu bad redirect message%s\n"); 1236 1.44 thorpej p(ICMP6_STAT_PMTUCHG, "\t%llu path MTU change%s\n"); 1237 1.5 itojun #undef p 1238 1.44 thorpej #undef p_oerr 1239 1.5 itojun } 1240 1.5 itojun 1241 1.5 itojun /* 1242 1.5 itojun * Dump ICMPv6 per-interface statistics based on RFC 2466. 1243 1.5 itojun */ 1244 1.5 itojun void 1245 1.52 lukem icmp6_ifstats(const char *ifname) 1246 1.5 itojun { 1247 1.5 itojun struct in6_ifreq ifr; 1248 1.5 itojun int s; 1249 1.80 msaitoh #define p(f, m) if (ifr.ifr_ifru.ifru_icmp6stat.f || sflag <= 1) \ 1250 1.80 msaitoh printf(m, (unsigned long long)ifr.ifr_ifru.ifru_icmp6stat.f, \ 1251 1.80 msaitoh plural(ifr.ifr_ifru.ifru_icmp6stat.f)) 1252 1.5 itojun 1253 1.5 itojun if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 1254 1.5 itojun perror("Warning: socket(AF_INET6)"); 1255 1.5 itojun return; 1256 1.5 itojun } 1257 1.5 itojun 1258 1.19 itojun strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 1259 1.19 itojun printf("icmp6 on %s:\n", ifname); 1260 1.5 itojun 1261 1.5 itojun if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) { 1262 1.5 itojun perror("Warning: ioctl(SIOCGIFSTAT_ICMP6)"); 1263 1.5 itojun goto end; 1264 1.5 itojun } 1265 1.5 itojun 1266 1.5 itojun p(ifs6_in_msg, "\t%llu total input message%s\n"); 1267 1.80 msaitoh p(ifs6_in_error, "\t%llu total input error message%s\n"); 1268 1.81 msaitoh p(ifs6_in_dstunreach, 1269 1.81 msaitoh "\t%llu input destination unreachable error%s\n"); 1270 1.81 msaitoh p(ifs6_in_adminprohib, 1271 1.81 msaitoh "\t%llu input administratively prohibited error%s\n"); 1272 1.5 itojun p(ifs6_in_timeexceed, "\t%llu input time exceeded error%s\n"); 1273 1.5 itojun p(ifs6_in_paramprob, "\t%llu input parameter problem error%s\n"); 1274 1.5 itojun p(ifs6_in_pkttoobig, "\t%llu input packet too big error%s\n"); 1275 1.5 itojun p(ifs6_in_echo, "\t%llu input echo request%s\n"); 1276 1.5 itojun p(ifs6_in_echoreply, "\t%llu input echo reply%s\n"); 1277 1.5 itojun p(ifs6_in_routersolicit, "\t%llu input router solicitation%s\n"); 1278 1.5 itojun p(ifs6_in_routeradvert, "\t%llu input router advertisement%s\n"); 1279 1.5 itojun p(ifs6_in_neighborsolicit, "\t%llu input neighbor solicitation%s\n"); 1280 1.5 itojun p(ifs6_in_neighboradvert, "\t%llu input neighbor advertisement%s\n"); 1281 1.5 itojun p(ifs6_in_redirect, "\t%llu input redirect%s\n"); 1282 1.5 itojun p(ifs6_in_mldquery, "\t%llu input MLD query%s\n"); 1283 1.5 itojun p(ifs6_in_mldreport, "\t%llu input MLD report%s\n"); 1284 1.5 itojun p(ifs6_in_mlddone, "\t%llu input MLD done%s\n"); 1285 1.5 itojun 1286 1.5 itojun p(ifs6_out_msg, "\t%llu total output message%s\n"); 1287 1.5 itojun p(ifs6_out_error, "\t%llu total output error message%s\n"); 1288 1.81 msaitoh p(ifs6_out_dstunreach, 1289 1.81 msaitoh "\t%llu output destination unreachable error%s\n"); 1290 1.81 msaitoh p(ifs6_out_adminprohib, 1291 1.81 msaitoh "\t%llu output administratively prohibited error%s\n"); 1292 1.5 itojun p(ifs6_out_timeexceed, "\t%llu output time exceeded error%s\n"); 1293 1.5 itojun p(ifs6_out_paramprob, "\t%llu output parameter problem error%s\n"); 1294 1.5 itojun p(ifs6_out_pkttoobig, "\t%llu output packet too big error%s\n"); 1295 1.5 itojun p(ifs6_out_echo, "\t%llu output echo request%s\n"); 1296 1.5 itojun p(ifs6_out_echoreply, "\t%llu output echo reply%s\n"); 1297 1.5 itojun p(ifs6_out_routersolicit, "\t%llu output router solicitation%s\n"); 1298 1.5 itojun p(ifs6_out_routeradvert, "\t%llu output router advertisement%s\n"); 1299 1.5 itojun p(ifs6_out_neighborsolicit, "\t%llu output neighbor solicitation%s\n"); 1300 1.5 itojun p(ifs6_out_neighboradvert, "\t%llu output neighbor advertisement%s\n"); 1301 1.5 itojun p(ifs6_out_redirect, "\t%llu output redirect%s\n"); 1302 1.5 itojun p(ifs6_out_mldquery, "\t%llu output MLD query%s\n"); 1303 1.5 itojun p(ifs6_out_mldreport, "\t%llu output MLD report%s\n"); 1304 1.5 itojun p(ifs6_out_mlddone, "\t%llu output MLD done%s\n"); 1305 1.5 itojun 1306 1.5 itojun end: 1307 1.5 itojun close(s); 1308 1.1 itojun #undef p 1309 1.1 itojun } 1310 1.1 itojun 1311 1.1 itojun /* 1312 1.1 itojun * Dump PIM statistics structure. 1313 1.1 itojun */ 1314 1.1 itojun void 1315 1.52 lukem pim6_stats(u_long off, const char *name) 1316 1.1 itojun { 1317 1.49 thorpej uint64_t pim6stat[PIM6_NSTATS]; 1318 1.1 itojun 1319 1.36 rpaulo if (use_sysctl) { 1320 1.36 rpaulo size_t size = sizeof(pim6stat); 1321 1.36 rpaulo 1322 1.73 kamil if (prog_sysctlbyname("net.inet6.pim6.stats", pim6stat, &size, 1323 1.77 ozaki NULL, 0) == -1 && errno != ENOMEM) 1324 1.50 thorpej return; 1325 1.80 msaitoh } else { 1326 1.50 thorpej warnx("%s stats not available via KVM.", name); 1327 1.50 thorpej return; 1328 1.36 rpaulo } 1329 1.1 itojun printf("%s:\n", name); 1330 1.1 itojun 1331 1.80 msaitoh #define p(f, m) if (pim6stat[f] || sflag <= 1) \ 1332 1.80 msaitoh printf(m, (unsigned long long)pim6stat[f], plural(pim6stat[f])) 1333 1.80 msaitoh 1334 1.49 thorpej p(PIM6_STAT_RCV_TOTAL, "\t%llu message%s received\n"); 1335 1.81 msaitoh p(PIM6_STAT_RCV_TOOSHORT, 1336 1.81 msaitoh "\t%llu message%s received with too few bytes\n"); 1337 1.81 msaitoh p(PIM6_STAT_RCV_BADSUM, 1338 1.81 msaitoh "\t%llu message%s received with bad checksum\n"); 1339 1.81 msaitoh p(PIM6_STAT_RCV_BADVERSION, 1340 1.81 msaitoh "\t%llu message%s received with bad version\n"); 1341 1.49 thorpej p(PIM6_STAT_RCV_REGISTERS, "\t%llu register%s received\n"); 1342 1.49 thorpej p(PIM6_STAT_RCV_BADREGISTERS, "\t%llu bad register%s received\n"); 1343 1.49 thorpej p(PIM6_STAT_SND_REGISTERS, "\t%llu register%s sent\n"); 1344 1.23 itojun #undef p 1345 1.23 itojun } 1346 1.23 itojun 1347 1.23 itojun /* 1348 1.23 itojun * Dump raw ip6 statistics structure. 1349 1.23 itojun */ 1350 1.23 itojun void 1351 1.52 lukem rip6_stats(u_long off, const char *name) 1352 1.23 itojun { 1353 1.48 thorpej uint64_t rip6stat[RIP6_NSTATS]; 1354 1.82 msaitoh uint64_t delivered; 1355 1.23 itojun 1356 1.36 rpaulo if (use_sysctl) { 1357 1.36 rpaulo size_t size = sizeof(rip6stat); 1358 1.36 rpaulo 1359 1.73 kamil if (prog_sysctlbyname("net.inet6.raw6.stats", rip6stat, &size, 1360 1.77 ozaki NULL, 0) == -1 && errno != ENOMEM) 1361 1.50 thorpej return; 1362 1.36 rpaulo } else { 1363 1.50 thorpej warnx("%s stats not available via KVM.", name); 1364 1.50 thorpej return; 1365 1.36 rpaulo } 1366 1.23 itojun printf("%s:\n", name); 1367 1.23 itojun 1368 1.48 thorpej #define p(f, m) if (rip6stat[f] || sflag <= 1) \ 1369 1.48 thorpej printf(m, (unsigned long long)rip6stat[f], plural(rip6stat[f])) 1370 1.48 thorpej p(RIP6_STAT_IPACKETS, "\t%llu message%s received\n"); 1371 1.48 thorpej p(RIP6_STAT_ISUM, "\t%llu checksum calculation%s on inbound\n"); 1372 1.48 thorpej p(RIP6_STAT_BADSUM, "\t%llu message%s with bad checksum\n"); 1373 1.48 thorpej p(RIP6_STAT_NOSOCK, "\t%llu message%s dropped due to no socket\n"); 1374 1.48 thorpej p(RIP6_STAT_NOSOCKMCAST, 1375 1.23 itojun "\t%llu multicast message%s dropped due to no socket\n"); 1376 1.48 thorpej p(RIP6_STAT_FULLSOCK, 1377 1.23 itojun "\t%llu message%s dropped due to full socket buffers\n"); 1378 1.48 thorpej delivered = rip6stat[RIP6_STAT_IPACKETS] - 1379 1.48 thorpej rip6stat[RIP6_STAT_BADSUM] - 1380 1.48 thorpej rip6stat[RIP6_STAT_NOSOCK] - 1381 1.48 thorpej rip6stat[RIP6_STAT_NOSOCKMCAST] - 1382 1.48 thorpej rip6stat[RIP6_STAT_FULLSOCK]; 1383 1.23 itojun if (delivered || sflag <= 1) 1384 1.23 itojun printf("\t%llu delivered\n", (unsigned long long)delivered); 1385 1.48 thorpej p(RIP6_STAT_OPACKETS, "\t%llu datagram%s output\n"); 1386 1.1 itojun #undef p 1387 1.1 itojun } 1388 1.1 itojun 1389 1.1 itojun /* 1390 1.1 itojun * Pretty print an Internet address (net address + port). 1391 1.20 assar * Take numeric_addr and numeric_port into consideration. 1392 1.1 itojun */ 1393 1.1 itojun void 1394 1.54 dyoung inet6print(const struct in6_addr *in6, int port, const char *proto) 1395 1.1 itojun { 1396 1.81 msaitoh #define GETSERVBYPORT6(port, proto, ret) \ 1397 1.81 msaitoh do { \ 1398 1.81 msaitoh if (strcmp((proto), "tcp6") == 0) \ 1399 1.81 msaitoh (ret) = getservbyport((int)(port), "tcp"); \ 1400 1.81 msaitoh else if (strcmp((proto), "udp6") == 0) \ 1401 1.81 msaitoh (ret) = getservbyport((int)(port), "udp"); \ 1402 1.81 msaitoh else \ 1403 1.81 msaitoh (ret) = getservbyport((int)(port), (proto)); \ 1404 1.81 msaitoh } while (0) 1405 1.81 msaitoh 1406 1.1 itojun struct servent *sp = 0; 1407 1.1 itojun char line[80], *cp; 1408 1.52 lukem int lwidth; 1409 1.1 itojun 1410 1.52 lukem lwidth = Aflag ? 12 : 16; 1411 1.52 lukem if (vflag && lwidth < (int)strlen(inet6name(in6))) 1412 1.52 lukem lwidth = strlen(inet6name(in6)); 1413 1.52 lukem snprintf(line, sizeof(line), "%.*s.", lwidth, inet6name(in6)); 1414 1.24 itojun cp = strchr(line, '\0'); 1415 1.20 assar if (!numeric_port && port) 1416 1.1 itojun GETSERVBYPORT6(port, proto, sp); 1417 1.1 itojun if (sp || port == 0) 1418 1.19 itojun snprintf(cp, sizeof(line) - (cp - line), 1419 1.26 jdolecek "%s", sp ? sp->s_name : "*"); 1420 1.1 itojun else 1421 1.19 itojun snprintf(cp, sizeof(line) - (cp - line), 1422 1.19 itojun "%d", ntohs((u_short)port)); 1423 1.52 lukem lwidth = Aflag ? 18 : 22; 1424 1.52 lukem if (vflag && lwidth < (int)strlen(line)) 1425 1.52 lukem lwidth = strlen(line); 1426 1.52 lukem printf(" %-*.*s", lwidth, lwidth, line); 1427 1.1 itojun } 1428 1.1 itojun 1429 1.1 itojun /* 1430 1.1 itojun * Construct an Internet address representation. 1431 1.20 assar * If the numeric_addr has been supplied, give 1432 1.1 itojun * numeric value, otherwise try for symbolic name. 1433 1.1 itojun */ 1434 1.1 itojun 1435 1.1 itojun char * 1436 1.83 ozaki inet6name(const struct in6_addr *inp) 1437 1.1 itojun { 1438 1.56 dyoung char *cp; 1439 1.17 itojun static char line[NI_MAXHOST]; 1440 1.1 itojun struct hostent *hp; 1441 1.1 itojun static char domain[MAXHOSTNAMELEN + 1]; 1442 1.1 itojun static int first = 1; 1443 1.5 itojun char hbuf[NI_MAXHOST]; 1444 1.5 itojun struct sockaddr_in6 sin6; 1445 1.5 itojun const int niflag = NI_NUMERICHOST; 1446 1.1 itojun 1447 1.20 assar if (first && !numeric_addr) { 1448 1.1 itojun first = 0; 1449 1.1 itojun if (gethostname(domain, MAXHOSTNAMELEN) == 0 && 1450 1.24 itojun (cp = strchr(domain, '.'))) 1451 1.19 itojun (void) strlcpy(domain, cp + 1, sizeof(domain)); 1452 1.1 itojun else 1453 1.1 itojun domain[0] = 0; 1454 1.1 itojun } 1455 1.1 itojun cp = 0; 1456 1.83 ozaki if (!numeric_addr && !IN6_IS_ADDR_UNSPECIFIED(inp)) { 1457 1.83 ozaki hp = gethostbyaddr((const char *)inp, sizeof(*inp), AF_INET6); 1458 1.1 itojun if (hp) { 1459 1.24 itojun if ((cp = strchr(hp->h_name, '.')) && 1460 1.1 itojun !strcmp(cp + 1, domain)) 1461 1.1 itojun *cp = 0; 1462 1.1 itojun cp = hp->h_name; 1463 1.1 itojun } 1464 1.1 itojun } 1465 1.83 ozaki if (IN6_IS_ADDR_UNSPECIFIED(inp)) 1466 1.17 itojun strlcpy(line, "*", sizeof(line)); 1467 1.1 itojun else if (cp) 1468 1.17 itojun strlcpy(line, cp, sizeof(line)); 1469 1.17 itojun else { 1470 1.5 itojun memset(&sin6, 0, sizeof(sin6)); 1471 1.5 itojun sin6.sin6_len = sizeof(sin6); 1472 1.5 itojun sin6.sin6_family = AF_INET6; 1473 1.83 ozaki sin6.sin6_addr = *inp; 1474 1.80 msaitoh inet6_getscopeid(&sin6, 1475 1.80 msaitoh INET6_IS_ADDR_LINKLOCAL | INET6_IS_ADDR_MC_LINKLOCAL); 1476 1.5 itojun if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len, 1477 1.17 itojun hbuf, sizeof(hbuf), NULL, 0, niflag) != 0) 1478 1.19 itojun strlcpy(hbuf, "?", sizeof(hbuf)); 1479 1.17 itojun strlcpy(line, hbuf, sizeof(line)); 1480 1.5 itojun } 1481 1.80 msaitoh return line; 1482 1.1 itojun } 1483 1.1 itojun 1484 1.1 itojun /* 1485 1.1 itojun * Dump the contents of a TCP6 PCB. 1486 1.1 itojun */ 1487 1.1 itojun void 1488 1.66 christos tcp6_dump(u_long off, const char *name, u_long pcbaddr) 1489 1.1 itojun { 1490 1.66 christos callout_impl_t *ci; 1491 1.66 christos int i, hardticks; 1492 1.61 christos struct kinfo_pcb *pcblist; 1493 1.66 christos #ifdef TCP6 1494 1.66 christos #define mypcb tcp6cb 1495 1.66 christos #else 1496 1.66 christos #define mypcb tcpcb 1497 1.66 christos #endif 1498 1.61 christos size_t j, len; 1499 1.61 christos 1500 1.61 christos if (use_sysctl) 1501 1.80 msaitoh pcblist = getpcblist_sysctl(name, &len); 1502 1.61 christos else 1503 1.80 msaitoh pcblist = getpcblist_kmem(off, name, &len); 1504 1.61 christos 1505 1.61 christos for (j = 0; j < len; j++) 1506 1.61 christos if (pcblist[j].ki_ppcbaddr == pcbaddr) 1507 1.61 christos break; 1508 1.61 christos free(pcblist); 1509 1.61 christos 1510 1.61 christos if (j == len) 1511 1.61 christos errx(1, "0x%lx is not a valid pcb address", pcbaddr); 1512 1.1 itojun 1513 1.66 christos kread(pcbaddr, (char *)&mypcb, sizeof(mypcb)); 1514 1.66 christos hardticks = get_hardticks(); 1515 1.1 itojun 1516 1.1 itojun printf("TCP Protocol Control Block at 0x%08lx:\n\n", pcbaddr); 1517 1.1 itojun printf("Timers:\n"); 1518 1.66 christos for (i = 0; i < TCP6T_NTIMERS; i++) { 1519 1.67 christos char buf[128]; 1520 1.66 christos ci = (callout_impl_t *)&tcpcb.t_timer[i]; 1521 1.67 christos snprintb(buf, sizeof(buf), CALLOUT_FMT, ci->c_flags); 1522 1.67 christos printf("\t%s\t%s", tcptimers[i], buf); 1523 1.67 christos if (ci->c_flags & CALLOUT_PENDING) 1524 1.67 christos printf("\t%d\n", ci->c_time - hardticks); 1525 1.67 christos else 1526 1.67 christos printf("\n"); 1527 1.66 christos } 1528 1.1 itojun printf("\n\n"); 1529 1.1 itojun 1530 1.66 christos if (mypcb.t_state < 0 || mypcb.t_state >= TCP6_NSTATES) 1531 1.66 christos printf("State: %d", mypcb.t_state); 1532 1.1 itojun else 1533 1.66 christos printf("State: %s", tcp6states[mypcb.t_state]); 1534 1.83 ozaki printf(", flags 0x%x, inpcb 0x%lx\n\n", mypcb.t_flags, 1535 1.83 ozaki (u_long)mypcb.t_inpcb); 1536 1.66 christos 1537 1.66 christos printf("rxtshift %d, rxtcur %d, dupacks %d\n", mypcb.t_rxtshift, 1538 1.66 christos mypcb.t_rxtcur, mypcb.t_dupacks); 1539 1.66 christos #ifdef TCP6 1540 1.66 christos printf("peermaxseg %u, maxseg %u, force %d\n\n", mypcb.t_peermaxseg, 1541 1.66 christos mypcb.t_maxseg, mypcb.t_force); 1542 1.69 mlelstv #else 1543 1.80 msaitoh printf("peermss %u, ourmss %u, segsz %u, segqlen %u\n\n", 1544 1.69 mlelstv tcpcb.t_peermss, tcpcb.t_ourmss, tcpcb.t_segsz, tcpcb.t_segqlen); 1545 1.66 christos #endif 1546 1.1 itojun 1547 1.1 itojun printf("snd_una %u, snd_nxt %u, snd_up %u\n", 1548 1.66 christos mypcb.snd_una, mypcb.snd_nxt, mypcb.snd_up); 1549 1.4 bouyer printf("snd_wl1 %u, snd_wl2 %u, iss %u, snd_wnd %llu\n\n", 1550 1.66 christos mypcb.snd_wl1, mypcb.snd_wl2, mypcb.iss, 1551 1.66 christos (unsigned long long)mypcb.snd_wnd); 1552 1.4 bouyer 1553 1.4 bouyer printf("rcv_wnd %llu, rcv_nxt %u, rcv_up %u, irs %u\n\n", 1554 1.66 christos (unsigned long long)mypcb.rcv_wnd, mypcb.rcv_nxt, 1555 1.66 christos mypcb.rcv_up, mypcb.irs); 1556 1.4 bouyer 1557 1.4 bouyer printf("rcv_adv %u, snd_max %u, snd_cwnd %llu, snd_ssthresh %llu\n", 1558 1.66 christos mypcb.rcv_adv, mypcb.snd_max, (unsigned long long)mypcb.snd_cwnd, 1559 1.66 christos (unsigned long long)mypcb.snd_ssthresh); 1560 1.1 itojun 1561 1.66 christos #ifdef TCP6 1562 1.69 mlelstv printf("idle %d, rtt %d, " mypcb.t_idle, mypcb.t_rtt); 1563 1.69 mlelstv #else 1564 1.69 mlelstv printf("rcvtime %u, rtttime %u, ", tcpcb.t_rcvtime, tcpcb.t_rtttime); 1565 1.66 christos #endif 1566 1.69 mlelstv 1567 1.66 christos printf("rtseq %u, srtt %d, rttvar %d, rttmin %d, " 1568 1.66 christos "max_sndwnd %llu\n\n", mypcb.t_rtseq, 1569 1.66 christos mypcb.t_srtt, mypcb.t_rttvar, mypcb.t_rttmin, 1570 1.66 christos (unsigned long long)mypcb.max_sndwnd); 1571 1.1 itojun 1572 1.66 christos printf("oobflags %d, iobc %d, softerror %d\n\n", mypcb.t_oobflags, 1573 1.66 christos mypcb.t_iobc, mypcb.t_softerror); 1574 1.1 itojun 1575 1.1 itojun printf("snd_scale %d, rcv_scale %d, req_r_scale %d, req_s_scale %d\n", 1576 1.66 christos mypcb.snd_scale, mypcb.rcv_scale, mypcb.request_r_scale, 1577 1.66 christos mypcb.requested_s_scale); 1578 1.1 itojun printf("ts_recent %u, ts_regent_age %d, last_ack_sent %u\n", 1579 1.66 christos mypcb.ts_recent, mypcb.ts_recent_age, mypcb.last_ack_sent); 1580 1.1 itojun } 1581 1.1 itojun 1582 1.1 itojun #endif /*INET6*/ 1583