diff options
Diffstat (limited to 'ipsec-tools/src/libipsec/pfkey_dump.c')
-rw-r--r-- | ipsec-tools/src/libipsec/pfkey_dump.c | 825 |
1 files changed, 825 insertions, 0 deletions
diff --git a/ipsec-tools/src/libipsec/pfkey_dump.c b/ipsec-tools/src/libipsec/pfkey_dump.c new file mode 100644 index 00000000..4627ebc8 --- /dev/null +++ b/ipsec-tools/src/libipsec/pfkey_dump.c @@ -0,0 +1,825 @@ +/* $NetBSD: pfkey_dump.c,v 1.18 2010/12/03 14:32:52 tteras Exp $ */ + +/* $KAME: pfkey_dump.c,v 1.45 2003/09/08 10:14:56 itojun Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/socket.h> +#include PATH_IPSEC_H +#include <net/pfkeyv2.h> + +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <netdb.h> + +#include "ipsec_strerror.h" +#include "libpfkey.h" + +/* cope with old kame headers - ugly */ +#ifndef SADB_X_AALG_MD5 +#define SADB_X_AALG_MD5 SADB_AALG_MD5 +#endif +#ifndef SADB_X_AALG_SHA +#define SADB_X_AALG_SHA SADB_AALG_SHA +#endif +#ifndef SADB_X_AALG_NULL +#define SADB_X_AALG_NULL SADB_AALG_NULL +#endif + +#ifndef SADB_X_EALG_BLOWFISHCBC +#define SADB_X_EALG_BLOWFISHCBC SADB_EALG_BLOWFISHCBC +#endif +#ifndef SADB_X_EALG_CAST128CBC +#define SADB_X_EALG_CAST128CBC SADB_EALG_CAST128CBC +#endif +#ifndef SADB_X_EALG_RC5CBC +#ifdef SADB_EALG_RC5CBC +#define SADB_X_EALG_RC5CBC SADB_EALG_RC5CBC +#endif +#endif +#if defined(SADB_X_EALG_AES) && ! defined(SADB_X_EALG_AESCBC) +#define SADB_X_EALG_AESCBC SADB_X_EALG_AES +#endif + +#define GETMSGSTR(str, num) \ +do { \ + /*CONSTCOND*/ \ + if (sizeof((str)[0]) == 0 \ + || num >= sizeof(str)/sizeof((str)[0])) \ + printf("%u ", (num)); \ + else if (strlen((str)[(num)]) == 0) \ + printf("%u ", (num)); \ + else \ + printf("%s ", (str)[(num)]); \ +} while (/*CONSTCOND*/0) + +#define GETMSGV2S(v2s, num) \ +do { \ + struct val2str *p; \ + for (p = (v2s); p && p->str; p++) { \ + if (p->val == (num)) \ + break; \ + } \ + if (p && p->str) \ + printf("%s ", p->str); \ + else \ + printf("%u ", (num)); \ +} while (/*CONSTCOND*/0) + +static char *str_ipaddr __P((struct sockaddr *)); +static char *str_ipport __P((struct sockaddr *)); +static char *str_prefport __P((u_int, u_int, u_int, u_int)); +static void str_upperspec __P((u_int, u_int, u_int)); +static char *str_time __P((time_t)); +static void str_lifetime_byte __P((struct sadb_lifetime *, char *)); +static void pfkey_sadump1(struct sadb_msg *, int); +static void pfkey_spdump1(struct sadb_msg *, int); + +struct val2str { + int val; + const char *str; +}; + +/* + * Must to be re-written about following strings. + */ +static char *str_satype[] = { + "unspec", + "unknown", + "ah", + "esp", + "unknown", + "rsvp", + "ospfv2", + "ripv2", + "mip", + "ipcomp", + "policy", + "tcp", +}; + +static char *str_mode[] = { + "any", + "transport", + "tunnel", +}; + +static char *str_state[] = { + "larval", + "mature", + "dying", + "dead", +}; + +static struct val2str str_alg_auth[] = { + { SADB_AALG_NONE, "none", }, + { SADB_AALG_MD5HMAC, "hmac-md5", }, + { SADB_AALG_SHA1HMAC, "hmac-sha1", }, + { SADB_X_AALG_MD5, "md5", }, + { SADB_X_AALG_SHA, "sha", }, + { SADB_X_AALG_NULL, "null", }, +#ifdef SADB_X_AALG_TCP_MD5 + { SADB_X_AALG_TCP_MD5, "tcp-md5", }, +#endif +#ifdef SADB_X_AALG_SHA2_256 + { SADB_X_AALG_SHA2_256, "hmac-sha256", }, +#endif +#ifdef SADB_X_AALG_SHA2_384 + { SADB_X_AALG_SHA2_384, "hmac-sha384", }, +#endif +#ifdef SADB_X_AALG_SHA2_512 + { SADB_X_AALG_SHA2_512, "hmac-sha512", }, +#endif +#ifdef SADB_X_AALG_RIPEMD160HMAC + { SADB_X_AALG_RIPEMD160HMAC, "hmac-ripemd160", }, +#endif +#ifdef SADB_X_AALG_AES_XCBC_MAC + { SADB_X_AALG_AES_XCBC_MAC, "aes-xcbc-mac", }, +#endif + { -1, NULL, }, +}; + +static struct val2str str_alg_enc[] = { + { SADB_EALG_NONE, "none", }, + { SADB_EALG_DESCBC, "des-cbc", }, + { SADB_EALG_3DESCBC, "3des-cbc", }, + { SADB_EALG_NULL, "null", }, +#ifdef SADB_X_EALG_RC5CBC + { SADB_X_EALG_RC5CBC, "rc5-cbc", }, +#endif + { SADB_X_EALG_CAST128CBC, "cast128-cbc", }, + { SADB_X_EALG_BLOWFISHCBC, "blowfish-cbc", }, +#ifdef SADB_X_EALG_AESCBC + { SADB_X_EALG_AESCBC, "aes-cbc", }, +#endif +#ifdef SADB_X_EALG_TWOFISHCBC + { SADB_X_EALG_TWOFISHCBC, "twofish-cbc", }, +#endif +#ifdef SADB_X_EALG_AESCTR + { SADB_X_EALG_AESCTR, "aes-ctr", }, +#endif +#ifdef SADB_X_EALG_CAMELLIACBC + { SADB_X_EALG_CAMELLIACBC, "camellia-cbc", }, +#endif + { -1, NULL, }, +}; + +static struct val2str str_alg_comp[] = { + { SADB_X_CALG_NONE, "none", }, + { SADB_X_CALG_OUI, "oui", }, + { SADB_X_CALG_DEFLATE, "deflate", }, + { SADB_X_CALG_LZS, "lzs", }, + { -1, NULL, }, +}; + +/* + * dump SADB_MSG formated. For debugging, you should use kdebug_sadb(). + */ + +void +pfkey_sadump(m) + struct sadb_msg *m; +{ + pfkey_sadump1(m, 0); +} + +void +pfkey_sadump_withports(m) + struct sadb_msg *m; +{ + pfkey_sadump1(m, 1); +} + +void +pfkey_sadump1(m, withports) + struct sadb_msg *m; + int withports; +{ + caddr_t mhp[SADB_EXT_MAX + 1]; + struct sadb_sa *m_sa; + struct sadb_x_sa2 *m_sa2; + struct sadb_lifetime *m_lftc, *m_lfth, *m_lfts; + struct sadb_address *m_saddr, *m_daddr; +#ifdef notdef + struct sadb_address *m_paddr; +#endif + struct sadb_key *m_auth, *m_enc; +#ifdef notdef + struct sadb_ident *m_sid, *m_did; + struct sadb_sens *m_sens; +#endif +#ifdef SADB_X_EXT_SEC_CTX + struct sadb_x_sec_ctx *m_sec_ctx; +#endif +#ifdef SADB_X_EXT_NAT_T_TYPE + struct sadb_x_nat_t_type *natt_type; + struct sadb_x_nat_t_port *natt_sport, *natt_dport; + struct sadb_address *natt_oa; + + int use_natt = 0; +#endif + struct sockaddr *sa; + + /* check pfkey message. */ + if (pfkey_align(m, mhp)) { + printf("%s\n", ipsec_strerror()); + return; + } + if (pfkey_check(mhp)) { + printf("%s\n", ipsec_strerror()); + return; + } + + m_sa = (void *)mhp[SADB_EXT_SA]; + m_sa2 = (void *)mhp[SADB_X_EXT_SA2]; + m_lftc = (void *)mhp[SADB_EXT_LIFETIME_CURRENT]; + m_lfth = (void *)mhp[SADB_EXT_LIFETIME_HARD]; + m_lfts = (void *)mhp[SADB_EXT_LIFETIME_SOFT]; + m_saddr = (void *)mhp[SADB_EXT_ADDRESS_SRC]; + m_daddr = (void *)mhp[SADB_EXT_ADDRESS_DST]; +#ifdef notdef + m_paddr = (void *)mhp[SADB_EXT_ADDRESS_PROXY]; +#endif + m_auth = (void *)mhp[SADB_EXT_KEY_AUTH]; + m_enc = (void *)mhp[SADB_EXT_KEY_ENCRYPT]; +#ifdef notdef + m_sid = (void *)mhp[SADB_EXT_IDENTITY_SRC]; + m_did = (void *)mhp[SADB_EXT_IDENTITY_DST]; + m_sens = (void *)mhp[SADB_EXT_SENSITIVITY]; +#endif +#ifdef SADB_X_EXT_SEC_CTX + m_sec_ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX]; +#endif +#ifdef SADB_X_EXT_NAT_T_TYPE + natt_type = (void *)mhp[SADB_X_EXT_NAT_T_TYPE]; + natt_sport = (void *)mhp[SADB_X_EXT_NAT_T_SPORT]; + natt_dport = (void *)mhp[SADB_X_EXT_NAT_T_DPORT]; + natt_oa = (void *)mhp[SADB_X_EXT_NAT_T_OA]; + + if (natt_type && natt_type->sadb_x_nat_t_type_type) + use_natt = 1; +#endif + /* source address */ + if (m_saddr == NULL) { + printf("no ADDRESS_SRC extension.\n"); + return; + } + sa = (void *)(m_saddr + 1); + if (withports) + printf("%s[%s]", str_ipaddr(sa), str_ipport(sa)); + else + printf("%s", str_ipaddr(sa)); +#ifdef SADB_X_EXT_NAT_T_TYPE + if (use_natt && natt_sport) + printf("[%u]", ntohs(natt_sport->sadb_x_nat_t_port_port)); +#endif + printf(" "); + + /* destination address */ + if (m_daddr == NULL) { + printf(" no ADDRESS_DST extension.\n"); + return; + } + sa = (void *)(m_daddr + 1); + if (withports) + printf("%s[%s]", str_ipaddr(sa), str_ipport(sa)); + else + printf("%s", str_ipaddr(sa)); +#ifdef SADB_X_EXT_NAT_T_TYPE + if (use_natt && natt_dport) + printf("[%u]", ntohs(natt_dport->sadb_x_nat_t_port_port)); +#endif + printf(" "); + + /* SA type */ + if (m_sa == NULL) { + printf("no SA extension.\n"); + return; + } + if (m_sa2 == NULL) { + printf("no SA2 extension.\n"); + return; + } + printf("\n\t"); + +#ifdef SADB_X_EXT_NAT_T_TYPE + if (use_natt && m->sadb_msg_satype == SADB_SATYPE_ESP) + printf("esp-udp "); + else if (use_natt) + printf("natt+"); + + if (!use_natt || m->sadb_msg_satype != SADB_SATYPE_ESP) +#endif + GETMSGSTR(str_satype, m->sadb_msg_satype); + + printf("mode="); + GETMSGSTR(str_mode, m_sa2->sadb_x_sa2_mode); + + printf("spi=%u(0x%08x) reqid=%u(0x%08x)\n", + (u_int32_t)ntohl(m_sa->sadb_sa_spi), + (u_int32_t)ntohl(m_sa->sadb_sa_spi), + (u_int32_t)m_sa2->sadb_x_sa2_reqid, + (u_int32_t)m_sa2->sadb_x_sa2_reqid); + +#ifdef SADB_X_EXT_NAT_T_TYPE + /* other NAT-T information */ + if (use_natt && natt_oa) + printf("\tNAT OA=%s\n", + str_ipaddr((void *)(natt_oa + 1))); +#endif + + /* encryption key */ + if (m->sadb_msg_satype == SADB_X_SATYPE_IPCOMP) { + printf("\tC: "); + GETMSGV2S(str_alg_comp, m_sa->sadb_sa_encrypt); + } else if (m->sadb_msg_satype == SADB_SATYPE_ESP) { + if (m_enc != NULL) { + printf("\tE: "); + GETMSGV2S(str_alg_enc, m_sa->sadb_sa_encrypt); + ipsec_hexdump((caddr_t)(void *)m_enc + sizeof(*m_enc), + m_enc->sadb_key_bits / 8); + printf("\n"); + } + } + + /* authentication key */ + if (m_auth != NULL) { + printf("\tA: "); + GETMSGV2S(str_alg_auth, m_sa->sadb_sa_auth); + ipsec_hexdump((caddr_t)(void *)m_auth + sizeof(*m_auth), + m_auth->sadb_key_bits / 8); + printf("\n"); + } + + /* replay windoe size & flags */ + printf("\tseq=0x%08x replay=%u flags=0x%08x ", + m_sa2->sadb_x_sa2_sequence, + m_sa->sadb_sa_replay, + m_sa->sadb_sa_flags); + + /* state */ + printf("state="); + GETMSGSTR(str_state, m_sa->sadb_sa_state); + printf("\n"); + + /* lifetime */ + if (m_lftc != NULL) { + time_t tmp_time = time(0); + + printf("\tcreated: %s", + str_time((long)m_lftc->sadb_lifetime_addtime)); + printf("\tcurrent: %s\n", str_time(tmp_time)); + printf("\tdiff: %lu(s)", + (u_long)(m_lftc->sadb_lifetime_addtime == 0 ? + 0 : (tmp_time - m_lftc->sadb_lifetime_addtime))); + + printf("\thard: %lu(s)", + (u_long)(m_lfth == NULL ? + 0 : m_lfth->sadb_lifetime_addtime)); + printf("\tsoft: %lu(s)\n", + (u_long)(m_lfts == NULL ? + 0 : m_lfts->sadb_lifetime_addtime)); + + printf("\tlast: %s", + str_time((long)m_lftc->sadb_lifetime_usetime)); + printf("\thard: %lu(s)", + (u_long)(m_lfth == NULL ? + 0 : m_lfth->sadb_lifetime_usetime)); + printf("\tsoft: %lu(s)\n", + (u_long)(m_lfts == NULL ? + 0 : m_lfts->sadb_lifetime_usetime)); + + str_lifetime_byte(m_lftc, "current"); + str_lifetime_byte(m_lfth, "hard"); + str_lifetime_byte(m_lfts, "soft"); + printf("\n"); + + printf("\tallocated: %lu", + (unsigned long)m_lftc->sadb_lifetime_allocations); + printf("\thard: %lu", + (u_long)(m_lfth == NULL ? + 0 : m_lfth->sadb_lifetime_allocations)); + printf("\tsoft: %lu\n", + (u_long)(m_lfts == NULL ? + 0 : m_lfts->sadb_lifetime_allocations)); + } + +#ifdef SADB_X_EXT_SEC_CTX + if (m_sec_ctx != NULL) { + printf("\tsecurity context doi: %u\n", + m_sec_ctx->sadb_x_ctx_doi); + printf("\tsecurity context algorithm: %u\n", + m_sec_ctx->sadb_x_ctx_alg); + printf("\tsecurity context length: %u\n", + m_sec_ctx->sadb_x_ctx_len); + printf("\tsecurity context: %s\n", + (char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx)); + } +#endif + + printf("\tsadb_seq=%lu pid=%lu ", + (u_long)m->sadb_msg_seq, + (u_long)m->sadb_msg_pid); + + /* XXX DEBUG */ + printf("refcnt=%u\n", m->sadb_msg_reserved); + + return; +} + +void +pfkey_spdump(m) + struct sadb_msg *m; +{ + pfkey_spdump1(m, 0); +} + +void +pfkey_spdump_withports(m) + struct sadb_msg *m; +{ + pfkey_spdump1(m, 1); +} + +static void +pfkey_spdump1(m, withports) + struct sadb_msg *m; + int withports; +{ + char pbuf[NI_MAXSERV]; + caddr_t mhp[SADB_EXT_MAX + 1]; + struct sadb_address *m_saddr, *m_daddr; +#ifdef SADB_X_EXT_TAG + struct sadb_x_tag *m_tag; +#endif + struct sadb_x_policy *m_xpl; + struct sadb_lifetime *m_lftc = NULL, *m_lfth = NULL; +#ifdef SADB_X_EXT_SEC_CTX + struct sadb_x_sec_ctx *m_sec_ctx; +#endif + struct sockaddr *sa; + u_int16_t sport = 0, dport = 0; + + /* check pfkey message. */ + if (pfkey_align(m, mhp)) { + printf("%s\n", ipsec_strerror()); + return; + } + if (pfkey_check(mhp)) { + printf("%s\n", ipsec_strerror()); + return; + } + + m_saddr = (void *)mhp[SADB_EXT_ADDRESS_SRC]; + m_daddr = (void *)mhp[SADB_EXT_ADDRESS_DST]; +#ifdef SADB_X_EXT_TAG + m_tag = (void *)mhp[SADB_X_EXT_TAG]; +#endif + m_xpl = (void *)mhp[SADB_X_EXT_POLICY]; + m_lftc = (void *)mhp[SADB_EXT_LIFETIME_CURRENT]; + m_lfth = (void *)mhp[SADB_EXT_LIFETIME_HARD]; + +#ifdef SADB_X_EXT_SEC_CTX + m_sec_ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX]; +#endif +#ifdef __linux__ + /* *bsd indicates per-socket policies by omiting src and dst + * extensions. Linux always includes them, but we can catch it + * by checkin for policy id. + */ + if (m_xpl->sadb_x_policy_id % 8 >= 3) { + printf("(per-socket policy) "); + } else +#endif + if (m_saddr && m_daddr) { + /* source address */ + sa = (void *)(m_saddr + 1); + switch (sa->sa_family) { + case AF_INET: + case AF_INET6: + if (getnameinfo(sa, (socklen_t)sysdep_sa_len(sa), NULL, + 0, pbuf, sizeof(pbuf), NI_NUMERICSERV) != 0) + sport = 0; /*XXX*/ + else + sport = atoi(pbuf); + printf("%s%s ", str_ipaddr(sa), + str_prefport((u_int)sa->sa_family, + (u_int)m_saddr->sadb_address_prefixlen, + (u_int)sport, + (u_int)m_saddr->sadb_address_proto)); + break; + default: + printf("unknown-af "); + break; + } + + /* destination address */ + sa = (void *)(m_daddr + 1); + switch (sa->sa_family) { + case AF_INET: + case AF_INET6: + if (getnameinfo(sa, (socklen_t)sysdep_sa_len(sa), NULL, + 0, pbuf, sizeof(pbuf), NI_NUMERICSERV) != 0) + dport = 0; /*XXX*/ + else + dport = atoi(pbuf); + printf("%s%s ", str_ipaddr(sa), + str_prefport((u_int)sa->sa_family, + (u_int)m_daddr->sadb_address_prefixlen, + (u_int)dport, + (u_int)m_saddr->sadb_address_proto)); + break; + default: + printf("unknown-af "); + break; + } + + /* upper layer protocol */ + if (m_saddr->sadb_address_proto != + m_daddr->sadb_address_proto) { + printf("upper layer protocol mismatched.\n"); + return; + } + str_upperspec((u_int)m_saddr->sadb_address_proto, (u_int)sport, + (u_int)dport); + } +#ifdef SADB_X_EXT_TAG + else if (m_tag) + printf("tagged \"%s\" ", m_tag->sadb_x_tag_name); +#endif + else + printf("(no selector, probably per-socket policy) "); + + /* policy */ + { + char *d_xpl; + + if (m_xpl == NULL) { + printf("no X_POLICY extension.\n"); + return; + } + if (withports) + d_xpl = ipsec_dump_policy_withports(m_xpl, "\n\t"); + else + d_xpl = ipsec_dump_policy((ipsec_policy_t)m_xpl, "\n\t"); + + if (!d_xpl) + printf("\n\tPolicy:[%s]\n", ipsec_strerror()); + else { + /* dump SPD */ + printf("\n\t%s\n", d_xpl); + free(d_xpl); + } + } + + /* lifetime */ + if (m_lftc) { + printf("\tcreated: %s ", + str_time((long)m_lftc->sadb_lifetime_addtime)); + printf("lastused: %s\n", + str_time((long)m_lftc->sadb_lifetime_usetime)); + } + if (m_lfth) { + printf("\tlifetime: %lu(s) ", + (u_long)m_lfth->sadb_lifetime_addtime); + printf("validtime: %lu(s)\n", + (u_long)m_lfth->sadb_lifetime_usetime); + } + +#ifdef SADB_X_EXT_SEC_CTX + if (m_sec_ctx != NULL) { + printf("\tsecurity context doi: %u\n", + m_sec_ctx->sadb_x_ctx_doi); + printf("\tsecurity context algorithm: %u\n", + m_sec_ctx->sadb_x_ctx_alg); + printf("\tsecurity context length: %u\n", + m_sec_ctx->sadb_x_ctx_len); + printf("\tsecurity context: %s\n", + (char *)m_sec_ctx + sizeof(struct sadb_x_sec_ctx)); + } +#endif + + printf("\tspid=%ld seq=%ld pid=%ld\n", + (u_long)m_xpl->sadb_x_policy_id, + (u_long)m->sadb_msg_seq, + (u_long)m->sadb_msg_pid); + + /* XXX TEST */ + printf("\trefcnt=%u\n", m->sadb_msg_reserved); + + return; +} + +/* + * set "ipaddress" to buffer. + */ +static char * +str_ipaddr(sa) + struct sockaddr *sa; +{ + static char buf[NI_MAXHOST]; + const int niflag = NI_NUMERICHOST; + + if (sa == NULL) + return ""; + + if (getnameinfo(sa, (socklen_t)sysdep_sa_len(sa), buf, sizeof(buf), + NULL, 0, niflag) == 0) + return buf; + return NULL; +} + +/* + * set "port" to buffer. + */ +static char * +str_ipport(sa) + struct sockaddr *sa; +{ + static char buf[NI_MAXHOST]; + const int niflag = NI_NUMERICSERV; + + if (sa == NULL) + return ""; + + if (getnameinfo(sa, (socklen_t)sysdep_sa_len(sa), NULL, 0, + buf, sizeof(buf), niflag) == 0) + return buf; + return NULL; +} + + +/* + * set "/prefix[port number]" to buffer. + */ +static char * +str_prefport(family, pref, port, ulp) + u_int family, pref, port, ulp; +{ + static char buf[128]; + char prefbuf[128]; + char portbuf[128]; + int plen; + + switch (family) { + case AF_INET: + plen = sizeof(struct in_addr) << 3; + break; + case AF_INET6: + plen = sizeof(struct in6_addr) << 3; + break; + default: + return "?"; + } + + if (pref == plen) + prefbuf[0] = '\0'; + else + snprintf(prefbuf, sizeof(prefbuf), "/%u", pref); + + switch (ulp) { + case IPPROTO_ICMP: + case IPPROTO_ICMPV6: + case IPPROTO_MH: + case IPPROTO_GRE: + memset(portbuf, 0, sizeof(portbuf)); + break; + default: + if (port == IPSEC_PORT_ANY) + strcpy(portbuf, "[any]"); + else + snprintf(portbuf, sizeof(portbuf), "[%u]", port); + break; + } + + snprintf(buf, sizeof(buf), "%s%s", prefbuf, portbuf); + + return buf; +} + +static void +str_upperspec(ulp, p1, p2) + u_int ulp, p1, p2; +{ + struct protoent *ent; + + ent = getprotobynumber((int)ulp); + if (ent) + printf("%s", ent->p_name); + else + printf("%u", ulp); + + if (p1 == IPSEC_PORT_ANY && p2 == IPSEC_PORT_ANY) + return; + + switch (ulp) { + case IPPROTO_ICMP: + case IPPROTO_ICMPV6: + case IPPROTO_MH: + printf(" %u,%u", p1, p2); + break; + case IPPROTO_GRE: + printf(" %u", (p1 << 16) + p2); + break; + } +} + +/* + * set "Mon Day Time Year" to buffer + */ +static char * +str_time(t) + time_t t; +{ + static char buf[128]; + + if (t == 0) { + int i = 0; + for (;i < 20;) buf[i++] = ' '; + } else { + char *t0; + if ((t0 = ctime(&t)) == NULL) + memset(buf, '?', 20); + else + memcpy(buf, t0 + 4, 20); + } + + buf[20] = '\0'; + + return(buf); +} + +static void +str_lifetime_byte(x, str) + struct sadb_lifetime *x; + char *str; +{ + double y; + char *unit; + int w; + + if (x == NULL) { + printf("\t%s: 0(bytes)", str); + return; + } + +#if 0 + if ((x->sadb_lifetime_bytes) / 1024 / 1024) { + y = (x->sadb_lifetime_bytes) * 1.0 / 1024 / 1024; + unit = "M"; + w = 1; + } else if ((x->sadb_lifetime_bytes) / 1024) { + y = (x->sadb_lifetime_bytes) * 1.0 / 1024; + unit = "K"; + w = 1; + } else { + y = (x->sadb_lifetime_bytes) * 1.0; + unit = ""; + w = 0; + } +#else + y = (x->sadb_lifetime_bytes) * 1.0; + unit = ""; + w = 0; +#endif + printf("\t%s: %.*f(%sbytes)", str, w, y, unit); +} |