xref: /freebsd/usr.bin/netstat/inet.c (revision d121b55666ca1b5d095feff691672167ce261aa6)
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 
839b50d902SRodney W. Grimes char	*inetname __P((struct in_addr *));
848d612dd2SPoul-Henning Kamp void	inetprint __P((struct in_addr *, int, char *, int));
85cfa1ca9dSYoshinobu Inoue #ifdef INET6
86cfa1ca9dSYoshinobu Inoue extern void	inet6print __P((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
97cfa1ca9dSYoshinobu Inoue protopr(proto, name, af)
984f81ef50SGarrett Wollman 	u_long proto;		/* for sysctl version we pass proto # */
999b50d902SRodney W. Grimes 	char *name;
100cfa1ca9dSYoshinobu Inoue 	int af;
1019b50d902SRodney W. Grimes {
1029b50d902SRodney W. Grimes 	int istcp;
1039b50d902SRodney W. Grimes 	static int first = 1;
1044f81ef50SGarrett Wollman 	char *buf;
1054f81ef50SGarrett Wollman 	const char *mibvar;
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) {
1474f81ef50SGarrett Wollman 		warn("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. */
1704f81ef50SGarrett Wollman 		if (so->xso_protocol != 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 
177cfa1ca9dSYoshinobu Inoue 		if ((af == AF_INET && (inp->inp_vflag & INP_IPV4) == 0)
178cfa1ca9dSYoshinobu Inoue #ifdef INET6
179cfa1ca9dSYoshinobu Inoue 		    || (af == AF_INET6 && (inp->inp_vflag & INP_IPV6) == 0)
180cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
181cfa1ca9dSYoshinobu Inoue 		    || (af == 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 		    (
191cfa1ca9dSYoshinobu Inoue 		     (af == AF_INET &&
192cfa1ca9dSYoshinobu Inoue 		      inet_lnaof(inp->inp_laddr) == INADDR_ANY)
193cfa1ca9dSYoshinobu Inoue #ifdef INET6
194cfa1ca9dSYoshinobu Inoue 		     || (af == AF_INET6 &&
195cfa1ca9dSYoshinobu Inoue 			 IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
196cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
197cfa1ca9dSYoshinobu Inoue 		     || (af == AF_UNSPEC &&
198cfa1ca9dSYoshinobu Inoue 			 (((inp->inp_vflag & INP_IPV4) != 0 &&
199cfa1ca9dSYoshinobu Inoue 			   inet_lnaof(inp->inp_laddr) == INADDR_ANY)
200cfa1ca9dSYoshinobu Inoue #ifdef INET6
201cfa1ca9dSYoshinobu Inoue 			  || ((inp->inp_vflag & INP_IPV6) != 0 &&
202cfa1ca9dSYoshinobu Inoue 			      IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
203cfa1ca9dSYoshinobu Inoue #endif
204cfa1ca9dSYoshinobu Inoue 			  ))
205cfa1ca9dSYoshinobu Inoue 		     ))
2064f81ef50SGarrett Wollman 			continue;
2074f81ef50SGarrett Wollman 
2089b50d902SRodney W. Grimes 		if (first) {
209ac55add0SGuido van Rooij 			if (!Lflag) {
2109b50d902SRodney W. Grimes 				printf("Active Internet connections");
2119b50d902SRodney W. Grimes 				if (aflag)
2129b50d902SRodney W. Grimes 					printf(" (including servers)");
213ac55add0SGuido van Rooij 			} else
214ac55add0SGuido van Rooij 				printf(
215ac55add0SGuido van Rooij 	"Current listen queue sizes (qlen/incqlen/maxqlen)");
2169b50d902SRodney W. Grimes 			putchar('\n');
2179b50d902SRodney W. Grimes 			if (Aflag)
2184f81ef50SGarrett Wollman 				printf("%-8.8s ", "Socket");
219ac55add0SGuido van Rooij 			if (Lflag)
220fc60ab7bSYoshinobu Inoue 				printf("%-14.14s %-22.22s\n",
221ac55add0SGuido van Rooij 					"Listen", "Local Address");
222ac55add0SGuido van Rooij 			else
223cfa1ca9dSYoshinobu Inoue 				printf(Aflag ?
224cfa1ca9dSYoshinobu Inoue 		"%-5.5s %-6.6s %-6.6s  %-18.18s %-18.18s %s\n" :
225cfa1ca9dSYoshinobu Inoue 		"%-5.5s %-6.6s %-6.6s  %-22.22s %-22.22s %s\n",
2269b50d902SRodney W. Grimes 					"Proto", "Recv-Q", "Send-Q",
227ac55add0SGuido van Rooij 					"Local Address", "Foreign Address",
228ac55add0SGuido van Rooij 					"(state)");
2299b50d902SRodney W. Grimes 			first = 0;
2309b50d902SRodney W. Grimes 		}
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 		}
237ac55add0SGuido van Rooij 		if (Lflag)
238ac55add0SGuido van Rooij 			if (so->so_qlimit) {
239ac55add0SGuido van Rooij 				char buf[15];
240ac55add0SGuido van Rooij 
241ac55add0SGuido van Rooij 				snprintf(buf, 15, "%d/%d/%d", so->so_qlen,
242ac55add0SGuido van Rooij 					 so->so_incqlen, so->so_qlimit);
243ac55add0SGuido van Rooij 				printf("%-14.14s ", buf);
244ac55add0SGuido van Rooij 			} else
245ac55add0SGuido van Rooij 				continue;
246fc60ab7bSYoshinobu Inoue 		else {
247fc60ab7bSYoshinobu Inoue 			const u_char *vchar;
248fc60ab7bSYoshinobu Inoue 
249cfa1ca9dSYoshinobu Inoue #ifdef INET6
250fc60ab7bSYoshinobu Inoue 			if ((inp->inp_vflag & INP_IPV6) != 0)
251fc60ab7bSYoshinobu Inoue 				vchar = ((inp->inp_vflag & INP_IPV4) != 0)
252fc60ab7bSYoshinobu Inoue 					? "46" : "6 ";
253fc60ab7bSYoshinobu Inoue 			else
254cfa1ca9dSYoshinobu Inoue #endif
255fc60ab7bSYoshinobu Inoue 			vchar = ((inp->inp_vflag & INP_IPV4) != 0)
256fc60ab7bSYoshinobu Inoue 					? "4 " : "  ";
257fc60ab7bSYoshinobu Inoue 
258fc60ab7bSYoshinobu Inoue 			printf("%-3.3s%-2.2s %6ld %6ld  ", name, vchar,
259cfa1ca9dSYoshinobu Inoue 			       so->so_rcv.sb_cc,
2604f81ef50SGarrett Wollman 			       so->so_snd.sb_cc);
261fc60ab7bSYoshinobu Inoue 		}
2628d612dd2SPoul-Henning Kamp 		if (nflag) {
263cfa1ca9dSYoshinobu Inoue 			if (inp->inp_vflag & INP_IPV4) {
2644f81ef50SGarrett Wollman 				inetprint(&inp->inp_laddr, (int)inp->inp_lport,
2658d612dd2SPoul-Henning Kamp 					  name, 1);
266ac55add0SGuido van Rooij 				if (!Lflag)
267ac55add0SGuido van Rooij 					inetprint(&inp->inp_faddr,
268ac55add0SGuido van Rooij 						  (int)inp->inp_fport, name, 1);
269cfa1ca9dSYoshinobu Inoue 			}
270cfa1ca9dSYoshinobu Inoue #ifdef INET6
271cfa1ca9dSYoshinobu Inoue 			else if (inp->inp_vflag & INP_IPV6) {
272cfa1ca9dSYoshinobu Inoue 				inet6print(&inp->in6p_laddr,
273cfa1ca9dSYoshinobu Inoue 					   (int)inp->inp_lport, name, 1);
274ac55add0SGuido van Rooij 				if (!Lflag)
275cfa1ca9dSYoshinobu Inoue 					inet6print(&inp->in6p_faddr,
276cfa1ca9dSYoshinobu Inoue 						   (int)inp->inp_fport, name, 1);
277cfa1ca9dSYoshinobu Inoue 			} /* else nothing printed now */
278cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
2794f81ef50SGarrett Wollman 		} else if (inp->inp_flags & INP_ANONPORT) {
280cfa1ca9dSYoshinobu Inoue 			if (inp->inp_vflag & INP_IPV4) {
2814f81ef50SGarrett Wollman 				inetprint(&inp->inp_laddr, (int)inp->inp_lport,
2828d612dd2SPoul-Henning Kamp 					  name, 1);
283ac55add0SGuido van Rooij 				if (!Lflag)
284ac55add0SGuido van Rooij 					inetprint(&inp->inp_faddr,
285ac55add0SGuido van Rooij 						  (int)inp->inp_fport, name, 0);
286cfa1ca9dSYoshinobu Inoue 			}
287cfa1ca9dSYoshinobu Inoue #ifdef INET6
288cfa1ca9dSYoshinobu Inoue 			else if (inp->inp_vflag & INP_IPV6) {
289cfa1ca9dSYoshinobu Inoue 				inet6print(&inp->in6p_laddr,
290cfa1ca9dSYoshinobu Inoue 					   (int)inp->inp_lport, name, 1);
291ac55add0SGuido van Rooij 				if (!Lflag)
292cfa1ca9dSYoshinobu Inoue 					inet6print(&inp->in6p_faddr,
293cfa1ca9dSYoshinobu Inoue 						   (int)inp->inp_fport, name, 0);
294cfa1ca9dSYoshinobu Inoue 			} /* else nothing printed now */
295cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
2968d612dd2SPoul-Henning Kamp 		} else {
297cfa1ca9dSYoshinobu Inoue 			if (inp->inp_vflag & INP_IPV4) {
2984f81ef50SGarrett Wollman 				inetprint(&inp->inp_laddr, (int)inp->inp_lport,
2998d612dd2SPoul-Henning Kamp 					  name, 0);
300ac55add0SGuido van Rooij 				if (!Lflag)
301ac55add0SGuido van Rooij 					inetprint(&inp->inp_faddr,
302ac55add0SGuido van Rooij 						  (int)inp->inp_fport, name,
303ac55add0SGuido van Rooij 						  inp->inp_lport !=
304ac55add0SGuido van Rooij 							inp->inp_fport);
305cfa1ca9dSYoshinobu Inoue 			}
306cfa1ca9dSYoshinobu Inoue #ifdef INET6
307cfa1ca9dSYoshinobu Inoue 			else if (inp->inp_vflag & INP_IPV6) {
308cfa1ca9dSYoshinobu Inoue 				inet6print(&inp->in6p_laddr,
309cfa1ca9dSYoshinobu Inoue 					   (int)inp->inp_lport, name, 0);
310ac55add0SGuido van Rooij 				if (!Lflag)
311cfa1ca9dSYoshinobu Inoue 					inet6print(&inp->in6p_faddr,
312cfa1ca9dSYoshinobu Inoue 						   (int)inp->inp_fport, name,
313ac55add0SGuido van Rooij 						   inp->inp_lport !=
314ac55add0SGuido van Rooij 							inp->inp_fport);
315cfa1ca9dSYoshinobu Inoue 			} /* else nothing printed now */
316cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
3178d612dd2SPoul-Henning Kamp 		}
318ac55add0SGuido van Rooij 		if (istcp && !Lflag) {
3194f81ef50SGarrett Wollman 			if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES)
3204f81ef50SGarrett Wollman 				printf("%d", tp->t_state);
3219a94a597SGarrett Wollman                       else {
3224f81ef50SGarrett Wollman 				printf("%s", tcpstates[tp->t_state]);
323513822ddSAdam David #if defined(TF_NEEDSYN) && defined(TF_NEEDFIN)
3249a94a597SGarrett Wollman                               /* Show T/TCP `hidden state' */
3254f81ef50SGarrett Wollman                               if (tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN))
3269a94a597SGarrett Wollman                                       putchar('*');
327513822ddSAdam David #endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */
3289a94a597SGarrett Wollman                       }
3299b50d902SRodney W. Grimes 		}
3309b50d902SRodney W. Grimes 		putchar('\n');
3319b50d902SRodney W. Grimes 	}
3324f81ef50SGarrett Wollman 	if (xig != oxig && xig->xig_gen != oxig->xig_gen) {
3334f81ef50SGarrett Wollman 		if (oxig->xig_count > xig->xig_count) {
3344f81ef50SGarrett Wollman 			printf("Some %s sockets may have been deleted.\n",
3354f81ef50SGarrett Wollman 			       name);
3364f81ef50SGarrett Wollman 		} else if (oxig->xig_count < xig->xig_count) {
3374f81ef50SGarrett Wollman 			printf("Some %s sockets may have been created.\n",
3384f81ef50SGarrett Wollman 			       name);
3394f81ef50SGarrett Wollman 		} else {
3404f81ef50SGarrett Wollman 			printf("Some %s sockets may have been created or deleted",
3414f81ef50SGarrett Wollman 			       name);
3424f81ef50SGarrett Wollman 		}
3434f81ef50SGarrett Wollman 	}
3444f81ef50SGarrett Wollman 	free(buf);
3459b50d902SRodney W. Grimes }
3469b50d902SRodney W. Grimes 
3479b50d902SRodney W. Grimes /*
3489b50d902SRodney W. Grimes  * Dump TCP statistics structure.
3499b50d902SRodney W. Grimes  */
3509b50d902SRodney W. Grimes void
3519b50d902SRodney W. Grimes tcp_stats(off, name)
3529b50d902SRodney W. Grimes 	u_long off;
3539b50d902SRodney W. Grimes 	char *name;
3549b50d902SRodney W. Grimes {
3559b50d902SRodney W. Grimes 	struct tcpstat tcpstat;
3564f81ef50SGarrett Wollman 	size_t len = sizeof tcpstat;
3579b50d902SRodney W. Grimes 
3584f81ef50SGarrett Wollman 	if (sysctlbyname("net.inet.tcp.stats", &tcpstat, &len, 0, 0) < 0) {
3594f81ef50SGarrett Wollman 		warn("sysctl: net.inet.tcp.stats");
3609b50d902SRodney W. Grimes 		return;
3614f81ef50SGarrett Wollman 	}
3624f81ef50SGarrett Wollman 
363cfa1ca9dSYoshinobu Inoue #ifdef INET6
364cfa1ca9dSYoshinobu Inoue 	if (tcp_done != 0)
365cfa1ca9dSYoshinobu Inoue 		return;
366cfa1ca9dSYoshinobu Inoue 	else
367cfa1ca9dSYoshinobu Inoue 		tcp_done = 1;
368cfa1ca9dSYoshinobu Inoue #endif
369cfa1ca9dSYoshinobu Inoue 
3709b50d902SRodney W. Grimes 	printf ("%s:\n", name);
3719b50d902SRodney W. Grimes 
3729b50d902SRodney W. Grimes #define	p(f, m) if (tcpstat.f || sflag <= 1) \
3739b50d902SRodney W. Grimes     printf(m, tcpstat.f, plural(tcpstat.f))
37422694ebaSBruce Evans #define	p1a(f, m) if (tcpstat.f || sflag <= 1) \
37522694ebaSBruce Evans     printf(m, tcpstat.f)
3769b50d902SRodney W. Grimes #define	p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
3779b50d902SRodney W. Grimes     printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2))
37822694ebaSBruce Evans #define	p2a(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
37922694ebaSBruce Evans     printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2)
3809b50d902SRodney W. Grimes #define	p3(f, m) if (tcpstat.f || sflag <= 1) \
3819b50d902SRodney W. Grimes     printf(m, tcpstat.f, plurales(tcpstat.f))
3829b50d902SRodney W. Grimes 
383e1fb4daaSPaul Traina 	p(tcps_sndtotal, "\t%lu packet%s sent\n");
3849b50d902SRodney W. Grimes 	p2(tcps_sndpack,tcps_sndbyte,
385e1fb4daaSPaul Traina 		"\t\t%lu data packet%s (%lu byte%s)\n");
3869b50d902SRodney W. Grimes 	p2(tcps_sndrexmitpack, tcps_sndrexmitbyte,
387e1fb4daaSPaul Traina 		"\t\t%lu data packet%s (%lu byte%s) retransmitted\n");
388e1fb4daaSPaul Traina 	p(tcps_mturesent, "\t\t%lu resend%s initiated by MTU discovery\n");
38922694ebaSBruce Evans 	p2a(tcps_sndacks, tcps_delack,
390e1fb4daaSPaul Traina 		"\t\t%lu ack-only packet%s (%lu delayed)\n");
391e1fb4daaSPaul Traina 	p(tcps_sndurg, "\t\t%lu URG only packet%s\n");
392e1fb4daaSPaul Traina 	p(tcps_sndprobe, "\t\t%lu window probe packet%s\n");
393e1fb4daaSPaul Traina 	p(tcps_sndwinup, "\t\t%lu window update packet%s\n");
394e1fb4daaSPaul Traina 	p(tcps_sndctrl, "\t\t%lu control packet%s\n");
395e1fb4daaSPaul Traina 	p(tcps_rcvtotal, "\t%lu packet%s received\n");
396e1fb4daaSPaul Traina 	p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%lu ack%s (for %lu byte%s)\n");
397e1fb4daaSPaul Traina 	p(tcps_rcvdupack, "\t\t%lu duplicate ack%s\n");
398e1fb4daaSPaul Traina 	p(tcps_rcvacktoomuch, "\t\t%lu ack%s for unsent data\n");
3999b50d902SRodney W. Grimes 	p2(tcps_rcvpack, tcps_rcvbyte,
400e1fb4daaSPaul Traina 		"\t\t%lu packet%s (%lu byte%s) received in-sequence\n");
4019b50d902SRodney W. Grimes 	p2(tcps_rcvduppack, tcps_rcvdupbyte,
402e1fb4daaSPaul Traina 		"\t\t%lu completely duplicate packet%s (%lu byte%s)\n");
403e1fb4daaSPaul Traina 	p(tcps_pawsdrop, "\t\t%lu old duplicate packet%s\n");
4049b50d902SRodney W. Grimes 	p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte,
405e1fb4daaSPaul Traina 		"\t\t%lu packet%s with some dup. data (%lu byte%s duped)\n");
4069b50d902SRodney W. Grimes 	p2(tcps_rcvoopack, tcps_rcvoobyte,
407e1fb4daaSPaul Traina 		"\t\t%lu out-of-order packet%s (%lu byte%s)\n");
4089b50d902SRodney W. Grimes 	p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin,
409e1fb4daaSPaul Traina 		"\t\t%lu packet%s (%lu byte%s) of data after window\n");
410e1fb4daaSPaul Traina 	p(tcps_rcvwinprobe, "\t\t%lu window probe%s\n");
411e1fb4daaSPaul Traina 	p(tcps_rcvwinupd, "\t\t%lu window update packet%s\n");
412e1fb4daaSPaul Traina 	p(tcps_rcvafterclose, "\t\t%lu packet%s received after close\n");
413e1fb4daaSPaul Traina 	p(tcps_rcvbadsum, "\t\t%lu discarded for bad checksum%s\n");
414e1fb4daaSPaul Traina 	p(tcps_rcvbadoff, "\t\t%lu discarded for bad header offset field%s\n");
41522694ebaSBruce Evans 	p1a(tcps_rcvshort, "\t\t%lu discarded because packet too short\n");
416e1fb4daaSPaul Traina 	p(tcps_connattempt, "\t%lu connection request%s\n");
417e1fb4daaSPaul Traina 	p(tcps_accepts, "\t%lu connection accept%s\n");
418e1fb4daaSPaul Traina 	p(tcps_badsyn, "\t%lu bad connection attempt%s\n");
419e1fb4daaSPaul Traina 	p(tcps_listendrop, "\t%lu listen queue overflow%s\n");
420e1fb4daaSPaul Traina 	p(tcps_connects, "\t%lu connection%s established (including accepts)\n");
4219b50d902SRodney W. Grimes 	p2(tcps_closed, tcps_drops,
422e1fb4daaSPaul Traina 		"\t%lu connection%s closed (including %lu drop%s)\n");
423e1fb4daaSPaul Traina 	p(tcps_cachedrtt, "\t\t%lu connection%s updated cached RTT on close\n");
424861b1828SGarrett Wollman 	p(tcps_cachedrttvar,
425e1fb4daaSPaul Traina 	  "\t\t%lu connection%s updated cached RTT variance on close\n");
426861b1828SGarrett Wollman 	p(tcps_cachedssthresh,
427e1fb4daaSPaul Traina 	  "\t\t%lu connection%s updated cached ssthresh on close\n");
428e1fb4daaSPaul Traina 	p(tcps_conndrops, "\t%lu embryonic connection%s dropped\n");
4299b50d902SRodney W. Grimes 	p2(tcps_rttupdated, tcps_segstimed,
430e1fb4daaSPaul Traina 		"\t%lu segment%s updated rtt (of %lu attempt%s)\n");
431e1fb4daaSPaul Traina 	p(tcps_rexmttimeo, "\t%lu retransmit timeout%s\n");
432e1fb4daaSPaul Traina 	p(tcps_timeoutdrop, "\t\t%lu connection%s dropped by rexmit timeout\n");
433e1fb4daaSPaul Traina 	p(tcps_persisttimeo, "\t%lu persist timeout%s\n");
434e1fb4daaSPaul Traina 	p(tcps_persistdrop, "\t\t%lu connection%s dropped by persist timeout\n");
435e1fb4daaSPaul Traina 	p(tcps_keeptimeo, "\t%lu keepalive timeout%s\n");
436e1fb4daaSPaul Traina 	p(tcps_keepprobe, "\t\t%lu keepalive probe%s sent\n");
437e1fb4daaSPaul Traina 	p(tcps_keepdrops, "\t\t%lu connection%s dropped by keepalive\n");
438e1fb4daaSPaul Traina 	p(tcps_predack, "\t%lu correct ACK header prediction%s\n");
439e1fb4daaSPaul Traina 	p(tcps_preddat, "\t%lu correct data packet header prediction%s\n");
4409b50d902SRodney W. Grimes #undef p
44122694ebaSBruce Evans #undef p1a
4429b50d902SRodney W. Grimes #undef p2
44322694ebaSBruce Evans #undef p2a
4449b50d902SRodney W. Grimes #undef p3
4459b50d902SRodney W. Grimes }
4469b50d902SRodney W. Grimes 
4479b50d902SRodney W. Grimes /*
4489b50d902SRodney W. Grimes  * Dump UDP statistics structure.
4499b50d902SRodney W. Grimes  */
4509b50d902SRodney W. Grimes void
4519b50d902SRodney W. Grimes udp_stats(off, name)
4529b50d902SRodney W. Grimes 	u_long off;
4539b50d902SRodney W. Grimes 	char *name;
4549b50d902SRodney W. Grimes {
4559b50d902SRodney W. Grimes 	struct udpstat udpstat;
4564f81ef50SGarrett Wollman 	size_t len = sizeof udpstat;
4579b50d902SRodney W. Grimes 	u_long delivered;
4589b50d902SRodney W. Grimes 
4594f81ef50SGarrett Wollman 	if (sysctlbyname("net.inet.udp.stats", &udpstat, &len, 0, 0) < 0) {
4604f81ef50SGarrett Wollman 		warn("sysctl: net.inet.udp.stats");
4619b50d902SRodney W. Grimes 		return;
4624f81ef50SGarrett Wollman 	}
4634f81ef50SGarrett Wollman 
464cfa1ca9dSYoshinobu Inoue #ifdef INET6
465cfa1ca9dSYoshinobu Inoue 	if (udp_done != 0)
466cfa1ca9dSYoshinobu Inoue 		return;
467cfa1ca9dSYoshinobu Inoue 	else
468cfa1ca9dSYoshinobu Inoue 		udp_done = 1;
469cfa1ca9dSYoshinobu Inoue #endif
470cfa1ca9dSYoshinobu Inoue 
4719b50d902SRodney W. Grimes 	printf("%s:\n", name);
4729b50d902SRodney W. Grimes #define	p(f, m) if (udpstat.f || sflag <= 1) \
4739b50d902SRodney W. Grimes     printf(m, udpstat.f, plural(udpstat.f))
47422694ebaSBruce Evans #define	p1a(f, m) if (udpstat.f || sflag <= 1) \
47522694ebaSBruce Evans     printf(m, udpstat.f)
4767d56c0eeSAlexander Langer 	p(udps_ipackets, "\t%lu datagram%s received\n");
47722694ebaSBruce Evans 	p1a(udps_hdrops, "\t%lu with incomplete header\n");
47822694ebaSBruce Evans 	p1a(udps_badlen, "\t%lu with bad data length field\n");
47922694ebaSBruce Evans 	p1a(udps_badsum, "\t%lu with bad checksum\n");
480fb9aaba0SRuslan Ermilov 	p1a(udps_nosum, "\t%lu with no checksum\n");
48122694ebaSBruce Evans 	p1a(udps_noport, "\t%lu dropped due to no socket\n");
48222694ebaSBruce Evans 	p(udps_noportbcast,
48322694ebaSBruce Evans 	    "\t%lu broadcast/multicast datagram%s dropped due to no socket\n");
48422694ebaSBruce Evans 	p1a(udps_fullsock, "\t%lu dropped due to full socket buffers\n");
48522694ebaSBruce Evans 	p1a(udpps_pcbhashmiss, "\t%lu not for hashed pcb\n");
4869b50d902SRodney W. Grimes 	delivered = udpstat.udps_ipackets -
4879b50d902SRodney W. Grimes 		    udpstat.udps_hdrops -
4889b50d902SRodney W. Grimes 		    udpstat.udps_badlen -
4899b50d902SRodney W. Grimes 		    udpstat.udps_badsum -
4909b50d902SRodney W. Grimes 		    udpstat.udps_noport -
4919b50d902SRodney W. Grimes 		    udpstat.udps_noportbcast -
4929b50d902SRodney W. Grimes 		    udpstat.udps_fullsock;
4939b50d902SRodney W. Grimes 	if (delivered || sflag <= 1)
4947d56c0eeSAlexander Langer 		printf("\t%lu delivered\n", delivered);
4957d56c0eeSAlexander Langer 	p(udps_opackets, "\t%lu datagram%s output\n");
4969b50d902SRodney W. Grimes #undef p
49722694ebaSBruce Evans #undef p1a
4989b50d902SRodney W. Grimes }
4999b50d902SRodney W. Grimes 
5009b50d902SRodney W. Grimes /*
5019b50d902SRodney W. Grimes  * Dump IP statistics structure.
5029b50d902SRodney W. Grimes  */
5039b50d902SRodney W. Grimes void
5049b50d902SRodney W. Grimes ip_stats(off, name)
5059b50d902SRodney W. Grimes 	u_long off;
5069b50d902SRodney W. Grimes 	char *name;
5079b50d902SRodney W. Grimes {
5089b50d902SRodney W. Grimes 	struct ipstat ipstat;
5094f81ef50SGarrett Wollman 	size_t len = sizeof ipstat;
5109b50d902SRodney W. Grimes 
5114f81ef50SGarrett Wollman 	if (sysctlbyname("net.inet.ip.stats", &ipstat, &len, 0, 0) < 0) {
5124f81ef50SGarrett Wollman 		warn("sysctl: net.inet.ip.stats");
5139b50d902SRodney W. Grimes 		return;
5144f81ef50SGarrett Wollman 	}
5154f81ef50SGarrett Wollman 
5169b50d902SRodney W. Grimes 	printf("%s:\n", name);
5179b50d902SRodney W. Grimes 
5189b50d902SRodney W. Grimes #define	p(f, m) if (ipstat.f || sflag <= 1) \
5199b50d902SRodney W. Grimes     printf(m, ipstat.f, plural(ipstat.f))
52022694ebaSBruce Evans #define	p1a(f, m) if (ipstat.f || sflag <= 1) \
52122694ebaSBruce Evans     printf(m, ipstat.f)
5229b50d902SRodney W. Grimes 
5237d56c0eeSAlexander Langer 	p(ips_total, "\t%lu total packet%s received\n");
5247d56c0eeSAlexander Langer 	p(ips_badsum, "\t%lu bad header checksum%s\n");
52522694ebaSBruce Evans 	p1a(ips_toosmall, "\t%lu with size smaller than minimum\n");
52622694ebaSBruce Evans 	p1a(ips_tooshort, "\t%lu with data size < data length\n");
527cfa1ca9dSYoshinobu Inoue 	p1a(ips_toolong, "\t%lu with ip length > max ip packet size\n");
52822694ebaSBruce Evans 	p1a(ips_badhlen, "\t%lu with header length < data size\n");
52922694ebaSBruce Evans 	p1a(ips_badlen, "\t%lu with data length < header length\n");
53022694ebaSBruce Evans 	p1a(ips_badoptions, "\t%lu with bad options\n");
53122694ebaSBruce Evans 	p1a(ips_badvers, "\t%lu with incorrect version number\n");
5327d56c0eeSAlexander Langer 	p(ips_fragments, "\t%lu fragment%s received\n");
5337d56c0eeSAlexander Langer 	p(ips_fragdropped, "\t%lu fragment%s dropped (dup or out of space)\n");
5347d56c0eeSAlexander Langer 	p(ips_fragtimeout, "\t%lu fragment%s dropped after timeout\n");
5357d56c0eeSAlexander Langer 	p(ips_reassembled, "\t%lu packet%s reassembled ok\n");
5367d56c0eeSAlexander Langer 	p(ips_delivered, "\t%lu packet%s for this host\n");
5377d56c0eeSAlexander Langer 	p(ips_noproto, "\t%lu packet%s for unknown/unsupported protocol\n");
538958d6f7fSPierre Beyssac 	p(ips_forward, "\t%lu packet%s forwarded");
539958d6f7fSPierre Beyssac 	p(ips_fastforward, " (%lu packet%s fast forwarded)");
540958d6f7fSPierre Beyssac 	if (ipstat.ips_forward || sflag <= 1)
541958d6f7fSPierre Beyssac 		putchar('\n');
5427d56c0eeSAlexander Langer 	p(ips_cantforward, "\t%lu packet%s not forwardable\n");
543a5969f5fSGarrett Wollman 	p(ips_notmember,
544a5969f5fSGarrett Wollman 	  "\t%lu packet%s received for unknown multicast group\n");
5457d56c0eeSAlexander Langer 	p(ips_redirectsent, "\t%lu redirect%s sent\n");
5467d56c0eeSAlexander Langer 	p(ips_localout, "\t%lu packet%s sent from this host\n");
5477d56c0eeSAlexander Langer 	p(ips_rawout, "\t%lu packet%s sent with fabricated ip header\n");
548a5969f5fSGarrett Wollman 	p(ips_odropped,
549a5969f5fSGarrett Wollman 	  "\t%lu output packet%s dropped due to no bufs, etc.\n");
5507d56c0eeSAlexander Langer 	p(ips_noroute, "\t%lu output packet%s discarded due to no route\n");
5517d56c0eeSAlexander Langer 	p(ips_fragmented, "\t%lu output datagram%s fragmented\n");
5527d56c0eeSAlexander Langer 	p(ips_ofragments, "\t%lu fragment%s created\n");
5537d56c0eeSAlexander Langer 	p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n");
554cfa1ca9dSYoshinobu Inoue 	p(ips_nogif, "\t%lu tunneling packet%s that can't find gif\n");
5559b50d902SRodney W. Grimes #undef p
55622694ebaSBruce Evans #undef p1a
5579b50d902SRodney W. Grimes }
5589b50d902SRodney W. Grimes 
5599b50d902SRodney W. Grimes static	char *icmpnames[] = {
5609b50d902SRodney W. Grimes 	"echo reply",
5619b50d902SRodney W. Grimes 	"#1",
5629b50d902SRodney W. Grimes 	"#2",
5639b50d902SRodney W. Grimes 	"destination unreachable",
5649b50d902SRodney W. Grimes 	"source quench",
5659b50d902SRodney W. Grimes 	"routing redirect",
5669b50d902SRodney W. Grimes 	"#6",
5679b50d902SRodney W. Grimes 	"#7",
5689b50d902SRodney W. Grimes 	"echo",
5697b46dd00SGarrett Wollman 	"router advertisement",
5707b46dd00SGarrett Wollman 	"router solicitation",
5719b50d902SRodney W. Grimes 	"time exceeded",
5729b50d902SRodney W. Grimes 	"parameter problem",
5739b50d902SRodney W. Grimes 	"time stamp",
5749b50d902SRodney W. Grimes 	"time stamp reply",
5759b50d902SRodney W. Grimes 	"information request",
5769b50d902SRodney W. Grimes 	"information request reply",
5779b50d902SRodney W. Grimes 	"address mask request",
5789b50d902SRodney W. Grimes 	"address mask reply",
5799b50d902SRodney W. Grimes };
5809b50d902SRodney W. Grimes 
5819b50d902SRodney W. Grimes /*
5829b50d902SRodney W. Grimes  * Dump ICMP statistics.
5839b50d902SRodney W. Grimes  */
5849b50d902SRodney W. Grimes void
5859b50d902SRodney W. Grimes icmp_stats(off, name)
5869b50d902SRodney W. Grimes 	u_long off;
5879b50d902SRodney W. Grimes 	char *name;
5889b50d902SRodney W. Grimes {
5899b50d902SRodney W. Grimes 	struct icmpstat icmpstat;
5904e00c309SGarrett Wollman 	int i, first;
5914e00c309SGarrett Wollman 	int mib[4];		/* CTL_NET + PF_INET + IPPROTO_ICMP + req */
5924e00c309SGarrett Wollman 	size_t len;
5939b50d902SRodney W. Grimes 
5944e00c309SGarrett Wollman 	mib[0] = CTL_NET;
5954e00c309SGarrett Wollman 	mib[1] = PF_INET;
5964e00c309SGarrett Wollman 	mib[2] = IPPROTO_ICMP;
5974e00c309SGarrett Wollman 	mib[3] = ICMPCTL_STATS;
5984e00c309SGarrett Wollman 
5994e00c309SGarrett Wollman 	len = sizeof icmpstat;
6004e00c309SGarrett Wollman 	memset(&icmpstat, 0, len);
6014e00c309SGarrett Wollman 	if (sysctl(mib, 4, &icmpstat, &len, (void *)0, 0) < 0)
6024e00c309SGarrett Wollman 		return;		/* XXX should complain, but not traditional */
6034e00c309SGarrett Wollman 
6049b50d902SRodney W. Grimes 	printf("%s:\n", name);
6059b50d902SRodney W. Grimes 
6069b50d902SRodney W. Grimes #define	p(f, m) if (icmpstat.f || sflag <= 1) \
6079b50d902SRodney W. Grimes     printf(m, icmpstat.f, plural(icmpstat.f))
60822694ebaSBruce Evans #define	p1a(f, m) if (icmpstat.f || sflag <= 1) \
60922694ebaSBruce Evans     printf(m, icmpstat.f)
6109b50d902SRodney W. Grimes 
6117d56c0eeSAlexander Langer 	p(icps_error, "\t%lu call%s to icmp_error\n");
6129b50d902SRodney W. Grimes 	p(icps_oldicmp,
6137d56c0eeSAlexander Langer 	    "\t%lu error%s not generated 'cuz old message was icmp\n");
6149b50d902SRodney W. Grimes 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
6159b50d902SRodney W. Grimes 		if (icmpstat.icps_outhist[i] != 0) {
6169b50d902SRodney W. Grimes 			if (first) {
6179b50d902SRodney W. Grimes 				printf("\tOutput histogram:\n");
6189b50d902SRodney W. Grimes 				first = 0;
6199b50d902SRodney W. Grimes 			}
6207d56c0eeSAlexander Langer 			printf("\t\t%s: %lu\n", icmpnames[i],
6219b50d902SRodney W. Grimes 				icmpstat.icps_outhist[i]);
6229b50d902SRodney W. Grimes 		}
6237d56c0eeSAlexander Langer 	p(icps_badcode, "\t%lu message%s with bad code fields\n");
6247d56c0eeSAlexander Langer 	p(icps_tooshort, "\t%lu message%s < minimum length\n");
6257d56c0eeSAlexander Langer 	p(icps_checksum, "\t%lu bad checksum%s\n");
6267d56c0eeSAlexander Langer 	p(icps_badlen, "\t%lu message%s with bad length\n");
62722694ebaSBruce Evans 	p1a(icps_bmcastecho, "\t%lu multicast echo requests ignored\n");
62822694ebaSBruce Evans 	p1a(icps_bmcasttstamp, "\t%lu multicast timestamp requests ignored\n");
6299b50d902SRodney W. Grimes 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
6309b50d902SRodney W. Grimes 		if (icmpstat.icps_inhist[i] != 0) {
6319b50d902SRodney W. Grimes 			if (first) {
6329b50d902SRodney W. Grimes 				printf("\tInput histogram:\n");
6339b50d902SRodney W. Grimes 				first = 0;
6349b50d902SRodney W. Grimes 			}
6357d56c0eeSAlexander Langer 			printf("\t\t%s: %lu\n", icmpnames[i],
6369b50d902SRodney W. Grimes 				icmpstat.icps_inhist[i]);
6379b50d902SRodney W. Grimes 		}
6387d56c0eeSAlexander Langer 	p(icps_reflect, "\t%lu message response%s generated\n");
6399b50d902SRodney W. Grimes #undef p
64022694ebaSBruce Evans #undef p1a
6414e00c309SGarrett Wollman 	mib[3] = ICMPCTL_MASKREPL;
6424e00c309SGarrett Wollman 	len = sizeof i;
6434e00c309SGarrett Wollman 	if (sysctl(mib, 4, &i, &len, (void *)0, 0) < 0)
6444e00c309SGarrett Wollman 		return;
6454e00c309SGarrett Wollman 	printf("\tICMP address mask responses are %sabled\n",
6464e00c309SGarrett Wollman 	       i ? "en" : "dis");
6479b50d902SRodney W. Grimes }
6489b50d902SRodney W. Grimes 
6499b50d902SRodney W. Grimes /*
6509b50d902SRodney W. Grimes  * Dump IGMP statistics structure.
6519b50d902SRodney W. Grimes  */
6529b50d902SRodney W. Grimes void
6539b50d902SRodney W. Grimes igmp_stats(off, name)
6549b50d902SRodney W. Grimes 	u_long off;
6559b50d902SRodney W. Grimes 	char *name;
6569b50d902SRodney W. Grimes {
6579b50d902SRodney W. Grimes 	struct igmpstat igmpstat;
6584f81ef50SGarrett Wollman 	size_t len = sizeof igmpstat;
6599b50d902SRodney W. Grimes 
6604f81ef50SGarrett Wollman 	if (sysctlbyname("net.inet.igmp.stats", &igmpstat, &len, 0, 0) < 0) {
6614f81ef50SGarrett Wollman 		warn("sysctl: net.inet.igmp.stats");
6629b50d902SRodney W. Grimes 		return;
6634f81ef50SGarrett Wollman 	}
6644f81ef50SGarrett Wollman 
6659b50d902SRodney W. Grimes 	printf("%s:\n", name);
6669b50d902SRodney W. Grimes 
6679b50d902SRodney W. Grimes #define	p(f, m) if (igmpstat.f || sflag <= 1) \
6689b50d902SRodney W. Grimes     printf(m, igmpstat.f, plural(igmpstat.f))
6699b50d902SRodney W. Grimes #define	py(f, m) if (igmpstat.f || sflag <= 1) \
6709b50d902SRodney W. Grimes     printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y")
6719b50d902SRodney W. Grimes 	p(igps_rcv_total, "\t%u message%s received\n");
6729b50d902SRodney W. Grimes         p(igps_rcv_tooshort, "\t%u message%s received with too few bytes\n");
6739b50d902SRodney W. Grimes         p(igps_rcv_badsum, "\t%u message%s received with bad checksum\n");
6749b50d902SRodney W. Grimes         py(igps_rcv_queries, "\t%u membership quer%s received\n");
6759b50d902SRodney W. Grimes         py(igps_rcv_badqueries, "\t%u membership quer%s received with invalid field(s)\n");
6769b50d902SRodney W. Grimes         p(igps_rcv_reports, "\t%u membership report%s received\n");
6779b50d902SRodney W. Grimes         p(igps_rcv_badreports, "\t%u membership report%s received with invalid field(s)\n");
6789b50d902SRodney W. Grimes         p(igps_rcv_ourreports, "\t%u membership report%s received for groups to which we belong\n");
6799b50d902SRodney W. Grimes         p(igps_snd_reports, "\t%u membership report%s sent\n");
6809b50d902SRodney W. Grimes #undef p
6819b50d902SRodney W. Grimes #undef py
6829b50d902SRodney W. Grimes }
6839b50d902SRodney W. Grimes 
6849b50d902SRodney W. Grimes /*
6859b50d902SRodney W. Grimes  * Pretty print an Internet address (net address + port).
6869b50d902SRodney W. Grimes  */
6879b50d902SRodney W. Grimes void
6888d612dd2SPoul-Henning Kamp inetprint(in, port, proto,numeric)
6899b50d902SRodney W. Grimes 	register struct in_addr *in;
6909b50d902SRodney W. Grimes 	int port;
6919b50d902SRodney W. Grimes 	char *proto;
6928d612dd2SPoul-Henning Kamp 	int numeric;
6939b50d902SRodney W. Grimes {
6949b50d902SRodney W. Grimes 	struct servent *sp = 0;
6959b50d902SRodney W. Grimes 	char line[80], *cp;
696cfa1ca9dSYoshinobu Inoue 	int width;
6979b50d902SRodney W. Grimes 
6988d612dd2SPoul-Henning Kamp 	sprintf(line, "%.*s.", (Aflag && !numeric) ? 12 : 16, inetname(in));
6999b50d902SRodney W. Grimes 	cp = index(line, '\0');
7008d612dd2SPoul-Henning Kamp 	if (!numeric && port)
7019b50d902SRodney W. Grimes 		sp = getservbyport((int)port, proto);
7029b50d902SRodney W. Grimes 	if (sp || port == 0)
7031ef69972SAndrey A. Chernov 		sprintf(cp, "%.15s", sp ? sp->s_name : "*");
7049b50d902SRodney W. Grimes 	else
7059b50d902SRodney W. Grimes 		sprintf(cp, "%d", ntohs((u_short)port));
706cfa1ca9dSYoshinobu Inoue 	width = Aflag ? 18 : 22;
707cfa1ca9dSYoshinobu Inoue 	printf("%-*.*s ", width, width, line);
7089b50d902SRodney W. Grimes }
7099b50d902SRodney W. Grimes 
7109b50d902SRodney W. Grimes /*
7119b50d902SRodney W. Grimes  * Construct an Internet address representation.
7129b50d902SRodney W. Grimes  * If the nflag has been supplied, give
7139b50d902SRodney W. Grimes  * numeric value, otherwise try for symbolic name.
7149b50d902SRodney W. Grimes  */
7159b50d902SRodney W. Grimes char *
7169b50d902SRodney W. Grimes inetname(inp)
7179b50d902SRodney W. Grimes 	struct in_addr *inp;
7189b50d902SRodney W. Grimes {
7199b50d902SRodney W. Grimes 	register char *cp;
720d121b556SBrian Somers 	static char line[MAXHOSTNAMELEN];
7219b50d902SRodney W. Grimes 	struct hostent *hp;
7229b50d902SRodney W. Grimes 	struct netent *np;
7239b50d902SRodney W. Grimes 
7249b50d902SRodney W. Grimes 	cp = 0;
7259b50d902SRodney W. Grimes 	if (!nflag && inp->s_addr != INADDR_ANY) {
7269b50d902SRodney W. Grimes 		int net = inet_netof(*inp);
7279b50d902SRodney W. Grimes 		int lna = inet_lnaof(*inp);
7289b50d902SRodney W. Grimes 
7299b50d902SRodney W. Grimes 		if (lna == INADDR_ANY) {
7309b50d902SRodney W. Grimes 			np = getnetbyaddr(net, AF_INET);
7319b50d902SRodney W. Grimes 			if (np)
7329b50d902SRodney W. Grimes 				cp = np->n_name;
7339b50d902SRodney W. Grimes 		}
7349b50d902SRodney W. Grimes 		if (cp == 0) {
7359b50d902SRodney W. Grimes 			hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET);
7369b50d902SRodney W. Grimes 			if (hp) {
7379b50d902SRodney W. Grimes 				cp = hp->h_name;
738d121b556SBrian Somers 				trimdomain(cp, strlen(cp));
7399b50d902SRodney W. Grimes 			}
7409b50d902SRodney W. Grimes 		}
7419b50d902SRodney W. Grimes 	}
7429b50d902SRodney W. Grimes 	if (inp->s_addr == INADDR_ANY)
7439b50d902SRodney W. Grimes 		strcpy(line, "*");
7449a1f6729SWarner Losh 	else if (cp) {
7459a1f6729SWarner Losh 		strncpy(line, cp, sizeof(line) - 1);
7469a1f6729SWarner Losh 		line[sizeof(line) - 1] = '\0';
7479a1f6729SWarner Losh 	} else {
7489b50d902SRodney W. Grimes 		inp->s_addr = ntohl(inp->s_addr);
74922694ebaSBruce Evans #define C(x)	((u_int)((x) & 0xff))
75022694ebaSBruce Evans 		sprintf(line, "%u.%u.%u.%u", C(inp->s_addr >> 24),
7519b50d902SRodney W. Grimes 		    C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr));
7529b50d902SRodney W. Grimes 	}
7539b50d902SRodney W. Grimes 	return (line);
7549b50d902SRodney W. Grimes }
755