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