summaryrefslogtreecommitdiffstats
path: root/etc
diff options
context:
space:
mode:
Diffstat (limited to 'etc')
-rw-r--r--etc/inc/filter.inc95
1 files changed, 77 insertions, 18 deletions
diff --git a/etc/inc/filter.inc b/etc/inc/filter.inc
index 472be3e..bac63d7 100644
--- a/etc/inc/filter.inc
+++ b/etc/inc/filter.inc
@@ -1052,10 +1052,13 @@ function filter_generate_reflection_nat($rule, &$route_table, $nat_ifs, $protoco
}
}
+ if(!empty($natrules))
+ $natrules .= "\n";
+
return $natrules;
}
-function filter_generate_reflection($rule, $nordr, $rdr_ifs, $srcaddr, $dstaddr_port, &$starting_localhost_port, &$reflection_txt) {
+function filter_generate_reflection_proxy($rule, $nordr, $rdr_ifs, $srcaddr, $dstaddr_port, &$starting_localhost_port, &$reflection_txt) {
global $FilterIflist, $config;
// Initialize natrules holder string
@@ -1676,10 +1679,27 @@ function filter_nat_rules_generate() {
continue; /* unresolvable alias */
}
+ if(is_alias($rule['target']))
+ $target_ip = filter_expand_alias($rule['target']);
+ else if(is_ipaddr($rule['target']))
+ $target_ip = $rule['target'];
+ else if(is_ipaddr($FilterIflist[$rule['target']]['ip']))
+ $target_ip = $FilterIflist[$rule['target']]['ip'];
+ else
+ $target_ip = $rule['target'];
+ $target_ip = trim($target_ip);
+
if($rule['associated-rule-id'] == "pass")
$rdrpass = "pass ";
else
$rdrpass = "";
+
+ if (isset($rule['nordr'])) {
+ $nordr = "no ";
+ $rdrpass = "";
+ } else
+ $nordr = "";
+
if(!$rule['interface'])
$natif = "wan";
else
@@ -1690,33 +1710,65 @@ function filter_nat_rules_generate() {
$srcaddr = filter_generate_address($rule, 'source', true);
$dstaddr = filter_generate_address($rule, 'destination', true);
+ $srcaddr = trim($srcaddr);
+ $dstaddr = trim($dstaddr);
if(!$dstaddr)
$dstaddr = $FilterIflist[$natif]['ip'];
+ $dstaddr_port = explode(" ", $dstaddr);
+ if(empty($dstaddr_port[0]) || strtolower(trim($dstaddr_port[0])) == "port")
+ continue; // Skip port forward if no destination address found
+ $dstaddr_reflect = $dstaddr;
+ if(isset($rule['destination']['any'])) {
+ /* With reflection enabled, destination of 'any' has side effects
+ * that most people would not expect, so change it on reflection rules. */
+ $dstaddr_reflect = $FilterIflist[$natif]['ip'];
+ if(!empty($FilterIflist[$natif]['sn']))
+ $dstaddr_reflect = gen_subnet($dstaddr_reflect, $FilterIflist[$natif]['sn']) . '/' . $FilterIflist[$natif]['sn'];
+
+ if($dstaddr_port[2])
+ $dstaddr_reflect .= " port " . $dstaddr_port[2];
+ }
+
$natif = $FilterIflist[$natif]['if'];
- if (isset($rule['nordr'])) {
- $nordr = "no ";
- $rdrpass = "";
- } else
- $nordr = "";
+ $reflection_type = "none";
+ if($rule['natreflection'] != "disable" && $dstaddr_port[0] != "0.0.0.0") {
+ if($rule['natreflection'] == "enable")
+ $reflection_type = "proxy";
+ else if($rule['natreflection'] == "purenat")
+ $reflection_type = "purenat";
+ else if(!isset($config['system']['disablenatreflection'])) {
+ if(isset($config['system']['enablenatreflectionpurenat']))
+ $reflection_type = "purenat";
+ else
+ $reflection_type = "proxy";
+ }
+ }
- if((!isset($config['system']['disablenatreflection']) || $rule['natreflection'] == "enable")
- && $rule['natreflection'] != "disable") {
+ if($reflection_type != "none")
$nat_if_list = filter_get_reflection_interfaces($natif);
- } else {
+ else
$nat_if_list = array();
- }
+
+ $localport_nat = $localport;
+ if(empty($localport_nat) && $dstaddr_port[2])
+ $localport_nat = " port " . $dstaddr_port[2];
if($srcaddr <> "" && $dstaddr <> "" && $natif) {
- $srcaddr = trim($srcaddr);
- $dstaddr = trim($dstaddr);
+ $rdr_if_list = $natif;
+ if($reflection_type == "purenat" || isset($rule['nordr'])) {
+ $nat_if_list = array_merge(array($natif), $nat_if_list);
+ $rdr_if_list = implode(" ", $nat_if_list);
+ if(count($nat_if_list) > 1)
+ $rdr_if_list = "{ {$rdr_if_list} }";
+ }
- $natrules .= "{$nordr}rdr {$rdrpass}on {$natif} proto {$protocol} from {$srcaddr} to {$dstaddr}" . ($nordr == "" ? " -> {$target}{$localport}" : "");
+ $natrules .= "{$nordr}rdr {$rdrpass}on {$rdr_if_list} proto {$protocol} from {$srcaddr} to {$dstaddr}" . ($nordr == "" ? " -> {$target}{$localport}" : "");
/* Does this rule redirect back to a internal host? */
- if(isset($rule['destination']['any']) && !interface_has_gateway($rule['interface']) && !isset($rule['nordr'])) {
+ if(isset($rule['destination']['any']) && !isset($rule['nordr']) && !isset($config['system']['enablenatreflectionhelper']) && !interface_has_gateway($rule['interface'])) {
$rule_interface_ip = find_interface_ip($natif);
$rule_interface_subnet = find_interface_subnet($natif);
if(!empty($rule_interface_ip) && !empty($rule_interface_subnet)) {
@@ -1726,11 +1778,18 @@ function filter_nat_rules_generate() {
$natrules .= "nat on {$natif} proto tcp from {$rule_subnet}/{$rule_interface_subnet} to {$target} port {$dstport[0]} -> ({$natif})\n";
}
}
- $natrules .= filter_generate_reflection($rule, $nordr, $nat_if_list, $srcaddr, $dstaddr, $starting_localhost_port, $reflection_rules);
- $natrules .= "\n";
- foreach ($reflection_rules as $txtline)
- fwrite($inetd_fd, $txtline);
+ if($reflection_type == "proxy" && !isset($rule['nordr'])) {
+ $natrules .= filter_generate_reflection_proxy($rule, $nordr, $nat_if_list, $srcaddr, $dstaddr, $starting_localhost_port, $reflection_rules);
+ $nat_if_list = array($natif);
+
+ foreach ($reflection_rules as $txtline)
+ fwrite($inetd_fd, $txtline);
+ }
+
+ $natrules .= "\n";
+ if(!isset($rule['nordr']))
+ $natrules .= filter_generate_reflection_nat($rule, $route_table, $nat_if_list, $protocol, "{$target}{$localport_nat}", $target_ip);
}
}
}
OpenPOWER on IntegriCloud