Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Scan multiple IP subnets

by vlad3848 (Acolyte)
on Jul 22, 2013 at 02:24 UTC ( #1045561=perlquestion: print w/ replies, xml ) Need Help??
vlad3848 has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to create a script that scans my network with ICMP ping and then, if the ping is successful, scans it for Cisco OID hostname. The idea is that when i am done scanning all IP subnets I only going to end up with Cisco devices, which then will be ported over to other network management solutions. The script is doing pretty good job, however, as it is written now, it is limited to 255 (\24) usable host IPs. I have to add a new subnet to the array each time to expand my scan. Is there any way it can be optimized to expand on \24 subnet range to \22 or \16? Thanks!

use warnings; use Getopt::Std; use Net::SNMP; use Data::Dumper; use Net::Ping; use Parallel::ForkManager qw( ); use Fcntl qw(:flock); use Socket qw( inet_aton ); #Declare the variables my $desc = '1.3.6.1.2.1.1.5.0'; my $host; my $pingable = "pingable.txt"; my $numOfProc = 25; my $manager = Parallel::ForkManager->new($numOfProc); #declare the desired host range my @sn_array = ("7.3.1."); my ($session, $error, %pdesc, $respnse); #delete the previously created file if (-e "pingable.txt"){ unlink "pingable.txt"; } #ping the host array and write to a file foreach $host (@sn_array){ for ($s=1; $s<255; $s++){ $manager->start and next; my $p = Net::Ping->new("icmp"); $host = $host . $s; print "pinging $host\n"; if ($p->ping($host)){ open PingFile, ">>", "$pingable" or die $!; flock(PingFile, LOCK_EX); print PingFile "$host\n"; flock(PingFile, LOCK_UN); close(PingFile); } $manager->finish; } } sleep(5); #count the new host ips in the file my $pingCount; open PINGFILE, "<", "$pingable"; $pingCount++ while(<PINGFILE>); close PINGFILE; # if there are new hosts in the file, scan them Cisco HostName OID and + print it out if ($pingCount > 1) { open PINGFILE, "<", "$pingable"; while(<PINGFILE>) { chomp; push @file, $_; } foreach my $host (@file) { &snmpwalk($host); } } #sub to get the Cisco host name OID and print it out sub snmpwalk{ ($session, $error) = Net::SNMP->session( -hostname => shift, -community => "public", -timeout => "5", -port => "161"); if (!defined($session)) { printf("ERROR: %s.\n", $error); exit 1; } my $response = $session->get_request($desc); if (!defined $response) { printf "ERROR: Get request failed for host '%s': %s.\n", $session->hostname(), $session->error(); return; } my %pdesc = %{$response}; for my $key ( keys %pdesc ) { my $value = $pdesc{$key}; print "$value\n"; } my $err = $session->error; if ($err){ return 1; } }

Comment on Scan multiple IP subnets
Download Code
Re: Scan multiple IP subnets
by NetWallah (Abbot) on Jul 22, 2013 at 03:19 UTC
    Several CPAN modules can help enumerate and loop through IP CIDR ranges (x.x.x.x/24) : Net::IP , NetAddr::IP , Net::IP::AddrRanges.

                 My goal ... to kill off the slow brain cells that are holding me back from synergizing my knowledge of vertically integrated mobile platforms in local cloud-based content management system datafication.

      Thank you! I looked it up today and it seems pretty doable. Thanks!
Re: Scan multiple IP subnets
by Anonymous Monk on Jul 22, 2013 at 03:59 UTC

    Why is adding a new array element a problem?

      It wasn't a problem in itself, I was just trying to figure out a better way to write the script in case if I need to scan more than 255 host IP addresses.
Re: Scan multiple IP subnets
by Loops (Hermit) on Jul 22, 2013 at 04:13 UTC

    As NetWallah suggested, using a CPAN module will be best. Below is an example for using Net::IP. It would replace the @sn_array assignment and the "foreach $host" loop in the original code

    use Net::IP; my @sn_array = qw( 172.22.0.0/30 7.3.1.0/24 ); ... for my $net (map {new Net::IP $_} @sn_array) { do { $manager->start and next; my $p = Net::Ping->new("icmp"); my $host = $net->ip; print "pinging $host\n"; if ($p->ping($host)){ open PingFile, ">>", "$pingable" or die $!; flock(PingFile, LOCK_EX); print PingFile "$host\n"; flock(PingFile, LOCK_UN); close(PingFile); } $manager->finish; } while (++$net); }
      That did it! Thank you!
        Why is it that when I make the changes above, it pings 192.168.1.0 and 192.168.2.0 as actual addresses?

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1045561]
Approved by Happy-the-monk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (8)
As of 2014-09-03 00:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite cookbook is:










    Results (34 votes), past polls