* 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("services.inc"); require_once("interfaces.inc"); $a_gateways = return_gateways_array(true, false, true); $a_gateways_arr = array(); foreach ($a_gateways as $gw) { $a_gateways_arr[] = $gw; } $a_gateways = $a_gateways_arr; $dpinger_default = return_dpinger_defaults(); // form processing if ($_SERVER['REQUEST_METHOD'] === 'POST') { $pconfig = $_POST; if (isset($pconfig['id']) && isset($a_gateways[$pconfig['id']])) { $id = $pconfig['id']; } $input_errors = array(); /* input validation */ $reqdfields = explode(" ", "name interface"); $reqdfieldsn = array(gettext("Name"), gettext("Interface")); do_input_validation($pconfig, $reqdfields, $reqdfieldsn, $input_errors); if (!isset($pconfig['name'])) { $input_errors[] = gettext("A valid gateway name must be specified."); } $valid = is_validaliasname($pconfig['name']); if ($valid === false) { $input_errors[] = sprintf(gettext('The name must be less than 32 characters long and may only consist of the following characters: %s'), 'a-z, A-Z, 0-9, _'); } elseif ($valid === null) { $input_errors[] = sprintf(gettext('The name cannot be the internally reserved keyword "%s".'), $pconfig['name']); } /* skip system gateways which have been automatically added */ if (!empty($pconfig['gateway']) && !is_ipaddr($pconfig['gateway']) && $pconfig['attribute'] !== "system" && $pconfig['gateway'] != "dynamic") { $input_errors[] = gettext("A valid gateway IP address must be specified."); } if (!empty($pconfig['gateway']) && is_ipaddr($pconfig['gateway'])) { if (is_ipaddrv4($pconfig['gateway'])) { list ($parent_ip, $parent_sn) = explode('/', find_interface_network(get_real_interface($pconfig['interface']), false)); $parent_ip = empty($pconfig['ajaxip']) ? $parent_ip : $pconfig['ajaxip']; $parent_sn = empty($pconfig['ajaxnet']) ? $parent_sn : $pconfig['ajaxnet']; if (empty($parent_ip) || empty($parent_sn)) { $input_errors[] = gettext("Cannot add IPv4 Gateway Address because no IPv4 address could be found on the interface."); } else { $subnets = array(gen_subnet($parent_ip, $parent_sn) . "/" . $parent_sn); $vips = link_interface_to_vips($pconfig['interface']); if (is_array($vips)) { foreach ($vips as $vip) { if (!is_ipaddrv4($vip['subnet'])) { continue; } $subnets[] = gen_subnet($vip['subnet'], $vip['subnet_bits']) . "/" . $vip['subnet_bits']; } } $found = false; foreach ($subnets as $subnet) { if (ip_in_subnet($pconfig['gateway'], $subnet)) { $found = true; break; } } if (!$found && !isset($pconfig['fargw'])) { $input_errors[] = sprintf(gettext('The gateway address "%s" does not lie within one of the chosen interface\'s IPv4 subnets.'), $pconfig['gateway']); } } } elseif (is_ipaddrv6($pconfig['gateway'])) { /* do not do a subnet match on a link local address, it's valid */ if (!is_linklocal($pconfig['gateway'])) { list ($parent_ip, $parent_sn) = explode('/', find_interface_networkv6(get_real_interface($pconfig['interface'], 'inet6'), false)); $parent_ip = empty($pconfig['ajaxip']) ? $parent_ip : $pconfig['ajaxip']; $parent_sn = empty($pconfig['ajaxnet']) ? $parent_sn : $pconfig['ajaxnet']; if (empty($parent_ip) || empty($parent_sn)) { $input_errors[] = gettext("Cannot add IPv6 Gateway Address because no IPv6 address could be found on the interface."); } else { $subnets = array(gen_subnetv6($parent_ip, $parent_sn) . "/" . $parent_sn); $vips = link_interface_to_vips($pconfig['interface']); if (is_array($vips)) { foreach ($vips as $vip) { if (!is_ipaddrv6($vip['subnet'])) { continue; } $subnets[] = gen_subnetv6($vip['subnet'], $vip['subnet_bits']) . "/" . $vip['subnet_bits']; } } $found = false; foreach ($subnets as $subnet) { if (ip_in_subnet($pconfig['gateway'], $subnet)) { $found = true; break; } } if (!$found) { $input_errors[] = sprintf(gettext('The gateway address "%s" does not lie within one of the chosen interface\'s IPv6 subnets.'), $pconfig['gateway']); } } } } if (!empty($config['interfaces'][$pconfig['interface']]['ipaddr'])) { if (is_ipaddr($config['interfaces'][$pconfig['interface']]['ipaddr']) && (empty($pconfig['gateway']) || $pconfig['gateway'] == "dynamic")) { $input_errors[] = gettext("Dynamic gateway values cannot be specified for interfaces with a static IPv4 configuration."); } } if (!empty($config['interfaces'][$pconfig['interface']]['ipaddrv6'])) { if (is_ipaddr($config['interfaces'][$pconfig['interface']]['ipaddrv6']) && (empty($pconfig['gateway']) || $pconfig['gateway'] == "dynamic")) { $input_errors[] = gettext("Dynamic gateway values cannot be specified for interfaces with a static IPv6 configuration."); } } } if (($pconfig['monitor'] != '') && !is_ipaddr($pconfig['monitor']) && $pconfig['monitor'] != 'dynamic') { $input_errors[] = gettext("A valid monitor IP address must be specified."); } /* only allow correct IPv4 and IPv6 gateway addresses */ if (!empty($pconfig['gateway']) && is_ipaddr($pconfig['gateway']) && $pconfig['gateway'] != "dynamic") { if (is_ipaddrv6($pconfig['gateway']) && ($pconfig['ipprotocol'] == "inet")) { $input_errors[] = sprintf(gettext('The IPv6 gateway address "%s" cannot be used as an IPv4 gateway.'), $pconfig['gateway']); } if (is_ipaddrv4($pconfig['gateway']) && ($pconfig['ipprotocol'] == "inet6")) { $input_errors[] = sprintf(gettext('The IPv4 gateway address "%s" can not be used as an IPv6 gateway.'), $pconfig['gateway']); } } /* only allow correct IPv4 and IPv6 monitor addresses */ if (!empty($pconfig['monitor']) && is_ipaddr($pconfig['monitor']) && $pconfig['monitor'] != "dynamic") { if (is_ipaddrv6($pconfig['monitor']) && ($pconfig['ipprotocol'] == "inet")) { $input_errors[] = sprintf(gettext('The IPv6 monitor address "%s" can not be used on an IPv4 gateway.'), $pconfig['monitor']); } if (is_ipaddrv4($pconfig['monitor']) && ($pconfig['ipprotocol'] == "inet6")) { $input_errors[] = sprintf(gettext('The IPv4 monitor address "%s" can not be used on an IPv6 gateway.'), $pconfig['monitor']); } } if (isset($pconfig['name'])) { /* check for overlaps */ foreach ($a_gateways as $gateway) { if (isset($id) && $a_gateways[$id] === $gateway) { if ($gateway['name'] != $pconfig['name']) { $input_errors[] = gettext("Changing name on a gateway is not allowed."); } continue; } if (!empty($pconfig['name'])) { if (!empty($gateway['name']) && $pconfig['name'] == $gateway['name'] && $gateway['attribute'] !== "system") { $input_errors[] = sprintf(gettext('The gateway name "%s" already exists.'), $pconfig['name']); break; } } if (is_ipaddr($pconfig['gateway'])) { if (!empty($gateway['name']) && $pconfig['gateway'] == $gateway['gateway'] && $gateway['attribute'] !== "system") { $input_errors[] = sprintf(gettext('The gateway IP address "%s" already exists.'), $pconfig['gateway']); break; } } if (is_ipaddr($pconfig['monitor'])) { if (!empty($gateway['monitor']) && $pconfig['monitor'] == $gateway['monitor'] && $gateway['attribute'] !== "system") { $input_errors[] = sprintf(gettext('The monitor IP address "%s" is already in use. You must choose a different monitor IP.'), $pconfig['monitor']); break; } } } } if (!empty($pconfig['latencylow'])) { if (!is_numeric($pconfig['latencylow'])) { $input_errors[] = gettext("The low latency threshold needs to be a numeric value."); } elseif ($pconfig['latencylow'] < 1) { $input_errors[] = gettext("The low latency threshold needs to be positive."); } } if (!empty($pconfig['latencyhigh'])) { if (!is_numeric($pconfig['latencyhigh'])) { $input_errors[] = gettext("The high latency threshold needs to be a numeric value."); } elseif ($pconfig['latencyhigh'] < 1) { $input_errors[] = gettext("The high latency threshold needs to be positive."); } } if (!empty($pconfig['losslow'])) { if (!is_numeric($pconfig['losslow'])) { $input_errors[] = gettext("The low Packet Loss threshold needs to be a numeric value."); } elseif ($pconfig['losslow'] < 1) { $input_errors[] = gettext("The low Packet Loss threshold needs to be positive."); } elseif ($pconfig['losslow'] >= 100) { $input_errors[] = gettext("The low Packet Loss threshold needs to be less than 100."); } } if (!empty($pconfig['losshigh'])) { if (!is_numeric($pconfig['losshigh'])) { $input_errors[] = gettext("The high Packet Loss threshold needs to be a numeric value."); } elseif ($pconfig['losshigh'] < 1) { $input_errors[] = gettext("The high Packet Loss threshold needs to be positive."); } elseif ($pconfig['losshigh'] > 100) { $input_errors[] = gettext("The high Packet Loss threshold needs to be 100 or less."); } } if (!empty($pconfig['latencylow']) && !empty($pconfig['latencyhigh'])) { if (is_numeric($pconfig['latencylow']) && is_numeric($pconfig['latencyhigh']) && $pconfig['latencylow'] > $pconfig['latencyhigh'] ) { $input_errors[] = gettext("The high latency threshold needs to be higher than the low latency threshold"); } } elseif (!empty($pconfig['latencylow'])) { if (is_numeric($pconfig['latencylow']) && $pconfig['latencylow'] > $dpinger_default['latencyhigh']) { $input_errors[] = sprintf(gettext('The low latency threshold needs to be less than the default high latency threshold (%d)'), $dpinger_default['latencyhigh']); } } elseif (!empty($pconfig['latencyhigh'])) { if (is_numeric($pconfig['latencyhigh']) && $pconfig['latencyhigh'] < $dpinger_default['latencylow']) { $input_errors[] = sprintf(gettext('The high latency threshold needs to be higher than the default low latency threshold (%d)'), $dpinger_default['latencylow']); } } if (!empty($pconfig['losslow']) && !empty($pconfig['losshigh'])) { if (is_numeric($pconfig['losslow']) && is_numeric($pconfig['losshigh']) && $pconfig['losslow'] > $pconfig['losshigh']) { $input_errors[] = gettext("The high Packet Loss threshold needs to be higher than the low Packet Loss threshold"); } } elseif (!empty($pconfig['losslow'])) { if (is_numeric($pconfig['losslow']) && $pconfig['losslow'] > $dpinger_default['losshigh']) { $input_errors[] = sprintf(gettext('The low Packet Loss threshold needs to be less than the default high Packet Loss threshold (%d)'), $dpinger_default['losshigh']); } } elseif (!empty($pconfig['losshigh'])) { if (is_numeric($pconfig['losshigh']) && $pconfig['losshigh'] < $dpinger_default['losslow']) { $input_errors[] = sprintf(gettext('The high Packet Loss threshold needs to be higher than the default low Packet Loss threshold (%d)'), $dpinger_default['losslow']); } } if (!empty($pconfig['interval'])) { if (!is_numeric($pconfig['interval'])) { $input_errors[] = gettext("The probe interval needs to be a numeric value."); } elseif ($pconfig['interval'] < 1) { $input_errors[] = gettext("The probe interval needs to be positive."); } } if (!empty($pconfig['alert_interval'])) { if (!is_numeric($pconfig['alert_interval'])) { $input_errors[] = gettext("The alert interval needs to be a numeric value."); } elseif ($pconfig['alert_interval'] < 1) { $input_errors[] = gettext("The alert interval needs to be positive."); } } if (!empty($pconfig['time_period'])) { if (!is_numeric($pconfig['time_period'])) { $input_errors[] = gettext("The time period needs to be a numeric value."); } elseif ($pconfig['time_period'] < 1) { $input_errors[] = gettext("The time period needs to be positive."); } elseif ($pconfig['time_period'] < (2.1*$pconfig['interval'])) { $input_errors[] = gettext("The time period needs at least 2.1 times that of the probe interval."); } } if (!empty($pconfig['loss_interval'])) { if (!is_numeric($pconfig['loss_interval'])) { $input_errors[] = gettext("The loss interval needs to be a numeric value."); } elseif ($pconfig['loss_interval'] < 1) { $input_errors[] = gettext("The loss interval needs to be positive."); } } if (count($input_errors) == 0) { // A result of obfuscating the list of gateways is that over here we need to map things back that should // be aligned with the configuration. Not going to fix this now. if (isset($a_gateways[$id]['attribute']) && is_numeric($a_gateways[$id]['attribute']) ) { $realid = $a_gateways[$id]['attribute']; } $a_gateway_item = &config_read_array('gateways', 'gateway_item'); $reloadif = ""; $gateway = array(); if (empty($pconfig['interface'])) { $gateway['interface'] = $pconfig['friendlyiface']; } else { $gateway['interface'] = $pconfig['interface']; } if (is_ipaddr($pconfig['gateway'])) { $gateway['gateway'] = $pconfig['gateway']; } else { $gateway['gateway'] = "dynamic"; } $gateway['name'] = $pconfig['name']; $gateway['weight'] = $pconfig['weight']; $gateway['ipprotocol'] = $pconfig['ipprotocol']; $gateway['interval'] = $pconfig['interval']; $gateway['descr'] = $pconfig['descr']; if ($pconfig['monitor_disable'] == "yes") { $gateway['monitor_disable'] = true; } if ($pconfig['force_down'] == "yes") { $gateway['force_down'] = true; } if (is_ipaddr($pconfig['monitor'])) { $gateway['monitor'] = $pconfig['monitor']; } /* NOTE: If monitor ip is changed need to cleanup the old static route */ if (isset($realid) && $pconfig['monitor'] != "dynamic" && !empty($a_gateway_item[$realid]) && is_ipaddr($a_gateway_item[$realid]['monitor']) && $pconfig['monitor'] != $a_gateway_item[$realid]['monitor'] && $gateway['gateway'] != $a_gateway_item[$realid]['monitor']) { if (is_ipaddrv4($a_gateway_item[$realid]['monitor'])) { mwexec("/sbin/route delete " . escapeshellarg($a_gateway_item[$realid]['monitor'])); } else { mwexec("/sbin/route delete -inet6 " . escapeshellarg($a_gateway_item[$realid]['monitor'])); } } if ($pconfig['defaultgw'] == "yes" || $pconfig['defaultgw'] == "on") { $i = 0; /* remove the default gateway bits for all gateways with the same address family */ foreach ($a_gateway_item as $gw) { if ($gateway['ipprotocol'] == $gw['ipprotocol']) { unset($config['gateways']['gateway_item'][$i]['defaultgw']); if ($gw['interface'] != $pconfig['interface'] && $gw['defaultgw']) { $reloadif = $gw['interface']; } } $i++; } $gateway['defaultgw'] = true; } foreach (array('alert_interval', 'latencylow', 'latencyhigh', 'loss_interval', 'losslow', 'losshigh', 'time_period') as $fieldname) { if (!empty($pconfig[$fieldname])) { $gateway[$fieldname] = $pconfig[$fieldname]; } } if (isset($pconfig['disabled'])) { $gateway['disabled'] = true; } elseif (isset($gateway['disabled'])) { unset($gateway['disabled']); } if (isset($pconfig['fargw'])) { $gateway['fargw'] = true; } elseif (isset($gateway['fargw'])) { unset($gateway['fargw']); } /* when saving the manual gateway we use the attribute which has the corresponding id */ if (isset($realid)) { $a_gateway_item[$realid] = $gateway; } else { $a_gateway_item[] = $gateway; } mark_subsystem_dirty('staticroutes'); write_config(); if (!empty($pconfig['isAjax'])) { echo $pconfig['name']; exit; } elseif (!empty($reloadif)) { configdp_run('interface reconfigure', array($reloadif)); } header(url_safe('Location: /system_gateways.php')); exit; } else { if (!empty($pconfig['isAjax'])) { header("HTTP/1.0 500 Internal Server Error"); header("Content-type: text/plain"); echo implode("\n\n", $input_errors); exit; } if (!empty($pconfig['interface'])) { $pconfig['friendlyiface'] = $pconfig['interface']; } } } elseif ($_SERVER['REQUEST_METHOD'] === 'GET') { // retrieve form data if (isset($_GET['id']) && isset($a_gateways[$_GET['id']])) { $id = $_GET['id']; $configId = $id; } elseif (isset($_GET['dup']) && isset($a_gateways[$_GET['dup']])) { $configId = $_GET['dup']; } // set config details $pconfig = array(); $pconfig['attribute'] = null; $pconfig['monitor_disable'] = true; // load data from config $copy_fields = array( 'defaultgw', 'descr', 'disabled', 'dynamic', 'fargw', 'force_down', 'friendlyiface', 'gateway', 'interface', 'interval', 'ipprotocol', 'latencyhigh', 'latencylow', 'losshigh', 'losslow', 'monitor', 'monitor_disable', 'name', 'weight', 'alert_interval', 'time_period', 'loss_interval', ); foreach ($copy_fields as $fieldname) { if (isset($configId) && isset($a_gateways[$configId][$fieldname])) { $pconfig[$fieldname] = $a_gateways[$configId][$fieldname]; } elseif (empty($pconfig[$fieldname]) || isset($configId)) { $pconfig[$fieldname] = null; } } if (isset($id) && isset($a_gateways[$configId]['attribute'])) { $pconfig['attribute'] = $a_gateways[$configId]['attribute']; } } legacy_html_escape_form_data($a_gateways); legacy_html_escape_form_data($pconfig); include("head.inc"); ?>