The FreeBSD Diary

The FreeBSD Diary (TM)

Providing practical examples since 1998

If you buy from Amazon USA, please support us by using this link.
[ HOME | TOPICS | INDEX | WEB RESOURCES | BOOKS | CONTRIBUTE | SEARCH | FEEDBACK | FAQ | FORUMS ]
Dynamic DNS - the scripts
These are the script files for Dynamic DNS.  You will need to modify the items in bold.

If you click on the <headers>, you can get the raw text instead of html.

<dns_fetch.sh>
#!/bin/sh

#HTTP_AUTH="basic:*"

export HTTP_AUTH="basic:*:userid:password"

#                                                                   
# this isn't needed.  It doesn't do much good anyway.  but was in the
# original yi.org script                                            
#                                                                   
                                                                    
#ip_addr=`netstat -rn | egrep ^0.0.0.0 | sed -e "s,.* ,,g" | \      
#       xargs /sbin/ifconfig | grep "inet.addr" | sed -e "s,.*addr:,," \
#       -e "s, .*,,"`                                               
                                                                    
#                                                                   
# get the incoming parameter from our perl script from where 
# we were launched
#                                                                   
ip_addr=$1                                                          
                               
now=`date`

fetch  -q -o /usr/home/dan/fetch_results.html\
        http://www.yi.org/bin/dyndns.fcgi?ipaddr=$ip_addr | \
        sed -e "s,^,$now: ," -e "s,<.*\?>,,g"
<obtain_ip.pl>
#!/usr/bin/perl
#

use Socket;
use MIME::Base64;

# ----------------------------------------------------------------------
# globals
# ----------------------------------------------------------------------

$routerAddress       = "192.168.1.254";
$username            = "blank";
$password            = "Telecom";
$NotifyByMail        = "root, yourname\@yourdomain.com";
$EmptyIP             = "0.0.0.0";
$IPFilename          = "/usr/home/dan/myip.txt";
$DNSUpdateScript     = "/usr/home/dan/dns_fetch.sh";
$DNSUpdateResults    = "/usr/home/dan/fetch_results.html";

# ----------------------------------------------------------------------
# syslog
# ----------------------------------------------------------------------

sub syslog( $ )
{
   my $msg = shift( @_ );

   system("logger -i -t DYDNS $msg");
}

# ----------------------------------------------------------------------
# FetchM10Address
# ----------------------------------------------------------------------

sub FetchM10Address()
{
   my $encoded;
   my $httpRequest;
   my $httpResponse;
   my $sin;

   $encoded = encode_base64( "$username:$password" );
   $httpRequest = "GET /shell/show+ip+interfaces HTTP 1.0\r\n"
                . "Accept: text/*, text/html\r\n"
                . "Authorization: Basic $encoded\r\n"
                . "\r\n";
   $httpResponse = "";

   socket( SH, PF_INET, SOCK_STREAM, getprotobyname('tcp') ) 
                            || die "can not create socket, $!\n";
   $sin = sockaddr_in( 80, inet_aton($routerAddress) );
   connect( SH, $sin ) || die "can not connect to router, $!\n";
   send( SH, $httpRequest, 0 );
   while ()
   {
      $httpResponse = $httpResponse . $_;
   }
   close( SH );

   $httpResponse =~ m/inet ([\d.]+) netmask 0 peer/;
   return $1;
}

# ----------------------------------------------------------------------
# getLastIP
# ----------------------------------------------------------------------

sub getLastIP()
{
   my $OldIP = "";

   if (open( FILE,"<$ipfilename" )) { $OldIP="<FILE">;
      chomp( $OldIP );
      close FILE;
   }

   return $OldIP;
}

# ----------------------------------------------------------------------
# writeIP
# ----------------------------------------------------------------------

sub writeIP( $ )
{
   $ip = shift( @_ );

   if (open( FILE, ">$IPFilename" ))
   {
      print FILE $ip;
      close FILE;
   }
   else
   {
      print "Error: couldn't write to file $IPFilename: $!\n";
   }
}

# ----------------------------------------------------------------------
# UpdateDNS
# ----------------------------------------------------------------------
#
# this returns a number > 0 (most likely one).
# otherwise, it returns zero.
#
sub UpdateDNS( $ )
{
   $ip = shift( @_ );

   print "Updating to IP $ip\n";

   #
   # although we get passed the new IP, we don't 
   # actually use it here because the DNS update script is self 
   # contained.
   #
   system $DNSUpdateScript,$ip;

   #
   # Confirm that the IP returned by the script is contained in the html.
   # If it is, then the update succeeded.  If not, it failed.
   #
   $Count = `grep -c $ip $DNSUpdateResults 2>/dev/null`;
   print "count = $Count\n";

   if ($Count == 0) {
      $Result = "0"
   }
   else {
      $Result = "1";
   }

   return $Result
}

# ------------------------------------------------------------------------
# main
# ------------------------------------------------------------------------

print "DYNDNS\n";

syslog( "start" );

$currentIP = FetchM10Address();
$lastIP    = getLastIP();

print "currentIP = $currentIP,  lastIP = $lastIP\n";

if ($currentIP eq $EmptyIP)
{
   #
   # sometimes the router has no IP address
   #
   syslog( "The IP Address is unassigned ($currentIP)" );
}
else
{
   if ($currentIP ne $lastIP)
   {
      print "change detected\n";

      #
      # update our DNS with the new IP
      #
      $Result = UpdateDNS( $currentIP );
      print "Result = '$Result'\n";

      syslog( "The IP Address has changed to $currentIP" );

      #
      # send some email to let people know it's changed
      #
      open  MAIL, "|mail -s 'Dynamic DNS change' $NotifyByMail";
      print MAIL "The IP Address has changed to $currentIP\n";

      #
      # but if the DNS updated failed, let them know that too.
      #
      if ($Result eq "0") {
         syslog( "but the update script has failed.  Details follow.");
         print MAIL "but the update script has failed.  Details follow.\n";
         print "update failed\n";
      }
      else {
         writeIP( $currentIP );
         print "update succeeded\n";
      }

      #
      # include the fetch results in the email
      #
      open (RESULTS, "fetch_results.html");
      while() {
         print MAIL;
      }
      close RESULTS;
            
      close MAIL;
   }
}
syslog( "stopped" );