diff options
-rwxr-xr-x | Porting/Maintainers.pl | 8 | ||||
-rw-r--r-- | dist/Net-Ping/Changes | 23 | ||||
-rw-r--r-- | dist/Net-Ping/lib/Net/Ping.pm | 52 | ||||
-rw-r--r-- | dist/Net-Ping/t/200_ping_tcp.t | 20 |
4 files changed, 73 insertions, 30 deletions
diff --git a/Porting/Maintainers.pl b/Porting/Maintainers.pl index 54b1edb956..cc5732fd0e 100755 --- a/Porting/Maintainers.pl +++ b/Porting/Maintainers.pl @@ -843,13 +843,19 @@ use File::Glob qw(:case); }, 'Net::Ping' => { - 'DISTRIBUTION' => 'RURBAN/Net-Ping-2.73.tar.gz', + 'DISTRIBUTION' => 'RURBAN/Net-Ping-2.74.tar.gz', 'FILES' => q[dist/Net-Ping], 'EXCLUDED' => [ + qr{^\.[awc]}, qw(README.md.PL), qw(t/020_external.t), qw(t/600_pod.t), qw(t/601_pod-coverage.t), + qw(t/602_kwalitee.t), + qw(t/603_meta.t), + qw(t/604_manifest.t), + qw(t/appveyor-test.bat), + ], 'CUSTOMIZED' => [ qw{ diff --git a/dist/Net-Ping/Changes b/dist/Net-Ping/Changes index 51d6550789..9e5e9e80d1 100644 --- a/dist/Net-Ping/Changes +++ b/dist/Net-Ping/Changes @@ -1,5 +1,28 @@ CHANGES ------- +2.74 2020-09-09 09:21:39 rurban + Features + - Add ICMPv6_NI_REPLY support. + Bugfixes + - Fix icmp payload offset to match icmpv6 (JimC Leones GH #21) + Skip the 20 byte header to reliably find the various return types. + This unifies icmpv6 with icmp better. + - Fix $SOCKET::VERSION eval (Petr Pavlu, PR #22) + META Changes + - Fix and improve the META repository as hashref, license as arrayref + (Tom Hukins, PR #19) + - add TEST_REQUIRES + - sort MANIFEST + - add windows smokers: appveyor + Test fixes + - Improve the tcp test to localhost, when there is no route to localhost + (freebsd mostly) + - TODO a flaky 450_service.t on 127.0.0.1 on port 2 on Windows (analog to freebsd, ...) + (Christian Walde, PR #20) + - Skip 501_ping_icmpv6.t when icmpv6 cannot be initialized. Mostly due to missing + icmpv6 support. (GH #15) + - add more xt tests: t/602_kwalitee.t, t/603_meta.t, t/604_manifest.t + 2.73 Thu Feb 27 14:32:25 CET 2020 (rurban) Bugfixes - Fix shadowing of hash options in constructor (Patrick Heesom, RT #131919) diff --git a/dist/Net-Ping/lib/Net/Ping.pm b/dist/Net-Ping/lib/Net/Ping.pm index 779e55daed..19bb51ec1a 100644 --- a/dist/Net-Ping/lib/Net/Ping.pm +++ b/dist/Net-Ping/lib/Net/Ping.pm @@ -8,6 +8,7 @@ use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION $def_timeout $def_proto $def_factor $def_family $max_datasize $pingstring $hires $source_verify $syn_forking); use Fcntl qw( F_GETFL F_SETFL O_NONBLOCK ); +use Socket 2.007; use Socket qw( SOCK_DGRAM SOCK_STREAM SOCK_RAW AF_INET PF_INET IPPROTO_TCP SOL_SOCKET SO_ERROR SO_BROADCAST IPPROTO_IP IP_TOS IP_TTL @@ -21,7 +22,7 @@ use Time::HiRes; @ISA = qw(Exporter); @EXPORT = qw(pingecho); @EXPORT_OK = qw(wakeonlan); -$VERSION = "2.73_01"; +$VERSION = "2.74"; # Globals @@ -46,7 +47,7 @@ my $NIx_NOSERV = eval { Socket::NIx_NOSERV() } || 2; #my $IPV6_HOPLIMIT = eval { Socket::IPV6_HOPLIMIT() }; # ping6 -h 0-255 my $qr_family = qr/^(?:(?:(:?ip)?v?(?:4|6))|${\AF_INET}|$AF_INET6)$/; my $qr_family4 = qr/^(?:(?:(:?ip)?v?4)|${\AF_INET})$/; -my $Socket_VERSION = eval { $Socket::VERSION }; +my $Socket_VERSION = eval $Socket::VERSION; if ($^O =~ /Win32/i) { # Hack to avoid this Win32 spewage: @@ -644,10 +645,11 @@ sub ping_external { # h2ph "asm/socket.h" # require "asm/socket.ph"; use constant SO_BINDTODEVICE => 25; -use constant ICMP_ECHOREPLY => 0; # ICMP packet types +use constant ICMP_ECHOREPLY => 0; # ICMP packet types use constant ICMPv6_ECHOREPLY => 129; # ICMP packet types -use constant ICMP_UNREACHABLE => 3; # ICMP packet types +use constant ICMP_UNREACHABLE => 3; # ICMP packet types use constant ICMPv6_UNREACHABLE => 1; # ICMP packet types +use constant ICMPv6_NI_REPLY => 140; # ICMP packet types use constant ICMP_ECHO => 8; use constant ICMPv6_ECHO => 128; use constant ICMP_TIME_EXCEEDED => 11; # ICMP packet types @@ -781,31 +783,25 @@ sub ping_icmp $from_saddr = recv($self->{fh}, $recv_msg, 1500, ICMP_FLAGS); $recv_msg_len = length($recv_msg) - length($self->{data}); ($from_port, $from_ip) = _unpack_sockaddr_in($from_saddr, $ip->{family}); - ($from_type, $from_subcode) = unpack("C2", substr($recv_msg, 20, 2)); + # ICMP echo includes the header and ICMPv6 doesn't. + # IPv4 length($recv_msg) is 28 (20 header + 8 payload) + # while IPv6 length is only 8 (sans header). + my $off = ($ip->{family} == AF_INET) ? 20 : 0; # payload offset + ($from_type, $from_subcode) = unpack("C2", substr($recv_msg, $off, 2)); if ($from_type == ICMP_TIMESTAMP_REPLY) { - ($from_pid, $from_seq) = unpack("n3", substr($recv_msg, 24, 4)) - if length $recv_msg >= 28; - } elsif ($from_type == ICMP_ECHOREPLY) { + ($from_pid, $from_seq) = unpack("n3", substr($recv_msg, $off + 4, 4)) + if length $recv_msg >= $off + 8; + } elsif ($from_type == ICMP_ECHOREPLY || $from_type == ICMPv6_ECHOREPLY) { #warn "ICMP_ECHOREPLY: ", $ip->{family}, " ",$recv_msg, ":", length($recv_msg); - ($from_pid, $from_seq) = unpack("n2", substr($recv_msg, 24, 4)) - if ($ip->{family} == AF_INET && $recv_msg_len == 28); + ($from_pid, $from_seq) = unpack("n2", substr($recv_msg, $off + 4, 4)) + if $recv_msg_len == $off + 8; + } elsif ($from_type == ICMPv6_NI_REPLY) { ($from_pid, $from_seq) = unpack("n2", substr($recv_msg, 4, 4)) - if ($ip->{family} == $AF_INET6 && $recv_msg_len == 8); - } elsif ($from_type == ICMPv6_ECHOREPLY) { - #($from_pid, $from_seq) = unpack("n3", substr($recv_msg, 24, 4)) - # if length $recv_msg >= 28; - #($from_pid, $from_seq) = unpack("n2", substr($recv_msg, 24, 4)) - # if ($ip->{family} == AF_INET && length $recv_msg == 28); - #warn "ICMPv6_ECHOREPLY: ", $ip->{family}, " ",$recv_msg, ":", length($recv_msg); - ($from_pid, $from_seq) = unpack("n2", substr($recv_msg, 4, 4)) - if ($ip->{family} == $AF_INET6 && $recv_msg_len == 8); - #} elsif ($from_type == ICMPv6_NI_REPLY) { - # ($from_pid, $from_seq) = unpack("n2", substr($recv_msg, 4, 4)) - # if ($ip->{family} == $AF_INET6 && length $recv_msg == 8); + if ($ip->{family} == $AF_INET6 && length $recv_msg == 8); } else { #warn "ICMP: ", $from_type, " ",$ip->{family}, " ",$recv_msg, ":", length($recv_msg); - ($from_pid, $from_seq) = unpack("n2", substr($recv_msg, 52, 4)) - if length $recv_msg >= 56; + ($from_pid, $from_seq) = unpack("n2", substr($recv_msg, $off + 32, 4)) + if length $recv_msg >= $off + 36; } $self->{from_ip} = $from_ip; $self->{from_type} = $from_type; @@ -2023,6 +2019,10 @@ Net::Ping - check a remote host for reachability } $p->close(); + $p = Net::Ping->new("icmpv6"); + $ip = "[fd00:dead:beef::4e]"; + print "$ip is alive.\n" if $p->ping($ip); + $p = Net::Ping->new("tcp", 2); # Try connecting to the www port instead of the echo port $p->port_number(scalar(getservbyname("http", "tcp"))); @@ -2368,7 +2368,7 @@ X<ping_icmp> The L</ping> method used with the icmp protocol. -=item $p->ping_icmpv6([$host, $timeout, $family]) I<NYI> +=item $p->ping_icmpv6([$host, $timeout, $family]) X<ping_icmpv6> The L</ping> method used with the icmpv6 protocol. @@ -2574,7 +2574,7 @@ L<https://github.com/rurban/Net-Ping/issues> =head1 COPYRIGHT -Copyright (c) 2017-2018, Reini Urban. All rights reserved. +Copyright (c) 2017-2020, Reini Urban. All rights reserved. Copyright (c) 2016, cPanel Inc. All rights reserved. diff --git a/dist/Net-Ping/t/200_ping_tcp.t b/dist/Net-Ping/t/200_ping_tcp.t index 47168b014a..e2bfe18c37 100644 --- a/dist/Net-Ping/t/200_ping_tcp.t +++ b/dist/Net-Ping/t/200_ping_tcp.t @@ -44,14 +44,28 @@ eval { }; like($@, qr/message type only supported on 'icmp' protocol/, "message_type() API only concern 'icmp' protocol"); -isnt($p->ping("localhost"), 0, 'Test on the default port'); +my $localhost = $p->ping("localhost"); +if ($localhost) { + isnt($p->ping("localhost"), 0, 'Test on the default port'); +} else { + ok(1, "SKIP localhost on the default port on $^O"); +} # Change to use the more common web port. # This will pull from /etc/services on UNIX. # (Make sure getservbyname works in scalar context.) -isnt($p->{port_num} = (getservbyname("http", "tcp") || 80), undef); +isnt($p->{port_num} = (getservbyname("http", "tcp") || 80), undef, "getservbyname http"); -isnt($p->ping("localhost"), 0, 'Test localhost on the web port'); +if ($localhost) { + isnt($p->ping("localhost"), 0, 'Test localhost on the web port'); +} else { + my $result = $p->ping("localhost"); + if ($result) { + isnt($p->ping("localhost"), 0, "localhost on the web port unexpectedly worked on $^O"); + } else { + ok(1, "SKIP localhost on the web port on $^O"); + } +} is($p->ping($fail_ip), 0, "Can't reach $fail_ip"); |