Initial import of binutils 2.22 on the new vendor branch
[dragonfly.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  * @(#)mbufs.c     8.1 (Berkeley) 6/6/93
34  * $FreeBSD: src/usr.bin/systat/icmp6.c,v 1.3 2006/04/30 04:47:23 bde Exp $
35  * $DragonFly: src/usr.bin/systat/icmp6.c,v 1.3 2008/10/16 01:52:33 swildner Exp $
36  */
37
38 #include <sys/cdefs.h>
39
40 #ifdef INET6
41 #include <sys/param.h>
42 #include <sys/types.h>
43 #include <sys/socket.h>
44 #include <sys/sysctl.h>
45
46 #include <netinet/in.h>
47 #include <netinet/icmp6.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 icmp6stat icmp6stat, initstat, oldstat;
57
58 /*-
59 --0         1         2         3         4         5         6         7
60 --0123456789012345678901234567890123456789012345678901234567890123456789012345
61 00          ICMPv6 Input                       ICMPv6 Output
62 01999999999 total messages           999999999 total messages
63 02999999999 with bad code            999999999 errors generated
64 03999999999 with bad length          999999999 suppressed - original too short
65 04999999999 with bad checksum        999999999 suppressed - original was ICMP
66 05999999999 with insufficient data   999999999 responses sent
67 06
68 07          Input Histogram                    Output Histogram
69 08999999999 echo response            999999999 echo response
70 09999999999 echo request             999999999 echo request
71 10999999999 destination unreachable  999999999 destination unreachable
72 11999999999 redirect                 999999999 redirect
73 12999999999 time-to-live exceeded    999999999 time-to-line exceeded
74 13999999999 parameter problem        999999999 parameter problem
75 14999999999 neighbor solicitation    999999999 neighbor solicitation
76 15999999999 neighbor advertisment    999999999 neighbor advertisment
77 16999999999 router advertisement     999999999 router solicitation
78 17
79 18
80 --0123456789012345678901234567890123456789012345678901234567890123456789012345
81 --0         1         2         3         4         5         6         7
82 */
83
84 WINDOW *
85 openicmp6(void)
86 {
87         return (subwin(stdscr, LINES-4-1, 0, 4, 0));
88 }
89
90 void
91 closeicmp6(WINDOW *w)
92 {
93         if (w == NULL)
94                 return;
95         wclear(w);
96         wrefresh(w);
97         delwin(w);
98 }
99
100 void
101 labelicmp6(void)
102 {
103         wmove(wnd, 0, 0); wclrtoeol(wnd);
104 #define L(row, str) mvwprintw(wnd, row, 10, str)
105 #define R(row, str) mvwprintw(wnd, row, 45, str);
106         L(1, "ICMPv6 Input");           R(1, "ICMPv6 Output");
107         L(2, "total messages");         R(2, "total messages");
108         L(3, "with bad code");          R(3, "errors generated");
109         L(4, "with bad length");        R(4, "suppressed - original too short");
110         L(5, "with bad checksum");      R(5, "suppressed - original was ICMP");
111         L(6, "with insufficient data"); R(6, "responses sent");
112
113         L(8, "Input Histogram");        R(8, "Output Histogram");
114 #define B(row, str) L(row, str); R(row, str)
115         B(9, "echo response");
116         B(10, "echo request");
117         B(11, "destination unreachable");
118         B(12, "redirect");
119         B(13, "time-to-live exceeded");
120         B(14, "parameter problem");
121         B(15, "neighbor solicitation");
122         B(16, "neighbor advertisement");
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 icmp6stat *ret)
131 {
132         const struct icmp6stat *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 = icmp6stat;
148                 return;
149         }
150 #define DO(stat) ret->stat = (icmp6stat.stat - sub->stat) / divisor
151         DO(icp6s_error);
152         DO(icp6s_tooshort);
153         DO(icp6s_canterror);
154         for (i = 0; i <= ICMP6_MAXTYPE; i++) {
155                 DO(icp6s_outhist[i]);
156         }
157         DO(icp6s_badcode);
158         DO(icp6s_tooshort);
159         DO(icp6s_checksum);
160         DO(icp6s_badlen);
161         DO(icp6s_reflect);
162         for (i = 0; i <= ICMP6_MAXTYPE; i++) {
163                 DO(icp6s_inhist[i]);
164         }
165 #undef DO
166 }
167
168 void
169 showicmp6(void)
170 {
171         struct icmp6stat stats;
172         u_long totalin, totalout;
173         int i;
174
175         memset(&stats, 0, sizeof stats);
176         domode(&stats);
177         for (i = totalin = totalout = 0; i <= ICMP6_MAXTYPE; i++) {
178                 totalin += stats.icp6s_inhist[i];
179                 totalout += stats.icp6s_outhist[i];
180         }
181         totalin += stats.icp6s_badcode + stats.icp6s_badlen +
182                 stats.icp6s_checksum + stats.icp6s_tooshort;
183         mvwprintw(wnd, 2, 0, "%9lu", totalin);
184         mvwprintw(wnd, 2, 35, "%9lu", totalout);
185
186 #define DO(stat, row, col) \
187         mvwprintw(wnd, row, col, "%9lu", stats.stat)
188
189         DO(icp6s_badcode, 3, 0);
190         DO(icp6s_badlen, 4, 0);
191         DO(icp6s_checksum, 5, 0);
192         DO(icp6s_tooshort, 6, 0);
193         DO(icp6s_error, 3, 35);
194         DO(icp6s_tooshort, 4, 35);
195         DO(icp6s_canterror, 5, 35);
196         DO(icp6s_reflect, 6, 35);
197 #define DO2(type, row) DO(icp6s_inhist[type], row, 0); DO(icp6s_outhist[type], \
198                                                          row, 35)
199         DO2(ICMP6_ECHO_REPLY, 9);
200         DO2(ICMP6_ECHO_REQUEST, 10);
201         DO2(ICMP6_DST_UNREACH, 11);
202         DO2(ND_REDIRECT, 12);
203         DO2(ICMP6_TIME_EXCEEDED, 13);
204         DO2(ICMP6_PARAM_PROB, 14);
205         DO2(ND_NEIGHBOR_SOLICIT, 15);
206         DO2(ND_NEIGHBOR_ADVERT, 16);
207         DO(icp6s_inhist[ND_ROUTER_SOLICIT], 17, 0);
208         DO(icp6s_outhist[ND_ROUTER_ADVERT], 17, 35);
209 #undef DO
210 #undef DO2
211 }
212
213 int
214 initicmp6(void)
215 {
216         size_t len;
217         int name[4];
218
219         name[0] = CTL_NET;
220         name[1] = PF_INET6;
221         name[2] = IPPROTO_ICMPV6;
222         name[3] = ICMPV6CTL_STATS;
223
224         len = 0;
225         if (sysctl(name, 4, 0, &len, 0, 0) < 0) {
226                 error("sysctl getting icmp6stat size failed");
227                 return 0;
228         }
229         if (len > sizeof icmp6stat) {
230                 error("icmp6stat structure has grown--recompile systat!");
231                 return 0;
232         }
233         if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
234                 error("sysctl getting icmp6stat size failed");
235                 return 0;
236         }
237         oldstat = initstat;
238         return 1;
239 }
240
241 void
242 reseticmp6(void)
243 {
244         size_t len;
245         int name[4];
246
247         name[0] = CTL_NET;
248         name[1] = PF_INET6;
249         name[2] = IPPROTO_ICMPV6;
250         name[3] = ICMPV6CTL_STATS;
251
252         len = sizeof initstat;
253         if (sysctl(name, 4, &initstat, &len, 0, 0) < 0) {
254                 error("sysctl getting icmp6stat size failed");
255         }
256         oldstat = initstat;
257 }
258
259 void
260 fetchicmp6(void)
261 {
262         int name[4];
263         size_t len;
264
265         oldstat = icmp6stat;
266         name[0] = CTL_NET;
267         name[1] = PF_INET6;
268         name[2] = IPPROTO_ICMPV6;
269         name[3] = ICMPV6CTL_STATS;
270         len = sizeof icmp6stat;
271
272         if (sysctl(name, 4, &icmp6stat, &len, 0, 0) < 0)
273                 return;
274 }
275
276 #endif