diff options
author | Bob Beck <beck@cvs.openbsd.org> | 2001-07-03 03:34:43 +0000 |
---|---|---|
committer | Bob Beck <beck@cvs.openbsd.org> | 2001-07-03 03:34:43 +0000 |
commit | cb0964c5669b8b278225fca7a9e10e6a92e0c68c (patch) | |
tree | fa92eb6f8a4e62d83d3d507a7ea24d04da47febf /sys/net | |
parent | 7de1a6cacc8f5a738dfb30ded1dfcfca88433690 (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')
-rw-r--r-- | sys/net/pf.c | 45 | ||||
-rw-r--r-- | sys/net/pfvar.h | 17 |
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 |