Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

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 -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 (Archbishop) 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 # specifically returns a 403 error otherwise my $ua = LWP::UserAgent->new(agent=>"Mozilla/5.0"); my $response = $ua->get(" +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('') ); 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?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1006276]
Approved by marto
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (6)
As of 2018-05-21 15:25 GMT
Find Nodes?
    Voting Booth?