xref: /freebsd/lib/libipsec/pfkey_dump.c (revision 3d95e9e3fe24f598a37c30e0418c49cfcec1b502)
1bd9f52d5SHajimu UMEMOTO /*	$KAME: pfkey_dump.c,v 1.45 2003/09/08 10:14:56 itojun Exp $	*/
23c62e87aSJun-ichiro itojun Hagino 
38a16b7a1SPedro F. Giffuni /*-
48a16b7a1SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
58a16b7a1SPedro F. Giffuni  *
69a4365d0SYoshinobu Inoue  * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
79a4365d0SYoshinobu Inoue  * All rights reserved.
89a4365d0SYoshinobu Inoue  *
99a4365d0SYoshinobu Inoue  * Redistribution and use in source and binary forms, with or without
109a4365d0SYoshinobu Inoue  * modification, are permitted provided that the following conditions
119a4365d0SYoshinobu Inoue  * are met:
129a4365d0SYoshinobu Inoue  * 1. Redistributions of source code must retain the above copyright
139a4365d0SYoshinobu Inoue  *    notice, this list of conditions and the following disclaimer.
149a4365d0SYoshinobu Inoue  * 2. Redistributions in binary form must reproduce the above copyright
159a4365d0SYoshinobu Inoue  *    notice, this list of conditions and the following disclaimer in the
169a4365d0SYoshinobu Inoue  *    documentation and/or other materials provided with the distribution.
179a4365d0SYoshinobu Inoue  * 3. Neither the name of the project nor the names of its contributors
189a4365d0SYoshinobu Inoue  *    may be used to endorse or promote products derived from this software
199a4365d0SYoshinobu Inoue  *    without specific prior written permission.
209a4365d0SYoshinobu Inoue  *
219a4365d0SYoshinobu Inoue  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
229a4365d0SYoshinobu Inoue  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
239a4365d0SYoshinobu Inoue  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
249a4365d0SYoshinobu Inoue  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
259a4365d0SYoshinobu Inoue  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
269a4365d0SYoshinobu Inoue  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
279a4365d0SYoshinobu Inoue  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
289a4365d0SYoshinobu Inoue  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
299a4365d0SYoshinobu Inoue  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
309a4365d0SYoshinobu Inoue  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
319a4365d0SYoshinobu Inoue  * SUCH DAMAGE.
329a4365d0SYoshinobu Inoue  */
339a4365d0SYoshinobu Inoue 
349a4365d0SYoshinobu Inoue #include <sys/types.h>
359a4365d0SYoshinobu Inoue #include <sys/param.h>
369a4365d0SYoshinobu Inoue #include <sys/socket.h>
3722986c67SAndrey V. Elsukov #include <net/if.h>
389a4365d0SYoshinobu Inoue #include <net/pfkeyv2.h>
3922986c67SAndrey V. Elsukov #include <netipsec/ipsec.h>
408409aedfSGeorge V. Neville-Neil #include <netipsec/key_var.h>
418409aedfSGeorge V. Neville-Neil #include <netipsec/key_debug.h>
429a4365d0SYoshinobu Inoue 
439a4365d0SYoshinobu Inoue #include <netinet/in.h>
449a4365d0SYoshinobu Inoue #include <arpa/inet.h>
459a4365d0SYoshinobu Inoue 
46*3d95e9e3SKonstantin Belousov #include <stdbool.h>
479a4365d0SYoshinobu Inoue #include <stdlib.h>
489a4365d0SYoshinobu Inoue #include <unistd.h>
499a4365d0SYoshinobu Inoue #include <stdio.h>
509a4365d0SYoshinobu Inoue #include <string.h>
519a4365d0SYoshinobu Inoue #include <time.h>
523c62e87aSJun-ichiro itojun Hagino #include <netdb.h>
539a4365d0SYoshinobu Inoue 
549a4365d0SYoshinobu Inoue #include "ipsec_strerror.h"
553c62e87aSJun-ichiro itojun Hagino #include "libpfkey.h"
569a4365d0SYoshinobu Inoue 
5733841545SHajimu UMEMOTO /* cope with old kame headers - ugly */
5833841545SHajimu UMEMOTO #ifndef SADB_X_AALG_NULL
5933841545SHajimu UMEMOTO #define SADB_X_AALG_NULL	SADB_AALG_NULL
6033841545SHajimu UMEMOTO #endif
6133841545SHajimu UMEMOTO 
6233841545SHajimu UMEMOTO #ifndef SADB_X_EALG_RC5CBC
6333841545SHajimu UMEMOTO #ifdef SADB_EALG_RC5CBC
6433841545SHajimu UMEMOTO #define SADB_X_EALG_RC5CBC	SADB_EALG_RC5CBC
6533841545SHajimu UMEMOTO #endif
6633841545SHajimu UMEMOTO #endif
6733841545SHajimu UMEMOTO 
689a4365d0SYoshinobu Inoue #define GETMSGSTR(str, num) \
693c62e87aSJun-ichiro itojun Hagino do { \
709a4365d0SYoshinobu Inoue 	if (sizeof((str)[0]) == 0 \
719a4365d0SYoshinobu Inoue 	 || num >= sizeof(str)/sizeof((str)[0])) \
729713f5c1SHajimu UMEMOTO 		printf("%u ", (num)); \
739a4365d0SYoshinobu Inoue 	else if (strlen((str)[(num)]) == 0) \
749713f5c1SHajimu UMEMOTO 		printf("%u ", (num)); \
759a4365d0SYoshinobu Inoue 	else \
769a4365d0SYoshinobu Inoue 		printf("%s ", (str)[(num)]); \
773c62e87aSJun-ichiro itojun Hagino } while (0)
789a4365d0SYoshinobu Inoue 
7933841545SHajimu UMEMOTO #define GETMSGV2S(v2s, num) \
8033841545SHajimu UMEMOTO do { \
8133841545SHajimu UMEMOTO 	struct val2str *p;  \
8233841545SHajimu UMEMOTO 	for (p = (v2s); p && p->str; p++) { \
8333841545SHajimu UMEMOTO 		if (p->val == (num)) \
8433841545SHajimu UMEMOTO 			break; \
8533841545SHajimu UMEMOTO 	} \
8633841545SHajimu UMEMOTO 	if (p && p->str) \
8733841545SHajimu UMEMOTO 		printf("%s ", p->str); \
8833841545SHajimu UMEMOTO 	else \
899713f5c1SHajimu UMEMOTO 		printf("%u ", (num)); \
9033841545SHajimu UMEMOTO } while (0)
9133841545SHajimu UMEMOTO 
9269160b1eSDavid E. O'Brien static char *str_ipaddr(struct sockaddr *);
93bd9f52d5SHajimu UMEMOTO static char *str_prefport(u_int, u_int, u_int, u_int);
94bd9f52d5SHajimu UMEMOTO static void str_upperspec(u_int, u_int, u_int);
9569160b1eSDavid E. O'Brien static char *str_time(time_t);
9669160b1eSDavid E. O'Brien static void str_lifetime_byte(struct sadb_lifetime *, char *);
979a4365d0SYoshinobu Inoue 
9833841545SHajimu UMEMOTO struct val2str {
9933841545SHajimu UMEMOTO 	int val;
10033841545SHajimu UMEMOTO 	const char *str;
10133841545SHajimu UMEMOTO };
10233841545SHajimu UMEMOTO 
1039a4365d0SYoshinobu Inoue /*
1049a4365d0SYoshinobu Inoue  * Must to be re-written about following strings.
1059a4365d0SYoshinobu Inoue  */
10633841545SHajimu UMEMOTO static char *str_satype[] = {
1079a4365d0SYoshinobu Inoue 	"unspec",
1089a4365d0SYoshinobu Inoue 	"unknown",
1099a4365d0SYoshinobu Inoue 	"ah",
1109a4365d0SYoshinobu Inoue 	"esp",
1119a4365d0SYoshinobu Inoue 	"unknown",
1129a4365d0SYoshinobu Inoue 	"rsvp",
1139a4365d0SYoshinobu Inoue 	"ospfv2",
1149a4365d0SYoshinobu Inoue 	"ripv2",
1159a4365d0SYoshinobu Inoue 	"mip",
1169a4365d0SYoshinobu Inoue 	"ipcomp",
1171922fd12SBruce M Simpson 	"policy",
1181922fd12SBruce M Simpson 	"tcp"
1199a4365d0SYoshinobu Inoue };
1209a4365d0SYoshinobu Inoue 
12133841545SHajimu UMEMOTO static char *str_mode[] = {
1229a4365d0SYoshinobu Inoue 	"any",
1239a4365d0SYoshinobu Inoue 	"transport",
1249a4365d0SYoshinobu Inoue 	"tunnel",
1259a4365d0SYoshinobu Inoue };
1269a4365d0SYoshinobu Inoue 
12733841545SHajimu UMEMOTO static char *str_state[] = {
1289a4365d0SYoshinobu Inoue 	"larval",
1299a4365d0SYoshinobu Inoue 	"mature",
1309a4365d0SYoshinobu Inoue 	"dying",
1319a4365d0SYoshinobu Inoue 	"dead",
1329a4365d0SYoshinobu Inoue };
1339a4365d0SYoshinobu Inoue 
13433841545SHajimu UMEMOTO static struct val2str str_alg_auth[] = {
13533841545SHajimu UMEMOTO 	{ SADB_AALG_NONE, "none", },
13633841545SHajimu UMEMOTO 	{ SADB_AALG_SHA1HMAC, "hmac-sha1", },
13733841545SHajimu UMEMOTO 	{ SADB_X_AALG_NULL, "null", },
1381922fd12SBruce M Simpson 	{ SADB_X_AALG_TCP_MD5, "tcp-md5", },
13933841545SHajimu UMEMOTO #ifdef SADB_X_AALG_SHA2_256
14033841545SHajimu UMEMOTO 	{ SADB_X_AALG_SHA2_256, "hmac-sha2-256", },
14133841545SHajimu UMEMOTO #endif
14233841545SHajimu UMEMOTO #ifdef SADB_X_AALG_SHA2_384
14333841545SHajimu UMEMOTO 	{ SADB_X_AALG_SHA2_384, "hmac-sha2-384", },
14433841545SHajimu UMEMOTO #endif
14533841545SHajimu UMEMOTO #ifdef SADB_X_AALG_SHA2_512
14633841545SHajimu UMEMOTO 	{ SADB_X_AALG_SHA2_512, "hmac-sha2-512", },
14733841545SHajimu UMEMOTO #endif
148c65ee7c7SHajimu UMEMOTO #ifdef SADB_X_AALG_AES_XCBC_MAC
149c65ee7c7SHajimu UMEMOTO 	{ SADB_X_AALG_AES_XCBC_MAC, "aes-xcbc-mac", },
150c65ee7c7SHajimu UMEMOTO #endif
1519f8f3a8eSKristof Provost #ifdef SADB_X_AALG_CHACHA20POLY1305
1529f8f3a8eSKristof Provost 	{ SADB_X_AALG_CHACHA20POLY1305, "chacha20-poly1305", },
1539f8f3a8eSKristof Provost #endif
15433841545SHajimu UMEMOTO 	{ -1, NULL, },
1559a4365d0SYoshinobu Inoue };
1569a4365d0SYoshinobu Inoue 
15733841545SHajimu UMEMOTO static struct val2str str_alg_enc[] = {
15833841545SHajimu UMEMOTO 	{ SADB_EALG_NONE, "none", },
15933841545SHajimu UMEMOTO 	{ SADB_EALG_NULL, "null", },
16033841545SHajimu UMEMOTO #ifdef SADB_X_EALG_RC5CBC
16133841545SHajimu UMEMOTO 	{ SADB_X_EALG_RC5CBC, "rc5-cbc", },
16233841545SHajimu UMEMOTO #endif
16300a4311aSJohn Baldwin #ifdef SADB_X_EALG_AESCBC
16400a4311aSJohn Baldwin 	{ SADB_X_EALG_AESCBC, "aes-cbc", },
16533841545SHajimu UMEMOTO #endif
16633841545SHajimu UMEMOTO #ifdef SADB_X_EALG_TWOFISHCBC
16733841545SHajimu UMEMOTO 	{ SADB_X_EALG_TWOFISHCBC, "twofish-cbc", },
16833841545SHajimu UMEMOTO #endif
169b42ac57fSHajimu UMEMOTO #ifdef SADB_X_EALG_AESCTR
170b42ac57fSHajimu UMEMOTO 	{ SADB_X_EALG_AESCTR, "aes-ctr", },
171b42ac57fSHajimu UMEMOTO #endif
172987de844SGeorge V. Neville-Neil #ifdef SADB_X_EALG_AESGCM16
173987de844SGeorge V. Neville-Neil 	{ SADB_X_EALG_AESGCM16, "aes-gcm-16", },
174987de844SGeorge V. Neville-Neil #endif
1759f8f3a8eSKristof Provost #ifdef SADB_X_EALG_CHACHA20POLY1305
1769f8f3a8eSKristof Provost 	{ SADB_X_EALG_CHACHA20POLY1305, "chacha20-poly1305", },
1779f8f3a8eSKristof Provost #endif
17833841545SHajimu UMEMOTO 	{ -1, NULL, },
1799a4365d0SYoshinobu Inoue };
1809a4365d0SYoshinobu Inoue 
18133841545SHajimu UMEMOTO static struct val2str str_alg_comp[] = {
18233841545SHajimu UMEMOTO 	{ SADB_X_CALG_NONE, "none", },
18333841545SHajimu UMEMOTO 	{ SADB_X_CALG_OUI, "oui", },
18433841545SHajimu UMEMOTO 	{ SADB_X_CALG_DEFLATE, "deflate", },
18533841545SHajimu UMEMOTO 	{ SADB_X_CALG_LZS, "lzs", },
18633841545SHajimu UMEMOTO 	{ -1, NULL, },
1879a4365d0SYoshinobu Inoue };
1889a4365d0SYoshinobu Inoue 
18922986c67SAndrey V. Elsukov static struct val2str str_sp_scope[] = {
19022986c67SAndrey V. Elsukov 	{ IPSEC_POLICYSCOPE_GLOBAL, "global" },
19122986c67SAndrey V. Elsukov 	{ IPSEC_POLICYSCOPE_IFNET, "ifnet" },
19222986c67SAndrey V. Elsukov 	{ IPSEC_POLICYSCOPE_PCB, "pcb"},
19322986c67SAndrey V. Elsukov 	{ -1, NULL },
19422986c67SAndrey V. Elsukov };
19522986c67SAndrey V. Elsukov 
1969a4365d0SYoshinobu Inoue /*
1977a33c6bfSGordon Bergling  * dump SADB_MSG formatted.  For debugging, you should use kdebug_sadb().
1989a4365d0SYoshinobu Inoue  */
1999a4365d0SYoshinobu Inoue void
200650d6cc1SKonstantin Belousov pfkey_sadump(struct sadb_msg *m)
2019a4365d0SYoshinobu Inoue {
2029a4365d0SYoshinobu Inoue 	caddr_t mhp[SADB_EXT_MAX + 1];
2039a4365d0SYoshinobu Inoue 	struct sadb_sa *m_sa;
2043c62e87aSJun-ichiro itojun Hagino 	struct sadb_x_sa2 *m_sa2;
2051b1cd327SKonstantin Belousov 	struct sadb_lifetime *m_lftc, *m_lfth, *m_lfts, *m_lft_sw, *m_lft_hw;
2069a4365d0SYoshinobu Inoue 	struct sadb_address *m_saddr, *m_daddr, *m_paddr;
2079a4365d0SYoshinobu Inoue 	struct sadb_key *m_auth, *m_enc;
2089a4365d0SYoshinobu Inoue 	struct sadb_ident *m_sid, *m_did;
2099a4365d0SYoshinobu Inoue 	struct sadb_sens *m_sens;
210bf435626SFabien Thomas 	struct sadb_x_sa_replay *m_sa_replay;
211fcf59617SAndrey V. Elsukov 	struct sadb_x_nat_t_type *natt_type;
212fcf59617SAndrey V. Elsukov 	struct sadb_x_nat_t_port *natt_sport, *natt_dport;
213fcf59617SAndrey V. Elsukov 	struct sadb_address *natt_oai, *natt_oar;
214*3d95e9e3SKonstantin Belousov 	struct sadb_x_if_hw_offl *if_hw_offl;
215*3d95e9e3SKonstantin Belousov 	caddr_t p, ep;
216*3d95e9e3SKonstantin Belousov 	struct sadb_ext *ext;
217*3d95e9e3SKonstantin Belousov 	bool first;
2189a4365d0SYoshinobu Inoue 
2199a4365d0SYoshinobu Inoue 	/* check pfkey message. */
2209a4365d0SYoshinobu Inoue 	if (pfkey_align(m, mhp)) {
2219a4365d0SYoshinobu Inoue 		printf("%s\n", ipsec_strerror());
2229a4365d0SYoshinobu Inoue 		return;
2239a4365d0SYoshinobu Inoue 	}
2249a4365d0SYoshinobu Inoue 	if (pfkey_check(mhp)) {
2259a4365d0SYoshinobu Inoue 		printf("%s\n", ipsec_strerror());
2269a4365d0SYoshinobu Inoue 		return;
2279a4365d0SYoshinobu Inoue 	}
2289a4365d0SYoshinobu Inoue 
2299a4365d0SYoshinobu Inoue 	m_sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
2303c62e87aSJun-ichiro itojun Hagino 	m_sa2 = (struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2];
2319a4365d0SYoshinobu Inoue 	m_lftc = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_CURRENT];
2329a4365d0SYoshinobu Inoue 	m_lfth = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD];
2339a4365d0SYoshinobu Inoue 	m_lfts = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_SOFT];
2349a4365d0SYoshinobu Inoue 	m_saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2359a4365d0SYoshinobu Inoue 	m_daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2369a4365d0SYoshinobu Inoue 	m_paddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_PROXY];
2379a4365d0SYoshinobu Inoue 	m_auth = (struct sadb_key *)mhp[SADB_EXT_KEY_AUTH];
2389a4365d0SYoshinobu Inoue 	m_enc = (struct sadb_key *)mhp[SADB_EXT_KEY_ENCRYPT];
2399a4365d0SYoshinobu Inoue 	m_sid = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_SRC];
2403c62e87aSJun-ichiro itojun Hagino 	m_did = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_DST];
2419a4365d0SYoshinobu Inoue 	m_sens = (struct sadb_sens *)mhp[SADB_EXT_SENSITIVITY];
242bf435626SFabien Thomas 	m_sa_replay = (struct sadb_x_sa_replay *)mhp[SADB_X_EXT_SA_REPLAY];
243fcf59617SAndrey V. Elsukov 	natt_type = (struct sadb_x_nat_t_type *)mhp[SADB_X_EXT_NAT_T_TYPE];
244fcf59617SAndrey V. Elsukov 	natt_sport = (struct sadb_x_nat_t_port *)mhp[SADB_X_EXT_NAT_T_SPORT];
245fcf59617SAndrey V. Elsukov 	natt_dport = (struct sadb_x_nat_t_port *)mhp[SADB_X_EXT_NAT_T_DPORT];
246fcf59617SAndrey V. Elsukov 	natt_oai = (struct sadb_address *)mhp[SADB_X_EXT_NAT_T_OAI];
247fcf59617SAndrey V. Elsukov 	natt_oar = (struct sadb_address *)mhp[SADB_X_EXT_NAT_T_OAR];
2481b1cd327SKonstantin Belousov 	m_lft_sw = (struct sadb_lifetime *)mhp[SADB_X_EXT_LFT_CUR_SW_OFFL];
2491b1cd327SKonstantin Belousov 	m_lft_hw = (struct sadb_lifetime *)mhp[SADB_X_EXT_LFT_CUR_HW_OFFL];
250*3d95e9e3SKonstantin Belousov 	if_hw_offl = (struct sadb_x_if_hw_offl *)mhp[SADB_X_EXT_IF_HW_OFFL];
2519a4365d0SYoshinobu Inoue 
2529a4365d0SYoshinobu Inoue 	/* source address */
2539a4365d0SYoshinobu Inoue 	if (m_saddr == NULL) {
2549a4365d0SYoshinobu Inoue 		printf("no ADDRESS_SRC extension.\n");
2559a4365d0SYoshinobu Inoue 		return;
2569a4365d0SYoshinobu Inoue 	}
2573c62e87aSJun-ichiro itojun Hagino 	printf("%s", str_ipaddr((struct sockaddr *)(m_saddr + 1)));
258fcf59617SAndrey V. Elsukov 	if (natt_type != NULL && natt_sport != NULL)
259fcf59617SAndrey V. Elsukov 		printf("[%u]", ntohs(natt_sport->sadb_x_nat_t_port_port));
2609a4365d0SYoshinobu Inoue 
2619a4365d0SYoshinobu Inoue 	/* destination address */
2629a4365d0SYoshinobu Inoue 	if (m_daddr == NULL) {
263fcf59617SAndrey V. Elsukov 		printf("\nno ADDRESS_DST extension.\n");
2649a4365d0SYoshinobu Inoue 		return;
2659a4365d0SYoshinobu Inoue 	}
2663c62e87aSJun-ichiro itojun Hagino 	printf(" %s", str_ipaddr((struct sockaddr *)(m_daddr + 1)));
267fcf59617SAndrey V. Elsukov 	if (natt_type != NULL && natt_dport != NULL)
268fcf59617SAndrey V. Elsukov 		printf("[%u]", ntohs(natt_dport->sadb_x_nat_t_port_port));
2699a4365d0SYoshinobu Inoue 
2709a4365d0SYoshinobu Inoue 	/* SA type */
2719a4365d0SYoshinobu Inoue 	if (m_sa == NULL) {
272fcf59617SAndrey V. Elsukov 		printf("\nno SA extension.\n");
2739a4365d0SYoshinobu Inoue 		return;
2749a4365d0SYoshinobu Inoue 	}
2753c62e87aSJun-ichiro itojun Hagino 	if (m_sa2 == NULL) {
276fcf59617SAndrey V. Elsukov 		printf("\nno SA2 extension.\n");
2773c62e87aSJun-ichiro itojun Hagino 		return;
2783c62e87aSJun-ichiro itojun Hagino 	}
2799a4365d0SYoshinobu Inoue 	printf("\n\t");
2809a4365d0SYoshinobu Inoue 
281fcf59617SAndrey V. Elsukov 	if (m->sadb_msg_satype == SADB_SATYPE_ESP && natt_type != NULL)
282fcf59617SAndrey V. Elsukov 		printf("esp-udp ");
283fcf59617SAndrey V. Elsukov 	else
28433841545SHajimu UMEMOTO 		GETMSGSTR(str_satype, m->sadb_msg_satype);
2859a4365d0SYoshinobu Inoue 
2869a4365d0SYoshinobu Inoue 	printf("mode=");
28733841545SHajimu UMEMOTO 	GETMSGSTR(str_mode, m_sa2->sadb_x_sa2_mode);
2889a4365d0SYoshinobu Inoue 
2893c62e87aSJun-ichiro itojun Hagino 	printf("spi=%u(0x%08x) reqid=%u(0x%08x)\n",
2909a4365d0SYoshinobu Inoue 		(u_int32_t)ntohl(m_sa->sadb_sa_spi),
2919a4365d0SYoshinobu Inoue 		(u_int32_t)ntohl(m_sa->sadb_sa_spi),
2923c62e87aSJun-ichiro itojun Hagino 		(u_int32_t)m_sa2->sadb_x_sa2_reqid,
2933c62e87aSJun-ichiro itojun Hagino 		(u_int32_t)m_sa2->sadb_x_sa2_reqid);
2949a4365d0SYoshinobu Inoue 
295fcf59617SAndrey V. Elsukov 	/* other NAT-T information */
296fcf59617SAndrey V. Elsukov 	if (natt_type != NULL && (natt_oai != NULL || natt_oar != NULL)) {
297fcf59617SAndrey V. Elsukov 		printf("\tNAT:");
298fcf59617SAndrey V. Elsukov 		if (natt_oai != NULL)
299fcf59617SAndrey V. Elsukov 			printf(" OAI=%s",
300fcf59617SAndrey V. Elsukov 			    str_ipaddr((struct sockaddr *)(natt_oai + 1)));
301fcf59617SAndrey V. Elsukov 		if (natt_oar != NULL)
302fcf59617SAndrey V. Elsukov 			printf(" OAR=%s",
303fcf59617SAndrey V. Elsukov 			    str_ipaddr((struct sockaddr *)(natt_oar + 1)));
304fcf59617SAndrey V. Elsukov 		printf("\n");
305fcf59617SAndrey V. Elsukov 	}
306fcf59617SAndrey V. Elsukov 
3079a4365d0SYoshinobu Inoue 	/* encryption key */
3089a4365d0SYoshinobu Inoue 	if (m->sadb_msg_satype == SADB_X_SATYPE_IPCOMP) {
3099a4365d0SYoshinobu Inoue 		printf("\tC: ");
31033841545SHajimu UMEMOTO 		GETMSGV2S(str_alg_comp, m_sa->sadb_sa_encrypt);
3119a4365d0SYoshinobu Inoue 	} else if (m->sadb_msg_satype == SADB_SATYPE_ESP) {
3129a4365d0SYoshinobu Inoue 		if (m_enc != NULL) {
3139a4365d0SYoshinobu Inoue 			printf("\tE: ");
31433841545SHajimu UMEMOTO 			GETMSGV2S(str_alg_enc, m_sa->sadb_sa_encrypt);
3159a4365d0SYoshinobu Inoue 			ipsec_hexdump((caddr_t)m_enc + sizeof(*m_enc),
3169a4365d0SYoshinobu Inoue 				      m_enc->sadb_key_bits / 8);
3179a4365d0SYoshinobu Inoue 			printf("\n");
3189a4365d0SYoshinobu Inoue 		}
3199a4365d0SYoshinobu Inoue 	}
3209a4365d0SYoshinobu Inoue 
3219a4365d0SYoshinobu Inoue 	/* authentication key */
3229a4365d0SYoshinobu Inoue 	if (m_auth != NULL) {
3239a4365d0SYoshinobu Inoue 		printf("\tA: ");
32433841545SHajimu UMEMOTO 		GETMSGV2S(str_alg_auth, m_sa->sadb_sa_auth);
3259a4365d0SYoshinobu Inoue 		ipsec_hexdump((caddr_t)m_auth + sizeof(*m_auth),
3269a4365d0SYoshinobu Inoue 		              m_auth->sadb_key_bits / 8);
3279a4365d0SYoshinobu Inoue 		printf("\n");
3289a4365d0SYoshinobu Inoue 	}
3299a4365d0SYoshinobu Inoue 
3303c62e87aSJun-ichiro itojun Hagino 	/* replay windoe size & flags */
331232bdaf6SHajimu UMEMOTO 	printf("\tseq=0x%08x replay=%u flags=0x%08x ",
332232bdaf6SHajimu UMEMOTO 		m_sa2->sadb_x_sa2_sequence,
333bf435626SFabien Thomas 		m_sa_replay ? (m_sa_replay->sadb_x_sa_replay_replay >> 3) :
3343c62e87aSJun-ichiro itojun Hagino 			m_sa->sadb_sa_replay,
3353c62e87aSJun-ichiro itojun Hagino 		m_sa->sadb_sa_flags);
3363c62e87aSJun-ichiro itojun Hagino 
3379a4365d0SYoshinobu Inoue 	/* state */
3383c62e87aSJun-ichiro itojun Hagino 	printf("state=");
33933841545SHajimu UMEMOTO 	GETMSGSTR(str_state, m_sa->sadb_sa_state);
340232bdaf6SHajimu UMEMOTO 	printf("\n");
3419a4365d0SYoshinobu Inoue 
342*3d95e9e3SKonstantin Belousov 	/* hw offload interface */
343*3d95e9e3SKonstantin Belousov 	if (if_hw_offl != NULL) {
344*3d95e9e3SKonstantin Belousov 		p = (caddr_t)m;
345*3d95e9e3SKonstantin Belousov 		ep = p + PFKEY_UNUNIT64(m->sadb_msg_len);
346*3d95e9e3SKonstantin Belousov 		p += sizeof(struct sadb_msg);
347*3d95e9e3SKonstantin Belousov 		printf("\thw offl if: ");
348*3d95e9e3SKonstantin Belousov 
349*3d95e9e3SKonstantin Belousov 		for (first = true; p < ep; p += PFKEY_EXTLEN(ext)) {
350*3d95e9e3SKonstantin Belousov 			ext = (struct sadb_ext *)p;
351*3d95e9e3SKonstantin Belousov 			if (ext->sadb_ext_type != SADB_X_EXT_IF_HW_OFFL)
352*3d95e9e3SKonstantin Belousov 				continue;
353*3d95e9e3SKonstantin Belousov 			if_hw_offl = (struct sadb_x_if_hw_offl *)ext;
354*3d95e9e3SKonstantin Belousov 			if (first)
355*3d95e9e3SKonstantin Belousov 				first = false;
356*3d95e9e3SKonstantin Belousov 			else
357*3d95e9e3SKonstantin Belousov 				printf(",");
358*3d95e9e3SKonstantin Belousov 			printf("%s", if_hw_offl->sadb_x_if_hw_offl_if);
359*3d95e9e3SKonstantin Belousov 		}
360*3d95e9e3SKonstantin Belousov 		printf("\n");
361*3d95e9e3SKonstantin Belousov 	}
362*3d95e9e3SKonstantin Belousov 
3639a4365d0SYoshinobu Inoue 	/* lifetime */
3649a4365d0SYoshinobu Inoue 	if (m_lftc != NULL) {
3659a4365d0SYoshinobu Inoue 		time_t tmp_time = time(0);
3669a4365d0SYoshinobu Inoue 
3679a4365d0SYoshinobu Inoue 		printf("\tcreated: %s",
3683c62e87aSJun-ichiro itojun Hagino 			str_time(m_lftc->sadb_lifetime_addtime));
3693c62e87aSJun-ichiro itojun Hagino 		printf("\tcurrent: %s\n", str_time(tmp_time));
3709a4365d0SYoshinobu Inoue 		printf("\tdiff: %lu(s)",
3719a4365d0SYoshinobu Inoue 			(u_long)(m_lftc->sadb_lifetime_addtime == 0 ?
3729a4365d0SYoshinobu Inoue 			0 : (tmp_time - m_lftc->sadb_lifetime_addtime)));
3739a4365d0SYoshinobu Inoue 
3749a4365d0SYoshinobu Inoue 		printf("\thard: %lu(s)",
3759a4365d0SYoshinobu Inoue 			(u_long)(m_lfth == NULL ?
3769a4365d0SYoshinobu Inoue 			0 : m_lfth->sadb_lifetime_addtime));
3779a4365d0SYoshinobu Inoue 		printf("\tsoft: %lu(s)\n",
3789a4365d0SYoshinobu Inoue 			(u_long)(m_lfts == NULL ?
3799a4365d0SYoshinobu Inoue 			0 : m_lfts->sadb_lifetime_addtime));
3809a4365d0SYoshinobu Inoue 
3819a4365d0SYoshinobu Inoue 		printf("\tlast: %s",
3823c62e87aSJun-ichiro itojun Hagino 			str_time(m_lftc->sadb_lifetime_usetime));
3839a4365d0SYoshinobu Inoue 		printf("\thard: %lu(s)",
3849a4365d0SYoshinobu Inoue 			(u_long)(m_lfth == NULL ?
3859a4365d0SYoshinobu Inoue 			0 : m_lfth->sadb_lifetime_usetime));
3869a4365d0SYoshinobu Inoue 		printf("\tsoft: %lu(s)\n",
3879a4365d0SYoshinobu Inoue 			(u_long)(m_lfts == NULL ?
3889a4365d0SYoshinobu Inoue 			0 : m_lfts->sadb_lifetime_usetime));
3899a4365d0SYoshinobu Inoue 
3903c62e87aSJun-ichiro itojun Hagino 		str_lifetime_byte(m_lftc, "current");
3913c62e87aSJun-ichiro itojun Hagino 		str_lifetime_byte(m_lfth, "hard");
3923c62e87aSJun-ichiro itojun Hagino 		str_lifetime_byte(m_lfts, "soft");
3939a4365d0SYoshinobu Inoue 		printf("\n");
3949a4365d0SYoshinobu Inoue 
3959a4365d0SYoshinobu Inoue 		printf("\tallocated: %lu",
3969a4365d0SYoshinobu Inoue 			(unsigned long)m_lftc->sadb_lifetime_allocations);
3979a4365d0SYoshinobu Inoue 		printf("\thard: %lu",
3989a4365d0SYoshinobu Inoue 			(u_long)(m_lfth == NULL ?
3999a4365d0SYoshinobu Inoue 			0 : m_lfth->sadb_lifetime_allocations));
4009a4365d0SYoshinobu Inoue 		printf("\tsoft: %lu\n",
4019a4365d0SYoshinobu Inoue 			(u_long)(m_lfts == NULL ?
4029a4365d0SYoshinobu Inoue 			0 : m_lfts->sadb_lifetime_allocations));
4039a4365d0SYoshinobu Inoue 	}
4049a4365d0SYoshinobu Inoue 
405232bdaf6SHajimu UMEMOTO 	printf("\tsadb_seq=%lu pid=%lu ",
406232bdaf6SHajimu UMEMOTO 		(u_long)m->sadb_msg_seq,
407232bdaf6SHajimu UMEMOTO 		(u_long)m->sadb_msg_pid);
408232bdaf6SHajimu UMEMOTO 
4099a4365d0SYoshinobu Inoue 	/* XXX DEBUG */
410232bdaf6SHajimu UMEMOTO 	printf("refcnt=%u\n", m->sadb_msg_reserved);
4119a4365d0SYoshinobu Inoue 
4121b1cd327SKonstantin Belousov 	if (m_lft_sw != NULL) {
4131b1cd327SKonstantin Belousov 		printf("\tsw offl use: %s",
4141b1cd327SKonstantin Belousov 		    str_time(m_lft_sw->sadb_lifetime_usetime));
4151b1cd327SKonstantin Belousov 		printf("\tsw offl allocated: %lu",
4161b1cd327SKonstantin Belousov 		    (unsigned long)m_lft_sw->sadb_lifetime_allocations);
4171b1cd327SKonstantin Belousov 		str_lifetime_byte(m_lft_sw, "sw offl");
4181b1cd327SKonstantin Belousov 		printf("\n");
4191b1cd327SKonstantin Belousov 	}
4201b1cd327SKonstantin Belousov 
4211b1cd327SKonstantin Belousov 	if (m_lft_hw != NULL) {
4221b1cd327SKonstantin Belousov 		printf("\thw offl use: %s",
4231b1cd327SKonstantin Belousov 		    str_time(m_lft_hw->sadb_lifetime_usetime));
4241b1cd327SKonstantin Belousov 		printf("\thw offl allocated: %lu",
4251b1cd327SKonstantin Belousov 		    (unsigned long)m_lft_hw->sadb_lifetime_allocations);
4261b1cd327SKonstantin Belousov 		str_lifetime_byte(m_lft_hw, "hw offl");
4271b1cd327SKonstantin Belousov 		printf("\n");
4281b1cd327SKonstantin Belousov 	}
4299a4365d0SYoshinobu Inoue }
4309a4365d0SYoshinobu Inoue 
4319a4365d0SYoshinobu Inoue void
43222986c67SAndrey V. Elsukov pfkey_spdump(struct sadb_msg *m)
4339a4365d0SYoshinobu Inoue {
4343c62e87aSJun-ichiro itojun Hagino 	char pbuf[NI_MAXSERV];
4359a4365d0SYoshinobu Inoue 	caddr_t mhp[SADB_EXT_MAX + 1];
4369a4365d0SYoshinobu Inoue 	struct sadb_address *m_saddr, *m_daddr;
4379a4365d0SYoshinobu Inoue 	struct sadb_x_policy *m_xpl;
438bd9f52d5SHajimu UMEMOTO 	struct sadb_lifetime *m_lftc = NULL, *m_lfth = NULL;
4393c62e87aSJun-ichiro itojun Hagino 	struct sockaddr *sa;
440bd9f52d5SHajimu UMEMOTO 	u_int16_t sport = 0, dport = 0;
4419a4365d0SYoshinobu Inoue 
4429a4365d0SYoshinobu Inoue 	/* check pfkey message. */
4439a4365d0SYoshinobu Inoue 	if (pfkey_align(m, mhp)) {
4449a4365d0SYoshinobu Inoue 		printf("%s\n", ipsec_strerror());
4459a4365d0SYoshinobu Inoue 		return;
4469a4365d0SYoshinobu Inoue 	}
4479a4365d0SYoshinobu Inoue 	if (pfkey_check(mhp)) {
4489a4365d0SYoshinobu Inoue 		printf("%s\n", ipsec_strerror());
4499a4365d0SYoshinobu Inoue 		return;
4509a4365d0SYoshinobu Inoue 	}
4519a4365d0SYoshinobu Inoue 
4529a4365d0SYoshinobu Inoue 	m_saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
4539a4365d0SYoshinobu Inoue 	m_daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
4549a4365d0SYoshinobu Inoue 	m_xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
455bd9f52d5SHajimu UMEMOTO 	m_lftc = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_CURRENT];
456bd9f52d5SHajimu UMEMOTO 	m_lfth = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD];
4579a4365d0SYoshinobu Inoue 
458bd9f52d5SHajimu UMEMOTO 	if (m_saddr && m_daddr) {
4599a4365d0SYoshinobu Inoue 		/* source address */
4603c62e87aSJun-ichiro itojun Hagino 		sa = (struct sockaddr *)(m_saddr + 1);
4613c62e87aSJun-ichiro itojun Hagino 		switch (sa->sa_family) {
4623c62e87aSJun-ichiro itojun Hagino 		case AF_INET:
4633c62e87aSJun-ichiro itojun Hagino 		case AF_INET6:
464bd9f52d5SHajimu UMEMOTO 			if (getnameinfo(sa, sa->sa_len, NULL, 0,
465bd9f52d5SHajimu UMEMOTO 			    pbuf, sizeof(pbuf), NI_NUMERICSERV) != 0)
466bd9f52d5SHajimu UMEMOTO 				sport = 0;	/*XXX*/
4673c62e87aSJun-ichiro itojun Hagino 			else
468bd9f52d5SHajimu UMEMOTO 				sport = atoi(pbuf);
4693c62e87aSJun-ichiro itojun Hagino 			printf("%s%s ", str_ipaddr(sa),
4703c62e87aSJun-ichiro itojun Hagino 				str_prefport(sa->sa_family,
471bd9f52d5SHajimu UMEMOTO 				    m_saddr->sadb_address_prefixlen, sport,
472bd9f52d5SHajimu UMEMOTO 				    m_saddr->sadb_address_proto));
4733c62e87aSJun-ichiro itojun Hagino 			break;
4743c62e87aSJun-ichiro itojun Hagino 		default:
4753c62e87aSJun-ichiro itojun Hagino 			printf("unknown-af ");
4763c62e87aSJun-ichiro itojun Hagino 			break;
4773c62e87aSJun-ichiro itojun Hagino 		}
4789a4365d0SYoshinobu Inoue 
4799a4365d0SYoshinobu Inoue 		/* destination address */
4803c62e87aSJun-ichiro itojun Hagino 		sa = (struct sockaddr *)(m_daddr + 1);
4813c62e87aSJun-ichiro itojun Hagino 		switch (sa->sa_family) {
4823c62e87aSJun-ichiro itojun Hagino 		case AF_INET:
4833c62e87aSJun-ichiro itojun Hagino 		case AF_INET6:
484bd9f52d5SHajimu UMEMOTO 			if (getnameinfo(sa, sa->sa_len, NULL, 0,
485bd9f52d5SHajimu UMEMOTO 			    pbuf, sizeof(pbuf), NI_NUMERICSERV) != 0)
486bd9f52d5SHajimu UMEMOTO 				dport = 0;	/*XXX*/
4873c62e87aSJun-ichiro itojun Hagino 			else
488bd9f52d5SHajimu UMEMOTO 				dport = atoi(pbuf);
4893c62e87aSJun-ichiro itojun Hagino 			printf("%s%s ", str_ipaddr(sa),
4903c62e87aSJun-ichiro itojun Hagino 				str_prefport(sa->sa_family,
491bd9f52d5SHajimu UMEMOTO 				    m_daddr->sadb_address_prefixlen, dport,
492bd9f52d5SHajimu UMEMOTO 				    m_saddr->sadb_address_proto));
4933c62e87aSJun-ichiro itojun Hagino 			break;
4943c62e87aSJun-ichiro itojun Hagino 		default:
4953c62e87aSJun-ichiro itojun Hagino 			printf("unknown-af ");
4963c62e87aSJun-ichiro itojun Hagino 			break;
4973c62e87aSJun-ichiro itojun Hagino 		}
4989a4365d0SYoshinobu Inoue 
4999a4365d0SYoshinobu Inoue 		/* upper layer protocol */
500bd9f52d5SHajimu UMEMOTO 		if (m_saddr->sadb_address_proto !=
501bd9f52d5SHajimu UMEMOTO 		    m_daddr->sadb_address_proto) {
5029a4365d0SYoshinobu Inoue 			printf("upper layer protocol mismatched.\n");
5039a4365d0SYoshinobu Inoue 			return;
5049a4365d0SYoshinobu Inoue 		}
505bd9f52d5SHajimu UMEMOTO 		str_upperspec(m_saddr->sadb_address_proto, sport, dport);
506bd9f52d5SHajimu UMEMOTO 	}
5079a4365d0SYoshinobu Inoue 	else
508bd9f52d5SHajimu UMEMOTO 		printf("(no selector, probably per-socket policy) ");
5099a4365d0SYoshinobu Inoue 
5109a4365d0SYoshinobu Inoue 	/* policy */
5119a4365d0SYoshinobu Inoue     {
5129a4365d0SYoshinobu Inoue 	char *d_xpl;
5139a4365d0SYoshinobu Inoue 
5149a4365d0SYoshinobu Inoue 	if (m_xpl == NULL) {
5159a4365d0SYoshinobu Inoue 		printf("no X_POLICY extension.\n");
5169a4365d0SYoshinobu Inoue 		return;
5179a4365d0SYoshinobu Inoue 	}
5189a4365d0SYoshinobu Inoue 	d_xpl = ipsec_dump_policy((char *)m_xpl, "\n\t");
5199a4365d0SYoshinobu Inoue 
5209a4365d0SYoshinobu Inoue 	/* dump SPD */
5219a4365d0SYoshinobu Inoue 	printf("\n\t%s\n", d_xpl);
5229a4365d0SYoshinobu Inoue 	free(d_xpl);
5239a4365d0SYoshinobu Inoue     }
5249a4365d0SYoshinobu Inoue 
52533841545SHajimu UMEMOTO 	/* lifetime */
526bd9f52d5SHajimu UMEMOTO 	if (m_lftc) {
527bd9f52d5SHajimu UMEMOTO 		printf("\tcreated: %s  ",
528bd9f52d5SHajimu UMEMOTO 			str_time(m_lftc->sadb_lifetime_addtime));
529bd9f52d5SHajimu UMEMOTO 		printf("lastused: %s\n",
530bd9f52d5SHajimu UMEMOTO 			str_time(m_lftc->sadb_lifetime_usetime));
53133841545SHajimu UMEMOTO 	}
532bd9f52d5SHajimu UMEMOTO 	if (m_lfth) {
533bd9f52d5SHajimu UMEMOTO 		printf("\tlifetime: %lu(s) ",
534bd9f52d5SHajimu UMEMOTO 			(u_long)m_lfth->sadb_lifetime_addtime);
535bd9f52d5SHajimu UMEMOTO 		printf("validtime: %lu(s)\n",
536bd9f52d5SHajimu UMEMOTO 			(u_long)m_lfth->sadb_lifetime_usetime);
537bd9f52d5SHajimu UMEMOTO 	}
538bd9f52d5SHajimu UMEMOTO 
53933841545SHajimu UMEMOTO 
54022986c67SAndrey V. Elsukov 	printf("\tspid=%ld seq=%ld pid=%ld scope=",
5413c62e87aSJun-ichiro itojun Hagino 		(u_long)m_xpl->sadb_x_policy_id,
5429a4365d0SYoshinobu Inoue 		(u_long)m->sadb_msg_seq,
5439a4365d0SYoshinobu Inoue 		(u_long)m->sadb_msg_pid);
54422986c67SAndrey V. Elsukov 	GETMSGV2S(str_sp_scope, m_xpl->sadb_x_policy_scope);
54522986c67SAndrey V. Elsukov 	if (m_xpl->sadb_x_policy_scope == IPSEC_POLICYSCOPE_IFNET &&
54622986c67SAndrey V. Elsukov 	    if_indextoname(m_xpl->sadb_x_policy_ifindex, pbuf) != NULL)
54722986c67SAndrey V. Elsukov 		printf("ifname=%s", pbuf);
54822986c67SAndrey V. Elsukov 	printf("\n");
5499a4365d0SYoshinobu Inoue 
5509a4365d0SYoshinobu Inoue 	/* XXX TEST */
5513c62e87aSJun-ichiro itojun Hagino 	printf("\trefcnt=%u\n", m->sadb_msg_reserved);
5529a4365d0SYoshinobu Inoue 
5539a4365d0SYoshinobu Inoue 	return;
5549a4365d0SYoshinobu Inoue }
5559a4365d0SYoshinobu Inoue 
5569a4365d0SYoshinobu Inoue /*
5579a4365d0SYoshinobu Inoue  * set "ipaddress" to buffer.
5589a4365d0SYoshinobu Inoue  */
5599a4365d0SYoshinobu Inoue static char *
560650d6cc1SKonstantin Belousov str_ipaddr(struct sockaddr *sa)
5619a4365d0SYoshinobu Inoue {
5623c62e87aSJun-ichiro itojun Hagino 	static char buf[NI_MAXHOST];
5633c62e87aSJun-ichiro itojun Hagino 	const int niflag = NI_NUMERICHOST;
5649a4365d0SYoshinobu Inoue 
5653c62e87aSJun-ichiro itojun Hagino 	if (sa == NULL)
5669a4365d0SYoshinobu Inoue 		return "";
5679a4365d0SYoshinobu Inoue 
5683c62e87aSJun-ichiro itojun Hagino 	if (getnameinfo(sa, sa->sa_len, buf, sizeof(buf), NULL, 0, niflag) == 0)
5699a4365d0SYoshinobu Inoue 		return buf;
5703c62e87aSJun-ichiro itojun Hagino 	return NULL;
5719a4365d0SYoshinobu Inoue }
5729a4365d0SYoshinobu Inoue 
5739a4365d0SYoshinobu Inoue /*
5749a4365d0SYoshinobu Inoue  * set "/prefix[port number]" to buffer.
5759a4365d0SYoshinobu Inoue  */
5769a4365d0SYoshinobu Inoue static char *
577650d6cc1SKonstantin Belousov str_prefport(u_int family, u_int pref, u_int port, u_int ulp)
5789a4365d0SYoshinobu Inoue {
5799a4365d0SYoshinobu Inoue 	static char buf[128];
580296e054fSMunechika SUMIKAWA 	char prefbuf[128];
581296e054fSMunechika SUMIKAWA 	char portbuf[128];
5823c62e87aSJun-ichiro itojun Hagino 	int plen;
5839a4365d0SYoshinobu Inoue 
5843c62e87aSJun-ichiro itojun Hagino 	switch (family) {
5853c62e87aSJun-ichiro itojun Hagino 	case AF_INET:
5863c62e87aSJun-ichiro itojun Hagino 		plen = sizeof(struct in_addr) << 3;
5873c62e87aSJun-ichiro itojun Hagino 		break;
5883c62e87aSJun-ichiro itojun Hagino 	case AF_INET6:
5893c62e87aSJun-ichiro itojun Hagino 		plen = sizeof(struct in6_addr) << 3;
5903c62e87aSJun-ichiro itojun Hagino 		break;
5913c62e87aSJun-ichiro itojun Hagino 	default:
5923c62e87aSJun-ichiro itojun Hagino 		return "?";
5933c62e87aSJun-ichiro itojun Hagino 	}
5943c62e87aSJun-ichiro itojun Hagino 
5953c62e87aSJun-ichiro itojun Hagino 	if (pref == plen)
5969a4365d0SYoshinobu Inoue 		prefbuf[0] = '\0';
5979a4365d0SYoshinobu Inoue 	else
5989a4365d0SYoshinobu Inoue 		snprintf(prefbuf, sizeof(prefbuf), "/%u", pref);
5999a4365d0SYoshinobu Inoue 
600bd9f52d5SHajimu UMEMOTO 	if (ulp == IPPROTO_ICMPV6)
601bd9f52d5SHajimu UMEMOTO 		memset(portbuf, 0, sizeof(portbuf));
602bd9f52d5SHajimu UMEMOTO 	else {
6039a4365d0SYoshinobu Inoue 		if (port == IPSEC_PORT_ANY)
6049a4365d0SYoshinobu Inoue 			snprintf(portbuf, sizeof(portbuf), "[%s]", "any");
6059a4365d0SYoshinobu Inoue 		else
6063c62e87aSJun-ichiro itojun Hagino 			snprintf(portbuf, sizeof(portbuf), "[%u]", port);
607bd9f52d5SHajimu UMEMOTO 	}
6089a4365d0SYoshinobu Inoue 
6099a4365d0SYoshinobu Inoue 	snprintf(buf, sizeof(buf), "%s%s", prefbuf, portbuf);
6109a4365d0SYoshinobu Inoue 
6119a4365d0SYoshinobu Inoue 	return buf;
6129a4365d0SYoshinobu Inoue }
6139a4365d0SYoshinobu Inoue 
614bd9f52d5SHajimu UMEMOTO static void
615650d6cc1SKonstantin Belousov str_upperspec(u_int ulp, u_int p1, u_int p2)
616bd9f52d5SHajimu UMEMOTO {
617bd9f52d5SHajimu UMEMOTO 	if (ulp == IPSEC_ULPROTO_ANY)
618bd9f52d5SHajimu UMEMOTO 		printf("any");
619bd9f52d5SHajimu UMEMOTO 	else if (ulp == IPPROTO_ICMPV6) {
620bd9f52d5SHajimu UMEMOTO 		printf("icmp6");
621bd9f52d5SHajimu UMEMOTO 		if (!(p1 == IPSEC_PORT_ANY && p2 == IPSEC_PORT_ANY))
622bd9f52d5SHajimu UMEMOTO 			printf(" %u,%u", p1, p2);
623bd9f52d5SHajimu UMEMOTO 	} else {
624bd9f52d5SHajimu UMEMOTO 		struct protoent *ent;
625bd9f52d5SHajimu UMEMOTO 
626bd9f52d5SHajimu UMEMOTO 		switch (ulp) {
627bd9f52d5SHajimu UMEMOTO 		case IPPROTO_IPV4:
628bd9f52d5SHajimu UMEMOTO 			printf("ip4");
629bd9f52d5SHajimu UMEMOTO 			break;
630bd9f52d5SHajimu UMEMOTO 		default:
631bd9f52d5SHajimu UMEMOTO 			ent = getprotobynumber(ulp);
632bd9f52d5SHajimu UMEMOTO 			if (ent)
633bd9f52d5SHajimu UMEMOTO 				printf("%s", ent->p_name);
634bd9f52d5SHajimu UMEMOTO 			else
635bd9f52d5SHajimu UMEMOTO 				printf("%u", ulp);
636bd9f52d5SHajimu UMEMOTO 
637bd9f52d5SHajimu UMEMOTO 			endprotoent();
638bd9f52d5SHajimu UMEMOTO 			break;
639bd9f52d5SHajimu UMEMOTO 		}
640bd9f52d5SHajimu UMEMOTO 	}
641bd9f52d5SHajimu UMEMOTO }
642bd9f52d5SHajimu UMEMOTO 
6439a4365d0SYoshinobu Inoue /*
6449a4365d0SYoshinobu Inoue  * set "Mon Day Time Year" to buffer
6459a4365d0SYoshinobu Inoue  */
6469a4365d0SYoshinobu Inoue static char *
647650d6cc1SKonstantin Belousov str_time(time_t t)
6489a4365d0SYoshinobu Inoue {
6499a4365d0SYoshinobu Inoue 	static char buf[128];
6509a4365d0SYoshinobu Inoue 
6519a4365d0SYoshinobu Inoue 	if (t == 0) {
6529a4365d0SYoshinobu Inoue 		int i = 0;
6539a4365d0SYoshinobu Inoue 		for (;i < 20;) buf[i++] = ' ';
6549a4365d0SYoshinobu Inoue 	} else {
6559a4365d0SYoshinobu Inoue 		char *t0;
6569a4365d0SYoshinobu Inoue 		t0 = ctime(&t);
6579a4365d0SYoshinobu Inoue 		memcpy(buf, t0 + 4, 20);
6589a4365d0SYoshinobu Inoue 	}
6599a4365d0SYoshinobu Inoue 
6609a4365d0SYoshinobu Inoue 	buf[20] = '\0';
6619a4365d0SYoshinobu Inoue 
6629a4365d0SYoshinobu Inoue 	return(buf);
6639a4365d0SYoshinobu Inoue }
6649a4365d0SYoshinobu Inoue 
6659a4365d0SYoshinobu Inoue static void
666650d6cc1SKonstantin Belousov str_lifetime_byte(struct sadb_lifetime *x, char *str)
6679a4365d0SYoshinobu Inoue {
6689a4365d0SYoshinobu Inoue 	double y;
6699a4365d0SYoshinobu Inoue 	char *unit;
6709a4365d0SYoshinobu Inoue 	int w;
6719a4365d0SYoshinobu Inoue 
6729a4365d0SYoshinobu Inoue 	if (x == NULL) {
6739a4365d0SYoshinobu Inoue 		printf("\t%s: 0(bytes)", str);
6749a4365d0SYoshinobu Inoue 		return;
6759a4365d0SYoshinobu Inoue 	}
6769a4365d0SYoshinobu Inoue 
6773c62e87aSJun-ichiro itojun Hagino #if 0
6783c62e87aSJun-ichiro itojun Hagino 	if ((x->sadb_lifetime_bytes) / 1024 / 1024) {
6793c62e87aSJun-ichiro itojun Hagino 		y = (x->sadb_lifetime_bytes) * 1.0 / 1024 / 1024;
6803c62e87aSJun-ichiro itojun Hagino 		unit = "M";
6813c62e87aSJun-ichiro itojun Hagino 		w = 1;
6823c62e87aSJun-ichiro itojun Hagino 	} else if ((x->sadb_lifetime_bytes) / 1024) {
6833c62e87aSJun-ichiro itojun Hagino 		y = (x->sadb_lifetime_bytes) * 1.0 / 1024;
6843c62e87aSJun-ichiro itojun Hagino 		unit = "K";
6853c62e87aSJun-ichiro itojun Hagino 		w = 1;
6863c62e87aSJun-ichiro itojun Hagino 	} else {
6879a4365d0SYoshinobu Inoue 		y = (x->sadb_lifetime_bytes) * 1.0;
6889a4365d0SYoshinobu Inoue 		unit = "";
6899a4365d0SYoshinobu Inoue 		w = 0;
6903c62e87aSJun-ichiro itojun Hagino 	}
6913c62e87aSJun-ichiro itojun Hagino #else
6923c62e87aSJun-ichiro itojun Hagino 	y = (x->sadb_lifetime_bytes) * 1.0;
6933c62e87aSJun-ichiro itojun Hagino 	unit = "";
6943c62e87aSJun-ichiro itojun Hagino 	w = 0;
6953c62e87aSJun-ichiro itojun Hagino #endif
6969a4365d0SYoshinobu Inoue 	printf("\t%s: %.*f(%sbytes)", str, w, y, unit);
6979a4365d0SYoshinobu Inoue }
698