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