summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Joerg Hoexer <hshoexer@cvs.openbsd.org>2005-05-27 05:19:56 +0000
committerHans-Joerg Hoexer <hshoexer@cvs.openbsd.org>2005-05-27 05:19:56 +0000
commit74406ee6e13d7c7a189ebec85a9be69948eb5c91 (patch)
tree23a21d6d191a73d356df4c75a8e8cdb760d0fcae
parent059769e15d5c84c13ea1a442d57bc60741a4c9c1 (diff)
Support for dumping the SADB.
-rw-r--r--sbin/ipsecctl/Makefile4
-rw-r--r--sbin/ipsecctl/ipsecctl.818
-rw-r--r--sbin/ipsecctl/ipsecctl.c134
-rw-r--r--sbin/ipsecctl/ipsecctl.h3
-rw-r--r--sbin/ipsecctl/pfkdump.c321
-rw-r--r--sbin/ipsecctl/pfkey.h3
6 files changed, 457 insertions, 26 deletions
diff --git a/sbin/ipsecctl/Makefile b/sbin/ipsecctl/Makefile
index f9df063b4de..170f6246dec 100644
--- a/sbin/ipsecctl/Makefile
+++ b/sbin/ipsecctl/Makefile
@@ -1,9 +1,9 @@
-# $OpenBSD: Makefile,v 1.2 2005/04/04 22:22:55 hshoexer Exp $
+# $OpenBSD: Makefile,v 1.3 2005/05/27 05:19:55 hshoexer Exp $
PROG= ipsecctl
MAN= ipsecctl.8 ipsec.conf.5
-SRCS= ipsecctl.c pfkey.c parse.y
+SRCS= ipsecctl.c pfkey.c pfkdump.c parse.y
CFLAGS+= -Wall -I${.CURDIR}
CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
diff --git a/sbin/ipsecctl/ipsecctl.8 b/sbin/ipsecctl/ipsecctl.8
index d3e48599a93..da82fd4b47b 100644
--- a/sbin/ipsecctl/ipsecctl.8
+++ b/sbin/ipsecctl/ipsecctl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ipsecctl.8,v 1.7 2005/05/23 20:25:54 kjell Exp $
+.\" $OpenBSD: ipsecctl.8,v 1.8 2005/05/27 05:19:55 hshoexer Exp $
.\"
.\" Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org>
.\"
@@ -22,8 +22,9 @@
.Nd control flows for IPsec
.Sh SYNOPSIS
.Nm ipsecctl
-.Op Fl Fnsv
+.Op Fl Fnv
.Op Fl f Ar file
+.Op Fl s Ar modifier
.Sh DESCRIPTION
The
.Nm
@@ -46,8 +47,19 @@ Load the rules contained in
.Ar file .
.It Fl n
Do not actually load rules, just parse them.
-.It Fl s
+.It Fl s Ar modifier
+Show the kernels databases specified by
+.Ar modifier
+(may be abbreviated):
+.Pp
+.Bl -tag -width xxxxxxxxxxxxx -compact
+.It Fl s Cm flow
Show the ruleset loaded into the SPD.
+.It Fl s Cm sa
+Show the active SADB entries.
+.It Fl s Cm all
+Show all of the above.
+.El
.It Fl v
Produce more verbose output.
A second use of
diff --git a/sbin/ipsecctl/ipsecctl.c b/sbin/ipsecctl/ipsecctl.c
index dd8bb185bd4..beb040f3f1c 100644
--- a/sbin/ipsecctl/ipsecctl.c
+++ b/sbin/ipsecctl/ipsecctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsecctl.c,v 1.7 2005/05/25 17:10:26 hshoexer Exp $ */
+/* $OpenBSD: ipsecctl.c,v 1.8 2005/05/27 05:19:55 hshoexer Exp $ */
/*
* Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org>
*
@@ -46,10 +46,20 @@ void ipsecctl_print_addr(struct ipsec_addr *);
void ipsecctl_print_rule(struct ipsec_rule *, int);
int ipsecctl_flush(int);
void ipsecctl_get_rules(struct ipsecctl *);
-void ipsecctl_show(int);
+void ipsecctl_print_title(char *);
+void ipsecctl_show_flows(int);
+void ipsecctl_show_sas(int);
void usage(void);
+const char *ipsecctl_lookup_option(char *, const char **);
const char *infile; /* Used by parse.y */
+const char *showopt;
+
+int first_title = 1;
+
+static const char *showopt_list[] = {
+ "flow", "sa", "all", NULL
+};
int
ipsecctl_rules(char *filename, int opts)
@@ -140,7 +150,7 @@ ipsecctl_add_rule(struct ipsecctl *ipsec, struct ipsec_rule *r)
if ((ipsec->opts & IPSECCTL_OPT_VERBOSE) && !(ipsec->opts &
IPSECCTL_OPT_SHOW))
- ipsecctl_print_rule(r, ipsec->opts & IPSECCTL_OPT_VERBOSE2);
+ ipsecctl_print_rule(r, ipsec->opts);
return (0);
}
@@ -170,13 +180,13 @@ ipsecctl_print_addr(struct ipsec_addr *ipa)
}
void
-ipsecctl_print_rule(struct ipsec_rule *r, int verbose)
+ipsecctl_print_rule(struct ipsec_rule *r, int opts)
{
static const char *direction[] = {"?", "in", "out"};
static const char *proto[] = {"?", "esp", "ah"};
static const char *auth[] = {"?", "psk", "rsa"};
- if (verbose)
+ if (opts & IPSECCTL_OPT_VERBOSE2)
printf("@%d ", r->nr);
printf("flow %s %s", proto[r->proto], direction[r->direction]);
@@ -187,14 +197,14 @@ ipsecctl_print_rule(struct ipsec_rule *r, int verbose)
printf(" peer ");
ipsecctl_print_addr(r->peer);
- if (r->auth.srcid)
- printf(" srcid %s", r->auth.srcid);
- if (r->auth.dstid)
- printf(" dstid %s", r->auth.dstid);
-
- if (r->auth.type > 0)
- printf(" %s", auth[r->auth.type]);
-
+ if (opts & IPSECCTL_OPT_VERBOSE) {
+ if (r->auth.srcid)
+ printf("\n\tsrcid %s", r->auth.srcid);
+ if (r->auth.dstid)
+ printf("\n\tdstid %s", r->auth.dstid);
+ if (r->auth.type > 0)
+ printf(" %s", auth[r->auth.type]);
+ }
printf("\n");
}
@@ -318,7 +328,16 @@ ipsecctl_get_rules(struct ipsecctl *ipsec)
}
void
-ipsecctl_show(int opts)
+ipsecctl_print_title(char *title)
+{
+ if (!first_title)
+ printf("\n");
+ first_title = 0;
+ printf("%s\n", title);
+}
+
+void
+ipsecctl_show_flows(int opts)
{
struct ipsecctl ipsec;
struct ipsec_rule *rp;
@@ -329,10 +348,19 @@ ipsecctl_show(int opts)
ipsecctl_get_rules(&ipsec);
+ if (opts & IPSECCTL_OPT_SHOWALL)
+ ipsecctl_print_title("FLOWS:");
+
+ if (TAILQ_FIRST(&ipsec.rule_queue) == 0) {
+ if (opts & IPSECCTL_OPT_SHOWALL)
+ printf("No flows\n");
+ return;
+ }
+
while ((rp = TAILQ_FIRST(&ipsec.rule_queue))) {
TAILQ_REMOVE(&ipsec.rule_queue, rp, entries);
- ipsecctl_print_rule(rp, ipsec.opts & IPSECCTL_OPT_VERBOSE2);
+ ipsecctl_print_rule(rp, ipsec.opts);
free(rp->src);
free(rp->dst);
@@ -347,15 +375,65 @@ ipsecctl_show(int opts)
return;
}
+void
+ipsecctl_show_sas(int opts)
+{
+ struct sadb_msg *msg;
+ int mib[5];
+ size_t need = 0;
+ char *buf, *lim, *next;
+
+ mib[0] = CTL_NET;
+ mib[1] = PF_KEY;
+ mib[2] = PF_KEY_V2;
+ mib[3] = NET_KEY_SADB_DUMP;
+ mib[4] = SADB_SATYPE_UNSPEC;
+
+ if (opts & IPSECCTL_OPT_SHOWALL)
+ ipsecctl_print_title("SADB:");
+
+ /* When the SADB is empty we get ENOENT, no need to err(). */
+ if (sysctl(mib, 5, NULL, &need, NULL, 0) == -1 && errno != ENOENT)
+ err(1, "sysctl");
+ if (need == 0) {
+ if (opts & IPSECCTL_OPT_SHOWALL)
+ printf("No entries\n");
+ return;
+ }
+ if ((buf = malloc(need)) == NULL)
+ err(1, "malloc");
+ if (sysctl(mib, 5, buf, &need, NULL, 0) == -1)
+ err(1, "sysctl");
+ lim = buf + need;
+ for (next = buf; next < lim;
+ next += msg->sadb_msg_len * PFKEYV2_CHUNK) {
+ msg = (struct sadb_msg *)next;
+ if (msg->sadb_msg_len == 0)
+ break;
+ pfkey_print_sa(msg, opts);
+ }
+}
+
__dead void
usage(void)
{
extern char *__progname;
- fprintf(stderr, "usage: %s [-Fnsv] [-f file]\n", __progname);
+ fprintf(stderr, "usage: %s [-Fnv] [-f file] [-s modifier]\n",
+ __progname);
exit(1);
}
+const char *
+ipsecctl_lookup_option(char *cmd, const char **list)
+{
+ if (cmd != NULL && *cmd)
+ for (; *list; list++)
+ if (!strncmp(cmd, *list, strlen(cmd)))
+ return (*list);
+ return (NULL);
+}
+
int
main(int argc, char *argv[])
{
@@ -367,7 +445,7 @@ main(int argc, char *argv[])
if (argc < 2)
usage();
- while ((ch = getopt(argc, argv, "f:Fnvs")) != -1) {
+ while ((ch = getopt(argc, argv, "f:Fnvs:")) != -1) {
switch (ch) {
case 'f':
rulesopt = optarg;
@@ -388,6 +466,12 @@ main(int argc, char *argv[])
break;
case 's':
+ showopt = ipsecctl_lookup_option(optarg, showopt_list);
+ if (showopt == NULL) {
+ warnx("Unknown show modifier '%s'", optarg);
+ usage();
+ /* NOTREACHED */
+ }
opts |= IPSECCTL_OPT_SHOW;
break;
@@ -410,8 +494,20 @@ main(int argc, char *argv[])
if (ipsecctl_rules(rulesopt, opts))
error = 1;
- if (opts & IPSECCTL_OPT_SHOW)
- ipsecctl_show(opts);
+ if (showopt != NULL) {
+ switch (*showopt) {
+ case 'f':
+ ipsecctl_show_flows(opts);
+ break;
+ case 's':
+ ipsecctl_show_sas(opts);
+ break;
+ case 'a':
+ opts |= IPSECCTL_OPT_SHOWALL;
+ ipsecctl_show_flows(opts);
+ ipsecctl_show_sas(opts);
+ }
+ }
exit(error);
}
diff --git a/sbin/ipsecctl/ipsecctl.h b/sbin/ipsecctl/ipsecctl.h
index 2a7be598c06..a1d831aeb1b 100644
--- a/sbin/ipsecctl/ipsecctl.h
+++ b/sbin/ipsecctl/ipsecctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsecctl.h,v 1.4 2005/05/25 17:10:26 hshoexer Exp $ */
+/* $OpenBSD: ipsecctl.h,v 1.5 2005/05/27 05:19:55 hshoexer Exp $ */
/*
* Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org>
*
@@ -24,6 +24,7 @@
#define IPSECCTL_OPT_VERBOSE 0x0010
#define IPSECCTL_OPT_VERBOSE2 0x0020
#define IPSECCTL_OPT_SHOW 0x0040
+#define IPSECCTL_OPT_SHOWALL 0x0080
#define IPSECCTL_OPT_FLUSH 0x0100
enum {
diff --git a/sbin/ipsecctl/pfkdump.c b/sbin/ipsecctl/pfkdump.c
new file mode 100644
index 00000000000..6c2c1d79c1d
--- /dev/null
+++ b/sbin/ipsecctl/pfkdump.c
@@ -0,0 +1,321 @@
+/* $OpenBSD: pfkdump.c,v 1.1 2005/05/27 05:19:55 hshoexer Exp $ */
+
+/*
+ * Copyright (c) 2003 Markus Friedl. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <sys/time.h>
+#include <sys/sysctl.h>
+#include <net/pfkeyv2.h>
+#include <netinet/ip_ipsp.h>
+#include <netdb.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <err.h>
+
+#include "ipsecctl.h"
+#include "pfkey.h"
+
+static void print_sa(struct sadb_ext *, struct sadb_msg *);
+static void print_addr(struct sadb_ext *, struct sadb_msg *);
+static void print_key(struct sadb_ext *, struct sadb_msg *);
+static void print_life(struct sadb_ext *, struct sadb_msg *);
+static void print_ident(struct sadb_ext *, struct sadb_msg *);
+static void print_auth(struct sadb_ext *, struct sadb_msg *);
+static void print_udpenc(struct sadb_ext *, struct sadb_msg *);
+
+static struct idname *lookup(struct idname [], u_int8_t);
+static char *lookup_name(struct idname [], u_int8_t);
+static void print_ext(struct sadb_ext *, struct sadb_msg *, int);
+
+void pfkey_print_sa(struct sadb_msg *, int);
+
+struct idname {
+ u_int8_t id;
+ char *name;
+ void (*func)(struct sadb_ext *, struct sadb_msg *);
+};
+
+struct idname ext_types[] = {
+ { SADB_EXT_RESERVED, "reserved", NULL },
+ { SADB_EXT_SA, "sa", print_sa},
+ { SADB_EXT_LIFETIME_CURRENT, "lifetime_cur", print_life },
+ { SADB_EXT_LIFETIME_HARD, "lifetime_hard", print_life },
+ { SADB_EXT_LIFETIME_SOFT, "lifetime_soft", print_life },
+ { SADB_EXT_ADDRESS_SRC, "address_src", print_addr},
+ { SADB_EXT_ADDRESS_DST, "address_dst", print_addr},
+ { SADB_EXT_KEY_AUTH, "key_auth", print_key},
+ { SADB_EXT_KEY_ENCRYPT, "key_encrypt", print_key},
+ { SADB_EXT_IDENTITY_SRC, "identity_src", print_ident },
+ { SADB_EXT_IDENTITY_DST, "identity_dst", print_ident },
+ { SADB_X_EXT_REMOTE_AUTH, "remote_auth", print_auth },
+ { SADB_X_EXT_UDPENCAP, "udpencap", print_udpenc },
+ { SADB_X_EXT_LIFETIME_LASTUSE, "lifetime_lastuse", print_life },
+ { 0, NULL, NULL }
+};
+
+struct idname sa_types[] = {
+ { SADB_SATYPE_UNSPEC, "unspec", NULL },
+ { SADB_SATYPE_AH, "ah", NULL },
+ { SADB_SATYPE_ESP, "esp", NULL },
+ { SADB_SATYPE_RSVP, "rsvp", NULL },
+ { SADB_SATYPE_OSPFV2, "ospfv2", NULL },
+ { SADB_SATYPE_RIPV2, "ripv2", NULL },
+ { SADB_SATYPE_MIP, "mip", NULL },
+ { SADB_X_SATYPE_IPIP, "ipip", NULL },
+ { SADB_X_SATYPE_TCPSIGNATURE, "tcpmd5", NULL },
+ { SADB_X_SATYPE_IPCOMP, "ipcomp", NULL },
+ { 0, NULL, NULL }
+};
+
+struct idname auth_types[] = {
+ { SADB_AALG_NONE, "none", NULL },
+ { SADB_X_AALG_DES, "des", NULL },
+ { SADB_AALG_MD5HMAC, "hmac-md5", NULL },
+ { SADB_X_AALG_RIPEMD160HMAC, "hmac-ripemd160", NULL },
+ { SADB_AALG_SHA1HMAC, "hmac-sha1", NULL },
+ { SADB_X_AALG_SHA2_256, "hmac-sha2-256", NULL },
+ { SADB_X_AALG_SHA2_384, "hmac-sha2-384", NULL },
+ { SADB_X_AALG_SHA2_512, "hmac-sha2-512", NULL },
+ { SADB_X_AALG_MD5, "md5", NULL },
+ { SADB_X_AALG_SHA1, "sha1", NULL },
+ { 0, NULL, NULL }
+};
+
+struct idname enc_types[] = {
+ { SADB_EALG_NONE, "none", NULL },
+ { SADB_EALG_3DESCBC, "3des-cbc", NULL },
+ { SADB_EALG_DESCBC, "des-cbc", NULL },
+ { SADB_X_EALG_3IDEA, "idea3", NULL },
+ { SADB_X_EALG_AES, "aes", NULL },
+ { SADB_X_EALG_AESCTR, "aesctr", NULL },
+ { SADB_X_EALG_BLF, "blowfish", NULL },
+ { SADB_X_EALG_CAST, "cast128", NULL },
+ { SADB_X_EALG_DES_IV32, "des-iv32", NULL },
+ { SADB_X_EALG_DES_IV64, "des-iv64", NULL },
+ { SADB_X_EALG_IDEA, "idea", NULL },
+ { SADB_EALG_NULL, "null", NULL },
+ { SADB_X_EALG_RC4, "rc4", NULL },
+ { SADB_X_EALG_RC5, "rc5", NULL },
+ { SADB_X_EALG_SKIPJACK, "skipjack", NULL },
+ { 0, NULL, NULL }
+};
+
+struct idname comp_types[] = {
+ { SADB_X_CALG_NONE, "none", NULL },
+ { SADB_X_CALG_OUI, "oui", NULL },
+ { SADB_X_CALG_DEFLATE, "deflate", NULL },
+ { SADB_X_CALG_LZS, "lzs", NULL },
+ { 0, NULL, NULL }
+};
+
+struct idname xauth_types[] = {
+ { SADB_X_AUTHTYPE_NONE, "none", NULL },
+ { SADB_X_AUTHTYPE_PASSPHRASE, "passphrase", NULL },
+ { SADB_X_AUTHTYPE_RSA, "rsa", NULL },
+ { 0, NULL, NULL }
+};
+
+struct idname identity_types[] = {
+ { SADB_IDENTTYPE_RESERVED, "reserved", NULL },
+ { SADB_IDENTTYPE_PREFIX, "prefix", NULL },
+ { SADB_IDENTTYPE_FQDN, "fqdn", NULL },
+ { SADB_IDENTTYPE_USERFQDN, "ufqdn", NULL },
+ { SADB_X_IDENTTYPE_CONNECTION, "x_connection", NULL },
+ { 0, NULL, NULL }
+};
+
+struct idname states[] = {
+ { SADB_SASTATE_LARVAL, "larval", NULL },
+ { SADB_SASTATE_MATURE, "mature", NULL },
+ { SADB_SASTATE_DYING, "dying", NULL },
+ { SADB_SASTATE_DEAD, "dead", NULL },
+ { 0, NULL, NULL }
+};
+
+static struct idname *
+lookup(struct idname tab[], u_int8_t id)
+{
+ struct idname *entry;
+
+ for (entry = tab; entry->name; entry++)
+ if (entry->id == id)
+ return (entry);
+ return (NULL);
+}
+
+static char *
+lookup_name(struct idname tab[], u_int8_t id)
+{
+ struct idname *entry;
+
+ entry = lookup(tab, id);
+ return (entry ? entry->name : "unknown");
+}
+
+static void
+print_ext(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
+{
+ struct idname *entry;
+
+ if ((entry = lookup(ext_types, ext->sadb_ext_type)) == NULL) {
+ printf("unknown ext: type %u len %u\n",
+ ext->sadb_ext_type, ext->sadb_ext_len);
+ return;
+ }
+
+ if (!(opts & IPSECCTL_OPT_VERBOSE) && entry->id != SADB_EXT_SA)
+ return;
+ if (entry->id != SADB_EXT_SA)
+ printf("\t%s: ", entry->name);
+ if (entry->func != NULL)
+ (*entry->func)(ext, msg);
+ else
+ printf("type %u len %u\n",
+ ext->sadb_ext_type, ext->sadb_ext_len);
+}
+
+static void
+print_sa(struct sadb_ext *ext, struct sadb_msg *msg)
+{
+ struct sadb_sa *sa = (struct sadb_sa *) ext;
+
+ if (msg->sadb_msg_satype == SADB_X_SATYPE_IPCOMP)
+ printf("cpi 0x%8.8x comp %s",
+ ntohl(sa->sadb_sa_spi),
+ lookup_name(comp_types, sa->sadb_sa_encrypt));
+ else
+ printf("spi 0x%8.8x auth %s enc %s",
+ ntohl(sa->sadb_sa_spi),
+ lookup_name(auth_types, sa->sadb_sa_auth),
+ lookup_name(enc_types, sa->sadb_sa_encrypt));
+ if (sa->sadb_sa_flags & SADB_X_SAFLAGS_TUNNEL)
+ printf(" tunnel");
+ printf("\n");
+}
+
+static void
+print_addr(struct sadb_ext *ext, struct sadb_msg *msg)
+{
+ struct sadb_address *addr = (struct sadb_address *) ext;
+ struct sockaddr *sa;
+ struct sockaddr_in *sin4;
+ struct sockaddr_in6 *sin6;
+ char hbuf[NI_MAXHOST];
+
+ sa = (struct sockaddr *)(addr + 1);
+ if (sa->sa_family == 0)
+ printf("<any>");
+ else if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0,
+ NI_NUMERICHOST))
+ printf("<could not get numeric hostname>");
+ else
+ printf("%s", hbuf);
+ switch (sa->sa_family) {
+ case AF_INET:
+ sin4 = (struct sockaddr_in *)sa;
+ if (sin4->sin_port)
+ printf(" port %u", ntohs(sin4->sin_port));
+ break;
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *)sa;
+ if (sin6->sin6_port)
+ printf(" port %u", ntohs(sin6->sin6_port));
+ break;
+ }
+ printf("\n");
+}
+
+static void
+print_key(struct sadb_ext *ext, struct sadb_msg *msg)
+{
+ struct sadb_key *key = (struct sadb_key *) ext;
+ u_int8_t *data;
+ int i;
+
+ printf("bits %u: ", key->sadb_key_bits);
+ data = (u_int8_t *)(key + 1);
+ for (i = 0; i < key->sadb_key_bits / 8; i++) {
+ printf("%2.2x", data[i]);
+ data[i] = 0x00; /* clear sensitive data */
+ }
+ printf("\n");
+}
+
+static void
+print_life(struct sadb_ext *ext, struct sadb_msg *msg)
+{
+ struct sadb_lifetime *life = (struct sadb_lifetime *) ext;
+
+ printf("alloc %u bytes %llu add %llu first %llu\n",
+ life->sadb_lifetime_allocations,
+ life->sadb_lifetime_bytes,
+ life->sadb_lifetime_addtime,
+ life->sadb_lifetime_usetime);
+}
+
+static void
+print_ident(struct sadb_ext *ext, struct sadb_msg *msg)
+{
+ struct sadb_ident *ident = (struct sadb_ident *) ext;
+
+ printf("type %s id %llu: %s\n",
+ lookup_name(identity_types, ident->sadb_ident_type),
+ ident->sadb_ident_id, (char *)(ident + 1));
+}
+
+static void
+print_auth(struct sadb_ext *ext, struct sadb_msg *msg)
+{
+ struct sadb_x_cred *x_cred = (struct sadb_x_cred *) ext;
+
+ printf("type %s\n",
+ lookup_name(xauth_types, x_cred->sadb_x_cred_type));
+}
+
+static void
+print_udpenc(struct sadb_ext *ext, struct sadb_msg *msg)
+{
+ struct sadb_x_udpencap *x_udpencap = (struct sadb_x_udpencap *) ext;
+
+ printf("udpencap port %u\n", ntohs(x_udpencap->sadb_x_udpencap_port));
+}
+
+void
+pfkey_print_sa(struct sadb_msg *msg, int opts)
+{
+ struct sadb_ext *ext;
+
+ printf("%s ", lookup_name(sa_types, msg->sadb_msg_satype));
+ for (ext = (struct sadb_ext *)(msg + 1);
+ (size_t)((u_int8_t *)ext - (u_int8_t *)msg) <
+ msg->sadb_msg_len * PFKEYV2_CHUNK && ext->sadb_ext_len > 0;
+ ext = (struct sadb_ext *)((u_int8_t *)ext +
+ ext->sadb_ext_len * PFKEYV2_CHUNK))
+ print_ext(ext, msg, opts);
+ fflush(stdout);
+}
diff --git a/sbin/ipsecctl/pfkey.h b/sbin/ipsecctl/pfkey.h
index 94853c9580a..cae6646a5d9 100644
--- a/sbin/ipsecctl/pfkey.h
+++ b/sbin/ipsecctl/pfkey.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkey.h,v 1.1 2005/05/25 17:10:26 hshoexer Exp $ */
+/* $OpenBSD: pfkey.h,v 1.2 2005/05/27 05:19:55 hshoexer Exp $ */
/*
* Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org>
*
@@ -21,6 +21,7 @@
#define PFKEYV2_CHUNK sizeof(u_int64_t)
int pfkey_parse(struct sadb_msg *, struct ipsec_rule *);
+void pfkey_print_sa(struct sadb_msg *, int);
int pfkey_ipsec_establish(struct ipsec_rule *);
int pfkey_ipsec_flush(void);
int pfkey_init(void);