diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 2003-02-08 08:35:06 +0000 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2003-02-08 08:35:06 +0000 |
commit | 9c36735de2bc373cab0c4275429b13fc1c754d20 (patch) | |
tree | e81e1199f2f8921408d72b56ce8302feda98c61b /lib/Net/Ping | |
parent | 12f98225223fc8656cd9a46ff1e4f49c6c3f2943 (diff) | |
download | perl-9c36735de2bc373cab0c4275429b13fc1c754d20.tar.gz |
Upgrade to Net::Ping 2.28, from Rob Brown.
p4raw-id: //depot/perl@18671
Diffstat (limited to 'lib/Net/Ping')
-rw-r--r-- | lib/Net/Ping/Changes | 100 | ||||
-rw-r--r-- | lib/Net/Ping/README | 117 | ||||
-rw-r--r-- | lib/Net/Ping/t/190_alarm.t | 50 | ||||
-rw-r--r-- | lib/Net/Ping/t/300_ping_stream.t | 45 | ||||
-rw-r--r-- | lib/Net/Ping/t/400_ping_syn.t | 16 | ||||
-rw-r--r-- | lib/Net/Ping/t/410_syn_host.t | 18 | ||||
-rw-r--r-- | lib/Net/Ping/t/500_ping_icmp.t | 29 |
7 files changed, 319 insertions, 56 deletions
diff --git a/lib/Net/Ping/Changes b/lib/Net/Ping/Changes index d8dad1625b..01454ac904 100644 --- a/lib/Net/Ping/Changes +++ b/lib/Net/Ping/Changes @@ -1,6 +1,106 @@ CHANGES ------- +2.28 Jan 23 18:00 2003 + - No new features. Bug fixes only. + - Fixed ICMP_STRUCT to work on Big Endian platforms. + Thanks to danb@thelittlemacshop.com (Dan Buettner) + for testing on Mac OS X 10.2.3 and many others + for testing on Big Endian boxes. + - Not do binmode(). Causes more problems than helps. + - Perl 5.004 compatibility fixes (Spot by Honza). + +2.27 Jan 15 23:00 2003 + - Patch by slebedev@iwl.net (Sergey Lebedev): + - 1) Fixed response packet parsing offsets in ping_icmp. + - 2) Added icmp_result method. + - Patch by radu@netsoft.ro (Radu Greab): + - 1) Changed ping_tcp() to use non-blocking connect + instead of alarm() interface in order to avoid + conflicts with user applications. + - 2) Also get rid of all eval {} code in ping_tcp + in order to avoid catching SIGALRM trigger and + to avoid conflicts with other evals. + - 3) Avoid ioctl() syscall for more accurate error + detection on non-blocking tcp connects. + - 4) Fix fcntl() syntax usage. + - Patch by adelton@fi.muni.cz (Honza Pazdziora): + - 1) Fix icmp request pack code to be more platform + independent regardless of Big/Little Endian. + - 2) Use binmode for filehandle in case perl 5.8.0 + tries to dink with the data stream. + - Other changes by Rob Brown: + - Fixed ack() failures under certain rare conditions. + - Use more appropriate \z instead of $ in regex. + - Resolved Cygwin "make test" problems reported by + h.m.brand@hccnet.nl (H.Merijn Brand). + - Add sending a real ICMP packet in the test suite. + - Add Socket to PREREQ_PM (missing on some boxes?) + - Adjust syn_forking IPC pipe for fatter Win32 pids. + - Better handling of alarm() in test suite for Win32. + - Add a DESTROY method to reduce chances of + lingering connect-choking children. + +2.26 Dec 02 12:00 2002 + - More compatibility fixes. + - Thanks for Solaris bug reports: + Paul.Gaborit@enstimac.fr (Paul Gaborit) + Jost.Krieger@ruhr-uni-bochum.de (Jost Krieger) + - Thanks for Solaris testing box: + Gunther.Heintzen@rrze.uni-erlangen.de (Gunther Heintzen) + - Solaris ENOTCONN select() for write choke bug. + - Thanks for Cygwin bug reports: + h.m.brand@hccnet.nl (H.Merijn Brand) + - Cygwin "EAGAIN instead of ECONNREFUSED" buttwag. + +2.25 Nov 19 12:00 2002 + - Handle condition where O_NONBLOCK tcp connects + immediately fail without EINPROGRESS + (certain platforms or SMP optimizations). + +2.24 Oct 21 22:00 2002 + - Compatibility fixes. + - Avoid using 127.1.1.1 and 127.2.2.2 because + it breaks on some platforms (Irix). + - Handle condition where nonblocking tcp connects + immediately connect on some platforms + (solaris and freebsd) and to be SMP safer. + - Win32 $p->ack( $host ) method should now work. + - Add ack( $host ) test cases to test suite. + +2.23 Oct 18 22:00 2002 + - Fix ack() fd "each" detection bug. + - Add nack() method for OO interface to the + reason why the ack() failed. + - Fix premature "Timed out" side effect when a + different specified ack( $host ) fails. + - IO::Socket::INET ephemeral port buttwag + hack for the t/450_service.t test. + - Documental changes. + +2.22 Oct 17 16:00 2002 + - Add $p->tcp_service_check() method to enforce + remote tcp service availability checking. + Patch by jef@linuxbe.org (Jean-Francois Dive). + - Changed default behavior of "syn" protocol to + disabled tcp_service_check instead of enabled. + - Win32 compatibility changes ("syn" protocol). + - Increase timeouts for tests in case client or + server network(s) are busy. + +2.21 Oct 14 12:00 2002 + - Preserve/restore ALRM settings for tcp mode pings. + Spot by d@niel-berlin.de (Daniel Berlin) + - Can now select device for udp and icmp protocols. + Patch by sarfata@altern.org (Thomas Sarlandie). + - Add new "syn" protocol to allow for mass parallel + (syncronous) TCP service reachability checking. + - Add ack() method to utilize non-blocking connect + (SYN/ACK) feature of the "syn" protocol. + - Add demo/fping script as a "syn" demonstration. + - Compatibiliy patches for cygwin. + Spot by frazee.23@osu.edu (Joseph Frazee) + 2.20 Jun 20 10:00 2002 - Perl 5.8.0 compatibility stuff. Spot by dcd@tc.fluke.com (David Dyck). diff --git a/lib/Net/Ping/README b/lib/Net/Ping/README index 2dc4b95280..38300c1dd4 100644 --- a/lib/Net/Ping/README +++ b/lib/Net/Ping/README @@ -1,7 +1,7 @@ NAME Net::Ping - check a remote host for reachability - $Id: Ping.pm,v 1.6 2002/06/19 15:23:48 rob Exp $ + $Id: Ping.pm,v 1.69 2003/01/23 17:21:29 rob Exp $ SYNOPSIS use Net::Ping; @@ -32,6 +32,16 @@ SYNOPSIS } undef($p); + # Like tcp protocol, but with many hosts + $p = Net::Ping->new("syn"); + $p->{port_num} = getservbyname("http", "tcp"); + foreach $host (@host_array) { + $p->ping($host); + } + while (($host,$rtt,$ip) = $p->ack) { + print "HOST: $host [$ip] ACKed in $rtt seconds.\n"; + } + # High precision syntax (requires Time::HiRes) $p = Net::Ping->new(); $p->hires(); @@ -49,16 +59,16 @@ DESCRIPTION variable number of hosts may be pinged multiple times and then the connection is closed. - You may choose one of four different protocols to use for the ping. The - "udp" protocol is the default. Note that a live remote host may still + You may choose one of six different protocols to use for the ping. The + "tcp" protocol is the default. Note that a live remote host may still fail to be pingable by one or more of these protocols. For example, - www.microsoft.com is generally alive but not pingable. + www.microsoft.com is generally alive but not "icmp" pingable. With the "tcp" protocol the ping() method attempts to establish a connection to the remote host's echo port. If the connection is successfully established, the remote host is considered reachable. No data is actually echoed. This protocol does not require any special - privileges but has higher overhead than the other two protocols. + privileges but has higher overhead than the "udp" and "icmp" protocols. Specifying the "udp" protocol causes the ping() method to send a udp packet to the remote host's echo port. If the echoed packet is received @@ -77,18 +87,34 @@ DESCRIPTION or that the program be setuid to root. If the "external" protocol is specified, the ping() method attempts to - use the `Net::Ping::External' module to ping the remote host. - `Net::Ping::External' interfaces with your system's default `ping' + use the "Net::Ping::External" module to ping the remote host. + "Net::Ping::External" interfaces with your system's default "ping" utility to perform the ping, and generally produces relatively accurate - results. If `Net::Ping::External' if not installed on your system, + results. If "Net::Ping::External" if not installed on your system, specifying the "external" protocol will result in an error. + If the "syn" protocol is specified, the ping() method will only send a + TCP SYN packet to the remote host then immediately return. If the syn + packet was sent successfully, it will return a true value, otherwise it + will return false. NOTE: Unlike the other protocols, the return value + does NOT determine if the remote host is alive or not since the full TCP + three-way handshake may not have completed yet. The remote host is only + considered reachable if it receives a TCP ACK within the timeout + specifed. To begin waiting for the ACK packets, use the ack() method as + explained below. Use the "syn" protocol instead the "tcp" protocol to + determine reachability of multiple destinations simultaneously by + sending parallel TCP SYN packets. It will not block while testing each + remote host. demo/fping is provided in this distribution to demonstrate + the "syn" protocol as an example. This protocol does not require any + special privileges. + Functions - Net::Ping->new([$proto [, $def_timeout [, $bytes]]]); + Net::Ping->new([$proto [, $def_timeout [, $bytes [, $device ]]]]); Create a new ping object. All of the parameters are optional. $proto specifies the protocol to use when doing a ping. The current choices - are "tcp", "udp" or "icmp". The default is "udp". + are "tcp", "udp", "icmp", "stream", "syn", or "external". The + default is "tcp". If a default timeout ($def_timeout) in seconds is provided, it is used when a timeout is not given to the ping() method (below). The @@ -102,6 +128,10 @@ DESCRIPTION otherwise. The maximum number of data bytes that can be specified is 1024. + If $device is given, this device is used to bind the source endpoint + before sending the ping packet. I beleive this only works with + superuser privileges and with udp and icmp protocols at this time. + $p->ping($host [, $timeout]); Ping the remote host and wait for a response. $host can be either the hostname or the IP number of the remote host. The optional @@ -111,10 +141,11 @@ DESCRIPTION number, the success flag returned will be undef. Otherwise, the success flag will be 1 if the host is reachable and 0 if it is not. For most practical purposes, undef and 0 and can be treated as the - same case. In array context, the elapsed time is also returned. The - elapsed time value will be a float, as retuned by the - Time::HiRes::time() function, if hires() has been previously called, - otherwise it is returned as an integer. + same case. In array context, the elapsed time as well as the string + form of the ip the host resolved to are also returned. The elapsed + time value will be a float, as retuned by the Time::HiRes::time() + function, if hires() has been previously called, otherwise it is + returned as an integer. $p->source_verify( { 0 | 1 } ); Allows source endpoint verification to be enabled or disabled. This @@ -125,6 +156,25 @@ DESCRIPTION This is enabled by default. + $p->tcp_service_check( { 0 | 1 } ); + Set whether or not the tcp connect behavior should enforce remote + service availability as well as reachability. Normally, if the + remote server reported ECONNREFUSED, it must have been reachable + because of the status packet that it reported. With this option + enabled, the full three-way tcp handshake must have been established + successfully before it will claim it is reachable. NOTE: It still + does nothing more than connect and disconnect. It does not speak any + protocol (i.e., HTTP or FTP) to ensure the remote server is sane in + any way. The remote server CPU could be grinding to a halt and + unresponsive to any clients connecting, but if the kernel throws the + ACK packet, it is considered alive anyway. To really determine if + the server is responding well would be application specific and is + beyond the scope of Net::Ping. + + This only affects "tcp" and "syn" protocols. + + This is disabled by default. + $p->hires( { 0 | 1 } ); Causes this module to use Time::HiRes module, allowing milliseconds to be returned by subsequent calls to ping(). @@ -145,14 +195,35 @@ DESCRIPTION that object. $p->open($host); - When you are using the stream protocol, this call pre-opens the tcp - socket. It's only necessary to do this if you want to provide a + When you are using the "stream" protocol, this call pre-opens the + tcp socket. It's only necessary to do this if you want to provide a different timeout when creating the connection, or remove the overhead of establishing the connection from the first ping. If you - don't call `open()', the connection is automatically opened the - first time `ping()' is called. This call simply does nothing if you + don't call "open()", the connection is automatically opened the + first time "ping()" is called. This call simply does nothing if you are using any protocol other than stream. + $p->ack( [ $host ] ); + When using the "syn" protocol, use this method to determine the + reachability of the remote host. This method is meant to be called + up to as many times as ping() was called. Each call returns the host + (as passed to ping()) that came back with the TCP ACK. The order in + which the hosts are returned may not necessarily be the same order + in which they were SYN queued using the ping() method. If the + timeout is reached before the TCP ACK is received, or if the remote + host is not listening on the port attempted, then the TCP connection + will not be established and ack() will return undef. In list + context, the host, the ack time, and the dotted ip string will be + returned instead of just the host. If the optional $host argument is + specified, the return value will be partaining to that host only. + This call simply does nothing if you are using any protocol other + than syn. + + $p->nack( $failed_ack_host ); + The reason that host $failed_ack_host did not receive a valid ACK. + Useful to find out why when ack( $fail_ack_host ) returns a false + value. + $p->close(); Close the network connection for this ping object. The network connection is also closed by "undef $p". The network connection is @@ -167,12 +238,6 @@ DESCRIPTION ping() method. This subroutine is obsolete and may be removed in a future version of Net::Ping. -WARNING - pingecho() or a ping object with the tcp protocol use alarm() to - implement the timeout. So, don't use alarm() in your program while you - are using pingecho() or a ping object with the tcp protocol. The udp and - icmp protocols do not use alarm() to implement the timeout. - NOTES There will be less network overhead (and some efficiency in your program) if you specify either the udp or the icmp protocol. The tcp @@ -204,7 +269,7 @@ NOTES INSTALL The latest source tree is available via cvs: - cvs -z3 -q -d :pserver:anonymous@cvs.roobik.com.:/usr/local/cvsroot/freeware co Net-Ping + cvs -z3 -q -d :pserver:anonymous@cvs.roobik.com.:/usr/local/cvsroot/freeware checkout Net-Ping cd Net-Ping The tarball can be created as follows: @@ -255,7 +320,7 @@ AUTHORS mose@ns.ccsn.edu (Russell Mosemann) COPYRIGHT - Copyright (c) 2002, Rob Brown. All rights reserved. + Copyright (c) 2002-2003, Rob Brown. All rights reserved. Copyright (c) 2001, Colin McMillen. All rights reserved. diff --git a/lib/Net/Ping/t/190_alarm.t b/lib/Net/Ping/t/190_alarm.t new file mode 100644 index 0000000000..513d96ed27 --- /dev/null +++ b/lib/Net/Ping/t/190_alarm.t @@ -0,0 +1,50 @@ +# Test to make sure alarm / SIGALM does not interfere +# with Net::Ping. (This test was derived to ensure +# compatibility with the "spamassassin" utility.) +# Based on code written by radu@netsoft.ro (Radu Greab). + +BEGIN { + unless (eval "require Socket") { + print "1..0 \# Skip: no Socket\n"; + exit; + } + unless (eval {alarm 0; 1;}) { + print "1..0 \# Skip: alarm borks on $^O $^X $] ?\n"; + exit; + } +} + +use strict; +use Test; +use Net::Ping; + +plan tests => 6; + +# Everything compiled +ok 1; + +eval { + my $timeout = 11; + + ok 1; # In eval + local $SIG{ALRM} = sub { die "alarm works" }; + ok 1; # SIGALRM can be set on this platform + alarm $timeout; + ok 1; # alarm() can be set on this platform + + my $start = time; + while (1) { + my $ping = Net::Ping->new("tcp", 2); + # It does not matter if alive or not + $ping->ping("127.0.0.1"); + $ping->ping("172.29.249.249"); + die "alarm failed" if time > $start + $timeout + 1; + } +}; +# Got out of "infinite loop" okay +ok 1; + +# Make sure it died for a good excuse +ok $@ =~ /alarm works/ or die $@; + +alarm 0; # Reset alarm diff --git a/lib/Net/Ping/t/300_ping_stream.t b/lib/Net/Ping/t/300_ping_stream.t index 270650a2c3..ddc36a2ec8 100644 --- a/lib/Net/Ping/t/300_ping_stream.t +++ b/lib/Net/Ping/t/300_ping_stream.t @@ -11,7 +11,14 @@ BEGIN { print "1..0 \# Skip: no Socket\n"; exit; } - unless (getservbyname('echo', 'udp')) { + if (my $port = getservbyname('echo', 'tcp')) { + socket(*ECHO, &Socket::PF_INET(), &Socket::SOCK_STREAM(), (getprotobyname 'tcp')[2]); + unless (connect(*ECHO, scalar &Socket::sockaddr_in($port, &Socket::inet_aton("localhost")))) { + print "1..0 \# Skip: loopback echo service is off ($!)\n"; + exit; + } + close (*ECHO); + } else { print "1..0 \# Skip: no echo port\n"; exit; } @@ -21,11 +28,12 @@ BEGIN { # # NOTE: # The echo service must be enabled on localhost -# to really test the stream protocol ping. +# to really test the stream protocol ping. See +# the end of this document on how to enable it. use Test; use Net::Ping; -plan tests => 12; +plan tests => 22; my $p = new Net::Ping "stream"; @@ -33,16 +41,12 @@ my $p = new Net::Ping "stream"; ok !!$p; # Attempt to connect to the echo port -if ($p -> ping("localhost")) { - ok 1; - # Try several pings while it is connected - for (1..10) { - ok $p -> ping("localhost"); - } -} else { - # Echo port is off, skip the tests - for (2..12) { skip "Local echo port is off", 1; } - exit; +ok ($p -> ping("localhost")); + +# Try several pings while it is connected +for (1..20) { + select (undef,undef,undef,0.1); + ok $p -> ping("localhost"); } __END__ @@ -52,16 +56,19 @@ Just create the following file before restarting xinetd: /etc/xinetd.d/echo: -# description: echo service +# description: An echo server. service echo { - socket_type = stream - wait = no - user = root - server = /bin/cat - disable = no + type = INTERNAL + id = echo-stream + socket_type = stream + protocol = tcp + user = root + wait = no + disable = no } + Or if you are using inetd, before restarting, add this line to your /etc/inetd.conf: diff --git a/lib/Net/Ping/t/400_ping_syn.t b/lib/Net/Ping/t/400_ping_syn.t index 29022d2d09..ae89800d3a 100644 --- a/lib/Net/Ping/t/400_ping_syn.t +++ b/lib/Net/Ping/t/400_ping_syn.t @@ -55,7 +55,13 @@ plan tests => ((keys %{ $webs }) * 2 + 3); # Everything loaded fine ok 1; -alarm(50); +my $can_alarm = eval {alarm 0; 1;}; + +sub Alarm { + alarm(shift) if $can_alarm; +} + +Alarm(50); $SIG{ALRM} = sub { ok 0; die "TIMED OUT!"; @@ -73,13 +79,13 @@ ok ($p -> {port_num} = getservbyname("http", "tcp")); foreach my $host (keys %{ $webs }) { # ping() does dns resolution and # only sends the SYN at this point - alarm(50); # (Plenty for a DNS lookup) + Alarm(50); # (Plenty for a DNS lookup) if (!ok $p -> ping($host)) { print STDERR "CANNOT RESOLVE $host $p->{bad}->{$host}\n"; } } -alarm(20); +Alarm(20); while (my $host = $p->ack()) { if (!ok $webs->{$host}) { print STDERR "SUPPOSED TO BE DOWN: http://$host/\n"; @@ -87,9 +93,9 @@ while (my $host = $p->ack()) { delete $webs->{$host}; } -alarm(0); +Alarm(0); foreach my $host (keys %{ $webs }) { if (!ok !$webs->{$host}) { - print STDERR "DOWN: http://$host/ [$p->{bad}->{$host}]\n"; + print STDERR "DOWN: http://$host/ [",($p->{bad}->{$host} || ""),"]\n"; } } diff --git a/lib/Net/Ping/t/410_syn_host.t b/lib/Net/Ping/t/410_syn_host.t index 38bc7f2909..8374b20623 100644 --- a/lib/Net/Ping/t/410_syn_host.t +++ b/lib/Net/Ping/t/410_syn_host.t @@ -57,7 +57,13 @@ plan tests => ((keys %{ $webs }) * 2 + 3); # Everything loaded fine ok 1; -alarm(50); +my $can_alarm = eval {alarm 0; 1;}; + +sub Alarm { + alarm(shift) if $can_alarm; +} + +Alarm(50); $SIG{ALRM} = sub { ok 0; die "TIMED OUT!"; @@ -75,13 +81,13 @@ ok ($p -> {port_num} = getservbyname("http", "tcp")); foreach my $host (keys %{ $webs }) { # ping() does dns resolution and # only sends the SYN at this point - alarm(50); # (Plenty for a DNS lookup) + Alarm(50); # (Plenty for a DNS lookup) if (!ok($p -> ping($host))) { print STDERR "CANNOT RESOLVE $host $p->{bad}->{$host}\n"; } } -alarm(20); +Alarm(20); foreach my $host (sort keys %{ $webs }) { my $on = $p->ack($host); if (!ok (($on && $webs->{$host}) || @@ -89,11 +95,11 @@ foreach my $host (sort keys %{ $webs }) { if ($on) { print STDERR "SUPPOSED TO BE DOWN: http://$host/\n"; } else { - print STDERR "DOWN: http://$host/ $p->{bad}->{$host}\n"; + print STDERR "DOWN: http://$host/ [",($p->{bad}->{$host} || ""),"]\n"; } } delete $webs->{$host}; - alarm(20); + Alarm(20); } -alarm(0); +Alarm(0); diff --git a/lib/Net/Ping/t/500_ping_icmp.t b/lib/Net/Ping/t/500_ping_icmp.t new file mode 100644 index 0000000000..6b6c3eff27 --- /dev/null +++ b/lib/Net/Ping/t/500_ping_icmp.t @@ -0,0 +1,29 @@ +# Test to perform icmp protocol testing. +# Root access is required. + +BEGIN { + unless (eval "require Socket") { + print "1..0 \# Skip: no Socket\n"; + exit; + } +} + +use Test; +use Net::Ping; +plan tests => 2; + +# Everything loaded fine +ok 1; + +if (($> and $^O ne 'VMS' and $^O ne 'cygwin') + or ($^O eq 'MSWin32' + and Win32::IsWinNT()) + or ($^O eq 'VMS' + and (`write sys\$output f\$privilege("SYSPRV")` =~ m/FALSE/))) { + skip "icmp ping requires root privileges.", 1; +} elsif ($^O eq 'MacOS') { + skip "icmp protocol not supported.", 1; +} else { + my $p = new Net::Ping "icmp"; + ok $p->ping("127.0.0.1"); +} |