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