diff options
Diffstat (limited to 'src/usr/local/www/firewall_nat_out_edit.php')
-rw-r--r-- | src/usr/local/www/firewall_nat_out_edit.php | 1050 |
1 files changed, 498 insertions, 552 deletions
diff --git a/src/usr/local/www/firewall_nat_out_edit.php b/src/usr/local/www/firewall_nat_out_edit.php index e99cebb..4d85609 100644 --- a/src/usr/local/www/firewall_nat_out_edit.php +++ b/src/usr/local/www/firewall_nat_out_edit.php @@ -2,37 +2,62 @@ /* $Id$ */ /* firewall_nat_out_edit.php - Copyright (C) 2004 Scott Ullrich - Copyright (C) 2013-2015 Electric Sheep Fencing, LP - All rights reserved. - - originally part of m0n0wall (http://m0n0.ch/wall) - 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. */ +/* ==================================================================== + * Copyright (c) 2004-2015 Electric Sheep Fencing, LLC. All rights reserved. + * Copyright (c) 2004 Scott Ullrich + * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net> + * Originally part of pfSense (https://www.pfsense.org) + * + * 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. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgment: + * "This product includes software developed by the pfSense Project + * for use in the pfSense software distribution. (http://www.pfsense.org/). + * + * 4. The names "pfSense" and "pfSense Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * coreteam@pfsense.org. + * + * 5. Products derived from this software may not be called "pfSense" + * nor may "pfSense" appear in their names without prior written + * permission of the Electric Sheep Fencing, LLC. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * + * "This product includes software developed by the pfSense Project + * for use in the pfSense software distribution (http://www.pfsense.org/). + * + * THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 pfSense PROJECT OR + * ITS CONTRIBUTORS 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. + * + * ==================================================================== + * + */ /* - pfSense_MODULE: nat + pfSense_MODULE: nat */ ##|+PRIV @@ -46,15 +71,8 @@ require("guiconfig.inc"); require_once("filter.inc"); require("shaper.inc"); -if (isset($_POST['referer'])) { - $referer = $_POST['referer']; -} else { - $referer = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/firewall_nat_out.php'); -} - -if (!is_array($config['nat']['outbound'])) { +if (!is_array($config['nat']['outbound'])) $config['nat']['outbound'] = array(); -} if (!is_array($config['nat']['outbound']['rule'])) { $config['nat']['outbound']['rule'] = array(); @@ -104,6 +122,7 @@ if (isset($id) && $a_out[$id]) { address_to_pconfig($a_out[$id]['destination'], $pconfig['destination'], $pconfig['destination_subnet'], $pconfig['destination_not'], $none, $none); + $pconfig['dstport'] = $a_out[$id]['dstport']; $pconfig['natport'] = $a_out[$id]['natport']; $pconfig['target'] = $a_out[$id]['target']; @@ -111,9 +130,11 @@ if (isset($id) && $a_out[$id]) { $pconfig['targetip_subnet'] = $a_out[$id]['targetip_subnet']; $pconfig['poolopts'] = $a_out[$id]['poolopts']; $pconfig['interface'] = $a_out[$id]['interface']; + if (!$pconfig['interface']) { $pconfig['interface'] = "wan"; } + $pconfig['descr'] = $a_out[$id]['descr']; $pconfig['nonat'] = $a_out[$id]['nonat']; $pconfig['disabled'] = isset($a_out[$id]['disabled']); @@ -135,6 +156,7 @@ if ($_POST) { $_POST['destination'] = "any"; $_POST['destination_subnet'] = 24; } + if ($_POST['source_type'] == "any") { $_POST['source'] = "any"; $_POST['source_subnet'] = 24; @@ -196,21 +218,25 @@ if ($_POST) { } if (($_POST['source_type'] != "any") && ($_POST['source_type'] != "(self)")) { - if ($_POST['source'] && !is_ipaddroralias($_POST['source']) && $_POST['source'] <> "any") { + if ($_POST['source'] && !is_ipaddroralias($_POST['source']) && $_POST['source'] != "any") { $input_errors[] = gettext("A valid source must be specified."); } } + if ($_POST['source_subnet'] && !is_numericint($_POST['source_subnet'])) { $input_errors[] = gettext("A valid source bit count must be specified."); } + if ($_POST['destination_type'] != "any") { if ($_POST['destination'] && !is_ipaddroralias($_POST['destination'])) { $input_errors[] = gettext("A valid destination must be specified."); } } + if ($_POST['destination_subnet'] && !is_numericint($_POST['destination_subnet'])) { $input_errors[] = gettext("A valid destination bit count must be specified."); } + if ($_POST['destination_type'] == "any") { if ($_POST['destination_not']) { $input_errors[] = gettext("Negating destination address of \"any\" is invalid."); @@ -225,6 +251,7 @@ if ($_POST) { if (!is_ipaddr($_POST['targetip'])) { $input_errors[] = gettext("A valid target IP must be specified when using the 'Other Subnet' type."); } + if (!is_numericint($_POST['targetip_subnet'])) { $input_errors[] = gettext("A valid target bit count must be specified when using the 'Other Subnet' type."); } @@ -270,13 +297,10 @@ if ($_POST) { } if (!$natent['interface']) { - $natent['interface'] == "wan"; + $natent['interface'] = "wan"; } } - // Allow extending of the firewall edit page and include custom input validation - pfSense_handle_custom_code("/usr/local/pkg/firewall_aon/input_validation"); - if (!$input_errors) { $natent = array(); $natent['source']['network'] = $osn; @@ -372,534 +396,456 @@ $pgtitle = array(gettext("Firewall"), gettext("NAT"), gettext("Outbound"), gette $closehead = false; include("head.inc"); -?> +function build_target_list() { + global $config, $sn, $a_aliases; + $list = array(); -<script type="text/javascript" src="/javascript/suggestions.js"></script> -<script type="text/javascript" src="/javascript/autosuggest.js?rev=1"></script> -<script type="text/javascript"> -//<![CDATA[ -var portsenabled = 1; -function staticportchange() { - if (document.iform.staticnatport.checked) { - document.iform.natport.value = ""; - document.iform.natport.disabled = 1; - } else { - document.iform.natport.disabled = 0; - } -} -function typesel_change() { - switch (document.iform.destination_type.selectedIndex) { - case 1: // network - document.iform.destination.disabled = 0; - document.iform.destination_subnet.disabled = 0; - break; - default: - document.iform.destination.value = ""; - document.iform.destination.disabled = 1; - document.iform.destination_subnet.value = "24"; - document.iform.destination_subnet.disabled = 1; - break; + $list[""] = 'Interface Address'; + + if (is_array($config['virtualip']['vip'])) { + foreach ($config['virtualip']['vip'] as $sn) { + if (isset($sn['noexpand'])) + continue; + + if ($sn['mode'] == "proxyarp" && $sn['type'] == "network") { + $start = ip2long32(gen_subnet($sn['subnet'], $sn['subnet_bits'])); + $end = ip2long32(gen_subnet_max($sn['subnet'], $sn['subnet_bits'])); + $len = $end - $start; + $list[$sn['subnet'] . '/' . $sn['subnet_bits']] = 'Subnet: ' . $sn['subnet'] . '/' . $sn['subnet_bits'] . ' (' . $sn['descr'] . ')'; + + for ($i = 0; $i <= $len; $i++) { + $snip = long2ip32($start+$i); + + $list[$snip] = $snip . ' (' . $sn['descr'] . ')'; + } + } else { + $list[$sn['subnet']] = $sn['subnet'] . ' (' . $sn['descr'] . ')'; + } + } } -} -function sourcesel_change() { - switch (document.iform.source_type.selectedIndex) { - case 2: // network - document.iform.source.disabled = 0; - document.iform.source_subnet.disabled = 0; - break; - default: - document.iform.source.value = ""; - document.iform.source.disabled = 1; - document.iform.source_subnet.value = "24"; - document.iform.source_subnet.disabled = 1; - break; + + foreach ($a_aliases as $alias) { + if ($alias['type'] != "host") + continue; + + $list[$alias['name']] = 'Host Alias: ' . $alias['name'] . ' (' . $alias['descr'] . ')'; } + + $list['other-subnet'] = 'Other Subnet (Enter Below)'; + + return($list); } -function nonat_change() { - if (document.iform.nonat.checked) { - document.getElementById("transtable").style.display = 'none'; - } else { - document.getElementById("transtable").style.display = ''; - } + +if ($input_errors) + print_input_errors($input_errors); + +require('classes/Form.class.php'); + +$form = new Form(new Form_Button( + 'Submit', + gettext("Save") +)); + +$section = new Form_Section('Edit Advanced Outbound NAT entry'); + +$section->addInput(new Form_Checkbox( + 'disabled', + 'Disabled', + 'Disable this rule', + $pconfig['disabled'] +)); + +$section->addInput(new Form_Checkbox( + 'nonat', + 'Do not NAT', + 'Enabling this option will disable NAT for traffic matching this rule and stop processing Outbound NAT rules', + $pconfig['nonat'] +))->setHelp('In most cases this option is not required'); + +$iflist = get_configured_interface_with_descr(false, true); + +foreach ($iflist as $if => $ifdesc) + if(have_ruleint_access($if)) + $interfaces[$if] = $ifdesc; + +if ($config['l2tp']['mode'] == "server") + if(have_ruleint_access("l2tp")) + $interfaces['l2tp'] = "L2TP VPN"; + +if ($config['pptpd']['mode'] == "server") + if(have_ruleint_access("pptp")) + $interfaces['pptp'] = "PPTP VPN"; + +if (is_pppoe_server_enabled() && have_ruleint_access("pppoe")) + $interfaces['pppoe'] = "PPPoE Server"; + +/* add ipsec interfaces */ +if (isset($config['ipsec']['enable']) || isset($config['ipsec']['client']['enable'])) + if(have_ruleint_access("enc0")) + $interfaces["enc0"] = "IPsec"; + +/* add openvpn/tun interfaces */ +if ($config['openvpn']["openvpn-server"] || $config['openvpn']["openvpn-client"]) + $interfaces["openvpn"] = "OpenVPN"; + +$section->addInput(new Form_Select( + 'interface', + 'Interface', + $pconfig['interface'], + $interfaces +))->setHelp('Choose which interface this rule applies to. In most cases "WAN" is specified.'); + +$protocols = "any TCP UDP TCP/UDP ICMP ESP AH GRE IPV6 IGMP carp pfsync"; + +$section->addInput(new Form_Select( + 'protocol', + 'Protocol', + $pconfig['protocol'], + array_combine(explode(" ", strtolower($protocols)), explode(" ", $protocols)) +))->setHelp('Choose which protocol this rule should match. In most cases "any" is specified.'); + +$group = new Form_Group('Source'); + +$group->add(new Form_Select( + 'source_type', + null, + $pconfig['source_type'], + array('any' => 'Any', '(self)' => 'This Firewall (self)', 'network' => 'Network') +))->setHelp('Type')->setWidth('3'); + +$group->add(new Form_IpAddress( + 'source', + null, + $pconfig['source'] +))->addMask('source_subnet', $pconfig['source_subnet'])->setHelp('Source network for the outbound NAT mapping.'); + +$group->add(new Form_Input( + 'sourceport', + null, + 'number', + $pconfig['sourceport'], + ['min' => '1', 'max' => '65536'] +))->setHelp('Port')->setWidth('2'); + +$section->add($group); + +$group = new Form_Group('Destination'); + +$group->add(new Form_Select( + 'destination_type', + null, + $pconfig['destination'] == "any" ? "any":"network", + array('any' => 'Any', 'network' => 'Network') +))->setHelp('Type')->setWidth('3'); + +$group->add(new Form_IpAddress( + 'destination', + null, + $pconfig['destination'] == "any" ? "":$pconfig['destination'] +))->addMask('destination_subnet', $pconfig['destination_subnet'])->setHelp('Destination network for the outbound NAT mapping.'); + +$group->add(new Form_Input( + 'dstport', + null, + 'number', + $pconfig['dstport'], + ['min' => '1', 'max' => '65536'] +))->setHelp('Port')->setWidth('2'); + +$section->add($group); + +$section->addInput(new Form_Checkbox( + 'destination_not', + null, + 'Not', + $pconfig['destination_not'] +))->setHelp('Invert the sense of the destination match'); + +$form->add($section); + +$section = new Form_Section('Translation'); +$section->addClass('translation'); + +$section->addInput(new Form_Select( + 'target', + 'Address', + $pconfig['target'], + build_target_list() +)); + +$section->addInput(new Form_IpAddress( + 'targetip', + 'Other subnet', + $pconfig['targetip'] +))->addMask('targetip_subnet', $pconfig['targetip_subnet'])->addClass('othersubnet')->setHelp( + 'Packets matching this rule will be mapped to the IP address given here.' . '<br />' . + 'If you want this rule to apply to another IP address rather than the IP address of the interface chosen above, ' . + 'select it here (you will need to define ' . + '<a href="firewall_virtual_ip.php">' . gettext("Virtual IP") . '</a> ' . + 'addresses on the interface first)'); + +$section->addInput(new Form_Select( + 'poolopts', + 'Pool options', + $pconfig['poolopts'], + array( + '' => 'Default', + 'round-robin' => 'Round Robin', + 'round-robin sticky-address' => 'Round Robin with Sticky Address', + 'random' => 'Random', + 'random sticky-address' => 'Random with Sticky Address', + 'source-hash' => 'Source hash', + 'bitmask' => 'Bit mask' + ) +))->setHelp('Only Round Robin types work with Host Aliases. Any type can be used with a Subnet.' . '<br />' . + '<ul>' . + '<li>' . 'Round Robin: Loops through the translation addresses.' . '</li>' . '<br />' . + '<li>' . 'Random: Selects an address from the translation address pool at random.' . '</li>' . '<br />' . + '<li>' . '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.' . '</li>' . '<br />' . + '<li>' . 'Bitmask: Applies the subnet mask and keeps the last portion identical; 10.0.1.50 -> x.x.x.50.' . '</li>' . '<br />' . + '<li>' . '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.' . '</li>' . + '</ul>'); + +$group = new Form_Group('Port'); +$group->addClass('natportgrp'); + +$group->add(new Form_Input( + 'natport', + null, + 'number', + $pconfig['natport'], + ['min' => '1', 'max' => '65536'] +))->setHelp('Enter the source port for the outbound NAT mapping.'); + +$group->add(new Form_Checkbox( + 'staticnatport', + null, + 'Static port', + $pconfig['staticnatport'] +)); + +$section->add($group); +$form->add($section); + +$section = new Form_Section('Misc'); + +$section->addInput(new Form_Checkbox( + 'nosync', + 'No XMLRPC Sync', + null, + $pconfig['nosync'], + 'yes' +))->setHelp('Prevents the rule on Master from automatically syncing to other CARP members. ' . + 'This does NOT prevent the rule from being overwritten on Slave.'); + +$section->addInput(new Form_Input( + 'descr', + 'Description', + 'text', + $pconfig['descr'] +))->setHelp('You may enter a description here for your reference (not parsed).'); + +if (isset($id) && $a_out[$id]) { + $section->addInput(new Form_Input( + 'id', + null, + 'hidden', + $id + )); } -function proto_change() { - if (document.iform.protocol.selectedIndex >= 0 && document.iform.protocol.selectedIndex <= 3) { - portsenabled = 1; - } else { - portsenabled = 0; - } - if (portsenabled) { - document.getElementById("sport_tr").style.display = ''; - document.getElementById("dport_tr").style.display = ''; - document.getElementById("tport_tr").style.display = ''; - document.getElementById("tporttext_tr").style.display = ''; - document.getElementById("tportstatic_tr").style.display = ''; - } else { - document.getElementById("sport_tr").style.display = 'none'; - document.getElementById("dport_tr").style.display = 'none'; - document.getElementById("tport_tr").style.display = 'none'; - document.getElementById("tporttext_tr").style.display = 'none'; - document.getElementById("tportstatic_tr").style.display = 'none'; +$section->addInput(new Form_Input( + 'after', + null, + 'hidden', + $after +)); + +$form->add($section); + +$has_created_time = (isset($a_out[$id]['created']) && is_array($a_out[$id]['created'])); +$has_updated_time = (isset($a_out[$id]['updated']) && is_array($a_out[$id]['updated'])); + +if ($has_created_time || $has_updated_time) { + $section = new Form_Section('Rule Information'); + + if($has_created_time) { + $section->addInput(new Form_StaticText( + 'Created', + date(gettext("n/j/y H:i:s"), $a_out[$id]['created']['time']) . gettext("by") . $a_out[$id]['created']['username'] + )); } -} -function poolopts_change() { - if (jQuery('#target option:selected').text().trim().substring(0, 4) == "Host") { - jQuery('#poolopts_tr').css('display', ''); - jQuery('#target_network').css('display', 'none'); - } else if (jQuery('#target option:selected').text().trim().substring(0, 6) == "Subnet") { - jQuery('#poolopts_tr').css('display', ''); - jQuery('#target_network').css('display', 'none'); - } else if (jQuery('#target option:selected').text().trim().substring(0, 5) == "Other") { - jQuery('#poolopts_tr').css('display', ''); - jQuery('#target_network').css('display', ''); - } else { - jQuery('#poolopts').prop('selectedIndex', 0); - jQuery('#poolopts_tr').css('display', 'none'); - jQuery('#target_network').css('display', 'none'); - jQuery('#targetip').val(''); - jQuery('#targetip_subnet').val('0'); + + if($has_updated_time) { + $section->addInput(new Form_StaticText( + 'Updated', + date(gettext("n/j/y H:i:s"), $a_out[$id]['updated']['time']) . gettext("by") . $a_out[$id]['updated']['username'] + )); } + + $form->add($section); } -//]]> -</script> -</head> - -<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> -<?php include("fbegin.inc"); ?> -<?php if ($input_errors) print_input_errors($input_errors); ?> -<form action="firewall_nat_out_edit.php" method="post" name="iform" id="iform"> - <table width="100%" border="0" cellpadding="6" cellspacing="1" summary="firewall nat outbound edit"> - <tr> - <td colspan="2" valign="top" class="listtopic"><?=gettext("Edit Advanced Outbound NAT entry");?></td> - </tr> -<?php - // Allow extending of the firewall edit page and include custom input validation - pfSense_handle_custom_code("/usr/local/pkg/firewall_rules/htmlphpearly"); -?> - <tr> - <td width="22%" valign="top" class="vncellreq"><?=gettext("Disabled");?></td> - <td width="78%" class="vtable"> - <input name="disabled" type="checkbox" id="disabled" value="yes" <?php if ($pconfig['disabled']) echo "checked=\"checked\""; ?> /> - <strong><?=gettext("Disable this rule");?></strong><br /> - <span class="vexpl"><?=gettext("Set this option to disable this rule without removing it from the list.");?></span> - </td> - </tr> - <tr> - <td width="22%" valign="top" class="vncell"><?=gettext("Do not NAT");?></td> - <td width="78%" class="vtable"> - <input type="checkbox" name="nonat" id="nonat" onclick="nonat_change();" <?php if (isset($pconfig['nonat'])) echo " checked=\"checked\""; ?> /> - <span class="vexpl"><?=gettext("Enabling this option will disable NAT for traffic matching this rule and stop processing Outbound NAT rules.");?> - <br /><?=gettext("Hint: in most cases, you won't use this option.");?></span> - </td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq"><?=gettext("Interface");?></td> - <td width="78%" class="vtable"> - <select name="interface" class="formselect"> -<?php - $iflist = get_configured_interface_with_descr(false, true); - foreach ($iflist as $if => $ifdesc) { - if (have_ruleint_access($if)) { - $interfaces[$if] = $ifdesc; - } - } - - if ($config['l2tp']['mode'] == "server") { - if (have_ruleint_access("l2tp")) { - $interfaces['l2tp'] = "L2TP VPN"; - } - } - - if ($config['pptpd']['mode'] == "server") { - if (have_ruleint_access("pptp")) { - $interfaces['pptp'] = "PPTP VPN"; - } - } - - if (is_pppoe_server_enabled() && have_ruleint_access("pppoe")) { - $interfaces['pppoe'] = "PPPoE Server"; - } - - /* add ipsec interfaces */ - if (isset($config['ipsec']['enable']) || isset($config['ipsec']['client']['enable'])) { - if (have_ruleint_access("enc0")) { - $interfaces["enc0"] = "IPsec"; - } - } - - /* add openvpn/tun interfaces */ - if ($config['openvpn']["openvpn-server"] || $config['openvpn']["openvpn-client"]) { - $interfaces["openvpn"] = "OpenVPN"; - } - - foreach ($interfaces as $iface => $ifacename): -?> - <option value="<?=$iface;?>" <?php if ($iface == $pconfig['interface']) echo "selected=\"selected\""; ?>> - <?=htmlspecialchars($ifacename);?> - </option> -<?php - endforeach; -?> - </select><br /> - <span class="vexpl"><?=gettext("Choose which interface this rule applies to.");?><br /> - <?=gettext("Hint: in most cases, you'll want to use WAN here.");?> - </span> - </td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq"><?=gettext("Protocol");?></td> - <td width="78%" class="vtable"> - <select name="protocol" class="formselect" onchange="proto_change();"> -<?php - $protocols = explode(" ", "any TCP UDP TCP/UDP ICMP ESP AH GRE IPV6 IGMP carp pfsync"); - foreach ($protocols as $proto): -?> - <option value="<?=strtolower($proto);?>" <?php if (strtolower($proto) == $pconfig['protocol']) echo "selected=\"selected\""; ?>><?=htmlspecialchars($proto);?></option> -<?php - endforeach; -?> - </select><br /> - <span class="vexpl"><?=gettext("Choose which protocol this rule should match.");?><br /> -<?php - printf(gettext("Hint: in most cases, you should specify %s any %s here."), "<em>", "</em> "); -?> - </span> - </td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq"><?=gettext("Source");?></td> - <td width="78%" class="vtable"> - <table border="0" cellspacing="1" cellpadding="1" summary="source"> - <tr> - <td><?=gettext("Type:");?> </td> - <td> - <select name="source_type" class="formselect" onchange="sourcesel_change()"> - <option value="any" <?php if ($pconfig['source'] == "any") echo "selected=\"selected\""; ?>><?=gettext("any");?></option> - <option value="(self)" <?PHP if ($pconfig['source'] == "(self)") echo "selected=\"selected\""; ?>><?=gettext("This Firewall (self)");?></option> - <option value="network" <?php if (($pconfig['source'] != "any") && ($pconfig['source'] != "(self)")) echo "selected=\"selected\""; ?>><?=gettext("Network");?></option> - </select> - </td> - </tr> - <tr> - <td><?=gettext("Address:");?> </td> - <td> - <input name="source" type="text" autocomplete="off" class="formfldalias" id="source" size="20" value="<?=htmlspecialchars($pconfig['source']);?>" />/ - <select name="source_subnet" class="formfld" id="source_subnet"> -<?php - for ($i = 32; $i >= 0; $i--): -?> - <option value="<?=$i;?>"<?php if ($i == $pconfig['source_subnet']) echo " selected=\"selected\""; ?>><?=$i;?></option> -<?php - endfor; -?> - </select> - </td> - </tr> - <tr> - <td> </td> - <td> - <span class="vexpl"><?=gettext("Enter the source network for the outbound NAT mapping.");?></span> - </td> - </tr> - <tr name="sport_tr" id="sport_tr"> - <td><?=gettext("Source port:");?> </td> - <td> - <input name="sourceport" type="text" autocomplete="off" class="formfldalias" id="sourceport" size="5" value="<?=htmlspecialchars($pconfig['sourceport']);?>" /> - <?=gettext("(leave blank for any)");?> - </td> - </tr> - </table> - </td> - </tr> - <tr> - <td width="22%" valign="top" class="vncellreq"><?=gettext("Destination");?></td> - <td width="78%" class="vtable"> - <input name="destination_not" type="checkbox" id="destination_not" value="yes" <?php if ($pconfig['destination_not']) echo "checked=\"checked\""; ?> /> - <strong><?=gettext("not");?></strong><br /> - <?=gettext("Use this option to invert the sense of the match.");?><br /> - <br /> - <table border="0" cellspacing="1" cellpadding="1" summary="destination"> - <tr> - <td><?=gettext("Type:");?> </td> - <td> - <select name="destination_type" class="formselect" onchange="typesel_change()"> - <option value="any"<?php if ($pconfig['destination'] == "any") echo " selected=\"selected\""; ?>> - <?=gettext("any");?> - </option> - <option value="network"<?php if ($pconfig['destination'] != "any") echo " selected=\"selected\""; ?>> - <?=gettext("Network");?> - </option> - </select> - </td> - </tr> - <tr> - <td><?=gettext("Address:");?> </td> - <td> - <input name="destination" type="text" autocomplete="off" class="formfldalias" id="destination" size="20" value="<?=htmlspecialchars($pconfig['destination']);?>" />/ - <select name="destination_subnet" class="formselect" id="destination_subnet"> -<?php - for ($i = 32; $i >= 0; $i--): -?> - <option value="<?=$i;?>"<?php if ($i == $pconfig['destination_subnet']) echo " selected=\"selected\""; ?>><?=$i;?></option> -<?php - endfor; -?> - </select> - </td> - </tr> - <tr> - <td> </td> - <td> - <span class="vexpl"><?=gettext("Enter the destination network for the outbound NAT mapping.");?></span> - </td> - </tr> - <tr name="dport_tr" id="dport_tr"> - <td><?=gettext("Destination port:");?> </td> - <td> - <input name="dstport" type="text" autocomplete="off" class="formfldalias" id="dstport" size="5" value="<?=htmlspecialchars($pconfig['dstport']);?>" /> - <?=gettext("(leave blank for any)");?> - </td> - </tr> - </table> - </td> - </tr> - <tr name="transtable" id="transtable"> - <td width="22%" valign="top" class="vncell"><?=gettext("Translation");?></td> - <td width="78%" class="vtable"> - <table border="0" cellspacing="1" cellpadding="1" summary="translation"> - <tr> - <td><?=gettext("Address:");?> </td> - <td> - <select name="target" class="formselect" id="target" onchange="poolopts_change();"> - <option value=""<?php if (!$pconfig['target']) echo " selected=\"selected\""; ?>> - <?=gettext("Interface address");?> - </option> -<?php - if (is_array($config['virtualip']['vip'])): - foreach ($config['virtualip']['vip'] as $sn): - if (isset($sn['noexpand'])) { - continue; - } - if ($sn['mode'] == "proxyarp" && $sn['type'] == "network"): - $start = ip2long32(gen_subnet($sn['subnet'], $sn['subnet_bits'])); - $end = ip2long32(gen_subnet_max($sn['subnet'], $sn['subnet_bits'])); - $len = $end - $start; -?> - <option value="<?=$sn['subnet'].'/'.$sn['subnet_bits'];?>" <?php if ($sn['subnet'].'/'.$sn['subnet_bits'] == $pconfig['target']) echo "selected=\"selected\""; ?>> - <?=htmlspecialchars("Subnet: {$sn['subnet']}/{$sn['subnet_bits']} ({$sn['descr']})");?> - </option> -<?php - for ($i = 0; $i <= $len; $i++): - $snip = long2ip32($start+$i); -?> - <option value="<?=$snip;?>" <?php if ($snip == $pconfig['target']) echo "selected"; ?>> - <?=htmlspecialchars("{$snip} ({$sn['descr']})");?> - </option> -<?php - endfor; -?> -<?php - else: -?> - <option value="<?=$sn['subnet'];?>" <?php if ($sn['subnet'] == $pconfig['target']) echo "selected=\"selected\""; ?>> - <?=htmlspecialchars("{$sn['subnet']} ({$sn['descr']})");?> - </option> -<?php - endif; - endforeach; - endif; - foreach ($a_aliases as $alias): - if ($alias['type'] != "host") { - continue; - } -?> - <option value="<?=$alias['name'];?>" <?php if ($alias['name'] == $pconfig['target']) echo "selected=\"selected\""; ?>> - <?=htmlspecialchars("Host Alias: {$alias['name']} ({$alias['descr']})");?> - </option> -<?php - endforeach; -?> - <option value="other-subnet"<?php if ($pconfig['target'] == "other-subnet") echo " selected=\"selected\""; ?>> - <?=gettext("Other Subnet (Enter Below)");?> - </option> - </select> - </td> - </tr> - - <tr id="target_network"> - <td><?=gettext("Other Subnet:");?> </td> - <td> - <input name="targetip" type="text" class="formfld unknown" id="targetip" size="20" value="<?=htmlspecialchars($pconfig['targetip']);?>" />/ - <select name="targetip_subnet" class="formfld" id="targetip_subnet"> -<?php - for ($i = 32; $i >= 0; $i--): -?> - <option value="<?=$i;?>"<?php if ($i == $pconfig['targetip_subnet']) echo " selected=\"selected\""; ?>><?=$i;?></option> -<?php - endfor; -?> - </select> - </td> - </tr> - - <tr> - <td> </td> - <td> - <span class="vexpl"><?=gettext("Packets matching this rule will be mapped to the IP address given here.");?><br /> - <?=gettext("If you want this rule to apply to another IP address rather than the IP address of the interface chosen above, ". - "select it here (you will need to define ");?> - <a href="firewall_virtual_ip.php"><?=gettext("Virtual IP");?></a> - <?=gettext("addresses on the interface first).");?> - </span><br /> - </td> - </tr> - <tr id="poolopts_tr"> - <td valign="top">Pool Options</td> - <td> - <select name="poolopts" id="poolopts"> - <option value="" <?php if ($pconfig['poolopts'] == "") echo "selected=\"selected\""; ?>> - <?=htmlspecialchars("Default");?> - </option> - <option value="round-robin" <?php if ($pconfig['poolopts'] == "round-robin") echo "selected=\"selected\""; ?>> - <?=htmlspecialchars("Round Robin");?> - </option> - <option value="round-robin sticky-address" <?php if ($pconfig['poolopts'] == "round-robin sticky-address") echo "selected=\"selected\""; ?>> - <?=htmlspecialchars("Round Robin with Sticky Address");?> - </option> - <option value="random" <?php if ($pconfig['poolopts'] == "random") echo "selected=\"selected\""; ?>> - <?=htmlspecialchars("Random");?> - </option> - <option value="random sticky-address" <?php if ($pconfig['poolopts'] == "random sticky-address") echo "selected=\"selected\""; ?>> - <?=htmlspecialchars("Random with Sticky Address");?> - </option> - <option value="source-hash" <?php if ($pconfig['poolopts'] == "source-hash") echo "selected=\"selected\""; ?>> - <?=htmlspecialchars("Source Hash");?> - </option> - <option value="bitmask" <?php if ($pconfig['poolopts'] == "bitmask") echo "selected=\"selected\""; ?>> - <?=htmlspecialchars("Bitmask");?> - </option> - </select> - <br /> - <span class="vexpl"> - <?=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 /> - </span><br /> - </td> - </tr> - <tr name="tport_tr" id="tport_tr"> - <td><?=gettext("Port:");?> </td> - <td> - <input name="natport" type="text" class="formfld unknown" id="natport" size="5" value="<?=htmlspecialchars($pconfig['natport']);?>" /> - </td> - </tr> - <tr name="tporttext_tr" id="tporttext_tr"> - <td> </td> - <td> - <span class="vexpl"><?=gettext("Enter the source port for the outbound NAT mapping.");?></span> - </td> - </tr> - <tr name="tportstatic_tr" id="tportstatic_tr"> - <td><?=gettext("Static-port:");?> </td> - <td> - <input onchange="staticportchange();" name="staticnatport" type="checkbox" class="formfld" id="staticnatport" size="5"<?php if ($pconfig['staticnatport']) echo " checked=\"checked\"";?> /> - </td> - </tr> - </table> - </td> - </tr> - <tr> - <td width="22%" valign="top" class="vncell"><?=gettext("No XMLRPC Sync");?></td> - <td width="78%" class="vtable"> - <input value="yes" name="nosync" type="checkbox" class="formfld" id="nosync"<?php if ($pconfig['nosync']) echo " checked=\"checked\""; ?> /><br /> - <?=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.");?> - </td> - </tr> - <tr> - <td width="22%" valign="top" class="vncell"><?=gettext("Description");?></td> - <td width="78%" class="vtable"> - <input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>" /> - <br /> - <span class="vexpl"><?=gettext("You may enter a description here for your reference (not parsed).");?></span> - </td> - </tr> -<?php - $has_created_time = (isset($a_out[$id]['created']) && is_array($a_out[$id]['created'])); - $has_updated_time = (isset($a_out[$id]['updated']) && is_array($a_out[$id]['updated'])); - if ($has_created_time || $has_updated_time): -?> - <tr> - <td> </td> - </tr> - <tr> - <td colspan="2" valign="top" class="listtopic"><?=gettext("Rule Information");?></td> - </tr> -<?php - if ($has_created_time): -?> - <tr> - <td width="22%" valign="top" class="vncell"><?=gettext("Created");?></td> - <td width="78%" class="vtable"> - <?= date(gettext("n/j/y H:i:s"), $a_out[$id]['created']['time']) ?> <?= gettext("by") ?> <strong><?= $a_out[$id]['created']['username'] ?></strong> - </td> - </tr> -<?php - endif; - if ($has_updated_time): -?> - <tr> - <td width="22%" valign="top" class="vncell"><?=gettext("Updated");?></td> - <td width="78%" class="vtable"> - <?= date(gettext("n/j/y H:i:s"), $a_out[$id]['updated']['time']) ?> <?= gettext("by") ?> <strong><?= $a_out[$id]['updated']['username'] ?></strong> - </td> - </tr> -<?php - endif; - endif; - // Allow extending of the firewall edit page and include custom input validation - pfSense_handle_custom_code("/usr/local/pkg/firewall_aon/htmlphplate"); -?> - <tr> - <td width="22%" valign="top"> </td> - <td width="78%"> - <input name="Submit" type="submit" class="formbtn" value="<?=gettext("Save"); ?>" /> - <input type="button" class="formbtn" value="<?=gettext("Cancel");?>" onclick="window.location.href='<?=$referer;?>'" /> - <input name="referer" type="hidden" value="<?=$referer;?>" /> -<?php - if (isset($id) && $a_out[$id]): -?> - <input name="id" type="hidden" value="<?=htmlspecialchars($id);?>" /> -<?php - endif; +print($form); + ?> - <input name="after" type="hidden" value="<?=htmlspecialchars($after);?>" /> - </td> - </tr> - </table> -</form> + <script type="text/javascript"> //<![CDATA[ +events.push(function(){ + var portsenabled = 1; + + // Hides the <div> in which the specified input element lives so that the input, its label and help text are hidden + function hideInput(id, hide) { + if(hide) + $('#' + id).parent().parent('div').addClass('hidden'); + else + $('#' + id).parent().parent('div').removeClass('hidden'); + } + + // Hides the <div> in which the specified group input element lives so that the input, + // its label and help text are hidden + function hideGroupInput(id, hide) { + if(hide) + $('#' + id).parent('div').addClass('hidden'); + else + $('#' + id).parent('div').removeClass('hidden'); + } + + // Hides the <div> in which the specified checkbox lives so that the checkbox, its label and help text are hidden + function hideCheckbox(id, hide) { + if(hide) + $('#' + id).parent().parent().parent('div').addClass('hidden'); + else + $('#' + id).parent().parent().parent('div').removeClass('hidden'); + } + + // Disables the specified input element + function disableInput(id, disable) { + $('#' + id).prop("disabled", disable); + } + + // Hides all elements of the specified class. This will usually be a section + function hideClass(s_class, hide) { + if(hide) + $('.' + s_class).hide(); + else + $('.' + s_class).show(); + } + + // Hides all elements of the specified class assigned to a group. This will usually be a group + function hideGroupClass(s_class, hide) { + if(hide) + $('.' + s_class).parent().parent().parent().hide(); + else + $('.' + s_class).parent().parent().parent().show(); + } + + function staticportchange() { + if($('#staticnatport').prop('checked')) { + $('#natport').val(""); + disableInput('natport' , true); + } else { + disableInput('natport' , false); + } + } + + function sourcesel_change() { + if($('#source_type').find(":selected").val() == "network") { + disableInput('source', false); + disableInput('source_subnet', false); + } + else { + $('#source').val(""); + disableInput('source', true); + $('#source_subnet').val("24"); + disableInput('source_subnet', true); + } + } + + function typesel_change() { + if($('#destination_type').find(":selected").val() == "network") { + disableInput('destination', false); + disableInput('destination_subnet', false); + } + else { + $('#destination').val(""); + disableInput('destination', true); + $('#destination_subnet').val("24"); + disableInput('destination_subnet', true); + } + } + + function nonat_change() { + hideClass('translation', $('#nonat').prop('checked')); + } + + function proto_change() { + if( ($('#protocol').find(":selected").index() > 0) && ($('#protocol').find(":selected").index() <= 3) ) { + hideGroupInput('sourceport', false); + hideGroupInput('dstport', false); + hideClass('natportgrp', false); + } else { + hideGroupInput('sourceport', true); + hideGroupInput('dstport', true); + hideClass('natportgrp', true); + } + } + + function poolopts_change() { + if ($('#target option:selected').text().trim().substring(0,4) == "Host") { + hideInput('poolopts', false); + hideGroupClass('othersubnet', true); + } else if ($('#target option:selected').text().trim().substring(0,6) == "Subnet") { + hideInput('poolopts', false); + hideGroupClass('othersubnet', true); + } else if ($('#target option:selected').text().trim().substring(0,5) == "Other") { + hideInput('poolopts', false); + hideGroupClass('othersubnet', false); + } else { + $('#poolopts').prop('selectedIndex',0); + hideInput('poolopts', true); + hideGroupClass('othersubnet', true); + $('#targetip').val(''); + $('#targetip_subnet').val('0'); + } + } + + // When controls are clicked . . + $('#staticnatport').click(function () { + staticportchange(); + }); + + $('#source_type').on('change', function() { + sourcesel_change(); + }); + + $('#destination_type').on('change', function() { + typesel_change(); + }); + + $('#nonat').on('change', function() { + nonat_change(); + }); + + $('#protocol').on('change', function() { + proto_change(); + }); + + $('#target').on('change', function() { + poolopts_change(); + }); + + // Set initial states + staticportchange(); sourcesel_change(); typesel_change(); - staticportchange(); nonat_change(); proto_change(); poolopts_change(); - var addressarray = <?= json_encode(get_alias_list(array("host", "network", "openvpn", "urltable"))) ?>; - var customarray = <?= json_encode(get_alias_list(array("port", "url_ports", "urltable_ports"))) ?>; - - var oTextbox1 = new AutoSuggestControl(document.getElementById("source"), new StateSuggestions(addressarray)); - var oTextbox2 = new AutoSuggestControl(document.getElementById("sourceport"), new StateSuggestions(customarray)); - var oTextbox3 = new AutoSuggestControl(document.getElementById("destination"), new StateSuggestions(addressarray)); - var oTextbox4 = new AutoSuggestControl(document.getElementById("dstport"), new StateSuggestions(customarray)); +}); //]]> </script> -<?php include("fend.inc"); ?> -</body> -</html> + +<?php include("foot.inc");
\ No newline at end of file |