]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - usr.bin/systat/icmp6.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.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  * 4. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #include <sys/cdefs.h>
31
32 __FBSDID("$FreeBSD$");
33
34 #ifdef lint
35 static char sccsid[] = "@(#)mbufs.c     8.1 (Berkeley) 6/6/93";
36 #endif
37
38 /* From:
39         "Id: mbufs.c,v 1.5 1997/02/24 20:59:03 wollman Exp"
40 */
41
42 #ifdef INET6
43 #include <sys/param.h>
44 #include <sys/types.h>
45 #include <sys/socket.h>
46 #include <sys/sysctl.h>
47
48 #include <netinet/in.h>
49 #include <netinet/icmp6.h>
50
51 #include <stdlib.h>
52 #include <string.h>
53 #include <paths.h>
54 #include "systat.h"
55 #include "extern.h"
56 #include "mode.h"
57
58 static struct icmp6stat icmp6stat, initstat, oldstat;
59
60 /*-
61 --0         1         2         3         4         5         6         7
62 --0123456789012345678901234567890123456789012345678901234567890123456789012345
63 00          ICMPv6 Input                       ICMPv6 Output
64 01999999999 total messages           999999999 total messages
65 02999999999 with bad code            999999999 errors generated
66 03999999999 with bad length          999999999 suppressed - original too short
67 04999999999 with bad checksum        999999999 suppressed - original was ICMP
68 05999999999 with insufficient data   999999999 responses sent
69 06
70 07          Input Histogram                    Output Histogram
71 08999999999 echo response            999999999 echo response
72 09999999999 echo request             999999999 echo request
73 10999999999 destination unreachable  999999999 destination unreachable
74 11999999999 redirect                 999999999 redirect
75 12999999999 time-to-live exceeded    999999999 time-to-line exceeded
76 13999999999 parameter problem        999999999 parameter problem
77 14999999999 neighbor solicitation    999999999 neighbor solicitation
78 15999999999 neighbor advertisment    999999999 neighbor advertisment
79 16999999999 router advertisement     999999999 router solicitation
80 17
81 18
82 --0123456789012345678901234567890123456789012345678901234567890123456789012345
83 --0         1         2         3         4         5         6         7
84 */
85
86 WINDOW *
87 openicmp6(void)
88 {
89         return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0));
90 }
91
92 void
93 closeicmp6(WINDOW *w)
94 {
95         if (w == NULL)
96                 return;
97         wclear(w);
98         wrefresh(w);
99         delwin(w);
100 }
101
102 void
103 labelicmp6(void)
104 {
105         wmove(wnd, 0, 0); wclrtoeol(wnd);
106 #define L(row, str) mvwprintw(wnd, row, 10, str)
107 #define R(row, str) mvwprintw(wnd, row, 45, str);
108         L(0, "ICMPv6 Input");           R(0, "ICMPv6 Output");
109         L(1, "total messages");         R(1, "total messages");
110         L(2, "with bad code");          R(2, "errors generated");
111         L(3, "with bad length");        R(3, "suppressed - original too short");
112         L(4, "with bad checksum");      R(4, "suppressed - original was ICMP");
113         L(5, "with insufficient data"); R(5, "responses sent");
114
115         L(7, "Input Histogram");        R(7, "Output Histogram");
116 #define B(row, str) L(row, str); R(row, str)
117         B(8, "echo response");
118         B(9, "echo request");
119         B(10, "destination unreachable");
120         B(11, "redirect");
121         B(12, "time-to-live exceeded");
122         B(13, "parameter problem");
123         B(14, "neighbor solicitation");
124         B(15, "neighbor advertisment");
125         L(16, "router advertisement");  R(16, "router solicitation");
126 #undef L
127 #undef R
128 #undef B
129 }
130
131 static void
132 domode(struct icmp6stat *ret)
133 {
134         const struct icmp6stat *sub;
135         int i, divisor = 1;
136
137         switch(currentmode) {
138         case display_RATE:
139                 sub = &oldstat;
140                 divisor = (delay > 1000000) ? delay / 1000000 : 1;
141                 break;
142         case display_DELTA:
143                 sub = &oldstat;
144                 break;
145         case display_SINCE:
146                 sub = &initstat;
147                 break;
148         default:
149                 *ret = icmp6stat;
150                 return;
151         }
152 #define DO(stat) ret->stat = (icmp6stat.stat - sub->stat) / divisor
153         DO(icp6s_error);
154         DO(icp6s_tooshort);
155         DO(icp6s_canterror);
156         for (i = 0; i <= ICMP6_MAXTYPE; i++) {
157                 DO(icp6s_outhist[i]);
158         }
159         DO(icp6s_badcode);
160         DO(icp6s_tooshort);
161         DO(icp6s_checksum);
162         DO(icp6s_badlen);
163         DO(icp6s_reflect);
164         for (i = 0; i <= ICMP6_MAXTYPE; i++) {
165                 DO(icp6s_inhist[i]);
166         }
167 #undef DO
168 }
169
170 void
171 showicmp6(void)
172 {
173         struct icmp6stat 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 <= ICMP6_MAXTYPE; i++) {
180                 totalin += stats.icp6s_inhist[i];
181                 totalout += stats.icp6s_outhist[i];
182         }
183         totalin += stats.icp6s_badcode + stats.icp6s_badlen +
184                 stats.icp6s_checksum + stats.icp6s_tooshort;
185         mvwprintw(wnd, 1, 0, "%9lu", totalin);
186         mvwprintw(wnd, 1, 35, "%9lu", totalout);
187
188 #define DO(stat, row, col) \
189         mvwprintw(wnd, row, col, "%9lu", stats.stat)
190
191         DO(icp6s_badcode, 2, 0);
192         DO(icp6s_badlen, 3, 0);
193         DO(icp6s_checksum, 4, 0);
194         DO(icp6s_tooshort, 5, 0);
195         DO(icp6s_error, 2, 35);
196         DO(icp6s_tooshort, 3, 35);
197         DO(icp6s_canterror, 4, 35);
198         DO(icp6s_reflect, 5, 35);
199 #define DO2(type, row) DO(icp6s_inhist[type], row, 0); DO(icp6s_outhist[type], \
200                                                          row, 35)
201         DO2(ICMP6_ECHO_REPLY, 8);
202         DO2(ICMP6_ECHO_REQUEST, 9);
203         DO2(ICMP6_DST_UNREACH, 10);
204         DO2(ND_REDIRECT, 11);
205         DO2(ICMP6_TIME_EXCEEDED, 12);
206         DO2(ICMP6_PARAM_PROB, 13);
207         DO2(ND_NEIGHBOR_SOLICIT, 14);
208         DO2(ND_NEIGHBOR_ADVERT, 15);
209         DO(icp6s_inhist[ND_ROUTER_SOLICIT], 16, 0);
210         DO(icp6s_outhist[ND_ROUTER_ADVERT], 16, 35);
211 #undef DO
212 #undef DO2
213 }
214
215 int
216 initicmp6(void)
217 {
218         size_t len;
219         int name[4];
220
221         name[0] = CTL_NET;
222         name[1] = PF_INET6;
223         name[2] = IPPROTO_ICMPV6;
224         name[3] = ICMPV6CTL_STATS;
225
226         len = 0;
227         if (sysctl(name, 4, 0, &len, 0, 0) < 0) {
228                 error("sysctl getting icmp6stat size failed");
229                 return 0;
230         }
231         if (len > sizeof icmp6stat) {
232                 error("icmp6stat structure has grown--recompile systat!");
233                 return 0;
234         }
235         if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
236                 error("sysctl getting icmp6stat size failed");
237                 return 0;
238         }
239         oldstat = initstat;
240         return 1;
241 }
242
243 void
244 reseticmp6(void)
245 {
246         size_t len;
247         int name[4];
248
249         name[0] = CTL_NET;
250         name[1] = PF_INET6;
251         name[2] = IPPROTO_ICMPV6;
252         name[3] = ICMPV6CTL_STATS;
253
254         len = sizeof initstat;
255         if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
256                 error("sysctl getting icmp6stat size failed");
257         }
258         oldstat = initstat;
259 }
260
261 void
262 fetchicmp6(void)
263 {
264         int name[4];
265         size_t len;
266
267         oldstat = icmp6stat;
268         name[0] = CTL_NET;
269         name[1] = PF_INET6;
270         name[2] = IPPROTO_ICMPV6;
271         name[3] = ICMPV6CTL_STATS;
272         len = sizeof icmp6stat;
273
274         if (sysctl(name, 4, &icmp6stat, &len, 0, 0) < 0)
275                 return;
276 }
277
278 #endif