Description
===========
A simple Ruby interface to the 'ping' command

Prerequisites
=============
Win32 users need the "win32_popen" package by Park Heesob.  Available on the
RAA.

Synopsis
========
require "net/pingsimple"
include Net

PingTCP.econnrefused = true

pt = Net::PingTCP.new(host)
pu = Net::PingUDP.new(host)
pe = Net::PingExternal.new(host)

if pt.ping
   puts "TCP ping successful"
else
   puts "TCP ping unsuccessful: " +  pt.exception
end

if pu.ping
   puts "UDP ping successful"
else
   puts "UDP ping unsuccessful: " +  pu.exception
end

if pe.ping
   puts "External ping successful"
else
   puts "External ping unsuccessful: " +  pe.exception
end

Ping Classes
============

All Ping classes are children of the PingSimple parent class (which should
never be instantiated directly).

PingTCP

Attempts to open a connection using TCPSocket.  A successful open means
the ping was successful.
PingUDP

Attempts to open a connection using UDPSocket and sends a small string.  If
the return string matches, the ping was successful.

PingExternal

Uses the 'open3' module and calls your system's local 'ping' command.  If
nothing is sent to stderr, the ping was successful.

Class Methods
=============
PingXXX.new(host,port=7,timeout=5)

Creates a new Ping object of the appropriate type

PingTCP.econnrefused=(boolean)

Sets the behavior for handling ECONNREFUSED.  By default, this is set to 
false (i.e. ECONNREFUSED causes ping to return false).

PingXXX.VERSION

Returns the current version number

Instance Methods
================

ping

Returns one of two values - true or false.  If you want to know *why* it
failed, you can check the 'exception' attribute.

ping?

An alias for 'ping'

Instance Attributes
===================

host

Reset the host

port

Set the port number to open socket connections on.  The default is 7 (or
whatever your 'echo' port is set to).

data

The string sent in UDP connections.  The default is "ping".

timeout

The amount of time before the timeout module raises a TimeoutError
exception during connection attempts.

exception

If an exception is raised, it is caught and stored in this attribute.  It
is not raised in your code.

NOTES
=====
If a host is down *IT IS CONSIDERED A FAILED PING*, and the 'no answer from
<host>' text is assigned to the 'exception' attribute.
You may disagree with this behavior, in which case you need merely check the
exception attribute against a regex as a simple workaround.

FAQ
===
Q: "Why don't you return exceptions if a connection fails?"

A: Because ping is only meant to return one of two things - success or failure.
It's very simple.  If you want to find out *why* the ping failed, you can check
the 'exception' attribute.

Q: "I know the host is alive, but a TCP or UDP ping tells me otherwise.  What
gives?"

A: It's possible that the echo port has been disabled on the remote
host for security reasons.  Your best best is to specify a different port
or to use PingExternal instead.

Q: "Why does TCP ping return false when I know it should return true?"

A: By default ECONNREFUSED errors will return a value of false.  This is contrary
to what most other folks do for TCP pings.  The problem with their philosphy
is that you can get false positives if a firewall blocks the route to the
host.  The problem with my philosophy is that you can get false negatives
if there is no firewall (or it's not blocking the route).  Given the alternatives
I chose the latter.  You can always change the default behavior by using the
'econnrefused' class method.

Q: "Couldn't you use traceroute information to tell for sure?"

A: I *could* but I won't so don't bug me about it.  It's far more effort than it's
worth.  Besides, this is pingsimple, not pingcomplex. :)

Known Bugs
==========
None known.  Please report any bugs on the project page at
http://ruby-netutils.sf.net.

Future Plans
============
Add an PingICMP class (help wanted)
(Though see arton's icmpping package on the RAA)

License
=======
Ruby's

Copyright
=========
(C) 2003, 2004 Daniel J. Berger, All Rights Reserved

Warranty
========
This package is provided "as is" and without any express or
implied warranties, including, without limitation, the implied
warranties of merchantability and fitness for a particular purpose.

Author
======
Daniel J. Berger
djberg96 at yahoo dot com
rubyhacker1 on IRC
