129759Swollman/*- 229759Swollman * Copyright (c) 1980, 1992, 1993 329759Swollman * The Regents of the University of California. All rights reserved. 429759Swollman * 529759Swollman * Redistribution and use in source and binary forms, with or without 629759Swollman * modification, are permitted provided that the following conditions 729759Swollman * are met: 829759Swollman * 1. Redistributions of source code must retain the above copyright 929759Swollman * notice, this list of conditions and the following disclaimer. 1029759Swollman * 2. Redistributions in binary form must reproduce the above copyright 1129759Swollman * notice, this list of conditions and the following disclaimer in the 1229759Swollman * documentation and/or other materials provided with the distribution. 1329759Swollman * 4. Neither the name of the University nor the names of its contributors 1429759Swollman * may be used to endorse or promote products derived from this software 1529759Swollman * without specific prior written permission. 1629759Swollman * 1729759Swollman * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1829759Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1929759Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2029759Swollman * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2129759Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2229759Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2329759Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2429759Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2529759Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2629759Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2729759Swollman * SUCH DAMAGE. 2829759Swollman */ 2929759Swollman 3087715Smarkm#include <sys/cdefs.h> 3187715Smarkm 3287715Smarkm__FBSDID("$FreeBSD: releng/10.2/usr.bin/systat/icmp.c 240605 2012-09-17 13:36:47Z melifaro $"); 3387715Smarkm 3487715Smarkm#ifdef lint 3587715Smarkmstatic char sccsid[] = "@(#)mbufs.c 8.1 (Berkeley) 6/6/93"; 3687715Smarkm#endif 3787715Smarkm 3829759Swollman/* From: 3987715Smarkm "Id: mbufs.c,v 1.5 1997/02/24 20:59:03 wollman Exp" 4029759Swollman*/ 4129759Swollman 4229759Swollman#include <sys/param.h> 4329759Swollman#include <sys/types.h> 4429759Swollman#include <sys/socket.h> 4529759Swollman#include <sys/sysctl.h> 4629759Swollman 4729759Swollman#include <netinet/in.h> 4829759Swollman#include <netinet/in_systm.h> 4929759Swollman#include <netinet/ip.h> 5029759Swollman#include <netinet/ip_icmp.h> 5129759Swollman#include <netinet/icmp_var.h> 5229759Swollman 53200462Sdelphij#include <stdlib.h> 5429759Swollman#include <string.h> 55200462Sdelphij#include <paths.h> 5629759Swollman#include "systat.h" 5729759Swollman#include "extern.h" 5829759Swollman#include "mode.h" 5929759Swollman 6029759Swollmanstatic struct icmpstat icmpstat, initstat, oldstat; 6129759Swollman 6229759Swollman/*- 6329759Swollman--0 1 2 3 4 5 6 7 6429759Swollman--0123456789012345678901234567890123456789012345678901234567890123456789012345 65158160Sbde00 ICMP Input ICMP Output 66158160Sbde01999999999 total messages 999999999 total messages 67158160Sbde02999999999 with bad code 999999999 errors generated 68158160Sbde03999999999 with bad length 999999999 suppressed - original too short 69158160Sbde04999999999 with bad checksum 999999999 suppressed - original was ICMP 70158160Sbde05999999999 with insufficient data 999999999 responses sent 71158160Sbde06 999999999 suppressed - multicast echo 72158160Sbde07 999999999 suppressed - multicast tstamp 73158160Sbde08 74158160Sbde09 Input Histogram Output Histogram 75158160Sbde10999999999 echo response 999999999 echo response 76158160Sbde11999999999 echo request 999999999 echo request 77158160Sbde12999999999 destination unreachable 999999999 destination unreachable 78158160Sbde13999999999 redirect 999999999 redirect 79158160Sbde14999999999 time-to-live exceeded 999999999 time-to-line exceeded 80158160Sbde15999999999 parameter problem 999999999 parameter problem 81158160Sbde16999999999 router advertisement 999999999 router solicitation 82158160Sbde17 8329759Swollman18 8429759Swollman--0123456789012345678901234567890123456789012345678901234567890123456789012345 8529759Swollman--0 1 2 3 4 5 6 7 8629759Swollman*/ 8729759Swollman 8829759SwollmanWINDOW * 8929759Swollmanopenicmp(void) 9029759Swollman{ 91158160Sbde return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0)); 9229759Swollman} 9329759Swollman 9429759Swollmanvoid 95175387Sdelphijcloseicmp(WINDOW *w) 9629759Swollman{ 9729759Swollman if (w == NULL) 9829759Swollman return; 9929759Swollman wclear(w); 10029759Swollman wrefresh(w); 10129759Swollman delwin(w); 10229759Swollman} 10329759Swollman 10429759Swollmanvoid 10529759Swollmanlabelicmp(void) 10629759Swollman{ 10729759Swollman wmove(wnd, 0, 0); wclrtoeol(wnd); 10829759Swollman#define L(row, str) mvwprintw(wnd, row, 10, str) 10929759Swollman#define R(row, str) mvwprintw(wnd, row, 45, str); 110158160Sbde L(0, "ICMP Input"); R(0, "ICMP Output"); 111158160Sbde L(1, "total messages"); R(1, "total messages"); 112158160Sbde L(2, "with bad code"); R(2, "errors generated"); 113158160Sbde L(3, "with bad length"); R(3, "suppressed - original too short"); 114158160Sbde L(4, "with bad checksum"); R(4, "suppressed - original was ICMP"); 115158160Sbde L(5, "with insufficient data"); R(5, "responses sent"); 116158160Sbde R(6, "suppressed - multicast echo"); 117158160Sbde R(7, "suppressed - multicast tstamp"); 118158160Sbde L(9, "Input Histogram"); R(9, "Output Histogram"); 11929759Swollman#define B(row, str) L(row, str); R(row, str) 120158160Sbde B(10, "echo response"); 121158160Sbde B(11, "echo request"); 122158160Sbde B(12, "destination unreachable"); 123158160Sbde B(13, "redirect"); 124158160Sbde B(14, "time-to-live exceeded"); 125158160Sbde B(15, "parameter problem"); 126158160Sbde L(16, "router advertisement"); R(16, "router solicitation"); 12729759Swollman#undef L 12829759Swollman#undef R 12929759Swollman#undef B 13029759Swollman} 13129759Swollman 13229759Swollmanstatic void 13329759Swollmandomode(struct icmpstat *ret) 13429759Swollman{ 13529759Swollman const struct icmpstat *sub; 13629759Swollman int i, divisor = 1; 13729759Swollman 13829759Swollman switch(currentmode) { 13929759Swollman case display_RATE: 14029759Swollman sub = &oldstat; 141240605Smelifaro divisor = (delay > 1000000) ? delay / 1000000 : 1; 14229759Swollman break; 14329759Swollman case display_DELTA: 14429759Swollman sub = &oldstat; 14529759Swollman break; 14629759Swollman case display_SINCE: 14729759Swollman sub = &initstat; 14829759Swollman break; 14929759Swollman default: 15029759Swollman *ret = icmpstat; 15129759Swollman return; 15229759Swollman } 15329759Swollman#define DO(stat) ret->stat = (icmpstat.stat - sub->stat) / divisor 15429759Swollman DO(icps_error); 15529759Swollman DO(icps_oldshort); 15629759Swollman DO(icps_oldicmp); 15729759Swollman for (i = 0; i <= ICMP_MAXTYPE; i++) { 15829759Swollman DO(icps_outhist[i]); 15929759Swollman } 16029759Swollman DO(icps_badcode); 16129759Swollman DO(icps_tooshort); 16229759Swollman DO(icps_checksum); 16329759Swollman DO(icps_badlen); 16429759Swollman DO(icps_reflect); 16529759Swollman for (i = 0; i <= ICMP_MAXTYPE; i++) { 16629759Swollman DO(icps_inhist[i]); 16729759Swollman } 16829759Swollman DO(icps_bmcastecho); 16929759Swollman DO(icps_bmcasttstamp); 17029759Swollman#undef DO 17129759Swollman} 172158161Sbde 17329759Swollmanvoid 17429759Swollmanshowicmp(void) 17529759Swollman{ 17629759Swollman struct icmpstat stats; 17729759Swollman u_long totalin, totalout; 17829759Swollman int i; 17929759Swollman 18029759Swollman memset(&stats, 0, sizeof stats); 18129759Swollman domode(&stats); 18229759Swollman for (i = totalin = totalout = 0; i <= ICMP_MAXTYPE; i++) { 18329759Swollman totalin += stats.icps_inhist[i]; 18429759Swollman totalout += stats.icps_outhist[i]; 18529759Swollman } 186158161Sbde totalin += stats.icps_badcode + stats.icps_badlen + 18729759Swollman stats.icps_checksum + stats.icps_tooshort; 188158160Sbde mvwprintw(wnd, 1, 0, "%9lu", totalin); 189158160Sbde mvwprintw(wnd, 1, 35, "%9lu", totalout); 19029759Swollman 19129759Swollman#define DO(stat, row, col) \ 19229759Swollman mvwprintw(wnd, row, col, "%9lu", stats.stat) 19329759Swollman 194158160Sbde DO(icps_badcode, 2, 0); 195158160Sbde DO(icps_badlen, 3, 0); 196158160Sbde DO(icps_checksum, 4, 0); 197158160Sbde DO(icps_tooshort, 5, 0); 198158160Sbde DO(icps_error, 2, 35); 199158160Sbde DO(icps_oldshort, 3, 35); 200158160Sbde DO(icps_oldicmp, 4, 35); 201158160Sbde DO(icps_reflect, 5, 35); 202158160Sbde DO(icps_bmcastecho, 6, 35); 203158160Sbde DO(icps_bmcasttstamp, 7, 35); 20429759Swollman#define DO2(type, row) DO(icps_inhist[type], row, 0); DO(icps_outhist[type], \ 20529759Swollman row, 35) 206158160Sbde DO2(ICMP_ECHOREPLY, 10); 207158160Sbde DO2(ICMP_ECHO, 11); 208158160Sbde DO2(ICMP_UNREACH, 12); 209158160Sbde DO2(ICMP_REDIRECT, 13); 210158160Sbde DO2(ICMP_TIMXCEED, 14); 211158160Sbde DO2(ICMP_PARAMPROB, 15); 212158160Sbde DO(icps_inhist[ICMP_ROUTERADVERT], 16, 0); 213158160Sbde DO(icps_outhist[ICMP_ROUTERSOLICIT], 16, 35); 21429759Swollman#undef DO 21529759Swollman#undef DO2 21629759Swollman} 21729759Swollman 21829759Swollmanint 21929759Swollmaniniticmp(void) 22029759Swollman{ 22129759Swollman size_t len; 22229759Swollman int name[4]; 22329759Swollman 22429759Swollman name[0] = CTL_NET; 22529759Swollman name[1] = PF_INET; 22629759Swollman name[2] = IPPROTO_ICMP; 22729759Swollman name[3] = ICMPCTL_STATS; 22829759Swollman 22929759Swollman len = 0; 23029759Swollman if (sysctl(name, 4, 0, &len, 0, 0) < 0) { 23129759Swollman error("sysctl getting icmpstat size failed"); 23229759Swollman return 0; 23329759Swollman } 23429759Swollman if (len > sizeof icmpstat) { 23529759Swollman error("icmpstat structure has grown--recompile systat!"); 23629759Swollman return 0; 23729759Swollman } 23829759Swollman if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) { 23929759Swollman error("sysctl getting icmpstat size failed"); 24029759Swollman return 0; 24129759Swollman } 24229759Swollman oldstat = initstat; 24329759Swollman return 1; 24429759Swollman} 24529759Swollman 24629759Swollmanvoid 24729759Swollmanreseticmp(void) 24829759Swollman{ 24929759Swollman size_t len; 25029759Swollman int name[4]; 25129759Swollman 25229759Swollman name[0] = CTL_NET; 25329759Swollman name[1] = PF_INET; 25429759Swollman name[2] = IPPROTO_ICMP; 25529759Swollman name[3] = ICMPCTL_STATS; 25629759Swollman 25729759Swollman len = sizeof initstat; 25829759Swollman if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) { 25929759Swollman error("sysctl getting icmpstat size failed"); 26029759Swollman } 26129759Swollman oldstat = initstat; 26229759Swollman} 26329759Swollman 26429759Swollmanvoid 26529759Swollmanfetchicmp(void) 26629759Swollman{ 26729759Swollman int name[4]; 26829759Swollman size_t len; 26929759Swollman 27029759Swollman oldstat = icmpstat; 27129759Swollman name[0] = CTL_NET; 27229759Swollman name[1] = PF_INET; 27329759Swollman name[2] = IPPROTO_ICMP; 27429759Swollman name[3] = ICMPCTL_STATS; 27529759Swollman len = sizeof icmpstat; 27629759Swollman 27729759Swollman if (sysctl(name, 4, &icmpstat, &len, 0, 0) < 0) 27829759Swollman return; 27929759Swollman} 280