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