#!/usr/bin/perl -w # # wanipup.pl Mar 29 2002 by David Efflandt # Unix version (Linux, etc.) # # Gets WAN IP and Connection Time from modified /begin.htm on DI-704[P]. # Only returns output when IP changes or error (for cron mail). # Optional Unix system log output ('tail -f /var/log/messages' to view). # Optional local file logging. # # NOTE: Requires modified firmware to display WAN IP on /begin.htm # without logging in. Firmware modification only changes # "Web Configuration" string to "Web Conf $XI $MT0" in BIN file # so $XI displays WAN IP and $MT0 displays Connection Time. # This is for PPP0E or DHCP, Connection Time for modem is $MT1. # # Perl Modules Used: # vars, Env, LWP, POSIX # Sys::Syslog if doing system logging # Var declarations (do not change) my ($ip, $ut, $newip); # main variables that can be in separate require file use vars qw ($di704 $ipfile $bg $poll $tick $tock $logfile); use Env qw(HOME); ### User Variables ### # DI-704 IP (or IP:88 when WAN access is activated) $di704 = '192.168.0.1'; # default # File to store previous IP (full path) $ipfile = "$HOME/.wanip"; # Background (daemon) if any string or positive number on commandline. # If changed from 0 to 1 below, use 0 on commandline to run once. $bg = shift or 0; # Poll interval if background (daemon) mode $poll = 300; # sec # How often to announce WAN IP in logs (alive status) # One less than multiple of $poll $tick = 3600; # sec # Subroutine to run if IP changes (full path) - use backticks # sub newip { return `/usr/local/bin/noip`; } # no-ip.com example sub newip { return `echo $ip "(newip cmd example)"`; } # DEBUG test # Log full path (comment out to not use, also see syslog below) # $logfile = "$HOME/wanip.log"; # Alternate file to override above variables (ignored if not readable) $rcfile = "$HOME/.waniprc"; # Flag for Unix syslog, 1 (yes), 0 (no) BEGIN { $main::syslog = 1; } ### End User Variables ### # Name of this script if ($0 =~ m|/([^/]+)$|) { $id = $1; } else { $id = $0; } # Exit if already running (to restart from cron if not running) # DEBUG NOTE: Comment out this block while editing/testing. if (grep(/$id/, `ps ax`) > 1) { exit 0 if $bg; die "Already running or being edited.\n"; } # Initialize local system log (unix) BEGIN { if ($main::syslog) { use Sys::Syslog qw(:DEFAULT setlogsock); setlogsock 'unix' || die "Can't setlogsock"; } } # Alternate $rcfile variables if it exists and readable if (-r $rcfile) { eval `cat $rcfile`; warn $@ if $@; } sub mylog { my $msg = shift; chomp $msg; if ($logfile) { if (open(LOG,">> $logfile") || open(LOG,"> $logfile")) { print LOG localtime() . " $id\[$$]: $msg\n"; close LOG; } } if ($syslog) { syslog('info',"$id\[$$]:$msg"); closelog(); } print "$msg\n" unless $bg; } # Initialize use LWP::UserAgent; $ua = new LWP::UserAgent; $tock = 0; sub checkip { my $req = new HTTP::Request GET => "http://$di704/begin.htm?RC=\@"; my $res = $ua->request($req); if ($res->is_success) { @lines = split /\n/, $res->content; $ip = ''; $ut = ''; foreach $line (@lines) { # find IP if ($line =~ /[^\d]?(\d+\.\d+\.\d+\.\d+)[^\d]+/) { $ip = $1; if ($line =~ /[^\d](\d+\:[\d:]+)[^\d]/) { $ut = $1; } last; } } return "Can't parse IP from /begin.htm" unless $ip; # Check if IP changed my $newip; if ((-s $ipfile) && open(IP, "+< $ipfile")) { if ("$ip\n" ne ) { seek IP,0,0; truncate IP,0; print IP "$ip\n"; $newip = 1; } close IP; } elsif (open (IP, "> $ipfile")) { print IP "$ip\n"; $newip = 1; close IP; } else { mylog("Can't store current IP: $!"); } if ($newip) { if ($ip eq '0.0.0.0') { mylog("$ip down"); } else { mylog("new IP $ip"); # Do sub and log result if any $_ = newip; # Comment next line if program does own syslog mylog($_) if ($_); } $tock = time + $tick; } else { if (time > $tock) { $tock = time + $tick; mylog("WAN $ip up $ut"); } } sleep $poll if $bg; return 0; } else { return "Could not access $di704"; } } use POSIX 'setsid'; # to daemonize sub daemonize { chdir '/' or die "Can't chdir to /: $!"; open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!"; defined(my $pid = fork) or die "Can't fork: $!"; exit if $pid; setsid or die "Can't start a new session: $!"; open STDERR, '>&STDOUT' or die "Can't dup stdout: $!"; } if ($bg) { mylog("Poll $di704 $poll/$tick sec"); daemonize; while (1) { mylog($_) if $_ = checkip; } } else { mylog("Polling $di704"); checkip; }