diff --git a/ddclient b/ddclient index 3e3bd8f..3ebcb17 100755 --- a/ddclient +++ b/ddclient @@ -292,6 +292,7 @@ my %builtinfw = ( }, ); my %ip_strategies = ( + 'no' => ": do not obtain an IPv4 address for this host", 'ip' => ": obtain IP from -ip {address}", 'web' => ": obtain IP from an IP discovery page on the web", 'fw' => ": obtain IP from the firewall specified by -fw {type|address}", @@ -307,6 +308,7 @@ sub ip_strategies_usage { my %ipv6_strategies = ( + 'no' => ": do not obtain an IPv6 address for this host", 'ip' => ": obtain IP from -ipv6 {address}", 'if' => ": obtain IP from the -if {interface}", 'cmd' => ": obtain IP from the -cmdv6 {external-command}", @@ -391,7 +393,7 @@ my %variables = ( 'host' => setv(T_STRING, 1, 1, 1, '', undef), 'use' => setv(T_USE, 0, 0, 1, 'ip', undef), - 'usev6' => setv(T_USE, 0, 0, 1, undef, undef), + 'usev6' => setv(T_USEV6, 0, 0, 1, undef, undef), 'if' => setv(T_IF, 0, 0, 1, 'ppp0', undef), 'if-skip' => setv(T_STRING,0, 0, 1, '', undef), 'web' => setv(T_STRING,0, 0, 1, 'dyndns', undef), @@ -947,7 +949,7 @@ sub update_nics { } else { $ip = get_ip($use, $h); if (!defined $ip || !$ip) { - warning("%s: unable to determine IPv4 address", $h) + warning("%s: unable to determine IPv4 address with strategy use=%s", $h, $use) if !$daemon || opt('verbose'); } elsif ($ip !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { warning("%s: malformed IPv4 address (%s)", $h, $ip); @@ -963,7 +965,7 @@ sub update_nics { } else { $ipv6 = get_ipv6($usev6, $h); if (!defined $ipv6 || !$ipv6) { - warning("%s: unable to determine IPv6 address", $h) + warning("%s: unable to determine IPv6 address with strategy usev6=%s", $h, $usev6) if !$daemon || opt('verbose'); } elsif ($ipv6 !~ /^(((?=.*(::))(?!.*\3.+\3))\3?|([\dA-F]{1,4}(\3|:\b|$)|\2))(?4){5}((?4){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})\z/ai) { # That little gem from http://home.deds.nl/~aeron/regex/ @@ -2273,35 +2275,35 @@ sub get_ip { $arg = '' unless $arg; if ($use eq 'ip') { - $ip = opt('ip', $h); - $arg = 'ip'; + $ip = opt('ip', $h); + $arg = 'ip'; } elsif ($use eq 'if') { - $skip = opt('if-skip', $h) || ''; - $reply = `ifconfig $arg 2> /dev/null`; - $reply = `ip addr list dev $arg 2> /dev/null` if $?; - $reply = '' if $?; + $skip = opt('if-skip', $h) || ''; + $reply = `ifconfig $arg 2> /dev/null`; + $reply = `ip addr list dev $arg 2> /dev/null` if $?; + $reply = '' if $?; } elsif ($use eq 'cmd') { - if ($arg) { - $skip = opt('cmd-skip', $h) || ''; - $reply = `$arg`; - $reply = '' if $?; - } + if ($arg) { + $skip = opt('cmd-skip', $h) || ''; + $reply = `$arg`; + $reply = '' if $?; + } } elsif ($use eq 'web') { - $url = opt('web', $h) || ''; - $skip = opt('web-skip', $h) || ''; + $url = opt('web', $h) || ''; + $skip = opt('web-skip', $h) || ''; - if (exists $builtinweb{$url}) { - $skip = $builtinweb{$url}->{'skip'} unless $skip; - $url = $builtinweb{$url}->{'url'}; - } - $arg = $url; + if (exists $builtinweb{$url}) { + $skip = $builtinweb{$url}->{'skip'} unless $skip; + $url = $builtinweb{$url}->{'url'}; + } + $arg = $url; - if ($url) { - # when using a web server to find public IPv4 address we should force use of IPv4 - $reply = geturl(opt('proxy', $h), $url, undef, undef, undef, undef, undef, '4') || ''; + if ($url) { + # when using a web server to find public IPv4 address we should force use of IPv4 + $reply = geturl(opt('proxy', $h), $url, undef, undef, undef, undef, undef, '4') || ''; } } elsif (($use eq 'cisco')) { @@ -2338,6 +2340,9 @@ sub get_ip { $reply = geturl('', $url, opt('fw-login', $h), opt('fw-password', $h)) || ''; $arg = $url; + } elsif ($use eq 'no') { + $reply = '0.0.0.0'; + } else { $url = opt('fw', $h) || ''; $skip = opt('fw-skip', $h) || ''; @@ -2354,7 +2359,8 @@ sub get_ip { } if (!defined $reply) { $reply = ''; - } + } + if ($skip) { $skip =~ s/ /\\s/is; $reply =~ s/^.*?${skip}//is; @@ -2365,7 +2371,7 @@ sub get_ip { $ip = filter_local($ip) if opt('fw-banlocal', $h); } if (($use ne 'ip') && (define($ip,'') eq '0.0.0.0')) { - $ip = undef; + $ip = undef; } debug("get_ip: using %s, %s reports %s", $use, $arg, define($ip, "")); @@ -2389,38 +2395,41 @@ sub get_ipv6 { $skip = opt('if-skip', $h) || ''; $reply = `ip -6 addr list dev $arg | grep "scope.global" 2> /dev/null`; if ($reply =~ /.*? ([0-9:][^\/]*)/i) { - $reply = $1; + $reply = $1; } else { $reply = '' } } elsif ($usev6 eq 'cmd') { - $arg = opt('cmdv6', $h); - if ($arg) { - $skip = opt('cmdv6-skip', $h) || ''; - debug("GetIPv6 cmd: %s",$arg); - $reply = `$arg`; - $reply = '' if $?; - } + $arg = opt('cmdv6', $h); + if ($arg) { + $skip = opt('cmdv6-skip', $h) || ''; + debug("GetIPv6 cmd: %s",$arg); + $reply = `$arg`; + $reply = '' if $?; + } } elsif ($usev6 eq 'web') { - $url = opt('webv6', $h) || ''; - $skip = opt('webv6-skip', $h) || ''; + $url = opt('webv6', $h) || ''; + $skip = opt('webv6-skip', $h) || ''; - if (exists $builtinweb{$url}) { - $skip = $builtinweb{$url}->{'skip'} unless $skip; - $url = $builtinweb{$url}->{'url'}; + if (exists $builtinweb{$url}) { + $skip = $builtinweb{$url}->{'skip'} unless $skip; + $url = $builtinweb{$url}->{'url'}; + } + $arg = $url; + + if ($url) { + # when using a web server to find our IPv6 address we should force use of IPv6 + $reply = geturl(opt('proxy', $h), $url, undef, undef, undef, undef, undef, '6') || ''; + } + + } elsif ($usev6 eq 'no') { + $reply = ''; } - $arg = $url; - - if ($url) { - # when using a web server to find our IPv6 address we should force use of IPv6 - $reply = geturl(opt('proxy', $h), $url, undef, undef, undef, undef, undef, '6') || ''; - } - - } + if (!defined $reply) { - $reply = ''; + $reply = '::'; } if ($skip) { $skip =~ s/ /\\s/is; @@ -2530,101 +2539,99 @@ sub nic_updateable { my $ipv6 = $config{$host}{'wantipv6'}; if ($config{$host}{'login'} eq '') { - warning("null login name specified for host %s.", $host); + warning("null login name specified for host %s.", $host); } elsif ($config{$host}{'password'} eq '') { - warning("null password specified for host %s.", $host); + warning("null password specified for host %s.", $host); } elsif ($opt{'force'}) { - info("forcing update of %s.", $host); - $update = 1; + info("forcing update of %s.", $host); + $update = 1; } elsif (!exists($cache{$host})) { - info("forcing updating %s because no cached entry exists.", $host); - $update = 1; + info("forcing updating %s because no cached entry exists.", $host); + $update = 1; } elsif ($cache{$host}{'wtime'} && $cache{$host}{'wtime'} > $now) { - warning("cannot update %s from %s to %s until after %s.", - $host, - ($cache{$host}{'ip'} ? $cache{$host}{'ip'} : ''), $ip, - prettytime($cache{$host}{'wtime'}) - ); + warning("cannot update %s from %s to %s until after %s.", + $host, + ($cache{$host}{'ip'} ? $cache{$host}{'ip'} : ''), $ip, + prettytime($cache{$host}{'wtime'}) + ); } elsif ($cache{$host}{'mtime'} && interval_expired($host, 'mtime', 'max-interval')) { - warning("forcing update of %s from %s to %s; %s since last update on %s.", - $host, - ($cache{$host}{'ip'} ? $cache{$host}{'ip'} : ''), $ip, - prettyinterval($config{$host}{'max-interval'}), - prettytime($cache{$host}{'mtime'}) - ); - $update = 1; + warning("forcing update of %s from %s to %s; %s since last update on %s.", + $host, + ($cache{$host}{'ip'} ? $cache{$host}{'ip'} : ''), $ip, + prettyinterval($config{$host}{'max-interval'}), + prettytime($cache{$host}{'mtime'}) + ); + $update = 1; - } elsif ((!exists($cache{$host}{'ip'})) || - ("$cache{$host}{'ip'}" ne "$ip")) { + } elsif (defined($cache{$host}{'use'} && ($cache{$host}{'use'} ne 'no')) && + ((!exists($cache{$host}{'ip'})) || ("$cache{$host}{'ip'}" ne "$ip"))) { if (($cache{$host}{'status'} eq 'good') && !interval_expired($host, 'mtime', 'min-interval')) { - warning("skipping update of %s from %s to %s.\nlast updated %s.\nWait at least %s between update attempts.", - $host, - ($cache{$host}{'ip'} ? $cache{$host}{'ip'} : ''), - $ip, - ($cache{$host}{'mtime'} ? prettytime($cache{$host}{'mtime'}) : ''), - prettyinterval($config{$host}{'min-interval'}) - ) - if opt('verbose') || !define($cache{$host}{'warned-min-interval'}, 0); - - $cache{$host}{'warned-min-interval'} = $now; + warning("skipping update of %s from %s to %s.\nlast updated %s.\nWait at least %s between update attempts.", + $host, + ($cache{$host}{'ip'} ? $cache{$host}{'ip'} : ''), + $ip, + ($cache{$host}{'mtime'} ? prettytime($cache{$host}{'mtime'}) : ''), + prettyinterval($config{$host}{'min-interval'}) + ) + if opt('verbose') || !define($cache{$host}{'warned-min-interval'}, 0); + $cache{$host}{'warned-min-interval'} = $now; - } elsif (($cache{$host}{'status'} ne 'good') && !interval_expired($host, 'atime', 'min-error-interval')) { + } elsif (($cache{$host}{'status'} ne 'good') && !interval_expired($host, 'atime', 'min-error-interval')) { - warning("skipping update of %s from %s to %s.\nlast updated %s but last attempt on %s failed.\nWait at least %s between update attempts.", - $host, - ($cache{$host}{'ip'} ? $cache{$host}{'ip'} : ''), - $ip, - ($cache{$host}{'mtime'} ? prettytime($cache{$host}{'mtime'}) : ''), - ($cache{$host}{'atime'} ? prettytime($cache{$host}{'atime'}) : ''), - prettyinterval($config{$host}{'min-error-interval'}) - ) - if opt('verbose') || !define($cache{$host}{'warned-min-error-interval'}, 0); + warning("skipping update of %s from %s to %s.\nlast updated %s but last attempt on %s failed.\nWait at least %s between update attempts.", + $host, + ($cache{$host}{'ip'} ? $cache{$host}{'ip'} : ''), + $ip, + ($cache{$host}{'mtime'} ? prettytime($cache{$host}{'mtime'}) : ''), + ($cache{$host}{'atime'} ? prettytime($cache{$host}{'atime'}) : ''), + prettyinterval($config{$host}{'min-error-interval'}) + ) + if opt('verbose') || !define($cache{$host}{'warned-min-error-interval'}, 0); + $cache{$host}{'warned-min-error-interval'} = $now; - $cache{$host}{'warned-min-error-interval'} = $now; - - } else { - $update = 1; - } - } elsif ((!exists($cache{$host}{'ipv6'})) || - ("$cache{$host}{'ipv6'}" ne "$ipv6")) { + } else { + $update = 1; + } + + } elsif (defined($cache{$host}{'usev6'} && ($cache{$host}{'usev6'} ne 'no') ) && + ((!exists($cache{$host}{'ipv6'})) || ("$cache{$host}{'ipv6'}" ne "$ipv6"))) { if (($cache{$host}{'status'} eq 'good') && !interval_expired($host, 'mtime', 'min-interval')) { warning("skipping update of %s from %s to %s.\nlast updated %s.\nWait at least %s between update attempts.", - $host, - ($cache{$host}{'ipv6'} ? $cache{$host}{'ipv6'} : ''), - $ipv6, - ($cache{$host}{'mtime'} ? prettytime($cache{$host}{'mtime'}) : ''), - prettyinterval($config{$host}{'min-interval'}) + $host, + ($cache{$host}{'ipv6'} ? $cache{$host}{'ipv6'} : ''), + $ipv6, + ($cache{$host}{'mtime'} ? prettytime($cache{$host}{'mtime'}) : ''), + prettyinterval($config{$host}{'min-interval'}) ) if opt('verbose') || !define($cache{$host}{'warned-min-interval'}, 0); - - $cache{$host}{'warned-min-interval'} = $now; + $cache{$host}{'warned-min-interval'} = $now; } elsif (($cache{$host}{'status'} ne 'good') && !interval_expired($host, 'atime', 'min-error-interval')) { warning("skipping update of %s from %s to %s.\nlast updated %s but last attempt on %s failed.\nWait at least %s between update attempts.", - $host, - ($cache{$host}{'ipv6'} ? $cache{$host}{'ipv6'} : ''), - $ipv6, - ($cache{$host}{'mtime'} ? prettytime($cache{$host}{'mtime'}) : ''), - ($cache{$host}{'atime'} ? prettytime($cache{$host}{'atime'}) : ''), - prettyinterval($config{$host}{'min-error-interval'}) + $host, + ($cache{$host}{'ipv6'} ? $cache{$host}{'ipv6'} : ''), + $ipv6, + ($cache{$host}{'mtime'} ? prettytime($cache{$host}{'mtime'}) : ''), + ($cache{$host}{'atime'} ? prettytime($cache{$host}{'atime'}) : ''), + prettyinterval($config{$host}{'min-error-interval'}) ) if opt('verbose') || !define($cache{$host}{'warned-min-error-interval'}, 0); - - $cache{$host}{'warned-min-error-interval'} = $now; + $cache{$host}{'warned-min-error-interval'} = $now; } else { $update = 1; } + } elsif (defined($sub) && &$sub($host)) { - $update = 1; + $update = 1; } elsif ((defined($cache{$host}{'static'}) && defined($config{$host}{'static'}) && ($cache{$host}{'static'} ne $config{$host}{'static'})) || (defined($cache{$host}{'wildcard'}) && defined($config{$host}{'wildcard'}) && @@ -2633,28 +2640,29 @@ sub nic_updateable { ($cache{$host}{'mx'} ne $config{$host}{'mx'})) || (defined($cache{$host}{'backupmx'}) && defined($config{$host}{'backupmx'}) && ($cache{$host}{'backupmx'} ne $config{$host}{'backupmx'})) ) { - info("updating %s because host settings have been changed.", $host); - $update = 1; + info("updating %s because host settings have been changed.", $host); + $update = 1; } else { - success("%s: skipped: IP address was already set to %s.", $host, $ip) - if opt('verbose'); + success("%s: skipped: IP address was already set to %s.", $host, $ip) + if opt('verbose'); } $config{$host}{'status'} = define($cache{$host}{'status'},''); $config{$host}{'update'} = $update; if ($update) { - $config{$host}{'status'} = 'noconnect'; - $config{$host}{'atime'} = $now; - $config{$host}{'wtime'} = 0; - $config{$host}{'warned-min-interval'} = 0; - $config{$host}{'warned-min-error-interval'} = 0; + $config{$host}{'status'} = 'noconnect'; + $config{$host}{'atime'} = $now; + $config{$host}{'wtime'} = 0; + $config{$host}{'warned-min-interval'} = 0; + $config{$host}{'warned-min-error-interval'} = 0; - delete $cache{$host}{'warned-min-interval'}; - delete $cache{$host}{'warned-min-error-interval'}; + delete $cache{$host}{'warned-min-interval'}; + delete $cache{$host}{'warned-min-error-interval'}; } return $update; } + ###################################################################### ## header_ok ######################################################################