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[] = 394f81ef50SGarrett Wollman "$Id: inet.c,v 1.26 1997/08/25 16:57:05 wollman 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)) 2429b50d902SRodney W. Grimes #define p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \ 2439b50d902SRodney W. Grimes printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2)) 2449b50d902SRodney W. Grimes #define p3(f, m) if (tcpstat.f || sflag <= 1) \ 2459b50d902SRodney W. Grimes printf(m, tcpstat.f, plurales(tcpstat.f)) 2469b50d902SRodney W. Grimes 247e1fb4daaSPaul Traina p(tcps_sndtotal, "\t%lu packet%s sent\n"); 2489b50d902SRodney W. Grimes p2(tcps_sndpack,tcps_sndbyte, 249e1fb4daaSPaul Traina "\t\t%lu data packet%s (%lu byte%s)\n"); 2509b50d902SRodney W. Grimes p2(tcps_sndrexmitpack, tcps_sndrexmitbyte, 251e1fb4daaSPaul Traina "\t\t%lu data packet%s (%lu byte%s) retransmitted\n"); 252e1fb4daaSPaul Traina p(tcps_mturesent, "\t\t%lu resend%s initiated by MTU discovery\n"); 2539b50d902SRodney W. Grimes p2(tcps_sndacks, tcps_delack, 254e1fb4daaSPaul Traina "\t\t%lu ack-only packet%s (%lu delayed)\n"); 255e1fb4daaSPaul Traina p(tcps_sndurg, "\t\t%lu URG only packet%s\n"); 256e1fb4daaSPaul Traina p(tcps_sndprobe, "\t\t%lu window probe packet%s\n"); 257e1fb4daaSPaul Traina p(tcps_sndwinup, "\t\t%lu window update packet%s\n"); 258e1fb4daaSPaul Traina p(tcps_sndctrl, "\t\t%lu control packet%s\n"); 259e1fb4daaSPaul Traina p(tcps_rcvtotal, "\t%lu packet%s received\n"); 260e1fb4daaSPaul Traina p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%lu ack%s (for %lu byte%s)\n"); 261e1fb4daaSPaul Traina p(tcps_rcvdupack, "\t\t%lu duplicate ack%s\n"); 262e1fb4daaSPaul Traina p(tcps_rcvacktoomuch, "\t\t%lu ack%s for unsent data\n"); 2639b50d902SRodney W. Grimes p2(tcps_rcvpack, tcps_rcvbyte, 264e1fb4daaSPaul Traina "\t\t%lu packet%s (%lu byte%s) received in-sequence\n"); 2659b50d902SRodney W. Grimes p2(tcps_rcvduppack, tcps_rcvdupbyte, 266e1fb4daaSPaul Traina "\t\t%lu completely duplicate packet%s (%lu byte%s)\n"); 267e1fb4daaSPaul Traina p(tcps_pawsdrop, "\t\t%lu old duplicate packet%s\n"); 2689b50d902SRodney W. Grimes p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte, 269e1fb4daaSPaul Traina "\t\t%lu packet%s with some dup. data (%lu byte%s duped)\n"); 2709b50d902SRodney W. Grimes p2(tcps_rcvoopack, tcps_rcvoobyte, 271e1fb4daaSPaul Traina "\t\t%lu out-of-order packet%s (%lu byte%s)\n"); 2729b50d902SRodney W. Grimes p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin, 273e1fb4daaSPaul Traina "\t\t%lu packet%s (%lu byte%s) of data after window\n"); 274e1fb4daaSPaul Traina p(tcps_rcvwinprobe, "\t\t%lu window probe%s\n"); 275e1fb4daaSPaul Traina p(tcps_rcvwinupd, "\t\t%lu window update packet%s\n"); 276e1fb4daaSPaul Traina p(tcps_rcvafterclose, "\t\t%lu packet%s received after close\n"); 277e1fb4daaSPaul Traina p(tcps_rcvbadsum, "\t\t%lu discarded for bad checksum%s\n"); 278e1fb4daaSPaul Traina p(tcps_rcvbadoff, "\t\t%lu discarded for bad header offset field%s\n"); 279e1fb4daaSPaul Traina p(tcps_rcvshort, "\t\t%lu discarded because packet too short\n"); 280e1fb4daaSPaul Traina p(tcps_connattempt, "\t%lu connection request%s\n"); 281e1fb4daaSPaul Traina p(tcps_accepts, "\t%lu connection accept%s\n"); 282e1fb4daaSPaul Traina p(tcps_badsyn, "\t%lu bad connection attempt%s\n"); 283e1fb4daaSPaul Traina p(tcps_listendrop, "\t%lu listen queue overflow%s\n"); 284e1fb4daaSPaul Traina p(tcps_connects, "\t%lu connection%s established (including accepts)\n"); 2859b50d902SRodney W. Grimes p2(tcps_closed, tcps_drops, 286e1fb4daaSPaul Traina "\t%lu connection%s closed (including %lu drop%s)\n"); 287e1fb4daaSPaul Traina p(tcps_cachedrtt, "\t\t%lu connection%s updated cached RTT on close\n"); 288861b1828SGarrett Wollman p(tcps_cachedrttvar, 289e1fb4daaSPaul Traina "\t\t%lu connection%s updated cached RTT variance on close\n"); 290861b1828SGarrett Wollman p(tcps_cachedssthresh, 291e1fb4daaSPaul Traina "\t\t%lu connection%s updated cached ssthresh on close\n"); 292e1fb4daaSPaul Traina p(tcps_conndrops, "\t%lu embryonic connection%s dropped\n"); 2939b50d902SRodney W. Grimes p2(tcps_rttupdated, tcps_segstimed, 294e1fb4daaSPaul Traina "\t%lu segment%s updated rtt (of %lu attempt%s)\n"); 295e1fb4daaSPaul Traina p(tcps_rexmttimeo, "\t%lu retransmit timeout%s\n"); 296e1fb4daaSPaul Traina p(tcps_timeoutdrop, "\t\t%lu connection%s dropped by rexmit timeout\n"); 297e1fb4daaSPaul Traina p(tcps_persisttimeo, "\t%lu persist timeout%s\n"); 298e1fb4daaSPaul Traina p(tcps_persistdrop, "\t\t%lu connection%s dropped by persist timeout\n"); 299e1fb4daaSPaul Traina p(tcps_keeptimeo, "\t%lu keepalive timeout%s\n"); 300e1fb4daaSPaul Traina p(tcps_keepprobe, "\t\t%lu keepalive probe%s sent\n"); 301e1fb4daaSPaul Traina p(tcps_keepdrops, "\t\t%lu connection%s dropped by keepalive\n"); 302e1fb4daaSPaul Traina p(tcps_predack, "\t%lu correct ACK header prediction%s\n"); 303e1fb4daaSPaul Traina p(tcps_preddat, "\t%lu correct data packet header prediction%s\n"); 3049b50d902SRodney W. Grimes #undef p 3059b50d902SRodney W. Grimes #undef p2 3069b50d902SRodney W. Grimes #undef p3 3079b50d902SRodney W. Grimes } 3089b50d902SRodney W. Grimes 3099b50d902SRodney W. Grimes /* 3109b50d902SRodney W. Grimes * Dump UDP statistics structure. 3119b50d902SRodney W. Grimes */ 3129b50d902SRodney W. Grimes void 3139b50d902SRodney W. Grimes udp_stats(off, name) 3149b50d902SRodney W. Grimes u_long off; 3159b50d902SRodney W. Grimes char *name; 3169b50d902SRodney W. Grimes { 3179b50d902SRodney W. Grimes struct udpstat udpstat; 3184f81ef50SGarrett Wollman size_t len = sizeof udpstat; 3199b50d902SRodney W. Grimes u_long delivered; 3209b50d902SRodney W. Grimes 3214f81ef50SGarrett Wollman if (sysctlbyname("net.inet.udp.stats", &udpstat, &len, 0, 0) < 0) { 3224f81ef50SGarrett Wollman warn("sysctl: net.inet.udp.stats"); 3239b50d902SRodney W. Grimes return; 3244f81ef50SGarrett Wollman } 3254f81ef50SGarrett Wollman 3269b50d902SRodney W. Grimes printf("%s:\n", name); 3279b50d902SRodney W. Grimes #define p(f, m) if (udpstat.f || sflag <= 1) \ 3289b50d902SRodney W. Grimes printf(m, udpstat.f, plural(udpstat.f)) 3297d56c0eeSAlexander Langer p(udps_ipackets, "\t%lu datagram%s received\n"); 3307d56c0eeSAlexander Langer p(udps_hdrops, "\t%lu with incomplete header\n"); 3317d56c0eeSAlexander Langer p(udps_badlen, "\t%lu with bad data length field\n"); 3327d56c0eeSAlexander Langer p(udps_badsum, "\t%lu with bad checksum\n"); 3337d56c0eeSAlexander Langer p(udps_noport, "\t%lu dropped due to no socket\n"); 3347d56c0eeSAlexander Langer p(udps_noportbcast, "\t%lu broadcast/multicast datagram%s dropped due to no socket\n"); 3357d56c0eeSAlexander Langer p(udps_fullsock, "\t%lu dropped due to full socket buffers\n"); 336759b7d75SGarrett Wollman p(udpps_pcbhashmiss, "\t%lu not for hashed pcb\n"); 3379b50d902SRodney W. Grimes delivered = udpstat.udps_ipackets - 3389b50d902SRodney W. Grimes udpstat.udps_hdrops - 3399b50d902SRodney W. Grimes udpstat.udps_badlen - 3409b50d902SRodney W. Grimes udpstat.udps_badsum - 3419b50d902SRodney W. Grimes udpstat.udps_noport - 3429b50d902SRodney W. Grimes udpstat.udps_noportbcast - 3439b50d902SRodney W. Grimes udpstat.udps_fullsock; 3449b50d902SRodney W. Grimes if (delivered || sflag <= 1) 3457d56c0eeSAlexander Langer printf("\t%lu delivered\n", delivered); 3467d56c0eeSAlexander Langer p(udps_opackets, "\t%lu datagram%s output\n"); 3479b50d902SRodney W. Grimes #undef p 3489b50d902SRodney W. Grimes } 3499b50d902SRodney W. Grimes 3509b50d902SRodney W. Grimes /* 3519b50d902SRodney W. Grimes * Dump IP statistics structure. 3529b50d902SRodney W. Grimes */ 3539b50d902SRodney W. Grimes void 3549b50d902SRodney W. Grimes ip_stats(off, name) 3559b50d902SRodney W. Grimes u_long off; 3569b50d902SRodney W. Grimes char *name; 3579b50d902SRodney W. Grimes { 3589b50d902SRodney W. Grimes struct ipstat ipstat; 3594f81ef50SGarrett Wollman size_t len = sizeof ipstat; 3609b50d902SRodney W. Grimes 3614f81ef50SGarrett Wollman if (sysctlbyname("net.inet.ip.stats", &ipstat, &len, 0, 0) < 0) { 3624f81ef50SGarrett Wollman warn("sysctl: net.inet.ip.stats"); 3639b50d902SRodney W. Grimes return; 3644f81ef50SGarrett Wollman } 3654f81ef50SGarrett Wollman 3669b50d902SRodney W. Grimes printf("%s:\n", name); 3679b50d902SRodney W. Grimes 3689b50d902SRodney W. Grimes #define p(f, m) if (ipstat.f || sflag <= 1) \ 3699b50d902SRodney W. Grimes printf(m, ipstat.f, plural(ipstat.f)) 3709b50d902SRodney W. Grimes 3717d56c0eeSAlexander Langer p(ips_total, "\t%lu total packet%s received\n"); 3727d56c0eeSAlexander Langer p(ips_badsum, "\t%lu bad header checksum%s\n"); 3737d56c0eeSAlexander Langer p(ips_toosmall, "\t%lu with size smaller than minimum\n"); 3747d56c0eeSAlexander Langer p(ips_tooshort, "\t%lu with data size < data length\n"); 3757d56c0eeSAlexander Langer p(ips_badhlen, "\t%lu with header length < data size\n"); 3767d56c0eeSAlexander Langer p(ips_badlen, "\t%lu with data length < header length\n"); 3777d56c0eeSAlexander Langer p(ips_badoptions, "\t%lu with bad options\n"); 3787d56c0eeSAlexander Langer p(ips_badvers, "\t%lu with incorrect version number\n"); 3797d56c0eeSAlexander Langer p(ips_fragments, "\t%lu fragment%s received\n"); 3807d56c0eeSAlexander Langer p(ips_fragdropped, "\t%lu fragment%s dropped (dup or out of space)\n"); 3817d56c0eeSAlexander Langer p(ips_fragtimeout, "\t%lu fragment%s dropped after timeout\n"); 3827d56c0eeSAlexander Langer p(ips_reassembled, "\t%lu packet%s reassembled ok\n"); 3837d56c0eeSAlexander Langer p(ips_delivered, "\t%lu packet%s for this host\n"); 3847d56c0eeSAlexander Langer p(ips_noproto, "\t%lu packet%s for unknown/unsupported protocol\n"); 3857d56c0eeSAlexander Langer p(ips_forward, "\t%lu packet%s forwarded\n"); 3867d56c0eeSAlexander Langer p(ips_cantforward, "\t%lu packet%s not forwardable\n"); 387a5969f5fSGarrett Wollman p(ips_notmember, 388a5969f5fSGarrett Wollman "\t%lu packet%s received for unknown multicast group\n"); 3897d56c0eeSAlexander Langer p(ips_redirectsent, "\t%lu redirect%s sent\n"); 3907d56c0eeSAlexander Langer p(ips_localout, "\t%lu packet%s sent from this host\n"); 3917d56c0eeSAlexander Langer p(ips_rawout, "\t%lu packet%s sent with fabricated ip header\n"); 392a5969f5fSGarrett Wollman p(ips_odropped, 393a5969f5fSGarrett Wollman "\t%lu output packet%s dropped due to no bufs, etc.\n"); 3947d56c0eeSAlexander Langer p(ips_noroute, "\t%lu output packet%s discarded due to no route\n"); 3957d56c0eeSAlexander Langer p(ips_fragmented, "\t%lu output datagram%s fragmented\n"); 3967d56c0eeSAlexander Langer p(ips_ofragments, "\t%lu fragment%s created\n"); 3977d56c0eeSAlexander Langer p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n"); 3989b50d902SRodney W. Grimes #undef p 3999b50d902SRodney W. Grimes } 4009b50d902SRodney W. Grimes 4019b50d902SRodney W. Grimes static char *icmpnames[] = { 4029b50d902SRodney W. Grimes "echo reply", 4039b50d902SRodney W. Grimes "#1", 4049b50d902SRodney W. Grimes "#2", 4059b50d902SRodney W. Grimes "destination unreachable", 4069b50d902SRodney W. Grimes "source quench", 4079b50d902SRodney W. Grimes "routing redirect", 4089b50d902SRodney W. Grimes "#6", 4099b50d902SRodney W. Grimes "#7", 4109b50d902SRodney W. Grimes "echo", 4117b46dd00SGarrett Wollman "router advertisement", 4127b46dd00SGarrett Wollman "router solicitation", 4139b50d902SRodney W. Grimes "time exceeded", 4149b50d902SRodney W. Grimes "parameter problem", 4159b50d902SRodney W. Grimes "time stamp", 4169b50d902SRodney W. Grimes "time stamp reply", 4179b50d902SRodney W. Grimes "information request", 4189b50d902SRodney W. Grimes "information request reply", 4199b50d902SRodney W. Grimes "address mask request", 4209b50d902SRodney W. Grimes "address mask reply", 4219b50d902SRodney W. Grimes }; 4229b50d902SRodney W. Grimes 4239b50d902SRodney W. Grimes /* 4249b50d902SRodney W. Grimes * Dump ICMP statistics. 4259b50d902SRodney W. Grimes */ 4269b50d902SRodney W. Grimes void 4279b50d902SRodney W. Grimes icmp_stats(off, name) 4289b50d902SRodney W. Grimes u_long off; 4299b50d902SRodney W. Grimes char *name; 4309b50d902SRodney W. Grimes { 4319b50d902SRodney W. Grimes struct icmpstat icmpstat; 4324e00c309SGarrett Wollman int i, first; 4334e00c309SGarrett Wollman int mib[4]; /* CTL_NET + PF_INET + IPPROTO_ICMP + req */ 4344e00c309SGarrett Wollman size_t len; 4359b50d902SRodney W. Grimes 4364e00c309SGarrett Wollman mib[0] = CTL_NET; 4374e00c309SGarrett Wollman mib[1] = PF_INET; 4384e00c309SGarrett Wollman mib[2] = IPPROTO_ICMP; 4394e00c309SGarrett Wollman mib[3] = ICMPCTL_STATS; 4404e00c309SGarrett Wollman 4414e00c309SGarrett Wollman len = sizeof icmpstat; 4424e00c309SGarrett Wollman memset(&icmpstat, 0, len); 4434e00c309SGarrett Wollman if (sysctl(mib, 4, &icmpstat, &len, (void *)0, 0) < 0) 4444e00c309SGarrett Wollman return; /* XXX should complain, but not traditional */ 4454e00c309SGarrett Wollman 4469b50d902SRodney W. Grimes printf("%s:\n", name); 4479b50d902SRodney W. Grimes 4489b50d902SRodney W. Grimes #define p(f, m) if (icmpstat.f || sflag <= 1) \ 4499b50d902SRodney W. Grimes printf(m, icmpstat.f, plural(icmpstat.f)) 4509b50d902SRodney W. Grimes 4517d56c0eeSAlexander Langer p(icps_error, "\t%lu call%s to icmp_error\n"); 4529b50d902SRodney W. Grimes p(icps_oldicmp, 4537d56c0eeSAlexander Langer "\t%lu error%s not generated 'cuz old message was icmp\n"); 4549b50d902SRodney W. Grimes for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) 4559b50d902SRodney W. Grimes if (icmpstat.icps_outhist[i] != 0) { 4569b50d902SRodney W. Grimes if (first) { 4579b50d902SRodney W. Grimes printf("\tOutput histogram:\n"); 4589b50d902SRodney W. Grimes first = 0; 4599b50d902SRodney W. Grimes } 4607d56c0eeSAlexander Langer printf("\t\t%s: %lu\n", icmpnames[i], 4619b50d902SRodney W. Grimes icmpstat.icps_outhist[i]); 4629b50d902SRodney W. Grimes } 4637d56c0eeSAlexander Langer p(icps_badcode, "\t%lu message%s with bad code fields\n"); 4647d56c0eeSAlexander Langer p(icps_tooshort, "\t%lu message%s < minimum length\n"); 4657d56c0eeSAlexander Langer p(icps_checksum, "\t%lu bad checksum%s\n"); 4667d56c0eeSAlexander Langer p(icps_badlen, "\t%lu message%s with bad length\n"); 4674e00c309SGarrett Wollman p(icps_bmcastecho, "\t%lu multicast echo requests ignored\n"); 4684e00c309SGarrett Wollman p(icps_bmcasttstamp, "\t%lu multicast timestamp requests ignored\n"); 4699b50d902SRodney W. Grimes for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) 4709b50d902SRodney W. Grimes if (icmpstat.icps_inhist[i] != 0) { 4719b50d902SRodney W. Grimes if (first) { 4729b50d902SRodney W. Grimes printf("\tInput histogram:\n"); 4739b50d902SRodney W. Grimes first = 0; 4749b50d902SRodney W. Grimes } 4757d56c0eeSAlexander Langer printf("\t\t%s: %lu\n", icmpnames[i], 4769b50d902SRodney W. Grimes icmpstat.icps_inhist[i]); 4779b50d902SRodney W. Grimes } 4787d56c0eeSAlexander Langer p(icps_reflect, "\t%lu message response%s generated\n"); 4799b50d902SRodney W. Grimes #undef p 4804e00c309SGarrett Wollman mib[3] = ICMPCTL_MASKREPL; 4814e00c309SGarrett Wollman len = sizeof i; 4824e00c309SGarrett Wollman if (sysctl(mib, 4, &i, &len, (void *)0, 0) < 0) 4834e00c309SGarrett Wollman return; 4844e00c309SGarrett Wollman printf("\tICMP address mask responses are %sabled\n", 4854e00c309SGarrett Wollman i ? "en" : "dis"); 4869b50d902SRodney W. Grimes } 4879b50d902SRodney W. Grimes 4889b50d902SRodney W. Grimes /* 4899b50d902SRodney W. Grimes * Dump IGMP statistics structure. 4909b50d902SRodney W. Grimes */ 4919b50d902SRodney W. Grimes void 4929b50d902SRodney W. Grimes igmp_stats(off, name) 4939b50d902SRodney W. Grimes u_long off; 4949b50d902SRodney W. Grimes char *name; 4959b50d902SRodney W. Grimes { 4969b50d902SRodney W. Grimes struct igmpstat igmpstat; 4974f81ef50SGarrett Wollman size_t len = sizeof igmpstat; 4989b50d902SRodney W. Grimes 4994f81ef50SGarrett Wollman if (sysctlbyname("net.inet.igmp.stats", &igmpstat, &len, 0, 0) < 0) { 5004f81ef50SGarrett Wollman warn("sysctl: net.inet.igmp.stats"); 5019b50d902SRodney W. Grimes return; 5024f81ef50SGarrett Wollman } 5034f81ef50SGarrett Wollman 5049b50d902SRodney W. Grimes printf("%s:\n", name); 5059b50d902SRodney W. Grimes 5069b50d902SRodney W. Grimes #define p(f, m) if (igmpstat.f || sflag <= 1) \ 5079b50d902SRodney W. Grimes printf(m, igmpstat.f, plural(igmpstat.f)) 5089b50d902SRodney W. Grimes #define py(f, m) if (igmpstat.f || sflag <= 1) \ 5099b50d902SRodney W. Grimes printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y") 5109b50d902SRodney W. Grimes p(igps_rcv_total, "\t%u message%s received\n"); 5119b50d902SRodney W. Grimes p(igps_rcv_tooshort, "\t%u message%s received with too few bytes\n"); 5129b50d902SRodney W. Grimes p(igps_rcv_badsum, "\t%u message%s received with bad checksum\n"); 5139b50d902SRodney W. Grimes py(igps_rcv_queries, "\t%u membership quer%s received\n"); 5149b50d902SRodney W. Grimes py(igps_rcv_badqueries, "\t%u membership quer%s received with invalid field(s)\n"); 5159b50d902SRodney W. Grimes p(igps_rcv_reports, "\t%u membership report%s received\n"); 5169b50d902SRodney W. Grimes p(igps_rcv_badreports, "\t%u membership report%s received with invalid field(s)\n"); 5179b50d902SRodney W. Grimes p(igps_rcv_ourreports, "\t%u membership report%s received for groups to which we belong\n"); 5189b50d902SRodney W. Grimes p(igps_snd_reports, "\t%u membership report%s sent\n"); 5199b50d902SRodney W. Grimes #undef p 5209b50d902SRodney W. Grimes #undef py 5219b50d902SRodney W. Grimes } 5229b50d902SRodney W. Grimes 5239b50d902SRodney W. Grimes /* 5249b50d902SRodney W. Grimes * Pretty print an Internet address (net address + port). 5259b50d902SRodney W. Grimes */ 5269b50d902SRodney W. Grimes void 5278d612dd2SPoul-Henning Kamp inetprint(in, port, proto,numeric) 5289b50d902SRodney W. Grimes register struct in_addr *in; 5299b50d902SRodney W. Grimes int port; 5309b50d902SRodney W. Grimes char *proto; 5318d612dd2SPoul-Henning Kamp int numeric; 5329b50d902SRodney W. Grimes { 5339b50d902SRodney W. Grimes struct servent *sp = 0; 5349b50d902SRodney W. Grimes char line[80], *cp; 5359b50d902SRodney W. Grimes int width; 5369b50d902SRodney W. Grimes 5378d612dd2SPoul-Henning Kamp sprintf(line, "%.*s.", (Aflag && !numeric) ? 12 : 16, inetname(in)); 5389b50d902SRodney W. Grimes cp = index(line, '\0'); 5398d612dd2SPoul-Henning Kamp if (!numeric && port) 5409b50d902SRodney W. Grimes sp = getservbyport((int)port, proto); 5419b50d902SRodney W. Grimes if (sp || port == 0) 5421ef69972SAndrey A. Chernov sprintf(cp, "%.15s", sp ? sp->s_name : "*"); 5439b50d902SRodney W. Grimes else 5449b50d902SRodney W. Grimes sprintf(cp, "%d", ntohs((u_short)port)); 5459b50d902SRodney W. Grimes width = Aflag ? 18 : 22; 5469b50d902SRodney W. Grimes printf(" %-*.*s", width, width, line); 5479b50d902SRodney W. Grimes } 5489b50d902SRodney W. Grimes 5499b50d902SRodney W. Grimes /* 5509b50d902SRodney W. Grimes * Construct an Internet address representation. 5519b50d902SRodney W. Grimes * If the nflag has been supplied, give 5529b50d902SRodney W. Grimes * numeric value, otherwise try for symbolic name. 5539b50d902SRodney W. Grimes */ 5549b50d902SRodney W. Grimes char * 5559b50d902SRodney W. Grimes inetname(inp) 5569b50d902SRodney W. Grimes struct in_addr *inp; 5579b50d902SRodney W. Grimes { 5589b50d902SRodney W. Grimes register char *cp; 5599b50d902SRodney W. Grimes static char line[50]; 5609b50d902SRodney W. Grimes struct hostent *hp; 5619b50d902SRodney W. Grimes struct netent *np; 5629b50d902SRodney W. Grimes 5639b50d902SRodney W. Grimes cp = 0; 5649b50d902SRodney W. Grimes if (!nflag && inp->s_addr != INADDR_ANY) { 5659b50d902SRodney W. Grimes int net = inet_netof(*inp); 5669b50d902SRodney W. Grimes int lna = inet_lnaof(*inp); 5679b50d902SRodney W. Grimes 5689b50d902SRodney W. Grimes if (lna == INADDR_ANY) { 5699b50d902SRodney W. Grimes np = getnetbyaddr(net, AF_INET); 5709b50d902SRodney W. Grimes if (np) 5719b50d902SRodney W. Grimes cp = np->n_name; 5729b50d902SRodney W. Grimes } 5739b50d902SRodney W. Grimes if (cp == 0) { 5749b50d902SRodney W. Grimes hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET); 5759b50d902SRodney W. Grimes if (hp) { 5769b50d902SRodney W. Grimes cp = hp->h_name; 5779c437f50SPeter Wemm trimdomain(cp); 5789b50d902SRodney W. Grimes } 5799b50d902SRodney W. Grimes } 5809b50d902SRodney W. Grimes } 5819b50d902SRodney W. Grimes if (inp->s_addr == INADDR_ANY) 5829b50d902SRodney W. Grimes strcpy(line, "*"); 5839b50d902SRodney W. Grimes else if (cp) 5849b50d902SRodney W. Grimes strcpy(line, cp); 5859b50d902SRodney W. Grimes else { 5869b50d902SRodney W. Grimes inp->s_addr = ntohl(inp->s_addr); 5879b50d902SRodney W. Grimes #define C(x) ((x) & 0xff) 5887d56c0eeSAlexander Langer sprintf(line, "%lu.%lu.%lu.%lu", C(inp->s_addr >> 24), 5899b50d902SRodney W. Grimes C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr)); 5909b50d902SRodney W. Grimes } 5919b50d902SRodney W. Grimes return (line); 5929b50d902SRodney W. Grimes } 593