From b6cc999ce45a8b6db633fa795d8990aabd181aea Mon Sep 17 00:00:00 2001 From: Andrew Tomaka Date: Sat, 23 Feb 2013 13:16:08 -0500 Subject: [PATCH] Initial commit --- README.md | 11 +++++ pinger | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 README.md create mode 100755 pinger diff --git a/README.md b/README.md new file mode 100644 index 0000000..72c26d6 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +#Misc Linux Tools + +Miscellaneous tools used at the Linux command line. + +##pinger + +Tool to imcp ping an IP or range of IPs and return which ones are reacable. + +``` +$ sudo pinger -h +``` diff --git a/pinger b/pinger new file mode 100755 index 0000000..d24b959 --- /dev/null +++ b/pinger @@ -0,0 +1,130 @@ +#!/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); +}