diff --git a/ddclient b/ddclient index 63a51a2..112acb8 100755 --- a/ddclient +++ b/ddclient @@ -947,7 +947,7 @@ sub update_nics { if !$daemon || opt('verbose'); next; } - if ($ip !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { + if (!is_ipv4($ip)) { if (!extract_ipv6($ip)) { warning("malformed IP address (%s)", $ip); next; @@ -1900,7 +1900,7 @@ sub check_value { } elsif ($type eq T_IP) { if (!extract_ipv6($value)) { - return undef if $value !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/; + return undef if !is_ipv4($value); } } return $value; @@ -2281,8 +2281,7 @@ sub get_ip { } if (defined($ip)) { # no need to parse $reply - } elsif ($reply =~ /^.*?\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b.*/is) { - $ip = $1; + } elsif ($ip = extract_ipv4($reply)) { $ip = un_zero_pad($ip); } elsif ($ip = extract_ipv6($reply)) { $ip = un_zero_pad($ip); @@ -2297,6 +2296,23 @@ sub get_ip { return $ip; } +###################################################################### +## is_ipv4() validates if string is valid IPv4 address and only +## a valid IPv4 address (no preceding or trailing spaces/characters) +###################################################################### +sub is_ipv4 { + my ($value) = @_; + return (length($value // '') != 0) && ($value eq (extract_ipv4($value) // '')); +} + +###################################################################### +## extract_ipv4() extracts the first valid IPv4 address from the given string +###################################################################### +sub extract_ipv4 { + (shift // '') =~ /\b((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))\b/ai; + return $1; +} + ###################################################################### ## is_ipv6() validates if string is valid IPv6 address ######################################################################