icmp6.c revision 118318
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 118318 2003-08-01 20:28:20Z dwmalone $");
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
67118318Sdwmalone01          ICMPv6 Input                       ICMPv6 Output
68118318Sdwmalone02999999999 total messages           999999999 total messages
69118318Sdwmalone03999999999 with bad code            999999999 errors generated
70118318Sdwmalone04999999999 with bad length          999999999 suppressed - original too short
71118318Sdwmalone05999999999 with bad checksum        999999999 suppressed - original was ICMP
72118318Sdwmalone06999999999 with insufficient data   999999999 responses sent
73118318Sdwmalone07
74118318Sdwmalone08          Input Histogram                    Output Histogram
75118318Sdwmalone09999999999 echo response            999999999 echo response
76118318Sdwmalone10999999999 echo request             999999999 echo request
77118318Sdwmalone11999999999 destination unreachable  999999999 destination unreachable
78118318Sdwmalone12999999999 redirect                 999999999 redirect
79118318Sdwmalone13999999999 time-to-live exceeded    999999999 time-to-line exceeded
80118318Sdwmalone14999999999 parameter problem        999999999 parameter problem
81118318Sdwmalone15999999999 neighbor solicitation    999999999 neighbor solicitation
82118318Sdwmalone16999999999 neighbor advertisment    999999999 neighbor advertisment
83118318Sdwmalone17999999999 router advertisement     999999999 router solicitation
84118318Sdwmalone18
85118318Sdwmalone19
86118318Sdwmalone--0123456789012345678901234567890123456789012345678901234567890123456789012345
87118318Sdwmalone--0         1         2         3         4         5         6         7
88118318Sdwmalone*/
89118318Sdwmalone
90118318SdwmaloneWINDOW *
91118318Sdwmaloneopenicmp6(void)
92118318Sdwmalone{
93118318Sdwmalone	return (subwin(stdscr, LINES-5-1, 0, 5, 0));
94118318Sdwmalone}
95118318Sdwmalone
96118318Sdwmalonevoid
97118318Sdwmalonecloseicmp6(w)
98118318Sdwmalone	WINDOW *w;
99118318Sdwmalone{
100118318Sdwmalone	if (w == NULL)
101118318Sdwmalone		return;
102118318Sdwmalone	wclear(w);
103118318Sdwmalone	wrefresh(w);
104118318Sdwmalone	delwin(w);
105118318Sdwmalone}
106118318Sdwmalone
107118318Sdwmalonevoid
108118318Sdwmalonelabelicmp6(void)
109118318Sdwmalone{
110118318Sdwmalone	wmove(wnd, 0, 0); wclrtoeol(wnd);
111118318Sdwmalone#define L(row, str) mvwprintw(wnd, row, 10, str)
112118318Sdwmalone#define R(row, str) mvwprintw(wnd, row, 45, str);
113118318Sdwmalone	L(1, "ICMPv6 Input");		R(1, "ICMPv6 Output");
114118318Sdwmalone	L(2, "total messages");		R(2, "total messages");
115118318Sdwmalone	L(3, "with bad code");		R(3, "errors generated");
116118318Sdwmalone	L(4, "with bad length");	R(4, "suppressed - original too short");
117118318Sdwmalone	L(5, "with bad checksum");	R(5, "suppressed - original was ICMP");
118118318Sdwmalone	L(6, "with insufficient data");	R(6, "responses sent");
119118318Sdwmalone
120118318Sdwmalone	L(8, "Input Histogram");	R(8, "Output Histogram");
121118318Sdwmalone#define B(row, str) L(row, str); R(row, str)
122118318Sdwmalone	B(9, "echo response");
123118318Sdwmalone	B(10, "echo request");
124118318Sdwmalone	B(11, "destination unreachable");
125118318Sdwmalone	B(12, "redirect");
126118318Sdwmalone	B(13, "time-to-live exceeded");
127118318Sdwmalone	B(14, "parameter problem");
128118318Sdwmalone	B(15, "neighbor solicitation");
129118318Sdwmalone	B(16, "neighbor advertisment");
130118318Sdwmalone	L(17, "router advertisement");	R(17, "router solicitation");
131118318Sdwmalone#undef L
132118318Sdwmalone#undef R
133118318Sdwmalone#undef B
134118318Sdwmalone}
135118318Sdwmalone
136118318Sdwmalonestatic void
137118318Sdwmalonedomode(struct icmp6stat *ret)
138118318Sdwmalone{
139118318Sdwmalone	const struct icmp6stat *sub;
140118318Sdwmalone	int i, divisor = 1;
141118318Sdwmalone
142118318Sdwmalone	switch(currentmode) {
143118318Sdwmalone	case display_RATE:
144118318Sdwmalone		sub = &oldstat;
145118318Sdwmalone		divisor = naptime;
146118318Sdwmalone		break;
147118318Sdwmalone	case display_DELTA:
148118318Sdwmalone		sub = &oldstat;
149118318Sdwmalone		break;
150118318Sdwmalone	case display_SINCE:
151118318Sdwmalone		sub = &initstat;
152118318Sdwmalone		break;
153118318Sdwmalone	default:
154118318Sdwmalone		*ret = icmp6stat;
155118318Sdwmalone		return;
156118318Sdwmalone	}
157118318Sdwmalone#define DO(stat) ret->stat = (icmp6stat.stat - sub->stat) / divisor
158118318Sdwmalone	DO(icp6s_error);
159118318Sdwmalone	DO(icp6s_tooshort);
160118318Sdwmalone	DO(icp6s_canterror);
161118318Sdwmalone	for (i = 0; i <= ICMP6_MAXTYPE; i++) {
162118318Sdwmalone		DO(icp6s_outhist[i]);
163118318Sdwmalone	}
164118318Sdwmalone	DO(icp6s_badcode);
165118318Sdwmalone	DO(icp6s_tooshort);
166118318Sdwmalone	DO(icp6s_checksum);
167118318Sdwmalone	DO(icp6s_badlen);
168118318Sdwmalone	DO(icp6s_reflect);
169118318Sdwmalone	for (i = 0; i <= ICMP6_MAXTYPE; i++) {
170118318Sdwmalone		DO(icp6s_inhist[i]);
171118318Sdwmalone	}
172118318Sdwmalone#undef DO
173118318Sdwmalone}
174118318Sdwmalone
175118318Sdwmalonevoid
176118318Sdwmaloneshowicmp6(void)
177118318Sdwmalone{
178118318Sdwmalone	struct icmp6stat stats;
179118318Sdwmalone	u_long totalin, totalout;
180118318Sdwmalone	int i;
181118318Sdwmalone
182118318Sdwmalone	memset(&stats, 0, sizeof stats);
183118318Sdwmalone	domode(&stats);
184118318Sdwmalone	for (i = totalin = totalout = 0; i <= ICMP6_MAXTYPE; i++) {
185118318Sdwmalone		totalin += stats.icp6s_inhist[i];
186118318Sdwmalone		totalout += stats.icp6s_outhist[i];
187118318Sdwmalone	}
188118318Sdwmalone	totalin += stats.icp6s_badcode + stats.icp6s_badlen +
189118318Sdwmalone		stats.icp6s_checksum + stats.icp6s_tooshort;
190118318Sdwmalone	mvwprintw(wnd, 2, 0, "%9lu", totalin);
191118318Sdwmalone	mvwprintw(wnd, 2, 35, "%9lu", totalout);
192118318Sdwmalone
193118318Sdwmalone#define DO(stat, row, col) \
194118318Sdwmalone	mvwprintw(wnd, row, col, "%9lu", stats.stat)
195118318Sdwmalone
196118318Sdwmalone	DO(icp6s_badcode, 3, 0);
197118318Sdwmalone	DO(icp6s_badlen, 4, 0);
198118318Sdwmalone	DO(icp6s_checksum, 5, 0);
199118318Sdwmalone	DO(icp6s_tooshort, 6, 0);
200118318Sdwmalone	DO(icp6s_error, 3, 35);
201118318Sdwmalone	DO(icp6s_tooshort, 4, 35);
202118318Sdwmalone	DO(icp6s_canterror, 5, 35);
203118318Sdwmalone	DO(icp6s_reflect, 6, 35);
204118318Sdwmalone#define DO2(type, row) DO(icp6s_inhist[type], row, 0); DO(icp6s_outhist[type], \
205118318Sdwmalone							 row, 35)
206118318Sdwmalone	DO2(ICMP6_ECHO_REPLY, 9);
207118318Sdwmalone	DO2(ICMP6_ECHO_REQUEST, 10);
208118318Sdwmalone	DO2(ICMP6_DST_UNREACH, 11);
209118318Sdwmalone	DO2(ND_REDIRECT, 12);
210118318Sdwmalone	DO2(ICMP6_TIME_EXCEEDED, 13);
211118318Sdwmalone	DO2(ICMP6_PARAM_PROB, 14);
212118318Sdwmalone	DO2(ND_NEIGHBOR_SOLICIT, 15);
213118318Sdwmalone	DO2(ND_NEIGHBOR_ADVERT, 16);
214118318Sdwmalone	DO(icp6s_inhist[ND_ROUTER_SOLICIT], 17, 0);
215118318Sdwmalone	DO(icp6s_outhist[ND_ROUTER_ADVERT], 17, 35);
216118318Sdwmalone#undef DO
217118318Sdwmalone#undef DO2
218118318Sdwmalone}
219118318Sdwmalone
220118318Sdwmaloneint
221118318Sdwmaloneiniticmp6(void)
222118318Sdwmalone{
223118318Sdwmalone	size_t len;
224118318Sdwmalone	int name[4];
225118318Sdwmalone
226118318Sdwmalone	name[0] = CTL_NET;
227118318Sdwmalone	name[1] = PF_INET6;
228118318Sdwmalone	name[2] = IPPROTO_ICMPV6;
229118318Sdwmalone	name[3] = ICMPV6CTL_STATS;
230118318Sdwmalone
231118318Sdwmalone	len = 0;
232118318Sdwmalone	if (sysctl(name, 4, 0, &len, 0, 0) < 0) {
233118318Sdwmalone		error("sysctl getting icmp6stat size failed");
234118318Sdwmalone		return 0;
235118318Sdwmalone	}
236118318Sdwmalone	if (len > sizeof icmp6stat) {
237118318Sdwmalone		error("icmp6stat structure has grown--recompile systat!");
238118318Sdwmalone		return 0;
239118318Sdwmalone	}
240118318Sdwmalone	if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
241118318Sdwmalone		error("sysctl getting icmp6stat size failed");
242118318Sdwmalone		return 0;
243118318Sdwmalone	}
244118318Sdwmalone	oldstat = initstat;
245118318Sdwmalone	return 1;
246118318Sdwmalone}
247118318Sdwmalone
248118318Sdwmalonevoid
249118318Sdwmalonereseticmp6(void)
250118318Sdwmalone{
251118318Sdwmalone	size_t len;
252118318Sdwmalone	int name[4];
253118318Sdwmalone
254118318Sdwmalone	name[0] = CTL_NET;
255118318Sdwmalone	name[1] = PF_INET6;
256118318Sdwmalone	name[2] = IPPROTO_ICMPV6;
257118318Sdwmalone	name[3] = ICMPV6CTL_STATS;
258118318Sdwmalone
259118318Sdwmalone	len = sizeof initstat;
260118318Sdwmalone	if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
261118318Sdwmalone		error("sysctl getting icmp6stat size failed");
262118318Sdwmalone	}
263118318Sdwmalone	oldstat = initstat;
264118318Sdwmalone}
265118318Sdwmalone
266118318Sdwmalonevoid
267118318Sdwmalonefetchicmp6(void)
268118318Sdwmalone{
269118318Sdwmalone	int name[4];
270118318Sdwmalone	size_t len;
271118318Sdwmalone
272118318Sdwmalone	oldstat = icmp6stat;
273118318Sdwmalone	name[0] = CTL_NET;
274118318Sdwmalone	name[1] = PF_INET6;
275118318Sdwmalone	name[2] = IPPROTO_ICMPV6;
276118318Sdwmalone	name[3] = ICMPV6CTL_STATS;
277118318Sdwmalone	len = sizeof icmp6stat;
278118318Sdwmalone
279118318Sdwmalone	if (sysctl(name, 4, &icmp6stat, &len, 0, 0) < 0)
280118318Sdwmalone		return;
281118318Sdwmalone}
282118318Sdwmalone
283118318Sdwmalone#endif
284