Upgrade to Net::Ping 2.20.
[p5sagit/p5-mst-13.2.git] / lib / Net / Ping.pm
1 package Net::Ping;
2
3 # $Id: Ping.pm,v 1.6 2002/06/19 15:23:48 rob Exp $
4
5 require 5.002;
6 require Exporter;
7
8 use strict;
9 use vars qw(@ISA @EXPORT $VERSION
10             $def_timeout $def_proto $max_datasize $pingstring $hires $source_verify);
11 use FileHandle;
12 use Socket qw( SOCK_DGRAM SOCK_STREAM SOCK_RAW PF_INET
13                inet_aton inet_ntoa sockaddr_in );
14 use Carp;
15 use POSIX qw(ECONNREFUSED);
16
17 @ISA = qw(Exporter);
18 @EXPORT = qw(pingecho);
19 $VERSION = "2.20";
20
21 # Constants
22
23 $def_timeout = 5;           # Default timeout to wait for a reply
24 $def_proto = "tcp";         # Default protocol to use for pinging
25 $max_datasize = 1024;       # Maximum data bytes in a packet
26 # The data we exchange with the server for the stream protocol
27 $pingstring = "pingschwingping!\n";
28 $source_verify = 1;         # Default is to verify source endpoint
29
30 if ($^O =~ /Win32/i) {
31   # Hack to avoid this Win32 spewage:
32   # Your vendor has not defined POSIX macro ECONNREFUSED
33   *ECONNREFUSED = sub {10061;}; # "Unknown Error" Special Win32 Response?
34 };
35
36 # Description:  The pingecho() subroutine is provided for backward
37 # compatibility with the original Net::Ping.  It accepts a host
38 # name/IP and an optional timeout in seconds.  Create a tcp ping
39 # object and try pinging the host.  The result of the ping is returned.
40
41 sub pingecho
42 {
43   my ($host,              # Name or IP number of host to ping
44       $timeout            # Optional timeout in seconds
45       ) = @_;
46   my ($p);                # A ping object
47
48   $p = Net::Ping->new("tcp", $timeout);
49   $p->ping($host);        # Going out of scope closes the connection
50 }
51
52 # Description:  The new() method creates a new ping object.  Optional
53 # parameters may be specified for the protocol to use, the timeout in
54 # seconds and the size in bytes of additional data which should be
55 # included in the packet.
56 #   After the optional parameters are checked, the data is constructed
57 # and a socket is opened if appropriate.  The object is returned.
58
59 sub new
60 {
61   my ($this,
62       $proto,             # Optional protocol to use for pinging
63       $timeout,           # Optional timeout in seconds
64       $data_size          # Optional additional bytes of data
65       ) = @_;
66   my  $class = ref($this) || $this;
67   my  $self = {};
68   my ($cnt,               # Count through data bytes
69       $min_datasize       # Minimum data bytes required
70       );
71
72   bless($self, $class);
73
74   $proto = $def_proto unless $proto;          # Determine the protocol
75   croak('Protocol for ping must be "icmp", "udp", "tcp", "stream", or "external"')
76     unless $proto =~ m/^(icmp|udp|tcp|stream|external)$/;
77   $self->{"proto"} = $proto;
78
79   $timeout = $def_timeout unless $timeout;    # Determine the timeout
80   croak("Default timeout for ping must be greater than 0 seconds")
81     if $timeout <= 0;
82   $self->{"timeout"} = $timeout;
83
84   $min_datasize = ($proto eq "udp") ? 1 : 0;  # Determine data size
85   $data_size = $min_datasize unless defined($data_size) && $proto ne "tcp";
86   croak("Data for ping must be from $min_datasize to $max_datasize bytes")
87     if ($data_size < $min_datasize) || ($data_size > $max_datasize);
88   $data_size-- if $self->{"proto"} eq "udp";  # We provide the first byte
89   $self->{"data_size"} = $data_size;
90
91   $self->{"data"} = "";                       # Construct data bytes
92   for ($cnt = 0; $cnt < $self->{"data_size"}; $cnt++)
93   {
94     $self->{"data"} .= chr($cnt % 256);
95   }
96
97   $self->{"local_addr"} = undef;              # Don't bind by default
98
99   $self->{"seq"} = 0;                         # For counting packets
100   if ($self->{"proto"} eq "udp")              # Open a socket
101   {
102     $self->{"proto_num"} = (getprotobyname('udp'))[2] ||
103       croak("Can't udp protocol by name");
104     $self->{"port_num"} = (getservbyname('echo', 'udp'))[2] ||
105       croak("Can't get udp echo port by name");
106     $self->{"fh"} = FileHandle->new();
107     socket($self->{"fh"}, PF_INET, SOCK_DGRAM,
108            $self->{"proto_num"}) ||
109              croak("udp socket error - $!");
110   }
111   elsif ($self->{"proto"} eq "icmp")
112   {
113     croak("icmp ping requires root privilege") if ($> and $^O ne 'VMS');
114     $self->{"proto_num"} = (getprotobyname('icmp'))[2] ||
115       croak("Can't get icmp protocol by name");
116     $self->{"pid"} = $$ & 0xffff;           # Save lower 16 bits of pid
117     $self->{"fh"} = FileHandle->new();
118     socket($self->{"fh"}, PF_INET, SOCK_RAW, $self->{"proto_num"}) ||
119       croak("icmp socket error - $!");
120   }
121   elsif ($self->{"proto"} eq "tcp" || $self->{"proto"} eq "stream")
122   {
123     $self->{"proto_num"} = (getprotobyname('tcp'))[2] ||
124       croak("Can't get tcp protocol by name");
125     $self->{"port_num"} = (getservbyname('echo', 'tcp'))[2] ||
126       croak("Can't get tcp echo port by name");
127     $self->{"fh"} = FileHandle->new();
128   }
129
130   return($self);
131 }
132
133 # Description: Set the local IP address from which pings will be sent.
134 # For ICMP and UDP pings, this calls bind() on the already-opened socket;
135 # for TCP pings, just saves the address to be used when the socket is
136 # opened.  Returns non-zero if successful; croaks on error.
137 sub bind
138 {
139   my ($self,
140       $local_addr         # Name or IP number of local interface
141       ) = @_;
142   my ($ip                 # Packed IP number of $local_addr
143       );
144
145   croak("Usage: \$p->bind(\$local_addr)") unless @_ == 2;
146   croak("already bound") if defined($self->{"local_addr"}) &&
147     ($self->{"proto"} eq "udp" || $self->{"proto"} eq "icmp");
148
149   $ip = inet_aton($local_addr);
150   croak("nonexistent local address $local_addr") unless defined($ip);
151   $self->{"local_addr"} = $ip; # Only used if proto is tcp
152
153   if ($self->{"proto"} eq "udp" || $self->{"proto"} eq "icmp")
154   {
155   CORE::bind($self->{"fh"}, sockaddr_in(0, $ip)) ||
156     croak("$self->{'proto'} bind error - $!");
157   }
158   elsif ($self->{"proto"} ne "tcp")
159   {
160     croak("Unknown protocol \"$self->{proto}\" in bind()");
161   }
162
163   return 1;
164 }
165
166
167 # Description: Allow UDP source endpoint comparision to be
168 #              skipped for those remote interfaces that do
169 #              not response from the same endpoint.
170
171 sub source_verify
172 {
173   my $self = shift;
174   $source_verify = 1 unless defined
175     ($source_verify = ((defined $self) && (ref $self)) ? shift() : $self);
176 }
177
178 # Description: allows the module to use milliseconds as returned by
179 # the Time::HiRes module
180
181 $hires = 0;
182 sub hires
183 {
184   my $self = shift;
185   $hires = 1 unless defined
186     ($hires = ((defined $self) && (ref $self)) ? shift() : $self);
187   require Time::HiRes if $hires;
188 }
189
190 sub time
191 {
192   return $hires ? Time::HiRes::time() : CORE::time();
193 }
194
195 # Description: Ping a host name or IP number with an optional timeout.
196 # First lookup the host, and return undef if it is not found.  Otherwise
197 # perform the specific ping method based on the protocol.  Return the
198 # result of the ping.
199
200 sub ping
201 {
202   my ($self,
203       $host,              # Name or IP number of host to ping
204       $timeout,           # Seconds after which ping times out
205       ) = @_;
206   my ($ip,                # Packed IP number of $host
207       $ret,               # The return value
208       $ping_time,         # When ping began
209       );
210
211   croak("Usage: \$p->ping(\$host [, \$timeout])") unless @_ == 2 || @_ == 3;
212   $timeout = $self->{"timeout"} unless $timeout;
213   croak("Timeout must be greater than 0 seconds") if $timeout <= 0;
214
215   $ip = inet_aton($host);
216   return(undef) unless defined($ip);      # Does host exist?
217
218   # Dispatch to the appropriate routine.
219   $ping_time = &time();
220   if ($self->{"proto"} eq "external") {
221     $ret = $self->ping_external($ip, $timeout);
222   }
223   elsif ($self->{"proto"} eq "udp") {
224     $ret = $self->ping_udp($ip, $timeout);
225   }
226   elsif ($self->{"proto"} eq "icmp") {
227     $ret = $self->ping_icmp($ip, $timeout);
228   }
229   elsif ($self->{"proto"} eq "tcp") {
230     $ret = $self->ping_tcp($ip, $timeout);
231   }
232   elsif ($self->{"proto"} eq "stream") {
233     $ret = $self->ping_stream($ip, $timeout);
234   } else {
235     croak("Unknown protocol \"$self->{proto}\" in ping()");
236   }
237
238   return wantarray ? ($ret, &time() - $ping_time, inet_ntoa($ip)) : $ret;
239 }
240
241 # Uses Net::Ping::External to do an external ping.
242 sub ping_external {
243   my ($self,
244       $ip,                # Packed IP number of the host
245       $timeout            # Seconds after which ping times out
246      ) = @_;
247
248   eval { require Net::Ping::External; }
249     or croak('Protocol "external" not supported on your system: Net::Ping::External not found');
250   return Net::Ping::External::ping(ip => $ip, timeout => $timeout);
251 }
252
253 use constant ICMP_ECHOREPLY => 0; # ICMP packet types
254 use constant ICMP_ECHO      => 8;
255 use constant ICMP_STRUCT    => "C2 S3 A";  # Structure of a minimal ICMP packet
256 use constant SUBCODE        => 0; # No ICMP subcode for ECHO and ECHOREPLY
257 use constant ICMP_FLAGS     => 0; # No special flags for send or recv
258 use constant ICMP_PORT      => 0; # No port with ICMP
259
260 sub ping_icmp
261 {
262   my ($self,
263       $ip,                # Packed IP number of the host
264       $timeout            # Seconds after which ping times out
265       ) = @_;
266
267   my ($saddr,             # sockaddr_in with port and ip
268       $checksum,          # Checksum of ICMP packet
269       $msg,               # ICMP packet to send
270       $len_msg,           # Length of $msg
271       $rbits,             # Read bits, filehandles for reading
272       $nfound,            # Number of ready filehandles found
273       $finish_time,       # Time ping should be finished
274       $done,              # set to 1 when we are done
275       $ret,               # Return value
276       $recv_msg,          # Received message including IP header
277       $from_saddr,        # sockaddr_in of sender
278       $from_port,         # Port packet was sent from
279       $from_ip,           # Packed IP of sender
280       $from_type,         # ICMP type
281       $from_subcode,      # ICMP subcode
282       $from_chk,          # ICMP packet checksum
283       $from_pid,          # ICMP packet id
284       $from_seq,          # ICMP packet sequence
285       $from_msg           # ICMP message
286       );
287
288   $self->{"seq"} = ($self->{"seq"} + 1) % 65536; # Increment sequence
289   $checksum = 0;                          # No checksum for starters
290   $msg = pack(ICMP_STRUCT . $self->{"data_size"}, ICMP_ECHO, SUBCODE,
291               $checksum, $self->{"pid"}, $self->{"seq"}, $self->{"data"});
292   $checksum = Net::Ping->checksum($msg);
293   $msg = pack(ICMP_STRUCT . $self->{"data_size"}, ICMP_ECHO, SUBCODE,
294               $checksum, $self->{"pid"}, $self->{"seq"}, $self->{"data"});
295   $len_msg = length($msg);
296   $saddr = sockaddr_in(ICMP_PORT, $ip);
297   send($self->{"fh"}, $msg, ICMP_FLAGS, $saddr); # Send the message
298
299   $rbits = "";
300   vec($rbits, $self->{"fh"}->fileno(), 1) = 1;
301   $ret = 0;
302   $done = 0;
303   $finish_time = &time() + $timeout;      # Must be done by this time
304   while (!$done && $timeout > 0)          # Keep trying if we have time
305   {
306     $nfound = select($rbits, undef, undef, $timeout); # Wait for packet
307     $timeout = $finish_time - &time();    # Get remaining time
308     if (!defined($nfound))                # Hmm, a strange error
309     {
310       $ret = undef;
311       $done = 1;
312     }
313     elsif ($nfound)                     # Got a packet from somewhere
314     {
315       $recv_msg = "";
316       $from_saddr = recv($self->{"fh"}, $recv_msg, 1500, ICMP_FLAGS);
317       ($from_port, $from_ip) = sockaddr_in($from_saddr);
318       ($from_type, $from_subcode, $from_chk,
319        $from_pid, $from_seq, $from_msg) =
320          unpack(ICMP_STRUCT . $self->{"data_size"},
321                 substr($recv_msg, length($recv_msg) - $len_msg,
322                        $len_msg));
323       if (($from_type == ICMP_ECHOREPLY) &&
324           (!$source_verify || $from_ip eq $ip) &&
325           ($from_pid == $self->{"pid"}) && # Does the packet check out?
326           ($from_seq == $self->{"seq"}))
327       {
328         $ret = 1;                   # It's a winner
329         $done = 1;
330       }
331     }
332     else                                # Oops, timed out
333     {
334       $done = 1;
335     }
336   }
337   return $ret;
338 }
339
340 # Description:  Do a checksum on the message.  Basically sum all of
341 # the short words and fold the high order bits into the low order bits.
342
343 sub checksum
344 {
345   my ($class,
346       $msg            # The message to checksum
347       ) = @_;
348   my ($len_msg,       # Length of the message
349       $num_short,     # The number of short words in the message
350       $short,         # One short word
351       $chk            # The checksum
352       );
353
354   $len_msg = length($msg);
355   $num_short = int($len_msg / 2);
356   $chk = 0;
357   foreach $short (unpack("S$num_short", $msg))
358   {
359     $chk += $short;
360   }                                           # Add the odd byte in
361   $chk += (unpack("C", substr($msg, $len_msg - 1, 1)) << 8) if $len_msg % 2;
362   $chk = ($chk >> 16) + ($chk & 0xffff);      # Fold high into low
363   return(~(($chk >> 16) + $chk) & 0xffff);    # Again and complement
364 }
365
366
367 # Description:  Perform a tcp echo ping.  Since a tcp connection is
368 # host specific, we have to open and close each connection here.  We
369 # can't just leave a socket open.  Because of the robust nature of
370 # tcp, it will take a while before it gives up trying to establish a
371 # connection.  Therefore, we use select() on a non-blocking socket to
372 # check against our timeout.  No data bytes are actually
373 # sent since the successful establishment of a connection is proof
374 # enough of the reachability of the remote host.  Also, tcp is
375 # expensive and doesn't need our help to add to the overhead.
376
377 sub ping_tcp
378 {
379   my ($self,
380       $ip,                # Packed IP number of the host
381       $timeout            # Seconds after which ping times out
382       ) = @_;
383   my ($ret                # The return value
384       );
385
386   $@ = ""; $! = 0;
387   $ret = $self -> tcp_connect( $ip, $timeout);
388   $ret = 1 if $! == ECONNREFUSED;  # Connection refused
389   $self->{"fh"}->close();
390   return $ret;
391 }
392
393 sub tcp_connect
394 {
395   my ($self,
396       $ip,                # Packed IP number of the host
397       $timeout            # Seconds after which connect times out
398       ) = @_;
399   my ($saddr);            # Packed IP and Port
400
401   $saddr = sockaddr_in($self->{"port_num"}, $ip);
402
403   my $ret = 0;            # Default to unreachable
404
405   my $do_socket = sub {
406     socket($self->{"fh"}, PF_INET, SOCK_STREAM, $self->{"proto_num"}) ||
407       croak("tcp socket error - $!");
408     if (defined $self->{"local_addr"} &&
409         !CORE::bind($self->{"fh"}, sockaddr_in(0, $self->{"local_addr"}))) {
410       croak("tcp bind error - $!");
411     }
412   };
413   my $do_connect = sub {
414     eval {
415       die $! unless connect($self->{"fh"}, $saddr);
416       $self->{"ip"} = $ip;
417       $ret = 1;
418     };
419     $ret;
420   };
421
422   if ($^O =~ /Win32/i) {
423
424     # Buggy Winsock API doesn't allow us to use alarm() calls.
425     # Hence, if our OS is Windows, we need to create a separate
426     # process to do the blocking connect attempt.
427
428     $| = 1; # Clear buffer prior to fork to prevent duplicate flushing.
429     my $pid = fork;
430     if (!$pid) {
431       if (!defined $pid) {
432         # Fork did not work
433         warn "Win32 Fork error: $!";
434         return 0;
435       }
436       &{ $do_socket }();
437
438       # Try a slow blocking connect() call
439       # and report the status to the pipe.
440       if ( &{ $do_connect }() ) {
441         $self->{"fh"}->close();
442         # No error
443         exit 0;
444       } else {
445         # Pass the error status to the parent
446         exit $!;
447       }
448     }
449
450     &{ $do_socket }();
451
452     my $patience = &time() + $timeout;
453
454     require POSIX;
455     my ($child);
456     $? = 0;
457     # Wait up to the timeout
458     # And clean off the zombie
459     do {
460       $child = waitpid($pid, &POSIX::WNOHANG);
461       $! = $? >> 8;
462       $@ = $!;
463       select(undef, undef, undef, 0.1);
464     } while &time() < $patience && $child != $pid;
465
466     if ($child == $pid) {
467       # Since she finished within the timeout,
468       # it is probably safe for me to try it too
469       &{ $do_connect }();
470     } else {
471       # Time must have run out.
472       $@ = "Timed out!";
473       # Put that choking client out of its misery
474       kill "KILL", $pid;
475       # Clean off the zombie
476       waitpid($pid, 0);
477       $ret = 0;
478     }
479   } else { # Win32
480     # Otherwise don't waste the resources to fork
481
482     &{ $do_socket }();
483
484     $SIG{'ALRM'} = sub { die "Timed out!"; };
485     alarm($timeout);        # Interrupt connect() if we have to
486
487     &{ $do_connect }();
488     alarm(0);
489   }
490
491   return $ret;
492 }
493
494 # This writes the given string to the socket and then reads it
495 # back.  It returns 1 on success, 0 on failure.
496 sub tcp_echo
497 {
498   my $self = shift;
499   my $timeout = shift;
500   my $pingstring = shift;
501
502   my $ret = undef;
503   my $time = &time();
504   my $wrstr = $pingstring;
505   my $rdstr = "";
506
507   eval <<'EOM';
508     do {
509       my $rin = "";
510       vec($rin, $self->{"fh"}->fileno(), 1) = 1;
511
512       my $rout = undef;
513       if($wrstr) {
514         $rout = "";
515         vec($rout, $self->{"fh"}->fileno(), 1) = 1;
516       }
517
518       if(select($rin, $rout, undef, ($time + $timeout) - &time())) {
519
520         if($rout && vec($rout,$self->{"fh"}->fileno(),1)) {
521           my $num = syswrite($self->{"fh"}, $wrstr);
522           if($num) {
523             # If it was a partial write, update and try again.
524             $wrstr = substr($wrstr,$num);
525           } else {
526             # There was an error.
527             $ret = 0;
528           }
529         }
530
531         if(vec($rin,$self->{"fh"}->fileno(),1)) {
532           my $reply;
533           if(sysread($self->{"fh"},$reply,length($pingstring)-length($rdstr))) {
534             $rdstr .= $reply;
535             $ret = 1 if $rdstr eq $pingstring;
536           } else {
537             # There was an error.
538             $ret = 0;
539           }
540         }
541
542       }
543     } until &time() > ($time + $timeout) || defined($ret);
544 EOM
545
546   return $ret;
547 }
548
549
550
551
552 # Description: Perform a stream ping.  If the tcp connection isn't
553 # already open, it opens it.  It then sends some data and waits for
554 # a reply.  It leaves the stream open on exit.
555
556 sub ping_stream
557 {
558   my ($self,
559       $ip,                # Packed IP number of the host
560       $timeout            # Seconds after which ping times out
561       ) = @_;
562
563   # Open the stream if it's not already open
564   if(!defined $self->{"fh"}->fileno()) {
565     $self->tcp_connect($ip, $timeout) or return 0;
566   }
567
568   croak "tried to switch servers while stream pinging"
569     if $self->{"ip"} ne $ip;
570
571   return $self->tcp_echo($timeout, $pingstring);
572 }
573
574 # Description: opens the stream.  You would do this if you want to
575 # separate the overhead of opening the stream from the first ping.
576
577 sub open
578 {
579   my ($self,
580       $host,              # Host or IP address
581       $timeout            # Seconds after which open times out
582       ) = @_;
583
584   my ($ip);               # Packed IP number of the host
585   $ip = inet_aton($host);
586   $timeout = $self->{"timeout"} unless $timeout;
587
588   if($self->{"proto"} eq "stream") {
589     if(defined($self->{"fh"}->fileno())) {
590       croak("socket is already open");
591     } else {
592       $self->tcp_connect($ip, $timeout);
593     }
594   }
595 }
596
597
598 # Description:  Perform a udp echo ping.  Construct a message of
599 # at least the one-byte sequence number and any additional data bytes.
600 # Send the message out and wait for a message to come back.  If we
601 # get a message, make sure all of its parts match.  If they do, we are
602 # done.  Otherwise go back and wait for the message until we run out
603 # of time.  Return the result of our efforts.
604
605 use constant UDP_FLAGS => 0; # Nothing special on send or recv
606
607 sub ping_udp
608 {
609   my ($self,
610       $ip,                # Packed IP number of the host
611       $timeout            # Seconds after which ping times out
612       ) = @_;
613
614   my ($saddr,             # sockaddr_in with port and ip
615       $ret,               # The return value
616       $msg,               # Message to be echoed
617       $finish_time,       # Time ping should be finished
618       $done,              # Set to 1 when we are done pinging
619       $rbits,             # Read bits, filehandles for reading
620       $nfound,            # Number of ready filehandles found
621       $from_saddr,        # sockaddr_in of sender
622       $from_msg,          # Characters echoed by $host
623       $from_port,         # Port message was echoed from
624       $from_ip            # Packed IP number of sender
625       );
626
627   $saddr = sockaddr_in($self->{"port_num"}, $ip);
628   $self->{"seq"} = ($self->{"seq"} + 1) % 256;    # Increment sequence
629   $msg = chr($self->{"seq"}) . $self->{"data"};   # Add data if any
630   send($self->{"fh"}, $msg, UDP_FLAGS, $saddr);   # Send it
631
632   $rbits = "";
633   vec($rbits, $self->{"fh"}->fileno(), 1) = 1;
634   $ret = 0;                   # Default to unreachable
635   $done = 0;
636   $finish_time = &time() + $timeout;       # Ping needs to be done by then
637   while (!$done && $timeout > 0)
638   {
639     $nfound = select($rbits, undef, undef, $timeout); # Wait for response
640     $timeout = $finish_time - &time();   # Get remaining time
641
642     if (!defined($nfound))  # Hmm, a strange error
643     {
644       $ret = undef;
645       $done = 1;
646     }
647     elsif ($nfound)         # A packet is waiting
648     {
649       $from_msg = "";
650       $from_saddr = recv($self->{"fh"}, $from_msg, 1500, UDP_FLAGS)
651         or last; # For example an unreachable host will make recv() fail.
652       ($from_port, $from_ip) = sockaddr_in($from_saddr);
653       if (!$source_verify ||
654           (($from_ip eq $ip) &&        # Does the packet check out?
655            ($from_port == $self->{"port_num"}) &&
656            ($from_msg eq $msg)))
657       {
658         $ret = 1;       # It's a winner
659         $done = 1;
660       }
661     }
662     else                    # Oops, timed out
663     {
664       $done = 1;
665     }
666   }
667   return $ret;
668 }
669
670 # Description:  Close the connection unless we are using the tcp
671 # protocol, since it will already be closed.
672
673 sub close
674 {
675   my ($self) = @_;
676
677   $self->{"fh"}->close() unless $self->{"proto"} eq "tcp";
678 }
679
680
681 1;
682 __END__
683
684 =head1 NAME
685
686 Net::Ping - check a remote host for reachability
687
688 $Id: Ping.pm,v 1.6 2002/06/19 15:23:48 rob Exp $
689
690 =head1 SYNOPSIS
691
692     use Net::Ping;
693
694     $p = Net::Ping->new();
695     print "$host is alive.\n" if $p->ping($host);
696     $p->close();
697
698     $p = Net::Ping->new("icmp");
699     $p->bind($my_addr); # Specify source interface of pings
700     foreach $host (@host_array)
701     {
702         print "$host is ";
703         print "NOT " unless $p->ping($host, 2);
704         print "reachable.\n";
705         sleep(1);
706     }
707     $p->close();
708
709     $p = Net::Ping->new("tcp", 2);
710     # Try connecting to the www port instead of the echo port
711     $p->{port_num} = getservbyname("http", "tcp");
712     while ($stop_time > time())
713     {
714         print "$host not reachable ", scalar(localtime()), "\n"
715             unless $p->ping($host);
716         sleep(300);
717     }
718     undef($p);
719
720     # High precision syntax (requires Time::HiRes)
721     $p = Net::Ping->new();
722     $p->hires();
723     ($ret, $duration, $ip) = $p->ping($host, 5.5);
724     printf("$host [ip: $ip] is alive (packet return time: %.2f ms)\n", 1000 * $duration)
725       if $ret;
726     $p->close();
727
728     # For backward compatibility
729     print "$host is alive.\n" if pingecho($host);
730
731 =head1 DESCRIPTION
732
733 This module contains methods to test the reachability of remote
734 hosts on a network.  A ping object is first created with optional
735 parameters, a variable number of hosts may be pinged multiple
736 times and then the connection is closed.
737
738 You may choose one of four different protocols to use for the
739 ping. The "udp" protocol is the default. Note that a live remote host
740 may still fail to be pingable by one or more of these protocols. For
741 example, www.microsoft.com is generally alive but not pingable.
742
743 With the "tcp" protocol the ping() method attempts to establish a
744 connection to the remote host's echo port.  If the connection is
745 successfully established, the remote host is considered reachable.  No
746 data is actually echoed.  This protocol does not require any special
747 privileges but has higher overhead than the other two protocols.
748
749 Specifying the "udp" protocol causes the ping() method to send a udp
750 packet to the remote host's echo port.  If the echoed packet is
751 received from the remote host and the received packet contains the
752 same data as the packet that was sent, the remote host is considered
753 reachable.  This protocol does not require any special privileges.
754 It should be borne in mind that, for a udp ping, a host
755 will be reported as unreachable if it is not running the
756 appropriate echo service.  For Unix-like systems see L<inetd(8)>
757 for more information.
758
759 If the "icmp" protocol is specified, the ping() method sends an icmp
760 echo message to the remote host, which is what the UNIX ping program
761 does.  If the echoed message is received from the remote host and
762 the echoed information is correct, the remote host is considered
763 reachable.  Specifying the "icmp" protocol requires that the program
764 be run as root or that the program be setuid to root.
765
766 If the "external" protocol is specified, the ping() method attempts to
767 use the C<Net::Ping::External> module to ping the remote host.
768 C<Net::Ping::External> interfaces with your system's default C<ping>
769 utility to perform the ping, and generally produces relatively
770 accurate results. If C<Net::Ping::External> if not installed on your
771 system, specifying the "external" protocol will result in an error.
772
773 =head2 Functions
774
775 =over 4
776
777 =item Net::Ping->new([$proto [, $def_timeout [, $bytes]]]);
778
779 Create a new ping object.  All of the parameters are optional.  $proto
780 specifies the protocol to use when doing a ping.  The current choices
781 are "tcp", "udp" or "icmp".  The default is "udp".
782
783 If a default timeout ($def_timeout) in seconds is provided, it is used
784 when a timeout is not given to the ping() method (below).  The timeout
785 must be greater than 0 and the default, if not specified, is 5 seconds.
786
787 If the number of data bytes ($bytes) is given, that many data bytes
788 are included in the ping packet sent to the remote host. The number of
789 data bytes is ignored if the protocol is "tcp".  The minimum (and
790 default) number of data bytes is 1 if the protocol is "udp" and 0
791 otherwise.  The maximum number of data bytes that can be specified is
792 1024.
793
794 =item $p->ping($host [, $timeout]);
795
796 Ping the remote host and wait for a response.  $host can be either the
797 hostname or the IP number of the remote host.  The optional timeout
798 must be greater than 0 seconds and defaults to whatever was specified
799 when the ping object was created.  Returns a success flag.  If the
800 hostname cannot be found or there is a problem with the IP number, the
801 success flag returned will be undef.  Otherwise, the success flag will
802 be 1 if the host is reachable and 0 if it is not.  For most practical
803 purposes, undef and 0 and can be treated as the same case.  In array
804 context, the elapsed time is also returned.  The elapsed time value will
805 be a float, as retuned by the Time::HiRes::time() function, if hires()
806 has been previously called, otherwise it is returned as an integer.
807
808 =item $p->source_verify( { 0 | 1 } );
809
810 Allows source endpoint verification to be enabled or disabled.
811 This is useful for those remote destinations with multiples
812 interfaces where the response may not originate from the same
813 endpoint that the original destination endpoint was sent to.
814 This only affects udp and icmp protocol pings.
815
816 This is enabled by default.
817
818 =item $p->hires( { 0 | 1 } );
819
820 Causes this module to use Time::HiRes module, allowing milliseconds
821 to be returned by subsequent calls to ping().
822
823 This is disabled by default.
824
825 =item $p->bind($local_addr);
826
827 Sets the source address from which pings will be sent.  This must be
828 the address of one of the interfaces on the local host.  $local_addr
829 may be specified as a hostname or as a text IP address such as
830 "192.168.1.1".
831
832 If the protocol is set to "tcp", this method may be called any
833 number of times, and each call to the ping() method (below) will use
834 the most recent $local_addr.  If the protocol is "icmp" or "udp",
835 then bind() must be called at most once per object, and (if it is
836 called at all) must be called before the first call to ping() for that
837 object.
838
839 =item $p->open($host);
840
841 When you are using the stream protocol, this call pre-opens the
842 tcp socket.  It's only necessary to do this if you want to
843 provide a different timeout when creating the connection, or
844 remove the overhead of establishing the connection from the
845 first ping.  If you don't call C<open()>, the connection is
846 automatically opened the first time C<ping()> is called.
847 This call simply does nothing if you are using any protocol other
848 than stream.
849
850 =item $p->close();
851
852 Close the network connection for this ping object.  The network
853 connection is also closed by "undef $p".  The network connection is
854 automatically closed if the ping object goes out of scope (e.g. $p is
855 local to a subroutine and you leave the subroutine).
856
857 =item pingecho($host [, $timeout]);
858
859 To provide backward compatibility with the previous version of
860 Net::Ping, a pingecho() subroutine is available with the same
861 functionality as before.  pingecho() uses the tcp protocol.  The
862 return values and parameters are the same as described for the ping()
863 method.  This subroutine is obsolete and may be removed in a future
864 version of Net::Ping.
865
866 =back
867
868 =head1 WARNING
869
870 pingecho() or a ping object with the tcp protocol use alarm() to
871 implement the timeout.  So, don't use alarm() in your program while
872 you are using pingecho() or a ping object with the tcp protocol.  The
873 udp and icmp protocols do not use alarm() to implement the timeout.
874
875 =head1 NOTES
876
877 There will be less network overhead (and some efficiency in your
878 program) if you specify either the udp or the icmp protocol.  The tcp
879 protocol will generate 2.5 times or more traffic for each ping than
880 either udp or icmp.  If many hosts are pinged frequently, you may wish
881 to implement a small wait (e.g. 25ms or more) between each ping to
882 avoid flooding your network with packets.
883
884 The icmp protocol requires that the program be run as root or that it
885 be setuid to root.  The other protocols do not require special
886 privileges, but not all network devices implement tcp or udp echo.
887
888 Local hosts should normally respond to pings within milliseconds.
889 However, on a very congested network it may take up to 3 seconds or
890 longer to receive an echo packet from the remote host.  If the timeout
891 is set too low under these conditions, it will appear that the remote
892 host is not reachable (which is almost the truth).
893
894 Reachability doesn't necessarily mean that the remote host is actually
895 functioning beyond its ability to echo packets.  tcp is slightly better
896 at indicating the health of a system than icmp because it uses more
897 of the networking stack to respond.
898
899 Because of a lack of anything better, this module uses its own
900 routines to pack and unpack ICMP packets.  It would be better for a
901 separate module to be written which understands all of the different
902 kinds of ICMP packets.
903
904 =head1 INSTALL
905
906 The latest source tree is available via cvs:
907
908   cvs -z3 -q -d :pserver:anonymous@cvs.roobik.com.:/usr/local/cvsroot/freeware co Net-Ping
909   cd Net-Ping
910
911 The tarball can be created as follows:
912
913   perl Makefile.PL ; make ; make dist
914
915 The latest Net::Ping release can be found at CPAN:
916
917   $CPAN/modules/by-module/Net/
918
919 1) Extract the tarball
920
921   gtar -zxvf Net-Ping-xxxx.tar.gz
922   cd Net-Ping-xxxx
923
924 2) Build:
925
926   make realclean
927   perl Makefile.PL
928   make
929   make test
930
931 3) Install
932
933   make install
934
935 Or install it RPM Style:
936
937   rpm -ta SOURCES/Net-Ping-xxxx.tar.gz
938
939   rpm -ih RPMS/noarch/perl-Net-Ping-xxxx.rpm
940
941 =head1 AUTHORS
942
943   Current maintainer:
944     bbb@cpan.org (Rob Brown)
945
946   External protocol:
947     colinm@cpan.org (Colin McMillen)
948
949   Stream protocol:
950     bronson@trestle.com (Scott Bronson)
951
952   Original pingecho():
953     karrer@bernina.ethz.ch (Andreas Karrer)
954     pmarquess@bfsec.bt.co.uk (Paul Marquess)
955
956   Original Net::Ping author:
957     mose@ns.ccsn.edu (Russell Mosemann)
958
959 =head1 COPYRIGHT
960
961 Copyright (c) 2002, Rob Brown.  All rights reserved.
962
963 Copyright (c) 2001, Colin McMillen.  All rights reserved.
964
965 This program is free software; you may redistribute it and/or
966 modify it under the same terms as Perl itself.
967
968 =cut