diff --git a/dns/dyndns/src/etc/inc/plugins.inc.d/dyndns.inc b/dns/dyndns/src/etc/inc/plugins.inc.d/dyndns.inc index 762549e53..54f1db403 100644 --- a/dns/dyndns/src/etc/inc/plugins.inc.d/dyndns.inc +++ b/dns/dyndns/src/etc/inc/plugins.inc.d/dyndns.inc @@ -249,3 +249,42 @@ function dyndns_failover_interface($interface, $family = 'all') /* fall through to get real interface the hard way */ return get_real_interface($interface, $family); } + + +function get_dyndns_ip_address($int, $ipver = 4) +{ + $ip_address = $ipver == 6 ? get_interface_ipv6($int) : get_interface_ip($int); + if (empty($ip_address)) { + log_error("Aborted IPv{$ipver} detection: no address for {$int}"); + return 'down'; + } + + if ($ipver != 6 && is_private_ip($ip_address)) { + /* Chinese alternative is http://ip.3322.net/ */ + $hosttocheck = 'http://checkip.dyndns.org'; + $ip_ch = curl_init($hosttocheck); + curl_setopt($ip_ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ip_ch, CURLOPT_INTERFACE, $ip_address); + curl_setopt($ip_ch, CURLOPT_CONNECTTIMEOUT, 5); + curl_setopt($ip_ch, CURLOPT_TIMEOUT, 30); + curl_setopt($ip_ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); + $ip_result = curl_exec($ip_ch); + if ($ip_result !== false) { + preg_match('=
Current IP Address: (.*)=siU', $ip_result, $matches); + $ip_address = trim($matches[1]); + } else { + log_error('Aborted IPv4 detection: ' . curl_error($ip_ch)); + $ip_address = ''; + } + curl_close($ip_ch); + } elseif ($ipver == 6 && is_linklocal($ip_address)) { + log_error('Aborted IPv6 detection: cannot bind to link-local address'); + $ip_address = ''; + } + + if (($ipver == 6 && !is_ipaddrv6($ip_address)) || ($ipver != 6 && !is_ipaddrv4($ip_address))) { + return 'down'; + } + + return $ip_address; +} diff --git a/dns/dyndns/src/etc/inc/plugins.inc.d/dyndns/phpDynDNS.inc b/dns/dyndns/src/etc/inc/plugins.inc.d/dyndns/phpDynDNS.inc index 44ceb9755..0bf690816 100644 --- a/dns/dyndns/src/etc/inc/plugins.inc.d/dyndns/phpDynDNS.inc +++ b/dns/dyndns/src/etc/inc/plugins.inc.d/dyndns/phpDynDNS.inc @@ -2022,7 +2022,7 @@ class updatedns function _checkIP() { - $ip_address = get_dyndns_ip($this->_if, $this->_useIPv6 ? 6 : 4); + $ip_address = get_dyndns_ip_address($this->_if, $this->_useIPv6 ? 6 : 4); if (!is_ipaddr($ip_address)) { if ($this->_dnsVerboseLog) { log_error("Dynamic DNS ({$this->_dnsHost}): IP address could not be extracted"); diff --git a/dns/dyndns/src/www/services_dyndns.php b/dns/dyndns/src/www/services_dyndns.php index 30f5d259c..a209477ba 100644 --- a/dns/dyndns/src/www/services_dyndns.php +++ b/dns/dyndns/src/www/services_dyndns.php @@ -110,6 +110,11 @@ legacy_html_escape_form_data($a_dyndns);