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 3505ddff6eSPeter Wemm static char sccsid[] = "@(#)inet.c 8.5 (Berkeley) 5/24/95"; 369b50d902SRodney W. Grimes #endif /* not lint */ 379b50d902SRodney W. Grimes 389b50d902SRodney W. Grimes #include <sys/param.h> 399b50d902SRodney W. Grimes #include <sys/socket.h> 409b50d902SRodney W. Grimes #include <sys/socketvar.h> 419b50d902SRodney W. Grimes #include <sys/mbuf.h> 429b50d902SRodney W. Grimes #include <sys/protosw.h> 437452c2a5SDavid Greenman #include <sys/queue.h> 449b50d902SRodney W. Grimes 459b50d902SRodney W. Grimes #include <net/route.h> 469b50d902SRodney W. Grimes #include <netinet/in.h> 479b50d902SRodney W. Grimes #include <netinet/in_systm.h> 489b50d902SRodney W. Grimes #include <netinet/ip.h> 499b50d902SRodney W. Grimes #include <netinet/in_pcb.h> 509b50d902SRodney W. Grimes #include <netinet/ip_icmp.h> 519b50d902SRodney W. Grimes #include <netinet/icmp_var.h> 529b50d902SRodney W. Grimes #include <netinet/igmp_var.h> 539b50d902SRodney W. Grimes #include <netinet/ip_var.h> 549b50d902SRodney W. Grimes #include <netinet/tcp.h> 559b50d902SRodney W. Grimes #include <netinet/tcpip.h> 569b50d902SRodney W. Grimes #include <netinet/tcp_seq.h> 579b50d902SRodney W. Grimes #define TCPSTATES 589b50d902SRodney W. Grimes #include <netinet/tcp_fsm.h> 599b50d902SRodney W. Grimes #include <netinet/tcp_timer.h> 609b50d902SRodney W. Grimes #include <netinet/tcp_var.h> 619b50d902SRodney W. Grimes #include <netinet/tcp_debug.h> 629b50d902SRodney W. Grimes #include <netinet/udp.h> 639b50d902SRodney W. Grimes #include <netinet/udp_var.h> 649b50d902SRodney W. Grimes 659b50d902SRodney W. Grimes #include <arpa/inet.h> 669b50d902SRodney W. Grimes #include <netdb.h> 679b50d902SRodney W. Grimes #include <stdio.h> 689b50d902SRodney W. Grimes #include <string.h> 699b50d902SRodney W. Grimes #include <unistd.h> 709b50d902SRodney W. Grimes #include "netstat.h" 719b50d902SRodney W. Grimes 729b50d902SRodney W. Grimes struct inpcb inpcb; 739b50d902SRodney W. Grimes struct tcpcb tcpcb; 749b50d902SRodney W. Grimes struct socket sockb; 759b50d902SRodney W. Grimes 769b50d902SRodney W. Grimes char *inetname __P((struct in_addr *)); 779b50d902SRodney W. Grimes void inetprint __P((struct in_addr *, int, char *)); 789b50d902SRodney W. Grimes 799b50d902SRodney W. Grimes /* 809b50d902SRodney W. Grimes * Print a summary of connections related to an Internet 819b50d902SRodney W. Grimes * protocol. For TCP, also give state of connection. 829b50d902SRodney W. Grimes * Listening processes (aflag) are suppressed unless the 839b50d902SRodney W. Grimes * -a (all) flag is specified. 849b50d902SRodney W. Grimes */ 859b50d902SRodney W. Grimes void 869b50d902SRodney W. Grimes protopr(off, name) 879b50d902SRodney W. Grimes u_long off; 889b50d902SRodney W. Grimes char *name; 899b50d902SRodney W. Grimes { 907452c2a5SDavid Greenman struct inpcbhead head; 919b50d902SRodney W. Grimes register struct inpcb *prev, *next; 929b50d902SRodney W. Grimes int istcp; 939b50d902SRodney W. Grimes static int first = 1; 949b50d902SRodney W. Grimes 959b50d902SRodney W. Grimes if (off == 0) 969b50d902SRodney W. Grimes return; 977452c2a5SDavid Greenman 989b50d902SRodney W. Grimes istcp = strcmp(name, "tcp") == 0; 997452c2a5SDavid Greenman kread(off, (char *)&head, sizeof (struct inpcbhead)); 1009b50d902SRodney W. Grimes prev = (struct inpcb *)off; 1017452c2a5SDavid Greenman 102a9d6f1a7SDavid Greenman for (next = head.lh_first; next != NULL; next = inpcb.inp_list.le_next) { 1033aa80b1dSDavid Greenman if (kread((u_long)next, (char *)&inpcb, sizeof (inpcb))) { 1043aa80b1dSDavid Greenman printf("???\n"); 1053aa80b1dSDavid Greenman break; 1063aa80b1dSDavid Greenman } 1079b50d902SRodney W. Grimes if (!aflag && 1089b50d902SRodney W. Grimes inet_lnaof(inpcb.inp_laddr) == INADDR_ANY) { 1099b50d902SRodney W. Grimes prev = next; 1109b50d902SRodney W. Grimes continue; 1119b50d902SRodney W. Grimes } 1123aa80b1dSDavid Greenman if (kread((u_long)inpcb.inp_socket, (char *)&sockb, sizeof (sockb))) { 1133aa80b1dSDavid Greenman printf("???\n"); 1143aa80b1dSDavid Greenman break; 1153aa80b1dSDavid Greenman }; 1169b50d902SRodney W. Grimes if (istcp) { 1173aa80b1dSDavid Greenman if (kread((u_long)inpcb.inp_ppcb, 1183aa80b1dSDavid Greenman (char *)&tcpcb, sizeof (tcpcb))) { 1193aa80b1dSDavid Greenman printf("???\n"); 1203aa80b1dSDavid Greenman break; 1213aa80b1dSDavid Greenman }; 1229b50d902SRodney W. Grimes } 1239b50d902SRodney W. Grimes if (first) { 1249b50d902SRodney W. Grimes printf("Active Internet connections"); 1259b50d902SRodney W. Grimes if (aflag) 1269b50d902SRodney W. Grimes printf(" (including servers)"); 1279b50d902SRodney W. Grimes putchar('\n'); 1289b50d902SRodney W. Grimes if (Aflag) 1299b50d902SRodney W. Grimes printf("%-8.8s ", "PCB"); 1309b50d902SRodney W. Grimes printf(Aflag ? 1319b50d902SRodney W. Grimes "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" : 1329b50d902SRodney W. Grimes "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n", 1339b50d902SRodney W. Grimes "Proto", "Recv-Q", "Send-Q", 1349b50d902SRodney W. Grimes "Local Address", "Foreign Address", "(state)"); 1359b50d902SRodney W. Grimes first = 0; 1369b50d902SRodney W. Grimes } 1379b50d902SRodney W. Grimes if (Aflag) 1389b50d902SRodney W. Grimes if (istcp) 1399b50d902SRodney W. Grimes printf("%8x ", inpcb.inp_ppcb); 1409b50d902SRodney W. Grimes else 1419b50d902SRodney W. Grimes printf("%8x ", next); 1429b50d902SRodney W. Grimes printf("%-5.5s %6d %6d ", name, sockb.so_rcv.sb_cc, 1439b50d902SRodney W. Grimes sockb.so_snd.sb_cc); 1449b50d902SRodney W. Grimes inetprint(&inpcb.inp_laddr, (int)inpcb.inp_lport, name); 1459b50d902SRodney W. Grimes inetprint(&inpcb.inp_faddr, (int)inpcb.inp_fport, name); 1469b50d902SRodney W. Grimes if (istcp) { 1479b50d902SRodney W. Grimes if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES) 1489b50d902SRodney W. Grimes printf(" %d", tcpcb.t_state); 1499a94a597SGarrett Wollman else { 1509b50d902SRodney W. Grimes printf(" %s", tcpstates[tcpcb.t_state]); 151513822ddSAdam David #if defined(TF_NEEDSYN) && defined(TF_NEEDFIN) 1529a94a597SGarrett Wollman /* Show T/TCP `hidden state' */ 1539a94a597SGarrett Wollman if (tcpcb.t_flags & (TF_NEEDSYN|TF_NEEDFIN)) 1549a94a597SGarrett Wollman putchar('*'); 155513822ddSAdam David #endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */ 1569a94a597SGarrett Wollman } 1579b50d902SRodney W. Grimes } 1589b50d902SRodney W. Grimes putchar('\n'); 1599b50d902SRodney W. Grimes prev = next; 1609b50d902SRodney W. Grimes } 1619b50d902SRodney W. Grimes } 1629b50d902SRodney W. Grimes 1639b50d902SRodney W. Grimes /* 1649b50d902SRodney W. Grimes * Dump TCP statistics structure. 1659b50d902SRodney W. Grimes */ 1669b50d902SRodney W. Grimes void 1679b50d902SRodney W. Grimes tcp_stats(off, name) 1689b50d902SRodney W. Grimes u_long off; 1699b50d902SRodney W. Grimes char *name; 1709b50d902SRodney W. Grimes { 1719b50d902SRodney W. Grimes struct tcpstat tcpstat; 1729b50d902SRodney W. Grimes 1739b50d902SRodney W. Grimes if (off == 0) 1749b50d902SRodney W. Grimes return; 1759b50d902SRodney W. Grimes printf ("%s:\n", name); 1769b50d902SRodney W. Grimes kread(off, (char *)&tcpstat, sizeof (tcpstat)); 1779b50d902SRodney W. Grimes 1789b50d902SRodney W. Grimes #define p(f, m) if (tcpstat.f || sflag <= 1) \ 1799b50d902SRodney W. Grimes printf(m, tcpstat.f, plural(tcpstat.f)) 1809b50d902SRodney W. Grimes #define p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \ 1819b50d902SRodney W. Grimes printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2)) 1829b50d902SRodney W. Grimes #define p3(f, m) if (tcpstat.f || sflag <= 1) \ 1839b50d902SRodney W. Grimes printf(m, tcpstat.f, plurales(tcpstat.f)) 1849b50d902SRodney W. Grimes 1859b50d902SRodney W. Grimes p(tcps_sndtotal, "\t%d packet%s sent\n"); 1869b50d902SRodney W. Grimes p2(tcps_sndpack,tcps_sndbyte, 1879b50d902SRodney W. Grimes "\t\t%d data packet%s (%d byte%s)\n"); 1889b50d902SRodney W. Grimes p2(tcps_sndrexmitpack, tcps_sndrexmitbyte, 1899b50d902SRodney W. Grimes "\t\t%d data packet%s (%d byte%s) retransmitted\n"); 190231bfb09SGarrett Wollman p(tcps_mturesent, "\t\t%d resend%s initiated by MTU discovery\n"); 1919b50d902SRodney W. Grimes p2(tcps_sndacks, tcps_delack, 1929b50d902SRodney W. Grimes "\t\t%d ack-only packet%s (%d delayed)\n"); 1939b50d902SRodney W. Grimes p(tcps_sndurg, "\t\t%d URG only packet%s\n"); 1949b50d902SRodney W. Grimes p(tcps_sndprobe, "\t\t%d window probe packet%s\n"); 1959b50d902SRodney W. Grimes p(tcps_sndwinup, "\t\t%d window update packet%s\n"); 1969b50d902SRodney W. Grimes p(tcps_sndctrl, "\t\t%d control packet%s\n"); 1979b50d902SRodney W. Grimes p(tcps_rcvtotal, "\t%d packet%s received\n"); 1989b50d902SRodney W. Grimes p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%d ack%s (for %d byte%s)\n"); 1999b50d902SRodney W. Grimes p(tcps_rcvdupack, "\t\t%d duplicate ack%s\n"); 2009b50d902SRodney W. Grimes p(tcps_rcvacktoomuch, "\t\t%d ack%s for unsent data\n"); 2019b50d902SRodney W. Grimes p2(tcps_rcvpack, tcps_rcvbyte, 2029b50d902SRodney W. Grimes "\t\t%d packet%s (%d byte%s) received in-sequence\n"); 2039b50d902SRodney W. Grimes p2(tcps_rcvduppack, tcps_rcvdupbyte, 2049b50d902SRodney W. Grimes "\t\t%d completely duplicate packet%s (%d byte%s)\n"); 2059b50d902SRodney W. Grimes p(tcps_pawsdrop, "\t\t%d old duplicate packet%s\n"); 2069b50d902SRodney W. Grimes p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte, 2079b50d902SRodney W. Grimes "\t\t%d packet%s with some dup. data (%d byte%s duped)\n"); 2089b50d902SRodney W. Grimes p2(tcps_rcvoopack, tcps_rcvoobyte, 2099b50d902SRodney W. Grimes "\t\t%d out-of-order packet%s (%d byte%s)\n"); 2109b50d902SRodney W. Grimes p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin, 2119b50d902SRodney W. Grimes "\t\t%d packet%s (%d byte%s) of data after window\n"); 2129b50d902SRodney W. Grimes p(tcps_rcvwinprobe, "\t\t%d window probe%s\n"); 2139b50d902SRodney W. Grimes p(tcps_rcvwinupd, "\t\t%d window update packet%s\n"); 2149b50d902SRodney W. Grimes p(tcps_rcvafterclose, "\t\t%d packet%s received after close\n"); 2159b50d902SRodney W. Grimes p(tcps_rcvbadsum, "\t\t%d discarded for bad checksum%s\n"); 2169b50d902SRodney W. Grimes p(tcps_rcvbadoff, "\t\t%d discarded for bad header offset field%s\n"); 2179b50d902SRodney W. Grimes p(tcps_rcvshort, "\t\t%d discarded because packet too short\n"); 2189b50d902SRodney W. Grimes p(tcps_connattempt, "\t%d connection request%s\n"); 2199b50d902SRodney W. Grimes p(tcps_accepts, "\t%d connection accept%s\n"); 22005ddff6eSPeter Wemm p(tcps_badsyn, "\t%d bad connection attempt%s\n"); 2219b50d902SRodney W. Grimes p(tcps_connects, "\t%d connection%s established (including accepts)\n"); 2229b50d902SRodney W. Grimes p2(tcps_closed, tcps_drops, 2239b50d902SRodney W. Grimes "\t%d connection%s closed (including %d drop%s)\n"); 2247b4315a7SGarrett Wollman p(tcps_cachedrtt, "\t\t%d connection%s updated cached RTT on close\n"); 225861b1828SGarrett Wollman p(tcps_cachedrttvar, 2267b4315a7SGarrett Wollman "\t\t%d connection%s updated cached RTT variance on close\n"); 227861b1828SGarrett Wollman p(tcps_cachedssthresh, 228861b1828SGarrett Wollman "\t\t%d connection%s updated cached ssthresh on close\n"); 2299b50d902SRodney W. Grimes p(tcps_conndrops, "\t%d embryonic connection%s dropped\n"); 2309b50d902SRodney W. Grimes p2(tcps_rttupdated, tcps_segstimed, 2319b50d902SRodney W. Grimes "\t%d segment%s updated rtt (of %d attempt%s)\n"); 2329b50d902SRodney W. Grimes p(tcps_rexmttimeo, "\t%d retransmit timeout%s\n"); 2339b50d902SRodney W. Grimes p(tcps_timeoutdrop, "\t\t%d connection%s dropped by rexmit timeout\n"); 2349b50d902SRodney W. Grimes p(tcps_persisttimeo, "\t%d persist timeout%s\n"); 23589d7f49aSDavid Greenman p(tcps_persistdrop, "\t\t%d connection%s dropped by persist timeout\n"); 2369b50d902SRodney W. Grimes p(tcps_keeptimeo, "\t%d keepalive timeout%s\n"); 2379b50d902SRodney W. Grimes p(tcps_keepprobe, "\t\t%d keepalive probe%s sent\n"); 2389b50d902SRodney W. Grimes p(tcps_keepdrops, "\t\t%d connection%s dropped by keepalive\n"); 2399b50d902SRodney W. Grimes p(tcps_predack, "\t%d correct ACK header prediction%s\n"); 2409b50d902SRodney W. Grimes p(tcps_preddat, "\t%d correct data packet header prediction%s\n"); 2419b50d902SRodney W. Grimes #undef p 2429b50d902SRodney W. Grimes #undef p2 2439b50d902SRodney W. Grimes #undef p3 2449b50d902SRodney W. Grimes } 2459b50d902SRodney W. Grimes 2469b50d902SRodney W. Grimes /* 2479b50d902SRodney W. Grimes * Dump UDP statistics structure. 2489b50d902SRodney W. Grimes */ 2499b50d902SRodney W. Grimes void 2509b50d902SRodney W. Grimes udp_stats(off, name) 2519b50d902SRodney W. Grimes u_long off; 2529b50d902SRodney W. Grimes char *name; 2539b50d902SRodney W. Grimes { 2549b50d902SRodney W. Grimes struct udpstat udpstat; 2559b50d902SRodney W. Grimes u_long delivered; 2569b50d902SRodney W. Grimes 2579b50d902SRodney W. Grimes if (off == 0) 2589b50d902SRodney W. Grimes return; 2599b50d902SRodney W. Grimes kread(off, (char *)&udpstat, sizeof (udpstat)); 2609b50d902SRodney W. Grimes printf("%s:\n", name); 2619b50d902SRodney W. Grimes #define p(f, m) if (udpstat.f || sflag <= 1) \ 2629b50d902SRodney W. Grimes printf(m, udpstat.f, plural(udpstat.f)) 2639b50d902SRodney W. Grimes p(udps_ipackets, "\t%u datagram%s received\n"); 2649b50d902SRodney W. Grimes p(udps_hdrops, "\t%u with incomplete header\n"); 2659b50d902SRodney W. Grimes p(udps_badlen, "\t%u with bad data length field\n"); 2669b50d902SRodney W. Grimes p(udps_badsum, "\t%u with bad checksum\n"); 2679b50d902SRodney W. Grimes p(udps_noport, "\t%u dropped due to no socket\n"); 2689b50d902SRodney W. Grimes p(udps_noportbcast, "\t%u broadcast/multicast datagram%s dropped due to no socket\n"); 2699b50d902SRodney W. Grimes p(udps_fullsock, "\t%u dropped due to full socket buffers\n"); 2709b50d902SRodney W. Grimes delivered = udpstat.udps_ipackets - 2719b50d902SRodney W. Grimes udpstat.udps_hdrops - 2729b50d902SRodney W. Grimes udpstat.udps_badlen - 2739b50d902SRodney W. Grimes udpstat.udps_badsum - 2749b50d902SRodney W. Grimes udpstat.udps_noport - 2759b50d902SRodney W. Grimes udpstat.udps_noportbcast - 2769b50d902SRodney W. Grimes udpstat.udps_fullsock; 2779b50d902SRodney W. Grimes if (delivered || sflag <= 1) 2789b50d902SRodney W. Grimes printf("\t%u delivered\n", delivered); 2799b50d902SRodney W. Grimes p(udps_opackets, "\t%u datagram%s output\n"); 2809b50d902SRodney W. Grimes #undef p 2819b50d902SRodney W. Grimes } 2829b50d902SRodney W. Grimes 2839b50d902SRodney W. Grimes /* 2849b50d902SRodney W. Grimes * Dump IP statistics structure. 2859b50d902SRodney W. Grimes */ 2869b50d902SRodney W. Grimes void 2879b50d902SRodney W. Grimes ip_stats(off, name) 2889b50d902SRodney W. Grimes u_long off; 2899b50d902SRodney W. Grimes char *name; 2909b50d902SRodney W. Grimes { 2919b50d902SRodney W. Grimes struct ipstat ipstat; 2929b50d902SRodney W. Grimes 2939b50d902SRodney W. Grimes if (off == 0) 2949b50d902SRodney W. Grimes return; 2959b50d902SRodney W. Grimes kread(off, (char *)&ipstat, sizeof (ipstat)); 2969b50d902SRodney W. Grimes printf("%s:\n", name); 2979b50d902SRodney W. Grimes 2989b50d902SRodney W. Grimes #define p(f, m) if (ipstat.f || sflag <= 1) \ 2999b50d902SRodney W. Grimes printf(m, ipstat.f, plural(ipstat.f)) 3009b50d902SRodney W. Grimes 3019b50d902SRodney W. Grimes p(ips_total, "\t%u total packet%s received\n"); 3029b50d902SRodney W. Grimes p(ips_badsum, "\t%u bad header checksum%s\n"); 3039b50d902SRodney W. Grimes p(ips_toosmall, "\t%u with size smaller than minimum\n"); 3049b50d902SRodney W. Grimes p(ips_tooshort, "\t%u with data size < data length\n"); 3059b50d902SRodney W. Grimes p(ips_badhlen, "\t%u with header length < data size\n"); 3069b50d902SRodney W. Grimes p(ips_badlen, "\t%u with data length < header length\n"); 3079b50d902SRodney W. Grimes p(ips_badoptions, "\t%u with bad options\n"); 3089b50d902SRodney W. Grimes p(ips_badvers, "\t%u with incorrect version number\n"); 3099b50d902SRodney W. Grimes p(ips_fragments, "\t%u fragment%s received\n"); 3109b50d902SRodney W. Grimes p(ips_fragdropped, "\t%u fragment%s dropped (dup or out of space)\n"); 3119b50d902SRodney W. Grimes p(ips_fragtimeout, "\t%u fragment%s dropped after timeout\n"); 3129b50d902SRodney W. Grimes p(ips_reassembled, "\t%u packet%s reassembled ok\n"); 3139b50d902SRodney W. Grimes p(ips_delivered, "\t%u packet%s for this host\n"); 3149b50d902SRodney W. Grimes p(ips_noproto, "\t%u packet%s for unknown/unsupported protocol\n"); 3159b50d902SRodney W. Grimes p(ips_forward, "\t%u packet%s forwarded\n"); 3169b50d902SRodney W. Grimes p(ips_cantforward, "\t%u packet%s not forwardable\n"); 3179b50d902SRodney W. Grimes p(ips_redirectsent, "\t%u redirect%s sent\n"); 3189b50d902SRodney W. Grimes p(ips_localout, "\t%u packet%s sent from this host\n"); 3199b50d902SRodney W. Grimes p(ips_rawout, "\t%u packet%s sent with fabricated ip header\n"); 3209b50d902SRodney W. Grimes p(ips_odropped, "\t%u output packet%s dropped due to no bufs, etc.\n"); 3219b50d902SRodney W. Grimes p(ips_noroute, "\t%u output packet%s discarded due to no route\n"); 3229b50d902SRodney W. Grimes p(ips_fragmented, "\t%u output datagram%s fragmented\n"); 3239b50d902SRodney W. Grimes p(ips_ofragments, "\t%u fragment%s created\n"); 3249b50d902SRodney W. Grimes p(ips_cantfrag, "\t%u datagram%s that can't be fragmented\n"); 3259b50d902SRodney W. Grimes #undef p 3269b50d902SRodney W. Grimes } 3279b50d902SRodney W. Grimes 3289b50d902SRodney W. Grimes static char *icmpnames[] = { 3299b50d902SRodney W. Grimes "echo reply", 3309b50d902SRodney W. Grimes "#1", 3319b50d902SRodney W. Grimes "#2", 3329b50d902SRodney W. Grimes "destination unreachable", 3339b50d902SRodney W. Grimes "source quench", 3349b50d902SRodney W. Grimes "routing redirect", 3359b50d902SRodney W. Grimes "#6", 3369b50d902SRodney W. Grimes "#7", 3379b50d902SRodney W. Grimes "echo", 3387b46dd00SGarrett Wollman "router advertisement", 3397b46dd00SGarrett Wollman "router solicitation", 3409b50d902SRodney W. Grimes "time exceeded", 3419b50d902SRodney W. Grimes "parameter problem", 3429b50d902SRodney W. Grimes "time stamp", 3439b50d902SRodney W. Grimes "time stamp reply", 3449b50d902SRodney W. Grimes "information request", 3459b50d902SRodney W. Grimes "information request reply", 3469b50d902SRodney W. Grimes "address mask request", 3479b50d902SRodney W. Grimes "address mask reply", 3489b50d902SRodney W. Grimes }; 3499b50d902SRodney W. Grimes 3509b50d902SRodney W. Grimes /* 3519b50d902SRodney W. Grimes * Dump ICMP statistics. 3529b50d902SRodney W. Grimes */ 3539b50d902SRodney W. Grimes void 3549b50d902SRodney W. Grimes icmp_stats(off, name) 3559b50d902SRodney W. Grimes u_long off; 3569b50d902SRodney W. Grimes char *name; 3579b50d902SRodney W. Grimes { 3589b50d902SRodney W. Grimes struct icmpstat icmpstat; 3599b50d902SRodney W. Grimes register int i, first; 3609b50d902SRodney W. Grimes 3619b50d902SRodney W. Grimes if (off == 0) 3629b50d902SRodney W. Grimes return; 3639b50d902SRodney W. Grimes kread(off, (char *)&icmpstat, sizeof (icmpstat)); 3649b50d902SRodney W. Grimes printf("%s:\n", name); 3659b50d902SRodney W. Grimes 3669b50d902SRodney W. Grimes #define p(f, m) if (icmpstat.f || sflag <= 1) \ 3679b50d902SRodney W. Grimes printf(m, icmpstat.f, plural(icmpstat.f)) 3689b50d902SRodney W. Grimes 3699b50d902SRodney W. Grimes p(icps_error, "\t%u call%s to icmp_error\n"); 3709b50d902SRodney W. Grimes p(icps_oldicmp, 3719b50d902SRodney W. Grimes "\t%u error%s not generated 'cuz old message was icmp\n"); 3729b50d902SRodney W. Grimes for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) 3739b50d902SRodney W. Grimes if (icmpstat.icps_outhist[i] != 0) { 3749b50d902SRodney W. Grimes if (first) { 3759b50d902SRodney W. Grimes printf("\tOutput histogram:\n"); 3769b50d902SRodney W. Grimes first = 0; 3779b50d902SRodney W. Grimes } 3789b50d902SRodney W. Grimes printf("\t\t%s: %u\n", icmpnames[i], 3799b50d902SRodney W. Grimes icmpstat.icps_outhist[i]); 3809b50d902SRodney W. Grimes } 3819b50d902SRodney W. Grimes p(icps_badcode, "\t%u message%s with bad code fields\n"); 3829b50d902SRodney W. Grimes p(icps_tooshort, "\t%u message%s < minimum length\n"); 3839b50d902SRodney W. Grimes p(icps_checksum, "\t%u bad checksum%s\n"); 3849b50d902SRodney W. Grimes p(icps_badlen, "\t%u message%s with bad length\n"); 3859b50d902SRodney W. Grimes for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) 3869b50d902SRodney W. Grimes if (icmpstat.icps_inhist[i] != 0) { 3879b50d902SRodney W. Grimes if (first) { 3889b50d902SRodney W. Grimes printf("\tInput histogram:\n"); 3899b50d902SRodney W. Grimes first = 0; 3909b50d902SRodney W. Grimes } 3919b50d902SRodney W. Grimes printf("\t\t%s: %u\n", icmpnames[i], 3929b50d902SRodney W. Grimes icmpstat.icps_inhist[i]); 3939b50d902SRodney W. Grimes } 3949b50d902SRodney W. Grimes p(icps_reflect, "\t%u message response%s generated\n"); 3959b50d902SRodney W. Grimes #undef p 3969b50d902SRodney W. Grimes } 3979b50d902SRodney W. Grimes 3989b50d902SRodney W. Grimes /* 3999b50d902SRodney W. Grimes * Dump IGMP statistics structure. 4009b50d902SRodney W. Grimes */ 4019b50d902SRodney W. Grimes void 4029b50d902SRodney W. Grimes igmp_stats(off, name) 4039b50d902SRodney W. Grimes u_long off; 4049b50d902SRodney W. Grimes char *name; 4059b50d902SRodney W. Grimes { 4069b50d902SRodney W. Grimes struct igmpstat igmpstat; 4079b50d902SRodney W. Grimes 4089b50d902SRodney W. Grimes if (off == 0) 4099b50d902SRodney W. Grimes return; 4109b50d902SRodney W. Grimes kread(off, (char *)&igmpstat, sizeof (igmpstat)); 4119b50d902SRodney W. Grimes printf("%s:\n", name); 4129b50d902SRodney W. Grimes 4139b50d902SRodney W. Grimes #define p(f, m) if (igmpstat.f || sflag <= 1) \ 4149b50d902SRodney W. Grimes printf(m, igmpstat.f, plural(igmpstat.f)) 4159b50d902SRodney W. Grimes #define py(f, m) if (igmpstat.f || sflag <= 1) \ 4169b50d902SRodney W. Grimes printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y") 4179b50d902SRodney W. Grimes p(igps_rcv_total, "\t%u message%s received\n"); 4189b50d902SRodney W. Grimes p(igps_rcv_tooshort, "\t%u message%s received with too few bytes\n"); 4199b50d902SRodney W. Grimes p(igps_rcv_badsum, "\t%u message%s received with bad checksum\n"); 4209b50d902SRodney W. Grimes py(igps_rcv_queries, "\t%u membership quer%s received\n"); 4219b50d902SRodney W. Grimes py(igps_rcv_badqueries, "\t%u membership quer%s received with invalid field(s)\n"); 4229b50d902SRodney W. Grimes p(igps_rcv_reports, "\t%u membership report%s received\n"); 4239b50d902SRodney W. Grimes p(igps_rcv_badreports, "\t%u membership report%s received with invalid field(s)\n"); 4249b50d902SRodney W. Grimes p(igps_rcv_ourreports, "\t%u membership report%s received for groups to which we belong\n"); 4259b50d902SRodney W. Grimes p(igps_snd_reports, "\t%u membership report%s sent\n"); 4269b50d902SRodney W. Grimes #undef p 4279b50d902SRodney W. Grimes #undef py 4289b50d902SRodney W. Grimes } 4299b50d902SRodney W. Grimes 4309b50d902SRodney W. Grimes /* 4319b50d902SRodney W. Grimes * Pretty print an Internet address (net address + port). 4329b50d902SRodney W. Grimes * If the nflag was specified, use numbers instead of names. 4339b50d902SRodney W. Grimes */ 4349b50d902SRodney W. Grimes void 4359b50d902SRodney W. Grimes inetprint(in, port, proto) 4369b50d902SRodney W. Grimes register struct in_addr *in; 4379b50d902SRodney W. Grimes int port; 4389b50d902SRodney W. Grimes char *proto; 4399b50d902SRodney W. Grimes { 4409b50d902SRodney W. Grimes struct servent *sp = 0; 4419b50d902SRodney W. Grimes char line[80], *cp; 4429b50d902SRodney W. Grimes int width; 4439b50d902SRodney W. Grimes 4449b50d902SRodney W. Grimes sprintf(line, "%.*s.", (Aflag && !nflag) ? 12 : 16, inetname(in)); 4459b50d902SRodney W. Grimes cp = index(line, '\0'); 4469b50d902SRodney W. Grimes if (!nflag && port) 4479b50d902SRodney W. Grimes sp = getservbyport((int)port, proto); 4489b50d902SRodney W. Grimes if (sp || port == 0) 4491ef69972SAndrey A. Chernov sprintf(cp, "%.15s", sp ? sp->s_name : "*"); 4509b50d902SRodney W. Grimes else 4519b50d902SRodney W. Grimes sprintf(cp, "%d", ntohs((u_short)port)); 4529b50d902SRodney W. Grimes width = Aflag ? 18 : 22; 4539b50d902SRodney W. Grimes printf(" %-*.*s", width, width, line); 4549b50d902SRodney W. Grimes } 4559b50d902SRodney W. Grimes 4569b50d902SRodney W. Grimes /* 4579b50d902SRodney W. Grimes * Construct an Internet address representation. 4589b50d902SRodney W. Grimes * If the nflag has been supplied, give 4599b50d902SRodney W. Grimes * numeric value, otherwise try for symbolic name. 4609b50d902SRodney W. Grimes */ 4619b50d902SRodney W. Grimes char * 4629b50d902SRodney W. Grimes inetname(inp) 4639b50d902SRodney W. Grimes struct in_addr *inp; 4649b50d902SRodney W. Grimes { 4659b50d902SRodney W. Grimes register char *cp; 4669b50d902SRodney W. Grimes static char line[50]; 4679b50d902SRodney W. Grimes struct hostent *hp; 4689b50d902SRodney W. Grimes struct netent *np; 4699b50d902SRodney W. Grimes static char domain[MAXHOSTNAMELEN + 1]; 4709b50d902SRodney W. Grimes static int first = 1; 4719b50d902SRodney W. Grimes 4729b50d902SRodney W. Grimes if (first && !nflag) { 4739b50d902SRodney W. Grimes first = 0; 4749b50d902SRodney W. Grimes if (gethostname(domain, MAXHOSTNAMELEN) == 0 && 4759b50d902SRodney W. Grimes (cp = index(domain, '.'))) 4769b50d902SRodney W. Grimes (void) strcpy(domain, cp + 1); 4779b50d902SRodney W. Grimes else 4789b50d902SRodney W. Grimes domain[0] = 0; 4799b50d902SRodney W. Grimes } 4809b50d902SRodney W. Grimes cp = 0; 4819b50d902SRodney W. Grimes if (!nflag && inp->s_addr != INADDR_ANY) { 4829b50d902SRodney W. Grimes int net = inet_netof(*inp); 4839b50d902SRodney W. Grimes int lna = inet_lnaof(*inp); 4849b50d902SRodney W. Grimes 4859b50d902SRodney W. Grimes if (lna == INADDR_ANY) { 4869b50d902SRodney W. Grimes np = getnetbyaddr(net, AF_INET); 4879b50d902SRodney W. Grimes if (np) 4889b50d902SRodney W. Grimes cp = np->n_name; 4899b50d902SRodney W. Grimes } 4909b50d902SRodney W. Grimes if (cp == 0) { 4919b50d902SRodney W. Grimes hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET); 4929b50d902SRodney W. Grimes if (hp) { 4939b50d902SRodney W. Grimes if ((cp = index(hp->h_name, '.')) && 4949b50d902SRodney W. Grimes !strcmp(cp + 1, domain)) 4959b50d902SRodney W. Grimes *cp = 0; 4969b50d902SRodney W. Grimes cp = hp->h_name; 4979b50d902SRodney W. Grimes } 4989b50d902SRodney W. Grimes } 4999b50d902SRodney W. Grimes } 5009b50d902SRodney W. Grimes if (inp->s_addr == INADDR_ANY) 5019b50d902SRodney W. Grimes strcpy(line, "*"); 5029b50d902SRodney W. Grimes else if (cp) 5039b50d902SRodney W. Grimes strcpy(line, cp); 5049b50d902SRodney W. Grimes else { 5059b50d902SRodney W. Grimes inp->s_addr = ntohl(inp->s_addr); 5069b50d902SRodney W. Grimes #define C(x) ((x) & 0xff) 5079b50d902SRodney W. Grimes sprintf(line, "%u.%u.%u.%u", C(inp->s_addr >> 24), 5089b50d902SRodney W. Grimes C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr)); 5099b50d902SRodney W. Grimes } 5109b50d902SRodney W. Grimes return (line); 5119b50d902SRodney W. Grimes } 512