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