1package Net::Ping;
2
3require 5.002;
4require Exporter;
5
6use strict;
7use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION
8            $def_timeout $def_proto $def_factor $def_family
9            $max_datasize $pingstring $hires $source_verify $syn_forking);
10use Fcntl qw( F_GETFL F_SETFL O_NONBLOCK );
11use Socket 2.007;
12use Socket qw( SOCK_DGRAM SOCK_STREAM SOCK_RAW AF_INET PF_INET IPPROTO_TCP
13	       SOL_SOCKET SO_ERROR SO_BROADCAST
14               IPPROTO_IP IP_TOS IP_TTL
15               inet_ntoa inet_aton getnameinfo sockaddr_in );
16use POSIX qw( ENOTCONN ECONNREFUSED ECONNRESET EINPROGRESS EWOULDBLOCK EAGAIN
17	      WNOHANG );
18use FileHandle;
19use Carp;
20use Time::HiRes;
21
22@ISA = qw(Exporter);
23@EXPORT = qw(pingecho);
24@EXPORT_OK = qw(wakeonlan);
25$VERSION = "2.76";
26
27# Globals
28
29$def_timeout = 5;           # Default timeout to wait for a reply
30$def_proto = "tcp";         # Default protocol to use for pinging
31$def_factor = 1.2;          # Default exponential backoff rate.
32$def_family = AF_INET;      # Default family.
33$max_datasize = 65535;      # Maximum data bytes. recommended: 1472 (Ethernet MTU: 1500)
34# The data we exchange with the server for the stream protocol
35$pingstring = "pingschwingping!\n";
36$source_verify = 1;         # Default is to verify source endpoint
37$syn_forking = 0;
38
39# Constants
40
41my $AF_INET6  = eval { Socket::AF_INET6() } || 30;
42my $AF_UNSPEC = eval { Socket::AF_UNSPEC() };
43my $AI_NUMERICHOST = eval { Socket::AI_NUMERICHOST() } || 4;
44my $NI_NUMERICHOST = eval { Socket::NI_NUMERICHOST() } || 2;
45my $IPPROTO_IPV6   = eval { Socket::IPPROTO_IPV6() }   || 41;
46my $NIx_NOSERV = eval { Socket::NIx_NOSERV() } || 2;
47#my $IPV6_HOPLIMIT  = eval { Socket::IPV6_HOPLIMIT() };  # ping6 -h 0-255
48my $qr_family = qr/^(?:(?:(:?ip)?v?(?:4|6))|${\AF_INET}|$AF_INET6)$/;
49my $qr_family4 = qr/^(?:(?:(:?ip)?v?4)|${\AF_INET})$/;
50my $Socket_VERSION = eval $Socket::VERSION;
51
52if ($^O =~ /Win32/i) {
53  # Hack to avoid this Win32 spewage:
54  # Your vendor has not defined POSIX macro ECONNREFUSED
55  my @pairs = (ECONNREFUSED => 10061, # "Unknown Error" Special Win32 Response?
56	       ENOTCONN     => 10057,
57	       ECONNRESET   => 10054,
58	       EINPROGRESS  => 10036,
59	       EWOULDBLOCK  => 10035,
60	  );
61  while (my $name = shift @pairs) {
62    my $value = shift @pairs;
63    # When defined, these all are non-zero
64    unless (eval $name) {
65      no strict 'refs';
66      *{$name} = defined prototype \&{$name} ? sub () {$value} : sub {$value};
67    }
68  }
69#  $syn_forking = 1;    # XXX possibly useful in < Win2K ?
70};
71
72# Description:  The pingecho() subroutine is provided for backward
73# compatibility with the original Net::Ping.  It accepts a host
74# name/IP and an optional timeout in seconds.  Create a tcp ping
75# object and try pinging the host.  The result of the ping is returned.
76
77sub pingecho
78{
79  my ($host,              # Name or IP number of host to ping
80      $timeout            # Optional timeout in seconds
81      ) = @_;
82  my ($p);                # A ping object
83
84  $p = Net::Ping->new("tcp", $timeout);
85  $p->ping($host);        # Going out of scope closes the connection
86}
87
88# Description:  The new() method creates a new ping object.  Optional
89# parameters may be specified for the protocol to use, the timeout in
90# seconds and the size in bytes of additional data which should be
91# included in the packet.
92#   After the optional parameters are checked, the data is constructed
93# and a socket is opened if appropriate.  The object is returned.
94
95sub new
96{
97  my ($this,
98      $proto,             # Optional protocol to use for pinging
99      $timeout,           # Optional timeout in seconds
100      $data_size,         # Optional additional bytes of data
101      $device,            # Optional device to use
102      $tos,               # Optional ToS to set
103      $ttl,               # Optional TTL to set
104      $family,            # Optional address family (AF_INET)
105      ) = @_;
106  my  $class = ref($this) || $this;
107  my  $self = {};
108  my ($cnt,               # Count through data bytes
109      $min_datasize       # Minimum data bytes required
110      );
111
112  bless($self, $class);
113  if (ref $proto eq 'HASH') { # support named args
114    for my $k (qw(proto timeout data_size device tos ttl family
115                  gateway host port bind retrans pingstring source_verify
116                  econnrefused dontfrag
117                  IPV6_USE_MIN_MTU IPV6_RECVPATHMTU IPV6_HOPLIMIT))
118    {
119      if (exists $proto->{$k}) {
120        $self->{$k} = $proto->{$k};
121        # some are still globals
122        if ($k eq 'pingstring') { $pingstring = $proto->{$k} }
123        if ($k eq 'source_verify') { $source_verify = $proto->{$k} }
124        # and some are local
125        $timeout = $proto->{$k}   if ($k eq 'timeout');
126        $data_size = $proto->{$k} if ($k eq 'data_size');
127        $device = $proto->{$k}    if ($k eq 'device');
128        $tos = $proto->{$k}       if ($k eq 'tos');
129        $ttl = $proto->{$k}       if ($k eq 'ttl');
130        $family = $proto->{$k}    if ($k eq 'family');
131        delete $proto->{$k};
132      }
133    }
134    if (%$proto) {
135      croak("Invalid named argument: ",join(" ",keys (%$proto)));
136    }
137    $proto = $self->{'proto'};
138  }
139
140  $proto = $def_proto unless $proto;          # Determine the protocol
141  croak('Protocol for ping must be "icmp", "icmpv6", "udp", "tcp", "syn", "stream" or "external"')
142    unless $proto =~ m/^(icmp|icmpv6|udp|tcp|syn|stream|external)$/;
143  $self->{proto} = $proto;
144
145  $timeout = $def_timeout unless defined $timeout;    # Determine the timeout
146  croak("Default timeout for ping must be greater than 0 seconds")
147    if $timeout <= 0;
148  $self->{timeout} = $timeout;
149
150  $self->{device} = $device;
151
152  $self->{tos} = $tos;
153
154  if ($self->{'host'}) {
155    my $host = $self->{'host'};
156    my $ip = $self->_resolv($host) or
157      carp("could not resolve host $host");
158    $self->{host} = $ip;
159    $self->{family} = $ip->{family};
160  }
161
162  if ($self->{bind}) {
163    my $addr = $self->{bind};
164    my $ip = $self->_resolv($addr)
165      or carp("could not resolve local addr $addr");
166    $self->{local_addr} = $ip;
167  } else {
168    $self->{local_addr} = undef;              # Don't bind by default
169  }
170
171  if ($self->{proto} eq 'icmp') {
172    croak('TTL must be from 0 to 255')
173      if ($ttl && ($ttl < 0 || $ttl > 255));
174    $self->{ttl} = $ttl;
175  }
176
177  if ($family) {
178    if ($family =~ $qr_family) {
179      if ($family =~ $qr_family4) {
180        $self->{family} = AF_INET;
181      } else {
182        $self->{family} = $AF_INET6;
183      }
184    } else {
185      croak('Family must be "ipv4" or "ipv6"')
186    }
187  } else {
188    if ($self->{proto} eq 'icmpv6') {
189      $self->{family} = $AF_INET6;
190    } else {
191      $self->{family} = $def_family;
192    }
193  }
194
195  $min_datasize = ($proto eq "udp") ? 1 : 0;  # Determine data size
196  $data_size = $min_datasize unless defined($data_size) && $proto ne "tcp";
197  # allow for fragmented packets if data_size>1472 (MTU 1500)
198  croak("Data for ping must be from $min_datasize to $max_datasize bytes")
199    if ($data_size < $min_datasize) || ($data_size > $max_datasize);
200  $data_size-- if $self->{proto} eq "udp";  # We provide the first byte
201  $self->{data_size} = $data_size;
202
203  $self->{data} = "";                       # Construct data bytes
204  for ($cnt = 0; $cnt < $self->{data_size}; $cnt++)
205  {
206    $self->{data} .= chr($cnt % 256);
207  }
208
209  # Default exponential backoff rate
210  $self->{retrans} = $def_factor unless exists $self->{retrans};
211  # Default Connection refused behavior
212  $self->{econnrefused} = undef unless exists $self->{econnrefused};
213
214  $self->{seq} = 0;                         # For counting packets
215  if ($self->{proto} eq "udp")              # Open a socket
216  {
217    $self->{proto_num} = eval { (getprotobyname('udp'))[2] } ||
218      croak("Can't udp protocol by name");
219    $self->{port_num} = $self->{port}
220      || (getservbyname('echo', 'udp'))[2]
221      || croak("Can't get udp echo port by name");
222    $self->{fh} = FileHandle->new();
223    socket($self->{fh}, PF_INET, SOCK_DGRAM,
224           $self->{proto_num}) ||
225             croak("udp socket error - $!");
226    $self->_setopts();
227  }
228  elsif ($self->{proto} eq "icmp")
229  {
230    croak("icmp ping requires root privilege") if !_isroot();
231    $self->{proto_num} = eval { (getprotobyname('icmp'))[2] } ||
232      croak("Can't get icmp protocol by name");
233    $self->{pid} = $$ & 0xffff;           # Save lower 16 bits of pid
234    $self->{fh} = FileHandle->new();
235    socket($self->{fh}, PF_INET, SOCK_RAW, $self->{proto_num}) ||
236      croak("icmp socket error - $!");
237    $self->_setopts();
238    if ($self->{'ttl'}) {
239      setsockopt($self->{fh}, IPPROTO_IP, IP_TTL, pack("I*", $self->{'ttl'}))
240        or croak "error configuring ttl to $self->{'ttl'} $!";
241    }
242  }
243  elsif ($self->{proto} eq "icmpv6")
244  {
245    #croak("icmpv6 ping requires root privilege") if !_isroot();
246    croak("Wrong family $self->{family} for icmpv6 protocol")
247      if $self->{family} and $self->{family} != $AF_INET6;
248    $self->{family} = $AF_INET6;
249    $self->{proto_num} = eval { (getprotobyname('ipv6-icmp'))[2] } ||
250      croak("Can't get ipv6-icmp protocol by name"); # 58
251    $self->{pid} = $$ & 0xffff;           # Save lower 16 bits of pid
252    $self->{fh} = FileHandle->new();
253    socket($self->{fh}, $AF_INET6, SOCK_RAW, $self->{proto_num}) ||
254      croak("icmp socket error - $!");
255    $self->_setopts();
256    if ($self->{'gateway'}) {
257      my $g = $self->{gateway};
258      my $ip = $self->_resolv($g)
259        or croak("nonexistent gateway $g");
260      $self->{family} eq $AF_INET6
261        or croak("gateway requires the AF_INET6 family");
262      $ip->{family} eq $AF_INET6
263        or croak("gateway address needs to be IPv6");
264      my $IPV6_NEXTHOP = eval { Socket::IPV6_NEXTHOP() } || 48; # IPV6_3542NEXTHOP, or 21
265      setsockopt($self->{fh}, $IPPROTO_IPV6, $IPV6_NEXTHOP, _pack_sockaddr_in($ip))
266        or croak "error configuring gateway to $g NEXTHOP $!";
267    }
268    if (exists $self->{IPV6_USE_MIN_MTU}) {
269      my $IPV6_USE_MIN_MTU = eval { Socket::IPV6_USE_MIN_MTU() } || 42;
270      setsockopt($self->{fh}, $IPPROTO_IPV6, $IPV6_USE_MIN_MTU,
271                 pack("I*", $self->{'IPV6_USE_MIN_MT'}))
272        or croak "error configuring IPV6_USE_MIN_MT} $!";
273    }
274    if (exists $self->{IPV6_RECVPATHMTU}) {
275      my $IPV6_RECVPATHMTU = eval { Socket::IPV6_RECVPATHMTU() } || 43;
276      setsockopt($self->{fh}, $IPPROTO_IPV6, $IPV6_RECVPATHMTU,
277                 pack("I*", $self->{'RECVPATHMTU'}))
278        or croak "error configuring IPV6_RECVPATHMTU $!";
279    }
280    if ($self->{'tos'}) {
281      my $proto = $self->{family} == AF_INET ? IPPROTO_IP : $IPPROTO_IPV6;
282      setsockopt($self->{fh}, $proto, IP_TOS, pack("I*", $self->{'tos'}))
283        or croak "error configuring tos to $self->{'tos'} $!";
284    }
285    if ($self->{'ttl'}) {
286      my $proto = $self->{family} == AF_INET ? IPPROTO_IP : $IPPROTO_IPV6;
287      setsockopt($self->{fh}, $proto, IP_TTL, pack("I*", $self->{'ttl'}))
288        or croak "error configuring ttl to $self->{'ttl'} $!";
289    }
290  }
291  elsif ($self->{proto} eq "tcp" || $self->{proto} eq "stream")
292  {
293    $self->{proto_num} = eval { (getprotobyname('tcp'))[2] } ||
294      croak("Can't get tcp protocol by name");
295    $self->{port_num} = $self->{port}
296      || (getservbyname('echo', 'tcp'))[2]
297      ||  croak("Can't get tcp echo port by name");
298    $self->{fh} = FileHandle->new();
299  }
300  elsif ($self->{proto} eq "syn")
301  {
302    $self->{proto_num} = eval { (getprotobyname('tcp'))[2] } ||
303      croak("Can't get tcp protocol by name");
304    $self->{port_num} = (getservbyname('echo', 'tcp'))[2] ||
305      croak("Can't get tcp echo port by name");
306    if ($syn_forking) {
307      $self->{fork_rd} = FileHandle->new();
308      $self->{fork_wr} = FileHandle->new();
309      pipe($self->{fork_rd}, $self->{fork_wr});
310      $self->{fh} = FileHandle->new();
311      $self->{good} = {};
312      $self->{bad} = {};
313    } else {
314      $self->{wbits} = "";
315      $self->{bad} = {};
316    }
317    $self->{syn} = {};
318    $self->{stop_time} = 0;
319  }
320
321  return($self);
322}
323
324# Description: Set the local IP address from which pings will be sent.
325# For ICMP, UDP and TCP pings, just saves the address to be used when
326# the socket is opened.  Returns non-zero if successful; croaks on error.
327sub bind
328{
329  my ($self,
330      $local_addr         # Name or IP number of local interface
331      ) = @_;
332  my ($ip,                # Hash of addr (string), addr_in (packed), family
333      $h		  # resolved hash
334      );
335
336  croak("Usage: \$p->bind(\$local_addr)") unless @_ == 2;
337  croak("already bound") if defined($self->{local_addr}) &&
338    ($self->{proto} eq "udp" || $self->{proto} eq "icmp");
339
340  $ip = $self->_resolv($local_addr);
341  carp("nonexistent local address $local_addr") unless defined($ip);
342  $self->{local_addr} = $ip;
343
344  if (($self->{proto} ne "udp") &&
345      ($self->{proto} ne "icmp") &&
346      ($self->{proto} ne "tcp") &&
347      ($self->{proto} ne "syn"))
348  {
349    croak("Unknown protocol \"$self->{proto}\" in bind()");
350  }
351
352  return 1;
353}
354
355# Description: A select() wrapper that compensates for platform
356# peculiarities.
357sub mselect
358{
359    if ($_[3] > 0 and $^O eq 'MSWin32') {
360	# On windows, select() doesn't process the message loop,
361	# but sleep() will, allowing alarm() to interrupt the latter.
362	# So we chop up the timeout into smaller pieces and interleave
363	# select() and sleep() calls.
364	my $t = $_[3];
365	my $gran = 0.5;  # polling granularity in seconds
366	my @args = @_;
367	while (1) {
368	    $gran = $t if $gran > $t;
369	    my $nfound = select($_[0], $_[1], $_[2], $gran);
370	    undef $nfound if $nfound == -1;
371	    $t -= $gran;
372	    return $nfound if $nfound or !defined($nfound) or $t <= 0;
373
374	    sleep(0);
375	    ($_[0], $_[1], $_[2]) = @args;
376	}
377    }
378    else {
379	my $nfound = select($_[0], $_[1], $_[2], $_[3]);
380	undef $nfound if $nfound == -1;
381	return $nfound;
382    }
383}
384
385# Description: Allow UDP source endpoint comparison to be
386#              skipped for those remote interfaces that do
387#              not response from the same endpoint.
388
389sub source_verify
390{
391  my $self = shift;
392  $source_verify = 1 unless defined
393    ($source_verify = ((defined $self) && (ref $self)) ? shift() : $self);
394}
395
396# Description: Set whether or not the connect
397# behavior should enforce remote service
398# availability as well as reachability.
399
400sub service_check
401{
402  my $self = shift;
403  $self->{econnrefused} = 1 unless defined
404    ($self->{econnrefused} = shift());
405}
406
407sub tcp_service_check
408{
409  service_check(@_);
410}
411
412# Description: Set exponential backoff for retransmission.
413# Should be > 1 to retain exponential properties.
414# If set to 0, retransmissions are disabled.
415
416sub retrans
417{
418  my $self = shift;
419  $self->{retrans} = shift;
420}
421
422sub _IsAdminUser {
423  return unless $^O eq 'MSWin32' or $^O eq "cygwin";
424  return unless eval { require Win32 };
425  return unless defined &Win32::IsAdminUser;
426  return Win32::IsAdminUser();
427}
428
429sub _isroot {
430  if (($> and $^O ne 'VMS' and $^O ne 'cygwin')
431    or (($^O eq 'MSWin32' or $^O eq 'cygwin')
432        and !_IsAdminUser())
433    or ($^O eq 'VMS'
434        and (`write sys\$output f\$privilege("SYSPRV")` =~ m/FALSE/))) {
435      return 0;
436  }
437  else {
438    return 1;
439  }
440}
441
442# Description: Sets ipv6 reachability
443# REACHCONF was removed in RFC3542, ping6 -R supports it. requires root.
444
445sub IPV6_REACHCONF
446{
447  my $self = shift;
448  my $on = shift;
449  if ($on) {
450    my $reachconf = eval { Socket::IPV6_REACHCONF() };
451    if (!$reachconf) {
452      carp "IPV6_REACHCONF not supported on this platform";
453      return 0;
454    }
455    if (!_isroot()) {
456      carp "IPV6_REACHCONF requires root permissions";
457      return 0;
458    }
459    $self->{IPV6_REACHCONF} = 1;
460  }
461  else {
462    return $self->{IPV6_REACHCONF};
463  }
464}
465
466# Description: set it on or off.
467
468sub IPV6_USE_MIN_MTU
469{
470  my $self = shift;
471  my $on = shift;
472  if (defined $on) {
473    my $IPV6_USE_MIN_MTU = eval { Socket::IPV6_USE_MIN_MTU() } || 43;
474    #if (!$IPV6_USE_MIN_MTU) {
475    #  carp "IPV6_USE_MIN_MTU not supported on this platform";
476    #  return 0;
477    #}
478    $self->{IPV6_USE_MIN_MTU} = $on ? 1 : 0;
479    setsockopt($self->{fh}, $IPPROTO_IPV6, $IPV6_USE_MIN_MTU,
480               pack("I*", $self->{'IPV6_USE_MIN_MT'}))
481      or croak "error configuring IPV6_USE_MIN_MT} $!";
482  }
483  else {
484    return $self->{IPV6_USE_MIN_MTU};
485  }
486}
487
488# Description: notify an according MTU
489
490sub IPV6_RECVPATHMTU
491{
492  my $self = shift;
493  my $on = shift;
494  if ($on) {
495    my $IPV6_RECVPATHMTU = eval { Socket::IPV6_RECVPATHMTU() } || 43;
496    #if (!$RECVPATHMTU) {
497    #  carp "IPV6_RECVPATHMTU not supported on this platform";
498    #  return 0;
499    #}
500    $self->{IPV6_RECVPATHMTU} = 1;
501    setsockopt($self->{fh}, $IPPROTO_IPV6, $IPV6_RECVPATHMTU,
502               pack("I*", $self->{'IPV6_RECVPATHMTU'}))
503      or croak "error configuring IPV6_RECVPATHMTU} $!";
504  }
505  else {
506    return $self->{IPV6_RECVPATHMTU};
507  }
508}
509
510# Description: allows the module to use milliseconds as returned by
511# the Time::HiRes module
512
513$hires = 1;
514sub hires
515{
516  my $self = shift;
517  $hires = 1 unless defined
518    ($hires = ((defined $self) && (ref $self)) ? shift() : $self);
519}
520
521sub time
522{
523  return $hires ? Time::HiRes::time() : CORE::time();
524}
525
526# Description: Sets or clears the O_NONBLOCK flag on a file handle.
527sub socket_blocking_mode
528{
529  my ($self,
530      $fh,              # the file handle whose flags are to be modified
531      $block) = @_;     # if true then set the blocking
532                        # mode (clear O_NONBLOCK), otherwise
533                        # set the non-blocking mode (set O_NONBLOCK)
534
535  my $flags;
536  if ($^O eq 'MSWin32' || $^O eq 'VMS') {
537      # FIONBIO enables non-blocking sockets on windows and vms.
538      # FIONBIO is (0x80000000|(4<<16)|(ord('f')<<8)|126), as per winsock.h, ioctl.h
539      my $f = 0x8004667e;
540      my $v = pack("L", $block ? 0 : 1);
541      ioctl($fh, $f, $v) or croak("ioctl failed: $!");
542      return;
543  }
544  if ($flags = fcntl($fh, F_GETFL, 0)) {
545    $flags = $block ? ($flags & ~O_NONBLOCK) : ($flags | O_NONBLOCK);
546    if (!fcntl($fh, F_SETFL, $flags)) {
547      croak("fcntl F_SETFL: $!");
548    }
549  } else {
550    croak("fcntl F_GETFL: $!");
551  }
552}
553
554# Description: Ping a host name or IP number with an optional timeout.
555# First lookup the host, and return undef if it is not found.  Otherwise
556# perform the specific ping method based on the protocol.  Return the
557# result of the ping.
558
559sub ping
560{
561  my ($self,
562      $host,              # Name or IP number of host to ping
563      $timeout,           # Seconds after which ping times out
564      $family,            # Address family
565      ) = @_;
566  my ($ip,                # Hash of addr (string), addr_in (packed), family
567      $ret,               # The return value
568      $ping_time,         # When ping began
569      );
570
571  $host = $self->{host} if !defined $host and $self->{host};
572  croak("Usage: \$p->ping([ \$host [, \$timeout [, \$family]]])") if @_ > 4 or !$host;
573  $timeout = $self->{timeout} unless $timeout;
574  croak("Timeout must be greater than 0 seconds") if $timeout <= 0;
575
576  if ($family) {
577    if ($family =~ $qr_family) {
578      if ($family =~ $qr_family4) {
579        $self->{family_local} = AF_INET;
580      } else {
581        $self->{family_local} = $AF_INET6;
582      }
583    } else {
584      croak('Family must be "ipv4" or "ipv6"')
585    }
586  } else {
587    $self->{family_local} = $self->{family};
588  }
589
590  $ip = $self->_resolv($host);
591  return () unless defined($ip);      # Does host exist?
592
593  # Dispatch to the appropriate routine.
594  $ping_time = &time();
595  if ($self->{proto} eq "external") {
596    $ret = $self->ping_external($ip, $timeout);
597  }
598  elsif ($self->{proto} eq "udp") {
599    $ret = $self->ping_udp($ip, $timeout);
600  }
601  elsif ($self->{proto} eq "icmp") {
602    $ret = $self->ping_icmp($ip, $timeout);
603  }
604  elsif ($self->{proto} eq "icmpv6") {
605    $ret = $self->ping_icmpv6($ip, $timeout);
606  }
607  elsif ($self->{proto} eq "tcp") {
608    $ret = $self->ping_tcp($ip, $timeout);
609  }
610  elsif ($self->{proto} eq "stream") {
611    $ret = $self->ping_stream($ip, $timeout);
612  }
613  elsif ($self->{proto} eq "syn") {
614    $ret = $self->ping_syn($host, $ip, $ping_time, $ping_time+$timeout);
615  } else {
616    croak("Unknown protocol \"$self->{proto}\" in ping()");
617  }
618
619  return wantarray ? ($ret, &time() - $ping_time, $self->ntop($ip)) : $ret;
620}
621
622# Uses Net::Ping::External to do an external ping.
623sub ping_external {
624  my ($self,
625      $ip,                # Hash of addr (string), addr_in (packed), family
626      $timeout,           # Seconds after which ping times out
627      $family
628     ) = @_;
629
630  $ip = $self->{host} if !defined $ip and $self->{host};
631  $timeout = $self->{timeout} if !defined $timeout and $self->{timeout};
632  my @addr = exists $ip->{addr_in}
633    ? ('ip' => $ip->{addr_in})
634    : ('host' => $ip->{host});
635
636  eval {
637    local @INC = @INC;
638    pop @INC if $INC[-1] eq '.';
639    require Net::Ping::External;
640  } or croak('Protocol "external" not supported on your system: Net::Ping::External not found');
641  return Net::Ping::External::ping(@addr, timeout => $timeout,
642                                   family => $family);
643}
644
645# h2ph "asm/socket.h"
646# require "asm/socket.ph";
647use constant SO_BINDTODEVICE  => 25;
648use constant ICMP_ECHOREPLY   => 0;   # ICMP packet types
649use constant ICMPv6_ECHOREPLY => 129; # ICMP packet types
650use constant ICMP_UNREACHABLE => 3;   # ICMP packet types
651use constant ICMPv6_UNREACHABLE => 1; # ICMP packet types
652use constant ICMPv6_NI_REPLY => 140;  # ICMP packet types
653use constant ICMP_ECHO        => 8;
654use constant ICMPv6_ECHO      => 128;
655use constant ICMP_TIME_EXCEEDED => 11; # ICMP packet types
656use constant ICMP_PARAMETER_PROBLEM => 12; # ICMP packet types
657use constant ICMP_TIMESTAMP   => 13;
658use constant ICMP_TIMESTAMP_REPLY => 14;
659use constant ICMP_STRUCT      => "C2 n3 A"; # Structure of a minimal ICMP packet
660use constant ICMP_TIMESTAMP_STRUCT => "C2 n3 N3"; # Structure of a minimal timestamp ICMP packet
661use constant SUBCODE          => 0; # No ICMP subcode for ECHO and ECHOREPLY
662use constant ICMP_FLAGS       => 0; # No special flags for send or recv
663use constant ICMP_PORT        => 0; # No port with ICMP
664use constant IP_MTU_DISCOVER  => 10; # linux only
665
666sub message_type
667{
668  my ($self,
669      $type
670      ) = @_;
671
672  croak "Setting message type only supported on 'icmp' protocol"
673    unless $self->{proto} eq 'icmp';
674
675  return $self->{message_type} || 'echo'
676    unless defined($type);
677
678  croak "Supported icmp message type are limited to 'echo' and 'timestamp': '$type' not supported"
679    unless $type =~ /^echo|timestamp$/i;
680
681  $self->{message_type} = lc($type);
682}
683
684sub ping_icmp
685{
686  my ($self,
687      $ip,                # Hash of addr (string), addr_in (packed), family
688      $timeout            # Seconds after which ping times out
689      ) = @_;
690
691  my ($saddr,             # sockaddr_in with port and ip
692      $checksum,          # Checksum of ICMP packet
693      $msg,               # ICMP packet to send
694      $len_msg,           # Length of $msg
695      $rbits,             # Read bits, filehandles for reading
696      $nfound,            # Number of ready filehandles found
697      $finish_time,       # Time ping should be finished
698      $done,              # set to 1 when we are done
699      $ret,               # Return value
700      $recv_msg,          # Received message including IP header
701      $recv_msg_len,      # Length of recevied message, less any additional data
702      $from_saddr,        # sockaddr_in of sender
703      $from_port,         # Port packet was sent from
704      $from_ip,           # Packed IP of sender
705      $timestamp_msg,     # ICMP timestamp message type
706      $from_type,         # ICMP type
707      $from_subcode,      # ICMP subcode
708      $from_chk,          # ICMP packet checksum
709      $from_pid,          # ICMP packet id
710      $from_seq,          # ICMP packet sequence
711      $from_msg           # ICMP message
712      );
713
714  $ip = $self->{host} if !defined $ip and $self->{host};
715  $timeout = $self->{timeout} if !defined $timeout and $self->{timeout};
716  $timestamp_msg = $self->{message_type} && $self->{message_type} eq 'timestamp' ? 1 : 0;
717
718  socket($self->{fh}, $ip->{family}, SOCK_RAW, $self->{proto_num}) ||
719    croak("icmp socket error - $!");
720
721  if (defined $self->{local_addr} &&
722      !CORE::bind($self->{fh}, _pack_sockaddr_in(0, $self->{local_addr}))) {
723    croak("icmp bind error - $!");
724  }
725  $self->_setopts();
726
727  $self->{seq} = ($self->{seq} + 1) % 65536; # Increment sequence
728  $checksum = 0;                          # No checksum for starters
729  if ($ip->{family} == AF_INET) {
730    if ($timestamp_msg) {
731      $msg = pack(ICMP_TIMESTAMP_STRUCT, ICMP_TIMESTAMP, SUBCODE,
732                  $checksum, $self->{pid}, $self->{seq}, 0, 0, 0);
733    } else {
734      $msg = pack(ICMP_STRUCT . $self->{data_size}, ICMP_ECHO, SUBCODE,
735                  $checksum, $self->{pid}, $self->{seq}, $self->{data});
736    }
737  } else {
738                                          # how to get SRC
739    my $pseudo_header = pack('a16a16Nnn', $ip->{addr_in}, $ip->{addr_in}, 8+length($self->{data}), 0, 0x003a);
740    $msg = pack(ICMP_STRUCT . $self->{data_size}, ICMPv6_ECHO, SUBCODE,
741                $checksum, $self->{pid}, $self->{seq}, $self->{data});
742    $msg = $pseudo_header.$msg
743  }
744  $checksum = Net::Ping->checksum($msg);
745  if ($ip->{family} == AF_INET) {
746    if ($timestamp_msg) {
747      $msg = pack(ICMP_TIMESTAMP_STRUCT, ICMP_TIMESTAMP, SUBCODE,
748                  $checksum, $self->{pid}, $self->{seq}, 0, 0, 0);
749    } else {
750      $msg = pack(ICMP_STRUCT . $self->{data_size}, ICMP_ECHO, SUBCODE,
751                  $checksum, $self->{pid}, $self->{seq}, $self->{data});
752    }
753  } else {
754    $msg = pack(ICMP_STRUCT . $self->{data_size}, ICMPv6_ECHO, SUBCODE,
755                $checksum, $self->{pid}, $self->{seq}, $self->{data});
756  }
757  $len_msg = length($msg);
758  $saddr = _pack_sockaddr_in(ICMP_PORT, $ip);
759  $self->{from_ip} = undef;
760  $self->{from_type} = undef;
761  $self->{from_subcode} = undef;
762  send($self->{fh}, $msg, ICMP_FLAGS, $saddr); # Send the message
763
764  $rbits = "";
765  vec($rbits, $self->{fh}->fileno(), 1) = 1;
766  $ret = 0;
767  $done = 0;
768  $finish_time = &time() + $timeout;      # Must be done by this time
769  while (!$done && $timeout > 0)          # Keep trying if we have time
770  {
771    $nfound = mselect((my $rout=$rbits), undef, undef, $timeout); # Wait for packet
772    $timeout = $finish_time - &time();    # Get remaining time
773    if (!defined($nfound))                # Hmm, a strange error
774    {
775      $ret = undef;
776      $done = 1;
777    }
778    elsif ($nfound)                     # Got a packet from somewhere
779    {
780      $recv_msg = "";
781      $from_pid = -1;
782      $from_seq = -1;
783      $from_saddr = recv($self->{fh}, $recv_msg, 1500, ICMP_FLAGS);
784      $recv_msg_len = length($recv_msg) - length($self->{data});
785      ($from_port, $from_ip) = _unpack_sockaddr_in($from_saddr, $ip->{family});
786      # ICMP echo includes the header and ICMPv6 doesn't.
787      # IPv4 length($recv_msg) is 28 (20 header + 8 payload)
788      # while IPv6 length is only 8 (sans header).
789      my $off = ($ip->{family} == AF_INET) ? 20 : 0; # payload offset
790      ($from_type, $from_subcode) = unpack("C2", substr($recv_msg, $off, 2));
791      if ($from_type == ICMP_TIMESTAMP_REPLY) {
792        ($from_pid, $from_seq) = unpack("n3", substr($recv_msg, $off + 4, 4))
793          if length $recv_msg >= $off + 8;
794      } elsif ($from_type == ICMP_ECHOREPLY || $from_type == ICMPv6_ECHOREPLY) {
795        #warn "ICMP_ECHOREPLY: ", $ip->{family}, " ",$recv_msg, ":", length($recv_msg);
796        ($from_pid, $from_seq) = unpack("n2", substr($recv_msg, $off + 4, 4))
797          if $recv_msg_len == $off + 8;
798      } elsif ($from_type == ICMPv6_NI_REPLY) {
799        ($from_pid, $from_seq) = unpack("n2", substr($recv_msg, 4, 4))
800          if ($ip->{family} == $AF_INET6 && length $recv_msg == 8);
801      } else {
802        #warn "ICMP: ", $from_type, " ",$ip->{family}, " ",$recv_msg, ":", length($recv_msg);
803        ($from_pid, $from_seq) = unpack("n2", substr($recv_msg, $off + 32, 4))
804          if length $recv_msg >= $off + 36;
805      }
806      $self->{from_ip} = $from_ip;
807      $self->{from_type} = $from_type;
808      $self->{from_subcode} = $from_subcode;
809      next if ($from_pid != $self->{pid});
810      next if ($from_seq != $self->{seq});
811      if (! $source_verify || ($self->ntop($from_ip) eq $self->ntop($ip))) { # Does the packet check out?
812        if (!$timestamp_msg && (($from_type == ICMP_ECHOREPLY) || ($from_type == ICMPv6_ECHOREPLY))) {
813          $ret = 1;
814          $done = 1;
815        } elsif ($timestamp_msg && $from_type == ICMP_TIMESTAMP_REPLY) {
816          $ret = 1;
817          $done = 1;
818        } elsif (($from_type == ICMP_UNREACHABLE) || ($from_type == ICMPv6_UNREACHABLE)) {
819          $done = 1;
820        } elsif ($from_type == ICMP_TIME_EXCEEDED) {
821          $ret = 0;
822          $done = 1;
823        }
824      }
825    } else {     # Oops, timed out
826      $done = 1;
827    }
828  }
829  return $ret;
830}
831
832sub ping_icmpv6
833{
834  shift->ping_icmp(@_);
835}
836
837sub icmp_result {
838  my ($self) = @_;
839  my $addr = $self->{from_ip} || "";
840  $addr = "\0\0\0\0" unless 4 == length $addr;
841  return ($self->ntop($addr),($self->{from_type} || 0), ($self->{from_subcode} || 0));
842}
843
844# Description:  Do a checksum on the message.  Basically sum all of
845# the short words and fold the high order bits into the low order bits.
846
847sub checksum
848{
849  my ($class,
850      $msg            # The message to checksum
851      ) = @_;
852  my ($len_msg,       # Length of the message
853      $num_short,     # The number of short words in the message
854      $short,         # One short word
855      $chk            # The checksum
856      );
857
858  $len_msg = length($msg);
859  $num_short = int($len_msg / 2);
860  $chk = 0;
861  foreach $short (unpack("n$num_short", $msg))
862  {
863    $chk += $short;
864  }                                           # Add the odd byte in
865  $chk += (unpack("C", substr($msg, $len_msg - 1, 1)) << 8) if $len_msg % 2;
866  $chk = ($chk >> 16) + ($chk & 0xffff);      # Fold high into low
867  return(~(($chk >> 16) + $chk) & 0xffff);    # Again and complement
868}
869
870
871# Description:  Perform a tcp echo ping.  Since a tcp connection is
872# host specific, we have to open and close each connection here.  We
873# can't just leave a socket open.  Because of the robust nature of
874# tcp, it will take a while before it gives up trying to establish a
875# connection.  Therefore, we use select() on a non-blocking socket to
876# check against our timeout.  No data bytes are actually
877# sent since the successful establishment of a connection is proof
878# enough of the reachability of the remote host.  Also, tcp is
879# expensive and doesn't need our help to add to the overhead.
880
881sub ping_tcp
882{
883  my ($self,
884      $ip,                # Hash of addr (string), addr_in (packed), family
885      $timeout            # Seconds after which ping times out
886      ) = @_;
887  my ($ret                # The return value
888      );
889
890  $ip = $self->{host} if !defined $ip and $self->{host};
891  $timeout = $self->{timeout} if !defined $timeout and $self->{timeout};
892
893  $! = 0;
894  $ret = $self -> tcp_connect( $ip, $timeout);
895  if (!$self->{econnrefused} &&
896      $! == ECONNREFUSED) {
897    $ret = 1;  # "Connection refused" means reachable
898  }
899  $self->{fh}->close();
900  return $ret;
901}
902
903sub tcp_connect
904{
905  my ($self,
906      $ip,                # Hash of addr (string), addr_in (packed), family
907      $timeout            # Seconds after which connect times out
908      ) = @_;
909  my ($saddr);            # Packed IP and Port
910
911  $ip = $self->{host} if !defined $ip and $self->{host};
912  $timeout = $self->{timeout} if !defined $timeout and $self->{timeout};
913
914  $saddr = _pack_sockaddr_in($self->{port_num}, $ip);
915
916  my $ret = 0;            # Default to unreachable
917
918  my $do_socket = sub {
919    socket($self->{fh}, $ip->{family}, SOCK_STREAM, $self->{proto_num}) ||
920      croak("tcp socket error - $!");
921    if (defined $self->{local_addr} &&
922        !CORE::bind($self->{fh}, _pack_sockaddr_in(0, $self->{local_addr}))) {
923      croak("tcp bind error - $!");
924    }
925    $self->_setopts();
926  };
927  my $do_connect = sub {
928    $self->{ip} = $ip->{addr_in};
929    # ECONNREFUSED is 10061 on MSWin32. If we pass it as child error through $?,
930    # we'll get (10061 & 255) = 77, so we cannot check it in the parent process.
931    return ($ret = connect($self->{fh}, $saddr) || ($! == ECONNREFUSED && !$self->{econnrefused}));
932  };
933  my $do_connect_nb = sub {
934    # Set O_NONBLOCK property on filehandle
935    $self->socket_blocking_mode($self->{fh}, 0);
936
937    # start the connection attempt
938    if (!connect($self->{fh}, $saddr)) {
939      if ($! == ECONNREFUSED) {
940        $ret = 1 unless $self->{econnrefused};
941      } elsif ($! != EINPROGRESS && ($^O ne 'MSWin32' || $! != EWOULDBLOCK)) {
942        # EINPROGRESS is the expected error code after a connect()
943        # on a non-blocking socket.  But if the kernel immediately
944        # determined that this connect() will never work,
945        # Simply respond with "unreachable" status.
946        # (This can occur on some platforms with errno
947        # EHOSTUNREACH or ENETUNREACH.)
948        return 0;
949      } else {
950        # Got the expected EINPROGRESS.
951        # Just wait for connection completion...
952        my ($wbits, $wout, $wexc);
953        $wout = $wexc = $wbits = "";
954        vec($wbits, $self->{fh}->fileno, 1) = 1;
955
956        my $nfound = mselect(undef,
957			    ($wout = $wbits),
958			    ($^O eq 'MSWin32' ? ($wexc = $wbits) : undef),
959			    $timeout);
960        warn("select: $!") unless defined $nfound;
961
962        if ($nfound && vec($wout, $self->{fh}->fileno, 1)) {
963          # the socket is ready for writing so the connection
964          # attempt completed. test whether the connection
965          # attempt was successful or not
966
967          if (getpeername($self->{fh})) {
968            # Connection established to remote host
969            $ret = 1;
970          } else {
971            # TCP ACK will never come from this host
972            # because there was an error connecting.
973
974            # This should set $! to the correct error.
975            my $char;
976            sysread($self->{fh},$char,1);
977            $! = ECONNREFUSED if ($! == EAGAIN && $^O =~ /cygwin/i);
978
979            $ret = 1 if (!$self->{econnrefused}
980                         && $! == ECONNREFUSED);
981          }
982        } else {
983          # the connection attempt timed out (or there were connect
984	  # errors on Windows)
985	  if ($^O =~ 'MSWin32') {
986	      # If the connect will fail on a non-blocking socket,
987	      # winsock reports ECONNREFUSED as an exception, and we
988	      # need to fetch the socket-level error code via getsockopt()
989	      # instead of using the thread-level error code that is in $!.
990	      if ($nfound && vec($wexc, $self->{fh}->fileno, 1)) {
991		  $! = unpack("i", getsockopt($self->{fh}, SOL_SOCKET,
992			                      SO_ERROR));
993	      }
994	  }
995        }
996      }
997    } else {
998      # Connection established to remote host
999      $ret = 1;
1000    }
1001
1002    # Unset O_NONBLOCK property on filehandle
1003    $self->socket_blocking_mode($self->{fh}, 1);
1004    $self->{ip} = $ip->{addr_in};
1005    return $ret;
1006  };
1007
1008  if ($syn_forking) {
1009    # Buggy Winsock API doesn't allow nonblocking connect.
1010    # Hence, if our OS is Windows, we need to create a separate
1011    # process to do the blocking connect attempt.
1012    # XXX Above comments are not true at least for Win2K, where
1013    # nonblocking connect works.
1014
1015    $| = 1; # Clear buffer prior to fork to prevent duplicate flushing.
1016    $self->{'tcp_chld'} = fork;
1017    if (!$self->{'tcp_chld'}) {
1018      if (!defined $self->{'tcp_chld'}) {
1019        # Fork did not work
1020        warn "Fork error: $!";
1021        return 0;
1022      }
1023      &{ $do_socket }();
1024
1025      # Try a slow blocking connect() call
1026      # and report the status to the parent.
1027      if ( &{ $do_connect }() ) {
1028        $self->{fh}->close();
1029        # No error
1030        exit 0;
1031      } else {
1032        # Pass the error status to the parent
1033        # Make sure that $! <= 255
1034        exit($! <= 255 ? $! : 255);
1035      }
1036    }
1037
1038    &{ $do_socket }();
1039
1040    my $patience = &time() + $timeout;
1041
1042    my ($child, $child_errno);
1043    $? = 0; $child_errno = 0;
1044    # Wait up to the timeout
1045    # And clean off the zombie
1046    do {
1047      $child = waitpid($self->{'tcp_chld'}, &WNOHANG());
1048      $child_errno = $? >> 8;
1049      select(undef, undef, undef, 0.1);
1050    } while &time() < $patience && $child != $self->{'tcp_chld'};
1051
1052    if ($child == $self->{'tcp_chld'}) {
1053      if ($self->{proto} eq "stream") {
1054        # We need the socket connected here, in parent
1055        # Should be safe to connect because the child finished
1056        # within the timeout
1057        &{ $do_connect }();
1058      }
1059      # $ret cannot be set by the child process
1060      $ret = !$child_errno;
1061    } else {
1062      # Time must have run out.
1063      # Put that choking client out of its misery
1064      kill "KILL", $self->{'tcp_chld'};
1065      # Clean off the zombie
1066      waitpid($self->{'tcp_chld'}, 0);
1067      $ret = 0;
1068    }
1069    delete $self->{'tcp_chld'};
1070    $! = $child_errno;
1071  } else {
1072    # Otherwise don't waste the resources to fork
1073
1074    &{ $do_socket }();
1075
1076    &{ $do_connect_nb }();
1077  }
1078
1079  return $ret;
1080}
1081
1082sub DESTROY {
1083  my $self = shift;
1084  if ($self->{'proto'} && ($self->{'proto'} eq 'tcp') && $self->{'tcp_chld'}) {
1085    # Put that choking client out of its misery
1086    kill "KILL", $self->{'tcp_chld'};
1087    # Clean off the zombie
1088    waitpid($self->{'tcp_chld'}, 0);
1089  }
1090}
1091
1092# This writes the given string to the socket and then reads it
1093# back.  It returns 1 on success, 0 on failure.
1094sub tcp_echo
1095{
1096  my ($self, $timeout, $pingstring) = @_;
1097
1098  $timeout = $self->{timeout} if !defined $timeout and $self->{timeout};
1099  $pingstring = $self->{pingstring} if !defined $pingstring and $self->{pingstring};
1100
1101  my $ret = undef;
1102  my $time = &time();
1103  my $wrstr = $pingstring;
1104  my $rdstr = "";
1105
1106  eval <<'EOM';
1107    do {
1108      my $rin = "";
1109      vec($rin, $self->{fh}->fileno(), 1) = 1;
1110
1111      my $rout = undef;
1112      if($wrstr) {
1113        $rout = "";
1114        vec($rout, $self->{fh}->fileno(), 1) = 1;
1115      }
1116
1117      if(mselect($rin, $rout, undef, ($time + $timeout) - &time())) {
1118
1119        if($rout && vec($rout,$self->{fh}->fileno(),1)) {
1120          my $num = syswrite($self->{fh}, $wrstr, length $wrstr);
1121          if($num) {
1122            # If it was a partial write, update and try again.
1123            $wrstr = substr($wrstr,$num);
1124          } else {
1125            # There was an error.
1126            $ret = 0;
1127          }
1128        }
1129
1130        if(vec($rin,$self->{fh}->fileno(),1)) {
1131          my $reply;
1132          if(sysread($self->{fh},$reply,length($pingstring)-length($rdstr))) {
1133            $rdstr .= $reply;
1134            $ret = 1 if $rdstr eq $pingstring;
1135          } else {
1136            # There was an error.
1137            $ret = 0;
1138          }
1139        }
1140
1141      }
1142    } until &time() > ($time + $timeout) || defined($ret);
1143EOM
1144
1145  return $ret;
1146}
1147
1148# Description: Perform a stream ping.  If the tcp connection isn't
1149# already open, it opens it.  It then sends some data and waits for
1150# a reply.  It leaves the stream open on exit.
1151
1152sub ping_stream
1153{
1154  my ($self,
1155      $ip,                # Hash of addr (string), addr_in (packed), family
1156      $timeout            # Seconds after which ping times out
1157      ) = @_;
1158
1159  # Open the stream if it's not already open
1160  if(!defined $self->{fh}->fileno()) {
1161    $self->tcp_connect($ip, $timeout) or return 0;
1162  }
1163
1164  croak "tried to switch servers while stream pinging"
1165    if $self->{ip} ne $ip->{addr_in};
1166
1167  return $self->tcp_echo($timeout, $pingstring);
1168}
1169
1170# Description: opens the stream.  You would do this if you want to
1171# separate the overhead of opening the stream from the first ping.
1172
1173sub open
1174{
1175  my ($self,
1176      $host,              # Host or IP address
1177      $timeout,           # Seconds after which open times out
1178      $family
1179      ) = @_;
1180  my $ip;                 # Hash of addr (string), addr_in (packed), family
1181  $host = $self->{host} unless defined $host;
1182
1183  if ($family) {
1184    if ($family =~ $qr_family) {
1185      if ($family =~ $qr_family4) {
1186        $self->{family_local} = AF_INET;
1187      } else {
1188        $self->{family_local} = $AF_INET6;
1189      }
1190    } else {
1191      croak('Family must be "ipv4" or "ipv6"')
1192    }
1193  } else {
1194    $self->{family_local} = $self->{family};
1195  }
1196
1197  $timeout = $self->{timeout} unless $timeout;
1198  $ip = $self->_resolv($host);
1199
1200  if ($self->{proto} eq "stream") {
1201    if (defined($self->{fh}->fileno())) {
1202      croak("socket is already open");
1203    } else {
1204      return () unless $ip;
1205      $self->tcp_connect($ip, $timeout);
1206    }
1207  }
1208}
1209
1210sub _dontfrag {
1211  my $self = shift;
1212  # bsd solaris
1213  my $IP_DONTFRAG = eval { Socket::IP_DONTFRAG() };
1214  if ($IP_DONTFRAG) {
1215    my $i = 1;
1216    setsockopt($self->{fh}, IPPROTO_IP, $IP_DONTFRAG, pack("I*", $i))
1217      or croak "error configuring IP_DONTFRAG $!";
1218    # Linux needs more: Path MTU Discovery as defined in RFC 1191
1219    # For non SOCK_STREAM sockets it is the user's responsibility to packetize
1220    # the data in MTU sized chunks and to do the retransmits if necessary.
1221    # The kernel will reject packets that are bigger than the known path
1222    # MTU if this flag is set (with EMSGSIZE).
1223    if ($^O eq 'linux') {
1224      my $i = 2; # IP_PMTUDISC_DO
1225      setsockopt($self->{fh}, IPPROTO_IP, IP_MTU_DISCOVER, pack("I*", $i))
1226        or croak "error configuring IP_MTU_DISCOVER $!";
1227    }
1228  }
1229}
1230
1231# SO_BINDTODEVICE + IP_TOS
1232sub _setopts {
1233  my $self = shift;
1234  if ($self->{'device'}) {
1235    setsockopt($self->{fh}, SOL_SOCKET, SO_BINDTODEVICE, pack("Z*", $self->{'device'}))
1236      or croak "error binding to device $self->{'device'} $!";
1237  }
1238  if ($self->{'tos'}) { # need to re-apply ToS (RT #6706)
1239    setsockopt($self->{fh}, IPPROTO_IP, IP_TOS, pack("I*", $self->{'tos'}))
1240      or croak "error applying tos to $self->{'tos'} $!";
1241  }
1242  if ($self->{'dontfrag'}) {
1243    $self->_dontfrag;
1244  }
1245}
1246
1247
1248# Description:  Perform a udp echo ping.  Construct a message of
1249# at least the one-byte sequence number and any additional data bytes.
1250# Send the message out and wait for a message to come back.  If we
1251# get a message, make sure all of its parts match.  If they do, we are
1252# done.  Otherwise go back and wait for the message until we run out
1253# of time.  Return the result of our efforts.
1254
1255use constant UDP_FLAGS => 0; # Nothing special on send or recv
1256sub ping_udp
1257{
1258  my ($self,
1259      $ip,                # Hash of addr (string), addr_in (packed), family
1260      $timeout            # Seconds after which ping times out
1261      ) = @_;
1262
1263  my ($saddr,             # sockaddr_in with port and ip
1264      $ret,               # The return value
1265      $msg,               # Message to be echoed
1266      $finish_time,       # Time ping should be finished
1267      $flush,             # Whether socket needs to be disconnected
1268      $connect,           # Whether socket needs to be connected
1269      $done,              # Set to 1 when we are done pinging
1270      $rbits,             # Read bits, filehandles for reading
1271      $nfound,            # Number of ready filehandles found
1272      $from_saddr,        # sockaddr_in of sender
1273      $from_msg,          # Characters echoed by $host
1274      $from_port,         # Port message was echoed from
1275      $from_ip            # Packed IP number of sender
1276      );
1277
1278  $saddr = _pack_sockaddr_in($self->{port_num}, $ip);
1279  $self->{seq} = ($self->{seq} + 1) % 256;    # Increment sequence
1280  $msg = chr($self->{seq}) . $self->{data};   # Add data if any
1281
1282  socket($self->{fh}, $ip->{family}, SOCK_DGRAM,
1283         $self->{proto_num}) ||
1284           croak("udp socket error - $!");
1285
1286  if (defined $self->{local_addr} &&
1287      !CORE::bind($self->{fh}, _pack_sockaddr_in(0, $self->{local_addr}))) {
1288    croak("udp bind error - $!");
1289  }
1290
1291  $self->_setopts();
1292
1293  if ($self->{connected}) {
1294    if ($self->{connected} ne $saddr) {
1295      # Still connected to wrong destination.
1296      # Need to flush out the old one.
1297      $flush = 1;
1298    }
1299  } else {
1300    # Not connected yet.
1301    # Need to connect() before send()
1302    $connect = 1;
1303  }
1304
1305  # Have to connect() and send() instead of sendto()
1306  # in order to pick up on the ECONNREFUSED setting
1307  # from recv() or double send() errno as utilized in
1308  # the concept by rdw @ perlmonks.  See:
1309  # http://perlmonks.thepen.com/42898.html
1310  if ($flush) {
1311    # Need to socket() again to flush the descriptor
1312    # This will disconnect from the old saddr.
1313    socket($self->{fh}, $ip->{family}, SOCK_DGRAM,
1314           $self->{proto_num});
1315    $self->_setopts();
1316  }
1317  # Connect the socket if it isn't already connected
1318  # to the right destination.
1319  if ($flush || $connect) {
1320    connect($self->{fh}, $saddr);               # Tie destination to socket
1321    $self->{connected} = $saddr;
1322  }
1323  send($self->{fh}, $msg, UDP_FLAGS);           # Send it
1324
1325  $rbits = "";
1326  vec($rbits, $self->{fh}->fileno(), 1) = 1;
1327  $ret = 0;                   # Default to unreachable
1328  $done = 0;
1329  my $retrans = 0.01;
1330  my $factor = $self->{retrans};
1331  $finish_time = &time() + $timeout;       # Ping needs to be done by then
1332  while (!$done && $timeout > 0)
1333  {
1334    if ($factor > 1)
1335    {
1336      $timeout = $retrans if $timeout > $retrans;
1337      $retrans*= $factor; # Exponential backoff
1338    }
1339    $nfound  = mselect((my $rout=$rbits), undef, undef, $timeout); # Wait for response
1340    my $why = $!;
1341    $timeout = $finish_time - &time();   # Get remaining time
1342
1343    if (!defined($nfound))  # Hmm, a strange error
1344    {
1345      $ret = undef;
1346      $done = 1;
1347    }
1348    elsif ($nfound)         # A packet is waiting
1349    {
1350      $from_msg = "";
1351      $from_saddr = recv($self->{fh}, $from_msg, 1500, UDP_FLAGS);
1352      if (!$from_saddr) {
1353        # For example an unreachable host will make recv() fail.
1354        if (!$self->{econnrefused} &&
1355            ($! == ECONNREFUSED ||
1356             $! == ECONNRESET)) {
1357          # "Connection refused" means reachable
1358          # Good, continue
1359          $ret = 1;
1360        }
1361        $done = 1;
1362      } else {
1363        ($from_port, $from_ip) = _unpack_sockaddr_in($from_saddr, $ip->{family});
1364        my $addr_in = ref($ip) eq "HASH" ? $ip->{addr_in} : $ip;
1365        if (!$source_verify ||
1366            (($from_ip eq $addr_in) &&        # Does the packet check out?
1367             ($from_port == $self->{port_num}) &&
1368             ($from_msg eq $msg)))
1369        {
1370          $ret = 1;       # It's a winner
1371          $done = 1;
1372        }
1373      }
1374    }
1375    elsif ($timeout <= 0)              # Oops, timed out
1376    {
1377      $done = 1;
1378    }
1379    else
1380    {
1381      # Send another in case the last one dropped
1382      if (send($self->{fh}, $msg, UDP_FLAGS)) {
1383        # Another send worked?  The previous udp packet
1384        # must have gotten lost or is still in transit.
1385        # Hopefully this new packet will arrive safely.
1386      } else {
1387        if (!$self->{econnrefused} &&
1388            $! == ECONNREFUSED) {
1389          # "Connection refused" means reachable
1390          # Good, continue
1391          $ret = 1;
1392        }
1393        $done = 1;
1394      }
1395    }
1396  }
1397  return $ret;
1398}
1399
1400# Description: Send a TCP SYN packet to host specified.
1401sub ping_syn
1402{
1403  my $self = shift;
1404  my $host = shift;
1405  my $ip = shift;
1406  my $start_time = shift;
1407  my $stop_time = shift;
1408
1409  if ($syn_forking) {
1410    return $self->ping_syn_fork($host, $ip, $start_time, $stop_time);
1411  }
1412
1413  my $fh = FileHandle->new();
1414  my $saddr = _pack_sockaddr_in($self->{port_num}, $ip);
1415
1416  # Create TCP socket
1417  if (!socket ($fh, $ip->{family}, SOCK_STREAM, $self->{proto_num})) {
1418    croak("tcp socket error - $!");
1419  }
1420
1421  if (defined $self->{local_addr} &&
1422      !CORE::bind($fh, _pack_sockaddr_in(0, $self->{local_addr}))) {
1423    croak("tcp bind error - $!");
1424  }
1425
1426  $self->_setopts();
1427  # Set O_NONBLOCK property on filehandle
1428  $self->socket_blocking_mode($fh, 0);
1429
1430  # Attempt the non-blocking connect
1431  # by just sending the TCP SYN packet
1432  if (connect($fh, $saddr)) {
1433    # Non-blocking, yet still connected?
1434    # Must have connected very quickly,
1435    # or else it wasn't very non-blocking.
1436    #warn "WARNING: Nonblocking connect connected anyway? ($^O)";
1437  } else {
1438    # Error occurred connecting.
1439    if ($! == EINPROGRESS || ($^O eq 'MSWin32' && $! == EWOULDBLOCK)) {
1440      # The connection is just still in progress.
1441      # This is the expected condition.
1442    } else {
1443      # Just save the error and continue on.
1444      # The ack() can check the status later.
1445      $self->{bad}->{$host} = $!;
1446    }
1447  }
1448
1449  my $entry = [ $host, $ip, $fh, $start_time, $stop_time, $self->{port_num} ];
1450  $self->{syn}->{$fh->fileno} = $entry;
1451  if ($self->{stop_time} < $stop_time) {
1452    $self->{stop_time} = $stop_time;
1453  }
1454  vec($self->{wbits}, $fh->fileno, 1) = 1;
1455
1456  return 1;
1457}
1458
1459sub ping_syn_fork {
1460  my ($self, $host, $ip, $start_time, $stop_time) = @_;
1461
1462  # Buggy Winsock API doesn't allow nonblocking connect.
1463  # Hence, if our OS is Windows, we need to create a separate
1464  # process to do the blocking connect attempt.
1465  my $pid = fork();
1466  if (defined $pid) {
1467    if ($pid) {
1468      # Parent process
1469      my $entry = [ $host, $ip, $pid, $start_time, $stop_time ];
1470      $self->{syn}->{$pid} = $entry;
1471      if ($self->{stop_time} < $stop_time) {
1472        $self->{stop_time} = $stop_time;
1473      }
1474    } else {
1475      # Child process
1476      my $saddr = _pack_sockaddr_in($self->{port_num}, $ip);
1477
1478      # Create TCP socket
1479      if (!socket ($self->{fh}, $ip->{family}, SOCK_STREAM, $self->{proto_num})) {
1480        croak("tcp socket error - $!");
1481      }
1482
1483      if (defined $self->{local_addr} &&
1484          !CORE::bind($self->{fh}, _pack_sockaddr_in(0, $self->{local_addr}))) {
1485        croak("tcp bind error - $!");
1486      }
1487
1488      $self->_setopts();
1489
1490      $!=0;
1491      # Try to connect (could take a long time)
1492      connect($self->{fh}, $saddr);
1493      # Notify parent of connect error status
1494      my $err = $!+0;
1495      my $wrstr = "$$ $err";
1496      # Force to 16 chars including \n
1497      $wrstr .= " "x(15 - length $wrstr). "\n";
1498      syswrite($self->{fork_wr}, $wrstr, length $wrstr);
1499      exit;
1500    }
1501  } else {
1502    # fork() failed?
1503    die "fork: $!";
1504  }
1505  return 1;
1506}
1507
1508# Description: Wait for TCP ACK from host specified
1509# from ping_syn above.  If no host is specified, wait
1510# for TCP ACK from any of the hosts in the SYN queue.
1511sub ack
1512{
1513  my $self = shift;
1514
1515  if ($self->{proto} eq "syn") {
1516    if ($syn_forking) {
1517      my @answer = $self->ack_unfork(shift);
1518      return wantarray ? @answer : $answer[0];
1519    }
1520    my $wbits = "";
1521    my $stop_time = 0;
1522    if (my $host = shift or $self->{host}) {
1523      # Host passed as arg or as option to new
1524      $host = $self->{host} unless defined $host;
1525      if (exists $self->{bad}->{$host}) {
1526        if (!$self->{econnrefused} &&
1527            $self->{bad}->{ $host } &&
1528            (($! = ECONNREFUSED)>0) &&
1529            $self->{bad}->{ $host } eq "$!") {
1530          # "Connection refused" means reachable
1531          # Good, continue
1532        } else {
1533          # ECONNREFUSED means no good
1534          return ();
1535        }
1536      }
1537      my $host_fd = undef;
1538      foreach my $fd (keys %{ $self->{syn} }) {
1539        my $entry = $self->{syn}->{$fd};
1540        if ($entry->[0] eq $host) {
1541          $host_fd = $fd;
1542          $stop_time = $entry->[4]
1543            || croak("Corrupted SYN entry for [$host]");
1544          last;
1545        }
1546      }
1547      croak("ack called on [$host] without calling ping first!")
1548        unless defined $host_fd;
1549      vec($wbits, $host_fd, 1) = 1;
1550    } else {
1551      # No $host passed so scan all hosts
1552      # Use the latest stop_time
1553      $stop_time = $self->{stop_time};
1554      # Use all the bits
1555      $wbits = $self->{wbits};
1556    }
1557
1558    while ($wbits !~ /^\0*\z/) {
1559      my $timeout = $stop_time - &time();
1560      # Force a minimum of 10 ms timeout.
1561      $timeout = 0.01 if $timeout <= 0.01;
1562
1563      my $winner_fd = undef;
1564      my $wout = $wbits;
1565      my $fd = 0;
1566      # Do "bad" fds from $wbits first
1567      while ($wout !~ /^\0*\z/) {
1568        if (vec($wout, $fd, 1)) {
1569          # Wipe it from future scanning.
1570          vec($wout, $fd, 1) = 0;
1571          if (my $entry = $self->{syn}->{$fd}) {
1572            if ($self->{bad}->{ $entry->[0] }) {
1573              $winner_fd = $fd;
1574              last;
1575            }
1576          }
1577        }
1578        $fd++;
1579      }
1580
1581      if (defined($winner_fd) or my $nfound = mselect(undef, ($wout=$wbits), undef, $timeout)) {
1582        if (defined $winner_fd) {
1583          $fd = $winner_fd;
1584        } else {
1585          # Done waiting for one of the ACKs
1586          $fd = 0;
1587          # Determine which one
1588          while ($wout !~ /^\0*\z/ &&
1589                 !vec($wout, $fd, 1)) {
1590            $fd++;
1591          }
1592        }
1593        if (my $entry = $self->{syn}->{$fd}) {
1594          # Wipe it from future scanning.
1595          delete $self->{syn}->{$fd};
1596          vec($self->{wbits}, $fd, 1) = 0;
1597          vec($wbits, $fd, 1) = 0;
1598          if (!$self->{econnrefused} &&
1599              $self->{bad}->{ $entry->[0] } &&
1600              (($! = ECONNREFUSED)>0) &&
1601              $self->{bad}->{ $entry->[0] } eq "$!") {
1602            # "Connection refused" means reachable
1603            # Good, continue
1604          } elsif (getpeername($entry->[2])) {
1605            # Connection established to remote host
1606            # Good, continue
1607          } else {
1608            # TCP ACK will never come from this host
1609            # because there was an error connecting.
1610
1611            # This should set $! to the correct error.
1612            my $char;
1613            sysread($entry->[2],$char,1);
1614            # Store the excuse why the connection failed.
1615            $self->{bad}->{$entry->[0]} = $!;
1616            if (!$self->{econnrefused} &&
1617                (($! == ECONNREFUSED) ||
1618                 ($! == EAGAIN && $^O =~ /cygwin/i))) {
1619              # "Connection refused" means reachable
1620              # Good, continue
1621            } else {
1622              # No good, try the next socket...
1623              next;
1624            }
1625          }
1626          # Everything passed okay, return the answer
1627          return wantarray ?
1628            ($entry->[0], &time() - $entry->[3], $self->ntop($entry->[1]), $entry->[5])
1629            : $entry->[0];
1630        } else {
1631          warn "Corrupted SYN entry: unknown fd [$fd] ready!";
1632          vec($wbits, $fd, 1) = 0;
1633          vec($self->{wbits}, $fd, 1) = 0;
1634        }
1635      } elsif (defined $nfound) {
1636        # Timed out waiting for ACK
1637        foreach my $fd (keys %{ $self->{syn} }) {
1638          if (vec($wbits, $fd, 1)) {
1639            my $entry = $self->{syn}->{$fd};
1640            $self->{bad}->{$entry->[0]} = "Timed out";
1641            vec($wbits, $fd, 1) = 0;
1642            vec($self->{wbits}, $fd, 1) = 0;
1643            delete $self->{syn}->{$fd};
1644          }
1645        }
1646      } else {
1647        # Weird error occurred with select()
1648        warn("select: $!");
1649        $self->{syn} = {};
1650        $wbits = "";
1651      }
1652    }
1653  }
1654  return ();
1655}
1656
1657sub ack_unfork {
1658  my ($self,$host) = @_;
1659  my $stop_time = $self->{stop_time};
1660  if ($host) {
1661    # Host passed as arg
1662    if (my $entry = $self->{good}->{$host}) {
1663      delete $self->{good}->{$host};
1664      return ($entry->[0], &time() - $entry->[3], $self->ntop($entry->[1]));
1665    }
1666  }
1667
1668  my $rbits = "";
1669  my $timeout;
1670
1671  if (keys %{ $self->{syn} }) {
1672    # Scan all hosts that are left
1673    vec($rbits, fileno($self->{fork_rd}), 1) = 1;
1674    $timeout = $stop_time - &time();
1675    # Force a minimum of 10 ms timeout.
1676    $timeout = 0.01 if $timeout < 0.01;
1677  } else {
1678    # No hosts left to wait for
1679    $timeout = 0;
1680  }
1681
1682  if ($timeout > 0) {
1683    my $nfound;
1684    while ( keys %{ $self->{syn} } and
1685           $nfound = mselect((my $rout=$rbits), undef, undef, $timeout)) {
1686      # Done waiting for one of the ACKs
1687      if (!sysread($self->{fork_rd}, $_, 16)) {
1688        # Socket closed, which means all children are done.
1689        return ();
1690      }
1691      my ($pid, $how) = split;
1692      if ($pid) {
1693        # Flush the zombie
1694        waitpid($pid, 0);
1695        if (my $entry = $self->{syn}->{$pid}) {
1696          # Connection attempt to remote host is done
1697          delete $self->{syn}->{$pid};
1698          if (!$how || # If there was no error connecting
1699              (!$self->{econnrefused} &&
1700               $how == ECONNREFUSED)) {  # "Connection refused" means reachable
1701            if ($host && $entry->[0] ne $host) {
1702              # A good connection, but not the host we need.
1703              # Move it from the "syn" hash to the "good" hash.
1704              $self->{good}->{$entry->[0]} = $entry;
1705              # And wait for the next winner
1706              next;
1707            }
1708            return ($entry->[0], &time() - $entry->[3], $self->ntop($entry->[1]));
1709          }
1710        } else {
1711          # Should never happen
1712          die "Unknown ping from pid [$pid]";
1713        }
1714      } else {
1715        die "Empty response from status socket?";
1716      }
1717    }
1718    if (defined $nfound) {
1719      # Timed out waiting for ACK status
1720    } else {
1721      # Weird error occurred with select()
1722      warn("select: $!");
1723    }
1724  }
1725  if (my @synners = keys %{ $self->{syn} }) {
1726    # Kill all the synners
1727    kill 9, @synners;
1728    foreach my $pid (@synners) {
1729      # Wait for the deaths to finish
1730      # Then flush off the zombie
1731      waitpid($pid, 0);
1732    }
1733  }
1734  $self->{syn} = {};
1735  return ();
1736}
1737
1738# Description:  Tell why the ack() failed
1739sub nack {
1740  my $self = shift;
1741  my $host = shift || croak('Usage> nack($failed_ack_host)');
1742  return $self->{bad}->{$host} || undef;
1743}
1744
1745# Description:  Close the connection.
1746
1747sub close
1748{
1749  my ($self) = @_;
1750
1751  if ($self->{proto} eq "syn") {
1752    delete $self->{syn};
1753  } elsif ($self->{proto} eq "tcp") {
1754    # The connection will already be closed
1755  } elsif ($self->{proto} eq "external") {
1756    # Nothing to close
1757  } else {
1758    $self->{fh}->close();
1759  }
1760}
1761
1762sub port_number {
1763   my $self = shift;
1764   if(@_) {
1765       $self->{port_num} = shift @_;
1766       $self->service_check(1);
1767   }
1768   return $self->{port_num};
1769}
1770
1771sub ntop {
1772    my($self, $ip) = @_;
1773
1774    # Vista doesn't define a inet_ntop.  It has InetNtop instead.
1775    # Not following ANSI... priceless.  getnameinfo() is defined
1776    # for Windows 2000 and later, so that may be the choice.
1777
1778    # Any port will work, even undef, but this will work for now.
1779    # Socket warns when undef is passed in, but it still works.
1780    my $port = getservbyname('echo', 'udp');
1781    my $sockaddr = _pack_sockaddr_in($port, $ip);
1782    my ($error, $address) = getnameinfo($sockaddr, $NI_NUMERICHOST);
1783    croak $error if $error;
1784    return $address;
1785}
1786
1787sub wakeonlan {
1788  my ($mac_addr, $host, $port) = @_;
1789
1790  # use the discard service if $port not passed in
1791  if (! defined $host) { $host = '255.255.255.255' }
1792  if (! defined $port || $port !~ /^\d+$/ ) { $port = 9 }
1793
1794  require IO::Socket::INET;
1795  my $sock = IO::Socket::INET->new(Proto=>'udp') || return undef;
1796
1797  my $ip_addr = inet_aton($host);
1798  my $sock_addr = sockaddr_in($port, $ip_addr);
1799  $mac_addr =~ s/://g;
1800  my $packet = pack('C6H*', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, $mac_addr x 16);
1801
1802  setsockopt($sock, SOL_SOCKET, SO_BROADCAST, 1);
1803  send($sock, $packet, 0, $sock_addr);
1804  $sock->close;
1805
1806  return 1;
1807}
1808
1809########################################################
1810# DNS hostname resolution
1811# return:
1812#   $h->{name}    = host - as passed in
1813#   $h->{host}    = host - as passed in without :port
1814#   $h->{port}    = OPTIONAL - if :port, then value of port
1815#   $h->{addr}    = resolved numeric address
1816#   $h->{addr_in} = aton/pton result
1817#   $h->{family}  = AF_INET/6
1818############################
1819sub _resolv {
1820  my ($self,
1821      $name,
1822      ) = @_;
1823
1824  my %h;
1825  $h{name} = $name;
1826  my $family = $self->{family};
1827
1828  if (defined($self->{family_local})) {
1829    $family = $self->{family_local}
1830  }
1831
1832# START - host:port
1833  my $cnt = 0;
1834
1835  # Count ":"
1836  $cnt++ while ($name =~ m/:/g);
1837
1838  # 0 = hostname or IPv4 address
1839  if ($cnt == 0) {
1840    $h{host} = $name
1841  # 1 = IPv4 address with port
1842  } elsif ($cnt == 1) {
1843    ($h{host}, $h{port}) = split /:/, $name
1844  # >=2 = IPv6 address
1845  } elsif ($cnt >= 2) {
1846    #IPv6 with port - [2001::1]:port
1847    if ($name =~ /^\[.*\]:\d{1,5}$/) {
1848      ($h{host}, $h{port}) = split /:([^:]+)$/, $name # split after last :
1849    # IPv6 without port
1850    } else {
1851      $h{host} = $name
1852    }
1853  }
1854
1855  # Clean up host
1856  $h{host} =~ s/\[//g;
1857  $h{host} =~ s/\]//g;
1858  # Clean up port
1859  if (defined($h{port}) && (($h{port} !~ /^\d{1,5}$/) || ($h{port} < 1) || ($h{port} > 65535))) {
1860    croak("Invalid port `$h{port}' in `$name'");
1861    return undef;
1862  }
1863# END - host:port
1864
1865  # address check
1866  # new way
1867  if ($Socket_VERSION > 1.94) {
1868    my %hints = (
1869      family   => $AF_UNSPEC,
1870      protocol => IPPROTO_TCP,
1871      flags => $AI_NUMERICHOST
1872    );
1873
1874    # numeric address, return
1875    my ($err, @getaddr) = Socket::getaddrinfo($h{host}, undef, \%hints);
1876    if (defined($getaddr[0])) {
1877      $h{addr} = $h{host};
1878      $h{family} = $getaddr[0]->{family};
1879      if ($h{family} == AF_INET) {
1880        (undef, $h{addr_in}, undef, undef) = Socket::unpack_sockaddr_in $getaddr[0]->{addr};
1881      } else {
1882        (undef, $h{addr_in}, undef, undef) = Socket::unpack_sockaddr_in6 $getaddr[0]->{addr};
1883      }
1884      return \%h
1885    }
1886  # old way
1887  } else {
1888    # numeric address, return
1889    my $ret = gethostbyname($h{host});
1890    if (defined($ret) && (_inet_ntoa($ret) eq $h{host})) {
1891      $h{addr} = $h{host};
1892      $h{addr_in} = $ret;
1893      $h{family} = AF_INET;
1894      return \%h
1895    }
1896  }
1897
1898  # resolve
1899  # new way
1900  if ($Socket_VERSION >= 1.94) {
1901    my %hints = (
1902      family   => $family,
1903      protocol => IPPROTO_TCP
1904    );
1905
1906    my ($err, @getaddr) = Socket::getaddrinfo($h{host}, undef, \%hints);
1907    if (defined($getaddr[0])) {
1908      my ($err, $address) = Socket::getnameinfo($getaddr[0]->{addr}, $NI_NUMERICHOST, $NIx_NOSERV);
1909      if (defined($address)) {
1910        $h{addr} = $address;
1911        $h{addr} =~ s/\%(.)*$//; # remove %ifID if IPv6
1912        $h{family} = $getaddr[0]->{family};
1913        if ($h{family} == AF_INET) {
1914          (undef, $h{addr_in}, undef, undef) = Socket::unpack_sockaddr_in $getaddr[0]->{addr};
1915        } else {
1916          (undef, $h{addr_in}, undef, undef) = Socket::unpack_sockaddr_in6 $getaddr[0]->{addr};
1917        }
1918        return \%h;
1919      } else {
1920        carp("getnameinfo($getaddr[0]->{addr}) failed - $err");
1921        return undef;
1922      }
1923    } else {
1924      warn(sprintf("getaddrinfo($h{host},,%s) failed - $err",
1925                    $family == AF_INET ? "AF_INET" : "AF_INET6"));
1926      return undef;
1927    }
1928  # old way
1929  } else {
1930    if ($family == $AF_INET6) {
1931      croak("Socket >= 1.94 required for IPv6 - found Socket $Socket::VERSION");
1932      return undef;
1933    }
1934
1935    my @gethost = gethostbyname($h{host});
1936    if (defined($gethost[4])) {
1937      $h{addr} = inet_ntoa($gethost[4]);
1938      $h{addr_in} = $gethost[4];
1939      $h{family} = AF_INET;
1940      return \%h
1941    } else {
1942      carp("gethostbyname($h{host}) failed - $^E");
1943      return undef;
1944    }
1945  }
1946  return undef;
1947}
1948
1949sub _pack_sockaddr_in($$) {
1950  my ($port,
1951      $ip,
1952      ) = @_;
1953
1954  my $addr = ref($ip) eq "HASH" ? $ip->{addr_in} : $ip;
1955  if (length($addr) <= 4 ) {
1956    return Socket::pack_sockaddr_in($port, $addr);
1957  } else {
1958    return Socket::pack_sockaddr_in6($port, $addr);
1959  }
1960}
1961
1962sub _unpack_sockaddr_in($;$) {
1963  my ($addr,
1964      $family,
1965      ) = @_;
1966
1967  my ($port, $host);
1968  if ($family == AF_INET || (!defined($family) and length($addr) <= 16 )) {
1969    ($port, $host) = Socket::unpack_sockaddr_in($addr);
1970  } else {
1971    ($port, $host) = Socket::unpack_sockaddr_in6($addr);
1972  }
1973  return $port, $host
1974}
1975
1976sub _inet_ntoa {
1977  my ($addr
1978      ) = @_;
1979
1980  my $ret;
1981  if ($Socket_VERSION >= 1.94) {
1982    my ($err, $address) = Socket::getnameinfo($addr, $NI_NUMERICHOST);
1983    if (defined($address)) {
1984      $ret = $address;
1985    } else {
1986      carp("getnameinfo($addr) failed - $err");
1987    }
1988  } else {
1989    $ret = inet_ntoa($addr)
1990  }
1991
1992  return $ret
1993}
1994
19951;
1996__END__
1997
1998=head1 NAME
1999
2000Net::Ping - check a remote host for reachability
2001
2002=head1 SYNOPSIS
2003
2004    use Net::Ping;
2005
2006    my $p = Net::Ping->new();
2007    print "$host is alive.\n" if $p->ping($host);
2008    $p->close();
2009
2010    my $p = Net::Ping->new("icmp");
2011    $p->bind($my_addr); # Specify source interface of pings
2012    foreach my $host (@host_array)
2013    {
2014        print "$host is ";
2015        print "NOT " unless $p->ping($host, 2);
2016        print "reachable.\n";
2017        sleep(1);
2018    }
2019    $p->close();
2020
2021    my $p = Net::Ping->new("icmpv6");
2022    my $ip = "[fd00:dead:beef::4e]";
2023    print "$ip is alive.\n" if $p->ping($ip);
2024
2025    my $p = Net::Ping->new("tcp", 2);
2026    # Try connecting to the www port instead of the echo port
2027    $p->port_number(scalar(getservbyname("http", "tcp")));
2028    while ($stop_time > time())
2029    {
2030        print "$host not reachable ", scalar(localtime()), "\n"
2031            unless $p->ping($host);
2032        sleep(300);
2033    }
2034    undef($p);
2035
2036    # Like tcp protocol, but with many hosts
2037    my $p = Net::Ping->new("syn");
2038    $p->port_number(getservbyname("http", "tcp"));
2039    foreach my $host (@host_array) {
2040      $p->ping($host);
2041    }
2042    while (my ($host, $rtt, $ip) = $p->ack) {
2043      print "HOST: $host [$ip] ACKed in $rtt seconds.\n";
2044    }
2045
2046    # High precision syntax (requires Time::HiRes)
2047    my $p = Net::Ping->new();
2048    $p->hires();
2049    my ($ret, $duration, $ip) = $p->ping($host, 5.5);
2050    printf("$host [ip: $ip] is alive (packet return time: %.2f ms)\n",
2051            1000 * $duration)
2052      if $ret;
2053    $p->close();
2054
2055    # For backward compatibility
2056    print "$host is alive.\n" if pingecho($host);
2057
2058=head1 DESCRIPTION
2059
2060This module contains methods to test the reachability of remote
2061hosts on a network.  A ping object is first created with optional
2062parameters, a variable number of hosts may be pinged multiple
2063times and then the connection is closed.
2064
2065You may choose one of six different protocols to use for the
2066ping. The "tcp" protocol is the default. Note that a live remote host
2067may still fail to be pingable by one or more of these protocols. For
2068example, www.microsoft.com is generally alive but not "icmp" pingable.
2069
2070With the "tcp" protocol the ping() method attempts to establish a
2071connection to the remote host's echo port.  If the connection is
2072successfully established, the remote host is considered reachable.  No
2073data is actually echoed.  This protocol does not require any special
2074privileges but has higher overhead than the "udp" and "icmp" protocols.
2075
2076Specifying the "udp" protocol causes the ping() method to send a udp
2077packet to the remote host's echo port.  If the echoed packet is
2078received from the remote host and the received packet contains the
2079same data as the packet that was sent, the remote host is considered
2080reachable.  This protocol does not require any special privileges.
2081It should be borne in mind that, for a udp ping, a host
2082will be reported as unreachable if it is not running the
2083appropriate echo service.  For Unix-like systems see L<inetd(8)>
2084for more information.
2085
2086If the "icmp" protocol is specified, the ping() method sends an icmp
2087echo message to the remote host, which is what the UNIX ping program
2088does.  If the echoed message is received from the remote host and
2089the echoed information is correct, the remote host is considered
2090reachable.  Specifying the "icmp" protocol requires that the program
2091be run as root or that the program be setuid to root.
2092
2093If the "external" protocol is specified, the ping() method attempts to
2094use the C<Net::Ping::External> module to ping the remote host.
2095C<Net::Ping::External> interfaces with your system's default C<ping>
2096utility to perform the ping, and generally produces relatively
2097accurate results. If C<Net::Ping::External> if not installed on your
2098system, specifying the "external" protocol will result in an error.
2099
2100If the "syn" protocol is specified, the L</ping> method will only
2101send a TCP SYN packet to the remote host then immediately return.
2102If the syn packet was sent successfully, it will return a true value,
2103otherwise it will return false.  NOTE: Unlike the other protocols,
2104the return value does NOT determine if the remote host is alive or
2105not since the full TCP three-way handshake may not have completed
2106yet.  The remote host is only considered reachable if it receives
2107a TCP ACK within the timeout specified.  To begin waiting for the
2108ACK packets, use the L</ack> method as explained below.  Use the
2109"syn" protocol instead the "tcp" protocol to determine reachability
2110of multiple destinations simultaneously by sending parallel TCP
2111SYN packets.  It will not block while testing each remote host.
2112This protocol does not require any special privileges.
2113
2114=head2 Functions
2115
2116=over 4
2117
2118=item Net::Ping->new([proto, timeout, bytes, device, tos, ttl, family,
2119                      host, port, bind, gateway, retrans, pingstring,
2120                      source_verify econnrefused dontfrag
2121                      IPV6_USE_MIN_MTU IPV6_RECVPATHMTU])
2122X<new>
2123
2124Create a new ping object.  All of the parameters are optional and can
2125be passed as hash ref.  All options besides the first 7 must be passed
2126as hash ref.
2127
2128C<proto> specifies the protocol to use when doing a ping.  The current
2129choices are "tcp", "udp", "icmp", "icmpv6", "stream", "syn", or
2130"external".  The default is "tcp".
2131
2132If a C<timeout> in seconds is provided, it is used
2133when a timeout is not given to the ping() method (below).  The timeout
2134must be greater than 0 and the default, if not specified, is 5 seconds.
2135
2136If the number of data bytes (C<bytes>) is given, that many data bytes
2137are included in the ping packet sent to the remote host. The number of
2138data bytes is ignored if the protocol is "tcp".  The minimum (and
2139default) number of data bytes is 1 if the protocol is "udp" and 0
2140otherwise.  The maximum number of data bytes that can be specified is
214165535, but staying below the MTU (1472 bytes for ICMP) is recommended.
2142Many small devices cannot deal with fragmented ICMP packets.
2143
2144If C<device> is given, this device is used to bind the source endpoint
2145before sending the ping packet.  I believe this only works with
2146superuser privileges and with udp and icmp protocols at this time.
2147
2148If <tos> is given, this ToS is configured into the socket.
2149
2150For icmp, C<ttl> can be specified to set the TTL of the outgoing packet.
2151
2152Valid C<family> values for IPv4:
2153
2154   4, v4, ip4, ipv4, AF_INET (constant)
2155
2156Valid C<family> values for IPv6:
2157
2158   6, v6, ip6, ipv6, AF_INET6 (constant)
2159
2160The C<host> argument implicitly specifies the family if the family
2161argument is not given.
2162
2163The C<port> argument is only valid for a udp, tcp or stream ping, and will not
2164do what you think it does. ping returns true when we get a "Connection refused"!
2165The default is the echo port.
2166
2167The C<bind> argument specifies the local_addr to bind to.
2168By specifying a bind argument you don't need the bind method.
2169
2170The C<gateway> argument is only valid for IPv6, and requires a IPv6
2171address.
2172
2173The C<retrans> argument the exponential backoff rate, default 1.2.
2174It matches the $def_factor global.
2175
2176The C<dontfrag> argument sets the IP_DONTFRAG bit, but note that
2177IP_DONTFRAG is not yet defined by Socket, and not available on many
2178systems. Then it is ignored. On linux it also sets IP_MTU_DISCOVER to
2179IP_PMTUDISC_DO but need we don't chunk oversized packets. You need to
2180set $data_size manually.
2181
2182=item $p->ping($host [, $timeout [, $family]]);
2183X<ping>
2184
2185Ping the remote host and wait for a response.  $host can be either the
2186hostname or the IP number of the remote host.  The optional timeout
2187must be greater than 0 seconds and defaults to whatever was specified
2188when the ping object was created.  Returns a success flag.  If the
2189hostname cannot be found or there is a problem with the IP number, the
2190success flag returned will be undef.  Otherwise, the success flag will
2191be 1 if the host is reachable and 0 if it is not.  For most practical
2192purposes, undef and 0 and can be treated as the same case.  In array
2193context, the elapsed time as well as the string form of the ip the
2194host resolved to are also returned.  The elapsed time value will
2195be a float, as returned by the Time::HiRes::time() function, if hires()
2196has been previously called, otherwise it is returned as an integer.
2197
2198=item $p->source_verify( { 0 | 1 } );
2199X<source_verify>
2200
2201Allows source endpoint verification to be enabled or disabled.
2202This is useful for those remote destinations with multiples
2203interfaces where the response may not originate from the same
2204endpoint that the original destination endpoint was sent to.
2205This only affects udp and icmp protocol pings.
2206
2207This is enabled by default.
2208
2209=item $p->service_check( { 0 | 1 } );
2210X<service_check>
2211
2212Set whether or not the connect behavior should enforce
2213remote service availability as well as reachability.  Normally,
2214if the remote server reported ECONNREFUSED, it must have been
2215reachable because of the status packet that it reported.
2216With this option enabled, the full three-way tcp handshake
2217must have been established successfully before it will
2218claim it is reachable.  NOTE:  It still does nothing more
2219than connect and disconnect.  It does not speak any protocol
2220(i.e., HTTP or FTP) to ensure the remote server is sane in
2221any way.  The remote server CPU could be grinding to a halt
2222and unresponsive to any clients connecting, but if the kernel
2223throws the ACK packet, it is considered alive anyway.  To
2224really determine if the server is responding well would be
2225application specific and is beyond the scope of Net::Ping.
2226For udp protocol, enabling this option demands that the
2227remote server replies with the same udp data that it was sent
2228as defined by the udp echo service.
2229
2230This affects the "udp", "tcp", and "syn" protocols.
2231
2232This is disabled by default.
2233
2234=item $p->tcp_service_check( { 0 | 1 } );
2235X<tcp_service_check>
2236
2237Deprecated method, but does the same as service_check() method.
2238
2239=item $p->hires( { 0 | 1 } );
2240X<hires>
2241
2242With 1 causes this module to use Time::HiRes module, allowing milliseconds
2243to be returned by subsequent calls to ping().
2244
2245=item $p->time
2246X<time>
2247
2248The current time, hires or not.
2249
2250=item $p->socket_blocking_mode( $fh, $mode );
2251X<socket_blocking_mode>
2252
2253Sets or clears the O_NONBLOCK flag on a file handle.
2254
2255=item $p->IPV6_USE_MIN_MTU
2256X<IPV6_USE_MIN_MTU>
2257
2258With argument sets the option.
2259Without returns the option value.
2260
2261=item $p->IPV6_RECVPATHMTU
2262X<IPV6_RECVPATHMTU>
2263
2264Notify an according IPv6 MTU.
2265
2266With argument sets the option.
2267Without returns the option value.
2268
2269=item $p->IPV6_HOPLIMIT
2270X<IPV6_HOPLIMIT>
2271
2272With argument sets the option.
2273Without returns the option value.
2274
2275=item $p->IPV6_REACHCONF I<NYI>
2276X<IPV6_REACHCONF>
2277
2278Sets ipv6 reachability
2279IPV6_REACHCONF was removed in RFC3542. ping6 -R supports it.
2280IPV6_REACHCONF requires root/admin permissions.
2281
2282With argument sets the option.
2283Without returns the option value.
2284
2285Not yet implemented.
2286
2287=item $p->bind($local_addr);
2288X<bind>
2289
2290Sets the source address from which pings will be sent.  This must be
2291the address of one of the interfaces on the local host.  $local_addr
2292may be specified as a hostname or as a text IP address such as
2293"192.168.1.1".
2294
2295If the protocol is set to "tcp", this method may be called any
2296number of times, and each call to the ping() method (below) will use
2297the most recent $local_addr.  If the protocol is "icmp" or "udp",
2298then bind() must be called at most once per object, and (if it is
2299called at all) must be called before the first call to ping() for that
2300object.
2301
2302The bind() call can be omitted when specifying the C<bind> option to
2303new().
2304
2305=item $p->message_type([$ping_type]);
2306X<message_type>
2307
2308When you are using the "icmp" protocol, this call permit to change the
2309message type to 'echo' or 'timestamp' (only for IPv4, see RFC 792).
2310
2311Without argument, it returns the currently used icmp protocol message type.
2312By default, it returns 'echo'.
2313
2314=item $p->open($host);
2315X<open>
2316
2317When you are using the "stream" protocol, this call pre-opens the
2318tcp socket.  It's only necessary to do this if you want to
2319provide a different timeout when creating the connection, or
2320remove the overhead of establishing the connection from the
2321first ping.  If you don't call C<open()>, the connection is
2322automatically opened the first time C<ping()> is called.
2323This call simply does nothing if you are using any protocol other
2324than stream.
2325
2326The $host argument can be omitted when specifying the C<host> option to
2327new().
2328
2329=item $p->ack( [ $host ] );
2330X<ack>
2331
2332When using the "syn" protocol, use this method to determine
2333the reachability of the remote host.  This method is meant
2334to be called up to as many times as ping() was called.  Each
2335call returns the host (as passed to ping()) that came back
2336with the TCP ACK.  The order in which the hosts are returned
2337may not necessarily be the same order in which they were
2338SYN queued using the ping() method.  If the timeout is
2339reached before the TCP ACK is received, or if the remote
2340host is not listening on the port attempted, then the TCP
2341connection will not be established and ack() will return
2342undef.  In list context, the host, the ack time, the dotted ip
2343string, and the port number will be returned instead of just the host.
2344If the optional C<$host> argument is specified, the return
2345value will be pertaining to that host only.
2346This call simply does nothing if you are using any protocol
2347other than "syn".
2348
2349When L</new> had a host option, this host will be used.
2350Without C<$host> argument, all hosts are scanned.
2351
2352=item $p->nack( $failed_ack_host );
2353X<nack>
2354
2355The reason that C<host $failed_ack_host> did not receive a
2356valid ACK.  Useful to find out why when C<ack($fail_ack_host)>
2357returns a false value.
2358
2359=item $p->ack_unfork($host)
2360X<ack_unfork>
2361
2362The variant called by L</ack> with the "syn" protocol and C<$syn_forking>
2363enabled.
2364
2365=item $p->ping_icmp([$host, $timeout, $family])
2366X<ping_icmp>
2367
2368The L</ping> method used with the icmp protocol.
2369
2370=item $p->ping_icmpv6([$host, $timeout, $family])
2371X<ping_icmpv6>
2372
2373The L</ping> method used with the icmpv6 protocol.
2374
2375=item $p->ping_stream([$host, $timeout, $family])
2376X<ping_stream>
2377
2378The L</ping> method used with the stream protocol.
2379
2380Perform a stream ping.  If the tcp connection isn't
2381already open, it opens it.  It then sends some data and waits for
2382a reply.  It leaves the stream open on exit.
2383
2384=item $p->ping_syn([$host, $ip, $start_time, $stop_time])
2385X<ping_syn>
2386
2387The L</ping> method used with the syn protocol.
2388Sends a TCP SYN packet to host specified.
2389
2390=item $p->ping_syn_fork([$host, $timeout, $family])
2391X<ping_syn_fork>
2392
2393The L</ping> method used with the forking syn protocol.
2394
2395=item $p->ping_tcp([$host, $timeout, $family])
2396X<ping_tcp>
2397
2398The L</ping> method used with the tcp protocol.
2399
2400=item $p->ping_udp([$host, $timeout, $family])
2401X<ping_udp>
2402
2403The L</ping> method used with the udp protocol.
2404
2405Perform a udp echo ping.  Construct a message of
2406at least the one-byte sequence number and any additional data bytes.
2407Send the message out and wait for a message to come back.  If we
2408get a message, make sure all of its parts match.  If they do, we are
2409done.  Otherwise go back and wait for the message until we run out
2410of time.  Return the result of our efforts.
2411
2412=item $p->ping_external([$host, $timeout, $family])
2413X<ping_external>
2414
2415The L</ping> method used with the external protocol.
2416Uses L<Net::Ping::External> to do an external ping.
2417
2418=item $p->tcp_connect([$ip, $timeout])
2419X<tcp_connect>
2420
2421Initiates a TCP connection, for a tcp ping.
2422
2423=item $p->tcp_echo([$ip, $timeout, $pingstring])
2424X<tcp_echo>
2425
2426Performs a TCP echo.
2427It writes the given string to the socket and then reads it
2428back.  It returns 1 on success, 0 on failure.
2429
2430=item $p->close();
2431X<close>
2432
2433Close the network connection for this ping object.  The network
2434connection is also closed by "undef $p".  The network connection is
2435automatically closed if the ping object goes out of scope (e.g. $p is
2436local to a subroutine and you leave the subroutine).
2437
2438=item $p->port_number([$port_number])
2439X<port_number>
2440
2441When called with a port number, the port number used to ping is set to
2442C<$port_number> rather than using the echo port.  It also has the effect
2443of calling C<$p-E<gt>service_check(1)> causing a ping to return a successful
2444response only if that specific port is accessible.  This function returns
2445the value of the port that L</ping> will connect to.
2446
2447=item $p->mselect
2448X<mselect>
2449
2450A C<select()> wrapper that compensates for platform
2451peculiarities.
2452
2453=item $p->ntop
2454X<ntop>
2455
2456Platform abstraction over C<inet_ntop()>
2457
2458=item $p->checksum($msg)
2459X<checksum>
2460
2461Do a checksum on the message.  Basically sum all of
2462the short words and fold the high order bits into the low order bits.
2463
2464=item $p->icmp_result
2465X<icmp_result>
2466
2467Returns a list of addr, type, subcode.
2468
2469=item pingecho($host [, $timeout]);
2470X<pingecho>
2471
2472To provide backward compatibility with the previous version of
2473L<Net::Ping>, a C<pingecho()> subroutine is available with the same
2474functionality as before.  C<pingecho()> uses the tcp protocol.  The
2475return values and parameters are the same as described for the L</ping>
2476method.  This subroutine is obsolete and may be removed in a future
2477version of L<Net::Ping>.
2478
2479=item wakeonlan($mac, [$host, [$port]])
2480X<wakeonlan>
2481
2482Emit the popular wake-on-lan magic udp packet to wake up a local
2483device.  See also L<Net::Wake>, but this has the mac address as 1st arg.
2484C<$host> should be the local gateway. Without it will broadcast.
2485
2486Default host: '255.255.255.255'
2487Default port: 9
2488
2489  perl -MNet::Ping=wakeonlan -e'wakeonlan "e0:69:95:35:68:d2"'
2490
2491=back
2492
2493=head1 NOTES
2494
2495There will be less network overhead (and some efficiency in your
2496program) if you specify either the udp or the icmp protocol.  The tcp
2497protocol will generate 2.5 times or more traffic for each ping than
2498either udp or icmp.  If many hosts are pinged frequently, you may wish
2499to implement a small wait (e.g. 25ms or more) between each ping to
2500avoid flooding your network with packets.
2501
2502The icmp and icmpv6 protocols requires that the program be run as root
2503or that it be setuid to root.  The other protocols do not require
2504special privileges, but not all network devices implement tcp or udp
2505echo.
2506
2507Local hosts should normally respond to pings within milliseconds.
2508However, on a very congested network it may take up to 3 seconds or
2509longer to receive an echo packet from the remote host.  If the timeout
2510is set too low under these conditions, it will appear that the remote
2511host is not reachable (which is almost the truth).
2512
2513Reachability doesn't necessarily mean that the remote host is actually
2514functioning beyond its ability to echo packets.  tcp is slightly better
2515at indicating the health of a system than icmp because it uses more
2516of the networking stack to respond.
2517
2518Because of a lack of anything better, this module uses its own
2519routines to pack and unpack ICMP packets.  It would be better for a
2520separate module to be written which understands all of the different
2521kinds of ICMP packets.
2522
2523=head1 INSTALL
2524
2525The latest source tree is available via git:
2526
2527  git clone https://github.com/rurban/Net-Ping.git
2528  cd Net-Ping
2529
2530The tarball can be created as follows:
2531
2532  perl Makefile.PL ; make ; make dist
2533
2534The latest Net::Ping releases are included in cperl and perl5.
2535
2536=head1 BUGS
2537
2538For a list of known issues, visit:
2539
2540L<https://rt.cpan.org/NoAuth/Bugs.html?Dist=Net-Ping>
2541and
2542L<https://github.com/rurban/Net-Ping/issues>
2543
2544To report a new bug, visit:
2545
2546L<https://github.com/rurban/Net-Ping/issues>
2547
2548=head1 AUTHORS
2549
2550  Current maintainers:
2551    perl11 (for cperl, with IPv6 support and more)
2552    p5p    (for perl5)
2553
2554  Previous maintainers:
2555    bbb@cpan.org (Rob Brown)
2556    Steve Peters
2557
2558  External protocol:
2559    colinm@cpan.org (Colin McMillen)
2560
2561  Stream protocol:
2562    bronson@trestle.com (Scott Bronson)
2563
2564  Wake-on-lan:
2565    1999-2003 Clinton Wong
2566
2567  Original pingecho():
2568    karrer@bernina.ethz.ch (Andreas Karrer)
2569    pmarquess@bfsec.bt.co.uk (Paul Marquess)
2570
2571  Original Net::Ping author:
2572    mose@ns.ccsn.edu (Russell Mosemann)
2573
2574=head1 COPYRIGHT
2575
2576Copyright (c) 2017-2020, Reini Urban.  All rights reserved.
2577
2578Copyright (c) 2016, cPanel Inc.  All rights reserved.
2579
2580Copyright (c) 2012, Steve Peters.  All rights reserved.
2581
2582Copyright (c) 2002-2003, Rob Brown.  All rights reserved.
2583
2584Copyright (c) 2001, Colin McMillen.  All rights reserved.
2585
2586This program is free software; you may redistribute it and/or
2587modify it under the same terms as Perl itself.
2588
2589=cut
2590