xref: /freebsd/usr.bin/netstat/inet.c (revision a97719482dd97b6690bed7276136b54af7f22a21)
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 
346cc6f122SPhilippe Charnier #if 0
359b50d902SRodney W. Grimes #ifndef lint
3605ddff6eSPeter Wemm static char sccsid[] = "@(#)inet.c	8.5 (Berkeley) 5/24/95";
379b50d902SRodney W. Grimes #endif /* not lint */
386cc6f122SPhilippe Charnier #endif
396cc6f122SPhilippe Charnier 
406cc6f122SPhilippe Charnier #include <sys/cdefs.h>
416cc6f122SPhilippe Charnier __FBSDID("$FreeBSD$");
429b50d902SRodney W. Grimes 
439b50d902SRodney W. Grimes #include <sys/param.h>
44d8d89152SDavid Greenman #include <sys/queue.h>
459b50d902SRodney W. Grimes #include <sys/socket.h>
469b50d902SRodney W. Grimes #include <sys/socketvar.h>
474e00c309SGarrett Wollman #include <sys/sysctl.h>
489b50d902SRodney W. Grimes #include <sys/protosw.h>
499b50d902SRodney W. Grimes 
509b50d902SRodney W. Grimes #include <net/route.h>
519b50d902SRodney W. Grimes #include <netinet/in.h>
529b50d902SRodney W. Grimes #include <netinet/in_systm.h>
539b50d902SRodney W. Grimes #include <netinet/ip.h>
54a9771948SGleb Smirnoff #include <netinet/ip_carp.h>
55cfa1ca9dSYoshinobu Inoue #ifdef INET6
56cfa1ca9dSYoshinobu Inoue #include <netinet/ip6.h>
57cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
589b50d902SRodney W. Grimes #include <netinet/in_pcb.h>
599b50d902SRodney W. Grimes #include <netinet/ip_icmp.h>
609b50d902SRodney W. Grimes #include <netinet/icmp_var.h>
619b50d902SRodney W. Grimes #include <netinet/igmp_var.h>
629b50d902SRodney W. Grimes #include <netinet/ip_var.h>
63c7b9b5bbSJeffrey Hsu #include <netinet/pim_var.h>
649b50d902SRodney W. Grimes #include <netinet/tcp.h>
659b50d902SRodney W. Grimes #include <netinet/tcpip.h>
669b50d902SRodney W. Grimes #include <netinet/tcp_seq.h>
679b50d902SRodney W. Grimes #define TCPSTATES
689b50d902SRodney W. Grimes #include <netinet/tcp_fsm.h>
699b50d902SRodney W. Grimes #include <netinet/tcp_timer.h>
709b50d902SRodney W. Grimes #include <netinet/tcp_var.h>
719b50d902SRodney W. Grimes #include <netinet/tcp_debug.h>
729b50d902SRodney W. Grimes #include <netinet/udp.h>
739b50d902SRodney W. Grimes #include <netinet/udp_var.h>
749b50d902SRodney W. Grimes 
759b50d902SRodney W. Grimes #include <arpa/inet.h>
764f81ef50SGarrett Wollman #include <err.h>
774f81ef50SGarrett Wollman #include <errno.h>
78d121b556SBrian Somers #include <libutil.h>
799b50d902SRodney W. Grimes #include <netdb.h>
809b50d902SRodney W. Grimes #include <stdio.h>
814f81ef50SGarrett Wollman #include <stdlib.h>
829b50d902SRodney W. Grimes #include <string.h>
839b50d902SRodney W. Grimes #include <unistd.h>
849b50d902SRodney W. Grimes #include "netstat.h"
859b50d902SRodney W. Grimes 
865e051718SAssar Westerlund char	*inetname (struct in_addr *);
87a01e3379SDavid Malone void	inetprint (struct in_addr *, int, const char *, int);
88cfa1ca9dSYoshinobu Inoue #ifdef INET6
89cfa1ca9dSYoshinobu Inoue static int udp_done, tcp_done;
90cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
919b50d902SRodney W. Grimes 
929b50d902SRodney W. Grimes /*
939b50d902SRodney W. Grimes  * Print a summary of connections related to an Internet
949b50d902SRodney W. Grimes  * protocol.  For TCP, also give state of connection.
959b50d902SRodney W. Grimes  * Listening processes (aflag) are suppressed unless the
969b50d902SRodney W. Grimes  * -a (all) flag is specified.
979b50d902SRodney W. Grimes  */
989b50d902SRodney W. Grimes void
995e051718SAssar Westerlund protopr(u_long proto,		/* for sysctl version we pass proto # */
100a01e3379SDavid Malone 	const char *name, int af1)
1019b50d902SRodney W. Grimes {
1029b50d902SRodney W. Grimes 	int istcp;
1039b50d902SRodney W. Grimes 	static int first = 1;
1044f81ef50SGarrett Wollman 	char *buf;
105fb5d0fbdSRuslan Ermilov 	const char *mibvar, *vchar;
106a97a9922SJulian Elischer 	struct tcpcb *tp = NULL;
1074f81ef50SGarrett Wollman 	struct inpcb *inp;
1084f81ef50SGarrett Wollman 	struct xinpgen *xig, *oxig;
1094f81ef50SGarrett Wollman 	struct xsocket *so;
1104f81ef50SGarrett Wollman 	size_t len;
1119b50d902SRodney W. Grimes 
1124f81ef50SGarrett Wollman 	istcp = 0;
1134f81ef50SGarrett Wollman 	switch (proto) {
1144f81ef50SGarrett Wollman 	case IPPROTO_TCP:
115cfa1ca9dSYoshinobu Inoue #ifdef INET6
116cfa1ca9dSYoshinobu Inoue 		if (tcp_done != 0)
117cfa1ca9dSYoshinobu Inoue 			return;
118cfa1ca9dSYoshinobu Inoue 		else
119cfa1ca9dSYoshinobu Inoue 			tcp_done = 1;
120cfa1ca9dSYoshinobu Inoue #endif
1214f81ef50SGarrett Wollman 		istcp = 1;
1224f81ef50SGarrett Wollman 		mibvar = "net.inet.tcp.pcblist";
1234f81ef50SGarrett Wollman 		break;
1244f81ef50SGarrett Wollman 	case IPPROTO_UDP:
125cfa1ca9dSYoshinobu Inoue #ifdef INET6
126cfa1ca9dSYoshinobu Inoue 		if (udp_done != 0)
127cfa1ca9dSYoshinobu Inoue 			return;
128cfa1ca9dSYoshinobu Inoue 		else
129cfa1ca9dSYoshinobu Inoue 			udp_done = 1;
130cfa1ca9dSYoshinobu Inoue #endif
1314f81ef50SGarrett Wollman 		mibvar = "net.inet.udp.pcblist";
1324f81ef50SGarrett Wollman 		break;
1334f81ef50SGarrett Wollman 	case IPPROTO_DIVERT:
1344f81ef50SGarrett Wollman 		mibvar = "net.inet.divert.pcblist";
1354f81ef50SGarrett Wollman 		break;
1364f81ef50SGarrett Wollman 	default:
1374f81ef50SGarrett Wollman 		mibvar = "net.inet.raw.pcblist";
1384f81ef50SGarrett Wollman 		break;
1394f81ef50SGarrett Wollman 	}
1404f81ef50SGarrett Wollman 	len = 0;
1414f81ef50SGarrett Wollman 	if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
1424f81ef50SGarrett Wollman 		if (errno != ENOENT)
1434f81ef50SGarrett Wollman 			warn("sysctl: %s", mibvar);
1449b50d902SRodney W. Grimes 		return;
1453aa80b1dSDavid Greenman 	}
1464f81ef50SGarrett Wollman 	if ((buf = malloc(len)) == 0) {
1476cc6f122SPhilippe Charnier 		warnx("malloc %lu bytes", (u_long)len);
1484f81ef50SGarrett Wollman 		return;
1499b50d902SRodney W. Grimes 	}
1504f81ef50SGarrett Wollman 	if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) {
1514f81ef50SGarrett Wollman 		warn("sysctl: %s", mibvar);
1524f81ef50SGarrett Wollman 		free(buf);
1534f81ef50SGarrett Wollman 		return;
1544f81ef50SGarrett Wollman 	}
1554f81ef50SGarrett Wollman 
1564f81ef50SGarrett Wollman 	oxig = xig = (struct xinpgen *)buf;
1574f81ef50SGarrett Wollman 	for (xig = (struct xinpgen *)((char *)xig + xig->xig_len);
1584f81ef50SGarrett Wollman 	     xig->xig_len > sizeof(struct xinpgen);
1594f81ef50SGarrett Wollman 	     xig = (struct xinpgen *)((char *)xig + xig->xig_len)) {
1609b50d902SRodney W. Grimes 		if (istcp) {
1614f81ef50SGarrett Wollman 			tp = &((struct xtcpcb *)xig)->xt_tp;
1624f81ef50SGarrett Wollman 			inp = &((struct xtcpcb *)xig)->xt_inp;
1634f81ef50SGarrett Wollman 			so = &((struct xtcpcb *)xig)->xt_socket;
1644f81ef50SGarrett Wollman 		} else {
1654f81ef50SGarrett Wollman 			inp = &((struct xinpcb *)xig)->xi_inp;
1664f81ef50SGarrett Wollman 			so = &((struct xinpcb *)xig)->xi_socket;
1679b50d902SRodney W. Grimes 		}
1684f81ef50SGarrett Wollman 
1694f81ef50SGarrett Wollman 		/* Ignore sockets for protocols other than the desired one. */
170f964d60dSAssar Westerlund 		if (so->xso_protocol != (int)proto)
1714f81ef50SGarrett Wollman 			continue;
1724f81ef50SGarrett Wollman 
1734f81ef50SGarrett Wollman 		/* Ignore PCBs which were freed during copyout. */
1744f81ef50SGarrett Wollman 		if (inp->inp_gencnt > oxig->xig_gen)
1754f81ef50SGarrett Wollman 			continue;
1764f81ef50SGarrett Wollman 
177a01e3379SDavid Malone 		if ((af1 == AF_INET && (inp->inp_vflag & INP_IPV4) == 0)
178cfa1ca9dSYoshinobu Inoue #ifdef INET6
179a01e3379SDavid Malone 		    || (af1 == AF_INET6 && (inp->inp_vflag & INP_IPV6) == 0)
180cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
181a01e3379SDavid Malone 		    || (af1 == AF_UNSPEC && ((inp->inp_vflag & INP_IPV4) == 0
182cfa1ca9dSYoshinobu Inoue #ifdef INET6
183cfa1ca9dSYoshinobu Inoue 					    && (inp->inp_vflag &
184cfa1ca9dSYoshinobu Inoue 						INP_IPV6) == 0
185cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
186cfa1ca9dSYoshinobu Inoue 			))
187cfa1ca9dSYoshinobu Inoue 		    )
188cfa1ca9dSYoshinobu Inoue 			continue;
189cfa1ca9dSYoshinobu Inoue 		if (!aflag &&
190cfa1ca9dSYoshinobu Inoue 		    (
1912b286cedSBruce M Simpson 		     (istcp && tp->t_state == TCPS_LISTEN)
1922b286cedSBruce M Simpson 		     || (af1 == AF_INET &&
193cfa1ca9dSYoshinobu Inoue 		      inet_lnaof(inp->inp_laddr) == INADDR_ANY)
194cfa1ca9dSYoshinobu Inoue #ifdef INET6
195a01e3379SDavid Malone 		     || (af1 == AF_INET6 &&
196cfa1ca9dSYoshinobu Inoue 			 IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
197cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
198a01e3379SDavid Malone 		     || (af1 == AF_UNSPEC &&
199cfa1ca9dSYoshinobu Inoue 			 (((inp->inp_vflag & INP_IPV4) != 0 &&
200cfa1ca9dSYoshinobu Inoue 			   inet_lnaof(inp->inp_laddr) == INADDR_ANY)
201cfa1ca9dSYoshinobu Inoue #ifdef INET6
202cfa1ca9dSYoshinobu Inoue 			  || ((inp->inp_vflag & INP_IPV6) != 0 &&
203cfa1ca9dSYoshinobu Inoue 			      IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
204cfa1ca9dSYoshinobu Inoue #endif
205cfa1ca9dSYoshinobu Inoue 			  ))
206cfa1ca9dSYoshinobu Inoue 		     ))
2074f81ef50SGarrett Wollman 			continue;
2084f81ef50SGarrett Wollman 
2099b50d902SRodney W. Grimes 		if (first) {
210ac55add0SGuido van Rooij 			if (!Lflag) {
2119b50d902SRodney W. Grimes 				printf("Active Internet connections");
2129b50d902SRodney W. Grimes 				if (aflag)
2139b50d902SRodney W. Grimes 					printf(" (including servers)");
214ac55add0SGuido van Rooij 			} else
215ac55add0SGuido van Rooij 				printf(
216ac55add0SGuido van Rooij 	"Current listen queue sizes (qlen/incqlen/maxqlen)");
2179b50d902SRodney W. Grimes 			putchar('\n');
2189b50d902SRodney W. Grimes 			if (Aflag)
2194f81ef50SGarrett Wollman 				printf("%-8.8s ", "Socket");
220ac55add0SGuido van Rooij 			if (Lflag)
221fb5d0fbdSRuslan Ermilov 				printf("%-5.5s %-14.14s %-22.22s\n",
222fb5d0fbdSRuslan Ermilov 					"Proto", "Listen", "Local Address");
223ac55add0SGuido van Rooij 			else
224080b7f49SDag-Erling Smørgrav 				printf((Aflag && !Wflag) ?
225cfa1ca9dSYoshinobu Inoue 		"%-5.5s %-6.6s %-6.6s  %-18.18s %-18.18s %s\n" :
226cfa1ca9dSYoshinobu Inoue 		"%-5.5s %-6.6s %-6.6s  %-22.22s %-22.22s %s\n",
2279b50d902SRodney W. Grimes 					"Proto", "Recv-Q", "Send-Q",
228ac55add0SGuido van Rooij 					"Local Address", "Foreign Address",
229ac55add0SGuido van Rooij 					"(state)");
2309b50d902SRodney W. Grimes 			first = 0;
2319b50d902SRodney W. Grimes 		}
232fb5d0fbdSRuslan Ermilov 		if (Lflag && so->so_qlimit == 0)
233fb5d0fbdSRuslan Ermilov 			continue;
234e4ec3989SDag-Erling Smørgrav 		if (Aflag) {
235e4ec3989SDag-Erling Smørgrav 			if (istcp)
236e4ec3989SDag-Erling Smørgrav 				printf("%8lx ", (u_long)inp->inp_ppcb);
237e4ec3989SDag-Erling Smørgrav 			else
2384f81ef50SGarrett Wollman 				printf("%8lx ", (u_long)so->so_pcb);
239e4ec3989SDag-Erling Smørgrav 		}
240cfa1ca9dSYoshinobu Inoue #ifdef INET6
241fc60ab7bSYoshinobu Inoue 		if ((inp->inp_vflag & INP_IPV6) != 0)
242fc60ab7bSYoshinobu Inoue 			vchar = ((inp->inp_vflag & INP_IPV4) != 0)
243fc60ab7bSYoshinobu Inoue 				? "46" : "6 ";
244fc60ab7bSYoshinobu Inoue 		else
245cfa1ca9dSYoshinobu Inoue #endif
246fc60ab7bSYoshinobu Inoue 		vchar = ((inp->inp_vflag & INP_IPV4) != 0)
247fc60ab7bSYoshinobu Inoue 				? "4 " : "  ";
248fb5d0fbdSRuslan Ermilov 		printf("%-3.3s%-2.2s ", name, vchar);
249fb5d0fbdSRuslan Ermilov 		if (Lflag) {
250a01e3379SDavid Malone 			char buf1[15];
251fc60ab7bSYoshinobu Inoue 
252a01e3379SDavid Malone 			snprintf(buf1, 15, "%d/%d/%d", so->so_qlen,
253fb5d0fbdSRuslan Ermilov 				 so->so_incqlen, so->so_qlimit);
254a01e3379SDavid Malone 			printf("%-14.14s ", buf1);
255fb5d0fbdSRuslan Ermilov 		} else {
256f824b518SJohn Polstra 			printf("%6u %6u  ",
257cfa1ca9dSYoshinobu Inoue 			       so->so_rcv.sb_cc,
2584f81ef50SGarrett Wollman 			       so->so_snd.sb_cc);
259fc60ab7bSYoshinobu Inoue 		}
26065ea0024SAssar Westerlund 		if (numeric_port) {
261cfa1ca9dSYoshinobu Inoue 			if (inp->inp_vflag & INP_IPV4) {
2624f81ef50SGarrett Wollman 				inetprint(&inp->inp_laddr, (int)inp->inp_lport,
2638d612dd2SPoul-Henning Kamp 					  name, 1);
264ac55add0SGuido van Rooij 				if (!Lflag)
265ac55add0SGuido van Rooij 					inetprint(&inp->inp_faddr,
266ac55add0SGuido van Rooij 						  (int)inp->inp_fport, name, 1);
267cfa1ca9dSYoshinobu Inoue 			}
268cfa1ca9dSYoshinobu Inoue #ifdef INET6
269cfa1ca9dSYoshinobu Inoue 			else if (inp->inp_vflag & INP_IPV6) {
270cfa1ca9dSYoshinobu Inoue 				inet6print(&inp->in6p_laddr,
271cfa1ca9dSYoshinobu Inoue 					   (int)inp->inp_lport, name, 1);
272ac55add0SGuido van Rooij 				if (!Lflag)
273cfa1ca9dSYoshinobu Inoue 					inet6print(&inp->in6p_faddr,
274cfa1ca9dSYoshinobu Inoue 						   (int)inp->inp_fport, name, 1);
275cfa1ca9dSYoshinobu Inoue 			} /* else nothing printed now */
276cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
2774f81ef50SGarrett Wollman 		} else if (inp->inp_flags & INP_ANONPORT) {
278cfa1ca9dSYoshinobu Inoue 			if (inp->inp_vflag & INP_IPV4) {
2794f81ef50SGarrett Wollman 				inetprint(&inp->inp_laddr, (int)inp->inp_lport,
2808d612dd2SPoul-Henning Kamp 					  name, 1);
281ac55add0SGuido van Rooij 				if (!Lflag)
282ac55add0SGuido van Rooij 					inetprint(&inp->inp_faddr,
283ac55add0SGuido van Rooij 						  (int)inp->inp_fport, name, 0);
284cfa1ca9dSYoshinobu Inoue 			}
285cfa1ca9dSYoshinobu Inoue #ifdef INET6
286cfa1ca9dSYoshinobu Inoue 			else if (inp->inp_vflag & INP_IPV6) {
287cfa1ca9dSYoshinobu Inoue 				inet6print(&inp->in6p_laddr,
288cfa1ca9dSYoshinobu Inoue 					   (int)inp->inp_lport, name, 1);
289ac55add0SGuido van Rooij 				if (!Lflag)
290cfa1ca9dSYoshinobu Inoue 					inet6print(&inp->in6p_faddr,
291cfa1ca9dSYoshinobu Inoue 						   (int)inp->inp_fport, name, 0);
292cfa1ca9dSYoshinobu Inoue 			} /* else nothing printed now */
293cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
2948d612dd2SPoul-Henning Kamp 		} else {
295cfa1ca9dSYoshinobu Inoue 			if (inp->inp_vflag & INP_IPV4) {
2964f81ef50SGarrett Wollman 				inetprint(&inp->inp_laddr, (int)inp->inp_lport,
2978d612dd2SPoul-Henning Kamp 					  name, 0);
298ac55add0SGuido van Rooij 				if (!Lflag)
299ac55add0SGuido van Rooij 					inetprint(&inp->inp_faddr,
300ac55add0SGuido van Rooij 						  (int)inp->inp_fport, name,
301ac55add0SGuido van Rooij 						  inp->inp_lport !=
302ac55add0SGuido van Rooij 							inp->inp_fport);
303cfa1ca9dSYoshinobu Inoue 			}
304cfa1ca9dSYoshinobu Inoue #ifdef INET6
305cfa1ca9dSYoshinobu Inoue 			else if (inp->inp_vflag & INP_IPV6) {
306cfa1ca9dSYoshinobu Inoue 				inet6print(&inp->in6p_laddr,
307cfa1ca9dSYoshinobu Inoue 					   (int)inp->inp_lport, name, 0);
308ac55add0SGuido van Rooij 				if (!Lflag)
309cfa1ca9dSYoshinobu Inoue 					inet6print(&inp->in6p_faddr,
310cfa1ca9dSYoshinobu Inoue 						   (int)inp->inp_fport, name,
311ac55add0SGuido van Rooij 						   inp->inp_lport !=
312ac55add0SGuido van Rooij 							inp->inp_fport);
313cfa1ca9dSYoshinobu Inoue 			} /* else nothing printed now */
314cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
3158d612dd2SPoul-Henning Kamp 		}
316ac55add0SGuido van Rooij 		if (istcp && !Lflag) {
3174f81ef50SGarrett Wollman 			if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES)
3184f81ef50SGarrett Wollman 				printf("%d", tp->t_state);
3199a94a597SGarrett Wollman                       else {
3204f81ef50SGarrett Wollman 				printf("%s", tcpstates[tp->t_state]);
321513822ddSAdam David #if defined(TF_NEEDSYN) && defined(TF_NEEDFIN)
3229a94a597SGarrett Wollman                               /* Show T/TCP `hidden state' */
3234f81ef50SGarrett Wollman                               if (tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN))
3249a94a597SGarrett Wollman                                       putchar('*');
325513822ddSAdam David #endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */
3269a94a597SGarrett Wollman                       }
3279b50d902SRodney W. Grimes 		}
3289b50d902SRodney W. Grimes 		putchar('\n');
3299b50d902SRodney W. Grimes 	}
3304f81ef50SGarrett Wollman 	if (xig != oxig && xig->xig_gen != oxig->xig_gen) {
3314f81ef50SGarrett Wollman 		if (oxig->xig_count > xig->xig_count) {
3324f81ef50SGarrett Wollman 			printf("Some %s sockets may have been deleted.\n",
3334f81ef50SGarrett Wollman 			       name);
3344f81ef50SGarrett Wollman 		} else if (oxig->xig_count < xig->xig_count) {
3354f81ef50SGarrett Wollman 			printf("Some %s sockets may have been created.\n",
3364f81ef50SGarrett Wollman 			       name);
3374f81ef50SGarrett Wollman 		} else {
338eb6fe0d9SMax Khon 			printf("Some %s sockets may have been created or deleted.\n",
3394f81ef50SGarrett Wollman 			       name);
3404f81ef50SGarrett Wollman 		}
3414f81ef50SGarrett Wollman 	}
3424f81ef50SGarrett Wollman 	free(buf);
3439b50d902SRodney W. Grimes }
3449b50d902SRodney W. Grimes 
3459b50d902SRodney W. Grimes /*
3469b50d902SRodney W. Grimes  * Dump TCP statistics structure.
3479b50d902SRodney W. Grimes  */
3489b50d902SRodney W. Grimes void
349a01e3379SDavid Malone tcp_stats(u_long off __unused, const char *name, int af1 __unused)
3509b50d902SRodney W. Grimes {
351c73d99b5SRuslan Ermilov 	struct tcpstat tcpstat, zerostat;
3524f81ef50SGarrett Wollman 	size_t len = sizeof tcpstat;
3539b50d902SRodney W. Grimes 
354c73d99b5SRuslan Ermilov 	if (zflag)
355c73d99b5SRuslan Ermilov 		memset(&zerostat, 0, len);
356c73d99b5SRuslan Ermilov 	if (sysctlbyname("net.inet.tcp.stats", &tcpstat, &len,
357c73d99b5SRuslan Ermilov 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
3584f81ef50SGarrett Wollman 		warn("sysctl: net.inet.tcp.stats");
3599b50d902SRodney W. Grimes 		return;
3604f81ef50SGarrett Wollman 	}
3614f81ef50SGarrett Wollman 
362cfa1ca9dSYoshinobu Inoue #ifdef INET6
363cfa1ca9dSYoshinobu Inoue 	if (tcp_done != 0)
364cfa1ca9dSYoshinobu Inoue 		return;
365cfa1ca9dSYoshinobu Inoue 	else
366cfa1ca9dSYoshinobu Inoue 		tcp_done = 1;
367cfa1ca9dSYoshinobu Inoue #endif
368cfa1ca9dSYoshinobu Inoue 
3699b50d902SRodney W. Grimes 	printf ("%s:\n", name);
3709b50d902SRodney W. Grimes 
3719b50d902SRodney W. Grimes #define	p(f, m) if (tcpstat.f || sflag <= 1) \
3729b50d902SRodney W. Grimes     printf(m, tcpstat.f, plural(tcpstat.f))
37322694ebaSBruce Evans #define	p1a(f, m) if (tcpstat.f || sflag <= 1) \
37422694ebaSBruce Evans     printf(m, tcpstat.f)
3759b50d902SRodney W. Grimes #define	p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
3769b50d902SRodney W. Grimes     printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2))
37722694ebaSBruce Evans #define	p2a(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
37822694ebaSBruce Evans     printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2)
3799b50d902SRodney W. Grimes #define	p3(f, m) if (tcpstat.f || sflag <= 1) \
3809b50d902SRodney W. Grimes     printf(m, tcpstat.f, plurales(tcpstat.f))
3819b50d902SRodney W. Grimes 
382e1fb4daaSPaul Traina 	p(tcps_sndtotal, "\t%lu packet%s sent\n");
3839b50d902SRodney W. Grimes 	p2(tcps_sndpack,tcps_sndbyte,
384e1fb4daaSPaul Traina 		"\t\t%lu data packet%s (%lu byte%s)\n");
3859b50d902SRodney W. Grimes 	p2(tcps_sndrexmitpack, tcps_sndrexmitbyte,
386e1fb4daaSPaul Traina 		"\t\t%lu data packet%s (%lu byte%s) retransmitted\n");
387d65bf08aSMatthew Dillon 	p(tcps_sndrexmitbad,
388d65bf08aSMatthew Dillon 		"\t\t%lu data packet%s unnecessarily retransmitted\n");
389e1fb4daaSPaul Traina 	p(tcps_mturesent, "\t\t%lu resend%s initiated by MTU discovery\n");
39022694ebaSBruce Evans 	p2a(tcps_sndacks, tcps_delack,
391e1fb4daaSPaul Traina 		"\t\t%lu ack-only packet%s (%lu delayed)\n");
392e1fb4daaSPaul Traina 	p(tcps_sndurg, "\t\t%lu URG only packet%s\n");
393e1fb4daaSPaul Traina 	p(tcps_sndprobe, "\t\t%lu window probe packet%s\n");
394e1fb4daaSPaul Traina 	p(tcps_sndwinup, "\t\t%lu window update packet%s\n");
395e1fb4daaSPaul Traina 	p(tcps_sndctrl, "\t\t%lu control packet%s\n");
396e1fb4daaSPaul Traina 	p(tcps_rcvtotal, "\t%lu packet%s received\n");
397e1fb4daaSPaul Traina 	p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%lu ack%s (for %lu byte%s)\n");
398e1fb4daaSPaul Traina 	p(tcps_rcvdupack, "\t\t%lu duplicate ack%s\n");
399e1fb4daaSPaul Traina 	p(tcps_rcvacktoomuch, "\t\t%lu ack%s for unsent data\n");
4009b50d902SRodney W. Grimes 	p2(tcps_rcvpack, tcps_rcvbyte,
401e1fb4daaSPaul Traina 		"\t\t%lu packet%s (%lu byte%s) received in-sequence\n");
4029b50d902SRodney W. Grimes 	p2(tcps_rcvduppack, tcps_rcvdupbyte,
403e1fb4daaSPaul Traina 		"\t\t%lu completely duplicate packet%s (%lu byte%s)\n");
404e1fb4daaSPaul Traina 	p(tcps_pawsdrop, "\t\t%lu old duplicate packet%s\n");
4059b50d902SRodney W. Grimes 	p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte,
406e1fb4daaSPaul Traina 		"\t\t%lu packet%s with some dup. data (%lu byte%s duped)\n");
4079b50d902SRodney W. Grimes 	p2(tcps_rcvoopack, tcps_rcvoobyte,
408e1fb4daaSPaul Traina 		"\t\t%lu out-of-order packet%s (%lu byte%s)\n");
4099b50d902SRodney W. Grimes 	p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin,
410e1fb4daaSPaul Traina 		"\t\t%lu packet%s (%lu byte%s) of data after window\n");
411e1fb4daaSPaul Traina 	p(tcps_rcvwinprobe, "\t\t%lu window probe%s\n");
412e1fb4daaSPaul Traina 	p(tcps_rcvwinupd, "\t\t%lu window update packet%s\n");
413e1fb4daaSPaul Traina 	p(tcps_rcvafterclose, "\t\t%lu packet%s received after close\n");
414e1fb4daaSPaul Traina 	p(tcps_rcvbadsum, "\t\t%lu discarded for bad checksum%s\n");
415e1fb4daaSPaul Traina 	p(tcps_rcvbadoff, "\t\t%lu discarded for bad header offset field%s\n");
41622694ebaSBruce Evans 	p1a(tcps_rcvshort, "\t\t%lu discarded because packet too short\n");
417e1fb4daaSPaul Traina 	p(tcps_connattempt, "\t%lu connection request%s\n");
418e1fb4daaSPaul Traina 	p(tcps_accepts, "\t%lu connection accept%s\n");
419e1fb4daaSPaul Traina 	p(tcps_badsyn, "\t%lu bad connection attempt%s\n");
420e1fb4daaSPaul Traina 	p(tcps_listendrop, "\t%lu listen queue overflow%s\n");
42101d3e1c0SRuslan Ermilov 	p(tcps_badrst, "\t%lu ignored RSTs in the window%s\n");
422e1fb4daaSPaul Traina 	p(tcps_connects, "\t%lu connection%s established (including accepts)\n");
4239b50d902SRodney W. Grimes 	p2(tcps_closed, tcps_drops,
424e1fb4daaSPaul Traina 		"\t%lu connection%s closed (including %lu drop%s)\n");
425e1fb4daaSPaul Traina 	p(tcps_cachedrtt, "\t\t%lu connection%s updated cached RTT on close\n");
426861b1828SGarrett Wollman 	p(tcps_cachedrttvar,
427e1fb4daaSPaul Traina 	  "\t\t%lu connection%s updated cached RTT variance on close\n");
428861b1828SGarrett Wollman 	p(tcps_cachedssthresh,
429e1fb4daaSPaul Traina 	  "\t\t%lu connection%s updated cached ssthresh on close\n");
430e1fb4daaSPaul Traina 	p(tcps_conndrops, "\t%lu embryonic connection%s dropped\n");
4319b50d902SRodney W. Grimes 	p2(tcps_rttupdated, tcps_segstimed,
432e1fb4daaSPaul Traina 		"\t%lu segment%s updated rtt (of %lu attempt%s)\n");
433e1fb4daaSPaul Traina 	p(tcps_rexmttimeo, "\t%lu retransmit timeout%s\n");
434e1fb4daaSPaul Traina 	p(tcps_timeoutdrop, "\t\t%lu connection%s dropped by rexmit timeout\n");
435e1fb4daaSPaul Traina 	p(tcps_persisttimeo, "\t%lu persist timeout%s\n");
436e1fb4daaSPaul Traina 	p(tcps_persistdrop, "\t\t%lu connection%s dropped by persist timeout\n");
437e1fb4daaSPaul Traina 	p(tcps_keeptimeo, "\t%lu keepalive timeout%s\n");
438e1fb4daaSPaul Traina 	p(tcps_keepprobe, "\t\t%lu keepalive probe%s sent\n");
439e1fb4daaSPaul Traina 	p(tcps_keepdrops, "\t\t%lu connection%s dropped by keepalive\n");
440e1fb4daaSPaul Traina 	p(tcps_predack, "\t%lu correct ACK header prediction%s\n");
441e1fb4daaSPaul Traina 	p(tcps_preddat, "\t%lu correct data packet header prediction%s\n");
44260a31b3aSJonathan Lemon 
443a01e3379SDavid Malone 	p(tcps_sc_added, "\t%lu syncache entrie%s added\n");
444a01e3379SDavid Malone 	p1a(tcps_sc_retransmitted, "\t\t%lu retransmitted\n");
445a01e3379SDavid Malone 	p1a(tcps_sc_dupsyn, "\t\t%lu dupsyn\n");
446a01e3379SDavid Malone 	p1a(tcps_sc_dropped, "\t\t%lu dropped\n");
447a01e3379SDavid Malone 	p1a(tcps_sc_completed, "\t\t%lu completed\n");
448a01e3379SDavid Malone 	p1a(tcps_sc_bucketoverflow, "\t\t%lu bucket overflow\n");
449a01e3379SDavid Malone 	p1a(tcps_sc_cacheoverflow, "\t\t%lu cache overflow\n");
450a01e3379SDavid Malone 	p1a(tcps_sc_reset, "\t\t%lu reset\n");
451a01e3379SDavid Malone 	p1a(tcps_sc_stale, "\t\t%lu stale\n");
452a01e3379SDavid Malone 	p1a(tcps_sc_aborted, "\t\t%lu aborted\n");
453a01e3379SDavid Malone 	p1a(tcps_sc_badack, "\t\t%lu badack\n");
454a01e3379SDavid Malone 	p1a(tcps_sc_unreach, "\t\t%lu unreach\n");
455a01e3379SDavid Malone 	p(tcps_sc_zonefail, "\t\t%lu zone failure%s\n");
456a01e3379SDavid Malone 	p(tcps_sc_sendcookie, "\t%lu cookie%s sent\n");
457a01e3379SDavid Malone 	p(tcps_sc_recvcookie, "\t%lu cookie%s received\n");
458b6101dafSPaul Saab 
459b6101dafSPaul Saab 	p(tcps_sack_recovery_episode, "\t%lu SACK recovery episode%s\n");
460b6101dafSPaul Saab 	p(tcps_sack_rexmits,
461b6101dafSPaul Saab 		"\t%lu segment rexmit%s in SACK recovery episodes\n");
462b6101dafSPaul Saab 	p(tcps_sack_rexmit_bytes,
463b6101dafSPaul Saab 		"\t%lu byte rexmit%s in SACK recovery episodes\n");
464b6101dafSPaul Saab 	p(tcps_sack_rcv_blocks,
465b6101dafSPaul Saab 		"\t%lu SACK option%s (SACK blocks) received\n");
466b6101dafSPaul Saab 	p(tcps_sack_send_blocks, "\t%lu SACK option%s (SACK blocks) sent\n");
467b6101dafSPaul Saab 
4689b50d902SRodney W. Grimes #undef p
46922694ebaSBruce Evans #undef p1a
4709b50d902SRodney W. Grimes #undef p2
47122694ebaSBruce Evans #undef p2a
4729b50d902SRodney W. Grimes #undef p3
4739b50d902SRodney W. Grimes }
4749b50d902SRodney W. Grimes 
4759b50d902SRodney W. Grimes /*
4769b50d902SRodney W. Grimes  * Dump UDP statistics structure.
4779b50d902SRodney W. Grimes  */
4789b50d902SRodney W. Grimes void
479a01e3379SDavid Malone udp_stats(u_long off __unused, const char *name, int af1 __unused)
4809b50d902SRodney W. Grimes {
481c73d99b5SRuslan Ermilov 	struct udpstat udpstat, zerostat;
4824f81ef50SGarrett Wollman 	size_t len = sizeof udpstat;
4839b50d902SRodney W. Grimes 	u_long delivered;
4849b50d902SRodney W. Grimes 
485c73d99b5SRuslan Ermilov 	if (zflag)
486c73d99b5SRuslan Ermilov 		memset(&zerostat, 0, len);
487c73d99b5SRuslan Ermilov 	if (sysctlbyname("net.inet.udp.stats", &udpstat, &len,
488c73d99b5SRuslan Ermilov 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
4894f81ef50SGarrett Wollman 		warn("sysctl: net.inet.udp.stats");
4909b50d902SRodney W. Grimes 		return;
4914f81ef50SGarrett Wollman 	}
4924f81ef50SGarrett Wollman 
493cfa1ca9dSYoshinobu Inoue #ifdef INET6
494cfa1ca9dSYoshinobu Inoue 	if (udp_done != 0)
495cfa1ca9dSYoshinobu Inoue 		return;
496cfa1ca9dSYoshinobu Inoue 	else
497cfa1ca9dSYoshinobu Inoue 		udp_done = 1;
498cfa1ca9dSYoshinobu Inoue #endif
499cfa1ca9dSYoshinobu Inoue 
5009b50d902SRodney W. Grimes 	printf("%s:\n", name);
5019b50d902SRodney W. Grimes #define	p(f, m) if (udpstat.f || sflag <= 1) \
5029b50d902SRodney W. Grimes     printf(m, udpstat.f, plural(udpstat.f))
50322694ebaSBruce Evans #define	p1a(f, m) if (udpstat.f || sflag <= 1) \
50422694ebaSBruce Evans     printf(m, udpstat.f)
5057d56c0eeSAlexander Langer 	p(udps_ipackets, "\t%lu datagram%s received\n");
50622694ebaSBruce Evans 	p1a(udps_hdrops, "\t%lu with incomplete header\n");
50722694ebaSBruce Evans 	p1a(udps_badlen, "\t%lu with bad data length field\n");
50822694ebaSBruce Evans 	p1a(udps_badsum, "\t%lu with bad checksum\n");
509fb9aaba0SRuslan Ermilov 	p1a(udps_nosum, "\t%lu with no checksum\n");
51022694ebaSBruce Evans 	p1a(udps_noport, "\t%lu dropped due to no socket\n");
51122694ebaSBruce Evans 	p(udps_noportbcast,
51222694ebaSBruce Evans 	    "\t%lu broadcast/multicast datagram%s dropped due to no socket\n");
51322694ebaSBruce Evans 	p1a(udps_fullsock, "\t%lu dropped due to full socket buffers\n");
51422694ebaSBruce Evans 	p1a(udpps_pcbhashmiss, "\t%lu not for hashed pcb\n");
5159b50d902SRodney W. Grimes 	delivered = udpstat.udps_ipackets -
5169b50d902SRodney W. Grimes 		    udpstat.udps_hdrops -
5179b50d902SRodney W. Grimes 		    udpstat.udps_badlen -
5189b50d902SRodney W. Grimes 		    udpstat.udps_badsum -
5199b50d902SRodney W. Grimes 		    udpstat.udps_noport -
5209b50d902SRodney W. Grimes 		    udpstat.udps_noportbcast -
5219b50d902SRodney W. Grimes 		    udpstat.udps_fullsock;
5229b50d902SRodney W. Grimes 	if (delivered || sflag <= 1)
5237d56c0eeSAlexander Langer 		printf("\t%lu delivered\n", delivered);
5247d56c0eeSAlexander Langer 	p(udps_opackets, "\t%lu datagram%s output\n");
5259b50d902SRodney W. Grimes #undef p
52622694ebaSBruce Evans #undef p1a
5279b50d902SRodney W. Grimes }
5289b50d902SRodney W. Grimes 
5299b50d902SRodney W. Grimes /*
530a9771948SGleb Smirnoff  * Dump CARP statistics structure.
531a9771948SGleb Smirnoff  */
532a9771948SGleb Smirnoff void
533a9771948SGleb Smirnoff carp_stats(u_long off, const char *name, int af1 __unused)
534a9771948SGleb Smirnoff {
535a9771948SGleb Smirnoff 	struct carpstats carpstat, zerostat;
536a9771948SGleb Smirnoff 	size_t len = sizeof(struct carpstats);
537a9771948SGleb Smirnoff 
538a9771948SGleb Smirnoff 	if (zflag)
539a9771948SGleb Smirnoff 		memset(&zerostat, 0, len);
540a9771948SGleb Smirnoff 	if (sysctlbyname("net.inet.carp.stats", &carpstat, &len,
541a9771948SGleb Smirnoff 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
542a9771948SGleb Smirnoff 		warn("sysctl: net.inet.carp.stats");
543a9771948SGleb Smirnoff 		return;
544a9771948SGleb Smirnoff 	}
545a9771948SGleb Smirnoff 
546a9771948SGleb Smirnoff 	printf("%s:\n", name);
547a9771948SGleb Smirnoff 
548a9771948SGleb Smirnoff #define p(f, m) if (carpstat.f || sflag <= 1) \
549a9771948SGleb Smirnoff 	printf(m, (unsigned long long)carpstat.f, plural((int)carpstat.f))
550a9771948SGleb Smirnoff #define p2(f, m) if (carpstat.f || sflag <= 1) \
551a9771948SGleb Smirnoff 	printf(m, (unsigned long long)carpstat.f)
552a9771948SGleb Smirnoff 
553a9771948SGleb Smirnoff 	p(carps_ipackets, "\t%llu packet%s received (IPv4)\n");
554a9771948SGleb Smirnoff 	p(carps_ipackets6, "\t%llu packet%s received (IPv6)\n");
555a9771948SGleb Smirnoff 	p(carps_badttl, "\t\t%llu packet%s discarded for wrong TTL\n");
556a9771948SGleb Smirnoff 	p(carps_hdrops, "\t\t%llu packet%s shorter than header\n");
557a9771948SGleb Smirnoff 	p(carps_badsum, "\t\t%llu discarded for bad checksum%s\n");
558a9771948SGleb Smirnoff 	p(carps_badver,	"\t\t%llu discarded packet%s with a bad version\n");
559a9771948SGleb Smirnoff 	p2(carps_badlen, "\t\t%llu discarded because packet too short\n");
560a9771948SGleb Smirnoff 	p2(carps_badauth, "\t\t%llu discarded for bad authentication\n");
561a9771948SGleb Smirnoff 	p2(carps_badvhid, "\t\t%llu discarded for bad vhid\n");
562a9771948SGleb Smirnoff 	p2(carps_badaddrs, "\t\t%llu discarded because of a bad address list\n");
563a9771948SGleb Smirnoff 	p(carps_opackets, "\t%llu packet%s sent (IPv4)\n");
564a9771948SGleb Smirnoff 	p(carps_opackets6, "\t%llu packet%s sent (IPv6)\n");
565a9771948SGleb Smirnoff 	p2(carps_onomem, "\t\t%llu send failed due to mbuf memory error\n");
566a9771948SGleb Smirnoff #if notyet
567a9771948SGleb Smirnoff 	p(carps_ostates, "\t\t%s state update%s sent\n");
568a9771948SGleb Smirnoff #endif
569a9771948SGleb Smirnoff #undef p
570a9771948SGleb Smirnoff #undef p2
571a9771948SGleb Smirnoff }
572a9771948SGleb Smirnoff 
573a9771948SGleb Smirnoff /*
5749b50d902SRodney W. Grimes  * Dump IP statistics structure.
5759b50d902SRodney W. Grimes  */
5769b50d902SRodney W. Grimes void
577a01e3379SDavid Malone ip_stats(u_long off __unused, const char *name, int af1 __unused)
5789b50d902SRodney W. Grimes {
579c73d99b5SRuslan Ermilov 	struct ipstat ipstat, zerostat;
5804f81ef50SGarrett Wollman 	size_t len = sizeof ipstat;
5819b50d902SRodney W. Grimes 
582c73d99b5SRuslan Ermilov 	if (zflag)
583c73d99b5SRuslan Ermilov 		memset(&zerostat, 0, len);
584c73d99b5SRuslan Ermilov 	if (sysctlbyname("net.inet.ip.stats", &ipstat, &len,
585c73d99b5SRuslan Ermilov 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
5864f81ef50SGarrett Wollman 		warn("sysctl: net.inet.ip.stats");
5879b50d902SRodney W. Grimes 		return;
5884f81ef50SGarrett Wollman 	}
5894f81ef50SGarrett Wollman 
5909b50d902SRodney W. Grimes 	printf("%s:\n", name);
5919b50d902SRodney W. Grimes 
5929b50d902SRodney W. Grimes #define	p(f, m) if (ipstat.f || sflag <= 1) \
5939b50d902SRodney W. Grimes     printf(m, ipstat.f, plural(ipstat.f))
59422694ebaSBruce Evans #define	p1a(f, m) if (ipstat.f || sflag <= 1) \
59522694ebaSBruce Evans     printf(m, ipstat.f)
5969b50d902SRodney W. Grimes 
5977d56c0eeSAlexander Langer 	p(ips_total, "\t%lu total packet%s received\n");
5987d56c0eeSAlexander Langer 	p(ips_badsum, "\t%lu bad header checksum%s\n");
59922694ebaSBruce Evans 	p1a(ips_toosmall, "\t%lu with size smaller than minimum\n");
60022694ebaSBruce Evans 	p1a(ips_tooshort, "\t%lu with data size < data length\n");
601cfa1ca9dSYoshinobu Inoue 	p1a(ips_toolong, "\t%lu with ip length > max ip packet size\n");
60222694ebaSBruce Evans 	p1a(ips_badhlen, "\t%lu with header length < data size\n");
60322694ebaSBruce Evans 	p1a(ips_badlen, "\t%lu with data length < header length\n");
60422694ebaSBruce Evans 	p1a(ips_badoptions, "\t%lu with bad options\n");
60522694ebaSBruce Evans 	p1a(ips_badvers, "\t%lu with incorrect version number\n");
6067d56c0eeSAlexander Langer 	p(ips_fragments, "\t%lu fragment%s received\n");
6077d56c0eeSAlexander Langer 	p(ips_fragdropped, "\t%lu fragment%s dropped (dup or out of space)\n");
6087d56c0eeSAlexander Langer 	p(ips_fragtimeout, "\t%lu fragment%s dropped after timeout\n");
6097d56c0eeSAlexander Langer 	p(ips_reassembled, "\t%lu packet%s reassembled ok\n");
6107d56c0eeSAlexander Langer 	p(ips_delivered, "\t%lu packet%s for this host\n");
6117d56c0eeSAlexander Langer 	p(ips_noproto, "\t%lu packet%s for unknown/unsupported protocol\n");
612958d6f7fSPierre Beyssac 	p(ips_forward, "\t%lu packet%s forwarded");
613958d6f7fSPierre Beyssac 	p(ips_fastforward, " (%lu packet%s fast forwarded)");
614958d6f7fSPierre Beyssac 	if (ipstat.ips_forward || sflag <= 1)
615958d6f7fSPierre Beyssac 		putchar('\n');
6167d56c0eeSAlexander Langer 	p(ips_cantforward, "\t%lu packet%s not forwardable\n");
617a5969f5fSGarrett Wollman 	p(ips_notmember,
618a5969f5fSGarrett Wollman 	  "\t%lu packet%s received for unknown multicast group\n");
6197d56c0eeSAlexander Langer 	p(ips_redirectsent, "\t%lu redirect%s sent\n");
6207d56c0eeSAlexander Langer 	p(ips_localout, "\t%lu packet%s sent from this host\n");
6217d56c0eeSAlexander Langer 	p(ips_rawout, "\t%lu packet%s sent with fabricated ip header\n");
622a5969f5fSGarrett Wollman 	p(ips_odropped,
623a5969f5fSGarrett Wollman 	  "\t%lu output packet%s dropped due to no bufs, etc.\n");
6247d56c0eeSAlexander Langer 	p(ips_noroute, "\t%lu output packet%s discarded due to no route\n");
6257d56c0eeSAlexander Langer 	p(ips_fragmented, "\t%lu output datagram%s fragmented\n");
6267d56c0eeSAlexander Langer 	p(ips_ofragments, "\t%lu fragment%s created\n");
6277d56c0eeSAlexander Langer 	p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n");
628cfa1ca9dSYoshinobu Inoue 	p(ips_nogif, "\t%lu tunneling packet%s that can't find gif\n");
62933841545SHajimu UMEMOTO 	p(ips_badaddr, "\t%lu datagram%s with bad address in header\n");
6309b50d902SRodney W. Grimes #undef p
63122694ebaSBruce Evans #undef p1a
6329b50d902SRodney W. Grimes }
6339b50d902SRodney W. Grimes 
634a01e3379SDavid Malone static	const char *icmpnames[] = {
6359b50d902SRodney W. Grimes 	"echo reply",
6369b50d902SRodney W. Grimes 	"#1",
6379b50d902SRodney W. Grimes 	"#2",
6389b50d902SRodney W. Grimes 	"destination unreachable",
6399b50d902SRodney W. Grimes 	"source quench",
6409b50d902SRodney W. Grimes 	"routing redirect",
6419b50d902SRodney W. Grimes 	"#6",
6429b50d902SRodney W. Grimes 	"#7",
6439b50d902SRodney W. Grimes 	"echo",
6447b46dd00SGarrett Wollman 	"router advertisement",
6457b46dd00SGarrett Wollman 	"router solicitation",
6469b50d902SRodney W. Grimes 	"time exceeded",
6479b50d902SRodney W. Grimes 	"parameter problem",
6489b50d902SRodney W. Grimes 	"time stamp",
6499b50d902SRodney W. Grimes 	"time stamp reply",
6509b50d902SRodney W. Grimes 	"information request",
6519b50d902SRodney W. Grimes 	"information request reply",
6529b50d902SRodney W. Grimes 	"address mask request",
6539b50d902SRodney W. Grimes 	"address mask reply",
6549b50d902SRodney W. Grimes };
6559b50d902SRodney W. Grimes 
6569b50d902SRodney W. Grimes /*
6579b50d902SRodney W. Grimes  * Dump ICMP statistics.
6589b50d902SRodney W. Grimes  */
6599b50d902SRodney W. Grimes void
660a01e3379SDavid Malone icmp_stats(u_long off __unused, const char *name, int af1 __unused)
6619b50d902SRodney W. Grimes {
662c73d99b5SRuslan Ermilov 	struct icmpstat icmpstat, zerostat;
6634e00c309SGarrett Wollman 	int i, first;
6644e00c309SGarrett Wollman 	int mib[4];		/* CTL_NET + PF_INET + IPPROTO_ICMP + req */
6654e00c309SGarrett Wollman 	size_t len;
6669b50d902SRodney W. Grimes 
6674e00c309SGarrett Wollman 	mib[0] = CTL_NET;
6684e00c309SGarrett Wollman 	mib[1] = PF_INET;
6694e00c309SGarrett Wollman 	mib[2] = IPPROTO_ICMP;
6704e00c309SGarrett Wollman 	mib[3] = ICMPCTL_STATS;
6714e00c309SGarrett Wollman 
6724e00c309SGarrett Wollman 	len = sizeof icmpstat;
673c73d99b5SRuslan Ermilov 	if (zflag)
674c73d99b5SRuslan Ermilov 		memset(&zerostat, 0, len);
675c73d99b5SRuslan Ermilov 	if (sysctl(mib, 4, &icmpstat, &len,
676c73d99b5SRuslan Ermilov 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
677c73d99b5SRuslan Ermilov 		warn("sysctl: net.inet.icmp.stats");
678c73d99b5SRuslan Ermilov 		return;
679c73d99b5SRuslan Ermilov 	}
6804e00c309SGarrett Wollman 
6819b50d902SRodney W. Grimes 	printf("%s:\n", name);
6829b50d902SRodney W. Grimes 
6839b50d902SRodney W. Grimes #define	p(f, m) if (icmpstat.f || sflag <= 1) \
6849b50d902SRodney W. Grimes     printf(m, icmpstat.f, plural(icmpstat.f))
68522694ebaSBruce Evans #define	p1a(f, m) if (icmpstat.f || sflag <= 1) \
68622694ebaSBruce Evans     printf(m, icmpstat.f)
687bd714208SRuslan Ermilov #define	p2(f, m) if (icmpstat.f || sflag <= 1) \
688bd714208SRuslan Ermilov     printf(m, icmpstat.f, plurales(icmpstat.f))
6899b50d902SRodney W. Grimes 
6907d56c0eeSAlexander Langer 	p(icps_error, "\t%lu call%s to icmp_error\n");
6919b50d902SRodney W. Grimes 	p(icps_oldicmp,
692f99a4046SMike Makonnen 	    "\t%lu error%s not generated in response to an icmp message\n");
6939b50d902SRodney W. Grimes 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
6949b50d902SRodney W. Grimes 		if (icmpstat.icps_outhist[i] != 0) {
6959b50d902SRodney W. Grimes 			if (first) {
6969b50d902SRodney W. Grimes 				printf("\tOutput histogram:\n");
6979b50d902SRodney W. Grimes 				first = 0;
6989b50d902SRodney W. Grimes 			}
6997d56c0eeSAlexander Langer 			printf("\t\t%s: %lu\n", icmpnames[i],
7009b50d902SRodney W. Grimes 				icmpstat.icps_outhist[i]);
7019b50d902SRodney W. Grimes 		}
7027d56c0eeSAlexander Langer 	p(icps_badcode, "\t%lu message%s with bad code fields\n");
7037d56c0eeSAlexander Langer 	p(icps_tooshort, "\t%lu message%s < minimum length\n");
7047d56c0eeSAlexander Langer 	p(icps_checksum, "\t%lu bad checksum%s\n");
7057d56c0eeSAlexander Langer 	p(icps_badlen, "\t%lu message%s with bad length\n");
70622694ebaSBruce Evans 	p1a(icps_bmcastecho, "\t%lu multicast echo requests ignored\n");
70722694ebaSBruce Evans 	p1a(icps_bmcasttstamp, "\t%lu multicast timestamp requests ignored\n");
7089b50d902SRodney W. Grimes 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
7099b50d902SRodney W. Grimes 		if (icmpstat.icps_inhist[i] != 0) {
7109b50d902SRodney W. Grimes 			if (first) {
7119b50d902SRodney W. Grimes 				printf("\tInput histogram:\n");
7129b50d902SRodney W. Grimes 				first = 0;
7139b50d902SRodney W. Grimes 			}
7147d56c0eeSAlexander Langer 			printf("\t\t%s: %lu\n", icmpnames[i],
7159b50d902SRodney W. Grimes 				icmpstat.icps_inhist[i]);
7169b50d902SRodney W. Grimes 		}
7177d56c0eeSAlexander Langer 	p(icps_reflect, "\t%lu message response%s generated\n");
718bd714208SRuslan Ermilov 	p2(icps_badaddr, "\t%lu invalid return address%s\n");
7190237ca7bSRuslan Ermilov 	p(icps_noroute, "\t%lu no return route%s\n");
7209b50d902SRodney W. Grimes #undef p
72122694ebaSBruce Evans #undef p1a
722bd714208SRuslan Ermilov #undef p2
7234e00c309SGarrett Wollman 	mib[3] = ICMPCTL_MASKREPL;
7244e00c309SGarrett Wollman 	len = sizeof i;
7254e00c309SGarrett Wollman 	if (sysctl(mib, 4, &i, &len, (void *)0, 0) < 0)
7264e00c309SGarrett Wollman 		return;
7274e00c309SGarrett Wollman 	printf("\tICMP address mask responses are %sabled\n",
7284e00c309SGarrett Wollman 	       i ? "en" : "dis");
7299b50d902SRodney W. Grimes }
7309b50d902SRodney W. Grimes 
7319b50d902SRodney W. Grimes /*
7329b50d902SRodney W. Grimes  * Dump IGMP statistics structure.
7339b50d902SRodney W. Grimes  */
7349b50d902SRodney W. Grimes void
735a01e3379SDavid Malone igmp_stats(u_long off __unused, const char *name, int af1 __unused)
7369b50d902SRodney W. Grimes {
737c73d99b5SRuslan Ermilov 	struct igmpstat igmpstat, zerostat;
7384f81ef50SGarrett Wollman 	size_t len = sizeof igmpstat;
7399b50d902SRodney W. Grimes 
740c73d99b5SRuslan Ermilov 	if (zflag)
741c73d99b5SRuslan Ermilov 		memset(&zerostat, 0, len);
742c73d99b5SRuslan Ermilov 	if (sysctlbyname("net.inet.igmp.stats", &igmpstat, &len,
743c73d99b5SRuslan Ermilov 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
7444f81ef50SGarrett Wollman 		warn("sysctl: net.inet.igmp.stats");
7459b50d902SRodney W. Grimes 		return;
7464f81ef50SGarrett Wollman 	}
7474f81ef50SGarrett Wollman 
7489b50d902SRodney W. Grimes 	printf("%s:\n", name);
7499b50d902SRodney W. Grimes 
7509b50d902SRodney W. Grimes #define	p(f, m) if (igmpstat.f || sflag <= 1) \
7519b50d902SRodney W. Grimes     printf(m, igmpstat.f, plural(igmpstat.f))
7529b50d902SRodney W. Grimes #define	py(f, m) if (igmpstat.f || sflag <= 1) \
7539b50d902SRodney W. Grimes     printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y")
7549b50d902SRodney W. Grimes 	p(igps_rcv_total, "\t%u message%s received\n");
7559b50d902SRodney W. Grimes         p(igps_rcv_tooshort, "\t%u message%s received with too few bytes\n");
7569b50d902SRodney W. Grimes         p(igps_rcv_badsum, "\t%u message%s received with bad checksum\n");
7579b50d902SRodney W. Grimes         py(igps_rcv_queries, "\t%u membership quer%s received\n");
7589b50d902SRodney W. Grimes         py(igps_rcv_badqueries, "\t%u membership quer%s received with invalid field(s)\n");
7599b50d902SRodney W. Grimes         p(igps_rcv_reports, "\t%u membership report%s received\n");
7609b50d902SRodney W. Grimes         p(igps_rcv_badreports, "\t%u membership report%s received with invalid field(s)\n");
7619b50d902SRodney W. Grimes         p(igps_rcv_ourreports, "\t%u membership report%s received for groups to which we belong\n");
7629b50d902SRodney W. Grimes         p(igps_snd_reports, "\t%u membership report%s sent\n");
7639b50d902SRodney W. Grimes #undef p
7649b50d902SRodney W. Grimes #undef py
7659b50d902SRodney W. Grimes }
7669b50d902SRodney W. Grimes 
7679b50d902SRodney W. Grimes /*
768c7b9b5bbSJeffrey Hsu  * Dump PIM statistics structure.
769c7b9b5bbSJeffrey Hsu  */
770c7b9b5bbSJeffrey Hsu void
771c7b9b5bbSJeffrey Hsu pim_stats(u_long off __unused, const char *name, int af1 __unused)
772c7b9b5bbSJeffrey Hsu {
773c7b9b5bbSJeffrey Hsu 	struct pimstat pimstat, zerostat;
774c7b9b5bbSJeffrey Hsu 	size_t len = sizeof pimstat;
775c7b9b5bbSJeffrey Hsu 
776c7b9b5bbSJeffrey Hsu 	if (zflag)
777c7b9b5bbSJeffrey Hsu 		memset(&zerostat, 0, len);
778c7b9b5bbSJeffrey Hsu 	if (sysctlbyname("net.inet.pim.stats", &pimstat, &len,
779c7b9b5bbSJeffrey Hsu 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
7806d7c0d2fSDag-Erling Smørgrav 		if (errno != ENOENT)
781c7b9b5bbSJeffrey Hsu 			warn("sysctl: net.inet.pim.stats");
782c7b9b5bbSJeffrey Hsu 		return;
783c7b9b5bbSJeffrey Hsu 	}
784c7b9b5bbSJeffrey Hsu 
785c7b9b5bbSJeffrey Hsu 	printf("%s:\n", name);
786c7b9b5bbSJeffrey Hsu 
787c7b9b5bbSJeffrey Hsu #define	p(f, m) if (pimstat.f || sflag <= 1) \
788c7b9b5bbSJeffrey Hsu     printf(m, pimstat.f, plural(pimstat.f))
789c7b9b5bbSJeffrey Hsu #define	py(f, m) if (pimstat.f || sflag <= 1) \
790c7b9b5bbSJeffrey Hsu     printf(m, pimstat.f, pimstat.f != 1 ? "ies" : "y")
791c7b9b5bbSJeffrey Hsu 	p(pims_rcv_total_msgs, "\t%llu message%s received\n");
792c7b9b5bbSJeffrey Hsu 	p(pims_rcv_total_bytes, "\t%llu byte%s received\n");
793c7b9b5bbSJeffrey Hsu 	p(pims_rcv_tooshort, "\t%llu message%s received with too few bytes\n");
794c7b9b5bbSJeffrey Hsu         p(pims_rcv_badsum, "\t%llu message%s received with bad checksum\n");
795c7b9b5bbSJeffrey Hsu 	p(pims_rcv_badversion, "\t%llu message%s received with bad version\n");
796c7b9b5bbSJeffrey Hsu 	p(pims_rcv_registers_msgs, "\t%llu data register message%s received\n");
797c7b9b5bbSJeffrey Hsu 	p(pims_rcv_registers_bytes, "\t%llu data register byte%s received\n");
798c7b9b5bbSJeffrey Hsu 	p(pims_rcv_registers_wrongiif, "\t%llu data register message%s received on wrong iif\n");
799c7b9b5bbSJeffrey Hsu 	p(pims_rcv_badregisters, "\t%llu bad register%s received\n");
800c7b9b5bbSJeffrey Hsu 	p(pims_snd_registers_msgs, "\t%llu data register message%s sent\n");
801c7b9b5bbSJeffrey Hsu 	p(pims_snd_registers_bytes, "\t%llu data register byte%s sent\n");
802c7b9b5bbSJeffrey Hsu #undef p
803c7b9b5bbSJeffrey Hsu #undef py
804c7b9b5bbSJeffrey Hsu }
805c7b9b5bbSJeffrey Hsu 
806c7b9b5bbSJeffrey Hsu /*
8079b50d902SRodney W. Grimes  * Pretty print an Internet address (net address + port).
8089b50d902SRodney W. Grimes  */
8099b50d902SRodney W. Grimes void
810a01e3379SDavid Malone inetprint(struct in_addr *in, int port, const char *proto, int num_port)
8119b50d902SRodney W. Grimes {
8129b50d902SRodney W. Grimes 	struct servent *sp = 0;
8139b50d902SRodney W. Grimes 	char line[80], *cp;
814cfa1ca9dSYoshinobu Inoue 	int width;
8159b50d902SRodney W. Grimes 
816080b7f49SDag-Erling Smørgrav 	if (Wflag)
817080b7f49SDag-Erling Smørgrav 	    sprintf(line, "%s.", inetname(in));
818080b7f49SDag-Erling Smørgrav 	else
819a01e3379SDavid Malone 	    sprintf(line, "%.*s.", (Aflag && !num_port) ? 12 : 16, inetname(in));
8209b50d902SRodney W. Grimes 	cp = index(line, '\0');
821a01e3379SDavid Malone 	if (!num_port && port)
8229b50d902SRodney W. Grimes 		sp = getservbyport((int)port, proto);
8239b50d902SRodney W. Grimes 	if (sp || port == 0)
8241ef69972SAndrey A. Chernov 		sprintf(cp, "%.15s ", sp ? sp->s_name : "*");
8259b50d902SRodney W. Grimes 	else
8269b50d902SRodney W. Grimes 		sprintf(cp, "%d ", ntohs((u_short)port));
827080b7f49SDag-Erling Smørgrav 	width = (Aflag && !Wflag) ? 18 : 22;
828080b7f49SDag-Erling Smørgrav 	if (Wflag)
829080b7f49SDag-Erling Smørgrav 	    printf("%-*s ", width, line);
830080b7f49SDag-Erling Smørgrav 	else
831cfa1ca9dSYoshinobu Inoue 	    printf("%-*.*s ", width, width, line);
8329b50d902SRodney W. Grimes }
8339b50d902SRodney W. Grimes 
8349b50d902SRodney W. Grimes /*
8359b50d902SRodney W. Grimes  * Construct an Internet address representation.
83665ea0024SAssar Westerlund  * If numeric_addr has been supplied, give
8379b50d902SRodney W. Grimes  * numeric value, otherwise try for symbolic name.
8389b50d902SRodney W. Grimes  */
8399b50d902SRodney W. Grimes char *
8405e051718SAssar Westerlund inetname(struct in_addr *inp)
8419b50d902SRodney W. Grimes {
842a01e3379SDavid Malone 	char *cp;
843d121b556SBrian Somers 	static char line[MAXHOSTNAMELEN];
8449b50d902SRodney W. Grimes 	struct hostent *hp;
8459b50d902SRodney W. Grimes 	struct netent *np;
8469b50d902SRodney W. Grimes 
8479b50d902SRodney W. Grimes 	cp = 0;
84865ea0024SAssar Westerlund 	if (!numeric_addr && inp->s_addr != INADDR_ANY) {
8499b50d902SRodney W. Grimes 		int net = inet_netof(*inp);
8509b50d902SRodney W. Grimes 		int lna = inet_lnaof(*inp);
8519b50d902SRodney W. Grimes 
8529b50d902SRodney W. Grimes 		if (lna == INADDR_ANY) {
8539b50d902SRodney W. Grimes 			np = getnetbyaddr(net, AF_INET);
8549b50d902SRodney W. Grimes 			if (np)
8559b50d902SRodney W. Grimes 				cp = np->n_name;
8569b50d902SRodney W. Grimes 		}
8579b50d902SRodney W. Grimes 		if (cp == 0) {
8589b50d902SRodney W. Grimes 			hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET);
8599b50d902SRodney W. Grimes 			if (hp) {
8609b50d902SRodney W. Grimes 				cp = hp->h_name;
861d121b556SBrian Somers 				trimdomain(cp, strlen(cp));
8629b50d902SRodney W. Grimes 			}
8639b50d902SRodney W. Grimes 		}
8649b50d902SRodney W. Grimes 	}
8659b50d902SRodney W. Grimes 	if (inp->s_addr == INADDR_ANY)
8669b50d902SRodney W. Grimes 		strcpy(line, "*");
8679a1f6729SWarner Losh 	else if (cp) {
8689a1f6729SWarner Losh 		strncpy(line, cp, sizeof(line) - 1);
8699a1f6729SWarner Losh 		line[sizeof(line) - 1] = '\0';
8709a1f6729SWarner Losh 	} else {
8719b50d902SRodney W. Grimes 		inp->s_addr = ntohl(inp->s_addr);
87222694ebaSBruce Evans #define C(x)	((u_int)((x) & 0xff))
87322694ebaSBruce Evans 		sprintf(line, "%u.%u.%u.%u", C(inp->s_addr >> 24),
8749b50d902SRodney W. Grimes 		    C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr));
8759b50d902SRodney W. Grimes 	}
8769b50d902SRodney W. Grimes 	return (line);
8779b50d902SRodney W. Grimes }
878