#!/usr/bin/perl
#
# obtain the IP address from M10
# Copyright 1999-2003 DVL Software Limited
#
# This script is available from http://www.freebsddiary.org/samples/obtain_ip.pl
# For more information on this script, please 
# read http://freebsddiary.org/dyndns2.php
#
# You are free to use, modify, distribute this script so long as the comments
# at the top of the file remain intact.

use Socket;
use MIME::Base64;

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

$routerAddress       = "192.168.1.254";
$username            = "blank";
$password            = "Telecom";
$NotifyByMail        = "root, youremail\@example.org";
$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 (<SH>)
   {
      $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(<RESULTS>) {
         print MAIL;
      }
      close RESULTS;
            
      close MAIL;
   }
}
syslog( "stopped" );
