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 CPU_STATS_FUNC(udp, struct udpstat); 392 393 /* 394 * Dump TCP statistics structure. 395 */ 396 void 397 tcp_stats(u_long off __unused, const char *name, int af1 __unused) 398 { 399 struct tcp_stats tcpstat, *stattmp; 400 struct tcp_stats zerostat[SMP_MAXCPU]; 401 size_t len = sizeof(struct tcp_stats) * SMP_MAXCPU; 402 int cpucnt; 403 404 if (zflag) 405 memset(zerostat, 0, len); 406 407 if ((stattmp = malloc(len)) == NULL) { 408 return; 409 } else { 410 if (sysctlbyname("net.inet.tcp.stats", stattmp, &len, 411 zflag ? zerostat : NULL, zflag ? len : 0) < 0) { 412 warn("sysctl: net.inet.tcp.stats"); 413 free(stattmp); 414 return; 415 } else { 416 if ((stattmp = realloc(stattmp, len)) == NULL) { 417 warn("tcp_stats"); 418 return; 419 } 420 } 421 } 422 cpucnt = len / sizeof(struct tcp_stats); 423 tcp_stats_agg(stattmp, &tcpstat, cpucnt); 424 425 #ifdef INET6 426 if (tcp_done != 0) 427 return; 428 else 429 tcp_done = 1; 430 #endif 431 432 printf ("%s:\n", name); 433 434 #define p(f, m) if (tcpstat.f || sflag <= 1) \ 435 printf(m, tcpstat.f, plural(tcpstat.f)) 436 #define p1a(f, m) if (tcpstat.f || sflag <= 1) \ 437 printf(m, tcpstat.f) 438 #define p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \ 439 printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2)) 440 #define p2a(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \ 441 printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2) 442 #define p3(f, m) if (tcpstat.f || sflag <= 1) \ 443 printf(m, tcpstat.f, plurales(tcpstat.f)) 444 445 p(tcps_sndtotal, "\t%lu packet%s sent\n"); 446 p2(tcps_sndpack,tcps_sndbyte, 447 "\t\t%lu data packet%s (%lu byte%s)\n"); 448 p2(tcps_sndrexmitpack, tcps_sndrexmitbyte, 449 "\t\t%lu data packet%s (%lu byte%s) retransmitted\n"); 450 p2(tcps_sndsackrtopack, tcps_sndsackrtobyte, 451 "\t\t%lu data packet%s (%lu byte%s) retransmitted by SACK\n"); 452 p2(tcps_sndsackpack, tcps_sndsackbyte, 453 "\t\t%lu data packet%s (%lu byte%s) sent by SACK recovery\n"); 454 p2(tcps_sackrescue, tcps_sackrescue_try, 455 "\t\t%lu SACK rescue packet%s sent (of %lu attempt%s)\n"); 456 p2a(tcps_sndfastrexmit, tcps_sndearlyrexmit, 457 "\t\t%lu Fast Retransmit%s (%lu early)\n"); 458 p(tcps_sndlimited, "\t\t%lu packet%s sent by Limited Transmit\n"); 459 p2(tcps_sndrtobad, tcps_eifelresponse, 460 "\t\t%lu spurious RTO retransmit%s (%lu Eifel-response%s)\n"); 461 p2a(tcps_sndfastrexmitbad, tcps_sndearlyrexmitbad, 462 "\t\t%lu spurious Fast Retransmit%s (%lu early)\n"); 463 p2a(tcps_eifeldetected, tcps_rttcantdetect, 464 "\t\t%lu Eifel-detected spurious retransmit%s (%lu non-RTT)\n"); 465 p(tcps_rttdetected, "\t\t%lu RTT-detected spurious retransmit%s\n"); 466 p(tcps_mturesent, "\t\t%lu resend%s initiated by MTU discovery\n"); 467 p(tcps_sndsackopt, "\t\t%lu SACK option%s sent\n"); 468 p(tcps_snddsackopt, "\t\t%lu D-SACK option%s sent\n"); 469 p2a(tcps_sndacks, tcps_delack, 470 "\t\t%lu ack-only packet%s (%lu delayed)\n"); 471 p(tcps_sndurg, "\t\t%lu URG only packet%s\n"); 472 p(tcps_sndprobe, "\t\t%lu window probe packet%s\n"); 473 p(tcps_sndwinup, "\t\t%lu window update packet%s\n"); 474 p(tcps_sndctrl, "\t\t%lu control packet%s\n"); 475 p(tcps_rcvtotal, "\t%lu packet%s received\n"); 476 p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%lu ack%s (for %lu byte%s)\n"); 477 p(tcps_rcvdupack, "\t\t%lu duplicate ack%s\n"); 478 p(tcps_rcvacktoomuch, "\t\t%lu ack%s for unsent data\n"); 479 p2(tcps_rcvpack, tcps_rcvbyte, 480 "\t\t%lu packet%s (%lu byte%s) received in-sequence\n"); 481 p2(tcps_rcvduppack, tcps_rcvdupbyte, 482 "\t\t%lu completely duplicate packet%s (%lu byte%s)\n"); 483 p2(tcps_pawsdrop, tcps_pawsaccept, 484 "\t\t%lu old duplicate packet%s (%lu packet%s accepted)\n"); 485 p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte, 486 "\t\t%lu packet%s with some dup. data (%lu byte%s duped)\n"); 487 p2(tcps_rcvoopack, tcps_rcvoobyte, 488 "\t\t%lu out-of-order packet%s (%lu byte%s)\n"); 489 p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin, 490 "\t\t%lu packet%s (%lu byte%s) of data after window\n"); 491 p(tcps_rcvwinprobe, "\t\t%lu window probe%s\n"); 492 p(tcps_rcvwinupd, "\t\t%lu window update packet%s\n"); 493 p(tcps_rcvafterclose, "\t\t%lu packet%s received after close\n"); 494 p(tcps_rcvbadsum, "\t\t%lu discarded for bad checksum%s\n"); 495 p(tcps_rcvbadoff, "\t\t%lu discarded for bad header offset field%s\n"); 496 p1a(tcps_rcvshort, "\t\t%lu discarded because packet too short\n"); 497 p(tcps_rcvbadsackopt, "\t\t%lu bad SACK option%s\n"); 498 p1a(tcps_sackrenege, "\t\t%lu other side reneged\n"); 499 p(tcps_connattempt, "\t%lu connection request%s\n"); 500 p(tcps_accepts, "\t%lu connection accept%s\n"); 501 p(tcps_badsyn, "\t%lu bad connection attempt%s\n"); 502 p(tcps_listendrop, "\t%lu listen queue overflow%s\n"); 503 p(tcps_connects, "\t%lu connection%s established (including accepts)\n"); 504 p2(tcps_closed, tcps_drops, 505 "\t%lu connection%s closed (including %lu drop%s)\n"); 506 p(tcps_cachedrtt, "\t\t%lu connection%s updated cached RTT on close\n"); 507 p(tcps_cachedrttvar, 508 "\t\t%lu connection%s updated cached RTT variance on close\n"); 509 p(tcps_cachedssthresh, 510 "\t\t%lu connection%s updated cached ssthresh on close\n"); 511 p(tcps_conndrops, "\t%lu embryonic connection%s dropped\n"); 512 p2(tcps_rttupdated, tcps_segstimed, 513 "\t%lu segment%s updated rtt (of %lu attempt%s)\n"); 514 p(tcps_rexmttimeo, "\t%lu retransmit timeout%s\n"); 515 p(tcps_timeoutdrop, "\t\t%lu connection%s dropped by rexmit timeout\n"); 516 p(tcps_persisttimeo, "\t%lu persist timeout%s\n"); 517 p(tcps_persistdrop, "\t\t%lu connection%s dropped by persist timeout\n"); 518 p(tcps_keeptimeo, "\t%lu keepalive timeout%s\n"); 519 p(tcps_keepprobe, "\t\t%lu keepalive probe%s sent\n"); 520 p(tcps_keepdrops, "\t\t%lu connection%s dropped by keepalive\n"); 521 p(tcps_predack, "\t%lu correct ACK header prediction%s\n"); 522 p(tcps_preddat, "\t%lu correct data packet header prediction%s\n"); 523 p(tcps_sndidle, "\t%lu send idle%s\n"); 524 525 p1a(tcps_sc_added, "\t%lu syncache entries added\n"); 526 p1a(tcps_sc_retransmitted, "\t\t%lu retransmitted\n"); 527 p1a(tcps_sc_dupsyn, "\t\t%lu dupsyn\n"); 528 p1a(tcps_sc_dropped, "\t\t%lu dropped\n"); 529 p1a(tcps_sc_completed, "\t\t%lu completed\n"); 530 p1a(tcps_sc_bucketoverflow, "\t\t%lu bucket overflow\n"); 531 p1a(tcps_sc_cacheoverflow, "\t\t%lu cache overflow\n"); 532 p1a(tcps_sc_reset, "\t\t%lu reset\n"); 533 p1a(tcps_sc_stale, "\t\t%lu stale\n"); 534 p1a(tcps_sc_aborted, "\t\t%lu aborted\n"); 535 p1a(tcps_sc_badack, "\t\t%lu badack\n"); 536 p1a(tcps_sc_unreach, "\t\t%lu unreach\n"); 537 p1a(tcps_sc_zonefail, "\t\t%lu zone failures\n"); 538 p1a(tcps_sc_sendcookie, "\t\t%lu cookies sent\n"); 539 p1a(tcps_sc_recvcookie, "\t\t%lu cookies received\n"); 540 541 p(tcps_sacksbupdate, "\t%lu SACK scoreboard update%s\n"); 542 p(tcps_sacksboverflow, "\t\t%lu overflow%s\n"); 543 p(tcps_sacksbfailed, "\t\t%lu failure%s\n"); 544 p(tcps_sacksbreused, "\t\t%lu record%s reused\n"); 545 p(tcps_sacksbfast, "\t\t%lu record%s fast allocated\n"); 546 547 free(stattmp); 548 #undef p 549 #undef p1a 550 #undef p2 551 #undef p2a 552 #undef p3 553 } 554 555 /* 556 * Dump UDP statistics structure. 557 */ 558 void 559 udp_stats(u_long off __unused, const char *name, int af1 __unused) 560 { 561 struct udpstat udpstat, *stattmp; 562 struct udpstat zerostat[SMP_MAXCPU]; 563 size_t len = sizeof(struct udpstat) * SMP_MAXCPU; 564 int cpucnt; 565 u_long delivered; 566 567 if (zflag) 568 memset(&zerostat, 0, len); 569 570 if ((stattmp = malloc(len)) == NULL) { 571 return; 572 } else { 573 if (sysctlbyname("net.inet.udp.stats", stattmp, &len, 574 zflag ? zerostat : NULL, zflag ? len : 0) < 0) { 575 warn("sysctl: net.inet.udp.stats"); 576 free(stattmp); 577 return; 578 } else { 579 if ((stattmp = realloc(stattmp, len)) == NULL) { 580 warn("udp_stats"); 581 return; 582 } 583 } 584 } 585 cpucnt = len / sizeof(struct udpstat); 586 udp_stats_agg(stattmp, &udpstat, cpucnt); 587 588 #ifdef INET6 589 if (udp_done != 0) 590 return; 591 else 592 udp_done = 1; 593 #endif 594 595 printf("%s:\n", name); 596 #define p(f, m) if (udpstat.f || sflag <= 1) \ 597 printf(m, udpstat.f, plural(udpstat.f)) 598 #define p1a(f, m) if (udpstat.f || sflag <= 1) \ 599 printf(m, udpstat.f) 600 p(udps_ipackets, "\t%lu datagram%s received\n"); 601 p1a(udps_hdrops, "\t%lu with incomplete header\n"); 602 p1a(udps_badlen, "\t%lu with bad data length field\n"); 603 p1a(udps_badsum, "\t%lu with bad checksum\n"); 604 p1a(udps_nosum, "\t%lu with no checksum\n"); 605 p1a(udps_noport, "\t%lu dropped due to no socket\n"); 606 p(udps_noportbcast, 607 "\t%lu broadcast/multicast datagram%s dropped due to no socket\n"); 608 p1a(udps_fullsock, "\t%lu dropped due to full socket buffers\n"); 609 p1a(udpps_pcbhashmiss, "\t%lu not for hashed pcb\n"); 610 delivered = udpstat.udps_ipackets - 611 udpstat.udps_hdrops - 612 udpstat.udps_badlen - 613 udpstat.udps_badsum - 614 udpstat.udps_noport - 615 udpstat.udps_noportbcast - 616 udpstat.udps_fullsock; 617 if (delivered || sflag <= 1) 618 printf("\t%lu delivered\n", delivered); 619 p(udps_opackets, "\t%lu datagram%s output\n"); 620 #undef p 621 #undef p1a 622 } 623 624 /* 625 * Dump CARP statistics structure. 626 */ 627 void 628 carp_stats(u_long off __unused, const char *name, int af1 __unused) 629 { 630 struct carpstats carpstat, zerostat; 631 size_t len = sizeof(struct carpstats); 632 633 if (zflag) 634 memset(&zerostat, 0, len); 635 if (sysctlbyname("net.inet.carp.stats", &carpstat, &len, 636 zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { 637 warn("sysctl: net.inet.carp.stats"); 638 return; 639 } 640 641 printf("%s:\n", name); 642 643 #define p(f, m) if (carpstat.f || sflag <= 1) \ 644 printf(m, (uintmax_t)carpstat.f, plural((int)carpstat.f)) 645 #define p2(f, m) if (carpstat.f || sflag <= 1) \ 646 printf(m, (uintmax_t)carpstat.f) 647 648 p(carps_ipackets, "\t%ju packet%s received (IPv4)\n"); 649 p(carps_ipackets6, "\t%ju packet%s received (IPv6)\n"); 650 p(carps_badttl, "\t\t%ju packet%s discarded for wrong TTL\n"); 651 p(carps_hdrops, "\t\t%ju packet%s shorter than header\n"); 652 p(carps_badsum, "\t\t%ju discarded for bad checksum%s\n"); 653 p(carps_badver, "\t\t%ju discarded packet%s with a bad version\n"); 654 p2(carps_badlen, "\t\t%ju discarded because packet too short\n"); 655 p2(carps_badauth, "\t\t%ju discarded for bad authentication\n"); 656 p2(carps_badvhid, "\t\t%ju discarded for bad vhid\n"); 657 p2(carps_badaddrs, "\t\t%ju discarded because of a bad address list\n"); 658 p(carps_opackets, "\t%ju packet%s sent (IPv4)\n"); 659 p(carps_opackets6, "\t%ju packet%s sent (IPv6)\n"); 660 p2(carps_onomem, "\t\t%ju send failed due to mbuf memory error\n"); 661 #if notyet 662 p(carps_ostates, "\t\t%s state update%s sent\n"); 663 #endif 664 #undef p 665 #undef p2 666 } 667 668 /* 669 * Dump IP statistics structure. 670 */ 671 void 672 ip_stats(u_long off __unused, const char *name, int af1 __unused) 673 { 674 struct ip_stats ipstat, *stattmp; 675 struct ip_stats zerostat[SMP_MAXCPU]; 676 size_t len = sizeof(struct ip_stats) * SMP_MAXCPU; 677 int cpucnt; 678 679 if (zflag) 680 memset(zerostat, 0, len); 681 if ((stattmp = malloc(len)) == NULL) { 682 return; 683 } else { 684 if (sysctlbyname("net.inet.ip.stats", stattmp, &len, 685 zflag ? zerostat : NULL, zflag ? len : 0) < 0) { 686 warn("sysctl: net.inet.ip.stats"); 687 free(stattmp); 688 return; 689 } else { 690 if ((stattmp = realloc(stattmp, len)) == NULL) { 691 warn("ip_stats"); 692 return; 693 } 694 } 695 } 696 cpucnt = len / sizeof(struct ip_stats); 697 ip_stats_agg(stattmp, &ipstat, cpucnt); 698 699 printf("%s:\n", name); 700 701 #define p(f, m) if (ipstat.f || sflag <= 1) \ 702 printf(m, ipstat.f, plural(ipstat.f)) 703 #define p1a(f, m) if (ipstat.f || sflag <= 1) \ 704 printf(m, ipstat.f) 705 706 p(ips_total, "\t%lu total packet%s received\n"); 707 p(ips_badsum, "\t%lu bad header checksum%s\n"); 708 p1a(ips_toosmall, "\t%lu with size smaller than minimum\n"); 709 p1a(ips_tooshort, "\t%lu with data size < data length\n"); 710 p1a(ips_toolong, "\t%lu with ip length > max ip packet size\n"); 711 p1a(ips_badhlen, "\t%lu with header length < data size\n"); 712 p1a(ips_badlen, "\t%lu with data length < header length\n"); 713 p1a(ips_badoptions, "\t%lu with bad options\n"); 714 p1a(ips_badvers, "\t%lu with incorrect version number\n"); 715 p(ips_fragments, "\t%lu fragment%s received\n"); 716 p(ips_fragdropped, "\t%lu fragment%s dropped (dup or out of space)\n"); 717 p(ips_fragtimeout, "\t%lu fragment%s dropped after timeout\n"); 718 p(ips_reassembled, "\t%lu packet%s reassembled ok\n"); 719 p(ips_delivered, "\t%lu packet%s for this host\n"); 720 p(ips_noproto, "\t%lu packet%s for unknown/unsupported protocol\n"); 721 p(ips_forward, "\t%lu packet%s forwarded"); 722 p(ips_fastforward, " (%lu packet%s fast forwarded)"); 723 if (ipstat.ips_forward || sflag <= 1) 724 putchar('\n'); 725 p(ips_cantforward, "\t%lu packet%s not forwardable\n"); 726 p(ips_notmember, 727 "\t%lu packet%s received for unknown multicast group\n"); 728 p(ips_redirectsent, "\t%lu redirect%s sent\n"); 729 p(ips_localout, "\t%lu packet%s sent from this host\n"); 730 p(ips_rawout, "\t%lu packet%s sent with fabricated ip header\n"); 731 p(ips_odropped, 732 "\t%lu output packet%s dropped due to no bufs, etc.\n"); 733 p(ips_noroute, "\t%lu output packet%s discarded due to no route\n"); 734 p(ips_fragmented, "\t%lu output datagram%s fragmented\n"); 735 p(ips_ofragments, "\t%lu fragment%s created\n"); 736 p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n"); 737 p(ips_nogif, "\t%lu tunneling packet%s that can't find gif\n"); 738 p(ips_badaddr, "\t%lu datagram%s with bad address in header\n"); 739 free(stattmp); 740 #undef p 741 #undef p1a 742 } 743 744 static const char *icmpnames[] = { 745 "echo reply", 746 "#1", 747 "#2", 748 "destination unreachable", 749 "source quench", 750 "routing redirect", 751 "#6", 752 "#7", 753 "echo", 754 "router advertisement", 755 "router solicitation", 756 "time exceeded", 757 "parameter problem", 758 "time stamp", 759 "time stamp reply", 760 "information request", 761 "information request reply", 762 "address mask request", 763 "address mask reply", 764 }; 765 766 /* 767 * Dump ICMP statistics. 768 */ 769 void 770 icmp_stats(u_long off __unused, const char *name, int af1 __unused) 771 { 772 struct icmpstat icmpstat, zerostat; 773 int i, first; 774 int mib[4]; /* CTL_NET + PF_INET + IPPROTO_ICMP + req */ 775 size_t len; 776 777 mib[0] = CTL_NET; 778 mib[1] = PF_INET; 779 mib[2] = IPPROTO_ICMP; 780 mib[3] = ICMPCTL_STATS; 781 782 len = sizeof icmpstat; 783 if (zflag) 784 memset(&zerostat, 0, len); 785 if (sysctl(mib, 4, &icmpstat, &len, 786 zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { 787 warn("sysctl: net.inet.icmp.stats"); 788 return; 789 } 790 791 printf("%s:\n", name); 792 793 #define p(f, m) if (icmpstat.f || sflag <= 1) \ 794 printf(m, icmpstat.f, plural(icmpstat.f)) 795 #define p1a(f, m) if (icmpstat.f || sflag <= 1) \ 796 printf(m, icmpstat.f) 797 #define p2(f, m) if (icmpstat.f || sflag <= 1) \ 798 printf(m, icmpstat.f, plurales(icmpstat.f)) 799 800 p(icps_error, "\t%lu call%s to icmp_error\n"); 801 p(icps_oldicmp, 802 "\t%lu error%s not generated 'cuz old message was icmp\n"); 803 for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) 804 if (icmpstat.icps_outhist[i] != 0) { 805 if (first) { 806 printf("\tOutput histogram:\n"); 807 first = 0; 808 } 809 printf("\t\t%s: %lu\n", icmpnames[i], 810 icmpstat.icps_outhist[i]); 811 } 812 p(icps_badcode, "\t%lu message%s with bad code fields\n"); 813 p(icps_tooshort, "\t%lu message%s < minimum length\n"); 814 p(icps_checksum, "\t%lu bad checksum%s\n"); 815 p(icps_badlen, "\t%lu message%s with bad length\n"); 816 p1a(icps_bmcastecho, "\t%lu multicast echo requests ignored\n"); 817 p1a(icps_bmcasttstamp, "\t%lu multicast timestamp requests ignored\n"); 818 for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) 819 if (icmpstat.icps_inhist[i] != 0) { 820 if (first) { 821 printf("\tInput histogram:\n"); 822 first = 0; 823 } 824 printf("\t\t%s: %lu\n", icmpnames[i], 825 icmpstat.icps_inhist[i]); 826 } 827 p(icps_reflect, "\t%lu message response%s generated\n"); 828 p2(icps_badaddr, "\t%lu invalid return address%s\n"); 829 p(icps_noroute, "\t%lu no return route%s\n"); 830 #undef p 831 #undef p1a 832 #undef p2 833 mib[3] = ICMPCTL_MASKREPL; 834 len = sizeof i; 835 if (sysctl(mib, 4, &i, &len, NULL, 0) < 0) 836 return; 837 printf("\tICMP address mask responses are %sabled\n", 838 i ? "en" : "dis"); 839 } 840 841 /* 842 * Dump IGMP statistics structure. 843 */ 844 void 845 igmp_stats(u_long off __unused, const char *name, int af1 __unused) 846 { 847 struct igmpstat igmpstat, zerostat; 848 size_t len = sizeof igmpstat; 849 850 if (zflag) 851 memset(&zerostat, 0, len); 852 if (sysctlbyname("net.inet.igmp.stats", &igmpstat, &len, 853 zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { 854 warn("sysctl: net.inet.igmp.stats"); 855 return; 856 } 857 858 printf("%s:\n", name); 859 860 #define p(f, m) if (igmpstat.f || sflag <= 1) \ 861 printf(m, igmpstat.f, plural(igmpstat.f)) 862 #define py(f, m) if (igmpstat.f || sflag <= 1) \ 863 printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y") 864 p(igps_rcv_total, "\t%u message%s received\n"); 865 p(igps_rcv_tooshort, "\t%u message%s received with too few bytes\n"); 866 p(igps_rcv_badsum, "\t%u message%s received with bad checksum\n"); 867 py(igps_rcv_queries, "\t%u membership quer%s received\n"); 868 py(igps_rcv_badqueries, "\t%u membership quer%s received with invalid field(s)\n"); 869 p(igps_rcv_reports, "\t%u membership report%s received\n"); 870 p(igps_rcv_badreports, "\t%u membership report%s received with invalid field(s)\n"); 871 p(igps_rcv_ourreports, "\t%u membership report%s received for groups to which we belong\n"); 872 p(igps_snd_reports, "\t%u membership report%s sent\n"); 873 #undef p 874 #undef py 875 } 876 877 /* 878 * Dump PIM statistics structure. 879 */ 880 void 881 pim_stats(u_long off __unused, const char *name, int af1 __unused) 882 { 883 struct pimstat pimstat, zerostat; 884 size_t len = sizeof pimstat; 885 886 if (zflag) 887 memset(&zerostat, 0, len); 888 if (sysctlbyname("net.inet.pim.stats", &pimstat, &len, 889 zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { 890 if (errno != ENOENT) 891 warn("sysctl: net.inet.pim.stats"); 892 return; 893 } 894 895 printf("%s:\n", name); 896 897 #define p(f, m) if (pimstat.f || sflag <= 1) \ 898 printf(m, (uintmax_t)pimstat.f, plural(pimstat.f)) 899 #define py(f, m) if (pimstat.f || sflag <= 1) \ 900 printf(m, (uintmax_t)pimstat.f, pimstat.f != 1 ? "ies" : "y") 901 p(pims_rcv_total_msgs, "\t%ju message%s received\n"); 902 p(pims_rcv_total_bytes, "\t%ju byte%s received\n"); 903 p(pims_rcv_tooshort, "\t%ju message%s received with too few bytes\n"); 904 p(pims_rcv_badsum, "\t%ju message%s received with bad checksum\n"); 905 p(pims_rcv_badversion, "\t%ju message%s received with bad version\n"); 906 p(pims_rcv_registers_msgs, "\t%ju data register message%s received\n"); 907 p(pims_rcv_registers_bytes, "\t%ju data register byte%s received\n"); 908 p(pims_rcv_registers_wrongiif, "\t%ju data register message%s received on wrong iif\n"); 909 p(pims_rcv_badregisters, "\t%ju bad register%s received\n"); 910 p(pims_snd_registers_msgs, "\t%ju data register message%s sent\n"); 911 p(pims_snd_registers_bytes, "\t%ju data register byte%s sent\n"); 912 #undef p 913 #undef py 914 } 915 916 /* 917 * Pretty print an Internet address (net address + port). 918 */ 919 void 920 inetprint(struct in_addr *in, int port, const char *proto, int num_port) 921 { 922 struct servent *sp = NULL; 923 char line[80], *cp; 924 int width; 925 926 if (Wflag) 927 sprintf(line, "%s.", inetname(in)); 928 else 929 sprintf(line, "%.*s.", (Aflag && !num_port) ? 12 : 16, inetname(in)); 930 cp = strchr(line, '\0'); 931 if (!num_port && port) 932 sp = getservbyport((int)port, proto); 933 if (sp || port == 0) 934 sprintf(cp, "%.15s ", sp ? sp->s_name : "*"); 935 else 936 sprintf(cp, "%d ", ntohs((u_short)port)); 937 width = (Aflag && !Wflag) ? 17 : 21; 938 if (Wflag) 939 printf("%-*s ", width, line); 940 else 941 printf("%-*.*s ", width, width, line); 942 } 943 944 /* 945 * Construct an Internet address representation. 946 * If numeric_addr has been supplied, give 947 * numeric value, otherwise try for symbolic name. 948 */ 949 char * 950 inetname(struct in_addr *inp) 951 { 952 char *cp; 953 static char line[MAXHOSTNAMELEN]; 954 struct hostent *hp; 955 struct netent *np; 956 957 cp = NULL; 958 if (!numeric_addr && inp->s_addr != INADDR_ANY) { 959 int net = inet_netof(*inp); 960 int lna = inet_lnaof(*inp); 961 962 if (lna == INADDR_ANY) { 963 np = getnetbyaddr(net, AF_INET); 964 if (np) 965 cp = np->n_name; 966 } 967 if (cp == NULL) { 968 hp = gethostbyaddr(inp, sizeof (*inp), AF_INET); 969 if (hp) { 970 cp = hp->h_name; 971 trimdomain(cp, strlen(cp)); 972 } 973 } 974 } 975 if (inp->s_addr == INADDR_ANY) 976 strcpy(line, "*"); 977 else if (cp) { 978 strncpy(line, cp, sizeof(line) - 1); 979 line[sizeof(line) - 1] = '\0'; 980 } else { 981 inp->s_addr = ntohl(inp->s_addr); 982 #define C(x) ((u_int)((x) & 0xff)) 983 sprintf(line, "%u.%u.%u.%u", C(inp->s_addr >> 24), 984 C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr)); 985 } 986 return (line); 987 } 988