xref: /freebsd/usr.bin/systat/icmp.c (revision 03e00a72c68a5546196978ca2a460d8cf361dd44)
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.
1303e00a72SGarrett Wollman  * 3. All advertising materials mentioning features or use of this software
1403e00a72SGarrett Wollman  *    must display the following acknowledgement:
1503e00a72SGarrett Wollman  *	This product includes software developed by the University of
1603e00a72SGarrett Wollman  *	California, Berkeley and its contributors.
1703e00a72SGarrett Wollman  * 4. Neither the name of the University nor the names of its contributors
1803e00a72SGarrett Wollman  *    may be used to endorse or promote products derived from this software
1903e00a72SGarrett Wollman  *    without specific prior written permission.
2003e00a72SGarrett Wollman  *
2103e00a72SGarrett Wollman  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2203e00a72SGarrett Wollman  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2303e00a72SGarrett Wollman  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2403e00a72SGarrett Wollman  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2503e00a72SGarrett Wollman  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2603e00a72SGarrett Wollman  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2703e00a72SGarrett Wollman  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2803e00a72SGarrett Wollman  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2903e00a72SGarrett Wollman  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3003e00a72SGarrett Wollman  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3103e00a72SGarrett Wollman  * SUCH DAMAGE.
3203e00a72SGarrett Wollman  */
3303e00a72SGarrett Wollman 
3403e00a72SGarrett Wollman #ifndef lint
3503e00a72SGarrett Wollman /* From:
3603e00a72SGarrett Wollman static char sccsid[] = "@(#)mbufs.c	8.1 (Berkeley) 6/6/93";
3703e00a72SGarrett Wollman static const char rcsid[] =
3803e00a72SGarrett Wollman 	"Id: mbufs.c,v 1.5 1997/02/24 20:59:03 wollman Exp";
3903e00a72SGarrett Wollman */
4003e00a72SGarrett Wollman static const char rcsid[] =
4103e00a72SGarrett Wollman 	"$Id$";
4203e00a72SGarrett Wollman #endif /* not lint */
4303e00a72SGarrett Wollman 
4403e00a72SGarrett Wollman #include <sys/param.h>
4503e00a72SGarrett Wollman #include <sys/types.h>
4603e00a72SGarrett Wollman #include <sys/socket.h>
4703e00a72SGarrett Wollman #include <sys/sysctl.h>
4803e00a72SGarrett Wollman 
4903e00a72SGarrett Wollman #include <netinet/in.h>
5003e00a72SGarrett Wollman #include <netinet/in_systm.h>
5103e00a72SGarrett Wollman #include <netinet/ip.h>
5203e00a72SGarrett Wollman #include <netinet/ip_icmp.h>
5303e00a72SGarrett Wollman #include <netinet/icmp_var.h>
5403e00a72SGarrett Wollman 
5503e00a72SGarrett Wollman #include <stdlib.h>
5603e00a72SGarrett Wollman #include <string.h>
5703e00a72SGarrett Wollman #include <paths.h>
5803e00a72SGarrett Wollman #include "systat.h"
5903e00a72SGarrett Wollman #include "extern.h"
6003e00a72SGarrett Wollman #include "mode.h"
6103e00a72SGarrett Wollman 
6203e00a72SGarrett Wollman static struct icmpstat icmpstat, initstat, oldstat;
6303e00a72SGarrett Wollman 
6403e00a72SGarrett Wollman /*-
6503e00a72SGarrett Wollman --0         1         2         3         4         5         6         7
6603e00a72SGarrett Wollman --0123456789012345678901234567890123456789012345678901234567890123456789012345
6703e00a72SGarrett Wollman 01          ICMP Input                         ICMP Output
6803e00a72SGarrett Wollman 02999999999 total messages           999999999 total messages
6903e00a72SGarrett Wollman 03999999999 with bad code            999999999 errors generated
7003e00a72SGarrett Wollman 04999999999 with bad length          999999999 suppressed - original too short
7103e00a72SGarrett Wollman 05999999999 with bad checksum        999999999 suppressed - original was ICMP
7203e00a72SGarrett Wollman 06999999999 with insufficient data   999999999 responses sent
7303e00a72SGarrett Wollman 07                                   999999999 suppressed - multicast echo
7403e00a72SGarrett Wollman 08                                   999999999 suppressed - multicast tstamp
7503e00a72SGarrett Wollman 09
7603e00a72SGarrett Wollman 10          Input Histogram                    Output Histogram
7703e00a72SGarrett Wollman 11999999999 echo response            999999999 echo response
7803e00a72SGarrett Wollman 12999999999 echo request             999999999 echo request
7903e00a72SGarrett Wollman 13999999999 destination unreachable  999999999 destination unreachable
8003e00a72SGarrett Wollman 14999999999 redirect                 999999999 redirect
8103e00a72SGarrett Wollman 15999999999 time-to-live exceeded    999999999 time-to-line exceeded
8203e00a72SGarrett Wollman 16999999999 parameter problem        999999999 parameter problem
8303e00a72SGarrett Wollman 17999999999 router advertisement     999999999 router solicitation
8403e00a72SGarrett Wollman 18
8503e00a72SGarrett Wollman 19
8603e00a72SGarrett Wollman --0123456789012345678901234567890123456789012345678901234567890123456789012345
8703e00a72SGarrett Wollman --0         1         2         3         4         5         6         7
8803e00a72SGarrett Wollman */
8903e00a72SGarrett Wollman 
9003e00a72SGarrett Wollman WINDOW *
9103e00a72SGarrett Wollman openicmp(void)
9203e00a72SGarrett Wollman {
9303e00a72SGarrett Wollman 	return (subwin(stdscr, LINES-5-1, 0, 5, 0));
9403e00a72SGarrett Wollman }
9503e00a72SGarrett Wollman 
9603e00a72SGarrett Wollman void
9703e00a72SGarrett Wollman closeicmp(w)
9803e00a72SGarrett Wollman 	WINDOW *w;
9903e00a72SGarrett Wollman {
10003e00a72SGarrett Wollman 	if (w == NULL)
10103e00a72SGarrett Wollman 		return;
10203e00a72SGarrett Wollman 	wclear(w);
10303e00a72SGarrett Wollman 	wrefresh(w);
10403e00a72SGarrett Wollman 	delwin(w);
10503e00a72SGarrett Wollman }
10603e00a72SGarrett Wollman 
10703e00a72SGarrett Wollman void
10803e00a72SGarrett Wollman labelicmp(void)
10903e00a72SGarrett Wollman {
11003e00a72SGarrett Wollman 	wmove(wnd, 0, 0); wclrtoeol(wnd);
11103e00a72SGarrett Wollman #define L(row, str) mvwprintw(wnd, row, 10, str)
11203e00a72SGarrett Wollman #define R(row, str) mvwprintw(wnd, row, 45, str);
11303e00a72SGarrett Wollman 	L(1, "ICMP Input");		R(1, "ICMP Output");
11403e00a72SGarrett Wollman 	L(2, "total messages");		R(2, "total messages");
11503e00a72SGarrett Wollman 	L(3, "with bad code");		R(3, "errors generated");
11603e00a72SGarrett Wollman 	L(4, "with bad length");	R(4, "suppressed - original too short");
11703e00a72SGarrett Wollman 	L(5, "with bad checksum");	R(5, "suppressed - original was ICMP");
11803e00a72SGarrett Wollman 	L(6, "with insufficient data");	R(6, "responses sent");
11903e00a72SGarrett Wollman 	;				R(7, "suppressed - multicast echo");
12003e00a72SGarrett Wollman 	;				R(8, "suppressed - multicast tstamp");
12103e00a72SGarrett Wollman 	L(10, "Input Histogram");	R(10, "Output Histogram");
12203e00a72SGarrett Wollman #define B(row, str) L(row, str); R(row, str)
12303e00a72SGarrett Wollman 	B(11, "echo response");
12403e00a72SGarrett Wollman 	B(12, "echo request");
12503e00a72SGarrett Wollman 	B(13, "destination unreachable");
12603e00a72SGarrett Wollman 	B(14, "redirect");
12703e00a72SGarrett Wollman 	B(15, "time-to-live exceeded");
12803e00a72SGarrett Wollman 	B(16, "parameter problem");
12903e00a72SGarrett Wollman 	L(17, "router advertisement");	R(17, "router solicitation");
13003e00a72SGarrett Wollman #undef L
13103e00a72SGarrett Wollman #undef R
13203e00a72SGarrett Wollman #undef B
13303e00a72SGarrett Wollman }
13403e00a72SGarrett Wollman 
13503e00a72SGarrett Wollman static void
13603e00a72SGarrett Wollman domode(struct icmpstat *ret)
13703e00a72SGarrett Wollman {
13803e00a72SGarrett Wollman 	const struct icmpstat *sub;
13903e00a72SGarrett Wollman 	int i, divisor = 1;
14003e00a72SGarrett Wollman 
14103e00a72SGarrett Wollman 	switch(currentmode) {
14203e00a72SGarrett Wollman 	case display_RATE:
14303e00a72SGarrett Wollman 		sub = &oldstat;
14403e00a72SGarrett Wollman 		divisor = naptime;
14503e00a72SGarrett Wollman 		break;
14603e00a72SGarrett Wollman 	case display_DELTA:
14703e00a72SGarrett Wollman 		sub = &oldstat;
14803e00a72SGarrett Wollman 		break;
14903e00a72SGarrett Wollman 	case display_SINCE:
15003e00a72SGarrett Wollman 		sub = &initstat;
15103e00a72SGarrett Wollman 		break;
15203e00a72SGarrett Wollman 	default:
15303e00a72SGarrett Wollman 		*ret = icmpstat;
15403e00a72SGarrett Wollman 		return;
15503e00a72SGarrett Wollman 	}
15603e00a72SGarrett Wollman #define DO(stat) ret->stat = (icmpstat.stat - sub->stat) / divisor
15703e00a72SGarrett Wollman 	DO(icps_error);
15803e00a72SGarrett Wollman 	DO(icps_oldshort);
15903e00a72SGarrett Wollman 	DO(icps_oldicmp);
16003e00a72SGarrett Wollman 	for (i = 0; i <= ICMP_MAXTYPE; i++) {
16103e00a72SGarrett Wollman 		DO(icps_outhist[i]);
16203e00a72SGarrett Wollman 	}
16303e00a72SGarrett Wollman 	DO(icps_badcode);
16403e00a72SGarrett Wollman 	DO(icps_tooshort);
16503e00a72SGarrett Wollman 	DO(icps_checksum);
16603e00a72SGarrett Wollman 	DO(icps_badlen);
16703e00a72SGarrett Wollman 	DO(icps_reflect);
16803e00a72SGarrett Wollman 	for (i = 0; i <= ICMP_MAXTYPE; i++) {
16903e00a72SGarrett Wollman 		DO(icps_inhist[i]);
17003e00a72SGarrett Wollman 	}
17103e00a72SGarrett Wollman 	DO(icps_bmcastecho);
17203e00a72SGarrett Wollman 	DO(icps_bmcasttstamp);
17303e00a72SGarrett Wollman #undef DO
17403e00a72SGarrett Wollman }
17503e00a72SGarrett Wollman 
17603e00a72SGarrett Wollman void
17703e00a72SGarrett Wollman showicmp(void)
17803e00a72SGarrett Wollman {
17903e00a72SGarrett Wollman 	struct icmpstat stats;
18003e00a72SGarrett Wollman 	u_long totalin, totalout;
18103e00a72SGarrett Wollman 	int i;
18203e00a72SGarrett Wollman 
18303e00a72SGarrett Wollman 	memset(&stats, 0, sizeof stats);
18403e00a72SGarrett Wollman 	domode(&stats);
18503e00a72SGarrett Wollman 	for (i = totalin = totalout = 0; i <= ICMP_MAXTYPE; i++) {
18603e00a72SGarrett Wollman 		totalin += stats.icps_inhist[i];
18703e00a72SGarrett Wollman 		totalout += stats.icps_outhist[i];
18803e00a72SGarrett Wollman 	}
18903e00a72SGarrett Wollman 	totalin += stats.icps_badcode + stats.icps_badlen +
19003e00a72SGarrett Wollman 		stats.icps_checksum + stats.icps_tooshort;
19103e00a72SGarrett Wollman 	mvwprintw(wnd, 2, 0, "%9lu", totalin);
19203e00a72SGarrett Wollman 	mvwprintw(wnd, 2, 35, "%9lu", totalout);
19303e00a72SGarrett Wollman 
19403e00a72SGarrett Wollman #define DO(stat, row, col) \
19503e00a72SGarrett Wollman 	mvwprintw(wnd, row, col, "%9lu", stats.stat)
19603e00a72SGarrett Wollman 
19703e00a72SGarrett Wollman 	DO(icps_badcode, 3, 0);
19803e00a72SGarrett Wollman 	DO(icps_badlen, 4, 0);
19903e00a72SGarrett Wollman 	DO(icps_checksum, 5, 0);
20003e00a72SGarrett Wollman 	DO(icps_tooshort, 6, 0);
20103e00a72SGarrett Wollman 	DO(icps_error, 3, 35);
20203e00a72SGarrett Wollman 	DO(icps_oldshort, 4, 35);
20303e00a72SGarrett Wollman 	DO(icps_oldicmp, 5, 35);
20403e00a72SGarrett Wollman 	DO(icps_reflect, 6, 35);
20503e00a72SGarrett Wollman 	DO(icps_bmcastecho, 7, 35);
20603e00a72SGarrett Wollman 	DO(icps_bmcasttstamp, 8, 35);
20703e00a72SGarrett Wollman #define DO2(type, row) DO(icps_inhist[type], row, 0); DO(icps_outhist[type], \
20803e00a72SGarrett Wollman 							 row, 35)
20903e00a72SGarrett Wollman 	DO2(ICMP_ECHOREPLY, 11);
21003e00a72SGarrett Wollman 	DO2(ICMP_ECHO, 12);
21103e00a72SGarrett Wollman 	DO2(ICMP_UNREACH, 13);
21203e00a72SGarrett Wollman 	DO2(ICMP_REDIRECT, 14);
21303e00a72SGarrett Wollman 	DO2(ICMP_TIMXCEED, 15);
21403e00a72SGarrett Wollman 	DO2(ICMP_PARAMPROB, 16);
21503e00a72SGarrett Wollman 	DO(icps_inhist[ICMP_ROUTERADVERT], 17, 0);
21603e00a72SGarrett Wollman 	DO(icps_outhist[ICMP_ROUTERSOLICIT], 17, 35);
21703e00a72SGarrett Wollman #undef DO
21803e00a72SGarrett Wollman #undef DO2
21903e00a72SGarrett Wollman }
22003e00a72SGarrett Wollman 
22103e00a72SGarrett Wollman int
22203e00a72SGarrett Wollman initicmp(void)
22303e00a72SGarrett Wollman {
22403e00a72SGarrett Wollman 	size_t len;
22503e00a72SGarrett Wollman 	int name[4];
22603e00a72SGarrett Wollman 
22703e00a72SGarrett Wollman 	name[0] = CTL_NET;
22803e00a72SGarrett Wollman 	name[1] = PF_INET;
22903e00a72SGarrett Wollman 	name[2] = IPPROTO_ICMP;
23003e00a72SGarrett Wollman 	name[3] = ICMPCTL_STATS;
23103e00a72SGarrett Wollman 
23203e00a72SGarrett Wollman 	len = 0;
23303e00a72SGarrett Wollman 	if (sysctl(name, 4, 0, &len, 0, 0) < 0) {
23403e00a72SGarrett Wollman 		error("sysctl getting icmpstat size failed");
23503e00a72SGarrett Wollman 		return 0;
23603e00a72SGarrett Wollman 	}
23703e00a72SGarrett Wollman 	if (len > sizeof icmpstat) {
23803e00a72SGarrett Wollman 		error("icmpstat structure has grown--recompile systat!");
23903e00a72SGarrett Wollman 		return 0;
24003e00a72SGarrett Wollman 	}
24103e00a72SGarrett Wollman 	if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
24203e00a72SGarrett Wollman 		error("sysctl getting icmpstat size failed");
24303e00a72SGarrett Wollman 		return 0;
24403e00a72SGarrett Wollman 	}
24503e00a72SGarrett Wollman 	oldstat = initstat;
24603e00a72SGarrett Wollman 	return 1;
24703e00a72SGarrett Wollman }
24803e00a72SGarrett Wollman 
24903e00a72SGarrett Wollman void
25003e00a72SGarrett Wollman reseticmp(void)
25103e00a72SGarrett Wollman {
25203e00a72SGarrett Wollman 	size_t len;
25303e00a72SGarrett Wollman 	int name[4];
25403e00a72SGarrett Wollman 
25503e00a72SGarrett Wollman 	name[0] = CTL_NET;
25603e00a72SGarrett Wollman 	name[1] = PF_INET;
25703e00a72SGarrett Wollman 	name[2] = IPPROTO_ICMP;
25803e00a72SGarrett Wollman 	name[3] = ICMPCTL_STATS;
25903e00a72SGarrett Wollman 
26003e00a72SGarrett Wollman 	len = sizeof initstat;
26103e00a72SGarrett Wollman 	if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
26203e00a72SGarrett Wollman 		error("sysctl getting icmpstat size failed");
26303e00a72SGarrett Wollman 	}
26403e00a72SGarrett Wollman 	oldstat = initstat;
26503e00a72SGarrett Wollman }
26603e00a72SGarrett Wollman 
26703e00a72SGarrett Wollman void
26803e00a72SGarrett Wollman fetchicmp(void)
26903e00a72SGarrett Wollman {
27003e00a72SGarrett Wollman 	int name[4];
27103e00a72SGarrett Wollman 	size_t len;
27203e00a72SGarrett Wollman 
27303e00a72SGarrett Wollman 	oldstat = icmpstat;
27403e00a72SGarrett Wollman 	name[0] = CTL_NET;
27503e00a72SGarrett Wollman 	name[1] = PF_INET;
27603e00a72SGarrett Wollman 	name[2] = IPPROTO_ICMP;
27703e00a72SGarrett Wollman 	name[3] = ICMPCTL_STATS;
27803e00a72SGarrett Wollman 	len = sizeof icmpstat;
27903e00a72SGarrett Wollman 
28003e00a72SGarrett Wollman 	if (sysctl(name, 4, &icmpstat, &len, 0, 0) < 0)
28103e00a72SGarrett Wollman 		return;
28203e00a72SGarrett Wollman }
28303e00a72SGarrett Wollman 
284