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