xref: /freebsd/usr.bin/netstat/inet.c (revision b6101dafe98e32eb052597341af0afb7ecc5d25e)
19b50d902SRodney W. Grimes /*
205ddff6eSPeter Wemm  * Copyright (c) 1983, 1988, 1993, 1995
39b50d902SRodney W. Grimes  *	The Regents of the University of California.  All rights reserved.
49b50d902SRodney W. Grimes  *
59b50d902SRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
69b50d902SRodney W. Grimes  * modification, are permitted provided that the following conditions
79b50d902SRodney W. Grimes  * are met:
89b50d902SRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
99b50d902SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer.
109b50d902SRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
119b50d902SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer in the
129b50d902SRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
139b50d902SRodney W. Grimes  * 3. All advertising materials mentioning features or use of this software
149b50d902SRodney W. Grimes  *    must display the following acknowledgement:
159b50d902SRodney W. Grimes  *	This product includes software developed by the University of
169b50d902SRodney W. Grimes  *	California, Berkeley and its contributors.
179b50d902SRodney W. Grimes  * 4. Neither the name of the University nor the names of its contributors
189b50d902SRodney W. Grimes  *    may be used to endorse or promote products derived from this software
199b50d902SRodney W. Grimes  *    without specific prior written permission.
209b50d902SRodney W. Grimes  *
219b50d902SRodney W. Grimes  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
229b50d902SRodney W. Grimes  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
239b50d902SRodney W. Grimes  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
249b50d902SRodney W. Grimes  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
259b50d902SRodney W. Grimes  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
269b50d902SRodney W. Grimes  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
279b50d902SRodney W. Grimes  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
289b50d902SRodney W. Grimes  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
299b50d902SRodney W. Grimes  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
309b50d902SRodney W. Grimes  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
319b50d902SRodney W. Grimes  * SUCH DAMAGE.
329b50d902SRodney W. Grimes  */
339b50d902SRodney W. Grimes 
349b50d902SRodney W. Grimes #ifndef lint
3590864998SGarrett Wollman /*
3605ddff6eSPeter Wemm static char sccsid[] = "@(#)inet.c	8.5 (Berkeley) 5/24/95";
3790864998SGarrett Wollman */
3890864998SGarrett Wollman static const char rcsid[] =
39c3aac50fSPeter Wemm   "$FreeBSD$";
409b50d902SRodney W. Grimes #endif /* not lint */
419b50d902SRodney W. Grimes 
429b50d902SRodney W. Grimes #include <sys/param.h>
43d8d89152SDavid Greenman #include <sys/queue.h>
449b50d902SRodney W. Grimes #include <sys/socket.h>
459b50d902SRodney W. Grimes #include <sys/socketvar.h>
464e00c309SGarrett Wollman #include <sys/sysctl.h>
479b50d902SRodney W. Grimes #include <sys/protosw.h>
489b50d902SRodney W. Grimes 
499b50d902SRodney W. Grimes #include <net/route.h>
509b50d902SRodney W. Grimes #include <netinet/in.h>
519b50d902SRodney W. Grimes #include <netinet/in_systm.h>
529b50d902SRodney W. Grimes #include <netinet/ip.h>
53cfa1ca9dSYoshinobu Inoue #ifdef INET6
54cfa1ca9dSYoshinobu Inoue #include <netinet/ip6.h>
55cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
569b50d902SRodney W. Grimes #include <netinet/in_pcb.h>
579b50d902SRodney W. Grimes #include <netinet/ip_icmp.h>
589b50d902SRodney W. Grimes #include <netinet/icmp_var.h>
599b50d902SRodney W. Grimes #include <netinet/igmp_var.h>
609b50d902SRodney W. Grimes #include <netinet/ip_var.h>
61c7b9b5bbSJeffrey Hsu #include <netinet/pim_var.h>
629b50d902SRodney W. Grimes #include <netinet/tcp.h>
639b50d902SRodney W. Grimes #include <netinet/tcpip.h>
649b50d902SRodney W. Grimes #include <netinet/tcp_seq.h>
659b50d902SRodney W. Grimes #define TCPSTATES
669b50d902SRodney W. Grimes #include <netinet/tcp_fsm.h>
679b50d902SRodney W. Grimes #include <netinet/tcp_timer.h>
689b50d902SRodney W. Grimes #include <netinet/tcp_var.h>
699b50d902SRodney W. Grimes #include <netinet/tcp_debug.h>
709b50d902SRodney W. Grimes #include <netinet/udp.h>
719b50d902SRodney W. Grimes #include <netinet/udp_var.h>
729b50d902SRodney W. Grimes 
739b50d902SRodney W. Grimes #include <arpa/inet.h>
744f81ef50SGarrett Wollman #include <err.h>
754f81ef50SGarrett Wollman #include <errno.h>
76d121b556SBrian Somers #include <libutil.h>
779b50d902SRodney W. Grimes #include <netdb.h>
789b50d902SRodney W. Grimes #include <stdio.h>
794f81ef50SGarrett Wollman #include <stdlib.h>
809b50d902SRodney W. Grimes #include <string.h>
819b50d902SRodney W. Grimes #include <unistd.h>
829b50d902SRodney W. Grimes #include "netstat.h"
839b50d902SRodney W. Grimes 
845e051718SAssar Westerlund char	*inetname (struct in_addr *);
85a01e3379SDavid Malone void	inetprint (struct in_addr *, int, const char *, int);
86cfa1ca9dSYoshinobu Inoue #ifdef INET6
87cfa1ca9dSYoshinobu Inoue static int udp_done, tcp_done;
88cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
899b50d902SRodney W. Grimes 
909b50d902SRodney W. Grimes /*
919b50d902SRodney W. Grimes  * Print a summary of connections related to an Internet
929b50d902SRodney W. Grimes  * protocol.  For TCP, also give state of connection.
939b50d902SRodney W. Grimes  * Listening processes (aflag) are suppressed unless the
949b50d902SRodney W. Grimes  * -a (all) flag is specified.
959b50d902SRodney W. Grimes  */
969b50d902SRodney W. Grimes void
975e051718SAssar Westerlund protopr(u_long proto,		/* for sysctl version we pass proto # */
98a01e3379SDavid Malone 	const char *name, int af1)
999b50d902SRodney W. Grimes {
1009b50d902SRodney W. Grimes 	int istcp;
1019b50d902SRodney W. Grimes 	static int first = 1;
1024f81ef50SGarrett Wollman 	char *buf;
103fb5d0fbdSRuslan Ermilov 	const char *mibvar, *vchar;
104a97a9922SJulian Elischer 	struct tcpcb *tp = NULL;
1054f81ef50SGarrett Wollman 	struct inpcb *inp;
1064f81ef50SGarrett Wollman 	struct xinpgen *xig, *oxig;
1074f81ef50SGarrett Wollman 	struct xsocket *so;
1084f81ef50SGarrett Wollman 	size_t len;
1099b50d902SRodney W. Grimes 
1104f81ef50SGarrett Wollman 	istcp = 0;
1114f81ef50SGarrett Wollman 	switch (proto) {
1124f81ef50SGarrett Wollman 	case IPPROTO_TCP:
113cfa1ca9dSYoshinobu Inoue #ifdef INET6
114cfa1ca9dSYoshinobu Inoue 		if (tcp_done != 0)
115cfa1ca9dSYoshinobu Inoue 			return;
116cfa1ca9dSYoshinobu Inoue 		else
117cfa1ca9dSYoshinobu Inoue 			tcp_done = 1;
118cfa1ca9dSYoshinobu Inoue #endif
1194f81ef50SGarrett Wollman 		istcp = 1;
1204f81ef50SGarrett Wollman 		mibvar = "net.inet.tcp.pcblist";
1214f81ef50SGarrett Wollman 		break;
1224f81ef50SGarrett Wollman 	case IPPROTO_UDP:
123cfa1ca9dSYoshinobu Inoue #ifdef INET6
124cfa1ca9dSYoshinobu Inoue 		if (udp_done != 0)
125cfa1ca9dSYoshinobu Inoue 			return;
126cfa1ca9dSYoshinobu Inoue 		else
127cfa1ca9dSYoshinobu Inoue 			udp_done = 1;
128cfa1ca9dSYoshinobu Inoue #endif
1294f81ef50SGarrett Wollman 		mibvar = "net.inet.udp.pcblist";
1304f81ef50SGarrett Wollman 		break;
1314f81ef50SGarrett Wollman 	case IPPROTO_DIVERT:
1324f81ef50SGarrett Wollman 		mibvar = "net.inet.divert.pcblist";
1334f81ef50SGarrett Wollman 		break;
1344f81ef50SGarrett Wollman 	default:
1354f81ef50SGarrett Wollman 		mibvar = "net.inet.raw.pcblist";
1364f81ef50SGarrett Wollman 		break;
1374f81ef50SGarrett Wollman 	}
1384f81ef50SGarrett Wollman 	len = 0;
1394f81ef50SGarrett Wollman 	if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
1404f81ef50SGarrett Wollman 		if (errno != ENOENT)
1414f81ef50SGarrett Wollman 			warn("sysctl: %s", mibvar);
1429b50d902SRodney W. Grimes 		return;
1433aa80b1dSDavid Greenman 	}
1444f81ef50SGarrett Wollman 	if ((buf = malloc(len)) == 0) {
1454f81ef50SGarrett Wollman 		warn("malloc %lu bytes", (u_long)len);
1464f81ef50SGarrett Wollman 		return;
1479b50d902SRodney W. Grimes 	}
1484f81ef50SGarrett Wollman 	if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) {
1494f81ef50SGarrett Wollman 		warn("sysctl: %s", mibvar);
1504f81ef50SGarrett Wollman 		free(buf);
1514f81ef50SGarrett Wollman 		return;
1524f81ef50SGarrett Wollman 	}
1534f81ef50SGarrett Wollman 
1544f81ef50SGarrett Wollman 	oxig = xig = (struct xinpgen *)buf;
1554f81ef50SGarrett Wollman 	for (xig = (struct xinpgen *)((char *)xig + xig->xig_len);
1564f81ef50SGarrett Wollman 	     xig->xig_len > sizeof(struct xinpgen);
1574f81ef50SGarrett Wollman 	     xig = (struct xinpgen *)((char *)xig + xig->xig_len)) {
1589b50d902SRodney W. Grimes 		if (istcp) {
1594f81ef50SGarrett Wollman 			tp = &((struct xtcpcb *)xig)->xt_tp;
1604f81ef50SGarrett Wollman 			inp = &((struct xtcpcb *)xig)->xt_inp;
1614f81ef50SGarrett Wollman 			so = &((struct xtcpcb *)xig)->xt_socket;
1624f81ef50SGarrett Wollman 		} else {
1634f81ef50SGarrett Wollman 			inp = &((struct xinpcb *)xig)->xi_inp;
1644f81ef50SGarrett Wollman 			so = &((struct xinpcb *)xig)->xi_socket;
1659b50d902SRodney W. Grimes 		}
1664f81ef50SGarrett Wollman 
1674f81ef50SGarrett Wollman 		/* Ignore sockets for protocols other than the desired one. */
168f964d60dSAssar Westerlund 		if (so->xso_protocol != (int)proto)
1694f81ef50SGarrett Wollman 			continue;
1704f81ef50SGarrett Wollman 
1714f81ef50SGarrett Wollman 		/* Ignore PCBs which were freed during copyout. */
1724f81ef50SGarrett Wollman 		if (inp->inp_gencnt > oxig->xig_gen)
1734f81ef50SGarrett Wollman 			continue;
1744f81ef50SGarrett Wollman 
175a01e3379SDavid Malone 		if ((af1 == AF_INET && (inp->inp_vflag & INP_IPV4) == 0)
176cfa1ca9dSYoshinobu Inoue #ifdef INET6
177a01e3379SDavid Malone 		    || (af1 == AF_INET6 && (inp->inp_vflag & INP_IPV6) == 0)
178cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
179a01e3379SDavid Malone 		    || (af1 == AF_UNSPEC && ((inp->inp_vflag & INP_IPV4) == 0
180cfa1ca9dSYoshinobu Inoue #ifdef INET6
181cfa1ca9dSYoshinobu Inoue 					    && (inp->inp_vflag &
182cfa1ca9dSYoshinobu Inoue 						INP_IPV6) == 0
183cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
184cfa1ca9dSYoshinobu Inoue 			))
185cfa1ca9dSYoshinobu Inoue 		    )
186cfa1ca9dSYoshinobu Inoue 			continue;
187cfa1ca9dSYoshinobu Inoue 		if (!aflag &&
188cfa1ca9dSYoshinobu Inoue 		    (
1892b286cedSBruce M Simpson 		     (istcp && tp->t_state == TCPS_LISTEN)
1902b286cedSBruce M Simpson 		     || (af1 == AF_INET &&
191cfa1ca9dSYoshinobu Inoue 		      inet_lnaof(inp->inp_laddr) == INADDR_ANY)
192cfa1ca9dSYoshinobu Inoue #ifdef INET6
193a01e3379SDavid Malone 		     || (af1 == AF_INET6 &&
194cfa1ca9dSYoshinobu Inoue 			 IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
195cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
196a01e3379SDavid Malone 		     || (af1 == AF_UNSPEC &&
197cfa1ca9dSYoshinobu Inoue 			 (((inp->inp_vflag & INP_IPV4) != 0 &&
198cfa1ca9dSYoshinobu Inoue 			   inet_lnaof(inp->inp_laddr) == INADDR_ANY)
199cfa1ca9dSYoshinobu Inoue #ifdef INET6
200cfa1ca9dSYoshinobu Inoue 			  || ((inp->inp_vflag & INP_IPV6) != 0 &&
201cfa1ca9dSYoshinobu Inoue 			      IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
202cfa1ca9dSYoshinobu Inoue #endif
203cfa1ca9dSYoshinobu Inoue 			  ))
204cfa1ca9dSYoshinobu Inoue 		     ))
2054f81ef50SGarrett Wollman 			continue;
2064f81ef50SGarrett Wollman 
2079b50d902SRodney W. Grimes 		if (first) {
208ac55add0SGuido van Rooij 			if (!Lflag) {
2099b50d902SRodney W. Grimes 				printf("Active Internet connections");
2109b50d902SRodney W. Grimes 				if (aflag)
2119b50d902SRodney W. Grimes 					printf(" (including servers)");
212ac55add0SGuido van Rooij 			} else
213ac55add0SGuido van Rooij 				printf(
214ac55add0SGuido van Rooij 	"Current listen queue sizes (qlen/incqlen/maxqlen)");
2159b50d902SRodney W. Grimes 			putchar('\n');
2169b50d902SRodney W. Grimes 			if (Aflag)
2174f81ef50SGarrett Wollman 				printf("%-8.8s ", "Socket");
218ac55add0SGuido van Rooij 			if (Lflag)
219fb5d0fbdSRuslan Ermilov 				printf("%-5.5s %-14.14s %-22.22s\n",
220fb5d0fbdSRuslan Ermilov 					"Proto", "Listen", "Local Address");
221ac55add0SGuido van Rooij 			else
222080b7f49SDag-Erling Smørgrav 				printf((Aflag && !Wflag) ?
223cfa1ca9dSYoshinobu Inoue 		"%-5.5s %-6.6s %-6.6s  %-18.18s %-18.18s %s\n" :
224cfa1ca9dSYoshinobu Inoue 		"%-5.5s %-6.6s %-6.6s  %-22.22s %-22.22s %s\n",
2259b50d902SRodney W. Grimes 					"Proto", "Recv-Q", "Send-Q",
226ac55add0SGuido van Rooij 					"Local Address", "Foreign Address",
227ac55add0SGuido van Rooij 					"(state)");
2289b50d902SRodney W. Grimes 			first = 0;
2299b50d902SRodney W. Grimes 		}
230fb5d0fbdSRuslan Ermilov 		if (Lflag && so->so_qlimit == 0)
231fb5d0fbdSRuslan Ermilov 			continue;
232e4ec3989SDag-Erling Smørgrav 		if (Aflag) {
233e4ec3989SDag-Erling Smørgrav 			if (istcp)
234e4ec3989SDag-Erling Smørgrav 				printf("%8lx ", (u_long)inp->inp_ppcb);
235e4ec3989SDag-Erling Smørgrav 			else
2364f81ef50SGarrett Wollman 				printf("%8lx ", (u_long)so->so_pcb);
237e4ec3989SDag-Erling Smørgrav 		}
238cfa1ca9dSYoshinobu Inoue #ifdef INET6
239fc60ab7bSYoshinobu Inoue 		if ((inp->inp_vflag & INP_IPV6) != 0)
240fc60ab7bSYoshinobu Inoue 			vchar = ((inp->inp_vflag & INP_IPV4) != 0)
241fc60ab7bSYoshinobu Inoue 				? "46" : "6 ";
242fc60ab7bSYoshinobu Inoue 		else
243cfa1ca9dSYoshinobu Inoue #endif
244fc60ab7bSYoshinobu Inoue 		vchar = ((inp->inp_vflag & INP_IPV4) != 0)
245fc60ab7bSYoshinobu Inoue 				? "4 " : "  ";
246fb5d0fbdSRuslan Ermilov 		printf("%-3.3s%-2.2s ", name, vchar);
247fb5d0fbdSRuslan Ermilov 		if (Lflag) {
248a01e3379SDavid Malone 			char buf1[15];
249fc60ab7bSYoshinobu Inoue 
250a01e3379SDavid Malone 			snprintf(buf1, 15, "%d/%d/%d", so->so_qlen,
251fb5d0fbdSRuslan Ermilov 				 so->so_incqlen, so->so_qlimit);
252a01e3379SDavid Malone 			printf("%-14.14s ", buf1);
253fb5d0fbdSRuslan Ermilov 		} else {
254f824b518SJohn Polstra 			printf("%6u %6u  ",
255cfa1ca9dSYoshinobu Inoue 			       so->so_rcv.sb_cc,
2564f81ef50SGarrett Wollman 			       so->so_snd.sb_cc);
257fc60ab7bSYoshinobu Inoue 		}
25865ea0024SAssar Westerlund 		if (numeric_port) {
259cfa1ca9dSYoshinobu Inoue 			if (inp->inp_vflag & INP_IPV4) {
2604f81ef50SGarrett Wollman 				inetprint(&inp->inp_laddr, (int)inp->inp_lport,
2618d612dd2SPoul-Henning Kamp 					  name, 1);
262ac55add0SGuido van Rooij 				if (!Lflag)
263ac55add0SGuido van Rooij 					inetprint(&inp->inp_faddr,
264ac55add0SGuido van Rooij 						  (int)inp->inp_fport, name, 1);
265cfa1ca9dSYoshinobu Inoue 			}
266cfa1ca9dSYoshinobu Inoue #ifdef INET6
267cfa1ca9dSYoshinobu Inoue 			else if (inp->inp_vflag & INP_IPV6) {
268cfa1ca9dSYoshinobu Inoue 				inet6print(&inp->in6p_laddr,
269cfa1ca9dSYoshinobu Inoue 					   (int)inp->inp_lport, name, 1);
270ac55add0SGuido van Rooij 				if (!Lflag)
271cfa1ca9dSYoshinobu Inoue 					inet6print(&inp->in6p_faddr,
272cfa1ca9dSYoshinobu Inoue 						   (int)inp->inp_fport, name, 1);
273cfa1ca9dSYoshinobu Inoue 			} /* else nothing printed now */
274cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
2754f81ef50SGarrett Wollman 		} else if (inp->inp_flags & INP_ANONPORT) {
276cfa1ca9dSYoshinobu Inoue 			if (inp->inp_vflag & INP_IPV4) {
2774f81ef50SGarrett Wollman 				inetprint(&inp->inp_laddr, (int)inp->inp_lport,
2788d612dd2SPoul-Henning Kamp 					  name, 1);
279ac55add0SGuido van Rooij 				if (!Lflag)
280ac55add0SGuido van Rooij 					inetprint(&inp->inp_faddr,
281ac55add0SGuido van Rooij 						  (int)inp->inp_fport, name, 0);
282cfa1ca9dSYoshinobu Inoue 			}
283cfa1ca9dSYoshinobu Inoue #ifdef INET6
284cfa1ca9dSYoshinobu Inoue 			else if (inp->inp_vflag & INP_IPV6) {
285cfa1ca9dSYoshinobu Inoue 				inet6print(&inp->in6p_laddr,
286cfa1ca9dSYoshinobu Inoue 					   (int)inp->inp_lport, name, 1);
287ac55add0SGuido van Rooij 				if (!Lflag)
288cfa1ca9dSYoshinobu Inoue 					inet6print(&inp->in6p_faddr,
289cfa1ca9dSYoshinobu Inoue 						   (int)inp->inp_fport, name, 0);
290cfa1ca9dSYoshinobu Inoue 			} /* else nothing printed now */
291cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
2928d612dd2SPoul-Henning Kamp 		} else {
293cfa1ca9dSYoshinobu Inoue 			if (inp->inp_vflag & INP_IPV4) {
2944f81ef50SGarrett Wollman 				inetprint(&inp->inp_laddr, (int)inp->inp_lport,
2958d612dd2SPoul-Henning Kamp 					  name, 0);
296ac55add0SGuido van Rooij 				if (!Lflag)
297ac55add0SGuido van Rooij 					inetprint(&inp->inp_faddr,
298ac55add0SGuido van Rooij 						  (int)inp->inp_fport, name,
299ac55add0SGuido van Rooij 						  inp->inp_lport !=
300ac55add0SGuido van Rooij 							inp->inp_fport);
301cfa1ca9dSYoshinobu Inoue 			}
302cfa1ca9dSYoshinobu Inoue #ifdef INET6
303cfa1ca9dSYoshinobu Inoue 			else if (inp->inp_vflag & INP_IPV6) {
304cfa1ca9dSYoshinobu Inoue 				inet6print(&inp->in6p_laddr,
305cfa1ca9dSYoshinobu Inoue 					   (int)inp->inp_lport, name, 0);
306ac55add0SGuido van Rooij 				if (!Lflag)
307cfa1ca9dSYoshinobu Inoue 					inet6print(&inp->in6p_faddr,
308cfa1ca9dSYoshinobu Inoue 						   (int)inp->inp_fport, name,
309ac55add0SGuido van Rooij 						   inp->inp_lport !=
310ac55add0SGuido van Rooij 							inp->inp_fport);
311cfa1ca9dSYoshinobu Inoue 			} /* else nothing printed now */
312cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
3138d612dd2SPoul-Henning Kamp 		}
314ac55add0SGuido van Rooij 		if (istcp && !Lflag) {
3154f81ef50SGarrett Wollman 			if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES)
3164f81ef50SGarrett Wollman 				printf("%d", tp->t_state);
3179a94a597SGarrett Wollman                       else {
3184f81ef50SGarrett Wollman 				printf("%s", tcpstates[tp->t_state]);
319513822ddSAdam David #if defined(TF_NEEDSYN) && defined(TF_NEEDFIN)
3209a94a597SGarrett Wollman                               /* Show T/TCP `hidden state' */
3214f81ef50SGarrett Wollman                               if (tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN))
3229a94a597SGarrett Wollman                                       putchar('*');
323513822ddSAdam David #endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */
3249a94a597SGarrett Wollman                       }
3259b50d902SRodney W. Grimes 		}
3269b50d902SRodney W. Grimes 		putchar('\n');
3279b50d902SRodney W. Grimes 	}
3284f81ef50SGarrett Wollman 	if (xig != oxig && xig->xig_gen != oxig->xig_gen) {
3294f81ef50SGarrett Wollman 		if (oxig->xig_count > xig->xig_count) {
3304f81ef50SGarrett Wollman 			printf("Some %s sockets may have been deleted.\n",
3314f81ef50SGarrett Wollman 			       name);
3324f81ef50SGarrett Wollman 		} else if (oxig->xig_count < xig->xig_count) {
3334f81ef50SGarrett Wollman 			printf("Some %s sockets may have been created.\n",
3344f81ef50SGarrett Wollman 			       name);
3354f81ef50SGarrett Wollman 		} else {
336eb6fe0d9SMax Khon 			printf("Some %s sockets may have been created or deleted.\n",
3374f81ef50SGarrett Wollman 			       name);
3384f81ef50SGarrett Wollman 		}
3394f81ef50SGarrett Wollman 	}
3404f81ef50SGarrett Wollman 	free(buf);
3419b50d902SRodney W. Grimes }
3429b50d902SRodney W. Grimes 
3439b50d902SRodney W. Grimes /*
3449b50d902SRodney W. Grimes  * Dump TCP statistics structure.
3459b50d902SRodney W. Grimes  */
3469b50d902SRodney W. Grimes void
347a01e3379SDavid Malone tcp_stats(u_long off __unused, const char *name, int af1 __unused)
3489b50d902SRodney W. Grimes {
349c73d99b5SRuslan Ermilov 	struct tcpstat tcpstat, zerostat;
3504f81ef50SGarrett Wollman 	size_t len = sizeof tcpstat;
3519b50d902SRodney W. Grimes 
352c73d99b5SRuslan Ermilov 	if (zflag)
353c73d99b5SRuslan Ermilov 		memset(&zerostat, 0, len);
354c73d99b5SRuslan Ermilov 	if (sysctlbyname("net.inet.tcp.stats", &tcpstat, &len,
355c73d99b5SRuslan Ermilov 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
3564f81ef50SGarrett Wollman 		warn("sysctl: net.inet.tcp.stats");
3579b50d902SRodney W. Grimes 		return;
3584f81ef50SGarrett Wollman 	}
3594f81ef50SGarrett Wollman 
360cfa1ca9dSYoshinobu Inoue #ifdef INET6
361cfa1ca9dSYoshinobu Inoue 	if (tcp_done != 0)
362cfa1ca9dSYoshinobu Inoue 		return;
363cfa1ca9dSYoshinobu Inoue 	else
364cfa1ca9dSYoshinobu Inoue 		tcp_done = 1;
365cfa1ca9dSYoshinobu Inoue #endif
366cfa1ca9dSYoshinobu Inoue 
3679b50d902SRodney W. Grimes 	printf ("%s:\n", name);
3689b50d902SRodney W. Grimes 
3699b50d902SRodney W. Grimes #define	p(f, m) if (tcpstat.f || sflag <= 1) \
3709b50d902SRodney W. Grimes     printf(m, tcpstat.f, plural(tcpstat.f))
37122694ebaSBruce Evans #define	p1a(f, m) if (tcpstat.f || sflag <= 1) \
37222694ebaSBruce Evans     printf(m, tcpstat.f)
3739b50d902SRodney W. Grimes #define	p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
3749b50d902SRodney W. Grimes     printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2))
37522694ebaSBruce Evans #define	p2a(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
37622694ebaSBruce Evans     printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2)
3779b50d902SRodney W. Grimes #define	p3(f, m) if (tcpstat.f || sflag <= 1) \
3789b50d902SRodney W. Grimes     printf(m, tcpstat.f, plurales(tcpstat.f))
3799b50d902SRodney W. Grimes 
380e1fb4daaSPaul Traina 	p(tcps_sndtotal, "\t%lu packet%s sent\n");
3819b50d902SRodney W. Grimes 	p2(tcps_sndpack,tcps_sndbyte,
382e1fb4daaSPaul Traina 		"\t\t%lu data packet%s (%lu byte%s)\n");
3839b50d902SRodney W. Grimes 	p2(tcps_sndrexmitpack, tcps_sndrexmitbyte,
384e1fb4daaSPaul Traina 		"\t\t%lu data packet%s (%lu byte%s) retransmitted\n");
385d65bf08aSMatthew Dillon 	p(tcps_sndrexmitbad,
386d65bf08aSMatthew Dillon 		"\t\t%lu data packet%s unnecessarily retransmitted\n");
387e1fb4daaSPaul Traina 	p(tcps_mturesent, "\t\t%lu resend%s initiated by MTU discovery\n");
38822694ebaSBruce Evans 	p2a(tcps_sndacks, tcps_delack,
389e1fb4daaSPaul Traina 		"\t\t%lu ack-only packet%s (%lu delayed)\n");
390e1fb4daaSPaul Traina 	p(tcps_sndurg, "\t\t%lu URG only packet%s\n");
391e1fb4daaSPaul Traina 	p(tcps_sndprobe, "\t\t%lu window probe packet%s\n");
392e1fb4daaSPaul Traina 	p(tcps_sndwinup, "\t\t%lu window update packet%s\n");
393e1fb4daaSPaul Traina 	p(tcps_sndctrl, "\t\t%lu control packet%s\n");
394e1fb4daaSPaul Traina 	p(tcps_rcvtotal, "\t%lu packet%s received\n");
395e1fb4daaSPaul Traina 	p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%lu ack%s (for %lu byte%s)\n");
396e1fb4daaSPaul Traina 	p(tcps_rcvdupack, "\t\t%lu duplicate ack%s\n");
397e1fb4daaSPaul Traina 	p(tcps_rcvacktoomuch, "\t\t%lu ack%s for unsent data\n");
3989b50d902SRodney W. Grimes 	p2(tcps_rcvpack, tcps_rcvbyte,
399e1fb4daaSPaul Traina 		"\t\t%lu packet%s (%lu byte%s) received in-sequence\n");
4009b50d902SRodney W. Grimes 	p2(tcps_rcvduppack, tcps_rcvdupbyte,
401e1fb4daaSPaul Traina 		"\t\t%lu completely duplicate packet%s (%lu byte%s)\n");
402e1fb4daaSPaul Traina 	p(tcps_pawsdrop, "\t\t%lu old duplicate packet%s\n");
4039b50d902SRodney W. Grimes 	p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte,
404e1fb4daaSPaul Traina 		"\t\t%lu packet%s with some dup. data (%lu byte%s duped)\n");
4059b50d902SRodney W. Grimes 	p2(tcps_rcvoopack, tcps_rcvoobyte,
406e1fb4daaSPaul Traina 		"\t\t%lu out-of-order packet%s (%lu byte%s)\n");
4079b50d902SRodney W. Grimes 	p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin,
408e1fb4daaSPaul Traina 		"\t\t%lu packet%s (%lu byte%s) of data after window\n");
409e1fb4daaSPaul Traina 	p(tcps_rcvwinprobe, "\t\t%lu window probe%s\n");
410e1fb4daaSPaul Traina 	p(tcps_rcvwinupd, "\t\t%lu window update packet%s\n");
411e1fb4daaSPaul Traina 	p(tcps_rcvafterclose, "\t\t%lu packet%s received after close\n");
412e1fb4daaSPaul Traina 	p(tcps_rcvbadsum, "\t\t%lu discarded for bad checksum%s\n");
413e1fb4daaSPaul Traina 	p(tcps_rcvbadoff, "\t\t%lu discarded for bad header offset field%s\n");
41422694ebaSBruce Evans 	p1a(tcps_rcvshort, "\t\t%lu discarded because packet too short\n");
415e1fb4daaSPaul Traina 	p(tcps_connattempt, "\t%lu connection request%s\n");
416e1fb4daaSPaul Traina 	p(tcps_accepts, "\t%lu connection accept%s\n");
417e1fb4daaSPaul Traina 	p(tcps_badsyn, "\t%lu bad connection attempt%s\n");
418e1fb4daaSPaul Traina 	p(tcps_listendrop, "\t%lu listen queue overflow%s\n");
41901d3e1c0SRuslan Ermilov 	p(tcps_badrst, "\t%lu ignored RSTs in the window%s\n");
420e1fb4daaSPaul Traina 	p(tcps_connects, "\t%lu connection%s established (including accepts)\n");
4219b50d902SRodney W. Grimes 	p2(tcps_closed, tcps_drops,
422e1fb4daaSPaul Traina 		"\t%lu connection%s closed (including %lu drop%s)\n");
423e1fb4daaSPaul Traina 	p(tcps_cachedrtt, "\t\t%lu connection%s updated cached RTT on close\n");
424861b1828SGarrett Wollman 	p(tcps_cachedrttvar,
425e1fb4daaSPaul Traina 	  "\t\t%lu connection%s updated cached RTT variance on close\n");
426861b1828SGarrett Wollman 	p(tcps_cachedssthresh,
427e1fb4daaSPaul Traina 	  "\t\t%lu connection%s updated cached ssthresh on close\n");
428e1fb4daaSPaul Traina 	p(tcps_conndrops, "\t%lu embryonic connection%s dropped\n");
4299b50d902SRodney W. Grimes 	p2(tcps_rttupdated, tcps_segstimed,
430e1fb4daaSPaul Traina 		"\t%lu segment%s updated rtt (of %lu attempt%s)\n");
431e1fb4daaSPaul Traina 	p(tcps_rexmttimeo, "\t%lu retransmit timeout%s\n");
432e1fb4daaSPaul Traina 	p(tcps_timeoutdrop, "\t\t%lu connection%s dropped by rexmit timeout\n");
433e1fb4daaSPaul Traina 	p(tcps_persisttimeo, "\t%lu persist timeout%s\n");
434e1fb4daaSPaul Traina 	p(tcps_persistdrop, "\t\t%lu connection%s dropped by persist timeout\n");
435e1fb4daaSPaul Traina 	p(tcps_keeptimeo, "\t%lu keepalive timeout%s\n");
436e1fb4daaSPaul Traina 	p(tcps_keepprobe, "\t\t%lu keepalive probe%s sent\n");
437e1fb4daaSPaul Traina 	p(tcps_keepdrops, "\t\t%lu connection%s dropped by keepalive\n");
438e1fb4daaSPaul Traina 	p(tcps_predack, "\t%lu correct ACK header prediction%s\n");
439e1fb4daaSPaul Traina 	p(tcps_preddat, "\t%lu correct data packet header prediction%s\n");
44060a31b3aSJonathan Lemon 
441a01e3379SDavid Malone 	p(tcps_sc_added, "\t%lu syncache entrie%s added\n");
442a01e3379SDavid Malone 	p1a(tcps_sc_retransmitted, "\t\t%lu retransmitted\n");
443a01e3379SDavid Malone 	p1a(tcps_sc_dupsyn, "\t\t%lu dupsyn\n");
444a01e3379SDavid Malone 	p1a(tcps_sc_dropped, "\t\t%lu dropped\n");
445a01e3379SDavid Malone 	p1a(tcps_sc_completed, "\t\t%lu completed\n");
446a01e3379SDavid Malone 	p1a(tcps_sc_bucketoverflow, "\t\t%lu bucket overflow\n");
447a01e3379SDavid Malone 	p1a(tcps_sc_cacheoverflow, "\t\t%lu cache overflow\n");
448a01e3379SDavid Malone 	p1a(tcps_sc_reset, "\t\t%lu reset\n");
449a01e3379SDavid Malone 	p1a(tcps_sc_stale, "\t\t%lu stale\n");
450a01e3379SDavid Malone 	p1a(tcps_sc_aborted, "\t\t%lu aborted\n");
451a01e3379SDavid Malone 	p1a(tcps_sc_badack, "\t\t%lu badack\n");
452a01e3379SDavid Malone 	p1a(tcps_sc_unreach, "\t\t%lu unreach\n");
453a01e3379SDavid Malone 	p(tcps_sc_zonefail, "\t\t%lu zone failure%s\n");
454a01e3379SDavid Malone 	p(tcps_sc_sendcookie, "\t%lu cookie%s sent\n");
455a01e3379SDavid Malone 	p(tcps_sc_recvcookie, "\t%lu cookie%s received\n");
456b6101dafSPaul Saab 
457b6101dafSPaul Saab 	p(tcps_sack_recovery_episode, "\t%lu SACK recovery episode%s\n");
458b6101dafSPaul Saab 	p(tcps_sack_rexmits,
459b6101dafSPaul Saab 		"\t%lu segment rexmit%s in SACK recovery episodes\n");
460b6101dafSPaul Saab 	p(tcps_sack_rexmit_bytes,
461b6101dafSPaul Saab 		"\t%lu byte rexmit%s in SACK recovery episodes\n");
462b6101dafSPaul Saab 	p(tcps_sack_rcv_blocks,
463b6101dafSPaul Saab 		"\t%lu SACK option%s (SACK blocks) received\n");
464b6101dafSPaul Saab 	p(tcps_sack_send_blocks, "\t%lu SACK option%s (SACK blocks) sent\n");
465b6101dafSPaul Saab 
4669b50d902SRodney W. Grimes #undef p
46722694ebaSBruce Evans #undef p1a
4689b50d902SRodney W. Grimes #undef p2
46922694ebaSBruce Evans #undef p2a
4709b50d902SRodney W. Grimes #undef p3
4719b50d902SRodney W. Grimes }
4729b50d902SRodney W. Grimes 
4739b50d902SRodney W. Grimes /*
4749b50d902SRodney W. Grimes  * Dump UDP statistics structure.
4759b50d902SRodney W. Grimes  */
4769b50d902SRodney W. Grimes void
477a01e3379SDavid Malone udp_stats(u_long off __unused, const char *name, int af1 __unused)
4789b50d902SRodney W. Grimes {
479c73d99b5SRuslan Ermilov 	struct udpstat udpstat, zerostat;
4804f81ef50SGarrett Wollman 	size_t len = sizeof udpstat;
4819b50d902SRodney W. Grimes 	u_long delivered;
4829b50d902SRodney W. Grimes 
483c73d99b5SRuslan Ermilov 	if (zflag)
484c73d99b5SRuslan Ermilov 		memset(&zerostat, 0, len);
485c73d99b5SRuslan Ermilov 	if (sysctlbyname("net.inet.udp.stats", &udpstat, &len,
486c73d99b5SRuslan Ermilov 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
4874f81ef50SGarrett Wollman 		warn("sysctl: net.inet.udp.stats");
4889b50d902SRodney W. Grimes 		return;
4894f81ef50SGarrett Wollman 	}
4904f81ef50SGarrett Wollman 
491cfa1ca9dSYoshinobu Inoue #ifdef INET6
492cfa1ca9dSYoshinobu Inoue 	if (udp_done != 0)
493cfa1ca9dSYoshinobu Inoue 		return;
494cfa1ca9dSYoshinobu Inoue 	else
495cfa1ca9dSYoshinobu Inoue 		udp_done = 1;
496cfa1ca9dSYoshinobu Inoue #endif
497cfa1ca9dSYoshinobu Inoue 
4989b50d902SRodney W. Grimes 	printf("%s:\n", name);
4999b50d902SRodney W. Grimes #define	p(f, m) if (udpstat.f || sflag <= 1) \
5009b50d902SRodney W. Grimes     printf(m, udpstat.f, plural(udpstat.f))
50122694ebaSBruce Evans #define	p1a(f, m) if (udpstat.f || sflag <= 1) \
50222694ebaSBruce Evans     printf(m, udpstat.f)
5037d56c0eeSAlexander Langer 	p(udps_ipackets, "\t%lu datagram%s received\n");
50422694ebaSBruce Evans 	p1a(udps_hdrops, "\t%lu with incomplete header\n");
50522694ebaSBruce Evans 	p1a(udps_badlen, "\t%lu with bad data length field\n");
50622694ebaSBruce Evans 	p1a(udps_badsum, "\t%lu with bad checksum\n");
507fb9aaba0SRuslan Ermilov 	p1a(udps_nosum, "\t%lu with no checksum\n");
50822694ebaSBruce Evans 	p1a(udps_noport, "\t%lu dropped due to no socket\n");
50922694ebaSBruce Evans 	p(udps_noportbcast,
51022694ebaSBruce Evans 	    "\t%lu broadcast/multicast datagram%s dropped due to no socket\n");
51122694ebaSBruce Evans 	p1a(udps_fullsock, "\t%lu dropped due to full socket buffers\n");
51222694ebaSBruce Evans 	p1a(udpps_pcbhashmiss, "\t%lu not for hashed pcb\n");
5139b50d902SRodney W. Grimes 	delivered = udpstat.udps_ipackets -
5149b50d902SRodney W. Grimes 		    udpstat.udps_hdrops -
5159b50d902SRodney W. Grimes 		    udpstat.udps_badlen -
5169b50d902SRodney W. Grimes 		    udpstat.udps_badsum -
5179b50d902SRodney W. Grimes 		    udpstat.udps_noport -
5189b50d902SRodney W. Grimes 		    udpstat.udps_noportbcast -
5199b50d902SRodney W. Grimes 		    udpstat.udps_fullsock;
5209b50d902SRodney W. Grimes 	if (delivered || sflag <= 1)
5217d56c0eeSAlexander Langer 		printf("\t%lu delivered\n", delivered);
5227d56c0eeSAlexander Langer 	p(udps_opackets, "\t%lu datagram%s output\n");
5239b50d902SRodney W. Grimes #undef p
52422694ebaSBruce Evans #undef p1a
5259b50d902SRodney W. Grimes }
5269b50d902SRodney W. Grimes 
5279b50d902SRodney W. Grimes /*
5289b50d902SRodney W. Grimes  * Dump IP statistics structure.
5299b50d902SRodney W. Grimes  */
5309b50d902SRodney W. Grimes void
531a01e3379SDavid Malone ip_stats(u_long off __unused, const char *name, int af1 __unused)
5329b50d902SRodney W. Grimes {
533c73d99b5SRuslan Ermilov 	struct ipstat ipstat, zerostat;
5344f81ef50SGarrett Wollman 	size_t len = sizeof ipstat;
5359b50d902SRodney W. Grimes 
536c73d99b5SRuslan Ermilov 	if (zflag)
537c73d99b5SRuslan Ermilov 		memset(&zerostat, 0, len);
538c73d99b5SRuslan Ermilov 	if (sysctlbyname("net.inet.ip.stats", &ipstat, &len,
539c73d99b5SRuslan Ermilov 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
5404f81ef50SGarrett Wollman 		warn("sysctl: net.inet.ip.stats");
5419b50d902SRodney W. Grimes 		return;
5424f81ef50SGarrett Wollman 	}
5434f81ef50SGarrett Wollman 
5449b50d902SRodney W. Grimes 	printf("%s:\n", name);
5459b50d902SRodney W. Grimes 
5469b50d902SRodney W. Grimes #define	p(f, m) if (ipstat.f || sflag <= 1) \
5479b50d902SRodney W. Grimes     printf(m, ipstat.f, plural(ipstat.f))
54822694ebaSBruce Evans #define	p1a(f, m) if (ipstat.f || sflag <= 1) \
54922694ebaSBruce Evans     printf(m, ipstat.f)
5509b50d902SRodney W. Grimes 
5517d56c0eeSAlexander Langer 	p(ips_total, "\t%lu total packet%s received\n");
5527d56c0eeSAlexander Langer 	p(ips_badsum, "\t%lu bad header checksum%s\n");
55322694ebaSBruce Evans 	p1a(ips_toosmall, "\t%lu with size smaller than minimum\n");
55422694ebaSBruce Evans 	p1a(ips_tooshort, "\t%lu with data size < data length\n");
555cfa1ca9dSYoshinobu Inoue 	p1a(ips_toolong, "\t%lu with ip length > max ip packet size\n");
55622694ebaSBruce Evans 	p1a(ips_badhlen, "\t%lu with header length < data size\n");
55722694ebaSBruce Evans 	p1a(ips_badlen, "\t%lu with data length < header length\n");
55822694ebaSBruce Evans 	p1a(ips_badoptions, "\t%lu with bad options\n");
55922694ebaSBruce Evans 	p1a(ips_badvers, "\t%lu with incorrect version number\n");
5607d56c0eeSAlexander Langer 	p(ips_fragments, "\t%lu fragment%s received\n");
5617d56c0eeSAlexander Langer 	p(ips_fragdropped, "\t%lu fragment%s dropped (dup or out of space)\n");
5627d56c0eeSAlexander Langer 	p(ips_fragtimeout, "\t%lu fragment%s dropped after timeout\n");
5637d56c0eeSAlexander Langer 	p(ips_reassembled, "\t%lu packet%s reassembled ok\n");
5647d56c0eeSAlexander Langer 	p(ips_delivered, "\t%lu packet%s for this host\n");
5657d56c0eeSAlexander Langer 	p(ips_noproto, "\t%lu packet%s for unknown/unsupported protocol\n");
566958d6f7fSPierre Beyssac 	p(ips_forward, "\t%lu packet%s forwarded");
567958d6f7fSPierre Beyssac 	p(ips_fastforward, " (%lu packet%s fast forwarded)");
568958d6f7fSPierre Beyssac 	if (ipstat.ips_forward || sflag <= 1)
569958d6f7fSPierre Beyssac 		putchar('\n');
5707d56c0eeSAlexander Langer 	p(ips_cantforward, "\t%lu packet%s not forwardable\n");
571a5969f5fSGarrett Wollman 	p(ips_notmember,
572a5969f5fSGarrett Wollman 	  "\t%lu packet%s received for unknown multicast group\n");
5737d56c0eeSAlexander Langer 	p(ips_redirectsent, "\t%lu redirect%s sent\n");
5747d56c0eeSAlexander Langer 	p(ips_localout, "\t%lu packet%s sent from this host\n");
5757d56c0eeSAlexander Langer 	p(ips_rawout, "\t%lu packet%s sent with fabricated ip header\n");
576a5969f5fSGarrett Wollman 	p(ips_odropped,
577a5969f5fSGarrett Wollman 	  "\t%lu output packet%s dropped due to no bufs, etc.\n");
5787d56c0eeSAlexander Langer 	p(ips_noroute, "\t%lu output packet%s discarded due to no route\n");
5797d56c0eeSAlexander Langer 	p(ips_fragmented, "\t%lu output datagram%s fragmented\n");
5807d56c0eeSAlexander Langer 	p(ips_ofragments, "\t%lu fragment%s created\n");
5817d56c0eeSAlexander Langer 	p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n");
582cfa1ca9dSYoshinobu Inoue 	p(ips_nogif, "\t%lu tunneling packet%s that can't find gif\n");
58333841545SHajimu UMEMOTO 	p(ips_badaddr, "\t%lu datagram%s with bad address in header\n");
5849b50d902SRodney W. Grimes #undef p
58522694ebaSBruce Evans #undef p1a
5869b50d902SRodney W. Grimes }
5879b50d902SRodney W. Grimes 
588a01e3379SDavid Malone static	const char *icmpnames[] = {
5899b50d902SRodney W. Grimes 	"echo reply",
5909b50d902SRodney W. Grimes 	"#1",
5919b50d902SRodney W. Grimes 	"#2",
5929b50d902SRodney W. Grimes 	"destination unreachable",
5939b50d902SRodney W. Grimes 	"source quench",
5949b50d902SRodney W. Grimes 	"routing redirect",
5959b50d902SRodney W. Grimes 	"#6",
5969b50d902SRodney W. Grimes 	"#7",
5979b50d902SRodney W. Grimes 	"echo",
5987b46dd00SGarrett Wollman 	"router advertisement",
5997b46dd00SGarrett Wollman 	"router solicitation",
6009b50d902SRodney W. Grimes 	"time exceeded",
6019b50d902SRodney W. Grimes 	"parameter problem",
6029b50d902SRodney W. Grimes 	"time stamp",
6039b50d902SRodney W. Grimes 	"time stamp reply",
6049b50d902SRodney W. Grimes 	"information request",
6059b50d902SRodney W. Grimes 	"information request reply",
6069b50d902SRodney W. Grimes 	"address mask request",
6079b50d902SRodney W. Grimes 	"address mask reply",
6089b50d902SRodney W. Grimes };
6099b50d902SRodney W. Grimes 
6109b50d902SRodney W. Grimes /*
6119b50d902SRodney W. Grimes  * Dump ICMP statistics.
6129b50d902SRodney W. Grimes  */
6139b50d902SRodney W. Grimes void
614a01e3379SDavid Malone icmp_stats(u_long off __unused, const char *name, int af1 __unused)
6159b50d902SRodney W. Grimes {
616c73d99b5SRuslan Ermilov 	struct icmpstat icmpstat, zerostat;
6174e00c309SGarrett Wollman 	int i, first;
6184e00c309SGarrett Wollman 	int mib[4];		/* CTL_NET + PF_INET + IPPROTO_ICMP + req */
6194e00c309SGarrett Wollman 	size_t len;
6209b50d902SRodney W. Grimes 
6214e00c309SGarrett Wollman 	mib[0] = CTL_NET;
6224e00c309SGarrett Wollman 	mib[1] = PF_INET;
6234e00c309SGarrett Wollman 	mib[2] = IPPROTO_ICMP;
6244e00c309SGarrett Wollman 	mib[3] = ICMPCTL_STATS;
6254e00c309SGarrett Wollman 
6264e00c309SGarrett Wollman 	len = sizeof icmpstat;
627c73d99b5SRuslan Ermilov 	if (zflag)
628c73d99b5SRuslan Ermilov 		memset(&zerostat, 0, len);
629c73d99b5SRuslan Ermilov 	if (sysctl(mib, 4, &icmpstat, &len,
630c73d99b5SRuslan Ermilov 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
631c73d99b5SRuslan Ermilov 		warn("sysctl: net.inet.icmp.stats");
632c73d99b5SRuslan Ermilov 		return;
633c73d99b5SRuslan Ermilov 	}
6344e00c309SGarrett Wollman 
6359b50d902SRodney W. Grimes 	printf("%s:\n", name);
6369b50d902SRodney W. Grimes 
6379b50d902SRodney W. Grimes #define	p(f, m) if (icmpstat.f || sflag <= 1) \
6389b50d902SRodney W. Grimes     printf(m, icmpstat.f, plural(icmpstat.f))
63922694ebaSBruce Evans #define	p1a(f, m) if (icmpstat.f || sflag <= 1) \
64022694ebaSBruce Evans     printf(m, icmpstat.f)
641bd714208SRuslan Ermilov #define	p2(f, m) if (icmpstat.f || sflag <= 1) \
642bd714208SRuslan Ermilov     printf(m, icmpstat.f, plurales(icmpstat.f))
6439b50d902SRodney W. Grimes 
6447d56c0eeSAlexander Langer 	p(icps_error, "\t%lu call%s to icmp_error\n");
6459b50d902SRodney W. Grimes 	p(icps_oldicmp,
646f99a4046SMike Makonnen 	    "\t%lu error%s not generated in response to an icmp message\n");
6479b50d902SRodney W. Grimes 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
6489b50d902SRodney W. Grimes 		if (icmpstat.icps_outhist[i] != 0) {
6499b50d902SRodney W. Grimes 			if (first) {
6509b50d902SRodney W. Grimes 				printf("\tOutput histogram:\n");
6519b50d902SRodney W. Grimes 				first = 0;
6529b50d902SRodney W. Grimes 			}
6537d56c0eeSAlexander Langer 			printf("\t\t%s: %lu\n", icmpnames[i],
6549b50d902SRodney W. Grimes 				icmpstat.icps_outhist[i]);
6559b50d902SRodney W. Grimes 		}
6567d56c0eeSAlexander Langer 	p(icps_badcode, "\t%lu message%s with bad code fields\n");
6577d56c0eeSAlexander Langer 	p(icps_tooshort, "\t%lu message%s < minimum length\n");
6587d56c0eeSAlexander Langer 	p(icps_checksum, "\t%lu bad checksum%s\n");
6597d56c0eeSAlexander Langer 	p(icps_badlen, "\t%lu message%s with bad length\n");
66022694ebaSBruce Evans 	p1a(icps_bmcastecho, "\t%lu multicast echo requests ignored\n");
66122694ebaSBruce Evans 	p1a(icps_bmcasttstamp, "\t%lu multicast timestamp requests ignored\n");
6629b50d902SRodney W. Grimes 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
6639b50d902SRodney W. Grimes 		if (icmpstat.icps_inhist[i] != 0) {
6649b50d902SRodney W. Grimes 			if (first) {
6659b50d902SRodney W. Grimes 				printf("\tInput histogram:\n");
6669b50d902SRodney W. Grimes 				first = 0;
6679b50d902SRodney W. Grimes 			}
6687d56c0eeSAlexander Langer 			printf("\t\t%s: %lu\n", icmpnames[i],
6699b50d902SRodney W. Grimes 				icmpstat.icps_inhist[i]);
6709b50d902SRodney W. Grimes 		}
6717d56c0eeSAlexander Langer 	p(icps_reflect, "\t%lu message response%s generated\n");
672bd714208SRuslan Ermilov 	p2(icps_badaddr, "\t%lu invalid return address%s\n");
6730237ca7bSRuslan Ermilov 	p(icps_noroute, "\t%lu no return route%s\n");
6749b50d902SRodney W. Grimes #undef p
67522694ebaSBruce Evans #undef p1a
676bd714208SRuslan Ermilov #undef p2
6774e00c309SGarrett Wollman 	mib[3] = ICMPCTL_MASKREPL;
6784e00c309SGarrett Wollman 	len = sizeof i;
6794e00c309SGarrett Wollman 	if (sysctl(mib, 4, &i, &len, (void *)0, 0) < 0)
6804e00c309SGarrett Wollman 		return;
6814e00c309SGarrett Wollman 	printf("\tICMP address mask responses are %sabled\n",
6824e00c309SGarrett Wollman 	       i ? "en" : "dis");
6839b50d902SRodney W. Grimes }
6849b50d902SRodney W. Grimes 
6859b50d902SRodney W. Grimes /*
6869b50d902SRodney W. Grimes  * Dump IGMP statistics structure.
6879b50d902SRodney W. Grimes  */
6889b50d902SRodney W. Grimes void
689a01e3379SDavid Malone igmp_stats(u_long off __unused, const char *name, int af1 __unused)
6909b50d902SRodney W. Grimes {
691c73d99b5SRuslan Ermilov 	struct igmpstat igmpstat, zerostat;
6924f81ef50SGarrett Wollman 	size_t len = sizeof igmpstat;
6939b50d902SRodney W. Grimes 
694c73d99b5SRuslan Ermilov 	if (zflag)
695c73d99b5SRuslan Ermilov 		memset(&zerostat, 0, len);
696c73d99b5SRuslan Ermilov 	if (sysctlbyname("net.inet.igmp.stats", &igmpstat, &len,
697c73d99b5SRuslan Ermilov 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
6984f81ef50SGarrett Wollman 		warn("sysctl: net.inet.igmp.stats");
6999b50d902SRodney W. Grimes 		return;
7004f81ef50SGarrett Wollman 	}
7014f81ef50SGarrett Wollman 
7029b50d902SRodney W. Grimes 	printf("%s:\n", name);
7039b50d902SRodney W. Grimes 
7049b50d902SRodney W. Grimes #define	p(f, m) if (igmpstat.f || sflag <= 1) \
7059b50d902SRodney W. Grimes     printf(m, igmpstat.f, plural(igmpstat.f))
7069b50d902SRodney W. Grimes #define	py(f, m) if (igmpstat.f || sflag <= 1) \
7079b50d902SRodney W. Grimes     printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y")
7089b50d902SRodney W. Grimes 	p(igps_rcv_total, "\t%u message%s received\n");
7099b50d902SRodney W. Grimes         p(igps_rcv_tooshort, "\t%u message%s received with too few bytes\n");
7109b50d902SRodney W. Grimes         p(igps_rcv_badsum, "\t%u message%s received with bad checksum\n");
7119b50d902SRodney W. Grimes         py(igps_rcv_queries, "\t%u membership quer%s received\n");
7129b50d902SRodney W. Grimes         py(igps_rcv_badqueries, "\t%u membership quer%s received with invalid field(s)\n");
7139b50d902SRodney W. Grimes         p(igps_rcv_reports, "\t%u membership report%s received\n");
7149b50d902SRodney W. Grimes         p(igps_rcv_badreports, "\t%u membership report%s received with invalid field(s)\n");
7159b50d902SRodney W. Grimes         p(igps_rcv_ourreports, "\t%u membership report%s received for groups to which we belong\n");
7169b50d902SRodney W. Grimes         p(igps_snd_reports, "\t%u membership report%s sent\n");
7179b50d902SRodney W. Grimes #undef p
7189b50d902SRodney W. Grimes #undef py
7199b50d902SRodney W. Grimes }
7209b50d902SRodney W. Grimes 
7219b50d902SRodney W. Grimes /*
722c7b9b5bbSJeffrey Hsu  * Dump PIM statistics structure.
723c7b9b5bbSJeffrey Hsu  */
724c7b9b5bbSJeffrey Hsu void
725c7b9b5bbSJeffrey Hsu pim_stats(u_long off __unused, const char *name, int af1 __unused)
726c7b9b5bbSJeffrey Hsu {
727c7b9b5bbSJeffrey Hsu 	struct pimstat pimstat, zerostat;
728c7b9b5bbSJeffrey Hsu 	size_t len = sizeof pimstat;
729c7b9b5bbSJeffrey Hsu 
730c7b9b5bbSJeffrey Hsu 	if (zflag)
731c7b9b5bbSJeffrey Hsu 		memset(&zerostat, 0, len);
732c7b9b5bbSJeffrey Hsu 	if (sysctlbyname("net.inet.pim.stats", &pimstat, &len,
733c7b9b5bbSJeffrey Hsu 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
7346d7c0d2fSDag-Erling Smørgrav 		if (errno != ENOENT)
735c7b9b5bbSJeffrey Hsu 			warn("sysctl: net.inet.pim.stats");
736c7b9b5bbSJeffrey Hsu 		return;
737c7b9b5bbSJeffrey Hsu 	}
738c7b9b5bbSJeffrey Hsu 
739c7b9b5bbSJeffrey Hsu 	printf("%s:\n", name);
740c7b9b5bbSJeffrey Hsu 
741c7b9b5bbSJeffrey Hsu #define	p(f, m) if (pimstat.f || sflag <= 1) \
742c7b9b5bbSJeffrey Hsu     printf(m, pimstat.f, plural(pimstat.f))
743c7b9b5bbSJeffrey Hsu #define	py(f, m) if (pimstat.f || sflag <= 1) \
744c7b9b5bbSJeffrey Hsu     printf(m, pimstat.f, pimstat.f != 1 ? "ies" : "y")
745c7b9b5bbSJeffrey Hsu 	p(pims_rcv_total_msgs, "\t%llu message%s received\n");
746c7b9b5bbSJeffrey Hsu 	p(pims_rcv_total_bytes, "\t%llu byte%s received\n");
747c7b9b5bbSJeffrey Hsu 	p(pims_rcv_tooshort, "\t%llu message%s received with too few bytes\n");
748c7b9b5bbSJeffrey Hsu         p(pims_rcv_badsum, "\t%llu message%s received with bad checksum\n");
749c7b9b5bbSJeffrey Hsu 	p(pims_rcv_badversion, "\t%llu message%s received with bad version\n");
750c7b9b5bbSJeffrey Hsu 	p(pims_rcv_registers_msgs, "\t%llu data register message%s received\n");
751c7b9b5bbSJeffrey Hsu 	p(pims_rcv_registers_bytes, "\t%llu data register byte%s received\n");
752c7b9b5bbSJeffrey Hsu 	p(pims_rcv_registers_wrongiif, "\t%llu data register message%s received on wrong iif\n");
753c7b9b5bbSJeffrey Hsu 	p(pims_rcv_badregisters, "\t%llu bad register%s received\n");
754c7b9b5bbSJeffrey Hsu 	p(pims_snd_registers_msgs, "\t%llu data register message%s sent\n");
755c7b9b5bbSJeffrey Hsu 	p(pims_snd_registers_bytes, "\t%llu data register byte%s sent\n");
756c7b9b5bbSJeffrey Hsu #undef p
757c7b9b5bbSJeffrey Hsu #undef py
758c7b9b5bbSJeffrey Hsu }
759c7b9b5bbSJeffrey Hsu 
760c7b9b5bbSJeffrey Hsu /*
7619b50d902SRodney W. Grimes  * Pretty print an Internet address (net address + port).
7629b50d902SRodney W. Grimes  */
7639b50d902SRodney W. Grimes void
764a01e3379SDavid Malone inetprint(struct in_addr *in, int port, const char *proto, int num_port)
7659b50d902SRodney W. Grimes {
7669b50d902SRodney W. Grimes 	struct servent *sp = 0;
7679b50d902SRodney W. Grimes 	char line[80], *cp;
768cfa1ca9dSYoshinobu Inoue 	int width;
7699b50d902SRodney W. Grimes 
770080b7f49SDag-Erling Smørgrav 	if (Wflag)
771080b7f49SDag-Erling Smørgrav 	    sprintf(line, "%s.", inetname(in));
772080b7f49SDag-Erling Smørgrav 	else
773a01e3379SDavid Malone 	    sprintf(line, "%.*s.", (Aflag && !num_port) ? 12 : 16, inetname(in));
7749b50d902SRodney W. Grimes 	cp = index(line, '\0');
775a01e3379SDavid Malone 	if (!num_port && port)
7769b50d902SRodney W. Grimes 		sp = getservbyport((int)port, proto);
7779b50d902SRodney W. Grimes 	if (sp || port == 0)
7781ef69972SAndrey A. Chernov 		sprintf(cp, "%.15s ", sp ? sp->s_name : "*");
7799b50d902SRodney W. Grimes 	else
7809b50d902SRodney W. Grimes 		sprintf(cp, "%d ", ntohs((u_short)port));
781080b7f49SDag-Erling Smørgrav 	width = (Aflag && !Wflag) ? 18 : 22;
782080b7f49SDag-Erling Smørgrav 	if (Wflag)
783080b7f49SDag-Erling Smørgrav 	    printf("%-*s ", width, line);
784080b7f49SDag-Erling Smørgrav 	else
785cfa1ca9dSYoshinobu Inoue 	    printf("%-*.*s ", width, width, line);
7869b50d902SRodney W. Grimes }
7879b50d902SRodney W. Grimes 
7889b50d902SRodney W. Grimes /*
7899b50d902SRodney W. Grimes  * Construct an Internet address representation.
79065ea0024SAssar Westerlund  * If numeric_addr has been supplied, give
7919b50d902SRodney W. Grimes  * numeric value, otherwise try for symbolic name.
7929b50d902SRodney W. Grimes  */
7939b50d902SRodney W. Grimes char *
7945e051718SAssar Westerlund inetname(struct in_addr *inp)
7959b50d902SRodney W. Grimes {
796a01e3379SDavid Malone 	char *cp;
797d121b556SBrian Somers 	static char line[MAXHOSTNAMELEN];
7989b50d902SRodney W. Grimes 	struct hostent *hp;
7999b50d902SRodney W. Grimes 	struct netent *np;
8009b50d902SRodney W. Grimes 
8019b50d902SRodney W. Grimes 	cp = 0;
80265ea0024SAssar Westerlund 	if (!numeric_addr && inp->s_addr != INADDR_ANY) {
8039b50d902SRodney W. Grimes 		int net = inet_netof(*inp);
8049b50d902SRodney W. Grimes 		int lna = inet_lnaof(*inp);
8059b50d902SRodney W. Grimes 
8069b50d902SRodney W. Grimes 		if (lna == INADDR_ANY) {
8079b50d902SRodney W. Grimes 			np = getnetbyaddr(net, AF_INET);
8089b50d902SRodney W. Grimes 			if (np)
8099b50d902SRodney W. Grimes 				cp = np->n_name;
8109b50d902SRodney W. Grimes 		}
8119b50d902SRodney W. Grimes 		if (cp == 0) {
8129b50d902SRodney W. Grimes 			hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET);
8139b50d902SRodney W. Grimes 			if (hp) {
8149b50d902SRodney W. Grimes 				cp = hp->h_name;
815d121b556SBrian Somers 				trimdomain(cp, strlen(cp));
8169b50d902SRodney W. Grimes 			}
8179b50d902SRodney W. Grimes 		}
8189b50d902SRodney W. Grimes 	}
8199b50d902SRodney W. Grimes 	if (inp->s_addr == INADDR_ANY)
8209b50d902SRodney W. Grimes 		strcpy(line, "*");
8219a1f6729SWarner Losh 	else if (cp) {
8229a1f6729SWarner Losh 		strncpy(line, cp, sizeof(line) - 1);
8239a1f6729SWarner Losh 		line[sizeof(line) - 1] = '\0';
8249a1f6729SWarner Losh 	} else {
8259b50d902SRodney W. Grimes 		inp->s_addr = ntohl(inp->s_addr);
82622694ebaSBruce Evans #define C(x)	((u_int)((x) & 0xff))
82722694ebaSBruce Evans 		sprintf(line, "%u.%u.%u.%u", C(inp->s_addr >> 24),
8289b50d902SRodney W. Grimes 		    C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr));
8299b50d902SRodney W. Grimes 	}
8309b50d902SRodney W. Grimes 	return (line);
8319b50d902SRodney W. Grimes }
832