1 /* 2 * Copyright (c) 1983, 1988, 1993, 1995 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #if 0 35 #ifndef lint 36 static char sccsid[] = "@(#)inet.c 8.5 (Berkeley) 5/24/95"; 37 #endif /* not lint */ 38 #endif 39 40 #include <sys/cdefs.h> 41 __FBSDID("$FreeBSD$"); 42 43 #include <sys/param.h> 44 #include <sys/queue.h> 45 #include <sys/socket.h> 46 #include <sys/socketvar.h> 47 #include <sys/sysctl.h> 48 #include <sys/protosw.h> 49 50 #include <net/route.h> 51 #include <netinet/in.h> 52 #include <netinet/in_systm.h> 53 #include <netinet/ip.h> 54 #include <netinet/ip_carp.h> 55 #ifdef INET6 56 #include <netinet/ip6.h> 57 #endif /* INET6 */ 58 #include <netinet/in_pcb.h> 59 #include <netinet/ip_icmp.h> 60 #include <netinet/icmp_var.h> 61 #include <netinet/igmp_var.h> 62 #include <netinet/ip_var.h> 63 #include <netinet/pim_var.h> 64 #include <netinet/tcp.h> 65 #include <netinet/tcpip.h> 66 #include <netinet/tcp_seq.h> 67 #define TCPSTATES 68 #include <netinet/tcp_fsm.h> 69 #include <netinet/tcp_timer.h> 70 #include <netinet/tcp_var.h> 71 #include <netinet/tcp_debug.h> 72 #include <netinet/udp.h> 73 #include <netinet/udp_var.h> 74 75 #include <arpa/inet.h> 76 #include <err.h> 77 #include <errno.h> 78 #include <libutil.h> 79 #include <netdb.h> 80 #include <stdint.h> 81 #include <stdio.h> 82 #include <stdlib.h> 83 #include <string.h> 84 #include <unistd.h> 85 #include "netstat.h" 86 87 char *inetname (struct in_addr *); 88 void inetprint (struct in_addr *, int, const char *, int); 89 #ifdef INET6 90 static int udp_done, tcp_done; 91 #endif /* INET6 */ 92 93 /* 94 * Print a summary of connections related to an Internet 95 * protocol. For TCP, also give state of connection. 96 * Listening processes (aflag) are suppressed unless the 97 * -a (all) flag is specified. 98 */ 99 void 100 protopr(u_long proto, /* for sysctl version we pass proto # */ 101 const char *name, int af1) 102 { 103 int istcp; 104 static int first = 1; 105 char *buf; 106 const char *mibvar, *vchar; 107 struct tcpcb *tp = NULL; 108 struct inpcb *inp; 109 struct xinpgen *xig, *oxig; 110 struct xsocket *so; 111 size_t len; 112 113 istcp = 0; 114 switch (proto) { 115 case IPPROTO_TCP: 116 #ifdef INET6 117 if (tcp_done != 0) 118 return; 119 else 120 tcp_done = 1; 121 #endif 122 istcp = 1; 123 mibvar = "net.inet.tcp.pcblist"; 124 break; 125 case IPPROTO_UDP: 126 #ifdef INET6 127 if (udp_done != 0) 128 return; 129 else 130 udp_done = 1; 131 #endif 132 mibvar = "net.inet.udp.pcblist"; 133 break; 134 case IPPROTO_DIVERT: 135 mibvar = "net.inet.divert.pcblist"; 136 break; 137 default: 138 mibvar = "net.inet.raw.pcblist"; 139 break; 140 } 141 len = 0; 142 if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) { 143 if (errno != ENOENT) 144 warn("sysctl: %s", mibvar); 145 return; 146 } 147 if ((buf = malloc(len)) == 0) { 148 warnx("malloc %lu bytes", (u_long)len); 149 return; 150 } 151 if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) { 152 warn("sysctl: %s", mibvar); 153 free(buf); 154 return; 155 } 156 157 oxig = xig = (struct xinpgen *)buf; 158 for (xig = (struct xinpgen *)((char *)xig + xig->xig_len); 159 xig->xig_len > sizeof(struct xinpgen); 160 xig = (struct xinpgen *)((char *)xig + xig->xig_len)) { 161 if (istcp) { 162 tp = &((struct xtcpcb *)xig)->xt_tp; 163 inp = &((struct xtcpcb *)xig)->xt_inp; 164 so = &((struct xtcpcb *)xig)->xt_socket; 165 } else { 166 inp = &((struct xinpcb *)xig)->xi_inp; 167 so = &((struct xinpcb *)xig)->xi_socket; 168 } 169 170 /* Ignore sockets for protocols other than the desired one. */ 171 if (so->xso_protocol != (int)proto) 172 continue; 173 174 /* Ignore PCBs which were freed during copyout. */ 175 if (inp->inp_gencnt > oxig->xig_gen) 176 continue; 177 178 if ((af1 == AF_INET && (inp->inp_vflag & INP_IPV4) == 0) 179 #ifdef INET6 180 || (af1 == AF_INET6 && (inp->inp_vflag & INP_IPV6) == 0) 181 #endif /* INET6 */ 182 || (af1 == AF_UNSPEC && ((inp->inp_vflag & INP_IPV4) == 0 183 #ifdef INET6 184 && (inp->inp_vflag & 185 INP_IPV6) == 0 186 #endif /* INET6 */ 187 )) 188 ) 189 continue; 190 if (!aflag && 191 ( 192 (istcp && tp->t_state == TCPS_LISTEN) 193 || (af1 == AF_INET && 194 inet_lnaof(inp->inp_laddr) == INADDR_ANY) 195 #ifdef INET6 196 || (af1 == AF_INET6 && 197 IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) 198 #endif /* INET6 */ 199 || (af1 == AF_UNSPEC && 200 (((inp->inp_vflag & INP_IPV4) != 0 && 201 inet_lnaof(inp->inp_laddr) == INADDR_ANY) 202 #ifdef INET6 203 || ((inp->inp_vflag & INP_IPV6) != 0 && 204 IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) 205 #endif 206 )) 207 )) 208 continue; 209 210 if (first) { 211 if (!Lflag) { 212 printf("Active Internet connections"); 213 if (aflag) 214 printf(" (including servers)"); 215 } else 216 printf( 217 "Current listen queue sizes (qlen/incqlen/maxqlen)"); 218 putchar('\n'); 219 if (Aflag) 220 printf("%-8.8s ", "Socket"); 221 if (Lflag) 222 printf("%-5.5s %-14.14s %-22.22s\n", 223 "Proto", "Listen", "Local Address"); 224 else 225 printf((Aflag && !Wflag) ? 226 "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" : 227 "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n", 228 "Proto", "Recv-Q", "Send-Q", 229 "Local Address", "Foreign Address", 230 "(state)"); 231 first = 0; 232 } 233 if (Lflag && so->so_qlimit == 0) 234 continue; 235 if (Aflag) { 236 if (istcp) 237 printf("%8lx ", (u_long)inp->inp_ppcb); 238 else 239 printf("%8lx ", (u_long)so->so_pcb); 240 } 241 #ifdef INET6 242 if ((inp->inp_vflag & INP_IPV6) != 0) 243 vchar = ((inp->inp_vflag & INP_IPV4) != 0) 244 ? "46" : "6 "; 245 else 246 #endif 247 vchar = ((inp->inp_vflag & INP_IPV4) != 0) 248 ? "4 " : " "; 249 printf("%-3.3s%-2.2s ", name, vchar); 250 if (Lflag) { 251 char buf1[15]; 252 253 snprintf(buf1, 15, "%d/%d/%d", so->so_qlen, 254 so->so_incqlen, so->so_qlimit); 255 printf("%-14.14s ", buf1); 256 } else { 257 printf("%6u %6u ", 258 so->so_rcv.sb_cc, 259 so->so_snd.sb_cc); 260 } 261 if (numeric_port) { 262 if (inp->inp_vflag & INP_IPV4) { 263 inetprint(&inp->inp_laddr, (int)inp->inp_lport, 264 name, 1); 265 if (!Lflag) 266 inetprint(&inp->inp_faddr, 267 (int)inp->inp_fport, name, 1); 268 } 269 #ifdef INET6 270 else if (inp->inp_vflag & INP_IPV6) { 271 inet6print(&inp->in6p_laddr, 272 (int)inp->inp_lport, name, 1); 273 if (!Lflag) 274 inet6print(&inp->in6p_faddr, 275 (int)inp->inp_fport, name, 1); 276 } /* else nothing printed now */ 277 #endif /* INET6 */ 278 } else if (inp->inp_flags & INP_ANONPORT) { 279 if (inp->inp_vflag & INP_IPV4) { 280 inetprint(&inp->inp_laddr, (int)inp->inp_lport, 281 name, 1); 282 if (!Lflag) 283 inetprint(&inp->inp_faddr, 284 (int)inp->inp_fport, name, 0); 285 } 286 #ifdef INET6 287 else if (inp->inp_vflag & INP_IPV6) { 288 inet6print(&inp->in6p_laddr, 289 (int)inp->inp_lport, name, 1); 290 if (!Lflag) 291 inet6print(&inp->in6p_faddr, 292 (int)inp->inp_fport, name, 0); 293 } /* else nothing printed now */ 294 #endif /* INET6 */ 295 } else { 296 if (inp->inp_vflag & INP_IPV4) { 297 inetprint(&inp->inp_laddr, (int)inp->inp_lport, 298 name, 0); 299 if (!Lflag) 300 inetprint(&inp->inp_faddr, 301 (int)inp->inp_fport, name, 302 inp->inp_lport != 303 inp->inp_fport); 304 } 305 #ifdef INET6 306 else if (inp->inp_vflag & INP_IPV6) { 307 inet6print(&inp->in6p_laddr, 308 (int)inp->inp_lport, name, 0); 309 if (!Lflag) 310 inet6print(&inp->in6p_faddr, 311 (int)inp->inp_fport, name, 312 inp->inp_lport != 313 inp->inp_fport); 314 } /* else nothing printed now */ 315 #endif /* INET6 */ 316 } 317 if (istcp && !Lflag) { 318 if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES) 319 printf("%d", tp->t_state); 320 else { 321 printf("%s", tcpstates[tp->t_state]); 322 #if defined(TF_NEEDSYN) && defined(TF_NEEDFIN) 323 /* Show T/TCP `hidden state' */ 324 if (tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) 325 putchar('*'); 326 #endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */ 327 } 328 } 329 putchar('\n'); 330 } 331 if (xig != oxig && xig->xig_gen != oxig->xig_gen) { 332 if (oxig->xig_count > xig->xig_count) { 333 printf("Some %s sockets may have been deleted.\n", 334 name); 335 } else if (oxig->xig_count < xig->xig_count) { 336 printf("Some %s sockets may have been created.\n", 337 name); 338 } else { 339 printf("Some %s sockets may have been created or deleted.\n", 340 name); 341 } 342 } 343 free(buf); 344 } 345 346 /* 347 * Dump TCP statistics structure. 348 */ 349 void 350 tcp_stats(u_long off __unused, const char *name, int af1 __unused) 351 { 352 struct tcpstat tcpstat, zerostat; 353 size_t len = sizeof tcpstat; 354 355 if (zflag) 356 memset(&zerostat, 0, len); 357 if (sysctlbyname("net.inet.tcp.stats", &tcpstat, &len, 358 zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { 359 warn("sysctl: net.inet.tcp.stats"); 360 return; 361 } 362 363 #ifdef INET6 364 if (tcp_done != 0) 365 return; 366 else 367 tcp_done = 1; 368 #endif 369 370 printf ("%s:\n", name); 371 372 #define p(f, m) if (tcpstat.f || sflag <= 1) \ 373 printf(m, tcpstat.f, plural(tcpstat.f)) 374 #define p1a(f, m) if (tcpstat.f || sflag <= 1) \ 375 printf(m, tcpstat.f) 376 #define p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \ 377 printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2)) 378 #define p2a(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \ 379 printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2) 380 #define p3(f, m) if (tcpstat.f || sflag <= 1) \ 381 printf(m, tcpstat.f, plurales(tcpstat.f)) 382 383 p(tcps_sndtotal, "\t%lu packet%s sent\n"); 384 p2(tcps_sndpack,tcps_sndbyte, 385 "\t\t%lu data packet%s (%lu byte%s)\n"); 386 p2(tcps_sndrexmitpack, tcps_sndrexmitbyte, 387 "\t\t%lu data packet%s (%lu byte%s) retransmitted\n"); 388 p(tcps_sndrexmitbad, 389 "\t\t%lu data packet%s unnecessarily retransmitted\n"); 390 p(tcps_mturesent, "\t\t%lu resend%s initiated by MTU discovery\n"); 391 p2a(tcps_sndacks, tcps_delack, 392 "\t\t%lu ack-only packet%s (%lu delayed)\n"); 393 p(tcps_sndurg, "\t\t%lu URG only packet%s\n"); 394 p(tcps_sndprobe, "\t\t%lu window probe packet%s\n"); 395 p(tcps_sndwinup, "\t\t%lu window update packet%s\n"); 396 p(tcps_sndctrl, "\t\t%lu control packet%s\n"); 397 p(tcps_rcvtotal, "\t%lu packet%s received\n"); 398 p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%lu ack%s (for %lu byte%s)\n"); 399 p(tcps_rcvdupack, "\t\t%lu duplicate ack%s\n"); 400 p(tcps_rcvacktoomuch, "\t\t%lu ack%s for unsent data\n"); 401 p2(tcps_rcvpack, tcps_rcvbyte, 402 "\t\t%lu packet%s (%lu byte%s) received in-sequence\n"); 403 p2(tcps_rcvduppack, tcps_rcvdupbyte, 404 "\t\t%lu completely duplicate packet%s (%lu byte%s)\n"); 405 p(tcps_pawsdrop, "\t\t%lu old duplicate packet%s\n"); 406 p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte, 407 "\t\t%lu packet%s with some dup. data (%lu byte%s duped)\n"); 408 p2(tcps_rcvoopack, tcps_rcvoobyte, 409 "\t\t%lu out-of-order packet%s (%lu byte%s)\n"); 410 p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin, 411 "\t\t%lu packet%s (%lu byte%s) of data after window\n"); 412 p(tcps_rcvwinprobe, "\t\t%lu window probe%s\n"); 413 p(tcps_rcvwinupd, "\t\t%lu window update packet%s\n"); 414 p(tcps_rcvafterclose, "\t\t%lu packet%s received after close\n"); 415 p(tcps_rcvbadsum, "\t\t%lu discarded for bad checksum%s\n"); 416 p(tcps_rcvbadoff, "\t\t%lu discarded for bad header offset field%s\n"); 417 p1a(tcps_rcvshort, "\t\t%lu discarded because packet too short\n"); 418 p1a(tcps_rcvmemdrop, "\t\t%lu discarded due to memory problems\n"); 419 p(tcps_connattempt, "\t%lu connection request%s\n"); 420 p(tcps_accepts, "\t%lu connection accept%s\n"); 421 p(tcps_badsyn, "\t%lu bad connection attempt%s\n"); 422 p(tcps_listendrop, "\t%lu listen queue overflow%s\n"); 423 p(tcps_badrst, "\t%lu ignored RSTs in the window%s\n"); 424 p(tcps_connects, "\t%lu connection%s established (including accepts)\n"); 425 p2(tcps_closed, tcps_drops, 426 "\t%lu connection%s closed (including %lu drop%s)\n"); 427 p(tcps_cachedrtt, "\t\t%lu connection%s updated cached RTT on close\n"); 428 p(tcps_cachedrttvar, 429 "\t\t%lu connection%s updated cached RTT variance on close\n"); 430 p(tcps_cachedssthresh, 431 "\t\t%lu connection%s updated cached ssthresh on close\n"); 432 p(tcps_conndrops, "\t%lu embryonic connection%s dropped\n"); 433 p2(tcps_rttupdated, tcps_segstimed, 434 "\t%lu segment%s updated rtt (of %lu attempt%s)\n"); 435 p(tcps_rexmttimeo, "\t%lu retransmit timeout%s\n"); 436 p(tcps_timeoutdrop, "\t\t%lu connection%s dropped by rexmit timeout\n"); 437 p(tcps_persisttimeo, "\t%lu persist timeout%s\n"); 438 p(tcps_persistdrop, "\t\t%lu connection%s dropped by persist timeout\n"); 439 p(tcps_finwait2_drops, "\t%lu Connection%s (fin_wait_2) dropped because of timeout\n"); 440 p(tcps_keeptimeo, "\t%lu keepalive timeout%s\n"); 441 p(tcps_keepprobe, "\t\t%lu keepalive probe%s sent\n"); 442 p(tcps_keepdrops, "\t\t%lu connection%s dropped by keepalive\n"); 443 p(tcps_predack, "\t%lu correct ACK header prediction%s\n"); 444 p(tcps_preddat, "\t%lu correct data packet header prediction%s\n"); 445 446 p(tcps_sc_added, "\t%lu syncache entrie%s added\n"); 447 p1a(tcps_sc_retransmitted, "\t\t%lu retransmitted\n"); 448 p1a(tcps_sc_dupsyn, "\t\t%lu dupsyn\n"); 449 p1a(tcps_sc_dropped, "\t\t%lu dropped\n"); 450 p1a(tcps_sc_completed, "\t\t%lu completed\n"); 451 p1a(tcps_sc_bucketoverflow, "\t\t%lu bucket overflow\n"); 452 p1a(tcps_sc_cacheoverflow, "\t\t%lu cache overflow\n"); 453 p1a(tcps_sc_reset, "\t\t%lu reset\n"); 454 p1a(tcps_sc_stale, "\t\t%lu stale\n"); 455 p1a(tcps_sc_aborted, "\t\t%lu aborted\n"); 456 p1a(tcps_sc_badack, "\t\t%lu badack\n"); 457 p1a(tcps_sc_unreach, "\t\t%lu unreach\n"); 458 p(tcps_sc_zonefail, "\t\t%lu zone failure%s\n"); 459 p(tcps_sc_sendcookie, "\t%lu cookie%s sent\n"); 460 p(tcps_sc_recvcookie, "\t%lu cookie%s received\n"); 461 462 p(tcps_sack_recovery_episode, "\t%lu SACK recovery episode%s\n"); 463 p(tcps_sack_rexmits, 464 "\t%lu segment rexmit%s in SACK recovery episodes\n"); 465 p(tcps_sack_rexmit_bytes, 466 "\t%lu byte rexmit%s in SACK recovery episodes\n"); 467 p(tcps_sack_rcv_blocks, 468 "\t%lu SACK option%s (SACK blocks) received\n"); 469 p(tcps_sack_send_blocks, "\t%lu SACK option%s (SACK blocks) sent\n"); 470 p1a(tcps_sack_sboverflow, "\t%lu SACK scoreboard overflow\n"); 471 472 #undef p 473 #undef p1a 474 #undef p2 475 #undef p2a 476 #undef p3 477 } 478 479 /* 480 * Dump UDP statistics structure. 481 */ 482 void 483 udp_stats(u_long off __unused, const char *name, int af1 __unused) 484 { 485 struct udpstat udpstat, zerostat; 486 size_t len = sizeof udpstat; 487 u_long delivered; 488 489 if (zflag) 490 memset(&zerostat, 0, len); 491 if (sysctlbyname("net.inet.udp.stats", &udpstat, &len, 492 zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { 493 warn("sysctl: net.inet.udp.stats"); 494 return; 495 } 496 497 #ifdef INET6 498 if (udp_done != 0) 499 return; 500 else 501 udp_done = 1; 502 #endif 503 504 printf("%s:\n", name); 505 #define p(f, m) if (udpstat.f || sflag <= 1) \ 506 printf(m, udpstat.f, plural(udpstat.f)) 507 #define p1a(f, m) if (udpstat.f || sflag <= 1) \ 508 printf(m, udpstat.f) 509 p(udps_ipackets, "\t%lu datagram%s received\n"); 510 p1a(udps_hdrops, "\t%lu with incomplete header\n"); 511 p1a(udps_badlen, "\t%lu with bad data length field\n"); 512 p1a(udps_badsum, "\t%lu with bad checksum\n"); 513 p1a(udps_nosum, "\t%lu with no checksum\n"); 514 p1a(udps_noport, "\t%lu dropped due to no socket\n"); 515 p(udps_noportbcast, 516 "\t%lu broadcast/multicast datagram%s dropped due to no socket\n"); 517 p1a(udps_fullsock, "\t%lu dropped due to full socket buffers\n"); 518 p1a(udpps_pcbhashmiss, "\t%lu not for hashed pcb\n"); 519 delivered = udpstat.udps_ipackets - 520 udpstat.udps_hdrops - 521 udpstat.udps_badlen - 522 udpstat.udps_badsum - 523 udpstat.udps_noport - 524 udpstat.udps_noportbcast - 525 udpstat.udps_fullsock; 526 if (delivered || sflag <= 1) 527 printf("\t%lu delivered\n", delivered); 528 p(udps_opackets, "\t%lu datagram%s output\n"); 529 #undef p 530 #undef p1a 531 } 532 533 /* 534 * Dump CARP statistics structure. 535 */ 536 void 537 carp_stats(u_long off __unused, const char *name, int af1 __unused) 538 { 539 struct carpstats carpstat, zerostat; 540 size_t len = sizeof(struct carpstats); 541 542 if (zflag) 543 memset(&zerostat, 0, len); 544 if (sysctlbyname("net.inet.carp.stats", &carpstat, &len, 545 zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { 546 if (errno != ENOENT) 547 warn("sysctl: net.inet.carp.stats"); 548 return; 549 } 550 551 printf("%s:\n", name); 552 553 #define p(f, m) if (carpstat.f || sflag <= 1) \ 554 printf(m, (uintmax_t)carpstat.f, plural(carpstat.f)) 555 #define p2(f, m) if (carpstat.f || sflag <= 1) \ 556 printf(m, (uintmax_t)carpstat.f) 557 558 p(carps_ipackets, "\t%ju packet%s received (IPv4)\n"); 559 p(carps_ipackets6, "\t%ju packet%s received (IPv6)\n"); 560 p(carps_badttl, "\t\t%ju packet%s discarded for wrong TTL\n"); 561 p(carps_hdrops, "\t\t%ju packet%s shorter than header\n"); 562 p(carps_badsum, "\t\t%ju discarded for bad checksum%s\n"); 563 p(carps_badver, "\t\t%ju discarded packet%s with a bad version\n"); 564 p2(carps_badlen, "\t\t%ju discarded because packet too short\n"); 565 p2(carps_badauth, "\t\t%ju discarded for bad authentication\n"); 566 p2(carps_badvhid, "\t\t%ju discarded for bad vhid\n"); 567 p2(carps_badaddrs, "\t\t%ju discarded because of a bad address list\n"); 568 p(carps_opackets, "\t%ju packet%s sent (IPv4)\n"); 569 p(carps_opackets6, "\t%ju packet%s sent (IPv6)\n"); 570 p2(carps_onomem, "\t\t%ju send failed due to mbuf memory error\n"); 571 #if notyet 572 p(carps_ostates, "\t\t%s state update%s sent\n"); 573 #endif 574 #undef p 575 #undef p2 576 } 577 578 /* 579 * Dump IP statistics structure. 580 */ 581 void 582 ip_stats(u_long off __unused, const char *name, int af1 __unused) 583 { 584 struct ipstat ipstat, zerostat; 585 size_t len = sizeof ipstat; 586 587 if (zflag) 588 memset(&zerostat, 0, len); 589 if (sysctlbyname("net.inet.ip.stats", &ipstat, &len, 590 zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { 591 warn("sysctl: net.inet.ip.stats"); 592 return; 593 } 594 595 printf("%s:\n", name); 596 597 #define p(f, m) if (ipstat.f || sflag <= 1) \ 598 printf(m, ipstat.f, plural(ipstat.f)) 599 #define p1a(f, m) if (ipstat.f || sflag <= 1) \ 600 printf(m, ipstat.f) 601 602 p(ips_total, "\t%lu total packet%s received\n"); 603 p(ips_badsum, "\t%lu bad header checksum%s\n"); 604 p1a(ips_toosmall, "\t%lu with size smaller than minimum\n"); 605 p1a(ips_tooshort, "\t%lu with data size < data length\n"); 606 p1a(ips_toolong, "\t%lu with ip length > max ip packet size\n"); 607 p1a(ips_badhlen, "\t%lu with header length < data size\n"); 608 p1a(ips_badlen, "\t%lu with data length < header length\n"); 609 p1a(ips_badoptions, "\t%lu with bad options\n"); 610 p1a(ips_badvers, "\t%lu with incorrect version number\n"); 611 p(ips_fragments, "\t%lu fragment%s received\n"); 612 p(ips_fragdropped, "\t%lu fragment%s dropped (dup or out of space)\n"); 613 p(ips_fragtimeout, "\t%lu fragment%s dropped after timeout\n"); 614 p(ips_reassembled, "\t%lu packet%s reassembled ok\n"); 615 p(ips_delivered, "\t%lu packet%s for this host\n"); 616 p(ips_noproto, "\t%lu packet%s for unknown/unsupported protocol\n"); 617 p(ips_forward, "\t%lu packet%s forwarded"); 618 p(ips_fastforward, " (%lu packet%s fast forwarded)"); 619 if (ipstat.ips_forward || sflag <= 1) 620 putchar('\n'); 621 p(ips_cantforward, "\t%lu packet%s not forwardable\n"); 622 p(ips_notmember, 623 "\t%lu packet%s received for unknown multicast group\n"); 624 p(ips_redirectsent, "\t%lu redirect%s sent\n"); 625 p(ips_localout, "\t%lu packet%s sent from this host\n"); 626 p(ips_rawout, "\t%lu packet%s sent with fabricated ip header\n"); 627 p(ips_odropped, 628 "\t%lu output packet%s dropped due to no bufs, etc.\n"); 629 p(ips_noroute, "\t%lu output packet%s discarded due to no route\n"); 630 p(ips_fragmented, "\t%lu output datagram%s fragmented\n"); 631 p(ips_ofragments, "\t%lu fragment%s created\n"); 632 p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n"); 633 p(ips_nogif, "\t%lu tunneling packet%s that can't find gif\n"); 634 p(ips_badaddr, "\t%lu datagram%s with bad address in header\n"); 635 #undef p 636 #undef p1a 637 } 638 639 static const char *icmpnames[] = { 640 "echo reply", 641 "#1", 642 "#2", 643 "destination unreachable", 644 "source quench", 645 "routing redirect", 646 "#6", 647 "#7", 648 "echo", 649 "router advertisement", 650 "router solicitation", 651 "time exceeded", 652 "parameter problem", 653 "time stamp", 654 "time stamp reply", 655 "information request", 656 "information request reply", 657 "address mask request", 658 "address mask reply", 659 }; 660 661 /* 662 * Dump ICMP statistics. 663 */ 664 void 665 icmp_stats(u_long off __unused, const char *name, int af1 __unused) 666 { 667 struct icmpstat icmpstat, zerostat; 668 int i, first; 669 int mib[4]; /* CTL_NET + PF_INET + IPPROTO_ICMP + req */ 670 size_t len; 671 672 mib[0] = CTL_NET; 673 mib[1] = PF_INET; 674 mib[2] = IPPROTO_ICMP; 675 mib[3] = ICMPCTL_STATS; 676 677 len = sizeof icmpstat; 678 if (zflag) 679 memset(&zerostat, 0, len); 680 if (sysctl(mib, 4, &icmpstat, &len, 681 zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { 682 warn("sysctl: net.inet.icmp.stats"); 683 return; 684 } 685 686 printf("%s:\n", name); 687 688 #define p(f, m) if (icmpstat.f || sflag <= 1) \ 689 printf(m, icmpstat.f, plural(icmpstat.f)) 690 #define p1a(f, m) if (icmpstat.f || sflag <= 1) \ 691 printf(m, icmpstat.f) 692 #define p2(f, m) if (icmpstat.f || sflag <= 1) \ 693 printf(m, icmpstat.f, plurales(icmpstat.f)) 694 695 p(icps_error, "\t%lu call%s to icmp_error\n"); 696 p(icps_oldicmp, 697 "\t%lu error%s not generated in response to an icmp message\n"); 698 for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) 699 if (icmpstat.icps_outhist[i] != 0) { 700 if (first) { 701 printf("\tOutput histogram:\n"); 702 first = 0; 703 } 704 printf("\t\t%s: %lu\n", icmpnames[i], 705 icmpstat.icps_outhist[i]); 706 } 707 p(icps_badcode, "\t%lu message%s with bad code fields\n"); 708 p(icps_tooshort, "\t%lu message%s < minimum length\n"); 709 p(icps_checksum, "\t%lu bad checksum%s\n"); 710 p(icps_badlen, "\t%lu message%s with bad length\n"); 711 p1a(icps_bmcastecho, "\t%lu multicast echo requests ignored\n"); 712 p1a(icps_bmcasttstamp, "\t%lu multicast timestamp requests ignored\n"); 713 for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) 714 if (icmpstat.icps_inhist[i] != 0) { 715 if (first) { 716 printf("\tInput histogram:\n"); 717 first = 0; 718 } 719 printf("\t\t%s: %lu\n", icmpnames[i], 720 icmpstat.icps_inhist[i]); 721 } 722 p(icps_reflect, "\t%lu message response%s generated\n"); 723 p2(icps_badaddr, "\t%lu invalid return address%s\n"); 724 p(icps_noroute, "\t%lu no return route%s\n"); 725 #undef p 726 #undef p1a 727 #undef p2 728 mib[3] = ICMPCTL_MASKREPL; 729 len = sizeof i; 730 if (sysctl(mib, 4, &i, &len, (void *)0, 0) < 0) 731 return; 732 printf("\tICMP address mask responses are %sabled\n", 733 i ? "en" : "dis"); 734 } 735 736 /* 737 * Dump IGMP statistics structure. 738 */ 739 void 740 igmp_stats(u_long off __unused, const char *name, int af1 __unused) 741 { 742 struct igmpstat igmpstat, zerostat; 743 size_t len = sizeof igmpstat; 744 745 if (zflag) 746 memset(&zerostat, 0, len); 747 if (sysctlbyname("net.inet.igmp.stats", &igmpstat, &len, 748 zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { 749 warn("sysctl: net.inet.igmp.stats"); 750 return; 751 } 752 753 printf("%s:\n", name); 754 755 #define p(f, m) if (igmpstat.f || sflag <= 1) \ 756 printf(m, igmpstat.f, plural(igmpstat.f)) 757 #define py(f, m) if (igmpstat.f || sflag <= 1) \ 758 printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y") 759 p(igps_rcv_total, "\t%u message%s received\n"); 760 p(igps_rcv_tooshort, "\t%u message%s received with too few bytes\n"); 761 p(igps_rcv_badsum, "\t%u message%s received with bad checksum\n"); 762 py(igps_rcv_queries, "\t%u membership quer%s received\n"); 763 py(igps_rcv_badqueries, "\t%u membership quer%s received with invalid field(s)\n"); 764 p(igps_rcv_reports, "\t%u membership report%s received\n"); 765 p(igps_rcv_badreports, "\t%u membership report%s received with invalid field(s)\n"); 766 p(igps_rcv_ourreports, "\t%u membership report%s received for groups to which we belong\n"); 767 p(igps_snd_reports, "\t%u membership report%s sent\n"); 768 #undef p 769 #undef py 770 } 771 772 /* 773 * Dump PIM statistics structure. 774 */ 775 void 776 pim_stats(u_long off __unused, const char *name, int af1 __unused) 777 { 778 struct pimstat pimstat, zerostat; 779 size_t len = sizeof pimstat; 780 781 if (zflag) 782 memset(&zerostat, 0, len); 783 if (sysctlbyname("net.inet.pim.stats", &pimstat, &len, 784 zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { 785 if (errno != ENOENT) 786 warn("sysctl: net.inet.pim.stats"); 787 return; 788 } 789 790 printf("%s:\n", name); 791 792 #define p(f, m) if (pimstat.f || sflag <= 1) \ 793 printf(m, (uintmax_t)pimstat.f, plural(pimstat.f)) 794 #define py(f, m) if (pimstat.f || sflag <= 1) \ 795 printf(m, (uintmax_t)pimstat.f, pimstat.f != 1 ? "ies" : "y") 796 p(pims_rcv_total_msgs, "\t%ju message%s received\n"); 797 p(pims_rcv_total_bytes, "\t%ju byte%s received\n"); 798 p(pims_rcv_tooshort, "\t%ju message%s received with too few bytes\n"); 799 p(pims_rcv_badsum, "\t%ju message%s received with bad checksum\n"); 800 p(pims_rcv_badversion, "\t%ju message%s received with bad version\n"); 801 p(pims_rcv_registers_msgs, "\t%ju data register message%s received\n"); 802 p(pims_rcv_registers_bytes, "\t%ju data register byte%s received\n"); 803 p(pims_rcv_registers_wrongiif, "\t%ju data register message%s received on wrong iif\n"); 804 p(pims_rcv_badregisters, "\t%ju bad register%s received\n"); 805 p(pims_snd_registers_msgs, "\t%ju data register message%s sent\n"); 806 p(pims_snd_registers_bytes, "\t%ju data register byte%s sent\n"); 807 #undef p 808 #undef py 809 } 810 811 /* 812 * Pretty print an Internet address (net address + port). 813 */ 814 void 815 inetprint(struct in_addr *in, int port, const char *proto, int num_port) 816 { 817 struct servent *sp = 0; 818 char line[80], *cp; 819 int width; 820 821 if (Wflag) 822 sprintf(line, "%s.", inetname(in)); 823 else 824 sprintf(line, "%.*s.", (Aflag && !num_port) ? 12 : 16, inetname(in)); 825 cp = index(line, '\0'); 826 if (!num_port && port) 827 sp = getservbyport((int)port, proto); 828 if (sp || port == 0) 829 sprintf(cp, "%.15s ", sp ? sp->s_name : "*"); 830 else 831 sprintf(cp, "%d ", ntohs((u_short)port)); 832 width = (Aflag && !Wflag) ? 18 : 22; 833 if (Wflag) 834 printf("%-*s ", width, line); 835 else 836 printf("%-*.*s ", width, width, line); 837 } 838 839 /* 840 * Construct an Internet address representation. 841 * If numeric_addr has been supplied, give 842 * numeric value, otherwise try for symbolic name. 843 */ 844 char * 845 inetname(struct in_addr *inp) 846 { 847 char *cp; 848 static char line[MAXHOSTNAMELEN]; 849 struct hostent *hp; 850 struct netent *np; 851 852 cp = 0; 853 if (!numeric_addr && inp->s_addr != INADDR_ANY) { 854 int net = inet_netof(*inp); 855 int lna = inet_lnaof(*inp); 856 857 if (lna == INADDR_ANY) { 858 np = getnetbyaddr(net, AF_INET); 859 if (np) 860 cp = np->n_name; 861 } 862 if (cp == 0) { 863 hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET); 864 if (hp) { 865 cp = hp->h_name; 866 trimdomain(cp, strlen(cp)); 867 } 868 } 869 } 870 if (inp->s_addr == INADDR_ANY) 871 strcpy(line, "*"); 872 else if (cp) { 873 strncpy(line, cp, sizeof(line) - 1); 874 line[sizeof(line) - 1] = '\0'; 875 } else { 876 inp->s_addr = ntohl(inp->s_addr); 877 #define C(x) ((u_int)((x) & 0xff)) 878 sprintf(line, "%u.%u.%u.%u", C(inp->s_addr >> 24), 879 C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr)); 880 } 881 return (line); 882 } 883