summaryrefslogtreecommitdiffstats
path: root/usr.sbin/hoststated/pfe_filter.c
diff options
context:
space:
mode:
authorreyk <reyk@openbsd.org>2007-02-22 03:32:39 +0000
committerreyk <reyk@openbsd.org>2007-02-22 03:32:39 +0000
commit2edd718bd68a9c827be137ebb51a319071210c69 (patch)
tree8c1c5b888f71aa148d70db79b9527a623ad5e0be /usr.sbin/hoststated/pfe_filter.c
parentExpand description. (diff)
downloadwireguard-openbsd-2edd718bd68a9c827be137ebb51a319071210c69.tar.xz
wireguard-openbsd-2edd718bd68a9c827be137ebb51a319071210c69.zip
Add layer 7 functionality to hoststated used for layer 7
loadbalancing, SSL acceleration, general-purpose TCP relaying, and transparent proxying. see hoststated.conf(5) and my upcoming article on undeadly.org for details. ok to commit deraadt@ pyr@
Diffstat (limited to 'usr.sbin/hoststated/pfe_filter.c')
-rw-r--r--usr.sbin/hoststated/pfe_filter.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/usr.sbin/hoststated/pfe_filter.c b/usr.sbin/hoststated/pfe_filter.c
index 25e3ec43cec..27442c34006 100644
--- a/usr.sbin/hoststated/pfe_filter.c
+++ b/usr.sbin/hoststated/pfe_filter.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfe_filter.c,v 1.13 2007/02/20 04:06:17 reyk Exp $ */
+/* $OpenBSD: pfe_filter.c,v 1.14 2007/02/22 03:32:40 reyk Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -402,3 +402,75 @@ flush_rulesets(struct hoststated *env)
toolong:
fatal("flush_rulesets: name too long");
}
+
+int
+natlook(struct hoststated *env, struct ctl_natlook *cnl)
+{
+ struct pfioc_natlook pnl;
+ struct sockaddr_in *in, *out;
+ struct sockaddr_in6 *in6, *out6;
+ char ibuf[BUFSIZ], obuf[BUFSIZ];
+
+ bzero(&pnl, sizeof(pnl));
+
+ if ((pnl.af = cnl->src.ss_family) != cnl->dst.ss_family)
+ fatalx("natlook: illegal address families");
+ switch (pnl.af) {
+ case AF_INET:
+ in = (struct sockaddr_in *)&cnl->src;
+ out = (struct sockaddr_in *)&cnl->dst;
+ bcopy(&in->sin_addr, &pnl.saddr.addr8, in->sin_len);
+ pnl.sport = in->sin_port;
+ bcopy(&out->sin_addr, &pnl.daddr.addr8, out->sin_len);
+ pnl.dport = out->sin_port;
+ break;
+ case AF_INET6:
+ in6 = (struct sockaddr_in6 *)&cnl->src;
+ out6 = (struct sockaddr_in6 *)&cnl->dst;
+ bcopy(&in6->sin6_addr, &pnl.saddr.addr8, in6->sin6_len);
+ pnl.sport = in6->sin6_port;
+ bcopy(&out6->sin6_addr, &pnl.daddr.addr8, out6->sin6_len);
+ pnl.dport = out6->sin6_port;
+ }
+ pnl.proto = IPPROTO_TCP;
+ pnl.direction = PF_IN;
+ cnl->in = 1;
+
+ if (ioctl(env->pf->dev, DIOCNATLOOK, &pnl) == -1) {
+ pnl.direction = PF_OUT;
+ cnl->in = 0;
+ if (ioctl(env->pf->dev, DIOCNATLOOK, &pnl) == -1) {
+ log_debug("natlook: error");
+ return (-1);
+ }
+ }
+
+ inet_ntop(pnl.af, &pnl.rsaddr, ibuf, sizeof(ibuf));
+ inet_ntop(pnl.af, &pnl.rdaddr, obuf, sizeof(obuf));
+ log_debug("natlook: %s %s:%d -> %s:%d",
+ pnl.direction == PF_IN ? "in" : "out",
+ ibuf, ntohs(pnl.rsport), obuf, ntohs(pnl.rdport));
+
+ switch (pnl.af) {
+ case AF_INET:
+ in = (struct sockaddr_in *)&cnl->rsrc;
+ out = (struct sockaddr_in *)&cnl->rdst;
+ bcopy(&pnl.rsaddr.addr8, &in->sin_addr, sizeof(in->sin_addr));
+ in->sin_port = pnl.rsport;
+ bcopy(&pnl.rdaddr.addr8, &out->sin_addr, sizeof(out->sin_addr));
+ out->sin_port = pnl.rdport;
+ break;
+ case AF_INET6:
+ in6 = (struct sockaddr_in6 *)&cnl->rsrc;
+ out6 = (struct sockaddr_in6 *)&cnl->rdst;
+ bcopy(&pnl.rsaddr.addr8, &in6->sin6_addr, sizeof(in6->sin6_addr));
+ bcopy(&pnl.rdaddr.addr8, &out6->sin6_addr, sizeof(out6->sin6_addr));
+ break;
+ }
+ cnl->rsrc.ss_family = pnl.af;
+ cnl->rdst.ss_family = pnl.af;
+ cnl->rsport = pnl.rsport;
+ cnl->rdport = pnl.rdport;
+
+ return (0);
+}