Beefy Boxes and Bandwidth Generously Provided by pair Networks kudra
laziness, impatience, and hubris
 
PerlMonks  

IP Iterator

by camlet (Novice)
on Apr 17, 2008 at 14:06 UTC ( #681164=snippet: print w/ replies, xml ) Need Help??

Description: Do you know when a new server or network device is added to your network? Does someone else let you know a week later that a new device needs to be monitored? Are you putting a list of IP's together in a text file and writing a for loop to ping each of these servers? How about an IP iterator that walks from a start IP to end end IP.

#!/usr/bin/perl -w

use strict;
use Net::Ping;
use IO::Socket;

sub ip_fr_dotted { unpack 'N', pack 'C4', split /\./, $_[0] }
sub ip_to_dotted { join '.', unpack 'C4', pack 'N', $_[0] }

my $start = ip_fr_dotted($ARGV[0]);
my $end   = ip_fr_dotted($ARGV[1]);

for (my $ip=$start; $ip<=$end; $ip++) {
   print("\n ", ip_to_dotted($ip));
   &ping_ip($ip);
}

sub ping_ip{
        my $p = Net::Ping->new("icmp",2);
        if( $p->ping($_[0]) ){
                print " available ";
                &id_device($_[0]);
        }
        $p->close();

}

sub id_device {

my $host = shift || ip_to_dotted($_[0]);

#windows
if( &port_check('tcp',$host,'139') == 0 && &port_check('udp',$host,'13
+8') == 0 && &port_check('udp',$host,'137') == 0 ){
        print "windows";
}

}

sub port_check{
        my $handle = IO::Socket::INET->new (Proto=>$_[0], PeerAddr=>$_
+[1], PeerPort=>$_[2] );
        if($handle){
                return 0;
        }else{
                return 1;
        }
}
Comment on IP Iterator
Download Code
Re: IP Iterator
by grizzley (Chaplain) on Apr 17, 2008 at 14:31 UTC

    1. I guess you didn't know there is ++ operator? :) You can write your code $ip[3] = $ip[3] + 1; as $ip[3]++

    2. Do you know you can call function with splices? func($arr[0], $arr[1], $arr[2], $arr[3]) is the same as func(@arr[0..3]);

    3. Your function nextIp() would be two/three lines long if you operated on simple 32-bit int, passed 32-bit int to ping() function and there converted to IP like this:

    $ip = $_[0]; # your 32-bit int $arr[3] = $ip & 255; $ip >>= 8; $arr[2] = $ip & 255; $ip >>= 8; $arr[1] = $ip & 255; $ip >>= 8; $arr[0] = $ip & 255;
      2.) array worked thanks my code got better. i made the change.

      3.) still working on understanding the change but would the solution include incrementing the next octet if $_[i-1] hits 255?

        3) the recommended change doesn't include verifying octet[i-1]

        $ip = $_[0]; # your 32-bit int $arr[3] = $ip & 255; $ip >>= 8; $arr[2] = $ip & 255; $ip >>= 8; $arr[1] = $ip & 255; $ip >>= 8; $arr[0] = $ip & 255;
Re: IP Iterator
by poolpi (Hermit) on Apr 17, 2008 at 15:07 UTC

    See Perl Hacks by Chromatic, Damian CONWAY and Curtis POE, chapter 3, page #66 :
    Iterate and Generate Expensive Data

    hth,
    PooLpi

    'Ebry haffa hoe hab im tik a bush'. Jamaican proverb
      looks like a good book. if it were a simple iterator you could just write a for loop. carrying the ++i to the next octet and checking that 255 max was the reason a simple loop didn't work.
      after reading page 66 chapter 3 yes this is similar to what is being accomplished with the ip iterator. although the missing module issue. not all systems have that package installed. similar to the other solution below with Net::IP; the idea behind the tool is to monitor for new servers that are added to the network that can then be picked up from ip iterator and deploy a monitor agent or starting pinging for availability in response. both Net::IP and Net::Netmask may not be installed on the server. hth.

      Unix

      lpar23ml162f_pub[/opt/camlet/lib] > ./test2.pl Can't locate Net/Netmask.pm in @INC (@INC contains: /usr/opt/perl5/lib +/5.8.2/aix-thread-multi /usr/opt/perl5/lib/5.8.2 /usr/opt/perl5/lib/s +ite_perl/5.8.2/aix-thread-multi /usr/opt/perl5/lib/site_perl/5.8.2 /u +sr/opt/perl5/lib/site_perl .) at ./test2.pl line 3. BEGIN failed--compilation aborted at ./test2.pl line 3.

      Linux

      [camlet@cam-lin-s04 tmp]# ./test2.pl Can't locate Net/Netmask.pm in @INC (@INC contains: /usr/lib/perl5/sit +e_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.7/i +386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.6/i386-linux-thre +ad-multi /usr/lib/perl5/site_perl/5.8.5/i386-linux-thread-multi /usr/ +lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl/5.8.7 /usr/lib/per +l5/site_perl/5.8.6 /usr/lib/perl5/site_perl/5.8.5 /usr/lib/perl5/site +_perl /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi /usr/l +ib/perl5/vendor_perl/5.8.7/i386-linux-thread-multi /usr/lib/perl5/ven +dor_perl/5.8.6/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8 +.5/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/ +perl5/vendor_perl/5.8.7 /usr/lib/perl5/vendor_perl/5.8.6 /usr/lib/per +l5/vendor_perl/5.8.5 /usr/lib/perl5/vendor_perl /usr/lib/perl5/5.8.8/ +i386-linux-thread-multi /usr/lib/perl5/5.8.8 .) at ./test2.pl line 3. BEGIN failed--compilation aborted at ./test2.pl line 3. [root@cam-lin-s04 tmp]#
      PooLpi, thanks for the recommending the book i just pick up a copy. its a pretty good read with a lot of practical examples.
Re: IP Iterator
by jdporter (Canon) on Apr 17, 2008 at 15:31 UTC

    Sorry to say it, but... that pretty much sucks.

    use Net::Ping; use Net::IP; $|=1; my( $from, $to ) = @ARGV; my $p = Net::Ping->new('icmp',2); for ( my $ip = Net::IP->new( "$from - $to" ) or die "error creating Net::IP object: ".Net::IP::Error(); $ip; $ip++ ) { print "\n checking ip: ", $ip->ip, " "; print "ping success " if $p->ping($ip->ip); } $p->close;
    A word spoken in Mind will reach its own level, in the objective world, by its own weight
      in this case i really didnt want to use an extra module since this is deployed on a list of servers. and it seems Net/IP.pm is not in the default install.

      camlet@cam-lin-s04 tmp# ./test.pl

      Can't locate Net/IP.pm in @INC (@INC contains:

      [camlet@cam-lin-s04 tmp]# cat test.pl #!/usr/bin/perl use Net::Ping; use Net::IP; $|=1; my( $from, $to ) = @ARGV; my $p = Net::Ping->new('icmp',2); for ( my $ip = Net::IP->new( "$from - $to" ) or die "error creating Net::IP object: ".Net::IP::Error(); $ip; $ip++ ) { print "\n checking ip: ", $ip->ip, " "; print "ping success " if $p->ping($ip->ip); } $p->close;

        If you don't want to use an "extra module" then you can do it like this:

        #!/usr/bin/perl use warnings; use strict; use Net::Ping; if ( @ARGV != 2 ) { print "ipiterator <startip> <endip> \n"; exit 0; } my ( $start, $end ) = map unpack( 'N', pack 'CCCC', split /\./ ), @ARGV; for my $count ( $start .. $end ) { my $ip = join '.', unpack 'CCCC', pack 'N', $count; print "checking ip: $ip"; my $p = Net::Ping->new( 'icmp', 2 ); print ' ping success' if $p->ping( $ip ); $p->close(); print "\n"; }
Re: IP Iterator
by ikegami (Pope) on Apr 17, 2008 at 15:36 UTC

    IPv4 addresses are 32-bit numbers. Thinking of them as 4 individual bytes is counter-productive and leads to extremely convoluted code. nextIP should be:

    sub nextIP { my ($ip) = @_; return $ip+1; }

    exit shouldn't be called from nextIP. That's a user-interface detail while nextIP is clearly not an I/O function. A wrap can be detected by nextIP returning 0.

      3) yes this works well thank you. it makes sense but to think as 32bit rather than 4 individual byte. change made. still testing the code.
        sub nextIP { my ($ip) = @_; return $ip+1; } didnt work the user doesnt enter binary it still needs to be transformed with if.
Re: IP Iterator
by ikegami (Pope) on Apr 17, 2008 at 22:36 UTC

    if ( @ARGV lt 2 || @ARGV gt 2 )
    should be
    if ( @ARGV < 2 || @ARGV > 2 )
    lt and gt are for comparing strings.
    < and > are for comparing numbers.
    For example, 10 lt 2 is true.

    Better yet, use
    if ( @ARGV != 2 )

      change made.

      if ( @ARGV != 2 ). nice catch thx.

[untitled node, ID 681742]
by camlet (Novice) on Apr 20, 2008 at 02:33 UTC

    Back to Snippets Section

    Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Node Status?
    node history
    Node Type: snippet [id://681164]
    help
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others scrutinizing the Monastery: (9)
    As of 2014-04-19 08:08 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      April first is:







      Results (478 votes), past polls