#!/usr/bin/perl

use strict;
use LWP::UserAgent;
use Net::DNS;

### Configuration options!
# Web server to read external IP address from
my $ipserver = "http://www.whatismyip.com/automation/n09230945.asp";
# DNS server to push DNS updates to, and to read DNS from
my $dnsserver = "example.org";
# The DNS zone to update
my $zone = "example.org";
# TTL for our updates, in seconds
my $ttl = 60*5;
# Domain name to read IP of, and to change IP when it doesn't match ours
my $domain = "ddns.example.org.";
# Keyfile to use for TSIG or SIG(0)
my $privatefile = "Kddns.example.org.+005+12345.private";


# Read our IP address
my $ua = new LWP::UserAgent;
my $req = HTTP::Request->new(GET => $ipserver);
my $res = $ua->request($req);
my $ip;
if ($res->is_success) {
    $ip = $res->content;
    chomp $ip;
    print "My IP is $ip\n";
} else {
    die "Could not read IP address from $ipserver";
}

# Get IP address that our domain currently points to
my $res = Net::DNS::Resolver->new([nameservers => qw($dnsserver)]);
my $q = $res->query($domain, "A");
my $match = 0;
my $any = 0;
print "IPs for $domain:\n";
if ($q) {
    foreach my $rr (grep { $_->type eq 'A' } $q->answer) {
        $any = 1;
        print "  " . $rr->address . "\n";
        if ($rr->address eq $ip) {
            $match = 1;
        }
    }
}
print "  None!\n" if (!$any);

# Push new IP address if needed
if ($match) {
    print "Current IP address matches one in record.  No changes.\n";
} else {
    print "Current IP address does not show up in record.  Must dynamically update.\n";
    my $updatestr =  <<EOF;
server $dnsserver
zone $zone
update delete $domain A
update add $domain $ttl A $ip
show
send
quit
EOF
    `echo "$updatestr" | nsupdate -k $privatefile`;
}

