icmp.c revision 87715
129759Swollman/*-
229759Swollman * Copyright (c) 1980, 1992, 1993
329759Swollman *	The Regents of the University of California.  All rights reserved.
429759Swollman *
529759Swollman * Redistribution and use in source and binary forms, with or without
629759Swollman * modification, are permitted provided that the following conditions
729759Swollman * are met:
829759Swollman * 1. Redistributions of source code must retain the above copyright
929759Swollman *    notice, this list of conditions and the following disclaimer.
1029759Swollman * 2. Redistributions in binary form must reproduce the above copyright
1129759Swollman *    notice, this list of conditions and the following disclaimer in the
1229759Swollman *    documentation and/or other materials provided with the distribution.
1329759Swollman * 3. All advertising materials mentioning features or use of this software
1429759Swollman *    must display the following acknowledgement:
1529759Swollman *	This product includes software developed by the University of
1629759Swollman *	California, Berkeley and its contributors.
1729759Swollman * 4. Neither the name of the University nor the names of its contributors
1829759Swollman *    may be used to endorse or promote products derived from this software
1929759Swollman *    without specific prior written permission.
2029759Swollman *
2129759Swollman * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2229759Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2329759Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2429759Swollman * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2529759Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2629759Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2729759Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2829759Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2929759Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3029759Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3129759Swollman * SUCH DAMAGE.
3229759Swollman */
3329759Swollman
3487715Smarkm#include <sys/cdefs.h>
3587715Smarkm
3687715Smarkm__FBSDID("$FreeBSD: head/usr.bin/systat/icmp.c 87715 2001-12-12 00:13:37Z markm $");
3787715Smarkm
3887715Smarkm#ifdef lint
3987715Smarkmstatic char sccsid[] = "@(#)mbufs.c	8.1 (Berkeley) 6/6/93";
4087715Smarkm#endif
4187715Smarkm
4229759Swollman/* From:
4387715Smarkm	"Id: mbufs.c,v 1.5 1997/02/24 20:59:03 wollman Exp"
4429759Swollman*/
4529759Swollman
4629759Swollman#include <sys/param.h>
4729759Swollman#include <sys/types.h>
4829759Swollman#include <sys/socket.h>
4929759Swollman#include <sys/sysctl.h>
5029759Swollman
5129759Swollman#include <netinet/in.h>
5229759Swollman#include <netinet/in_systm.h>
5329759Swollman#include <netinet/ip.h>
5429759Swollman#include <netinet/ip_icmp.h>
5529759Swollman#include <netinet/icmp_var.h>
5629759Swollman
5729759Swollman#include <stdlib.h>
5829759Swollman#include <string.h>
5929759Swollman#include <paths.h>
6029759Swollman#include "systat.h"
6129759Swollman#include "extern.h"
6229759Swollman#include "mode.h"
6329759Swollman
6429759Swollmanstatic struct icmpstat icmpstat, initstat, oldstat;
6529759Swollman
6629759Swollman/*-
6729759Swollman--0         1         2         3         4         5         6         7
6829759Swollman--0123456789012345678901234567890123456789012345678901234567890123456789012345
6929759Swollman01          ICMP Input                         ICMP Output
7029759Swollman02999999999 total messages           999999999 total messages
7129759Swollman03999999999 with bad code            999999999 errors generated
7229759Swollman04999999999 with bad length          999999999 suppressed - original too short
7329759Swollman05999999999 with bad checksum        999999999 suppressed - original was ICMP
7429759Swollman06999999999 with insufficient data   999999999 responses sent
7529759Swollman07                                   999999999 suppressed - multicast echo
7629759Swollman08                                   999999999 suppressed - multicast tstamp
7729759Swollman09
7829759Swollman10          Input Histogram                    Output Histogram
7929759Swollman11999999999 echo response            999999999 echo response
8029759Swollman12999999999 echo request             999999999 echo request
8129759Swollman13999999999 destination unreachable  999999999 destination unreachable
8229759Swollman14999999999 redirect                 999999999 redirect
8329759Swollman15999999999 time-to-live exceeded    999999999 time-to-line exceeded
8429759Swollman16999999999 parameter problem        999999999 parameter problem
8529759Swollman17999999999 router advertisement     999999999 router solicitation
8629759Swollman18
8729759Swollman19
8829759Swollman--0123456789012345678901234567890123456789012345678901234567890123456789012345
8929759Swollman--0         1         2         3         4         5         6         7
9029759Swollman*/
9129759Swollman
9229759SwollmanWINDOW *
9329759Swollmanopenicmp(void)
9429759Swollman{
9529759Swollman	return (subwin(stdscr, LINES-5-1, 0, 5, 0));
9629759Swollman}
9729759Swollman
9829759Swollmanvoid
9929759Swollmancloseicmp(w)
10029759Swollman	WINDOW *w;
10129759Swollman{
10229759Swollman	if (w == NULL)
10329759Swollman		return;
10429759Swollman	wclear(w);
10529759Swollman	wrefresh(w);
10629759Swollman	delwin(w);
10729759Swollman}
10829759Swollman
10929759Swollmanvoid
11029759Swollmanlabelicmp(void)
11129759Swollman{
11229759Swollman	wmove(wnd, 0, 0); wclrtoeol(wnd);
11329759Swollman#define L(row, str) mvwprintw(wnd, row, 10, str)
11429759Swollman#define R(row, str) mvwprintw(wnd, row, 45, str);
11529759Swollman	L(1, "ICMP Input");		R(1, "ICMP Output");
11629759Swollman	L(2, "total messages");		R(2, "total messages");
11729759Swollman	L(3, "with bad code");		R(3, "errors generated");
11829759Swollman	L(4, "with bad length");	R(4, "suppressed - original too short");
11929759Swollman	L(5, "with bad checksum");	R(5, "suppressed - original was ICMP");
12029759Swollman	L(6, "with insufficient data");	R(6, "responses sent");
12129759Swollman	;				R(7, "suppressed - multicast echo");
12229759Swollman	;				R(8, "suppressed - multicast tstamp");
12329759Swollman	L(10, "Input Histogram");	R(10, "Output Histogram");
12429759Swollman#define B(row, str) L(row, str); R(row, str)
12529759Swollman	B(11, "echo response");
12629759Swollman	B(12, "echo request");
12729759Swollman	B(13, "destination unreachable");
12829759Swollman	B(14, "redirect");
12929759Swollman	B(15, "time-to-live exceeded");
13029759Swollman	B(16, "parameter problem");
13129759Swollman	L(17, "router advertisement");	R(17, "router solicitation");
13229759Swollman#undef L
13329759Swollman#undef R
13429759Swollman#undef B
13529759Swollman}
13629759Swollman
13729759Swollmanstatic void
13829759Swollmandomode(struct icmpstat *ret)
13929759Swollman{
14029759Swollman	const struct icmpstat *sub;
14129759Swollman	int i, divisor = 1;
14229759Swollman
14329759Swollman	switch(currentmode) {
14429759Swollman	case display_RATE:
14529759Swollman		sub = &oldstat;
14629759Swollman		divisor = naptime;
14729759Swollman		break;
14829759Swollman	case display_DELTA:
14929759Swollman		sub = &oldstat;
15029759Swollman		break;
15129759Swollman	case display_SINCE:
15229759Swollman		sub = &initstat;
15329759Swollman		break;
15429759Swollman	default:
15529759Swollman		*ret = icmpstat;
15629759Swollman		return;
15729759Swollman	}
15829759Swollman#define DO(stat) ret->stat = (icmpstat.stat - sub->stat) / divisor
15929759Swollman	DO(icps_error);
16029759Swollman	DO(icps_oldshort);
16129759Swollman	DO(icps_oldicmp);
16229759Swollman	for (i = 0; i <= ICMP_MAXTYPE; i++) {
16329759Swollman		DO(icps_outhist[i]);
16429759Swollman	}
16529759Swollman	DO(icps_badcode);
16629759Swollman	DO(icps_tooshort);
16729759Swollman	DO(icps_checksum);
16829759Swollman	DO(icps_badlen);
16929759Swollman	DO(icps_reflect);
17029759Swollman	for (i = 0; i <= ICMP_MAXTYPE; i++) {
17129759Swollman		DO(icps_inhist[i]);
17229759Swollman	}
17329759Swollman	DO(icps_bmcastecho);
17429759Swollman	DO(icps_bmcasttstamp);
17529759Swollman#undef DO
17629759Swollman}
17729759Swollman
17829759Swollmanvoid
17929759Swollmanshowicmp(void)
18029759Swollman{
18129759Swollman	struct icmpstat stats;
18229759Swollman	u_long totalin, totalout;
18329759Swollman	int i;
18429759Swollman
18529759Swollman	memset(&stats, 0, sizeof stats);
18629759Swollman	domode(&stats);
18729759Swollman	for (i = totalin = totalout = 0; i <= ICMP_MAXTYPE; i++) {
18829759Swollman		totalin += stats.icps_inhist[i];
18929759Swollman		totalout += stats.icps_outhist[i];
19029759Swollman	}
19129759Swollman	totalin += stats.icps_badcode + stats.icps_badlen +
19229759Swollman		stats.icps_checksum + stats.icps_tooshort;
19329759Swollman	mvwprintw(wnd, 2, 0, "%9lu", totalin);
19429759Swollman	mvwprintw(wnd, 2, 35, "%9lu", totalout);
19529759Swollman
19629759Swollman#define DO(stat, row, col) \
19729759Swollman	mvwprintw(wnd, row, col, "%9lu", stats.stat)
19829759Swollman
19929759Swollman	DO(icps_badcode, 3, 0);
20029759Swollman	DO(icps_badlen, 4, 0);
20129759Swollman	DO(icps_checksum, 5, 0);
20229759Swollman	DO(icps_tooshort, 6, 0);
20329759Swollman	DO(icps_error, 3, 35);
20429759Swollman	DO(icps_oldshort, 4, 35);
20529759Swollman	DO(icps_oldicmp, 5, 35);
20629759Swollman	DO(icps_reflect, 6, 35);
20729759Swollman	DO(icps_bmcastecho, 7, 35);
20829759Swollman	DO(icps_bmcasttstamp, 8, 35);
20929759Swollman#define DO2(type, row) DO(icps_inhist[type], row, 0); DO(icps_outhist[type], \
21029759Swollman							 row, 35)
21129759Swollman	DO2(ICMP_ECHOREPLY, 11);
21229759Swollman	DO2(ICMP_ECHO, 12);
21329759Swollman	DO2(ICMP_UNREACH, 13);
21429759Swollman	DO2(ICMP_REDIRECT, 14);
21529759Swollman	DO2(ICMP_TIMXCEED, 15);
21629759Swollman	DO2(ICMP_PARAMPROB, 16);
21729759Swollman	DO(icps_inhist[ICMP_ROUTERADVERT], 17, 0);
21829759Swollman	DO(icps_outhist[ICMP_ROUTERSOLICIT], 17, 35);
21929759Swollman#undef DO
22029759Swollman#undef DO2
22129759Swollman}
22229759Swollman
22329759Swollmanint
22429759Swollmaniniticmp(void)
22529759Swollman{
22629759Swollman	size_t len;
22729759Swollman	int name[4];
22829759Swollman
22929759Swollman	name[0] = CTL_NET;
23029759Swollman	name[1] = PF_INET;
23129759Swollman	name[2] = IPPROTO_ICMP;
23229759Swollman	name[3] = ICMPCTL_STATS;
23329759Swollman
23429759Swollman	len = 0;
23529759Swollman	if (sysctl(name, 4, 0, &len, 0, 0) < 0) {
23629759Swollman		error("sysctl getting icmpstat size failed");
23729759Swollman		return 0;
23829759Swollman	}
23929759Swollman	if (len > sizeof icmpstat) {
24029759Swollman		error("icmpstat structure has grown--recompile systat!");
24129759Swollman		return 0;
24229759Swollman	}
24329759Swollman	if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
24429759Swollman		error("sysctl getting icmpstat size failed");
24529759Swollman		return 0;
24629759Swollman	}
24729759Swollman	oldstat = initstat;
24829759Swollman	return 1;
24929759Swollman}
25029759Swollman
25129759Swollmanvoid
25229759Swollmanreseticmp(void)
25329759Swollman{
25429759Swollman	size_t len;
25529759Swollman	int name[4];
25629759Swollman
25729759Swollman	name[0] = CTL_NET;
25829759Swollman	name[1] = PF_INET;
25929759Swollman	name[2] = IPPROTO_ICMP;
26029759Swollman	name[3] = ICMPCTL_STATS;
26129759Swollman
26229759Swollman	len = sizeof initstat;
26329759Swollman	if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
26429759Swollman		error("sysctl getting icmpstat size failed");
26529759Swollman	}
26629759Swollman	oldstat = initstat;
26729759Swollman}
26829759Swollman
26929759Swollmanvoid
27029759Swollmanfetchicmp(void)
27129759Swollman{
27229759Swollman	int name[4];
27329759Swollman	size_t len;
27429759Swollman
27529759Swollman	oldstat = icmpstat;
27629759Swollman	name[0] = CTL_NET;
27729759Swollman	name[1] = PF_INET;
27829759Swollman	name[2] = IPPROTO_ICMP;
27929759Swollman	name[3] = ICMPCTL_STATS;
28029759Swollman	len = sizeof icmpstat;
28129759Swollman
28229759Swollman	if (sysctl(name, 4, &icmpstat, &len, 0, 0) < 0)
28329759Swollman		return;
28429759Swollman}
28529759Swollman
286