diff --git a/src/etc/inc/filter.inc b/src/etc/inc/filter.inc index 80ced6076..854a6490c 100644 --- a/src/etc/inc/filter.inc +++ b/src/etc/inc/filter.inc @@ -1525,6 +1525,8 @@ function filter_nat_rules_generate_if(&$FilterIflist, $if, $src = "any", $srcpor $tgt = $natip; } elseif (is_alias($natip)) { $tgt = "\${$natip}"; + } elseif (is_ipaddrv6($natip)) { + $tgt = "{$natip}/128"; } else { $tgt = "{$natip}/32"; } @@ -1546,13 +1548,6 @@ function filter_nat_rules_generate_if(&$FilterIflist, $if, $src = "any", $srcpor } else { $protocol = ""; } - /* Set tgt for IPv6 */ - if ($proto == "ipv6") { - $natip = get_interface_ipv6($if); - if (is_ipaddrv6($natip)) { - $tgt = "{$natip}/128"; - } - } /* Add the hard set source port (useful for ISAKMP) */ if ($natport != "") { $tgt .= " port {$natport}"; diff --git a/src/www/firewall_nat_out_edit.php b/src/www/firewall_nat_out_edit.php index 1d66dfa2b..14ba10b3c 100644 --- a/src/www/firewall_nat_out_edit.php +++ b/src/www/firewall_nat_out_edit.php @@ -141,7 +141,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { // load data from config foreach (array('protocol','sourceport','dstport','natport','target','targetip' ,'targetip_subnet','poolopts','interface','descr','nonat' - ,'disabled','staticnatport','nosync') as $fieldname) { + ,'disabled','staticnatport','nosync','ipprotocol') as $fieldname) { if (isset($a_out[$configId][$fieldname])) { $pconfig[$fieldname] = $a_out[$configId][$fieldname]; } @@ -163,13 +163,18 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { // initialize unused elements foreach (array('protocol','sourceport','dstport','natport','target','targetip' ,'targetip_subnet','poolopts','interface','descr','nonat' - ,'disabled','staticnatport','nosync','source','source_subnet') as $fieldname) { + ,'disabled','staticnatport','nosync','source','source_subnet','ipprotocol') as $fieldname) { if (!isset($pconfig[$fieldname])) { $pconfig[$fieldname] = null; } } - - + if (empty($pconfig['ipprotocol'])) { + if (strpos($pconfig['source'].$pconfig['destination'].$pconfig['targetip'], ":") !== false) { + $pconfig['ipprotocol'] = 'inet6'; + } else { + $pconfig['ipprotocol'] = 'inet'; + } + } } elseif ($_SERVER['REQUEST_METHOD'] === 'POST') { $input_errors = array(); $pconfig = $_POST; @@ -222,6 +227,16 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { $input_errors[] = gettext("Only Round Robin pool options may be chosen when selecting an alias."); } + // validate ipv4/v6, addresses should use selected address family + foreach (array('source', 'destination', 'targetip') as $fieldname) { + if (is_ipaddrv6($pconfig[$fieldname]) && $pconfig['ipprotocol'] != 'inet6') { + $input_errors[] = sprintf(gettext("%s is not a valid IPv4 address."), $pconfig[$fieldname]); + } + if (is_ipaddrv4($pconfig[$fieldname]) && $pconfig['ipprotocol'] != 'inet') { + $input_errors[] = sprintf(gettext("%s is not a valid IPv6 address."), $pconfig[$fieldname]); + } + } + if (count($input_errors) == 0) { $natent = array(); $natent['source'] = array(); @@ -229,6 +244,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { $natent['descr'] = $pconfig['descr']; $natent['interface'] = $pconfig['interface']; $natent['poolopts'] = $pconfig['poolopts']; + $natent['ipprotocol'] = $pconfig['ipprotocol']; if ( isset($a_out[$id]['created']) && is_array($a_out[$id]['created']) ){ $natent['created'] = $a_out[$id]['created']; @@ -279,7 +295,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { } else if(is_alias($pconfig['source'])) { $natent['source']['network'] = trim($pconfig['source']); } else { - $natent['source']['network'] = gen_subnet(trim($pconfig['source']), $pconfig['source_subnet']) . "/" . $pconfig['source_subnet']; + if (is_ipaddrv6($pconfig['source'])) { + $natent['source']['network'] = gen_subnetv6(trim($pconfig['source']), $pconfig['source_subnet']) . "/" . $pconfig['source_subnet']; + } else { + $natent['source']['network'] = gen_subnet(trim($pconfig['source']), $pconfig['source_subnet']) . "/" . $pconfig['source_subnet']; + } } // destination address @@ -288,7 +308,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { } elseif (is_alias($pconfig['destination'])){ $natent['destination']['address'] = trim($pconfig['destination']) ; } else { - $natent['destination']['address'] = gen_subnet(trim($pconfig['destination']), $pconfig['destination_subnet']) . "/" . $pconfig['destination_subnet'];; + if (is_ipaddrv6($pconfig['destination'])) { + $natent['destination']['address'] = gen_subnetv6(trim($pconfig['destination']), $pconfig['destination_subnet']) . "/" . $pconfig['destination_subnet'];; + } else { + $natent['destination']['address'] = gen_subnet(trim($pconfig['destination']), $pconfig['destination_subnet']) . "/" . $pconfig['destination_subnet'];; + } } // boolean fields @@ -375,6 +399,8 @@ include("head.inc"); } }); + // IPv4/IPv6 select + hook_ipv4v6('ipv4v6net', 'network-id'); }); @@ -439,6 +465,23 @@ include("head.inc"); +