Home | History | Annotate | Line # | Download | only in netstat
inet.c revision 1.65
      1  1.65      elad /*	$NetBSD: inet.c,v 1.65 2005/08/06 17:58:13 elad Exp $	*/
      2  1.14   thorpej 
      3   1.1       cgd /*
      4   1.9   mycroft  * Copyright (c) 1983, 1988, 1993
      5   1.9   mycroft  *	The Regents of the University of California.  All rights reserved.
      6   1.1       cgd  *
      7   1.1       cgd  * Redistribution and use in source and binary forms, with or without
      8   1.1       cgd  * modification, are permitted provided that the following conditions
      9   1.1       cgd  * are met:
     10   1.1       cgd  * 1. Redistributions of source code must retain the above copyright
     11   1.1       cgd  *    notice, this list of conditions and the following disclaimer.
     12   1.1       cgd  * 2. Redistributions in binary form must reproduce the above copyright
     13   1.1       cgd  *    notice, this list of conditions and the following disclaimer in the
     14   1.1       cgd  *    documentation and/or other materials provided with the distribution.
     15  1.58       agc  * 3. Neither the name of the University nor the names of its contributors
     16   1.1       cgd  *    may be used to endorse or promote products derived from this software
     17   1.1       cgd  *    without specific prior written permission.
     18   1.1       cgd  *
     19   1.1       cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20   1.1       cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21   1.1       cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22   1.1       cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23   1.1       cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24   1.1       cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25   1.1       cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26   1.1       cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27   1.1       cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28   1.1       cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29   1.1       cgd  * SUCH DAMAGE.
     30   1.1       cgd  */
     31   1.1       cgd 
     32  1.23     lukem #include <sys/cdefs.h>
     33   1.1       cgd #ifndef lint
     34  1.14   thorpej #if 0
     35  1.14   thorpej static char sccsid[] = "from: @(#)inet.c	8.4 (Berkeley) 4/20/94";
     36  1.14   thorpej #else
     37  1.65      elad __RCSID("$NetBSD: inet.c,v 1.65 2005/08/06 17:58:13 elad Exp $");
     38  1.14   thorpej #endif
     39   1.1       cgd #endif /* not lint */
     40   1.1       cgd 
     41   1.1       cgd #include <sys/param.h>
     42  1.10       cgd #include <sys/queue.h>
     43   1.1       cgd #include <sys/socket.h>
     44   1.1       cgd #include <sys/socketvar.h>
     45   1.1       cgd #include <sys/mbuf.h>
     46   1.1       cgd #include <sys/protosw.h>
     47  1.65      elad #include <sys/sysctl.h>
     48   1.1       cgd 
     49  1.41     jhawk #include <net/if_arp.h>
     50   1.1       cgd #include <net/route.h>
     51   1.1       cgd #include <netinet/in.h>
     52   1.1       cgd #include <netinet/in_systm.h>
     53   1.1       cgd #include <netinet/ip.h>
     54   1.1       cgd #include <netinet/in_pcb.h>
     55   1.1       cgd #include <netinet/ip_icmp.h>
     56  1.37    itojun 
     57  1.37    itojun #ifdef INET6
     58  1.37    itojun #include <netinet/ip6.h>
     59  1.37    itojun #endif
     60  1.37    itojun 
     61   1.1       cgd #include <netinet/icmp_var.h>
     62   1.6    brezak #include <netinet/igmp_var.h>
     63   1.1       cgd #include <netinet/ip_var.h>
     64  1.62      manu #include <netinet/pim_var.h>
     65   1.1       cgd #include <netinet/tcp.h>
     66   1.1       cgd #include <netinet/tcpip.h>
     67   1.1       cgd #include <netinet/tcp_seq.h>
     68   1.1       cgd #define TCPSTATES
     69   1.1       cgd #include <netinet/tcp_fsm.h>
     70  1.30   thorpej #define	TCPTIMERS
     71   1.1       cgd #include <netinet/tcp_timer.h>
     72   1.1       cgd #include <netinet/tcp_var.h>
     73   1.1       cgd #include <netinet/tcp_debug.h>
     74   1.1       cgd #include <netinet/udp.h>
     75   1.1       cgd #include <netinet/udp_var.h>
     76   1.1       cgd 
     77   1.9   mycroft #include <arpa/inet.h>
     78  1.64    rpaulo #include <kvm.h>
     79   1.1       cgd #include <netdb.h>
     80   1.1       cgd #include <stdio.h>
     81   1.1       cgd #include <string.h>
     82   1.9   mycroft #include <unistd.h>
     83  1.65      elad #include <err.h>
     84   1.9   mycroft #include "netstat.h"
     85   1.1       cgd 
     86   1.1       cgd struct	inpcb inpcb;
     87   1.1       cgd struct	tcpcb tcpcb;
     88   1.1       cgd struct	socket sockb;
     89   1.1       cgd 
     90   1.9   mycroft char	*inetname __P((struct in_addr *));
     91  1.28     lukem void	inetprint __P((struct in_addr *, u_int16_t, const char *, int));
     92   1.1       cgd 
     93   1.1       cgd /*
     94   1.1       cgd  * Print a summary of connections related to an Internet
     95   1.1       cgd  * protocol.  For TCP, also give state of connection.
     96   1.1       cgd  * Listening processes (aflag) are suppressed unless the
     97   1.1       cgd  * -a (all) flag is specified.
     98   1.1       cgd  */
     99  1.35     lukem static int width;
    100  1.35     lukem 
    101   1.9   mycroft void
    102   1.1       cgd protopr(off, name)
    103   1.8       cgd 	u_long off;
    104   1.1       cgd 	char *name;
    105   1.1       cgd {
    106  1.12   mycroft 	struct inpcbtable table;
    107  1.23     lukem 	struct inpcb *head, *next, *prev;
    108  1.13       cgd 	struct inpcb inpcb;
    109  1.35     lukem 	int istcp, compact;
    110   1.1       cgd 	static int first = 1;
    111  1.35     lukem 	static char *shorttcpstates[] = {
    112  1.35     lukem 		"CLOSED",	"LISTEN",	"SYNSEN",	"SYSRCV",
    113  1.35     lukem 		"ESTABL",	"CLWAIT",	"FWAIT1",	"CLOSNG",
    114  1.35     lukem 		"LASTAK",	"FWAIT2",	"TMWAIT",
    115  1.35     lukem 	};
    116   1.1       cgd 
    117   1.1       cgd 	if (off == 0)
    118   1.1       cgd 		return;
    119   1.1       cgd 	istcp = strcmp(name, "tcp") == 0;
    120  1.12   mycroft 	kread(off, (char *)&table, sizeof table);
    121  1.13       cgd 	prev = head =
    122  1.13       cgd 	    (struct inpcb *)&((struct inpcbtable *)off)->inpt_queue.cqh_first;
    123  1.59    itojun 	next = (struct inpcb *)table.inpt_queue.cqh_first;
    124  1.13       cgd 
    125  1.35     lukem 	compact = 0;
    126  1.35     lukem 	if (Aflag) {
    127  1.46     assar 		if (!numeric_addr)
    128  1.35     lukem 			width = 18;
    129  1.35     lukem 		else {
    130  1.35     lukem 			width = 21;
    131  1.35     lukem 			compact = 1;
    132  1.35     lukem 		}
    133  1.35     lukem 	} else
    134  1.35     lukem 		width = 22;
    135  1.13       cgd 	while (next != head) {
    136  1.12   mycroft 		kread((u_long)next, (char *)&inpcb, sizeof inpcb);
    137  1.59    itojun 		if ((struct inpcb *)inpcb.inp_queue.cqe_prev != prev) {
    138   1.1       cgd 			printf("???\n");
    139   1.1       cgd 			break;
    140   1.1       cgd 		}
    141  1.13       cgd 		prev = next;
    142  1.59    itojun 		next = (struct inpcb *)inpcb.inp_queue.cqe_next;
    143  1.59    itojun 
    144  1.59    itojun 		if (inpcb.inp_af != AF_INET)
    145  1.59    itojun 			continue;
    146  1.13       cgd 
    147   1.1       cgd 		if (!aflag &&
    148  1.12   mycroft 		    inet_lnaof(inpcb.inp_laddr) == INADDR_ANY)
    149   1.1       cgd 			continue;
    150   1.9   mycroft 		kread((u_long)inpcb.inp_socket, (char *)&sockb, sizeof (sockb));
    151   1.1       cgd 		if (istcp) {
    152   1.9   mycroft 			kread((u_long)inpcb.inp_ppcb,
    153   1.9   mycroft 			    (char *)&tcpcb, sizeof (tcpcb));
    154   1.1       cgd 		}
    155   1.1       cgd 		if (first) {
    156   1.1       cgd 			printf("Active Internet connections");
    157   1.1       cgd 			if (aflag)
    158   1.1       cgd 				printf(" (including servers)");
    159   1.1       cgd 			putchar('\n');
    160   1.1       cgd 			if (Aflag)
    161   1.1       cgd 				printf("%-8.8s ", "PCB");
    162  1.35     lukem 			printf("%-5.5s %-6.6s %-6.6s %s%-*.*s %-*.*s %s\n",
    163   1.1       cgd 				"Proto", "Recv-Q", "Send-Q",
    164  1.35     lukem 				compact ? "" : " ",
    165  1.35     lukem 				width, width, "Local Address",
    166  1.35     lukem 				width, width, "Foreign Address", "State");
    167   1.1       cgd 			first = 0;
    168   1.1       cgd 		}
    169  1.34      ross 		if (Aflag) {
    170   1.1       cgd 			if (istcp)
    171  1.21  christos 				printf("%8lx ", (u_long) inpcb.inp_ppcb);
    172   1.1       cgd 			else
    173  1.21  christos 				printf("%8lx ", (u_long) prev);
    174  1.34      ross 		}
    175  1.35     lukem 		printf("%-5.5s %6ld %6ld%s", name, sockb.so_rcv.sb_cc,
    176  1.35     lukem 			sockb.so_snd.sb_cc, compact ? "" : " ");
    177  1.46     assar 		if (numeric_port) {
    178  1.28     lukem 			inetprint(&inpcb.inp_laddr, inpcb.inp_lport, name, 1);
    179  1.28     lukem 			inetprint(&inpcb.inp_faddr, inpcb.inp_fport, name, 1);
    180  1.28     lukem 		} else if (inpcb.inp_flags & INP_ANONPORT) {
    181  1.28     lukem 			inetprint(&inpcb.inp_laddr, inpcb.inp_lport, name, 1);
    182  1.28     lukem 			inetprint(&inpcb.inp_faddr, inpcb.inp_fport, name, 0);
    183  1.28     lukem 		} else {
    184  1.28     lukem 			inetprint(&inpcb.inp_laddr, inpcb.inp_lport, name, 0);
    185  1.51     lukem 			inetprint(&inpcb.inp_faddr, inpcb.inp_fport, name, 0);
    186  1.28     lukem 		}
    187   1.1       cgd 		if (istcp) {
    188   1.1       cgd 			if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES)
    189   1.1       cgd 				printf(" %d", tcpcb.t_state);
    190   1.1       cgd 			else
    191  1.35     lukem 				printf(" %s", compact ?
    192  1.35     lukem 				    shorttcpstates[tcpcb.t_state] :
    193  1.35     lukem 				    tcpstates[tcpcb.t_state]);
    194   1.1       cgd 		}
    195   1.1       cgd 		putchar('\n');
    196   1.1       cgd 	}
    197   1.1       cgd }
    198   1.1       cgd 
    199   1.1       cgd /*
    200   1.1       cgd  * Dump TCP statistics structure.
    201   1.1       cgd  */
    202   1.9   mycroft void
    203   1.1       cgd tcp_stats(off, name)
    204   1.8       cgd 	u_long off;
    205   1.1       cgd 	char *name;
    206   1.1       cgd {
    207   1.1       cgd 	struct tcpstat tcpstat;
    208   1.1       cgd 
    209  1.65      elad 	if (use_sysctl) {
    210  1.65      elad 		size_t size = sizeof(tcpstat);
    211  1.65      elad 
    212  1.65      elad 		if (sysctlbyname("net.inet.tcp.stats", &tcpstat, &size,
    213  1.65      elad 				 NULL, 0) == -1)
    214  1.65      elad 			err(1, "net.inet.tcp.stats");
    215  1.65      elad 	} else {
    216  1.65      elad 		if (off == 0)
    217  1.65      elad 			return;
    218  1.65      elad 		kread(off, (char *)&tcpstat, sizeof (tcpstat));
    219  1.65      elad 	}
    220  1.65      elad 
    221   1.1       cgd 	printf ("%s:\n", name);
    222   1.9   mycroft 
    223  1.20  christos #define	ps(f, m) if (tcpstat.f || sflag <= 1) \
    224  1.38    bouyer     printf(m, (unsigned long long)tcpstat.f)
    225   1.9   mycroft #define	p(f, m) if (tcpstat.f || sflag <= 1) \
    226  1.38    bouyer     printf(m, (unsigned long long)tcpstat.f, plural(tcpstat.f))
    227   1.9   mycroft #define	p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
    228  1.38    bouyer     printf(m, (unsigned long long)tcpstat.f1, plural(tcpstat.f1), \
    229  1.38    bouyer     (unsigned long long)tcpstat.f2, plural(tcpstat.f2))
    230  1.20  christos #define	p2s(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
    231  1.38    bouyer     printf(m, (unsigned long long)tcpstat.f1, plural(tcpstat.f1), \
    232  1.38    bouyer     (unsigned long long)tcpstat.f2)
    233   1.9   mycroft #define	p3(f, m) if (tcpstat.f || sflag <= 1) \
    234  1.38    bouyer     printf(m, (unsigned long long)tcpstat.f, plurales(tcpstat.f))
    235   1.1       cgd 
    236  1.38    bouyer 	p(tcps_sndtotal, "\t%llu packet%s sent\n");
    237   1.1       cgd 	p2(tcps_sndpack,tcps_sndbyte,
    238  1.38    bouyer 		"\t\t%llu data packet%s (%llu byte%s)\n");
    239   1.1       cgd 	p2(tcps_sndrexmitpack, tcps_sndrexmitbyte,
    240  1.38    bouyer 		"\t\t%llu data packet%s (%llu byte%s) retransmitted\n");
    241  1.20  christos 	p2s(tcps_sndacks, tcps_delack,
    242  1.38    bouyer 		"\t\t%llu ack-only packet%s (%llu delayed)\n");
    243  1.38    bouyer 	p(tcps_sndurg, "\t\t%llu URG only packet%s\n");
    244  1.38    bouyer 	p(tcps_sndprobe, "\t\t%llu window probe packet%s\n");
    245  1.38    bouyer 	p(tcps_sndwinup, "\t\t%llu window update packet%s\n");
    246  1.38    bouyer 	p(tcps_sndctrl, "\t\t%llu control packet%s\n");
    247  1.47   thorpej 	p(tcps_selfquench,
    248  1.47   thorpej 	    "\t\t%llu send attempt%s resulted in self-quench\n");
    249  1.38    bouyer 	p(tcps_rcvtotal, "\t%llu packet%s received\n");
    250  1.38    bouyer 	p2(tcps_rcvackpack, tcps_rcvackbyte,
    251  1.38    bouyer 		"\t\t%llu ack%s (for %llu byte%s)\n");
    252  1.38    bouyer 	p(tcps_rcvdupack, "\t\t%llu duplicate ack%s\n");
    253  1.38    bouyer 	p(tcps_rcvacktoomuch, "\t\t%llu ack%s for unsent data\n");
    254   1.1       cgd 	p2(tcps_rcvpack, tcps_rcvbyte,
    255  1.38    bouyer 		"\t\t%llu packet%s (%llu byte%s) received in-sequence\n");
    256   1.1       cgd 	p2(tcps_rcvduppack, tcps_rcvdupbyte,
    257  1.38    bouyer 		"\t\t%llu completely duplicate packet%s (%llu byte%s)\n");
    258  1.38    bouyer 	p(tcps_pawsdrop, "\t\t%llu old duplicate packet%s\n");
    259   1.1       cgd 	p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte,
    260  1.38    bouyer 		"\t\t%llu packet%s with some dup. data (%llu byte%s duped)\n");
    261   1.1       cgd 	p2(tcps_rcvoopack, tcps_rcvoobyte,
    262  1.38    bouyer 		"\t\t%llu out-of-order packet%s (%llu byte%s)\n");
    263   1.1       cgd 	p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin,
    264  1.38    bouyer 		"\t\t%llu packet%s (%llu byte%s) of data after window\n");
    265  1.38    bouyer 	p(tcps_rcvwinprobe, "\t\t%llu window probe%s\n");
    266  1.38    bouyer 	p(tcps_rcvwinupd, "\t\t%llu window update packet%s\n");
    267  1.38    bouyer 	p(tcps_rcvafterclose, "\t\t%llu packet%s received after close\n");
    268  1.38    bouyer 	p(tcps_rcvbadsum, "\t\t%llu discarded for bad checksum%s\n");
    269  1.38    bouyer 	p(tcps_rcvbadoff, "\t\t%llu discarded for bad header offset field%s\n");
    270  1.38    bouyer 	ps(tcps_rcvshort, "\t\t%llu discarded because packet too short\n");
    271  1.38    bouyer 	p(tcps_connattempt, "\t%llu connection request%s\n");
    272  1.38    bouyer 	p(tcps_accepts, "\t%llu connection accept%s\n");
    273  1.38    bouyer 	p(tcps_connects,
    274  1.38    bouyer 		"\t%llu connection%s established (including accepts)\n");
    275   1.1       cgd 	p2(tcps_closed, tcps_drops,
    276  1.38    bouyer 		"\t%llu connection%s closed (including %llu drop%s)\n");
    277  1.38    bouyer 	p(tcps_conndrops, "\t%llu embryonic connection%s dropped\n");
    278  1.57        he 	p(tcps_delayed_free, "\t%llu delayed free%s of tcpcb\n");
    279   1.1       cgd 	p2(tcps_rttupdated, tcps_segstimed,
    280  1.38    bouyer 		"\t%llu segment%s updated rtt (of %llu attempt%s)\n");
    281  1.38    bouyer 	p(tcps_rexmttimeo, "\t%llu retransmit timeout%s\n");
    282  1.38    bouyer 	p(tcps_timeoutdrop,
    283  1.38    bouyer 		"\t\t%llu connection%s dropped by rexmit timeout\n");
    284  1.27   thorpej 	p2(tcps_persisttimeo, tcps_persistdrops,
    285  1.38    bouyer 	   "\t%llu persist timeout%s (resulting in %llu dropped "
    286  1.38    bouyer 		"connection%s)\n");
    287  1.38    bouyer 	p(tcps_keeptimeo, "\t%llu keepalive timeout%s\n");
    288  1.38    bouyer 	p(tcps_keepprobe, "\t\t%llu keepalive probe%s sent\n");
    289  1.38    bouyer 	p(tcps_keepdrops, "\t\t%llu connection%s dropped by keepalive\n");
    290  1.38    bouyer 	p(tcps_predack, "\t%llu correct ACK header prediction%s\n");
    291  1.38    bouyer 	p(tcps_preddat, "\t%llu correct data packet header prediction%s\n");
    292  1.38    bouyer 	p3(tcps_pcbhashmiss, "\t%llu PCB hash miss%s\n");
    293  1.38    bouyer 	ps(tcps_noport, "\t%llu dropped due to no socket\n");
    294  1.38    bouyer 	p(tcps_connsdrained, "\t%llu connection%s drained due to memory "
    295  1.38    bouyer 		"shortage\n");
    296  1.52    itojun 	p(tcps_pmtublackhole, "\t%llu PMTUD blackhole%s detected\n");
    297  1.38    bouyer 
    298  1.38    bouyer 	p(tcps_badsyn, "\t%llu bad connection attempt%s\n");
    299  1.38    bouyer 	ps(tcps_sc_added, "\t%llu SYN cache entries added\n");
    300  1.38    bouyer 	p(tcps_sc_collisions, "\t\t%llu hash collision%s\n");
    301  1.38    bouyer 	ps(tcps_sc_completed, "\t\t%llu completed\n");
    302  1.38    bouyer 	ps(tcps_sc_aborted, "\t\t%llu aborted (no space to build PCB)\n");
    303  1.38    bouyer 	ps(tcps_sc_timed_out, "\t\t%llu timed out\n");
    304  1.38    bouyer 	ps(tcps_sc_overflowed, "\t\t%llu dropped due to overflow\n");
    305  1.38    bouyer 	ps(tcps_sc_bucketoverflow, "\t\t%llu dropped due to bucket overflow\n");
    306  1.38    bouyer 	ps(tcps_sc_reset, "\t\t%llu dropped due to RST\n");
    307  1.38    bouyer 	ps(tcps_sc_unreach, "\t\t%llu dropped due to ICMP unreachable\n");
    308  1.57        he 	ps(tcps_sc_delayed_free, "\t\t%llu delayed free of SYN cache "
    309  1.57        he 		"entries\n");
    310  1.38    bouyer 	p(tcps_sc_retransmitted, "\t%llu SYN,ACK%s retransmitted\n");
    311  1.38    bouyer 	p(tcps_sc_dupesyn, "\t%llu duplicate SYN%s received for entries "
    312  1.38    bouyer 		"already in the cache\n");
    313  1.38    bouyer 	p(tcps_sc_dropped, "\t%llu SYN%s dropped (no route or no space)\n");
    314  1.61    itojun 	p(tcps_badsig, "\t%llu packet%s with bad signature\n");
    315  1.61    itojun 	p(tcps_goodsig, "\t%llu packet%s with good signature\n");
    316  1.15   mycroft 
    317   1.1       cgd #undef p
    318  1.20  christos #undef ps
    319   1.1       cgd #undef p2
    320  1.20  christos #undef p2s
    321   1.9   mycroft #undef p3
    322   1.1       cgd }
    323   1.1       cgd 
    324   1.1       cgd /*
    325   1.1       cgd  * Dump UDP statistics structure.
    326   1.1       cgd  */
    327   1.9   mycroft void
    328   1.1       cgd udp_stats(off, name)
    329   1.8       cgd 	u_long off;
    330   1.1       cgd 	char *name;
    331   1.1       cgd {
    332   1.1       cgd 	struct udpstat udpstat;
    333  1.38    bouyer 	u_quad_t delivered;
    334   1.1       cgd 
    335  1.65      elad 	if (use_sysctl) {
    336  1.65      elad 		size_t size = sizeof(udpstat);
    337  1.65      elad 
    338  1.65      elad 		if (sysctlbyname("net.inet.udp.stats", &udpstat, &size,
    339  1.65      elad 				 NULL, 0) == -1)
    340  1.65      elad 			err(1, "net.inet.udp.stats");
    341  1.65      elad 	} else {
    342  1.65      elad 		if (off == 0)
    343  1.65      elad 			return;
    344  1.65      elad 		kread(off, (char *)&udpstat, sizeof (udpstat));
    345  1.65      elad 	}
    346  1.65      elad 
    347  1.65      elad 	printf ("%s:\n", name);
    348  1.15   mycroft 
    349  1.20  christos #define	ps(f, m) if (udpstat.f || sflag <= 1) \
    350  1.38    bouyer     printf(m, (unsigned long long)udpstat.f)
    351   1.9   mycroft #define	p(f, m) if (udpstat.f || sflag <= 1) \
    352  1.38    bouyer     printf(m, (unsigned long long)udpstat.f, plural(udpstat.f))
    353  1.15   mycroft #define	p3(f, m) if (udpstat.f || sflag <= 1) \
    354  1.38    bouyer     printf(m, (unsigned long long)udpstat.f, plurales(udpstat.f))
    355  1.15   mycroft 
    356  1.38    bouyer 	p(udps_ipackets, "\t%llu datagram%s received\n");
    357  1.38    bouyer 	ps(udps_hdrops, "\t%llu with incomplete header\n");
    358  1.38    bouyer 	ps(udps_badlen, "\t%llu with bad data length field\n");
    359  1.38    bouyer 	ps(udps_badsum, "\t%llu with bad checksum\n");
    360  1.38    bouyer 	ps(udps_noport, "\t%llu dropped due to no socket\n");
    361  1.38    bouyer 	p(udps_noportbcast, "\t%llu broadcast/multicast datagram%s dropped due to no socket\n");
    362  1.38    bouyer 	ps(udps_fullsock, "\t%llu dropped due to full socket buffers\n");
    363   1.9   mycroft 	delivered = udpstat.udps_ipackets -
    364   1.9   mycroft 		    udpstat.udps_hdrops -
    365   1.9   mycroft 		    udpstat.udps_badlen -
    366   1.9   mycroft 		    udpstat.udps_badsum -
    367   1.9   mycroft 		    udpstat.udps_noport -
    368   1.9   mycroft 		    udpstat.udps_noportbcast -
    369   1.9   mycroft 		    udpstat.udps_fullsock;
    370   1.9   mycroft 	if (delivered || sflag <= 1)
    371  1.38    bouyer 		printf("\t%llu delivered\n", (unsigned long long)delivered);
    372  1.38    bouyer 	p3(udps_pcbhashmiss, "\t%llu PCB hash miss%s\n");
    373  1.38    bouyer 	p(udps_opackets, "\t%llu datagram%s output\n");
    374  1.15   mycroft 
    375  1.20  christos #undef ps
    376   1.9   mycroft #undef p
    377  1.15   mycroft #undef p3
    378   1.1       cgd }
    379   1.1       cgd 
    380   1.1       cgd /*
    381   1.1       cgd  * Dump IP statistics structure.
    382   1.1       cgd  */
    383   1.9   mycroft void
    384   1.1       cgd ip_stats(off, name)
    385   1.8       cgd 	u_long off;
    386   1.1       cgd 	char *name;
    387   1.1       cgd {
    388   1.1       cgd 	struct ipstat ipstat;
    389   1.1       cgd 
    390  1.65      elad 	if (use_sysctl) {
    391  1.65      elad 		size_t size = sizeof(ipstat);
    392  1.65      elad 
    393  1.65      elad 		if (sysctlbyname("net.inet.ip.stats", &ipstat, &size,
    394  1.65      elad 				 NULL, 0) == -1)
    395  1.65      elad 			err(1, "net.inet.ip.stats");
    396  1.65      elad 	} else {
    397  1.65      elad 		if (off == 0)
    398  1.65      elad 			return;
    399  1.65      elad 		kread(off, (char *)&ipstat, sizeof (ipstat));
    400  1.65      elad 	}
    401  1.65      elad 
    402   1.9   mycroft 	printf("%s:\n", name);
    403   1.9   mycroft 
    404  1.20  christos #define	ps(f, m) if (ipstat.f || sflag <= 1) \
    405  1.38    bouyer     printf(m, (unsigned long long)ipstat.f)
    406   1.9   mycroft #define	p(f, m) if (ipstat.f || sflag <= 1) \
    407  1.38    bouyer     printf(m, (unsigned long long)ipstat.f, plural(ipstat.f))
    408   1.9   mycroft 
    409  1.38    bouyer 	p(ips_total, "\t%llu total packet%s received\n");
    410  1.38    bouyer 	p(ips_badsum, "\t%llu bad header checksum%s\n");
    411  1.38    bouyer 	ps(ips_toosmall, "\t%llu with size smaller than minimum\n");
    412  1.38    bouyer 	ps(ips_tooshort, "\t%llu with data size < data length\n");
    413  1.38    bouyer 	ps(ips_toolong, "\t%llu with length > max ip packet size\n");
    414  1.38    bouyer 	ps(ips_badhlen, "\t%llu with header length < data size\n");
    415  1.38    bouyer 	ps(ips_badlen, "\t%llu with data length < header length\n");
    416  1.38    bouyer 	ps(ips_badoptions, "\t%llu with bad options\n");
    417  1.38    bouyer 	ps(ips_badvers, "\t%llu with incorrect version number\n");
    418  1.40     enami 	p(ips_fragments, "\t%llu fragment%s received\n");
    419  1.38    bouyer 	p(ips_fragdropped, "\t%llu fragment%s dropped (dup or out of space)\n");
    420  1.60     enami 	p(ips_rcvmemdrop, "\t%llu fragment%s dropped (out of ipqent)\n");
    421  1.38    bouyer 	p(ips_badfrags, "\t%llu malformed fragment%s dropped\n");
    422  1.38    bouyer 	p(ips_fragtimeout, "\t%llu fragment%s dropped after timeout\n");
    423  1.38    bouyer 	p(ips_reassembled, "\t%llu packet%s reassembled ok\n");
    424  1.38    bouyer 	p(ips_delivered, "\t%llu packet%s for this host\n");
    425  1.38    bouyer 	p(ips_noproto, "\t%llu packet%s for unknown/unsupported protocol\n");
    426  1.38    bouyer 	p(ips_forward, "\t%llu packet%s forwarded");
    427  1.38    bouyer 	p(ips_fastforward, " (%llu packet%s fast forwarded)");
    428  1.29      matt 	if (ipstat.ips_forward || sflag <= 1)
    429  1.29      matt 		putchar('\n');
    430  1.38    bouyer 	p(ips_cantforward, "\t%llu packet%s not forwardable\n");
    431  1.38    bouyer 	p(ips_redirectsent, "\t%llu redirect%s sent\n");
    432  1.60     enami 	p(ips_nogif, "\t%llu packet%s no matching gif found\n");
    433  1.38    bouyer 	p(ips_localout, "\t%llu packet%s sent from this host\n");
    434  1.38    bouyer 	p(ips_rawout, "\t%llu packet%s sent with fabricated ip header\n");
    435  1.38    bouyer 	p(ips_odropped, "\t%llu output packet%s dropped due to no bufs, etc.\n");
    436  1.38    bouyer 	p(ips_noroute, "\t%llu output packet%s discarded due to no route\n");
    437  1.38    bouyer 	p(ips_fragmented, "\t%llu output datagram%s fragmented\n");
    438  1.38    bouyer 	p(ips_ofragments, "\t%llu fragment%s created\n");
    439  1.38    bouyer 	p(ips_cantfrag, "\t%llu datagram%s that can't be fragmented\n");
    440  1.43    itojun 	p(ips_badaddr, "\t%llu datagram%s with bad address in header\n");
    441  1.20  christos #undef ps
    442   1.9   mycroft #undef p
    443   1.1       cgd }
    444   1.1       cgd 
    445   1.1       cgd static	char *icmpnames[] = {
    446   1.1       cgd 	"echo reply",
    447   1.1       cgd 	"#1",
    448   1.1       cgd 	"#2",
    449   1.1       cgd 	"destination unreachable",
    450   1.1       cgd 	"source quench",
    451   1.1       cgd 	"routing redirect",
    452  1.44    itojun 	"alternate host address",
    453   1.1       cgd 	"#7",
    454   1.1       cgd 	"echo",
    455  1.44    itojun 	"router advertisement",
    456  1.44    itojun 	"router solicitation",
    457   1.1       cgd 	"time exceeded",
    458   1.1       cgd 	"parameter problem",
    459   1.1       cgd 	"time stamp",
    460   1.1       cgd 	"time stamp reply",
    461   1.1       cgd 	"information request",
    462   1.1       cgd 	"information request reply",
    463   1.1       cgd 	"address mask request",
    464   1.1       cgd 	"address mask reply",
    465   1.1       cgd };
    466   1.1       cgd 
    467   1.1       cgd /*
    468   1.1       cgd  * Dump ICMP statistics.
    469   1.1       cgd  */
    470   1.9   mycroft void
    471   1.1       cgd icmp_stats(off, name)
    472   1.8       cgd 	u_long off;
    473   1.1       cgd 	char *name;
    474   1.1       cgd {
    475   1.1       cgd 	struct icmpstat icmpstat;
    476  1.23     lukem 	int i, first;
    477   1.1       cgd 
    478  1.65      elad 	if (use_sysctl) {
    479  1.65      elad 		size_t size = sizeof(icmpstat);
    480  1.65      elad 
    481  1.65      elad 		if (sysctlbyname("net.inet.icmp.stats", &icmpstat, &size,
    482  1.65      elad 				 NULL, 0) == -1)
    483  1.65      elad 			err(1, "net.inet.icmp.stats");
    484  1.65      elad 	} else {
    485  1.65      elad 		if (off == 0)
    486  1.65      elad 			return;
    487  1.65      elad 		kread(off, (char *)&icmpstat, sizeof (icmpstat));
    488  1.65      elad 	}
    489  1.65      elad 
    490   1.9   mycroft 	printf("%s:\n", name);
    491   1.9   mycroft 
    492   1.9   mycroft #define	p(f, m) if (icmpstat.f || sflag <= 1) \
    493  1.38    bouyer     printf(m, (unsigned long long)icmpstat.f, plural(icmpstat.f))
    494   1.9   mycroft 
    495  1.38    bouyer 	p(icps_error, "\t%llu call%s to icmp_error\n");
    496   1.9   mycroft 	p(icps_oldicmp,
    497  1.38    bouyer 	    "\t%llu error%s not generated because old message was icmp\n");
    498   1.1       cgd 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
    499   1.1       cgd 		if (icmpstat.icps_outhist[i] != 0) {
    500   1.1       cgd 			if (first) {
    501   1.1       cgd 				printf("\tOutput histogram:\n");
    502   1.1       cgd 				first = 0;
    503   1.1       cgd 			}
    504  1.38    bouyer 			printf("\t\t%s: %llu\n", icmpnames[i],
    505  1.38    bouyer 				(unsigned long long)icmpstat.icps_outhist[i]);
    506   1.1       cgd 		}
    507  1.38    bouyer 	p(icps_badcode, "\t%llu message%s with bad code fields\n");
    508  1.38    bouyer 	p(icps_tooshort, "\t%llu message%s < minimum length\n");
    509  1.38    bouyer 	p(icps_checksum, "\t%llu bad checksum%s\n");
    510  1.38    bouyer 	p(icps_badlen, "\t%llu message%s with bad length\n");
    511   1.1       cgd 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
    512   1.1       cgd 		if (icmpstat.icps_inhist[i] != 0) {
    513   1.1       cgd 			if (first) {
    514   1.1       cgd 				printf("\tInput histogram:\n");
    515   1.1       cgd 				first = 0;
    516   1.1       cgd 			}
    517  1.38    bouyer 			printf("\t\t%s: %llu\n", icmpnames[i],
    518  1.38    bouyer 				(unsigned long long)icmpstat.icps_inhist[i]);
    519   1.1       cgd 		}
    520  1.38    bouyer 	p(icps_reflect, "\t%llu message response%s generated\n");
    521  1.42    itojun 	p(icps_pmtuchg, "\t%llu path MTU change%s\n");
    522   1.9   mycroft #undef p
    523   1.6    brezak }
    524   1.6    brezak 
    525   1.6    brezak /*
    526   1.9   mycroft  * Dump IGMP statistics structure.
    527   1.6    brezak  */
    528   1.6    brezak void
    529   1.6    brezak igmp_stats(off, name)
    530   1.8       cgd 	u_long off;
    531   1.6    brezak 	char *name;
    532   1.6    brezak {
    533   1.6    brezak 	struct igmpstat igmpstat;
    534   1.6    brezak 
    535   1.6    brezak 	if (off == 0)
    536   1.6    brezak 		return;
    537   1.9   mycroft 	kread(off, (char *)&igmpstat, sizeof (igmpstat));
    538   1.9   mycroft 	printf("%s:\n", name);
    539   1.9   mycroft 
    540   1.9   mycroft #define	p(f, m) if (igmpstat.f || sflag <= 1) \
    541  1.38    bouyer     printf(m, (unsigned long long)igmpstat.f, plural(igmpstat.f))
    542   1.9   mycroft #define	py(f, m) if (igmpstat.f || sflag <= 1) \
    543  1.38    bouyer     printf(m, (unsigned long long)igmpstat.f, igmpstat.f != 1 ? "ies" : "y")
    544  1.38    bouyer 	p(igps_rcv_total, "\t%llu message%s received\n");
    545  1.38    bouyer         p(igps_rcv_tooshort, "\t%llu message%s received with too few bytes\n");
    546  1.38    bouyer         p(igps_rcv_badsum, "\t%llu message%s received with bad checksum\n");
    547  1.38    bouyer         py(igps_rcv_queries, "\t%llu membership quer%s received\n");
    548  1.38    bouyer         py(igps_rcv_badqueries, "\t%llu membership quer%s received with invalid field(s)\n");
    549  1.38    bouyer         p(igps_rcv_reports, "\t%llu membership report%s received\n");
    550  1.38    bouyer         p(igps_rcv_badreports, "\t%llu membership report%s received with invalid field(s)\n");
    551  1.38    bouyer         p(igps_rcv_ourreports, "\t%llu membership report%s received for groups to which we belong\n");
    552  1.38    bouyer         p(igps_snd_reports, "\t%llu membership report%s sent\n");
    553   1.9   mycroft #undef p
    554   1.9   mycroft #undef py
    555  1.41     jhawk }
    556  1.41     jhawk 
    557  1.41     jhawk /*
    558  1.62      manu  * Dump PIM statistics structure.
    559  1.62      manu  */
    560  1.62      manu void
    561  1.62      manu pim_stats(off, name)
    562  1.62      manu 	u_long off;
    563  1.62      manu 	char *name;
    564  1.62      manu {
    565  1.62      manu 	struct pimstat pimstat;
    566  1.62      manu 
    567  1.62      manu 	if (off == 0)
    568  1.62      manu 		return;
    569  1.62      manu 	if (kread(off, (char *)&pimstat, sizeof (pimstat)) != 0) {
    570  1.62      manu 		/* XXX: PIM is probably not enabled in the kernel */
    571  1.62      manu 		return;
    572  1.62      manu 	}
    573  1.62      manu 
    574  1.62      manu 	printf("%s:\n", name);
    575  1.62      manu 
    576  1.62      manu #define	p(f, m) if (pimstat.f || sflag <= 1) \
    577  1.63    martin 	printf(m, (unsigned long long)pimstat.f, plural(pimstat.f))
    578  1.62      manu 
    579  1.62      manu 	p(pims_rcv_total_msgs, "\t%llu message%s received\n");
    580  1.62      manu 	p(pims_rcv_total_bytes, "\t%llu byte%s received\n");
    581  1.62      manu 	p(pims_rcv_tooshort, "\t%llu message%s received with too few bytes\n");
    582  1.62      manu         p(pims_rcv_badsum, "\t%llu message%s received with bad checksum\n");
    583  1.62      manu 	p(pims_rcv_badversion, "\t%llu message%s received with bad version\n");
    584  1.62      manu 	p(pims_rcv_registers_msgs, "\t%llu data register message%s received\n");
    585  1.62      manu 	p(pims_rcv_registers_bytes, "\t%llu data register byte%s received\n");
    586  1.62      manu 	p(pims_rcv_registers_wrongiif, "\t%llu data register message%s received on wrong iif\n");
    587  1.62      manu 	p(pims_rcv_badregisters, "\t%llu bad register%s received\n");
    588  1.62      manu 	p(pims_snd_registers_msgs, "\t%llu data register message%s sent\n");
    589  1.62      manu 	p(pims_snd_registers_bytes, "\t%llu data register byte%s sent\n");
    590  1.62      manu #undef p
    591  1.62      manu }
    592  1.62      manu 
    593  1.62      manu /*
    594  1.41     jhawk  * Dump the ARP statistics structure.
    595  1.41     jhawk  */
    596  1.41     jhawk void
    597  1.41     jhawk arp_stats(off, name)
    598  1.41     jhawk 	u_long off;
    599  1.41     jhawk 	char *name;
    600  1.41     jhawk {
    601  1.41     jhawk 	struct arpstat arpstat;
    602  1.41     jhawk 
    603  1.41     jhawk 	if (off == 0)
    604  1.41     jhawk 		return;
    605  1.41     jhawk 	kread(off, (char *)&arpstat, sizeof (arpstat));
    606  1.41     jhawk 	printf("%s:\n", name);
    607  1.41     jhawk 
    608  1.41     jhawk #define	ps(f, m) if (arpstat.f || sflag <= 1) \
    609  1.41     jhawk     printf(m, (unsigned long long)arpstat.f)
    610  1.41     jhawk #define	p(f, m) if (arpstat.f || sflag <= 1) \
    611  1.41     jhawk     printf(m, (unsigned long long)arpstat.f, plural(arpstat.f))
    612  1.41     jhawk 
    613  1.41     jhawk 	p(as_sndtotal, "\t%llu packet%s sent\n");
    614  1.41     jhawk 	p(as_sndreply, "\t\t%llu reply packet%s\n");
    615  1.41     jhawk 	p(as_sndrequest, "\t\t%llu request packet%s\n");
    616  1.41     jhawk 
    617  1.41     jhawk 	p(as_rcvtotal, "\t%llu packet%s received\n");
    618  1.41     jhawk 	p(as_rcvreply, "\t\t%llu reply packet%s\n");
    619  1.41     jhawk 	p(as_rcvrequest, "\t\t%llu valid request packet%s\n");
    620  1.41     jhawk 	p(as_rcvmcast, "\t\t%llu broadcast/multicast packet%s\n");
    621  1.41     jhawk 	p(as_rcvbadproto, "\t\t%llu packet%s with unknown protocol type\n");
    622  1.41     jhawk 	p(as_rcvbadlen, "\t\t%llu packet%s with bad (short) length\n");
    623  1.41     jhawk 	p(as_rcvzerotpa, "\t\t%llu packet%s with null target IP address\n");
    624  1.41     jhawk 	p(as_rcvzerospa, "\t\t%llu packet%s with null source IP address\n");
    625  1.41     jhawk 	ps(as_rcvnoint, "\t\t%llu could not be mapped to an interface\n");
    626  1.41     jhawk 	p(as_rcvlocalsha, "\t\t%llu packet%s sourced from a local hardware "
    627  1.41     jhawk 	    "address\n");
    628  1.41     jhawk 	p(as_rcvbcastsha, "\t\t%llu packet%s with a broadcast "
    629  1.41     jhawk 	    "source hardware address\n");
    630  1.41     jhawk 	p(as_rcvlocalspa, "\t\t%llu duplicate%s for a local IP address\n");
    631  1.41     jhawk 	p(as_rcvoverperm, "\t\t%llu attempt%s to overwrite a static entry\n");
    632  1.41     jhawk 	p(as_rcvoverint, "\t\t%llu packet%s received on wrong interface\n");
    633  1.41     jhawk 	p(as_rcvover, "\t\t%llu entry%s overwritten\n");
    634  1.41     jhawk 	p(as_rcvlenchg, "\t\t%llu change%s in hardware address length\n");
    635  1.41     jhawk 
    636  1.41     jhawk 	p(as_dfrtotal, "\t%llu packet%s deferred pending ARP resolution\n");
    637  1.41     jhawk 	ps(as_dfrsent, "\t\t%llu sent\n");
    638  1.41     jhawk 	ps(as_dfrdropped, "\t\t%llu dropped\n");
    639  1.41     jhawk 
    640  1.41     jhawk 	p(as_allocfail, "\t%llu failure%s to allocate llinfo\n");
    641  1.41     jhawk 
    642  1.41     jhawk #undef ps
    643  1.41     jhawk #undef p
    644   1.1       cgd }
    645   1.1       cgd 
    646   1.1       cgd /*
    647   1.1       cgd  * Pretty print an Internet address (net address + port).
    648  1.46     assar  * Take numeric_addr and numeric_port into consideration.
    649   1.1       cgd  */
    650   1.9   mycroft void
    651  1.46     assar inetprint(in, port, proto, numeric_port)
    652  1.23     lukem 	struct in_addr *in;
    653  1.28     lukem 	u_int16_t port;
    654  1.28     lukem 	const char *proto;
    655  1.46     assar 	int numeric_port;
    656   1.1       cgd {
    657   1.1       cgd 	struct servent *sp = 0;
    658   1.9   mycroft 	char line[80], *cp;
    659  1.33  sommerfe 	size_t space;
    660   1.1       cgd 
    661  1.32       mrg 	(void)snprintf(line, sizeof line, "%.*s.",
    662  1.46     assar 	    (Aflag && !numeric_addr) ? 12 : 16, inetname(in));
    663  1.23     lukem 	cp = strchr(line, '\0');
    664  1.46     assar 	if (!numeric_port && port)
    665   1.1       cgd 		sp = getservbyport((int)port, proto);
    666  1.33  sommerfe 	space = sizeof line - (cp-line);
    667   1.1       cgd 	if (sp || port == 0)
    668  1.55  jdolecek 		(void)snprintf(cp, space, "%s", sp ? sp->s_name : "*");
    669   1.1       cgd 	else
    670  1.33  sommerfe 		(void)snprintf(cp, space, "%u", ntohs(port));
    671  1.32       mrg 	(void)printf(" %-*.*s", width, width, line);
    672   1.1       cgd }
    673   1.1       cgd 
    674   1.1       cgd /*
    675   1.1       cgd  * Construct an Internet address representation.
    676  1.46     assar  * If numeric_addr has been supplied, give
    677   1.1       cgd  * numeric value, otherwise try for symbolic name.
    678   1.1       cgd  */
    679   1.1       cgd char *
    680   1.9   mycroft inetname(inp)
    681   1.9   mycroft 	struct in_addr *inp;
    682   1.1       cgd {
    683  1.23     lukem 	char *cp;
    684   1.1       cgd 	static char line[50];
    685   1.1       cgd 	struct hostent *hp;
    686   1.1       cgd 	struct netent *np;
    687   1.1       cgd 	static char domain[MAXHOSTNAMELEN + 1];
    688   1.1       cgd 	static int first = 1;
    689   1.1       cgd 
    690  1.46     assar 	if (first && !numeric_addr) {
    691   1.1       cgd 		first = 0;
    692  1.31       mrg 		if (gethostname(domain, sizeof domain) == 0) {
    693  1.31       mrg 			domain[sizeof(domain) - 1] = '\0';
    694  1.31       mrg 			if ((cp = strchr(domain, '.')))
    695  1.45    itojun 				(void) strlcpy(domain, cp + 1, sizeof(domain));
    696  1.31       mrg 			else
    697  1.31       mrg 				domain[0] = 0;
    698  1.31       mrg 		} else
    699   1.1       cgd 			domain[0] = 0;
    700   1.1       cgd 	}
    701   1.1       cgd 	cp = 0;
    702  1.46     assar 	if (!numeric_addr && inp->s_addr != INADDR_ANY) {
    703   1.9   mycroft 		int net = inet_netof(*inp);
    704   1.9   mycroft 		int lna = inet_lnaof(*inp);
    705   1.1       cgd 
    706   1.1       cgd 		if (lna == INADDR_ANY) {
    707   1.1       cgd 			np = getnetbyaddr(net, AF_INET);
    708   1.1       cgd 			if (np)
    709   1.1       cgd 				cp = np->n_name;
    710   1.1       cgd 		}
    711   1.1       cgd 		if (cp == 0) {
    712   1.9   mycroft 			hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET);
    713   1.1       cgd 			if (hp) {
    714  1.23     lukem 				if ((cp = strchr(hp->h_name, '.')) &&
    715   1.1       cgd 				    !strcmp(cp + 1, domain))
    716   1.1       cgd 					*cp = 0;
    717   1.1       cgd 				cp = hp->h_name;
    718   1.1       cgd 			}
    719   1.1       cgd 		}
    720   1.1       cgd 	}
    721   1.9   mycroft 	if (inp->s_addr == INADDR_ANY)
    722  1.56    itojun 		strlcpy(line, "*", sizeof line);
    723   1.1       cgd 	else if (cp)
    724  1.56    itojun 		strlcpy(line, cp, sizeof line);
    725   1.1       cgd 	else {
    726   1.9   mycroft 		inp->s_addr = ntohl(inp->s_addr);
    727   1.1       cgd #define C(x)	((x) & 0xff)
    728  1.32       mrg 		(void)snprintf(line, sizeof line, "%u.%u.%u.%u",
    729  1.32       mrg 		    C(inp->s_addr >> 24), C(inp->s_addr >> 16),
    730  1.32       mrg 		    C(inp->s_addr >> 8), C(inp->s_addr));
    731  1.32       mrg #undef C
    732   1.1       cgd 	}
    733   1.1       cgd 	return (line);
    734  1.30   thorpej }
    735  1.30   thorpej 
    736  1.30   thorpej /*
    737  1.30   thorpej  * Dump the contents of a TCP PCB.
    738  1.30   thorpej  */
    739  1.30   thorpej void
    740  1.30   thorpej tcp_dump(pcbaddr)
    741  1.30   thorpej 	u_long pcbaddr;
    742  1.30   thorpej {
    743  1.30   thorpej 	struct tcpcb tcpcb;
    744  1.54   thorpej 	int i, hardticks;
    745  1.30   thorpej 
    746  1.30   thorpej 	kread(pcbaddr, (char *)&tcpcb, sizeof(tcpcb));
    747  1.54   thorpej 	hardticks = get_hardticks();
    748  1.30   thorpej 
    749  1.30   thorpej 	printf("TCP Protocol Control Block at 0x%08lx:\n\n", pcbaddr);
    750  1.30   thorpej 
    751  1.30   thorpej 	printf("Timers:\n");
    752  1.48   thorpej 	for (i = 0; i < TCPT_NTIMERS; i++) {
    753  1.54   thorpej 		printf("\t%s: %d", tcptimers[i],
    754  1.53   thorpej 		    (tcpcb.t_timer[i].c_flags & CALLOUT_PENDING) ?
    755  1.54   thorpej 		    tcpcb.t_timer[i].c_time - hardticks : 0);
    756  1.48   thorpej 	}
    757  1.30   thorpej 	printf("\n\n");
    758  1.30   thorpej 
    759  1.30   thorpej 	if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES)
    760  1.30   thorpej 		printf("State: %d", tcpcb.t_state);
    761  1.30   thorpej 	else
    762  1.30   thorpej 		printf("State: %s", tcpstates[tcpcb.t_state]);
    763  1.49   thorpej 	printf(", flags 0x%x, inpcb 0x%lx, in6pcb 0x%lx\n\n", tcpcb.t_flags,
    764  1.49   thorpej 	    (u_long)tcpcb.t_inpcb, (u_long)tcpcb.t_in6pcb);
    765  1.30   thorpej 
    766  1.30   thorpej 	printf("rxtshift %d, rxtcur %d, dupacks %d\n", tcpcb.t_rxtshift,
    767  1.30   thorpej 	    tcpcb.t_rxtcur, tcpcb.t_dupacks);
    768  1.30   thorpej 	printf("peermss %u, ourmss %u, segsz %u\n\n", tcpcb.t_peermss,
    769  1.30   thorpej 	    tcpcb.t_ourmss, tcpcb.t_segsz);
    770  1.30   thorpej 
    771  1.30   thorpej 	printf("snd_una %u, snd_nxt %u, snd_up %u\n",
    772  1.30   thorpej 	    tcpcb.snd_una, tcpcb.snd_nxt, tcpcb.snd_up);
    773  1.30   thorpej 	printf("snd_wl1 %u, snd_wl2 %u, iss %u, snd_wnd %lu\n\n",
    774  1.30   thorpej 	    tcpcb.snd_wl1, tcpcb.snd_wl2, tcpcb.iss, tcpcb.snd_wnd);
    775  1.30   thorpej 
    776  1.30   thorpej 	printf("rcv_wnd %lu, rcv_nxt %u, rcv_up %u, irs %u\n\n",
    777  1.30   thorpej 	    tcpcb.rcv_wnd, tcpcb.rcv_nxt, tcpcb.rcv_up, tcpcb.irs);
    778  1.30   thorpej 
    779  1.30   thorpej 	printf("rcv_adv %u, snd_max %u, snd_cwnd %lu, snd_ssthresh %lu\n",
    780  1.30   thorpej 	    tcpcb.rcv_adv, tcpcb.snd_max, tcpcb.snd_cwnd, tcpcb.snd_ssthresh);
    781  1.30   thorpej 
    782  1.47   thorpej 	printf("rcvtime %u, rtttime %u, rtseq %u, srtt %d, rttvar %d, "
    783  1.47   thorpej 	    "rttmin %d, max_sndwnd %lu\n\n", tcpcb.t_rcvtime, tcpcb.t_rtttime,
    784  1.47   thorpej 	    tcpcb.t_rtseq, tcpcb.t_srtt, tcpcb.t_rttvar, tcpcb.t_rttmin,
    785  1.47   thorpej 	    tcpcb.max_sndwnd);
    786  1.30   thorpej 
    787  1.30   thorpej 	printf("oobflags %d, iobc %d, softerror %d\n\n", tcpcb.t_oobflags,
    788  1.30   thorpej 	    tcpcb.t_iobc, tcpcb.t_softerror);
    789  1.30   thorpej 
    790  1.30   thorpej 	printf("snd_scale %d, rcv_scale %d, req_r_scale %d, req_s_scale %d\n",
    791  1.30   thorpej 	    tcpcb.snd_scale, tcpcb.rcv_scale, tcpcb.request_r_scale,
    792  1.30   thorpej 	    tcpcb.requested_s_scale);
    793  1.30   thorpej 	printf("ts_recent %u, ts_regent_age %d, last_ack_sent %u\n",
    794  1.30   thorpej 	    tcpcb.ts_recent, tcpcb.ts_recent_age, tcpcb.last_ack_sent);
    795   1.1       cgd }
    796