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/icmp.c,v 1.2 1999/08/28 01:06:01 peter Exp $ 35 * $DragonFly: src/usr.bin/systat/icmp.c,v 1.3 2003/07/12 03:09:50 dillon Exp $ 36 */ 37 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/in_systm.h> 45 #include <netinet/ip.h> 46 #include <netinet/ip_icmp.h> 47 #include <netinet/icmp_var.h> 48 49 #include <stdlib.h> 50 #include <string.h> 51 #include <paths.h> 52 #include "systat.h" 53 #include "extern.h" 54 #include "mode.h" 55 56 static struct icmpstat icmpstat, initstat, oldstat; 57 58 /*- 59 --0 1 2 3 4 5 6 7 60 --0123456789012345678901234567890123456789012345678901234567890123456789012345 61 01 ICMP Input ICMP Output 62 02999999999 total messages 999999999 total messages 63 03999999999 with bad code 999999999 errors generated 64 04999999999 with bad length 999999999 suppressed - original too short 65 05999999999 with bad checksum 999999999 suppressed - original was ICMP 66 06999999999 with insufficient data 999999999 responses sent 67 07 999999999 suppressed - multicast echo 68 08 999999999 suppressed - multicast tstamp 69 09 70 10 Input Histogram Output Histogram 71 11999999999 echo response 999999999 echo response 72 12999999999 echo request 999999999 echo request 73 13999999999 destination unreachable 999999999 destination unreachable 74 14999999999 redirect 999999999 redirect 75 15999999999 time-to-live exceeded 999999999 time-to-line exceeded 76 16999999999 parameter problem 999999999 parameter problem 77 17999999999 router advertisement 999999999 router solicitation 78 18 79 19 80 --0123456789012345678901234567890123456789012345678901234567890123456789012345 81 --0 1 2 3 4 5 6 7 82 */ 83 84 WINDOW * 85 openicmp(void) 86 { 87 return (subwin(stdscr, LINES-5-1, 0, 5, 0)); 88 } 89 90 void 91 closeicmp(w) 92 WINDOW *w; 93 { 94 if (w == NULL) 95 return; 96 wclear(w); 97 wrefresh(w); 98 delwin(w); 99 } 100 101 void 102 labelicmp(void) 103 { 104 wmove(wnd, 0, 0); wclrtoeol(wnd); 105 #define L(row, str) mvwprintw(wnd, row, 10, str) 106 #define R(row, str) mvwprintw(wnd, row, 45, str); 107 L(1, "ICMP Input"); R(1, "ICMP Output"); 108 L(2, "total messages"); R(2, "total messages"); 109 L(3, "with bad code"); R(3, "errors generated"); 110 L(4, "with bad length"); R(4, "suppressed - original too short"); 111 L(5, "with bad checksum"); R(5, "suppressed - original was ICMP"); 112 L(6, "with insufficient data"); R(6, "responses sent"); 113 ; R(7, "suppressed - multicast echo"); 114 ; R(8, "suppressed - multicast tstamp"); 115 L(10, "Input Histogram"); R(10, "Output Histogram"); 116 #define B(row, str) L(row, str); R(row, str) 117 B(11, "echo response"); 118 B(12, "echo request"); 119 B(13, "destination unreachable"); 120 B(14, "redirect"); 121 B(15, "time-to-live exceeded"); 122 B(16, "parameter problem"); 123 L(17, "router advertisement"); R(17, "router solicitation"); 124 #undef L 125 #undef R 126 #undef B 127 } 128 129 static void 130 domode(struct icmpstat *ret) 131 { 132 const struct icmpstat *sub; 133 int i; 134 double divisor = 1.0; 135 136 switch(currentmode) { 137 case display_RATE: 138 sub = &oldstat; 139 divisor = naptime; 140 break; 141 case display_DELTA: 142 sub = &oldstat; 143 break; 144 case display_SINCE: 145 sub = &initstat; 146 break; 147 default: 148 *ret = icmpstat; 149 return; 150 } 151 #define DO(stat) ret->stat = (double)(icmpstat.stat - sub->stat) / divisor 152 DO(icps_error); 153 DO(icps_oldshort); 154 DO(icps_oldicmp); 155 for (i = 0; i <= ICMP_MAXTYPE; i++) { 156 DO(icps_outhist[i]); 157 } 158 DO(icps_badcode); 159 DO(icps_tooshort); 160 DO(icps_checksum); 161 DO(icps_badlen); 162 DO(icps_reflect); 163 for (i = 0; i <= ICMP_MAXTYPE; i++) { 164 DO(icps_inhist[i]); 165 } 166 DO(icps_bmcastecho); 167 DO(icps_bmcasttstamp); 168 #undef DO 169 } 170 171 void 172 showicmp(void) 173 { 174 struct icmpstat stats; 175 u_long totalin, totalout; 176 int i; 177 178 memset(&stats, 0, sizeof stats); 179 domode(&stats); 180 for (i = totalin = totalout = 0; i <= ICMP_MAXTYPE; i++) { 181 totalin += stats.icps_inhist[i]; 182 totalout += stats.icps_outhist[i]; 183 } 184 totalin += stats.icps_badcode + stats.icps_badlen + 185 stats.icps_checksum + stats.icps_tooshort; 186 mvwprintw(wnd, 2, 0, "%9lu", totalin); 187 mvwprintw(wnd, 2, 35, "%9lu", totalout); 188 189 #define DO(stat, row, col) \ 190 mvwprintw(wnd, row, col, "%9lu", stats.stat) 191 192 DO(icps_badcode, 3, 0); 193 DO(icps_badlen, 4, 0); 194 DO(icps_checksum, 5, 0); 195 DO(icps_tooshort, 6, 0); 196 DO(icps_error, 3, 35); 197 DO(icps_oldshort, 4, 35); 198 DO(icps_oldicmp, 5, 35); 199 DO(icps_reflect, 6, 35); 200 DO(icps_bmcastecho, 7, 35); 201 DO(icps_bmcasttstamp, 8, 35); 202 #define DO2(type, row) DO(icps_inhist[type], row, 0); DO(icps_outhist[type], \ 203 row, 35) 204 DO2(ICMP_ECHOREPLY, 11); 205 DO2(ICMP_ECHO, 12); 206 DO2(ICMP_UNREACH, 13); 207 DO2(ICMP_REDIRECT, 14); 208 DO2(ICMP_TIMXCEED, 15); 209 DO2(ICMP_PARAMPROB, 16); 210 DO(icps_inhist[ICMP_ROUTERADVERT], 17, 0); 211 DO(icps_outhist[ICMP_ROUTERSOLICIT], 17, 35); 212 #undef DO 213 #undef DO2 214 } 215 216 int 217 initicmp(void) 218 { 219 size_t len; 220 int name[4]; 221 222 name[0] = CTL_NET; 223 name[1] = PF_INET; 224 name[2] = IPPROTO_ICMP; 225 name[3] = ICMPCTL_STATS; 226 227 len = 0; 228 if (sysctl(name, 4, 0, &len, 0, 0) < 0) { 229 error("sysctl getting icmpstat size failed"); 230 return 0; 231 } 232 if (len > sizeof icmpstat) { 233 error("icmpstat structure has grown--recompile systat!"); 234 return 0; 235 } 236 if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) { 237 error("sysctl getting icmpstat size failed"); 238 return 0; 239 } 240 oldstat = initstat; 241 return 1; 242 } 243 244 void 245 reseticmp(void) 246 { 247 size_t len; 248 int name[4]; 249 250 name[0] = CTL_NET; 251 name[1] = PF_INET; 252 name[2] = IPPROTO_ICMP; 253 name[3] = ICMPCTL_STATS; 254 255 len = sizeof initstat; 256 if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) { 257 error("sysctl getting icmpstat size failed"); 258 } 259 oldstat = initstat; 260 } 261 262 void 263 fetchicmp(void) 264 { 265 int name[4]; 266 size_t len; 267 268 oldstat = icmpstat; 269 name[0] = CTL_NET; 270 name[1] = PF_INET; 271 name[2] = IPPROTO_ICMP; 272 name[3] = ICMPCTL_STATS; 273 len = sizeof icmpstat; 274 275 if (sysctl(name, 4, &icmpstat, &len, 0, 0) < 0) 276 return; 277 } 278 279