1*c4f11a12Stobhe /* $OpenBSD: pfkdump.c,v 1.58 2023/10/10 16:16:16 tobhe Exp $ */
23dd59ad2Shshoexer
33dd59ad2Shshoexer /*
43dd59ad2Shshoexer * Copyright (c) 2003 Markus Friedl. All rights reserved.
53dd59ad2Shshoexer *
63dd59ad2Shshoexer * Redistribution and use in source and binary forms, with or without
73dd59ad2Shshoexer * modification, are permitted provided that the following conditions
83dd59ad2Shshoexer * are met:
93dd59ad2Shshoexer * 1. Redistributions of source code must retain the above copyright
103dd59ad2Shshoexer * notice, this list of conditions and the following disclaimer.
113dd59ad2Shshoexer * 2. Redistributions in binary form must reproduce the above copyright
123dd59ad2Shshoexer * notice, this list of conditions and the following disclaimer in the
133dd59ad2Shshoexer * documentation and/or other materials provided with the distribution.
143dd59ad2Shshoexer *
153dd59ad2Shshoexer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
163dd59ad2Shshoexer * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
173dd59ad2Shshoexer * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
183dd59ad2Shshoexer * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
193dd59ad2Shshoexer * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
203dd59ad2Shshoexer * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
213dd59ad2Shshoexer * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
223dd59ad2Shshoexer * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
233dd59ad2Shshoexer * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
243dd59ad2Shshoexer * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
253dd59ad2Shshoexer */
26b9fc9a72Sderaadt
273dd59ad2Shshoexer #include <sys/socket.h>
283dd59ad2Shshoexer #include <sys/time.h>
293dd59ad2Shshoexer #include <sys/sysctl.h>
300bfe572bSmpi #include <sys/queue.h>
317fc6e3f0Smpi
323dd59ad2Shshoexer #include <net/pfkeyv2.h>
333dd59ad2Shshoexer #include <netinet/ip_ipsp.h>
343dd59ad2Shshoexer #include <netdb.h>
353dd59ad2Shshoexer #include <string.h>
363dd59ad2Shshoexer #include <unistd.h>
373dd59ad2Shshoexer #include <stdlib.h>
383dd59ad2Shshoexer #include <stdio.h>
393dd59ad2Shshoexer #include <err.h>
40ae5feee3Smillert #include <errno.h>
413dd59ad2Shshoexer
423dd59ad2Shshoexer #include "ipsecctl.h"
433dd59ad2Shshoexer #include "pfkey.h"
443dd59ad2Shshoexer
457fc6e3f0Smpi static void print_proto(struct sadb_ext *, struct sadb_msg *, int);
467fc6e3f0Smpi static void print_flow(struct sadb_ext *, struct sadb_msg *, int);
477fc6e3f0Smpi static void print_supp(struct sadb_ext *, struct sadb_msg *, int);
487fc6e3f0Smpi static void print_prop(struct sadb_ext *, struct sadb_msg *, int);
497fc6e3f0Smpi static void print_sens(struct sadb_ext *, struct sadb_msg *, int);
507fc6e3f0Smpi static void print_spir(struct sadb_ext *, struct sadb_msg *, int);
517fc6e3f0Smpi static void print_policy(struct sadb_ext *, struct sadb_msg *, int);
527fc6e3f0Smpi static void print_sa(struct sadb_ext *, struct sadb_msg *, int);
537fc6e3f0Smpi static void print_addr(struct sadb_ext *, struct sadb_msg *, int);
547fc6e3f0Smpi static void print_key(struct sadb_ext *, struct sadb_msg *, int);
557fc6e3f0Smpi static void print_life(struct sadb_ext *, struct sadb_msg *, int);
567fc6e3f0Smpi static void print_ident(struct sadb_ext *, struct sadb_msg *, int);
577fc6e3f0Smpi static void print_udpenc(struct sadb_ext *, struct sadb_msg *, int);
587fc6e3f0Smpi static void print_tag(struct sadb_ext *, struct sadb_msg *, int);
59f5924638Stobhe static void print_rdomain(struct sadb_ext *, struct sadb_msg *, int);
60094e3f7dStobhe static void print_replay(struct sadb_ext *, struct sadb_msg *, int);
6149c3446eStobhe static void print_mtu(struct sadb_ext *, struct sadb_msg *, int);
627fc6e3f0Smpi static void print_tap(struct sadb_ext *, struct sadb_msg *, int);
637fc6e3f0Smpi static void print_satype(struct sadb_ext *, struct sadb_msg *, int);
647fc6e3f0Smpi static void print_counter(struct sadb_ext *, struct sadb_msg *, int);
658fd570bdSdlg static void print_iface(struct sadb_ext *, struct sadb_msg *, int);
663dd59ad2Shshoexer
67fd81a95bSmikeb static struct idname *lookup(struct idname *, u_int32_t);
68fd81a95bSmikeb static char *lookup_name(struct idname *, u_int32_t);
697fc6e3f0Smpi static void print_ext(struct sadb_ext *, struct sadb_msg *, int);
703dd59ad2Shshoexer
718a87fca6Smsf void pfkey_print_raw(u_int8_t *, ssize_t);
72fd81a95bSmikeb static char *print_flags(uint32_t);
733dd59ad2Shshoexer
7494de6926Smarkus struct sadb_ext *extensions[SADB_EXT_MAX + 1];
7595f27d1eShshoexer
763dd59ad2Shshoexer struct idname {
77fd81a95bSmikeb u_int32_t id;
783dd59ad2Shshoexer char *name;
797fc6e3f0Smpi void (*func)(struct sadb_ext *, struct sadb_msg *, int);
803dd59ad2Shshoexer };
813dd59ad2Shshoexer
823dd59ad2Shshoexer struct idname ext_types[] = {
833dd59ad2Shshoexer { SADB_EXT_RESERVED, "reserved", NULL },
843dd59ad2Shshoexer { SADB_EXT_SA, "sa", print_sa },
853dd59ad2Shshoexer { SADB_EXT_LIFETIME_CURRENT, "lifetime_cur", print_life },
863dd59ad2Shshoexer { SADB_EXT_LIFETIME_HARD, "lifetime_hard", print_life },
873dd59ad2Shshoexer { SADB_EXT_LIFETIME_SOFT, "lifetime_soft", print_life },
883dd59ad2Shshoexer { SADB_EXT_ADDRESS_SRC, "address_src", print_addr },
893dd59ad2Shshoexer { SADB_EXT_ADDRESS_DST, "address_dst", print_addr },
908a87fca6Smsf { SADB_EXT_ADDRESS_PROXY, "address_proxy", print_addr },
913dd59ad2Shshoexer { SADB_EXT_KEY_AUTH, "key_auth", print_key },
923dd59ad2Shshoexer { SADB_EXT_KEY_ENCRYPT, "key_encrypt", print_key },
933dd59ad2Shshoexer { SADB_EXT_IDENTITY_SRC, "identity_src", print_ident },
943dd59ad2Shshoexer { SADB_EXT_IDENTITY_DST, "identity_dst", print_ident },
958a87fca6Smsf { SADB_EXT_SENSITIVITY, "sensitivity", print_sens },
968a87fca6Smsf { SADB_EXT_PROPOSAL, "proposal", print_prop },
978a87fca6Smsf { SADB_EXT_SUPPORTED_AUTH, "supported_auth", print_supp },
988a87fca6Smsf { SADB_EXT_SUPPORTED_ENCRYPT, "supported_encrypt", print_supp },
998a87fca6Smsf { SADB_EXT_SPIRANGE, "spirange", print_spir },
1008a87fca6Smsf { SADB_X_EXT_SRC_MASK, "src_mask", print_addr },
1018a87fca6Smsf { SADB_X_EXT_DST_MASK, "dst_mask", print_addr },
1028a87fca6Smsf { SADB_X_EXT_PROTOCOL, "protocol", print_proto },
1038a87fca6Smsf { SADB_X_EXT_FLOW_TYPE, "flow_type", print_flow },
1048a87fca6Smsf { SADB_X_EXT_SRC_FLOW, "src_flow", print_addr },
1058a87fca6Smsf { SADB_X_EXT_DST_FLOW, "dst_flow", print_addr },
1068a87fca6Smsf { SADB_X_EXT_SA2, "sa2", print_sa },
1078a87fca6Smsf { SADB_X_EXT_DST2, "dst2", print_addr },
1088a87fca6Smsf { SADB_X_EXT_POLICY, "policy", print_policy },
1098a87fca6Smsf { SADB_X_EXT_SUPPORTED_COMP, "supported_comp", print_supp },
1103dd59ad2Shshoexer { SADB_X_EXT_UDPENCAP, "udpencap", print_udpenc },
1113dd59ad2Shshoexer { SADB_X_EXT_LIFETIME_LASTUSE, "lifetime_lastuse", print_life },
112aa920ac7Sreyk { SADB_X_EXT_TAG, "tag", print_tag },
113f5924638Stobhe { SADB_X_EXT_RDOMAIN, "rdomain", print_rdomain },
114094e3f7dStobhe { SADB_X_EXT_REPLAY, "replay", print_replay },
11549c3446eStobhe { SADB_X_EXT_MTU, "mtu", print_mtu },
1160d5acc6aSreyk { SADB_X_EXT_TAP, "tap", print_tap },
117d44c51a1Sbluhm { SADB_X_EXT_SATYPE2, "satype2", print_satype },
1187fc6e3f0Smpi { SADB_X_EXT_COUNTER, "counter", print_counter },
1198fd570bdSdlg { SADB_X_EXT_IFACE, "interface", print_iface },
1203dd59ad2Shshoexer { 0, NULL, NULL }
1213dd59ad2Shshoexer };
1223dd59ad2Shshoexer
1238a87fca6Smsf struct idname msg_types[] = {
1248a87fca6Smsf { SADB_ACQUIRE, "sadb_acquire", NULL },
1258a87fca6Smsf { SADB_ADD, "sadb_add", NULL },
1268a87fca6Smsf { SADB_DELETE, "sadb_delete", NULL },
1278a87fca6Smsf { SADB_DUMP, "sadb_dump", NULL },
1288a87fca6Smsf { SADB_EXPIRE, "sadb_expire", NULL },
1298a87fca6Smsf { SADB_FLUSH, "sadb_flush", NULL },
1308a87fca6Smsf { SADB_GET, "sadb_get", NULL },
1318a87fca6Smsf { SADB_GETSPI, "sadb_getspi", NULL },
1328a87fca6Smsf { SADB_REGISTER, "sadb_register", NULL },
1338a87fca6Smsf { SADB_UPDATE, "sadb_update", NULL },
1348a87fca6Smsf { SADB_X_ADDFLOW, "sadb_addflow", NULL },
1358a87fca6Smsf { SADB_X_ASKPOLICY, "sadb_askpolicy", NULL },
1368a87fca6Smsf { SADB_X_DELFLOW, "sadb_delflow", NULL },
1378a87fca6Smsf { SADB_X_GRPSPIS, "sadb_grpspis", NULL },
1388a87fca6Smsf { SADB_X_PROMISC, "sadb_promisc", NULL },
1398a87fca6Smsf { 0, NULL, NULL },
1408a87fca6Smsf };
1418a87fca6Smsf
1423dd59ad2Shshoexer struct idname sa_types[] = {
1433dd59ad2Shshoexer { SADB_SATYPE_UNSPEC, "unspec", NULL },
1443dd59ad2Shshoexer { SADB_SATYPE_AH, "ah", NULL },
1453dd59ad2Shshoexer { SADB_SATYPE_ESP, "esp", NULL },
1463dd59ad2Shshoexer { SADB_SATYPE_RSVP, "rsvp", NULL },
1473dd59ad2Shshoexer { SADB_SATYPE_OSPFV2, "ospfv2", NULL },
1483dd59ad2Shshoexer { SADB_SATYPE_RIPV2, "ripv2", NULL },
1493dd59ad2Shshoexer { SADB_SATYPE_MIP, "mip", NULL },
1503dd59ad2Shshoexer { SADB_X_SATYPE_IPIP, "ipip", NULL },
1513dd59ad2Shshoexer { SADB_X_SATYPE_TCPSIGNATURE, "tcpmd5", NULL },
1523dd59ad2Shshoexer { SADB_X_SATYPE_IPCOMP, "ipcomp", NULL },
1533dd59ad2Shshoexer { 0, NULL, NULL }
1543dd59ad2Shshoexer };
1553dd59ad2Shshoexer
1563dd59ad2Shshoexer struct idname auth_types[] = {
1573dd59ad2Shshoexer { SADB_AALG_NONE, "none", NULL },
1583dd59ad2Shshoexer { SADB_AALG_MD5HMAC, "hmac-md5", NULL },
1593dd59ad2Shshoexer { SADB_X_AALG_RIPEMD160HMAC, "hmac-ripemd160", NULL },
1603dd59ad2Shshoexer { SADB_AALG_SHA1HMAC, "hmac-sha1", NULL },
1613dd59ad2Shshoexer { SADB_X_AALG_SHA2_256, "hmac-sha2-256", NULL },
1623dd59ad2Shshoexer { SADB_X_AALG_SHA2_384, "hmac-sha2-384", NULL },
1633dd59ad2Shshoexer { SADB_X_AALG_SHA2_512, "hmac-sha2-512", NULL },
164783454c1Smikeb { SADB_X_AALG_AES128GMAC, "gmac-aes-128", NULL },
165783454c1Smikeb { SADB_X_AALG_AES192GMAC, "gmac-aes-192", NULL },
166783454c1Smikeb { SADB_X_AALG_AES256GMAC, "gmac-aes-256", NULL },
167f705960cSmikeb { SADB_X_AALG_CHACHA20POLY1305, "chacha20-poly1305", NULL },
1683dd59ad2Shshoexer { 0, NULL, NULL }
1693dd59ad2Shshoexer };
1703dd59ad2Shshoexer
1713dd59ad2Shshoexer struct idname enc_types[] = {
1723dd59ad2Shshoexer { SADB_EALG_NONE, "none", NULL },
1733dd59ad2Shshoexer { SADB_EALG_3DESCBC, "3des-cbc", NULL },
1743dd59ad2Shshoexer { SADB_X_EALG_AES, "aes", NULL },
1753dd59ad2Shshoexer { SADB_X_EALG_AESCTR, "aesctr", NULL },
176783454c1Smikeb { SADB_X_EALG_AESGCM16, "aes-gcm", NULL },
177783454c1Smikeb { SADB_X_EALG_AESGMAC, "aes-gmac", NULL },
1783dd59ad2Shshoexer { SADB_X_EALG_BLF, "blowfish", NULL },
1793dd59ad2Shshoexer { SADB_X_EALG_CAST, "cast128", NULL },
1803dd59ad2Shshoexer { SADB_EALG_NULL, "null", NULL },
181f705960cSmikeb { SADB_X_EALG_CHACHA20POLY1305, "chacha20-poly1305", NULL },
1823dd59ad2Shshoexer { 0, NULL, NULL }
1833dd59ad2Shshoexer };
1843dd59ad2Shshoexer
1853dd59ad2Shshoexer struct idname comp_types[] = {
1863dd59ad2Shshoexer { SADB_X_CALG_NONE, "none", NULL },
1873dd59ad2Shshoexer { SADB_X_CALG_OUI, "oui", NULL },
1883dd59ad2Shshoexer { SADB_X_CALG_DEFLATE, "deflate", NULL },
1893dd59ad2Shshoexer { 0, NULL, NULL }
1903dd59ad2Shshoexer };
1913dd59ad2Shshoexer
192fd81a95bSmikeb struct idname flag_types[] = {
193fd81a95bSmikeb { SADB_SAFLAGS_PFS, "pfs", NULL },
194fd81a95bSmikeb { SADB_X_SAFLAGS_TUNNEL, "tunnel", NULL },
195fd81a95bSmikeb { SADB_X_SAFLAGS_CHAINDEL, "chaindel", NULL },
196fd81a95bSmikeb { SADB_X_SAFLAGS_UDPENCAP, "udpencap", NULL },
197fd81a95bSmikeb { SADB_X_SAFLAGS_ESN, "esn", NULL },
198fd81a95bSmikeb { 0, NULL, NULL }
199fd81a95bSmikeb };
200fd81a95bSmikeb
2013dd59ad2Shshoexer struct idname identity_types[] = {
2023dd59ad2Shshoexer { SADB_IDENTTYPE_RESERVED, "reserved", NULL },
2033dd59ad2Shshoexer { SADB_IDENTTYPE_PREFIX, "prefix", NULL },
2043dd59ad2Shshoexer { SADB_IDENTTYPE_FQDN, "fqdn", NULL },
2053dd59ad2Shshoexer { SADB_IDENTTYPE_USERFQDN, "ufqdn", NULL },
206d8131d03Sphessler { SADB_IDENTTYPE_ASN1_DN, "asn1_dn", NULL },
2073dd59ad2Shshoexer { 0, NULL, NULL }
2083dd59ad2Shshoexer };
2093dd59ad2Shshoexer
2108a87fca6Smsf struct idname flow_types[] = {
2118a87fca6Smsf { SADB_X_FLOW_TYPE_USE, "use", NULL },
2128a87fca6Smsf { SADB_X_FLOW_TYPE_ACQUIRE, "acquire", NULL },
2138a87fca6Smsf { SADB_X_FLOW_TYPE_REQUIRE, "require", NULL },
2148a87fca6Smsf { SADB_X_FLOW_TYPE_BYPASS, "bypass", NULL },
2158a87fca6Smsf { SADB_X_FLOW_TYPE_DENY, "deny", NULL },
2168a87fca6Smsf { SADB_X_FLOW_TYPE_DONTACQ, "dontacq", NULL },
2178a87fca6Smsf { 0, NULL, NULL }
2188a87fca6Smsf };
2198a87fca6Smsf
2208a87fca6Smsf struct idname states[] = {
2218a87fca6Smsf { SADB_SASTATE_LARVAL, "larval", NULL },
2228a87fca6Smsf { SADB_SASTATE_MATURE, "mature", NULL },
2238a87fca6Smsf { SADB_SASTATE_DYING, "dying", NULL },
2248a87fca6Smsf { SADB_SASTATE_DEAD, "dead", NULL },
2258a87fca6Smsf { 0, NULL, NULL }
2268a87fca6Smsf };
2278a87fca6Smsf
2283dd59ad2Shshoexer static struct idname *
lookup(struct idname * tab,u_int32_t id)229fd81a95bSmikeb lookup(struct idname *tab, u_int32_t id)
2303dd59ad2Shshoexer {
2313dd59ad2Shshoexer struct idname *entry;
2323dd59ad2Shshoexer
2333dd59ad2Shshoexer for (entry = tab; entry->name; entry++)
2343dd59ad2Shshoexer if (entry->id == id)
2353dd59ad2Shshoexer return (entry);
2363dd59ad2Shshoexer return (NULL);
2373dd59ad2Shshoexer }
2383dd59ad2Shshoexer
2393dd59ad2Shshoexer static char *
lookup_name(struct idname * tab,u_int32_t id)240fd81a95bSmikeb lookup_name(struct idname *tab, u_int32_t id)
2413dd59ad2Shshoexer {
2423dd59ad2Shshoexer struct idname *entry;
2433dd59ad2Shshoexer
2443dd59ad2Shshoexer entry = lookup(tab, id);
2453dd59ad2Shshoexer return (entry ? entry->name : "unknown");
2463dd59ad2Shshoexer }
2473dd59ad2Shshoexer
2483dd59ad2Shshoexer static void
print_ext(struct sadb_ext * ext,struct sadb_msg * msg,int opts)2497fc6e3f0Smpi print_ext(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
2503dd59ad2Shshoexer {
2513dd59ad2Shshoexer struct idname *entry;
2523dd59ad2Shshoexer
2533dd59ad2Shshoexer if ((entry = lookup(ext_types, ext->sadb_ext_type)) == NULL) {
2543dd59ad2Shshoexer printf("unknown ext: type %u len %u\n",
2553dd59ad2Shshoexer ext->sadb_ext_type, ext->sadb_ext_len);
2563dd59ad2Shshoexer return;
2573dd59ad2Shshoexer }
2583dd59ad2Shshoexer printf("\t%s: ", entry->name);
2593dd59ad2Shshoexer if (entry->func != NULL)
2607fc6e3f0Smpi (*entry->func)(ext, msg, opts);
2613dd59ad2Shshoexer else
2628685c612Smsf printf("type %u len %u",
2633dd59ad2Shshoexer ext->sadb_ext_type, ext->sadb_ext_len);
2648685c612Smsf printf("\n");
2653dd59ad2Shshoexer }
2663dd59ad2Shshoexer
267fd81a95bSmikeb static char *
print_flags(uint32_t flags)268fd81a95bSmikeb print_flags(uint32_t flags)
269fd81a95bSmikeb {
270fd81a95bSmikeb static char fstr[80];
271fd81a95bSmikeb struct idname *entry;
272515e489cSderaadt int len;
27379d7816aSderaadt int i, comma = 0, n;
274fd81a95bSmikeb
275fd81a95bSmikeb len = snprintf(fstr, sizeof(fstr), "%#x<", flags);
27614c62822Stobhe if (len < 0 || (size_t)len >= sizeof(fstr))
27779d7816aSderaadt return (NULL);
278fd81a95bSmikeb for (i = 0; i < 32; i++) {
279fd81a95bSmikeb if ((flags & (1 << i)) == 0 ||
280fd81a95bSmikeb (entry = lookup(flag_types, 1 << i)) == NULL)
281fd81a95bSmikeb continue;
28279d7816aSderaadt n = snprintf(fstr + len, sizeof(fstr) - len - 1,
283fd81a95bSmikeb comma ? ",%s" : "%s", entry->name);
28414c62822Stobhe if (n < 0 || (size_t)n >= sizeof(fstr) - len - 1)
28579d7816aSderaadt return (NULL);
28679d7816aSderaadt len += n;
287fd81a95bSmikeb comma = 1;
288fd81a95bSmikeb }
289fd81a95bSmikeb strlcat(fstr, ">", sizeof(fstr));
290fd81a95bSmikeb
291fd81a95bSmikeb return (fstr);
292fd81a95bSmikeb }
293fd81a95bSmikeb
2943dd59ad2Shshoexer static void
print_sa(struct sadb_ext * ext,struct sadb_msg * msg,int opts)2957fc6e3f0Smpi print_sa(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
2963dd59ad2Shshoexer {
2973dd59ad2Shshoexer struct sadb_sa *sa = (struct sadb_sa *)ext;
2983dd59ad2Shshoexer
29905f7f063Shshoexer if (msg->sadb_msg_satype == SADB_X_SATYPE_IPCOMP)
3000c77d9beSmarkus printf("cpi 0x%8.8x comp %s\n",
3010c77d9beSmarkus ntohl(sa->sadb_sa_spi),
3020c77d9beSmarkus lookup_name(comp_types, sa->sadb_sa_encrypt));
3030c77d9beSmarkus else
3040c77d9beSmarkus printf("spi 0x%8.8x auth %s enc %s\n",
3050c77d9beSmarkus ntohl(sa->sadb_sa_spi),
3060c77d9beSmarkus lookup_name(auth_types, sa->sadb_sa_auth),
3070c77d9beSmarkus lookup_name(enc_types, sa->sadb_sa_encrypt));
308fd81a95bSmikeb printf("\t\tstate %s replay %u flags %s",
3090c77d9beSmarkus lookup_name(states, sa->sadb_sa_state),
310fd81a95bSmikeb sa->sadb_sa_replay, print_flags(sa->sadb_sa_flags));
3113dd59ad2Shshoexer }
3123dd59ad2Shshoexer
3133dd59ad2Shshoexer static void
print_addr(struct sadb_ext * ext,struct sadb_msg * msg,int opts)3147fc6e3f0Smpi print_addr(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
3153dd59ad2Shshoexer {
3163dd59ad2Shshoexer struct sadb_address *addr = (struct sadb_address *)ext;
3173dd59ad2Shshoexer struct sockaddr *sa;
3183dd59ad2Shshoexer struct sockaddr_in *sin4;
3193dd59ad2Shshoexer struct sockaddr_in6 *sin6;
3203dd59ad2Shshoexer char hbuf[NI_MAXHOST];
3213dd59ad2Shshoexer
3223dd59ad2Shshoexer sa = (struct sockaddr *)(addr + 1);
3233dd59ad2Shshoexer if (sa->sa_family == 0)
3243dd59ad2Shshoexer printf("<any>");
3253dd59ad2Shshoexer else if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0,
3263dd59ad2Shshoexer NI_NUMERICHOST))
3273dd59ad2Shshoexer printf("<could not get numeric hostname>");
3283dd59ad2Shshoexer else
3293dd59ad2Shshoexer printf("%s", hbuf);
3303dd59ad2Shshoexer switch (sa->sa_family) {
3313dd59ad2Shshoexer case AF_INET:
3323dd59ad2Shshoexer sin4 = (struct sockaddr_in *)sa;
3333dd59ad2Shshoexer if (sin4->sin_port)
3343dd59ad2Shshoexer printf(" port %u", ntohs(sin4->sin_port));
3353dd59ad2Shshoexer break;
3363dd59ad2Shshoexer case AF_INET6:
3373dd59ad2Shshoexer sin6 = (struct sockaddr_in6 *)sa;
3383dd59ad2Shshoexer if (sin6->sin6_port)
3393dd59ad2Shshoexer printf(" port %u", ntohs(sin6->sin6_port));
3403dd59ad2Shshoexer break;
3413dd59ad2Shshoexer }
3423dd59ad2Shshoexer }
3433dd59ad2Shshoexer
3443dd59ad2Shshoexer static void
print_key(struct sadb_ext * ext,struct sadb_msg * msg,int opts)3457fc6e3f0Smpi print_key(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
3463dd59ad2Shshoexer {
3473dd59ad2Shshoexer struct sadb_key *key = (struct sadb_key *)ext;
3483dd59ad2Shshoexer u_int8_t *data;
3493dd59ad2Shshoexer int i;
3503dd59ad2Shshoexer
3513dd59ad2Shshoexer printf("bits %u: ", key->sadb_key_bits);
3523dd59ad2Shshoexer data = (u_int8_t *)(key + 1);
3533dd59ad2Shshoexer for (i = 0; i < key->sadb_key_bits / 8; i++) {
3543dd59ad2Shshoexer printf("%2.2x", data[i]);
3553dd59ad2Shshoexer data[i] = 0x00; /* clear sensitive data */
3563dd59ad2Shshoexer }
3573dd59ad2Shshoexer }
3583dd59ad2Shshoexer
3593dd59ad2Shshoexer static void
print_life(struct sadb_ext * ext,struct sadb_msg * msg,int opts)3607fc6e3f0Smpi print_life(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
3613dd59ad2Shshoexer {
3623dd59ad2Shshoexer struct sadb_lifetime *life = (struct sadb_lifetime *)ext;
3633dd59ad2Shshoexer
3648685c612Smsf printf("alloc %u bytes %llu add %llu first %llu",
3653dd59ad2Shshoexer life->sadb_lifetime_allocations,
3663dd59ad2Shshoexer life->sadb_lifetime_bytes,
3673dd59ad2Shshoexer life->sadb_lifetime_addtime,
3683dd59ad2Shshoexer life->sadb_lifetime_usetime);
3693dd59ad2Shshoexer }
3703dd59ad2Shshoexer
3718a87fca6Smsf static void
print_proto(struct sadb_ext * ext,struct sadb_msg * msg,int opts)3727fc6e3f0Smpi print_proto(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
3738a87fca6Smsf {
3748a87fca6Smsf struct sadb_protocol *proto = (struct sadb_protocol *)ext;
3758a87fca6Smsf
3768a87fca6Smsf /* overloaded */
3778a87fca6Smsf if (msg->sadb_msg_type == SADB_X_GRPSPIS)
3786507611dSmarkus printf("satype %s flags %x",
3798a87fca6Smsf lookup_name(sa_types, proto->sadb_protocol_proto),
3808a87fca6Smsf proto->sadb_protocol_flags);
3818a87fca6Smsf else
3826507611dSmarkus printf("proto %u flags %x",
3838a87fca6Smsf proto->sadb_protocol_proto, proto->sadb_protocol_flags);
3848a87fca6Smsf }
3858a87fca6Smsf
3868a87fca6Smsf static void
print_flow(struct sadb_ext * ext,struct sadb_msg * msg,int opts)3877fc6e3f0Smpi print_flow(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
3888a87fca6Smsf {
3898a87fca6Smsf struct sadb_protocol *proto = (struct sadb_protocol *)ext;
3908a87fca6Smsf char *dir = "unknown";
3918a87fca6Smsf
3928a87fca6Smsf switch (proto->sadb_protocol_direction) {
3938a87fca6Smsf case IPSP_DIRECTION_IN:
3948a87fca6Smsf dir = "in";
3958a87fca6Smsf break;
3968a87fca6Smsf case IPSP_DIRECTION_OUT:
3978a87fca6Smsf dir = "out";
3988a87fca6Smsf break;
3998a87fca6Smsf }
4008a87fca6Smsf printf("type %s direction %s",
4018a87fca6Smsf lookup_name(flow_types, proto->sadb_protocol_proto), dir);
4028a87fca6Smsf }
4038a87fca6Smsf
404aa920ac7Sreyk static void
print_tag(struct sadb_ext * ext,struct sadb_msg * msg,int opts)4057fc6e3f0Smpi print_tag(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
406aa920ac7Sreyk {
407aa920ac7Sreyk struct sadb_x_tag *stag = (struct sadb_x_tag *)ext;
408aa920ac7Sreyk char *p;
409*c4f11a12Stobhe int plen;
410aa920ac7Sreyk
411aa920ac7Sreyk p = (char *)(stag + 1);
412*c4f11a12Stobhe plen = stag->sadb_x_tag_len * 8 - sizeof(*stag);
413*c4f11a12Stobhe printf("%.*s", plen, p);
414aa920ac7Sreyk }
415aa920ac7Sreyk
4160d5acc6aSreyk static void
print_replay(struct sadb_ext * ext,struct sadb_msg * msg,int opts)417094e3f7dStobhe print_replay(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
418094e3f7dStobhe {
419094e3f7dStobhe struct sadb_x_replay *sreplay = (struct sadb_x_replay *)ext;
420094e3f7dStobhe
421094e3f7dStobhe printf("rpl %llu", sreplay->sadb_x_replay_count);
422094e3f7dStobhe }
423094e3f7dStobhe
424094e3f7dStobhe static void
print_mtu(struct sadb_ext * ext,struct sadb_msg * msg,int opts)42549c3446eStobhe print_mtu(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
42649c3446eStobhe {
42749c3446eStobhe struct sadb_x_mtu *smtu = (struct sadb_x_mtu *)ext;
42849c3446eStobhe
42949c3446eStobhe printf("mtu %u", smtu->sadb_x_mtu_mtu);
43049c3446eStobhe }
43149c3446eStobhe
43249c3446eStobhe static void
print_tap(struct sadb_ext * ext,struct sadb_msg * msg,int opts)4337fc6e3f0Smpi print_tap(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
4340d5acc6aSreyk {
4350d5acc6aSreyk struct sadb_x_tap *stap = (struct sadb_x_tap *)ext;
4360d5acc6aSreyk
4370d5acc6aSreyk printf("enc%u", stap->sadb_x_tap_unit);
4380d5acc6aSreyk }
4390d5acc6aSreyk
440d44c51a1Sbluhm static void
print_satype(struct sadb_ext * ext,struct sadb_msg * msg,int opts)4417fc6e3f0Smpi print_satype(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
442d44c51a1Sbluhm {
443d44c51a1Sbluhm struct sadb_protocol *proto = (struct sadb_protocol *)ext;
444d44c51a1Sbluhm
445d44c51a1Sbluhm printf("type %s", lookup_name(sa_types, proto->sadb_protocol_proto));
446d44c51a1Sbluhm }
447d44c51a1Sbluhm
4487fc6e3f0Smpi static void
print_counter(struct sadb_ext * ext,struct sadb_msg * msg,int opts)4497fc6e3f0Smpi print_counter(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
4507fc6e3f0Smpi {
4517fc6e3f0Smpi struct sadb_x_counter *scnt = (struct sadb_x_counter *)ext;
4527fc6e3f0Smpi
4537fc6e3f0Smpi printf("\n");
4547fc6e3f0Smpi
4557fc6e3f0Smpi #define plural(n) ((n) != 1 ? "s" : "")
4567fc6e3f0Smpi #define p(f, m) if (scnt->f || opts & IPSECCTL_OPT_VERBOSE2) \
4577fc6e3f0Smpi printf(m, scnt->f, plural(scnt->f))
4587fc6e3f0Smpi p(sadb_x_counter_ipackets, "\t\t%llu input packet%s\n");
4597fc6e3f0Smpi p(sadb_x_counter_opackets, "\t\t%llu output packet%s\n");
4607fc6e3f0Smpi p(sadb_x_counter_ibytes, "\t\t%llu input byte%s\n");
4617fc6e3f0Smpi p(sadb_x_counter_obytes, "\t\t%llu output byte%s\n");
4627fc6e3f0Smpi p(sadb_x_counter_idecompbytes, "\t\t%llu input byte%s, decompressed\n");
4637fc6e3f0Smpi p(sadb_x_counter_ouncompbytes,"\t\t%llu output byte%s, uncompressed\n");
4647fc6e3f0Smpi p(sadb_x_counter_idrops, "\t\t%llu packet%s dropped on input\n");
4657fc6e3f0Smpi p(sadb_x_counter_odrops, "\t\t%llu packet%s dropped on output\n");
4667fc6e3f0Smpi #undef p
4677fc6e3f0Smpi #undef plural
4687fc6e3f0Smpi }
4697fc6e3f0Smpi
4708fd570bdSdlg static void
print_iface(struct sadb_ext * ext,struct sadb_msg * msg,int opts)4718fd570bdSdlg print_iface(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
4728fd570bdSdlg {
4738fd570bdSdlg struct sadb_x_iface *siface = (struct sadb_x_iface *)ext;
4748fd570bdSdlg const char *dir = "unknown";
4758fd570bdSdlg
4768fd570bdSdlg switch (siface->sadb_x_iface_direction) {
4778fd570bdSdlg case IPSP_DIRECTION_IN:
4788fd570bdSdlg dir = "in";
4798fd570bdSdlg break;
4808fd570bdSdlg case IPSP_DIRECTION_OUT:
4818fd570bdSdlg dir = "out";
4828fd570bdSdlg break;
4838fd570bdSdlg }
4848fd570bdSdlg
4858fd570bdSdlg printf("sec%u direction %s", siface->sadb_x_iface_unit, dir);
4868fd570bdSdlg }
4878fd570bdSdlg
4888a87fca6Smsf static char *
alg_by_ext(u_int8_t ext_type,u_int8_t id)4898a87fca6Smsf alg_by_ext(u_int8_t ext_type, u_int8_t id)
4908a87fca6Smsf {
4918a87fca6Smsf switch (ext_type) {
4928a87fca6Smsf case SADB_EXT_SUPPORTED_ENCRYPT:
4938a87fca6Smsf return lookup_name(enc_types, id);
4948a87fca6Smsf case SADB_EXT_SUPPORTED_AUTH:
4958a87fca6Smsf return lookup_name(auth_types, id);
4968a87fca6Smsf case SADB_X_EXT_SUPPORTED_COMP:
4978a87fca6Smsf return lookup_name(comp_types, id);
4988a87fca6Smsf default:
4998a87fca6Smsf return "unknown";
5008a87fca6Smsf }
5018a87fca6Smsf }
5028a87fca6Smsf
5038a87fca6Smsf static void
print_alg(struct sadb_alg * alg,u_int8_t ext_type)5048a87fca6Smsf print_alg(struct sadb_alg *alg, u_int8_t ext_type)
5058a87fca6Smsf {
5068685c612Smsf printf("\t\t%s iv %u min %u max %u",
5078a87fca6Smsf alg_by_ext(ext_type, alg->sadb_alg_id), alg->sadb_alg_ivlen,
5088a87fca6Smsf alg->sadb_alg_minbits, alg->sadb_alg_maxbits);
5098a87fca6Smsf }
5108a87fca6Smsf
5118a87fca6Smsf static void
print_supp(struct sadb_ext * ext,struct sadb_msg * msg,int opts)5127fc6e3f0Smpi print_supp(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
5138a87fca6Smsf {
5148a87fca6Smsf struct sadb_supported *supported = (struct sadb_supported *)ext;
5158a87fca6Smsf struct sadb_alg *alg;
5168a87fca6Smsf
5178a87fca6Smsf printf("\n");
5188a87fca6Smsf for (alg = (struct sadb_alg *)(supported + 1);
5198a87fca6Smsf (size_t)((u_int8_t *)alg - (u_int8_t *)ext) <
5208a87fca6Smsf ext->sadb_ext_len * PFKEYV2_CHUNK;
521863d7323Smsf alg++) {
522863d7323Smsf struct sadb_alg *next = alg + 1;
5238a87fca6Smsf print_alg(alg, ext->sadb_ext_type);
524863d7323Smsf if ((size_t)((u_int8_t *)next - (u_int8_t *)ext) <
525863d7323Smsf ext->sadb_ext_len * PFKEYV2_CHUNK)
526863d7323Smsf printf("\n");
527863d7323Smsf }
5288a87fca6Smsf }
5298a87fca6Smsf
5308a87fca6Smsf static void
print_comb(struct sadb_comb * comb,struct sadb_msg * msg,int opts)5317fc6e3f0Smpi print_comb(struct sadb_comb *comb, struct sadb_msg *msg, int opts)
5328a87fca6Smsf {
5338a87fca6Smsf printf("\t\tauth %s min %u max %u\n"
5348a87fca6Smsf "\t\tenc %s min %u max %u\n"
5358a87fca6Smsf "\t\taddtime hard %llu soft %llu\n"
5368685c612Smsf "\t\tusetime hard %llu soft %llu",
5378a87fca6Smsf lookup_name(auth_types, comb->sadb_comb_auth),
5388a87fca6Smsf comb->sadb_comb_auth_minbits,
5398a87fca6Smsf comb->sadb_comb_auth_maxbits,
5408a87fca6Smsf lookup_name(enc_types, comb->sadb_comb_encrypt),
5418a87fca6Smsf comb->sadb_comb_encrypt_minbits,
5428a87fca6Smsf comb->sadb_comb_encrypt_maxbits,
5438a87fca6Smsf comb->sadb_comb_soft_addtime,
5448a87fca6Smsf comb->sadb_comb_hard_addtime,
5458a87fca6Smsf comb->sadb_comb_soft_usetime,
5468a87fca6Smsf comb->sadb_comb_hard_usetime);
5478a87fca6Smsf #if 0
5488a87fca6Smsf comb->sadb_comb_flags,
5498a87fca6Smsf comb->sadb_comb_reserved,
5508a87fca6Smsf comb->sadb_comb_soft_allocations,
5518a87fca6Smsf comb->sadb_comb_hard_allocations,
5528a87fca6Smsf comb->sadb_comb_soft_bytes,
5538a87fca6Smsf comb->sadb_comb_hard_bytes,
5548a87fca6Smsf #endif
5558a87fca6Smsf }
5568a87fca6Smsf
5578a87fca6Smsf static void
print_prop(struct sadb_ext * ext,struct sadb_msg * msg,int opts)5587fc6e3f0Smpi print_prop(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
5598a87fca6Smsf {
5608a87fca6Smsf struct sadb_prop *prop = (struct sadb_prop *)ext;
5618a87fca6Smsf struct sadb_comb *comb;
5628a87fca6Smsf
563863d7323Smsf printf("replay %u\n", prop->sadb_prop_replay);
5648a87fca6Smsf for (comb = (struct sadb_comb *)(prop + 1);
5658a87fca6Smsf (size_t)((u_int8_t *)comb - (u_int8_t *)ext) <
5668a87fca6Smsf ext->sadb_ext_len * PFKEYV2_CHUNK;
5678a87fca6Smsf comb++)
5687fc6e3f0Smpi print_comb(comb, msg, opts);
5698a87fca6Smsf }
5708a87fca6Smsf
5718a87fca6Smsf static void
print_sens(struct sadb_ext * ext,struct sadb_msg * msg,int opts)5727fc6e3f0Smpi print_sens(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
5738a87fca6Smsf {
5748a87fca6Smsf struct sadb_sens *sens = (struct sadb_sens *)ext;
5758a87fca6Smsf
5768685c612Smsf printf("dpd %u sens_level %u integ_level %u",
5778a87fca6Smsf sens->sadb_sens_dpd,
5788a87fca6Smsf sens->sadb_sens_sens_level,
5798a87fca6Smsf sens->sadb_sens_integ_level);
5808a87fca6Smsf }
5818a87fca6Smsf
5828a87fca6Smsf static void
print_spir(struct sadb_ext * ext,struct sadb_msg * msg,int opts)5837fc6e3f0Smpi print_spir(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
5848a87fca6Smsf {
5858a87fca6Smsf struct sadb_spirange *spirange = (struct sadb_spirange *)ext;
5868a87fca6Smsf
5878685c612Smsf printf("min 0x%8.8x max 0x%8.8x",
5888a87fca6Smsf spirange->sadb_spirange_min, spirange->sadb_spirange_max);
5898a87fca6Smsf }
5908a87fca6Smsf
5913dd59ad2Shshoexer static void
print_ident(struct sadb_ext * ext,struct sadb_msg * msg,int opts)5927fc6e3f0Smpi print_ident(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
5933dd59ad2Shshoexer {
5943dd59ad2Shshoexer struct sadb_ident *ident = (struct sadb_ident *)ext;
595*c4f11a12Stobhe int ilen;
5963dd59ad2Shshoexer
597*c4f11a12Stobhe ilen = ident->sadb_ident_len * 8 - sizeof(*ident);
598*c4f11a12Stobhe printf("type %s id %llu: %.*s",
5993dd59ad2Shshoexer lookup_name(identity_types, ident->sadb_ident_type),
600*c4f11a12Stobhe ident->sadb_ident_id, ilen, (char *)(ident + 1));
6013dd59ad2Shshoexer }
6023dd59ad2Shshoexer
6033dd59ad2Shshoexer static void
print_policy(struct sadb_ext * ext,struct sadb_msg * msg,int opts)6047fc6e3f0Smpi print_policy(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
6058a87fca6Smsf {
6068a87fca6Smsf struct sadb_x_policy *x_policy = (struct sadb_x_policy *)ext;
6078a87fca6Smsf
6088685c612Smsf printf("seq %u", x_policy->sadb_x_policy_seq);
6098a87fca6Smsf }
6108a87fca6Smsf
6118a87fca6Smsf static void
print_udpenc(struct sadb_ext * ext,struct sadb_msg * msg,int opts)6127fc6e3f0Smpi print_udpenc(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
6133dd59ad2Shshoexer {
6143dd59ad2Shshoexer struct sadb_x_udpencap *x_udpencap = (struct sadb_x_udpencap *)ext;
6153dd59ad2Shshoexer
6168685c612Smsf printf("udpencap port %u", ntohs(x_udpencap->sadb_x_udpencap_port));
6173dd59ad2Shshoexer }
6183dd59ad2Shshoexer
619f5924638Stobhe static void
print_rdomain(struct sadb_ext * ext,struct sadb_msg * msg,int opts)620f5924638Stobhe print_rdomain(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
621f5924638Stobhe {
622f5924638Stobhe struct sadb_x_rdomain *srdomain = (struct sadb_x_rdomain *)ext;
623f5924638Stobhe
624f5924638Stobhe printf("%d/%d", srdomain->sadb_x_rdomain_dom1,
625f5924638Stobhe srdomain->sadb_x_rdomain_dom2);
626f5924638Stobhe }
627f5924638Stobhe
6288a87fca6Smsf static void
setup_extensions(struct sadb_msg * msg)6298a87fca6Smsf setup_extensions(struct sadb_msg *msg)
6303dd59ad2Shshoexer {
6313dd59ad2Shshoexer struct sadb_ext *ext;
63295f27d1eShshoexer
63395f27d1eShshoexer bzero(extensions, sizeof(extensions));
6348a87fca6Smsf if (msg->sadb_msg_len == 0)
6358a87fca6Smsf return;
6363dd59ad2Shshoexer for (ext = (struct sadb_ext *)(msg + 1);
6373dd59ad2Shshoexer (size_t)((u_int8_t *)ext - (u_int8_t *)msg) <
6383dd59ad2Shshoexer msg->sadb_msg_len * PFKEYV2_CHUNK && ext->sadb_ext_len > 0;
6393dd59ad2Shshoexer ext = (struct sadb_ext *)((u_int8_t *)ext +
6403dd59ad2Shshoexer ext->sadb_ext_len * PFKEYV2_CHUNK))
64195f27d1eShshoexer extensions[ext->sadb_ext_type] = ext;
6428a87fca6Smsf }
64395f27d1eShshoexer
6440c77d9beSmarkus static void
parse_addr(struct sadb_ext * ext,struct ipsec_addr_wrap * ipa)6450c77d9beSmarkus parse_addr(struct sadb_ext *ext, struct ipsec_addr_wrap *ipa)
6460c77d9beSmarkus {
6470c77d9beSmarkus struct sadb_address *addr = (struct sadb_address *)ext;
6480c77d9beSmarkus struct sockaddr *sa;
6490c77d9beSmarkus
6500c77d9beSmarkus if (addr == NULL)
6510c77d9beSmarkus return;
6520c77d9beSmarkus sa = (struct sockaddr *)(addr + 1);
6530c77d9beSmarkus switch (sa->sa_family) {
6540c77d9beSmarkus case AF_INET:
6550c77d9beSmarkus ipa->address.v4 = ((struct sockaddr_in *)sa)->sin_addr;
6560c77d9beSmarkus set_ipmask(ipa, 32);
6570c77d9beSmarkus break;
6580c77d9beSmarkus case AF_INET6:
6590c77d9beSmarkus ipa->address.v6 = ((struct sockaddr_in6 *)sa)->sin6_addr;
6600c77d9beSmarkus set_ipmask(ipa, 128);
6610c77d9beSmarkus break;
6620c77d9beSmarkus }
6630c77d9beSmarkus ipa->af = sa->sa_family;
6640c77d9beSmarkus ipa->next = NULL;
6650c77d9beSmarkus ipa->tail = ipa;
6660c77d9beSmarkus }
6670c77d9beSmarkus
6680c77d9beSmarkus static void
parse_key(struct sadb_ext * ext,struct ipsec_key * ikey)6690c77d9beSmarkus parse_key(struct sadb_ext *ext, struct ipsec_key *ikey)
6700c77d9beSmarkus {
6710c77d9beSmarkus struct sadb_key *key = (struct sadb_key *)ext;
6720c77d9beSmarkus u_int8_t *data;
6730c77d9beSmarkus
6740c77d9beSmarkus if (key == NULL)
6750c77d9beSmarkus return;
6760c77d9beSmarkus data = (u_int8_t *)(key + 1);
6770c77d9beSmarkus ikey->data = data;
6780c77d9beSmarkus ikey->len = key->sadb_key_bits / 8;
6790c77d9beSmarkus }
6800c77d9beSmarkus
681fbd50af5Sbluhm static void
parse_satype(struct sadb_ext * ext,u_int8_t * satype)682fbd50af5Sbluhm parse_satype(struct sadb_ext *ext, u_int8_t *satype)
683fbd50af5Sbluhm {
684fbd50af5Sbluhm struct sadb_protocol *proto = (struct sadb_protocol *)ext;
685fbd50af5Sbluhm
686fbd50af5Sbluhm if (proto == NULL)
687fbd50af5Sbluhm return;
688fbd50af5Sbluhm switch (proto->sadb_protocol_proto) {
689fbd50af5Sbluhm case SADB_SATYPE_ESP:
690fbd50af5Sbluhm *satype = IPSEC_ESP;
691fbd50af5Sbluhm break;
692fbd50af5Sbluhm case SADB_SATYPE_AH:
693fbd50af5Sbluhm *satype = IPSEC_AH;
694fbd50af5Sbluhm break;
695fbd50af5Sbluhm case SADB_X_SATYPE_IPCOMP:
696fbd50af5Sbluhm *satype = IPSEC_IPCOMP;
697fbd50af5Sbluhm break;
698fbd50af5Sbluhm case SADB_X_SATYPE_IPIP:
699fbd50af5Sbluhm *satype = IPSEC_IPIP;
700fbd50af5Sbluhm break;
701fbd50af5Sbluhm default:
702fbd50af5Sbluhm return;
703fbd50af5Sbluhm }
704fbd50af5Sbluhm }
705fbd50af5Sbluhm
706895bd039Smarkus u_int32_t
pfkey_get_spi(struct sadb_msg * msg)707895bd039Smarkus pfkey_get_spi(struct sadb_msg *msg)
708895bd039Smarkus {
709895bd039Smarkus struct sadb_sa *sa;
710895bd039Smarkus
711895bd039Smarkus setup_extensions(msg);
712895bd039Smarkus sa = (struct sadb_sa *)extensions[SADB_EXT_SA];
713895bd039Smarkus return (ntohl(sa->sadb_sa_spi));
714895bd039Smarkus }
715895bd039Smarkus
7160c77d9beSmarkus /* opposite of pfkey_sa() */
7178a87fca6Smsf void
pfkey_print_sa(struct sadb_msg * msg,int opts)7188a87fca6Smsf pfkey_print_sa(struct sadb_msg *msg, int opts)
7198a87fca6Smsf {
7208a87fca6Smsf int i;
7210c77d9beSmarkus struct ipsec_rule r;
7220c77d9beSmarkus struct ipsec_key enckey, authkey;
7230c77d9beSmarkus struct ipsec_transforms xfs;
724fbd50af5Sbluhm struct ipsec_addr_wrap src, dst, dst2;
725fbd50af5Sbluhm struct sadb_sa *sa, *sa2;
7268a87fca6Smsf
7278a87fca6Smsf setup_extensions(msg);
7280c77d9beSmarkus sa = (struct sadb_sa *)extensions[SADB_EXT_SA];
7290c77d9beSmarkus bzero(&r, sizeof r);
7300c77d9beSmarkus r.type |= RULE_SA;
7310c77d9beSmarkus r.tmode = (msg->sadb_msg_satype != SADB_X_SATYPE_TCPSIGNATURE) &&
7320c77d9beSmarkus (sa->sadb_sa_flags & SADB_X_SAFLAGS_TUNNEL) ?
7330c77d9beSmarkus IPSEC_TUNNEL : IPSEC_TRANSPORT;
7340c77d9beSmarkus r.spi = ntohl(sa->sadb_sa_spi);
7358685c612Smsf
7360c77d9beSmarkus switch (msg->sadb_msg_satype) {
7370c77d9beSmarkus case SADB_SATYPE_AH:
7380c77d9beSmarkus r.satype = IPSEC_AH;
7390c77d9beSmarkus break;
7400c77d9beSmarkus case SADB_SATYPE_ESP:
7410c77d9beSmarkus r.satype = IPSEC_ESP;
7420c77d9beSmarkus break;
7430c77d9beSmarkus case SADB_X_SATYPE_IPCOMP:
7440c77d9beSmarkus r.satype = IPSEC_IPCOMP;
7450c77d9beSmarkus break;
7460c77d9beSmarkus case SADB_X_SATYPE_TCPSIGNATURE:
7470c77d9beSmarkus r.satype = IPSEC_TCPMD5;
7480c77d9beSmarkus break;
7490c77d9beSmarkus case SADB_X_SATYPE_IPIP:
7500c77d9beSmarkus r.satype = IPSEC_IPIP;
7510c77d9beSmarkus break;
7520c77d9beSmarkus default:
7538a87fca6Smsf return;
7548a87fca6Smsf }
7550c77d9beSmarkus bzero(&dst, sizeof dst);
7560c77d9beSmarkus bzero(&src, sizeof src);
7570c77d9beSmarkus parse_addr(extensions[SADB_EXT_ADDRESS_SRC], &src);
7580c77d9beSmarkus parse_addr(extensions[SADB_EXT_ADDRESS_DST], &dst);
7590c77d9beSmarkus r.src = &src;
7600c77d9beSmarkus r.dst = &dst;
76145ad2739Smarkus if (r.satype == IPSEC_IPCOMP) {
76245ad2739Smarkus if (sa->sadb_sa_encrypt) {
76345ad2739Smarkus bzero(&xfs, sizeof xfs);
76445ad2739Smarkus r.xfs = &xfs;
76545ad2739Smarkus switch (sa->sadb_sa_encrypt) {
76645ad2739Smarkus case SADB_X_CALG_DEFLATE:
767b6ffab99Smarkus xfs.compxf = &compxfs[COMPXF_DEFLATE];
76845ad2739Smarkus break;
76945ad2739Smarkus }
77045ad2739Smarkus }
77145ad2739Smarkus } else if (r.satype == IPSEC_TCPMD5) {
77245ad2739Smarkus bzero(&authkey, sizeof authkey);
77345ad2739Smarkus parse_key(extensions[SADB_EXT_KEY_AUTH], &authkey);
77445ad2739Smarkus r.authkey = &authkey;
7754b7bcba6Snaddy } else if (sa->sadb_sa_encrypt || sa->sadb_sa_auth) {
7760c77d9beSmarkus bzero(&xfs, sizeof xfs);
7770c77d9beSmarkus r.xfs = &xfs;
7780c77d9beSmarkus if (sa->sadb_sa_encrypt) {
779a18fcb51Smarkus bzero(&enckey, sizeof enckey);
780a18fcb51Smarkus parse_key(extensions[SADB_EXT_KEY_ENCRYPT], &enckey);
781a18fcb51Smarkus r.enckey = &enckey;
782a18fcb51Smarkus
7830c77d9beSmarkus switch (sa->sadb_sa_encrypt) {
7840c77d9beSmarkus case SADB_EALG_3DESCBC:
7850c77d9beSmarkus xfs.encxf = &encxfs[ENCXF_3DES_CBC];
7860c77d9beSmarkus break;
7870c77d9beSmarkus case SADB_X_EALG_AES:
788a18fcb51Smarkus switch (r.enckey->len) {
789a18fcb51Smarkus case 192/8:
790a18fcb51Smarkus xfs.encxf = &encxfs[ENCXF_AES_192];
791a18fcb51Smarkus break;
792a18fcb51Smarkus case 256/8:
793a18fcb51Smarkus xfs.encxf = &encxfs[ENCXF_AES_256];
794a18fcb51Smarkus break;
795a18fcb51Smarkus default:
7960c77d9beSmarkus xfs.encxf = &encxfs[ENCXF_AES];
7970c77d9beSmarkus break;
798a18fcb51Smarkus }
799a18fcb51Smarkus break;
8000c77d9beSmarkus case SADB_X_EALG_AESCTR:
8015f649d51Snaddy switch (r.enckey->len) {
8025f649d51Snaddy case 28:
8035f649d51Snaddy xfs.encxf = &encxfs[ENCXF_AES_192_CTR];
8045f649d51Snaddy break;
8055f649d51Snaddy case 36:
8065f649d51Snaddy xfs.encxf = &encxfs[ENCXF_AES_256_CTR];
8075f649d51Snaddy break;
8085f649d51Snaddy default:
8090c77d9beSmarkus xfs.encxf = &encxfs[ENCXF_AESCTR];
8100c77d9beSmarkus break;
8115f649d51Snaddy }
8125f649d51Snaddy break;
813783454c1Smikeb case SADB_X_EALG_AESGCM16:
814783454c1Smikeb switch (r.enckey->len) {
815783454c1Smikeb case 28:
816783454c1Smikeb xfs.encxf = &encxfs[ENCXF_AES_192_GCM];
817783454c1Smikeb break;
818783454c1Smikeb case 36:
819783454c1Smikeb xfs.encxf = &encxfs[ENCXF_AES_256_GCM];
820783454c1Smikeb break;
821783454c1Smikeb default:
822783454c1Smikeb xfs.encxf = &encxfs[ENCXF_AES_128_GCM];
823783454c1Smikeb break;
824783454c1Smikeb }
825783454c1Smikeb break;
826783454c1Smikeb case SADB_X_EALG_AESGMAC:
827783454c1Smikeb switch (r.enckey->len) {
828783454c1Smikeb case 28:
829783454c1Smikeb xfs.encxf = &encxfs[ENCXF_AES_192_GMAC];
830783454c1Smikeb break;
831783454c1Smikeb case 36:
832783454c1Smikeb xfs.encxf = &encxfs[ENCXF_AES_256_GMAC];
833783454c1Smikeb break;
834783454c1Smikeb default:
835783454c1Smikeb xfs.encxf = &encxfs[ENCXF_AES_128_GMAC];
836783454c1Smikeb break;
837783454c1Smikeb }
838783454c1Smikeb break;
8390c77d9beSmarkus case SADB_X_EALG_BLF:
8400c77d9beSmarkus xfs.encxf = &encxfs[ENCXF_BLOWFISH];
8410c77d9beSmarkus break;
8420c77d9beSmarkus case SADB_X_EALG_CAST:
8430c77d9beSmarkus xfs.encxf = &encxfs[ENCXF_CAST128];
8440c77d9beSmarkus break;
845f705960cSmikeb case SADB_X_EALG_CHACHA20POLY1305:
846f705960cSmikeb xfs.encxf = &encxfs[ENCXF_CHACHA20_POLY1305];
847f705960cSmikeb break;
8480c77d9beSmarkus case SADB_EALG_NULL:
8490c77d9beSmarkus xfs.encxf = &encxfs[ENCXF_NULL];
8500c77d9beSmarkus break;
8510c77d9beSmarkus }
8520c77d9beSmarkus }
8530c77d9beSmarkus if (sa->sadb_sa_auth) {
854a18fcb51Smarkus bzero(&authkey, sizeof authkey);
855a18fcb51Smarkus parse_key(extensions[SADB_EXT_KEY_AUTH], &authkey);
856a18fcb51Smarkus r.authkey = &authkey;
857a18fcb51Smarkus
8580c77d9beSmarkus switch (sa->sadb_sa_auth) {
8590c77d9beSmarkus case SADB_AALG_MD5HMAC:
8600c77d9beSmarkus xfs.authxf = &authxfs[AUTHXF_HMAC_MD5];
8610c77d9beSmarkus break;
8620c77d9beSmarkus case SADB_X_AALG_RIPEMD160HMAC:
8630c77d9beSmarkus xfs.authxf = &authxfs[AUTHXF_HMAC_RIPEMD160];
8640c77d9beSmarkus break;
8650c77d9beSmarkus case SADB_AALG_SHA1HMAC:
8660c77d9beSmarkus xfs.authxf = &authxfs[AUTHXF_HMAC_SHA1];
8670c77d9beSmarkus break;
8680c77d9beSmarkus case SADB_X_AALG_SHA2_256:
8690c77d9beSmarkus xfs.authxf = &authxfs[AUTHXF_HMAC_SHA2_256];
8700c77d9beSmarkus break;
8710c77d9beSmarkus case SADB_X_AALG_SHA2_384:
8720c77d9beSmarkus xfs.authxf = &authxfs[AUTHXF_HMAC_SHA2_384];
8730c77d9beSmarkus break;
8740c77d9beSmarkus case SADB_X_AALG_SHA2_512:
8750c77d9beSmarkus xfs.authxf = &authxfs[AUTHXF_HMAC_SHA2_512];
8760c77d9beSmarkus break;
8770c77d9beSmarkus }
8780c77d9beSmarkus }
8790c77d9beSmarkus }
880a18fcb51Smarkus if (!(opts & IPSECCTL_OPT_SHOWKEY)) {
881a18fcb51Smarkus bzero(&enckey, sizeof enckey);
882a18fcb51Smarkus bzero(&authkey, sizeof authkey);
883a18fcb51Smarkus extensions[SADB_EXT_KEY_AUTH] = NULL;
884a18fcb51Smarkus extensions[SADB_EXT_KEY_ENCRYPT] = NULL;
885a18fcb51Smarkus }
886fbd50af5Sbluhm if (extensions[SADB_X_EXT_SA2]) {
887a6bcba92Sbluhm r.type |= RULE_BUNDLE;
888fbd50af5Sbluhm sa2 = (struct sadb_sa *)extensions[SADB_X_EXT_SA2];
889fbd50af5Sbluhm r.spi2 = ntohl(sa2->sadb_sa_spi);
890fbd50af5Sbluhm parse_addr(extensions[SADB_X_EXT_DST2], &dst2);
891fbd50af5Sbluhm r.dst2 = &dst2;
892fbd50af5Sbluhm parse_satype(extensions[SADB_X_EXT_SATYPE2], &r.proto2);
893fbd50af5Sbluhm r.proto = r.satype;
894fbd50af5Sbluhm }
8950c77d9beSmarkus ipsecctl_print_rule(&r, opts);
8960c77d9beSmarkus
8970c77d9beSmarkus if (opts & IPSECCTL_OPT_VERBOSE) {
89894de6926Smarkus for (i = 0; i <= SADB_EXT_MAX; i++)
8990c77d9beSmarkus if (extensions[i])
9007fc6e3f0Smpi print_ext(extensions[i], msg, opts);
9010c77d9beSmarkus }
9020c77d9beSmarkus fflush(stdout);
9038a87fca6Smsf }
9048a87fca6Smsf
9058a87fca6Smsf void
pfkey_monitor_sa(struct sadb_msg * msg,int opts)9068a87fca6Smsf pfkey_monitor_sa(struct sadb_msg *msg, int opts)
9078a87fca6Smsf {
9088a87fca6Smsf int i;
9098a87fca6Smsf
9108a87fca6Smsf setup_extensions(msg);
9118a87fca6Smsf
9128a87fca6Smsf printf("%s: satype %s vers %u len %u seq %u pid %u\n",
9138a87fca6Smsf lookup_name(msg_types, msg->sadb_msg_type),
9148a87fca6Smsf lookup_name(sa_types, msg->sadb_msg_satype),
9158a87fca6Smsf msg->sadb_msg_version, msg->sadb_msg_len,
9168a87fca6Smsf msg->sadb_msg_seq,
9178a87fca6Smsf msg->sadb_msg_pid);
9188a87fca6Smsf if (msg->sadb_msg_errno)
9198a87fca6Smsf printf("\terrno %u: %s\n", msg->sadb_msg_errno,
9208a87fca6Smsf strerror(msg->sadb_msg_errno));
92194de6926Smarkus for (i = 0; i <= SADB_EXT_MAX; i++)
9228a87fca6Smsf if (extensions[i])
9237fc6e3f0Smpi print_ext(extensions[i], msg, opts);
9248a87fca6Smsf fflush(stdout);
9258a87fca6Smsf }
9268a87fca6Smsf
9278a87fca6Smsf void
pfkey_print_raw(u_int8_t * data,ssize_t len)9288a87fca6Smsf pfkey_print_raw(u_int8_t *data, ssize_t len)
9298a87fca6Smsf {
9308a87fca6Smsf int i;
9318a87fca6Smsf const u_int8_t *sp = (const u_int8_t *)data;
9328a87fca6Smsf
9338a87fca6Smsf printf("RAW PFKEYV2 MESSAGE:\n");
9348a87fca6Smsf for (i = 0; i < len; i++) {
9358a87fca6Smsf if ((i % 8 == 0) && (i != 0))
9368a87fca6Smsf printf("\n");
9378a87fca6Smsf printf("%02x ", *sp);
9388a87fca6Smsf sp++;
9398a87fca6Smsf }
9408a87fca6Smsf printf("\n");
9418a87fca6Smsf }
942