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
      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.
      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
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