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