NAME
    Win32::PingICMP - ICMP Ping support for Win32 based on ICMP.DLL

SYNOPSIS
      use Win32::PingICMP;
      use Data::Dumper;

      my $p = Win32::PingICMP->new();

      if ($p->ping(@ARGV)) {
        print "Ping took ".$p->details->{roundtriptime}."\n";
      } else {
        print "Ping unsuccessful: ".$p->details->{status}."\n";
      }
      print Data::Dumper->Dump([$p->details()]);

      $p->ping_async(@ARGV);

      until ($p->wait(0)) {
        Win32::Sleep(10);
        print "Waiting\n";
      }

      if ($p->details()->{status} eq 'IP_SUCCESS') {
        print "Ping took ".$p->details()->{roundtriptime}."\n";
      } else {
        print "Ping unsuccessful: ".$p->details()->{status}."\n";
      }
      print Data::Dumper->Dump([$p->details()]);

DESCRIPTION
    "Win32::PingICMP" is designed to mimic the ICMP ping functionality of
    "Net::Ping", but because "Win32::PingICMP" uses "ICMP.DLL" instead of
    raw sockets, it will work without local Administrative privileges under
    Windows NT/2000/XP. In addition, it supports:

    *   access to the "ICMP_ECHO_REPLY" data structure, making it possible
        to get more accurate timing values from pings

    *   setting the TTL, TOS, and IP Header Flags fields

    *   operation in an asynchronous mode

  Installation instructions
    This module requires Aldo Calpini's "Win32::API", available from CPAN
    and via PPM, "Win32::Event", included with the ActivePerl distribution,
    and "Data::BitMask", available from CPAN.

AUTHOR
    Toby Ovod-Everett, toby@ovod-everett.org

ACKNOWLEDGEMENTS
    Some of the documentation is copied from that for "Net::Ping" 2.02.
    Since I was attempting to make this a replacement for that module,
    similarity in documentation struck me as a Good Thing(TM).

    I would never have done this if I hadn't seen
    http://perlmonks.thepen.com/42739.html. I would never have attempted
    this if "Win32::API" didn't bring the Win32 API within the reach of mere
    mortals like me.

    I would never have seen that if Christopher Elkin hadn't tried using
    "Win32::ProcFarm" on his web server to do monitoring via pings and asked
    me why things weren't working when the code ran without admin privs.

METHODS
    new
          Win32::PingICMP->new([$proto [, $def_timeout [, $bytes]]]);

        Create a new ping object. All of the parameters are optional. $proto
        specifies the protocol to use when doing a ping. The only currently
        supported choice is '"icmp"'.

        If a default timeout ($def_timeout) in seconds is provided, it is
        used when a timeout is not given to the "ping()" method (below). It
        is recommended that the timeout be greater than 0 and the default,
        if not specified, is 5 seconds. Fractional values are permitted.

        If the number of data bytes ($bytes) is given, that many data bytes
        are included in the ping packet sent to the remote host. The default
        is 0 bytes. The maximum is 996.

    ping
          $p->ping($host [, $timeout [, %options]]);

        Ping the remote host and wait for a response. $host can be either
        the hostname or the IP number of the remote host. The optional
        timeout should be greater than 0 seconds and defaults to whatever
        was specified when the ping object was created. Fractional values
        are permitted for the timeout. The %options hash accepts values for
        "ttl", "tos", and "flags". If any of the values are specified, the
        other values default to 0, so you may want to specify them as well
        (especially "ttl"!). If none are specified, then they default to
        whatever the Windows defaults are (I don't have a packet sniffer or
        the expertise to determine them).

        Hostname resolution is done via gethostbyname. If the hostname
        cannot be found or there is a problem with the IP number, "undef" is
        returned. Otherwise, 1 is returned if the host is reachable and 0 if
        it is not. For all practical purposes, "undef" and 0 and can be
        treated as the same case.

    ping_async
          $p->ping_async($host [, $timeout [, %options]]);

        Initiates an asynchronous ping to a remote host. Only one
        asynchronous ping can be run at a time per "Win32::PingICMP" object,
        but you can have multiple "Win32::PingICMP" objects to enable
        parallel pinging. See "ping" for an overview of the parameters.

    wait
          $p->wait([$timeout]);

        Used in conjunction with "ping_async" to wait for a response. Pass
        the timeout for which the "Win32::PingICMP" object should wait for
        the response during this call. Multiple calls to "wait" are
        permissible, as is a timeout value of 0. The call will return 0 if
        the ping is still outstanding and 1 is a response has been received
        or the ping timeout exceeded. Once a 1 has been returned from a call
        to "wait", you can call "details" to get the response information.
        Use "$p->details()->success()" to get a value that mirrors the
        return value from "ping".

    close
          $p->close();

        Close the network connection for this ping object. The network
        connection is also closed by ""undef $p"". The network connection is
        automatically closed if the ping object goes out of scope.

    requestdata
          $p->requestdata([$requestdata]);

        Get and/or set the request data to be used in the packet.

    details
          $p->details();

        Returns the gory details of the last ping attempted by the object.
        This is a reference to an anonymous hash and contains:

        replies
            This is a reference to an anonymous array containing anonymous
            hash references with the gory details of the replies to the
            ping. In certain pathological cases, it *might* be possible for
            there to be multiple replies, which is why this is an array.
            This would be the case if the "IcmpSendEcho" call returned a
            value greater than 1, indicating that more than one packet was
            received in response. Of course, the first packet received
            should cause "IcmpSendEcho" to return, so I'm not quite sure how
            this would happen. The Microsoft documentation is incomplete on
            this point - they clearly state "Upon return, the buffer
            contains an array of "ICMP_ECHO_REPLY" structures followed by
            options and data." This would seem to indicate that multiple
            "ICMP_ECHO_REPLY" structures might reasonably be expected, as
            does the comment "The call returns when the time-out has expired
            or the reply buffer is filled." However, the functions appears
            to return as soon as there is one entry in the reply buffer,
            even when there is copious space left in the reply buffer and
            the time-out has yet to expire. My best guess is that there will
            never be more than one "ICMP_ECHO_REPLY" structure returned, but
            I have written the code to deal with the multiple structure case
            should it occur.

            The anonymous hashes consist of the following elements:

            address
                Address from which the reply packet was sent.

            data
                Data present in the reply packet.

            flags
                IP header flags from the reply packet.

            optionsdata
                Bytes from the options area following the IP header.

            roundtriptime
                Round trip time. This appears to be inaccurate if there is
                no actual reply packet (as in the case of a
                '"IP_REQ_TIMED_OUT"').

            status
                The per reply status returned by the "IcmpSendEcho",
                returned as a text string constant.

            tos The type-of-service for the reply packet.

            ttl The time-to-live for the reply packet.

        host
            The originally specified IP address or DNS name from the "ping"
            call.

        ipaddr
            The IP address used for the actual ping.

        roundtriptime
            The "roundtriptime" value for the first reply.

        status
            The "status" value for the first reply.

        success
            The same value returned by the "ping" call. This is absent if an
            IP address could not be determined for the host, 1 if there were
            one or more replies with a status value of '"IP_STATUS"', and 0
            if there were none.

        timeout
            The specified timeout value in milliseconds.

