Hydro has asked for the wisdom of the Perl Monks concerning the following question:

I am writing a CGI script that goes out and ping's all of our DSL routers to determine whether thay are UP or DOWN and produces a page providing all the required information. I use the ping via the system() command and send out only one ping. The problem is that if the router is down it take about 10 seconds to return from the system ping command. Is there a better/faster way to do this? Jonathan Southwick Allegheny College jsouthwi@allegheny.edu

Replies are listed 'Best First'.
Re: PING taking too long
by rchiav (Deacon) on Sep 25, 2001 at 18:28 UTC
    Use the Net::Ping Module. You can specify the timeout value for the ping so it should be much faster. The module is failry simple to use and there's good examples in the documentation. One word of caution: I'd recomend only useing the ICMP ping. I've had troubles with TCP and UDP pings. From what I've found on the web, ICMP ping is the only one that works reliably.

    Hope this helps,
    Rich

      I would also try the Net::Ping module and use a defined timeout. Here is an example.

      use strict; use Net::Ping; use constant TIMEOUT => 1; my $mNetPing = Net::Ping->new('icmp',TIMEOUT); foreach ('host1', 'host2', '172.20.41.152') { print $_,($mNetPing->ping($_) ? ' is alive' : ' is not alive'),"\n"; } $mNetPing->close();
      Word of caution, on top of caution icmp usually requires suid root. tcp is prefered as it has the lowest overhead but tcp echo may be turned off at target hosts as a normal security necessity.

      see Re: Net::Ping just don't werk.

      mitd-Made in the Dark
      'My favourite colour appears to be grey.'

      I tried using Net::Ping but it doesn't seem to be working. If I print out $p->ping($ipaddress) where $ipaddress is a valid ip address on our network, all I get are zeros. Is there something I am doing wrong? Jonathan Southwick Allegheny College jsouthwi@allegheny.edu
        It's hard to tell if you're doing something wrong without seeing your code. Here's an example I just threw together that works. Note - this is on a windows 2000 box, so issues with being suid root aren't something I take into consideration.
        use strict; use warnings; use Net::Ping; my $p = Net::Ping->new('icmp', 1); my $result = $p->ping('192.168.2.1'); print "Result is $result\n";
        If you're still having problems, post your code so we can figure out where things might be going wrong.

        Rich

Re: PING taking too long
by grinder (Bishop) on Sep 25, 2001 at 19:14 UTC

    You might be able to get some mileage out of a script I wrote and uploaded to perlmonks a while back: pinger - ping a range of hosts.

    --
    g r i n d e r
Re: PING taking too long
by xphase_work (Pilgrim) on Sep 25, 2001 at 18:25 UTC
    According to the ping man page in Solaris 2.7:
    /usr/sbin/ping host [ timeout ]
    If you specify your timeout to be less, then it will take less time to return after a down router, but then again it may tell you a router is down when it's just not returning your ping very fast.

    --xPhase

    UPDATE: See rchiav's advice, as Net::Ping seems a better way of doing this.

Re: PING taking too long
by tachyon (Chancellor) on Sep 25, 2001 at 20:13 UTC

    Sounds like a job for fork(). Fork a stack of kids to do the pinging and waiting in parallel.

    #!/usr/bin/perl -w use strict; use POSIX ":sys_wait_h"; $|++; my @hosts = qw( www.perlmonks.com www.perl.com www.netscape.com ); my (@pids, $count); for my $host(@hosts) { sleep 1; # this limits to 1 kid per second, not actually required $count++; my $pid = fork(); push @pids , $pid; die "Fork failed\n" unless defined $pid; next if $pid; # get parent to reiterate and fork more kids my $reply = `ping -n 1 $host`; # get kids pinging, single ping print "I am child $count, pinged $host\n$reply\n\n"; exit; # kill child } # wait for kids to finish, no zombies on us my $kids; do { $kids = waitpid(-1,&WNOHANG); } until $kids == -1; print "Spawned $count kids, waited on @pids\nAll done!";

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: PING taking too long
by ducky (Scribe) on Sep 25, 2001 at 20:34 UTC

    While it's not a pure perl solution, fping may help immensely if you've got more than a couple of hosts to check for. It's a threaded ping util designed to check large number of hosts and report back. I used this for uptime monitoring under Big Brother, improved performance by a substantial amount.

    -Ducky