xref: /freebsd/lib/libipsec/pfkey_dump.c (revision 3c62e87aa307c7566c1e7986655911494d813dc5)
13c62e87aSJun-ichiro itojun Hagino /*	$FreeBSD$	*/
23c62e87aSJun-ichiro itojun Hagino /*	$KAME: pfkey_dump.c,v 1.19 2000/06/10 06:47:11 sakane Exp $	*/
33c62e87aSJun-ichiro itojun Hagino 
49a4365d0SYoshinobu Inoue /*
59a4365d0SYoshinobu Inoue  * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
69a4365d0SYoshinobu Inoue  * All rights reserved.
79a4365d0SYoshinobu Inoue  *
89a4365d0SYoshinobu Inoue  * Redistribution and use in source and binary forms, with or without
99a4365d0SYoshinobu Inoue  * modification, are permitted provided that the following conditions
109a4365d0SYoshinobu Inoue  * are met:
119a4365d0SYoshinobu Inoue  * 1. Redistributions of source code must retain the above copyright
129a4365d0SYoshinobu Inoue  *    notice, this list of conditions and the following disclaimer.
139a4365d0SYoshinobu Inoue  * 2. Redistributions in binary form must reproduce the above copyright
149a4365d0SYoshinobu Inoue  *    notice, this list of conditions and the following disclaimer in the
159a4365d0SYoshinobu Inoue  *    documentation and/or other materials provided with the distribution.
169a4365d0SYoshinobu Inoue  * 3. Neither the name of the project nor the names of its contributors
179a4365d0SYoshinobu Inoue  *    may be used to endorse or promote products derived from this software
189a4365d0SYoshinobu Inoue  *    without specific prior written permission.
199a4365d0SYoshinobu Inoue  *
209a4365d0SYoshinobu Inoue  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
219a4365d0SYoshinobu Inoue  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
229a4365d0SYoshinobu Inoue  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
239a4365d0SYoshinobu Inoue  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
249a4365d0SYoshinobu Inoue  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
259a4365d0SYoshinobu Inoue  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
269a4365d0SYoshinobu Inoue  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
279a4365d0SYoshinobu Inoue  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
289a4365d0SYoshinobu Inoue  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
299a4365d0SYoshinobu Inoue  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
309a4365d0SYoshinobu Inoue  * SUCH DAMAGE.
319a4365d0SYoshinobu Inoue  */
329a4365d0SYoshinobu Inoue 
339a4365d0SYoshinobu Inoue #include <sys/types.h>
349a4365d0SYoshinobu Inoue #include <sys/param.h>
359a4365d0SYoshinobu Inoue #include <sys/socket.h>
369a4365d0SYoshinobu Inoue #include <netinet6/ipsec.h>
379a4365d0SYoshinobu Inoue #include <net/pfkeyv2.h>
389a4365d0SYoshinobu Inoue #include <netkey/key_var.h>
399a4365d0SYoshinobu Inoue #include <netkey/key_debug.h>
409a4365d0SYoshinobu Inoue 
419a4365d0SYoshinobu Inoue #include <netinet/in.h>
429a4365d0SYoshinobu Inoue #include <netinet6/ipsec.h>
439a4365d0SYoshinobu Inoue #include <arpa/inet.h>
449a4365d0SYoshinobu Inoue 
459a4365d0SYoshinobu Inoue #include <stdlib.h>
469a4365d0SYoshinobu Inoue #include <unistd.h>
479a4365d0SYoshinobu Inoue #include <stdio.h>
489a4365d0SYoshinobu Inoue #include <string.h>
499a4365d0SYoshinobu Inoue #include <time.h>
503c62e87aSJun-ichiro itojun Hagino #include <netdb.h>
519a4365d0SYoshinobu Inoue 
529a4365d0SYoshinobu Inoue #include "ipsec_strerror.h"
533c62e87aSJun-ichiro itojun Hagino #include "libpfkey.h"
549a4365d0SYoshinobu Inoue 
559a4365d0SYoshinobu Inoue #define GETMSGSTR(str, num) \
563c62e87aSJun-ichiro itojun Hagino do { \
579a4365d0SYoshinobu Inoue 	if (sizeof((str)[0]) == 0 \
589a4365d0SYoshinobu Inoue 	 || num >= sizeof(str)/sizeof((str)[0])) \
599a4365d0SYoshinobu Inoue 		printf("%d ", (num)); \
609a4365d0SYoshinobu Inoue 	else if (strlen((str)[(num)]) == 0) \
619a4365d0SYoshinobu Inoue 		printf("%d ", (num)); \
629a4365d0SYoshinobu Inoue 	else \
639a4365d0SYoshinobu Inoue 		printf("%s ", (str)[(num)]); \
643c62e87aSJun-ichiro itojun Hagino } while (0)
659a4365d0SYoshinobu Inoue 
663c62e87aSJun-ichiro itojun Hagino static char *str_ipaddr __P((struct sockaddr *));
673c62e87aSJun-ichiro itojun Hagino static char *str_prefport __P((u_int, u_int, u_int));
683c62e87aSJun-ichiro itojun Hagino static char *str_time __P((time_t));
693c62e87aSJun-ichiro itojun Hagino static void str_lifetime_byte __P((struct sadb_lifetime *, char *));
709a4365d0SYoshinobu Inoue 
719a4365d0SYoshinobu Inoue /*
729a4365d0SYoshinobu Inoue  * Must to be re-written about following strings.
739a4365d0SYoshinobu Inoue  */
749a4365d0SYoshinobu Inoue static char *_str_satype[] = {
759a4365d0SYoshinobu Inoue 	"unspec",
769a4365d0SYoshinobu Inoue 	"unknown",
779a4365d0SYoshinobu Inoue 	"ah",
789a4365d0SYoshinobu Inoue 	"esp",
799a4365d0SYoshinobu Inoue 	"unknown",
809a4365d0SYoshinobu Inoue 	"rsvp",
819a4365d0SYoshinobu Inoue 	"ospfv2",
829a4365d0SYoshinobu Inoue 	"ripv2",
839a4365d0SYoshinobu Inoue 	"mip",
849a4365d0SYoshinobu Inoue 	"ipcomp",
859a4365d0SYoshinobu Inoue };
869a4365d0SYoshinobu Inoue 
879a4365d0SYoshinobu Inoue static char *_str_mode[] = {
889a4365d0SYoshinobu Inoue 	"any",
899a4365d0SYoshinobu Inoue 	"transport",
909a4365d0SYoshinobu Inoue 	"tunnel",
919a4365d0SYoshinobu Inoue };
929a4365d0SYoshinobu Inoue 
939a4365d0SYoshinobu Inoue static char *_str_upper[] = {
949a4365d0SYoshinobu Inoue /*0*/	"ip", "icmp", "igmp", "ggp", "ip4",
959a4365d0SYoshinobu Inoue 	"", "tcp", "", "egp", "",
969a4365d0SYoshinobu Inoue /*10*/	"", "", "", "", "",
979a4365d0SYoshinobu Inoue 	"", "", "udp", "", "",
989a4365d0SYoshinobu Inoue /*20*/	"", "", "idp", "", "",
999a4365d0SYoshinobu Inoue 	"", "", "", "", "tp",
1009a4365d0SYoshinobu Inoue /*30*/	"", "", "", "", "",
1019a4365d0SYoshinobu Inoue 	"", "", "", "", "",
1029a4365d0SYoshinobu Inoue /*40*/	"", "ip6", "", "rt6", "frag6",
1039a4365d0SYoshinobu Inoue 	"", "rsvp", "gre", "", "",
1049a4365d0SYoshinobu Inoue /*50*/	"esp", "ah", "", "", "",
1059a4365d0SYoshinobu Inoue 	"", "", "", "icmp6", "none",
1069a4365d0SYoshinobu Inoue /*60*/	"dst6",
1079a4365d0SYoshinobu Inoue };
1089a4365d0SYoshinobu Inoue 
1099a4365d0SYoshinobu Inoue static char *_str_state[] = {
1109a4365d0SYoshinobu Inoue 	"larval",
1119a4365d0SYoshinobu Inoue 	"mature",
1129a4365d0SYoshinobu Inoue 	"dying",
1139a4365d0SYoshinobu Inoue 	"dead",
1149a4365d0SYoshinobu Inoue };
1159a4365d0SYoshinobu Inoue 
1169a4365d0SYoshinobu Inoue static char *_str_alg_auth[] = {
1179a4365d0SYoshinobu Inoue 	"none",
1189a4365d0SYoshinobu Inoue 	"hmac-md5",
1199a4365d0SYoshinobu Inoue 	"hmac-sha1",
1209a4365d0SYoshinobu Inoue 	"md5",
1219a4365d0SYoshinobu Inoue 	"sha",
1229a4365d0SYoshinobu Inoue 	"null",
1239a4365d0SYoshinobu Inoue };
1249a4365d0SYoshinobu Inoue 
1259a4365d0SYoshinobu Inoue static char *_str_alg_enc[] = {
1269a4365d0SYoshinobu Inoue 	"none",
1279a4365d0SYoshinobu Inoue 	"des-cbc",
1289a4365d0SYoshinobu Inoue 	"3des-cbc",
1299a4365d0SYoshinobu Inoue 	"null",
1309a4365d0SYoshinobu Inoue 	"blowfish-cbc",
1319a4365d0SYoshinobu Inoue 	"cast128-cbc",
1329a4365d0SYoshinobu Inoue 	"rc5-cbc",
1339a4365d0SYoshinobu Inoue };
1349a4365d0SYoshinobu Inoue 
1359a4365d0SYoshinobu Inoue static char *_str_alg_comp[] = {
1369a4365d0SYoshinobu Inoue 	"none",
1379a4365d0SYoshinobu Inoue 	"oui",
1389a4365d0SYoshinobu Inoue 	"deflate",
1399a4365d0SYoshinobu Inoue 	"lzs",
1409a4365d0SYoshinobu Inoue };
1419a4365d0SYoshinobu Inoue 
1429a4365d0SYoshinobu Inoue /*
1439a4365d0SYoshinobu Inoue  * dump SADB_MSG formated.  For debugging, you should use kdebug_sadb().
1449a4365d0SYoshinobu Inoue  */
1459a4365d0SYoshinobu Inoue void
1469a4365d0SYoshinobu Inoue pfkey_sadump(m)
1479a4365d0SYoshinobu Inoue 	struct sadb_msg *m;
1489a4365d0SYoshinobu Inoue {
1499a4365d0SYoshinobu Inoue 	caddr_t mhp[SADB_EXT_MAX + 1];
1509a4365d0SYoshinobu Inoue 	struct sadb_sa *m_sa;
1513c62e87aSJun-ichiro itojun Hagino 	struct sadb_x_sa2 *m_sa2;
1529a4365d0SYoshinobu Inoue 	struct sadb_lifetime *m_lftc, *m_lfth, *m_lfts;
1539a4365d0SYoshinobu Inoue 	struct sadb_address *m_saddr, *m_daddr, *m_paddr;
1549a4365d0SYoshinobu Inoue 	struct sadb_key *m_auth, *m_enc;
1559a4365d0SYoshinobu Inoue 	struct sadb_ident *m_sid, *m_did;
1569a4365d0SYoshinobu Inoue 	struct sadb_sens *m_sens;
1579a4365d0SYoshinobu Inoue 
1589a4365d0SYoshinobu Inoue 	/* check pfkey message. */
1599a4365d0SYoshinobu Inoue 	if (pfkey_align(m, mhp)) {
1609a4365d0SYoshinobu Inoue 		printf("%s\n", ipsec_strerror());
1619a4365d0SYoshinobu Inoue 		return;
1629a4365d0SYoshinobu Inoue 	}
1639a4365d0SYoshinobu Inoue 	if (pfkey_check(mhp)) {
1649a4365d0SYoshinobu Inoue 		printf("%s\n", ipsec_strerror());
1659a4365d0SYoshinobu Inoue 		return;
1669a4365d0SYoshinobu Inoue 	}
1679a4365d0SYoshinobu Inoue 
1689a4365d0SYoshinobu Inoue 	m_sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1693c62e87aSJun-ichiro itojun Hagino 	m_sa2 = (struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2];
1709a4365d0SYoshinobu Inoue 	m_lftc = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_CURRENT];
1719a4365d0SYoshinobu Inoue 	m_lfth = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD];
1729a4365d0SYoshinobu Inoue 	m_lfts = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_SOFT];
1739a4365d0SYoshinobu Inoue 	m_saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
1749a4365d0SYoshinobu Inoue 	m_daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
1759a4365d0SYoshinobu Inoue 	m_paddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_PROXY];
1769a4365d0SYoshinobu Inoue 	m_auth = (struct sadb_key *)mhp[SADB_EXT_KEY_AUTH];
1779a4365d0SYoshinobu Inoue 	m_enc = (struct sadb_key *)mhp[SADB_EXT_KEY_ENCRYPT];
1789a4365d0SYoshinobu Inoue 	m_sid = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_SRC];
1793c62e87aSJun-ichiro itojun Hagino 	m_did = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_DST];
1809a4365d0SYoshinobu Inoue 	m_sens = (struct sadb_sens *)mhp[SADB_EXT_SENSITIVITY];
1819a4365d0SYoshinobu Inoue 
1829a4365d0SYoshinobu Inoue 	/* source address */
1839a4365d0SYoshinobu Inoue 	if (m_saddr == NULL) {
1849a4365d0SYoshinobu Inoue 		printf("no ADDRESS_SRC extension.\n");
1859a4365d0SYoshinobu Inoue 		return;
1869a4365d0SYoshinobu Inoue 	}
1873c62e87aSJun-ichiro itojun Hagino 	printf("%s ", str_ipaddr((struct sockaddr *)(m_saddr + 1)));
1889a4365d0SYoshinobu Inoue 
1899a4365d0SYoshinobu Inoue 	/* destination address */
1909a4365d0SYoshinobu Inoue 	if (m_daddr == NULL) {
1919a4365d0SYoshinobu Inoue 		printf("no ADDRESS_DST extension.\n");
1929a4365d0SYoshinobu Inoue 		return;
1939a4365d0SYoshinobu Inoue 	}
1943c62e87aSJun-ichiro itojun Hagino 	printf("%s ", str_ipaddr((struct sockaddr *)(m_daddr + 1)));
1959a4365d0SYoshinobu Inoue 
1969a4365d0SYoshinobu Inoue 	/* SA type */
1979a4365d0SYoshinobu Inoue 	if (m_sa == NULL) {
1989a4365d0SYoshinobu Inoue 		printf("no SA extension.\n");
1999a4365d0SYoshinobu Inoue 		return;
2009a4365d0SYoshinobu Inoue 	}
2013c62e87aSJun-ichiro itojun Hagino 	if (m_sa2 == NULL) {
2023c62e87aSJun-ichiro itojun Hagino 		printf("no SA2 extension.\n");
2033c62e87aSJun-ichiro itojun Hagino 		return;
2043c62e87aSJun-ichiro itojun Hagino 	}
2059a4365d0SYoshinobu Inoue 	printf("\n\t");
2069a4365d0SYoshinobu Inoue 
2079a4365d0SYoshinobu Inoue 	GETMSGSTR(_str_satype, m->sadb_msg_satype);
2089a4365d0SYoshinobu Inoue 
2099a4365d0SYoshinobu Inoue 	printf("mode=");
2103c62e87aSJun-ichiro itojun Hagino 	GETMSGSTR(_str_mode, m_sa2->sadb_x_sa2_mode);
2119a4365d0SYoshinobu Inoue 
2123c62e87aSJun-ichiro itojun Hagino 	printf("spi=%u(0x%08x) reqid=%u(0x%08x)\n",
2139a4365d0SYoshinobu Inoue 		(u_int32_t)ntohl(m_sa->sadb_sa_spi),
2149a4365d0SYoshinobu Inoue 		(u_int32_t)ntohl(m_sa->sadb_sa_spi),
2153c62e87aSJun-ichiro itojun Hagino 		(u_int32_t)m_sa2->sadb_x_sa2_reqid,
2163c62e87aSJun-ichiro itojun Hagino 		(u_int32_t)m_sa2->sadb_x_sa2_reqid);
2179a4365d0SYoshinobu Inoue 
2189a4365d0SYoshinobu Inoue 	/* encryption key */
2199a4365d0SYoshinobu Inoue 	if (m->sadb_msg_satype == SADB_X_SATYPE_IPCOMP) {
2209a4365d0SYoshinobu Inoue 		printf("\tC: ");
2219a4365d0SYoshinobu Inoue 		GETMSGSTR(_str_alg_comp, m_sa->sadb_sa_encrypt);
2229a4365d0SYoshinobu Inoue 	} else if (m->sadb_msg_satype == SADB_SATYPE_ESP) {
2239a4365d0SYoshinobu Inoue 		if (m_enc != NULL) {
2249a4365d0SYoshinobu Inoue 			printf("\tE: ");
2259a4365d0SYoshinobu Inoue 			GETMSGSTR(_str_alg_enc, m_sa->sadb_sa_encrypt);
2269a4365d0SYoshinobu Inoue 			ipsec_hexdump((caddr_t)m_enc + sizeof(*m_enc),
2279a4365d0SYoshinobu Inoue 				      m_enc->sadb_key_bits / 8);
2289a4365d0SYoshinobu Inoue 			printf("\n");
2299a4365d0SYoshinobu Inoue 		}
2309a4365d0SYoshinobu Inoue 	}
2319a4365d0SYoshinobu Inoue 
2329a4365d0SYoshinobu Inoue 	/* authentication key */
2339a4365d0SYoshinobu Inoue 	if (m_auth != NULL) {
2349a4365d0SYoshinobu Inoue 		printf("\tA: ");
2359a4365d0SYoshinobu Inoue 		GETMSGSTR(_str_alg_auth, m_sa->sadb_sa_auth);
2369a4365d0SYoshinobu Inoue 		ipsec_hexdump((caddr_t)m_auth + sizeof(*m_auth),
2379a4365d0SYoshinobu Inoue 		              m_auth->sadb_key_bits / 8);
2389a4365d0SYoshinobu Inoue 		printf("\n");
2399a4365d0SYoshinobu Inoue 	}
2409a4365d0SYoshinobu Inoue 
2413c62e87aSJun-ichiro itojun Hagino 	/* replay windoe size & flags */
2423c62e87aSJun-ichiro itojun Hagino 	printf("\treplay=%u flags=0x%08x ",
2433c62e87aSJun-ichiro itojun Hagino 		m_sa->sadb_sa_replay,
2443c62e87aSJun-ichiro itojun Hagino 		m_sa->sadb_sa_flags);
2453c62e87aSJun-ichiro itojun Hagino 
2469a4365d0SYoshinobu Inoue 	/* state */
2473c62e87aSJun-ichiro itojun Hagino 	printf("state=");
2489a4365d0SYoshinobu Inoue 	GETMSGSTR(_str_state, m_sa->sadb_sa_state);
2499a4365d0SYoshinobu Inoue 
2509a4365d0SYoshinobu Inoue 	printf("seq=%lu pid=%lu\n",
2519a4365d0SYoshinobu Inoue 		(u_long)m->sadb_msg_seq,
2529a4365d0SYoshinobu Inoue 		(u_long)m->sadb_msg_pid);
2539a4365d0SYoshinobu Inoue 
2549a4365d0SYoshinobu Inoue 	/* lifetime */
2559a4365d0SYoshinobu Inoue 	if (m_lftc != NULL) {
2569a4365d0SYoshinobu Inoue 		time_t tmp_time = time(0);
2579a4365d0SYoshinobu Inoue 
2589a4365d0SYoshinobu Inoue 		printf("\tcreated: %s",
2593c62e87aSJun-ichiro itojun Hagino 			str_time(m_lftc->sadb_lifetime_addtime));
2603c62e87aSJun-ichiro itojun Hagino 		printf("\tcurrent: %s\n", str_time(tmp_time));
2619a4365d0SYoshinobu Inoue 		printf("\tdiff: %lu(s)",
2629a4365d0SYoshinobu Inoue 			(u_long)(m_lftc->sadb_lifetime_addtime == 0 ?
2639a4365d0SYoshinobu Inoue 			0 : (tmp_time - m_lftc->sadb_lifetime_addtime)));
2649a4365d0SYoshinobu Inoue 
2659a4365d0SYoshinobu Inoue 		printf("\thard: %lu(s)",
2669a4365d0SYoshinobu Inoue 			(u_long)(m_lfth == NULL ?
2679a4365d0SYoshinobu Inoue 			0 : m_lfth->sadb_lifetime_addtime));
2689a4365d0SYoshinobu Inoue 		printf("\tsoft: %lu(s)\n",
2699a4365d0SYoshinobu Inoue 			(u_long)(m_lfts == NULL ?
2709a4365d0SYoshinobu Inoue 			0 : m_lfts->sadb_lifetime_addtime));
2719a4365d0SYoshinobu Inoue 
2729a4365d0SYoshinobu Inoue 		printf("\tlast: %s",
2733c62e87aSJun-ichiro itojun Hagino 			str_time(m_lftc->sadb_lifetime_usetime));
2749a4365d0SYoshinobu Inoue 		printf("\thard: %lu(s)",
2759a4365d0SYoshinobu Inoue 			(u_long)(m_lfth == NULL ?
2769a4365d0SYoshinobu Inoue 			0 : m_lfth->sadb_lifetime_usetime));
2779a4365d0SYoshinobu Inoue 		printf("\tsoft: %lu(s)\n",
2789a4365d0SYoshinobu Inoue 			(u_long)(m_lfts == NULL ?
2799a4365d0SYoshinobu Inoue 			0 : m_lfts->sadb_lifetime_usetime));
2809a4365d0SYoshinobu Inoue 
2813c62e87aSJun-ichiro itojun Hagino 		str_lifetime_byte(m_lftc, "current");
2823c62e87aSJun-ichiro itojun Hagino 		str_lifetime_byte(m_lfth, "hard");
2833c62e87aSJun-ichiro itojun Hagino 		str_lifetime_byte(m_lfts, "soft");
2849a4365d0SYoshinobu Inoue 		printf("\n");
2859a4365d0SYoshinobu Inoue 
2869a4365d0SYoshinobu Inoue 		printf("\tallocated: %lu",
2879a4365d0SYoshinobu Inoue 			(unsigned long)m_lftc->sadb_lifetime_allocations);
2889a4365d0SYoshinobu Inoue 		printf("\thard: %lu",
2899a4365d0SYoshinobu Inoue 			(u_long)(m_lfth == NULL ?
2909a4365d0SYoshinobu Inoue 			0 : m_lfth->sadb_lifetime_allocations));
2919a4365d0SYoshinobu Inoue 		printf("\tsoft: %lu\n",
2929a4365d0SYoshinobu Inoue 			(u_long)(m_lfts == NULL ?
2939a4365d0SYoshinobu Inoue 			0 : m_lfts->sadb_lifetime_allocations));
2949a4365d0SYoshinobu Inoue 	}
2959a4365d0SYoshinobu Inoue 
2969a4365d0SYoshinobu Inoue 	/* XXX DEBUG */
2973c62e87aSJun-ichiro itojun Hagino 	printf("\trefcnt=%u\n", m->sadb_msg_reserved);
2989a4365d0SYoshinobu Inoue 
2999a4365d0SYoshinobu Inoue 	return;
3009a4365d0SYoshinobu Inoue }
3019a4365d0SYoshinobu Inoue 
3029a4365d0SYoshinobu Inoue void
3039a4365d0SYoshinobu Inoue pfkey_spdump(m)
3049a4365d0SYoshinobu Inoue 	struct sadb_msg *m;
3059a4365d0SYoshinobu Inoue {
3063c62e87aSJun-ichiro itojun Hagino 	char pbuf[NI_MAXSERV];
3079a4365d0SYoshinobu Inoue 	caddr_t mhp[SADB_EXT_MAX + 1];
3089a4365d0SYoshinobu Inoue 	struct sadb_address *m_saddr, *m_daddr;
3099a4365d0SYoshinobu Inoue 	struct sadb_x_policy *m_xpl;
3103c62e87aSJun-ichiro itojun Hagino 	struct sockaddr *sa;
3113c62e87aSJun-ichiro itojun Hagino 	u_int16_t port;
3129a4365d0SYoshinobu Inoue 
3139a4365d0SYoshinobu Inoue 	/* check pfkey message. */
3149a4365d0SYoshinobu Inoue 	if (pfkey_align(m, mhp)) {
3159a4365d0SYoshinobu Inoue 		printf("%s\n", ipsec_strerror());
3169a4365d0SYoshinobu Inoue 		return;
3179a4365d0SYoshinobu Inoue 	}
3189a4365d0SYoshinobu Inoue 	if (pfkey_check(mhp)) {
3199a4365d0SYoshinobu Inoue 		printf("%s\n", ipsec_strerror());
3209a4365d0SYoshinobu Inoue 		return;
3219a4365d0SYoshinobu Inoue 	}
3229a4365d0SYoshinobu Inoue 
3239a4365d0SYoshinobu Inoue 	m_saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
3249a4365d0SYoshinobu Inoue 	m_daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
3259a4365d0SYoshinobu Inoue 	m_xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
3269a4365d0SYoshinobu Inoue 
3279a4365d0SYoshinobu Inoue 	/* source address */
3289a4365d0SYoshinobu Inoue 	if (m_saddr == NULL) {
3299a4365d0SYoshinobu Inoue 		printf("no ADDRESS_SRC extension.\n");
3309a4365d0SYoshinobu Inoue 		return;
3319a4365d0SYoshinobu Inoue 	}
3323c62e87aSJun-ichiro itojun Hagino 	sa = (struct sockaddr *)(m_saddr + 1);
3333c62e87aSJun-ichiro itojun Hagino 	switch (sa->sa_family) {
3343c62e87aSJun-ichiro itojun Hagino 	case AF_INET:
3353c62e87aSJun-ichiro itojun Hagino 	case AF_INET6:
3363c62e87aSJun-ichiro itojun Hagino 		if (getnameinfo(sa, sa->sa_len, NULL, 0, pbuf, sizeof(pbuf),
3373c62e87aSJun-ichiro itojun Hagino 		    NI_NUMERICSERV) != 0)
3383c62e87aSJun-ichiro itojun Hagino 			port = 0;	/*XXX*/
3393c62e87aSJun-ichiro itojun Hagino 		else
3403c62e87aSJun-ichiro itojun Hagino 			port = atoi(pbuf);
3413c62e87aSJun-ichiro itojun Hagino 		printf("%s%s ", str_ipaddr(sa),
3423c62e87aSJun-ichiro itojun Hagino 			str_prefport(sa->sa_family,
3433c62e87aSJun-ichiro itojun Hagino 			    m_saddr->sadb_address_prefixlen, port));
3443c62e87aSJun-ichiro itojun Hagino 		break;
3453c62e87aSJun-ichiro itojun Hagino 	default:
3463c62e87aSJun-ichiro itojun Hagino 		printf("unknown-af ");
3473c62e87aSJun-ichiro itojun Hagino 		break;
3483c62e87aSJun-ichiro itojun Hagino 	}
3499a4365d0SYoshinobu Inoue 
3509a4365d0SYoshinobu Inoue 	/* destination address */
3519a4365d0SYoshinobu Inoue 	if (m_daddr == NULL) {
3529a4365d0SYoshinobu Inoue 		printf("no ADDRESS_DST extension.\n");
3539a4365d0SYoshinobu Inoue 		return;
3549a4365d0SYoshinobu Inoue 	}
3553c62e87aSJun-ichiro itojun Hagino 	sa = (struct sockaddr *)(m_daddr + 1);
3563c62e87aSJun-ichiro itojun Hagino 	switch (sa->sa_family) {
3573c62e87aSJun-ichiro itojun Hagino 	case AF_INET:
3583c62e87aSJun-ichiro itojun Hagino 	case AF_INET6:
3593c62e87aSJun-ichiro itojun Hagino 		if (getnameinfo(sa, sa->sa_len, NULL, 0, pbuf, sizeof(pbuf),
3603c62e87aSJun-ichiro itojun Hagino 		    NI_NUMERICSERV) != 0)
3613c62e87aSJun-ichiro itojun Hagino 			port = 0;	/*XXX*/
3623c62e87aSJun-ichiro itojun Hagino 		else
3633c62e87aSJun-ichiro itojun Hagino 			port = atoi(pbuf);
3643c62e87aSJun-ichiro itojun Hagino 		printf("%s%s ", str_ipaddr(sa),
3653c62e87aSJun-ichiro itojun Hagino 			str_prefport(sa->sa_family,
3663c62e87aSJun-ichiro itojun Hagino 			    m_daddr->sadb_address_prefixlen, port));
3673c62e87aSJun-ichiro itojun Hagino 		break;
3683c62e87aSJun-ichiro itojun Hagino 	default:
3693c62e87aSJun-ichiro itojun Hagino 		printf("unknown-af ");
3703c62e87aSJun-ichiro itojun Hagino 		break;
3713c62e87aSJun-ichiro itojun Hagino 	}
3729a4365d0SYoshinobu Inoue 
3739a4365d0SYoshinobu Inoue 	/* upper layer protocol */
3743c62e87aSJun-ichiro itojun Hagino 	if (m_saddr->sadb_address_proto != m_daddr->sadb_address_proto) {
3759a4365d0SYoshinobu Inoue 		printf("upper layer protocol mismatched.\n");
3769a4365d0SYoshinobu Inoue 		return;
3779a4365d0SYoshinobu Inoue 	}
3789a4365d0SYoshinobu Inoue 	if (m_saddr->sadb_address_proto == IPSEC_ULPROTO_ANY)
3799a4365d0SYoshinobu Inoue 		printf("any");
3809a4365d0SYoshinobu Inoue 	else
3819a4365d0SYoshinobu Inoue 		GETMSGSTR(_str_upper, m_saddr->sadb_address_proto);
3829a4365d0SYoshinobu Inoue 
3839a4365d0SYoshinobu Inoue 	/* policy */
3849a4365d0SYoshinobu Inoue     {
3859a4365d0SYoshinobu Inoue 	char *d_xpl;
3869a4365d0SYoshinobu Inoue 
3879a4365d0SYoshinobu Inoue 	if (m_xpl == NULL) {
3889a4365d0SYoshinobu Inoue 		printf("no X_POLICY extension.\n");
3899a4365d0SYoshinobu Inoue 		return;
3909a4365d0SYoshinobu Inoue 	}
3919a4365d0SYoshinobu Inoue 	d_xpl = ipsec_dump_policy((char *)m_xpl, "\n\t");
3929a4365d0SYoshinobu Inoue 
3939a4365d0SYoshinobu Inoue 	/* dump SPD */
3949a4365d0SYoshinobu Inoue 	printf("\n\t%s\n", d_xpl);
3959a4365d0SYoshinobu Inoue 	free(d_xpl);
3969a4365d0SYoshinobu Inoue     }
3979a4365d0SYoshinobu Inoue 
3983c62e87aSJun-ichiro itojun Hagino 	printf("\tspid=%ld seq=%ld pid=%ld\n",
3993c62e87aSJun-ichiro itojun Hagino 		(u_long)m_xpl->sadb_x_policy_id,
4009a4365d0SYoshinobu Inoue 		(u_long)m->sadb_msg_seq,
4019a4365d0SYoshinobu Inoue 		(u_long)m->sadb_msg_pid);
4029a4365d0SYoshinobu Inoue 
4039a4365d0SYoshinobu Inoue 	/* XXX TEST */
4043c62e87aSJun-ichiro itojun Hagino 	printf("\trefcnt=%u\n", m->sadb_msg_reserved);
4059a4365d0SYoshinobu Inoue 
4069a4365d0SYoshinobu Inoue 	return;
4079a4365d0SYoshinobu Inoue }
4089a4365d0SYoshinobu Inoue 
4099a4365d0SYoshinobu Inoue /*
4109a4365d0SYoshinobu Inoue  * set "ipaddress" to buffer.
4119a4365d0SYoshinobu Inoue  */
4129a4365d0SYoshinobu Inoue static char *
4133c62e87aSJun-ichiro itojun Hagino str_ipaddr(sa)
4143c62e87aSJun-ichiro itojun Hagino 	struct sockaddr *sa;
4159a4365d0SYoshinobu Inoue {
4163c62e87aSJun-ichiro itojun Hagino 	static char buf[NI_MAXHOST];
4173c62e87aSJun-ichiro itojun Hagino #ifdef NI_WITHSCOPEID
4183c62e87aSJun-ichiro itojun Hagino 	const int niflag = NI_NUMERICHOST | NI_WITHSCOPEID;
4193c62e87aSJun-ichiro itojun Hagino #else
4203c62e87aSJun-ichiro itojun Hagino 	const int niflag = NI_NUMERICHOST;
4213c62e87aSJun-ichiro itojun Hagino #endif
4229a4365d0SYoshinobu Inoue 
4233c62e87aSJun-ichiro itojun Hagino 	if (sa == NULL)
4249a4365d0SYoshinobu Inoue 		return "";
4259a4365d0SYoshinobu Inoue 
4263c62e87aSJun-ichiro itojun Hagino 	if (getnameinfo(sa, sa->sa_len, buf, sizeof(buf), NULL, 0, niflag) == 0)
4279a4365d0SYoshinobu Inoue 		return buf;
4283c62e87aSJun-ichiro itojun Hagino 	return NULL;
4299a4365d0SYoshinobu Inoue }
4309a4365d0SYoshinobu Inoue 
4319a4365d0SYoshinobu Inoue /*
4329a4365d0SYoshinobu Inoue  * set "/prefix[port number]" to buffer.
4339a4365d0SYoshinobu Inoue  */
4349a4365d0SYoshinobu Inoue static char *
4353c62e87aSJun-ichiro itojun Hagino str_prefport(family, pref, port)
4369a4365d0SYoshinobu Inoue 	u_int family, pref, port;
4379a4365d0SYoshinobu Inoue {
4389a4365d0SYoshinobu Inoue 	static char buf[128];
4399a4365d0SYoshinobu Inoue 	char prefbuf[10];
4409a4365d0SYoshinobu Inoue 	char portbuf[10];
4413c62e87aSJun-ichiro itojun Hagino 	int plen;
4429a4365d0SYoshinobu Inoue 
4433c62e87aSJun-ichiro itojun Hagino 	switch (family) {
4443c62e87aSJun-ichiro itojun Hagino 	case AF_INET:
4453c62e87aSJun-ichiro itojun Hagino 		plen = sizeof(struct in_addr) << 3;
4463c62e87aSJun-ichiro itojun Hagino 		break;
4473c62e87aSJun-ichiro itojun Hagino 	case AF_INET6:
4483c62e87aSJun-ichiro itojun Hagino 		plen = sizeof(struct in6_addr) << 3;
4493c62e87aSJun-ichiro itojun Hagino 		break;
4503c62e87aSJun-ichiro itojun Hagino 	default:
4513c62e87aSJun-ichiro itojun Hagino 		return "?";
4523c62e87aSJun-ichiro itojun Hagino 	}
4533c62e87aSJun-ichiro itojun Hagino 
4543c62e87aSJun-ichiro itojun Hagino 	if (pref == plen)
4559a4365d0SYoshinobu Inoue 		prefbuf[0] = '\0';
4569a4365d0SYoshinobu Inoue 	else
4579a4365d0SYoshinobu Inoue 		snprintf(prefbuf, sizeof(prefbuf), "/%u", pref);
4589a4365d0SYoshinobu Inoue 
4599a4365d0SYoshinobu Inoue 	if (port == IPSEC_PORT_ANY)
4609a4365d0SYoshinobu Inoue 		snprintf(portbuf, sizeof(portbuf), "[%s]", "any");
4619a4365d0SYoshinobu Inoue 	else
4623c62e87aSJun-ichiro itojun Hagino 		snprintf(portbuf, sizeof(portbuf), "[%u]", port);
4639a4365d0SYoshinobu Inoue 
4649a4365d0SYoshinobu Inoue 	snprintf(buf, sizeof(buf), "%s%s", prefbuf, portbuf);
4659a4365d0SYoshinobu Inoue 
4669a4365d0SYoshinobu Inoue 	return buf;
4679a4365d0SYoshinobu Inoue }
4689a4365d0SYoshinobu Inoue 
4699a4365d0SYoshinobu Inoue /*
4709a4365d0SYoshinobu Inoue  * set "Mon Day Time Year" to buffer
4719a4365d0SYoshinobu Inoue  */
4729a4365d0SYoshinobu Inoue static char *
4733c62e87aSJun-ichiro itojun Hagino str_time(t)
4749a4365d0SYoshinobu Inoue 	time_t t;
4759a4365d0SYoshinobu Inoue {
4769a4365d0SYoshinobu Inoue 	static char buf[128];
4779a4365d0SYoshinobu Inoue 
4789a4365d0SYoshinobu Inoue 	if (t == 0) {
4799a4365d0SYoshinobu Inoue 		int i = 0;
4809a4365d0SYoshinobu Inoue 		for (;i < 20;) buf[i++] = ' ';
4819a4365d0SYoshinobu Inoue 	} else {
4829a4365d0SYoshinobu Inoue 		char *t0;
4839a4365d0SYoshinobu Inoue 		t0 = ctime(&t);
4849a4365d0SYoshinobu Inoue 		memcpy(buf, t0 + 4, 20);
4859a4365d0SYoshinobu Inoue 	}
4869a4365d0SYoshinobu Inoue 
4879a4365d0SYoshinobu Inoue 	buf[20] = '\0';
4889a4365d0SYoshinobu Inoue 
4899a4365d0SYoshinobu Inoue 	return(buf);
4909a4365d0SYoshinobu Inoue }
4919a4365d0SYoshinobu Inoue 
4929a4365d0SYoshinobu Inoue static void
4933c62e87aSJun-ichiro itojun Hagino str_lifetime_byte(x, str)
4949a4365d0SYoshinobu Inoue 	struct sadb_lifetime *x;
4959a4365d0SYoshinobu Inoue 	char *str;
4969a4365d0SYoshinobu Inoue {
4979a4365d0SYoshinobu Inoue 	double y;
4989a4365d0SYoshinobu Inoue 	char *unit;
4999a4365d0SYoshinobu Inoue 	int w;
5009a4365d0SYoshinobu Inoue 
5019a4365d0SYoshinobu Inoue 	if (x == NULL) {
5029a4365d0SYoshinobu Inoue 		printf("\t%s: 0(bytes)", str);
5039a4365d0SYoshinobu Inoue 		return;
5049a4365d0SYoshinobu Inoue 	}
5059a4365d0SYoshinobu Inoue 
5063c62e87aSJun-ichiro itojun Hagino #if 0
5073c62e87aSJun-ichiro itojun Hagino 	if ((x->sadb_lifetime_bytes) / 1024 / 1024) {
5083c62e87aSJun-ichiro itojun Hagino 		y = (x->sadb_lifetime_bytes) * 1.0 / 1024 / 1024;
5093c62e87aSJun-ichiro itojun Hagino 		unit = "M";
5103c62e87aSJun-ichiro itojun Hagino 		w = 1;
5113c62e87aSJun-ichiro itojun Hagino 	} else if ((x->sadb_lifetime_bytes) / 1024) {
5123c62e87aSJun-ichiro itojun Hagino 		y = (x->sadb_lifetime_bytes) * 1.0 / 1024;
5133c62e87aSJun-ichiro itojun Hagino 		unit = "K";
5143c62e87aSJun-ichiro itojun Hagino 		w = 1;
5153c62e87aSJun-ichiro itojun Hagino 	} else {
5169a4365d0SYoshinobu Inoue 		y = (x->sadb_lifetime_bytes) * 1.0;
5179a4365d0SYoshinobu Inoue 		unit = "";
5189a4365d0SYoshinobu Inoue 		w = 0;
5193c62e87aSJun-ichiro itojun Hagino 	}
5203c62e87aSJun-ichiro itojun Hagino #else
5213c62e87aSJun-ichiro itojun Hagino 	y = (x->sadb_lifetime_bytes) * 1.0;
5223c62e87aSJun-ichiro itojun Hagino 	unit = "";
5233c62e87aSJun-ichiro itojun Hagino 	w = 0;
5243c62e87aSJun-ichiro itojun Hagino #endif
5259a4365d0SYoshinobu Inoue 	printf("\t%s: %.*f(%sbytes)", str, w, y, unit);
5269a4365d0SYoshinobu Inoue }
527