The FreeBSD Diary

The FreeBSD Diary (TM) Remember
I remember
[ HOME | TOPICS | INDEX | WEB RESOURCES | BOOKS | CONTRIBUTE | SEARCH | FEEDBACK | FAQ | FORUMS ]

Things look quiet here. But I've been doing a lot of blogging at dan.langille.org because I prefer WordPress now. Not all my posts there are FreeBSD related. I am in the midst of migrating The FreeBSD Diary over to WordPress (and you can read about that here). Once the migration is completed, I'll move the FreeBSD posts into the new FreeBSD Diary website.

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" );