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

Hi there, I am working on a script that need to ping a host. In the past I have accomplished this with Net::Ping. For some reason this time Net::Ping will NOT work for me.

At first I thought maybe it was my script, so I made a really small perl script to check that it was NOT my script.

#!/usr/bin/perl use strict; use warnings; use Net::Ping; my $target = 'esxi01'; my $ping_obj = Net::Ping->new(); if ($ping_obj->ping($target)) { print "Yes, I can ping $target\n"; } else { print "No, I cannot ping $target\n"; }

The script fails to ping anything but 127.0.0.1

**Update**

After plugging the right word in the magical Google, I got post from someone who had the same problem and their problem was fixed by doing;

 my $ping_obj = Net::Ping->new('icmp');

The part I cannot figure out is why does it work when specify "icmp" but not work when I use the defaults? That is how I have used it in the past and it worked fine.

I just tried to test for an open port using the function I have used in my last script(s), once again I made a test script based off the once above with the needed modifications.

#!/usr/bin/perl use strict; use warnings; use Net::Ping; my $target = 'esxi01'; my $ping_obj = Net::Ping->new('tcp'); $ping_obj->service_check('1'); $ping_obj->port_number('22'); if ($ping_obj->ping($target)) { print "Yes, I can ping $target\n"; } else { print "No, I cannot ping $target\n"; } $ping_obj->close();

This script also tells me the host is not pingable but yet I can already get into via SSH so its very much alive and open.

What is going on here?

Replies are listed 'Best First'.
Re: Solution to broken Net::Ping
by Anonymous Monk on Dec 16, 2011 at 08:31 UTC

    I am guessing its the module

    guessing virtually guarantees it is not the module

    Ah yes, and you are the first person to have noticed this bug since 1994. Sure.

    The Net::Ping description says

    You may choose one of six different protocols to use for the ping. The "tcp" protocol is the default. Note that a live remote host may still fail to be pingable by one or more of these protocols. For example, www.microsoft.com is generally alive but not "icmp" pingable.
    $ perl -MNet::Ping -le " print !! Net::Ping->new->ping( shift ) " loca +lhost 1 $ perl -MNet::Ping -le " print !! Net::Ping->new->ping( shift ) " goog +le.com $ perl -MNet::Ping -le " print !! Net::Ping->new( qw/syn/ )->ping( shi +ft ) " google.com 1

      I am aware that certain hosts are not always pingable.

      After a little RTFM it works now (what a surprise).

      Based on the above it looks like I need to create 2 ping tests (1 for icmp, 1 for tcp port test). Would it be cleaner to create the first object then undef it and recreate the object with the new options? or just create 2 different objects and destroy them after their very short lifespan?

      Thank you for your help

        Since I don't see an official way to change protocol choice after the fact, I recommend limiting scope with functions, however many you need , maybe

        sub MahPing { my ( $host ) = @_; for my $proto ( qw/ tcp icmp syn / ){ return !!1 if Net::Ping->new( $proto, 5 ) ->ping( $host ); } return !!0; }

        If you're concerned about performance, Benchmark it, not against some production host. What works for me under my current environment, may not be the best way for you under your constraints. A general solution to monitoring availability of hosts is non-trivial. And make sure you're not optimizing prematurely.

        The last time I was mucking about with ping, it was on a large scale internal network and I ended up using SNMP gets instead. If you usage needs to be efficient, you might want to look at Net::SNMP as well.

Re: Solution to broken Net::Ping
by GrandFather (Saint) on Dec 16, 2011 at 08:02 UTC
    #!/usr/bin/perl use strict; use warnings; use Net::Ping; my $target = 'perlmonks.org'; my $ping_obj = Net::Ping->new(); print "Net::Ping version is $Net::Ping::VERSION\n"; if ($ping_obj->ping($target)) { print "Yes, I can ping $target\n"; } else { print "No, I cannot ping $target\n"; }

    Prints:

    Net::Ping version is 2.36 Yes, I can ping perlmonks.org

    for me. Are you sure your target is reachable?

    True laziness is hard work
      What OS are you using? If Linux what version? What version of perl are you using? I feel like it has to be something wrong with my machine(s) now. I tried using my own script to ping google.com and I STILL got a failure.

        When I first posted I used Windows XP with Perl 5.10.1. I've just tried with Perl 5.10.0 in a Debian lenny VM.

        What happens when you try the same ping from the command line?

        True laziness is hard work
      I am very sure it is reachable, I am connected to the server 2 different ways. 1. The VMware client, 2. puTTY from my Windows box.
Re: Solution to broken Net::Ping
by Khen1950fx (Canon) on Dec 16, 2011 at 09:37 UTC
    This is one of those occasions where the method works, but the documentation is a mess:). This works:
    #!/usr/bin/perl use strict; use warnings; use Net::Ping; my $target = 'www.perlmonks.com'; my $ping = Net::Ping->new("tcp", 2); $ping->{'port_num'} = (getservbyname("http", "tcp") || 80); if ($ping->ping($target)) { print "Yes, I can ping $target\n"; } else { print "No, I cannot ping $target\n"; } $ping->close();

      This is one of those occasions where the method works, but the documentation is a mess:)

      except that it isn't

      you have 6 choices. If the default doesn't work for you, the documentation is explicit, make another choice.

        You may want to try.

        #!/usr/bin/perl -w use strict; use Net::Ping; $| = 1; my @hosts = <DATA>; my @proto = ("tcp", "udp", "icmp", "stream", "syn"); foreach my $pro ( @proto ) { print "\nProtocol $pro \n"; my $p = Net::Ping->new($pro); foreach my $host( @hosts ) { chomp($host); # Specify source interface of pings print "$host is "; print "NOT " unless $p->ping($host, 2); print "reachable.\n"; } $p->close(); } exit; __DATA__ 127.0.0.1 www.perlmonks.com