Home | History | Annotate | Line # | Download | only in netstat
inet.c revision 1.21.2.2
      1  1.21.2.2  thorpej /*	$NetBSD: inet.c,v 1.21.2.2 1997/07/12 18:06:27 thorpej Exp $	*/
      2  1.21.2.2  thorpej 
      3  1.21.2.2  thorpej /*
      4  1.21.2.2  thorpej  * Copyright (c) 1983, 1988, 1993
      5  1.21.2.2  thorpej  *	The Regents of the University of California.  All rights reserved.
      6  1.21.2.2  thorpej  *
      7  1.21.2.2  thorpej  * Redistribution and use in source and binary forms, with or without
      8  1.21.2.2  thorpej  * modification, are permitted provided that the following conditions
      9  1.21.2.2  thorpej  * are met:
     10  1.21.2.2  thorpej  * 1. Redistributions of source code must retain the above copyright
     11  1.21.2.2  thorpej  *    notice, this list of conditions and the following disclaimer.
     12  1.21.2.2  thorpej  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.21.2.2  thorpej  *    notice, this list of conditions and the following disclaimer in the
     14  1.21.2.2  thorpej  *    documentation and/or other materials provided with the distribution.
     15  1.21.2.2  thorpej  * 3. All advertising materials mentioning features or use of this software
     16  1.21.2.2  thorpej  *    must display the following acknowledgement:
     17  1.21.2.2  thorpej  *	This product includes software developed by the University of
     18  1.21.2.2  thorpej  *	California, Berkeley and its contributors.
     19  1.21.2.2  thorpej  * 4. Neither the name of the University nor the names of its contributors
     20  1.21.2.2  thorpej  *    may be used to endorse or promote products derived from this software
     21  1.21.2.2  thorpej  *    without specific prior written permission.
     22  1.21.2.2  thorpej  *
     23  1.21.2.2  thorpej  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     24  1.21.2.2  thorpej  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  1.21.2.2  thorpej  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  1.21.2.2  thorpej  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     27  1.21.2.2  thorpej  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  1.21.2.2  thorpej  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  1.21.2.2  thorpej  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  1.21.2.2  thorpej  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  1.21.2.2  thorpej  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  1.21.2.2  thorpej  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  1.21.2.2  thorpej  * SUCH DAMAGE.
     34  1.21.2.2  thorpej  */
     35  1.21.2.2  thorpej 
     36  1.21.2.2  thorpej #ifndef lint
     37  1.21.2.2  thorpej #if 0
     38  1.21.2.2  thorpej static char sccsid[] = "from: @(#)inet.c	8.4 (Berkeley) 4/20/94";
     39  1.21.2.2  thorpej #else
     40  1.21.2.2  thorpej static char *rcsid = "$NetBSD: inet.c,v 1.21.2.2 1997/07/12 18:06:27 thorpej Exp $";
     41  1.21.2.2  thorpej #endif
     42  1.21.2.2  thorpej #endif /* not lint */
     43  1.21.2.2  thorpej 
     44  1.21.2.2  thorpej #include <sys/param.h>
     45  1.21.2.2  thorpej #include <sys/queue.h>
     46  1.21.2.2  thorpej #include <sys/socket.h>
     47  1.21.2.2  thorpej #include <sys/socketvar.h>
     48  1.21.2.2  thorpej #include <sys/mbuf.h>
     49  1.21.2.2  thorpej #include <sys/protosw.h>
     50  1.21.2.2  thorpej 
     51  1.21.2.2  thorpej #include <net/route.h>
     52  1.21.2.2  thorpej #include <netinet/in.h>
     53  1.21.2.2  thorpej #include <netinet/in_systm.h>
     54  1.21.2.2  thorpej #include <netinet/ip.h>
     55  1.21.2.2  thorpej #include <netinet/in_pcb.h>
     56  1.21.2.2  thorpej #include <netinet/ip_icmp.h>
     57  1.21.2.2  thorpej #include <netinet/icmp_var.h>
     58  1.21.2.2  thorpej #include <netinet/igmp_var.h>
     59  1.21.2.2  thorpej #include <netinet/ip_var.h>
     60  1.21.2.2  thorpej #include <netinet/tcp.h>
     61  1.21.2.2  thorpej #include <netinet/tcpip.h>
     62  1.21.2.2  thorpej #include <netinet/tcp_seq.h>
     63  1.21.2.2  thorpej #define TCPSTATES
     64  1.21.2.2  thorpej #include <netinet/tcp_fsm.h>
     65  1.21.2.2  thorpej #include <netinet/tcp_timer.h>
     66  1.21.2.2  thorpej #include <netinet/tcp_var.h>
     67  1.21.2.2  thorpej #include <netinet/tcp_debug.h>
     68  1.21.2.2  thorpej #include <netinet/udp.h>
     69  1.21.2.2  thorpej #include <netinet/udp_var.h>
     70  1.21.2.2  thorpej 
     71  1.21.2.2  thorpej #include <arpa/inet.h>
     72  1.21.2.2  thorpej #include <netdb.h>
     73  1.21.2.2  thorpej #include <stdio.h>
     74  1.21.2.2  thorpej #include <string.h>
     75  1.21.2.2  thorpej #include <unistd.h>
     76  1.21.2.2  thorpej #include "netstat.h"
     77  1.21.2.2  thorpej 
     78  1.21.2.2  thorpej struct	inpcb inpcb;
     79  1.21.2.2  thorpej struct	tcpcb tcpcb;
     80  1.21.2.2  thorpej struct	socket sockb;
     81  1.21.2.2  thorpej 
     82  1.21.2.2  thorpej char	*inetname __P((struct in_addr *));
     83  1.21.2.2  thorpej void	inetprint __P((struct in_addr *, int, char *));
     84  1.21.2.2  thorpej 
     85  1.21.2.2  thorpej /*
     86  1.21.2.2  thorpej  * Print a summary of connections related to an Internet
     87  1.21.2.2  thorpej  * protocol.  For TCP, also give state of connection.
     88  1.21.2.2  thorpej  * Listening processes (aflag) are suppressed unless the
     89  1.21.2.2  thorpej  * -a (all) flag is specified.
     90  1.21.2.2  thorpej  */
     91  1.21.2.2  thorpej void
     92  1.21.2.2  thorpej protopr(off, name)
     93  1.21.2.2  thorpej 	u_long off;
     94  1.21.2.2  thorpej 	char *name;
     95  1.21.2.2  thorpej {
     96  1.21.2.2  thorpej 	struct inpcbtable table;
     97  1.21.2.2  thorpej 	register struct inpcb *head, *next, *prev;
     98  1.21.2.2  thorpej 	struct inpcb inpcb;
     99  1.21.2.2  thorpej 	int istcp;
    100  1.21.2.2  thorpej 	static int first = 1;
    101  1.21.2.2  thorpej 
    102  1.21.2.2  thorpej 	if (off == 0)
    103  1.21.2.2  thorpej 		return;
    104  1.21.2.2  thorpej 	istcp = strcmp(name, "tcp") == 0;
    105  1.21.2.2  thorpej 	kread(off, (char *)&table, sizeof table);
    106  1.21.2.2  thorpej 	prev = head =
    107  1.21.2.2  thorpej 	    (struct inpcb *)&((struct inpcbtable *)off)->inpt_queue.cqh_first;
    108  1.21.2.2  thorpej 	next = table.inpt_queue.cqh_first;
    109  1.21.2.2  thorpej 
    110  1.21.2.2  thorpej 	while (next != head) {
    111  1.21.2.2  thorpej 		kread((u_long)next, (char *)&inpcb, sizeof inpcb);
    112  1.21.2.2  thorpej 		if (inpcb.inp_queue.cqe_prev != prev) {
    113  1.21.2.2  thorpej 			printf("???\n");
    114  1.21.2.2  thorpej 			break;
    115  1.21.2.2  thorpej 		}
    116  1.21.2.2  thorpej 		prev = next;
    117  1.21.2.2  thorpej 		next = inpcb.inp_queue.cqe_next;
    118  1.21.2.2  thorpej 
    119  1.21.2.2  thorpej 		if (!aflag &&
    120  1.21.2.2  thorpej 		    inet_lnaof(inpcb.inp_laddr) == INADDR_ANY)
    121  1.21.2.2  thorpej 			continue;
    122  1.21.2.2  thorpej 		kread((u_long)inpcb.inp_socket, (char *)&sockb, sizeof (sockb));
    123  1.21.2.2  thorpej 		if (istcp) {
    124  1.21.2.2  thorpej 			kread((u_long)inpcb.inp_ppcb,
    125  1.21.2.2  thorpej 			    (char *)&tcpcb, sizeof (tcpcb));
    126  1.21.2.2  thorpej 		}
    127  1.21.2.2  thorpej 		if (first) {
    128  1.21.2.2  thorpej 			printf("Active Internet connections");
    129  1.21.2.2  thorpej 			if (aflag)
    130  1.21.2.2  thorpej 				printf(" (including servers)");
    131  1.21.2.2  thorpej 			putchar('\n');
    132  1.21.2.2  thorpej 			if (Aflag)
    133  1.21.2.2  thorpej 				printf("%-8.8s ", "PCB");
    134  1.21.2.2  thorpej 			printf(Aflag ?
    135  1.21.2.2  thorpej 				"%-5.5s %-6.6s %-6.6s  %-18.18s %-18.18s %s\n" :
    136  1.21.2.2  thorpej 				"%-5.5s %-6.6s %-6.6s  %-22.22s %-22.22s %s\n",
    137  1.21.2.2  thorpej 				"Proto", "Recv-Q", "Send-Q",
    138  1.21.2.2  thorpej 				"Local Address", "Foreign Address", "(state)");
    139  1.21.2.2  thorpej 			first = 0;
    140  1.21.2.2  thorpej 		}
    141  1.21.2.2  thorpej 		if (Aflag)
    142  1.21.2.2  thorpej 			if (istcp)
    143  1.21.2.2  thorpej 				printf("%8lx ", (u_long) inpcb.inp_ppcb);
    144  1.21.2.2  thorpej 			else
    145  1.21.2.2  thorpej 				printf("%8lx ", (u_long) prev);
    146  1.21.2.2  thorpej 		printf("%-5.5s %6ld %6ld ", name, sockb.so_rcv.sb_cc,
    147  1.21.2.2  thorpej 			sockb.so_snd.sb_cc);
    148  1.21.2.2  thorpej 		inetprint(&inpcb.inp_laddr, (int)inpcb.inp_lport, name);
    149  1.21.2.2  thorpej 		inetprint(&inpcb.inp_faddr, (int)inpcb.inp_fport, name);
    150  1.21.2.2  thorpej 		if (istcp) {
    151  1.21.2.2  thorpej 			if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES)
    152  1.21.2.2  thorpej 				printf(" %d", tcpcb.t_state);
    153  1.21.2.2  thorpej 			else
    154  1.21.2.2  thorpej 				printf(" %s", tcpstates[tcpcb.t_state]);
    155  1.21.2.2  thorpej 		}
    156  1.21.2.2  thorpej 		putchar('\n');
    157  1.21.2.2  thorpej 	}
    158  1.21.2.2  thorpej }
    159  1.21.2.2  thorpej 
    160  1.21.2.2  thorpej /*
    161  1.21.2.2  thorpej  * Dump TCP statistics structure.
    162  1.21.2.2  thorpej  */
    163  1.21.2.2  thorpej void
    164  1.21.2.2  thorpej tcp_stats(off, name)
    165  1.21.2.2  thorpej 	u_long off;
    166  1.21.2.2  thorpej 	char *name;
    167  1.21.2.2  thorpej {
    168  1.21.2.2  thorpej 	struct tcpstat tcpstat;
    169  1.21.2.2  thorpej 
    170  1.21.2.2  thorpej 	if (off == 0)
    171  1.21.2.2  thorpej 		return;
    172  1.21.2.2  thorpej 	printf ("%s:\n", name);
    173  1.21.2.2  thorpej 	kread(off, (char *)&tcpstat, sizeof (tcpstat));
    174  1.21.2.2  thorpej 
    175  1.21.2.2  thorpej #define	ps(f, m) if (tcpstat.f || sflag <= 1) \
    176  1.21.2.2  thorpej     printf(m, tcpstat.f)
    177  1.21.2.2  thorpej #define	p(f, m) if (tcpstat.f || sflag <= 1) \
    178  1.21.2.2  thorpej     printf(m, tcpstat.f, plural(tcpstat.f))
    179  1.21.2.2  thorpej #define	p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
    180  1.21.2.2  thorpej     printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2))
    181  1.21.2.2  thorpej #define	p2s(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
    182  1.21.2.2  thorpej     printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2)
    183  1.21.2.2  thorpej #define	p3(f, m) if (tcpstat.f || sflag <= 1) \
    184  1.21.2.2  thorpej     printf(m, tcpstat.f, plurales(tcpstat.f))
    185  1.21.2.2  thorpej 
    186  1.21.2.2  thorpej 	p(tcps_sndtotal, "\t%lu packet%s sent\n");
    187  1.21.2.2  thorpej 	p2(tcps_sndpack,tcps_sndbyte,
    188  1.21.2.2  thorpej 		"\t\t%lu data packet%s (%lu byte%s)\n");
    189  1.21.2.2  thorpej 	p2(tcps_sndrexmitpack, tcps_sndrexmitbyte,
    190  1.21.2.2  thorpej 		"\t\t%lu data packet%s (%lu byte%s) retransmitted\n");
    191  1.21.2.2  thorpej 	p2s(tcps_sndacks, tcps_delack,
    192  1.21.2.2  thorpej 		"\t\t%lu ack-only packet%s (%lu delayed)\n");
    193  1.21.2.2  thorpej 	p(tcps_sndurg, "\t\t%lu URG only packet%s\n");
    194  1.21.2.2  thorpej 	p(tcps_sndprobe, "\t\t%lu window probe packet%s\n");
    195  1.21.2.2  thorpej 	p(tcps_sndwinup, "\t\t%lu window update packet%s\n");
    196  1.21.2.2  thorpej 	p(tcps_sndctrl, "\t\t%lu control packet%s\n");
    197  1.21.2.2  thorpej 	p(tcps_rcvtotal, "\t%lu packet%s received\n");
    198  1.21.2.2  thorpej 	p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%lu ack%s (for %lu byte%s)\n");
    199  1.21.2.2  thorpej 	p(tcps_rcvdupack, "\t\t%lu duplicate ack%s\n");
    200  1.21.2.2  thorpej 	p(tcps_rcvacktoomuch, "\t\t%lu ack%s for unsent data\n");
    201  1.21.2.2  thorpej 	p2(tcps_rcvpack, tcps_rcvbyte,
    202  1.21.2.2  thorpej 		"\t\t%lu packet%s (%lu byte%s) received in-sequence\n");
    203  1.21.2.2  thorpej 	p2(tcps_rcvduppack, tcps_rcvdupbyte,
    204  1.21.2.2  thorpej 		"\t\t%lu completely duplicate packet%s (%lu byte%s)\n");
    205  1.21.2.2  thorpej 	p(tcps_pawsdrop, "\t\t%lu old duplicate packet%s\n");
    206  1.21.2.2  thorpej 	p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte,
    207  1.21.2.2  thorpej 		"\t\t%lu packet%s with some dup. data (%lu byte%s duped)\n");
    208  1.21.2.2  thorpej 	p2(tcps_rcvoopack, tcps_rcvoobyte,
    209  1.21.2.2  thorpej 		"\t\t%lu out-of-order packet%s (%lu byte%s)\n");
    210  1.21.2.2  thorpej 	p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin,
    211  1.21.2.2  thorpej 		"\t\t%lu packet%s (%lu byte%s) of data after window\n");
    212  1.21.2.2  thorpej 	p(tcps_rcvwinprobe, "\t\t%lu window probe%s\n");
    213  1.21.2.2  thorpej 	p(tcps_rcvwinupd, "\t\t%lu window update packet%s\n");
    214  1.21.2.2  thorpej 	p(tcps_rcvafterclose, "\t\t%lu packet%s received after close\n");
    215  1.21.2.2  thorpej 	p(tcps_rcvbadsum, "\t\t%lu discarded for bad checksum%s\n");
    216  1.21.2.2  thorpej 	p(tcps_rcvbadoff, "\t\t%lu discarded for bad header offset field%s\n");
    217  1.21.2.2  thorpej 	ps(tcps_rcvshort, "\t\t%lu discarded because packet too short\n");
    218  1.21.2.2  thorpej 	p(tcps_connattempt, "\t%lu connection request%s\n");
    219  1.21.2.2  thorpej 	p(tcps_accepts, "\t%lu connection accept%s\n");
    220  1.21.2.2  thorpej 	p(tcps_connects, "\t%lu connection%s established (including accepts)\n");
    221  1.21.2.2  thorpej 	p2(tcps_closed, tcps_drops,
    222  1.21.2.2  thorpej 		"\t%lu connection%s closed (including %lu drop%s)\n");
    223  1.21.2.2  thorpej 	p(tcps_conndrops, "\t%lu embryonic connection%s dropped\n");
    224  1.21.2.2  thorpej 	p2(tcps_rttupdated, tcps_segstimed,
    225  1.21.2.2  thorpej 		"\t%lu segment%s updated rtt (of %lu attempt%s)\n");
    226  1.21.2.2  thorpej 	p(tcps_rexmttimeo, "\t%lu retransmit timeout%s\n");
    227  1.21.2.2  thorpej 	p(tcps_timeoutdrop, "\t\t%lu connection%s dropped by rexmit timeout\n");
    228  1.21.2.2  thorpej 	p(tcps_persisttimeo, "\t%lu persist timeout%s\n");
    229  1.21.2.2  thorpej 	p(tcps_keeptimeo, "\t%lu keepalive timeout%s\n");
    230  1.21.2.2  thorpej 	p(tcps_keepprobe, "\t\t%lu keepalive probe%s sent\n");
    231  1.21.2.2  thorpej 	p(tcps_keepdrops, "\t\t%lu connection%s dropped by keepalive\n");
    232  1.21.2.2  thorpej 	p(tcps_predack, "\t%lu correct ACK header prediction%s\n");
    233  1.21.2.2  thorpej 	p(tcps_preddat, "\t%lu correct data packet header prediction%s\n");
    234  1.21.2.2  thorpej 	p3(tcps_pcbhashmiss, "\t%lu PCB hash miss%s\n");
    235  1.21.2.2  thorpej 	ps(tcps_noport, "\t%lu dropped due to no socket\n");
    236  1.21.2.2  thorpej 
    237  1.21.2.2  thorpej 	p(tcps_badsyn, "\t%lu bad connection attempt%s\n");
    238  1.21.2.2  thorpej 	ps(tcps_sc_added, "\t%lu SYN cache entries added\n");
    239  1.21.2.2  thorpej 	p(tcps_sc_collisions, "\t\t%lu hash collision%s\n");
    240  1.21.2.2  thorpej 	ps(tcps_sc_completed, "\t\t%lu completed\n");
    241  1.21.2.2  thorpej 	ps(tcps_sc_aborted, "\t\t%lu aborted (no space to build PCB)\n");
    242  1.21.2.2  thorpej 	ps(tcps_sc_timed_out, "\t\t%lu timed out\n");
    243  1.21.2.2  thorpej 	ps(tcps_sc_overflowed, "\t\t%lu dropped due to overflow\n");
    244  1.21.2.2  thorpej 	ps(tcps_sc_bucketoverflow, "\t\t%lu dropped due to bucket overflow\n");
    245  1.21.2.2  thorpej 	ps(tcps_sc_reset, "\t\t%lu dropped due to RST\n");
    246  1.21.2.2  thorpej 	ps(tcps_sc_unreach, "\t\t%lu dropped due to ICMP unreachable\n");
    247  1.21.2.2  thorpej 	p(tcps_sc_dupesyn, "\t%lu duplicate SYN%s received for entries already in the cache\n");
    248  1.21.2.2  thorpej 	p(tcps_sc_dropped, "\t%lu SYN%s dropped (no route or no space)\n");
    249  1.21.2.2  thorpej 
    250  1.21.2.2  thorpej #undef p
    251  1.21.2.2  thorpej #undef ps
    252  1.21.2.2  thorpej #undef p2
    253  1.21.2.2  thorpej #undef p2s
    254  1.21.2.2  thorpej #undef p3
    255  1.21.2.2  thorpej }
    256  1.21.2.2  thorpej 
    257  1.21.2.2  thorpej /*
    258  1.21.2.2  thorpej  * Dump UDP statistics structure.
    259  1.21.2.2  thorpej  */
    260  1.21.2.2  thorpej void
    261  1.21.2.2  thorpej udp_stats(off, name)
    262  1.21.2.2  thorpej 	u_long off;
    263  1.21.2.2  thorpej 	char *name;
    264  1.21.2.2  thorpej {
    265  1.21.2.2  thorpej 	struct udpstat udpstat;
    266  1.21.2.2  thorpej 	u_long delivered;
    267  1.21.2.2  thorpej 
    268  1.21.2.2  thorpej 	if (off == 0)
    269  1.21.2.2  thorpej 		return;
    270  1.21.2.2  thorpej 	printf("%s:\n", name);
    271  1.21.2.2  thorpej 	kread(off, (char *)&udpstat, sizeof (udpstat));
    272  1.21.2.2  thorpej 
    273  1.21.2.2  thorpej #define	ps(f, m) if (udpstat.f || sflag <= 1) \
    274  1.21.2.2  thorpej     printf(m, udpstat.f)
    275  1.21.2.2  thorpej #define	p(f, m) if (udpstat.f || sflag <= 1) \
    276  1.21.2.2  thorpej     printf(m, udpstat.f, plural(udpstat.f))
    277  1.21.2.2  thorpej #define	p3(f, m) if (udpstat.f || sflag <= 1) \
    278  1.21.2.2  thorpej     printf(m, udpstat.f, plurales(udpstat.f))
    279  1.21.2.2  thorpej 
    280  1.21.2.2  thorpej 	p(udps_ipackets, "\t%lu datagram%s received\n");
    281  1.21.2.2  thorpej 	ps(udps_hdrops, "\t%lu with incomplete header\n");
    282  1.21.2.2  thorpej 	ps(udps_badlen, "\t%lu with bad data length field\n");
    283  1.21.2.2  thorpej 	ps(udps_badsum, "\t%lu with bad checksum\n");
    284  1.21.2.2  thorpej 	ps(udps_noport, "\t%lu dropped due to no socket\n");
    285  1.21.2.2  thorpej 	p(udps_noportbcast, "\t%lu broadcast/multicast datagram%s dropped due to no socket\n");
    286  1.21.2.2  thorpej 	ps(udps_fullsock, "\t%lu dropped due to full socket buffers\n");
    287  1.21.2.2  thorpej 	delivered = udpstat.udps_ipackets -
    288  1.21.2.2  thorpej 		    udpstat.udps_hdrops -
    289  1.21.2.2  thorpej 		    udpstat.udps_badlen -
    290  1.21.2.2  thorpej 		    udpstat.udps_badsum -
    291  1.21.2.2  thorpej 		    udpstat.udps_noport -
    292  1.21.2.2  thorpej 		    udpstat.udps_noportbcast -
    293  1.21.2.2  thorpej 		    udpstat.udps_fullsock;
    294  1.21.2.2  thorpej 	if (delivered || sflag <= 1)
    295  1.21.2.2  thorpej 		printf("\t%lu delivered\n", delivered);
    296  1.21.2.2  thorpej 	p3(udps_pcbhashmiss, "\t%lu PCB hash miss%s\n");
    297  1.21.2.2  thorpej 	p(udps_opackets, "\t%lu datagram%s output\n");
    298  1.21.2.2  thorpej 
    299  1.21.2.2  thorpej #undef ps
    300  1.21.2.2  thorpej #undef p
    301  1.21.2.2  thorpej #undef p3
    302  1.21.2.2  thorpej }
    303  1.21.2.2  thorpej 
    304  1.21.2.2  thorpej /*
    305  1.21.2.2  thorpej  * Dump IP statistics structure.
    306  1.21.2.2  thorpej  */
    307  1.21.2.2  thorpej void
    308  1.21.2.2  thorpej ip_stats(off, name)
    309  1.21.2.2  thorpej 	u_long off;
    310  1.21.2.2  thorpej 	char *name;
    311  1.21.2.2  thorpej {
    312  1.21.2.2  thorpej 	struct ipstat ipstat;
    313  1.21.2.2  thorpej 
    314  1.21.2.2  thorpej 	if (off == 0)
    315  1.21.2.2  thorpej 		return;
    316  1.21.2.2  thorpej 	kread(off, (char *)&ipstat, sizeof (ipstat));
    317  1.21.2.2  thorpej 	printf("%s:\n", name);
    318  1.21.2.2  thorpej 
    319  1.21.2.2  thorpej #define	ps(f, m) if (ipstat.f || sflag <= 1) \
    320  1.21.2.2  thorpej     printf(m, ipstat.f)
    321  1.21.2.2  thorpej #define	p(f, m) if (ipstat.f || sflag <= 1) \
    322  1.21.2.2  thorpej     printf(m, ipstat.f, plural(ipstat.f))
    323  1.21.2.2  thorpej 
    324  1.21.2.2  thorpej 	p(ips_total, "\t%lu total packet%s received\n");
    325  1.21.2.2  thorpej 	p(ips_badsum, "\t%lu bad header checksum%s\n");
    326  1.21.2.2  thorpej 	ps(ips_toosmall, "\t%lu with size smaller than minimum\n");
    327  1.21.2.2  thorpej 	ps(ips_tooshort, "\t%lu with data size < data length\n");
    328  1.21.2.2  thorpej 	ps(ips_toolong, "\t%lu with length > max ip packet size\n");
    329  1.21.2.2  thorpej 	ps(ips_badhlen, "\t%lu with header length < data size\n");
    330  1.21.2.2  thorpej 	ps(ips_badlen, "\t%lu with data length < header length\n");
    331  1.21.2.2  thorpej 	ps(ips_badoptions, "\t%lu with bad options\n");
    332  1.21.2.2  thorpej 	ps(ips_badvers, "\t%lu with incorrect version number\n");
    333  1.21.2.2  thorpej 	p(ips_fragments, "\t%lu fragment%s received\n");
    334  1.21.2.2  thorpej 	p(ips_fragdropped, "\t%lu fragment%s dropped (dup or out of space)\n");
    335  1.21.2.2  thorpej 	p(ips_badfrags, "\t%lu malformed fragment%s dropped\n");
    336  1.21.2.2  thorpej 	p(ips_fragtimeout, "\t%lu fragment%s dropped after timeout\n");
    337  1.21.2.2  thorpej 	p(ips_reassembled, "\t%lu packet%s reassembled ok\n");
    338  1.21.2.2  thorpej 	p(ips_delivered, "\t%lu packet%s for this host\n");
    339  1.21.2.2  thorpej 	p(ips_noproto, "\t%lu packet%s for unknown/unsupported protocol\n");
    340  1.21.2.2  thorpej 	p(ips_forward, "\t%lu packet%s forwarded\n");
    341  1.21.2.2  thorpej 	p(ips_cantforward, "\t%lu packet%s not forwardable\n");
    342  1.21.2.2  thorpej 	p(ips_redirectsent, "\t%lu redirect%s sent\n");
    343  1.21.2.2  thorpej 	p(ips_localout, "\t%lu packet%s sent from this host\n");
    344  1.21.2.2  thorpej 	p(ips_rawout, "\t%lu packet%s sent with fabricated ip header\n");
    345  1.21.2.2  thorpej 	p(ips_odropped, "\t%lu output packet%s dropped due to no bufs, etc.\n");
    346  1.21.2.2  thorpej 	p(ips_noroute, "\t%lu output packet%s discarded due to no route\n");
    347  1.21.2.2  thorpej 	p(ips_fragmented, "\t%lu output datagram%s fragmented\n");
    348  1.21.2.2  thorpej 	p(ips_ofragments, "\t%lu fragment%s created\n");
    349  1.21.2.2  thorpej 	p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n");
    350  1.21.2.2  thorpej #undef ps
    351  1.21.2.2  thorpej #undef p
    352  1.21.2.2  thorpej }
    353  1.21.2.2  thorpej 
    354  1.21.2.2  thorpej static	char *icmpnames[] = {
    355  1.21.2.2  thorpej 	"echo reply",
    356  1.21.2.2  thorpej 	"#1",
    357  1.21.2.2  thorpej 	"#2",
    358  1.21.2.2  thorpej 	"destination unreachable",
    359  1.21.2.2  thorpej 	"source quench",
    360  1.21.2.2  thorpej 	"routing redirect",
    361  1.21.2.2  thorpej 	"#6",
    362  1.21.2.2  thorpej 	"#7",
    363  1.21.2.2  thorpej 	"echo",
    364  1.21.2.2  thorpej 	"#9",
    365  1.21.2.2  thorpej 	"#10",
    366  1.21.2.2  thorpej 	"time exceeded",
    367  1.21.2.2  thorpej 	"parameter problem",
    368  1.21.2.2  thorpej 	"time stamp",
    369  1.21.2.2  thorpej 	"time stamp reply",
    370  1.21.2.2  thorpej 	"information request",
    371  1.21.2.2  thorpej 	"information request reply",
    372  1.21.2.2  thorpej 	"address mask request",
    373  1.21.2.2  thorpej 	"address mask reply",
    374  1.21.2.2  thorpej };
    375  1.21.2.2  thorpej 
    376  1.21.2.2  thorpej /*
    377  1.21.2.2  thorpej  * Dump ICMP statistics.
    378  1.21.2.2  thorpej  */
    379  1.21.2.2  thorpej void
    380  1.21.2.2  thorpej icmp_stats(off, name)
    381  1.21.2.2  thorpej 	u_long off;
    382  1.21.2.2  thorpej 	char *name;
    383  1.21.2.2  thorpej {
    384  1.21.2.2  thorpej 	struct icmpstat icmpstat;
    385  1.21.2.2  thorpej 	register int i, first;
    386  1.21.2.2  thorpej 
    387  1.21.2.2  thorpej 	if (off == 0)
    388  1.21.2.2  thorpej 		return;
    389  1.21.2.2  thorpej 	kread(off, (char *)&icmpstat, sizeof (icmpstat));
    390  1.21.2.2  thorpej 	printf("%s:\n", name);
    391  1.21.2.2  thorpej 
    392  1.21.2.2  thorpej #define	p(f, m) if (icmpstat.f || sflag <= 1) \
    393  1.21.2.2  thorpej     printf(m, icmpstat.f, plural(icmpstat.f))
    394  1.21.2.2  thorpej 
    395  1.21.2.2  thorpej 	p(icps_error, "\t%lu call%s to icmp_error\n");
    396  1.21.2.2  thorpej 	p(icps_oldicmp,
    397  1.21.2.2  thorpej 	    "\t%lu error%s not generated because old message was icmp\n");
    398  1.21.2.2  thorpej 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
    399  1.21.2.2  thorpej 		if (icmpstat.icps_outhist[i] != 0) {
    400  1.21.2.2  thorpej 			if (first) {
    401  1.21.2.2  thorpej 				printf("\tOutput histogram:\n");
    402  1.21.2.2  thorpej 				first = 0;
    403  1.21.2.2  thorpej 			}
    404  1.21.2.2  thorpej 			printf("\t\t%s: %lu\n", icmpnames[i],
    405  1.21.2.2  thorpej 				icmpstat.icps_outhist[i]);
    406  1.21.2.2  thorpej 		}
    407  1.21.2.2  thorpej 	p(icps_badcode, "\t%lu message%s with bad code fields\n");
    408  1.21.2.2  thorpej 	p(icps_tooshort, "\t%lu message%s < minimum length\n");
    409  1.21.2.2  thorpej 	p(icps_checksum, "\t%lu bad checksum%s\n");
    410  1.21.2.2  thorpej 	p(icps_badlen, "\t%lu message%s with bad length\n");
    411  1.21.2.2  thorpej 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
    412  1.21.2.2  thorpej 		if (icmpstat.icps_inhist[i] != 0) {
    413  1.21.2.2  thorpej 			if (first) {
    414  1.21.2.2  thorpej 				printf("\tInput histogram:\n");
    415  1.21.2.2  thorpej 				first = 0;
    416  1.21.2.2  thorpej 			}
    417  1.21.2.2  thorpej 			printf("\t\t%s: %lu\n", icmpnames[i],
    418  1.21.2.2  thorpej 				icmpstat.icps_inhist[i]);
    419  1.21.2.2  thorpej 		}
    420  1.21.2.2  thorpej 	p(icps_reflect, "\t%lu message response%s generated\n");
    421  1.21.2.2  thorpej #undef p
    422  1.21.2.2  thorpej }
    423  1.21.2.2  thorpej 
    424  1.21.2.2  thorpej /*
    425  1.21.2.2  thorpej  * Dump IGMP statistics structure.
    426  1.21.2.2  thorpej  */
    427  1.21.2.2  thorpej void
    428  1.21.2.2  thorpej igmp_stats(off, name)
    429  1.21.2.2  thorpej 	u_long off;
    430  1.21.2.2  thorpej 	char *name;
    431  1.21.2.2  thorpej {
    432  1.21.2.2  thorpej 	struct igmpstat igmpstat;
    433  1.21.2.2  thorpej 
    434  1.21.2.2  thorpej 	if (off == 0)
    435  1.21.2.2  thorpej 		return;
    436  1.21.2.2  thorpej 	kread(off, (char *)&igmpstat, sizeof (igmpstat));
    437  1.21.2.2  thorpej 	printf("%s:\n", name);
    438  1.21.2.2  thorpej 
    439  1.21.2.2  thorpej #define	p(f, m) if (igmpstat.f || sflag <= 1) \
    440  1.21.2.2  thorpej     printf(m, igmpstat.f, plural(igmpstat.f))
    441  1.21.2.2  thorpej #define	py(f, m) if (igmpstat.f || sflag <= 1) \
    442  1.21.2.2  thorpej     printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y")
    443  1.21.2.2  thorpej 	p(igps_rcv_total, "\t%lu message%s received\n");
    444  1.21.2.2  thorpej         p(igps_rcv_tooshort, "\t%lu message%s received with too few bytes\n");
    445  1.21.2.2  thorpej         p(igps_rcv_badsum, "\t%lu message%s received with bad checksum\n");
    446  1.21.2.2  thorpej         py(igps_rcv_queries, "\t%lu membership quer%s received\n");
    447  1.21.2.2  thorpej         py(igps_rcv_badqueries, "\t%lu membership quer%s received with invalid field(s)\n");
    448  1.21.2.2  thorpej         p(igps_rcv_reports, "\t%lu membership report%s received\n");
    449  1.21.2.2  thorpej         p(igps_rcv_badreports, "\t%lu membership report%s received with invalid field(s)\n");
    450  1.21.2.2  thorpej         p(igps_rcv_ourreports, "\t%lu membership report%s received for groups to which we belong\n");
    451  1.21.2.2  thorpej         p(igps_snd_reports, "\t%lu membership report%s sent\n");
    452  1.21.2.2  thorpej #undef p
    453  1.21.2.2  thorpej #undef py
    454  1.21.2.2  thorpej }
    455  1.21.2.2  thorpej 
    456  1.21.2.2  thorpej /*
    457  1.21.2.2  thorpej  * Pretty print an Internet address (net address + port).
    458  1.21.2.2  thorpej  * If the nflag was specified, use numbers instead of names.
    459  1.21.2.2  thorpej  */
    460  1.21.2.2  thorpej void
    461  1.21.2.2  thorpej inetprint(in, port, proto)
    462  1.21.2.2  thorpej 	register struct in_addr *in;
    463  1.21.2.2  thorpej 	int port;
    464  1.21.2.2  thorpej 	char *proto;
    465  1.21.2.2  thorpej {
    466  1.21.2.2  thorpej 	struct servent *sp = 0;
    467  1.21.2.2  thorpej 	char line[80], *cp;
    468  1.21.2.2  thorpej 	int width;
    469  1.21.2.2  thorpej 
    470  1.21.2.2  thorpej 	sprintf(line, "%.*s.", (Aflag && !nflag) ? 12 : 16, inetname(in));
    471  1.21.2.2  thorpej 	cp = index(line, '\0');
    472  1.21.2.2  thorpej 	if (!nflag && port)
    473  1.21.2.2  thorpej 		sp = getservbyport((int)port, proto);
    474  1.21.2.2  thorpej 	if (sp || port == 0)
    475  1.21.2.2  thorpej 		sprintf(cp, "%.8s", sp ? sp->s_name : "*");
    476  1.21.2.2  thorpej 	else
    477  1.21.2.2  thorpej 		sprintf(cp, "%u", ntohs((u_short)port));
    478  1.21.2.2  thorpej 	width = Aflag ? 18 : 22;
    479  1.21.2.2  thorpej 	printf(" %-*.*s", width, width, line);
    480  1.21.2.2  thorpej }
    481  1.21.2.2  thorpej 
    482  1.21.2.2  thorpej /*
    483  1.21.2.2  thorpej  * Construct an Internet address representation.
    484  1.21.2.2  thorpej  * If the nflag has been supplied, give
    485  1.21.2.2  thorpej  * numeric value, otherwise try for symbolic name.
    486  1.21.2.2  thorpej  */
    487  1.21.2.2  thorpej char *
    488  1.21.2.2  thorpej inetname(inp)
    489  1.21.2.2  thorpej 	struct in_addr *inp;
    490  1.21.2.2  thorpej {
    491  1.21.2.2  thorpej 	register char *cp;
    492  1.21.2.2  thorpej 	static char line[50];
    493  1.21.2.2  thorpej 	struct hostent *hp;
    494  1.21.2.2  thorpej 	struct netent *np;
    495  1.21.2.2  thorpej 	static char domain[MAXHOSTNAMELEN + 1];
    496  1.21.2.2  thorpej 	static int first = 1;
    497  1.21.2.2  thorpej 
    498  1.21.2.2  thorpej 	if (first && !nflag) {
    499  1.21.2.2  thorpej 		first = 0;
    500  1.21.2.2  thorpej 		if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
    501  1.21.2.2  thorpej 		    (cp = index(domain, '.')))
    502  1.21.2.2  thorpej 			(void) strcpy(domain, cp + 1);
    503  1.21.2.2  thorpej 		else
    504  1.21.2.2  thorpej 			domain[0] = 0;
    505  1.21.2.2  thorpej 	}
    506  1.21.2.2  thorpej 	cp = 0;
    507  1.21.2.2  thorpej 	if (!nflag && inp->s_addr != INADDR_ANY) {
    508  1.21.2.2  thorpej 		int net = inet_netof(*inp);
    509  1.21.2.2  thorpej 		int lna = inet_lnaof(*inp);
    510  1.21.2.2  thorpej 
    511  1.21.2.2  thorpej 		if (lna == INADDR_ANY) {
    512  1.21.2.2  thorpej 			np = getnetbyaddr(net, AF_INET);
    513  1.21.2.2  thorpej 			if (np)
    514  1.21.2.2  thorpej 				cp = np->n_name;
    515  1.21.2.2  thorpej 		}
    516  1.21.2.2  thorpej 		if (cp == 0) {
    517  1.21.2.2  thorpej 			hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET);
    518  1.21.2.2  thorpej 			if (hp) {
    519  1.21.2.2  thorpej 				if ((cp = index(hp->h_name, '.')) &&
    520  1.21.2.2  thorpej 				    !strcmp(cp + 1, domain))
    521  1.21.2.2  thorpej 					*cp = 0;
    522  1.21.2.2  thorpej 				cp = hp->h_name;
    523  1.21.2.2  thorpej 			}
    524  1.21.2.2  thorpej 		}
    525  1.21.2.2  thorpej 	}
    526  1.21.2.2  thorpej 	if (inp->s_addr == INADDR_ANY)
    527  1.21.2.2  thorpej 		strcpy(line, "*");
    528  1.21.2.2  thorpej 	else if (cp)
    529  1.21.2.2  thorpej 		strcpy(line, cp);
    530  1.21.2.2  thorpej 	else {
    531  1.21.2.2  thorpej 		inp->s_addr = ntohl(inp->s_addr);
    532  1.21.2.2  thorpej #define C(x)	((x) & 0xff)
    533  1.21.2.2  thorpej 		sprintf(line, "%u.%u.%u.%u", C(inp->s_addr >> 24),
    534  1.21.2.2  thorpej 		    C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr));
    535  1.21.2.2  thorpej 	}
    536  1.21.2.2  thorpej 	return (line);
    537  1.21.2.2  thorpej }
    538