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