diff --git a/src/etc/inc/interfaces.inc b/src/etc/inc/interfaces.inc index 8710fdaa5..0248d690a 100644 --- a/src/etc/inc/interfaces.inc +++ b/src/etc/inc/interfaces.inc @@ -2863,13 +2863,11 @@ function interface_dhcpv6_configure($interface = 'wan', $wancfg) { global $config; - if (!is_array($wancfg)) { - return; - } - /* write DUID if override was set */ if (!empty($config['system']['ipv6duid'])) { - $temp = str_replace(':', '', $config['system']['ipv6duid']); + $temp = explode(':', $config['system']['ipv6duid']); + array_unshift($temp, sprintf('%02x', count($temp)), '00'); + $temp = implode('', $temp); $duid_binstring = pack('H*', $temp); $fd = fopen('/var/db/dhcp6c_duid', 'wb'); if ($fd) { @@ -2878,6 +2876,10 @@ function interface_dhcpv6_configure($interface = 'wan', $wancfg) } } + if (!is_array($wancfg)) { + return; + } + $wanif = get_real_interface($interface, 'inet6'); /* accept router advertisements for this interface */ diff --git a/src/www/system_advanced_network.php b/src/www/system_advanced_network.php index 07f989b4b..0038becc5 100644 --- a/src/www/system_advanced_network.php +++ b/src/www/system_advanced_network.php @@ -34,18 +34,68 @@ require_once("interfaces.inc"); require_once("filter.inc"); require_once("system.inc"); -/* - * Format a string to look (more) like the expected DUID format: - * - * 1) Replace any "-" with ":" - * 2) If the user inputs 14 components, then add the expected "0e:00:" to the front. - * This is convenience, because the actual DUID (which is reported in logs) is the last 14 components. - * 3) If any components are input with just a single char (hex digit hopefully), put a "0" in front. - * - * The final result should be closer to: - * - * "0e:00:00:01:00:01:nn:nn:nn:nn:nn:nn:nn:nn:nn:nn" - */ +function get_mac_address() +{ + $ip = getenv('REMOTE_ADDR'); + $mac = `/usr/sbin/arp -an | grep {$ip} | cut -d" " -f4`; + $mac = str_replace("\n","",$mac); + return $mac; +} + +function generate_new_duid($duid_type) +{ + switch ($duid_type) { + case '1': //LLT + $mac = get_mac_address(); + $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"; + while ($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 + $ts = time() - 946684800; + $hts = dechex($ts); + $timestamp = sprintf("%s",$hts); + $timestamp_array = str_split($timestamp,2); + $timestamp = implode(":",$timestamp_array); + $type = "\x00\x03\x00\x01"; + while ($count < strlen($type)) { + $new_duid .= bin2hex( $type[$count]); + $count++; + if ($count < strlen($type)) { + $new_duid .= ':'; + } + } + $new_duid = $new_duid.':'.$timestamp; + break; + case '3': //UUID + $type = "\x00\x00\x00\x04".openssl_random_pseudo_bytes(16); + while ($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:XX:XX'; + break; + } + + return $new_duid; +} + function format_duid($duid) { $values = explode(':', strtolower(str_replace('-', ':', $duid))); @@ -63,13 +113,33 @@ function format_duid($duid) function is_duid($duid) { + // Duid's can be any length. Just check the format is correct. $values = explode(":", $duid); - if (count($values) != 16 || strlen($duid) != 47) { + // 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 seperators 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 < 16; $i++) { + for ($i = 0; $i < count($values); $i++) { if (ctype_xdigit($values[$i]) == false) { return false; } @@ -86,20 +156,22 @@ function read_duid() { $duid = ''; $count = 0; + if (file_exists('/var/db/dhcp6c_duid')) { + $filesize = filesize('/var/db/dhcp6c_duid'); + if ($fd = fopen('/var/db/dhcp6c_duid', 'r')) { + $buffer = fread($fd, $filesize); + fclose($fd); - if (file_exists('/var/db/dhcp6c_duid') && - ($fd = fopen('/var/db/dhcp6c_duid', 'r'))) { - if (filesize('/var/db/dhcp6c_duid') == 16) { - $buffer = fread($fd, 16); - while ($count < 16) { - $duid .= bin2hex($buffer[$count]); + $duid_length = hexdec(bin2hex($buffer[0])); // This is the length of the duid, NOT the file + + while ($count < $duid_length) { + $duid .= bin2hex($buffer[$count+2]); // Offset by 2 bytes $count++; - if ($count < 16) { + if ($count < $duid_length) { $duid .= ':'; } } } - fclose($fd); } if (!is_duid($duid)) { @@ -123,6 +195,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { $pconfig['disablevlanhwfilter'] = $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'); } elseif ($_SERVER['REQUEST_METHOD'] === 'POST') { $input_errors = array(); $pconfig = $_POST; @@ -168,11 +243,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { unset($config['system']['ipv6duid']); /* clear the file as this means auto-generate */ @unlink('/var/db/dhcp6c_duid'); + @unlink('/conf/dhcp6c_duid'); } $savemsg = get_std_save_message(); write_config(); + interface_dhcpv6_configure('duidonly', null); /* XXX refactor */ system_arp_wrong_if(); } } @@ -184,9 +261,7 @@ include("head.inc"); ?> - - - +
@@ -271,22 +346,35 @@ include("head.inc"); - + + + + +
+
+
+
+
- - - -   - " /> - - - - - - +
+
+
+
+
+ +
+ + + +   + + + + + + +
@@ -294,6 +382,6 @@ include("head.inc");
+