]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/netstat/ipsec.c
This commit was generated by cvs2svn to compensate for changes in r103373,
[FreeBSD/FreeBSD.git] / usr.bin / netstat / ipsec.c
1 /*      $NetBSD: inet.c,v 1.35.2.1 1999/04/29 14:57:08 perry Exp $      */
2 /*      $KAME: ipsec.c,v 1.25 2001/03/12 09:04:39 itojun Exp $  */
3
4 /*
5  * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
6  * All rights reserved.
7  * 
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the project nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  * 
20  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32
33 /*
34  * Copyright (c) 1983, 1988, 1993
35  *      The Regents of the University of California.  All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  * 3. All advertising materials mentioning features or use of this software
46  *    must display the following acknowledgement:
47  *      This product includes software developed by the University of
48  *      California, Berkeley and its contributors.
49  * 4. Neither the name of the University nor the names of its contributors
50  *    may be used to endorse or promote products derived from this software
51  *    without specific prior written permission.
52  *
53  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63  * SUCH DAMAGE.
64  */
65
66 #include <sys/cdefs.h>
67 #ifndef lint
68 /*
69 static char sccsid[] = "@(#)inet.c      8.5 (Berkeley) 5/24/95";
70 */
71 static const char rcsid[] =
72   "$FreeBSD$";
73 #endif /* not lint */
74
75 #include <sys/param.h>
76 #include <sys/queue.h>
77 #include <sys/socket.h>
78
79 #include <netinet/in.h>
80
81 #ifdef IPSEC
82 #include <netinet6/ipsec.h>
83 #include <netkey/keysock.h>
84 #endif
85
86 #include <stdio.h>
87 #include <string.h>
88 #include <unistd.h>
89 #include "netstat.h"
90
91 /*
92  * portability issues:
93  * - bsdi[34] uses PLURAL(), not plural().
94  * - freebsd2 can't print "unsigned long long" properly.
95  */
96 /*
97  * XXX see PORTABILITY for the twist
98  */
99 #define LLU     "%llu"
100 #define CAST    unsigned long long
101
102 #ifdef IPSEC 
103 struct val2str {
104         int val;
105         const char *str;
106 };
107
108 static struct val2str ipsec_ahnames[] = {
109         { SADB_AALG_NONE, "none", },
110         { SADB_AALG_MD5HMAC, "hmac-md5", },
111         { SADB_AALG_SHA1HMAC, "hmac-sha1", },
112         { SADB_X_AALG_MD5, "md5", },
113         { SADB_X_AALG_SHA, "sha", },
114         { SADB_X_AALG_NULL, "null", },
115 #ifdef SADB_X_AALG_SHA2_256
116         { SADB_X_AALG_SHA2_256, "hmac-sha2-256", },
117 #endif
118 #ifdef SADB_X_AALG_SHA2_384
119         { SADB_X_AALG_SHA2_384, "hmac-sha2-384", },
120 #endif
121 #ifdef SADB_X_AALG_SHA2_512
122         { SADB_X_AALG_SHA2_512, "hmac-sha2-512", },
123 #endif
124         { -1, NULL },
125 };
126
127 static struct val2str ipsec_espnames[] = {
128         { SADB_EALG_NONE, "none", },
129         { SADB_EALG_DESCBC, "des-cbc", },
130         { SADB_EALG_3DESCBC, "3des-cbc", },
131         { SADB_EALG_NULL, "null", },
132 #ifdef SADB_X_EALG_RC5CBC
133         { SADB_X_EALG_RC5CBC, "rc5-cbc", },
134 #endif
135         { SADB_X_EALG_CAST128CBC, "cast128-cbc", },
136         { SADB_X_EALG_BLOWFISHCBC, "blowfish-cbc", },
137 #ifdef SADB_X_EALG_RIJNDAELCBC
138         { SADB_X_EALG_RIJNDAELCBC, "rijndael-cbc", },
139 #endif
140         { -1, NULL },
141 };
142
143 static struct val2str ipsec_compnames[] = {
144         { SADB_X_CALG_NONE, "none", },
145         { SADB_X_CALG_OUI, "oui", },
146         { SADB_X_CALG_DEFLATE, "deflate", },
147         { SADB_X_CALG_LZS, "lzs", },
148         { -1, NULL },
149 };
150
151 static const char *pfkey_msgtypenames[] = {
152         "reserved", "getspi", "update", "add", "delete",
153         "get", "acquire", "register", "expire", "flush",
154         "dump", "x_promisc", "x_pchange", "x_spdupdate", "x_spdadd",
155         "x_spddelete", "x_spdget", "x_spdacquire", "x_spddump", "x_spdflush",
156         "x_spdsetidx", "x_spdexpire", "x_spddelete2"
157 };
158
159 static struct ipsecstat ipsecstat;
160
161 static void print_ipsecstats (void);
162 static const char *pfkey_msgtype_names (int);
163 static void ipsec_hist (const u_quad_t *, size_t, const struct val2str *,
164         const char *);
165
166 /*
167  * Dump IPSEC statistics structure.
168  */
169 static void
170 ipsec_hist(const u_quad_t *hist,
171            size_t histmax,
172            const struct val2str *name,
173            const char *title)
174 {
175         int first;
176         size_t proto;
177         const struct val2str *p;
178
179         first = 1;
180         for (proto = 0; proto < histmax; proto++) {
181                 if (hist[proto] <= 0)
182                         continue;
183                 if (first) {
184                         printf("\t%s histogram:\n", title);
185                         first = 0;
186                 }
187                 for (p = name; p && p->str; p++) {
188                         if (p->val == (int)proto)
189                                 break;
190                 }
191                 if (p && p->str) {
192                         printf("\t\t%s: " LLU "\n", p->str, (CAST)hist[proto]);
193                 } else {
194                         printf("\t\t#%ld: " LLU "\n", (long)proto,
195                             (CAST)hist[proto]);
196                 }
197         }
198 }
199
200 static void
201 print_ipsecstats(void)
202 {
203 #define p(f, m) if (ipsecstat.f || sflag <= 1) \
204     printf(m, (CAST)ipsecstat.f, plural(ipsecstat.f))
205 #define hist(f, n, t) \
206     ipsec_hist((f), sizeof(f)/sizeof(f[0]), (n), (t));
207
208         p(in_success, "\t" LLU " inbound packet%s processed successfully\n");
209         p(in_polvio, "\t" LLU " inbound packet%s violated process security "
210                 "policy\n");
211         p(in_nosa, "\t" LLU " inbound packet%s with no SA available\n");
212         p(in_inval, "\t" LLU " invalid inbound packet%s\n");
213         p(in_nomem, "\t" LLU " inbound packet%s failed due to insufficient memory\n");
214         p(in_badspi, "\t" LLU " inbound packet%s failed getting SPI\n");
215         p(in_ahreplay, "\t" LLU " inbound packet%s failed on AH replay check\n");
216         p(in_espreplay, "\t" LLU " inbound packet%s failed on ESP replay check\n");
217         p(in_ahauthsucc, "\t" LLU " inbound packet%s considered authentic\n");
218         p(in_ahauthfail, "\t" LLU " inbound packet%s failed on authentication\n");
219         hist(ipsecstat.in_ahhist, ipsec_ahnames, "AH input");
220         hist(ipsecstat.in_esphist, ipsec_espnames, "ESP input");
221         hist(ipsecstat.in_comphist, ipsec_compnames, "IPComp input");
222
223         p(out_success, "\t" LLU " outbound packet%s processed successfully\n");
224         p(out_polvio, "\t" LLU " outbound packet%s violated process security "
225                 "policy\n");
226         p(out_nosa, "\t" LLU " outbound packet%s with no SA available\n");
227         p(out_inval, "\t" LLU " invalid outbound packet%s\n");
228         p(out_nomem, "\t" LLU " outbound packet%s failed due to insufficient memory\n");
229         p(out_noroute, "\t" LLU " outbound packet%s with no route\n");
230         hist(ipsecstat.out_ahhist, ipsec_ahnames, "AH output");
231         hist(ipsecstat.out_esphist, ipsec_espnames, "ESP output");
232         hist(ipsecstat.out_comphist, ipsec_compnames, "IPComp output");
233 #undef p
234 #undef hist
235 }
236
237 void
238 ipsec_stats(u_long off __unused, const char *name, int af1 __unused)
239 {
240         if (off == 0)
241                 return;
242         printf ("%s:\n", name);
243         kread(off, (char *)&ipsecstat, sizeof (ipsecstat));
244
245         print_ipsecstats();
246 }
247
248 static const char *
249 pfkey_msgtype_names(int x)
250 {
251         const int max =
252             sizeof(pfkey_msgtypenames)/sizeof(pfkey_msgtypenames[0]);
253         static char buf[10];
254
255         if (x < max && pfkey_msgtypenames[x])
256                 return pfkey_msgtypenames[x];
257         snprintf(buf, sizeof(buf), "#%d", x);
258         return buf;
259 }
260
261 void
262 pfkey_stats(u_long off __unused, const char *name, int af1 __unused)
263 {
264         struct pfkeystat pfkeystat;
265         unsigned first, type;
266
267         if (off == 0)
268                 return;
269         printf ("%s:\n", name);
270         kread(off, (char *)&pfkeystat, sizeof(pfkeystat));
271
272 #define p(f, m) if (pfkeystat.f || sflag <= 1) \
273     printf(m, (CAST)pfkeystat.f, plural(pfkeystat.f))
274
275         /* kernel -> userland */
276         p(out_total, "\t" LLU " request%s sent to userland\n");
277         p(out_bytes, "\t" LLU " byte%s sent to userland\n");
278         for (first = 1, type = 0;
279              type < sizeof(pfkeystat.out_msgtype)/sizeof(pfkeystat.out_msgtype[0]);
280              type++) {
281                 if (pfkeystat.out_msgtype[type] <= 0)
282                         continue;
283                 if (first) {
284                         printf("\thistogram by message type:\n");
285                         first = 0;
286                 }
287                 printf("\t\t%s: " LLU "\n", pfkey_msgtype_names(type),
288                         (CAST)pfkeystat.out_msgtype[type]);
289         }
290         p(out_invlen, "\t" LLU " message%s with invalid length field\n");
291         p(out_invver, "\t" LLU " message%s with invalid version field\n");
292         p(out_invmsgtype, "\t" LLU " message%s with invalid message type field\n");
293         p(out_tooshort, "\t" LLU " message%s too short\n");
294         p(out_nomem, "\t" LLU " message%s with memory allocation failure\n");
295         p(out_dupext, "\t" LLU " message%s with duplicate extension\n");
296         p(out_invexttype, "\t" LLU " message%s with invalid extension type\n");
297         p(out_invsatype, "\t" LLU " message%s with invalid sa type\n");
298         p(out_invaddr, "\t" LLU " message%s with invalid address extension\n");
299
300         /* userland -> kernel */
301         p(in_total, "\t" LLU " request%s sent from userland\n");
302         p(in_bytes, "\t" LLU " byte%s sent from userland\n");
303         for (first = 1, type = 0;
304              type < sizeof(pfkeystat.in_msgtype)/sizeof(pfkeystat.in_msgtype[0]);
305              type++) {
306                 if (pfkeystat.in_msgtype[type] <= 0)
307                         continue;
308                 if (first) {
309                         printf("\thistogram by message type:\n");
310                         first = 0;
311                 }
312                 printf("\t\t%s: " LLU "\n", pfkey_msgtype_names(type),
313                         (CAST)pfkeystat.in_msgtype[type]);
314         }
315         p(in_msgtarget[KEY_SENDUP_ONE],
316             "\t" LLU " message%s toward single socket\n");
317         p(in_msgtarget[KEY_SENDUP_ALL],
318             "\t" LLU " message%s toward all sockets\n");
319         p(in_msgtarget[KEY_SENDUP_REGISTERED],
320             "\t" LLU " message%s toward registered sockets\n");
321         p(in_nomem, "\t" LLU " message%s with memory allocation failure\n");
322 #undef p
323 }
324 #endif /*IPSEC*/