Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Script to Notify of Public IP Change

by Arkevius (Initiate)
on Nov 29, 2012 at 15:28 UTC ( #1006276=perlquestion: print w/replies, xml ) Need Help??
Arkevius has asked for the wisdom of the Perl Monks concerning the following question:

Hello all! I manage a Linux Ubuntu 12.04 LTS server for a local police department. They have cable internet, and unsure of whether or not their ISP provided them with a static or dynamic IP address, I wrote a perl script to notify me if the IP address should ever change (since I manage the server remotely). I only have 1 problem with this scripts. Sometimes, it seems to fetch a "blank" when trying to resolve the IP. It sees the "blank" address as new, so it will then send me an e-mail saying the address has changed. Then an hour later (when the cronjob goes off every hour on the hour), it will fetch the correct IP addy, and then notify again of the "new change." If I had to guess, it's during the actual resolving of the IP address and fetching that information that it seems to get this null IP. I've pasted my code below for review. What do you all think?
#! /usr/bin/perl -w use Net::SMTP::SSL; # FETCH THE PUBLIC IP ADDRESS $ip = `wget http://automation.whatismyip.com/n09230945.asp -O - -q ; e +cho`; chomp ($ip); # OPEN FILE THAT CONTAINS THE IP ADDRESS # AS OF THE LAST TIME THE SCRIPT WAS RAN open FILE, "<", "/root/scripts/currentIP" or die $!; $currentIP = <FILE>; chomp ($currentIP); close FILE; # COMPARE THE OLD IP AND THE FETCHED IP # FOR DIFFERENCES if ($currentIP ne $ip) { #IP HAS CHANGED; EMAIL ADMIN THE NEW IP #AND THEN CHANGE THE IP RECORD FILE open FILE, ">", "/root/scripts/currentIP" or die $!; print FILE $ip; close FILE; &emailAdmin; } # E-MAIL SUB ROUTINE # (I HAVE EXIM4 SETUP TO FORWARD TO GOOGLE # SMARTHOST SO I CAN RECEIVE MAIL AS ROOT) sub emailAdmin { my $headers = "PD IP Change\nFrom: ipUpdater Script\nUser-Agent: H +eirloom mailx 12.5 6/20/10\nMIME-Version: 1.0\nContent-Type: text/pla +in; charset=us-ascii\nContent-Transfer-Encoding: 7bit\n"; my $to = "root"; my $body = "The public IP address for the BPDServer has changed.\n +\nNew IP: $ip\nOld IP: $currentIP\n."; system("echo \"$body\" | mail -s \"$headers\" \"$to\""); }

Replies are listed 'Best First'.
Re: Script to Notify of Public IP Change
by marto (Bishop) on Nov 29, 2012 at 16:10 UTC

    "unsure of whether or not their ISP provided them with a static or dynamic IP address"

    Have you tried asking them? Or having the Police ask them on your behalf, as they are the customer? I'd consider using Dynamic_DNS, rather than reply on finding out changes via a cron job.

    "Sometimes, it seems to fetch a "blank" when trying to resolve the IP"

    Add some checking in your code, ensure $ip is a valid IP address, handle any errors accordingly.

      Well, I think the main reason why I went ahead and did the script was because I'm still new to Perl and wanted to challenge myself with this task, and because it seemed simpler at the time than getting on the phone and talking to someone.

        Fair enough, though as you know error checking/data validation isn't just a Perl thing. DDNS would be a more robust solution IMHO.

Re: Script to Notify of Public IP Change
by blue_cowdawg (Monsignor) on Nov 29, 2012 at 18:47 UTC

    Here is another alternative to retrieving your IP address.

    #!/usr/bin/perl -w ###################################################################### +## use strict; use LWP::UserAgent; # NOTE: make sure you mimic a browser with the agent name # whatismyip.com specifically returns a 403 error otherwise my $ua = LWP::UserAgent->new(agent=>"Mozilla/5.0"); my $response = $ua->get("http://automation.whatismyip.com/n09230945.as +p"); if ( $response->is_success ) { # this is how I caught the 403 orginal +ly printf "%s\n",$response->decoded_content; } else { printf "Bad Ju-Ju happened:\n\t%s\n",$response->status_line; } #comparison logic from here.
    I hate shelling out to an external command since I'd rather not assume that the command is there in the first place. A pure Perl way is more attractive to me.

    You can also look at this solution that I came up with for dealing with that issue by querying the administrative interface of my WRT54G router.


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
      That is indeed a nice bit of code there. Thanks for the share.

      I was also looking at querying the router they have, and actually tried a bit of code, but ran into an access problem. So, I just gave up and went the simpler way. I'll definitely have to read your solution a bit more in full later when I have the time.
Re: Script to Notify of Public IP Change
by space_monk (Chaplain) on Nov 29, 2012 at 16:09 UTC

    Well, it looks as thoough there is no provision for the wget to fail; I suspect that when it does fail it doesn't return a valid IP address! :-)

    The simple answer is that you could have it simply not perform any action if the ip returned from the wget is blank, or even does not match a regex.

    A Monk aims to give answers to those who have none, and to learn from those who know more.
      I figured I would have to do as much. I'm actually surprised I didn't add that in there when I was writing it. I guess I also wanted to have others look at the whole thing to see if it was okay or there was a simpler way to do what I am doing.
Re: Script to Notify of Public IP Change
by Kenosis (Priest) on Nov 29, 2012 at 16:37 UTC

    marto makes a good point about asking the ISP about whether a static or dynamic IP is provided. In the meantime, perhaps something like the following would be helpful:

    #!/usr/bin/env perl use strict; use warnings; use LWP::Simple; use Regexp::Common qw/net/; my $ip; for ( 0 .. 9 ) { chomp( $ip = get('http://ip-addr.es/') ); last if defined $ip and $ip =~ /$RE{net}{IPv4}/; sleep 1; } ...
      There seems to be a much faster response time (at least for me) with that address than with the one I currently use. I may very well substitute that bit of code with yours. Thank you for the contribution. I do agree with marto that the best solution would be talk with the ISP. However, in the interest of continuing my experience and learning of Perl, I went with the script, at least for now. I just wanted to clear up the cause of the blank address, which seems to just be an error in parsing the address.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1006276]
Approved by marto
help
Chatterbox?
[ambrus]: I'm currently in the process of rewriting my proof of concept programs. They sort of developped organically as I was experimenting, so now I've got an ugly mess of multiple programs and one-liners held together by nothing. I'll have to rewrite them to som
[ambrus]: ething that's both cleanly organized and mostly automated.
LanX in train, bad connection
[Corion]: ambrus: Yeah - we're in that situation too, except that there is no time to do the reorganizing :-/
[LanX]: ... so my boss started a project with the newest sun servers and invited the traders to come on weekend to test it... and they were so pleased, that they forced him to keep it in production...
[ambrus]: Corion: sure, this is the long-term plan. The short term is that I have to run this ungodly mess to get results from the new input data today.
[Corion]: ambrus: Most of our "automation" is tied to process exit codes and a shell pipeline :-\
[LanX]: ... a week later they realized that one of the databases - which recorded how much the other banks due to this bank - was not correctly plugged

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (16)
As of 2017-03-29 11:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Should Pluto Get Its Planethood Back?



    Results (350 votes). Check out past polls.