IPWatch

2009
05.27

Avevo fatto un post sul programma ma grazie agli amici di PerlMonks e alla mia proverbiale intelligenza, la cosa si è espansa al punto di necessitare una pagina a parte…

Purpose

Questo semplice script esiste per sostituire i vari Dynamic DNS gratuiti che spesso svolgono un lavoro frammentario e inaffidabile. Non si pone come DNS dinamico vero e proprio ma piuttosto cerca di sopperire alle lacune temporali di questi ultimi.

Descrizione

Il programma è composto principalmente di un file che contiene il sorgente vero e proprio dello script, di un file di testo e di una riga in crontab. Lo script in Perl viene eseguito ad intervalli regolari (spesso 10 minuti) da cron per interrogare la pagina http://www.chisono.it/ip.asp e ricavare l’indirizzo IP della propria connessione ad internet. Fatto ciò confronta l’indirizzo trovato con quello salvato precedentemente nel file di testo e in caso di cambiamento invia una email di notifica ad un determinato indirizzo internet tramite il software (installato su quasi tutti i sistemi *nix) mailx, quindi sostituisce l’indirizzo contenuto nel file di testo con quello appena ricavato. Se è impostata correttamente la variabile, viene fatto anche un aggiornamento su un server web che supporti i CGI.

Sorgente

#!/usr/bin/perl
use warnings;
use strict;
 
use HTTP::Request::Common;
use LWP::UserAgent;
use LWP::Simple;
use Tie::File;
use Sys::Syslog qw( :DEFAULT setlogsock );
 
# ------------------------------------------------------------------
# Variables definition
# PLEASE CHANGE THESE VARIABLES TO REFLECT YOUR OWN ENVIRONMENT
#
my $file     = 'myip.txt';
#
# Insert your email address where you want to receive notifications
my $emailadd = 'your@email.com';
#
# Change yourmachine with the name of your machine
my $fromadd  = 'ipwatch@yourmachine';
#
# Change this to 0 or comment it if you don't want to use
# the CGI update feature
my $usecgi = 1;
#
# Change this with the full URL of your CGI script
my $cgiurl = 'http://your/url/to/cgi';
#
# End variables definition
#
# ------------------------------------------------------------------
 
 
 
 
#
# Retrieves the ip from chisono.it or exit
#
my $current_ip = get( 'http://www.chisono.it/ip.asp' ) or do {
    logit( 'err', "Cannot retrieve the IP address\n" );
    exit 1;
    };
 
#
# Update the $current_ip variable
#
$current_ip =~ s/\s+$//;
 
#
# Read the (old) ip from the file
#
tie my @read_ip, 'Tie::File', $file or do {
    logit( 'err', "Cannot open $file: $!\n" );
    exit 2;
    };
 
#
# Check if the ip just retrieved is the same of the file
#
if ( $read_ip[ 0 ] eq $current_ip ) {
    logit( 'info', "Address not changed\n" );
    exit 0;
    }
 
#
# If the script arrives at this point means that the ip has changed
#
 
#
# Update the file
#
$read_ip[ 0 ] = $current_ip;
untie @read_ip;
 
#
# Send the email
#
0 == system qq(mailx -s "IP changed!" -a "From: IPWatch <$fromadd>" $emailadd < $file) or do {
    logit( 'err', "Cannot send the email!\n" );
    exit 3;
    };
 
logit( 'info', "Address changed: old IP: $read_ip[0] ; New IP: $current_ip\n" );
 
#
# Update the CGI
#
if ($usecgi) {
        my $ua = LWP::UserAgent->new;
        $ua->request(POST $cgiurl, [PAR1 => $current_ip]);
}
 
#
# Provide basilar functions to log into syslog
#
sub logit {
    my ( $priority, $msg ) = @_;
    return unless $priority =~ /^(?:info|err|debug)$/;
    setlogsock( 'unix' );
    openlog( $0, 'pid,cons', 'user' );
    syslog( $priority, $msg );
    closelog();
    }

Script CGI

#!/usr/bin/perl -w
 
use strict;
use CGI qw(:standard);
use CGI::Carp qw(fatalsToBrowser);
 
my $addr = param('PAR1');
my $file = 'list';
 
if ($addr) {
    open(F, ">>$file") or die "can't open $file $!";
    print F "$addr|" . scalar localtime() . "\n\n";
    close F;
}
 
exit;

Questo file va posizionato su di un server web nella cartella cgi-bin e reso eseguibile. Nella stessa directory deve anche trovarsi un file chiamato list che viene aggiornato da questo script.
Lo script accetta parametri in ingresso passati da ipwatch.pl tramite POST

#!/usr/bin/perl
use strict;
use CGI qw(:standard);
use CGI::Carp qw(fatalsToBrowser);
 
my $file = 'list';
 
open(R, "<$file") or die "can't open $file $!";
my @cont = <R>;
close R;
 
print "Content-type: text/html\n\n";
print "<html>\n";
print "<head>\n";
print "<title>TEST DYNAMIC DNS</title>\n";
print "</head>\n";
print "<body>\n";
print "<h1>TEST DNS DINAMICO</h1>\n";
print "<table cellpadding=5 border=1>\n";
print "<tr><th>IP</th><th>ORARIO</th>\n";
 
chomp(@cont);
foreach my $line (@cont){
	(my $ip,my $orario)=split(/\|/,$line);
	print "<tr><td>$ip</td><td>$orario</td></tr>\n";
}
 
print "</table>\n";
print "</body>\n";
print "</html>\n";

Questo file va posizionato su di un server web nella cartella cgi-bin e reso eseguibile. Nella stessa directory deve anche trovarsi un file chiamato list che viene letto da questo script.

Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • email
  • Identi.ca
  • LinkedIn
  • PDF
  • RSS
  • Twitter
  • FriendFeed
  • Slashdot

Your Reply

Spam Protection by WP-SpamFree