* Copyright (C) 2008 Shrew Soft Inc. * Copyright (C) 2003-2004 Manuel Kasper * 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"); require_once("filter.inc"); require_once("system.inc"); function get_mac_address($ip) { $macs = []; exec(exec_safe('/usr/sbin/arp -an | grep %s | awk \'{ print $4 }\'', $ip), $macs); return !empty($macs[0]) ? $macs[0] : ''; } function generate_new_duid($duid_type) { $new_duid = ''; switch ($duid_type) { case '1': //LLT $mac = get_mac_address(getenv('REMOTE_ADDR')); $ts = time() - 946684800; $hts = dechex($ts); $timestamp = sprintf("%s",$hts); $timestamp_array = str_split($timestamp,2); $timestamp = implode(":",$timestamp_array); $type = "\x00\x01\x00\x01"; for ($count = 0; $count < strlen($type); ) { $new_duid .= bin2hex( $type[$count]); $count++; if ($count < strlen($type)) { $new_duid .= ':'; } } $new_duid = $new_duid.':'.$timestamp.':'.$mac; break; case '2': //LL - NO TIMESTAMP: Just 00:03:00:01: + Link layer address in canonical form, so says RFC. $mac = get_mac_address(getenv('REMOTE_ADDR')); $type = "\x00\x03\x00\x01"; for ($count = 0; $count < strlen($type); ) { $new_duid .= bin2hex( $type[$count]); $count++; if ($count < strlen($type)) { $new_duid .= ':'; } } $new_duid = $new_duid.':'.$mac; break; case '3': //UUID $type = "\x00\x00\x00\x04".random_bytes(16); for ($count = 0; $count < strlen($type); ) { $new_duid .= bin2hex( $type[$count]); $count++; if ($count < strlen($type)) { $new_duid .= ':'; } } break; case '4': //EN - Using Opnsense PEN!!! $type = "\x00\x02\x00\x00\xD2\x6D".random_bytes(8); for ($count = 0; $count < strlen($type); ) { $new_duid .= bin2hex( $type[$count]); $count++; if ($count < strlen($type)) { $new_duid .= ':'; } } break; default: $new_duid = 'XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX'; break; } return strtoupper($new_duid); } function format_duid($duid) { $values = explode(':', strtoupper(str_replace('-', ':', $duid))); foreach ($values as &$value) { $value = str_pad($value, 2, '0', STR_PAD_LEFT); }; return implode(':', $values); } function is_duid($duid) { // Duid's can be any length. Just check the format is correct. $values = explode(":", $duid); // need to get the DUID type. There are four types, in the // first three the type number is in byte[2] in the fourth it's // in byte[4]. Offset is either 0 or 2 depending if it's the read # // from file duid or the user input. $valid_duid = false; $duid_length = count($values); $test1 = hexdec($values[1]); $test2 = hexdec($values[3]); if (($test1 == 1 && $test2 == 1 ) || ($test1 == 3 && $test2 == 1 ) || ($test1 == 0 && $test2 == 4 ) || ($test1 == 2)) { $valid_duid = true; } /* max DUID length is 128, but with the separators it could be up to 254 */ if ($duid_length < 6 || $duid_length > 254) { $valid_duid = false; } if ($valid_duid == false) { return false; } for ($i = 0; $i < count($values); $i++) { if (ctype_xdigit($values[$i]) == false) { return false; } if (hexdec($values[$i]) < 0 || hexdec($values[$i]) > 255) { return false; } } return true; } /* read duid from disk or return blank DUID string */ function read_duid() { $duid = dhcp6c_duid_read(); if (!is_duid($duid)) { $duid = 'XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX'; } return $duid; } $duid = read_duid(); if ($_SERVER['REQUEST_METHOD'] === 'GET') { $pconfig = []; $pconfig['disablechecksumoffloading'] = isset($config['system']['disablechecksumoffloading']); $pconfig['disablesegmentationoffloading'] = isset($config['system']['disablesegmentationoffloading']); $pconfig['disablelargereceiveoffloading'] = isset($config['system']['disablelargereceiveoffloading']); $pconfig['dhcp6_norelease'] = isset($config['system']['dhcp6_norelease']); $pconfig['dhcp6_debug'] = !isset($config['system']['dhcp6_debug']) ? '0' : $config['system']['dhcp6_debug']; $pconfig['ipv6duid'] = $config['system']['ipv6duid']; $pconfig['disablevlanhwfilter'] = !isset($config['system']['disablevlanhwfilter']) ? '0' : $config['system']['disablevlanhwfilter']; $pconfig['sharednet'] = isset($config['system']['sharednet']); $pconfig['ipv6_duid_llt_value'] = generate_new_duid('1'); $pconfig['ipv6_duid_ll_value'] = generate_new_duid('2'); $pconfig['ipv6_duid_uuid_value'] = generate_new_duid('3'); $pconfig['ipv6_duid_en_value'] = generate_new_duid('4'); } elseif ($_SERVER['REQUEST_METHOD'] === 'POST') { $input_errors = []; $pconfig = $_POST; if (!empty($pconfig['ipv6duid']) && !is_duid($pconfig['ipv6duid'])) { $input_errors[] = gettext('A valid DUID must be specified.'); } if (!count($input_errors)) { if (!empty($pconfig['sharednet'])) { $config['system']['sharednet'] = true; } elseif (isset($config['system']['sharednet'])) { unset($config['system']['sharednet']); } if (!empty($pconfig['disablechecksumoffloading'])) { $config['system']['disablechecksumoffloading'] = true; } elseif (isset($config['system']['disablechecksumoffloading'])) { unset($config['system']['disablechecksumoffloading']); } if (!empty($pconfig['disablesegmentationoffloading'])) { $config['system']['disablesegmentationoffloading'] = true; } elseif (isset($config['system']['disablesegmentationoffloading'])) { unset($config['system']['disablesegmentationoffloading']); } if (!empty($pconfig['disablelargereceiveoffloading'])) { $config['system']['disablelargereceiveoffloading'] = true; } elseif (isset($config['system']['disablelargereceiveoffloading'])) { unset($config['system']['disablelargereceiveoffloading']); } if (!empty($pconfig['disablevlanhwfilter'])) { $config['system']['disablevlanhwfilter'] = $pconfig['disablevlanhwfilter']; } elseif (isset($config['system']['disablevlanhwfilter'])) { unset($config['system']['disablevlanhwfilter']); } if (!empty($pconfig['dhcp6_norelease'])) { $config['system']['dhcp6_norelease'] = $pconfig['dhcp6_norelease']; } elseif (isset($config['system']['dhcp6_norelease'])) { unset($config['system']['dhcp6_norelease']); } if (!empty($pconfig['dhcp6_debug'])) { $config['system']['dhcp6_debug'] = $pconfig['dhcp6_debug']; } elseif (isset($config['system']['dhcp6_debug'])) { unset($config['system']['dhcp6_debug']); } if (!empty($pconfig['ipv6duid'])) { $config['system']['ipv6duid'] = $pconfig['ipv6duid'] = format_duid($pconfig['ipv6duid']); } elseif (isset($config['system']['ipv6duid'])) { unset($config['system']['ipv6duid']); /* clear the file as this means auto-generate */ dhcp6c_duid_clear(); } $savemsg = get_std_save_message(); write_config(); interface_dhcpv6_configure('duidonly', null); /* XXX refactor */ system_sysctl_configure(); interfaces_hardware(); } } legacy_html_escape_form_data($pconfig); include("head.inc"); ?>
/>
/>
/>
/>
/>