diff options
-rw-r--r-- | sbin/ipsecadm/pfkdump.c | 37 | ||||
-rw-r--r-- | sys/net/pfkey.c | 3 | ||||
-rw-r--r-- | sys/net/pfkeyv2.c | 111 | ||||
-rw-r--r-- | sys/net/pfkeyv2.h | 7 |
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 **); |