summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/ipsecadm/pfkdump.c37
-rw-r--r--sys/net/pfkey.c3
-rw-r--r--sys/net/pfkeyv2.c111
-rw-r--r--sys/net/pfkeyv2.h7
4 files changed, 148 insertions, 10 deletions
diff --git a/sbin/ipsecadm/pfkdump.c b/sbin/ipsecadm/pfkdump.c
index 7222fa39491..8b74062fd8b 100644
--- a/sbin/ipsecadm/pfkdump.c
+++ b/sbin/ipsecadm/pfkdump.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkdump.c,v 1.14 2004/10/08 05:59:55 ho Exp $ */
+/* $OpenBSD: pfkdump.c,v 1.15 2004/11/26 18:02:22 markus Exp $ */
/*
* Copyright (c) 2003 Markus Friedl. All rights reserved.
@@ -23,10 +23,11 @@
* (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/types.h>
+#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>
@@ -635,5 +636,35 @@ ipsecadm_monitor(void)
void
ipsecadm_show(u_int8_t satype)
{
- do_pfkey(0, satype);
+ struct sadb_msg *msg;
+ int mib[5];
+ size_t need;
+ 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] = satype;
+
+ /*
+ * Dump the SADB using sysctl(3), but fall back to the pfkey
+ * socket if sysctl fails.
+ */
+ if (sysctl(mib, 5, NULL, &need, NULL, 0) == -1)
+ do_pfkey(0, satype);
+ if (need == 0)
+ 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 * PFKEY2_CHUNK) {
+ msg = (struct sadb_msg *)next;
+ if (msg->sadb_msg_len == 0)
+ break;
+ print_msg(msg, 0);
+ }
}
diff --git a/sys/net/pfkey.c b/sys/net/pfkey.c
index 03906b349c6..a6dcf60db03 100644
--- a/sys/net/pfkey.c
+++ b/sys/net/pfkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkey.c,v 1.15 2004/08/03 12:10:48 todd Exp $ */
+/* $OpenBSD: pfkey.c,v 1.16 2004/11/26 18:02:22 markus Exp $ */
/*
* @(#)COPYRIGHT 1.1 (NRL) 17 January 1995
@@ -321,6 +321,7 @@ pfkey_buildprotosw(void)
bcopy(&pfkey_protosw_template, p,
sizeof(struct protosw));
p->pr_protocol = pfkey_versions[i]->protocol;
+ p->pr_sysctl = pfkey_versions[i]->sysctl;
p++;
}
diff --git a/sys/net/pfkeyv2.c b/sys/net/pfkeyv2.c
index 136d75c7994..1e6b8a75395 100644
--- a/sys/net/pfkeyv2.c
+++ b/sys/net/pfkeyv2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkeyv2.c,v 1.93 2004/11/19 10:11:52 hshoexer Exp $ */
+/* $OpenBSD: pfkeyv2.c,v 1.94 2004/11/26 18:02:22 markus Exp $ */
/*
* @(#)COPYRIGHT 1.1 (NRL) 17 January 1995
@@ -493,7 +493,7 @@ ret:
* Get all the information contained in an SA to a PFKEYV2 message.
*/
int
-pfkeyv2_get(struct tdb *sa, void **headers, void **buffer)
+pfkeyv2_get(struct tdb *sa, void **headers, void **buffer, int *lenp)
{
int rval, i;
void *p;
@@ -550,6 +550,14 @@ pfkeyv2_get(struct tdb *sa, void **headers, void **buffer)
if (sa->tdb_udpencap_port)
i+= sizeof(struct sadb_x_udpencap);
+ if (lenp)
+ *lenp = i;
+
+ if (buffer == NULL) {
+ rval = 0;
+ goto ret;
+ }
+
if (!(p = malloc(i, M_PFKEY, M_DONTWAIT))) {
rval = ENOMEM;
goto ret;
@@ -674,7 +682,7 @@ pfkeyv2_dump_walker(struct tdb *sa, void *state, int last)
headers[0] = (void *) dump_state->sadb_msg;
/* Get the information from the TDB to a PFKEYv2 message */
- if ((rval = pfkeyv2_get(sa, headers, &buffer)) != 0)
+ if ((rval = pfkeyv2_get(sa, headers, &buffer, NULL)) != 0)
return (rval);
if (last)
@@ -1229,7 +1237,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
goto splxret;
}
- rval = pfkeyv2_get(sa2, headers, &freeme);
+ rval = pfkeyv2_get(sa2, headers, &freeme, NULL);
if (rval)
mode = PFKEYV2_SENDMESSAGE_UNICAST;
@@ -2131,6 +2139,100 @@ pfkeyv2_expire(struct tdb *sa, u_int16_t type)
return (rval);
}
+struct pfkeyv2_sysctl_walk {
+ void *w_where;
+ size_t w_len;
+ int w_op;
+ u_int8_t w_satype;
+};
+
+int
+pfkeyv2_sysctl_walker(struct tdb *sa, void *arg, int last)
+{
+ struct pfkeyv2_sysctl_walk *w = (struct pfkeyv2_sysctl_walk *)arg;
+ void *buffer = NULL;
+ int error = 0;
+ int buflen, i;
+
+ if (w->w_satype != SADB_SATYPE_UNSPEC &&
+ w->w_satype != sa->tdb_satype)
+ return (0);
+
+ if (w->w_where) {
+ void *headers[SADB_EXT_MAX+1];
+ struct sadb_msg msg;
+
+ bzero(headers, sizeof(headers));
+ if ((error = pfkeyv2_get(sa, headers, &buffer, &buflen)) != 0)
+ goto done;
+ if (w->w_len < sizeof(msg) + buflen) {
+ error = ENOMEM;
+ goto done;
+ }
+ /* prepend header */
+ msg.sadb_msg_version = PF_KEY_V2;
+ msg.sadb_msg_pid = 0;
+ msg.sadb_msg_seq = 0;
+ msg.sadb_msg_satype = sa->tdb_satype;
+ msg.sadb_msg_type = SADB_DUMP;
+ msg.sadb_msg_len = (sizeof(msg) + buflen) / sizeof(uint64_t);
+ if ((error = copyout(&msg, w->w_where, sizeof(msg))) != 0)
+ goto done;
+ w->w_where += sizeof(msg);
+ w->w_len -= sizeof(msg);
+ /* set extension type */
+ for (i = 1; i <= SADB_EXT_MAX; i++)
+ if (headers[i])
+ ((struct sadb_ext *)
+ headers[i])->sadb_ext_type = i;
+ if ((error = copyout(buffer, w->w_where, buflen)) != 0)
+ goto done;
+ w->w_where += buflen;
+ w->w_len -= buflen;
+ } else {
+ if ((error = pfkeyv2_get(sa, NULL, NULL, &buflen)) != 0)
+ return (error);
+ w->w_len += buflen;
+ w->w_len += sizeof(struct sadb_msg);
+ }
+
+done:
+ if (buffer)
+ free(buffer, M_PFKEY);
+ return (error);
+}
+
+int
+pfkeyv2_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
+ void *new, size_t newlen)
+{
+ struct pfkeyv2_sysctl_walk w;
+ int s, error = EINVAL;
+
+ if (new)
+ return (EPERM);
+ if (namelen < 1)
+ return (EINVAL);
+ w.w_op = name[0];
+ w.w_satype = name[1];
+ w.w_where = oldp;
+ w.w_len = oldp ? *oldlenp : 0;
+
+ switch(w.w_op) {
+ case NET_KEY_SADB_DUMP:
+ if ((error = suser(curproc, 0)) != 0)
+ return (error);
+ s = spltdb();
+ error = tdb_walk(pfkeyv2_sysctl_walker, &w);
+ splx(s);
+ if (oldp)
+ *oldlenp = w.w_where - oldp;
+ else
+ *oldlenp = w.w_len;
+ }
+ return (error);
+}
+
int
pfkeyv2_init(void)
{
@@ -2141,6 +2243,7 @@ pfkeyv2_init(void)
pfkeyv2_version.create = &pfkeyv2_create;
pfkeyv2_version.release = &pfkeyv2_release;
pfkeyv2_version.send = &pfkeyv2_send;
+ pfkeyv2_version.sysctl = &pfkeyv2_sysctl;
rval = pfkey_register(&pfkeyv2_version);
return (rval);
diff --git a/sys/net/pfkeyv2.h b/sys/net/pfkeyv2.h
index 824a7c4647f..f7d3c7fd99a 100644
--- a/sys/net/pfkeyv2.h
+++ b/sys/net/pfkeyv2.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkeyv2.h,v 1.51 2004/08/10 16:17:05 ho Exp $ */
+/* $OpenBSD: pfkeyv2.h,v 1.52 2004/11/26 18:02:22 markus Exp $ */
/*
* @(#)COPYRIGHT 1.1 (NRL) January 1998
*
@@ -386,6 +386,7 @@ struct pfkey_version
int (*create)(struct socket *socket);
int (*release)(struct socket *socket);
int (*send)(struct socket *socket, void *message, int len);
+ int (*sysctl)(int *, u_int, void *, size_t *, void *, size_t);
};
struct pfkeyv2_socket
@@ -415,7 +416,7 @@ int pfkey_unregister(struct pfkey_version *version);
int pfkey_sendup(struct socket *socket, struct mbuf *packet, int more);
int pfkeyv2_create(struct socket *);
-int pfkeyv2_get(struct tdb *, void **, void **);
+int pfkeyv2_get(struct tdb *, void **, void **, int *);
int pfkeyv2_policy(struct ipsec_acquire *, void **, void **);
int pfkeyv2_release(struct socket *);
int pfkeyv2_send(struct socket *, void *, int);
@@ -423,6 +424,8 @@ int pfkeyv2_sendmessage(void **, int, struct socket *, u_int8_t, int);
int pfkeyv2_dump_walker(struct tdb *, void *, int);
int pfkeyv2_flush_walker(struct tdb *, void *, int);
int pfkeyv2_get_proto_alg(u_int8_t, u_int8_t *, int *);
+int pfkeyv2_sysctl(int *, u_int, void *, size_t *, void *, size_t);
+int pfkeyv2_sysctl_walker(struct tdb *, void *, int);
int pfdatatopacket(void *, int, struct mbuf **);