* Copyright (C) 2003-2005 Manuel Kasper * Copyright (C) 2004-2005 Scott Ullrich * 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("interfaces.inc"); /** * find max vhid */ function find_last_used_vhid() { global $config; $vhid = 0; if (isset($config['virtualip']['vip'])) { foreach($config['virtualip']['vip'] as $vip) { if(!empty($vip['vhid']) && $vip['vhid'] > $vhid) { $vhid = $vip['vhid']; } } } return $vhid; } // create new vip array if none existent $a_vip = &config_read_array('virtualip', 'vip'); if ($_SERVER['REQUEST_METHOD'] === 'GET') { // input record id, if valid if (isset($_GET['dup']) && isset($a_vip[$_GET['dup']])) { $configId = $_GET['dup']; $after = $configId; } elseif (isset($_GET['id']) && isset($a_vip[$_GET['id']])) { $id = $_GET['id']; $configId = $id; } $pconfig = array(); $form_fields = array('mode', 'vhid', 'advskew', 'advbase', 'password', 'subnet', 'subnet_bits' , 'descr' ,'type', 'interface', 'gateway' ); if (isset($configId)) { // 1-on-1 copy of config data foreach ($form_fields as $fieldname) { if (isset($a_vip[$configId][$fieldname])) { $pconfig[$fieldname] = $a_vip[$configId][$fieldname] ; } } } // initialize empty form fields foreach ($form_fields as $fieldname) { if (!isset($pconfig[$fieldname])) { $pconfig[$fieldname] = null ; } } } elseif ($_SERVER['REQUEST_METHOD'] === 'POST') { $input_errors = array(); $pconfig = $_POST; // input record id, if valid if (isset($pconfig['id']) && isset($a_vip[$pconfig['id']])) { $id = $pconfig['id']; } // perform form validations $reqdfields = array("mode"); $reqdfieldsn = array(gettext("Type")); do_input_validation($pconfig, $reqdfields, $reqdfieldsn, $input_errors); if (isset($id) && $pconfig['mode'] != $a_vip[$id]['mode']) { $input_errors[] = gettext("Virtual IP mode may not be changed for an existing entry."); } else { if (isset($pconfig['subnet'])) { $pconfig['subnet'] = trim($pconfig['subnet']); if (!is_ipaddr($pconfig['subnet'])) { $input_errors[] = gettext("A valid IP address must be specified."); } else { $ignore_if = isset($id) ? $a_vip[$id]['interface'] : $pconfig['interface']; if (is_ipaddr_configured($pconfig['subnet'], $ignore_if)) { $input_errors[] = gettext("This IP address is being used by another interface or VIP."); } } } if (!empty($pconfig['gateway']) && !is_ipaddr($pconfig['gateway'])) { $input_errors[] = gettext("A valid gateway IP address must be specified."); } /* ipalias and carp should not use network or broadcast address */ if ($pconfig['mode'] == "ipalias" || $pconfig['mode'] == "carp") { if (is_ipaddrv4($pconfig['subnet']) && $pconfig['subnet_bits'] != '32' && $pconfig['subnet_bits'] != '31') { $network_addr = gen_subnet($pconfig['subnet'], $pconfig['subnet_bits']); $broadcast_addr = gen_subnet_max($pconfig['subnet'], $pconfig['subnet_bits']); if (isset($network_addr) && $pconfig['subnet'] == $network_addr) { $input_errors[] = gettext("You cannot use the network address for this VIP"); } else if (isset($broadcast_addr) && $pconfig['subnet'] == $broadcast_addr) { $input_errors[] = gettext("You cannot use the broadcast address for this VIP"); } } } /* make sure new ip is within the subnet of a valid ip * on one of our interfaces (wan, lan optX) */ if ($pconfig['mode'] == 'carp') { /* verify against reusage of vhids */ foreach($config['virtualip']['vip'] as $vipId => $vip) { if (isset($vip['vhid']) && $vip['vhid'] == $pconfig['vhid'] && $vip['type'] == 'carp' && $vip['interface'] == $pconfig['interface'] && $vipId != $id) { $input_errors[] = sprintf(gettext("VHID %s is already in use on interface %s. Pick a unique number on this interface."),$pconfig['vhid'], convert_friendly_interface_to_friendly_descr($pconfig['interface'])); } } if (empty($pconfig['password'])) { $input_errors[] = gettext("You must specify a CARP password that is shared between the two VHID members."); } if (empty($pconfig['vhid'])) { $input_errors[] = gettext('A VHID must be selected for this CARP VIP.'); } if ($pconfig['interface'] == 'lo0') { $input_errors[] = gettext('For this type of VIP loopback is not allowed.'); } } else if ($pconfig['mode'] != 'ipalias' && $pconfig['interface'] == 'lo0') { $input_errors[] = gettext('For this type of VIP loopback is not allowed.'); } elseif ($pconfig['mode'] == 'ipalias' && !empty($pconfig['vhid'])) { $carpvip_found = false; foreach($config['virtualip']['vip'] as $vipId => $vip) { if ($vip['interface'] == $pconfig['interface'] && $vip['vhid'] == $pconfig['vhid'] && $vip['mode'] == 'carp') { $carpvip_found = true ; } } if (!$carpvip_found) { $input_errors[] = sprintf(gettext("VHID %s must be defined on interface %s as a CARP VIP first."),$pconfig['vhid'], convert_friendly_interface_to_friendly_descr($pconfig['interface'])); } } } if (count($input_errors) == 0) { $vipent = array(); // defaults $vipent['type'] = "single"; $vipent['subnet_bits'] = "32"; // 1-on-1 copy attributes foreach (array('mode', 'interface', 'descr', 'type', 'subnet_bits', 'subnet', 'vhid' ,'advskew','advbase','password', 'gateway') as $fieldname) { if (isset($pconfig[$fieldname]) && $pconfig[$fieldname] != "") { $vipent[$fieldname] = $pconfig[$fieldname]; } } if (!empty($pconfig['noexpand'])) { // noexpand, only used for proxyarp $vipent['noexpand'] = true; } // virtual ip UI keeps track of its changes in a separate file // (which is only use on apply in firewall_virtual_ip) // add or change this administration here. // Not the nicest thing to do, but we keep it for now. if (file_exists('/tmp/.firewall_virtual_ip.apply')) { $toapplylist = unserialize(file_get_contents('/tmp/.firewall_virtual_ip.apply')); } else { $toapplylist = array(); } if (isset($id)) { // save existing content before changing it $toapplylist[$id] = $a_vip[$id]; } else { // new entry, no old data $toapplylist[count($a_vip)] = array(); } if (isset($id)) { /* modify all virtual IP rules with this address */ for ($i = 0; isset($config['nat']['rule'][$i]); $i++) { if (isset($config['nat']['rule'][$i]['destination']['address']) && $config['nat']['rule'][$i]['destination']['address'] == $a_vip[$id]['subnet']) { $config['nat']['rule'][$i]['destination']['address'] = $vipent['subnet']; } } } // update or insert item in config if (isset($id)) { $a_vip[$id] = $vipent; } else { $a_vip[] = $vipent; } write_config(); mark_subsystem_dirty('vip'); file_put_contents('/tmp/.firewall_virtual_ip.apply', serialize($toapplylist)); header(url_safe('Location: /firewall_virtual_ip.php')); exit; } } legacy_html_escape_form_data($pconfig); include("head.inc"); ?>
0) print_input_errors($input_errors); ?>
/>
: :