1 | #include <machine/rtems-bsd-user-space.h> |
---|
2 | |
---|
3 | /* $NetBSD: pfkey_dump.c,v 1.18 2010/12/03 14:32:52 tteras Exp $ */ |
---|
4 | |
---|
5 | /* $KAME: pfkey_dump.c,v 1.45 2003/09/08 10:14:56 itojun Exp $ */ |
---|
6 | |
---|
7 | /* |
---|
8 | * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. |
---|
9 | * All rights reserved. |
---|
10 | * |
---|
11 | * Redistribution and use in source and binary forms, with or without |
---|
12 | * modification, are permitted provided that the following conditions |
---|
13 | * are met: |
---|
14 | * 1. Redistributions of source code must retain the above copyright |
---|
15 | * notice, this list of conditions and the following disclaimer. |
---|
16 | * 2. Redistributions in binary form must reproduce the above copyright |
---|
17 | * notice, this list of conditions and the following disclaimer in the |
---|
18 | * documentation and/or other materials provided with the distribution. |
---|
19 | * 3. Neither the name of the project nor the names of its contributors |
---|
20 | * may be used to endorse or promote products derived from this software |
---|
21 | * without specific prior written permission. |
---|
22 | * |
---|
23 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND |
---|
24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE |
---|
27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
---|
28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
---|
29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
---|
30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
---|
31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
---|
32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
---|
33 | * SUCH DAMAGE. |
---|
34 | */ |
---|
35 | |
---|
36 | #ifdef HAVE_CONFIG_H |
---|
37 | #include "config.h" |
---|
38 | #endif |
---|
39 | |
---|
40 | #include <sys/types.h> |
---|
41 | #include <sys/param.h> |
---|
42 | #include <sys/socket.h> |
---|
43 | #include PATH_IPSEC_H |
---|
44 | #include <net/pfkeyv2.h> |
---|
45 | |
---|
46 | #include <netinet/in.h> |
---|
47 | #include <arpa/inet.h> |
---|
48 | |
---|
49 | #include <stdlib.h> |
---|
50 | #include <unistd.h> |
---|
51 | #include <stdio.h> |
---|
52 | #include <string.h> |
---|
53 | #include <time.h> |
---|
54 | #include <netdb.h> |
---|
55 | |
---|
56 | #include "ipsec_strerror.h" |
---|
57 | #include "libpfkey.h" |
---|
58 | |
---|
59 | /* cope with old kame headers - ugly */ |
---|
60 | #ifndef SADB_X_AALG_MD5 |
---|
61 | #define SADB_X_AALG_MD5 SADB_AALG_MD5 |
---|
62 | #endif |
---|
63 | #ifndef SADB_X_AALG_SHA |
---|
64 | #define SADB_X_AALG_SHA SADB_AALG_SHA |
---|
65 | #endif |
---|
66 | #ifndef SADB_X_AALG_NULL |
---|
67 | #define SADB_X_AALG_NULL SADB_AALG_NULL |
---|
68 | #endif |
---|
69 | |
---|
70 | #ifndef SADB_X_EALG_BLOWFISHCBC |
---|
71 | #define SADB_X_EALG_BLOWFISHCBC SADB_EALG_BLOWFISHCBC |
---|
72 | #endif |
---|
73 | #ifndef SADB_X_EALG_CAST128CBC |
---|
74 | #define SADB_X_EALG_CAST128CBC SADB_EALG_CAST128CBC |
---|
75 | #endif |
---|
76 | #ifndef SADB_X_EALG_RC5CBC |
---|
77 | #ifdef SADB_EALG_RC5CBC |
---|
78 | #define SADB_X_EALG_RC5CBC SADB_EALG_RC5CBC |
---|
79 | #endif |
---|
80 | #endif |
---|
81 | #if defined(SADB_X_EALG_AES) && ! defined(SADB_X_EALG_AESCBC) |
---|
82 | #define SADB_X_EALG_AESCBC SADB_X_EALG_AES |
---|
83 | #endif |
---|
84 | |
---|
85 | #define GETMSGSTR(str, num) \ |
---|
86 | do { \ |
---|
87 | /*CONSTCOND*/ \ |
---|
88 | if (sizeof((str)[0]) == 0 \ |
---|
89 | || num >= sizeof(str)/sizeof((str)[0])) \ |
---|
90 | printf("%u ", (num)); \ |
---|
91 | else if (strlen((str)[(num)]) == 0) \ |
---|
92 | printf("%u ", (num)); \ |
---|
93 | else \ |
---|
94 | printf("%s ", (str)[(num)]); \ |
---|
95 | } while (/*CONSTCOND*/0) |
---|
96 | |
---|
97 | #define GETMSGV2S(v2s, num) \ |
---|
98 | do { \ |
---|
99 | struct val2str *p; \ |
---|
100 | for (p = (v2s); p && p->str; p++) { \ |
---|
101 | if (p->val == (num)) \ |
---|
102 | break; \ |
---|
103 | } \ |
---|
104 | if (p && p->str) \ |
---|
105 | printf("%s ", p->str); \ |
---|
106 | else \ |
---|
107 | printf("%u ", (num)); \ |
---|
108 | } while (/*CONSTCOND*/0) |
---|
109 | |
---|
110 | static char *str_ipaddr __P((struct sockaddr *)); |
---|
111 | static char *str_ipport __P((struct sockaddr *)); |
---|
112 | static char *str_prefport __P((u_int, u_int, u_int, u_int)); |
---|
113 | static void str_upperspec __P((u_int, u_int, u_int)); |
---|
114 | static char *str_time __P((time_t)); |
---|
115 | static void str_lifetime_byte __P((struct sadb_lifetime *, char *)); |
---|
116 | static void pfkey_sadump1(struct sadb_msg *, int); |
---|
117 | static void pfkey_spdump1(struct sadb_msg *, int); |
---|
118 | |
---|
119 | struct val2str { |
---|
120 | int val; |
---|
121 | const char *str; |
---|
122 | }; |
---|
123 | |
---|
124 | /* |
---|
125 | * Must to be re-written about following strings. |
---|
126 | */ |
---|
127 | #ifndef __rtems__ |
---|
128 | static char *str_satype[] = { |
---|
129 | #else /* __rtems__ */ |
---|
130 | static const char *str_satype[] = { |
---|
131 | #endif /* __rtems__ */ |
---|
132 | "unspec", |
---|
133 | "unknown", |
---|
134 | "ah", |
---|
135 | "esp", |
---|
136 | "unknown", |
---|
137 | "rsvp", |
---|
138 | "ospfv2", |
---|
139 | "ripv2", |
---|
140 | "mip", |
---|
141 | "ipcomp", |
---|
142 | "policy", |
---|
143 | "tcp", |
---|
144 | }; |
---|
145 | |
---|
146 | #ifndef __rtems__ |
---|
147 | static char *str_mode[] = { |
---|
148 | #else /* __rtems__ */ |
---|
149 | static const char *str_mode[] = { |
---|
150 | #endif /* __rtems__ */ |
---|
151 | "any", |
---|
152 | "transport", |
---|
153 | "tunnel", |
---|
154 | }; |
---|
155 | |
---|
156 | #ifndef __rtems__ |
---|
157 | static char *str_state[] = { |
---|
158 | #else /* __rtems__ */ |
---|
159 | static const char *str_state[] = { |
---|
160 | #endif /* __rtems__ */ |
---|
161 | "larval", |
---|
162 | "mature", |
---|
163 | "dying", |
---|
164 | "dead", |
---|
165 | }; |
---|
166 | |
---|
167 | #ifndef __rtems__ |
---|
168 | static struct val2str str_alg_auth[] = { |
---|
169 | #else /* __rtems__ */ |
---|
170 | static const struct val2str str_alg_auth[] = { |
---|
171 | #endif /* __rtems__ */ |
---|
172 | { SADB_AALG_NONE, "none", }, |
---|
173 | { SADB_AALG_MD5HMAC, "hmac-md5", }, |
---|
174 | { SADB_AALG_SHA1HMAC, "hmac-sha1", }, |
---|
175 | { SADB_X_AALG_MD5, "md5", }, |
---|
176 | { SADB_X_AALG_SHA, "sha", }, |
---|
177 | { SADB_X_AALG_NULL, "null", }, |
---|
178 | #ifdef SADB_X_AALG_TCP_MD5 |
---|
179 | { SADB_X_AALG_TCP_MD5, "tcp-md5", }, |
---|
180 | #endif |
---|
181 | #ifdef SADB_X_AALG_SHA2_256 |
---|
182 | { SADB_X_AALG_SHA2_256, "hmac-sha256", }, |
---|
183 | #endif |
---|
184 | #ifdef SADB_X_AALG_SHA2_384 |
---|
185 | { SADB_X_AALG_SHA2_384, "hmac-sha384", }, |
---|
186 | #endif |
---|
187 | #ifdef SADB_X_AALG_SHA2_512 |
---|
188 | { SADB_X_AALG_SHA2_512, "hmac-sha512", }, |
---|
189 | #endif |
---|
190 | #ifdef SADB_X_AALG_RIPEMD160HMAC |
---|
191 | { SADB_X_AALG_RIPEMD160HMAC, "hmac-ripemd160", }, |
---|
192 | #endif |
---|
193 | #ifdef SADB_X_AALG_AES_XCBC_MAC |
---|
194 | { SADB_X_AALG_AES_XCBC_MAC, "aes-xcbc-mac", }, |
---|
195 | #endif |
---|
196 | { -1, NULL, }, |
---|
197 | }; |
---|
198 | |
---|
199 | #ifndef __rtems__ |
---|
200 | static struct val2str str_alg_enc[] = { |
---|
201 | #else /* __rtems__ */ |
---|
202 | static const struct val2str str_alg_enc[] = { |
---|
203 | #endif /* __rtems__ */ |
---|
204 | { SADB_EALG_NONE, "none", }, |
---|
205 | { SADB_EALG_DESCBC, "des-cbc", }, |
---|
206 | { SADB_EALG_3DESCBC, "3des-cbc", }, |
---|
207 | { SADB_EALG_NULL, "null", }, |
---|
208 | #ifdef SADB_X_EALG_RC5CBC |
---|
209 | { SADB_X_EALG_RC5CBC, "rc5-cbc", }, |
---|
210 | #endif |
---|
211 | { SADB_X_EALG_CAST128CBC, "cast128-cbc", }, |
---|
212 | { SADB_X_EALG_BLOWFISHCBC, "blowfish-cbc", }, |
---|
213 | #ifdef SADB_X_EALG_AESCBC |
---|
214 | { SADB_X_EALG_AESCBC, "aes-cbc", }, |
---|
215 | #endif |
---|
216 | #ifdef SADB_X_EALG_TWOFISHCBC |
---|
217 | { SADB_X_EALG_TWOFISHCBC, "twofish-cbc", }, |
---|
218 | #endif |
---|
219 | #ifdef SADB_X_EALG_AESCTR |
---|
220 | { SADB_X_EALG_AESCTR, "aes-ctr", }, |
---|
221 | #endif |
---|
222 | #ifdef SADB_X_EALG_CAMELLIACBC |
---|
223 | { SADB_X_EALG_CAMELLIACBC, "camellia-cbc", }, |
---|
224 | #endif |
---|
225 | { -1, NULL, }, |
---|
226 | }; |
---|
227 | |
---|
228 | #ifndef __rtems__ |
---|
229 | static struct val2str str_alg_comp[] = { |
---|
230 | #else /* __rtems__ */ |
---|
231 | static const struct val2str str_alg_comp[] = { |
---|
232 | #endif /* __rtems__ */ |
---|
233 | { SADB_X_CALG_NONE, "none", }, |
---|
234 | { SADB_X_CALG_OUI, "oui", }, |
---|
235 | { SADB_X_CALG_DEFLATE, "deflate", }, |
---|
236 | { SADB_X_CALG_LZS, "lzs", }, |
---|
237 | { -1, NULL, }, |
---|
238 | }; |
---|
239 | |
---|
240 | /* |
---|
241 | * dump SADB_MSG formated. For debugging, you should use kdebug_sadb(). |
---|
242 | */ |
---|
243 | |
---|
244 | void |
---|
245 | pfkey_sadump(m) |
---|
246 | struct sadb_msg *m; |
---|
247 | { |
---|
248 | pfkey_sadump1(m, 0); |
---|
249 | } |
---|
250 | |
---|
251 | void |
---|
252 | pfkey_sadump_withports(m) |
---|
253 | struct sadb_msg *m; |
---|
254 | { |
---|
255 | pfkey_sadump1(m, 1); |
---|
256 | } |
---|
257 | |
---|
258 | void |
---|
259 | pfkey_sadump1(m, withports) |
---|
260 | struct sadb_msg *m; |
---|
261 | int withports; |
---|
262 | { |
---|
263 | caddr_t mhp[SADB_EXT_MAX + 1]; |
---|
264 | struct sadb_sa *m_sa; |
---|
265 | struct sadb_x_sa2 *m_sa2; |
---|
266 | struct sadb_lifetime *m_lftc, *m_lfth, *m_lfts; |
---|
267 | struct sadb_address *m_saddr, *m_daddr; |
---|
268 | #ifdef notdef |
---|
269 | struct sadb_address *m_paddr; |
---|
270 | #endif |
---|
271 | struct sadb_key *m_auth, *m_enc; |
---|
272 | #ifdef notdef |
---|
273 | struct sadb_ident *m_sid, *m_did; |
---|
274 | struct sadb_sens *m_sens; |
---|
275 | #endif |
---|
276 | #ifdef SADB_X_EXT_SEC_CTX |
---|
277 | struct sadb_x_sec_ctx *m_sec_ctx; |
---|
278 | #endif |
---|
279 | #ifdef SADB_X_EXT_NAT_T_TYPE |
---|
280 | struct sadb_x_nat_t_type *natt_type; |
---|
281 | struct sadb_x_nat_t_port *natt_sport, *natt_dport; |
---|
282 | struct sadb_address *natt_oa; |
---|
283 | |
---|
284 | int use_natt = 0; |
---|
285 | #endif |
---|
286 | struct sockaddr *sa; |
---|
287 | |
---|
288 | /* check pfkey message. */ |
---|
289 | if (pfkey_align(m, mhp)) { |
---|
290 | printf("%s\n", ipsec_strerror()); |
---|
291 | return; |
---|
292 | } |
---|
293 | if (pfkey_check(mhp)) { |
---|
294 | printf("%s\n", ipsec_strerror()); |
---|
295 | return; |
---|
296 | } |
---|
297 | |
---|
298 | m_sa = (void *)mhp[SADB_EXT_SA]; |
---|
299 | m_sa2 = (void *)mhp[SADB_X_EXT_SA2]; |
---|
300 | m_lftc = (void *)mhp[SADB_EXT_LIFETIME_CURRENT]; |
---|
301 | m_lfth = (void *)mhp[SADB_EXT_LIFETIME_HARD]; |
---|
302 | m_lfts = (void *)mhp[SADB_EXT_LIFETIME_SOFT]; |
---|
303 | m_saddr = (void *)mhp[SADB_EXT_ADDRESS_SRC]; |
---|
304 | m_daddr = (void *)mhp[SADB_EXT_ADDRESS_DST]; |
---|
305 | #ifdef notdef |
---|
306 | m_paddr = (void *)mhp[SADB_EXT_ADDRESS_PROXY]; |
---|
307 | #endif |
---|
308 | m_auth = (void *)mhp[SADB_EXT_KEY_AUTH]; |
---|
309 | m_enc = (void *)mhp[SADB_EXT_KEY_ENCRYPT]; |
---|
310 | #ifdef notdef |
---|
311 | m_sid = (void *)mhp[SADB_EXT_IDENTITY_SRC]; |
---|
312 | m_did = (void *)mhp[SADB_EXT_IDENTITY_DST]; |
---|
313 | m_sens = (void *)mhp[SADB_EXT_SENSITIVITY]; |
---|
314 | #endif |
---|
315 | #ifdef SADB_X_EXT_SEC_CTX |
---|
316 | m_sec_ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX]; |
---|
317 | #endif |
---|
318 | #ifdef SADB_X_EXT_NAT_T_TYPE |
---|
319 | natt_type = (void *)mhp[SADB_X_EXT_NAT_T_TYPE]; |
---|
320 | natt_sport = (void *)mhp[SADB_X_EXT_NAT_T_SPORT]; |
---|
321 | natt_dport = (void *)mhp[SADB_X_EXT_NAT_T_DPORT]; |
---|
322 | natt_oa = (void *)mhp[SADB_X_EXT_NAT_T_OA]; |
---|
323 | |
---|
324 | if (natt_type && natt_type->sadb_x_nat_t_type_type) |
---|
325 | use_natt = 1; |
---|
326 | #endif |
---|
327 | /* source address */ |
---|
328 | if (m_saddr == NULL) { |
---|
329 | printf("no ADDRESS_SRC extension.\n"); |
---|
330 | return; |
---|
331 | } |
---|
332 | sa = (void *)(m_saddr + 1); |
---|
333 | if (withports) |
---|
334 | printf("%s[%s]", str_ipaddr(sa), str_ipport(sa)); |
---|
335 | else |
---|
336 | printf("%s", str_ipaddr(sa)); |
---|
337 | #ifdef SADB_X_EXT_NAT_T_TYPE |
---|
338 | if (use_natt && natt_sport) |
---|
339 | printf("[%u]", ntohs(natt_sport->sadb_x_nat_t_port_port)); |
---|
340 | #endif |
---|
341 | printf(" "); |
---|
342 | |
---|
343 | /* destination address */ |
---|
344 | if (m_daddr == NULL) { |
---|
345 | printf(" no ADDRESS_DST extension.\n"); |
---|
346 | return; |
---|
347 | } |
---|
348 | sa = (void *)(m_daddr + 1); |
---|
349 | if (withports) |
---|
350 | printf("%s[%s]", str_ipaddr(sa), str_ipport(sa)); |
---|
351 | else |
---|
352 | printf("%s", str_ipaddr(sa)); |
---|
353 | #ifdef SADB_X_EXT_NAT_T_TYPE |
---|
354 | if (use_natt && natt_dport) |
---|
355 | printf("[%u]", ntohs(natt_dport->sadb_x_nat_t_port_port)); |
---|
356 | #endif |
---|
357 | printf(" "); |
---|
358 | |
---|
359 | /* SA type */ |
---|
360 | if (m_sa == NULL) { |
---|
361 | printf("no SA extension.\n"); |
---|
362 | return; |
---|
363 | } |
---|
364 | if (m_sa2 == NULL) { |
---|
365 | printf("no SA2 extension.\n"); |
---|
366 | return; |
---|
367 | } |
---|
368 | printf("\n\t"); |
---|
369 | |
---|
370 | #ifdef SADB_X_EXT_NAT_T_TYPE |
---|
371 | if (use_natt && m->sadb_msg_satype == SADB_SATYPE_ESP) |
---|
372 | printf("esp-udp "); |
---|
373 | else if (use_natt) |
---|
374 | printf("natt+"); |
---|
375 | |
---|
376 | if (!use_natt || m->sadb_msg_satype != SADB_SATYPE_ESP) |
---|
377 | #endif |
---|
378 | GETMSGSTR(str_satype, m->sadb_msg_satype); |
---|
379 | |
---|
380 | printf("mode="); |
---|
381 | GETMSGSTR(str_mode, m_sa2->sadb_x_sa2_mode); |
---|
382 | |
---|
383 | printf("spi=%u(0x%08x) reqid=%u(0x%08x)\n", |
---|
384 | (u_int32_t)ntohl(m_sa->sadb_sa_spi), |
---|
385 | (u_int32_t)ntohl(m_sa->sadb_sa_spi), |
---|
386 | (u_int32_t)m_sa2->sadb_x_sa2_reqid, |
---|
387 | (u_int32_t)m_sa2->sadb_x_sa2_reqid); |
---|
388 | |
---|
389 | #ifdef SADB_X_EXT_NAT_T_TYPE |
---|
390 | /* other NAT-T information */ |
---|
391 | if (use_natt && natt_oa) |
---|
392 | printf("\tNAT OA=%s\n", |
---|
393 | str_ipaddr((void *)(natt_oa + 1))); |
---|
394 | #endif |
---|
395 | |
---|
396 | /* encryption key */ |
---|
397 | if (m->sadb_msg_satype == SADB_X_SATYPE_IPCOMP) { |
---|
398 | printf("\tC: "); |
---|
399 | GETMSGV2S(str_alg_comp, m_sa->sadb_sa_encrypt); |
---|
400 | } else if (m->sadb_msg_satype == SADB_SATYPE_ESP) { |
---|
401 | if (m_enc != NULL) { |
---|
402 | printf("\tE: "); |
---|
403 | GETMSGV2S(str_alg_enc, m_sa->sadb_sa_encrypt); |
---|
404 | ipsec_hexdump((caddr_t)(void *)m_enc + sizeof(*m_enc), |
---|
405 | m_enc->sadb_key_bits / 8); |
---|
406 | printf("\n"); |
---|
407 | } |
---|
408 | } |
---|
409 | |
---|
410 | /* authentication key */ |
---|
411 | if (m_auth != NULL) { |
---|
412 | printf("\tA: "); |
---|
413 | GETMSGV2S(str_alg_auth, m_sa->sadb_sa_auth); |
---|
414 | ipsec_hexdump((caddr_t)(void *)m_auth + sizeof(*m_auth), |
---|
415 | m_auth->sadb_key_bits / 8); |
---|
416 | printf("\n"); |
---|
417 | } |
---|
418 | |
---|
419 | /* replay windoe size & flags */ |
---|
420 | printf("\tseq=0x%08x replay=%u flags=0x%08x ", |
---|
421 | m_sa2->sadb_x_sa2_sequence, |
---|
422 | m_sa->sadb_sa_replay, |
---|
423 | m_sa->sadb_sa_flags); |
---|
424 | |
---|
425 | /* state */ |
---|
426 | printf("state="); |
---|
427 | GETMSGSTR(str_state, m_sa->sadb_sa_state); |
---|
428 | printf("\n"); |
---|
429 | |
---|
430 | /* lifetime */ |
---|
431 | if (m_lftc != NULL) { |
---|
432 | time_t tmp_time = time(0); |
---|
433 | |
---|
434 | printf("\tcreated: %s", |
---|
435 | str_time((long)m_lftc->sadb_lifetime_addtime)); |
---|
436 | printf("\tcurrent: %s\n", str_time(tmp_time)); |
---|
437 | printf("\tdiff: %lu(s)", |
---|
438 | (u_long)(m_lftc->sadb_lifetime_addtime == 0 ? |
---|
439 | 0 : (tmp_time - m_lftc->sadb_lifetime_addtime))); |
---|
440 | |
---|
441 | printf("\thard: %lu(s)", |
---|
442 | (u_long)(m_lfth == NULL ? |
---|
443 | 0 : m_lfth->sadb_lifetime_addtime)); |
---|
444 | printf("\tsoft: %lu(s)\n", |
---|
445 | (u_long)(m_lfts == NULL ? |
---|
446 | 0 : m_lfts->sadb_lifetime_addtime)); |
---|
447 | |
---|
448 | printf("\tlast: %s", |
---|
449 | str_time((long)m_lftc->sadb_lifetime_usetime)); |
---|
450 | printf("\thard: %lu(s)", |
---|
451 | (u_long)(m_lfth == NULL ? |
---|
452 | 0 : m_lfth->sadb_lifetime_usetime)); |
---|
453 | printf("\tsoft: %lu(s)\n", |
---|
454 | (u_long)(m_lfts == NULL ? |
---|
455 | 0 : m_lfts->sadb_lifetime_usetime)); |
---|
456 | |
---|
457 | str_lifetime_byte(m_lftc, "current"); |
---|
458 | str_lifetime_byte(m_lfth, "hard"); |
---|
459 | str_lifetime_byte(m_lfts, "soft"); |
---|
460 | printf("\n"); |
---|
461 | |
---|
462 | printf("\tallocated: %lu", |
---|
463 | (unsigned long)m_lftc->sadb_lifetime_allocations); |
---|
464 | printf("\thard: %lu", |
---|
465 | (u_long)(m_lfth == NULL ? |
---|
466 | 0 : m_lfth->sadb_lifetime_allocations)); |
---|
467 | printf("\tsoft: %lu\n", |
---|
468 | (u_long)(m_lfts == NULL ? |
---|
469 | 0 : m_lfts->sadb_lifetime_allocations)); |
---|
470 | } |
---|
471 | |
---|
472 | #ifdef SADB_X_EXT_SEC_CTX |
---|
473 | if (m_sec_ctx != NULL) { |
---|
474 | printf("\tsecurity context doi: %u\n", |
---|
475 | m_sec_ctx->sadb_x_ctx_doi); |
---|
476 | printf("\tsecurity context algorithm: %u\n", |
---|
477 | m_sec_ctx->sadb_x_ctx_alg); |
---|
478 | printf("\tsecurity context length: %u\n", |
---|
479 | m_sec_ctx->sadb_x_ctx_len); |
---|
480 | printf("\tsecurity context: %s\n", |
---|
481 | (char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx)); |
---|
482 | } |
---|
483 | #endif |
---|
484 | |
---|
485 | printf("\tsadb_seq=%lu pid=%lu ", |
---|
486 | (u_long)m->sadb_msg_seq, |
---|
487 | (u_long)m->sadb_msg_pid); |
---|
488 | |
---|
489 | /* XXX DEBUG */ |
---|
490 | printf("refcnt=%u\n", m->sadb_msg_reserved); |
---|
491 | |
---|
492 | return; |
---|
493 | } |
---|
494 | |
---|
495 | void |
---|
496 | pfkey_spdump(m) |
---|
497 | struct sadb_msg *m; |
---|
498 | { |
---|
499 | pfkey_spdump1(m, 0); |
---|
500 | } |
---|
501 | |
---|
502 | void |
---|
503 | pfkey_spdump_withports(m) |
---|
504 | struct sadb_msg *m; |
---|
505 | { |
---|
506 | pfkey_spdump1(m, 1); |
---|
507 | } |
---|
508 | |
---|
509 | static void |
---|
510 | pfkey_spdump1(m, withports) |
---|
511 | struct sadb_msg *m; |
---|
512 | int withports; |
---|
513 | { |
---|
514 | char pbuf[NI_MAXSERV]; |
---|
515 | caddr_t mhp[SADB_EXT_MAX + 1]; |
---|
516 | struct sadb_address *m_saddr, *m_daddr; |
---|
517 | #ifdef SADB_X_EXT_TAG |
---|
518 | struct sadb_x_tag *m_tag; |
---|
519 | #endif |
---|
520 | struct sadb_x_policy *m_xpl; |
---|
521 | struct sadb_lifetime *m_lftc = NULL, *m_lfth = NULL; |
---|
522 | #ifdef SADB_X_EXT_SEC_CTX |
---|
523 | struct sadb_x_sec_ctx *m_sec_ctx; |
---|
524 | #endif |
---|
525 | struct sockaddr *sa; |
---|
526 | u_int16_t sport = 0, dport = 0; |
---|
527 | |
---|
528 | /* check pfkey message. */ |
---|
529 | if (pfkey_align(m, mhp)) { |
---|
530 | printf("%s\n", ipsec_strerror()); |
---|
531 | return; |
---|
532 | } |
---|
533 | if (pfkey_check(mhp)) { |
---|
534 | printf("%s\n", ipsec_strerror()); |
---|
535 | return; |
---|
536 | } |
---|
537 | |
---|
538 | m_saddr = (void *)mhp[SADB_EXT_ADDRESS_SRC]; |
---|
539 | m_daddr = (void *)mhp[SADB_EXT_ADDRESS_DST]; |
---|
540 | #ifdef SADB_X_EXT_TAG |
---|
541 | m_tag = (void *)mhp[SADB_X_EXT_TAG]; |
---|
542 | #endif |
---|
543 | m_xpl = (void *)mhp[SADB_X_EXT_POLICY]; |
---|
544 | m_lftc = (void *)mhp[SADB_EXT_LIFETIME_CURRENT]; |
---|
545 | m_lfth = (void *)mhp[SADB_EXT_LIFETIME_HARD]; |
---|
546 | |
---|
547 | #ifdef SADB_X_EXT_SEC_CTX |
---|
548 | m_sec_ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX]; |
---|
549 | #endif |
---|
550 | #ifdef __linux__ |
---|
551 | /* *bsd indicates per-socket policies by omiting src and dst |
---|
552 | * extensions. Linux always includes them, but we can catch it |
---|
553 | * by checkin for policy id. |
---|
554 | */ |
---|
555 | if (m_xpl->sadb_x_policy_id % 8 >= 3) { |
---|
556 | printf("(per-socket policy) "); |
---|
557 | } else |
---|
558 | #endif |
---|
559 | if (m_saddr && m_daddr) { |
---|
560 | /* source address */ |
---|
561 | sa = (void *)(m_saddr + 1); |
---|
562 | switch (sa->sa_family) { |
---|
563 | case AF_INET: |
---|
564 | case AF_INET6: |
---|
565 | if (getnameinfo(sa, (socklen_t)sysdep_sa_len(sa), NULL, |
---|
566 | 0, pbuf, sizeof(pbuf), NI_NUMERICSERV) != 0) |
---|
567 | sport = 0; /*XXX*/ |
---|
568 | else |
---|
569 | sport = atoi(pbuf); |
---|
570 | printf("%s%s ", str_ipaddr(sa), |
---|
571 | str_prefport((u_int)sa->sa_family, |
---|
572 | (u_int)m_saddr->sadb_address_prefixlen, |
---|
573 | (u_int)sport, |
---|
574 | (u_int)m_saddr->sadb_address_proto)); |
---|
575 | break; |
---|
576 | default: |
---|
577 | printf("unknown-af "); |
---|
578 | break; |
---|
579 | } |
---|
580 | |
---|
581 | /* destination address */ |
---|
582 | sa = (void *)(m_daddr + 1); |
---|
583 | switch (sa->sa_family) { |
---|
584 | case AF_INET: |
---|
585 | case AF_INET6: |
---|
586 | if (getnameinfo(sa, (socklen_t)sysdep_sa_len(sa), NULL, |
---|
587 | 0, pbuf, sizeof(pbuf), NI_NUMERICSERV) != 0) |
---|
588 | dport = 0; /*XXX*/ |
---|
589 | else |
---|
590 | dport = atoi(pbuf); |
---|
591 | printf("%s%s ", str_ipaddr(sa), |
---|
592 | str_prefport((u_int)sa->sa_family, |
---|
593 | (u_int)m_daddr->sadb_address_prefixlen, |
---|
594 | (u_int)dport, |
---|
595 | (u_int)m_saddr->sadb_address_proto)); |
---|
596 | break; |
---|
597 | default: |
---|
598 | printf("unknown-af "); |
---|
599 | break; |
---|
600 | } |
---|
601 | |
---|
602 | /* upper layer protocol */ |
---|
603 | if (m_saddr->sadb_address_proto != |
---|
604 | m_daddr->sadb_address_proto) { |
---|
605 | printf("upper layer protocol mismatched.\n"); |
---|
606 | return; |
---|
607 | } |
---|
608 | str_upperspec((u_int)m_saddr->sadb_address_proto, (u_int)sport, |
---|
609 | (u_int)dport); |
---|
610 | } |
---|
611 | #ifdef SADB_X_EXT_TAG |
---|
612 | else if (m_tag) |
---|
613 | printf("tagged \"%s\" ", m_tag->sadb_x_tag_name); |
---|
614 | #endif |
---|
615 | else |
---|
616 | printf("(no selector, probably per-socket policy) "); |
---|
617 | |
---|
618 | /* policy */ |
---|
619 | { |
---|
620 | char *d_xpl; |
---|
621 | |
---|
622 | if (m_xpl == NULL) { |
---|
623 | printf("no X_POLICY extension.\n"); |
---|
624 | return; |
---|
625 | } |
---|
626 | if (withports) |
---|
627 | d_xpl = ipsec_dump_policy_withports(m_xpl, "\n\t"); |
---|
628 | else |
---|
629 | d_xpl = ipsec_dump_policy((ipsec_policy_t)m_xpl, "\n\t"); |
---|
630 | |
---|
631 | if (!d_xpl) |
---|
632 | printf("\n\tPolicy:[%s]\n", ipsec_strerror()); |
---|
633 | else { |
---|
634 | /* dump SPD */ |
---|
635 | printf("\n\t%s\n", d_xpl); |
---|
636 | free(d_xpl); |
---|
637 | } |
---|
638 | } |
---|
639 | |
---|
640 | /* lifetime */ |
---|
641 | if (m_lftc) { |
---|
642 | printf("\tcreated: %s ", |
---|
643 | str_time((long)m_lftc->sadb_lifetime_addtime)); |
---|
644 | printf("lastused: %s\n", |
---|
645 | str_time((long)m_lftc->sadb_lifetime_usetime)); |
---|
646 | } |
---|
647 | if (m_lfth) { |
---|
648 | printf("\tlifetime: %lu(s) ", |
---|
649 | (u_long)m_lfth->sadb_lifetime_addtime); |
---|
650 | printf("validtime: %lu(s)\n", |
---|
651 | (u_long)m_lfth->sadb_lifetime_usetime); |
---|
652 | } |
---|
653 | |
---|
654 | #ifdef SADB_X_EXT_SEC_CTX |
---|
655 | if (m_sec_ctx != NULL) { |
---|
656 | printf("\tsecurity context doi: %u\n", |
---|
657 | m_sec_ctx->sadb_x_ctx_doi); |
---|
658 | printf("\tsecurity context algorithm: %u\n", |
---|
659 | m_sec_ctx->sadb_x_ctx_alg); |
---|
660 | printf("\tsecurity context length: %u\n", |
---|
661 | m_sec_ctx->sadb_x_ctx_len); |
---|
662 | printf("\tsecurity context: %s\n", |
---|
663 | (char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx)); |
---|
664 | } |
---|
665 | #endif |
---|
666 | |
---|
667 | printf("\tspid=%ld seq=%ld pid=%ld\n", |
---|
668 | (u_long)m_xpl->sadb_x_policy_id, |
---|
669 | (u_long)m->sadb_msg_seq, |
---|
670 | (u_long)m->sadb_msg_pid); |
---|
671 | |
---|
672 | /* XXX TEST */ |
---|
673 | printf("\trefcnt=%u\n", m->sadb_msg_reserved); |
---|
674 | |
---|
675 | return; |
---|
676 | } |
---|
677 | |
---|
678 | /* |
---|
679 | * set "ipaddress" to buffer. |
---|
680 | */ |
---|
681 | static char * |
---|
682 | str_ipaddr(sa) |
---|
683 | struct sockaddr *sa; |
---|
684 | { |
---|
685 | static char buf[NI_MAXHOST]; |
---|
686 | const int niflag = NI_NUMERICHOST; |
---|
687 | |
---|
688 | if (sa == NULL) |
---|
689 | return ""; |
---|
690 | |
---|
691 | if (getnameinfo(sa, (socklen_t)sysdep_sa_len(sa), buf, sizeof(buf), |
---|
692 | NULL, 0, niflag) == 0) |
---|
693 | return buf; |
---|
694 | return NULL; |
---|
695 | } |
---|
696 | |
---|
697 | /* |
---|
698 | * set "port" to buffer. |
---|
699 | */ |
---|
700 | static char * |
---|
701 | str_ipport(sa) |
---|
702 | struct sockaddr *sa; |
---|
703 | { |
---|
704 | static char buf[NI_MAXHOST]; |
---|
705 | const int niflag = NI_NUMERICSERV; |
---|
706 | |
---|
707 | if (sa == NULL) |
---|
708 | return ""; |
---|
709 | |
---|
710 | if (getnameinfo(sa, (socklen_t)sysdep_sa_len(sa), NULL, 0, |
---|
711 | buf, sizeof(buf), niflag) == 0) |
---|
712 | return buf; |
---|
713 | return NULL; |
---|
714 | } |
---|
715 | |
---|
716 | |
---|
717 | /* |
---|
718 | * set "/prefix[port number]" to buffer. |
---|
719 | */ |
---|
720 | static char * |
---|
721 | str_prefport(family, pref, port, ulp) |
---|
722 | u_int family, pref, port, ulp; |
---|
723 | { |
---|
724 | static char buf[128]; |
---|
725 | char prefbuf[128]; |
---|
726 | char portbuf[128]; |
---|
727 | int plen; |
---|
728 | |
---|
729 | switch (family) { |
---|
730 | case AF_INET: |
---|
731 | plen = sizeof(struct in_addr) << 3; |
---|
732 | break; |
---|
733 | case AF_INET6: |
---|
734 | plen = sizeof(struct in6_addr) << 3; |
---|
735 | break; |
---|
736 | default: |
---|
737 | return "?"; |
---|
738 | } |
---|
739 | |
---|
740 | if (pref == plen) |
---|
741 | prefbuf[0] = '\0'; |
---|
742 | else |
---|
743 | snprintf(prefbuf, sizeof(prefbuf), "/%u", pref); |
---|
744 | |
---|
745 | switch (ulp) { |
---|
746 | case IPPROTO_ICMP: |
---|
747 | case IPPROTO_ICMPV6: |
---|
748 | case IPPROTO_MH: |
---|
749 | case IPPROTO_GRE: |
---|
750 | memset(portbuf, 0, sizeof(portbuf)); |
---|
751 | break; |
---|
752 | default: |
---|
753 | if (port == IPSEC_PORT_ANY) |
---|
754 | strcpy(portbuf, "[any]"); |
---|
755 | else |
---|
756 | snprintf(portbuf, sizeof(portbuf), "[%u]", port); |
---|
757 | break; |
---|
758 | } |
---|
759 | |
---|
760 | snprintf(buf, sizeof(buf), "%s%s", prefbuf, portbuf); |
---|
761 | |
---|
762 | return buf; |
---|
763 | } |
---|
764 | |
---|
765 | static void |
---|
766 | str_upperspec(ulp, p1, p2) |
---|
767 | u_int ulp, p1, p2; |
---|
768 | { |
---|
769 | struct protoent *ent; |
---|
770 | |
---|
771 | ent = getprotobynumber((int)ulp); |
---|
772 | if (ent) |
---|
773 | printf("%s", ent->p_name); |
---|
774 | else |
---|
775 | printf("%u", ulp); |
---|
776 | |
---|
777 | if (p1 == IPSEC_PORT_ANY && p2 == IPSEC_PORT_ANY) |
---|
778 | return; |
---|
779 | |
---|
780 | switch (ulp) { |
---|
781 | case IPPROTO_ICMP: |
---|
782 | case IPPROTO_ICMPV6: |
---|
783 | case IPPROTO_MH: |
---|
784 | printf(" %u,%u", p1, p2); |
---|
785 | break; |
---|
786 | case IPPROTO_GRE: |
---|
787 | printf(" %u", (p1 << 16) + p2); |
---|
788 | break; |
---|
789 | } |
---|
790 | } |
---|
791 | |
---|
792 | /* |
---|
793 | * set "Mon Day Time Year" to buffer |
---|
794 | */ |
---|
795 | static char * |
---|
796 | str_time(t) |
---|
797 | time_t t; |
---|
798 | { |
---|
799 | static char buf[128]; |
---|
800 | |
---|
801 | if (t == 0) { |
---|
802 | int i = 0; |
---|
803 | for (;i < 20;) buf[i++] = ' '; |
---|
804 | } else { |
---|
805 | char *t0; |
---|
806 | if ((t0 = ctime(&t)) == NULL) |
---|
807 | memset(buf, '?', 20); |
---|
808 | else |
---|
809 | memcpy(buf, t0 + 4, 20); |
---|
810 | } |
---|
811 | |
---|
812 | buf[20] = '\0'; |
---|
813 | |
---|
814 | return(buf); |
---|
815 | } |
---|
816 | |
---|
817 | static void |
---|
818 | str_lifetime_byte(x, str) |
---|
819 | struct sadb_lifetime *x; |
---|
820 | char *str; |
---|
821 | { |
---|
822 | double y; |
---|
823 | char *unit; |
---|
824 | int w; |
---|
825 | |
---|
826 | if (x == NULL) { |
---|
827 | printf("\t%s: 0(bytes)", str); |
---|
828 | return; |
---|
829 | } |
---|
830 | |
---|
831 | #if 0 |
---|
832 | if ((x->sadb_lifetime_bytes) / 1024 / 1024) { |
---|
833 | y = (x->sadb_lifetime_bytes) * 1.0 / 1024 / 1024; |
---|
834 | unit = "M"; |
---|
835 | w = 1; |
---|
836 | } else if ((x->sadb_lifetime_bytes) / 1024) { |
---|
837 | y = (x->sadb_lifetime_bytes) * 1.0 / 1024; |
---|
838 | unit = "K"; |
---|
839 | w = 1; |
---|
840 | } else { |
---|
841 | y = (x->sadb_lifetime_bytes) * 1.0; |
---|
842 | unit = ""; |
---|
843 | w = 0; |
---|
844 | } |
---|
845 | #else |
---|
846 | y = (x->sadb_lifetime_bytes) * 1.0; |
---|
847 | unit = ""; |
---|
848 | w = 0; |
---|
849 | #endif |
---|
850 | printf("\t%s: %.*f(%sbytes)", str, w, y, unit); |
---|
851 | } |
---|