xref: /dragonfly/usr.bin/systat/icmp6.c (revision 815943a9)
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*815943a9SSascha Wildner  * $DragonFly: src/usr.bin/systat/icmp6.c,v 1.3 2008/10/16 01:52:33 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
91*815943a9SSascha Wildner closeicmp6(WINDOW *w)
920adc6530SHasso Tepper {
930adc6530SHasso Tepper 	if (w == NULL)
940adc6530SHasso Tepper 		return;
950adc6530SHasso Tepper 	wclear(w);
960adc6530SHasso Tepper 	wrefresh(w);
970adc6530SHasso Tepper 	delwin(w);
980adc6530SHasso Tepper }
990adc6530SHasso Tepper 
1000adc6530SHasso Tepper void
1010adc6530SHasso Tepper labelicmp6(void)
1020adc6530SHasso Tepper {
1030adc6530SHasso Tepper 	wmove(wnd, 0, 0); wclrtoeol(wnd);
1040adc6530SHasso Tepper #define L(row, str) mvwprintw(wnd, row, 10, str)
1050adc6530SHasso Tepper #define R(row, str) mvwprintw(wnd, row, 45, str);
1060adc6530SHasso Tepper 	L(1, "ICMPv6 Input");		R(1, "ICMPv6 Output");
1070adc6530SHasso Tepper 	L(2, "total messages");		R(2, "total messages");
1080adc6530SHasso Tepper 	L(3, "with bad code");		R(3, "errors generated");
1090adc6530SHasso Tepper 	L(4, "with bad length");	R(4, "suppressed - original too short");
1100adc6530SHasso Tepper 	L(5, "with bad checksum");	R(5, "suppressed - original was ICMP");
1110adc6530SHasso Tepper 	L(6, "with insufficient data");	R(6, "responses sent");
1120adc6530SHasso Tepper 
1130adc6530SHasso Tepper 	L(8, "Input Histogram");	R(8, "Output Histogram");
1140adc6530SHasso Tepper #define B(row, str) L(row, str); R(row, str)
1150adc6530SHasso Tepper 	B(9, "echo response");
1160adc6530SHasso Tepper 	B(10, "echo request");
1170adc6530SHasso Tepper 	B(11, "destination unreachable");
1180adc6530SHasso Tepper 	B(12, "redirect");
1190adc6530SHasso Tepper 	B(13, "time-to-live exceeded");
1200adc6530SHasso Tepper 	B(14, "parameter problem");
1210adc6530SHasso Tepper 	B(15, "neighbor solicitation");
1220ca0cd25SSascha Wildner 	B(16, "neighbor advertisement");
1230adc6530SHasso Tepper 	L(17, "router advertisement");	R(17, "router solicitation");
1240adc6530SHasso Tepper #undef L
1250adc6530SHasso Tepper #undef R
1260adc6530SHasso Tepper #undef B
1270adc6530SHasso Tepper }
1280adc6530SHasso Tepper 
1290adc6530SHasso Tepper static void
1300adc6530SHasso Tepper domode(struct icmp6stat *ret)
1310adc6530SHasso Tepper {
1320adc6530SHasso Tepper 	const struct icmp6stat *sub;
1330adc6530SHasso Tepper 	int i, divisor = 1;
1340adc6530SHasso Tepper 
1350adc6530SHasso Tepper 	switch(currentmode) {
1360adc6530SHasso Tepper 	case display_RATE:
1370adc6530SHasso Tepper 		sub = &oldstat;
1380adc6530SHasso Tepper 		divisor = naptime;
1390adc6530SHasso Tepper 		break;
1400adc6530SHasso Tepper 	case display_DELTA:
1410adc6530SHasso Tepper 		sub = &oldstat;
1420adc6530SHasso Tepper 		break;
1430adc6530SHasso Tepper 	case display_SINCE:
1440adc6530SHasso Tepper 		sub = &initstat;
1450adc6530SHasso Tepper 		break;
1460adc6530SHasso Tepper 	default:
1470adc6530SHasso Tepper 		*ret = icmp6stat;
1480adc6530SHasso Tepper 		return;
1490adc6530SHasso Tepper 	}
1500adc6530SHasso Tepper #define DO(stat) ret->stat = (icmp6stat.stat - sub->stat) / divisor
1510adc6530SHasso Tepper 	DO(icp6s_error);
1520adc6530SHasso Tepper 	DO(icp6s_tooshort);
1530adc6530SHasso Tepper 	DO(icp6s_canterror);
1540adc6530SHasso Tepper 	for (i = 0; i <= ICMP6_MAXTYPE; i++) {
1550adc6530SHasso Tepper 		DO(icp6s_outhist[i]);
1560adc6530SHasso Tepper 	}
1570adc6530SHasso Tepper 	DO(icp6s_badcode);
1580adc6530SHasso Tepper 	DO(icp6s_tooshort);
1590adc6530SHasso Tepper 	DO(icp6s_checksum);
1600adc6530SHasso Tepper 	DO(icp6s_badlen);
1610adc6530SHasso Tepper 	DO(icp6s_reflect);
1620adc6530SHasso Tepper 	for (i = 0; i <= ICMP6_MAXTYPE; i++) {
1630adc6530SHasso Tepper 		DO(icp6s_inhist[i]);
1640adc6530SHasso Tepper 	}
1650adc6530SHasso Tepper #undef DO
1660adc6530SHasso Tepper }
1670adc6530SHasso Tepper 
1680adc6530SHasso Tepper void
1690adc6530SHasso Tepper showicmp6(void)
1700adc6530SHasso Tepper {
1710adc6530SHasso Tepper 	struct icmp6stat stats;
1720adc6530SHasso Tepper 	u_long totalin, totalout;
1730adc6530SHasso Tepper 	int i;
1740adc6530SHasso Tepper 
1750adc6530SHasso Tepper 	memset(&stats, 0, sizeof stats);
1760adc6530SHasso Tepper 	domode(&stats);
1770adc6530SHasso Tepper 	for (i = totalin = totalout = 0; i <= ICMP6_MAXTYPE; i++) {
1780adc6530SHasso Tepper 		totalin += stats.icp6s_inhist[i];
1790adc6530SHasso Tepper 		totalout += stats.icp6s_outhist[i];
1800adc6530SHasso Tepper 	}
1810adc6530SHasso Tepper 	totalin += stats.icp6s_badcode + stats.icp6s_badlen +
1820adc6530SHasso Tepper 		stats.icp6s_checksum + stats.icp6s_tooshort;
1830adc6530SHasso Tepper 	mvwprintw(wnd, 2, 0, "%9lu", totalin);
1840adc6530SHasso Tepper 	mvwprintw(wnd, 2, 35, "%9lu", totalout);
1850adc6530SHasso Tepper 
1860adc6530SHasso Tepper #define DO(stat, row, col) \
1870adc6530SHasso Tepper 	mvwprintw(wnd, row, col, "%9lu", stats.stat)
1880adc6530SHasso Tepper 
1890adc6530SHasso Tepper 	DO(icp6s_badcode, 3, 0);
1900adc6530SHasso Tepper 	DO(icp6s_badlen, 4, 0);
1910adc6530SHasso Tepper 	DO(icp6s_checksum, 5, 0);
1920adc6530SHasso Tepper 	DO(icp6s_tooshort, 6, 0);
1930adc6530SHasso Tepper 	DO(icp6s_error, 3, 35);
1940adc6530SHasso Tepper 	DO(icp6s_tooshort, 4, 35);
1950adc6530SHasso Tepper 	DO(icp6s_canterror, 5, 35);
1960adc6530SHasso Tepper 	DO(icp6s_reflect, 6, 35);
1970adc6530SHasso Tepper #define DO2(type, row) DO(icp6s_inhist[type], row, 0); DO(icp6s_outhist[type], \
1980adc6530SHasso Tepper 							 row, 35)
1990adc6530SHasso Tepper 	DO2(ICMP6_ECHO_REPLY, 9);
2000adc6530SHasso Tepper 	DO2(ICMP6_ECHO_REQUEST, 10);
2010adc6530SHasso Tepper 	DO2(ICMP6_DST_UNREACH, 11);
2020adc6530SHasso Tepper 	DO2(ND_REDIRECT, 12);
2030adc6530SHasso Tepper 	DO2(ICMP6_TIME_EXCEEDED, 13);
2040adc6530SHasso Tepper 	DO2(ICMP6_PARAM_PROB, 14);
2050adc6530SHasso Tepper 	DO2(ND_NEIGHBOR_SOLICIT, 15);
2060adc6530SHasso Tepper 	DO2(ND_NEIGHBOR_ADVERT, 16);
2070adc6530SHasso Tepper 	DO(icp6s_inhist[ND_ROUTER_SOLICIT], 17, 0);
2080adc6530SHasso Tepper 	DO(icp6s_outhist[ND_ROUTER_ADVERT], 17, 35);
2090adc6530SHasso Tepper #undef DO
2100adc6530SHasso Tepper #undef DO2
2110adc6530SHasso Tepper }
2120adc6530SHasso Tepper 
2130adc6530SHasso Tepper int
2140adc6530SHasso Tepper initicmp6(void)
2150adc6530SHasso Tepper {
2160adc6530SHasso Tepper 	size_t len;
2170adc6530SHasso Tepper 	int name[4];
2180adc6530SHasso Tepper 
2190adc6530SHasso Tepper 	name[0] = CTL_NET;
2200adc6530SHasso Tepper 	name[1] = PF_INET6;
2210adc6530SHasso Tepper 	name[2] = IPPROTO_ICMPV6;
2220adc6530SHasso Tepper 	name[3] = ICMPV6CTL_STATS;
2230adc6530SHasso Tepper 
2240adc6530SHasso Tepper 	len = 0;
2250adc6530SHasso Tepper 	if (sysctl(name, 4, 0, &len, 0, 0) < 0) {
2260adc6530SHasso Tepper 		error("sysctl getting icmp6stat size failed");
2270adc6530SHasso Tepper 		return 0;
2280adc6530SHasso Tepper 	}
2290adc6530SHasso Tepper 	if (len > sizeof icmp6stat) {
2300adc6530SHasso Tepper 		error("icmp6stat structure has grown--recompile systat!");
2310adc6530SHasso Tepper 		return 0;
2320adc6530SHasso Tepper 	}
2330adc6530SHasso Tepper 	if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
2340adc6530SHasso Tepper 		error("sysctl getting icmp6stat size failed");
2350adc6530SHasso Tepper 		return 0;
2360adc6530SHasso Tepper 	}
2370adc6530SHasso Tepper 	oldstat = initstat;
2380adc6530SHasso Tepper 	return 1;
2390adc6530SHasso Tepper }
2400adc6530SHasso Tepper 
2410adc6530SHasso Tepper void
2420adc6530SHasso Tepper reseticmp6(void)
2430adc6530SHasso Tepper {
2440adc6530SHasso Tepper 	size_t len;
2450adc6530SHasso Tepper 	int name[4];
2460adc6530SHasso Tepper 
2470adc6530SHasso Tepper 	name[0] = CTL_NET;
2480adc6530SHasso Tepper 	name[1] = PF_INET6;
2490adc6530SHasso Tepper 	name[2] = IPPROTO_ICMPV6;
2500adc6530SHasso Tepper 	name[3] = ICMPV6CTL_STATS;
2510adc6530SHasso Tepper 
2520adc6530SHasso Tepper 	len = sizeof initstat;
2530adc6530SHasso Tepper 	if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
2540adc6530SHasso Tepper 		error("sysctl getting icmp6stat size failed");
2550adc6530SHasso Tepper 	}
2560adc6530SHasso Tepper 	oldstat = initstat;
2570adc6530SHasso Tepper }
2580adc6530SHasso Tepper 
2590adc6530SHasso Tepper void
2600adc6530SHasso Tepper fetchicmp6(void)
2610adc6530SHasso Tepper {
2620adc6530SHasso Tepper 	int name[4];
2630adc6530SHasso Tepper 	size_t len;
2640adc6530SHasso Tepper 
2650adc6530SHasso Tepper 	oldstat = icmp6stat;
2660adc6530SHasso Tepper 	name[0] = CTL_NET;
2670adc6530SHasso Tepper 	name[1] = PF_INET6;
2680adc6530SHasso Tepper 	name[2] = IPPROTO_ICMPV6;
2690adc6530SHasso Tepper 	name[3] = ICMPV6CTL_STATS;
2700adc6530SHasso Tepper 	len = sizeof icmp6stat;
2710adc6530SHasso Tepper 
2720adc6530SHasso Tepper 	if (sysctl(name, 4, &icmp6stat, &len, 0, 0) < 0)
2730adc6530SHasso Tepper 		return;
2740adc6530SHasso Tepper }
2750adc6530SHasso Tepper 
2760adc6530SHasso Tepper #endif
277