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