Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.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  * @(#)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.2 2003/06/17 04:29:32 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, divisor = 1;
134
135         switch(currentmode) {
136         case display_RATE:
137                 sub = &oldstat;
138                 divisor = naptime;
139                 break;
140         case display_DELTA:
141                 sub = &oldstat;
142                 break;
143         case display_SINCE:
144                 sub = &initstat;
145                 break;
146         default:
147                 *ret = icmpstat;
148                 return;
149         }
150 #define DO(stat) ret->stat = (icmpstat.stat - sub->stat) / divisor
151         DO(icps_error);
152         DO(icps_oldshort);
153         DO(icps_oldicmp);
154         for (i = 0; i <= ICMP_MAXTYPE; i++) {
155                 DO(icps_outhist[i]);
156         }
157         DO(icps_badcode);
158         DO(icps_tooshort);
159         DO(icps_checksum);
160         DO(icps_badlen);
161         DO(icps_reflect);
162         for (i = 0; i <= ICMP_MAXTYPE; i++) {
163                 DO(icps_inhist[i]);
164         }
165         DO(icps_bmcastecho);
166         DO(icps_bmcasttstamp);
167 #undef DO
168 }
169         
170 void
171 showicmp(void)
172 {
173         struct icmpstat stats;
174         u_long totalin, totalout;
175         int i;
176
177         memset(&stats, 0, sizeof stats);
178         domode(&stats);
179         for (i = totalin = totalout = 0; i <= ICMP_MAXTYPE; i++) {
180                 totalin += stats.icps_inhist[i];
181                 totalout += stats.icps_outhist[i];
182         }
183         totalin += stats.icps_badcode + stats.icps_badlen + 
184                 stats.icps_checksum + stats.icps_tooshort;
185         mvwprintw(wnd, 2, 0, "%9lu", totalin);
186         mvwprintw(wnd, 2, 35, "%9lu", totalout);
187
188 #define DO(stat, row, col) \
189         mvwprintw(wnd, row, col, "%9lu", stats.stat)
190
191         DO(icps_badcode, 3, 0);
192         DO(icps_badlen, 4, 0);
193         DO(icps_checksum, 5, 0);
194         DO(icps_tooshort, 6, 0);
195         DO(icps_error, 3, 35);
196         DO(icps_oldshort, 4, 35);
197         DO(icps_oldicmp, 5, 35);
198         DO(icps_reflect, 6, 35);
199         DO(icps_bmcastecho, 7, 35);
200         DO(icps_bmcasttstamp, 8, 35);
201 #define DO2(type, row) DO(icps_inhist[type], row, 0); DO(icps_outhist[type], \
202                                                          row, 35)
203         DO2(ICMP_ECHOREPLY, 11);
204         DO2(ICMP_ECHO, 12);
205         DO2(ICMP_UNREACH, 13);
206         DO2(ICMP_REDIRECT, 14);
207         DO2(ICMP_TIMXCEED, 15);
208         DO2(ICMP_PARAMPROB, 16);
209         DO(icps_inhist[ICMP_ROUTERADVERT], 17, 0);
210         DO(icps_outhist[ICMP_ROUTERSOLICIT], 17, 35);
211 #undef DO
212 #undef DO2
213 }
214
215 int
216 initicmp(void)
217 {
218         size_t len;
219         int name[4];
220
221         name[0] = CTL_NET;
222         name[1] = PF_INET;
223         name[2] = IPPROTO_ICMP;
224         name[3] = ICMPCTL_STATS;
225
226         len = 0;
227         if (sysctl(name, 4, 0, &len, 0, 0) < 0) {
228                 error("sysctl getting icmpstat size failed");
229                 return 0;
230         }
231         if (len > sizeof icmpstat) {
232                 error("icmpstat structure has grown--recompile systat!");
233                 return 0;
234         }
235         if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
236                 error("sysctl getting icmpstat size failed");
237                 return 0;
238         }
239         oldstat = initstat;
240         return 1;
241 }
242
243 void
244 reseticmp(void)
245 {
246         size_t len;
247         int name[4];
248
249         name[0] = CTL_NET;
250         name[1] = PF_INET;
251         name[2] = IPPROTO_ICMP;
252         name[3] = ICMPCTL_STATS;
253
254         len = sizeof initstat;
255         if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
256                 error("sysctl getting icmpstat size failed");
257         }
258         oldstat = initstat;
259 }
260
261 void
262 fetchicmp(void)
263 {
264         int name[4];
265         size_t len;
266
267         oldstat = icmpstat;
268         name[0] = CTL_NET;
269         name[1] = PF_INET;
270         name[2] = IPPROTO_ICMP;
271         name[3] = ICMPCTL_STATS;
272         len = sizeof icmpstat;
273
274         if (sysctl(name, 4, &icmpstat, &len, 0, 0) < 0)
275                 return;
276 }
277