#!/usr/bin/env perl use strict; use Net::Ping; use POSIX; use Time::HiRes qw/time/; if($> != 0) { die("pinger must be run as root\n"); } my $alive = 1; my $time = 0; my($start,$finish); while($ARGV[0] =~ /\-/) { my $arg = shift(@ARGV); $arg =~ s/-//; my @switches = split('', $arg); foreach my $switch (@switches) { if($switch eq "d") { $alive = 0; } elsif($switch eq "r") { $alive = 1; } elsif($switch eq "t") { $time = 1; } elsif($switch eq "h") { help(); } else { print "pinger: invalid option -- '$switch'\n"; help(); } } } if(scalar(@ARGV) < 1 || scalar(@ARGV) > 2) { die("Usage: pinger START_IP [END_IP]\n"); } $start = time if($time); my $p = Net::Ping->new('icmp'); my @ips; if(scalar(@ARGV) == 2) { # must be IP addresses if($ARGV[0] !~ /((?:\d{1,3}\.){3}\d{1,3})/ || $ARGV[1] !~ /((?:\d{1,3}\.){3}\d{1,3})/) { die("Both arguments must be IP addresses if two are specified.\n"); } # and only the final octet should differ my @ip1 = split(/\./, $ARGV[0]); my @ip2 = split(/\./, $ARGV[1]); if($ip1[0] != $ip2[0] || $ip1[1] != $ip2[1] || $ip1[2] != $ip2[2]) { die("The first three octets of the IP addresses must match.\n") } my $baseIp = $ip1[0] . '.' . $ip1[1] . '.' . $ip1[2]; my $start = $ip1[3]; my $end = $ip2[3]; my $count = $ip2[3] - $ip1[3] + 1; for(my $i = $start, my $k = 1; $i <= $end; $i++, $k++) { $| = 1; progressBar($k, $count); my $ip = $baseIp . '.' . $i; push(@ips, $ip) if($p->ping($ip, 1) == $alive); } } elsif(scalar(@ARGV) == 1) { my $host = $ARGV[0]; push(@ips, $host) if($p->ping($host, 1) == $alive); } $p->close(); $finish = time if($time); print "\n"; ($alive) ? print "Reachable:\n" : print "Dead:\n"; print join(", ", @ips); print "\n\n"; if($time) { my $completed = $finish - $start; printf("Completed in %.2f seconds.\n", $completed); } # details from http://stackoverflow.com/questions/1782107/how-do-i-retrieve-the-terminal-width-in-perl sub findTerminalWidth { my($winsize, $row, $col, $xpixel, $ypixel); my $available = 1; require 'sys/ioctl.ph'; $available = 0 unless defined &TIOCGWINSZ; open(TTY, "+ 0) { print "] ["; for(my $i = 1; $i < $barWidth; $i++) { ($i <= $barPercent) ? print '=' : print ' '; } } print "]\r"; } sub help { print "usage:\t pinger [-d] start [finish]\n\n"; print "\t-d\t\tList dead addresses\n"; print "\t-r\t\tList reachable addresses (default)\n"; print "\t-t\t\tTime ping execution\n"; exit(1); }