summaryrefslogtreecommitdiffstats
path: root/sbin/ipfw
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>1998-07-06 03:20:19 +0000
committerjulian <julian@FreeBSD.org>1998-07-06 03:20:19 +0000
commit22a5d80812f1c709917ff24ff791b1f952f8d6f7 (patch)
treebcc03ee3bb48fe95754fcda4fea765a7925f1343 /sbin/ipfw
parent04d286f6479d77492b97067c0d09e9c982b707c0 (diff)
downloadFreeBSD-src-22a5d80812f1c709917ff24ff791b1f952f8d6f7.zip
FreeBSD-src-22a5d80812f1c709917ff24ff791b1f952f8d6f7.tar.gz
Support for IPFW based transparent forwarding.
Any packet that can be matched by a ipfw rule can be redirected transparently to another port or machine. Redirection to another port mostly makes sense with tcp, where a session can be set up between a proxy and an unsuspecting client. Redirection to another machine requires that the other machine also be expecting to receive the forwarded packets, as their headers will not have been modified. /sbin/ipfw must be recompiled!!! Reviewed by: Peter Wemm <peter@freebsd.org> Submitted by: Chrisy Luke <chrisy@flix.net>
Diffstat (limited to 'sbin/ipfw')
-rw-r--r--sbin/ipfw/ipfw.826
-rw-r--r--sbin/ipfw/ipfw.c33
2 files changed, 56 insertions, 3 deletions
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
index fe29f08..f86f691 100644
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -195,7 +195,31 @@ Send a copy of packets matching this rule to the
.Xr divert 4
socket bound to port
.Ar port .
-The search continues with the next rule.
+The search continues with the next rule. This feature is not yet implemeted.
+.It Ar fwd ipaddr Op ,port
+Change the next-hop on matching packets to
+.Ar ipaddr ,
+which can be an IP address in dotted quad or a host name.
+If
+.Ar ipaddr
+is not a directly-reachable address, the route
+as found in the local routing table for that IP is used
+instead.
+If
+.Ar ipaddr
+is a local address, then on a packet entering the system from a remote
+host it will be diverted to
+.Ar port
+on the local machine, keeping the local address of the socket set
+to the original IP address the packet was destined for. This is intended
+for use with transparent proxy servers. If the IP is not
+a local address then the port number (if specified) is ignored and
+the rule only applies to packets leaving the system. This will
+also map addresses to local ports when packets are generated locally.
+The search terminates if this rule matches. If the port number is not
+given then the port number in the packet is used, so that a packet for
+an external machine port Y would be forwarded to local port Y. The kernel
+must have been compiled with optiions IPFIREWALL_FORWARD.
.It Ar skipto number
Skip all subsequent rules numbered less than
.Ar number .
diff --git a/sbin/ipfw/ipfw.c b/sbin/ipfw/ipfw.c
index 6e9a686..4f16279 100644
--- a/sbin/ipfw/ipfw.c
+++ b/sbin/ipfw/ipfw.c
@@ -16,7 +16,7 @@
*
* NEW command line interface for IP firewall facility
*
- * $Id: ipfw.c,v 1.56 1998/04/22 06:20:20 phk Exp $
+ * $Id: ipfw.c,v 1.57 1998/05/15 12:38:07 danny Exp $
*
*/
@@ -224,6 +224,11 @@ show_ipfw(struct ip_fw *chain, int pcwidth, int bcwidth)
print_reject_code(chain->fw_reject_code);
}
break;
+ case IP_FW_F_FWD:
+ printf("fwd %s", inet_ntoa(chain->fw_fwd_ip.sin_addr));
+ if(chain->fw_fwd_ip.sin_port)
+ printf(",%d", chain->fw_fwd_ip.sin_port);
+ break;
default:
errx(EX_OSERR, "impossible");
}
@@ -497,7 +502,7 @@ show_usage(const char *fmt, ...)
" rule: action proto src dst extras...\n"
" action:\n"
" {allow|permit|accept|pass|deny|drop|reject|unreach code|\n"
-" reset|count|skipto num|divert port|tee port} [log]\n"
+" reset|count|skipto num|divert port|tee port|fwd ip} [log]\n"
" proto: {ip|tcp|udp|icmp|<number>}\n"
" src: from [not] {any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n"
" dst: to [not] {any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n"
@@ -896,6 +901,30 @@ add(ac,av)
else
show_usage("illegal divert port");
}
+ } else if (!strncmp(*av,"fwd",strlen(*av)) ||
+ !strncmp(*av,"forward",strlen(*av))) {
+ struct in_addr dummyip;
+ char *pp;
+ rule.fw_flg |= IP_FW_F_FWD; av++; ac--;
+ if (!ac)
+ show_usage("missing forwarding IP address");
+ rule.fw_fwd_ip.sin_len = sizeof(struct sockaddr_in);
+ rule.fw_fwd_ip.sin_family = AF_INET;
+ rule.fw_fwd_ip.sin_port = 0;
+ pp = strchr(*av, ':');
+ if(pp == NULL)
+ pp = strchr(*av, ',');
+ if(pp != NULL)
+ {
+ *(pp++) = '\0';
+ rule.fw_fwd_ip.sin_port = lookup_port(pp, 1, 1);
+ if(rule.fw_fwd_ip.sin_port == (unsigned int)-1)
+ show_usage("illegal forwarding port");
+ }
+ fill_ip(&(rule.fw_fwd_ip.sin_addr), &dummyip, &ac, &av);
+ if (rule.fw_fwd_ip.sin_addr.s_addr == 0)
+ show_usage("illegal forwarding IP address");
+
} else if (!strncmp(*av,"skipto",strlen(*av))) {
rule.fw_flg |= IP_FW_F_SKIPTO; av++; ac--;
if (!ac)
OpenPOWER on IntegriCloud