net-ping 1.6.2-universal-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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
@@ -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,43 @@
1
+ require 'rubygems'
2
+ require 'rbconfig'
3
+
4
+ Gem::Specification.new do |spec|
5
+ spec.name = 'net-ping'
6
+ spec.version = '1.6.2'
7
+ spec.license = 'Artistic 2.0'
8
+ spec.author = 'Daniel J. Berger'
9
+ spec.email = 'djberg96@gmail.com'
10
+ spec.homepage = 'https://github.com/djberg96/net-ping'
11
+ spec.summary = 'A ping interface for Ruby.'
12
+ spec.test_file = 'test/test_net_ping.rb'
13
+ spec.files = Dir['**/*'].reject{ |f| f.include?('git') }
14
+
15
+ spec.rubyforge_project = 'shards'
16
+ spec.extra_rdoc_files = ['README', 'CHANGES', 'doc/ping.txt']
17
+
18
+ spec.add_dependency('ffi', '>= 1.0.0')
19
+
20
+ spec.add_development_dependency('test-unit', '>= 2.5.0')
21
+ spec.add_development_dependency('fakeweb', '>= 1.3.0')
22
+ spec.add_development_dependency('rake')
23
+
24
+ if File::ALT_SEPARATOR
25
+ require 'rbconfig'
26
+ arch = RbConfig::CONFIG['build_os']
27
+ spec.platform = Gem::Platform.new(['universal', arch])
28
+ spec.platform.version = nil
29
+
30
+ # Used for icmp pings.
31
+ spec.add_dependency('win32-security', '>= 0.2.0')
32
+
33
+ if RUBY_VERSION.to_f < 1.9 && RUBY_PLATFORM != 'java'
34
+ spec.add_dependency('win32-open3', '>= 0.3.1')
35
+ end
36
+ end
37
+
38
+ spec.description = <<-EOF
39
+ The net-ping library provides a ping interface for Ruby. It includes
40
+ separate TCP, HTTP, LDAP, ICMP, UDP, WMI (for Windows) and external ping
41
+ classes.
42
+ EOF
43
+ end
@@ -0,0 +1,35 @@
1
+ ######################################################################
2
+ # test_net_ping.rb
3
+ #
4
+ # Test suite for all the Ping subclasses. Note that the Ping::ICMP
5
+ # class test won't be run unless this is run as a privileged process.
6
+ ######################################################################
7
+ require 'test_net_ping_external'
8
+ require 'test_net_ping_http'
9
+ require 'test_net_ping_tcp'
10
+ require 'test_net_ping_udp'
11
+ require 'fakeweb'
12
+
13
+ if File::ALT_SEPARATOR
14
+ require 'win32/security'
15
+
16
+ if Win32::Security.elevated_security?
17
+ require 'test_net_ping_icmp'
18
+ end
19
+ else
20
+ if Process.euid == 0
21
+ require 'test_net_ping_icmp'
22
+ end
23
+ end
24
+
25
+ if File::ALT_SEPARATOR
26
+ require 'test_net_ping_wmi'
27
+ end
28
+
29
+ class TC_Net_Ping < Test::Unit::TestCase
30
+ def test_net_ping_version
31
+ assert_equal('1.6.2', Net::Ping::VERSION)
32
+ end
33
+ end
34
+
35
+ FakeWeb.allow_net_connect = false
@@ -0,0 +1,129 @@
1
+ #########################################################################
2
+ # test_net_ping_external.rb
3
+ #
4
+ # Test case for the Net::PingExternal class. Run this via the 'test' or
5
+ # 'test:external' rake task.
6
+ #
7
+ # WARNING: I've noticed that test failures will occur if you're using
8
+ # OpenDNS. This is apparently caused by them messing with upstream
9
+ # replies for advertising purposes.
10
+ #########################################################################
11
+ require 'test-unit'
12
+ require 'net/ping/external'
13
+
14
+ class TC_Net_Ping_External < Test::Unit::TestCase
15
+ def setup
16
+ @host = 'localhost'
17
+ @bogus = 'foo.bar.baz'
18
+ @pe = Net::Ping::External.new(@host)
19
+ @bad = Net::Ping::External.new(@bogus)
20
+ end
21
+
22
+ test "ping basic functionality" do
23
+ assert_respond_to(@pe, :ping)
24
+ end
25
+
26
+ test "ping with no arguments" do
27
+ assert_nothing_raised{ @pe.ping }
28
+ end
29
+
30
+ test "ping accepts a hostname" do
31
+ assert_nothing_raised{ @pe.ping(@host) }
32
+ end
33
+
34
+ test "ping returns a boolean" do
35
+ assert_boolean(@pe.ping)
36
+ assert_boolean(@bad.ping)
37
+ end
38
+
39
+ test "ping? alias" do
40
+ assert_respond_to(@pe, :ping?)
41
+ assert_alias_method(@pe, :ping?, :ping)
42
+ end
43
+
44
+ test "pingecho alias" do
45
+ assert_nothing_raised{ @pe.pingecho }
46
+ assert_alias_method(@pe, :pingecho, :ping)
47
+ end
48
+
49
+ test "pinging a good host returns true" do
50
+ assert_true(@pe.ping?)
51
+ end
52
+
53
+ test "pinging a bogus host returns false" do
54
+ assert_false(@bad.ping?)
55
+ end
56
+
57
+ test "duration basic functionality" do
58
+ assert_nothing_raised{ @pe.ping }
59
+ assert_respond_to(@pe, :duration)
60
+ assert_kind_of(Float, @pe.duration)
61
+ end
62
+
63
+ test "duration is unset if a bad ping follows a good ping" do
64
+ assert_nothing_raised{ @pe.ping }
65
+ assert_not_nil(@pe.duration)
66
+ assert_false(@pe.ping?(@bogus))
67
+ assert_nil(@pe.duration)
68
+ end
69
+
70
+ test "host getter basic functionality" do
71
+ assert_respond_to(@pe, :host)
72
+ assert_equal('localhost', @pe.host)
73
+ end
74
+
75
+ test "host setter basic functionality" do
76
+ assert_respond_to(@pe, :host=)
77
+ assert_nothing_raised{ @pe.host = @bad }
78
+ assert_equal(@bad, @pe.host)
79
+ end
80
+
81
+ test "port getter basic functionality" do
82
+ assert_respond_to(@pe, :port)
83
+ assert_equal(7, @pe.port)
84
+ end
85
+
86
+ test "port setter basic functionality" do
87
+ assert_respond_to(@pe, :port=)
88
+ assert_nothing_raised{ @pe.port = 90 }
89
+ assert_equal(90, @pe.port)
90
+ end
91
+
92
+ test "timeout getter basic functionality" do
93
+ assert_respond_to(@pe, :timeout)
94
+ assert_equal(5, @pe.timeout)
95
+ end
96
+
97
+ test "timeout setter basic functionality" do
98
+ assert_respond_to(@pe, :timeout=)
99
+ assert_nothing_raised{ @pe.timeout = 30 }
100
+ assert_equal(30, @pe.timeout)
101
+ end
102
+
103
+ test "exception method basic functionality" do
104
+ assert_respond_to(@pe, :exception)
105
+ assert_nil(@pe.exception)
106
+ end
107
+
108
+ test "pinging a bogus host stores exception data" do
109
+ assert_nothing_raised{ @bad.ping? }
110
+ assert_not_nil(@bad.exception)
111
+ end
112
+
113
+ test "pinging a good host results in no exception data" do
114
+ assert_nothing_raised{ @pe.ping }
115
+ assert_nil(@pe.exception)
116
+ end
117
+
118
+ test "warning basic functionality" do
119
+ assert_respond_to(@pe, :warning)
120
+ assert_nil(@pe.warning)
121
+ end
122
+
123
+ def teardown
124
+ @host = nil
125
+ @bogus = nil
126
+ @pe = nil
127
+ @bad = nil
128
+ end
129
+ end