summaryrefslogtreecommitdiff
path: root/sys/net/pf.c
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/net/pf.c
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/net/pf.c')
-rw-r--r--sys/net/pf.c45
1 files changed, 44 insertions, 1 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;