%PDF- %PDF-
| Direktori : /proc/thread-self/root/backups/router/usr/local/www/ |
| Current File : //proc/thread-self/root/backups/router/usr/local/www/firewall_nat_edit.php |
<?php
/*
* Copyright (C) 2014 Deciso B.V.
* Copyright (C) 2009 Janne Enberg <janne.enberg@lietu.net>
* Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
require_once("guiconfig.inc");
require_once("filter.inc");
$a_nat = &config_read_array('nat', 'rule');
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
// load form data from config
if (isset($_GET['id']) && is_numericint($_GET['id']) && isset($a_nat[$_GET['id']])) {
$id = $_GET['id'];
$configId = $id; // load form data from id
} elseif (isset($_GET['dup']) && isset($a_nat[$_GET['dup']])){
$after = $_GET['dup'];
$configId = $_GET['dup']; // load form data from id
}
if (isset($_GET['after']) && isset($a_nat[$_GET['after']])) {
$after = $_GET['after'];
}
// initialize form and set defaults
$pconfig = array();
$pconfig['protocol'] = "tcp";
$pconfig['srcbeginport'] = "any";
$pconfig['srcendport'] = "any";
$pconfig['interface'] = ["wan"];
$pconfig['dstbeginport'] = 80 ;
$pconfig['dstendport'] = 80 ;
$pconfig['local-port'] = 80;
$pconfig['associated-rule-id'] = "add-associated";
if (isset($configId)) {
// copy 1-on-1
foreach (array('protocol','target','local-port','descr','interface','nosync','log',
'natreflection','created','updated','ipprotocol','tag','tagged','poolopts', 'category') as $fieldname) {
if (isset($a_nat[$configId][$fieldname])) {
$pconfig[$fieldname] = $a_nat[$configId][$fieldname];
} else {
$pconfig[$fieldname] = null;
}
}
// fields with some kind of logic.
if (!isset($_GET['dup']) && isset($a_nat[$configId]['associated-rule-id'])) {
$pconfig['associated-rule-id'] = $a_nat[$configId]['associated-rule-id'];
}
$pconfig['disabled'] = isset($a_nat[$configId]['disabled']);
$pconfig['nordr'] = isset($a_nat[$configId]['nordr']);
$pconfig['interface'] = explode(",", $pconfig['interface']);
address_to_pconfig($a_nat[$configId]['source'], $pconfig['src'],
$pconfig['srcmask'], $pconfig['srcnot'],
$pconfig['srcbeginport'], $pconfig['srcendport']);
address_to_pconfig($a_nat[$configId]['destination'], $pconfig['dst'],
$pconfig['dstmask'], $pconfig['dstnot'],
$pconfig['dstbeginport'], $pconfig['dstendport']);
if (empty($pconfig['ipprotocol'])) {
if (strpos($pconfig['src'].$pconfig['dst'].$pconfig['target'], ":") !== false) {
$pconfig['ipprotocol'] = 'inet6';
} else {
$pconfig['ipprotocol'] = 'inet';
}
}
} elseif (isset($_GET['template']) && $_GET['template'] == 'transparent_proxy') {
// new rule for transparent proxy reflection, to use as sample
$pconfig['interface'] = ["lan"];
$pconfig['src'] = "lan";
$pconfig['dst'] = "any";
$pconfig['ipprotocol'] = "inet";
if (isset($_GET['https'])){
$pconfig['dstbeginport'] = 443;
$pconfig['dstendport'] = 443;
if (isset($config['OPNsense']['proxy']['forward']['sslbumpport'])) {
$pconfig['local-port'] = $config['OPNsense']['proxy']['forward']['sslbumpport'];
} else {
$pconfig['local-port'] = 3129;
}
} else {
$pconfig['dstbeginport'] = 80;
$pconfig['dstendport'] = 80;
// try to read the proxy configuration to determine the current port
// this has some disadvantages in case of dependencies, but there isn't
// a much better solution available at the moment.
if (isset($config['OPNsense']['proxy']['forward']['port'])) {
$pconfig['local-port'] = $config['OPNsense']['proxy']['forward']['port'];
} else {
$pconfig['local-port'] = 3128;
}
}
$pconfig['target'] = '127.0.0.1';
$pconfig['natreflection'] = 'enable';
$pconfig['descr'] = gettext("redirect traffic to proxy");
} else {
$pconfig['src'] = "any";
}
// init empty fields
foreach (array('dst','dstmask','srcmask','dstbeginport','dstendport','target',
'local-port','natreflection','descr','disabled','nosync','ipprotocol',
'tag','tagged','poolopts') as $fieldname) {
if (!isset($pconfig[$fieldname])) {
$pconfig[$fieldname] = null;
}
}
$pconfig['category'] = !empty($pconfig['category']) ? explode(",", $pconfig['category']) : [];
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
$pconfig = $_POST;
$input_errors = array();
// validate id and store if usable
if (isset($pconfig['id']) && is_numericint($pconfig['id']) && isset($a_nat[$pconfig['id']])) {
$id = $_POST['id'];
}
if (isset($pconfig['after']) && isset($a_nat[$pconfig['after']])) {
// place record after provided sequence number
$after = $pconfig['after'];
}
/* Validate input data */
if ($pconfig['protocol'] == 'tcp' || $pconfig['protocol'] == 'udp' || $pconfig['protocol'] == 'tcp/udp') {
$reqdfields = explode(" ", "interface protocol dstbeginport dstendport");
$reqdfieldsn = array(gettext("Interface"),gettext("Protocol"),gettext("Destination port from"),gettext("Destination port to"));
} else {
$reqdfields = explode(" ", "interface protocol");
$reqdfieldsn = array(gettext("Interface"),gettext("Protocol"));
}
$reqdfields[] = "src";
$reqdfieldsn[] = gettext("Source address");
$reqdfields[] = "dst";
$reqdfieldsn[] = gettext("Destination address");
if (empty($pconfig['nordr'])) {
$reqdfields[] = "target";
$reqdfieldsn[] = gettext("Redirect target IP");
}
do_input_validation($pconfig, $reqdfields, $reqdfieldsn, $input_errors);
if (!isset($pconfig['nordr']) && ($pconfig['target'] && !is_ipaddroralias($pconfig['target']) && !is_subnet($pconfig['target']))) {
$input_errors[] = sprintf(gettext("\"%s\" is not a valid redirect target IP address, network or host alias."), $pconfig['target']);
}
if (!empty($pconfig['srcbeginport']) && $pconfig['srcbeginport'] != 'any' && !is_portoralias($pconfig['srcbeginport']))
$input_errors[] = sprintf(gettext("%s is not a valid start source port. It must be a port alias or integer between 1 and 65535."), $pconfig['srcbeginport']);
if (!empty($pconfig['srcendport']) && $pconfig['srcendport'] != 'any' && !is_portoralias($pconfig['srcendport']))
$input_errors[] = sprintf(gettext("%s is not a valid end source port. It must be a port alias or integer between 1 and 65535."), $pconfig['srcendport']);
if (!empty($pconfig['dstbeginport']) && $pconfig['dstbeginport'] != 'any' && !is_portoralias($pconfig['dstbeginport']))
$input_errors[] = sprintf(gettext("%s is not a valid start destination port. It must be a port alias or integer between 1 and 65535."), $pconfig['dstbeginport']);
if (!empty($pconfig['dstendport']) && $pconfig['dstendport'] != 'any' && !is_portoralias($pconfig['dstendport']))
$input_errors[] = sprintf(gettext("%s is not a valid end destination port. It must be a port alias or integer between 1 and 65535."), $pconfig['dstendport']);
if (($pconfig['protocol'] == "tcp" || $pconfig['protocol'] == "udp" || $_POST['protocol'] == "tcp/udp") && (!isset($pconfig['nordr']) && !is_portoralias($pconfig['local-port']))) {
$input_errors[] = sprintf(gettext("A valid redirect target port must be specified. It must be a port alias or integer between 1 and 65535."), $pconfig['local-port']);
}
if (!is_specialnet($pconfig['src']) && !is_ipaddroralias($pconfig['src'])) {
$input_errors[] = sprintf(gettext("%s is not a valid source IP address or alias."), $pconfig['src']);
}
// validate ipv4/v6, addresses should use selected address family
foreach (array('src', 'dst', 'target') 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 (!empty($pconfig['srcmask']) && !is_numericint($pconfig['srcmask'])) {
$input_errors[] = gettext("A valid source bit count must be specified.");
}
if (!is_specialnet($pconfig['dst']) && !is_ipaddroralias($pconfig['dst'])) {
$input_errors[] = sprintf(gettext("%s is not a valid destination IP address or alias."), $pconfig['dst']);
}
if (!empty($pconfig['dstmask']) && !is_numericint($pconfig['dstmask'])) {
$input_errors[] = gettext("A valid destination bit count must be specified.");
}
if (!isset($_POST['nordr'])
&& is_numericint($pconfig['dstbeginport']) && is_numericint($pconfig['dstendport']) && is_numericint($pconfig['local-port'])
&&
(max($pconfig['dstendport'],$pconfig['dstbeginport']) - min($pconfig['dstendport'],$pconfig['dstbeginport']) + $pconfig['local-port']) > 65535) {
$input_errors[] = gettext("The target port range must be an integer between 1 and 65535.");
}
if (count($input_errors) == 0) {
$natent = array();
if ($pconfig['protocol'] != 'any') {
$natent['protocol'] = $pconfig['protocol'];
}
$natent['interface'] = !empty($pconfig['interface']) ? implode(",", $pconfig['interface']) : null;
$natent['category'] = !empty($pconfig['category']) ? implode(",", $pconfig['category']) : null;
$natent['ipprotocol'] = $pconfig['ipprotocol'];
$natent['descr'] = $pconfig['descr'];
$natent['tag'] = $pconfig['tag'];
$natent['tagged'] = $pconfig['tagged'];
$natent['poolopts'] = $pconfig['poolopts'];
if (!empty($natent['nordr'])) {
$natent['associated-rule-id'] = '';
} elseif (!empty($pconfig['associated-rule-id']) && $pconfig['associated-rule-id'] == "pass") {
$natent['associated-rule-id'] = "pass";
} elseif (!empty($pconfig['associated-rule-id']) && !in_array($pconfig['associated-rule-id'], ['add-associated', 'add-unassociated'])) {
$natent['associated-rule-id'] = $pconfig['associated-rule-id'];
} else {
$natent['associated-rule-id'] = null;
}
$natent['disabled'] = !empty($pconfig['disabled']);
$natent['nordr'] = !empty($pconfig['nordr']);
$natent['nosync'] = !empty($pconfig['nosync']);
$natent['log'] = !empty($pconfig['log']);
if (empty($natent['nordr'])) {
$natent['target'] = $pconfig['target'];
$natent['local-port'] = $pconfig['local-port'];
}
pconfig_to_address($natent['source'], $pconfig['src'],
$pconfig['srcmask'], !empty($pconfig['srcnot']),
$pconfig['srcbeginport'], $pconfig['srcendport']);
pconfig_to_address($natent['destination'], $pconfig['dst'],
$pconfig['dstmask'], !empty($pconfig['dstnot']),
$pconfig['dstbeginport'], $pconfig['dstendport']);
if ($pconfig['natreflection'] == "purenat" || $pconfig['natreflection'] == "disable") {
$natent['natreflection'] = $pconfig['natreflection'];
}
// If we used to have an associated filter rule, but no-longer should have one
if (isset($id) && !empty($a_nat[$id]['associated-rule-id']) && ( empty($natent['associated-rule-id']) || $natent['associated-rule-id'] != $a_nat[$id]['associated-rule-id'] ) ) {
// Delete the previous rule
foreach ($config['filter']['rule'] as $key => $item){
if (isset($item['associated-rule-id']) && $item['associated-rule-id']==$a_nat[$id]['associated-rule-id'] ){
unset($config['filter']['rule'][$key]);
break;
}
}
mark_subsystem_dirty('filter');
}
// Updating a rule with a filter rule associated
if (!empty($natent['associated-rule-id']) || in_array($pconfig['associated-rule-id'], ['add-associated', 'add-unassociated'])) {
/* auto-generate a matching firewall rule */
$filterent = ['type' => 'pass'];
if (in_array($pconfig['associated-rule-id'], ['add-associated', 'add-unassociated'])) {
$filterent['associated-rule-id'] = $natent['associated-rule-id'];
} else {
$filterent['associated-rule-id'] = $natent['associated-rule-id'];
foreach ($config['filter']['rule'] as $key => &$item){
if (isset($item['associated-rule-id']) && $item['associated-rule-id']==$natent['associated-rule-id']) {
$filterent = &config_read_array('filter', 'rule', $key);
break;
}
}
}
pconfig_to_address($filterent['source'], $pconfig['src'],
$pconfig['srcmask'], !empty($pconfig['srcnot']),
$pconfig['srcbeginport'], $pconfig['srcendport']);
// Update interface, protocol and destination
$filterent['interface'] = $natent['interface'];
$filterent['statetype'] = "keep state";
if (!empty($natent['protocol'])) {
$filterent['protocol'] = $natent['protocol'];
} elseif (isset($filterent['protocol'])) {
unset($filterent['protocol']);
}
$filterent['ipprotocol'] = $natent['ipprotocol'];
if (!isset($filterent['destination'])) {
$filterent['destination'] = array();
}
$filterent['destination']['address'] = $pconfig['target'];
if (count($pconfig['interface']) > 1) {
$filterent['floating'] = true;
$filterent['quick'] = "yes";
} else {
unset($filterent['floating']);
unset($filterent['quick']);
}
if (!empty($pconfig['log'])) {
$filterent['log'] = true;
} elseif (isset($filterent['log'])) {
unset($filterent['log']);
}
if (!empty($pconfig['disabled'])) {
$filterent['disabled'] = true;
} else {
unset($filterent['disabled']);
}
if (is_numericint($pconfig['local-port']) && is_numericint($pconfig['dstendport']) && is_numericint($pconfig['dstbeginport'])) {
$dstpfrom = $pconfig['local-port'];
$dstpto = $dstpfrom + max($pconfig['dstendport'], $pconfig['dstbeginport']) - min($pconfig['dstbeginport'],$pconfig['dstendport']) ;
if ($dstpfrom == $dstpto) {
$filterent['destination']['port'] = $dstpfrom;
} else {
$filterent['destination']['port'] = $dstpfrom . "-" . $dstpto;
}
} else {
// if any of the ports is an alias, copy contents of local-port
$filterent['destination']['port'] = $pconfig['local-port'];
}
$filterent['descr'] = $pconfig['descr'];
$filterent['category'] = $natent['category'];
// If this is a new rule, create an ID and add the rule
if (
!empty($pconfig['associated-rule-id']) &&
in_array($pconfig['associated-rule-id'], ['add-associated', 'add-unassociated'])
) {
if ($pconfig['associated-rule-id'] == 'add-associated') {
$filterent['associated-rule-id'] = $natent['associated-rule-id'] = uniqid("nat_", true);
}
$filterent['created'] = make_config_revision_entry();
$config['filter']['rule'][] = $filterent;
}
mark_subsystem_dirty('filter');
}
// Update the NAT entry now
$natent['updated'] = make_config_revision_entry();
if (isset($id)) {
if (isset($a_nat[$id]['created'])) {
$natent['created'] = $a_nat[$id]['created'];
}
$a_nat[$id] = $natent;
} else {
$natent['created'] = make_config_revision_entry();
if (isset($after)) {
array_splice($a_nat, $after+1, 0, array($natent));
} else {
$a_nat[] = $natent;
}
}
OPNsense\Core\Config::getInstance()->fromArray($config);
$catmdl = new OPNsense\Firewall\Category();
if ($catmdl->sync()) {
$catmdl->serializeToConfig();
$config = OPNsense\Core\Config::getInstance()->toArray(listtags());
}
write_config();
mark_subsystem_dirty('natconf');
header(url_safe('Location: /firewall_nat.php'));
exit;
}
}
legacy_html_escape_form_data($pconfig);
include("head.inc");
?>
<body>
<script src="<?= cache_safe('/ui/js/tokenize2.js') ?>"></script>
<link rel="stylesheet" type="text/css" href="<?= cache_safe(get_themed_filename('/css/tokenize2.css')) ?>">
<script src="<?= cache_safe('/ui/js/opnsense_ui.js') ?>"></script>
<script>
$( document ).ready(function() {
// show source fields (advanced)
$("#showadvancedboxsrc").click(function(){
$(".advanced_opt_src").toggleClass("hidden visible");
});
// on change event protocol change
$("#proto").change(function(){
let port_disabled = true;
if ($("#proto").val() == "tcp" || $("#proto").val() == "udp" || $("#proto").val() == "tcp/udp") {
port_disabled = false;
} else {
$("#dstbeginport optgroup:last option:first").prop('selected', true);
$("#dstendport optgroup:last option:first").prop('selected', true);
$("#srcbeginport optgroup:last option:first").prop('selected', true);
$("#srcendport optgroup:last option:first").prop('selected', true);
port_disabled = true;
}
$("#srcbeginport").prop('disabled', port_disabled);
$("#srcendport").prop('disabled', port_disabled);
$("#dstbeginport").prop('disabled', port_disabled);
$("#dstendport").prop('disabled', port_disabled);
$("#localbeginport").prop('disabled', port_disabled);
$("input[for='localbeginport']").prop('disabled', port_disabled);
$("#srcbeginport").selectpicker('refresh');
$("#srcendport").selectpicker('refresh');
$("#dstbeginport").selectpicker('refresh');
$("#dstendport").selectpicker('refresh');
$("#localbeginport").selectpicker('refresh');
$("input[for='localbeginport']").prop('disabled', port_disabled);
});
// on change event for "No RDR" checkbox
$("#nordr").change(function(){
if ($("#nordr").prop('checked')) {
$(".act_no_rdr").addClass("hidden");
$(".act_no_rdr :input").prop( "disabled", true );
} else {
$(".act_no_rdr").removeClass("hidden");
$(".act_no_rdr :input").prop( "disabled", false );
}
$(".act_no_rdr .selectpicker").selectpicker('refresh');
});
// trigger initial form change
$("#nordr").change(); // no-rdr
$("#proto").change(); // protocol
// show source address when selected
<?php if (!empty($pconfig['srcnot']) || $pconfig['src'] != "any" || $pconfig['srcbeginport'] != "any" || $pconfig['srcendport'] != "any"): ?>
$(".advanced_opt_src").toggleClass("hidden visible");
<?php endif; ?>
// select / input combination, link behaviour
// when the data attribute "data-other" is selected, display related input item(s)
// push changes from input back to selected option value
$('[for!=""][for]').each(function(){
var refObj = $("#"+$(this).attr("for"));
if (refObj.is("select")) {
// connect on change event to select box (show/hide)
refObj.change(function(){
if ($(this).find(":selected").attr("data-other") == "true") {
// show related controls
$('*[for="'+$(this).attr("id")+'"]').each(function(){
if ($(this).hasClass("selectpicker")) {
$(this).selectpicker('show');
} else {
$(this).removeClass("hidden");
}
$(this).prop("disabled", false);
});
} else {
// hide related controls
$('*[for="'+$(this).attr("id")+'"]').each(function(){
if ($(this).hasClass("selectpicker")) {
$(this).selectpicker('hide');
} else {
$(this).addClass("hidden");
}
$(this).prop("disabled", true);
});
}
});
// update initial
refObj.change();
// connect on change to input to save data to selector
if ($(this).attr("name") == undefined) {
$(this).change(function(){
var otherOpt = $('#'+$(this).attr('for')+' > option[data-other="true"]') ;
otherOpt.attr("value",$(this).val());
});
}
}
});
// align dropdown source from/to port
$("#srcbeginport").change(function(){
$('#srcendport').prop('selectedIndex', $("#srcbeginport").prop('selectedIndex') );
$('#srcendport').selectpicker('refresh');
$('#srcendport').change();
});
// align dropdown destination from/to port
$("#dstbeginport").change(function(){
$('#dstendport').prop('selectedIndex', $("#dstbeginport").prop('selectedIndex') );
$('#dstendport').selectpicker('refresh');
$('#dstendport').change();
// on new entry, align redirect target port to dst target
if ($("#entryid").length == 0) {
$('#localbeginport').prop('selectedIndex', $("#dstbeginport").prop('selectedIndex') );
$('#localbeginport').change();
}
});
$("input[for='dstbeginport']").change(function(){
// on new entry, align redirect target port to dst target
if ($("#entryid").length == 0) {
$("input[for='localbeginport']").val($(this).val());
$("input[for='localbeginport']").change();
}
});
// IPv4/IPv6 select
hook_ipv4v6('ipv4v6net', 'network-id');
formatTokenizersUI();
});
</script>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<?php if (isset($input_errors) && count($input_errors) > 0) print_input_errors($input_errors); ?>
<section class="col-xs-12">
<div class="content-box">
<form method="post" name="iform" id="iform">
<table role="presentation" class="table table-striped opnsense_standard_table_form">
<tr>
<td style="width:22%"><?=gettext("Edit Redirect entry"); ?></td>
<td style="width:78%; text-align:right">
<small><?=gettext("full help"); ?> </small>
<i class="fa fa-toggle-off text-danger" style="cursor: pointer;" id="show_all_help_page"></i>
</td>
</tr>
<tr>
<td><a id="help_for_disabled" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Disabled"); ?></td>
<td>
<input name="disabled" type="checkbox" id="disabled" value="yes" <?= !empty($pconfig['disabled']) ? "checked=\"checked\"" : ""; ?> />
<?=gettext("Disable this rule"); ?>
<div class="hidden" data-for="help_for_disabled">
<?=gettext("Set this option to disable this rule without removing it from the list."); ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_nordr" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("No RDR (NOT)"); ?></td>
<td>
<input type="checkbox" name="nordr" id="nordr" <?= !empty($pconfig['nordr']) ? "checked=\"checked\"" : ""; ?> />
<div class="hidden" data-for="help_for_nordr">
<?=gettext("Enabling this option will disable redirection for traffic matching this rule."); ?>
<br /><?=gettext("Hint: this option is rarely needed, don't use this unless you know what you're doing."); ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_interface" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Interface"); ?></td>
<td>
<select name="interface[]" class="selectpicker" data-width="348px" data-live-search="true" multiple="multiple">
<?php foreach (legacy_config_get_interfaces(["enable" => true], ['lo0']) as $iface => $ifdetail): ?>
<option value="<?=$iface;?>" <?= in_array($iface, $pconfig['interface'] ?? []) ? "selected=\"selected\"" : ""; ?>>
<?=htmlspecialchars($ifdetail['descr']);?>
</option>
<?php endforeach ?>
</select>
<div class="hidden" data-for="help_for_interface">
<?=gettext("Choose which interface this rule applies to."); ?><br />
<?=gettext("Hint: in most cases, you'll want to use WAN here."); ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_ipv46" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("TCP/IP Version");?></td>
<td>
<select name="ipprotocol" class="selectpicker" data-width="348px" data-live-search="true" data-size="5" >
<?php
foreach (array('inet' => 'IPv4','inet6' => 'IPv6', 'inet46' => 'IPv4+IPv6') as $proto => $name): ?>
<option value="<?=$proto;?>" <?= $proto == $pconfig['ipprotocol'] ? "selected=\"selected\"" : "";?>>
<?=$name;?>
</option>
<?php
endforeach; ?>
</select>
<div class="hidden" data-for="help_for_ipv46">
<?=gettext("Select the Internet Protocol version this rule applies to");?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_proto" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Protocol"); ?></td>
<td>
<select id="proto" name="protocol" class="selectpicker" data-live-search="true" data-size="5" data-width="348px">
<?php foreach (get_protocols() as $proto): ?>
<option value="<?=strtolower($proto);?>" <?= strtolower($proto) == $pconfig['protocol'] ? "selected=\"selected\"" : ""; ?>>
<?= $proto ?>
</option>
<?php endforeach ?>
</select>
<div class="hidden" data-for="help_for_proto">
<?=gettext("Choose which IP protocol " ."this rule should match."); ?><br/>
<?=gettext("Hint: in most cases, you should specify"); ?> <em><?=gettext("TCP"); ?></em> <?=gettext("here."); ?>
</div>
</td>
</tr>
<tr class="advanced_opt_src visible">
<td><?=gettext("Source"); ?></td>
<td>
<input type="button" class="btn btn-default" value="<?= html_safe(gettext('Advanced')) ?>" id="showadvancedboxsrc" />
<div class="hidden" data-for="help_for_source">
<?=gettext("Show source address and port range"); ?>
</div>
</td>
</tr>
<tr class="advanced_opt_src hidden">
<td> <a id="help_for_src_invert" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Source") . " / ".gettext("Invert");?> </td>
<td>
<input name="srcnot" type="checkbox" id="srcnot" value="yes" <?= !empty($pconfig['srcnot']) ? "checked=\"checked\"" : "";?> />
<div class="hidden" data-for="help_for_src_invert">
<?=gettext("Use this option to invert the sense of the match."); ?>
</div>
</td>
</tr>
<tr class="advanced_opt_src hidden">
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Source"); ?></td>
<td>
<table style="max-width: 348px">
<tr>
<td>
<select name="src" id="src" class="selectpicker" data-live-search="true" data-size="5" data-width="348px">
<option data-other=true value="<?=$pconfig['src'];?>" <?=!is_specialnet($pconfig['src']) && !is_alias($pconfig['src']) ? "selected=\"selected\"" : "";?>><?=gettext("Single host or Network"); ?></option>
<optgroup label="<?=gettext("Aliases");?>">
<?php foreach (legacy_list_aliases("network") as $alias):
?>
<option value="<?=$alias['name'];?>" <?=$alias['name'] == $pconfig['src'] ? "selected=\"selected\"" : "";?>><?=htmlspecialchars($alias['name']);?></option>
<?php endforeach; ?>
</optgroup>
<optgroup label="<?=gettext("Networks");?>">
<?php foreach (get_specialnets(true) as $ifent => $ifdesc):
?>
<option value="<?=$ifent;?>" <?= $pconfig['src'] == $ifent ? "selected=\"selected\"" : ""; ?>><?=$ifdesc;?></option>
<?php endforeach; ?>
</optgroup>
</select>
</td>
</tr>
</table>
<table style="max-width: 348px">
<tr>
<td style="width:285px">
<!-- updates to "other" option in src -->
<input type="text" id="src_address" for="src" value="<?=$pconfig['src'];?>" aria-label="<?=gettext("Source address");?>"/>
</td>
<td>
<select name="srcmask" data-network-id="src_address" class="selectpicker ipv4v6net" data-size="5" id="srcmask" data-width="70px" for="src" >
<?php for ($i = 128; $i > 0; $i--): ?>
<option value="<?=$i;?>" <?= $i == $pconfig['srcmask'] ? "selected=\"selected\"" : ""; ?>><?=$i;?></option>
<?php endfor; ?>
</select>
</td>
</tr>
</table>
</td>
</tr>
<tr class="hidden advanced_opt_src">
<td><a id="help_for_srcport" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Source port range"); ?></td>
<td>
<table class="table table-condensed">
<thead>
<tr>
<th><?=gettext("from:"); ?></th>
<th><?=gettext("to:"); ?></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<select id="srcbeginport" name="srcbeginport" class="selectpicker" data-live-search="true" data-size="5" data-width="auto">
<option data-other=true value="<?=$pconfig['srcbeginport'];?>">(<?=gettext("other"); ?>)</option>
<optgroup label="<?=gettext("Aliases");?>">
<?php foreach (legacy_list_aliases("port") as $alias):
?>
<option value="<?=$alias['name'];?>" <?= $pconfig['srcbeginport'] == $alias['name'] ? "selected=\"selected\"" : ""; ?> ><?=htmlspecialchars($alias['name']);?> </option>
<?php endforeach; ?>
</optgroup>
<optgroup label="<?=gettext("Well-known ports");?>">
<option value="any" <?= $pconfig['srcbeginport'] == "any" ? "selected=\"selected\"" : ""; ?>><?=gettext("any"); ?></option>
<?php foreach ($wkports as $wkport => $wkportdesc): ?>
<option value="<?=$wkport;?>" <?= $wkport == $pconfig['srcbeginport'] ? "selected=\"selected\"" : "" ;?>><?=htmlspecialchars($wkportdesc);?></option>
<?php endforeach; ?>
</optgroup>
</select>
</td>
<td>
<select id="srcendport" name="srcendport" class="selectpicker" data-live-search="true" data-size="5" data-width="auto">
<option data-other=true value="<?=$pconfig['srcendport'];?>">(<?=gettext("other"); ?>)</option>
<optgroup label="<?=gettext("Aliases");?>">
<?php foreach (legacy_list_aliases("port") as $alias):
?>
<option value="<?=$alias['name'];?>" <?= $pconfig['srcendport'] == $alias['name'] ? "selected=\"selected\"" : ""; ?> ><?=htmlspecialchars($alias['name']);?> </option>
<?php endforeach; ?>
</optgroup>
<optgroup label="<?=gettext("Well-known ports");?>">
<option value="any" <?= $pconfig['srcendport'] == "any" ? "selected=\"selected\"" : ""; ?>><?=gettext("any"); ?></option>
<?php foreach ($wkports as $wkport => $wkportdesc): ?>
<option value="<?=$wkport;?>" <?= $wkport == $pconfig['srcendport'] ? "selected=\"selected\"" : "" ;?>><?=htmlspecialchars($wkportdesc);?></option>
<?php endforeach; ?>
</optgroup>
</select>
</td>
</tr>
<tr>
<td>
<input type="text" value="<?=$pconfig['srcbeginport'];?>" for="srcbeginport"> <!-- updates to "other" option in srcbeginport -->
</td>
<td>
<input type="text" value="<?=$pconfig['srcendport'];?>" for="srcendport"> <!-- updates to "other" option in srcendport -->
</td>
</tr>
</tbody>
</table>
<div class="hidden" data-for="help_for_srcport">
<?=gettext("When using the TCP or UDP protocols, specify the source port or port range for this rule"); ?>.
<b><?=gettext("This is usually"); ?>
<em><?=gettext("random"); ?></em>
<?=gettext("and almost never equal to the destination port range (and should usually be 'any')"); ?>.
</b>
</div>
</td>
</tr>
<tr>
<td> <a id="help_for_dst_invert" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Destination") . " / ".gettext("Invert");?> </td>
<td>
<input name="dstnot" type="checkbox" id="dstnot" value="yes" <?= !empty($pconfig['dstnot']) ? "checked=\"checked\"" : "";?> />
<div class="hidden" data-for="help_for_dst_invert">
<?=gettext("Use this option to invert the sense of the match."); ?>
</div>
</td>
</tr>
<tr>
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Destination"); ?></td>
<td>
<table style="max-width: 348px">
<tr>
<td>
<select name="dst" id="dst" class="selectpicker" data-live-search="true" data-size="5" data-width="348px">
<option data-other=true value="<?=$pconfig['dst'];?>" <?=!is_specialnet($pconfig['dst']) && !is_alias($pconfig['dst']) ? "selected=\"selected\"" : "";?>><?=gettext("Single host or Network"); ?></option>
<optgroup label="<?=gettext("Aliases");?>">
<?php foreach (legacy_list_aliases("network") as $alias):
?>
<option value="<?=$alias['name'];?>" <?=$alias['name'] == $pconfig['dst'] ? "selected=\"selected\"" : "";?>><?=htmlspecialchars($alias['name']);?></option>
<?php endforeach; ?>
</optgroup>
<optgroup label="<?=gettext("Networks");?>">
<?php foreach (get_specialnets(true) as $ifent => $ifdesc):
?>
<option value="<?=$ifent;?>" <?= $pconfig['dst'] == $ifent ? "selected=\"selected\"" : ""; ?>><?=$ifdesc;?></option>
<?php endforeach;
?>
</optgroup>
<optgroup label="<?=gettext("Virtual IPs");?>">
<?php
if (isset($config['virtualip']['vip'])):
foreach ($config['virtualip']['vip'] as $sn):
if (!empty($sn['noexpand']))
continue;
if ($sn['mode'] == "proxyarp"):
$start = ip2long32(gen_subnet($sn['subnet'], $sn['subnet_bits']));
$end = ip2long32(gen_subnet_max($sn['subnet'], $sn['subnet_bits']));
$len = $end - $start;
for ($i = 0; $i <= $len; $i++):
$snip = long2ip32($start+$i);
?>
<option value="<?=$snip;?>" <?=$snip == $pconfig['dst'] ? "selected=\"selected\"" : "";?>>
<?=htmlspecialchars("{$snip} ({$sn['descr']})");?>
</option>
<?php
endfor;
else:
?>
<option value="<?=$sn['subnet'];?>" <?= $sn['subnet'] == $pconfig['dst'] ? "selected=\"selected\"" : ""; ?>>
<?=htmlspecialchars("{$sn['subnet']} ({$sn['descr']})");?>
</option>
<?php
endif;
endforeach;
endif;
?>
</optgroup>
</select>
</td>
</tr>
</table>
<!-- updates to "other" option in dst -->
<table style="max-width: 348px">
<tr>
<td style="width: 285px">
<input type="text" id="dst_address" for="dst" value="<?= !is_specialnet($pconfig['dst']) ? $pconfig['dst'] : "";?>" aria-label="<?=gettext("Destination address");?>"/>
</td>
<td>
<select name="dstmask" data-network-id="dst_address" class="selectpicker ipv4v6net" data-size="5" id="dstmask" data-width="70px" for="dst">
<?php for ($i = 128; $i > 0; $i--): ?>
<option value="<?=$i;?>" <?= $i == $pconfig['dstmask'] ? "selected=\"selected\"" : ""; ?>><?=$i;?></option>
<?php endfor; ?>
</select>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td><a id="help_for_dstport" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Destination port range"); ?></td>
<td>
<table class="table table-condensed">
<thead>
<tr>
<th><?=gettext("from:"); ?></th>
<th><?=gettext("to:"); ?></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<select id="dstbeginport" name="dstbeginport" class="selectpicker" data-live-search="true" data-size="5" data-width="auto">
<option data-other=true value="<?=$pconfig['dstbeginport'];?>">(<?=gettext("other"); ?>)</option>
<optgroup label="<?=gettext("Aliases");?>">
<?php foreach (legacy_list_aliases("port") as $alias):
?>
<option value="<?=$alias['name'];?>" <?= $pconfig['dstbeginport'] == $alias['name'] ? "selected=\"selected\"" : ""; ?> ><?=htmlspecialchars($alias['name']);?> </option>
<?php endforeach; ?>
</optgroup>
<optgroup label="<?=gettext("Well-known ports");?>">
<option value="any" <?= $pconfig['dstbeginport'] == "any" ? "selected=\"selected\"" : ""; ?>><?=gettext("any"); ?></option>
<?php foreach ($wkports as $wkport => $wkportdesc): ?>
<option value="<?=$wkport;?>" <?= $wkport == $pconfig['dstbeginport'] ? "selected=\"selected\"" : "" ;?>><?=htmlspecialchars($wkportdesc);?></option>
<?php endforeach; ?>
</optgroup>
</select>
</td>
<td>
<select id="dstendport" name="dstendport" class="selectpicker" data-live-search="true" data-size="5" data-width="auto">
<option data-other=true value="<?=$pconfig['dstendport'];?>">(<?=gettext("other"); ?>)</option>
<optgroup label="<?=gettext("Aliases");?>">
<?php foreach (legacy_list_aliases("port") as $alias):
?>
<option value="<?=$alias['name'];?>" <?= $pconfig['dstendport'] == $alias['name'] ? "selected=\"selected\"" : ""; ?> ><?=htmlspecialchars($alias['name']);?> </option>
<?php endforeach; ?>
</optgroup>
<optgroup label="<?=gettext("Well-known ports");?>">
<option value="any" <?= $pconfig['dstendport'] == "any" ? "selected=\"selected\"" : ""; ?>><?=gettext("any"); ?></option>
<?php foreach ($wkports as $wkport => $wkportdesc): ?>
<option value="<?=$wkport;?>" <?= $wkport == $pconfig['dstendport'] ? "selected=\"selected\"" : "" ;?>><?=htmlspecialchars($wkportdesc);?></option>
<?php endforeach; ?>
</optgroup>
</select>
</td>
</tr>
<tr>
<td>
<input type="text" value="<?=$pconfig['dstbeginport'];?>" for="dstbeginport"> <!-- updates to "other" option in dstbeginport -->
</td>
<td>
<input type="text" value="<?=$pconfig['dstendport'];?>" for="dstendport"> <!-- updates to "other" option in dstendport -->
</td>
</tr>
</tbody>
</table>
<div class="hidden" data-for="help_for_dstport">
<?=gettext("When using the TCP or UDP protocols, specify the port or port range for the destination of the packet for this mapping."); ?>
</div>
</td>
</tr>
<tr class="act_no_rdr">
<td><a id="help_for_localip" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Redirect target IP"); ?></td>
<td>
<table style="max-width: 348px">
<tr>
<td>
<select name="target" id="target" class="selectpicker" data-live-search="true" data-size="5" data-width="348px">
<option data-other=true value="<?=$pconfig['target'];?>" <?=!is_alias($pconfig['target']) ? "selected=\"selected\"" : "";?>><?=gettext("Single host or Network"); ?></option>
<optgroup label="<?=gettext("Aliases");?>">
<?php
foreach (legacy_list_aliases("network") as $alias):?>
<option value="<?=$alias['name'];?>" <?=$alias['name'] == $pconfig['target'] ? "selected=\"selected\"" : "";?>><?=htmlspecialchars($alias['name']);?></option>
<?php
endforeach; ?>
</optgroup>
</select>
</td>
</tr>
<tr>
<td>
<!-- updates to "other" option in target -->
<input type="text" id="target_address" for="target" value="<?=$pconfig['target'];?>" aria-label="<?=gettext("Redirect target IP");?>"/>
</td>
</tr>
</table>
<div class="hidden" data-for="help_for_localip">
<?=gettext("Enter the internal IP address of " .
"the server on which you want to map the ports."); ?><br/>
<?=gettext("e.g."); ?> <em>192.168.1.12</em>
</div>
</tr>
<tr class="act_no_rdr">
<td><a id="help_for_localbeginport" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Redirect target port"); ?></td>
<td>
<table class="table table-condensed">
<tbody>
<tr>
<td>
<select id="localbeginport" name="local-port" class="selectpicker" data-live-search="true" data-size="5" data-width="auto">
<option data-other=true value="<?=$pconfig['local-port'];?>">(<?=gettext("other"); ?>)</option>
<optgroup label="<?=gettext("Aliases");?>">
<?php foreach (legacy_list_aliases("port") as $alias):
?>
<option value="<?=$alias['name'];?>" <?= $pconfig['local-port'] == $alias['name'] ? "selected=\"selected\"" : ""; ?> ><?=htmlspecialchars($alias['name']);?> </option>
<?php endforeach; ?>
</optgroup>
<optgroup label="<?=gettext("Well-known ports");?>">
<option value="any" <?= $pconfig['local-port'] == "any" ? "selected=\"selected\"" : ""; ?>><?=gettext("any"); ?></option>
<?php foreach ($wkports as $wkport => $wkportdesc): ?>
<option value="<?=$wkport;?>" <?= $wkport == $pconfig['local-port'] ? "selected=\"selected\"" : "" ;?>><?=htmlspecialchars($wkportdesc);?></option>
<?php endforeach; ?>
</optgroup>
</select>
</td>
</tr>
<tr>
<td>
<input type="text" value="<?=$pconfig['local-port'];?>" for="localbeginport"> <!-- updates to "other" option in localbeginport -->
</td>
</tr>
</tbody>
</table>
<div class="hidden" data-for="help_for_localbeginport">
<?=gettext("Specify the port on the machine with the " .
"IP address entered above. In case of a port range, specify " .
"the beginning port of the range (the end port will be calculated " .
"automatically)."); ?><br />
<?=gettext("Hint: this is usually identical to the 'from' port above"); ?>
</div>
</td>
</tr>
<tr class="act_no_rdr">
<td><a id="help_for_poolopts" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Pool Options:");?></td>
<td>
<select name="poolopts" class="selectpicker">
<option value="" <?=empty($pconfig['poolopts']) ? "selected=\"selected\"" : ""; ?>>
<?=gettext("Default");?>
</option>
<option value="round-robin" <?=$pconfig['poolopts'] == "round-robin" ? "selected=\"selected\"" : ""; ?>>
<?=gettext("Round Robin");?>
</option>
<option value="round-robin sticky-address" <?=$pconfig['poolopts'] == "round-robin sticky-address" ? "selected=\"selected\"" : ""; ?>>
<?=gettext("Round Robin with Sticky Address");?>
</option>
<option value="random" <?=$pconfig['poolopts'] == "random" ? "selected=\"selected\"" : ""; ?>>
<?=gettext("Random");?>
</option>
<option value="random sticky-address" <?=$pconfig['poolopts'] == "random sticky-address" ? "selected=\"selected\"" : ""; ?>>
<?=gettext("Random with Sticky Address");?>
</option>
<option value="source-hash" <?=$pconfig['poolopts'] == "source-hash" ? "selected=\"selected\"" : ""; ?>>
<?=gettext("Source Hash");?>
</option>
<option value="bitmask" <?=$pconfig['poolopts'] == "bitmask" ? "selected=\"selected\"" : ""; ?>>
<?=gettext("Bitmask");?>
</option>
</select>
<div class="hidden" data-for="help_for_poolopts">
<?=gettext("Only Round Robin types work with Host Aliases. Any type can be used with a Subnet.");?><br />
* <?=gettext("Round Robin: Loops through the translation addresses.");?><br />
* <?=gettext("Random: Selects an address from the translation address pool at random.");?><br />
* <?=gettext("Source Hash: Uses a hash of the source address to determine the translation address, ensuring that the redirection address is always the same for a given source.");?><br />
* <?=gettext("Bitmask: Applies the subnet mask and keeps the last portion identical; 10.0.1.50 -> x.x.x.50.");?><br />
* <?=gettext("Sticky Address: The Sticky Address option can be used with the Random and Round Robin pool types to ensure that a particular source address is always mapped to the same translation address.");?><br />
</div>
</td>
</tr>
<tr>
<td><a id="help_for_log" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext('Log') ?></td>
<td>
<input name="log" type="checkbox" id="log" value="yes" <?= !empty($pconfig['log']) ? 'checked="checked"' : '' ?>/>
<?= gettext("Log packets that are handled by this rule") ?>
<div class="hidden" data-for="help_for_log">
<?=sprintf(gettext("Hint: the firewall has limited local log space. Don't turn on logging for everything. If you want to do a lot of logging, consider using a %sremote syslog server%s."),'<a href="ui/syslog/">','</a>') ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_category" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Category"); ?></td>
<td>
<select name="category[]" id="category" multiple="multiple" class="tokenize" data-allownew="true" data-width="348px" data-live-search="true">
<?php
foreach ((new OPNsense\Firewall\Category())->iterateCategories() as $category):
$catname = htmlspecialchars($category['name'], ENT_QUOTES | ENT_HTML401);?>
<option value="<?=$catname;?>" <?=!empty($pconfig['category']) && in_array($catname, $pconfig['category']) ? 'selected="selected"' : '';?> ><?=$catname;?></option>
<?php
endforeach;?>
</select>
<div class="hidden" data-for="help_for_category">
<?=gettext("You may enter or select a category here to group firewall rules (not parsed)."); ?>
</div>
</tr>
<tr>
<td><a id="help_for_descr" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Description"); ?></td>
<td>
<input name="descr" type="text" id="descr" size="40" value="<?=$pconfig['descr'];?>" />
<div class="hidden" data-for="help_for_descr">
<?=gettext("You may enter a description here for your reference (not parsed)."); ?>
</div>
</tr>
<tr>
<td><a id="help_for_tag" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Set local tag"); ?></td>
<td>
<input name="tag" type="text" value="<?=$pconfig['tag'];?>" />
<div class="hidden" data-for="help_for_tag">
<?= gettext("You can mark a packet matching this rule and use this mark to match on other NAT/filter rules.") ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_tagged" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Match local tag"); ?> </td>
<td>
<input name="tagged" type="text" value="<?=$pconfig['tagged'];?>" />
<div class="hidden" data-for="help_for_tagged">
<?=gettext("You can match packet on a mark placed before on another rule.")?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_nosync" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("No XMLRPC Sync"); ?></td>
<td>
<input type="checkbox" value="yes" name="nosync" <?=!empty($pconfig['nosync']) ? "checked=\"checked\"" :"";?> />
<div class="hidden" data-for="help_for_nosync">
<?=gettext("Hint: This prevents the rule on Master from automatically syncing to other CARP members. This does NOT prevent the rule from being overwritten on Slave.");?>
</div>
</td>
</tr>
<tr>
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("NAT reflection"); ?></td>
<td>
<select name="natreflection" class="selectpicker">
<option value="default" <?=$pconfig['natreflection'] != "enable" && $pconfig['natreflection'] != "purenat" && $pconfig['natreflection'] != "disable" ? "selected=\"selected\"" : ""; ?>><?=gettext("Use system default"); ?></option>
<option value="purenat" <?=$pconfig['natreflection'] == "purenat" ? "selected=\"selected\"" : ""; ?>><?=gettext("Enable"); ?></option>
<option value="disable" <?=$pconfig['natreflection'] == "disable" ? "selected=\"selected\"" : ""; ?>><?=gettext("Disable"); ?></option>
</select>
</td>
</tr>
<?php
// check if a filter rule is associated and return it.
$linkedrule = "";
$linkedrule_descr = "";
if (!empty($pconfig['associated-rule-id'])) {
filter_rules_sort(); // XXX: needed?
foreach ($config['filter']['rule'] as $filter_id => $filter_rule) {
if (
isset($filter_rule['associated-rule-id']) &&
$filter_rule['associated-rule-id'] == $pconfig['associated-rule-id']
) {
$linkedrule = $filter_rule['associated-rule-id'];
$linkedrule_descr = htmlspecialchars('Rule ' . $filter_rule['descr']);
}
}
}
?>
<tr class="act_no_rdr">
<td><a id="help_for_fra" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Filter rule association"); ?></td>
<td>
<select name="associated-rule-id">
<option value="" <?= empty($pconfig['associated-rule-id']) ? " selected=\"selected\"" : ""; ?>><?=gettext("None"); ?></option>
<?php if ($linkedrule !== ""):?>
<option value="<?=$linkedrule;?>" selected="selected"><?=$linkedrule_descr;?></option>
<?php else:?>
<option value="add-associated" <?= $pconfig['associated-rule-id'] == "add-associated" ? " selected=\"selected\"" : ""; ?>><?=gettext("Add associated filter rule"); ?></option>
<option value="add-unassociated" <?= $pconfig['associated-rule-id'] == "add-unassociated" ? " selected=\"selected\"" : ""; ?>><?=gettext("Add unassociated filter rule"); ?></option>
<?php endif;?>
<option value="pass" <?= $pconfig['associated-rule-id'] == "pass" ? " selected=\"selected\"" : ""; ?>><?=gettext("Pass"); ?></option>
</select>
<div class="hidden" data-for="help_for_fra">
<?=gettext("NOTE: The \"pass\" selection does not work properly with Multi-WAN. It will only work on an interface containing the default gateway.")?>
</div>
</td>
</tr>
<?php
$has_created_time = (isset($pconfig['created']) && is_array($pconfig['created']));
$has_updated_time = (isset($pconfig['updated']) && is_array($pconfig['updated']));
if ($has_created_time || $has_updated_time):
?>
<tr>
<td colspan="2"> </td>
</tr>
<tr>
<td colspan="2"><?=gettext("Rule Information");?></td>
</tr>
<?php if ($has_created_time): ?>
<tr>
<td><?=gettext("Created");?></td>
<td>
<?= date(gettext('n/j/y H:i:s'), (int)$pconfig['created']['time']) ?> (<?= $pconfig['created']['username'] ?>)
</td>
</tr>
<?php endif;
if ($has_updated_time):
?>
<tr>
<td><?=gettext("Updated");?></td>
<td>
<?= date(gettext('n/j/y H:i:s'), (int)$pconfig['updated']['time']) ?> (<?= $pconfig['updated']['username'] ?>)
</td>
</tr>
<?php endif;
endif;
?>
<tr>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td>
<input name="Submit" type="submit" class="btn btn-primary" value="<?=html_safe(gettext('Save')); ?>" />
<input type="button" class="btn btn-default" value="<?=html_safe(gettext('Cancel'));?>" onclick="window.location.href='/firewall_nat.php'" />
<?php if (isset($id)): ?>
<input id="entryid" name="id" type="hidden" value="<?=$id;?>" />
<?php endif; ?>
<?php if (isset($after)) : ?>
<input name="after" type="hidden" value="<?=$after;?>" />
<?php endif; ?>
</td>
</tr>
</table>
</form>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc"); ?>