xref: /freebsd/usr.bin/netstat/inet.c (revision 60a31b3ae1f6d19f5b52e8ee469df9b1d4ecf2e6)
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 *);
845e051718SAssar Westerlund void	inetprint (struct in_addr *, int, char *, int);
85cfa1ca9dSYoshinobu Inoue #ifdef INET6
865e051718SAssar Westerlund extern void	inet6print (struct in6_addr *, int, char *, int);
87cfa1ca9dSYoshinobu Inoue static int udp_done, tcp_done;
88cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
899b50d902SRodney W. Grimes 
909b50d902SRodney W. Grimes /*
919b50d902SRodney W. Grimes  * Print a summary of connections related to an Internet
929b50d902SRodney W. Grimes  * protocol.  For TCP, also give state of connection.
939b50d902SRodney W. Grimes  * Listening processes (aflag) are suppressed unless the
949b50d902SRodney W. Grimes  * -a (all) flag is specified.
959b50d902SRodney W. Grimes  */
969b50d902SRodney W. Grimes void
975e051718SAssar Westerlund protopr(u_long proto,		/* for sysctl version we pass proto # */
985e051718SAssar Westerlund 	char *name, int af)
999b50d902SRodney W. Grimes {
1009b50d902SRodney W. Grimes 	int istcp;
1019b50d902SRodney W. Grimes 	static int first = 1;
1024f81ef50SGarrett Wollman 	char *buf;
103fb5d0fbdSRuslan Ermilov 	const char *mibvar, *vchar;
104a97a9922SJulian Elischer 	struct tcpcb *tp = NULL;
1054f81ef50SGarrett Wollman 	struct inpcb *inp;
1064f81ef50SGarrett Wollman 	struct xinpgen *xig, *oxig;
1074f81ef50SGarrett Wollman 	struct xsocket *so;
1084f81ef50SGarrett Wollman 	size_t len;
1099b50d902SRodney W. Grimes 
1104f81ef50SGarrett Wollman 	istcp = 0;
1114f81ef50SGarrett Wollman 	switch (proto) {
1124f81ef50SGarrett Wollman 	case IPPROTO_TCP:
113cfa1ca9dSYoshinobu Inoue #ifdef INET6
114cfa1ca9dSYoshinobu Inoue 		if (tcp_done != 0)
115cfa1ca9dSYoshinobu Inoue 			return;
116cfa1ca9dSYoshinobu Inoue 		else
117cfa1ca9dSYoshinobu Inoue 			tcp_done = 1;
118cfa1ca9dSYoshinobu Inoue #endif
1194f81ef50SGarrett Wollman 		istcp = 1;
1204f81ef50SGarrett Wollman 		mibvar = "net.inet.tcp.pcblist";
1214f81ef50SGarrett Wollman 		break;
1224f81ef50SGarrett Wollman 	case IPPROTO_UDP:
123cfa1ca9dSYoshinobu Inoue #ifdef INET6
124cfa1ca9dSYoshinobu Inoue 		if (udp_done != 0)
125cfa1ca9dSYoshinobu Inoue 			return;
126cfa1ca9dSYoshinobu Inoue 		else
127cfa1ca9dSYoshinobu Inoue 			udp_done = 1;
128cfa1ca9dSYoshinobu Inoue #endif
1294f81ef50SGarrett Wollman 		mibvar = "net.inet.udp.pcblist";
1304f81ef50SGarrett Wollman 		break;
1314f81ef50SGarrett Wollman 	case IPPROTO_DIVERT:
1324f81ef50SGarrett Wollman 		mibvar = "net.inet.divert.pcblist";
1334f81ef50SGarrett Wollman 		break;
1344f81ef50SGarrett Wollman 	default:
1354f81ef50SGarrett Wollman 		mibvar = "net.inet.raw.pcblist";
1364f81ef50SGarrett Wollman 		break;
1374f81ef50SGarrett Wollman 	}
1384f81ef50SGarrett Wollman 	len = 0;
1394f81ef50SGarrett Wollman 	if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
1404f81ef50SGarrett Wollman 		if (errno != ENOENT)
1414f81ef50SGarrett Wollman 			warn("sysctl: %s", mibvar);
1429b50d902SRodney W. Grimes 		return;
1433aa80b1dSDavid Greenman 	}
1444f81ef50SGarrett Wollman 	if ((buf = malloc(len)) == 0) {
1454f81ef50SGarrett Wollman 		warn("malloc %lu bytes", (u_long)len);
1464f81ef50SGarrett Wollman 		return;
1479b50d902SRodney W. Grimes 	}
1484f81ef50SGarrett Wollman 	if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) {
1494f81ef50SGarrett Wollman 		warn("sysctl: %s", mibvar);
1504f81ef50SGarrett Wollman 		free(buf);
1514f81ef50SGarrett Wollman 		return;
1524f81ef50SGarrett Wollman 	}
1534f81ef50SGarrett Wollman 
1544f81ef50SGarrett Wollman 	oxig = xig = (struct xinpgen *)buf;
1554f81ef50SGarrett Wollman 	for (xig = (struct xinpgen *)((char *)xig + xig->xig_len);
1564f81ef50SGarrett Wollman 	     xig->xig_len > sizeof(struct xinpgen);
1574f81ef50SGarrett Wollman 	     xig = (struct xinpgen *)((char *)xig + xig->xig_len)) {
1589b50d902SRodney W. Grimes 		if (istcp) {
1594f81ef50SGarrett Wollman 			tp = &((struct xtcpcb *)xig)->xt_tp;
1604f81ef50SGarrett Wollman 			inp = &((struct xtcpcb *)xig)->xt_inp;
1614f81ef50SGarrett Wollman 			so = &((struct xtcpcb *)xig)->xt_socket;
1624f81ef50SGarrett Wollman 		} else {
1634f81ef50SGarrett Wollman 			inp = &((struct xinpcb *)xig)->xi_inp;
1644f81ef50SGarrett Wollman 			so = &((struct xinpcb *)xig)->xi_socket;
1659b50d902SRodney W. Grimes 		}
1664f81ef50SGarrett Wollman 
1674f81ef50SGarrett Wollman 		/* Ignore sockets for protocols other than the desired one. */
168f964d60dSAssar Westerlund 		if (so->xso_protocol != (int)proto)
1694f81ef50SGarrett Wollman 			continue;
1704f81ef50SGarrett Wollman 
1714f81ef50SGarrett Wollman 		/* Ignore PCBs which were freed during copyout. */
1724f81ef50SGarrett Wollman 		if (inp->inp_gencnt > oxig->xig_gen)
1734f81ef50SGarrett Wollman 			continue;
1744f81ef50SGarrett Wollman 
175cfa1ca9dSYoshinobu Inoue 		if ((af == AF_INET && (inp->inp_vflag & INP_IPV4) == 0)
176cfa1ca9dSYoshinobu Inoue #ifdef INET6
177cfa1ca9dSYoshinobu Inoue 		    || (af == AF_INET6 && (inp->inp_vflag & INP_IPV6) == 0)
178cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
179cfa1ca9dSYoshinobu Inoue 		    || (af == AF_UNSPEC && ((inp->inp_vflag & INP_IPV4) == 0
180cfa1ca9dSYoshinobu Inoue #ifdef INET6
181cfa1ca9dSYoshinobu Inoue 					    && (inp->inp_vflag &
182cfa1ca9dSYoshinobu Inoue 						INP_IPV6) == 0
183cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
184cfa1ca9dSYoshinobu Inoue 			))
185cfa1ca9dSYoshinobu Inoue 		    )
186cfa1ca9dSYoshinobu Inoue 			continue;
187cfa1ca9dSYoshinobu Inoue 		if (!aflag &&
188cfa1ca9dSYoshinobu Inoue 		    (
189cfa1ca9dSYoshinobu Inoue 		     (af == AF_INET &&
190cfa1ca9dSYoshinobu Inoue 		      inet_lnaof(inp->inp_laddr) == INADDR_ANY)
191cfa1ca9dSYoshinobu Inoue #ifdef INET6
192cfa1ca9dSYoshinobu Inoue 		     || (af == AF_INET6 &&
193cfa1ca9dSYoshinobu Inoue 			 IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
194cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
195cfa1ca9dSYoshinobu Inoue 		     || (af == AF_UNSPEC &&
196cfa1ca9dSYoshinobu Inoue 			 (((inp->inp_vflag & INP_IPV4) != 0 &&
197cfa1ca9dSYoshinobu Inoue 			   inet_lnaof(inp->inp_laddr) == INADDR_ANY)
198cfa1ca9dSYoshinobu Inoue #ifdef INET6
199cfa1ca9dSYoshinobu Inoue 			  || ((inp->inp_vflag & INP_IPV6) != 0 &&
200cfa1ca9dSYoshinobu Inoue 			      IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
201cfa1ca9dSYoshinobu Inoue #endif
202cfa1ca9dSYoshinobu Inoue 			  ))
203cfa1ca9dSYoshinobu Inoue 		     ))
2044f81ef50SGarrett Wollman 			continue;
2054f81ef50SGarrett Wollman 
2069b50d902SRodney W. Grimes 		if (first) {
207ac55add0SGuido van Rooij 			if (!Lflag) {
2089b50d902SRodney W. Grimes 				printf("Active Internet connections");
2099b50d902SRodney W. Grimes 				if (aflag)
2109b50d902SRodney W. Grimes 					printf(" (including servers)");
211ac55add0SGuido van Rooij 			} else
212ac55add0SGuido van Rooij 				printf(
213ac55add0SGuido van Rooij 	"Current listen queue sizes (qlen/incqlen/maxqlen)");
2149b50d902SRodney W. Grimes 			putchar('\n');
2159b50d902SRodney W. Grimes 			if (Aflag)
2164f81ef50SGarrett Wollman 				printf("%-8.8s ", "Socket");
217ac55add0SGuido van Rooij 			if (Lflag)
218fb5d0fbdSRuslan Ermilov 				printf("%-5.5s %-14.14s %-22.22s\n",
219fb5d0fbdSRuslan Ermilov 					"Proto", "Listen", "Local Address");
220ac55add0SGuido van Rooij 			else
221080b7f49SDag-Erling Smørgrav 				printf((Aflag && !Wflag) ?
222cfa1ca9dSYoshinobu Inoue 		"%-5.5s %-6.6s %-6.6s  %-18.18s %-18.18s %s\n" :
223cfa1ca9dSYoshinobu Inoue 		"%-5.5s %-6.6s %-6.6s  %-22.22s %-22.22s %s\n",
2249b50d902SRodney W. Grimes 					"Proto", "Recv-Q", "Send-Q",
225ac55add0SGuido van Rooij 					"Local Address", "Foreign Address",
226ac55add0SGuido van Rooij 					"(state)");
2279b50d902SRodney W. Grimes 			first = 0;
2289b50d902SRodney W. Grimes 		}
229fb5d0fbdSRuslan Ermilov 		if (Lflag && so->so_qlimit == 0)
230fb5d0fbdSRuslan Ermilov 			continue;
231e4ec3989SDag-Erling Smørgrav 		if (Aflag) {
232e4ec3989SDag-Erling Smørgrav 			if (istcp)
233e4ec3989SDag-Erling Smørgrav 				printf("%8lx ", (u_long)inp->inp_ppcb);
234e4ec3989SDag-Erling Smørgrav 			else
2354f81ef50SGarrett Wollman 				printf("%8lx ", (u_long)so->so_pcb);
236e4ec3989SDag-Erling Smørgrav 		}
237cfa1ca9dSYoshinobu Inoue #ifdef INET6
238fc60ab7bSYoshinobu Inoue 		if ((inp->inp_vflag & INP_IPV6) != 0)
239fc60ab7bSYoshinobu Inoue 			vchar = ((inp->inp_vflag & INP_IPV4) != 0)
240fc60ab7bSYoshinobu Inoue 				? "46" : "6 ";
241fc60ab7bSYoshinobu Inoue 		else
242cfa1ca9dSYoshinobu Inoue #endif
243fc60ab7bSYoshinobu Inoue 		vchar = ((inp->inp_vflag & INP_IPV4) != 0)
244fc60ab7bSYoshinobu Inoue 				? "4 " : "  ";
245fb5d0fbdSRuslan Ermilov 		printf("%-3.3s%-2.2s ", name, vchar);
246fb5d0fbdSRuslan Ermilov 		if (Lflag) {
247fb5d0fbdSRuslan Ermilov 			char buf[15];
248fc60ab7bSYoshinobu Inoue 
249fb5d0fbdSRuslan Ermilov 			snprintf(buf, 15, "%d/%d/%d", so->so_qlen,
250fb5d0fbdSRuslan Ermilov 				 so->so_incqlen, so->so_qlimit);
251fb5d0fbdSRuslan Ermilov 			printf("%-14.14s ", buf);
252fb5d0fbdSRuslan Ermilov 		} else {
253fb5d0fbdSRuslan Ermilov 			printf("%6ld %6ld  ",
254cfa1ca9dSYoshinobu Inoue 			       so->so_rcv.sb_cc,
2554f81ef50SGarrett Wollman 			       so->so_snd.sb_cc);
256fc60ab7bSYoshinobu Inoue 		}
25765ea0024SAssar Westerlund 		if (numeric_port) {
258cfa1ca9dSYoshinobu Inoue 			if (inp->inp_vflag & INP_IPV4) {
2594f81ef50SGarrett Wollman 				inetprint(&inp->inp_laddr, (int)inp->inp_lport,
2608d612dd2SPoul-Henning Kamp 					  name, 1);
261ac55add0SGuido van Rooij 				if (!Lflag)
262ac55add0SGuido van Rooij 					inetprint(&inp->inp_faddr,
263ac55add0SGuido van Rooij 						  (int)inp->inp_fport, name, 1);
264cfa1ca9dSYoshinobu Inoue 			}
265cfa1ca9dSYoshinobu Inoue #ifdef INET6
266cfa1ca9dSYoshinobu Inoue 			else if (inp->inp_vflag & INP_IPV6) {
267cfa1ca9dSYoshinobu Inoue 				inet6print(&inp->in6p_laddr,
268cfa1ca9dSYoshinobu Inoue 					   (int)inp->inp_lport, name, 1);
269ac55add0SGuido van Rooij 				if (!Lflag)
270cfa1ca9dSYoshinobu Inoue 					inet6print(&inp->in6p_faddr,
271cfa1ca9dSYoshinobu Inoue 						   (int)inp->inp_fport, name, 1);
272cfa1ca9dSYoshinobu Inoue 			} /* else nothing printed now */
273cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
2744f81ef50SGarrett Wollman 		} else if (inp->inp_flags & INP_ANONPORT) {
275cfa1ca9dSYoshinobu Inoue 			if (inp->inp_vflag & INP_IPV4) {
2764f81ef50SGarrett Wollman 				inetprint(&inp->inp_laddr, (int)inp->inp_lport,
2778d612dd2SPoul-Henning Kamp 					  name, 1);
278ac55add0SGuido van Rooij 				if (!Lflag)
279ac55add0SGuido van Rooij 					inetprint(&inp->inp_faddr,
280ac55add0SGuido van Rooij 						  (int)inp->inp_fport, name, 0);
281cfa1ca9dSYoshinobu Inoue 			}
282cfa1ca9dSYoshinobu Inoue #ifdef INET6
283cfa1ca9dSYoshinobu Inoue 			else if (inp->inp_vflag & INP_IPV6) {
284cfa1ca9dSYoshinobu Inoue 				inet6print(&inp->in6p_laddr,
285cfa1ca9dSYoshinobu Inoue 					   (int)inp->inp_lport, name, 1);
286ac55add0SGuido van Rooij 				if (!Lflag)
287cfa1ca9dSYoshinobu Inoue 					inet6print(&inp->in6p_faddr,
288cfa1ca9dSYoshinobu Inoue 						   (int)inp->inp_fport, name, 0);
289cfa1ca9dSYoshinobu Inoue 			} /* else nothing printed now */
290cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
2918d612dd2SPoul-Henning Kamp 		} else {
292cfa1ca9dSYoshinobu Inoue 			if (inp->inp_vflag & INP_IPV4) {
2934f81ef50SGarrett Wollman 				inetprint(&inp->inp_laddr, (int)inp->inp_lport,
2948d612dd2SPoul-Henning Kamp 					  name, 0);
295ac55add0SGuido van Rooij 				if (!Lflag)
296ac55add0SGuido van Rooij 					inetprint(&inp->inp_faddr,
297ac55add0SGuido van Rooij 						  (int)inp->inp_fport, name,
298ac55add0SGuido van Rooij 						  inp->inp_lport !=
299ac55add0SGuido van Rooij 							inp->inp_fport);
300cfa1ca9dSYoshinobu Inoue 			}
301cfa1ca9dSYoshinobu Inoue #ifdef INET6
302cfa1ca9dSYoshinobu Inoue 			else if (inp->inp_vflag & INP_IPV6) {
303cfa1ca9dSYoshinobu Inoue 				inet6print(&inp->in6p_laddr,
304cfa1ca9dSYoshinobu Inoue 					   (int)inp->inp_lport, name, 0);
305ac55add0SGuido van Rooij 				if (!Lflag)
306cfa1ca9dSYoshinobu Inoue 					inet6print(&inp->in6p_faddr,
307cfa1ca9dSYoshinobu Inoue 						   (int)inp->inp_fport, name,
308ac55add0SGuido van Rooij 						   inp->inp_lport !=
309ac55add0SGuido van Rooij 							inp->inp_fport);
310cfa1ca9dSYoshinobu Inoue 			} /* else nothing printed now */
311cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
3128d612dd2SPoul-Henning Kamp 		}
313ac55add0SGuido van Rooij 		if (istcp && !Lflag) {
3144f81ef50SGarrett Wollman 			if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES)
3154f81ef50SGarrett Wollman 				printf("%d", tp->t_state);
3169a94a597SGarrett Wollman                       else {
3174f81ef50SGarrett Wollman 				printf("%s", tcpstates[tp->t_state]);
318513822ddSAdam David #if defined(TF_NEEDSYN) && defined(TF_NEEDFIN)
3199a94a597SGarrett Wollman                               /* Show T/TCP `hidden state' */
3204f81ef50SGarrett Wollman                               if (tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN))
3219a94a597SGarrett Wollman                                       putchar('*');
322513822ddSAdam David #endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */
3239a94a597SGarrett Wollman                       }
3249b50d902SRodney W. Grimes 		}
3259b50d902SRodney W. Grimes 		putchar('\n');
3269b50d902SRodney W. Grimes 	}
3274f81ef50SGarrett Wollman 	if (xig != oxig && xig->xig_gen != oxig->xig_gen) {
3284f81ef50SGarrett Wollman 		if (oxig->xig_count > xig->xig_count) {
3294f81ef50SGarrett Wollman 			printf("Some %s sockets may have been deleted.\n",
3304f81ef50SGarrett Wollman 			       name);
3314f81ef50SGarrett Wollman 		} else if (oxig->xig_count < xig->xig_count) {
3324f81ef50SGarrett Wollman 			printf("Some %s sockets may have been created.\n",
3334f81ef50SGarrett Wollman 			       name);
3344f81ef50SGarrett Wollman 		} else {
3354f81ef50SGarrett Wollman 			printf("Some %s sockets may have been created or deleted",
3364f81ef50SGarrett Wollman 			       name);
3374f81ef50SGarrett Wollman 		}
3384f81ef50SGarrett Wollman 	}
3394f81ef50SGarrett Wollman 	free(buf);
3409b50d902SRodney W. Grimes }
3419b50d902SRodney W. Grimes 
3429b50d902SRodney W. Grimes /*
3439b50d902SRodney W. Grimes  * Dump TCP statistics structure.
3449b50d902SRodney W. Grimes  */
3459b50d902SRodney W. Grimes void
346f964d60dSAssar Westerlund tcp_stats(u_long off __unused, char *name, int af __unused)
3479b50d902SRodney W. Grimes {
348c73d99b5SRuslan Ermilov 	struct tcpstat tcpstat, zerostat;
3494f81ef50SGarrett Wollman 	size_t len = sizeof tcpstat;
3509b50d902SRodney W. Grimes 
351c73d99b5SRuslan Ermilov 	if (zflag)
352c73d99b5SRuslan Ermilov 		memset(&zerostat, 0, len);
353c73d99b5SRuslan Ermilov 	if (sysctlbyname("net.inet.tcp.stats", &tcpstat, &len,
354c73d99b5SRuslan Ermilov 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
3554f81ef50SGarrett Wollman 		warn("sysctl: net.inet.tcp.stats");
3569b50d902SRodney W. Grimes 		return;
3574f81ef50SGarrett Wollman 	}
3584f81ef50SGarrett Wollman 
359cfa1ca9dSYoshinobu Inoue #ifdef INET6
360cfa1ca9dSYoshinobu Inoue 	if (tcp_done != 0)
361cfa1ca9dSYoshinobu Inoue 		return;
362cfa1ca9dSYoshinobu Inoue 	else
363cfa1ca9dSYoshinobu Inoue 		tcp_done = 1;
364cfa1ca9dSYoshinobu Inoue #endif
365cfa1ca9dSYoshinobu Inoue 
3669b50d902SRodney W. Grimes 	printf ("%s:\n", name);
3679b50d902SRodney W. Grimes 
3689b50d902SRodney W. Grimes #define	p(f, m) if (tcpstat.f || sflag <= 1) \
3699b50d902SRodney W. Grimes     printf(m, tcpstat.f, plural(tcpstat.f))
37022694ebaSBruce Evans #define	p1a(f, m) if (tcpstat.f || sflag <= 1) \
37122694ebaSBruce Evans     printf(m, tcpstat.f)
3729b50d902SRodney W. Grimes #define	p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
3739b50d902SRodney W. Grimes     printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2))
37422694ebaSBruce Evans #define	p2a(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
37522694ebaSBruce Evans     printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2)
3769b50d902SRodney W. Grimes #define	p3(f, m) if (tcpstat.f || sflag <= 1) \
3779b50d902SRodney W. Grimes     printf(m, tcpstat.f, plurales(tcpstat.f))
3789b50d902SRodney W. Grimes 
379e1fb4daaSPaul Traina 	p(tcps_sndtotal, "\t%lu packet%s sent\n");
3809b50d902SRodney W. Grimes 	p2(tcps_sndpack,tcps_sndbyte,
381e1fb4daaSPaul Traina 		"\t\t%lu data packet%s (%lu byte%s)\n");
3829b50d902SRodney W. Grimes 	p2(tcps_sndrexmitpack, tcps_sndrexmitbyte,
383e1fb4daaSPaul Traina 		"\t\t%lu data packet%s (%lu byte%s) retransmitted\n");
384e1fb4daaSPaul Traina 	p(tcps_mturesent, "\t\t%lu resend%s initiated by MTU discovery\n");
38522694ebaSBruce Evans 	p2a(tcps_sndacks, tcps_delack,
386e1fb4daaSPaul Traina 		"\t\t%lu ack-only packet%s (%lu delayed)\n");
387e1fb4daaSPaul Traina 	p(tcps_sndurg, "\t\t%lu URG only packet%s\n");
388e1fb4daaSPaul Traina 	p(tcps_sndprobe, "\t\t%lu window probe packet%s\n");
389e1fb4daaSPaul Traina 	p(tcps_sndwinup, "\t\t%lu window update packet%s\n");
390e1fb4daaSPaul Traina 	p(tcps_sndctrl, "\t\t%lu control packet%s\n");
391e1fb4daaSPaul Traina 	p(tcps_rcvtotal, "\t%lu packet%s received\n");
392e1fb4daaSPaul Traina 	p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%lu ack%s (for %lu byte%s)\n");
393e1fb4daaSPaul Traina 	p(tcps_rcvdupack, "\t\t%lu duplicate ack%s\n");
394e1fb4daaSPaul Traina 	p(tcps_rcvacktoomuch, "\t\t%lu ack%s for unsent data\n");
3959b50d902SRodney W. Grimes 	p2(tcps_rcvpack, tcps_rcvbyte,
396e1fb4daaSPaul Traina 		"\t\t%lu packet%s (%lu byte%s) received in-sequence\n");
3979b50d902SRodney W. Grimes 	p2(tcps_rcvduppack, tcps_rcvdupbyte,
398e1fb4daaSPaul Traina 		"\t\t%lu completely duplicate packet%s (%lu byte%s)\n");
399e1fb4daaSPaul Traina 	p(tcps_pawsdrop, "\t\t%lu old duplicate packet%s\n");
4009b50d902SRodney W. Grimes 	p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte,
401e1fb4daaSPaul Traina 		"\t\t%lu packet%s with some dup. data (%lu byte%s duped)\n");
4029b50d902SRodney W. Grimes 	p2(tcps_rcvoopack, tcps_rcvoobyte,
403e1fb4daaSPaul Traina 		"\t\t%lu out-of-order packet%s (%lu byte%s)\n");
4049b50d902SRodney W. Grimes 	p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin,
405e1fb4daaSPaul Traina 		"\t\t%lu packet%s (%lu byte%s) of data after window\n");
406e1fb4daaSPaul Traina 	p(tcps_rcvwinprobe, "\t\t%lu window probe%s\n");
407e1fb4daaSPaul Traina 	p(tcps_rcvwinupd, "\t\t%lu window update packet%s\n");
408e1fb4daaSPaul Traina 	p(tcps_rcvafterclose, "\t\t%lu packet%s received after close\n");
409e1fb4daaSPaul Traina 	p(tcps_rcvbadsum, "\t\t%lu discarded for bad checksum%s\n");
410e1fb4daaSPaul Traina 	p(tcps_rcvbadoff, "\t\t%lu discarded for bad header offset field%s\n");
41122694ebaSBruce Evans 	p1a(tcps_rcvshort, "\t\t%lu discarded because packet too short\n");
412e1fb4daaSPaul Traina 	p(tcps_connattempt, "\t%lu connection request%s\n");
413e1fb4daaSPaul Traina 	p(tcps_accepts, "\t%lu connection accept%s\n");
414e1fb4daaSPaul Traina 	p(tcps_badsyn, "\t%lu bad connection attempt%s\n");
415e1fb4daaSPaul Traina 	p(tcps_listendrop, "\t%lu listen queue overflow%s\n");
416e1fb4daaSPaul Traina 	p(tcps_connects, "\t%lu connection%s established (including accepts)\n");
4179b50d902SRodney W. Grimes 	p2(tcps_closed, tcps_drops,
418e1fb4daaSPaul Traina 		"\t%lu connection%s closed (including %lu drop%s)\n");
419e1fb4daaSPaul Traina 	p(tcps_cachedrtt, "\t\t%lu connection%s updated cached RTT on close\n");
420861b1828SGarrett Wollman 	p(tcps_cachedrttvar,
421e1fb4daaSPaul Traina 	  "\t\t%lu connection%s updated cached RTT variance on close\n");
422861b1828SGarrett Wollman 	p(tcps_cachedssthresh,
423e1fb4daaSPaul Traina 	  "\t\t%lu connection%s updated cached ssthresh on close\n");
424e1fb4daaSPaul Traina 	p(tcps_conndrops, "\t%lu embryonic connection%s dropped\n");
4259b50d902SRodney W. Grimes 	p2(tcps_rttupdated, tcps_segstimed,
426e1fb4daaSPaul Traina 		"\t%lu segment%s updated rtt (of %lu attempt%s)\n");
427e1fb4daaSPaul Traina 	p(tcps_rexmttimeo, "\t%lu retransmit timeout%s\n");
428e1fb4daaSPaul Traina 	p(tcps_timeoutdrop, "\t\t%lu connection%s dropped by rexmit timeout\n");
429e1fb4daaSPaul Traina 	p(tcps_persisttimeo, "\t%lu persist timeout%s\n");
430e1fb4daaSPaul Traina 	p(tcps_persistdrop, "\t\t%lu connection%s dropped by persist timeout\n");
431e1fb4daaSPaul Traina 	p(tcps_keeptimeo, "\t%lu keepalive timeout%s\n");
432e1fb4daaSPaul Traina 	p(tcps_keepprobe, "\t\t%lu keepalive probe%s sent\n");
433e1fb4daaSPaul Traina 	p(tcps_keepdrops, "\t\t%lu connection%s dropped by keepalive\n");
434e1fb4daaSPaul Traina 	p(tcps_predack, "\t%lu correct ACK header prediction%s\n");
435e1fb4daaSPaul Traina 	p(tcps_preddat, "\t%lu correct data packet header prediction%s\n");
43660a31b3aSJonathan Lemon 
43760a31b3aSJonathan Lemon 	p(tcps_sc_added, "\t%lu syncache entries added\n");
43860a31b3aSJonathan Lemon 	p(tcps_sc_retransmitted, "\t\t%lu retransmitted\n");
43960a31b3aSJonathan Lemon 	p(tcps_sc_dupsyn, "\t\t%lu dupsyn\n");
44060a31b3aSJonathan Lemon 	p(tcps_sc_dropped, "\t\t%lu dropped\n");
44160a31b3aSJonathan Lemon 	p(tcps_sc_completed, "\t\t%lu completed\n");
44260a31b3aSJonathan Lemon 	p(tcps_sc_bucketoverflow, "\t\t%lu bucket overflow\n");
44360a31b3aSJonathan Lemon 	p(tcps_sc_cacheoverflow, "\t\t%lu cache overflow\n");
44460a31b3aSJonathan Lemon 	p(tcps_sc_reset, "\t\t%lu reset\n");
44560a31b3aSJonathan Lemon 	p(tcps_sc_stale, "\t\t%lu stale\n");
44660a31b3aSJonathan Lemon 	p(tcps_sc_aborted, "\t\t%lu aborted\n");
44760a31b3aSJonathan Lemon 	p(tcps_sc_badack, "\t\t%lu badack\n");
44860a31b3aSJonathan Lemon 	p(tcps_sc_unreach, "\t\t%lu unreach\n");
44960a31b3aSJonathan Lemon 	p(tcps_sc_zonefail, "\t\t%lu zone failures\n");
45060a31b3aSJonathan Lemon 	p(tcps_sc_sendcookie, "\t%lu cookies sent\n");
45160a31b3aSJonathan Lemon 	p(tcps_sc_recvcookie, "\t%lu cookies received\n");
4529b50d902SRodney W. Grimes #undef p
45322694ebaSBruce Evans #undef p1a
4549b50d902SRodney W. Grimes #undef p2
45522694ebaSBruce Evans #undef p2a
4569b50d902SRodney W. Grimes #undef p3
4579b50d902SRodney W. Grimes }
4589b50d902SRodney W. Grimes 
4599b50d902SRodney W. Grimes /*
4609b50d902SRodney W. Grimes  * Dump UDP statistics structure.
4619b50d902SRodney W. Grimes  */
4629b50d902SRodney W. Grimes void
463f964d60dSAssar Westerlund udp_stats(u_long off __unused, char *name, int af __unused)
4649b50d902SRodney W. Grimes {
465c73d99b5SRuslan Ermilov 	struct udpstat udpstat, zerostat;
4664f81ef50SGarrett Wollman 	size_t len = sizeof udpstat;
4679b50d902SRodney W. Grimes 	u_long delivered;
4689b50d902SRodney W. Grimes 
469c73d99b5SRuslan Ermilov 	if (zflag)
470c73d99b5SRuslan Ermilov 		memset(&zerostat, 0, len);
471c73d99b5SRuslan Ermilov 	if (sysctlbyname("net.inet.udp.stats", &udpstat, &len,
472c73d99b5SRuslan Ermilov 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
4734f81ef50SGarrett Wollman 		warn("sysctl: net.inet.udp.stats");
4749b50d902SRodney W. Grimes 		return;
4754f81ef50SGarrett Wollman 	}
4764f81ef50SGarrett Wollman 
477cfa1ca9dSYoshinobu Inoue #ifdef INET6
478cfa1ca9dSYoshinobu Inoue 	if (udp_done != 0)
479cfa1ca9dSYoshinobu Inoue 		return;
480cfa1ca9dSYoshinobu Inoue 	else
481cfa1ca9dSYoshinobu Inoue 		udp_done = 1;
482cfa1ca9dSYoshinobu Inoue #endif
483cfa1ca9dSYoshinobu Inoue 
4849b50d902SRodney W. Grimes 	printf("%s:\n", name);
4859b50d902SRodney W. Grimes #define	p(f, m) if (udpstat.f || sflag <= 1) \
4869b50d902SRodney W. Grimes     printf(m, udpstat.f, plural(udpstat.f))
48722694ebaSBruce Evans #define	p1a(f, m) if (udpstat.f || sflag <= 1) \
48822694ebaSBruce Evans     printf(m, udpstat.f)
4897d56c0eeSAlexander Langer 	p(udps_ipackets, "\t%lu datagram%s received\n");
49022694ebaSBruce Evans 	p1a(udps_hdrops, "\t%lu with incomplete header\n");
49122694ebaSBruce Evans 	p1a(udps_badlen, "\t%lu with bad data length field\n");
49222694ebaSBruce Evans 	p1a(udps_badsum, "\t%lu with bad checksum\n");
493fb9aaba0SRuslan Ermilov 	p1a(udps_nosum, "\t%lu with no checksum\n");
49422694ebaSBruce Evans 	p1a(udps_noport, "\t%lu dropped due to no socket\n");
49522694ebaSBruce Evans 	p(udps_noportbcast,
49622694ebaSBruce Evans 	    "\t%lu broadcast/multicast datagram%s dropped due to no socket\n");
49722694ebaSBruce Evans 	p1a(udps_fullsock, "\t%lu dropped due to full socket buffers\n");
49822694ebaSBruce Evans 	p1a(udpps_pcbhashmiss, "\t%lu not for hashed pcb\n");
4999b50d902SRodney W. Grimes 	delivered = udpstat.udps_ipackets -
5009b50d902SRodney W. Grimes 		    udpstat.udps_hdrops -
5019b50d902SRodney W. Grimes 		    udpstat.udps_badlen -
5029b50d902SRodney W. Grimes 		    udpstat.udps_badsum -
5039b50d902SRodney W. Grimes 		    udpstat.udps_noport -
5049b50d902SRodney W. Grimes 		    udpstat.udps_noportbcast -
5059b50d902SRodney W. Grimes 		    udpstat.udps_fullsock;
5069b50d902SRodney W. Grimes 	if (delivered || sflag <= 1)
5077d56c0eeSAlexander Langer 		printf("\t%lu delivered\n", delivered);
5087d56c0eeSAlexander Langer 	p(udps_opackets, "\t%lu datagram%s output\n");
5099b50d902SRodney W. Grimes #undef p
51022694ebaSBruce Evans #undef p1a
5119b50d902SRodney W. Grimes }
5129b50d902SRodney W. Grimes 
5139b50d902SRodney W. Grimes /*
5149b50d902SRodney W. Grimes  * Dump IP statistics structure.
5159b50d902SRodney W. Grimes  */
5169b50d902SRodney W. Grimes void
517f964d60dSAssar Westerlund ip_stats(u_long off __unused, char *name, int af __unused)
5189b50d902SRodney W. Grimes {
519c73d99b5SRuslan Ermilov 	struct ipstat ipstat, zerostat;
5204f81ef50SGarrett Wollman 	size_t len = sizeof ipstat;
5219b50d902SRodney W. Grimes 
522c73d99b5SRuslan Ermilov 	if (zflag)
523c73d99b5SRuslan Ermilov 		memset(&zerostat, 0, len);
524c73d99b5SRuslan Ermilov 	if (sysctlbyname("net.inet.ip.stats", &ipstat, &len,
525c73d99b5SRuslan Ermilov 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
5264f81ef50SGarrett Wollman 		warn("sysctl: net.inet.ip.stats");
5279b50d902SRodney W. Grimes 		return;
5284f81ef50SGarrett Wollman 	}
5294f81ef50SGarrett Wollman 
5309b50d902SRodney W. Grimes 	printf("%s:\n", name);
5319b50d902SRodney W. Grimes 
5329b50d902SRodney W. Grimes #define	p(f, m) if (ipstat.f || sflag <= 1) \
5339b50d902SRodney W. Grimes     printf(m, ipstat.f, plural(ipstat.f))
53422694ebaSBruce Evans #define	p1a(f, m) if (ipstat.f || sflag <= 1) \
53522694ebaSBruce Evans     printf(m, ipstat.f)
5369b50d902SRodney W. Grimes 
5377d56c0eeSAlexander Langer 	p(ips_total, "\t%lu total packet%s received\n");
5387d56c0eeSAlexander Langer 	p(ips_badsum, "\t%lu bad header checksum%s\n");
53922694ebaSBruce Evans 	p1a(ips_toosmall, "\t%lu with size smaller than minimum\n");
54022694ebaSBruce Evans 	p1a(ips_tooshort, "\t%lu with data size < data length\n");
541cfa1ca9dSYoshinobu Inoue 	p1a(ips_toolong, "\t%lu with ip length > max ip packet size\n");
54222694ebaSBruce Evans 	p1a(ips_badhlen, "\t%lu with header length < data size\n");
54322694ebaSBruce Evans 	p1a(ips_badlen, "\t%lu with data length < header length\n");
54422694ebaSBruce Evans 	p1a(ips_badoptions, "\t%lu with bad options\n");
54522694ebaSBruce Evans 	p1a(ips_badvers, "\t%lu with incorrect version number\n");
5467d56c0eeSAlexander Langer 	p(ips_fragments, "\t%lu fragment%s received\n");
5477d56c0eeSAlexander Langer 	p(ips_fragdropped, "\t%lu fragment%s dropped (dup or out of space)\n");
5487d56c0eeSAlexander Langer 	p(ips_fragtimeout, "\t%lu fragment%s dropped after timeout\n");
5497d56c0eeSAlexander Langer 	p(ips_reassembled, "\t%lu packet%s reassembled ok\n");
5507d56c0eeSAlexander Langer 	p(ips_delivered, "\t%lu packet%s for this host\n");
5517d56c0eeSAlexander Langer 	p(ips_noproto, "\t%lu packet%s for unknown/unsupported protocol\n");
552958d6f7fSPierre Beyssac 	p(ips_forward, "\t%lu packet%s forwarded");
553958d6f7fSPierre Beyssac 	p(ips_fastforward, " (%lu packet%s fast forwarded)");
554958d6f7fSPierre Beyssac 	if (ipstat.ips_forward || sflag <= 1)
555958d6f7fSPierre Beyssac 		putchar('\n');
5567d56c0eeSAlexander Langer 	p(ips_cantforward, "\t%lu packet%s not forwardable\n");
557a5969f5fSGarrett Wollman 	p(ips_notmember,
558a5969f5fSGarrett Wollman 	  "\t%lu packet%s received for unknown multicast group\n");
5597d56c0eeSAlexander Langer 	p(ips_redirectsent, "\t%lu redirect%s sent\n");
5607d56c0eeSAlexander Langer 	p(ips_localout, "\t%lu packet%s sent from this host\n");
5617d56c0eeSAlexander Langer 	p(ips_rawout, "\t%lu packet%s sent with fabricated ip header\n");
562a5969f5fSGarrett Wollman 	p(ips_odropped,
563a5969f5fSGarrett Wollman 	  "\t%lu output packet%s dropped due to no bufs, etc.\n");
5647d56c0eeSAlexander Langer 	p(ips_noroute, "\t%lu output packet%s discarded due to no route\n");
5657d56c0eeSAlexander Langer 	p(ips_fragmented, "\t%lu output datagram%s fragmented\n");
5667d56c0eeSAlexander Langer 	p(ips_ofragments, "\t%lu fragment%s created\n");
5677d56c0eeSAlexander Langer 	p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n");
568cfa1ca9dSYoshinobu Inoue 	p(ips_nogif, "\t%lu tunneling packet%s that can't find gif\n");
56933841545SHajimu UMEMOTO 	p(ips_badaddr, "\t%lu datagram%s with bad address in header\n");
5709b50d902SRodney W. Grimes #undef p
57122694ebaSBruce Evans #undef p1a
5729b50d902SRodney W. Grimes }
5739b50d902SRodney W. Grimes 
5749b50d902SRodney W. Grimes static	char *icmpnames[] = {
5759b50d902SRodney W. Grimes 	"echo reply",
5769b50d902SRodney W. Grimes 	"#1",
5779b50d902SRodney W. Grimes 	"#2",
5789b50d902SRodney W. Grimes 	"destination unreachable",
5799b50d902SRodney W. Grimes 	"source quench",
5809b50d902SRodney W. Grimes 	"routing redirect",
5819b50d902SRodney W. Grimes 	"#6",
5829b50d902SRodney W. Grimes 	"#7",
5839b50d902SRodney W. Grimes 	"echo",
5847b46dd00SGarrett Wollman 	"router advertisement",
5857b46dd00SGarrett Wollman 	"router solicitation",
5869b50d902SRodney W. Grimes 	"time exceeded",
5879b50d902SRodney W. Grimes 	"parameter problem",
5889b50d902SRodney W. Grimes 	"time stamp",
5899b50d902SRodney W. Grimes 	"time stamp reply",
5909b50d902SRodney W. Grimes 	"information request",
5919b50d902SRodney W. Grimes 	"information request reply",
5929b50d902SRodney W. Grimes 	"address mask request",
5939b50d902SRodney W. Grimes 	"address mask reply",
5949b50d902SRodney W. Grimes };
5959b50d902SRodney W. Grimes 
5969b50d902SRodney W. Grimes /*
5979b50d902SRodney W. Grimes  * Dump ICMP statistics.
5989b50d902SRodney W. Grimes  */
5999b50d902SRodney W. Grimes void
600f964d60dSAssar Westerlund icmp_stats(u_long off __unused, char *name, int af __unused)
6019b50d902SRodney W. Grimes {
602c73d99b5SRuslan Ermilov 	struct icmpstat icmpstat, zerostat;
6034e00c309SGarrett Wollman 	int i, first;
6044e00c309SGarrett Wollman 	int mib[4];		/* CTL_NET + PF_INET + IPPROTO_ICMP + req */
6054e00c309SGarrett Wollman 	size_t len;
6069b50d902SRodney W. Grimes 
6074e00c309SGarrett Wollman 	mib[0] = CTL_NET;
6084e00c309SGarrett Wollman 	mib[1] = PF_INET;
6094e00c309SGarrett Wollman 	mib[2] = IPPROTO_ICMP;
6104e00c309SGarrett Wollman 	mib[3] = ICMPCTL_STATS;
6114e00c309SGarrett Wollman 
6124e00c309SGarrett Wollman 	len = sizeof icmpstat;
613c73d99b5SRuslan Ermilov 	if (zflag)
614c73d99b5SRuslan Ermilov 		memset(&zerostat, 0, len);
615c73d99b5SRuslan Ermilov 	if (sysctl(mib, 4, &icmpstat, &len,
616c73d99b5SRuslan Ermilov 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
617c73d99b5SRuslan Ermilov 		warn("sysctl: net.inet.icmp.stats");
618c73d99b5SRuslan Ermilov 		return;
619c73d99b5SRuslan Ermilov 	}
6204e00c309SGarrett Wollman 
6219b50d902SRodney W. Grimes 	printf("%s:\n", name);
6229b50d902SRodney W. Grimes 
6239b50d902SRodney W. Grimes #define	p(f, m) if (icmpstat.f || sflag <= 1) \
6249b50d902SRodney W. Grimes     printf(m, icmpstat.f, plural(icmpstat.f))
62522694ebaSBruce Evans #define	p1a(f, m) if (icmpstat.f || sflag <= 1) \
62622694ebaSBruce Evans     printf(m, icmpstat.f)
6279b50d902SRodney W. Grimes 
6287d56c0eeSAlexander Langer 	p(icps_error, "\t%lu call%s to icmp_error\n");
6299b50d902SRodney W. Grimes 	p(icps_oldicmp,
6307d56c0eeSAlexander Langer 	    "\t%lu error%s not generated 'cuz old message was icmp\n");
6319b50d902SRodney W. Grimes 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
6329b50d902SRodney W. Grimes 		if (icmpstat.icps_outhist[i] != 0) {
6339b50d902SRodney W. Grimes 			if (first) {
6349b50d902SRodney W. Grimes 				printf("\tOutput histogram:\n");
6359b50d902SRodney W. Grimes 				first = 0;
6369b50d902SRodney W. Grimes 			}
6377d56c0eeSAlexander Langer 			printf("\t\t%s: %lu\n", icmpnames[i],
6389b50d902SRodney W. Grimes 				icmpstat.icps_outhist[i]);
6399b50d902SRodney W. Grimes 		}
6407d56c0eeSAlexander Langer 	p(icps_badcode, "\t%lu message%s with bad code fields\n");
6417d56c0eeSAlexander Langer 	p(icps_tooshort, "\t%lu message%s < minimum length\n");
6427d56c0eeSAlexander Langer 	p(icps_checksum, "\t%lu bad checksum%s\n");
6437d56c0eeSAlexander Langer 	p(icps_badlen, "\t%lu message%s with bad length\n");
64422694ebaSBruce Evans 	p1a(icps_bmcastecho, "\t%lu multicast echo requests ignored\n");
64522694ebaSBruce Evans 	p1a(icps_bmcasttstamp, "\t%lu multicast timestamp requests ignored\n");
6469b50d902SRodney W. Grimes 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
6479b50d902SRodney W. Grimes 		if (icmpstat.icps_inhist[i] != 0) {
6489b50d902SRodney W. Grimes 			if (first) {
6499b50d902SRodney W. Grimes 				printf("\tInput histogram:\n");
6509b50d902SRodney W. Grimes 				first = 0;
6519b50d902SRodney W. Grimes 			}
6527d56c0eeSAlexander Langer 			printf("\t\t%s: %lu\n", icmpnames[i],
6539b50d902SRodney W. Grimes 				icmpstat.icps_inhist[i]);
6549b50d902SRodney W. Grimes 		}
6557d56c0eeSAlexander Langer 	p(icps_reflect, "\t%lu message response%s generated\n");
6569b50d902SRodney W. Grimes #undef p
65722694ebaSBruce Evans #undef p1a
6584e00c309SGarrett Wollman 	mib[3] = ICMPCTL_MASKREPL;
6594e00c309SGarrett Wollman 	len = sizeof i;
6604e00c309SGarrett Wollman 	if (sysctl(mib, 4, &i, &len, (void *)0, 0) < 0)
6614e00c309SGarrett Wollman 		return;
6624e00c309SGarrett Wollman 	printf("\tICMP address mask responses are %sabled\n",
6634e00c309SGarrett Wollman 	       i ? "en" : "dis");
6649b50d902SRodney W. Grimes }
6659b50d902SRodney W. Grimes 
6669b50d902SRodney W. Grimes /*
6679b50d902SRodney W. Grimes  * Dump IGMP statistics structure.
6689b50d902SRodney W. Grimes  */
6699b50d902SRodney W. Grimes void
670f964d60dSAssar Westerlund igmp_stats(u_long off __unused, char *name, int af __unused)
6719b50d902SRodney W. Grimes {
672c73d99b5SRuslan Ermilov 	struct igmpstat igmpstat, zerostat;
6734f81ef50SGarrett Wollman 	size_t len = sizeof igmpstat;
6749b50d902SRodney W. Grimes 
675c73d99b5SRuslan Ermilov 	if (zflag)
676c73d99b5SRuslan Ermilov 		memset(&zerostat, 0, len);
677c73d99b5SRuslan Ermilov 	if (sysctlbyname("net.inet.igmp.stats", &igmpstat, &len,
678c73d99b5SRuslan Ermilov 	    zflag ? &zerostat : NULL, zflag ? len : 0) < 0) {
6794f81ef50SGarrett Wollman 		warn("sysctl: net.inet.igmp.stats");
6809b50d902SRodney W. Grimes 		return;
6814f81ef50SGarrett Wollman 	}
6824f81ef50SGarrett Wollman 
6839b50d902SRodney W. Grimes 	printf("%s:\n", name);
6849b50d902SRodney W. Grimes 
6859b50d902SRodney W. Grimes #define	p(f, m) if (igmpstat.f || sflag <= 1) \
6869b50d902SRodney W. Grimes     printf(m, igmpstat.f, plural(igmpstat.f))
6879b50d902SRodney W. Grimes #define	py(f, m) if (igmpstat.f || sflag <= 1) \
6889b50d902SRodney W. Grimes     printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y")
6899b50d902SRodney W. Grimes 	p(igps_rcv_total, "\t%u message%s received\n");
6909b50d902SRodney W. Grimes         p(igps_rcv_tooshort, "\t%u message%s received with too few bytes\n");
6919b50d902SRodney W. Grimes         p(igps_rcv_badsum, "\t%u message%s received with bad checksum\n");
6929b50d902SRodney W. Grimes         py(igps_rcv_queries, "\t%u membership quer%s received\n");
6939b50d902SRodney W. Grimes         py(igps_rcv_badqueries, "\t%u membership quer%s received with invalid field(s)\n");
6949b50d902SRodney W. Grimes         p(igps_rcv_reports, "\t%u membership report%s received\n");
6959b50d902SRodney W. Grimes         p(igps_rcv_badreports, "\t%u membership report%s received with invalid field(s)\n");
6969b50d902SRodney W. Grimes         p(igps_rcv_ourreports, "\t%u membership report%s received for groups to which we belong\n");
6979b50d902SRodney W. Grimes         p(igps_snd_reports, "\t%u membership report%s sent\n");
6989b50d902SRodney W. Grimes #undef p
6999b50d902SRodney W. Grimes #undef py
7009b50d902SRodney W. Grimes }
7019b50d902SRodney W. Grimes 
7029b50d902SRodney W. Grimes /*
7039b50d902SRodney W. Grimes  * Pretty print an Internet address (net address + port).
7049b50d902SRodney W. Grimes  */
7059b50d902SRodney W. Grimes void
7065e051718SAssar Westerlund inetprint(struct in_addr *in, int port, char *proto, int numeric_port)
7079b50d902SRodney W. Grimes {
7089b50d902SRodney W. Grimes 	struct servent *sp = 0;
7099b50d902SRodney W. Grimes 	char line[80], *cp;
710cfa1ca9dSYoshinobu Inoue 	int width;
7119b50d902SRodney W. Grimes 
712080b7f49SDag-Erling Smørgrav 	if (Wflag)
713080b7f49SDag-Erling Smørgrav 	    sprintf(line, "%s.", inetname(in));
714080b7f49SDag-Erling Smørgrav 	else
71565ea0024SAssar Westerlund 	    sprintf(line, "%.*s.", (Aflag && !numeric_port) ? 12 : 16, inetname(in));
7169b50d902SRodney W. Grimes 	cp = index(line, '\0');
71765ea0024SAssar Westerlund 	if (!numeric_port && port)
7189b50d902SRodney W. Grimes 		sp = getservbyport((int)port, proto);
7199b50d902SRodney W. Grimes 	if (sp || port == 0)
7201ef69972SAndrey A. Chernov 		sprintf(cp, "%.15s ", sp ? sp->s_name : "*");
7219b50d902SRodney W. Grimes 	else
7229b50d902SRodney W. Grimes 		sprintf(cp, "%d ", ntohs((u_short)port));
723080b7f49SDag-Erling Smørgrav 	width = (Aflag && !Wflag) ? 18 : 22;
724080b7f49SDag-Erling Smørgrav 	if (Wflag)
725080b7f49SDag-Erling Smørgrav 	    printf("%-*s ", width, line);
726080b7f49SDag-Erling Smørgrav 	else
727cfa1ca9dSYoshinobu Inoue 	    printf("%-*.*s ", width, width, line);
7289b50d902SRodney W. Grimes }
7299b50d902SRodney W. Grimes 
7309b50d902SRodney W. Grimes /*
7319b50d902SRodney W. Grimes  * Construct an Internet address representation.
73265ea0024SAssar Westerlund  * If numeric_addr has been supplied, give
7339b50d902SRodney W. Grimes  * numeric value, otherwise try for symbolic name.
7349b50d902SRodney W. Grimes  */
7359b50d902SRodney W. Grimes char *
7365e051718SAssar Westerlund inetname(struct in_addr *inp)
7379b50d902SRodney W. Grimes {
7389b50d902SRodney W. Grimes 	register char *cp;
739d121b556SBrian Somers 	static char line[MAXHOSTNAMELEN];
7409b50d902SRodney W. Grimes 	struct hostent *hp;
7419b50d902SRodney W. Grimes 	struct netent *np;
7429b50d902SRodney W. Grimes 
7439b50d902SRodney W. Grimes 	cp = 0;
74465ea0024SAssar Westerlund 	if (!numeric_addr && inp->s_addr != INADDR_ANY) {
7459b50d902SRodney W. Grimes 		int net = inet_netof(*inp);
7469b50d902SRodney W. Grimes 		int lna = inet_lnaof(*inp);
7479b50d902SRodney W. Grimes 
7489b50d902SRodney W. Grimes 		if (lna == INADDR_ANY) {
7499b50d902SRodney W. Grimes 			np = getnetbyaddr(net, AF_INET);
7509b50d902SRodney W. Grimes 			if (np)
7519b50d902SRodney W. Grimes 				cp = np->n_name;
7529b50d902SRodney W. Grimes 		}
7539b50d902SRodney W. Grimes 		if (cp == 0) {
7549b50d902SRodney W. Grimes 			hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET);
7559b50d902SRodney W. Grimes 			if (hp) {
7569b50d902SRodney W. Grimes 				cp = hp->h_name;
757d121b556SBrian Somers 				trimdomain(cp, strlen(cp));
7589b50d902SRodney W. Grimes 			}
7599b50d902SRodney W. Grimes 		}
7609b50d902SRodney W. Grimes 	}
7619b50d902SRodney W. Grimes 	if (inp->s_addr == INADDR_ANY)
7629b50d902SRodney W. Grimes 		strcpy(line, "*");
7639a1f6729SWarner Losh 	else if (cp) {
7649a1f6729SWarner Losh 		strncpy(line, cp, sizeof(line) - 1);
7659a1f6729SWarner Losh 		line[sizeof(line) - 1] = '\0';
7669a1f6729SWarner Losh 	} else {
7679b50d902SRodney W. Grimes 		inp->s_addr = ntohl(inp->s_addr);
76822694ebaSBruce Evans #define C(x)	((u_int)((x) & 0xff))
76922694ebaSBruce Evans 		sprintf(line, "%u.%u.%u.%u", C(inp->s_addr >> 24),
7709b50d902SRodney W. Grimes 		    C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr));
7719b50d902SRodney W. Grimes 	}
7729b50d902SRodney W. Grimes 	return (line);
7739b50d902SRodney W. Grimes }
774