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