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 * 4. Neither the name of the University nor the names of its contributors
14118318Sdwmalone *    may be used to endorse or promote products derived from this software
15118318Sdwmalone *    without specific prior written permission.
16118318Sdwmalone *
17118318Sdwmalone * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18118318Sdwmalone * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19118318Sdwmalone * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20118318Sdwmalone * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21118318Sdwmalone * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22118318Sdwmalone * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23118318Sdwmalone * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24118318Sdwmalone * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25118318Sdwmalone * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26118318Sdwmalone * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27118318Sdwmalone * SUCH DAMAGE.
28118318Sdwmalone */
29118318Sdwmalone
30118318Sdwmalone#include <sys/cdefs.h>
31118318Sdwmalone
32118318Sdwmalone__FBSDID("$FreeBSD$");
33118318Sdwmalone
34118318Sdwmalone#ifdef lint
35118318Sdwmalonestatic char sccsid[] = "@(#)mbufs.c	8.1 (Berkeley) 6/6/93";
36118318Sdwmalone#endif
37118318Sdwmalone
38118318Sdwmalone/* From:
39118318Sdwmalone	"Id: mbufs.c,v 1.5 1997/02/24 20:59:03 wollman Exp"
40118318Sdwmalone*/
41118318Sdwmalone
42118318Sdwmalone#ifdef INET6
43118318Sdwmalone#include <sys/param.h>
44118318Sdwmalone#include <sys/types.h>
45118318Sdwmalone#include <sys/socket.h>
46118318Sdwmalone#include <sys/sysctl.h>
47118318Sdwmalone
48118318Sdwmalone#include <netinet/in.h>
49118318Sdwmalone#include <netinet/icmp6.h>
50118318Sdwmalone
51118318Sdwmalone#include <stdlib.h>
52118318Sdwmalone#include <string.h>
53118318Sdwmalone#include <paths.h>
54118318Sdwmalone#include "systat.h"
55118318Sdwmalone#include "extern.h"
56118318Sdwmalone#include "mode.h"
57118318Sdwmalone
58118318Sdwmalonestatic struct icmp6stat icmp6stat, initstat, oldstat;
59118318Sdwmalone
60118318Sdwmalone/*-
61118318Sdwmalone--0         1         2         3         4         5         6         7
62118318Sdwmalone--0123456789012345678901234567890123456789012345678901234567890123456789012345
63158160Sbde00          ICMPv6 Input                       ICMPv6 Output
64158160Sbde01999999999 total messages           999999999 total messages
65158160Sbde02999999999 with bad code            999999999 errors generated
66158160Sbde03999999999 with bad length          999999999 suppressed - original too short
67158160Sbde04999999999 with bad checksum        999999999 suppressed - original was ICMP
68158160Sbde05999999999 with insufficient data   999999999 responses sent
69158160Sbde06
70158160Sbde07          Input Histogram                    Output Histogram
71158160Sbde08999999999 echo response            999999999 echo response
72158160Sbde09999999999 echo request             999999999 echo request
73158160Sbde10999999999 destination unreachable  999999999 destination unreachable
74158160Sbde11999999999 redirect                 999999999 redirect
75158160Sbde12999999999 time-to-live exceeded    999999999 time-to-line exceeded
76158160Sbde13999999999 parameter problem        999999999 parameter problem
77158160Sbde14999999999 neighbor solicitation    999999999 neighbor solicitation
78228992Suqs15999999999 neighbor advertisement   999999999 neighbor advertisement
79158160Sbde16999999999 router advertisement     999999999 router solicitation
80158160Sbde17
81118318Sdwmalone18
82118318Sdwmalone--0123456789012345678901234567890123456789012345678901234567890123456789012345
83118318Sdwmalone--0         1         2         3         4         5         6         7
84118318Sdwmalone*/
85118318Sdwmalone
86118318SdwmaloneWINDOW *
87118318Sdwmaloneopenicmp6(void)
88118318Sdwmalone{
89158160Sbde	return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0));
90118318Sdwmalone}
91118318Sdwmalone
92118318Sdwmalonevoid
93175387Sdelphijcloseicmp6(WINDOW *w)
94118318Sdwmalone{
95118318Sdwmalone	if (w == NULL)
96118318Sdwmalone		return;
97118318Sdwmalone	wclear(w);
98118318Sdwmalone	wrefresh(w);
99118318Sdwmalone	delwin(w);
100118318Sdwmalone}
101118318Sdwmalone
102118318Sdwmalonevoid
103118318Sdwmalonelabelicmp6(void)
104118318Sdwmalone{
105118318Sdwmalone	wmove(wnd, 0, 0); wclrtoeol(wnd);
106118318Sdwmalone#define L(row, str) mvwprintw(wnd, row, 10, str)
107118318Sdwmalone#define R(row, str) mvwprintw(wnd, row, 45, str);
108158160Sbde	L(0, "ICMPv6 Input");		R(0, "ICMPv6 Output");
109158160Sbde	L(1, "total messages");		R(1, "total messages");
110158160Sbde	L(2, "with bad code");		R(2, "errors generated");
111158160Sbde	L(3, "with bad length");	R(3, "suppressed - original too short");
112158160Sbde	L(4, "with bad checksum");	R(4, "suppressed - original was ICMP");
113158160Sbde	L(5, "with insufficient data");	R(5, "responses sent");
114118318Sdwmalone
115158160Sbde	L(7, "Input Histogram");	R(7, "Output Histogram");
116118318Sdwmalone#define B(row, str) L(row, str); R(row, str)
117158160Sbde	B(8, "echo response");
118158160Sbde	B(9, "echo request");
119158160Sbde	B(10, "destination unreachable");
120158160Sbde	B(11, "redirect");
121158160Sbde	B(12, "time-to-live exceeded");
122158160Sbde	B(13, "parameter problem");
123158160Sbde	B(14, "neighbor solicitation");
124228992Suqs	B(15, "neighbor advertisement");
125158160Sbde	L(16, "router advertisement");	R(16, "router solicitation");
126118318Sdwmalone#undef L
127118318Sdwmalone#undef R
128118318Sdwmalone#undef B
129118318Sdwmalone}
130118318Sdwmalone
131118318Sdwmalonestatic void
132118318Sdwmalonedomode(struct icmp6stat *ret)
133118318Sdwmalone{
134118318Sdwmalone	const struct icmp6stat *sub;
135118318Sdwmalone	int i, divisor = 1;
136118318Sdwmalone
137118318Sdwmalone	switch(currentmode) {
138118318Sdwmalone	case display_RATE:
139118318Sdwmalone		sub = &oldstat;
140240605Smelifaro		divisor = (delay > 1000000) ? delay / 1000000 : 1;
141118318Sdwmalone		break;
142118318Sdwmalone	case display_DELTA:
143118318Sdwmalone		sub = &oldstat;
144118318Sdwmalone		break;
145118318Sdwmalone	case display_SINCE:
146118318Sdwmalone		sub = &initstat;
147118318Sdwmalone		break;
148118318Sdwmalone	default:
149118318Sdwmalone		*ret = icmp6stat;
150118318Sdwmalone		return;
151118318Sdwmalone	}
152118318Sdwmalone#define DO(stat) ret->stat = (icmp6stat.stat - sub->stat) / divisor
153118318Sdwmalone	DO(icp6s_error);
154118318Sdwmalone	DO(icp6s_tooshort);
155118318Sdwmalone	DO(icp6s_canterror);
156118318Sdwmalone	for (i = 0; i <= ICMP6_MAXTYPE; i++) {
157118318Sdwmalone		DO(icp6s_outhist[i]);
158118318Sdwmalone	}
159118318Sdwmalone	DO(icp6s_badcode);
160118318Sdwmalone	DO(icp6s_tooshort);
161118318Sdwmalone	DO(icp6s_checksum);
162118318Sdwmalone	DO(icp6s_badlen);
163118318Sdwmalone	DO(icp6s_reflect);
164118318Sdwmalone	for (i = 0; i <= ICMP6_MAXTYPE; i++) {
165118318Sdwmalone		DO(icp6s_inhist[i]);
166118318Sdwmalone	}
167118318Sdwmalone#undef DO
168118318Sdwmalone}
169158161Sbde
170118318Sdwmalonevoid
171118318Sdwmaloneshowicmp6(void)
172118318Sdwmalone{
173118318Sdwmalone	struct icmp6stat stats;
174118318Sdwmalone	u_long totalin, totalout;
175118318Sdwmalone	int i;
176118318Sdwmalone
177118318Sdwmalone	memset(&stats, 0, sizeof stats);
178118318Sdwmalone	domode(&stats);
179118318Sdwmalone	for (i = totalin = totalout = 0; i <= ICMP6_MAXTYPE; i++) {
180118318Sdwmalone		totalin += stats.icp6s_inhist[i];
181118318Sdwmalone		totalout += stats.icp6s_outhist[i];
182118318Sdwmalone	}
183158161Sbde	totalin += stats.icp6s_badcode + stats.icp6s_badlen +
184118318Sdwmalone		stats.icp6s_checksum + stats.icp6s_tooshort;
185158160Sbde	mvwprintw(wnd, 1, 0, "%9lu", totalin);
186158160Sbde	mvwprintw(wnd, 1, 35, "%9lu", totalout);
187118318Sdwmalone
188118318Sdwmalone#define DO(stat, row, col) \
189118318Sdwmalone	mvwprintw(wnd, row, col, "%9lu", stats.stat)
190118318Sdwmalone
191158160Sbde	DO(icp6s_badcode, 2, 0);
192158160Sbde	DO(icp6s_badlen, 3, 0);
193158160Sbde	DO(icp6s_checksum, 4, 0);
194158160Sbde	DO(icp6s_tooshort, 5, 0);
195158160Sbde	DO(icp6s_error, 2, 35);
196158160Sbde	DO(icp6s_tooshort, 3, 35);
197158160Sbde	DO(icp6s_canterror, 4, 35);
198158160Sbde	DO(icp6s_reflect, 5, 35);
199118318Sdwmalone#define DO2(type, row) DO(icp6s_inhist[type], row, 0); DO(icp6s_outhist[type], \
200118318Sdwmalone							 row, 35)
201158160Sbde	DO2(ICMP6_ECHO_REPLY, 8);
202158160Sbde	DO2(ICMP6_ECHO_REQUEST, 9);
203158160Sbde	DO2(ICMP6_DST_UNREACH, 10);
204158160Sbde	DO2(ND_REDIRECT, 11);
205158160Sbde	DO2(ICMP6_TIME_EXCEEDED, 12);
206158160Sbde	DO2(ICMP6_PARAM_PROB, 13);
207158160Sbde	DO2(ND_NEIGHBOR_SOLICIT, 14);
208158160Sbde	DO2(ND_NEIGHBOR_ADVERT, 15);
209158160Sbde	DO(icp6s_inhist[ND_ROUTER_SOLICIT], 16, 0);
210158160Sbde	DO(icp6s_outhist[ND_ROUTER_ADVERT], 16, 35);
211118318Sdwmalone#undef DO
212118318Sdwmalone#undef DO2
213118318Sdwmalone}
214118318Sdwmalone
215118318Sdwmaloneint
216118318Sdwmaloneiniticmp6(void)
217118318Sdwmalone{
218118318Sdwmalone	size_t len;
219118318Sdwmalone	int name[4];
220118318Sdwmalone
221118318Sdwmalone	name[0] = CTL_NET;
222118318Sdwmalone	name[1] = PF_INET6;
223118318Sdwmalone	name[2] = IPPROTO_ICMPV6;
224118318Sdwmalone	name[3] = ICMPV6CTL_STATS;
225118318Sdwmalone
226118318Sdwmalone	len = 0;
227118318Sdwmalone	if (sysctl(name, 4, 0, &len, 0, 0) < 0) {
228118318Sdwmalone		error("sysctl getting icmp6stat size failed");
229118318Sdwmalone		return 0;
230118318Sdwmalone	}
231118318Sdwmalone	if (len > sizeof icmp6stat) {
232118318Sdwmalone		error("icmp6stat structure has grown--recompile systat!");
233118318Sdwmalone		return 0;
234118318Sdwmalone	}
235118318Sdwmalone	if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
236118318Sdwmalone		error("sysctl getting icmp6stat size failed");
237118318Sdwmalone		return 0;
238118318Sdwmalone	}
239118318Sdwmalone	oldstat = initstat;
240118318Sdwmalone	return 1;
241118318Sdwmalone}
242118318Sdwmalone
243118318Sdwmalonevoid
244118318Sdwmalonereseticmp6(void)
245118318Sdwmalone{
246118318Sdwmalone	size_t len;
247118318Sdwmalone	int name[4];
248118318Sdwmalone
249118318Sdwmalone	name[0] = CTL_NET;
250118318Sdwmalone	name[1] = PF_INET6;
251118318Sdwmalone	name[2] = IPPROTO_ICMPV6;
252118318Sdwmalone	name[3] = ICMPV6CTL_STATS;
253118318Sdwmalone
254118318Sdwmalone	len = sizeof initstat;
255118318Sdwmalone	if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
256118318Sdwmalone		error("sysctl getting icmp6stat size failed");
257118318Sdwmalone	}
258118318Sdwmalone	oldstat = initstat;
259118318Sdwmalone}
260118318Sdwmalone
261118318Sdwmalonevoid
262118318Sdwmalonefetchicmp6(void)
263118318Sdwmalone{
264118318Sdwmalone	int name[4];
265118318Sdwmalone	size_t len;
266118318Sdwmalone
267118318Sdwmalone	oldstat = icmp6stat;
268118318Sdwmalone	name[0] = CTL_NET;
269118318Sdwmalone	name[1] = PF_INET6;
270118318Sdwmalone	name[2] = IPPROTO_ICMPV6;
271118318Sdwmalone	name[3] = ICMPV6CTL_STATS;
272118318Sdwmalone	len = sizeof icmp6stat;
273118318Sdwmalone
274118318Sdwmalone	if (sysctl(name, 4, &icmp6stat, &len, 0, 0) < 0)
275118318Sdwmalone		return;
276118318Sdwmalone}
277118318Sdwmalone
278118318Sdwmalone#endif
279