xref: /dragonfly/usr.bin/systat/icmp6.c (revision 0ca0cd25)
10adc6530SHasso Tepper /*-
20adc6530SHasso Tepper  * Copyright (c) 1980, 1992, 1993
30adc6530SHasso Tepper  *	The Regents of the University of California.  All rights reserved.
40adc6530SHasso Tepper  *
50adc6530SHasso Tepper  * Redistribution and use in source and binary forms, with or without
60adc6530SHasso Tepper  * modification, are permitted provided that the following conditions
70adc6530SHasso Tepper  * are met:
80adc6530SHasso Tepper  * 1. Redistributions of source code must retain the above copyright
90adc6530SHasso Tepper  *    notice, this list of conditions and the following disclaimer.
100adc6530SHasso Tepper  * 2. Redistributions in binary form must reproduce the above copyright
110adc6530SHasso Tepper  *    notice, this list of conditions and the following disclaimer in the
120adc6530SHasso Tepper  *    documentation and/or other materials provided with the distribution.
130adc6530SHasso Tepper  * 3. All advertising materials mentioning features or use of this software
140adc6530SHasso Tepper  *    must display the following acknowledgement:
150adc6530SHasso Tepper  *	This product includes software developed by the University of
160adc6530SHasso Tepper  *	California, Berkeley and its contributors.
170adc6530SHasso Tepper  * 4. Neither the name of the University nor the names of its contributors
180adc6530SHasso Tepper  *    may be used to endorse or promote products derived from this software
190adc6530SHasso Tepper  *    without specific prior written permission.
200adc6530SHasso Tepper  *
210adc6530SHasso Tepper  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
220adc6530SHasso Tepper  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
230adc6530SHasso Tepper  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
240adc6530SHasso Tepper  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
250adc6530SHasso Tepper  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
260adc6530SHasso Tepper  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
270adc6530SHasso Tepper  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
280adc6530SHasso Tepper  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
290adc6530SHasso Tepper  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
300adc6530SHasso Tepper  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
310adc6530SHasso Tepper  * SUCH DAMAGE.
320adc6530SHasso Tepper  *
330adc6530SHasso Tepper  * @(#)mbufs.c     8.1 (Berkeley) 6/6/93
340adc6530SHasso Tepper  * $FreeBSD: src/usr.bin/systat/icmp6.c,v 1.3 2006/04/30 04:47:23 bde Exp $
35*0ca0cd25SSascha Wildner  * $DragonFly: src/usr.bin/systat/icmp6.c,v 1.2 2008/04/20 13:44:26 swildner Exp $
360adc6530SHasso Tepper  */
370adc6530SHasso Tepper 
380adc6530SHasso Tepper #include <sys/cdefs.h>
390adc6530SHasso Tepper 
400adc6530SHasso Tepper #ifdef INET6
410adc6530SHasso Tepper #include <sys/param.h>
420adc6530SHasso Tepper #include <sys/types.h>
430adc6530SHasso Tepper #include <sys/socket.h>
440adc6530SHasso Tepper #include <sys/sysctl.h>
450adc6530SHasso Tepper 
460adc6530SHasso Tepper #include <netinet/in.h>
470adc6530SHasso Tepper #include <netinet/icmp6.h>
480adc6530SHasso Tepper 
490adc6530SHasso Tepper #include <stdlib.h>
500adc6530SHasso Tepper #include <string.h>
510adc6530SHasso Tepper #include <paths.h>
520adc6530SHasso Tepper #include "systat.h"
530adc6530SHasso Tepper #include "extern.h"
540adc6530SHasso Tepper #include "mode.h"
550adc6530SHasso Tepper 
560adc6530SHasso Tepper static struct icmp6stat icmp6stat, initstat, oldstat;
570adc6530SHasso Tepper 
580adc6530SHasso Tepper /*-
590adc6530SHasso Tepper --0         1         2         3         4         5         6         7
600adc6530SHasso Tepper --0123456789012345678901234567890123456789012345678901234567890123456789012345
610adc6530SHasso Tepper 00          ICMPv6 Input                       ICMPv6 Output
620adc6530SHasso Tepper 01999999999 total messages           999999999 total messages
630adc6530SHasso Tepper 02999999999 with bad code            999999999 errors generated
640adc6530SHasso Tepper 03999999999 with bad length          999999999 suppressed - original too short
650adc6530SHasso Tepper 04999999999 with bad checksum        999999999 suppressed - original was ICMP
660adc6530SHasso Tepper 05999999999 with insufficient data   999999999 responses sent
670adc6530SHasso Tepper 06
680adc6530SHasso Tepper 07          Input Histogram                    Output Histogram
690adc6530SHasso Tepper 08999999999 echo response            999999999 echo response
700adc6530SHasso Tepper 09999999999 echo request             999999999 echo request
710adc6530SHasso Tepper 10999999999 destination unreachable  999999999 destination unreachable
720adc6530SHasso Tepper 11999999999 redirect                 999999999 redirect
730adc6530SHasso Tepper 12999999999 time-to-live exceeded    999999999 time-to-line exceeded
740adc6530SHasso Tepper 13999999999 parameter problem        999999999 parameter problem
750adc6530SHasso Tepper 14999999999 neighbor solicitation    999999999 neighbor solicitation
760adc6530SHasso Tepper 15999999999 neighbor advertisment    999999999 neighbor advertisment
770adc6530SHasso Tepper 16999999999 router advertisement     999999999 router solicitation
780adc6530SHasso Tepper 17
790adc6530SHasso Tepper 18
800adc6530SHasso Tepper --0123456789012345678901234567890123456789012345678901234567890123456789012345
810adc6530SHasso Tepper --0         1         2         3         4         5         6         7
820adc6530SHasso Tepper */
830adc6530SHasso Tepper 
840adc6530SHasso Tepper WINDOW *
850adc6530SHasso Tepper openicmp6(void)
860adc6530SHasso Tepper {
870adc6530SHasso Tepper 	return (subwin(stdscr, LINES-4-1, 0, 4, 0));
880adc6530SHasso Tepper }
890adc6530SHasso Tepper 
900adc6530SHasso Tepper void
910adc6530SHasso Tepper closeicmp6(w)
920adc6530SHasso Tepper 	WINDOW *w;
930adc6530SHasso Tepper {
940adc6530SHasso Tepper 	if (w == NULL)
950adc6530SHasso Tepper 		return;
960adc6530SHasso Tepper 	wclear(w);
970adc6530SHasso Tepper 	wrefresh(w);
980adc6530SHasso Tepper 	delwin(w);
990adc6530SHasso Tepper }
1000adc6530SHasso Tepper 
1010adc6530SHasso Tepper void
1020adc6530SHasso Tepper labelicmp6(void)
1030adc6530SHasso Tepper {
1040adc6530SHasso Tepper 	wmove(wnd, 0, 0); wclrtoeol(wnd);
1050adc6530SHasso Tepper #define L(row, str) mvwprintw(wnd, row, 10, str)
1060adc6530SHasso Tepper #define R(row, str) mvwprintw(wnd, row, 45, str);
1070adc6530SHasso Tepper 	L(1, "ICMPv6 Input");		R(1, "ICMPv6 Output");
1080adc6530SHasso Tepper 	L(2, "total messages");		R(2, "total messages");
1090adc6530SHasso Tepper 	L(3, "with bad code");		R(3, "errors generated");
1100adc6530SHasso Tepper 	L(4, "with bad length");	R(4, "suppressed - original too short");
1110adc6530SHasso Tepper 	L(5, "with bad checksum");	R(5, "suppressed - original was ICMP");
1120adc6530SHasso Tepper 	L(6, "with insufficient data");	R(6, "responses sent");
1130adc6530SHasso Tepper 
1140adc6530SHasso Tepper 	L(8, "Input Histogram");	R(8, "Output Histogram");
1150adc6530SHasso Tepper #define B(row, str) L(row, str); R(row, str)
1160adc6530SHasso Tepper 	B(9, "echo response");
1170adc6530SHasso Tepper 	B(10, "echo request");
1180adc6530SHasso Tepper 	B(11, "destination unreachable");
1190adc6530SHasso Tepper 	B(12, "redirect");
1200adc6530SHasso Tepper 	B(13, "time-to-live exceeded");
1210adc6530SHasso Tepper 	B(14, "parameter problem");
1220adc6530SHasso Tepper 	B(15, "neighbor solicitation");
123*0ca0cd25SSascha Wildner 	B(16, "neighbor advertisement");
1240adc6530SHasso Tepper 	L(17, "router advertisement");	R(17, "router solicitation");
1250adc6530SHasso Tepper #undef L
1260adc6530SHasso Tepper #undef R
1270adc6530SHasso Tepper #undef B
1280adc6530SHasso Tepper }
1290adc6530SHasso Tepper 
1300adc6530SHasso Tepper static void
1310adc6530SHasso Tepper domode(struct icmp6stat *ret)
1320adc6530SHasso Tepper {
1330adc6530SHasso Tepper 	const struct icmp6stat *sub;
1340adc6530SHasso Tepper 	int i, divisor = 1;
1350adc6530SHasso Tepper 
1360adc6530SHasso Tepper 	switch(currentmode) {
1370adc6530SHasso Tepper 	case display_RATE:
1380adc6530SHasso Tepper 		sub = &oldstat;
1390adc6530SHasso Tepper 		divisor = naptime;
1400adc6530SHasso Tepper 		break;
1410adc6530SHasso Tepper 	case display_DELTA:
1420adc6530SHasso Tepper 		sub = &oldstat;
1430adc6530SHasso Tepper 		break;
1440adc6530SHasso Tepper 	case display_SINCE:
1450adc6530SHasso Tepper 		sub = &initstat;
1460adc6530SHasso Tepper 		break;
1470adc6530SHasso Tepper 	default:
1480adc6530SHasso Tepper 		*ret = icmp6stat;
1490adc6530SHasso Tepper 		return;
1500adc6530SHasso Tepper 	}
1510adc6530SHasso Tepper #define DO(stat) ret->stat = (icmp6stat.stat - sub->stat) / divisor
1520adc6530SHasso Tepper 	DO(icp6s_error);
1530adc6530SHasso Tepper 	DO(icp6s_tooshort);
1540adc6530SHasso Tepper 	DO(icp6s_canterror);
1550adc6530SHasso Tepper 	for (i = 0; i <= ICMP6_MAXTYPE; i++) {
1560adc6530SHasso Tepper 		DO(icp6s_outhist[i]);
1570adc6530SHasso Tepper 	}
1580adc6530SHasso Tepper 	DO(icp6s_badcode);
1590adc6530SHasso Tepper 	DO(icp6s_tooshort);
1600adc6530SHasso Tepper 	DO(icp6s_checksum);
1610adc6530SHasso Tepper 	DO(icp6s_badlen);
1620adc6530SHasso Tepper 	DO(icp6s_reflect);
1630adc6530SHasso Tepper 	for (i = 0; i <= ICMP6_MAXTYPE; i++) {
1640adc6530SHasso Tepper 		DO(icp6s_inhist[i]);
1650adc6530SHasso Tepper 	}
1660adc6530SHasso Tepper #undef DO
1670adc6530SHasso Tepper }
1680adc6530SHasso Tepper 
1690adc6530SHasso Tepper void
1700adc6530SHasso Tepper showicmp6(void)
1710adc6530SHasso Tepper {
1720adc6530SHasso Tepper 	struct icmp6stat stats;
1730adc6530SHasso Tepper 	u_long totalin, totalout;
1740adc6530SHasso Tepper 	int i;
1750adc6530SHasso Tepper 
1760adc6530SHasso Tepper 	memset(&stats, 0, sizeof stats);
1770adc6530SHasso Tepper 	domode(&stats);
1780adc6530SHasso Tepper 	for (i = totalin = totalout = 0; i <= ICMP6_MAXTYPE; i++) {
1790adc6530SHasso Tepper 		totalin += stats.icp6s_inhist[i];
1800adc6530SHasso Tepper 		totalout += stats.icp6s_outhist[i];
1810adc6530SHasso Tepper 	}
1820adc6530SHasso Tepper 	totalin += stats.icp6s_badcode + stats.icp6s_badlen +
1830adc6530SHasso Tepper 		stats.icp6s_checksum + stats.icp6s_tooshort;
1840adc6530SHasso Tepper 	mvwprintw(wnd, 2, 0, "%9lu", totalin);
1850adc6530SHasso Tepper 	mvwprintw(wnd, 2, 35, "%9lu", totalout);
1860adc6530SHasso Tepper 
1870adc6530SHasso Tepper #define DO(stat, row, col) \
1880adc6530SHasso Tepper 	mvwprintw(wnd, row, col, "%9lu", stats.stat)
1890adc6530SHasso Tepper 
1900adc6530SHasso Tepper 	DO(icp6s_badcode, 3, 0);
1910adc6530SHasso Tepper 	DO(icp6s_badlen, 4, 0);
1920adc6530SHasso Tepper 	DO(icp6s_checksum, 5, 0);
1930adc6530SHasso Tepper 	DO(icp6s_tooshort, 6, 0);
1940adc6530SHasso Tepper 	DO(icp6s_error, 3, 35);
1950adc6530SHasso Tepper 	DO(icp6s_tooshort, 4, 35);
1960adc6530SHasso Tepper 	DO(icp6s_canterror, 5, 35);
1970adc6530SHasso Tepper 	DO(icp6s_reflect, 6, 35);
1980adc6530SHasso Tepper #define DO2(type, row) DO(icp6s_inhist[type], row, 0); DO(icp6s_outhist[type], \
1990adc6530SHasso Tepper 							 row, 35)
2000adc6530SHasso Tepper 	DO2(ICMP6_ECHO_REPLY, 9);
2010adc6530SHasso Tepper 	DO2(ICMP6_ECHO_REQUEST, 10);
2020adc6530SHasso Tepper 	DO2(ICMP6_DST_UNREACH, 11);
2030adc6530SHasso Tepper 	DO2(ND_REDIRECT, 12);
2040adc6530SHasso Tepper 	DO2(ICMP6_TIME_EXCEEDED, 13);
2050adc6530SHasso Tepper 	DO2(ICMP6_PARAM_PROB, 14);
2060adc6530SHasso Tepper 	DO2(ND_NEIGHBOR_SOLICIT, 15);
2070adc6530SHasso Tepper 	DO2(ND_NEIGHBOR_ADVERT, 16);
2080adc6530SHasso Tepper 	DO(icp6s_inhist[ND_ROUTER_SOLICIT], 17, 0);
2090adc6530SHasso Tepper 	DO(icp6s_outhist[ND_ROUTER_ADVERT], 17, 35);
2100adc6530SHasso Tepper #undef DO
2110adc6530SHasso Tepper #undef DO2
2120adc6530SHasso Tepper }
2130adc6530SHasso Tepper 
2140adc6530SHasso Tepper int
2150adc6530SHasso Tepper initicmp6(void)
2160adc6530SHasso Tepper {
2170adc6530SHasso Tepper 	size_t len;
2180adc6530SHasso Tepper 	int name[4];
2190adc6530SHasso Tepper 
2200adc6530SHasso Tepper 	name[0] = CTL_NET;
2210adc6530SHasso Tepper 	name[1] = PF_INET6;
2220adc6530SHasso Tepper 	name[2] = IPPROTO_ICMPV6;
2230adc6530SHasso Tepper 	name[3] = ICMPV6CTL_STATS;
2240adc6530SHasso Tepper 
2250adc6530SHasso Tepper 	len = 0;
2260adc6530SHasso Tepper 	if (sysctl(name, 4, 0, &len, 0, 0) < 0) {
2270adc6530SHasso Tepper 		error("sysctl getting icmp6stat size failed");
2280adc6530SHasso Tepper 		return 0;
2290adc6530SHasso Tepper 	}
2300adc6530SHasso Tepper 	if (len > sizeof icmp6stat) {
2310adc6530SHasso Tepper 		error("icmp6stat structure has grown--recompile systat!");
2320adc6530SHasso Tepper 		return 0;
2330adc6530SHasso Tepper 	}
2340adc6530SHasso Tepper 	if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
2350adc6530SHasso Tepper 		error("sysctl getting icmp6stat size failed");
2360adc6530SHasso Tepper 		return 0;
2370adc6530SHasso Tepper 	}
2380adc6530SHasso Tepper 	oldstat = initstat;
2390adc6530SHasso Tepper 	return 1;
2400adc6530SHasso Tepper }
2410adc6530SHasso Tepper 
2420adc6530SHasso Tepper void
2430adc6530SHasso Tepper reseticmp6(void)
2440adc6530SHasso Tepper {
2450adc6530SHasso Tepper 	size_t len;
2460adc6530SHasso Tepper 	int name[4];
2470adc6530SHasso Tepper 
2480adc6530SHasso Tepper 	name[0] = CTL_NET;
2490adc6530SHasso Tepper 	name[1] = PF_INET6;
2500adc6530SHasso Tepper 	name[2] = IPPROTO_ICMPV6;
2510adc6530SHasso Tepper 	name[3] = ICMPV6CTL_STATS;
2520adc6530SHasso Tepper 
2530adc6530SHasso Tepper 	len = sizeof initstat;
2540adc6530SHasso Tepper 	if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
2550adc6530SHasso Tepper 		error("sysctl getting icmp6stat size failed");
2560adc6530SHasso Tepper 	}
2570adc6530SHasso Tepper 	oldstat = initstat;
2580adc6530SHasso Tepper }
2590adc6530SHasso Tepper 
2600adc6530SHasso Tepper void
2610adc6530SHasso Tepper fetchicmp6(void)
2620adc6530SHasso Tepper {
2630adc6530SHasso Tepper 	int name[4];
2640adc6530SHasso Tepper 	size_t len;
2650adc6530SHasso Tepper 
2660adc6530SHasso Tepper 	oldstat = icmp6stat;
2670adc6530SHasso Tepper 	name[0] = CTL_NET;
2680adc6530SHasso Tepper 	name[1] = PF_INET6;
2690adc6530SHasso Tepper 	name[2] = IPPROTO_ICMPV6;
2700adc6530SHasso Tepper 	name[3] = ICMPV6CTL_STATS;
2710adc6530SHasso Tepper 	len = sizeof icmp6stat;
2720adc6530SHasso Tepper 
2730adc6530SHasso Tepper 	if (sysctl(name, 4, &icmp6stat, &len, 0, 0) < 0)
2740adc6530SHasso Tepper 		return;
2750adc6530SHasso Tepper }
2760adc6530SHasso Tepper 
2770adc6530SHasso Tepper #endif
278