xref: /freebsd/usr.bin/systat/icmp.c (revision fbbd9655e5107c68e4e0146ff22b73d7350475bc)
103e00a72SGarrett Wollman /*-
203e00a72SGarrett Wollman  * Copyright (c) 1980, 1992, 1993
303e00a72SGarrett Wollman  *	The Regents of the University of California.  All rights reserved.
403e00a72SGarrett Wollman  *
503e00a72SGarrett Wollman  * Redistribution and use in source and binary forms, with or without
603e00a72SGarrett Wollman  * modification, are permitted provided that the following conditions
703e00a72SGarrett Wollman  * are met:
803e00a72SGarrett Wollman  * 1. Redistributions of source code must retain the above copyright
903e00a72SGarrett Wollman  *    notice, this list of conditions and the following disclaimer.
1003e00a72SGarrett Wollman  * 2. Redistributions in binary form must reproduce the above copyright
1103e00a72SGarrett Wollman  *    notice, this list of conditions and the following disclaimer in the
1203e00a72SGarrett Wollman  *    documentation and/or other materials provided with the distribution.
13*fbbd9655SWarner Losh  * 3. Neither the name of the University nor the names of its contributors
1403e00a72SGarrett Wollman  *    may be used to endorse or promote products derived from this software
1503e00a72SGarrett Wollman  *    without specific prior written permission.
1603e00a72SGarrett Wollman  *
1703e00a72SGarrett Wollman  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1803e00a72SGarrett Wollman  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1903e00a72SGarrett Wollman  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2003e00a72SGarrett Wollman  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2103e00a72SGarrett Wollman  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2203e00a72SGarrett Wollman  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2303e00a72SGarrett Wollman  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2403e00a72SGarrett Wollman  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2503e00a72SGarrett Wollman  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2603e00a72SGarrett Wollman  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2703e00a72SGarrett Wollman  * SUCH DAMAGE.
2803e00a72SGarrett Wollman  */
2903e00a72SGarrett Wollman 
309ff712b0SMark Murray #include <sys/cdefs.h>
319ff712b0SMark Murray 
329ff712b0SMark Murray __FBSDID("$FreeBSD$");
339ff712b0SMark Murray 
349ff712b0SMark Murray #ifdef lint
3503e00a72SGarrett Wollman static char sccsid[] = "@(#)mbufs.c	8.1 (Berkeley) 6/6/93";
369ff712b0SMark Murray #endif
379ff712b0SMark Murray 
389ff712b0SMark Murray /* From:
399ff712b0SMark Murray 	"Id: mbufs.c,v 1.5 1997/02/24 20:59:03 wollman Exp"
4003e00a72SGarrett Wollman */
4103e00a72SGarrett Wollman 
4203e00a72SGarrett Wollman #include <sys/param.h>
4303e00a72SGarrett Wollman #include <sys/types.h>
4403e00a72SGarrett Wollman #include <sys/socket.h>
4503e00a72SGarrett Wollman #include <sys/sysctl.h>
4603e00a72SGarrett Wollman 
4703e00a72SGarrett Wollman #include <netinet/in.h>
4803e00a72SGarrett Wollman #include <netinet/in_systm.h>
4903e00a72SGarrett Wollman #include <netinet/ip.h>
5003e00a72SGarrett Wollman #include <netinet/ip_icmp.h>
5103e00a72SGarrett Wollman #include <netinet/icmp_var.h>
5203e00a72SGarrett Wollman 
53821df508SXin LI #include <stdlib.h>
5403e00a72SGarrett Wollman #include <string.h>
55821df508SXin LI #include <paths.h>
5603e00a72SGarrett Wollman #include "systat.h"
5703e00a72SGarrett Wollman #include "extern.h"
5803e00a72SGarrett Wollman #include "mode.h"
5903e00a72SGarrett Wollman 
6003e00a72SGarrett Wollman static struct icmpstat icmpstat, initstat, oldstat;
6103e00a72SGarrett Wollman 
6203e00a72SGarrett Wollman /*-
6303e00a72SGarrett Wollman --0         1         2         3         4         5         6         7
6403e00a72SGarrett Wollman --0123456789012345678901234567890123456789012345678901234567890123456789012345
658aa22952SBruce Evans 00          ICMP Input                         ICMP Output
668aa22952SBruce Evans 01999999999 total messages           999999999 total messages
678aa22952SBruce Evans 02999999999 with bad code            999999999 errors generated
688aa22952SBruce Evans 03999999999 with bad length          999999999 suppressed - original too short
698aa22952SBruce Evans 04999999999 with bad checksum        999999999 suppressed - original was ICMP
708aa22952SBruce Evans 05999999999 with insufficient data   999999999 responses sent
718aa22952SBruce Evans 06                                   999999999 suppressed - multicast echo
728aa22952SBruce Evans 07                                   999999999 suppressed - multicast tstamp
738aa22952SBruce Evans 08
748aa22952SBruce Evans 09          Input Histogram                    Output Histogram
758aa22952SBruce Evans 10999999999 echo response            999999999 echo response
768aa22952SBruce Evans 11999999999 echo request             999999999 echo request
778aa22952SBruce Evans 12999999999 destination unreachable  999999999 destination unreachable
788aa22952SBruce Evans 13999999999 redirect                 999999999 redirect
798aa22952SBruce Evans 14999999999 time-to-live exceeded    999999999 time-to-line exceeded
808aa22952SBruce Evans 15999999999 parameter problem        999999999 parameter problem
818aa22952SBruce Evans 16999999999 router advertisement     999999999 router solicitation
828aa22952SBruce Evans 17
8303e00a72SGarrett Wollman 18
8403e00a72SGarrett Wollman --0123456789012345678901234567890123456789012345678901234567890123456789012345
8503e00a72SGarrett Wollman --0         1         2         3         4         5         6         7
8603e00a72SGarrett Wollman */
8703e00a72SGarrett Wollman 
8803e00a72SGarrett Wollman WINDOW *
8903e00a72SGarrett Wollman openicmp(void)
9003e00a72SGarrett Wollman {
918aa22952SBruce Evans 	return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0));
9203e00a72SGarrett Wollman }
9303e00a72SGarrett Wollman 
9403e00a72SGarrett Wollman void
9593b9f504SXin LI closeicmp(WINDOW *w)
9603e00a72SGarrett Wollman {
9703e00a72SGarrett Wollman 	if (w == NULL)
9803e00a72SGarrett Wollman 		return;
9903e00a72SGarrett Wollman 	wclear(w);
10003e00a72SGarrett Wollman 	wrefresh(w);
10103e00a72SGarrett Wollman 	delwin(w);
10203e00a72SGarrett Wollman }
10303e00a72SGarrett Wollman 
10403e00a72SGarrett Wollman void
10503e00a72SGarrett Wollman labelicmp(void)
10603e00a72SGarrett Wollman {
10703e00a72SGarrett Wollman 	wmove(wnd, 0, 0); wclrtoeol(wnd);
10803e00a72SGarrett Wollman #define L(row, str) mvwprintw(wnd, row, 10, str)
10903e00a72SGarrett Wollman #define R(row, str) mvwprintw(wnd, row, 45, str);
1108aa22952SBruce Evans 	L(0, "ICMP Input");		R(0, "ICMP Output");
1118aa22952SBruce Evans 	L(1, "total messages");		R(1, "total messages");
1128aa22952SBruce Evans 	L(2, "with bad code");		R(2, "errors generated");
1138aa22952SBruce Evans 	L(3, "with bad length");	R(3, "suppressed - original too short");
1148aa22952SBruce Evans 	L(4, "with bad checksum");	R(4, "suppressed - original was ICMP");
1158aa22952SBruce Evans 	L(5, "with insufficient data");	R(5, "responses sent");
1168aa22952SBruce Evans 					R(6, "suppressed - multicast echo");
1178aa22952SBruce Evans 					R(7, "suppressed - multicast tstamp");
1188aa22952SBruce Evans 	L(9, "Input Histogram");	R(9, "Output Histogram");
11903e00a72SGarrett Wollman #define B(row, str) L(row, str); R(row, str)
1208aa22952SBruce Evans 	B(10, "echo response");
1218aa22952SBruce Evans 	B(11, "echo request");
1228aa22952SBruce Evans 	B(12, "destination unreachable");
1238aa22952SBruce Evans 	B(13, "redirect");
1248aa22952SBruce Evans 	B(14, "time-to-live exceeded");
1258aa22952SBruce Evans 	B(15, "parameter problem");
1268aa22952SBruce Evans 	L(16, "router advertisement");	R(16, "router solicitation");
12703e00a72SGarrett Wollman #undef L
12803e00a72SGarrett Wollman #undef R
12903e00a72SGarrett Wollman #undef B
13003e00a72SGarrett Wollman }
13103e00a72SGarrett Wollman 
13203e00a72SGarrett Wollman static void
13303e00a72SGarrett Wollman domode(struct icmpstat *ret)
13403e00a72SGarrett Wollman {
13503e00a72SGarrett Wollman 	const struct icmpstat *sub;
13603e00a72SGarrett Wollman 	int i, divisor = 1;
13703e00a72SGarrett Wollman 
13803e00a72SGarrett Wollman 	switch(currentmode) {
13903e00a72SGarrett Wollman 	case display_RATE:
14003e00a72SGarrett Wollman 		sub = &oldstat;
1418b3daf89SAlexander V. Chernikov 		divisor = (delay > 1000000) ? delay / 1000000 : 1;
14203e00a72SGarrett Wollman 		break;
14303e00a72SGarrett Wollman 	case display_DELTA:
14403e00a72SGarrett Wollman 		sub = &oldstat;
14503e00a72SGarrett Wollman 		break;
14603e00a72SGarrett Wollman 	case display_SINCE:
14703e00a72SGarrett Wollman 		sub = &initstat;
14803e00a72SGarrett Wollman 		break;
14903e00a72SGarrett Wollman 	default:
15003e00a72SGarrett Wollman 		*ret = icmpstat;
15103e00a72SGarrett Wollman 		return;
15203e00a72SGarrett Wollman 	}
15303e00a72SGarrett Wollman #define DO(stat) ret->stat = (icmpstat.stat - sub->stat) / divisor
15403e00a72SGarrett Wollman 	DO(icps_error);
15503e00a72SGarrett Wollman 	DO(icps_oldshort);
15603e00a72SGarrett Wollman 	DO(icps_oldicmp);
15703e00a72SGarrett Wollman 	for (i = 0; i <= ICMP_MAXTYPE; i++) {
15803e00a72SGarrett Wollman 		DO(icps_outhist[i]);
15903e00a72SGarrett Wollman 	}
16003e00a72SGarrett Wollman 	DO(icps_badcode);
16103e00a72SGarrett Wollman 	DO(icps_tooshort);
16203e00a72SGarrett Wollman 	DO(icps_checksum);
16303e00a72SGarrett Wollman 	DO(icps_badlen);
16403e00a72SGarrett Wollman 	DO(icps_reflect);
16503e00a72SGarrett Wollman 	for (i = 0; i <= ICMP_MAXTYPE; i++) {
16603e00a72SGarrett Wollman 		DO(icps_inhist[i]);
16703e00a72SGarrett Wollman 	}
16803e00a72SGarrett Wollman 	DO(icps_bmcastecho);
16903e00a72SGarrett Wollman 	DO(icps_bmcasttstamp);
17003e00a72SGarrett Wollman #undef DO
17103e00a72SGarrett Wollman }
17203e00a72SGarrett Wollman 
17303e00a72SGarrett Wollman void
17403e00a72SGarrett Wollman showicmp(void)
17503e00a72SGarrett Wollman {
17603e00a72SGarrett Wollman 	struct icmpstat stats;
17703e00a72SGarrett Wollman 	u_long totalin, totalout;
17803e00a72SGarrett Wollman 	int i;
17903e00a72SGarrett Wollman 
18003e00a72SGarrett Wollman 	memset(&stats, 0, sizeof stats);
18103e00a72SGarrett Wollman 	domode(&stats);
18203e00a72SGarrett Wollman 	for (i = totalin = totalout = 0; i <= ICMP_MAXTYPE; i++) {
18303e00a72SGarrett Wollman 		totalin += stats.icps_inhist[i];
18403e00a72SGarrett Wollman 		totalout += stats.icps_outhist[i];
18503e00a72SGarrett Wollman 	}
18603e00a72SGarrett Wollman 	totalin += stats.icps_badcode + stats.icps_badlen +
18703e00a72SGarrett Wollman 		stats.icps_checksum + stats.icps_tooshort;
1888aa22952SBruce Evans 	mvwprintw(wnd, 1, 0, "%9lu", totalin);
1898aa22952SBruce Evans 	mvwprintw(wnd, 1, 35, "%9lu", totalout);
19003e00a72SGarrett Wollman 
19103e00a72SGarrett Wollman #define DO(stat, row, col) \
19203e00a72SGarrett Wollman 	mvwprintw(wnd, row, col, "%9lu", stats.stat)
19303e00a72SGarrett Wollman 
1948aa22952SBruce Evans 	DO(icps_badcode, 2, 0);
1958aa22952SBruce Evans 	DO(icps_badlen, 3, 0);
1968aa22952SBruce Evans 	DO(icps_checksum, 4, 0);
1978aa22952SBruce Evans 	DO(icps_tooshort, 5, 0);
1988aa22952SBruce Evans 	DO(icps_error, 2, 35);
1998aa22952SBruce Evans 	DO(icps_oldshort, 3, 35);
2008aa22952SBruce Evans 	DO(icps_oldicmp, 4, 35);
2018aa22952SBruce Evans 	DO(icps_reflect, 5, 35);
2028aa22952SBruce Evans 	DO(icps_bmcastecho, 6, 35);
2038aa22952SBruce Evans 	DO(icps_bmcasttstamp, 7, 35);
20403e00a72SGarrett Wollman #define DO2(type, row) DO(icps_inhist[type], row, 0); DO(icps_outhist[type], \
20503e00a72SGarrett Wollman 							 row, 35)
2068aa22952SBruce Evans 	DO2(ICMP_ECHOREPLY, 10);
2078aa22952SBruce Evans 	DO2(ICMP_ECHO, 11);
2088aa22952SBruce Evans 	DO2(ICMP_UNREACH, 12);
2098aa22952SBruce Evans 	DO2(ICMP_REDIRECT, 13);
2108aa22952SBruce Evans 	DO2(ICMP_TIMXCEED, 14);
2118aa22952SBruce Evans 	DO2(ICMP_PARAMPROB, 15);
2128aa22952SBruce Evans 	DO(icps_inhist[ICMP_ROUTERADVERT], 16, 0);
2138aa22952SBruce Evans 	DO(icps_outhist[ICMP_ROUTERSOLICIT], 16, 35);
21403e00a72SGarrett Wollman #undef DO
21503e00a72SGarrett Wollman #undef DO2
21603e00a72SGarrett Wollman }
21703e00a72SGarrett Wollman 
21803e00a72SGarrett Wollman int
21903e00a72SGarrett Wollman initicmp(void)
22003e00a72SGarrett Wollman {
22103e00a72SGarrett Wollman 	size_t len;
22203e00a72SGarrett Wollman 	int name[4];
22303e00a72SGarrett Wollman 
22403e00a72SGarrett Wollman 	name[0] = CTL_NET;
22503e00a72SGarrett Wollman 	name[1] = PF_INET;
22603e00a72SGarrett Wollman 	name[2] = IPPROTO_ICMP;
22703e00a72SGarrett Wollman 	name[3] = ICMPCTL_STATS;
22803e00a72SGarrett Wollman 
22903e00a72SGarrett Wollman 	len = 0;
23003e00a72SGarrett Wollman 	if (sysctl(name, 4, 0, &len, 0, 0) < 0) {
23103e00a72SGarrett Wollman 		error("sysctl getting icmpstat size failed");
23203e00a72SGarrett Wollman 		return 0;
23303e00a72SGarrett Wollman 	}
23403e00a72SGarrett Wollman 	if (len > sizeof icmpstat) {
23503e00a72SGarrett Wollman 		error("icmpstat structure has grown--recompile systat!");
23603e00a72SGarrett Wollman 		return 0;
23703e00a72SGarrett Wollman 	}
23803e00a72SGarrett Wollman 	if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
23903e00a72SGarrett Wollman 		error("sysctl getting icmpstat size failed");
24003e00a72SGarrett Wollman 		return 0;
24103e00a72SGarrett Wollman 	}
24203e00a72SGarrett Wollman 	oldstat = initstat;
24303e00a72SGarrett Wollman 	return 1;
24403e00a72SGarrett Wollman }
24503e00a72SGarrett Wollman 
24603e00a72SGarrett Wollman void
24703e00a72SGarrett Wollman reseticmp(void)
24803e00a72SGarrett Wollman {
24903e00a72SGarrett Wollman 	size_t len;
25003e00a72SGarrett Wollman 	int name[4];
25103e00a72SGarrett Wollman 
25203e00a72SGarrett Wollman 	name[0] = CTL_NET;
25303e00a72SGarrett Wollman 	name[1] = PF_INET;
25403e00a72SGarrett Wollman 	name[2] = IPPROTO_ICMP;
25503e00a72SGarrett Wollman 	name[3] = ICMPCTL_STATS;
25603e00a72SGarrett Wollman 
25703e00a72SGarrett Wollman 	len = sizeof initstat;
25803e00a72SGarrett Wollman 	if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
25903e00a72SGarrett Wollman 		error("sysctl getting icmpstat size failed");
26003e00a72SGarrett Wollman 	}
26103e00a72SGarrett Wollman 	oldstat = initstat;
26203e00a72SGarrett Wollman }
26303e00a72SGarrett Wollman 
26403e00a72SGarrett Wollman void
26503e00a72SGarrett Wollman fetchicmp(void)
26603e00a72SGarrett Wollman {
26703e00a72SGarrett Wollman 	int name[4];
26803e00a72SGarrett Wollman 	size_t len;
26903e00a72SGarrett Wollman 
27003e00a72SGarrett Wollman 	oldstat = icmpstat;
27103e00a72SGarrett Wollman 	name[0] = CTL_NET;
27203e00a72SGarrett Wollman 	name[1] = PF_INET;
27303e00a72SGarrett Wollman 	name[2] = IPPROTO_ICMP;
27403e00a72SGarrett Wollman 	name[3] = ICMPCTL_STATS;
27503e00a72SGarrett Wollman 	len = sizeof icmpstat;
27603e00a72SGarrett Wollman 
27703e00a72SGarrett Wollman 	if (sysctl(name, 4, &icmpstat, &len, 0, 0) < 0)
27803e00a72SGarrett Wollman 		return;
27903e00a72SGarrett Wollman }
280