Printing out the ok messages helps successful testing.
[p5sagit/p5-mst-13.2.git] / lib / Net / Ping.pm
CommitLineData
a0d0e21e 1package Net::Ping;
2
edc5bd88 3# Current maintainer: colinm@cpan.org (Colin McMillen)
4#
5# Original author: mose@ccsn.edu (Russell Mosemann)
a3b93737 6#
7# Authors of the original pingecho():
8# karrer@bernina.ethz.ch (Andreas Karrer)
0536e0eb 9# Paul.Marquess@btinternet.com (Paul Marquess)
a3b93737 10#
edc5bd88 11# Copyright (c) 2001, Colin McMillen. All rights reserved. This
a3b93737 12# program is free software; you may redistribute it and/or modify it
13# under the same terms as Perl itself.
17f410f9 14use 5.005_64;
a0d0e21e 15require Exporter;
16
a3b93737 17use strict;
17f410f9 18our(@ISA, @EXPORT, $VERSION, $def_timeout, $def_proto, $max_datasize);
a3b93737 19use FileHandle;
20use Socket qw( SOCK_DGRAM SOCK_STREAM SOCK_RAW PF_INET
edc5bd88 21 inet_aton inet_ntoa sockaddr_in );
a3b93737 22use Carp;
a79c1648 23
a0d0e21e 24@ISA = qw(Exporter);
a3b93737 25@EXPORT = qw(pingecho);
edc5bd88 26$VERSION = 2.03;
a0d0e21e 27
a3b93737 28# Constants
a0d0e21e 29
a3b93737 30$def_timeout = 5; # Default timeout to wait for a reply
31$def_proto = "udp"; # Default protocol to use for pinging
32$max_datasize = 1024; # Maximum data bytes in a packet
a0d0e21e 33
a3b93737 34# Description: The pingecho() subroutine is provided for backward
35# compatibility with the original Net::Ping. It accepts a host
36# name/IP and an optional timeout in seconds. Create a tcp ping
37# object and try pinging the host. The result of the ping is returned.
a0d0e21e 38
a3b93737 39sub pingecho
40{
41 my ($host, # Name or IP number of host to ping
42 $timeout # Optional timeout in seconds
43 ) = @_;
44 my ($p); # A ping object
a0d0e21e 45
a3b93737 46 $p = Net::Ping->new("tcp", $timeout);
47 $p->ping($host); # Going out of scope closes the connection
48}
a0d0e21e 49
a3b93737 50# Description: The new() method creates a new ping object. Optional
51# parameters may be specified for the protocol to use, the timeout in
52# seconds and the size in bytes of additional data which should be
53# included in the packet.
54# After the optional parameters are checked, the data is constructed
55# and a socket is opened if appropriate. The object is returned.
56
57sub new
58{
59 my ($this,
60 $proto, # Optional protocol to use for pinging
61 $timeout, # Optional timeout in seconds
62 $data_size # Optional additional bytes of data
63 ) = @_;
64 my $class = ref($this) || $this;
65 my $self = {};
66 my ($cnt, # Count through data bytes
67 $min_datasize # Minimum data bytes required
68 );
69
70 bless($self, $class);
71
72 $proto = $def_proto unless $proto; # Determine the protocol
edc5bd88 73 croak('Protocol for ping must be "icmp", "tcp", "udp", or "external"')
74 unless $proto =~ m/^(tcp|udp|icmp|external)$/;
a3b93737 75 $self->{"proto"} = $proto;
76
77 $timeout = $def_timeout unless $timeout; # Determine the timeout
78 croak("Default timeout for ping must be greater than 0 seconds")
79 if $timeout <= 0;
80 $self->{"timeout"} = $timeout;
81
82 $min_datasize = ($proto eq "udp") ? 1 : 0; # Determine data size
83 $data_size = $min_datasize unless defined($data_size) && $proto ne "tcp";
84 croak("Data for ping must be from $min_datasize to $max_datasize bytes")
85 if ($data_size < $min_datasize) || ($data_size > $max_datasize);
86 $data_size-- if $self->{"proto"} eq "udp"; # We provide the first byte
87 $self->{"data_size"} = $data_size;
88
89 $self->{"data"} = ""; # Construct data bytes
90 for ($cnt = 0; $cnt < $self->{"data_size"}; $cnt++)
91 {
92 $self->{"data"} .= chr($cnt % 256);
93 }
94
95 $self->{"seq"} = 0; # For counting packets
96 if ($self->{"proto"} eq "udp") # Open a socket
97 {
98 $self->{"proto_num"} = (getprotobyname('udp'))[2] ||
99 croak("Can't udp protocol by name");
100 $self->{"port_num"} = (getservbyname('echo', 'udp'))[2] ||
101 croak("Can't get udp echo port by name");
102 $self->{"fh"} = FileHandle->new();
103 socket($self->{"fh"}, &PF_INET(), &SOCK_DGRAM(),
104 $self->{"proto_num"}) ||
105 croak("udp socket error - $!");
106 }
107 elsif ($self->{"proto"} eq "icmp")
108 {
17f28c40 109 croak("icmp ping requires root privilege") if ($> and $^O ne 'VMS');
a3b93737 110 $self->{"proto_num"} = (getprotobyname('icmp'))[2] ||
111 croak("Can't get icmp protocol by name");
112 $self->{"pid"} = $$ & 0xffff; # Save lower 16 bits of pid
113 $self->{"fh"} = FileHandle->new();
114 socket($self->{"fh"}, &PF_INET(), &SOCK_RAW(), $self->{"proto_num"}) ||
115 croak("icmp socket error - $!");
116 }
117 elsif ($self->{"proto"} eq "tcp") # Just a file handle for now
118 {
119 $self->{"proto_num"} = (getprotobyname('tcp'))[2] ||
120 croak("Can't get tcp protocol by name");
121 $self->{"port_num"} = (getservbyname('echo', 'tcp'))[2] ||
122 croak("Can't get tcp echo port by name");
123 $self->{"fh"} = FileHandle->new();
124 }
125
126
127 return($self);
128}
a0d0e21e 129
a3b93737 130# Description: Ping a host name or IP number with an optional timeout.
131# First lookup the host, and return undef if it is not found. Otherwise
132# perform the specific ping method based on the protocol. Return the
133# result of the ping.
134
135sub ping
136{
137 my ($self,
138 $host, # Name or IP number of host to ping
139 $timeout # Seconds after which ping times out
140 ) = @_;
141 my ($ip, # Packed IP number of $host
142 $ret # The return value
143 );
144
145 croak("Usage: \$p->ping(\$host [, \$timeout])") unless @_ == 2 || @_ == 3;
146 $timeout = $self->{"timeout"} unless $timeout;
147 croak("Timeout must be greater than 0 seconds") if $timeout <= 0;
148
149 $ip = inet_aton($host);
150 return(undef) unless defined($ip); # Does host exist?
151
edc5bd88 152 # Dispatch to the appropriate routine.
153 return $self->ping_external($ip, $timeout) if $self->{"proto"} eq "external";
154 return $self->ping_udp($ip, $timeout) if $self->{"proto"} eq "udp";
155 return $self->ping_icmp($ip, $timeout) if $self->{"proto"} eq "icmp";
156 return $self->ping_tcp($ip, $timeout) if $self->{"proto"} eq "tcp";
157
158 croak("Unknown protocol \"$self->{proto}\" in ping()");
159}
160
161# Uses Net::Ping::External to do an external ping.
162sub ping_external {
163 my ($self,
164 $ip, # Packed IP number of the host
165 $timeout # Seconds after which ping times out
166 ) = @_;
167
168 eval { require Net::Ping::External; };
169 croak('Protocol "external" not supported on your system: Net::Ping::External not found') if $@;
170 return Net::Ping::External::ping(ip => $ip, timeout => $timeout);
a3b93737 171}
a0d0e21e 172
a3b93737 173sub ping_icmp
174{
175 my ($self,
176 $ip, # Packed IP number of the host
177 $timeout # Seconds after which ping times out
178 ) = @_;
179
180 my $ICMP_ECHOREPLY = 0; # ICMP packet types
181 my $ICMP_ECHO = 8;
182 my $icmp_struct = "C2 S3 A"; # Structure of a minimal ICMP packet
183 my $subcode = 0; # No ICMP subcode for ECHO and ECHOREPLY
184 my $flags = 0; # No special flags when opening a socket
185 my $port = 0; # No port with ICMP
186
187 my ($saddr, # sockaddr_in with port and ip
188 $checksum, # Checksum of ICMP packet
189 $msg, # ICMP packet to send
190 $len_msg, # Length of $msg
191 $rbits, # Read bits, filehandles for reading
192 $nfound, # Number of ready filehandles found
193 $finish_time, # Time ping should be finished
194 $done, # set to 1 when we are done
195 $ret, # Return value
196 $recv_msg, # Received message including IP header
197 $from_saddr, # sockaddr_in of sender
198 $from_port, # Port packet was sent from
199 $from_ip, # Packed IP of sender
200 $from_type, # ICMP type
201 $from_subcode, # ICMP subcode
202 $from_chk, # ICMP packet checksum
203 $from_pid, # ICMP packet id
204 $from_seq, # ICMP packet sequence
205 $from_msg # ICMP message
206 );
207
208 $self->{"seq"} = ($self->{"seq"} + 1) % 65536; # Increment sequence
209 $checksum = 0; # No checksum for starters
210 $msg = pack($icmp_struct . $self->{"data_size"}, $ICMP_ECHO, $subcode,
211 $checksum, $self->{"pid"}, $self->{"seq"}, $self->{"data"});
212 $checksum = Net::Ping->checksum($msg);
213 $msg = pack($icmp_struct . $self->{"data_size"}, $ICMP_ECHO, $subcode,
214 $checksum, $self->{"pid"}, $self->{"seq"}, $self->{"data"});
215 $len_msg = length($msg);
216 $saddr = sockaddr_in($port, $ip);
217 send($self->{"fh"}, $msg, $flags, $saddr); # Send the message
218
219 $rbits = "";
220 vec($rbits, $self->{"fh"}->fileno(), 1) = 1;
8e07c86e 221 $ret = 0;
a3b93737 222 $done = 0;
223 $finish_time = time() + $timeout; # Must be done by this time
224 while (!$done && $timeout > 0) # Keep trying if we have time
225 {
226 $nfound = select($rbits, undef, undef, $timeout); # Wait for packet
227 $timeout = $finish_time - time(); # Get remaining time
228 if (!defined($nfound)) # Hmm, a strange error
229 {
230 $ret = undef;
231 $done = 1;
232 }
233 elsif ($nfound) # Got a packet from somewhere
234 {
235 $recv_msg = "";
236 $from_saddr = recv($self->{"fh"}, $recv_msg, 1500, $flags);
237 ($from_port, $from_ip) = sockaddr_in($from_saddr);
238 ($from_type, $from_subcode, $from_chk,
239 $from_pid, $from_seq, $from_msg) =
240 unpack($icmp_struct . $self->{"data_size"},
241 substr($recv_msg, length($recv_msg) - $len_msg,
242 $len_msg));
243 if (($from_type == $ICMP_ECHOREPLY) &&
244 ($from_ip eq $ip) &&
245 ($from_pid == $self->{"pid"}) && # Does the packet check out?
246 ($from_seq == $self->{"seq"}))
247 {
248 $ret = 1; # It's a winner
249 $done = 1;
250 }
251 }
252 else # Oops, timed out
253 {
254 $done = 1;
255 }
256 }
257 return($ret)
258}
259
260# Description: Do a checksum on the message. Basically sum all of
261# the short words and fold the high order bits into the low order bits.
262
263sub checksum
264{
265 my ($class,
266 $msg # The message to checksum
267 ) = @_;
268 my ($len_msg, # Length of the message
269 $num_short, # The number of short words in the message
270 $short, # One short word
271 $chk # The checksum
272 );
273
274 $len_msg = length($msg);
42fcf866 275 $num_short = int($len_msg / 2);
a3b93737 276 $chk = 0;
277 foreach $short (unpack("S$num_short", $msg))
278 {
279 $chk += $short;
280 } # Add the odd byte in
42fcf866 281 $chk += (unpack("C", substr($msg, $len_msg - 1, 1)) << 8) if $len_msg % 2;
a3b93737 282 $chk = ($chk >> 16) + ($chk & 0xffff); # Fold high into low
283 return(~(($chk >> 16) + $chk) & 0xffff); # Again and complement
284}
285
286# Description: Perform a tcp echo ping. Since a tcp connection is
287# host specific, we have to open and close each connection here. We
288# can't just leave a socket open. Because of the robust nature of
289# tcp, it will take a while before it gives up trying to establish a
edc5bd88 290# connection. Therefore, we use select() on a non-blocking socket to
291# check against our timeout. No data bytes are actually
a3b93737 292# sent since the successful establishment of a connection is proof
293# enough of the reachability of the remote host. Also, tcp is
294# expensive and doesn't need our help to add to the overhead.
295
296sub ping_tcp
297{
edc5bd88 298 my ($self,
299 $ip, # Packed IP number of the host
300 $timeout # Seconds after which ping times out
301 ) = @_;
302 my ($saddr, # sockaddr_in with port and ip
303 $rin, # Used in select()
304 $ret # The return value
305 );
306
307 socket($self->{"fh"}, &PF_INET(), &SOCK_STREAM(), $self->{"proto_num"}) ||
308 croak("tcp socket error - $!");
309
310 $saddr = sockaddr_in($self->{"port_num"}, $ip);
311
312 $ret = 0; # Default to unreachable
313
314 # Buggy Winsock API doesn't allow us to use non-blocking connect()
315 # calls. Hence, if our OS is Windows, we need to create a new process
316 # to run a blocking connect attempt, and kill it after the timeout has
317 # passed.
318 if ($^O =~ /win32/i)
319 {
320 my ($child, $ret, $pid, $time);
321 my $host = inet_ntoa($ip);
322
323 # The code we will be executing in our new process.
324 my $code = '"use Net::Ping; $p = Net::Ping->new(\'tcp\'); ';
325 $code .= 'exit($p->_ping_tcp_win(' . $host . '))"';
326
327 # Call the process.
328 $pid = system(1, "perl", "-e", $code);
329
330 # Import the POSIX version of <sys/wait.h>
331 require POSIX;
332 import POSIX qw(:sys_wait_h);
333
334 # Get the current time; will be used to tell if we've timed out.
335 $time = time;
336
337 # Wait for the child to return or for the timeout to expire.
338 do {
339 $child = waitpid($pid, &WNOHANG);
340 $ret = $?;
341 } until time > ($time + $timeout) or $child;
342
343 # Return an appropriate value; 0 if the child didn't return,
344 # the return value of the child otherwise.
345 return $ret >> 8 if $child;
346
347 kill $pid;
348 return 0;
349 }
350
351 # If our OS isn't Windows, do this stuff instead...
352 else
353 {
354 # Try a non-blocking TCP connect to the remote echo port.
355 # Our call to select() below will stop after the timeout has
356 # passed or set the return value to true if the connection
357 # succeeds in time.
358 $self->{"fh"}->blocking(0);
359 connect($self->{"fh"}, $saddr);
360
361 $rin = "";
362 vec($rin, fileno($self->{"fh"}), 1) = 1;
363 $ret = 1 if select($rin, undef, undef, $timeout);
364
365 # Close our filehandle, restore it to its default state (i.e. blocking),
366 # and return our result.
367 $self->{"fh"}->blocking(1);
368 $self->{"fh"}->close();
369 }
370 return($ret);
371}
372
373# Warning: this method may generate false positives.
374# It is meant to be a private method and should only
375# be invoked by ping_tcp() if $^O =~ /win32/i.
376sub _ping_tcp_win
377{
a3b93737 378 my ($self,
379 $ip, # Packed IP number of the host
a3b93737 380 ) = @_;
381 my ($saddr, # sockaddr_in with port and ip
382 $ret # The return value
383 );
edc5bd88 384
a3b93737 385 socket($self->{"fh"}, &PF_INET(), &SOCK_STREAM(), $self->{"proto_num"}) ||
386 croak("tcp socket error - $!");
edc5bd88 387
a3b93737 388 $saddr = sockaddr_in($self->{"port_num"}, $ip);
389
a3b93737 390 $ret = 0; # Default to unreachable
edc5bd88 391
392 eval { $ret = connect($self->{"fh"}, $saddr) };
393
394 # If the remote host exists but returns "Connection refused",
395 # the call to connect() sets $! to "Unknown error". So, we
396 # assume that an "Unknown error" actually means the host is
397 # alive. This assumption may occassionally give false positives.
398 $ret = 1 if $! =~ /Unknown error/i;
399
a3b93737 400 $self->{"fh"}->close();
edc5bd88 401 return $ret;
a3b93737 402}
403
404# Description: Perform a udp echo ping. Construct a message of
405# at least the one-byte sequence number and any additional data bytes.
406# Send the message out and wait for a message to come back. If we
407# get a message, make sure all of its parts match. If they do, we are
408# done. Otherwise go back and wait for the message until we run out
409# of time. Return the result of our efforts.
410
411sub ping_udp
412{
413 my ($self,
414 $ip, # Packed IP number of the host
415 $timeout # Seconds after which ping times out
416 ) = @_;
417
418 my $flags = 0; # Nothing special on open
419
420 my ($saddr, # sockaddr_in with port and ip
421 $ret, # The return value
422 $msg, # Message to be echoed
423 $finish_time, # Time ping should be finished
424 $done, # Set to 1 when we are done pinging
425 $rbits, # Read bits, filehandles for reading
426 $nfound, # Number of ready filehandles found
427 $from_saddr, # sockaddr_in of sender
428 $from_msg, # Characters echoed by $host
429 $from_port, # Port message was echoed from
430 $from_ip # Packed IP number of sender
431 );
432
433 $saddr = sockaddr_in($self->{"port_num"}, $ip);
434 $self->{"seq"} = ($self->{"seq"} + 1) % 256; # Increment sequence
435 $msg = chr($self->{"seq"}) . $self->{"data"}; # Add data if any
436 send($self->{"fh"}, $msg, $flags, $saddr); # Send it
437
438 $rbits = "";
439 vec($rbits, $self->{"fh"}->fileno(), 1) = 1;
440 $ret = 0; # Default to unreachable
441 $done = 0;
442 $finish_time = time() + $timeout; # Ping needs to be done by then
443 while (!$done && $timeout > 0)
444 {
445 $nfound = select($rbits, undef, undef, $timeout); # Wait for response
446 $timeout = $finish_time - time(); # Get remaining time
447
448 if (!defined($nfound)) # Hmm, a strange error
449 {
450 $ret = undef;
451 $done = 1;
452 }
453 elsif ($nfound) # A packet is waiting
454 {
455 $from_msg = "";
b4b1f609 456 $from_saddr = recv($self->{"fh"}, $from_msg, 1500, $flags)
457 or last; # For example an unreachable host will make recv() fail.
458 ($from_port, $from_ip) = sockaddr_in($from_saddr);
459 if (($from_ip eq $ip) && # Does the packet check out?
460 ($from_port == $self->{"port_num"}) &&
461 ($from_msg eq $msg))
462 {
463 $ret = 1; # It's a winner
464 $done = 1;
465 }
466 }
a3b93737 467 else # Oops, timed out
468 {
469 $done = 1;
470 }
471 }
472 return($ret);
a0d0e21e 473}
474
a3b93737 475# Description: Close the connection unless we are using the tcp
476# protocol, since it will already be closed.
477
478sub close
479{
480 my ($self) = @_;
481
482 $self->{"fh"}->close() unless $self->{"proto"} eq "tcp";
483}
484
485
a0d0e21e 4861;
8e07c86e 487__END__
488
8e07c86e 489=head1 NAME
490
a3b93737 491Net::Ping - check a remote host for reachability
8e07c86e 492
493=head1 SYNOPSIS
494
495 use Net::Ping;
8e07c86e 496
a3b93737 497 $p = Net::Ping->new();
498 print "$host is alive.\n" if $p->ping($host);
499 $p->close();
500
501 $p = Net::Ping->new("icmp");
502 foreach $host (@host_array)
503 {
504 print "$host is ";
505 print "NOT " unless $p->ping($host, 2);
506 print "reachable.\n";
507 sleep(1);
508 }
509 $p->close();
edc5bd88 510
a3b93737 511 $p = Net::Ping->new("tcp", 2);
512 while ($stop_time > time())
513 {
514 print "$host not reachable ", scalar(localtime()), "\n"
515 unless $p->ping($host);
516 sleep(300);
517 }
518 undef($p);
edc5bd88 519
a3b93737 520 # For backward compatibility
521 print "$host is alive.\n" if pingecho($host);
8e07c86e 522
a3b93737 523=head1 DESCRIPTION
8e07c86e 524
a3b93737 525This module contains methods to test the reachability of remote
526hosts on a network. A ping object is first created with optional
527parameters, a variable number of hosts may be pinged multiple
528times and then the connection is closed.
529
edc5bd88 530You may choose one of four different protocols to use for the
be3174d2 531ping. The "udp" protocol is the default. Note that a live remote host
532may still fail to be pingable by one or more of these protocols. For
533example, www.microsoft.com is generally alive but not pingable.
534
a3b93737 535With the "tcp" protocol the ping() method attempts to establish a
536connection to the remote host's echo port. If the connection is
537successfully established, the remote host is considered reachable. No
538data is actually echoed. This protocol does not require any special
539privileges but has higher overhead than the other two protocols.
540
541Specifying the "udp" protocol causes the ping() method to send a udp
542packet to the remote host's echo port. If the echoed packet is
543received from the remote host and the received packet contains the
544same data as the packet that was sent, the remote host is considered
545reachable. This protocol does not require any special privileges.
546
edc5bd88 547It should be borne in mind that, for both udp ping, a host
4d69506c 548will be reported as unreachable if it is not running the
ba830936 549appropriate echo service. For Unix-like systems see L<inetd(8)> for
550more information.
551
a3b93737 552If the "icmp" protocol is specified, the ping() method sends an icmp
553echo message to the remote host, which is what the UNIX ping program
554does. If the echoed message is received from the remote host and
555the echoed information is correct, the remote host is considered
556reachable. Specifying the "icmp" protocol requires that the program
557be run as root or that the program be setuid to root.
558
edc5bd88 559If the "external" protocol is specified, the ping() method attempts to
560use the C<Net::Ping::External> module to ping the remote host.
561C<Net::Ping::External> interfaces with your system's default C<ping>
562utility to perform the ping, and generally produces relatively
563accurate results. If C<Net::Ping::External> if not installed on your
564system, specifying the "external" protocol will result in an error.
565
a3b93737 566=head2 Functions
567
568=over 4
569
570=item Net::Ping->new([$proto [, $def_timeout [, $bytes]]]);
571
572Create a new ping object. All of the parameters are optional. $proto
573specifies the protocol to use when doing a ping. The current choices
574are "tcp", "udp" or "icmp". The default is "udp".
575
576If a default timeout ($def_timeout) in seconds is provided, it is used
577when a timeout is not given to the ping() method (below). The timeout
578must be greater than 0 and the default, if not specified, is 5 seconds.
579
580If the number of data bytes ($bytes) is given, that many data bytes
581are included in the ping packet sent to the remote host. The number of
582data bytes is ignored if the protocol is "tcp". The minimum (and
583default) number of data bytes is 1 if the protocol is "udp" and 0
584otherwise. The maximum number of data bytes that can be specified is
5851024.
586
587=item $p->ping($host [, $timeout]);
588
589Ping the remote host and wait for a response. $host can be either the
590hostname or the IP number of the remote host. The optional timeout
591must be greater than 0 seconds and defaults to whatever was specified
592when the ping object was created. If the hostname cannot be found or
593there is a problem with the IP number, undef is returned. Otherwise,
5941 is returned if the host is reachable and 0 if it is not. For all
595practical purposes, undef and 0 and can be treated as the same case.
596
597=item $p->close();
598
599Close the network connection for this ping object. The network
600connection is also closed by "undef $p". The network connection is
601automatically closed if the ping object goes out of scope (e.g. $p is
602local to a subroutine and you leave the subroutine).
603
604=item pingecho($host [, $timeout]);
605
606To provide backward compatibility with the previous version of
607Net::Ping, a pingecho() subroutine is available with the same
608functionality as before. pingecho() uses the tcp protocol. The
609return values and parameters are the same as described for the ping()
610method. This subroutine is obsolete and may be removed in a future
611version of Net::Ping.
8e07c86e 612
a3b93737 613=back
8e07c86e 614
a3b93737 615=head1 NOTES
8e07c86e 616
a3b93737 617There will be less network overhead (and some efficiency in your
618program) if you specify either the udp or the icmp protocol. The tcp
619protocol will generate 2.5 times or more traffic for each ping than
620either udp or icmp. If many hosts are pinged frequently, you may wish
621to implement a small wait (e.g. 25ms or more) between each ping to
622avoid flooding your network with packets.
8e07c86e 623
a3b93737 624The icmp protocol requires that the program be run as root or that it
625be setuid to root. The tcp and udp protocols do not require special
626privileges, but not all network devices implement the echo protocol
627for tcp or udp.
8e07c86e 628
a3b93737 629Local hosts should normally respond to pings within milliseconds.
630However, on a very congested network it may take up to 3 seconds or
631longer to receive an echo packet from the remote host. If the timeout
632is set too low under these conditions, it will appear that the remote
633host is not reachable (which is almost the truth).
8e07c86e 634
a3b93737 635Reachability doesn't necessarily mean that the remote host is actually
636functioning beyond its ability to echo packets.
8e07c86e 637
a3b93737 638Because of a lack of anything better, this module uses its own
639routines to pack and unpack ICMP packets. It would be better for a
640separate module to be written which understands all of the different
641kinds of ICMP packets.
8e07c86e 642
a3b93737 643=cut