From ccd0f07fa8e1b2313c97331cea23556b220807a8 Mon Sep 17 00:00:00 2001 From: Franco Fichtner Date: Fri, 28 Dec 2018 18:20:48 +0100 Subject: [PATCH] interfaces: clear a faulty automatic DUID; closes #3061 --- src/etc/inc/interfaces.inc | 13 +++------ src/etc/inc/util.inc | 44 +++++++++++++++++++++++++++++ src/www/system_advanced_network.php | 22 ++------------- 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/src/etc/inc/interfaces.inc b/src/etc/inc/interfaces.inc index 932d3dab5..7c5fce471 100644 --- a/src/etc/inc/interfaces.inc +++ b/src/etc/inc/interfaces.inc @@ -2858,15 +2858,10 @@ function interface_dhcpv6_configure($interface = 'wan', $wancfg) /* write DUID if override was set */ if (!empty($config['system']['ipv6duid'])) { - $fd = fopen('/var/db/dhcp6c_duid', 'wb'); - if ($fd) { - $parts = explode(':', $config['system']['ipv6duid']); - /* length is unsigned 16 bit integer, machine-dependent:*/ - fwrite($fd, pack('S', count($parts))); - /* buffer is binary string, according to advertised length: */ - fwrite($fd, pack('H*', implode('', $parts))); - fclose($fd); - } + dhcp6c_duid_write($config['system']['ipv6duid']); + /* clear DUID if it is faulty */ + } elseif (empty(dhcp6c_duid_read())) { + dhcp6c_duid_clear(); } if (!is_array($wancfg)) { diff --git a/src/etc/inc/util.inc b/src/etc/inc/util.inc index 35d0215ea..a6192754d 100644 --- a/src/etc/inc/util.inc +++ b/src/etc/inc/util.inc @@ -1281,3 +1281,47 @@ function is_install_media() return true; } + +function dhcp6c_duid_read() +{ + $parts = array(); + $skip = 2; + + if (file_exists('/var/db/dhcp6c_duid')) { + $size = filesize('/var/db/dhcp6c_duid'); + if ($size > $skip && ($fd = fopen('/var/db/dhcp6c_duid', 'r'))) { + $ret = unpack('Slen/H*buf', fread($fd, $size)); + fclose($fd); + + if (isset($ret['len']) && isset($ret['buf'])) { + if ($ret['len'] + $skip == $size && strlen($ret['buf']) == $ret['len'] * 2) { + $parts = str_split($ret['buf'], 2); + } + } + } + } + + $duid = strtoupper(implode(':', $parts)); + + return $duid; +} + +function dhcp6c_duid_write($duid) +{ + $fd = fopen('/var/db/dhcp6c_duid', 'wb'); + if ($fd) { + $parts = explode(':', $duid); + /* length is unsigned 16 bit integer, machine-dependent:*/ + fwrite($fd, pack('S', count($parts))); + /* buffer is binary string, according to advertised length: */ + fwrite($fd, pack('H*', implode('', $parts))); + fclose($fd); + } +} + +function dhcp6c_duid_clear() +{ + @unlink('/var/db/dhcp6c_duid'); + /* clear the backup so that it will not be restored: */ + @unlink('/conf/dhcp6c_duid'); +} diff --git a/src/www/system_advanced_network.php b/src/www/system_advanced_network.php index 0c14b061b..0678f77ab 100644 --- a/src/www/system_advanced_network.php +++ b/src/www/system_advanced_network.php @@ -148,24 +148,7 @@ function is_duid($duid) /* read duid from disk or return blank DUID string */ function read_duid() { - $parts = array(); - $skip = 2; - - if (file_exists('/var/db/dhcp6c_duid')) { - $size = filesize('/var/db/dhcp6c_duid'); - if ($size > $skip && ($fd = fopen('/var/db/dhcp6c_duid', 'r'))) { - $ret = unpack('Slen/H*buf', fread($fd, $size)); - fclose($fd); - - if (isset($ret['len']) && isset($ret['buf'])) { - if ($ret['len'] + $skip == $size && strlen($ret['buf']) == $ret['len'] * 2) { - $parts = str_split($ret['buf'], 2); - } - } - } - } - - $duid = strtoupper(implode(':', $parts)); + $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'; @@ -235,8 +218,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { } elseif (isset($config['system']['ipv6duid'])) { unset($config['system']['ipv6duid']); /* clear the file as this means auto-generate */ - @unlink('/var/db/dhcp6c_duid'); - @unlink('/conf/dhcp6c_duid'); + dhcp6c_duid_clear(); } $savemsg = get_std_save_message();