* 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"); if ($_SERVER['REQUEST_METHOD'] === 'GET') { // handle identifiers and action if (!empty($_GET['if']) && !empty($config['interfaces'][$_GET['if']])) { $if = $_GET['if']; } else { header(url_safe('Location: /services_dhcp.php')); exit; } if (isset($if) && isset($_GET['id']) && !empty($config['dhcpd'][$if]['staticmap'][$_GET['id']])) { $id = $_GET['id']; } // read form data $pconfig = array(); $config_copy_fieldnames = array('mac', 'cid', 'hostname', 'filename', 'rootpath', 'descr', 'arp_table_static_entry', 'defaultleasetime', 'maxleasetime', 'gateway', 'domain', 'domainsearchlist', 'winsserver', 'dnsserver', 'ddnsdomain', 'ntpserver', 'tftp', 'bootfilename', 'ipaddr', 'winsserver', 'dnsserver'); foreach ($config_copy_fieldnames as $fieldname) { if (isset($if) && isset($id) && isset($config['dhcpd'][$if]['staticmap'][$id][$fieldname])) { $pconfig[$fieldname] = $config['dhcpd'][$if]['staticmap'][$id][$fieldname]; } elseif (isset($_GET[$fieldname])) { $pconfig[$fieldname] = $_GET[$fieldname]; } else { $pconfig[$fieldname] = null; } } // handle array types if (isset($pconfig['winsserver'][0])) { $pconfig['wins1'] = $pconfig['winsserver'][0]; } if (isset($pconfig['winsserver'][1])) { $pconfig['wins2'] = $pconfig['winsserver'][1]; } if (isset($pconfig['dnsserver'][0])) { $pconfig['dns1'] = $pconfig['dnsserver'][0]; } if (isset($pconfig['dnsserver'][1])) { $pconfig['dns2'] = $pconfig['dnsserver'][1]; } if (isset($pconfig['ntpserver'][0])) { $pconfig['ntp1'] = $pconfig['ntpserver'][0]; } if (isset($pconfig['ntpserver'][1])) { $pconfig['ntp2'] = $pconfig['ntpserver'][1]; } } elseif ($_SERVER['REQUEST_METHOD'] === 'POST') { $pconfig = $_POST; // handle identifiers and actions if (!empty($pconfig['if']) && !empty($config['interfaces'][$pconfig['if']])) { $if = $pconfig['if']; } if (!empty($config['dhcpd'][$if]['staticmap'][$pconfig['id']])) { $id = $pconfig['id']; } $a_maps = &config_read_array('dhcpd', $if, 'staticmap'); $input_errors = array(); /* input validation */ $reqdfields = array(); $reqdfieldsn = array(); do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors); /* either MAC or Client-ID must be specified */ if (empty($pconfig['mac']) && empty($pconfig['cid'])) { $input_errors[] = gettext("Either MAC address or Client identifier must be specified"); } /* normalize MAC addresses - lowercase and convert Windows-ized hyphenated MACs to colon delimited */ $pconfig['mac'] = strtolower(str_replace("-", ":", $pconfig['mac'])); if (!empty($pconfig['hostname'])) { preg_match("/\-\$/", $pconfig['hostname'], $matches); if ($matches) { $input_errors[] = gettext("The hostname cannot end with a hyphen according to RFC952"); } if (!is_hostname($pconfig['hostname'])) { $input_errors[] = gettext("The hostname can only contain the characters A-Z, 0-9 and '-'."); } elseif (strpos($pconfig['hostname'],'.')) { $input_errors[] = gettext("A valid hostname is specified, but the domain name part should be omitted"); } } if (!empty($pconfig['ipaddr']) && !is_ipaddr($_POST['ipaddr'])) { $input_errors[] = gettext("A valid IP address must be specified."); } if (!empty($pconfig['mac']) && !is_macaddr($pconfig['mac'])) { $input_errors[] = gettext("A valid MAC address must be specified."); } if (isset($config['dhcpd'][$if]['staticarp']) && empty($pconfig['ipaddr'])) { $input_errors[] = gettext("Static ARP is enabled. You must specify an IP address."); } /* check for overlaps */ if (!empty($pconfig['domain'])) { $this_fqdn = $pconfig['hostname'] . "." . $pconfig['domain']; } elseif (!empty($if) && !empty($config['dhcpd'][$if]['domain'])) { $this_fqdn = $pconfig['hostname'] . "." . $config['dhcpd'][$if]['domain']; } else { $this_fqdn = $pconfig['hostname'] . "." . $config['system']['domain']; } foreach ($a_maps as $mapent) { if (isset($id) && ($a_maps[$id] === $mapent)) { continue; } if (empty($mapent['hostname'])) { $fqdn = ""; } elseif (!empty($mapent['domain'])) { $fqdn = $mapent['hostname'] . "." . $mapent['domain']; } elseif (!empty($if) && !empty($config['dhcpd'][$if]['domain'])) { $fqdn = $mapent['hostname'] . "." . $config['dhcpd'][$if]['domain']; } else { $fqdn = $mapent['hostname'] . "." . $config['system']['domain']; } if (($fqdn == $this_fqdn) || (($mapent['mac'] == $pconfig['mac']) && $mapent['mac']) || (($mapent['ipaddr'] == $pconfig['ipaddr']) && $mapent['ipaddr'] ) || (($mapent['cid'] == $pconfig['cid']) && $mapent['cid'])) { $input_errors[] = gettext("This Hostname, IP, MAC address or Client identifier already exists."); break; } } list (, $parent_net) = interfaces_primary_address($if); if (!empty($pconfig['ipaddr'])) { if (!ip_in_subnet($pconfig['ipaddr'], $parent_net)) { $ifcfgdescr = convert_friendly_interface_to_friendly_descr($if); $input_errors[] = sprintf(gettext('The IP address must lie in the %s subnet.'), $ifcfgdescr); } } if (!empty($pconfig['gateway']) && $pconfig['gateway'] != "none" && !is_ipaddrv4($pconfig['gateway'])) { $input_errors[] = gettext("A valid IP address must be specified for the gateway."); } if ((!empty($pconfig['wins1']) && !is_ipaddrv4($pconfig['wins1'])) || (!empty($pconfig['wins2']) && !is_ipaddrv4($pconfig['wins2']))) { $input_errors[] = gettext("A valid IP address must be specified for the primary/secondary WINS servers."); } if (is_subnetv4($parent_net) && $pconfig['gateway'] != "none" && !empty($pconfig['gateway'])) { if (!ip_in_subnet($pconfig['gateway'], $parent_net) && !ip_in_interface_alias_subnet($if, $pconfig['gateway'])) { $input_errors[] = sprintf(gettext("The gateway address %s does not lie within the chosen interface's subnet."), $_POST['gateway']); } } if ((!empty($pconfig['dns1']) && !is_ipaddrv4($pconfig['dns1'])) || (!empty($pconfig['dns2']) && !is_ipaddrv4($pconfig['dns2']))) { $input_errors[] = gettext("A valid IP address must be specified for the primary/secondary DNS servers."); } if (!empty($pconfig['defaultleasetime']) && (!is_numeric($pconfig['defaultleasetime']) || ($pconfig['defaultleasetime'] < 60))) { $input_errors[] = gettext("The default lease time must be at least 60 seconds."); } if (!empty($pconfig['maxleasetime']) && (!is_numeric($pconfig['maxleasetime']) || ($pconfig['maxleasetime'] < 60) || ($pconfig['maxleasetime'] <= $pconfig['defaultleasetime']))) { $input_errors[] = gettext("The maximum lease time must be at least 60 seconds and higher than the default lease time."); } if (!empty($pconfig['ddnsdomain']) && !is_domain($pconfig['ddnsdomain'])) { $input_errors[] = gettext("A valid domain name must be specified for the dynamic DNS registration."); } if (!empty($pconfig['domainsearchlist'])) { $domain_array=preg_split("/[ ;]+/", $pconfig['domainsearchlist']); foreach ($domain_array as $curdomain) { if (!is_domain($curdomain)) { $input_errors[] = gettext("A valid domain search list must be specified."); break; } } } if ((!empty($pconfig['ntp1']) && !is_ipaddrv4($pconfig['ntp1'])) || (!empty($pconfig['ntp2']) && !is_ipaddrv4($pconfig['ntp2']))) { $input_errors[] = gettext("A valid IP address must be specified for the primary/secondary NTP servers."); } if (!empty($pconfig['tftp']) && !is_ipaddrv4($pconfig['tftp']) && !is_domain($pconfig['tftp']) && !is_URL($pconfig['tftp'])) { $input_errors[] = gettext("A valid IP address or hostname must be specified for the TFTP server."); } if ((!empty($pconfig['nextserver']) && !is_ipaddrv4($pconfig['nextserver']))) { $input_errors[] = gettext("A valid IP address must be specified for the network boot server."); } if (count($input_errors) == 0){ $mapent = array(); $config_copy_fieldnames = array('mac', 'cid', 'ipaddr', 'hostname', 'descr', 'filename', 'rootpath', 'arp_table_static_entry', 'defaultleasetime', 'maxleasetime', 'gateway', 'domain', 'domainsearchlist', 'ddnsdomain', 'tftp', 'bootfilename', 'winsserver', 'dnsserver'); foreach ($config_copy_fieldnames as $fieldname) { if (!empty($pconfig[$fieldname])) { $mapent[$fieldname] = $pconfig[$fieldname]; } } // boolean $mapent['arp_table_static_entry'] = !empty($pconfig['arp_table_static_entry']); // arrays $mapent['winsserver'] = array(); if (!empty($pconfig['wins1'])) { $mapent['winsserver'][] = $pconfig['wins1']; } if (!empty($pconfig['wins2'])) { $mapent['winsserver'][] = $pconfig['wins2']; } $mapent['dnsserver'] = array(); if (!empty($pconfig['dns1'])) { $mapent['dnsserver'][] = $_POST['dns1']; } if (!empty($pconfig['dns2'])) { $mapent['dnsserver'][] = $_POST['dns2']; } $mapent['ntpserver'] = array(); if (!empty($pconfig['ntp1'])) { $mapent['ntpserver'][] = $pconfig['ntp1']; } if (!empty($pconfig['ntp2'])) { $mapent['ntpserver'][] = $pconfig['ntp2']; } if (isset($id)) { $a_maps[$id] = $mapent; } else { $a_maps[] = $mapent; } usort($config['dhcpd'][$if]['staticmap'], function ($a, $b) { return ipcmp($a['ipaddr'], $b['ipaddr']); }); write_config(); if (isset($config['dhcpd'][$if]['enable'])) { mark_subsystem_dirty('staticmaps'); mark_subsystem_dirty('hosts'); } header(url_safe('Location: /services_dhcp.php?if=%s', array($if))); exit; } } $service_hook = 'dhcpd'; legacy_html_escape_form_data($pconfig); include("head.inc"); ?>