1 /* $KAME: pfkey_dump.c,v 1.45 2003/09/08 10:14:56 itojun Exp $ */
4 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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
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>
42 # include <netinet/ipsec.h>
46 #include <System/net/pfkeyv2.h>
48 #include <net/pfkeyv2.h>
51 #include <netinet/in.h>
52 #include <arpa/inet.h>
61 #include "ipsec_strerror.h"
64 /* cope with old kame headers - ugly */
65 #ifndef SADB_X_AALG_MD5
66 #define SADB_X_AALG_MD5 SADB_AALG_MD5
68 #ifndef SADB_X_AALG_SHA
69 #define SADB_X_AALG_SHA SADB_AALG_SHA
71 #ifndef SADB_X_AALG_NULL
72 #define SADB_X_AALG_NULL SADB_AALG_NULL
75 #ifndef SADB_X_EALG_BLOWFISHCBC
76 #define SADB_X_EALG_BLOWFISHCBC SADB_EALG_BLOWFISHCBC
78 #ifndef SADB_X_EALG_CAST128CBC
79 #define SADB_X_EALG_CAST128CBC SADB_EALG_CAST128CBC
81 #ifndef SADB_X_EALG_RC5CBC
82 #ifdef SADB_EALG_RC5CBC
83 #define SADB_X_EALG_RC5CBC SADB_EALG_RC5CBC
87 #define GETMSGSTR(str, num) \
90 if (sizeof((str)[0]) == 0 \
91 || num >= sizeof(str)/sizeof((str)[0])) \
92 printf("%u ", (num)); \
93 else if (strlen((str)[(num)]) == 0) \
94 printf("%u ", (num)); \
96 printf("%s ", (str)[(num)]); \
97 } while (/*CONSTCOND*/0)
99 #define GETMSGV2S(v2s, num) \
102 for (p = (v2s); p && p->str; p++) { \
103 if (p->val == (num)) \
107 printf("%s ", p->str); \
109 printf("%u ", (num)); \
110 } while (/*CONSTCOND*/0)
112 static char *str_ipaddr
__P((struct sockaddr
*));
113 static char *str_ipport
__P((struct sockaddr
*));
114 static char *str_prefport
__P((u_int
, u_int
, u_int
, u_int
));
115 static void str_upperspec
__P((u_int
, u_int
, u_int
));
116 static char *str_time
__P((time_t));
117 static void str_lifetime_byte
__P((struct sadb_lifetime
*, char *));
118 static void pfkey_sadump1(struct sadb_msg
*, int);
119 static void pfkey_spdump1(struct sadb_msg
*, int);
127 * Must to be re-written about following strings.
129 static char *str_satype
[] = {
144 static char *str_mode
[] = {
150 static char *str_state
[] = {
157 static struct val2str str_alg_auth
[] = {
158 { SADB_AALG_NONE
, "none", },
159 { SADB_AALG_MD5HMAC
, "hmac-md5", },
160 { SADB_AALG_SHA1HMAC
, "hmac-sha1", },
161 { SADB_X_AALG_MD5
, "md5", },
162 { SADB_X_AALG_SHA
, "sha", },
163 { SADB_X_AALG_NULL
, "null", },
164 #ifdef SADB_X_AALG_TCP_MD5
165 { SADB_X_AALG_TCP_MD5
, "tcp-md5", },
167 #ifdef SADB_X_AALG_SHA2_256
168 { SADB_X_AALG_SHA2_256
, "hmac-sha256", },
170 #ifdef SADB_X_AALG_SHA2_384
171 { SADB_X_AALG_SHA2_384
, "hmac-sha384", },
173 #ifdef SADB_X_AALG_SHA2_512
174 { SADB_X_AALG_SHA2_512
, "hmac-sha512", },
176 #ifdef SADB_X_AALG_RIPEMD160HMAC
177 { SADB_X_AALG_RIPEMD160HMAC
, "hmac-ripemd160", },
179 #ifdef SADB_X_AALG_AES_XCBC_MAC
180 { SADB_X_AALG_AES_XCBC_MAC
, "aes-xcbc-mac", },
185 static struct val2str str_alg_enc
[] = {
186 { SADB_EALG_NONE
, "none", },
187 { SADB_EALG_DESCBC
, "des-cbc", },
188 { SADB_EALG_3DESCBC
, "3des-cbc", },
189 { SADB_EALG_NULL
, "null", },
190 #ifdef SADB_X_EALG_RC5CBC
191 { SADB_X_EALG_RC5CBC
, "rc5-cbc", },
193 { SADB_X_EALG_CAST128CBC
, "cast128-cbc", },
194 { SADB_X_EALG_BLOWFISHCBC
, "blowfish-cbc", },
195 #ifdef SADB_X_EALG_AESCBC
196 { SADB_X_EALG_AESCBC
, "aes-cbc", },
198 #ifdef SADB_X_EALG_TWOFISHCBC
199 { SADB_X_EALG_TWOFISHCBC
, "twofish-cbc", },
201 #ifdef SADB_X_EALG_AESCTR
202 { SADB_X_EALG_AESCTR
, "aes-ctr", },
207 static struct val2str str_alg_comp
[] = {
208 { SADB_X_CALG_NONE
, "none", },
209 { SADB_X_CALG_OUI
, "oui", },
210 { SADB_X_CALG_DEFLATE
, "deflate", },
211 { SADB_X_CALG_LZS
, "lzs", },
216 * dump SADB_MSG formated. For debugging, you should use kdebug_sadb().
227 pfkey_sadump_withports(m
)
234 pfkey_sadump1(m
, withports
)
238 caddr_t mhp
[SADB_EXT_MAX
+ 1];
239 struct sadb_sa
*m_sa
;
240 struct sadb_x_sa2
*m_sa2
;
241 struct sadb_lifetime
*m_lftc
, *m_lfth
, *m_lfts
;
242 struct sadb_address
*m_saddr
, *m_daddr
;
244 struct sadb_address
*m_paddr
;
246 struct sadb_key
*m_auth
, *m_enc
;
248 struct sadb_ident
*m_sid
, *m_did
;
249 struct sadb_sens
*m_sens
;
251 #ifdef SADB_X_EXT_NAT_T_TYPE
252 struct sadb_x_nat_t_type
*natt_type
;
253 struct sadb_x_nat_t_port
*natt_sport
, *natt_dport
;
254 struct sadb_address
*natt_oa
;
260 /* check pfkey message. */
261 if (pfkey_align(m
, mhp
)) {
262 printf("%s\n", ipsec_strerror());
265 if (pfkey_check(mhp
)) {
266 printf("%s\n", ipsec_strerror());
270 m_sa
= (void *)mhp
[SADB_EXT_SA
];
271 m_sa2
= (void *)mhp
[SADB_X_EXT_SA2
];
272 m_lftc
= (void *)mhp
[SADB_EXT_LIFETIME_CURRENT
];
273 m_lfth
= (void *)mhp
[SADB_EXT_LIFETIME_HARD
];
274 m_lfts
= (void *)mhp
[SADB_EXT_LIFETIME_SOFT
];
275 m_saddr
= (void *)mhp
[SADB_EXT_ADDRESS_SRC
];
276 m_daddr
= (void *)mhp
[SADB_EXT_ADDRESS_DST
];
278 m_paddr
= (void *)mhp
[SADB_EXT_ADDRESS_PROXY
];
280 m_auth
= (void *)mhp
[SADB_EXT_KEY_AUTH
];
281 m_enc
= (void *)mhp
[SADB_EXT_KEY_ENCRYPT
];
283 m_sid
= (void *)mhp
[SADB_EXT_IDENTITY_SRC
];
284 m_did
= (void *)mhp
[SADB_EXT_IDENTITY_DST
];
285 m_sens
= (void *)mhp
[SADB_EXT_SENSITIVITY
];
287 #ifdef SADB_X_EXT_NAT_T_TYPE
288 natt_type
= (void *)mhp
[SADB_X_EXT_NAT_T_TYPE
];
289 natt_sport
= (void *)mhp
[SADB_X_EXT_NAT_T_SPORT
];
290 natt_dport
= (void *)mhp
[SADB_X_EXT_NAT_T_DPORT
];
291 natt_oa
= (void *)mhp
[SADB_X_EXT_NAT_T_OA
];
293 if (natt_type
&& natt_type
->sadb_x_nat_t_type_type
)
297 if (m_saddr
== NULL
) {
298 printf("no ADDRESS_SRC extension.\n");
301 sa
= (void *)(m_saddr
+ 1);
303 printf("%s[%s]", str_ipaddr(sa
), str_ipport(sa
));
305 printf("%s", str_ipaddr(sa
));
306 #ifdef SADB_X_EXT_NAT_T_TYPE
307 if (use_natt
&& natt_sport
)
308 printf("[%u]", ntohs(natt_sport
->sadb_x_nat_t_port_port
));
312 /* destination address */
313 if (m_daddr
== NULL
) {
314 printf(" no ADDRESS_DST extension.\n");
317 sa
= (void *)(m_daddr
+ 1);
319 printf("%s[%s]", str_ipaddr(sa
), str_ipport(sa
));
321 printf("%s", str_ipaddr(sa
));
322 #ifdef SADB_X_EXT_NAT_T_TYPE
323 if (use_natt
&& natt_dport
)
324 printf("[%u]", ntohs(natt_dport
->sadb_x_nat_t_port_port
));
330 printf("no SA extension.\n");
334 printf("no SA2 extension.\n");
339 #ifdef SADB_X_EXT_NAT_T_TYPE
340 if (use_natt
&& m
->sadb_msg_satype
== SADB_SATYPE_ESP
)
345 if (!use_natt
|| m
->sadb_msg_satype
!= SADB_SATYPE_ESP
)
347 GETMSGSTR(str_satype
, m
->sadb_msg_satype
);
350 GETMSGSTR(str_mode
, m_sa2
->sadb_x_sa2_mode
);
352 printf("spi=%u(0x%08x) reqid=%u(0x%08x)\n",
353 (u_int32_t
)ntohl(m_sa
->sadb_sa_spi
),
354 (u_int32_t
)ntohl(m_sa
->sadb_sa_spi
),
355 (u_int32_t
)m_sa2
->sadb_x_sa2_reqid
,
356 (u_int32_t
)m_sa2
->sadb_x_sa2_reqid
);
358 #ifdef SADB_X_EXT_NAT_T_TYPE
359 /* other NAT-T information */
360 if (use_natt
&& natt_oa
)
361 printf("\tNAT OA=%s\n",
362 str_ipaddr((void *)(natt_oa
+ 1)));
366 if (m
->sadb_msg_satype
== SADB_X_SATYPE_IPCOMP
) {
368 GETMSGV2S(str_alg_comp
, m_sa
->sadb_sa_encrypt
);
369 } else if (m
->sadb_msg_satype
== SADB_SATYPE_ESP
) {
372 GETMSGV2S(str_alg_enc
, m_sa
->sadb_sa_encrypt
);
373 ipsec_hexdump((caddr_t
)(void *)m_enc
+ sizeof(*m_enc
),
374 m_enc
->sadb_key_bits
/ 8);
379 /* authentication key */
380 if (m_auth
!= NULL
) {
382 GETMSGV2S(str_alg_auth
, m_sa
->sadb_sa_auth
);
383 ipsec_hexdump((caddr_t
)(void *)m_auth
+ sizeof(*m_auth
),
384 m_auth
->sadb_key_bits
/ 8);
388 /* replay windoe size & flags */
389 printf("\tseq=0x%08x replay=%u flags=0x%08x ",
390 m_sa2
->sadb_x_sa2_sequence
,
391 m_sa
->sadb_sa_replay
,
392 m_sa
->sadb_sa_flags
);
396 GETMSGSTR(str_state
, m_sa
->sadb_sa_state
);
400 if (m_lftc
!= NULL
) {
401 time_t tmp_time
= time(0);
403 printf("\tcreated: %s",
404 str_time((long)m_lftc
->sadb_lifetime_addtime
));
405 printf("\tcurrent: %s\n", str_time(tmp_time
));
406 printf("\tdiff: %lu(s)",
407 (u_long
)(m_lftc
->sadb_lifetime_addtime
== 0 ?
408 0 : (tmp_time
- m_lftc
->sadb_lifetime_addtime
)));
410 printf("\thard: %lu(s)",
411 (u_long
)(m_lfth
== NULL
?
412 0 : m_lfth
->sadb_lifetime_addtime
));
413 printf("\tsoft: %lu(s)\n",
414 (u_long
)(m_lfts
== NULL
?
415 0 : m_lfts
->sadb_lifetime_addtime
));
418 str_time((long)m_lftc
->sadb_lifetime_usetime
));
419 printf("\thard: %lu(s)",
420 (u_long
)(m_lfth
== NULL
?
421 0 : m_lfth
->sadb_lifetime_usetime
));
422 printf("\tsoft: %lu(s)\n",
423 (u_long
)(m_lfts
== NULL
?
424 0 : m_lfts
->sadb_lifetime_usetime
));
426 str_lifetime_byte(m_lftc
, "current");
427 str_lifetime_byte(m_lfth
, "hard");
428 str_lifetime_byte(m_lfts
, "soft");
431 printf("\tallocated: %lu",
432 (unsigned long)m_lftc
->sadb_lifetime_allocations
);
433 printf("\thard: %lu",
434 (u_long
)(m_lfth
== NULL
?
435 0 : m_lfth
->sadb_lifetime_allocations
));
436 printf("\tsoft: %lu\n",
437 (u_long
)(m_lfts
== NULL
?
438 0 : m_lfts
->sadb_lifetime_allocations
));
441 printf("\tsadb_seq=%lu pid=%lu ",
442 (u_long
)m
->sadb_msg_seq
,
443 (u_long
)m
->sadb_msg_pid
);
446 printf("refcnt=%u\n", m
->sadb_msg_reserved
);
459 pfkey_spdump_withports(m
)
466 pfkey_spdump1(m
, withports
)
470 char pbuf
[NI_MAXSERV
];
471 caddr_t mhp
[SADB_EXT_MAX
+ 1];
472 struct sadb_address
*m_saddr
, *m_daddr
;
473 #ifdef SADB_X_EXT_TAG
474 struct sadb_x_tag
*m_tag
;
476 struct sadb_x_policy
*m_xpl
;
477 struct sadb_lifetime
*m_lftc
= NULL
, *m_lfth
= NULL
;
479 u_int16_t sport
= 0, dport
= 0;
481 /* check pfkey message. */
482 if (pfkey_align(m
, mhp
)) {
483 printf("%s\n", ipsec_strerror());
486 if (pfkey_check(mhp
)) {
487 printf("%s\n", ipsec_strerror());
491 m_saddr
= (void *)mhp
[SADB_EXT_ADDRESS_SRC
];
492 m_daddr
= (void *)mhp
[SADB_EXT_ADDRESS_DST
];
493 #ifdef SADB_X_EXT_TAG
494 m_tag
= (void *)mhp
[SADB_X_EXT_TAG
];
496 m_xpl
= (void *)mhp
[SADB_X_EXT_POLICY
];
497 m_lftc
= (void *)mhp
[SADB_EXT_LIFETIME_CURRENT
];
498 m_lfth
= (void *)mhp
[SADB_EXT_LIFETIME_HARD
];
501 /* *bsd indicates per-socket policies by omiting src and dst
502 * extensions. Linux always includes them, but we can catch it
503 * by checkin for policy id.
505 if (m_xpl
->sadb_x_policy_id
% 8 >= 3) {
506 printf("(per-socket policy) ");
509 if (m_saddr
&& m_daddr
) {
511 sa
= (void *)(m_saddr
+ 1);
512 switch (sa
->sa_family
) {
515 if (getnameinfo(sa
, (socklen_t
)sysdep_sa_len(sa
), NULL
,
516 0, pbuf
, sizeof(pbuf
), NI_NUMERICSERV
) != 0)
520 printf("%s%s ", str_ipaddr(sa
),
521 str_prefport((u_int
)sa
->sa_family
,
522 (u_int
)m_saddr
->sadb_address_prefixlen
,
524 (u_int
)m_saddr
->sadb_address_proto
));
527 printf("unknown-af ");
531 /* destination address */
532 sa
= (void *)(m_daddr
+ 1);
533 switch (sa
->sa_family
) {
536 if (getnameinfo(sa
, (socklen_t
)sysdep_sa_len(sa
), NULL
,
537 0, pbuf
, sizeof(pbuf
), NI_NUMERICSERV
) != 0)
541 printf("%s%s ", str_ipaddr(sa
),
542 str_prefport((u_int
)sa
->sa_family
,
543 (u_int
)m_daddr
->sadb_address_prefixlen
,
545 (u_int
)m_saddr
->sadb_address_proto
));
548 printf("unknown-af ");
552 /* upper layer protocol */
553 if (m_saddr
->sadb_address_proto
!=
554 m_daddr
->sadb_address_proto
) {
555 printf("upper layer protocol mismatched.\n");
558 str_upperspec((u_int
)m_saddr
->sadb_address_proto
, (u_int
)sport
,
561 #ifdef SADB_X_EXT_TAG
563 printf("tagged \"%s\" ", m_tag
->sadb_x_tag_name
);
566 printf("(no selector, probably per-socket policy) ");
573 printf("no X_POLICY extension.\n");
577 d_xpl
= ipsec_dump_policy_withports(m_xpl
, "\n\t");
579 d_xpl
= ipsec_dump_policy((ipsec_policy_t
)m_xpl
, "\n\t");
582 printf("\n\tPolicy:[%s]\n", ipsec_strerror());
585 printf("\n\t%s\n", d_xpl
);
592 printf("\tcreated: %s ",
593 str_time((long)m_lftc
->sadb_lifetime_addtime
));
594 printf("lastused: %s\n",
595 str_time((long)m_lftc
->sadb_lifetime_usetime
));
598 printf("\tlifetime: %lu(s) ",
599 (u_long
)m_lfth
->sadb_lifetime_addtime
);
600 printf("validtime: %lu(s)\n",
601 (u_long
)m_lfth
->sadb_lifetime_usetime
);
605 printf("\tspid=%ld seq=%ld pid=%ld\n",
606 (u_long
)m_xpl
->sadb_x_policy_id
,
607 (u_long
)m
->sadb_msg_seq
,
608 (u_long
)m
->sadb_msg_pid
);
611 printf("\trefcnt=%u\n", m
->sadb_msg_reserved
);
617 * set "ipaddress" to buffer.
623 static char buf
[NI_MAXHOST
];
624 const int niflag
= NI_NUMERICHOST
;
629 if (getnameinfo(sa
, (socklen_t
)sysdep_sa_len(sa
), buf
, sizeof(buf
),
630 NULL
, 0, niflag
) == 0)
636 * set "port" to buffer.
642 static char buf
[NI_MAXHOST
];
643 const int niflag
= NI_NUMERICSERV
;
648 if (getnameinfo(sa
, (socklen_t
)sysdep_sa_len(sa
), NULL
, 0,
649 buf
, sizeof(buf
), niflag
) == 0)
656 * set "/prefix[port number]" to buffer.
659 str_prefport(family
, pref
, port
, ulp
)
660 u_int family
, pref
, port
, ulp
;
662 static char buf
[128];
669 plen
= sizeof(struct in_addr
) << 3;
672 plen
= sizeof(struct in6_addr
) << 3;
681 snprintf(prefbuf
, sizeof(prefbuf
), "/%u", pref
);
683 if (ulp
== IPPROTO_ICMPV6
)
684 memset(portbuf
, 0, sizeof(portbuf
));
686 if (port
== IPSEC_PORT_ANY
)
687 snprintf(portbuf
, sizeof(portbuf
), "[%s]", "any");
689 snprintf(portbuf
, sizeof(portbuf
), "[%u]", port
);
692 snprintf(buf
, sizeof(buf
), "%s%s", prefbuf
, portbuf
);
698 str_upperspec(ulp
, p1
, p2
)
701 if (ulp
== IPSEC_ULPROTO_ANY
)
703 else if (ulp
== IPPROTO_ICMPV6
) {
705 if (!(p1
== IPSEC_PORT_ANY
&& p2
== IPSEC_PORT_ANY
))
706 printf(" %u,%u", p1
, p2
);
708 struct protoent
*ent
;
715 ent
= getprotobynumber((int)ulp
);
717 printf("%s", ent
->p_name
);
728 * set "Mon Day Time Year" to buffer
734 static char buf
[128];
738 for (;i
< 20;) buf
[i
++] = ' ';
742 memcpy(buf
, t0
+ 4, 20);
751 str_lifetime_byte(x
, str
)
752 struct sadb_lifetime
*x
;
760 printf("\t%s: 0(bytes)", str
);
765 if ((x
->sadb_lifetime_bytes
) / 1024 / 1024) {
766 y
= (x
->sadb_lifetime_bytes
) * 1.0 / 1024 / 1024;
769 } else if ((x
->sadb_lifetime_bytes
) / 1024) {
770 y
= (x
->sadb_lifetime_bytes
) * 1.0 / 1024;
774 y
= (x
->sadb_lifetime_bytes
) * 1.0;
779 y
= (x
->sadb_lifetime_bytes
) * 1.0;
783 printf("\t%s: %.*f(%sbytes)", str
, w
, y
, unit
);