DynamicDNS.pl

From Organic Design wiki
Legacy.svg Legacy: This article describes a concept that has been superseded in the course of ongoing development on the Organic Design wiki. Please do not develop this any further or base work on this concept, this is only useful for a historic record of work done. You may find a link to the currently used concept or function in this article, if not you can contact the author to find out what has taken the place of this legacy item.
#!/usr/bin/perl
# Get last IP from local wiki log on startup
$::IP = '';
if (wikiRawPage($::wiki, $::wikilog) =~ /^.+to ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/sm) {
	$::IP = $1;
	logAdd "Last IP obtained from Network Log: $::IP";
	}

# Get current external IP address from router
sub getIP {
	my $router = shift;
	my $model = shift;
	my $ip = '';

	if ($model eq 'Dynalink:RTA230') {
		my $url = "http://admin:$::pwd2\@$routerIP/wancfg.cmd?action=view";
		$ip = $1 if $::client->get($url)->content =~ /(\d+\.\d+\.\d+\.\d+)/;
		}

	elsif ($model eq 'LinkSys:WAG54G') {
		my $url = "http://admin:$::pwd2\@$routerIP/Status_Router.asp";
		$ip = $1 if $::client->get($url)->content =~ /IP Address.+?(\d+\.\d+\.\d+\.\d+)/sm;
		}

	elsif ($model eq 'Dlink:DSL-G604T') {
		my $url = "http://admin:$::pwd2\@$routerIP/cgi-bin/webcm";
		my %form = (
			getpage => '../html/status/deviceinfofile.htm',
			'var:mycon' => 'connection0',
			'var:conid' => 'encaps0'
			);
		$ip = $1 if $::client->post($url,\%form)->content =~ /IP Address.+?IP Address.+?(\d+\.\d+\.\d+\.\d+)/sm;
		}
	else { logAdd "No rules for router model: $model" }

	$ip eq '0.0.0.0' ? '' : $ip;
	}


sub updateDNS {
	my $ip = shift;
	my $domain = shift;
	my @subDomains = @_;
	my $comment = "External IP has changed to $ip";
	my @succeeded = ();
	my @failed = ();
	for my $subDomain (@subDomains) {
		my $url = $domain =~ /\.co\.nz$/
		  ? "http://ADunkley:$::pwd3\@dynamic.zoneedit.com/auth/dynamic.html?host=$subDomain.$domain"
		  : "http://dynamicdns.park-your-domain.com/update?host=$subDomain&domain=$domain&password=$::pwd3";
		$::client->get($url)->is_success ? push(@succeeded,"$subDomain.$domain") : push(@failed,"$subDomain.$domain");
		}
	if ($#failed >= 0) {
		$comment .= ', DNS updates failed!';
		my $od = 'http://www.organicdesign.co.nz/wiki/index.php';
		wikiLogin($od,$::peer,$::pwd1);
		wikiPageAppend(
			$od,
			'user_talk:nad',
			"\n----\n$comment.\n\nThese domains failed:\n*".join("\n*",@failed)."\n:--~~"."~~\n",
			"Sorry to bother you, but I need help updating some domains :-/"
			);
		}
	# update the IP log on the wiki
	logAdd $comment;
	wikiLogin($::wiki, $::peer, $::pwd1);
	wikiPageAppend($::wiki, $::wikilog, "\n*".localtime()." : $comment", $comment);

	$#failed < 0;
	}


# update IP with zoneedit.com/namecheap.com if changed
sub dynamicDNS {
	$::routerIP    = shift;
	$::routerModel = shift;
	$::domain      = shift;
	@::subDomains  = @_;

	# Loop forever checking IP from router every 10 seconds and updating DNS if changed
	while (1) {
		my $ip = getIP $::routerIP, $::routerModel;
		if ($ip && ($ip ne $::IP)) { $::IP = $ip if updateDNS $ip, $::domain, @::subDomains }
		sleep 10;
		}
	}

# Call this to do an immediate manual update (called from [[[[commands.pl]]]])
sub UpdateNow {
	my $ip = getIP $::routerIP, $::routerModel;
	$::IP = $ip if updateDNS $ip, $::domain, @::subDomains;
	}