Ok, I've managed to fix this.
Endian uses ez-ipupdate to do the actual updating, this program was last updated in 2002.
Since then, ZoneEdit changed their update url from
www.zoneedit.com to dynamic.zonedit.com
A quick change to the /usr/local/bin/setddns.pl script fixes this by sending the right server address directive to ez-ipupdate.
Here is the setddns script:
#!/usr/bin/perl
#!/usr/bin/perl
#
# SmoothWall CGIs
#
# This code is distributed under the terms of the GPL
#
# (c) The SmoothWall Team
#
# $Id: setddns.pl,v 1.4.2.7 2004/10/12 16:36:10 alanh Exp $
#
# Modded to work with new ZoneEdit update URL - dynamic.zoneedit.com - By Darren Carter, www.citsystems.co.za. 2009/03/15
#
close(STDIN);
close(STDOUT);
close(STDERR);
use IO::Socket;
require '/var/efw/header.pl';
my %settings;
my %noipsettings;
my $filename = "${swroot}/ddns/config";
my $cachefile = "${swroot}/ddns/ipcache";
my $ipcache = 0;
open(FILE, "$filename") or die 'Unable to open config file.';
my @current = <FILE>;
close(FILE);
my $lines = $#current + 1;
unless($lines) { exit 0; }
my $ip = '';
if ( -f "${swroot}/ddns/behindnat" )
{
$ip = `/usr/local/bin/detectip`;
} else {
if (-f "${swroot}/uplinks/main/data") {
my %conf_hash = ();
readhash("${swroot}/uplinks/main/data", \%conf_hash);
$ip = $conf_hash{'ip_address'};
}
}
chomp $ip;
if ($ARGV[0] ne '-f')
{
open(IPCACHE, "$cachefile");
$ipcache = <IPCACHE>;
close(IPCACHE);
chomp $ipcache;
}
if ($ip ne $ipcache)
{
my $id = 0;
my $success = 0;
my $line;
foreach $line (@current)
{
$id++;
chomp($line);
my @temp = split(/\,/,$line);
unless ($temp[7] eq "off")
{
$settings{'SERVICE'} = $temp[0];
$settings{'HOSTNAME'} = $temp[1];
$settings{'DOMAIN'} = $temp[2];
$settings{'PROXY'} = $temp[3];
$settings{'WILDCARDS'} = $temp[4];
$settings{'LOGIN'} = $temp[5];
$settings{'PASSWORD'} = $temp[6];
$settings{'ENABLED'} = $temp[7];
my @service = split(/\./, "$settings{'SERVICE'}");
$settings{'SERVICE'} = "$service[0]";
if ($settings{'SERVICE'} eq 'no-ip')
{
$noipsettings{'LOGIN'} = $settings{'LOGIN'};
$noipsettings{'PASSWORD'} = $settings{'PASSWORD'};
$noipsettings{'HOSTNAME'} = $settings{'HOSTNAME'};
$noipsettings{'DOMAIN'} = $settings{'DOMAIN'};
$noipsettings{'DAEMON'} = 'N';
$noipsettings{'DEVICE'} = '';
$noipsettings{'INTERVAL'} = '1';
$noipsettings{'NAT'} = 'N';
$noipsettings{'GROUP'} = '';
if ($settings{'PROXY'} eq 'on') { $noipsettings{'PROXY'} = 'Y'; }
else { $noipsettings{'PROXY'} = 'N'; }
&writehash("${swroot}/ddns/noipsettings", \%noipsettings);
open(F, "${swroot}/ddns/noipsettings");
my @unsorted = <F>;
close(F);
my @sorted = sort { $b cmp $a } @unsorted;
open(F, ">${swroot}/ddns/noipsettings");
flock F, 2;
print F @sorted;
close(F);
my @ddnscommand = ('/usr/bin/noip','-c',"${swroot}/ddns/noipsettings",'-i',"$ip");
my $result = system(@ddnscommand);
if ( $result != 0) { &log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'}: failure"); }
else
{
&log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'}: success");
$success++;
}
}
elsif ($settings{'SERVICE'} eq 'selfhost')
{
my %proxysettings;
&readhash("${swroot}/proxy/settings", \%proxysettings);
my $peer = 'www.ns4you.de';
my $peerport = 80;
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
}
my $sock;
unless($sock = new IO::Socket::INET (PeerAddr => $peer, PeerPort => $peerport, Proto => 'tcp', Timeout => 5)) {
die "Could not connect to $peer:$peerport: $@";
return 1;
}
my $GET_CMD;
$GET_CMD = "GET http://www.ns4you.de/cgi-dns/dns.pl?$settings{'LOGIN'}&$settings{'PASSWORD'}&$ip HTTP/1.1\r\n";
$GET_CMD .= "Host: www.ns4you.de\r\n";
$GET_CMD .= "Connection: close\r\n\r\n";
print $sock "$GET_CMD";
my $out = '';
while(<$sock>) {
$out .= $_;
}
close($sock);
if ( $out =~ m/<meta name="ns4you" title="error"/ ) {
&log("Dynamic DNS ip-update ns4you failure");
}
else
{
$out =~ m/<meta name="ns4you" title="url" content="(.*)"/;
&log("Dynamic DNS ip-update for $1: success");
$success++;
}
}
elsif ($settings{'SERVICE'} eq 'nsupdate') {
# Fetch UI configurable values and assemble the host name.
my $hostName="$settings{'DOMAIN'}";
if ($settings{'HOSTNAME'} ne "") {
$hostName="$settings{'HOSTNAME'}.$hostName";
}
my $keyName=$settings{'LOGIN'};
my $keySecret=$settings{'PASSWORD'};
# Use a relatively long TTL value to reduce load on DNS.
# Some public Dynamic DNS servers use values around 4 hours,
# some use values as low as 60 seconds.
# Maybe we could fetch the master value from the server
# (not the timed-down version supplied by DNS cache)
my $timeToLive="3600";
# Internal setting that can be used to override the DNS server
# where the update is applied. It can be of use when testing
# against a private DNS server.
my $masterServer="";
# Prepare the nsupdate command script to remove and re-add the
# updated A record for the domain.
my $cmdFile="/tmp/nsupdate-$hostName-commands";
my $logFile="/tmp/nsupdate-$hostName-result";
open(TF, ">$cmdFile");
if ($masterServer ne "") {
print TF "server $masterServer\n";
}
if ($keyName ne "" && $keySecret ne "") {
print TF "key $keyName $keySecret\n";
}
print TF "update delete $hostName A\n";
print TF "update add $hostName $timeToLive A $ip\n";
print TF "send\n";
close(TF);
# Run nsupdate with -v to use TCP instead of UDP because we're
# issuing multiple cmds and potentially long keys, and -d to
# get diagnostic result output.
my $result = system("/usr/bin/nsupdate -v -d $cmdFile 2>$logFile");
if ($result != 0) {
&log("Dynamic DNS ip-update for $hostName: failure");
open(NSLOG, "$logFile");
my @nsLog = <NSLOG>;
close(NSLOG);
my $logLine;
foreach $logLine (@nsLog) {
chomp($logLine);
if ($logLine ne "") {
&log("... $logLine");
}
}
}
else
{
&log("Dynamic DNS ip-update for $hostName: success");
$success++;
}
unlink $cmdFile, $logFile;
}
elsif ($settings{'SERVICE'} eq 'freedns-afraid')
{
my %proxysettings;
&readhash("${swroot}/proxy/settings", \%proxysettings);
my $peer = 'freedns.afraid.org';
my $peerport = 80;
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
}
my $sock;
unless($sock = new IO::Socket::INET (PeerAddr => $peer, PeerPort => $peerport, Proto => 'tcp', Timeout => 5)) {
die "Could not connect to $peer:$peerport: $@";
return 1;
}
my $GET_CMD;
$GET_CMD = "GET http://freedns.afraid.org/dynamic/update.php?$settings{'LOGIN'} HTTP/1.1\r\n";
$GET_CMD .= "Host: freedns.afraid.org\r\n";
$GET_CMD .= "Connection: close\r\n\r\n";
print $sock "$GET_CMD";
my $out = '';
while(<$sock>) {
$out .= $_;
}
close($sock);
#Valid responses from service are:
#Updated yourdomain.afraid.org to your IP
#Address <ip> has not changed.
if ( $out !~ m/(Updated|Address .* has not changed)/ig ) {
#cleanup http response...
$out =~ s/.+?\015?\012\015?\012//s; # header HTTP
@out = split("\r", $out);
&log("Dynamic DNS afraid.org : failure (@out[1])");
}
else
{
&log("Dynamic DNS afraid.org : success");
$success++;
}
}
elsif ($settings{'SERVICE'} eq 'regfish')
{
my %proxysettings;
&readhash("${swroot}/proxy/settings", \%proxysettings);
my $peer = 'www.regfish.com';
my $peerport = 80;
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
}
my $sock;
unless($sock = new IO::Socket::INET (PeerAddr => $peer, PeerPort => $peerport, Proto => 'tcp', Timeout => 5)) {
die "Could not connect to $peer:$peerport: $@";
return 1;
}
my $GET_CMD;
$GET_CMD = "GET http://www.regfish.com/dyndns/2/?fqdn=$settings{'DOMAIN'}&thisipv4=true&forcehost=1&authtype=secure&token=$settings{'LOGIN'} HTTP/1.1\r\n";
$GET_CMD .= "Host: www.regfish.com\r\n";
$GET_CMD .= "Connection: close\r\n\r\n";
print $sock "$GET_CMD";
my $out = '';
while(<$sock>) {
$out .= $_;
}
close($sock);
#Valid responses from service:
#success|100|update succeeded!
#success|101|no update needed at this time..
if ( $out !~ m/(success\|(100|101)\|)/ig ) {
#cleanup http response...
$out =~ s/.+?\015?\012\015?\012//s; # header HTTP
@out = split("\r", $out);
&log("Dynamic DNS regfish.com : @out[1]");
}
else
{
&log("Dynamic DNS regfish.com : success");
$success++;
}
}
elsif ($settings{'SERVICE'} eq 'ovh')
{
my %proxysettings;
&readhash("${swroot}/proxy/settings", \%proxysettings);
my $peer = 'www.ovh.com';
my $peerport = 80;
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
}
my $sock;
unless($sock = new IO::Socket::INET (PeerAddr => $peer, PeerPort => $peerport, Proto => 'tcp', Timeout => 5)) {
die "Could not connect to $peer:$peerport: $@";
return 1;
}
if ($settings{'HOSTNAME'} eq '') {
$settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
}
else {
$settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
}
my $GET_CMD;
$GET_CMD = "GET http://www.ovh.com/nic/update?system=dyndns&hostname=$settings{'HOSTDOMAIN'}&myip=$ip HTTP/1.1\r\n";
$GET_CMD .= "Host: www.ovh.com\r\n";
chomp($code64 = encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}"));
$GET_CMD .= "Authorization: Basic $code64\r\n";
#$GET_CMD .= "User-Agent: ipcop\r\n";
#$GET_CMD .= "Content-Type: application/x-www-form-urlencoded\r\n";
$GET_CMD .= "\r\n";
print $sock "$GET_CMD";
my $out = '';
while(<$sock>) {
$out .= $_;
}
close($sock);
#HTTP response => error (in Title tag) else text response
#Valid responses from service:good,nochg (ez-ipupdate like)
#Should use ez-ipdate but "system=dyndns" is not present
if ( $out =~ m/<Title>(.*)<\/Title>/ig ) {
&log("Dynamic DNS ovh.com : failure ($1)");
}
elsif ($out !~ m/good |nochg /ig) {
$out =~ s/.+?\015?\012\015?\012//s; # header HTTP
@out = split("\r", $out);
&log("Dynamic DNS ovh.com : failure ($out[1])");
}
else {
&log("Dynamic DNS ovh.com : success");
$success++;
}
}
else
{
if ($settings{'WILDCARDS'} eq 'on') {$settings{'WILDCARDS'} = '-w';}
else {$settings{'WILDCARDS'} = '';}
if ($settings{'SERVICE'} eq 'dyndns-custom' && $settings{'HOSTNAME'} eq '') {$settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};}
else {$settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";}
if ($settings{'SERVICE'} = 'zoneedit') {$serverdir = '-s'; $serveradd = 'dynamic.zoneedit.com';}
else {$serverdir = ''; $serveradd = '';}
my @ddnscommand = ('/usr/bin/ez-ipupdate', '-a', "$ip", '-S', "$settings{'SERVICE'}", "$serverdir", "$serveradd", '-u', "$settings{'LOGIN'}:$settings{'PASSWORD'}", '-h', "$settings{'HOSTDOMAIN'}", "$settings{'WILDCARDS'}", '-q');
my $result = system(@ddnscommand);
if ( $result != 0) { &log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'}: failure"); }
else
{
&log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'}: success");
$success++;
}
}
}
else
{
# If a line is disabled, then we should discount it
$lines--;
}
}
if ($lines == $success)
{
open(IPCACHE, ">$cachefile");
flock IPCACHE, 2;
print IPCACHE $ip;
close(IPCACHE);
}
}
# Extracted from Base64.pm
sub encode_base64 ($;$)
{
my $res = "";
my $eol = $_[1];
$eol = "\n" unless defined $eol;
pos($_[0]) = 0; # ensure start at the beginning
while ($_[0] =~ /(.{1,45})/gs) {
$res .= substr(pack('u', $1), 1);
chomp($res);
}
$res =~ tr|` -_|AA-Za-z0-9+/|; # `# help emacs
# fix padding at the end
my $padding = (3 - length($_[0]) % 3) % 3;
$res =~ s/.{$padding}$/'=' x $padding/e if $padding;
# break encoded string into lines of no more than 76 characters each
if (length $eol) {
$res =~ s/(.{1,76})/$1$eol/g;
}
$res;
}
This code sets the server address if ZoneEdit is used:
if ($settings{'SERVICE'} = 'zoneedit') {$serverdir = '-s'; $serveradd = 'dynamic.zoneedit.com';}
else {$serverdir = ''; $serveradd = '';}
This is the line which calles ez-ipupdate: (the server directive was added here)
my @ddnscommand = ('/usr/bin/ez-ipupdate', '-a', "$ip", '-S', "$settings{'SERVICE'}", "$serverdir", "$serveradd", '-u', "$settings{'LOGIN'}:$settings{'PASSWORD'}", '-h', "$settings{'HOSTDOMAIN'}", "$settings{'WILDCARDS'}", '-q');
A change to the /home/httpd/cgi-bin/ddns.cgi script was also needed as the service must be stored as "zoneedit" instead of "zoneedit.com" this can be done in any text editor, just Find and Replace all "zoneedit.com" with "zoneedit".
Just copy and past over the origional script if you wish to use it, I have tested it and it works for me. Remember to save a backup of the origional script.