xref: /freebsd/usr.bin/netstat/inet.c (revision a01e3379df7c510218ec793cf6f288ac4aac6487)
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>
619b50d902SRodney W. Grimes #include <netinet/tcp.h>
629b50d902SRodney W. Grimes #include <netinet/tcpip.h>
639b50d902SRodney W. Grimes #include <netinet/tcp_seq.h>
649b50d902SRodney W. Grimes #define TCPSTATES
659b50d902SRodney W. Grimes #include <netinet/tcp_fsm.h>
669b50d902SRodney W. Grimes #include <netinet/tcp_timer.h>
679b50d902SRodney W. Grimes #include <netinet/tcp_var.h>
689b50d902SRodney W. Grimes #include <netinet/tcp_debug.h>
699b50d902SRodney W. Grimes #include <netinet/udp.h>
709b50d902SRodney W. Grimes #include <netinet/udp_var.h>
719b50d902SRodney W. Grimes 
729b50d902SRodney W. Grimes #include <arpa/inet.h>
734f81ef50SGarrett Wollman #include <err.h>
744f81ef50SGarrett Wollman #include <errno.h>
75d121b556SBrian Somers #include <libutil.h>
769b50d902SRodney W. Grimes #include <netdb.h>
779b50d902SRodney W. Grimes #include <stdio.h>
784f81ef50SGarrett Wollman #include <stdlib.h>
799b50d902SRodney W. Grimes #include <string.h>
809b50d902SRodney W. Grimes #include <unistd.h>
819b50d902SRodney W. Grimes #include "netstat.h"
829b50d902SRodney W. Grimes 
835e051718SAssar Westerlund char	*inetname (struct in_addr *);
84a01e3379SDavid Malone void	inetprint (struct in_addr *, int, const char *, int);
85cfa1ca9dSYoshinobu Inoue #ifdef INET6
86cfa1ca9dSYoshinobu Inoue static int udp_done, tcp_done;
87cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
889b50d902SRodney W. Grimes 
899b50d902SRodney W. Grimes /*
909b50d902SRodney W. Grimes  * Print a summary of connections related to an Internet
919b50d902SRodney W. Grimes  * protocol.  For TCP, also give state of connection.
929b50d902SRodney W. Grimes  * Listening processes (aflag) are suppressed unless the
939b50d902SRodney W. Grimes  * -a (all) flag is specified.
949b50d902SRodney W. Grimes  */
959b50d902SRodney W. Grimes void
965e051718SAssar Westerlund protopr(u_long proto,		/* for sysctl version we pass proto # */
97a01e3379SDavid Malone 	const char *name, int af1)
989b50d902SRodney W. Grimes {
999b50d902SRodney W. Grimes 	int istcp;
1009b50d902SRodney W. Grimes 	static int first = 1;
1014f81ef50SGarrett Wollman 	char *buf;
102fb5d0fbdSRuslan Ermilov 	const char *mibvar, *vchar;
103a97a9922SJulian Elischer 	struct tcpcb *tp = NULL;
1044f81ef50SGarrett Wollman 	struct inpcb *inp;
1054f81ef50SGarrett Wollman 	struct xinpgen *xig, *oxig;
1064f81ef50SGarrett Wollman 	struct xsocket *so;
1074f81ef50SGarrett Wollman 	size_t len;
1089b50d902SRodney W. Grimes 
1094f81ef50SGarrett Wollman 	istcp = 0;
1104f81ef50SGarrett Wollman 	switch (proto) {
1114f81ef50SGarrett Wollman 	case IPPROTO_TCP:
112cfa1ca9dSYoshinobu Inoue #ifdef INET6
113cfa1ca9dSYoshinobu Inoue 		if (tcp_done != 0)
114cfa1ca9dSYoshinobu Inoue 			return;
115cfa1ca9dSYoshinobu Inoue 		else
116cfa1ca9dSYoshinobu Inoue 			tcp_done = 1;
117cfa1ca9dSYoshinobu Inoue #endif
1184f81ef50SGarrett Wollman 		istcp = 1;
1194f81ef50SGarrett Wollman 		mibvar = "net.inet.tcp.pcblist";
1204f81ef50SGarrett Wollman 		break;
1214f81ef50SGarrett Wollman 	case IPPROTO_UDP:
122cfa1ca9dSYoshinobu Inoue #ifdef INET6
123cfa1ca9dSYoshinobu Inoue 		if (udp_done != 0)
124cfa1ca9dSYoshinobu Inoue 			return;
125cfa1ca9dSYoshinobu Inoue 		else
126cfa1ca9dSYoshinobu Inoue 			udp_done = 1;
127cfa1ca9dSYoshinobu Inoue #endif
1284f81ef50SGarrett Wollman 		mibvar = "net.inet.udp.pcblist";
1294f81ef50SGarrett Wollman 		break;
1304f81ef50SGarrett Wollman 	case IPPROTO_DIVERT:
1314f81ef50SGarrett Wollman 		mibvar = "net.inet.divert.pcblist";
1324f81ef50SGarrett Wollman 		break;
1334f81ef50SGarrett Wollman 	default:
1344f81ef50SGarrett Wollman 		mibvar = "net.inet.raw.pcblist";
1354f81ef50SGarrett Wollman 		break;
1364f81ef50SGarrett Wollman 	}
1374f81ef50SGarrett Wollman 	len = 0;
1384f81ef50SGarrett Wollman 	if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
1394f81ef50SGarrett Wollman 		if (errno != ENOENT)
1404f81ef50SGarrett Wollman 			warn("sysctl: %s", mibvar);
1419b50d902SRodney W. Grimes 		return;
1423aa80b1dSDavid Greenman 	}
1434f81ef50SGarrett Wollman 	if ((buf = malloc(len)) == 0) {
1444f81ef50SGarrett Wollman 		warn("malloc %lu bytes", (u_long)len);
1454f81ef50SGarrett Wollman 		return;
1469b50d902SRodney W. Grimes 	}
1474f81ef50SGarrett Wollman 	if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) {
1484f81ef50SGarrett Wollman 		warn("sysctl: %s", mibvar);
1494f81ef50SGarrett Wollman 		free(buf);
1504f81ef50SGarrett Wollman 		return;
1514f81ef50SGarrett Wollman 	}
1524f81ef50SGarrett Wollman 
1534f81ef50SGarrett Wollman 	oxig = xig = (struct xinpgen *)buf;
1544f81ef50SGarrett Wollman 	for (xig = (struct xinpgen *)((char *)xig + xig->xig_len);
1554f81ef50SGarrett Wollman 	     xig->xig_len > sizeof(struct xinpgen);
1564f81ef50SGarrett Wollman 	     xig = (struct xinpgen *)((char *)xig + xig->xig_len)) {
1579b50d902SRodney W. Grimes 		if (istcp) {
1584f81ef50SGarrett Wollman 			tp = &((struct xtcpcb *)xig)->xt_tp;
1594f81ef50SGarrett Wollman 			inp = &((struct xtcpcb *)xig)->xt_inp;
1604f81ef50SGarrett Wollman 			so = &((struct xtcpcb *)xig)->xt_socket;
1614f81ef50SGarrett Wollman 		} else {
1624f81ef50SGarrett Wollman 			inp = &((struct xinpcb *)xig)->xi_inp;
1634f81ef50SGarrett Wollman 			so = &((struct xinpcb *)xig)->xi_socket;
1649b50d902SRodney W. Grimes 		}
1654f81ef50SGarrett Wollman 
1664f81ef50SGarrett Wollman 		/* Ignore sockets for protocols other than the desired one. */
167f964d60dSAssar Westerlund 		if (so->xso_protocol != (int)proto)
1684f81ef50SGarrett Wollman 			continue;
1694f81ef50SGarrett Wollman 
1704f81ef50SGarrett Wollman 		/* Ignore PCBs which were freed during copyout. */
1714f81ef50SGarrett Wollman 		if (inp->inp_gencnt > oxig->xig_gen)
1724f81ef50SGarrett Wollman 			continue;
1734f81ef50SGarrett Wollman 
174a01e3379SDavid Malone 		if ((af1 == AF_INET && (inp->inp_vflag & INP_IPV4) == 0)
175cfa1ca9dSYoshinobu Inoue #ifdef INET6
176a01e3379SDavid Malone 		    || (af1 == AF_INET6 && (inp->inp_vflag & INP_IPV6) == 0)
177cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
178a01e3379SDavid Malone 		    || (af1 == AF_UNSPEC && ((inp->inp_vflag & INP_IPV4) == 0
179cfa1ca9dSYoshinobu Inoue #ifdef INET6
180cfa1ca9dSYoshinobu Inoue 					    && (inp->inp_vflag &
181cfa1ca9dSYoshinobu Inoue 						INP_IPV6) == 0
182cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
183cfa1ca9dSYoshinobu Inoue 			))
184cfa1ca9dSYoshinobu Inoue 		    )
185cfa1ca9dSYoshinobu Inoue 			continue;
186cfa1ca9dSYoshinobu Inoue 		if (!aflag &&
187cfa1ca9dSYoshinobu Inoue 		    (
188a01e3379SDavid Malone 		     (af1 == AF_INET &&
189cfa1ca9dSYoshinobu Inoue 		      inet_lnaof(inp->inp_laddr) == INADDR_ANY)
190cfa1ca9dSYoshinobu Inoue #ifdef INET6
191a01e3379SDavid Malone 		     || (af1 == AF_INET6 &&
192cfa1ca9dSYoshinobu Inoue 			 IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
193cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
194a01e3379SDavid Malone 		     || (af1 == AF_UNSPEC &&
195cfa1ca9dSYoshinobu Inoue 			 (((inp->inp_vflag & INP_IPV4) != 0 &&
196cfa1ca9dSYoshinobu Inoue 			   inet_lnaof(inp->inp_laddr) == INADDR_ANY)
197cfa1ca9dSYoshinobu Inoue #ifdef INET6
198cfa1ca9dSYoshinobu Inoue 			  || ((inp->inp_vflag & INP_IPV6) != 0 &&
199cfa1ca9dSYoshinobu Inoue 			      IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
200cfa1ca9dSYoshinobu Inoue #endif
201cfa1ca9dSYoshinobu Inoue 			  ))
202cfa1ca9dSYoshinobu Inoue 		     ))
2034f81ef50SGarrett Wollman 			continue;
2044f81ef50SGarrett Wollman 
2059b50d902SRodney W. Grimes 		if (first) {
206ac55add0SGuido van Rooij 			if (!Lflag) {
2079b50d902SRodney W. Grimes 				printf("Active Internet connections");
2089b50d902SRodney W. Grimes 				if (aflag)
2099b50d902SRodney W. Grimes 					printf(" (including servers)");
210ac55add0SGuido van Rooij 			} else
211ac55add0SGuido van Rooij 				printf(
212ac55add0SGuido van Rooij 	"Current listen queue sizes (qlen/incqlen/maxqlen)");
2139b50d902SRodney W. Grimes 			putchar('\n');
2149b50d902SRodney W. Grimes 			if (Aflag)
2154f81ef50SGarrett Wollman 				printf("%-8.8s ", "Socket");
216ac55add0SGuido van Rooij 			if (Lflag)
217fb5d0fbdSRuslan Ermilov 				printf("%-5.5s %-14.14s %-22.22s\n",
218fb5d0fbdSRuslan Ermilov 					"Proto", "Listen", "Local Address");
219ac55add0SGuido van Rooij 			else
220080b7f49SDag-Erling Smørgrav 				printf((Aflag && !Wflag) ?
221cfa1ca9dSYoshinobu Inoue 		"%-5.5s %-6.6s %-6.6s  %-18.18s %-18.18s %s\n" :
222cfa1ca9dSYoshinobu Inoue 		"%-5.5s %-6.6s %-6.6s  %-22.22s %-22.22s %s\n",
2239b50d902SRodney W. Grimes 					"Proto", "Recv-Q", "Send-Q",
224ac55add0SGuido van Rooij 					"Local Address", "Foreign Address",
225ac55add0SGuido van Rooij 					"(state)");
2269b50d902SRodney W. Grimes 			first = 0;
2279b50d902SRodney W. Grimes 		}
228fb5d0fbdSRuslan Ermilov 		if (Lflag && so->so_qlimit == 0)
229fb5d0fbdSRuslan Ermilov 			continue;
230e4ec3989SDag-Erling Smørgrav 		if (Aflag) {
231e4ec3989SDag-Erling Smørgrav 			if (istcp)
232e4ec3989SDag-Erling Smørgrav 				printf("%8lx ", (u_long)inp->inp_ppcb);
233e4ec3989SDag-Erling Smørgrav 			else
2344f81ef50SGarrett Wollman 				printf("%8lx ", (u_long)so->so_pcb);
235e4ec3989SDag-Erling Smørgrav 		}
236cfa1ca9dSYoshinobu Inoue #ifdef INET6
237fc60ab7bSYoshinobu Inoue 		if ((inp->inp_vflag & INP_IPV6) != 0)
238fc60ab7bSYoshinobu Inoue 			vchar = ((inp->inp_vflag & INP_IPV4) != 0)
239fc60ab7bSYoshinobu Inoue 				? "46" : "6 ";
240fc60ab7bSYoshinobu Inoue 		else
241cfa1ca9dSYoshinobu Inoue #endif
242fc60ab7bSYoshinobu Inoue 		vchar = ((inp->inp_vflag & INP_IPV4) != 0)
243fc60ab7bSYoshinobu Inoue 				? "4 " : "  ";
244fb5d0fbdSRuslan Ermilov 		printf("%-3.3s%-2.2s ", name, vchar);
245fb5d0fbdSRuslan Ermilov 		if (Lflag) {
246a01e3379SDavid Malone 			char buf1[15];
247fc60ab7bSYoshinobu Inoue 
248a01e3379SDavid Malone 			snprintf(buf1, 15, "%d/%d/%d", so->so_qlen,
249fb5d0fbdSRuslan Ermilov 				 so->so_incqlen, so->so_qlimit);
250a01e3379SDavid Malone 			printf("%-14.14s ", buf1);
251fb5d0fbdSRuslan Ermilov 		} else {
252f824b518SJohn Polstra 			printf("%6u %6u  ",
253cfa1ca9dSYoshinobu Inoue 			       so->so_rcv.sb_cc,
2544f81ef50SGarrett Wollman 			       so->so_snd.sb_cc);
255fc60ab7bSYoshinobu Inoue 		}
25665ea0024SAssar Westerlund 		if (numeric_port) {
257cfa1ca9dSYoshinobu Inoue 			if (inp->inp_vflag & INP_IPV4) {
2584f81ef50SGarrett Wollman 				inetprint(&inp->inp_laddr, (int)inp->inp_lport,
2598d612dd2SPoul-Henning Kamp 					  name, 1);
260ac55add0SGuido van Rooij 				if (!Lflag)
261ac55add0SGuido van Rooij 					inetprint(&inp->inp_faddr,
262ac55add0SGuido van Rooij 						  (int)inp->inp_fport, name, 1);
263cfa1ca9dSYoshinobu Inoue 			}
264cfa1ca9dSYoshinobu Inoue #ifdef INET6
265cfa1ca9dSYoshinobu Inoue 			else if (inp->inp_vflag & INP_IPV6) {
266cfa1ca9dSYoshinobu Inoue 				inet6print(&inp->in6p_laddr,
267cfa1ca9dSYoshinobu Inoue 					   (int)inp->inp_lport, name, 1);
268ac55add0SGuido van Rooij 				if (!Lflag)
269cfa1ca9dSYoshinobu Inoue 					inet6print(&inp->in6p_faddr,
270cfa1ca9dSYoshinobu Inoue 						   (int)inp->inp_fport, name, 1);
271cfa1ca9dSYoshinobu Inoue 			} /* else nothing printed now */
272cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
2734f81ef50SGarrett Wollman 		} else if (inp->inp_flags & INP_ANONPORT) {
274cfa1ca9dSYoshinobu Inoue 			if (inp->inp_vflag & INP_IPV4) {
2754f81ef50SGarrett Wollman 				inetprint(&inp->inp_laddr, (int)inp->inp_lport,
2768d612dd2SPoul-Henning Kamp 					  name, 1);
277ac55add0SGuido van Rooij 				if (!Lflag)
278ac55add0SGuido van Rooij 					inetprint(&inp->inp_faddr,
279ac55add0SGuido van Rooij 						  (int)inp->inp_fport, name, 0);
280cfa1ca9dSYoshinobu Inoue 			}
281cfa1ca9dSYoshinobu Inoue #ifdef INET6
282cfa1ca9dSYoshinobu Inoue 			else if (inp->inp_vflag & INP_IPV6) {
283cfa1ca9dSYoshinobu Inoue 				inet6print(&inp->in6p_laddr,
284cfa1ca9dSYoshinobu Inoue 					   (int)inp->inp_lport, name, 1);
285ac55add0SGuido van Rooij 				if (!Lflag)
286cfa1ca9dSYoshinobu Inoue 					inet6print(&inp->in6p_faddr,
287cfa1ca9dSYoshinobu Inoue 						   (int)inp->inp_fport, name, 0);
288cfa1ca9dSYoshinobu Inoue 			} /* else nothing printed now */
289cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
2908d612dd2SPoul-Henning Kamp 		} else {
291cfa1ca9dSYoshinobu Inoue 			if (inp->inp_vflag & INP_IPV4) {
2924f81ef50SGarrett Wollman 				inetprint(&inp->inp_laddr, (int)inp->inp_lport,
2938d612dd2SPoul-Henning Kamp 					  name, 0);
294ac55add0SGuido van Rooij 				if (!Lflag)
295ac55add0SGuido van Rooij 					inetprint(&inp->inp_faddr,
296ac55add0SGuido van Rooij 						  (int)inp->inp_fport, name,
297ac55add0SGuido van Rooij 						  inp->inp_lport !=
298ac55add0SGuido van Rooij 							inp->inp_fport);
299cfa1ca9dSYoshinobu Inoue 			}
300cfa1ca9dSYoshinobu Inoue #ifdef INET6
301cfa1ca9dSYoshinobu Inoue 			else if (inp->inp_vflag & INP_IPV6) {
302cfa1ca9dSYoshinobu Inoue 				inet6print(&inp->in6p_laddr,
303cfa1ca9dSYoshinobu Inoue 					   (int)inp->inp_lport, name, 0);
304ac55add0SGuido van Rooij 				if (!Lflag)
305cfa1ca9dSYoshinobu Inoue 					inet6print(&inp->in6p_faddr,
306cfa1ca9dSYoshinobu Inoue 						   (int)inp->inp_fport, name,
307ac55add0SGuido van Rooij 						   inp->inp_lport !=
308ac55add0SGuido van Rooij 							inp->inp_fport);
309cfa1ca9dSYoshinobu Inoue 			} /* else nothing printed now */
310cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
3118d612dd2SPoul-Henning Kamp 		}
312ac55add0SGuido van Rooij 		if (istcp && !Lflag) {
3134f81ef50SGarrett Wollman 			if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES)
3144f81ef50SGarrett Wollman 				printf("%d", tp->t_state);
3159a94a597SGarrett Wollman                       else {
3164f81ef50SGarrett Wollman 				printf("%s", tcpstates[tp->t_state]);
317513822ddSAdam David #if defined(TF_NEEDSYN) && defined(TF_NEEDFIN)
3189a94a597SGarrett Wollman                               /* Show T/TCP `hidden state' */
3194f81ef50SGarrett Wollman                               if (tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN))
3209a94a597SGarrett Wollman                                       putchar('*');
321513822ddSAdam David #endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */
3229a94a597SGarrett Wollman                       }
3239b50d902SRodney W. Grimes 		}
3249b50d902SRodney W. Grimes 		putchar('\n');
3259b50d902SRodney W. Grimes 	}
3264f81ef50SGarrett Wollman 	if (xig != oxig && xig->xig_gen != oxig->xig_gen) {
3274f81ef50SGarrett Wollman 		if (oxig->xig_count > xig->xig_count) {
3284f81ef50SGarrett Wollman 			printf("Some %s sockets may have been deleted.\n",
3294f81ef50SGarrett Wollman 			       name);
3304f81ef50SGarrett Wollman 		} else if (oxig->xig_count < xig->xig_count) {
3314f81ef50SGarrett Wollman 			printf("Some %s sockets may have been created.\n",
3324f81ef50SGarrett Wollman 			       name);
3334f81ef50SGarrett Wollman 		} else {
3344f81ef50SGarrett Wollman 			printf("Some %s sockets may have been created or deleted",
3354f81ef50SGarrett Wollman 			       name);
3364f81ef50SGarrett Wollman 		}
3374f81ef50SGarrett Wollman 	}
3384f81ef50SGarrett Wollman 	free(buf);
3399b50d902SRodney W. Grimes }
3409b50d902SRodney W. Grimes 
3419b50d902SRodney W. Grimes /*
3429b50d902SRodney W. Grimes  * Dump TCP statistics structure.
3439b50d902SRodney W. Grimes  */
3449b50d902SRodney W. Grimes void
345a01e3379SDavid Malone tcp_stats(u_long off __unused, const char *name, int af1 __unused)
3469b50d902SRodney W. Grimes {
347c73d99b5SRuslan Ermilov 	struct tcpstat tcpstat, zerostat;
3484f81ef50SGarrett Wollman 	size_t len = sizeof tcpstat;
3499b50d902SRodney W. Grimes 
350c73d99b5SRuslan Ermilov 	if (zflag)
351c73d99b5SRuslan Ermilov 		memset(&zerostat, 0, len);
352c73d99b5SRuslan Ermilov 	if (sysctlbyname("net.inet.tcp.stats", &tcpstat, &len,
353c73d99b5SRuslan Ermilov 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
3544f81ef50SGarrett Wollman 		warn("sysctl: net.inet.tcp.stats");
3559b50d902SRodney W. Grimes 		return;
3564f81ef50SGarrett Wollman 	}
3574f81ef50SGarrett Wollman 
358cfa1ca9dSYoshinobu Inoue #ifdef INET6
359cfa1ca9dSYoshinobu Inoue 	if (tcp_done != 0)
360cfa1ca9dSYoshinobu Inoue 		return;
361cfa1ca9dSYoshinobu Inoue 	else
362cfa1ca9dSYoshinobu Inoue 		tcp_done = 1;
363cfa1ca9dSYoshinobu Inoue #endif
364cfa1ca9dSYoshinobu Inoue 
3659b50d902SRodney W. Grimes 	printf ("%s:\n", name);
3669b50d902SRodney W. Grimes 
3679b50d902SRodney W. Grimes #define	p(f, m) if (tcpstat.f || sflag <= 1) \
3689b50d902SRodney W. Grimes     printf(m, tcpstat.f, plural(tcpstat.f))
36922694ebaSBruce Evans #define	p1a(f, m) if (tcpstat.f || sflag <= 1) \
37022694ebaSBruce Evans     printf(m, tcpstat.f)
3719b50d902SRodney W. Grimes #define	p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
3729b50d902SRodney W. Grimes     printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2))
37322694ebaSBruce Evans #define	p2a(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
37422694ebaSBruce Evans     printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2)
3759b50d902SRodney W. Grimes #define	p3(f, m) if (tcpstat.f || sflag <= 1) \
3769b50d902SRodney W. Grimes     printf(m, tcpstat.f, plurales(tcpstat.f))
3779b50d902SRodney W. Grimes 
378e1fb4daaSPaul Traina 	p(tcps_sndtotal, "\t%lu packet%s sent\n");
3799b50d902SRodney W. Grimes 	p2(tcps_sndpack,tcps_sndbyte,
380e1fb4daaSPaul Traina 		"\t\t%lu data packet%s (%lu byte%s)\n");
3819b50d902SRodney W. Grimes 	p2(tcps_sndrexmitpack, tcps_sndrexmitbyte,
382e1fb4daaSPaul Traina 		"\t\t%lu data packet%s (%lu byte%s) retransmitted\n");
383d65bf08aSMatthew Dillon 	p(tcps_sndrexmitbad,
384d65bf08aSMatthew Dillon 		"\t\t%lu data packet%s unnecessarily retransmitted\n");
385e1fb4daaSPaul Traina 	p(tcps_mturesent, "\t\t%lu resend%s initiated by MTU discovery\n");
38622694ebaSBruce Evans 	p2a(tcps_sndacks, tcps_delack,
387e1fb4daaSPaul Traina 		"\t\t%lu ack-only packet%s (%lu delayed)\n");
388e1fb4daaSPaul Traina 	p(tcps_sndurg, "\t\t%lu URG only packet%s\n");
389e1fb4daaSPaul Traina 	p(tcps_sndprobe, "\t\t%lu window probe packet%s\n");
390e1fb4daaSPaul Traina 	p(tcps_sndwinup, "\t\t%lu window update packet%s\n");
391e1fb4daaSPaul Traina 	p(tcps_sndctrl, "\t\t%lu control packet%s\n");
392e1fb4daaSPaul Traina 	p(tcps_rcvtotal, "\t%lu packet%s received\n");
393e1fb4daaSPaul Traina 	p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%lu ack%s (for %lu byte%s)\n");
394e1fb4daaSPaul Traina 	p(tcps_rcvdupack, "\t\t%lu duplicate ack%s\n");
395e1fb4daaSPaul Traina 	p(tcps_rcvacktoomuch, "\t\t%lu ack%s for unsent data\n");
3969b50d902SRodney W. Grimes 	p2(tcps_rcvpack, tcps_rcvbyte,
397e1fb4daaSPaul Traina 		"\t\t%lu packet%s (%lu byte%s) received in-sequence\n");
3989b50d902SRodney W. Grimes 	p2(tcps_rcvduppack, tcps_rcvdupbyte,
399e1fb4daaSPaul Traina 		"\t\t%lu completely duplicate packet%s (%lu byte%s)\n");
400e1fb4daaSPaul Traina 	p(tcps_pawsdrop, "\t\t%lu old duplicate packet%s\n");
4019b50d902SRodney W. Grimes 	p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte,
402e1fb4daaSPaul Traina 		"\t\t%lu packet%s with some dup. data (%lu byte%s duped)\n");
4039b50d902SRodney W. Grimes 	p2(tcps_rcvoopack, tcps_rcvoobyte,
404e1fb4daaSPaul Traina 		"\t\t%lu out-of-order packet%s (%lu byte%s)\n");
4059b50d902SRodney W. Grimes 	p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin,
406e1fb4daaSPaul Traina 		"\t\t%lu packet%s (%lu byte%s) of data after window\n");
407e1fb4daaSPaul Traina 	p(tcps_rcvwinprobe, "\t\t%lu window probe%s\n");
408e1fb4daaSPaul Traina 	p(tcps_rcvwinupd, "\t\t%lu window update packet%s\n");
409e1fb4daaSPaul Traina 	p(tcps_rcvafterclose, "\t\t%lu packet%s received after close\n");
410e1fb4daaSPaul Traina 	p(tcps_rcvbadsum, "\t\t%lu discarded for bad checksum%s\n");
411e1fb4daaSPaul Traina 	p(tcps_rcvbadoff, "\t\t%lu discarded for bad header offset field%s\n");
41222694ebaSBruce Evans 	p1a(tcps_rcvshort, "\t\t%lu discarded because packet too short\n");
413e1fb4daaSPaul Traina 	p(tcps_connattempt, "\t%lu connection request%s\n");
414e1fb4daaSPaul Traina 	p(tcps_accepts, "\t%lu connection accept%s\n");
415e1fb4daaSPaul Traina 	p(tcps_badsyn, "\t%lu bad connection attempt%s\n");
416e1fb4daaSPaul Traina 	p(tcps_listendrop, "\t%lu listen queue overflow%s\n");
417e1fb4daaSPaul Traina 	p(tcps_connects, "\t%lu connection%s established (including accepts)\n");
4189b50d902SRodney W. Grimes 	p2(tcps_closed, tcps_drops,
419e1fb4daaSPaul Traina 		"\t%lu connection%s closed (including %lu drop%s)\n");
420e1fb4daaSPaul Traina 	p(tcps_cachedrtt, "\t\t%lu connection%s updated cached RTT on close\n");
421861b1828SGarrett Wollman 	p(tcps_cachedrttvar,
422e1fb4daaSPaul Traina 	  "\t\t%lu connection%s updated cached RTT variance on close\n");
423861b1828SGarrett Wollman 	p(tcps_cachedssthresh,
424e1fb4daaSPaul Traina 	  "\t\t%lu connection%s updated cached ssthresh on close\n");
425e1fb4daaSPaul Traina 	p(tcps_conndrops, "\t%lu embryonic connection%s dropped\n");
4269b50d902SRodney W. Grimes 	p2(tcps_rttupdated, tcps_segstimed,
427e1fb4daaSPaul Traina 		"\t%lu segment%s updated rtt (of %lu attempt%s)\n");
428e1fb4daaSPaul Traina 	p(tcps_rexmttimeo, "\t%lu retransmit timeout%s\n");
429e1fb4daaSPaul Traina 	p(tcps_timeoutdrop, "\t\t%lu connection%s dropped by rexmit timeout\n");
430e1fb4daaSPaul Traina 	p(tcps_persisttimeo, "\t%lu persist timeout%s\n");
431e1fb4daaSPaul Traina 	p(tcps_persistdrop, "\t\t%lu connection%s dropped by persist timeout\n");
432e1fb4daaSPaul Traina 	p(tcps_keeptimeo, "\t%lu keepalive timeout%s\n");
433e1fb4daaSPaul Traina 	p(tcps_keepprobe, "\t\t%lu keepalive probe%s sent\n");
434e1fb4daaSPaul Traina 	p(tcps_keepdrops, "\t\t%lu connection%s dropped by keepalive\n");
435e1fb4daaSPaul Traina 	p(tcps_predack, "\t%lu correct ACK header prediction%s\n");
436e1fb4daaSPaul Traina 	p(tcps_preddat, "\t%lu correct data packet header prediction%s\n");
43760a31b3aSJonathan Lemon 
438a01e3379SDavid Malone 	p(tcps_sc_added, "\t%lu syncache entrie%s added\n");
439a01e3379SDavid Malone 	p1a(tcps_sc_retransmitted, "\t\t%lu retransmitted\n");
440a01e3379SDavid Malone 	p1a(tcps_sc_dupsyn, "\t\t%lu dupsyn\n");
441a01e3379SDavid Malone 	p1a(tcps_sc_dropped, "\t\t%lu dropped\n");
442a01e3379SDavid Malone 	p1a(tcps_sc_completed, "\t\t%lu completed\n");
443a01e3379SDavid Malone 	p1a(tcps_sc_bucketoverflow, "\t\t%lu bucket overflow\n");
444a01e3379SDavid Malone 	p1a(tcps_sc_cacheoverflow, "\t\t%lu cache overflow\n");
445a01e3379SDavid Malone 	p1a(tcps_sc_reset, "\t\t%lu reset\n");
446a01e3379SDavid Malone 	p1a(tcps_sc_stale, "\t\t%lu stale\n");
447a01e3379SDavid Malone 	p1a(tcps_sc_aborted, "\t\t%lu aborted\n");
448a01e3379SDavid Malone 	p1a(tcps_sc_badack, "\t\t%lu badack\n");
449a01e3379SDavid Malone 	p1a(tcps_sc_unreach, "\t\t%lu unreach\n");
450a01e3379SDavid Malone 	p(tcps_sc_zonefail, "\t\t%lu zone failure%s\n");
451a01e3379SDavid Malone 	p(tcps_sc_sendcookie, "\t%lu cookie%s sent\n");
452a01e3379SDavid Malone 	p(tcps_sc_recvcookie, "\t%lu cookie%s received\n");
4539b50d902SRodney W. Grimes #undef p
45422694ebaSBruce Evans #undef p1a
4559b50d902SRodney W. Grimes #undef p2
45622694ebaSBruce Evans #undef p2a
4579b50d902SRodney W. Grimes #undef p3
4589b50d902SRodney W. Grimes }
4599b50d902SRodney W. Grimes 
4609b50d902SRodney W. Grimes /*
4619b50d902SRodney W. Grimes  * Dump UDP statistics structure.
4629b50d902SRodney W. Grimes  */
4639b50d902SRodney W. Grimes void
464a01e3379SDavid Malone udp_stats(u_long off __unused, const char *name, int af1 __unused)
4659b50d902SRodney W. Grimes {
466c73d99b5SRuslan Ermilov 	struct udpstat udpstat, zerostat;
4674f81ef50SGarrett Wollman 	size_t len = sizeof udpstat;
4689b50d902SRodney W. Grimes 	u_long delivered;
4699b50d902SRodney W. Grimes 
470c73d99b5SRuslan Ermilov 	if (zflag)
471c73d99b5SRuslan Ermilov 		memset(&zerostat, 0, len);
472c73d99b5SRuslan Ermilov 	if (sysctlbyname("net.inet.udp.stats", &udpstat, &len,
473c73d99b5SRuslan Ermilov 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
4744f81ef50SGarrett Wollman 		warn("sysctl: net.inet.udp.stats");
4759b50d902SRodney W. Grimes 		return;
4764f81ef50SGarrett Wollman 	}
4774f81ef50SGarrett Wollman 
478cfa1ca9dSYoshinobu Inoue #ifdef INET6
479cfa1ca9dSYoshinobu Inoue 	if (udp_done != 0)
480cfa1ca9dSYoshinobu Inoue 		return;
481cfa1ca9dSYoshinobu Inoue 	else
482cfa1ca9dSYoshinobu Inoue 		udp_done = 1;
483cfa1ca9dSYoshinobu Inoue #endif
484cfa1ca9dSYoshinobu Inoue 
4859b50d902SRodney W. Grimes 	printf("%s:\n", name);
4869b50d902SRodney W. Grimes #define	p(f, m) if (udpstat.f || sflag <= 1) \
4879b50d902SRodney W. Grimes     printf(m, udpstat.f, plural(udpstat.f))
48822694ebaSBruce Evans #define	p1a(f, m) if (udpstat.f || sflag <= 1) \
48922694ebaSBruce Evans     printf(m, udpstat.f)
4907d56c0eeSAlexander Langer 	p(udps_ipackets, "\t%lu datagram%s received\n");
49122694ebaSBruce Evans 	p1a(udps_hdrops, "\t%lu with incomplete header\n");
49222694ebaSBruce Evans 	p1a(udps_badlen, "\t%lu with bad data length field\n");
49322694ebaSBruce Evans 	p1a(udps_badsum, "\t%lu with bad checksum\n");
494fb9aaba0SRuslan Ermilov 	p1a(udps_nosum, "\t%lu with no checksum\n");
49522694ebaSBruce Evans 	p1a(udps_noport, "\t%lu dropped due to no socket\n");
49622694ebaSBruce Evans 	p(udps_noportbcast,
49722694ebaSBruce Evans 	    "\t%lu broadcast/multicast datagram%s dropped due to no socket\n");
49822694ebaSBruce Evans 	p1a(udps_fullsock, "\t%lu dropped due to full socket buffers\n");
49922694ebaSBruce Evans 	p1a(udpps_pcbhashmiss, "\t%lu not for hashed pcb\n");
5009b50d902SRodney W. Grimes 	delivered = udpstat.udps_ipackets -
5019b50d902SRodney W. Grimes 		    udpstat.udps_hdrops -
5029b50d902SRodney W. Grimes 		    udpstat.udps_badlen -
5039b50d902SRodney W. Grimes 		    udpstat.udps_badsum -
5049b50d902SRodney W. Grimes 		    udpstat.udps_noport -
5059b50d902SRodney W. Grimes 		    udpstat.udps_noportbcast -
5069b50d902SRodney W. Grimes 		    udpstat.udps_fullsock;
5079b50d902SRodney W. Grimes 	if (delivered || sflag <= 1)
5087d56c0eeSAlexander Langer 		printf("\t%lu delivered\n", delivered);
5097d56c0eeSAlexander Langer 	p(udps_opackets, "\t%lu datagram%s output\n");
5109b50d902SRodney W. Grimes #undef p
51122694ebaSBruce Evans #undef p1a
5129b50d902SRodney W. Grimes }
5139b50d902SRodney W. Grimes 
5149b50d902SRodney W. Grimes /*
5159b50d902SRodney W. Grimes  * Dump IP statistics structure.
5169b50d902SRodney W. Grimes  */
5179b50d902SRodney W. Grimes void
518a01e3379SDavid Malone ip_stats(u_long off __unused, const char *name, int af1 __unused)
5199b50d902SRodney W. Grimes {
520c73d99b5SRuslan Ermilov 	struct ipstat ipstat, zerostat;
5214f81ef50SGarrett Wollman 	size_t len = sizeof ipstat;
5229b50d902SRodney W. Grimes 
523c73d99b5SRuslan Ermilov 	if (zflag)
524c73d99b5SRuslan Ermilov 		memset(&zerostat, 0, len);
525c73d99b5SRuslan Ermilov 	if (sysctlbyname("net.inet.ip.stats", &ipstat, &len,
526c73d99b5SRuslan Ermilov 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
5274f81ef50SGarrett Wollman 		warn("sysctl: net.inet.ip.stats");
5289b50d902SRodney W. Grimes 		return;
5294f81ef50SGarrett Wollman 	}
5304f81ef50SGarrett Wollman 
5319b50d902SRodney W. Grimes 	printf("%s:\n", name);
5329b50d902SRodney W. Grimes 
5339b50d902SRodney W. Grimes #define	p(f, m) if (ipstat.f || sflag <= 1) \
5349b50d902SRodney W. Grimes     printf(m, ipstat.f, plural(ipstat.f))
53522694ebaSBruce Evans #define	p1a(f, m) if (ipstat.f || sflag <= 1) \
53622694ebaSBruce Evans     printf(m, ipstat.f)
5379b50d902SRodney W. Grimes 
5387d56c0eeSAlexander Langer 	p(ips_total, "\t%lu total packet%s received\n");
5397d56c0eeSAlexander Langer 	p(ips_badsum, "\t%lu bad header checksum%s\n");
54022694ebaSBruce Evans 	p1a(ips_toosmall, "\t%lu with size smaller than minimum\n");
54122694ebaSBruce Evans 	p1a(ips_tooshort, "\t%lu with data size < data length\n");
542cfa1ca9dSYoshinobu Inoue 	p1a(ips_toolong, "\t%lu with ip length > max ip packet size\n");
54322694ebaSBruce Evans 	p1a(ips_badhlen, "\t%lu with header length < data size\n");
54422694ebaSBruce Evans 	p1a(ips_badlen, "\t%lu with data length < header length\n");
54522694ebaSBruce Evans 	p1a(ips_badoptions, "\t%lu with bad options\n");
54622694ebaSBruce Evans 	p1a(ips_badvers, "\t%lu with incorrect version number\n");
5477d56c0eeSAlexander Langer 	p(ips_fragments, "\t%lu fragment%s received\n");
5487d56c0eeSAlexander Langer 	p(ips_fragdropped, "\t%lu fragment%s dropped (dup or out of space)\n");
5497d56c0eeSAlexander Langer 	p(ips_fragtimeout, "\t%lu fragment%s dropped after timeout\n");
5507d56c0eeSAlexander Langer 	p(ips_reassembled, "\t%lu packet%s reassembled ok\n");
5517d56c0eeSAlexander Langer 	p(ips_delivered, "\t%lu packet%s for this host\n");
5527d56c0eeSAlexander Langer 	p(ips_noproto, "\t%lu packet%s for unknown/unsupported protocol\n");
553958d6f7fSPierre Beyssac 	p(ips_forward, "\t%lu packet%s forwarded");
554958d6f7fSPierre Beyssac 	p(ips_fastforward, " (%lu packet%s fast forwarded)");
555958d6f7fSPierre Beyssac 	if (ipstat.ips_forward || sflag <= 1)
556958d6f7fSPierre Beyssac 		putchar('\n');
5577d56c0eeSAlexander Langer 	p(ips_cantforward, "\t%lu packet%s not forwardable\n");
558a5969f5fSGarrett Wollman 	p(ips_notmember,
559a5969f5fSGarrett Wollman 	  "\t%lu packet%s received for unknown multicast group\n");
5607d56c0eeSAlexander Langer 	p(ips_redirectsent, "\t%lu redirect%s sent\n");
5617d56c0eeSAlexander Langer 	p(ips_localout, "\t%lu packet%s sent from this host\n");
5627d56c0eeSAlexander Langer 	p(ips_rawout, "\t%lu packet%s sent with fabricated ip header\n");
563a5969f5fSGarrett Wollman 	p(ips_odropped,
564a5969f5fSGarrett Wollman 	  "\t%lu output packet%s dropped due to no bufs, etc.\n");
5657d56c0eeSAlexander Langer 	p(ips_noroute, "\t%lu output packet%s discarded due to no route\n");
5667d56c0eeSAlexander Langer 	p(ips_fragmented, "\t%lu output datagram%s fragmented\n");
5677d56c0eeSAlexander Langer 	p(ips_ofragments, "\t%lu fragment%s created\n");
5687d56c0eeSAlexander Langer 	p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n");
569cfa1ca9dSYoshinobu Inoue 	p(ips_nogif, "\t%lu tunneling packet%s that can't find gif\n");
57033841545SHajimu UMEMOTO 	p(ips_badaddr, "\t%lu datagram%s with bad address in header\n");
5719b50d902SRodney W. Grimes #undef p
57222694ebaSBruce Evans #undef p1a
5739b50d902SRodney W. Grimes }
5749b50d902SRodney W. Grimes 
575a01e3379SDavid Malone static	const char *icmpnames[] = {
5769b50d902SRodney W. Grimes 	"echo reply",
5779b50d902SRodney W. Grimes 	"#1",
5789b50d902SRodney W. Grimes 	"#2",
5799b50d902SRodney W. Grimes 	"destination unreachable",
5809b50d902SRodney W. Grimes 	"source quench",
5819b50d902SRodney W. Grimes 	"routing redirect",
5829b50d902SRodney W. Grimes 	"#6",
5839b50d902SRodney W. Grimes 	"#7",
5849b50d902SRodney W. Grimes 	"echo",
5857b46dd00SGarrett Wollman 	"router advertisement",
5867b46dd00SGarrett Wollman 	"router solicitation",
5879b50d902SRodney W. Grimes 	"time exceeded",
5889b50d902SRodney W. Grimes 	"parameter problem",
5899b50d902SRodney W. Grimes 	"time stamp",
5909b50d902SRodney W. Grimes 	"time stamp reply",
5919b50d902SRodney W. Grimes 	"information request",
5929b50d902SRodney W. Grimes 	"information request reply",
5939b50d902SRodney W. Grimes 	"address mask request",
5949b50d902SRodney W. Grimes 	"address mask reply",
5959b50d902SRodney W. Grimes };
5969b50d902SRodney W. Grimes 
5979b50d902SRodney W. Grimes /*
5989b50d902SRodney W. Grimes  * Dump ICMP statistics.
5999b50d902SRodney W. Grimes  */
6009b50d902SRodney W. Grimes void
601a01e3379SDavid Malone icmp_stats(u_long off __unused, const char *name, int af1 __unused)
6029b50d902SRodney W. Grimes {
603c73d99b5SRuslan Ermilov 	struct icmpstat icmpstat, zerostat;
6044e00c309SGarrett Wollman 	int i, first;
6054e00c309SGarrett Wollman 	int mib[4];		/* CTL_NET + PF_INET + IPPROTO_ICMP + req */
6064e00c309SGarrett Wollman 	size_t len;
6079b50d902SRodney W. Grimes 
6084e00c309SGarrett Wollman 	mib[0] = CTL_NET;
6094e00c309SGarrett Wollman 	mib[1] = PF_INET;
6104e00c309SGarrett Wollman 	mib[2] = IPPROTO_ICMP;
6114e00c309SGarrett Wollman 	mib[3] = ICMPCTL_STATS;
6124e00c309SGarrett Wollman 
6134e00c309SGarrett Wollman 	len = sizeof icmpstat;
614c73d99b5SRuslan Ermilov 	if (zflag)
615c73d99b5SRuslan Ermilov 		memset(&zerostat, 0, len);
616c73d99b5SRuslan Ermilov 	if (sysctl(mib, 4, &icmpstat, &len,
617c73d99b5SRuslan Ermilov 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
618c73d99b5SRuslan Ermilov 		warn("sysctl: net.inet.icmp.stats");
619c73d99b5SRuslan Ermilov 		return;
620c73d99b5SRuslan Ermilov 	}
6214e00c309SGarrett Wollman 
6229b50d902SRodney W. Grimes 	printf("%s:\n", name);
6239b50d902SRodney W. Grimes 
6249b50d902SRodney W. Grimes #define	p(f, m) if (icmpstat.f || sflag <= 1) \
6259b50d902SRodney W. Grimes     printf(m, icmpstat.f, plural(icmpstat.f))
62622694ebaSBruce Evans #define	p1a(f, m) if (icmpstat.f || sflag <= 1) \
62722694ebaSBruce Evans     printf(m, icmpstat.f)
628bd714208SRuslan Ermilov #define	p2(f, m) if (icmpstat.f || sflag <= 1) \
629bd714208SRuslan Ermilov     printf(m, icmpstat.f, plurales(icmpstat.f))
6309b50d902SRodney W. Grimes 
6317d56c0eeSAlexander Langer 	p(icps_error, "\t%lu call%s to icmp_error\n");
6329b50d902SRodney W. Grimes 	p(icps_oldicmp,
6337d56c0eeSAlexander Langer 	    "\t%lu error%s not generated 'cuz old message was icmp\n");
6349b50d902SRodney W. Grimes 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
6359b50d902SRodney W. Grimes 		if (icmpstat.icps_outhist[i] != 0) {
6369b50d902SRodney W. Grimes 			if (first) {
6379b50d902SRodney W. Grimes 				printf("\tOutput histogram:\n");
6389b50d902SRodney W. Grimes 				first = 0;
6399b50d902SRodney W. Grimes 			}
6407d56c0eeSAlexander Langer 			printf("\t\t%s: %lu\n", icmpnames[i],
6419b50d902SRodney W. Grimes 				icmpstat.icps_outhist[i]);
6429b50d902SRodney W. Grimes 		}
6437d56c0eeSAlexander Langer 	p(icps_badcode, "\t%lu message%s with bad code fields\n");
6447d56c0eeSAlexander Langer 	p(icps_tooshort, "\t%lu message%s < minimum length\n");
6457d56c0eeSAlexander Langer 	p(icps_checksum, "\t%lu bad checksum%s\n");
6467d56c0eeSAlexander Langer 	p(icps_badlen, "\t%lu message%s with bad length\n");
64722694ebaSBruce Evans 	p1a(icps_bmcastecho, "\t%lu multicast echo requests ignored\n");
64822694ebaSBruce Evans 	p1a(icps_bmcasttstamp, "\t%lu multicast timestamp requests ignored\n");
6499b50d902SRodney W. Grimes 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
6509b50d902SRodney W. Grimes 		if (icmpstat.icps_inhist[i] != 0) {
6519b50d902SRodney W. Grimes 			if (first) {
6529b50d902SRodney W. Grimes 				printf("\tInput histogram:\n");
6539b50d902SRodney W. Grimes 				first = 0;
6549b50d902SRodney W. Grimes 			}
6557d56c0eeSAlexander Langer 			printf("\t\t%s: %lu\n", icmpnames[i],
6569b50d902SRodney W. Grimes 				icmpstat.icps_inhist[i]);
6579b50d902SRodney W. Grimes 		}
6587d56c0eeSAlexander Langer 	p(icps_reflect, "\t%lu message response%s generated\n");
659bd714208SRuslan Ermilov 	p2(icps_badaddr, "\t%lu invalid return address%s\n");
660bd714208SRuslan Ermilov 	p(icps_badaddr, "\t%lu no return route%s\n");
6619b50d902SRodney W. Grimes #undef p
66222694ebaSBruce Evans #undef p1a
663bd714208SRuslan Ermilov #undef p2
6644e00c309SGarrett Wollman 	mib[3] = ICMPCTL_MASKREPL;
6654e00c309SGarrett Wollman 	len = sizeof i;
6664e00c309SGarrett Wollman 	if (sysctl(mib, 4, &i, &len, (void *)0, 0) < 0)
6674e00c309SGarrett Wollman 		return;
6684e00c309SGarrett Wollman 	printf("\tICMP address mask responses are %sabled\n",
6694e00c309SGarrett Wollman 	       i ? "en" : "dis");
6709b50d902SRodney W. Grimes }
6719b50d902SRodney W. Grimes 
6729b50d902SRodney W. Grimes /*
6739b50d902SRodney W. Grimes  * Dump IGMP statistics structure.
6749b50d902SRodney W. Grimes  */
6759b50d902SRodney W. Grimes void
676a01e3379SDavid Malone igmp_stats(u_long off __unused, const char *name, int af1 __unused)
6779b50d902SRodney W. Grimes {
678c73d99b5SRuslan Ermilov 	struct igmpstat igmpstat, zerostat;
6794f81ef50SGarrett Wollman 	size_t len = sizeof igmpstat;
6809b50d902SRodney W. Grimes 
681c73d99b5SRuslan Ermilov 	if (zflag)
682c73d99b5SRuslan Ermilov 		memset(&zerostat, 0, len);
683c73d99b5SRuslan Ermilov 	if (sysctlbyname("net.inet.igmp.stats", &igmpstat, &len,
684c73d99b5SRuslan Ermilov 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
6854f81ef50SGarrett Wollman 		warn("sysctl: net.inet.igmp.stats");
6869b50d902SRodney W. Grimes 		return;
6874f81ef50SGarrett Wollman 	}
6884f81ef50SGarrett Wollman 
6899b50d902SRodney W. Grimes 	printf("%s:\n", name);
6909b50d902SRodney W. Grimes 
6919b50d902SRodney W. Grimes #define	p(f, m) if (igmpstat.f || sflag <= 1) \
6929b50d902SRodney W. Grimes     printf(m, igmpstat.f, plural(igmpstat.f))
6939b50d902SRodney W. Grimes #define	py(f, m) if (igmpstat.f || sflag <= 1) \
6949b50d902SRodney W. Grimes     printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y")
6959b50d902SRodney W. Grimes 	p(igps_rcv_total, "\t%u message%s received\n");
6969b50d902SRodney W. Grimes         p(igps_rcv_tooshort, "\t%u message%s received with too few bytes\n");
6979b50d902SRodney W. Grimes         p(igps_rcv_badsum, "\t%u message%s received with bad checksum\n");
6989b50d902SRodney W. Grimes         py(igps_rcv_queries, "\t%u membership quer%s received\n");
6999b50d902SRodney W. Grimes         py(igps_rcv_badqueries, "\t%u membership quer%s received with invalid field(s)\n");
7009b50d902SRodney W. Grimes         p(igps_rcv_reports, "\t%u membership report%s received\n");
7019b50d902SRodney W. Grimes         p(igps_rcv_badreports, "\t%u membership report%s received with invalid field(s)\n");
7029b50d902SRodney W. Grimes         p(igps_rcv_ourreports, "\t%u membership report%s received for groups to which we belong\n");
7039b50d902SRodney W. Grimes         p(igps_snd_reports, "\t%u membership report%s sent\n");
7049b50d902SRodney W. Grimes #undef p
7059b50d902SRodney W. Grimes #undef py
7069b50d902SRodney W. Grimes }
7079b50d902SRodney W. Grimes 
7089b50d902SRodney W. Grimes /*
7099b50d902SRodney W. Grimes  * Pretty print an Internet address (net address + port).
7109b50d902SRodney W. Grimes  */
7119b50d902SRodney W. Grimes void
712a01e3379SDavid Malone inetprint(struct in_addr *in, int port, const char *proto, int num_port)
7139b50d902SRodney W. Grimes {
7149b50d902SRodney W. Grimes 	struct servent *sp = 0;
7159b50d902SRodney W. Grimes 	char line[80], *cp;
716cfa1ca9dSYoshinobu Inoue 	int width;
7179b50d902SRodney W. Grimes 
718080b7f49SDag-Erling Smørgrav 	if (Wflag)
719080b7f49SDag-Erling Smørgrav 	    sprintf(line, "%s.", inetname(in));
720080b7f49SDag-Erling Smørgrav 	else
721a01e3379SDavid Malone 	    sprintf(line, "%.*s.", (Aflag && !num_port) ? 12 : 16, inetname(in));
7229b50d902SRodney W. Grimes 	cp = index(line, '\0');
723a01e3379SDavid Malone 	if (!num_port && port)
7249b50d902SRodney W. Grimes 		sp = getservbyport((int)port, proto);
7259b50d902SRodney W. Grimes 	if (sp || port == 0)
7261ef69972SAndrey A. Chernov 		sprintf(cp, "%.15s ", sp ? sp->s_name : "*");
7279b50d902SRodney W. Grimes 	else
7289b50d902SRodney W. Grimes 		sprintf(cp, "%d ", ntohs((u_short)port));
729080b7f49SDag-Erling Smørgrav 	width = (Aflag && !Wflag) ? 18 : 22;
730080b7f49SDag-Erling Smørgrav 	if (Wflag)
731080b7f49SDag-Erling Smørgrav 	    printf("%-*s ", width, line);
732080b7f49SDag-Erling Smørgrav 	else
733cfa1ca9dSYoshinobu Inoue 	    printf("%-*.*s ", width, width, line);
7349b50d902SRodney W. Grimes }
7359b50d902SRodney W. Grimes 
7369b50d902SRodney W. Grimes /*
7379b50d902SRodney W. Grimes  * Construct an Internet address representation.
73865ea0024SAssar Westerlund  * If numeric_addr has been supplied, give
7399b50d902SRodney W. Grimes  * numeric value, otherwise try for symbolic name.
7409b50d902SRodney W. Grimes  */
7419b50d902SRodney W. Grimes char *
7425e051718SAssar Westerlund inetname(struct in_addr *inp)
7439b50d902SRodney W. Grimes {
744a01e3379SDavid Malone 	char *cp;
745d121b556SBrian Somers 	static char line[MAXHOSTNAMELEN];
7469b50d902SRodney W. Grimes 	struct hostent *hp;
7479b50d902SRodney W. Grimes 	struct netent *np;
7489b50d902SRodney W. Grimes 
7499b50d902SRodney W. Grimes 	cp = 0;
75065ea0024SAssar Westerlund 	if (!numeric_addr && inp->s_addr != INADDR_ANY) {
7519b50d902SRodney W. Grimes 		int net = inet_netof(*inp);
7529b50d902SRodney W. Grimes 		int lna = inet_lnaof(*inp);
7539b50d902SRodney W. Grimes 
7549b50d902SRodney W. Grimes 		if (lna == INADDR_ANY) {
7559b50d902SRodney W. Grimes 			np = getnetbyaddr(net, AF_INET);
7569b50d902SRodney W. Grimes 			if (np)
7579b50d902SRodney W. Grimes 				cp = np->n_name;
7589b50d902SRodney W. Grimes 		}
7599b50d902SRodney W. Grimes 		if (cp == 0) {
7609b50d902SRodney W. Grimes 			hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET);
7619b50d902SRodney W. Grimes 			if (hp) {
7629b50d902SRodney W. Grimes 				cp = hp->h_name;
763d121b556SBrian Somers 				trimdomain(cp, strlen(cp));
7649b50d902SRodney W. Grimes 			}
7659b50d902SRodney W. Grimes 		}
7669b50d902SRodney W. Grimes 	}
7679b50d902SRodney W. Grimes 	if (inp->s_addr == INADDR_ANY)
7689b50d902SRodney W. Grimes 		strcpy(line, "*");
7699a1f6729SWarner Losh 	else if (cp) {
7709a1f6729SWarner Losh 		strncpy(line, cp, sizeof(line) - 1);
7719a1f6729SWarner Losh 		line[sizeof(line) - 1] = '\0';
7729a1f6729SWarner Losh 	} else {
7739b50d902SRodney W. Grimes 		inp->s_addr = ntohl(inp->s_addr);
77422694ebaSBruce Evans #define C(x)	((u_int)((x) & 0xff))
77522694ebaSBruce Evans 		sprintf(line, "%u.%u.%u.%u", C(inp->s_addr >> 24),
7769b50d902SRodney W. Grimes 		    C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr));
7779b50d902SRodney W. Grimes 	}
7789b50d902SRodney W. Grimes 	return (line);
7799b50d902SRodney W. Grimes }
780