1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1980, 1992, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 33 34 /* From: 35 "Id: mbufs.c,v 1.5 1997/02/24 20:59:03 wollman Exp" 36 */ 37 38 #ifdef INET6 39 #include <sys/param.h> 40 #include <sys/types.h> 41 #include <sys/socket.h> 42 #include <sys/sysctl.h> 43 44 #include <netinet/in.h> 45 #include <netinet/icmp6.h> 46 47 #include <inttypes.h> 48 #include <stdlib.h> 49 #include <string.h> 50 #include <paths.h> 51 #include "systat.h" 52 #include "extern.h" 53 #include "mode.h" 54 55 static struct icmp6stat icmp6stat, initstat, oldstat; 56 57 /*- 58 --0 1 2 3 4 5 6 7 59 --0123456789012345678901234567890123456789012345678901234567890123456789012345 60 00 ICMPv6 Input ICMPv6 Output 61 01999999999 total messages 999999999 total messages 62 02999999999 with bad code 999999999 errors generated 63 03999999999 with bad length 999999999 suppressed - original too short 64 04999999999 with bad checksum 999999999 suppressed - original was ICMP 65 05999999999 with insufficient data 999999999 responses sent 66 06 67 07 Input Histogram Output Histogram 68 08999999999 echo response 999999999 echo response 69 09999999999 echo request 999999999 echo request 70 10999999999 destination unreachable 999999999 destination unreachable 71 11999999999 redirect 999999999 redirect 72 12999999999 time-to-live exceeded 999999999 time-to-line exceeded 73 13999999999 parameter problem 999999999 parameter problem 74 14999999999 neighbor solicitation 999999999 neighbor solicitation 75 15999999999 neighbor advertisement 999999999 neighbor advertisement 76 16999999999 router advertisement 999999999 router solicitation 77 17 78 18 79 --0123456789012345678901234567890123456789012345678901234567890123456789012345 80 --0 1 2 3 4 5 6 7 81 */ 82 83 WINDOW * 84 openicmp6(void) 85 { 86 return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0)); 87 } 88 89 void 90 closeicmp6(WINDOW *w) 91 { 92 if (w == NULL) 93 return; 94 wclear(w); 95 wrefresh(w); 96 delwin(w); 97 } 98 99 void 100 labelicmp6(void) 101 { 102 wmove(wnd, 0, 0); wclrtoeol(wnd); 103 #define L(row, str) mvwprintw(wnd, row, 10, str) 104 #define R(row, str) mvwprintw(wnd, row, 45, str); 105 L(0, "ICMPv6 Input"); R(0, "ICMPv6 Output"); 106 L(1, "total messages"); R(1, "total messages"); 107 L(2, "with bad code"); R(2, "errors generated"); 108 L(3, "with bad length"); R(3, "suppressed - original too short"); 109 L(4, "with bad checksum"); R(4, "suppressed - original was ICMP"); 110 L(5, "with insufficient data"); R(5, "responses sent"); 111 112 L(7, "Input Histogram"); R(7, "Output Histogram"); 113 #define B(row, str) L(row, str); R(row, str) 114 B(8, "echo response"); 115 B(9, "echo request"); 116 B(10, "destination unreachable"); 117 B(11, "redirect"); 118 B(12, "time-to-live exceeded"); 119 B(13, "parameter problem"); 120 B(14, "neighbor solicitation"); 121 B(15, "neighbor advertisement"); 122 L(16, "router advertisement"); R(16, "router solicitation"); 123 #undef L 124 #undef R 125 #undef B 126 } 127 128 static void 129 domode(struct icmp6stat *ret) 130 { 131 const struct icmp6stat *sub; 132 int i, divisor = 1; 133 134 switch(currentmode) { 135 case display_RATE: 136 sub = &oldstat; 137 divisor = (delay > 1000000) ? delay / 1000000 : 1; 138 break; 139 case display_DELTA: 140 sub = &oldstat; 141 break; 142 case display_SINCE: 143 sub = &initstat; 144 break; 145 default: 146 *ret = icmp6stat; 147 return; 148 } 149 #define DO(stat) ret->stat = (icmp6stat.stat - sub->stat) / divisor 150 DO(icp6s_error); 151 DO(icp6s_tooshort); 152 DO(icp6s_canterror); 153 for (i = 0; i <= ICMP6_MAXTYPE; i++) { 154 DO(icp6s_outhist[i]); 155 } 156 DO(icp6s_badcode); 157 DO(icp6s_tooshort); 158 DO(icp6s_checksum); 159 DO(icp6s_badlen); 160 DO(icp6s_reflect); 161 for (i = 0; i <= ICMP6_MAXTYPE; i++) { 162 DO(icp6s_inhist[i]); 163 } 164 #undef DO 165 } 166 167 void 168 showicmp6(void) 169 { 170 struct icmp6stat stats; 171 uint64_t totalin, totalout; 172 int i; 173 174 memset(&stats, 0, sizeof stats); 175 domode(&stats); 176 for (i = totalin = totalout = 0; i <= ICMP6_MAXTYPE; i++) { 177 totalin += stats.icp6s_inhist[i]; 178 totalout += stats.icp6s_outhist[i]; 179 } 180 totalin += stats.icp6s_badcode + stats.icp6s_badlen + 181 stats.icp6s_checksum + stats.icp6s_tooshort; 182 mvwprintw(wnd, 1, 0, "%9"PRIu64, totalin); 183 mvwprintw(wnd, 1, 35, "%9"PRIu64, totalout); 184 185 #define DO(stat, row, col) \ 186 mvwprintw(wnd, row, col, "%9"PRIu64, stats.stat) 187 188 DO(icp6s_badcode, 2, 0); 189 DO(icp6s_badlen, 3, 0); 190 DO(icp6s_checksum, 4, 0); 191 DO(icp6s_tooshort, 5, 0); 192 DO(icp6s_error, 2, 35); 193 DO(icp6s_tooshort, 3, 35); 194 DO(icp6s_canterror, 4, 35); 195 DO(icp6s_reflect, 5, 35); 196 #define DO2(type, row) DO(icp6s_inhist[type], row, 0); DO(icp6s_outhist[type], \ 197 row, 35) 198 DO2(ICMP6_ECHO_REPLY, 8); 199 DO2(ICMP6_ECHO_REQUEST, 9); 200 DO2(ICMP6_DST_UNREACH, 10); 201 DO2(ND_REDIRECT, 11); 202 DO2(ICMP6_TIME_EXCEEDED, 12); 203 DO2(ICMP6_PARAM_PROB, 13); 204 DO2(ND_NEIGHBOR_SOLICIT, 14); 205 DO2(ND_NEIGHBOR_ADVERT, 15); 206 DO(icp6s_inhist[ND_ROUTER_SOLICIT], 16, 0); 207 DO(icp6s_outhist[ND_ROUTER_ADVERT], 16, 35); 208 #undef DO 209 #undef DO2 210 } 211 212 int 213 initicmp6(void) 214 { 215 size_t len; 216 int name[4]; 217 218 name[0] = CTL_NET; 219 name[1] = PF_INET6; 220 name[2] = IPPROTO_ICMPV6; 221 name[3] = ICMPV6CTL_STATS; 222 223 len = 0; 224 if (sysctl(name, 4, 0, &len, 0, 0) < 0) { 225 error("sysctl getting icmp6stat size failed"); 226 return 0; 227 } 228 if (len > sizeof icmp6stat) { 229 error("icmp6stat structure has grown--recompile systat!"); 230 return 0; 231 } 232 if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) { 233 error("sysctl getting icmp6stat size failed"); 234 return 0; 235 } 236 oldstat = initstat; 237 return 1; 238 } 239 240 void 241 reseticmp6(void) 242 { 243 size_t len; 244 int name[4]; 245 246 name[0] = CTL_NET; 247 name[1] = PF_INET6; 248 name[2] = IPPROTO_ICMPV6; 249 name[3] = ICMPV6CTL_STATS; 250 251 len = sizeof initstat; 252 if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) { 253 error("sysctl getting icmp6stat size failed"); 254 } 255 oldstat = initstat; 256 } 257 258 void 259 fetchicmp6(void) 260 { 261 int name[4]; 262 size_t len; 263 264 oldstat = icmp6stat; 265 name[0] = CTL_NET; 266 name[1] = PF_INET6; 267 name[2] = IPPROTO_ICMPV6; 268 name[3] = ICMPV6CTL_STATS; 269 len = sizeof icmp6stat; 270 271 if (sysctl(name, 4, &icmp6stat, &len, 0, 0) < 0) 272 return; 273 } 274 275 #endif 276