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

Hi dear I am using Redhat 7.3 and SuSE8.0 and i want to ping on special port a server to know is it alive or not. at the first, when i run the example on cpan.org(Net::ping) it doesnt answer any, i download this module and installed it, then ping(icmp) replay. but when i want to ping on specified port with tcp or syn portocol it replay ok(no differnce that service is up or down). i use ur fping : ./fping 192.168.100.12 -P 80 it shows alive in each time that service is up or down. how could i solve the problem. and what is my fault. why it shows host is alive in each time. it is important for me. Best regurds R.A ralijani@yahoo.com

Replies are listed 'Best First'.
Re: ping problem
by xmath (Hermit) on Mar 04, 2003 at 13:32 UTC
    You probably you forgot to turn on the 'tcp_service_check' option. If it's turned off (which it is by default) then ping will report success if it gets an explicit "connection denied" from the server (since that means the server is up -- otherwise it couldn't have denied the connection)

    However, you don't want to check if the server itself is up but if a specific service is up, so a refused connection is a failure to you. If you turn on 'tcp_service_check', Net::Ping will only report success if it could actually establish a connection, and report failture if the connection was denied.

    Example:

    use strict; use warnings; use Net::Ping; my $p = Net::Ping->new('tcp'); $p->tcp_service_check(1); my $host = "192.168.100.12"; my $port = 80; $p->{'port_num'} = $port; print "The service on $host port $port is ", ($p->ping($host) ? "up" : "down"), ".\n";

    •Update: Note that the tcp_service_check option isn't available in the Net::Ping that is included with perl 5.8.0, however it is available in the latest version.

Re: ping problem
by Anonymous Monk on Mar 04, 2003 at 13:51 UTC
    Hi! I'd suggest that you simply create a socket connection to the port you want to check. If the connection succeeds, close it. If not, it's down. Example;
    use IO::Socket; $socket = eval { return IO::Socket::INET->new( Proto => "tcp", PeerAddr => $addr, PeerPort => $port, Reuse => 1, Timeout => 10) or return undef; }; if ($socket) { print "Port open\n"; eval { return $socket->close; }; return 1; } else { print "Port NOT open\n"; return undef; }
Re: ping problem
by robartes (Priest) on Mar 04, 2003 at 13:29 UTC
    According to the Net::Ping docs, this could be as straightforward as:
    #!/usr/local/bin/perl -w use strict; use Net::Ping; warn "Code is untested"; my $host="192.168.100.12"; my $p=Net::Ping->new('tcp'); $p->{'port_num'}=80; echo "$host is alive!\n" if $p->ping($host);
    According to the documentation, this will show the host as alive when Net::Ping can make a successful connection to port 80 of the target host, i.e. when there is something listening on that port (presumably a webserver).

    I have no idea what the syn protocol is, so I can't help you there.

    CU
    Robartes-

      Except your snippet will say the $host is alive regardless of whether it's running a server on port 80 or not, which is what the poster wanted to know.

      See my post below for the solution.

      btw, syn isn't a protocol by itself but rather the first phase of the tcp-protocol. Net::Ping allows you to use it to be able to tcp-ping multiple hosts simultaneously. The docs of the latest version of Net::Ping describe it pretty well.

        Granted, according to the docs, my snippet will say $host is alive if it accepts connections on port 80. This might or might not mean that a webserver is running, just that something is listening there, or - more precisely - that a successful connection was made (three way handshake completed).

        robartes reads some docs...

        Ah, that's what the syn 'protocol' is. The Perl 5.8.0 version of Net::Ping (whose docs I consulted) does not have this yet. If I understand correctly, for just testing one host, using syn is over the top, tcp does all of that in one call. If you are pinging various hosts, using a bunch of syn's and then using the ack method to listen for the returning ACK packets (if any) will be the way to go, as stated in the docs.

        robartes reads some more docs...

        Double ah. So the darn thing answers true if it gets a RST as well. xmath, you are fully correct in your reply to my comment.

        Thanks for the heads up, xmath.

        Update:: the confusion seems to stem from using different version of Net::Ping. My post assumes the version bundled with Perl 5.8.0, xmath is working off of version 2.28 of Net::Ping, which indeed shows the behaviour he comments on.

        CU
        Robartes-

Re: ping problem
by jasonk (Parson) on Mar 04, 2003 at 13:24 UTC

    The Net::Ping documentation contains an example of how to check the web port. If your code is based on that example and still doesn't work, then try including it in your question so we don't have to try and guess what is wrong with it.