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