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