diff options
author | julian <julian@FreeBSD.org> | 1998-07-06 03:20:19 +0000 |
---|---|---|
committer | julian <julian@FreeBSD.org> | 1998-07-06 03:20:19 +0000 |
commit | 22a5d80812f1c709917ff24ff791b1f952f8d6f7 (patch) | |
tree | bcc03ee3bb48fe95754fcda4fea765a7925f1343 /sbin/ipfw | |
parent | 04d286f6479d77492b97067c0d09e9c982b707c0 (diff) | |
download | FreeBSD-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.8 | 26 | ||||
-rw-r--r-- | sbin/ipfw/ipfw.c | 33 |
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) |