]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - usr.bin/systat/icmp.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.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(WINDOW *w)
100 {
101         if (w == NULL)
102                 return;
103         wclear(w);
104         wrefresh(w);
105         delwin(w);
106 }
107
108 void
109 labelicmp(void)
110 {
111         wmove(wnd, 0, 0); wclrtoeol(wnd);
112 #define L(row, str) mvwprintw(wnd, row, 10, str)
113 #define R(row, str) mvwprintw(wnd, row, 45, str);
114         L(0, "ICMP Input");             R(0, "ICMP Output");
115         L(1, "total messages");         R(1, "total messages");
116         L(2, "with bad code");          R(2, "errors generated");
117         L(3, "with bad length");        R(3, "suppressed - original too short");
118         L(4, "with bad checksum");      R(4, "suppressed - original was ICMP");
119         L(5, "with insufficient data"); R(5, "responses sent");
120                                         R(6, "suppressed - multicast echo");
121                                         R(7, "suppressed - multicast tstamp");
122         L(9, "Input Histogram");        R(9, "Output Histogram");
123 #define B(row, str) L(row, str); R(row, str)
124         B(10, "echo response");
125         B(11, "echo request");
126         B(12, "destination unreachable");
127         B(13, "redirect");
128         B(14, "time-to-live exceeded");
129         B(15, "parameter problem");
130         L(16, "router advertisement");  R(16, "router solicitation");
131 #undef L
132 #undef R
133 #undef B
134 }
135
136 static void
137 domode(struct icmpstat *ret)
138 {
139         const struct icmpstat *sub;
140         int i, divisor = 1;
141
142         switch(currentmode) {
143         case display_RATE:
144                 sub = &oldstat;
145                 divisor = naptime;
146                 break;
147         case display_DELTA:
148                 sub = &oldstat;
149                 break;
150         case display_SINCE:
151                 sub = &initstat;
152                 break;
153         default:
154                 *ret = icmpstat;
155                 return;
156         }
157 #define DO(stat) ret->stat = (icmpstat.stat - sub->stat) / divisor
158         DO(icps_error);
159         DO(icps_oldshort);
160         DO(icps_oldicmp);
161         for (i = 0; i <= ICMP_MAXTYPE; i++) {
162                 DO(icps_outhist[i]);
163         }
164         DO(icps_badcode);
165         DO(icps_tooshort);
166         DO(icps_checksum);
167         DO(icps_badlen);
168         DO(icps_reflect);
169         for (i = 0; i <= ICMP_MAXTYPE; i++) {
170                 DO(icps_inhist[i]);
171         }
172         DO(icps_bmcastecho);
173         DO(icps_bmcasttstamp);
174 #undef DO
175 }
176
177 void
178 showicmp(void)
179 {
180         struct icmpstat stats;
181         u_long totalin, totalout;
182         int i;
183
184         memset(&stats, 0, sizeof stats);
185         domode(&stats);
186         for (i = totalin = totalout = 0; i <= ICMP_MAXTYPE; i++) {
187                 totalin += stats.icps_inhist[i];
188                 totalout += stats.icps_outhist[i];
189         }
190         totalin += stats.icps_badcode + stats.icps_badlen +
191                 stats.icps_checksum + stats.icps_tooshort;
192         mvwprintw(wnd, 1, 0, "%9lu", totalin);
193         mvwprintw(wnd, 1, 35, "%9lu", totalout);
194
195 #define DO(stat, row, col) \
196         mvwprintw(wnd, row, col, "%9lu", stats.stat)
197
198         DO(icps_badcode, 2, 0);
199         DO(icps_badlen, 3, 0);
200         DO(icps_checksum, 4, 0);
201         DO(icps_tooshort, 5, 0);
202         DO(icps_error, 2, 35);
203         DO(icps_oldshort, 3, 35);
204         DO(icps_oldicmp, 4, 35);
205         DO(icps_reflect, 5, 35);
206         DO(icps_bmcastecho, 6, 35);
207         DO(icps_bmcasttstamp, 7, 35);
208 #define DO2(type, row) DO(icps_inhist[type], row, 0); DO(icps_outhist[type], \
209                                                          row, 35)
210         DO2(ICMP_ECHOREPLY, 10);
211         DO2(ICMP_ECHO, 11);
212         DO2(ICMP_UNREACH, 12);
213         DO2(ICMP_REDIRECT, 13);
214         DO2(ICMP_TIMXCEED, 14);
215         DO2(ICMP_PARAMPROB, 15);
216         DO(icps_inhist[ICMP_ROUTERADVERT], 16, 0);
217         DO(icps_outhist[ICMP_ROUTERSOLICIT], 16, 35);
218 #undef DO
219 #undef DO2
220 }
221
222 int
223 initicmp(void)
224 {
225         size_t len;
226         int name[4];
227
228         name[0] = CTL_NET;
229         name[1] = PF_INET;
230         name[2] = IPPROTO_ICMP;
231         name[3] = ICMPCTL_STATS;
232
233         len = 0;
234         if (sysctl(name, 4, 0, &len, 0, 0) < 0) {
235                 error("sysctl getting icmpstat size failed");
236                 return 0;
237         }
238         if (len > sizeof icmpstat) {
239                 error("icmpstat structure has grown--recompile systat!");
240                 return 0;
241         }
242         if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
243                 error("sysctl getting icmpstat size failed");
244                 return 0;
245         }
246         oldstat = initstat;
247         return 1;
248 }
249
250 void
251 reseticmp(void)
252 {
253         size_t len;
254         int name[4];
255
256         name[0] = CTL_NET;
257         name[1] = PF_INET;
258         name[2] = IPPROTO_ICMP;
259         name[3] = ICMPCTL_STATS;
260
261         len = sizeof initstat;
262         if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
263                 error("sysctl getting icmpstat size failed");
264         }
265         oldstat = initstat;
266 }
267
268 void
269 fetchicmp(void)
270 {
271         int name[4];
272         size_t len;
273
274         oldstat = icmpstat;
275         name[0] = CTL_NET;
276         name[1] = PF_INET;
277         name[2] = IPPROTO_ICMP;
278         name[3] = ICMPCTL_STATS;
279         len = sizeof icmpstat;
280
281         if (sysctl(name, 4, &icmpstat, &len, 0, 0) < 0)
282                 return;
283 }
284