summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
Diffstat (limited to 'sbin')
-rw-r--r--sbin/ipsecctl/ipsecctl.86
-rw-r--r--sbin/ipsecctl/ipsecctl.c19
-rw-r--r--sbin/ipsecctl/ipsecctl.h3
-rw-r--r--sbin/ipsecctl/pfkdump.c307
-rw-r--r--sbin/ipsecctl/pfkey.c91
-rw-r--r--sbin/ipsecctl/pfkey.h5
6 files changed, 411 insertions, 20 deletions
diff --git a/sbin/ipsecctl/ipsecctl.8 b/sbin/ipsecctl/ipsecctl.8
index d964b94f861..9eed01b53a6 100644
--- a/sbin/ipsecctl/ipsecctl.8
+++ b/sbin/ipsecctl/ipsecctl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ipsecctl.8,v 1.16 2006/03/22 16:01:23 reyk Exp $
+.\" $OpenBSD: ipsecctl.8,v 1.17 2006/05/30 21:56:05 msf Exp $
.\"
.\" Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org>
.\"
@@ -22,7 +22,7 @@
.Nd control flows for IPsec
.Sh SYNOPSIS
.Nm ipsecctl
-.Op Fl dFnv
+.Op Fl dFmnv
.Oo Fl D
.Ar macro Ns = Ns Ar value Oc
.Op Fl f Ar file
@@ -77,6 +77,8 @@ option flushes the SPD and the SADB.
.It Fl f Ar file
Load the rules contained in
.Ar file .
+.It Fl m
+Continuously display all PF_KEY messages exchanged with the kernel.
.It Fl n
Do not actually load rules, just parse them.
.It Fl s Ar modifier
diff --git a/sbin/ipsecctl/ipsecctl.c b/sbin/ipsecctl/ipsecctl.c
index 5d61323f2f4..d0939dfb9ec 100644
--- a/sbin/ipsecctl/ipsecctl.c
+++ b/sbin/ipsecctl/ipsecctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsecctl.c,v 1.47 2006/05/29 18:43:36 hshoexer Exp $ */
+/* $OpenBSD: ipsecctl.c,v 1.48 2006/05/30 21:56:05 msf Exp $ */
/*
* Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org>
*
@@ -56,6 +56,7 @@ void ipsecctl_get_rules(struct ipsecctl *);
void ipsecctl_print_title(char *);
void ipsecctl_show_flows(int);
void ipsecctl_show_sas(int);
+int ipsecctl_monitor(int);
void usage(void);
const char *ipsecctl_lookup_option(char *, const char **);
static int unmask(struct ipsec_addr *, sa_family_t);
@@ -511,6 +512,12 @@ ipsecctl_show_sas(int opts)
free(buf);
}
+int
+ipsecctl_monitor(int opts)
+{
+ return (pfkey_monitor(opts));
+}
+
__dead void
usage(void)
{
@@ -542,7 +549,7 @@ main(int argc, char *argv[])
if (argc < 2)
usage();
- while ((ch = getopt(argc, argv, "D:df:Fnvs:")) != -1) {
+ while ((ch = getopt(argc, argv, "D:df:Fmnvs:")) != -1) {
switch (ch) {
case 'D':
if (cmdline_symset(optarg) < 0)
@@ -560,6 +567,10 @@ main(int argc, char *argv[])
opts |= IPSECCTL_OPT_FLUSH;
break;
+ case 'm':
+ opts |= IPSECCTL_OPT_MONITOR;
+ break;
+
case 'n':
opts |= IPSECCTL_OPT_NOACTION;
break;
@@ -614,6 +625,10 @@ main(int argc, char *argv[])
}
}
+ if (opts & IPSECCTL_OPT_MONITOR)
+ if (ipsecctl_monitor(opts))
+ error = 1;
+
exit(error);
}
diff --git a/sbin/ipsecctl/ipsecctl.h b/sbin/ipsecctl/ipsecctl.h
index 704019fd029..089f6c7f816 100644
--- a/sbin/ipsecctl/ipsecctl.h
+++ b/sbin/ipsecctl/ipsecctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsecctl.h,v 1.36 2006/05/29 18:52:56 hshoexer Exp $ */
+/* $OpenBSD: ipsecctl.h,v 1.37 2006/05/30 21:56:05 msf Exp $ */
/*
* Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org>
*
@@ -27,6 +27,7 @@
#define IPSECCTL_OPT_SHOWALL 0x0080
#define IPSECCTL_OPT_FLUSH 0x0100
#define IPSECCTL_OPT_DELETE 0x0200
+#define IPSECCTL_OPT_MONITOR 0x0400
enum {
ACTION_ADD, ACTION_DELETE
diff --git a/sbin/ipsecctl/pfkdump.c b/sbin/ipsecctl/pfkdump.c
index ff2cfc26d8d..351ee000fbe 100644
--- a/sbin/ipsecctl/pfkdump.c
+++ b/sbin/ipsecctl/pfkdump.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkdump.c,v 1.10 2005/12/21 01:40:23 millert Exp $ */
+/* $OpenBSD: pfkdump.c,v 1.11 2006/05/30 21:56:05 msf Exp $ */
/*
* Copyright (c) 2003 Markus Friedl. All rights reserved.
@@ -40,6 +40,13 @@
#include "ipsecctl.h"
#include "pfkey.h"
+static void print_proto(struct sadb_ext *, struct sadb_msg *);
+static void print_flow(struct sadb_ext *, struct sadb_msg *);
+static void print_supp(struct sadb_ext *, struct sadb_msg *);
+static void print_prop(struct sadb_ext *, struct sadb_msg *);
+static void print_sens(struct sadb_ext *, struct sadb_msg *);
+static void print_spir(struct sadb_ext *, struct sadb_msg *);
+static void print_policy(struct sadb_ext *, struct sadb_msg *);
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 *);
@@ -54,6 +61,7 @@ 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);
+void pfkey_print_raw(u_int8_t *, ssize_t);
struct sadb_ext *extensions[SADB_EXT_MAX];
@@ -71,10 +79,27 @@ struct idname ext_types[] = {
{ 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_ADDRESS_PROXY, "address_proxy", 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_EXT_SENSITIVITY, "sensitivity", print_sens },
+ { SADB_EXT_PROPOSAL, "proposal", print_prop },
+ { SADB_EXT_SUPPORTED_AUTH, "supported_auth", print_supp },
+ { SADB_EXT_SUPPORTED_ENCRYPT, "supported_encrypt", print_supp },
+ { SADB_EXT_SPIRANGE, "spirange", print_spir },
+ { SADB_X_EXT_SRC_MASK, "src_mask", print_addr },
+ { SADB_X_EXT_DST_MASK, "dst_mask", print_addr },
+ { SADB_X_EXT_PROTOCOL, "protocol", print_proto },
+ { SADB_X_EXT_FLOW_TYPE, "flow_type", print_flow },
+ { SADB_X_EXT_SRC_FLOW, "src_flow", print_addr },
+ { SADB_X_EXT_DST_FLOW, "dst_flow", print_addr },
+ { SADB_X_EXT_SA2, "sa2", print_sa },
+ { SADB_X_EXT_DST2, "dst2", print_addr },
+ { SADB_X_EXT_POLICY, "policy", print_policy },
+ { SADB_X_EXT_LOCAL_AUTH, "local_auth", print_auth },
+ { SADB_X_EXT_SUPPORTED_COMP, "supported_comp", print_supp },
{ SADB_X_EXT_REMOTE_AUTH, "remote_auth", print_auth },
{ SADB_X_EXT_LOCAL_CREDENTIALS, "local_cred", print_cred },
{ SADB_X_EXT_REMOTE_CREDENTIALS,"remote_cred", print_cred },
@@ -83,6 +108,25 @@ struct idname ext_types[] = {
{ 0, NULL, NULL }
};
+struct idname msg_types[] = {
+ { SADB_ACQUIRE, "sadb_acquire", NULL },
+ { SADB_ADD, "sadb_add", NULL },
+ { SADB_DELETE, "sadb_delete", NULL },
+ { SADB_DUMP, "sadb_dump", NULL },
+ { SADB_EXPIRE, "sadb_expire", NULL },
+ { SADB_FLUSH, "sadb_flush", NULL },
+ { SADB_GET, "sadb_get", NULL },
+ { SADB_GETSPI, "sadb_getspi", NULL },
+ { SADB_REGISTER, "sadb_register", NULL },
+ { SADB_UPDATE, "sadb_update", NULL },
+ { SADB_X_ADDFLOW, "sadb_addflow", NULL },
+ { SADB_X_ASKPOLICY, "sadb_askpolicy", NULL },
+ { SADB_X_DELFLOW, "sadb_delflow", NULL },
+ { SADB_X_GRPSPIS, "sadb_grpspis", NULL },
+ { SADB_X_PROMISC, "sadb_promisc", NULL },
+ { 0, NULL, NULL },
+};
+
struct idname sa_types[] = {
{ SADB_SATYPE_UNSPEC, "unspec", NULL },
{ SADB_SATYPE_AH, "ah", NULL },
@@ -160,6 +204,24 @@ struct idname identity_types[] = {
{ 0, NULL, NULL }
};
+struct idname flow_types[] = {
+ { SADB_X_FLOW_TYPE_USE, "use", NULL },
+ { SADB_X_FLOW_TYPE_ACQUIRE, "acquire", NULL },
+ { SADB_X_FLOW_TYPE_REQUIRE, "require", NULL },
+ { SADB_X_FLOW_TYPE_BYPASS, "bypass", NULL },
+ { SADB_X_FLOW_TYPE_DENY, "deny", NULL },
+ { SADB_X_FLOW_TYPE_DONTACQ, "dontacq", 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)
{
@@ -304,6 +366,143 @@ print_life(struct sadb_ext *ext, struct sadb_msg *msg)
life->sadb_lifetime_usetime);
}
+static void
+print_proto(struct sadb_ext *ext, struct sadb_msg *msg)
+{
+ struct sadb_protocol *proto = (struct sadb_protocol *)ext;
+
+ /* overloaded */
+ if (msg->sadb_msg_type == SADB_X_GRPSPIS)
+ printf("satype %s flags %u",
+ lookup_name(sa_types, proto->sadb_protocol_proto),
+ proto->sadb_protocol_flags);
+ else
+ printf("proto %u flags %u",
+ proto->sadb_protocol_proto, proto->sadb_protocol_flags);
+}
+
+/* ARGSUSED1 */
+static void
+print_flow(struct sadb_ext *ext, struct sadb_msg *msg)
+{
+ struct sadb_protocol *proto = (struct sadb_protocol *)ext;
+ char *dir = "unknown";
+
+ switch (proto->sadb_protocol_direction) {
+ case IPSP_DIRECTION_IN:
+ dir = "in";
+ break;
+ case IPSP_DIRECTION_OUT:
+ dir = "out";
+ break;
+ }
+ printf("type %s direction %s",
+ lookup_name(flow_types, proto->sadb_protocol_proto), dir);
+}
+
+static char *
+alg_by_ext(u_int8_t ext_type, u_int8_t id)
+{
+ switch (ext_type) {
+ case SADB_EXT_SUPPORTED_ENCRYPT:
+ return lookup_name(enc_types, id);
+ case SADB_EXT_SUPPORTED_AUTH:
+ return lookup_name(auth_types, id);
+ case SADB_X_EXT_SUPPORTED_COMP:
+ return lookup_name(comp_types, id);
+ default:
+ return "unknown";
+ }
+}
+
+static void
+print_alg(struct sadb_alg *alg, u_int8_t ext_type)
+{
+ printf("\t\t%s iv %u min %u max %u\n",
+ alg_by_ext(ext_type, alg->sadb_alg_id), alg->sadb_alg_ivlen,
+ alg->sadb_alg_minbits, alg->sadb_alg_maxbits);
+}
+
+/* ARGSUSED1 */
+static void
+print_supp(struct sadb_ext *ext, struct sadb_msg *msg)
+{
+ struct sadb_supported *supported = (struct sadb_supported *)ext;
+ struct sadb_alg *alg;
+
+ printf("\n");
+ for (alg = (struct sadb_alg *)(supported + 1);
+ (size_t)((u_int8_t *)alg - (u_int8_t *)ext) <
+ ext->sadb_ext_len * PFKEYV2_CHUNK;
+ alg++)
+ print_alg(alg, ext->sadb_ext_type);
+}
+
+/* ARGSUSED1 */
+static void
+print_comb(struct sadb_comb *comb, struct sadb_msg *msg)
+{
+ printf("\t\tauth %s min %u max %u\n"
+ "\t\tenc %s min %u max %u\n"
+ "\t\taddtime hard %llu soft %llu\n"
+ "\t\tusetime hard %llu soft %llu\n",
+ lookup_name(auth_types, comb->sadb_comb_auth),
+ comb->sadb_comb_auth_minbits,
+ comb->sadb_comb_auth_maxbits,
+ lookup_name(enc_types, comb->sadb_comb_encrypt),
+ comb->sadb_comb_encrypt_minbits,
+ comb->sadb_comb_encrypt_maxbits,
+ comb->sadb_comb_soft_addtime,
+ comb->sadb_comb_hard_addtime,
+ comb->sadb_comb_soft_usetime,
+ comb->sadb_comb_hard_usetime);
+#if 0
+ comb->sadb_comb_flags,
+ comb->sadb_comb_reserved,
+ comb->sadb_comb_soft_allocations,
+ comb->sadb_comb_hard_allocations,
+ comb->sadb_comb_soft_bytes,
+ comb->sadb_comb_hard_bytes,
+#endif
+}
+
+/* ARGSUSED1 */
+static void
+print_prop(struct sadb_ext *ext, struct sadb_msg *msg)
+{
+ struct sadb_prop *prop = (struct sadb_prop *)ext;
+ struct sadb_comb *comb;
+
+ printf("replay %u\n", prop->sadb_prop_replay);
+ for (comb = (struct sadb_comb *)(prop + 1);
+ (size_t)((u_int8_t *)comb - (u_int8_t *)ext) <
+ ext->sadb_ext_len * PFKEYV2_CHUNK;
+ comb++)
+ print_comb(comb, msg);
+}
+
+/* ARGSUSED1 */
+static void
+print_sens(struct sadb_ext *ext, struct sadb_msg *msg)
+{
+ struct sadb_sens *sens = (struct sadb_sens *)ext;
+
+ printf("dpd %u sens_level %u integ_level %u\n",
+ sens->sadb_sens_dpd,
+ sens->sadb_sens_sens_level,
+ sens->sadb_sens_integ_level);
+}
+
+/* ARGSUSED1 */
+static void
+print_spir(struct sadb_ext *ext, struct sadb_msg *msg)
+{
+ struct sadb_spirange *spirange = (struct sadb_spirange *)ext;
+
+ printf("min 0x%8.8x max 0x%8.8x\n",
+ spirange->sadb_spirange_min, spirange->sadb_spirange_max);
+}
+
/* ARGSUSED1 */
static void
print_ident(struct sadb_ext *ext, struct sadb_msg *msg)
@@ -336,6 +535,15 @@ print_cred(struct sadb_ext *ext, struct sadb_msg *msg)
/* ARGSUSED1 */
static void
+print_policy(struct sadb_ext *ext, struct sadb_msg *msg)
+{
+ struct sadb_x_policy *x_policy = (struct sadb_x_policy *)ext;
+
+ printf("seq %u\n", x_policy->sadb_x_policy_seq);
+}
+
+/* ARGSUSED1 */
+static void
print_udpenc(struct sadb_ext *ext, struct sadb_msg *msg)
{
struct sadb_x_udpencap *x_udpencap = (struct sadb_x_udpencap *)ext;
@@ -343,24 +551,111 @@ print_udpenc(struct sadb_ext *ext, struct sadb_msg *msg)
printf("udpencap port %u\n", ntohs(x_udpencap->sadb_x_udpencap_port));
}
-void
-pfkey_print_sa(struct sadb_msg *msg, int opts)
+static void
+setup_extensions(struct sadb_msg *msg)
{
struct sadb_ext *ext;
- int i;
bzero(extensions, sizeof(extensions));
-
- printf("%s ", lookup_name(sa_types, msg->sadb_msg_satype));
+ if (msg->sadb_msg_len == 0)
+ return;
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))
extensions[ext->sadb_ext_type] = ext;
+}
+
+void
+pfkey_print_sa(struct sadb_msg *msg, int opts)
+{
+ int i;
+
+ setup_extensions(msg);
+ printf("%s ", lookup_name(sa_types, msg->sadb_msg_satype));
for (i = 0; i < SADB_EXT_MAX; i++)
if (extensions[i])
print_ext(extensions[i], msg, opts);
fflush(stdout);
}
+
+static void
+monitor_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\n",
+ ntohl(sa->sadb_sa_spi),
+ lookup_name(comp_types, sa->sadb_sa_encrypt));
+ else
+ printf("spi 0x%8.8x auth %s enc %s\n",
+ ntohl(sa->sadb_sa_spi),
+ lookup_name(auth_types, sa->sadb_sa_auth),
+ lookup_name(enc_types, sa->sadb_sa_encrypt));
+ printf("\t\tstate %s replay %u flags %u",
+ lookup_name(states, sa->sadb_sa_state),
+ sa->sadb_sa_replay, sa->sadb_sa_flags);
+}
+
+static void
+monitor_ext(struct sadb_ext *ext, struct sadb_msg *msg)
+{
+ 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;
+ }
+ printf("\t%s: ", entry->name);
+ if (entry->func == print_sa)
+ monitor_sa(ext, msg);
+ else if (entry->func != NULL)
+ (*entry->func)(ext, msg);
+ else
+ printf("type %u len %u",
+ ext->sadb_ext_type, ext->sadb_ext_len);
+ printf("\n");
+}
+
+/* ARGSUSED1 */
+void
+pfkey_monitor_sa(struct sadb_msg *msg, int opts)
+{
+ int i;
+
+ setup_extensions(msg);
+
+ printf("%s: satype %s vers %u len %u seq %u pid %u\n",
+ lookup_name(msg_types, msg->sadb_msg_type),
+ lookup_name(sa_types, msg->sadb_msg_satype),
+ msg->sadb_msg_version, msg->sadb_msg_len,
+ msg->sadb_msg_seq,
+ msg->sadb_msg_pid);
+ if (msg->sadb_msg_errno)
+ printf("\terrno %u: %s\n", msg->sadb_msg_errno,
+ strerror(msg->sadb_msg_errno));
+ for (i = 0; i < SADB_EXT_MAX; i++)
+ if (extensions[i])
+ monitor_ext(extensions[i], msg);
+ fflush(stdout);
+}
+
+void
+pfkey_print_raw(u_int8_t *data, ssize_t len)
+{
+ int i;
+ const u_int8_t *sp = (const u_int8_t *)data;
+
+ printf("RAW PFKEYV2 MESSAGE:\n");
+ for(i = 0; i < len; i++) {
+ if ((i % 8 == 0) && (i != 0))
+ printf("\n");
+ printf("%02x ", *sp);
+ sp++;
+ }
+ printf("\n");
+}
diff --git a/sbin/ipsecctl/pfkey.c b/sbin/ipsecctl/pfkey.c
index a72dc748299..e3b620ff07f 100644
--- a/sbin/ipsecctl/pfkey.c
+++ b/sbin/ipsecctl/pfkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkey.c,v 1.38 2006/05/28 21:08:42 hshoexer Exp $ */
+/* $OpenBSD: pfkey.c,v 1.39 2006/05/30 21:56:05 msf Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
* Copyright (c) 2003, 2004 Markus Friedl <markus@openbsd.org>
@@ -49,7 +49,7 @@ static int pfkey_sa(int, u_int8_t, u_int8_t, u_int32_t,
struct ipsec_addr_wrap *, struct ipsec_addr_wrap *,
struct ipsec_transforms *, struct ipsec_key *,
struct ipsec_key *, u_int8_t);
-static int pfkey_reply(int);
+static int pfkey_reply(int, u_int8_t **, ssize_t *);
int pfkey_parse(struct sadb_msg *, struct ipsec_rule *);
int pfkey_ipsec_flush(void);
int pfkey_ipsec_establish(int, struct ipsec_rule *);
@@ -598,7 +598,7 @@ pfkey_sa(int sd, u_int8_t satype, u_int8_t action, u_int32_t spi,
}
static int
-pfkey_reply(int sd)
+pfkey_reply(int sd, u_int8_t **datap, ssize_t *lenp)
{
struct sadb_msg hdr;
ssize_t len;
@@ -608,7 +608,7 @@ pfkey_reply(int sd)
warnx("short read");
return -1;
}
- if (hdr.sadb_msg_errno != 0) {
+ if (datap == NULL && hdr.sadb_msg_errno != 0) {
errno = hdr.sadb_msg_errno;
warn("PF_KEY failed");
return -1;
@@ -622,8 +622,14 @@ pfkey_reply(int sd)
free(data);
return -1;
}
- bzero(data, len);
- free(data);
+ if (datap) {
+ *datap = data;
+ if (lenp)
+ *lenp = len;
+ } else {
+ bzero(data, len);
+ free(data);
+ }
return 0;
}
@@ -1010,7 +1016,7 @@ pfkey_ipsec_establish(int action, struct ipsec_rule *r)
if (ret < 0)
return -1;
- if (pfkey_reply(fd) < 0)
+ if (pfkey_reply(fd, NULL, NULL) < 0)
return -1;
return 0;
@@ -1047,9 +1053,78 @@ pfkey_ipsec_flush(void)
warnx("short write");
return -1;
}
- if (pfkey_reply(fd) < 0)
+ if (pfkey_reply(fd, NULL, NULL) < 0)
+ return -1;
+
+ return 0;
+}
+
+static int
+pfkey_promisc(void)
+{
+ struct sadb_msg msg;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.sadb_msg_version = PF_KEY_V2;
+ msg.sadb_msg_seq = sadb_msg_seq++;
+ msg.sadb_msg_pid = getpid();
+ msg.sadb_msg_len = sizeof(msg) / PFKEYV2_CHUNK;
+ msg.sadb_msg_type = SADB_X_PROMISC;
+ msg.sadb_msg_satype = 1; /* enable */
+ if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
+ warn("pfkey_promisc: write failed");
+ return -1;
+ }
+ if (pfkey_reply(fd, NULL, NULL) < 0)
+ return -1;
+ return 0;
+}
+
+int
+pfkey_monitor(int opts)
+{
+ fd_set *rset;
+ u_int8_t *data;
+ struct sadb_msg *msg;
+ ssize_t len, set_size;
+ int n;
+
+ if (pfkey_init() < 0)
+ return -1;
+ if (pfkey_promisc() < 0)
return -1;
+ set_size = howmany(fd + 1, NFDBITS) * sizeof(fd_mask);
+ if ((rset = malloc(set_size)) == NULL) {
+ warn("malloc");
+ return -1;
+ }
+ for (;;) {
+ memset(rset, 0, set_size);
+ FD_SET(fd, rset);
+ if ((n = select(fd+1, rset, NULL, NULL, NULL)) < 0)
+ err(2, "select");
+ if (n == 0)
+ break;
+ if (!FD_ISSET(fd, rset))
+ continue;
+ if (pfkey_reply(fd, &data, &len) < 0)
+ continue;
+ msg = (struct sadb_msg *)data;
+ if (msg->sadb_msg_type == SADB_X_PROMISC) {
+ /* remove extra header from promisc messages */
+ if ((msg->sadb_msg_len * PFKEYV2_CHUNK) >=
+ 2 * sizeof(struct sadb_msg)) {
+ msg++;
+ }
+ }
+ pfkey_monitor_sa(msg, opts);
+ if (opts & IPSECCTL_OPT_VERBOSE)
+ pfkey_print_raw(data, len);
+ memset(data, 0, len);
+ free(data);
+ }
+ close(fd);
return 0;
}
diff --git a/sbin/ipsecctl/pfkey.h b/sbin/ipsecctl/pfkey.h
index 8ff8bd16ad8..e4a46654a30 100644
--- a/sbin/ipsecctl/pfkey.h
+++ b/sbin/ipsecctl/pfkey.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkey.h,v 1.4 2005/08/22 17:26:46 hshoexer Exp $ */
+/* $OpenBSD: pfkey.h,v 1.5 2006/05/30 21:56:05 msf Exp $ */
/*
* Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org>
*
@@ -22,8 +22,11 @@
int pfkey_parse(struct sadb_msg *, struct ipsec_rule *);
void pfkey_print_sa(struct sadb_msg *, int);
+void pfkey_monitor_sa(struct sadb_msg *, int);
+void pfkey_print_raw(u_int8_t *, ssize_t);
int pfkey_ipsec_establish(int, struct ipsec_rule *);
int pfkey_ipsec_flush(void);
int pfkey_init(void);
+int pfkey_monitor(int);
#endif /* _PFKEY_H_ */