xref: /freebsd/usr.bin/netstat/inet.c (revision cfa1ca9dfa0ee5bed5cc1cb0b07820701abbb431)
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>
71cfa1ca9dSYoshinobu Inoue #ifdef IPSEC
72cfa1ca9dSYoshinobu Inoue #include <netinet6/ipsec.h>
73cfa1ca9dSYoshinobu Inoue #endif
749b50d902SRodney W. Grimes 
759b50d902SRodney W. Grimes #include <arpa/inet.h>
764f81ef50SGarrett Wollman #include <err.h>
774f81ef50SGarrett Wollman #include <errno.h>
789b50d902SRodney W. Grimes #include <netdb.h>
799b50d902SRodney W. Grimes #include <stdio.h>
804f81ef50SGarrett Wollman #include <stdlib.h>
819b50d902SRodney W. Grimes #include <string.h>
829b50d902SRodney W. Grimes #include <unistd.h>
839b50d902SRodney W. Grimes #include "netstat.h"
849b50d902SRodney W. Grimes 
859b50d902SRodney W. Grimes char	*inetname __P((struct in_addr *));
868d612dd2SPoul-Henning Kamp void	inetprint __P((struct in_addr *, int, char *, int));
87cfa1ca9dSYoshinobu Inoue #ifdef INET6
88cfa1ca9dSYoshinobu Inoue extern void	inet6print __P((struct in6_addr *, int, char *, int));
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
99cfa1ca9dSYoshinobu Inoue protopr(proto, name, af)
1004f81ef50SGarrett Wollman 	u_long proto;		/* for sysctl version we pass proto # */
1019b50d902SRodney W. Grimes 	char *name;
102cfa1ca9dSYoshinobu Inoue 	int af;
1039b50d902SRodney W. Grimes {
1049b50d902SRodney W. Grimes 	int istcp;
1059b50d902SRodney W. Grimes 	static int first = 1;
1064f81ef50SGarrett Wollman 	char *buf;
1074f81ef50SGarrett Wollman 	const char *mibvar;
108a97a9922SJulian Elischer 	struct tcpcb *tp = NULL;
1094f81ef50SGarrett Wollman 	struct inpcb *inp;
1104f81ef50SGarrett Wollman 	struct xinpgen *xig, *oxig;
1114f81ef50SGarrett Wollman 	struct xsocket *so;
1124f81ef50SGarrett Wollman 	size_t len;
1139b50d902SRodney W. Grimes 
1144f81ef50SGarrett Wollman 	istcp = 0;
1154f81ef50SGarrett Wollman 	switch (proto) {
1164f81ef50SGarrett Wollman 	case IPPROTO_TCP:
117cfa1ca9dSYoshinobu Inoue #ifdef INET6
118cfa1ca9dSYoshinobu Inoue 		if (tcp_done != 0)
119cfa1ca9dSYoshinobu Inoue 			return;
120cfa1ca9dSYoshinobu Inoue 		else
121cfa1ca9dSYoshinobu Inoue 			tcp_done = 1;
122cfa1ca9dSYoshinobu Inoue #endif
1234f81ef50SGarrett Wollman 		istcp = 1;
1244f81ef50SGarrett Wollman 		mibvar = "net.inet.tcp.pcblist";
1254f81ef50SGarrett Wollman 		break;
1264f81ef50SGarrett Wollman 	case IPPROTO_UDP:
127cfa1ca9dSYoshinobu Inoue #ifdef INET6
128cfa1ca9dSYoshinobu Inoue 		if (udp_done != 0)
129cfa1ca9dSYoshinobu Inoue 			return;
130cfa1ca9dSYoshinobu Inoue 		else
131cfa1ca9dSYoshinobu Inoue 			udp_done = 1;
132cfa1ca9dSYoshinobu Inoue #endif
1334f81ef50SGarrett Wollman 		mibvar = "net.inet.udp.pcblist";
1344f81ef50SGarrett Wollman 		break;
1354f81ef50SGarrett Wollman 	case IPPROTO_DIVERT:
1364f81ef50SGarrett Wollman 		mibvar = "net.inet.divert.pcblist";
1374f81ef50SGarrett Wollman 		break;
1384f81ef50SGarrett Wollman 	default:
1394f81ef50SGarrett Wollman 		mibvar = "net.inet.raw.pcblist";
1404f81ef50SGarrett Wollman 		break;
1414f81ef50SGarrett Wollman 	}
1424f81ef50SGarrett Wollman 	len = 0;
1434f81ef50SGarrett Wollman 	if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
1444f81ef50SGarrett Wollman 		if (errno != ENOENT)
1454f81ef50SGarrett Wollman 			warn("sysctl: %s", mibvar);
1469b50d902SRodney W. Grimes 		return;
1473aa80b1dSDavid Greenman 	}
1484f81ef50SGarrett Wollman 	if ((buf = malloc(len)) == 0) {
1494f81ef50SGarrett Wollman 		warn("malloc %lu bytes", (u_long)len);
1504f81ef50SGarrett Wollman 		return;
1519b50d902SRodney W. Grimes 	}
1524f81ef50SGarrett Wollman 	if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) {
1534f81ef50SGarrett Wollman 		warn("sysctl: %s", mibvar);
1544f81ef50SGarrett Wollman 		free(buf);
1554f81ef50SGarrett Wollman 		return;
1564f81ef50SGarrett Wollman 	}
1574f81ef50SGarrett Wollman 
1584f81ef50SGarrett Wollman 	oxig = xig = (struct xinpgen *)buf;
1594f81ef50SGarrett Wollman 	for (xig = (struct xinpgen *)((char *)xig + xig->xig_len);
1604f81ef50SGarrett Wollman 	     xig->xig_len > sizeof(struct xinpgen);
1614f81ef50SGarrett Wollman 	     xig = (struct xinpgen *)((char *)xig + xig->xig_len)) {
1629b50d902SRodney W. Grimes 		if (istcp) {
1634f81ef50SGarrett Wollman 			tp = &((struct xtcpcb *)xig)->xt_tp;
1644f81ef50SGarrett Wollman 			inp = &((struct xtcpcb *)xig)->xt_inp;
1654f81ef50SGarrett Wollman 			so = &((struct xtcpcb *)xig)->xt_socket;
1664f81ef50SGarrett Wollman 		} else {
1674f81ef50SGarrett Wollman 			inp = &((struct xinpcb *)xig)->xi_inp;
1684f81ef50SGarrett Wollman 			so = &((struct xinpcb *)xig)->xi_socket;
1699b50d902SRodney W. Grimes 		}
1704f81ef50SGarrett Wollman 
1714f81ef50SGarrett Wollman 		/* Ignore sockets for protocols other than the desired one. */
1724f81ef50SGarrett Wollman 		if (so->xso_protocol != proto)
1734f81ef50SGarrett Wollman 			continue;
1744f81ef50SGarrett Wollman 
1754f81ef50SGarrett Wollman 		/* Ignore PCBs which were freed during copyout. */
1764f81ef50SGarrett Wollman 		if (inp->inp_gencnt > oxig->xig_gen)
1774f81ef50SGarrett Wollman 			continue;
1784f81ef50SGarrett Wollman 
179cfa1ca9dSYoshinobu Inoue 		if ((af == AF_INET && (inp->inp_vflag & INP_IPV4) == 0)
180cfa1ca9dSYoshinobu Inoue #ifdef INET6
181cfa1ca9dSYoshinobu Inoue 		    || (af == AF_INET6 && (inp->inp_vflag & INP_IPV6) == 0)
182cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
183cfa1ca9dSYoshinobu Inoue 		    || (af == AF_UNSPEC && ((inp->inp_vflag & INP_IPV4) == 0
184cfa1ca9dSYoshinobu Inoue #ifdef INET6
185cfa1ca9dSYoshinobu Inoue 					    && (inp->inp_vflag &
186cfa1ca9dSYoshinobu Inoue 						INP_IPV6) == 0
187cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
188cfa1ca9dSYoshinobu Inoue 			))
189cfa1ca9dSYoshinobu Inoue 		    )
190cfa1ca9dSYoshinobu Inoue 			continue;
191cfa1ca9dSYoshinobu Inoue 		if (!aflag &&
192cfa1ca9dSYoshinobu Inoue 		    (
193cfa1ca9dSYoshinobu Inoue 		     (af == AF_INET &&
194cfa1ca9dSYoshinobu Inoue 		      inet_lnaof(inp->inp_laddr) == INADDR_ANY)
195cfa1ca9dSYoshinobu Inoue #ifdef INET6
196cfa1ca9dSYoshinobu Inoue 		     || (af == AF_INET6 &&
197cfa1ca9dSYoshinobu Inoue 			 IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
198cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
199cfa1ca9dSYoshinobu Inoue 		     || (af == AF_UNSPEC &&
200cfa1ca9dSYoshinobu Inoue 			 (((inp->inp_vflag & INP_IPV4) != 0 &&
201cfa1ca9dSYoshinobu Inoue 			   inet_lnaof(inp->inp_laddr) == INADDR_ANY)
202cfa1ca9dSYoshinobu Inoue #ifdef INET6
203cfa1ca9dSYoshinobu Inoue 			  || ((inp->inp_vflag & INP_IPV6) != 0 &&
204cfa1ca9dSYoshinobu Inoue 			      IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
205cfa1ca9dSYoshinobu Inoue #endif
206cfa1ca9dSYoshinobu Inoue 			  ))
207cfa1ca9dSYoshinobu Inoue 		     ))
2084f81ef50SGarrett Wollman 			continue;
2094f81ef50SGarrett Wollman 
2109b50d902SRodney W. Grimes 		if (first) {
2119b50d902SRodney W. Grimes 			printf("Active Internet connections");
2129b50d902SRodney W. Grimes 			if (aflag)
2139b50d902SRodney W. Grimes 				printf(" (including servers)");
2149b50d902SRodney W. Grimes 			putchar('\n');
2159b50d902SRodney W. Grimes 			if (Aflag)
2164f81ef50SGarrett Wollman 				printf("%-8.8s ", "Socket");
217cfa1ca9dSYoshinobu Inoue 			printf(Aflag ?
218cfa1ca9dSYoshinobu Inoue 				"%-5.5s %-6.6s %-6.6s  %-18.18s %-18.18s %s\n" :
219cfa1ca9dSYoshinobu Inoue 				"%-5.5s %-6.6s %-6.6s  %-22.22s %-22.22s %s\n",
2209b50d902SRodney W. Grimes 				"Proto", "Recv-Q", "Send-Q",
2219b50d902SRodney W. Grimes 				"Local Address", "Foreign Address", "(state)");
2229b50d902SRodney W. Grimes 			first = 0;
2239b50d902SRodney W. Grimes 		}
224e4ec3989SDag-Erling Smørgrav 		if (Aflag) {
225e4ec3989SDag-Erling Smørgrav 			if (istcp)
226e4ec3989SDag-Erling Smørgrav 				printf("%8lx ", (u_long)inp->inp_ppcb);
227e4ec3989SDag-Erling Smørgrav 			else
2284f81ef50SGarrett Wollman 				printf("%8lx ", (u_long)so->so_pcb);
229e4ec3989SDag-Erling Smørgrav 		}
230cfa1ca9dSYoshinobu Inoue 		printf("%-3.3s%s%s %6ld %6ld ", name,
231cfa1ca9dSYoshinobu Inoue 		       (inp->inp_vflag & INP_IPV4) ? "4" : "",
232cfa1ca9dSYoshinobu Inoue #ifdef INET6
233cfa1ca9dSYoshinobu Inoue 		       (inp->inp_vflag & INP_IPV6) ? "6" :
234cfa1ca9dSYoshinobu Inoue #endif
235cfa1ca9dSYoshinobu Inoue 		       "",
236cfa1ca9dSYoshinobu Inoue 		       so->so_rcv.sb_cc,
2374f81ef50SGarrett Wollman 		       so->so_snd.sb_cc);
2388d612dd2SPoul-Henning Kamp 		if (nflag) {
239cfa1ca9dSYoshinobu Inoue 			if (inp->inp_vflag & INP_IPV4) {
2404f81ef50SGarrett Wollman 				inetprint(&inp->inp_laddr, (int)inp->inp_lport,
2418d612dd2SPoul-Henning Kamp 					  name, 1);
2424f81ef50SGarrett Wollman 				inetprint(&inp->inp_faddr, (int)inp->inp_fport,
2438d612dd2SPoul-Henning Kamp 					  name, 1);
244cfa1ca9dSYoshinobu Inoue 			}
245cfa1ca9dSYoshinobu Inoue #ifdef INET6
246cfa1ca9dSYoshinobu Inoue 			else if (inp->inp_vflag & INP_IPV6) {
247cfa1ca9dSYoshinobu Inoue 				inet6print(&inp->in6p_laddr,
248cfa1ca9dSYoshinobu Inoue 					   (int)inp->inp_lport, name, 1);
249cfa1ca9dSYoshinobu Inoue 				inet6print(&inp->in6p_faddr,
250cfa1ca9dSYoshinobu Inoue 					   (int)inp->inp_fport, name, 1);
251cfa1ca9dSYoshinobu Inoue 			} /* else nothing printed now */
252cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
2534f81ef50SGarrett Wollman 		} else if (inp->inp_flags & INP_ANONPORT) {
254cfa1ca9dSYoshinobu Inoue 			if (inp->inp_vflag & INP_IPV4) {
2554f81ef50SGarrett Wollman 				inetprint(&inp->inp_laddr, (int)inp->inp_lport,
2568d612dd2SPoul-Henning Kamp 					  name, 1);
2574f81ef50SGarrett Wollman 				inetprint(&inp->inp_faddr, (int)inp->inp_fport,
2588d612dd2SPoul-Henning Kamp 					  name, 0);
259cfa1ca9dSYoshinobu Inoue 			}
260cfa1ca9dSYoshinobu Inoue #ifdef INET6
261cfa1ca9dSYoshinobu Inoue 			else if (inp->inp_vflag & INP_IPV6) {
262cfa1ca9dSYoshinobu Inoue 				inet6print(&inp->in6p_laddr,
263cfa1ca9dSYoshinobu Inoue 					   (int)inp->inp_lport, name, 1);
264cfa1ca9dSYoshinobu Inoue 				inet6print(&inp->in6p_faddr,
265cfa1ca9dSYoshinobu Inoue 					   (int)inp->inp_fport, name, 0);
266cfa1ca9dSYoshinobu Inoue 			} /* else nothing printed now */
267cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
2688d612dd2SPoul-Henning Kamp 		} else {
269cfa1ca9dSYoshinobu Inoue 			if (inp->inp_vflag & INP_IPV4) {
2704f81ef50SGarrett Wollman 				inetprint(&inp->inp_laddr, (int)inp->inp_lport,
2718d612dd2SPoul-Henning Kamp 					  name, 0);
2724f81ef50SGarrett Wollman 				inetprint(&inp->inp_faddr, (int)inp->inp_fport,
273cfa1ca9dSYoshinobu Inoue 					  name,
274cfa1ca9dSYoshinobu Inoue 					  inp->inp_lport != inp->inp_fport);
275cfa1ca9dSYoshinobu Inoue 			}
276cfa1ca9dSYoshinobu Inoue #ifdef INET6
277cfa1ca9dSYoshinobu Inoue 			else if (inp->inp_vflag & INP_IPV6) {
278cfa1ca9dSYoshinobu Inoue 				inet6print(&inp->in6p_laddr,
279cfa1ca9dSYoshinobu Inoue 					   (int)inp->inp_lport, name, 0);
280cfa1ca9dSYoshinobu Inoue 				inet6print(&inp->in6p_faddr,
281cfa1ca9dSYoshinobu Inoue 					   (int)inp->inp_fport, name,
282cfa1ca9dSYoshinobu Inoue 					   inp->inp_lport != inp->inp_fport);
283cfa1ca9dSYoshinobu Inoue 			} /* else nothing printed now */
284cfa1ca9dSYoshinobu Inoue #endif /* INET6 */
2858d612dd2SPoul-Henning Kamp 		}
2869b50d902SRodney W. Grimes 		if (istcp) {
2874f81ef50SGarrett Wollman 			if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES)
2884f81ef50SGarrett Wollman 				printf("%d", tp->t_state);
2899a94a597SGarrett Wollman                       else {
2904f81ef50SGarrett Wollman 				printf("%s", tcpstates[tp->t_state]);
291513822ddSAdam David #if defined(TF_NEEDSYN) && defined(TF_NEEDFIN)
2929a94a597SGarrett Wollman                               /* Show T/TCP `hidden state' */
2934f81ef50SGarrett Wollman                               if (tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN))
2949a94a597SGarrett Wollman                                       putchar('*');
295513822ddSAdam David #endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */
2969a94a597SGarrett Wollman                       }
2979b50d902SRodney W. Grimes 		}
2989b50d902SRodney W. Grimes 		putchar('\n');
2999b50d902SRodney W. Grimes 	}
3004f81ef50SGarrett Wollman 	if (xig != oxig && xig->xig_gen != oxig->xig_gen) {
3014f81ef50SGarrett Wollman 		if (oxig->xig_count > xig->xig_count) {
3024f81ef50SGarrett Wollman 			printf("Some %s sockets may have been deleted.\n",
3034f81ef50SGarrett Wollman 			       name);
3044f81ef50SGarrett Wollman 		} else if (oxig->xig_count < xig->xig_count) {
3054f81ef50SGarrett Wollman 			printf("Some %s sockets may have been created.\n",
3064f81ef50SGarrett Wollman 			       name);
3074f81ef50SGarrett Wollman 		} else {
3084f81ef50SGarrett Wollman 			printf("Some %s sockets may have been created or deleted",
3094f81ef50SGarrett Wollman 			       name);
3104f81ef50SGarrett Wollman 		}
3114f81ef50SGarrett Wollman 	}
3124f81ef50SGarrett Wollman 	free(buf);
3139b50d902SRodney W. Grimes }
3149b50d902SRodney W. Grimes 
3159b50d902SRodney W. Grimes /*
3169b50d902SRodney W. Grimes  * Dump TCP statistics structure.
3179b50d902SRodney W. Grimes  */
3189b50d902SRodney W. Grimes void
3199b50d902SRodney W. Grimes tcp_stats(off, name)
3209b50d902SRodney W. Grimes 	u_long off;
3219b50d902SRodney W. Grimes 	char *name;
3229b50d902SRodney W. Grimes {
3239b50d902SRodney W. Grimes 	struct tcpstat tcpstat;
3244f81ef50SGarrett Wollman 	size_t len = sizeof tcpstat;
3259b50d902SRodney W. Grimes 
3264f81ef50SGarrett Wollman 	if (sysctlbyname("net.inet.tcp.stats", &tcpstat, &len, 0, 0) < 0) {
3274f81ef50SGarrett Wollman 		warn("sysctl: net.inet.tcp.stats");
3289b50d902SRodney W. Grimes 		return;
3294f81ef50SGarrett Wollman 	}
3304f81ef50SGarrett Wollman 
331cfa1ca9dSYoshinobu Inoue #ifdef INET6
332cfa1ca9dSYoshinobu Inoue 	if (tcp_done != 0)
333cfa1ca9dSYoshinobu Inoue 		return;
334cfa1ca9dSYoshinobu Inoue 	else
335cfa1ca9dSYoshinobu Inoue 		tcp_done = 1;
336cfa1ca9dSYoshinobu Inoue #endif
337cfa1ca9dSYoshinobu Inoue 
3389b50d902SRodney W. Grimes 	printf ("%s:\n", name);
3399b50d902SRodney W. Grimes 
3409b50d902SRodney W. Grimes #define	p(f, m) if (tcpstat.f || sflag <= 1) \
3419b50d902SRodney W. Grimes     printf(m, tcpstat.f, plural(tcpstat.f))
34222694ebaSBruce Evans #define	p1a(f, m) if (tcpstat.f || sflag <= 1) \
34322694ebaSBruce Evans     printf(m, tcpstat.f)
3449b50d902SRodney W. Grimes #define	p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
3459b50d902SRodney W. Grimes     printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2))
34622694ebaSBruce Evans #define	p2a(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \
34722694ebaSBruce Evans     printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2)
3489b50d902SRodney W. Grimes #define	p3(f, m) if (tcpstat.f || sflag <= 1) \
3499b50d902SRodney W. Grimes     printf(m, tcpstat.f, plurales(tcpstat.f))
3509b50d902SRodney W. Grimes 
351e1fb4daaSPaul Traina 	p(tcps_sndtotal, "\t%lu packet%s sent\n");
3529b50d902SRodney W. Grimes 	p2(tcps_sndpack,tcps_sndbyte,
353e1fb4daaSPaul Traina 		"\t\t%lu data packet%s (%lu byte%s)\n");
3549b50d902SRodney W. Grimes 	p2(tcps_sndrexmitpack, tcps_sndrexmitbyte,
355e1fb4daaSPaul Traina 		"\t\t%lu data packet%s (%lu byte%s) retransmitted\n");
356e1fb4daaSPaul Traina 	p(tcps_mturesent, "\t\t%lu resend%s initiated by MTU discovery\n");
35722694ebaSBruce Evans 	p2a(tcps_sndacks, tcps_delack,
358e1fb4daaSPaul Traina 		"\t\t%lu ack-only packet%s (%lu delayed)\n");
359e1fb4daaSPaul Traina 	p(tcps_sndurg, "\t\t%lu URG only packet%s\n");
360e1fb4daaSPaul Traina 	p(tcps_sndprobe, "\t\t%lu window probe packet%s\n");
361e1fb4daaSPaul Traina 	p(tcps_sndwinup, "\t\t%lu window update packet%s\n");
362e1fb4daaSPaul Traina 	p(tcps_sndctrl, "\t\t%lu control packet%s\n");
363e1fb4daaSPaul Traina 	p(tcps_rcvtotal, "\t%lu packet%s received\n");
364e1fb4daaSPaul Traina 	p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%lu ack%s (for %lu byte%s)\n");
365e1fb4daaSPaul Traina 	p(tcps_rcvdupack, "\t\t%lu duplicate ack%s\n");
366e1fb4daaSPaul Traina 	p(tcps_rcvacktoomuch, "\t\t%lu ack%s for unsent data\n");
3679b50d902SRodney W. Grimes 	p2(tcps_rcvpack, tcps_rcvbyte,
368e1fb4daaSPaul Traina 		"\t\t%lu packet%s (%lu byte%s) received in-sequence\n");
3699b50d902SRodney W. Grimes 	p2(tcps_rcvduppack, tcps_rcvdupbyte,
370e1fb4daaSPaul Traina 		"\t\t%lu completely duplicate packet%s (%lu byte%s)\n");
371e1fb4daaSPaul Traina 	p(tcps_pawsdrop, "\t\t%lu old duplicate packet%s\n");
3729b50d902SRodney W. Grimes 	p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte,
373e1fb4daaSPaul Traina 		"\t\t%lu packet%s with some dup. data (%lu byte%s duped)\n");
3749b50d902SRodney W. Grimes 	p2(tcps_rcvoopack, tcps_rcvoobyte,
375e1fb4daaSPaul Traina 		"\t\t%lu out-of-order packet%s (%lu byte%s)\n");
3769b50d902SRodney W. Grimes 	p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin,
377e1fb4daaSPaul Traina 		"\t\t%lu packet%s (%lu byte%s) of data after window\n");
378e1fb4daaSPaul Traina 	p(tcps_rcvwinprobe, "\t\t%lu window probe%s\n");
379e1fb4daaSPaul Traina 	p(tcps_rcvwinupd, "\t\t%lu window update packet%s\n");
380e1fb4daaSPaul Traina 	p(tcps_rcvafterclose, "\t\t%lu packet%s received after close\n");
381e1fb4daaSPaul Traina 	p(tcps_rcvbadsum, "\t\t%lu discarded for bad checksum%s\n");
382e1fb4daaSPaul Traina 	p(tcps_rcvbadoff, "\t\t%lu discarded for bad header offset field%s\n");
38322694ebaSBruce Evans 	p1a(tcps_rcvshort, "\t\t%lu discarded because packet too short\n");
384e1fb4daaSPaul Traina 	p(tcps_connattempt, "\t%lu connection request%s\n");
385e1fb4daaSPaul Traina 	p(tcps_accepts, "\t%lu connection accept%s\n");
386e1fb4daaSPaul Traina 	p(tcps_badsyn, "\t%lu bad connection attempt%s\n");
387e1fb4daaSPaul Traina 	p(tcps_listendrop, "\t%lu listen queue overflow%s\n");
388e1fb4daaSPaul Traina 	p(tcps_connects, "\t%lu connection%s established (including accepts)\n");
3899b50d902SRodney W. Grimes 	p2(tcps_closed, tcps_drops,
390e1fb4daaSPaul Traina 		"\t%lu connection%s closed (including %lu drop%s)\n");
391e1fb4daaSPaul Traina 	p(tcps_cachedrtt, "\t\t%lu connection%s updated cached RTT on close\n");
392861b1828SGarrett Wollman 	p(tcps_cachedrttvar,
393e1fb4daaSPaul Traina 	  "\t\t%lu connection%s updated cached RTT variance on close\n");
394861b1828SGarrett Wollman 	p(tcps_cachedssthresh,
395e1fb4daaSPaul Traina 	  "\t\t%lu connection%s updated cached ssthresh on close\n");
396e1fb4daaSPaul Traina 	p(tcps_conndrops, "\t%lu embryonic connection%s dropped\n");
3979b50d902SRodney W. Grimes 	p2(tcps_rttupdated, tcps_segstimed,
398e1fb4daaSPaul Traina 		"\t%lu segment%s updated rtt (of %lu attempt%s)\n");
399e1fb4daaSPaul Traina 	p(tcps_rexmttimeo, "\t%lu retransmit timeout%s\n");
400e1fb4daaSPaul Traina 	p(tcps_timeoutdrop, "\t\t%lu connection%s dropped by rexmit timeout\n");
401e1fb4daaSPaul Traina 	p(tcps_persisttimeo, "\t%lu persist timeout%s\n");
402e1fb4daaSPaul Traina 	p(tcps_persistdrop, "\t\t%lu connection%s dropped by persist timeout\n");
403e1fb4daaSPaul Traina 	p(tcps_keeptimeo, "\t%lu keepalive timeout%s\n");
404e1fb4daaSPaul Traina 	p(tcps_keepprobe, "\t\t%lu keepalive probe%s sent\n");
405e1fb4daaSPaul Traina 	p(tcps_keepdrops, "\t\t%lu connection%s dropped by keepalive\n");
406e1fb4daaSPaul Traina 	p(tcps_predack, "\t%lu correct ACK header prediction%s\n");
407e1fb4daaSPaul Traina 	p(tcps_preddat, "\t%lu correct data packet header prediction%s\n");
4089b50d902SRodney W. Grimes #undef p
40922694ebaSBruce Evans #undef p1a
4109b50d902SRodney W. Grimes #undef p2
41122694ebaSBruce Evans #undef p2a
4129b50d902SRodney W. Grimes #undef p3
4139b50d902SRodney W. Grimes }
4149b50d902SRodney W. Grimes 
4159b50d902SRodney W. Grimes /*
4169b50d902SRodney W. Grimes  * Dump UDP statistics structure.
4179b50d902SRodney W. Grimes  */
4189b50d902SRodney W. Grimes void
4199b50d902SRodney W. Grimes udp_stats(off, name)
4209b50d902SRodney W. Grimes 	u_long off;
4219b50d902SRodney W. Grimes 	char *name;
4229b50d902SRodney W. Grimes {
4239b50d902SRodney W. Grimes 	struct udpstat udpstat;
4244f81ef50SGarrett Wollman 	size_t len = sizeof udpstat;
4259b50d902SRodney W. Grimes 	u_long delivered;
4269b50d902SRodney W. Grimes 
4274f81ef50SGarrett Wollman 	if (sysctlbyname("net.inet.udp.stats", &udpstat, &len, 0, 0) < 0) {
4284f81ef50SGarrett Wollman 		warn("sysctl: net.inet.udp.stats");
4299b50d902SRodney W. Grimes 		return;
4304f81ef50SGarrett Wollman 	}
4314f81ef50SGarrett Wollman 
432cfa1ca9dSYoshinobu Inoue #ifdef INET6
433cfa1ca9dSYoshinobu Inoue 	if (udp_done != 0)
434cfa1ca9dSYoshinobu Inoue 		return;
435cfa1ca9dSYoshinobu Inoue 	else
436cfa1ca9dSYoshinobu Inoue 		udp_done = 1;
437cfa1ca9dSYoshinobu Inoue #endif
438cfa1ca9dSYoshinobu Inoue 
4399b50d902SRodney W. Grimes 	printf("%s:\n", name);
4409b50d902SRodney W. Grimes #define	p(f, m) if (udpstat.f || sflag <= 1) \
4419b50d902SRodney W. Grimes     printf(m, udpstat.f, plural(udpstat.f))
44222694ebaSBruce Evans #define	p1a(f, m) if (udpstat.f || sflag <= 1) \
44322694ebaSBruce Evans     printf(m, udpstat.f)
4447d56c0eeSAlexander Langer 	p(udps_ipackets, "\t%lu datagram%s received\n");
44522694ebaSBruce Evans 	p1a(udps_hdrops, "\t%lu with incomplete header\n");
44622694ebaSBruce Evans 	p1a(udps_badlen, "\t%lu with bad data length field\n");
44722694ebaSBruce Evans 	p1a(udps_badsum, "\t%lu with bad checksum\n");
44822694ebaSBruce Evans 	p1a(udps_noport, "\t%lu dropped due to no socket\n");
44922694ebaSBruce Evans 	p(udps_noportbcast,
45022694ebaSBruce Evans 	    "\t%lu broadcast/multicast datagram%s dropped due to no socket\n");
45122694ebaSBruce Evans 	p1a(udps_fullsock, "\t%lu dropped due to full socket buffers\n");
45222694ebaSBruce Evans 	p1a(udpps_pcbhashmiss, "\t%lu not for hashed pcb\n");
4539b50d902SRodney W. Grimes 	delivered = udpstat.udps_ipackets -
4549b50d902SRodney W. Grimes 		    udpstat.udps_hdrops -
4559b50d902SRodney W. Grimes 		    udpstat.udps_badlen -
4569b50d902SRodney W. Grimes 		    udpstat.udps_badsum -
4579b50d902SRodney W. Grimes 		    udpstat.udps_noport -
4589b50d902SRodney W. Grimes 		    udpstat.udps_noportbcast -
4599b50d902SRodney W. Grimes 		    udpstat.udps_fullsock;
4609b50d902SRodney W. Grimes 	if (delivered || sflag <= 1)
4617d56c0eeSAlexander Langer 		printf("\t%lu delivered\n", delivered);
4627d56c0eeSAlexander Langer 	p(udps_opackets, "\t%lu datagram%s output\n");
4639b50d902SRodney W. Grimes #undef p
46422694ebaSBruce Evans #undef p1a
4659b50d902SRodney W. Grimes }
4669b50d902SRodney W. Grimes 
4679b50d902SRodney W. Grimes /*
4689b50d902SRodney W. Grimes  * Dump IP statistics structure.
4699b50d902SRodney W. Grimes  */
4709b50d902SRodney W. Grimes void
4719b50d902SRodney W. Grimes ip_stats(off, name)
4729b50d902SRodney W. Grimes 	u_long off;
4739b50d902SRodney W. Grimes 	char *name;
4749b50d902SRodney W. Grimes {
4759b50d902SRodney W. Grimes 	struct ipstat ipstat;
4764f81ef50SGarrett Wollman 	size_t len = sizeof ipstat;
4779b50d902SRodney W. Grimes 
4784f81ef50SGarrett Wollman 	if (sysctlbyname("net.inet.ip.stats", &ipstat, &len, 0, 0) < 0) {
4794f81ef50SGarrett Wollman 		warn("sysctl: net.inet.ip.stats");
4809b50d902SRodney W. Grimes 		return;
4814f81ef50SGarrett Wollman 	}
4824f81ef50SGarrett Wollman 
4839b50d902SRodney W. Grimes 	printf("%s:\n", name);
4849b50d902SRodney W. Grimes 
4859b50d902SRodney W. Grimes #define	p(f, m) if (ipstat.f || sflag <= 1) \
4869b50d902SRodney W. Grimes     printf(m, ipstat.f, plural(ipstat.f))
48722694ebaSBruce Evans #define	p1a(f, m) if (ipstat.f || sflag <= 1) \
48822694ebaSBruce Evans     printf(m, ipstat.f)
4899b50d902SRodney W. Grimes 
4907d56c0eeSAlexander Langer 	p(ips_total, "\t%lu total packet%s received\n");
4917d56c0eeSAlexander Langer 	p(ips_badsum, "\t%lu bad header checksum%s\n");
49222694ebaSBruce Evans 	p1a(ips_toosmall, "\t%lu with size smaller than minimum\n");
49322694ebaSBruce Evans 	p1a(ips_tooshort, "\t%lu with data size < data length\n");
494cfa1ca9dSYoshinobu Inoue 	p1a(ips_toolong, "\t%lu with ip length > max ip packet size\n");
49522694ebaSBruce Evans 	p1a(ips_badhlen, "\t%lu with header length < data size\n");
49622694ebaSBruce Evans 	p1a(ips_badlen, "\t%lu with data length < header length\n");
49722694ebaSBruce Evans 	p1a(ips_badoptions, "\t%lu with bad options\n");
49822694ebaSBruce Evans 	p1a(ips_badvers, "\t%lu with incorrect version number\n");
4997d56c0eeSAlexander Langer 	p(ips_fragments, "\t%lu fragment%s received\n");
5007d56c0eeSAlexander Langer 	p(ips_fragdropped, "\t%lu fragment%s dropped (dup or out of space)\n");
5017d56c0eeSAlexander Langer 	p(ips_fragtimeout, "\t%lu fragment%s dropped after timeout\n");
5027d56c0eeSAlexander Langer 	p(ips_reassembled, "\t%lu packet%s reassembled ok\n");
5037d56c0eeSAlexander Langer 	p(ips_delivered, "\t%lu packet%s for this host\n");
5047d56c0eeSAlexander Langer 	p(ips_noproto, "\t%lu packet%s for unknown/unsupported protocol\n");
505958d6f7fSPierre Beyssac 	p(ips_forward, "\t%lu packet%s forwarded");
506958d6f7fSPierre Beyssac 	p(ips_fastforward, " (%lu packet%s fast forwarded)");
507958d6f7fSPierre Beyssac 	if (ipstat.ips_forward || sflag <= 1)
508958d6f7fSPierre Beyssac 		putchar('\n');
5097d56c0eeSAlexander Langer 	p(ips_cantforward, "\t%lu packet%s not forwardable\n");
510a5969f5fSGarrett Wollman 	p(ips_notmember,
511a5969f5fSGarrett Wollman 	  "\t%lu packet%s received for unknown multicast group\n");
5127d56c0eeSAlexander Langer 	p(ips_redirectsent, "\t%lu redirect%s sent\n");
5137d56c0eeSAlexander Langer 	p(ips_localout, "\t%lu packet%s sent from this host\n");
5147d56c0eeSAlexander Langer 	p(ips_rawout, "\t%lu packet%s sent with fabricated ip header\n");
515a5969f5fSGarrett Wollman 	p(ips_odropped,
516a5969f5fSGarrett Wollman 	  "\t%lu output packet%s dropped due to no bufs, etc.\n");
5177d56c0eeSAlexander Langer 	p(ips_noroute, "\t%lu output packet%s discarded due to no route\n");
5187d56c0eeSAlexander Langer 	p(ips_fragmented, "\t%lu output datagram%s fragmented\n");
5197d56c0eeSAlexander Langer 	p(ips_ofragments, "\t%lu fragment%s created\n");
5207d56c0eeSAlexander Langer 	p(ips_cantfrag, "\t%lu datagram%s that can't be fragmented\n");
521cfa1ca9dSYoshinobu Inoue 	p(ips_nogif, "\t%lu tunneling packet%s that can't find gif\n");
5229b50d902SRodney W. Grimes #undef p
52322694ebaSBruce Evans #undef p1a
5249b50d902SRodney W. Grimes }
5259b50d902SRodney W. Grimes 
5269b50d902SRodney W. Grimes static	char *icmpnames[] = {
5279b50d902SRodney W. Grimes 	"echo reply",
5289b50d902SRodney W. Grimes 	"#1",
5299b50d902SRodney W. Grimes 	"#2",
5309b50d902SRodney W. Grimes 	"destination unreachable",
5319b50d902SRodney W. Grimes 	"source quench",
5329b50d902SRodney W. Grimes 	"routing redirect",
5339b50d902SRodney W. Grimes 	"#6",
5349b50d902SRodney W. Grimes 	"#7",
5359b50d902SRodney W. Grimes 	"echo",
5367b46dd00SGarrett Wollman 	"router advertisement",
5377b46dd00SGarrett Wollman 	"router solicitation",
5389b50d902SRodney W. Grimes 	"time exceeded",
5399b50d902SRodney W. Grimes 	"parameter problem",
5409b50d902SRodney W. Grimes 	"time stamp",
5419b50d902SRodney W. Grimes 	"time stamp reply",
5429b50d902SRodney W. Grimes 	"information request",
5439b50d902SRodney W. Grimes 	"information request reply",
5449b50d902SRodney W. Grimes 	"address mask request",
5459b50d902SRodney W. Grimes 	"address mask reply",
5469b50d902SRodney W. Grimes };
5479b50d902SRodney W. Grimes 
5489b50d902SRodney W. Grimes /*
5499b50d902SRodney W. Grimes  * Dump ICMP statistics.
5509b50d902SRodney W. Grimes  */
5519b50d902SRodney W. Grimes void
5529b50d902SRodney W. Grimes icmp_stats(off, name)
5539b50d902SRodney W. Grimes 	u_long off;
5549b50d902SRodney W. Grimes 	char *name;
5559b50d902SRodney W. Grimes {
5569b50d902SRodney W. Grimes 	struct icmpstat icmpstat;
5574e00c309SGarrett Wollman 	int i, first;
5584e00c309SGarrett Wollman 	int mib[4];		/* CTL_NET + PF_INET + IPPROTO_ICMP + req */
5594e00c309SGarrett Wollman 	size_t len;
5609b50d902SRodney W. Grimes 
5614e00c309SGarrett Wollman 	mib[0] = CTL_NET;
5624e00c309SGarrett Wollman 	mib[1] = PF_INET;
5634e00c309SGarrett Wollman 	mib[2] = IPPROTO_ICMP;
5644e00c309SGarrett Wollman 	mib[3] = ICMPCTL_STATS;
5654e00c309SGarrett Wollman 
5664e00c309SGarrett Wollman 	len = sizeof icmpstat;
5674e00c309SGarrett Wollman 	memset(&icmpstat, 0, len);
5684e00c309SGarrett Wollman 	if (sysctl(mib, 4, &icmpstat, &len, (void *)0, 0) < 0)
5694e00c309SGarrett Wollman 		return;		/* XXX should complain, but not traditional */
5704e00c309SGarrett Wollman 
5719b50d902SRodney W. Grimes 	printf("%s:\n", name);
5729b50d902SRodney W. Grimes 
5739b50d902SRodney W. Grimes #define	p(f, m) if (icmpstat.f || sflag <= 1) \
5749b50d902SRodney W. Grimes     printf(m, icmpstat.f, plural(icmpstat.f))
57522694ebaSBruce Evans #define	p1a(f, m) if (icmpstat.f || sflag <= 1) \
57622694ebaSBruce Evans     printf(m, icmpstat.f)
5779b50d902SRodney W. Grimes 
5787d56c0eeSAlexander Langer 	p(icps_error, "\t%lu call%s to icmp_error\n");
5799b50d902SRodney W. Grimes 	p(icps_oldicmp,
5807d56c0eeSAlexander Langer 	    "\t%lu error%s not generated 'cuz old message was icmp\n");
5819b50d902SRodney W. Grimes 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
5829b50d902SRodney W. Grimes 		if (icmpstat.icps_outhist[i] != 0) {
5839b50d902SRodney W. Grimes 			if (first) {
5849b50d902SRodney W. Grimes 				printf("\tOutput histogram:\n");
5859b50d902SRodney W. Grimes 				first = 0;
5869b50d902SRodney W. Grimes 			}
5877d56c0eeSAlexander Langer 			printf("\t\t%s: %lu\n", icmpnames[i],
5889b50d902SRodney W. Grimes 				icmpstat.icps_outhist[i]);
5899b50d902SRodney W. Grimes 		}
5907d56c0eeSAlexander Langer 	p(icps_badcode, "\t%lu message%s with bad code fields\n");
5917d56c0eeSAlexander Langer 	p(icps_tooshort, "\t%lu message%s < minimum length\n");
5927d56c0eeSAlexander Langer 	p(icps_checksum, "\t%lu bad checksum%s\n");
5937d56c0eeSAlexander Langer 	p(icps_badlen, "\t%lu message%s with bad length\n");
59422694ebaSBruce Evans 	p1a(icps_bmcastecho, "\t%lu multicast echo requests ignored\n");
59522694ebaSBruce Evans 	p1a(icps_bmcasttstamp, "\t%lu multicast timestamp requests ignored\n");
5969b50d902SRodney W. Grimes 	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
5979b50d902SRodney W. Grimes 		if (icmpstat.icps_inhist[i] != 0) {
5989b50d902SRodney W. Grimes 			if (first) {
5999b50d902SRodney W. Grimes 				printf("\tInput histogram:\n");
6009b50d902SRodney W. Grimes 				first = 0;
6019b50d902SRodney W. Grimes 			}
6027d56c0eeSAlexander Langer 			printf("\t\t%s: %lu\n", icmpnames[i],
6039b50d902SRodney W. Grimes 				icmpstat.icps_inhist[i]);
6049b50d902SRodney W. Grimes 		}
6057d56c0eeSAlexander Langer 	p(icps_reflect, "\t%lu message response%s generated\n");
6069b50d902SRodney W. Grimes #undef p
60722694ebaSBruce Evans #undef p1a
6084e00c309SGarrett Wollman 	mib[3] = ICMPCTL_MASKREPL;
6094e00c309SGarrett Wollman 	len = sizeof i;
6104e00c309SGarrett Wollman 	if (sysctl(mib, 4, &i, &len, (void *)0, 0) < 0)
6114e00c309SGarrett Wollman 		return;
6124e00c309SGarrett Wollman 	printf("\tICMP address mask responses are %sabled\n",
6134e00c309SGarrett Wollman 	       i ? "en" : "dis");
6149b50d902SRodney W. Grimes }
6159b50d902SRodney W. Grimes 
6169b50d902SRodney W. Grimes /*
6179b50d902SRodney W. Grimes  * Dump IGMP statistics structure.
6189b50d902SRodney W. Grimes  */
6199b50d902SRodney W. Grimes void
6209b50d902SRodney W. Grimes igmp_stats(off, name)
6219b50d902SRodney W. Grimes 	u_long off;
6229b50d902SRodney W. Grimes 	char *name;
6239b50d902SRodney W. Grimes {
6249b50d902SRodney W. Grimes 	struct igmpstat igmpstat;
6254f81ef50SGarrett Wollman 	size_t len = sizeof igmpstat;
6269b50d902SRodney W. Grimes 
6274f81ef50SGarrett Wollman 	if (sysctlbyname("net.inet.igmp.stats", &igmpstat, &len, 0, 0) < 0) {
6284f81ef50SGarrett Wollman 		warn("sysctl: net.inet.igmp.stats");
6299b50d902SRodney W. Grimes 		return;
6304f81ef50SGarrett Wollman 	}
6314f81ef50SGarrett Wollman 
6329b50d902SRodney W. Grimes 	printf("%s:\n", name);
6339b50d902SRodney W. Grimes 
6349b50d902SRodney W. Grimes #define	p(f, m) if (igmpstat.f || sflag <= 1) \
6359b50d902SRodney W. Grimes     printf(m, igmpstat.f, plural(igmpstat.f))
6369b50d902SRodney W. Grimes #define	py(f, m) if (igmpstat.f || sflag <= 1) \
6379b50d902SRodney W. Grimes     printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y")
6389b50d902SRodney W. Grimes 	p(igps_rcv_total, "\t%u message%s received\n");
6399b50d902SRodney W. Grimes         p(igps_rcv_tooshort, "\t%u message%s received with too few bytes\n");
6409b50d902SRodney W. Grimes         p(igps_rcv_badsum, "\t%u message%s received with bad checksum\n");
6419b50d902SRodney W. Grimes         py(igps_rcv_queries, "\t%u membership quer%s received\n");
6429b50d902SRodney W. Grimes         py(igps_rcv_badqueries, "\t%u membership quer%s received with invalid field(s)\n");
6439b50d902SRodney W. Grimes         p(igps_rcv_reports, "\t%u membership report%s received\n");
6449b50d902SRodney W. Grimes         p(igps_rcv_badreports, "\t%u membership report%s received with invalid field(s)\n");
6459b50d902SRodney W. Grimes         p(igps_rcv_ourreports, "\t%u membership report%s received for groups to which we belong\n");
6469b50d902SRodney W. Grimes         p(igps_snd_reports, "\t%u membership report%s sent\n");
6479b50d902SRodney W. Grimes #undef p
6489b50d902SRodney W. Grimes #undef py
6499b50d902SRodney W. Grimes }
6509b50d902SRodney W. Grimes 
651cfa1ca9dSYoshinobu Inoue #ifdef IPSEC
652cfa1ca9dSYoshinobu Inoue static	char *ipsec_ahnames[] = {
653cfa1ca9dSYoshinobu Inoue 	"none",
654cfa1ca9dSYoshinobu Inoue 	"hmac MD5",
655cfa1ca9dSYoshinobu Inoue 	"hmac SHA1",
656cfa1ca9dSYoshinobu Inoue 	"keyed MD5",
657cfa1ca9dSYoshinobu Inoue 	"keyed SHA1",
658cfa1ca9dSYoshinobu Inoue 	"null",
659cfa1ca9dSYoshinobu Inoue };
660cfa1ca9dSYoshinobu Inoue 
661cfa1ca9dSYoshinobu Inoue static	char *ipsec_espnames[] = {
662cfa1ca9dSYoshinobu Inoue 	"none",
663cfa1ca9dSYoshinobu Inoue 	"DES CBC",
664cfa1ca9dSYoshinobu Inoue 	"3DES CBC",
665cfa1ca9dSYoshinobu Inoue 	"simple",
666cfa1ca9dSYoshinobu Inoue 	"blowfish CBC",
667cfa1ca9dSYoshinobu Inoue 	"CAST128 CBC",
668cfa1ca9dSYoshinobu Inoue 	"RC5 CBC",
669cfa1ca9dSYoshinobu Inoue };
670cfa1ca9dSYoshinobu Inoue 
671cfa1ca9dSYoshinobu Inoue /*
672cfa1ca9dSYoshinobu Inoue  * Dump IPSEC statistics structure.
673cfa1ca9dSYoshinobu Inoue  */
674cfa1ca9dSYoshinobu Inoue void
675cfa1ca9dSYoshinobu Inoue ipsec_stats(off, name)
676cfa1ca9dSYoshinobu Inoue 	u_long off;
677cfa1ca9dSYoshinobu Inoue 	char *name;
678cfa1ca9dSYoshinobu Inoue {
679cfa1ca9dSYoshinobu Inoue 	struct ipsecstat ipsecstat;
680cfa1ca9dSYoshinobu Inoue 	int first, proto;
681cfa1ca9dSYoshinobu Inoue 
682cfa1ca9dSYoshinobu Inoue 	if (off == 0)
683cfa1ca9dSYoshinobu Inoue 		return;
684cfa1ca9dSYoshinobu Inoue 	printf ("%s:\n", name);
685cfa1ca9dSYoshinobu Inoue 	kread(off, (char *)&ipsecstat, sizeof (ipsecstat));
686cfa1ca9dSYoshinobu Inoue 
687cfa1ca9dSYoshinobu Inoue #define	p(f, m) if (ipsecstat.f || sflag <= 1) \
688cfa1ca9dSYoshinobu Inoue     printf(m, ipsecstat.f, plural(ipsecstat.f))
689cfa1ca9dSYoshinobu Inoue 
690cfa1ca9dSYoshinobu Inoue 	p(in_success, "\t%lu inbound packet%s processed successfully\n");
691cfa1ca9dSYoshinobu Inoue 	p(in_polvio, "\t%lu inbound packet%s violated process security "
692cfa1ca9dSYoshinobu Inoue 		"policy\n");
693cfa1ca9dSYoshinobu Inoue 	p(in_nosa, "\t%lu inbound packet%s with no SA available\n");
694cfa1ca9dSYoshinobu Inoue 	p(in_inval, "\t%lu inbound packet%s failed processing due to EINVAL\n");
695cfa1ca9dSYoshinobu Inoue 	p(in_badspi, "\t%lu inbound packet%s failed getting SPI\n");
696cfa1ca9dSYoshinobu Inoue 	p(in_ahreplay, "\t%lu inbound packet%s failed on AH replay check\n");
697cfa1ca9dSYoshinobu Inoue 	p(in_espreplay, "\t%lu inbound packet%s failed on ESP replay check\n");
698cfa1ca9dSYoshinobu Inoue 	p(in_ahauthsucc, "\t%lu inbound AH packet%s considered authentic\n");
699cfa1ca9dSYoshinobu Inoue 	p(in_ahauthfail, "\t%lu inbound AH packet%s failed on authentication\n");
700cfa1ca9dSYoshinobu Inoue 	p(in_espauthsucc, "\t%lu inbound ESP packet%s considered authentic\n");
701cfa1ca9dSYoshinobu Inoue 	p(in_espauthfail, "\t%lu inbound ESP packet%s failed on authentication\n");
702cfa1ca9dSYoshinobu Inoue 	for (first = 1, proto = 0; proto < SADB_AALG_MAX; proto++) {
703cfa1ca9dSYoshinobu Inoue 		if (ipsecstat.in_ahhist[proto] <= 0)
704cfa1ca9dSYoshinobu Inoue 			continue;
705cfa1ca9dSYoshinobu Inoue 		if (first) {
706cfa1ca9dSYoshinobu Inoue 			printf("\tAH input histogram:\n");
707cfa1ca9dSYoshinobu Inoue 			first = 0;
708cfa1ca9dSYoshinobu Inoue 		}
709cfa1ca9dSYoshinobu Inoue 		printf("\t\t%s: %lu\n", ipsec_ahnames[proto],
710cfa1ca9dSYoshinobu Inoue 			ipsecstat.in_ahhist[proto]);
711cfa1ca9dSYoshinobu Inoue 	}
712cfa1ca9dSYoshinobu Inoue 	for (first = 1, proto = 0; proto < SADB_EALG_MAX; proto++) {
713cfa1ca9dSYoshinobu Inoue 		if (ipsecstat.in_esphist[proto] <= 0)
714cfa1ca9dSYoshinobu Inoue 			continue;
715cfa1ca9dSYoshinobu Inoue 		if (first) {
716cfa1ca9dSYoshinobu Inoue 			printf("\tESP input histogram:\n");
717cfa1ca9dSYoshinobu Inoue 		first = 0;
718cfa1ca9dSYoshinobu Inoue 		}
719cfa1ca9dSYoshinobu Inoue 		printf("\t\t%s: %lu\n", ipsec_espnames[proto],
720cfa1ca9dSYoshinobu Inoue 			ipsecstat.in_esphist[proto]);
721cfa1ca9dSYoshinobu Inoue 	}
722cfa1ca9dSYoshinobu Inoue 
723cfa1ca9dSYoshinobu Inoue 	p(out_success, "\t%lu outbound packet%s processed successfully\n");
724cfa1ca9dSYoshinobu Inoue 	p(out_polvio, "\t%lu outbound packet%s violated process security "
725cfa1ca9dSYoshinobu Inoue 		"policy\n");
726cfa1ca9dSYoshinobu Inoue 	p(out_nosa, "\t%lu outbound packet%s with no SA available\n");
727cfa1ca9dSYoshinobu Inoue 	p(out_inval, "\t%lu outbound packet%s failed processing due to "
728cfa1ca9dSYoshinobu Inoue 		"EINVAL\n");
729cfa1ca9dSYoshinobu Inoue 	p(out_noroute, "\t%lu outbound packet%s with no route\n");
730cfa1ca9dSYoshinobu Inoue 	for (first = 1, proto = 0; proto < SADB_AALG_MAX; proto++) {
731cfa1ca9dSYoshinobu Inoue 		if (ipsecstat.out_ahhist[proto] <= 0)
732cfa1ca9dSYoshinobu Inoue 			continue;
733cfa1ca9dSYoshinobu Inoue 		if (first) {
734cfa1ca9dSYoshinobu Inoue 			printf("\tAH output histogram:\n");
735cfa1ca9dSYoshinobu Inoue 			first = 0;
736cfa1ca9dSYoshinobu Inoue 		}
737cfa1ca9dSYoshinobu Inoue 		printf("\t\t%s: %lu\n", ipsec_ahnames[proto],
738cfa1ca9dSYoshinobu Inoue 			ipsecstat.out_ahhist[proto]);
739cfa1ca9dSYoshinobu Inoue 	}
740cfa1ca9dSYoshinobu Inoue 	for (first = 1, proto = 0; proto < SADB_EALG_MAX; proto++) {
741cfa1ca9dSYoshinobu Inoue 		if (ipsecstat.out_esphist[proto] <= 0)
742cfa1ca9dSYoshinobu Inoue 			continue;
743cfa1ca9dSYoshinobu Inoue 		if (first) {
744cfa1ca9dSYoshinobu Inoue 			printf("\tESP output histogram:\n");
745cfa1ca9dSYoshinobu Inoue 			first = 0;
746cfa1ca9dSYoshinobu Inoue 		}
747cfa1ca9dSYoshinobu Inoue 		printf("\t\t%s: %lu\n", ipsec_espnames[proto],
748cfa1ca9dSYoshinobu Inoue 			ipsecstat.out_esphist[proto]);
749cfa1ca9dSYoshinobu Inoue 	}
750cfa1ca9dSYoshinobu Inoue #undef p
751cfa1ca9dSYoshinobu Inoue }
752cfa1ca9dSYoshinobu Inoue #endif /*IPSEC*/
753cfa1ca9dSYoshinobu Inoue 
7549b50d902SRodney W. Grimes /*
7559b50d902SRodney W. Grimes  * Pretty print an Internet address (net address + port).
7569b50d902SRodney W. Grimes  */
7579b50d902SRodney W. Grimes void
7588d612dd2SPoul-Henning Kamp inetprint(in, port, proto,numeric)
7599b50d902SRodney W. Grimes 	register struct in_addr *in;
7609b50d902SRodney W. Grimes 	int port;
7619b50d902SRodney W. Grimes 	char *proto;
7628d612dd2SPoul-Henning Kamp 	int numeric;
7639b50d902SRodney W. Grimes {
7649b50d902SRodney W. Grimes 	struct servent *sp = 0;
7659b50d902SRodney W. Grimes 	char line[80], *cp;
766cfa1ca9dSYoshinobu Inoue 	int width;
7679b50d902SRodney W. Grimes 
7688d612dd2SPoul-Henning Kamp 	sprintf(line, "%.*s.", (Aflag && !numeric) ? 12 : 16, inetname(in));
7699b50d902SRodney W. Grimes 	cp = index(line, '\0');
7708d612dd2SPoul-Henning Kamp 	if (!numeric && port)
7719b50d902SRodney W. Grimes 		sp = getservbyport((int)port, proto);
7729b50d902SRodney W. Grimes 	if (sp || port == 0)
7731ef69972SAndrey A. Chernov 		sprintf(cp, "%.15s", sp ? sp->s_name : "*");
7749b50d902SRodney W. Grimes 	else
7759b50d902SRodney W. Grimes 		sprintf(cp, "%d", ntohs((u_short)port));
776cfa1ca9dSYoshinobu Inoue 	width = Aflag ? 18 : 22;
777cfa1ca9dSYoshinobu Inoue 	printf(" %-*.*s", width, width, line);
7789b50d902SRodney W. Grimes }
7799b50d902SRodney W. Grimes 
7809b50d902SRodney W. Grimes /*
7819b50d902SRodney W. Grimes  * Construct an Internet address representation.
7829b50d902SRodney W. Grimes  * If the nflag has been supplied, give
7839b50d902SRodney W. Grimes  * numeric value, otherwise try for symbolic name.
7849b50d902SRodney W. Grimes  */
7859b50d902SRodney W. Grimes char *
7869b50d902SRodney W. Grimes inetname(inp)
7879b50d902SRodney W. Grimes 	struct in_addr *inp;
7889b50d902SRodney W. Grimes {
7899b50d902SRodney W. Grimes 	register char *cp;
7909a1f6729SWarner Losh 	static char line[MAXHOSTNAMELEN + 1];
7919b50d902SRodney W. Grimes 	struct hostent *hp;
7929b50d902SRodney W. Grimes 	struct netent *np;
7939b50d902SRodney W. Grimes 
7949b50d902SRodney W. Grimes 	cp = 0;
7959b50d902SRodney W. Grimes 	if (!nflag && inp->s_addr != INADDR_ANY) {
7969b50d902SRodney W. Grimes 		int net = inet_netof(*inp);
7979b50d902SRodney W. Grimes 		int lna = inet_lnaof(*inp);
7989b50d902SRodney W. Grimes 
7999b50d902SRodney W. Grimes 		if (lna == INADDR_ANY) {
8009b50d902SRodney W. Grimes 			np = getnetbyaddr(net, AF_INET);
8019b50d902SRodney W. Grimes 			if (np)
8029b50d902SRodney W. Grimes 				cp = np->n_name;
8039b50d902SRodney W. Grimes 		}
8049b50d902SRodney W. Grimes 		if (cp == 0) {
8059b50d902SRodney W. Grimes 			hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET);
8069b50d902SRodney W. Grimes 			if (hp) {
8079b50d902SRodney W. Grimes 				cp = hp->h_name;
8089c437f50SPeter Wemm 				trimdomain(cp);
8099b50d902SRodney W. Grimes 			}
8109b50d902SRodney W. Grimes 		}
8119b50d902SRodney W. Grimes 	}
8129b50d902SRodney W. Grimes 	if (inp->s_addr == INADDR_ANY)
8139b50d902SRodney W. Grimes 		strcpy(line, "*");
8149a1f6729SWarner Losh 	else if (cp) {
8159a1f6729SWarner Losh 		strncpy(line, cp, sizeof(line) - 1);
8169a1f6729SWarner Losh 		line[sizeof(line) - 1] = '\0';
8179a1f6729SWarner Losh 	} else {
8189b50d902SRodney W. Grimes 		inp->s_addr = ntohl(inp->s_addr);
81922694ebaSBruce Evans #define C(x)	((u_int)((x) & 0xff))
82022694ebaSBruce Evans 		sprintf(line, "%u.%u.%u.%u", C(inp->s_addr >> 24),
8219b50d902SRodney W. Grimes 		    C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr));
8229b50d902SRodney W. Grimes 	}
8239b50d902SRodney W. Grimes 	return (line);
8249b50d902SRodney W. Grimes }
825