Howdy,
        After finding zoneedit's dynamic updating, I decided to write a 
perl script to auto update the records I host there whenever my IP address 
changes.  The problem I had is that I use a linksys router to do NAT and 
give me wireless.  So, after some noodling on it, I came up with this 
script to scrape the public IP address out of the linksys's Status page.  
I know that I'd heard of some folks using zoneedit on these lists, so I'm 
sending it around.  Feel free to improve/comment.  No warranty is given!

Ben



-- 

There are only 10 types of people in this world...
those who understand binary, and those who don't.

#!/usr/bin/perl -w
use strict;
use IO::Socket;

# Define the hostnames to update at zoneedit
my @hostnames = ( "mydomain.com",
                "mail.mydomain.com",
                "myotherdomain.com",
                "mail.myotherdomain.com",
                "www.myotherdomain.com",
                );
# zoneedit username
my $username = "Username1";
# zoneedit password for above username
my $password = "p455w0rd";
# location of the wget binary
my $wget = "/usr/bin/wget";
# location of the file you would like to store the router's public IP address in
my $router_ip_config = "/etc/router_pub_ip";

# password for the linksys, to do a screenscrape and grab the
# current IP.  Set linksys_in_use to 0 if you don't have one.
my $linksys_in_use = 1;
my $linksys_pw = "p455w0rd";
# we assume that the default GW is the linksys.
# if this is incorrect, set it here:
my $linksys_ip = "";

# get the linksys's current external IP address.
my $router_cur_ip;
if ($linksys_in_use) {
        $router_cur_ip = &linksys_scrape($linksys_pw, $linksys_ip);
} else { 
        # If you're not using a linksys, write your own function
        # here to retrieve the IP address of your external connection
        $router_cur_ip = 0; 
}       

# compare the linksys's current public IP with what we wrote down
# last time.
if ( -f $router_ip_config) {
        require $router_ip_config;
}

# if they're different, update the file containing the router's
# public IP and then update zoneedit.
if ($router_cur_ip ne $Config::router_pub_ip) { 
        &update_router_pub_ip($router_cur_ip);
        &update_zoneedit(\@hostnames);
}

# Linksys scrape sub.  This pulls the linksys's public IP address out of 
# the status page.  This may need some tuning for firmware versions other
# than 1.42.7
# Call this with linksys_scrape(linksys_pw, linksys_ip).  If your default
# gw is the linksys, no need for linksys_ip.
sub linksys_scrape {
        my $linksys_pw = shift;
        my $linksys_ip = shift;
        ($linksys_ip = &get_default_gw) unless $linksys_ip;
        my $data = `$wget -O - --http-user=x --http-passwd=$linksys_pw 
'http://$linksys_ip/Status.htm' 2>/dev/null`;
        $data =~ s/.*IP Address:<\/td><td><font face=verdana size=2>//;
        $data =~ s/<.*//;
        return $data;
}

# sub to get the default gateway.  relies on netstat.
sub get_default_gw {
        # get the output of netstat
        my @route_info_lines = split(/\n/, `netstat -rn`);
        # grab the last line (where the default gw hangs out)
        my $lastline = $route_info_lines[(scalar(@route_info_lines) - 1)];
        # split the line into fields and take the second field.
        my $defgw = (split(/\s+/, $lastline))[1];
        # return the default gw
        return $defgw;
}

# sub to update the config file that we store the default router IP
# address in.
sub update_router_pub_ip {
        my $new_ip = shift;
        # open (and clobber the old) file for writing
        open (RTRPUB, "+>$router_ip_config");
        print RTRPUB "# This file contains your router (linksys, linux, 
whatever)'s\n",
                        "# public IP Address.  This is used by the dynamic updating 
program\n",
                        "# you use to update zoneedit.  Please do not edit this file 
unless\n",
                        "# you're sure that you know what you're doing.\n",
                        "package Config;\n",
                        "\$router_pub_ip = \"$new_ip\";\n",
                        "# Old Router pub IP: $Config::router_pub_ip\n",
                        "1;";
        close RTRPUB;
}

sub update_zoneedit {
        my $hostsref = shift;
        my @hosts = @$hostsref;
        # iterate over the hosts we defined at the top, updating each
        # with zoneedit's dynamic updating page.  As we update each, 
        # print a message saying so.  This will allow cron to mail
        # the results of changes to root.
        foreach my $host (@hosts) {
                system("$wget -O /dev/null --http-user=$username 
--http-passwd=$password 'http://dynamic.zoneedit.com/auth/dynamic.html?host=$host' 
2>/dev/null");
                print "$host updated to new IP: $router_cur_ip\n";
        }
}

Reply via email to