net-ping 1.3.3-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +189 -0
- data/MANIFEST +23 -0
- data/README +48 -0
- data/Rakefile +84 -0
- data/doc/ping.txt +249 -0
- data/examples/example_pingexternal.rb +16 -0
- data/examples/example_pinghttp.rb +22 -0
- data/examples/example_pingtcp.rb +16 -0
- data/examples/example_pingudp.rb +12 -0
- data/lib/net/ping.rb +17 -0
- data/lib/net/ping/external.rb +126 -0
- data/lib/net/ping/http.rb +98 -0
- data/lib/net/ping/icmp.rb +165 -0
- data/lib/net/ping/ping.rb +88 -0
- data/lib/net/ping/tcp.rb +83 -0
- data/lib/net/ping/udp.rb +119 -0
- data/lib/net/ping/wmi.rb +118 -0
- data/net-ping.gemspec +38 -0
- data/test/test_net_ping.rb +26 -0
- data/test/test_net_ping_external.rb +87 -0
- data/test/test_net_ping_http.rb +115 -0
- data/test/test_net_ping_icmp.rb +126 -0
- data/test/test_net_ping_tcp.rb +108 -0
- data/test/test_net_ping_udp.rb +122 -0
- data/test/test_net_ping_wmi.rb +84 -0
- metadata +129 -0
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'timeout'
|
3
|
+
|
4
|
+
# The Net module serves as a namespace only.
|
5
|
+
#
|
6
|
+
module Net
|
7
|
+
|
8
|
+
# The Ping class serves as an abstract base class for all other Ping class
|
9
|
+
# types. You should not instantiate this class directly.
|
10
|
+
#
|
11
|
+
class Ping
|
12
|
+
# The version of the net-ping library.
|
13
|
+
VERSION = '1.3.3'
|
14
|
+
|
15
|
+
# The host to ping. In the case of Ping::HTTP, this is the URI.
|
16
|
+
attr_accessor :host
|
17
|
+
|
18
|
+
# The port to ping. This is set to the echo port (7) by default. The
|
19
|
+
# Ping::HTTP class defaults to port 80.
|
20
|
+
#
|
21
|
+
attr_accessor :port
|
22
|
+
|
23
|
+
# The maximum time a ping attempt is made.
|
24
|
+
attr_accessor :timeout
|
25
|
+
|
26
|
+
# If a ping fails, this value is set to the error that occurred which
|
27
|
+
# caused it to fail.
|
28
|
+
#
|
29
|
+
attr_reader :exception
|
30
|
+
|
31
|
+
# This value is set if a ping succeeds, but some other condition arose
|
32
|
+
# during the ping attempt which merits warning, e.g a redirect in the
|
33
|
+
# case of Ping::HTTP#ping.
|
34
|
+
#
|
35
|
+
attr_reader :warning
|
36
|
+
|
37
|
+
# The number of seconds (returned as a Float) that it took to ping
|
38
|
+
# the host. This is not a precise value, but rather a good estimate
|
39
|
+
# since there is a small amount of internal calculation that is added
|
40
|
+
# to the overall time.
|
41
|
+
#
|
42
|
+
attr_reader :duration
|
43
|
+
|
44
|
+
# The default constructor for the Net::Ping class. Accepts an optional
|
45
|
+
# +host+, +port+ and +timeout+. The port defaults to your echo port, or
|
46
|
+
# 7 if that happens to be undefined. The default timeout is 5 seconds.
|
47
|
+
#
|
48
|
+
# The host, although optional in the constructor, must be specified at
|
49
|
+
# some point before the Net::Ping#ping method is called, or else an
|
50
|
+
# ArgumentError will be raised.
|
51
|
+
#
|
52
|
+
# Yields +self+ in block context.
|
53
|
+
#
|
54
|
+
# This class is not meant to be instantiated directly. It is strictly
|
55
|
+
# meant as an interface for subclasses.
|
56
|
+
#
|
57
|
+
def initialize(host=nil, port=nil, timeout=5)
|
58
|
+
@host = host
|
59
|
+
@port = port || Socket.getservbyname('echo') || 7
|
60
|
+
@timeout = timeout
|
61
|
+
@exception = nil
|
62
|
+
@warning = nil
|
63
|
+
@duration = nil
|
64
|
+
|
65
|
+
yield self if block_given?
|
66
|
+
end
|
67
|
+
|
68
|
+
# The default interface for the Net::Ping#ping method. Each subclass
|
69
|
+
# should call super() before continuing with their own implementation in
|
70
|
+
# order to ensure that the @exception and @warning instance variables
|
71
|
+
# are reset.
|
72
|
+
#
|
73
|
+
# If +host+ is nil here, then it will use the host specified in the
|
74
|
+
# constructor. If the +host+ is nil and there was no host specified
|
75
|
+
# in the constructor then an ArgumentError is raised.
|
76
|
+
#--
|
77
|
+
# The @duration should be set in the subclass' ping method.
|
78
|
+
#
|
79
|
+
def ping(host = @host)
|
80
|
+
raise ArgumentError, 'no host specified' unless host
|
81
|
+
@exception = nil
|
82
|
+
@warning = nil
|
83
|
+
end
|
84
|
+
|
85
|
+
alias ping? ping
|
86
|
+
alias pingecho ping
|
87
|
+
end
|
88
|
+
end
|
data/lib/net/ping/tcp.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'ping')
|
2
|
+
|
3
|
+
# The Net module serves as a namespace only.
|
4
|
+
module Net
|
5
|
+
|
6
|
+
# With a TCP ping simply try to open a connection. If we are successful,
|
7
|
+
# assume success. In either case close the connection to be polite.
|
8
|
+
#
|
9
|
+
class Ping::TCP < Ping
|
10
|
+
@@service_check = false
|
11
|
+
|
12
|
+
# Returns whether or not Errno::ECONNREFUSED is considered a successful
|
13
|
+
# ping. The default is false.
|
14
|
+
#
|
15
|
+
def self.service_check
|
16
|
+
@@service_check
|
17
|
+
end
|
18
|
+
|
19
|
+
# Sets whether or not an Errno::ECONNREFUSED should be considered a
|
20
|
+
# successful ping.
|
21
|
+
#
|
22
|
+
def self.service_check=(bool)
|
23
|
+
unless bool.kind_of?(TrueClass) || bool.kind_of?(FalseClass)
|
24
|
+
raise ArgumentError, 'argument must be true or false'
|
25
|
+
end
|
26
|
+
@@service_check = bool
|
27
|
+
end
|
28
|
+
|
29
|
+
# This method attempts to ping a host and port using a TCPSocket with
|
30
|
+
# the host, port and timeout values passed in the constructor. Returns
|
31
|
+
# true if successful, or false otherwise.
|
32
|
+
#
|
33
|
+
# Note that, by default, an Errno::ECONNREFUSED return result will be
|
34
|
+
# considered a failed ping. See the documentation for the
|
35
|
+
# Ping::TCP.service_check= method if you wish to change this behavior.
|
36
|
+
#
|
37
|
+
def ping(host=@host)
|
38
|
+
super(host)
|
39
|
+
|
40
|
+
bool = false
|
41
|
+
tcp = nil
|
42
|
+
start_time = Time.now
|
43
|
+
|
44
|
+
begin
|
45
|
+
Timeout.timeout(@timeout){
|
46
|
+
begin
|
47
|
+
tcp = TCPSocket.new(host, @port)
|
48
|
+
rescue Errno::ECONNREFUSED => err
|
49
|
+
if @@service_check
|
50
|
+
bool = true
|
51
|
+
else
|
52
|
+
@exception = err
|
53
|
+
end
|
54
|
+
rescue Exception => err
|
55
|
+
@exception = err
|
56
|
+
else
|
57
|
+
bool = true
|
58
|
+
end
|
59
|
+
}
|
60
|
+
rescue Timeout::Error => err
|
61
|
+
@exception = err
|
62
|
+
ensure
|
63
|
+
tcp.close if tcp
|
64
|
+
end
|
65
|
+
|
66
|
+
# There is no duration if the ping failed
|
67
|
+
@duration = Time.now - start_time if bool
|
68
|
+
|
69
|
+
bool
|
70
|
+
end
|
71
|
+
|
72
|
+
alias ping? ping
|
73
|
+
alias pingecho ping
|
74
|
+
|
75
|
+
# Class method aliases. DEPRECATED.
|
76
|
+
class << self
|
77
|
+
alias econnrefused service_check
|
78
|
+
alias econnrefused= service_check=
|
79
|
+
alias ecr service_check
|
80
|
+
alias ecr= service_check=
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/net/ping/udp.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'ping')
|
2
|
+
|
3
|
+
# The Net module serves as a namespace only.
|
4
|
+
module Net
|
5
|
+
|
6
|
+
# The Ping::UDP class encapsulates methods for UDP pings.
|
7
|
+
class Ping::UDP < Ping
|
8
|
+
@@service_check = true
|
9
|
+
|
10
|
+
# Returns whether or not the connect behavior should enforce remote
|
11
|
+
# service availability as well as reachability. The default is true.
|
12
|
+
#
|
13
|
+
def self.service_check
|
14
|
+
@@service_check
|
15
|
+
end
|
16
|
+
|
17
|
+
# Set whether or not the connect behavior should enforce remote
|
18
|
+
# service availability as well as reachability. If set to false
|
19
|
+
# then Errno::ECONNREFUSED or Errno::ECONNRESET will be considered
|
20
|
+
# a successful ping, meaning no actual data handshaking is required.
|
21
|
+
# By default, if either of those errors occurs it is considered a failed
|
22
|
+
# ping.
|
23
|
+
#
|
24
|
+
def self.service_check=(bool)
|
25
|
+
unless bool.kind_of?(TrueClass) || bool.kind_of?(FalseClass)
|
26
|
+
raise ArgumentError, 'argument must be true or false'
|
27
|
+
end
|
28
|
+
@@service_check = bool
|
29
|
+
end
|
30
|
+
|
31
|
+
# The maximum data size that can be sent in a UDP ping.
|
32
|
+
MAX_DATA = 64
|
33
|
+
|
34
|
+
# The data to send to the remote host. By default this is 'ping'.
|
35
|
+
# This should be MAX_DATA size characters or less.
|
36
|
+
#
|
37
|
+
attr_reader :data
|
38
|
+
|
39
|
+
# Creates and returns a new Ping::UDP object. This is effectively
|
40
|
+
# identical to its superclass constructor.
|
41
|
+
#
|
42
|
+
def initialize(host=nil, port=nil, timeout=5)
|
43
|
+
@data = 'ping'
|
44
|
+
|
45
|
+
super(host, port, timeout)
|
46
|
+
|
47
|
+
@bind_host = nil
|
48
|
+
@bind_port = nil
|
49
|
+
end
|
50
|
+
|
51
|
+
# Sets the data string sent to the remote host. This value cannot have
|
52
|
+
# a size greater than MAX_DATA.
|
53
|
+
#
|
54
|
+
def data=(string)
|
55
|
+
if string.size > MAX_DATA
|
56
|
+
err = "cannot set data string larger than #{MAX_DATA} characters"
|
57
|
+
raise ArgumentError, err
|
58
|
+
end
|
59
|
+
|
60
|
+
@data = string
|
61
|
+
end
|
62
|
+
|
63
|
+
# Associates the local end of the UDP connection with the given +host+
|
64
|
+
# and +port+. This is essentially a wrapper for UDPSocket#bind.
|
65
|
+
#
|
66
|
+
def bind(host, port)
|
67
|
+
@bind_host = host
|
68
|
+
@bind_port = port
|
69
|
+
end
|
70
|
+
|
71
|
+
# Sends a simple text string to the host and checks the return string. If
|
72
|
+
# the string sent and the string returned are a match then the ping was
|
73
|
+
# successful and true is returned. Otherwise, false is returned.
|
74
|
+
#
|
75
|
+
def ping(host = @host)
|
76
|
+
super(host)
|
77
|
+
|
78
|
+
bool = false
|
79
|
+
udp = UDPSocket.open
|
80
|
+
array = []
|
81
|
+
|
82
|
+
if @bind_host
|
83
|
+
udp.bind(@bind_host, @bind_port)
|
84
|
+
end
|
85
|
+
|
86
|
+
start_time = Time.now
|
87
|
+
|
88
|
+
begin
|
89
|
+
Timeout.timeout(@timeout){
|
90
|
+
udp.connect(host, @port)
|
91
|
+
udp.send(@data, 0)
|
92
|
+
array = udp.recvfrom(MAX_DATA)
|
93
|
+
}
|
94
|
+
rescue Errno::ECONNREFUSED, Errno::ECONNRESET => err
|
95
|
+
if @@service_check
|
96
|
+
@exception = err
|
97
|
+
else
|
98
|
+
bool = true
|
99
|
+
end
|
100
|
+
rescue Exception => err
|
101
|
+
@exception = err
|
102
|
+
else
|
103
|
+
if array[0] == @data
|
104
|
+
bool = true
|
105
|
+
end
|
106
|
+
ensure
|
107
|
+
udp.close if udp
|
108
|
+
end
|
109
|
+
|
110
|
+
# There is no duration if the ping failed
|
111
|
+
@duration = Time.now - start_time if bool
|
112
|
+
|
113
|
+
bool
|
114
|
+
end
|
115
|
+
|
116
|
+
alias ping? ping
|
117
|
+
alias pingecho ping
|
118
|
+
end
|
119
|
+
end
|
data/lib/net/ping/wmi.rb
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'ping')
|
2
|
+
require 'win32ole'
|
3
|
+
|
4
|
+
# The Net module serves as a namespace only.
|
5
|
+
#
|
6
|
+
module Net
|
7
|
+
|
8
|
+
# The Ping::WMI class encapsulates the Win32_PingStatus WMI class for
|
9
|
+
# MS Windows.
|
10
|
+
#
|
11
|
+
class Ping::WMI < Ping
|
12
|
+
|
13
|
+
PingStatus = Struct.new(
|
14
|
+
'PingStatus',
|
15
|
+
:address,
|
16
|
+
:buffer_size,
|
17
|
+
:no_fragmentation,
|
18
|
+
:primary_address_resolution_status,
|
19
|
+
:protocol_address,
|
20
|
+
:protocol_address_resolved,
|
21
|
+
:record_route,
|
22
|
+
:reply_inconsistency,
|
23
|
+
:reply_size,
|
24
|
+
:resolve_address_names,
|
25
|
+
:response_time,
|
26
|
+
:response_time_to_live,
|
27
|
+
:route_record,
|
28
|
+
:route_record_resolved,
|
29
|
+
:source_route,
|
30
|
+
:source_route_type,
|
31
|
+
:status_code,
|
32
|
+
:timeout,
|
33
|
+
:timestamp_record,
|
34
|
+
:timestamp_record_address,
|
35
|
+
:timestamp_record_address_resolved,
|
36
|
+
:timestamp_route,
|
37
|
+
:time_to_live,
|
38
|
+
:type_of_service
|
39
|
+
)
|
40
|
+
|
41
|
+
# Unlike the ping method for other Ping subclasses, this version returns
|
42
|
+
# a PingStatus struct which contains various bits of information about
|
43
|
+
# the results of the ping itself, such as response time.
|
44
|
+
#
|
45
|
+
# In addition, this version allows you to pass certain options that are
|
46
|
+
# then passed on to the underlying WQL query. See the MSDN documentation
|
47
|
+
# on Win32_PingStatus for details.
|
48
|
+
#
|
49
|
+
# Examples:
|
50
|
+
#
|
51
|
+
# # Ping with no options
|
52
|
+
# Ping::WMI.ping('www.perl.com')
|
53
|
+
#
|
54
|
+
# # Ping with options
|
55
|
+
# Ping::WMI.ping('www.perl.com', :BufferSize => 64, :NoFragmentation => true)
|
56
|
+
#--
|
57
|
+
# The PingStatus struct is a wrapper for the Win32_PingStatus WMI class.
|
58
|
+
#
|
59
|
+
def ping(host = @host, options = {})
|
60
|
+
super(host)
|
61
|
+
|
62
|
+
lhost = Socket.gethostname
|
63
|
+
|
64
|
+
cs = "winmgmts:{impersonationLevel=impersonate}!//#{lhost}/root/cimv2"
|
65
|
+
wmi = WIN32OLE.connect(cs)
|
66
|
+
|
67
|
+
query = "select * from win32_pingstatus where address = '#{host}'"
|
68
|
+
|
69
|
+
unless options.empty?
|
70
|
+
options.each{ |key, value|
|
71
|
+
if value.is_a?(String)
|
72
|
+
query << " and #{key} = '#{value}'"
|
73
|
+
else
|
74
|
+
query << " and #{key} = #{value}"
|
75
|
+
end
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
status = Struct::PingStatus.new
|
80
|
+
|
81
|
+
wmi.execquery(query).each{ |obj|
|
82
|
+
status.address = obj.Address
|
83
|
+
status.buffer_size = obj.BufferSize
|
84
|
+
status.no_fragmentation = obj.NoFragmentation
|
85
|
+
status.primary_address_resolution_status = obj.PrimaryAddressResolutionStatus
|
86
|
+
status.protocol_address = obj.ProtocolAddress
|
87
|
+
status.protocol_address_resolved = obj.ProtocolAddressResolved
|
88
|
+
status.record_route = obj.RecordRoute
|
89
|
+
status.reply_inconsistency = obj.ReplyInconsistency
|
90
|
+
status.reply_size = obj.ReplySize
|
91
|
+
status.resolve_address_names = obj.ResolveAddressNames
|
92
|
+
status.response_time = obj.ResponseTime
|
93
|
+
status.response_time_to_live = obj.ResponseTimeToLive
|
94
|
+
status.route_record = obj.RouteRecord
|
95
|
+
status.route_record_resolved = obj.RouteRecordResolved
|
96
|
+
status.source_route = obj.SourceRoute
|
97
|
+
status.source_route_type = obj.SourceRouteType
|
98
|
+
status.status_code = obj.StatusCode
|
99
|
+
status.timeout = obj.Timeout
|
100
|
+
status.timestamp_record = obj.TimeStampRecord
|
101
|
+
status.timestamp_record_address = obj.TimeStampRecordAddress
|
102
|
+
status.timestamp_record_address_resolved = obj.TimeStampRecordAddressResolved
|
103
|
+
status.timestamp_route = obj.TimeStampRoute
|
104
|
+
status.time_to_live = obj.TimeToLive
|
105
|
+
status.type_of_service = obj.TypeOfService
|
106
|
+
}
|
107
|
+
|
108
|
+
status.freeze # Read-only data
|
109
|
+
end
|
110
|
+
|
111
|
+
# Unlike Net::Ping::WMI#ping, this method returns true or false to
|
112
|
+
# indicate whether or not the ping was successful.
|
113
|
+
#
|
114
|
+
def ping?(host = @host, options = {})
|
115
|
+
ping(host, options).status_code == 0
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
data/net-ping.gemspec
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rbconfig'
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = 'net-ping'
|
6
|
+
gem.version = '1.3.3'
|
7
|
+
gem.license = 'Artistic 2.0'
|
8
|
+
gem.author = 'Daniel J. Berger'
|
9
|
+
gem.email = 'djberg96@gmail.com'
|
10
|
+
gem.homepage = 'http://www.rubyforge.org/projects/shards'
|
11
|
+
gem.summary = 'A ping interface for Ruby.'
|
12
|
+
gem.test_file = 'test/test_net_ping.rb'
|
13
|
+
gem.has_rdoc = true
|
14
|
+
gem.files = Dir['**/*'].reject{ |f| f.include?('git') }
|
15
|
+
|
16
|
+
gem.rubyforge_project = 'shards'
|
17
|
+
gem.extra_rdoc_files = ['README', 'CHANGES', 'doc/ping.txt']
|
18
|
+
|
19
|
+
gem.add_development_dependency('test-unit', '>= 2.0.9')
|
20
|
+
|
21
|
+
# These dependencies are for Net::Ping::External
|
22
|
+
if Config::CONFIG['host_os'] =~ /mswin|dos|win32|cygwin|mingw/i &&
|
23
|
+
RUBY_PLATFORM != 'java'
|
24
|
+
then
|
25
|
+
gem.platform = Gem::Platform::CURRENT
|
26
|
+
gem.add_dependency('windows-pr', '>= 1.0.8')
|
27
|
+
|
28
|
+
if RUBY_VERSION.to_f < 1.9
|
29
|
+
gem.add_dependency('win32-open3', '>= 0.3.1')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
gem.description = <<-EOF
|
34
|
+
The net-ping library provides a ping interface for Ruby. It includes
|
35
|
+
separate TCP, HTTP, ICMP, UDP, WMI (for Windows) and external ping
|
36
|
+
classes.
|
37
|
+
EOF
|
38
|
+
end
|