19b50d902SRodney W. Grimes /* 205ddff6eSPeter Wemm * Copyright (c) 1983, 1988, 1993, 1995 39b50d902SRodney W. Grimes * The Regents of the University of California. All rights reserved. 49b50d902SRodney W. Grimes * 59b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 69b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions 79b50d902SRodney W. Grimes * are met: 89b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 99b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 109b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 119b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 129b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution. 139b50d902SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 149b50d902SRodney W. Grimes * must display the following acknowledgement: 159b50d902SRodney W. Grimes * This product includes software developed by the University of 169b50d902SRodney W. Grimes * California, Berkeley and its contributors. 179b50d902SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 189b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software 199b50d902SRodney W. Grimes * without specific prior written permission. 209b50d902SRodney W. Grimes * 219b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 229b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 239b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 249b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 259b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 269b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 279b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 289b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 299b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 309b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 319b50d902SRodney W. Grimes * SUCH DAMAGE. 329b50d902SRodney W. Grimes */ 339b50d902SRodney W. Grimes 349b50d902SRodney W. Grimes #ifndef lint 3590864998SGarrett Wollman /* 3605ddff6eSPeter Wemm static char sccsid[] = "@(#)inet.c 8.5 (Berkeley) 5/24/95"; 3790864998SGarrett Wollman */ 3890864998SGarrett Wollman static const char rcsid[] = 3922694ebaSBruce Evans "$Id: inet.c,v 1.29 1998/06/09 04:13:01 imp Exp $"; 409b50d902SRodney W. Grimes #endif /* not lint */ 419b50d902SRodney W. Grimes 429b50d902SRodney W. Grimes #include <sys/param.h> 43d8d89152SDavid Greenman #include <sys/queue.h> 449b50d902SRodney W. Grimes #include <sys/socket.h> 459b50d902SRodney W. Grimes #include <sys/socketvar.h> 464e00c309SGarrett Wollman #include <sys/sysctl.h> 479b50d902SRodney W. Grimes #include <sys/protosw.h> 489b50d902SRodney W. Grimes 499b50d902SRodney W. Grimes #include <net/route.h> 509b50d902SRodney W. Grimes #include <netinet/in.h> 519b50d902SRodney W. Grimes #include <netinet/in_systm.h> 529b50d902SRodney W. Grimes #include <netinet/ip.h> 539b50d902SRodney W. Grimes #include <netinet/in_pcb.h> 549b50d902SRodney W. Grimes #include <netinet/ip_icmp.h> 559b50d902SRodney W. Grimes #include <netinet/icmp_var.h> 569b50d902SRodney W. Grimes #include <netinet/igmp_var.h> 579b50d902SRodney W. Grimes #include <netinet/ip_var.h> 589b50d902SRodney W. Grimes #include <netinet/tcp.h> 599b50d902SRodney W. Grimes #include <netinet/tcpip.h> 609b50d902SRodney W. Grimes #include <netinet/tcp_seq.h> 619b50d902SRodney W. Grimes #define TCPSTATES 629b50d902SRodney W. Grimes #include <netinet/tcp_fsm.h> 639b50d902SRodney W. Grimes #include <netinet/tcp_timer.h> 649b50d902SRodney W. Grimes #include <netinet/tcp_var.h> 659b50d902SRodney W. Grimes #include <netinet/tcp_debug.h> 669b50d902SRodney W. Grimes #include <netinet/udp.h> 679b50d902SRodney W. Grimes #include <netinet/udp_var.h> 689b50d902SRodney W. Grimes 699b50d902SRodney W. Grimes #include <arpa/inet.h> 704f81ef50SGarrett Wollman #include <err.h> 714f81ef50SGarrett Wollman #include <errno.h> 729b50d902SRodney W. Grimes #include <netdb.h> 739b50d902SRodney W. Grimes #include <stdio.h> 744f81ef50SGarrett Wollman #include <stdlib.h> 759b50d902SRodney W. Grimes #include <string.h> 769b50d902SRodney W. Grimes #include <unistd.h> 779b50d902SRodney W. Grimes #include "netstat.h" 789b50d902SRodney W. Grimes 799b50d902SRodney W. Grimes char *inetname __P((struct in_addr *)); 808d612dd2SPoul-Henning Kamp void inetprint __P((struct in_addr *, int, char *, int)); 819b50d902SRodney W. Grimes 829b50d902SRodney W. Grimes /* 839b50d902SRodney W. Grimes * Print a summary of connections related to an Internet 849b50d902SRodney W. Grimes * protocol. For TCP, also give state of connection. 859b50d902SRodney W. Grimes * Listening processes (aflag) are suppressed unless the 869b50d902SRodney W. Grimes * -a (all) flag is specified. 879b50d902SRodney W. Grimes */ 889b50d902SRodney W. Grimes void 894f81ef50SGarrett Wollman protopr(proto, name) 904f81ef50SGarrett Wollman u_long proto; /* for sysctl version we pass proto # */ 919b50d902SRodney W. Grimes char *name; 929b50d902SRodney W. Grimes { 939b50d902SRodney W. Grimes int istcp; 949b50d902SRodney W. Grimes static int first = 1; 954f81ef50SGarrett Wollman char *buf; 964f81ef50SGarrett Wollman const char *mibvar; 974f81ef50SGarrett Wollman struct tcpcb *tp; 984f81ef50SGarrett Wollman struct inpcb *inp; 994f81ef50SGarrett Wollman struct xinpgen *xig, *oxig; 1004f81ef50SGarrett Wollman struct xsocket *so; 1014f81ef50SGarrett Wollman size_t len; 1029b50d902SRodney W. Grimes 1034f81ef50SGarrett Wollman istcp = 0; 1044f81ef50SGarrett Wollman switch (proto) { 1054f81ef50SGarrett Wollman case IPPROTO_TCP: 1064f81ef50SGarrett Wollman istcp = 1; 1074f81ef50SGarrett Wollman mibvar = "net.inet.tcp.pcblist"; 1084f81ef50SGarrett Wollman break; 1094f81ef50SGarrett Wollman case IPPROTO_UDP: 1104f81ef50SGarrett Wollman mibvar = "net.inet.udp.pcblist"; 1114f81ef50SGarrett Wollman break; 1124f81ef50SGarrett Wollman case IPPROTO_DIVERT: 1134f81ef50SGarrett Wollman mibvar = "net.inet.divert.pcblist"; 1144f81ef50SGarrett Wollman break; 1154f81ef50SGarrett Wollman default: 1164f81ef50SGarrett Wollman mibvar = "net.inet.raw.pcblist"; 1174f81ef50SGarrett Wollman break; 1184f81ef50SGarrett Wollman } 1194f81ef50SGarrett Wollman len = 0; 1204f81ef50SGarrett Wollman if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) { 1214f81ef50SGarrett Wollman if (errno != ENOENT) 1224f81ef50SGarrett Wollman warn("sysctl: %s", mibvar); 1239b50d902SRodney W. Grimes return; 1243aa80b1dSDavid Greenman } 1254f81ef50SGarrett Wollman if ((buf = malloc(len)) == 0) { 1264f81ef50SGarrett Wollman warn("malloc %lu bytes", (u_long)len); 1274f81ef50SGarrett Wollman return; 1289b50d902SRodney W. Grimes } 1294f81ef50SGarrett Wollman if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) { 1304f81ef50SGarrett Wollman warn("sysctl: %s", mibvar); 1314f81ef50SGarrett Wollman free(buf); 1324f81ef50SGarrett Wollman return; 1334f81ef50SGarrett Wollman } 1344f81ef50SGarrett Wollman 1354f81ef50SGarrett Wollman oxig = xig = (struct xinpgen *)buf; 1364f81ef50SGarrett Wollman for (xig = (struct xinpgen *)((char *)xig + xig->xig_len); 1374f81ef50SGarrett Wollman xig->xig_len > sizeof(struct xinpgen); 1384f81ef50SGarrett Wollman xig = (struct xinpgen *)((char *)xig + xig->xig_len)) { 1399b50d902SRodney W. Grimes if (istcp) { 1404f81ef50SGarrett Wollman tp = &((struct xtcpcb *)xig)->xt_tp; 1414f81ef50SGarrett Wollman inp = &((struct xtcpcb *)xig)->xt_inp; 1424f81ef50SGarrett Wollman so = &((struct xtcpcb *)xig)->xt_socket; 1434f81ef50SGarrett Wollman } else { 1444f81ef50SGarrett Wollman inp = &((struct xinpcb *)xig)->xi_inp; 1454f81ef50SGarrett Wollman so = &((struct xinpcb *)xig)->xi_socket; 1469b50d902SRodney W. Grimes } 1474f81ef50SGarrett Wollman 1484f81ef50SGarrett Wollman /* Ignore sockets for protocols other than the desired one. */ 1494f81ef50SGarrett Wollman if (so->xso_protocol != proto) 1504f81ef50SGarrett Wollman continue; 1514f81ef50SGarrett Wollman 1524f81ef50SGarrett Wollman /* Ignore PCBs which were freed during copyout. */ 1534f81ef50SGarrett Wollman if (inp->inp_gencnt > oxig->xig_gen) 1544f81ef50SGarrett Wollman continue; 1554f81ef50SGarrett Wollman 1564f81ef50SGarrett Wollman if (!aflag && inet_lnaof(inp->inp_laddr) == INADDR_ANY) 1574f81ef50SGarrett Wollman continue; 1584f81ef50SGarrett Wollman 1599b50d902SRodney W. Grimes if (first) { 1609b50d902SRodney W. Grimes printf("Active Internet connections"); 1619b50d902SRodney W. Grimes if (aflag) 1629b50d902SRodney W. Grimes printf(" (including servers)"); 1639b50d902SRodney W. Grimes putchar('\n'); 1649b50d902SRodney W. Grimes if (Aflag) 1654f81ef50SGarrett Wollman printf("%-8.8s ", "Socket"); 1669b50d902SRodney W. Grimes printf(Aflag ? 1679b50d902SRodney W. Grimes "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" : 1689b50d902SRodney W. Grimes "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n", 1699b50d902SRodney W. Grimes "Proto", "Recv-Q", "Send-Q", 1709b50d902SRodney W. Grimes "Local Address", "Foreign Address", "(state)"); 1719b50d902SRodney W. Grimes first = 0; 1729b50d902SRodney W. Grimes } 1739b50d902SRodney W. Grimes if (Aflag) 1744f81ef50SGarrett Wollman printf("%8lx ", (u_long)so->so_pcb); 1754f81ef50SGarrett Wollman printf("%-5.5s %6ld %6ld ", name, so->so_rcv.sb_cc, 1764f81ef50SGarrett Wollman so->so_snd.sb_cc); 1778d612dd2SPoul-Henning Kamp if (nflag) { 1784f81ef50SGarrett Wollman inetprint(&inp->inp_laddr, (int)inp->inp_lport, 1798d612dd2SPoul-Henning Kamp name, 1); 1804f81ef50SGarrett Wollman inetprint(&inp->inp_faddr, (int)inp->inp_fport, 1818d612dd2SPoul-Henning Kamp name, 1); 1824f81ef50SGarrett Wollman } else if (inp->inp_flags & INP_ANONPORT) { 1834f81ef50SGarrett Wollman inetprint(&inp->inp_laddr, (int)inp->inp_lport, 1848d612dd2SPoul-Henning Kamp name, 1); 1854f81ef50SGarrett Wollman inetprint(&inp->inp_faddr, (int)inp->inp_fport, 1868d612dd2SPoul-Henning Kamp name, 0); 1878d612dd2SPoul-Henning Kamp } else { 1884f81ef50SGarrett Wollman inetprint(&inp->inp_laddr, (int)inp->inp_lport, 1898d612dd2SPoul-Henning Kamp name, 0); 1904f81ef50SGarrett Wollman inetprint(&inp->inp_faddr, (int)inp->inp_fport, 1914f81ef50SGarrett Wollman name, inp->inp_lport != inp->inp_fport); 1928d612dd2SPoul-Henning Kamp } 1939b50d902SRodney W. Grimes if (istcp) { 1944f81ef50SGarrett Wollman if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES) 1954f81ef50SGarrett Wollman printf(" %d", tp->t_state); 1969a94a597SGarrett Wollman else { 1974f81ef50SGarrett Wollman printf(" %s", tcpstates[tp->t_state]); 198513822ddSAdam David #if defined(TF_NEEDSYN) && defined(TF_NEEDFIN) 1999a94a597SGarrett Wollman /* Show T/TCP `hidden state' */ 2004f81ef50SGarrett Wollman if (tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) 2019a94a597SGarrett Wollman putchar('*'); 202513822ddSAdam David #endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */ 2039a94a597SGarrett Wollman } 2049b50d902SRodney W. Grimes } 2059b50d902SRodney W. Grimes putchar('\n'); 2069b50d902SRodney W. Grimes } 2074f81ef50SGarrett Wollman if (xig != oxig && xig->xig_gen != oxig->xig_gen) { 2084f81ef50SGarrett Wollman if (oxig->xig_count > xig->xig_count) { 2094f81ef50SGarrett Wollman printf("Some %s sockets may have been deleted.\n", 2104f81ef50SGarrett Wollman name); 2114f81ef50SGarrett Wollman } else if (oxig->xig_count < xig->xig_count) { 2124f81ef50SGarrett Wollman printf("Some %s sockets may have been created.\n", 2134f81ef50SGarrett Wollman name); 2144f81ef50SGarrett Wollman } else { 2154f81ef50SGarrett Wollman printf("Some %s sockets may have been created or deleted", 2164f81ef50SGarrett Wollman name); 2174f81ef50SGarrett Wollman } 2184f81ef50SGarrett Wollman } 2194f81ef50SGarrett Wollman free(buf); 2209b50d902SRodney W. Grimes } 2219b50d902SRodney W. Grimes 2229b50d902SRodney W. Grimes /* 2239b50d902SRodney W. Grimes * Dump TCP statistics structure. 2249b50d902SRodney W. Grimes */ 2259b50d902SRodney W. Grimes void 2269b50d902SRodney W. Grimes tcp_stats(off, name) 2279b50d902SRodney W. Grimes u_long off; 2289b50d902SRodney W. Grimes char *name; 2299b50d902SRodney W. Grimes { 2309b50d902SRodney W. Grimes struct tcpstat tcpstat; 2314f81ef50SGarrett Wollman size_t len = sizeof tcpstat; 2329b50d902SRodney W. Grimes 2334f81ef50SGarrett Wollman if (sysctlbyname("net.inet.tcp.stats", &tcpstat, &len, 0, 0) < 0) { 2344f81ef50SGarrett Wollman warn("sysctl: net.inet.tcp.stats"); 2359b50d902SRodney W. Grimes return; 2364f81ef50SGarrett Wollman } 2374f81ef50SGarrett Wollman 2389b50d902SRodney W. Grimes printf ("%s:\n", name); 2399b50d902SRodney W. Grimes 2409b50d902SRodney W. Grimes #define p(f, m) if (tcpstat.f || sflag <= 1) \ 2419b50d902SRodney W. Grimes printf(m, tcpstat.f, plural(tcpstat.f)) 24222694ebaSBruce Evans #define p1a(f, m) if (tcpstat.f || sflag <= 1) \ 24322694ebaSBruce Evans printf(m, tcpstat.f) 2449b50d902SRodney W. Grimes #define p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \ 2459b50d902SRodney W. Grimes printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2)) 24622694ebaSBruce Evans #define p2a(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \ 24722694ebaSBruce Evans printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2) 2489b50d902SRodney W. Grimes #define p3(f, m) if (tcpstat.f || sflag <= 1) \ 2499b50d902SRodney W. Grimes printf(m, tcpstat.f, plurales(tcpstat.f)) 2509b50d902SRodney W. Grimes 251e1fb4daaSPaul Traina p(tcps_sndtotal, "\t%lu packet%s sent\n"); 2529b50d902SRodney W. Grimes p2(tcps_sndpack,tcps_sndbyte, 253e1fb4daaSPaul Traina "\t\t%lu data packet%s (%lu byte%s)\n"); 2549b50d902SRodney W. Grimes p2(tcps_sndrexmitpack, tcps_sndrexmitbyte, 255e1fb4daaSPaul Traina "\t\t%lu data packet%s (%lu byte%s) retransmitted\n"); 256e1fb4daaSPaul Traina p(tcps_mturesent, "\t\t%lu resend%s initiated by MTU discovery\n"); 25722694ebaSBruce Evans p2a(tcps_sndacks, tcps_delack, 258e1fb4daaSPaul Traina "\t\t%lu ack-only packet%s (%lu delayed)\n"); 259e1fb4daaSPaul Traina p(tcps_sndurg, "\t\t%lu URG only packet%s\n"); 260e1fb4daaSPaul Traina p(tcps_sndprobe, "\t\t%lu window probe packet%s\n"); 261e1fb4daaSPaul Traina p(tcps_sndwinup, "\t\t%lu window update packet%s\n"); 262e1fb4daaSPaul Traina p(tcps_sndctrl, "\t\t%lu control packet%s\n"); 263e1fb4daaSPaul Traina p(tcps_rcvtotal, "\t%lu packet%s received\n"); 264e1fb4daaSPaul Traina p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%lu ack%s (for %lu byte%s)\n"); 265e1fb4daaSPaul Traina p(tcps_rcvdupack, "\t\t%lu duplicate ack%s\n"); 266e1fb4daaSPaul Traina p(tcps_rcvacktoomuch, "\t\t%lu ack%s for unsent data\n"); 2679b50d902SRodney W. Grimes p2(tcps_rcvpack, tcps_rcvbyte, 268e1fb4daaSPaul Traina "\t\t%lu packet%s (%lu byte%s) received in-sequence\n"); 2699b50d902SRodney W. Grimes p2(tcps_rcvduppack, tcps_rcvdupbyte, 270e1fb4daaSPaul Traina "\t\t%lu completely duplicate packet%s (%lu byte%s)\n"); 271e1fb4daaSPaul Traina p(tcps_pawsdrop, "\t\t%lu old duplicate packet%s\n"); 2729b50d902SRodney W. Grimes p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte, 273e1fb4daaSPaul Traina "\t\t%lu packet%s with some dup. data (%lu byte%s duped)\n"); 2749b50d902SRodney W. Grimes p2(tcps_rcvoopack, tcps_rcvoobyte, 275e1fb4daaSPaul Traina "\t\t%lu out-of-order packet%s (%lu byte%s)\n"); 2769b50d902SRodney W. Grimes p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin, 277e1fb4daaSPaul Traina "\t\t%lu packet%s (%lu byte%s) of data after window\n"); 278e1fb4daaSPaul Traina p(tcps_rcvwinprobe, "\t\t%lu window probe%s\n"); 279e1fb4daaSPaul Traina p(tcps_rcvwinupd, "\t\t%lu window update packet%s\n"); 280e1fb4daaSPaul Traina p(tcps_rcvafterclose, "\t\t%lu packet%s received after close\n"); 281e1fb4daaSPaul Traina p(tcps_rcvbadsum, "\t\t%lu discarded for bad checksum%s\n"); 282e1fb4daaSPaul Traina p(tcps_rcvbadoff, "\t\t%lu discarded for bad header offset field%s\n"); 28322694ebaSBruce Evans p1a(tcps_rcvshort, "\t\t%lu discarded because packet too short\n"); 284e1fb4daaSPaul Traina p(tcps_connattempt, "\t%lu connection request%s\n"); 285e1fb4daaSPaul Traina p(tcps_accepts, "\t%lu connection accept%s\n"); 286e1fb4daaSPaul Traina p(tcps_badsyn, "\t%lu bad connection attempt%s\n"); 287e1fb4daaSPaul Traina p(tcps_listendrop, "\t%lu listen queue overflow%s\n"); 288e1fb4daaSPaul Traina p(tcps_connects, "\t%lu connection%s established (including accepts)\n"); 2899b50d902SRodney W. Grimes p2(tcps_closed, tcps_drops, 290e1fb4daaSPaul Traina "\t%lu connection%s closed (including %lu drop%s)\n"); 291e1fb4daaSPaul Traina p(tcps_cachedrtt, "\t\t%lu connection%s updated cached RTT on close\n"); 292861b1828SGarrett Wollman p(tcps_cachedrttvar, 293e1fb4daaSPaul Traina "\t\t%lu connection%s updated cached RTT variance on close\n"); 294861b1828SGarrett Wollman p(tcps_cachedssthresh, 295e1fb4daaSPaul Traina "\t\t%lu connection%s updated cached ssthresh on close\n"); 296e1fb4daaSPaul Traina p(tcps_conndrops, "\t%lu embryonic connection%s dropped\n"); 2979b50d902SRodney W. Grimes p2(tcps_rttupdated, tcps_segstimed, 298e1fb4daaSPaul Traina "\t%lu segment%s updated rtt (of %lu attempt%s)\n"); 299e1fb4daaSPaul Traina p(tcps_rexmttimeo, "\t%lu retransmit timeout%s\n"); 300e1fb4daaSPaul Traina p(tcps_timeoutdrop, "\t\t%lu connection%s dropped by rexmit timeout\n"); 301e1fb4daaSPaul Traina p(tcps_persisttimeo, "\t%lu persist timeout%s\n"); 302e1fb4daaSPaul Traina p(tcps_persistdrop, "\t\t%lu connection%s dropped by persist timeout\n"); 303e1fb4daaSPaul Traina p(tcps_keeptimeo, "\t%lu keepalive timeout%s\n"); 304e1fb4daaSPaul Traina p(tcps_keepprobe, "\t\t%lu keepalive probe%s sent\n"); 305e1fb4daaSPaul Traina p(tcps_keepdrops, "\t\t%lu connection%s dropped by keepalive\n"); 306e1fb4daaSPaul Traina p(tcps_predack, "\t%lu correct ACK header prediction%s\n"); 307e1fb4daaSPaul Traina p(tcps_preddat, "\t%lu correct data packet header prediction%s\n"); 3089b50d902SRodney W. Grimes #undef p 30922694ebaSBruce Evans #undef p1a 3109b50d902SRodney W. Grimes #undef p2 31122694ebaSBruce Evans #undef p2a 3129b50d902SRodney W. Grimes #undef p3 3139b50d902SRodney W. Grimes } 3149b50d902SRodney W. Grimes 3159b50d902SRodney W. Grimes /* 3169b50d902SRodney W. Grimes * Dump UDP statistics structure. 3179b50d902SRodney W. Grimes */ 3189b50d902SRodney W. Grimes void 3199b50d902SRodney W. Grimes udp_stats(off, name) 3209b50d902SRodney W. Grimes u_long off; 3219b50d902SRodney W. Grimes char *name; 3229b50d902SRodney W. Grimes { 3239b50d902SRodney W. Grimes struct udpstat udpstat; 3244f81ef50SGarrett Wollman size_t len = sizeof udpstat; 3259b50d902SRodney W. Grimes u_long delivered; 3269b50d902SRodney W. Grimes 3274f81ef50SGarrett Wollman if (sysctlbyname("net.inet.udp.stats", &udpstat, &len, 0, 0) < 0) { 3284f81ef50SGarrett Wollman warn("sysctl: net.inet.udp.stats"); 3299b50d902SRodney W. Grimes return; 3304f81ef50SGarrett Wollman } 3314f81ef50SGarrett Wollman 3329b50d902SRodney W. Grimes printf("%s:\n", name); 3339b50d902SRodney W. Grimes #define p(f, m) if (udpstat.f || sflag <= 1) \ 3349b50d902SRodney W. Grimes printf(m, udpstat.f, plural(udpstat.f)) 33522694ebaSBruce Evans #define p1a(f, m) if (udpstat.f || sflag <= 1) \ 33622694ebaSBruce Evans printf(m, udpstat.f) 3377d56c0eeSAlexander Langer p(udps_ipackets, "\t%lu datagram%s received\n"); 33822694ebaSBruce Evans p1a(udps_hdrops, "\t%lu with incomplete header\n"); 33922694ebaSBruce Evans p1a(udps_badlen, "\t%lu with bad data length field\n"); 34022694ebaSBruce Evans p1a(udps_badsum, "\t%lu with bad checksum\n"); 34122694ebaSBruce Evans p1a(udps_noport, "\t%lu dropped due to no socket\n"); 34222694ebaSBruce Evans p(udps_noportbcast, 34322694ebaSBruce Evans "\t%lu broadcast/multicast datagram%s dropped due to no socket\n"); 34422694ebaSBruce Evans p1a(udps_fullsock, "\t%lu dropped due to full socket buffers\n"); 34522694ebaSBruce Evans p1a(udpps_pcbhashmiss, "\t%lu not for hashed pcb\n"); 3469b50d902SRodney W. Grimes delivered = udpstat.udps_ipackets - 3479b50d902SRodney W. Grimes udpstat.udps_hdrops - 3489b50d902SRodney W. Grimes udpstat.udps_badlen - 3499b50d902SRodney W. Grimes udpstat.udps_badsum - 3509b50d902SRodney W. Grimes udpstat.udps_noport - 3519b50d902SRodney W. Grimes udpstat.udps_noportbcast - 3529b50d902SRodney W. Grimes udpstat.udps_fullsock; 3539b50d902SRodney W. Grimes if (delivered || sflag <= 1) 3547d56c0eeSAlexander Langer printf("\t%lu delivered\n", delivered); 3557d56c0eeSAlexander Langer p(udps_opackets, "\t%lu datagram%s output\n"); 3569b50d902SRodney W. Grimes #undef p 35722694ebaSBruce Evans #undef p1a 3589b50d902SRodney W. Grimes } 3599b50d902SRodney W. Grimes 3609b50d902SRodney W. Grimes /* 3619b50d902SRodney W. Grimes * Dump IP statistics structure. 3629b50d902SRodney W. Grimes */ 3639b50d902SRodney W. Grimes void 3649b50d902SRodney W. Grimes ip_stats(off, name) 3659b50d902SRodney W. Grimes u_long off; 3669b50d902SRodney W. Grimes char *name; 3679b50d902SRodney W. Grimes { 3689b50d902SRodney W. Grimes struct ipstat ipstat; 3694f81ef50SGarrett Wollman size_t len = sizeof ipstat; 3709b50d902SRodney W. Grimes 3714f81ef50SGarrett Wollman if (sysctlbyname("net.inet.ip.stats", &ipstat, &len, 0, 0) < 0) { 3724f81ef50SGarrett Wollman warn("sysctl: net.inet.ip.stats"); 3739b50d902SRodney W. Grimes return; 3744f81ef50SGarrett Wollman } 3754f81ef50SGarrett Wollman 3769b50d902SRodney W. Grimes printf("%s:\n", name); 3779b50d902SRodney W. Grimes 3789b50d902SRodney W. Grimes #define p(f, m) if (ipstat.f || sflag <= 1) \ 3799b50d902SRodney W. Grimes printf(m, ipstat.f, plural(ipstat.f)) 38022694ebaSBruce Evans #define p1a(f, m) if (ipstat.f || sflag <= 1) \ 38122694ebaSBruce Evans printf(m, ipstat.f) 3829b50d902SRodney W. Grimes 3837d56c0eeSAlexander Langer p(ips_total, "\t%lu total packet%s received\n"); 3847d56c0eeSAlexander Langer p(ips_badsum, "\t%lu bad header checksum%s\n"); 38522694ebaSBruce Evans p1a(ips_toosmall, "\t%lu with size smaller than minimum\n"); 38622694ebaSBruce Evans p1a(ips_tooshort, "\t%lu with data size < data length\n"); 38722694ebaSBruce Evans p1a(ips_badhlen, "\t%lu with header length < data size\n"); 38822694ebaSBruce Evans p1a(ips_badlen, "\t%lu with data length < header length\n"); 38922694ebaSBruce Evans p1a(ips_badoptions, "\t%lu with bad options\n"); 39022694ebaSBruce Evans p1a(ips_badvers, "\t%lu with incorrect version number\n"); 3917d56c0eeSAlexander Langer p(ips_fragments, "\t%lu fragment%s received\n"); 3927d56c0eeSAlexander Langer p(ips_fragdropped, "\t%lu fragment%s dropped (dup or out of space)\n"); 3937d56c0eeSAlexander Langer p(ips_fragtimeout, "\t%lu fragment%s dropped after timeout\n"); 3947d56c0eeSAlexander Langer p(ips_reassembled, "\t%lu packet%s reassembled ok\n"); 3957d56c0eeSAlexander Langer p(ips_delivered, "\t%lu packet%s for this host\n"); 3967d56c0eeSAlexander Langer p(ips_noproto, "\t%lu packet%s for unknown/unsupported protocol\n"); 397958d6f7fSPierre Beyssac p(ips_forward, "\t%lu packet%s forwarded"); 398958d6f7fSPierre Beyssac p(ips_fastforward, " (%lu packet%s fast forwarded)"); 399958d6f7fSPierre Beyssac if (ipstat.ips_forward || sflag <= 1) 400958d6f7fSPierre Beyssac putchar('\n'); 4017d56c0eeSAlexander Langer p(ips_cantforward, "\t%lu packet%s not forwardable\n"); 402a5969f5fSGarrett Wollman p(ips_notmember, 403a5969f5fSGarrett Wollman "\t%lu packet%s received for unknown multicast group\n"); 4047d56c0eeSAlexander Langer p(ips_redirectsent, "\t%lu redirect%s sent\n"); 4057d56c0eeSAlexander Langer p(ips_localout, "\t%lu packet%s sent from this host\n"); 4067d56c0eeSAlexander Langer p(ips_rawout, "\t%lu packet%s sent with fabricated ip header\n"); 407a5969f5fSGarrett Wollman p(ips_odropped, 408a5969f5fSGarrett Wollman "\t%lu output packet%s dropped due to no bufs, etc.\n"); 4097d56c0eeSAlexander Langer p(ips_noroute, "\t%lu output packet%s discarded due to no route\n"); 4107d56c0eeSAlexander Langer p(ips_fragmented, "\t%lu output datagram%s fragmented\n"); 4117d56c0eeSAlexander Langer p(ips_ofragments, "\t%lu fragment%s created\n"); 4127d56c0eeSAlexander Langer p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n"); 4139b50d902SRodney W. Grimes #undef p 41422694ebaSBruce Evans #undef p1a 4159b50d902SRodney W. Grimes } 4169b50d902SRodney W. Grimes 4179b50d902SRodney W. Grimes static char *icmpnames[] = { 4189b50d902SRodney W. Grimes "echo reply", 4199b50d902SRodney W. Grimes "#1", 4209b50d902SRodney W. Grimes "#2", 4219b50d902SRodney W. Grimes "destination unreachable", 4229b50d902SRodney W. Grimes "source quench", 4239b50d902SRodney W. Grimes "routing redirect", 4249b50d902SRodney W. Grimes "#6", 4259b50d902SRodney W. Grimes "#7", 4269b50d902SRodney W. Grimes "echo", 4277b46dd00SGarrett Wollman "router advertisement", 4287b46dd00SGarrett Wollman "router solicitation", 4299b50d902SRodney W. Grimes "time exceeded", 4309b50d902SRodney W. Grimes "parameter problem", 4319b50d902SRodney W. Grimes "time stamp", 4329b50d902SRodney W. Grimes "time stamp reply", 4339b50d902SRodney W. Grimes "information request", 4349b50d902SRodney W. Grimes "information request reply", 4359b50d902SRodney W. Grimes "address mask request", 4369b50d902SRodney W. Grimes "address mask reply", 4379b50d902SRodney W. Grimes }; 4389b50d902SRodney W. Grimes 4399b50d902SRodney W. Grimes /* 4409b50d902SRodney W. Grimes * Dump ICMP statistics. 4419b50d902SRodney W. Grimes */ 4429b50d902SRodney W. Grimes void 4439b50d902SRodney W. Grimes icmp_stats(off, name) 4449b50d902SRodney W. Grimes u_long off; 4459b50d902SRodney W. Grimes char *name; 4469b50d902SRodney W. Grimes { 4479b50d902SRodney W. Grimes struct icmpstat icmpstat; 4484e00c309SGarrett Wollman int i, first; 4494e00c309SGarrett Wollman int mib[4]; /* CTL_NET + PF_INET + IPPROTO_ICMP + req */ 4504e00c309SGarrett Wollman size_t len; 4519b50d902SRodney W. Grimes 4524e00c309SGarrett Wollman mib[0] = CTL_NET; 4534e00c309SGarrett Wollman mib[1] = PF_INET; 4544e00c309SGarrett Wollman mib[2] = IPPROTO_ICMP; 4554e00c309SGarrett Wollman mib[3] = ICMPCTL_STATS; 4564e00c309SGarrett Wollman 4574e00c309SGarrett Wollman len = sizeof icmpstat; 4584e00c309SGarrett Wollman memset(&icmpstat, 0, len); 4594e00c309SGarrett Wollman if (sysctl(mib, 4, &icmpstat, &len, (void *)0, 0) < 0) 4604e00c309SGarrett Wollman return; /* XXX should complain, but not traditional */ 4614e00c309SGarrett Wollman 4629b50d902SRodney W. Grimes printf("%s:\n", name); 4639b50d902SRodney W. Grimes 4649b50d902SRodney W. Grimes #define p(f, m) if (icmpstat.f || sflag <= 1) \ 4659b50d902SRodney W. Grimes printf(m, icmpstat.f, plural(icmpstat.f)) 46622694ebaSBruce Evans #define p1a(f, m) if (icmpstat.f || sflag <= 1) \ 46722694ebaSBruce Evans printf(m, icmpstat.f) 4689b50d902SRodney W. Grimes 4697d56c0eeSAlexander Langer p(icps_error, "\t%lu call%s to icmp_error\n"); 4709b50d902SRodney W. Grimes p(icps_oldicmp, 4717d56c0eeSAlexander Langer "\t%lu error%s not generated 'cuz old message was icmp\n"); 4729b50d902SRodney W. Grimes for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) 4739b50d902SRodney W. Grimes if (icmpstat.icps_outhist[i] != 0) { 4749b50d902SRodney W. Grimes if (first) { 4759b50d902SRodney W. Grimes printf("\tOutput histogram:\n"); 4769b50d902SRodney W. Grimes first = 0; 4779b50d902SRodney W. Grimes } 4787d56c0eeSAlexander Langer printf("\t\t%s: %lu\n", icmpnames[i], 4799b50d902SRodney W. Grimes icmpstat.icps_outhist[i]); 4809b50d902SRodney W. Grimes } 4817d56c0eeSAlexander Langer p(icps_badcode, "\t%lu message%s with bad code fields\n"); 4827d56c0eeSAlexander Langer p(icps_tooshort, "\t%lu message%s < minimum length\n"); 4837d56c0eeSAlexander Langer p(icps_checksum, "\t%lu bad checksum%s\n"); 4847d56c0eeSAlexander Langer p(icps_badlen, "\t%lu message%s with bad length\n"); 48522694ebaSBruce Evans p1a(icps_bmcastecho, "\t%lu multicast echo requests ignored\n"); 48622694ebaSBruce Evans p1a(icps_bmcasttstamp, "\t%lu multicast timestamp requests ignored\n"); 4879b50d902SRodney W. Grimes for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) 4889b50d902SRodney W. Grimes if (icmpstat.icps_inhist[i] != 0) { 4899b50d902SRodney W. Grimes if (first) { 4909b50d902SRodney W. Grimes printf("\tInput histogram:\n"); 4919b50d902SRodney W. Grimes first = 0; 4929b50d902SRodney W. Grimes } 4937d56c0eeSAlexander Langer printf("\t\t%s: %lu\n", icmpnames[i], 4949b50d902SRodney W. Grimes icmpstat.icps_inhist[i]); 4959b50d902SRodney W. Grimes } 4967d56c0eeSAlexander Langer p(icps_reflect, "\t%lu message response%s generated\n"); 4979b50d902SRodney W. Grimes #undef p 49822694ebaSBruce Evans #undef p1a 4994e00c309SGarrett Wollman mib[3] = ICMPCTL_MASKREPL; 5004e00c309SGarrett Wollman len = sizeof i; 5014e00c309SGarrett Wollman if (sysctl(mib, 4, &i, &len, (void *)0, 0) < 0) 5024e00c309SGarrett Wollman return; 5034e00c309SGarrett Wollman printf("\tICMP address mask responses are %sabled\n", 5044e00c309SGarrett Wollman i ? "en" : "dis"); 5059b50d902SRodney W. Grimes } 5069b50d902SRodney W. Grimes 5079b50d902SRodney W. Grimes /* 5089b50d902SRodney W. Grimes * Dump IGMP statistics structure. 5099b50d902SRodney W. Grimes */ 5109b50d902SRodney W. Grimes void 5119b50d902SRodney W. Grimes igmp_stats(off, name) 5129b50d902SRodney W. Grimes u_long off; 5139b50d902SRodney W. Grimes char *name; 5149b50d902SRodney W. Grimes { 5159b50d902SRodney W. Grimes struct igmpstat igmpstat; 5164f81ef50SGarrett Wollman size_t len = sizeof igmpstat; 5179b50d902SRodney W. Grimes 5184f81ef50SGarrett Wollman if (sysctlbyname("net.inet.igmp.stats", &igmpstat, &len, 0, 0) < 0) { 5194f81ef50SGarrett Wollman warn("sysctl: net.inet.igmp.stats"); 5209b50d902SRodney W. Grimes return; 5214f81ef50SGarrett Wollman } 5224f81ef50SGarrett Wollman 5239b50d902SRodney W. Grimes printf("%s:\n", name); 5249b50d902SRodney W. Grimes 5259b50d902SRodney W. Grimes #define p(f, m) if (igmpstat.f || sflag <= 1) \ 5269b50d902SRodney W. Grimes printf(m, igmpstat.f, plural(igmpstat.f)) 5279b50d902SRodney W. Grimes #define py(f, m) if (igmpstat.f || sflag <= 1) \ 5289b50d902SRodney W. Grimes printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y") 5299b50d902SRodney W. Grimes p(igps_rcv_total, "\t%u message%s received\n"); 5309b50d902SRodney W. Grimes p(igps_rcv_tooshort, "\t%u message%s received with too few bytes\n"); 5319b50d902SRodney W. Grimes p(igps_rcv_badsum, "\t%u message%s received with bad checksum\n"); 5329b50d902SRodney W. Grimes py(igps_rcv_queries, "\t%u membership quer%s received\n"); 5339b50d902SRodney W. Grimes py(igps_rcv_badqueries, "\t%u membership quer%s received with invalid field(s)\n"); 5349b50d902SRodney W. Grimes p(igps_rcv_reports, "\t%u membership report%s received\n"); 5359b50d902SRodney W. Grimes p(igps_rcv_badreports, "\t%u membership report%s received with invalid field(s)\n"); 5369b50d902SRodney W. Grimes p(igps_rcv_ourreports, "\t%u membership report%s received for groups to which we belong\n"); 5379b50d902SRodney W. Grimes p(igps_snd_reports, "\t%u membership report%s sent\n"); 5389b50d902SRodney W. Grimes #undef p 5399b50d902SRodney W. Grimes #undef py 5409b50d902SRodney W. Grimes } 5419b50d902SRodney W. Grimes 5429b50d902SRodney W. Grimes /* 5439b50d902SRodney W. Grimes * Pretty print an Internet address (net address + port). 5449b50d902SRodney W. Grimes */ 5459b50d902SRodney W. Grimes void 5468d612dd2SPoul-Henning Kamp inetprint(in, port, proto,numeric) 5479b50d902SRodney W. Grimes register struct in_addr *in; 5489b50d902SRodney W. Grimes int port; 5499b50d902SRodney W. Grimes char *proto; 5508d612dd2SPoul-Henning Kamp int numeric; 5519b50d902SRodney W. Grimes { 5529b50d902SRodney W. Grimes struct servent *sp = 0; 5539b50d902SRodney W. Grimes char line[80], *cp; 5549b50d902SRodney W. Grimes int width; 5559b50d902SRodney W. Grimes 5568d612dd2SPoul-Henning Kamp sprintf(line, "%.*s.", (Aflag && !numeric) ? 12 : 16, inetname(in)); 5579b50d902SRodney W. Grimes cp = index(line, '\0'); 5588d612dd2SPoul-Henning Kamp if (!numeric && port) 5599b50d902SRodney W. Grimes sp = getservbyport((int)port, proto); 5609b50d902SRodney W. Grimes if (sp || port == 0) 5611ef69972SAndrey A. Chernov sprintf(cp, "%.15s", sp ? sp->s_name : "*"); 5629b50d902SRodney W. Grimes else 5639b50d902SRodney W. Grimes sprintf(cp, "%d", ntohs((u_short)port)); 5649b50d902SRodney W. Grimes width = Aflag ? 18 : 22; 5659b50d902SRodney W. Grimes printf(" %-*.*s", width, width, line); 5669b50d902SRodney W. Grimes } 5679b50d902SRodney W. Grimes 5689b50d902SRodney W. Grimes /* 5699b50d902SRodney W. Grimes * Construct an Internet address representation. 5709b50d902SRodney W. Grimes * If the nflag has been supplied, give 5719b50d902SRodney W. Grimes * numeric value, otherwise try for symbolic name. 5729b50d902SRodney W. Grimes */ 5739b50d902SRodney W. Grimes char * 5749b50d902SRodney W. Grimes inetname(inp) 5759b50d902SRodney W. Grimes struct in_addr *inp; 5769b50d902SRodney W. Grimes { 5779b50d902SRodney W. Grimes register char *cp; 5789a1f6729SWarner Losh static char line[MAXHOSTNAMELEN + 1]; 5799b50d902SRodney W. Grimes struct hostent *hp; 5809b50d902SRodney W. Grimes struct netent *np; 5819b50d902SRodney W. Grimes 5829b50d902SRodney W. Grimes cp = 0; 5839b50d902SRodney W. Grimes if (!nflag && inp->s_addr != INADDR_ANY) { 5849b50d902SRodney W. Grimes int net = inet_netof(*inp); 5859b50d902SRodney W. Grimes int lna = inet_lnaof(*inp); 5869b50d902SRodney W. Grimes 5879b50d902SRodney W. Grimes if (lna == INADDR_ANY) { 5889b50d902SRodney W. Grimes np = getnetbyaddr(net, AF_INET); 5899b50d902SRodney W. Grimes if (np) 5909b50d902SRodney W. Grimes cp = np->n_name; 5919b50d902SRodney W. Grimes } 5929b50d902SRodney W. Grimes if (cp == 0) { 5939b50d902SRodney W. Grimes hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET); 5949b50d902SRodney W. Grimes if (hp) { 5959b50d902SRodney W. Grimes cp = hp->h_name; 5969c437f50SPeter Wemm trimdomain(cp); 5979b50d902SRodney W. Grimes } 5989b50d902SRodney W. Grimes } 5999b50d902SRodney W. Grimes } 6009b50d902SRodney W. Grimes if (inp->s_addr == INADDR_ANY) 6019b50d902SRodney W. Grimes strcpy(line, "*"); 6029a1f6729SWarner Losh else if (cp) { 6039a1f6729SWarner Losh strncpy(line, cp, sizeof(line) - 1); 6049a1f6729SWarner Losh line[sizeof(line) - 1] = '\0'; 6059a1f6729SWarner Losh } else { 6069b50d902SRodney W. Grimes inp->s_addr = ntohl(inp->s_addr); 60722694ebaSBruce Evans #define C(x) ((u_int)((x) & 0xff)) 60822694ebaSBruce Evans sprintf(line, "%u.%u.%u.%u", C(inp->s_addr >> 24), 6099b50d902SRodney W. Grimes C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr)); 6109b50d902SRodney W. Grimes } 6119b50d902SRodney W. Grimes return (line); 6129b50d902SRodney W. Grimes } 613