Home | History | Annotate | Line # | Download | only in systat
icmp.c revision 1.10
      1 /*	$NetBSD: icmp.c,v 1.10 2008/04/07 05:18:25 thorpej Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1999, 2000 Andrew Doran <ad (at) NetBSD.org>
      5  * 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  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  *
     28  */
     29 
     30 #include <sys/cdefs.h>
     31 #ifndef lint
     32 __RCSID("$NetBSD: icmp.c,v 1.10 2008/04/07 05:18:25 thorpej Exp $");
     33 #endif /* not lint */
     34 
     35 #include <sys/param.h>
     36 
     37 #include <netinet/in.h>
     38 #include <netinet/in_systm.h>
     39 #include <netinet/ip.h>
     40 #include <netinet/ip_icmp.h>
     41 #include <netinet/icmp_var.h>
     42 
     43 #include <string.h>
     44 
     45 #include "systat.h"
     46 #include "extern.h"
     47 
     48 #define LHD(row, str) mvwprintw(wnd, row, 10, str)
     49 #define RHD(row, str) mvwprintw(wnd, row, 45, str);
     50 #define BD(row, str) LHD(row, str); RHD(row, str)
     51 #define SHOW(stat, row, col) \
     52     mvwprintw(wnd, row, col, "%9llu", (unsigned long long)curstat[stat])
     53 #define SHOW2(type, row) SHOW(ICMP_STAT_INHIST + type, row, 0); \
     54     SHOW(ICMP_STAT_OUTHIST + type, row, 35)
     55 
     56 enum update {
     57 	UPDATE_TIME,
     58 	UPDATE_BOOT,
     59 	UPDATE_RUN,
     60 };
     61 
     62 static enum update update = UPDATE_TIME;
     63 static uint64_t curstat[ICMP_NSTATS];
     64 static uint64_t newstat[ICMP_NSTATS];
     65 static uint64_t oldstat[ICMP_NSTATS];
     66 
     67 static struct nlist namelist[] = {
     68 	{ .n_name = "_icmpstat" },
     69 	{ .n_name = NULL }
     70 };
     71 
     72 WINDOW *
     73 openicmp(void)
     74 {
     75 
     76 	return (subwin(stdscr, -1, 0, 5, 0));
     77 }
     78 
     79 void
     80 closeicmp(WINDOW *w)
     81 {
     82 
     83 	if (w != NULL) {
     84 		wclear(w);
     85 		wrefresh(w);
     86 		delwin(w);
     87 	}
     88 }
     89 
     90 void
     91 labelicmp(void)
     92 {
     93 
     94 	wmove(wnd, 0, 0); wclrtoeol(wnd);
     95 
     96 	mvwprintw(wnd, 1, 0,  "------------ ICMP input -----------");
     97 	mvwprintw(wnd, 1, 36, "------------- ICMP output ---------------");
     98 
     99 	mvwprintw(wnd, 8, 0,  "---------- Input histogram --------");
    100 	mvwprintw(wnd, 8, 36, "---------- Output histogram -------------");
    101 
    102 	LHD(3, "with bad code");
    103 	LHD(4, "with bad length");
    104 	LHD(5, "with bad checksum");
    105 	LHD(6, "with insufficient data");
    106 
    107 	RHD(3, "errors generated");
    108 	RHD(4, "suppressed - original too short");
    109 	RHD(5, "suppressed - original was ICMP");
    110 	RHD(6, "responses sent");
    111 
    112 	BD(2, "total messages");
    113 	BD(9, "echo response");
    114 	BD(10, "echo request");
    115 	BD(11, "destination unreachable");
    116 	BD(12, "redirect");
    117 	BD(13, "time-to-live exceeded");
    118 	BD(14, "parameter problem");
    119 	LHD(15, "router advertisement");
    120 	RHD(15, "router solicitation");
    121 }
    122 
    123 void
    124 showicmp(void)
    125 {
    126 	u_long tin, tout;
    127 	int i;
    128 
    129 	for (i = tin = tout = 0; i <= ICMP_MAXTYPE; i++) {
    130 		tin += curstat[ICMP_STAT_INHIST + i];
    131 		tout += curstat[ICMP_STAT_OUTHIST + i];
    132 	}
    133 
    134 	tin += curstat[ICMP_STAT_BADCODE] + curstat[ICMP_STAT_BADLEN] +
    135 	    curstat[ICMP_STAT_CHECKSUM] + curstat[ICMP_STAT_TOOSHORT];
    136 	mvwprintw(wnd, 2, 0, "%9lu", tin);
    137 	mvwprintw(wnd, 2, 35, "%9lu", tout);
    138 
    139 	SHOW(ICMP_STAT_BADCODE, 3, 0);
    140 	SHOW(ICMP_STAT_BADLEN, 4, 0);
    141 	SHOW(ICMP_STAT_CHECKSUM, 5, 0);
    142 	SHOW(ICMP_STAT_TOOSHORT, 6, 0);
    143 	SHOW(ICMP_STAT_ERROR, 3, 35);
    144 	SHOW(ICMP_STAT_OLDSHORT, 4, 35);
    145 	SHOW(ICMP_STAT_OLDICMP, 5, 35);
    146 	SHOW(ICMP_STAT_REFLECT, 6, 35);
    147 
    148 	SHOW2(ICMP_ECHOREPLY, 9);
    149 	SHOW2(ICMP_ECHO, 10);
    150 	SHOW2(ICMP_UNREACH, 11);
    151 	SHOW2(ICMP_REDIRECT, 12);
    152 	SHOW2(ICMP_TIMXCEED, 13);
    153 	SHOW2(ICMP_PARAMPROB, 14);
    154 	SHOW(ICMP_STAT_INHIST + ICMP_ROUTERADVERT, 15, 0);
    155 	SHOW(ICMP_STAT_OUTHIST + ICMP_ROUTERSOLICIT, 15, 35);
    156 }
    157 
    158 int
    159 initicmp(void)
    160 {
    161 
    162 	if (namelist[0].n_type == 0) {
    163 		if (kvm_nlist(kd, namelist)) {
    164 			nlisterr(namelist);
    165 			return(0);
    166 		}
    167 		if (namelist[0].n_type == 0) {
    168 			error("No namelist");
    169 			return(0);
    170 		}
    171 	}
    172 
    173 	return (1);
    174 }
    175 
    176 void
    177 fetchicmp(void)
    178 {
    179 	int i;
    180 
    181 	KREAD((void *)namelist[0].n_value, newstat, sizeof(newstat));
    182 
    183 	xADJINETCTR(curstat, oldstat, newstat, ICMP_STAT_BADCODE);
    184 	xADJINETCTR(curstat, oldstat, newstat, ICMP_STAT_BADLEN);
    185 	xADJINETCTR(curstat, oldstat, newstat, ICMP_STAT_CHECKSUM);
    186 	xADJINETCTR(curstat, oldstat, newstat, ICMP_STAT_TOOSHORT);
    187 	xADJINETCTR(curstat, oldstat, newstat, ICMP_STAT_ERROR);
    188 	xADJINETCTR(curstat, oldstat, newstat, ICMP_STAT_OLDSHORT);
    189 	xADJINETCTR(curstat, oldstat, newstat, ICMP_STAT_OLDICMP);
    190 	xADJINETCTR(curstat, oldstat, newstat, ICMP_STAT_REFLECT);
    191 
    192 	for (i = 0; i <= ICMP_MAXTYPE; i++) {
    193 		xADJINETCTR(curstat, oldstat, newstat, ICMP_STAT_INHIST + i);
    194 		xADJINETCTR(curstat, oldstat, newstat, ICMP_STAT_OUTHIST + i);
    195 	}
    196 
    197 	if (update == UPDATE_TIME)
    198 		memcpy(oldstat, newstat, sizeof(oldstat));
    199 }
    200 
    201 void
    202 icmp_boot(char *args)
    203 {
    204 
    205 	memset(oldstat, 0, sizeof(oldstat));
    206 	update = UPDATE_BOOT;
    207 }
    208 
    209 void
    210 icmp_run(char *args)
    211 {
    212 
    213 	if (update != UPDATE_RUN) {
    214 		memcpy(oldstat, newstat, sizeof(oldstat));
    215 		update = UPDATE_RUN;
    216 	}
    217 }
    218 
    219 void
    220 icmp_time(char *args)
    221 {
    222 
    223 	if (update != UPDATE_TIME) {
    224 		memcpy(oldstat, newstat, sizeof(oldstat));
    225 		update = UPDATE_TIME;
    226 	}
    227 }
    228 
    229 void
    230 icmp_zero(char *args)
    231 {
    232 
    233 	if (update == UPDATE_RUN)
    234 		memcpy(oldstat, newstat, sizeof(oldstat));
    235 }
    236