icmp6.c revision 175387
1118318Sdwmalone/*-
2118318Sdwmalone * Copyright (c) 1980, 1992, 1993
3118318Sdwmalone *	The Regents of the University of California.  All rights reserved.
4118318Sdwmalone *
5118318Sdwmalone * Redistribution and use in source and binary forms, with or without
6118318Sdwmalone * modification, are permitted provided that the following conditions
7118318Sdwmalone * are met:
8118318Sdwmalone * 1. Redistributions of source code must retain the above copyright
9118318Sdwmalone *    notice, this list of conditions and the following disclaimer.
10118318Sdwmalone * 2. Redistributions in binary form must reproduce the above copyright
11118318Sdwmalone *    notice, this list of conditions and the following disclaimer in the
12118318Sdwmalone *    documentation and/or other materials provided with the distribution.
13118318Sdwmalone * 3. All advertising materials mentioning features or use of this software
14118318Sdwmalone *    must display the following acknowledgement:
15118318Sdwmalone *	This product includes software developed by the University of
16118318Sdwmalone *	California, Berkeley and its contributors.
17118318Sdwmalone * 4. Neither the name of the University nor the names of its contributors
18118318Sdwmalone *    may be used to endorse or promote products derived from this software
19118318Sdwmalone *    without specific prior written permission.
20118318Sdwmalone *
21118318Sdwmalone * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22118318Sdwmalone * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23118318Sdwmalone * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24118318Sdwmalone * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25118318Sdwmalone * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26118318Sdwmalone * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27118318Sdwmalone * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28118318Sdwmalone * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29118318Sdwmalone * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30118318Sdwmalone * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31118318Sdwmalone * SUCH DAMAGE.
32118318Sdwmalone */
33118318Sdwmalone
34118318Sdwmalone#include <sys/cdefs.h>
35118318Sdwmalone
36118318Sdwmalone__FBSDID("$FreeBSD: head/usr.bin/systat/icmp6.c 175387 2008-01-16 19:27:43Z delphij $");
37118318Sdwmalone
38118318Sdwmalone#ifdef lint
39118318Sdwmalonestatic char sccsid[] = "@(#)mbufs.c	8.1 (Berkeley) 6/6/93";
40118318Sdwmalone#endif
41118318Sdwmalone
42118318Sdwmalone/* From:
43118318Sdwmalone	"Id: mbufs.c,v 1.5 1997/02/24 20:59:03 wollman Exp"
44118318Sdwmalone*/
45118318Sdwmalone
46118318Sdwmalone#ifdef INET6
47118318Sdwmalone#include <sys/param.h>
48118318Sdwmalone#include <sys/types.h>
49118318Sdwmalone#include <sys/socket.h>
50118318Sdwmalone#include <sys/sysctl.h>
51118318Sdwmalone
52118318Sdwmalone#include <netinet/in.h>
53118318Sdwmalone#include <netinet/icmp6.h>
54118318Sdwmalone
55118318Sdwmalone#include <stdlib.h>
56118318Sdwmalone#include <string.h>
57118318Sdwmalone#include <paths.h>
58118318Sdwmalone#include "systat.h"
59118318Sdwmalone#include "extern.h"
60118318Sdwmalone#include "mode.h"
61118318Sdwmalone
62118318Sdwmalonestatic struct icmp6stat icmp6stat, initstat, oldstat;
63118318Sdwmalone
64118318Sdwmalone/*-
65118318Sdwmalone--0         1         2         3         4         5         6         7
66118318Sdwmalone--0123456789012345678901234567890123456789012345678901234567890123456789012345
67158160Sbde00          ICMPv6 Input                       ICMPv6 Output
68158160Sbde01999999999 total messages           999999999 total messages
69158160Sbde02999999999 with bad code            999999999 errors generated
70158160Sbde03999999999 with bad length          999999999 suppressed - original too short
71158160Sbde04999999999 with bad checksum        999999999 suppressed - original was ICMP
72158160Sbde05999999999 with insufficient data   999999999 responses sent
73158160Sbde06
74158160Sbde07          Input Histogram                    Output Histogram
75158160Sbde08999999999 echo response            999999999 echo response
76158160Sbde09999999999 echo request             999999999 echo request
77158160Sbde10999999999 destination unreachable  999999999 destination unreachable
78158160Sbde11999999999 redirect                 999999999 redirect
79158160Sbde12999999999 time-to-live exceeded    999999999 time-to-line exceeded
80158160Sbde13999999999 parameter problem        999999999 parameter problem
81158160Sbde14999999999 neighbor solicitation    999999999 neighbor solicitation
82158160Sbde15999999999 neighbor advertisment    999999999 neighbor advertisment
83158160Sbde16999999999 router advertisement     999999999 router solicitation
84158160Sbde17
85118318Sdwmalone18
86118318Sdwmalone--0123456789012345678901234567890123456789012345678901234567890123456789012345
87118318Sdwmalone--0         1         2         3         4         5         6         7
88118318Sdwmalone*/
89118318Sdwmalone
90118318SdwmaloneWINDOW *
91118318Sdwmaloneopenicmp6(void)
92118318Sdwmalone{
93158160Sbde	return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0));
94118318Sdwmalone}
95118318Sdwmalone
96118318Sdwmalonevoid
97175387Sdelphijcloseicmp6(WINDOW *w)
98118318Sdwmalone{
99118318Sdwmalone	if (w == NULL)
100118318Sdwmalone		return;
101118318Sdwmalone	wclear(w);
102118318Sdwmalone	wrefresh(w);
103118318Sdwmalone	delwin(w);
104118318Sdwmalone}
105118318Sdwmalone
106118318Sdwmalonevoid
107118318Sdwmalonelabelicmp6(void)
108118318Sdwmalone{
109118318Sdwmalone	wmove(wnd, 0, 0); wclrtoeol(wnd);
110118318Sdwmalone#define L(row, str) mvwprintw(wnd, row, 10, str)
111118318Sdwmalone#define R(row, str) mvwprintw(wnd, row, 45, str);
112158160Sbde	L(0, "ICMPv6 Input");		R(0, "ICMPv6 Output");
113158160Sbde	L(1, "total messages");		R(1, "total messages");
114158160Sbde	L(2, "with bad code");		R(2, "errors generated");
115158160Sbde	L(3, "with bad length");	R(3, "suppressed - original too short");
116158160Sbde	L(4, "with bad checksum");	R(4, "suppressed - original was ICMP");
117158160Sbde	L(5, "with insufficient data");	R(5, "responses sent");
118118318Sdwmalone
119158160Sbde	L(7, "Input Histogram");	R(7, "Output Histogram");
120118318Sdwmalone#define B(row, str) L(row, str); R(row, str)
121158160Sbde	B(8, "echo response");
122158160Sbde	B(9, "echo request");
123158160Sbde	B(10, "destination unreachable");
124158160Sbde	B(11, "redirect");
125158160Sbde	B(12, "time-to-live exceeded");
126158160Sbde	B(13, "parameter problem");
127158160Sbde	B(14, "neighbor solicitation");
128158160Sbde	B(15, "neighbor advertisment");
129158160Sbde	L(16, "router advertisement");	R(16, "router solicitation");
130118318Sdwmalone#undef L
131118318Sdwmalone#undef R
132118318Sdwmalone#undef B
133118318Sdwmalone}
134118318Sdwmalone
135118318Sdwmalonestatic void
136118318Sdwmalonedomode(struct icmp6stat *ret)
137118318Sdwmalone{
138118318Sdwmalone	const struct icmp6stat *sub;
139118318Sdwmalone	int i, divisor = 1;
140118318Sdwmalone
141118318Sdwmalone	switch(currentmode) {
142118318Sdwmalone	case display_RATE:
143118318Sdwmalone		sub = &oldstat;
144118318Sdwmalone		divisor = naptime;
145118318Sdwmalone		break;
146118318Sdwmalone	case display_DELTA:
147118318Sdwmalone		sub = &oldstat;
148118318Sdwmalone		break;
149118318Sdwmalone	case display_SINCE:
150118318Sdwmalone		sub = &initstat;
151118318Sdwmalone		break;
152118318Sdwmalone	default:
153118318Sdwmalone		*ret = icmp6stat;
154118318Sdwmalone		return;
155118318Sdwmalone	}
156118318Sdwmalone#define DO(stat) ret->stat = (icmp6stat.stat - sub->stat) / divisor
157118318Sdwmalone	DO(icp6s_error);
158118318Sdwmalone	DO(icp6s_tooshort);
159118318Sdwmalone	DO(icp6s_canterror);
160118318Sdwmalone	for (i = 0; i <= ICMP6_MAXTYPE; i++) {
161118318Sdwmalone		DO(icp6s_outhist[i]);
162118318Sdwmalone	}
163118318Sdwmalone	DO(icp6s_badcode);
164118318Sdwmalone	DO(icp6s_tooshort);
165118318Sdwmalone	DO(icp6s_checksum);
166118318Sdwmalone	DO(icp6s_badlen);
167118318Sdwmalone	DO(icp6s_reflect);
168118318Sdwmalone	for (i = 0; i <= ICMP6_MAXTYPE; i++) {
169118318Sdwmalone		DO(icp6s_inhist[i]);
170118318Sdwmalone	}
171118318Sdwmalone#undef DO
172118318Sdwmalone}
173158161Sbde
174118318Sdwmalonevoid
175118318Sdwmaloneshowicmp6(void)
176118318Sdwmalone{
177118318Sdwmalone	struct icmp6stat stats;
178118318Sdwmalone	u_long totalin, totalout;
179118318Sdwmalone	int i;
180118318Sdwmalone
181118318Sdwmalone	memset(&stats, 0, sizeof stats);
182118318Sdwmalone	domode(&stats);
183118318Sdwmalone	for (i = totalin = totalout = 0; i <= ICMP6_MAXTYPE; i++) {
184118318Sdwmalone		totalin += stats.icp6s_inhist[i];
185118318Sdwmalone		totalout += stats.icp6s_outhist[i];
186118318Sdwmalone	}
187158161Sbde	totalin += stats.icp6s_badcode + stats.icp6s_badlen +
188118318Sdwmalone		stats.icp6s_checksum + stats.icp6s_tooshort;
189158160Sbde	mvwprintw(wnd, 1, 0, "%9lu", totalin);
190158160Sbde	mvwprintw(wnd, 1, 35, "%9lu", totalout);
191118318Sdwmalone
192118318Sdwmalone#define DO(stat, row, col) \
193118318Sdwmalone	mvwprintw(wnd, row, col, "%9lu", stats.stat)
194118318Sdwmalone
195158160Sbde	DO(icp6s_badcode, 2, 0);
196158160Sbde	DO(icp6s_badlen, 3, 0);
197158160Sbde	DO(icp6s_checksum, 4, 0);
198158160Sbde	DO(icp6s_tooshort, 5, 0);
199158160Sbde	DO(icp6s_error, 2, 35);
200158160Sbde	DO(icp6s_tooshort, 3, 35);
201158160Sbde	DO(icp6s_canterror, 4, 35);
202158160Sbde	DO(icp6s_reflect, 5, 35);
203118318Sdwmalone#define DO2(type, row) DO(icp6s_inhist[type], row, 0); DO(icp6s_outhist[type], \
204118318Sdwmalone							 row, 35)
205158160Sbde	DO2(ICMP6_ECHO_REPLY, 8);
206158160Sbde	DO2(ICMP6_ECHO_REQUEST, 9);
207158160Sbde	DO2(ICMP6_DST_UNREACH, 10);
208158160Sbde	DO2(ND_REDIRECT, 11);
209158160Sbde	DO2(ICMP6_TIME_EXCEEDED, 12);
210158160Sbde	DO2(ICMP6_PARAM_PROB, 13);
211158160Sbde	DO2(ND_NEIGHBOR_SOLICIT, 14);
212158160Sbde	DO2(ND_NEIGHBOR_ADVERT, 15);
213158160Sbde	DO(icp6s_inhist[ND_ROUTER_SOLICIT], 16, 0);
214158160Sbde	DO(icp6s_outhist[ND_ROUTER_ADVERT], 16, 35);
215118318Sdwmalone#undef DO
216118318Sdwmalone#undef DO2
217118318Sdwmalone}
218118318Sdwmalone
219118318Sdwmaloneint
220118318Sdwmaloneiniticmp6(void)
221118318Sdwmalone{
222118318Sdwmalone	size_t len;
223118318Sdwmalone	int name[4];
224118318Sdwmalone
225118318Sdwmalone	name[0] = CTL_NET;
226118318Sdwmalone	name[1] = PF_INET6;
227118318Sdwmalone	name[2] = IPPROTO_ICMPV6;
228118318Sdwmalone	name[3] = ICMPV6CTL_STATS;
229118318Sdwmalone
230118318Sdwmalone	len = 0;
231118318Sdwmalone	if (sysctl(name, 4, 0, &len, 0, 0) < 0) {
232118318Sdwmalone		error("sysctl getting icmp6stat size failed");
233118318Sdwmalone		return 0;
234118318Sdwmalone	}
235118318Sdwmalone	if (len > sizeof icmp6stat) {
236118318Sdwmalone		error("icmp6stat structure has grown--recompile systat!");
237118318Sdwmalone		return 0;
238118318Sdwmalone	}
239118318Sdwmalone	if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
240118318Sdwmalone		error("sysctl getting icmp6stat size failed");
241118318Sdwmalone		return 0;
242118318Sdwmalone	}
243118318Sdwmalone	oldstat = initstat;
244118318Sdwmalone	return 1;
245118318Sdwmalone}
246118318Sdwmalone
247118318Sdwmalonevoid
248118318Sdwmalonereseticmp6(void)
249118318Sdwmalone{
250118318Sdwmalone	size_t len;
251118318Sdwmalone	int name[4];
252118318Sdwmalone
253118318Sdwmalone	name[0] = CTL_NET;
254118318Sdwmalone	name[1] = PF_INET6;
255118318Sdwmalone	name[2] = IPPROTO_ICMPV6;
256118318Sdwmalone	name[3] = ICMPV6CTL_STATS;
257118318Sdwmalone
258118318Sdwmalone	len = sizeof initstat;
259118318Sdwmalone	if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
260118318Sdwmalone		error("sysctl getting icmp6stat size failed");
261118318Sdwmalone	}
262118318Sdwmalone	oldstat = initstat;
263118318Sdwmalone}
264118318Sdwmalone
265118318Sdwmalonevoid
266118318Sdwmalonefetchicmp6(void)
267118318Sdwmalone{
268118318Sdwmalone	int name[4];
269118318Sdwmalone	size_t len;
270118318Sdwmalone
271118318Sdwmalone	oldstat = icmp6stat;
272118318Sdwmalone	name[0] = CTL_NET;
273118318Sdwmalone	name[1] = PF_INET6;
274118318Sdwmalone	name[2] = IPPROTO_ICMPV6;
275118318Sdwmalone	name[3] = ICMPV6CTL_STATS;
276118318Sdwmalone	len = sizeof icmp6stat;
277118318Sdwmalone
278118318Sdwmalone	if (sysctl(name, 4, &icmp6stat, &len, 0, 0) < 0)
279118318Sdwmalone		return;
280118318Sdwmalone}
281118318Sdwmalone
282118318Sdwmalone#endif
283