#!/usr/bin/perl # name: Ping Scan # author: Matt Rankin # purpose: Scans IP subnets for reachable hosts because I forgot to check # http://netflow.latrobe.edu.au/ before going home for the weekend # to find hosts for the City Campus. # details: pings a single IP address or scans from x.x.x.1-254 in random order # and suppresses output of failed pings. On successful ping, it then # attempts a ping -R and finally a traceroute. If all succeed, pscan # writes the output and exits. # usage: pscan {ip} my $ip = shift; my @range = ( 1 .. 254 ); if( $ip =~ m/^(:?\d{1,3}\.){2}\d{1,3}$/ ){ &ping( $ip, \@range ) while( @range ); }elsif( $ip =~ m/^(:?\d{1,3}\.){3}\d{1,3}$/ ){ &ping( $ip ); }else{ print( STDERR "You did it wrong!\n" ); exit( 1 ); } exit( 0 ); # =============================== subroutines ================================ sub ping( $$ ){ my $addr = shift; if( @_ ){ my $range = shift; my $index = int( rand( scalar( @$range ) -1 ) ); $addr .= '.' . splice( @$range, $index, 1 ); } print( STDERR "Pinging $addr "); if( defined $range ){ print( STDERR scalar( @$range ) . " remaining ) " ); } my $result; my @output = `ping -c 1 $addr`; unless( &fail( \@output ) ){ print( STDERR "." ); $result = join( '', @output ) . "\n"; @output = `ping -R -c 1 $addr`; unless( &fail( \@output ) ){ print( STDERR "." ); $result .= join( '', @output ) . "\n"; @output = `traceroute -m 20 -w 2 $addr`; unless( &fail( \@output ) ){ print( STDERR "Success!\n" ); $result .= join( '', @output ); print( $result ); exit( 0 ); } else { print( STDERR "\n" ); } } else { print( STDERR "\n" ); } } else { print( STDERR "\n" ); } sleep( 1 ) if( defined $range ); } sub fail( $ ){ my $str = shift; foreach( @$str ){ return 1 if( m/(:?100% packet loss)|(:?wrong total length)|(:?\* \* \*)/i ); } }