]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - usr.bin/systat/icmp6.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / usr.bin / systat / icmp6.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 #ifdef INET6
47 #include <sys/param.h>
48 #include <sys/types.h>
49 #include <sys/socket.h>
50 #include <sys/sysctl.h>
51
52 #include <netinet/in.h>
53 #include <netinet/icmp6.h>
54
55 #include <stdlib.h>
56 #include <string.h>
57 #include <paths.h>
58 #include "systat.h"
59 #include "extern.h"
60 #include "mode.h"
61
62 static struct icmp6stat icmp6stat, initstat, oldstat;
63
64 /*-
65 --0         1         2         3         4         5         6         7
66 --0123456789012345678901234567890123456789012345678901234567890123456789012345
67 00          ICMPv6 Input                       ICMPv6 Output
68 01999999999 total messages           999999999 total messages
69 02999999999 with bad code            999999999 errors generated
70 03999999999 with bad length          999999999 suppressed - original too short
71 04999999999 with bad checksum        999999999 suppressed - original was ICMP
72 05999999999 with insufficient data   999999999 responses sent
73 06
74 07          Input Histogram                    Output Histogram
75 08999999999 echo response            999999999 echo response
76 09999999999 echo request             999999999 echo request
77 10999999999 destination unreachable  999999999 destination unreachable
78 11999999999 redirect                 999999999 redirect
79 12999999999 time-to-live exceeded    999999999 time-to-line exceeded
80 13999999999 parameter problem        999999999 parameter problem
81 14999999999 neighbor solicitation    999999999 neighbor solicitation
82 15999999999 neighbor advertisment    999999999 neighbor advertisment
83 16999999999 router advertisement     999999999 router solicitation
84 17
85 18
86 --0123456789012345678901234567890123456789012345678901234567890123456789012345
87 --0         1         2         3         4         5         6         7
88 */
89
90 WINDOW *
91 openicmp6(void)
92 {
93         return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0));
94 }
95
96 void
97 closeicmp6(WINDOW *w)
98 {
99         if (w == NULL)
100                 return;
101         wclear(w);
102         wrefresh(w);
103         delwin(w);
104 }
105
106 void
107 labelicmp6(void)
108 {
109         wmove(wnd, 0, 0); wclrtoeol(wnd);
110 #define L(row, str) mvwprintw(wnd, row, 10, str)
111 #define R(row, str) mvwprintw(wnd, row, 45, str);
112         L(0, "ICMPv6 Input");           R(0, "ICMPv6 Output");
113         L(1, "total messages");         R(1, "total messages");
114         L(2, "with bad code");          R(2, "errors generated");
115         L(3, "with bad length");        R(3, "suppressed - original too short");
116         L(4, "with bad checksum");      R(4, "suppressed - original was ICMP");
117         L(5, "with insufficient data"); R(5, "responses sent");
118
119         L(7, "Input Histogram");        R(7, "Output Histogram");
120 #define B(row, str) L(row, str); R(row, str)
121         B(8, "echo response");
122         B(9, "echo request");
123         B(10, "destination unreachable");
124         B(11, "redirect");
125         B(12, "time-to-live exceeded");
126         B(13, "parameter problem");
127         B(14, "neighbor solicitation");
128         B(15, "neighbor advertisment");
129         L(16, "router advertisement");  R(16, "router solicitation");
130 #undef L
131 #undef R
132 #undef B
133 }
134
135 static void
136 domode(struct icmp6stat *ret)
137 {
138         const struct icmp6stat *sub;
139         int i, divisor = 1;
140
141         switch(currentmode) {
142         case display_RATE:
143                 sub = &oldstat;
144                 divisor = naptime;
145                 break;
146         case display_DELTA:
147                 sub = &oldstat;
148                 break;
149         case display_SINCE:
150                 sub = &initstat;
151                 break;
152         default:
153                 *ret = icmp6stat;
154                 return;
155         }
156 #define DO(stat) ret->stat = (icmp6stat.stat - sub->stat) / divisor
157         DO(icp6s_error);
158         DO(icp6s_tooshort);
159         DO(icp6s_canterror);
160         for (i = 0; i <= ICMP6_MAXTYPE; i++) {
161                 DO(icp6s_outhist[i]);
162         }
163         DO(icp6s_badcode);
164         DO(icp6s_tooshort);
165         DO(icp6s_checksum);
166         DO(icp6s_badlen);
167         DO(icp6s_reflect);
168         for (i = 0; i <= ICMP6_MAXTYPE; i++) {
169                 DO(icp6s_inhist[i]);
170         }
171 #undef DO
172 }
173
174 void
175 showicmp6(void)
176 {
177         struct icmp6stat stats;
178         u_long totalin, totalout;
179         int i;
180
181         memset(&stats, 0, sizeof stats);
182         domode(&stats);
183         for (i = totalin = totalout = 0; i <= ICMP6_MAXTYPE; i++) {
184                 totalin += stats.icp6s_inhist[i];
185                 totalout += stats.icp6s_outhist[i];
186         }
187         totalin += stats.icp6s_badcode + stats.icp6s_badlen +
188                 stats.icp6s_checksum + stats.icp6s_tooshort;
189         mvwprintw(wnd, 1, 0, "%9lu", totalin);
190         mvwprintw(wnd, 1, 35, "%9lu", totalout);
191
192 #define DO(stat, row, col) \
193         mvwprintw(wnd, row, col, "%9lu", stats.stat)
194
195         DO(icp6s_badcode, 2, 0);
196         DO(icp6s_badlen, 3, 0);
197         DO(icp6s_checksum, 4, 0);
198         DO(icp6s_tooshort, 5, 0);
199         DO(icp6s_error, 2, 35);
200         DO(icp6s_tooshort, 3, 35);
201         DO(icp6s_canterror, 4, 35);
202         DO(icp6s_reflect, 5, 35);
203 #define DO2(type, row) DO(icp6s_inhist[type], row, 0); DO(icp6s_outhist[type], \
204                                                          row, 35)
205         DO2(ICMP6_ECHO_REPLY, 8);
206         DO2(ICMP6_ECHO_REQUEST, 9);
207         DO2(ICMP6_DST_UNREACH, 10);
208         DO2(ND_REDIRECT, 11);
209         DO2(ICMP6_TIME_EXCEEDED, 12);
210         DO2(ICMP6_PARAM_PROB, 13);
211         DO2(ND_NEIGHBOR_SOLICIT, 14);
212         DO2(ND_NEIGHBOR_ADVERT, 15);
213         DO(icp6s_inhist[ND_ROUTER_SOLICIT], 16, 0);
214         DO(icp6s_outhist[ND_ROUTER_ADVERT], 16, 35);
215 #undef DO
216 #undef DO2
217 }
218
219 int
220 initicmp6(void)
221 {
222         size_t len;
223         int name[4];
224
225         name[0] = CTL_NET;
226         name[1] = PF_INET6;
227         name[2] = IPPROTO_ICMPV6;
228         name[3] = ICMPV6CTL_STATS;
229
230         len = 0;
231         if (sysctl(name, 4, 0, &len, 0, 0) < 0) {
232                 error("sysctl getting icmp6stat size failed");
233                 return 0;
234         }
235         if (len > sizeof icmp6stat) {
236                 error("icmp6stat structure has grown--recompile systat!");
237                 return 0;
238         }
239         if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
240                 error("sysctl getting icmp6stat size failed");
241                 return 0;
242         }
243         oldstat = initstat;
244         return 1;
245 }
246
247 void
248 reseticmp6(void)
249 {
250         size_t len;
251         int name[4];
252
253         name[0] = CTL_NET;
254         name[1] = PF_INET6;
255         name[2] = IPPROTO_ICMPV6;
256         name[3] = ICMPV6CTL_STATS;
257
258         len = sizeof initstat;
259         if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
260                 error("sysctl getting icmp6stat size failed");
261         }
262         oldstat = initstat;
263 }
264
265 void
266 fetchicmp6(void)
267 {
268         int name[4];
269         size_t len;
270
271         oldstat = icmp6stat;
272         name[0] = CTL_NET;
273         name[1] = PF_INET6;
274         name[2] = IPPROTO_ICMPV6;
275         name[3] = ICMPV6CTL_STATS;
276         len = sizeof icmp6stat;
277
278         if (sysctl(name, 4, &icmp6stat, &len, 0, 0) < 0)
279                 return;
280 }
281
282 #endif