summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorBob Beck <beck@cvs.openbsd.org>2001-07-03 03:34:43 +0000
committerBob Beck <beck@cvs.openbsd.org>2001-07-03 03:34:43 +0000
commitcb0964c5669b8b278225fca7a9e10e6a92e0c68c (patch)
treefa92eb6f8a4e62d83d3d507a7ea24d04da47febf /sys
parent7de1a6cacc8f5a738dfb30ded1dfcfca88433690 (diff)
add DIOCNATLOOK ioctl and pf_natlook structure, this enables a userland
process recieving rdr'ed connections to look up the original destination of the connection before it was redirected - this enables the writing of transparent proxies.
Diffstat (limited to 'sys')
-rw-r--r--sys/net/pf.c45
-rw-r--r--sys/net/pfvar.h17
2 files changed, 60 insertions, 2 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 3e27052b301..944a4af3b0a 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.95 2001/07/02 19:19:49 provos Exp $ */
+/* $OpenBSD: pf.c,v 1.96 2001/07/03 03:34:41 beck Exp $ */
/*
* Copyright (c) 2001, Daniel Hartmeier
@@ -1136,7 +1136,50 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
pf_status.states = states;
break;
}
+ case DIOCNATLOOK: {
+ struct pf_natlook *pnl = (struct pf_natlook *)addr;
+ struct pf_state *st;
+ struct pf_tree_key key;
+ int direction;
+
+ direction = pnl->direction;
+ key.proto = pnl->proto;
+ /* userland gives us source and dest of connetion, reverse
+ * the lookup so we ask for what happens with the return
+ * traffic, enabling us to find it in the state tree.
+ */
+ key.addr[1].s_addr = pnl->saddr;
+ key.port[1] = pnl->sport;
+ key.addr[0].s_addr = pnl->daddr;
+ key.port[0] = pnl->dport;
+
+ if (!pnl->proto || !pnl->saddr || !pnl->daddr
+ || !pnl->dport || !pnl->sport)
+ error = EINVAL;
+ else {
+ s = splsoftnet();
+ st = pf_find_state((direction == PF_IN) ?
+ tree_ext_gwy : tree_lan_ext, &key);
+ if (st != NULL) {
+ if (direction == PF_IN) {
+ pnl->rsaddr = st->lan.addr;
+ pnl->rsport = st->lan.port;
+ pnl->rdaddr = pnl->daddr;
+ pnl->rdport = pnl->dport;
+ }
+ else {
+ pnl->rdaddr = st->gwy.addr;
+ pnl->rdport = st->gwy.port;
+ pnl->rsaddr = pnl->saddr;
+ pnl->rsport = pnl->sport;
+ }
+ } else
+ error = ENOENT;
+ splx(s);
+ }
+ break;
+ }
default:
error = ENODEV;
break;
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index a60d86fd6ae..f5fb7a1f478 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.28 2001/07/01 23:04:44 dhartmei Exp $ */
+/* $OpenBSD: pfvar.h,v 1.29 2001/07/03 03:34:42 beck Exp $ */
/*
* Copyright (c) 2001, Daniel Hartmeier
@@ -103,6 +103,20 @@ struct pf_state {
u_int8_t log;
};
+struct pf_natlook {
+ u_int32_t saddr;
+ u_int32_t daddr;
+ u_int32_t rsaddr;
+ u_int32_t rdaddr;
+ u_int16_t sport;
+ u_int16_t dport;
+ u_int16_t rsport;
+ u_int16_t rdport;
+ u_int8_t proto;
+ u_int8_t direction;
+};
+
+
struct pf_nat {
char ifname[IFNAMSIZ];
struct ifnet *ifp;
@@ -231,6 +245,7 @@ struct pfioc_if {
#define DIOCSETSTATUSIF _IOWR('D', 20, struct pfioc_if)
#define DIOCGETSTATUS _IOWR('D', 21, struct pf_status)
#define DIOCCLRSTATUS _IO ('D', 22)
+#define DIOCNATLOOK _IOWR('D', 23, struct pf_natlook)
#ifdef _KERNEL