net-ping 1.2.2-x86-mswin32-60

Sign up to get free protection for your applications and to get access to all the features.
data/lib/net/ping.rb ADDED
@@ -0,0 +1,11 @@
1
+ # By doing a "require 'net/ping'" you are requiring every subclass. If you
2
+ # want to require a specific ping type only, do "require 'net/ping/tcp'",
3
+ # for example.
4
+ #
5
+ $LOAD_PATH.unshift File.dirname(__FILE__)
6
+
7
+ require 'ping/tcp'
8
+ require 'ping/udp'
9
+ require 'ping/icmp'
10
+ require 'ping/external'
11
+ require 'ping/http'
@@ -0,0 +1,107 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__)
2
+ require 'ping'
3
+
4
+ if RUBY_PLATFORM.match('mswin')
5
+ require 'win32/open3'
6
+ require 'windows/console'
7
+ include Windows::Console
8
+ else
9
+ require 'open3'
10
+ end
11
+
12
+ module Net
13
+ class Ping::External < Ping
14
+
15
+ # Pings the host using your system's ping utility and checks for any
16
+ # errors or warnings. Returns true if boolful, or false if not.
17
+ #
18
+ # If false, then the Ping::External#exception method should contain a
19
+ # string indicating what went wrong. If true, the Ping::External#warning
20
+ # method may or may not contain a value.
21
+ #
22
+ def ping(host = @host)
23
+ super(host)
24
+
25
+ input, output, error = ""
26
+ pstring = "ping "
27
+ bool = false
28
+ orig_cp = nil
29
+
30
+ case RUBY_PLATFORM
31
+ when /linux|bsd|osx|mach|darwin/i
32
+ pstring += "-c 1 #{host}"
33
+ when /solaris|sunos/i
34
+ pstring += "#{host} 1"
35
+ when /hpux/i
36
+ pstring += "#{host} -n 1"
37
+ when /win32|windows|mswin/i
38
+ orig_cp = GetConsoleCP()
39
+ SetConsoleCP(437) if orig_cp != 437 # United States
40
+ pstring += "-n 1 #{host}"
41
+ else
42
+ pstring += "#{host}"
43
+ end
44
+
45
+ start_time = Time.now
46
+
47
+ begin
48
+ e = nil
49
+ Timeout.timeout(@timeout){
50
+ input, output, error = Open3.popen3(pstring)
51
+ e = error.gets # Can't chomp yet, might be nil
52
+ }
53
+
54
+ input.close
55
+ error.close
56
+
57
+ if RUBY_PLATFORM.match('mswin') && GetConsoleCP() != orig_cp
58
+ SetConsoleCP(orig_cp)
59
+ end
60
+
61
+ unless e.nil?
62
+ if e =~ /warning/i
63
+ @warning = e.chomp
64
+ bool = true
65
+ else
66
+ @exception = e.chomp
67
+ end
68
+ # The "no answer" response goes to stdout, not stderr, so check it
69
+ else
70
+ lines = output.readlines
71
+ output.close
72
+ if lines.nil? || lines.empty?
73
+ bool = true
74
+ else
75
+ regexp = /
76
+ no\ answer|
77
+ host\ unreachable|
78
+ could\ not\ find\ host|
79
+ request\ timed\ out|
80
+ 100%\ packet\ loss
81
+ /ix
82
+ lines.each{ |e|
83
+ if regexp.match(e)
84
+ @exception = e.chomp
85
+ break
86
+ end
87
+ }
88
+ bool = true unless @exception
89
+ end
90
+ end
91
+ rescue Exception => err
92
+ @exception = err.message
93
+ end
94
+
95
+ # There is no duration if the ping failed
96
+ @duration = Time.now - start_time if bool
97
+
98
+ bool
99
+ end
100
+
101
+ alias ping? ping
102
+ alias pingecho ping
103
+ end
104
+
105
+ # Class alias for backwards compatibility.
106
+ PingExternal = Ping::External
107
+ end
@@ -0,0 +1,88 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__)
2
+ require 'ping'
3
+ require 'net/http'
4
+ require 'uri'
5
+
6
+ # Force non-blocking Socket.getaddrinfo on Unix systems. Do not use on
7
+ # Windows because it causes problems.
8
+ unless RUBY_PLATFORM.match('mswin')
9
+ require 'resolv-replace'
10
+ end
11
+
12
+ module Net
13
+ class Ping::HTTP < Ping
14
+
15
+ # By default an http ping will follow a redirect and give you the result
16
+ # of the final URI. If this value is set to false, then it will not
17
+ # follow a redirect and will return false immediately on a redirect.
18
+ #
19
+ attr_accessor :follow_redirect
20
+
21
+ # Creates and returns a new Ping::HTTP object. Note that the default
22
+ # port for Ping::HTTP is 80.
23
+ #
24
+ def initialize(uri=nil, port=80, timeout=5)
25
+ @follow_redirect = true
26
+ super(uri, port, timeout)
27
+ end
28
+
29
+ # Looks for an HTTP response from the URI passed to the constructor.
30
+ # If the result is a kind of Net::HTTPSuccess then the ping was
31
+ # boolful and true is returned. Otherwise, false is returned
32
+ # and the Ping::HTTP#exception method should contain a string
33
+ # indicating what went wrong.
34
+ #
35
+ # If the HTTP#follow_redirect accessor is set to true (which it is
36
+ # by default) and a redirect occurs during the ping, then the
37
+ # HTTP#warning attribute is set to the redirect message, but the
38
+ # return result is still true. If it's set to false then a false
39
+ # value is returned if a redirect occurs.
40
+ #
41
+ def ping(host = @host)
42
+ super(host)
43
+ bool = false
44
+ uri = URI.parse(host)
45
+
46
+ start_time = Time.now
47
+
48
+ begin
49
+ response = nil
50
+ Timeout.timeout(@timeout){
51
+ response = Net::HTTP.get_response(uri.host, uri.path, @port)
52
+ }
53
+ rescue Exception => err
54
+ @exception = err.message
55
+ else
56
+ if response.is_a?(Net::HTTPSuccess)
57
+ bool = true
58
+ else
59
+ if @follow_redirect
60
+ @warning = response.message
61
+ while response.is_a?(Net::HTTPRedirection)
62
+ redirect = URI.parse(response['location'])
63
+ redirect = uri + redirect if redirect.relative?
64
+ response = Net::HTTP.get_response(redirect.host, redirect.path, @port)
65
+ end
66
+ bool = true if response.is_a?(Net::HTTPSuccess)
67
+ else
68
+ @exception = response.message
69
+ end
70
+ end
71
+ end
72
+
73
+ # There is no duration if the ping failed
74
+ @duration = Time.now - start_time if bool
75
+
76
+ bool
77
+ end
78
+
79
+ alias ping? ping
80
+ alias pingecho ping
81
+ alias follow_redirect? follow_redirect
82
+ alias uri host
83
+ alias uri= host=
84
+ end
85
+
86
+ # Class alias for backwards compatibility
87
+ PingHTTP = Ping::HTTP
88
+ end
@@ -0,0 +1,165 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__)
2
+ require 'ping'
3
+
4
+ module Net
5
+ class Ping::ICMP < Ping
6
+ ICMP_ECHOREPLY = 0
7
+ ICMP_ECHO = 8
8
+ ICMP_SUBCODE = 0
9
+
10
+ # You cannot set or change the port value. A value of 0 is always
11
+ # used internally for ICMP pings.
12
+ #
13
+ undef_method :port=
14
+
15
+ # Returns the data size, i.e. number of bytes sent on the ping. The
16
+ # default size is 56.
17
+ #
18
+ attr_reader :data_size
19
+
20
+ # Creates and returns a new Ping::ICMP object. This is similar to its
21
+ # superclass constructor, but must be created with root privileges (on
22
+ # UNIX systems), and the port value is ignored.
23
+ #
24
+ def initialize(host=nil, port=nil, timeout=5)
25
+ raise 'requires root privileges' if Process.euid > 0
26
+
27
+ @seq = 0
28
+ @bind_port = 0
29
+ @bind_host = nil
30
+ @data_size = 56
31
+ @data = ''
32
+
33
+ 0.upto(@data_size){ |n| @data << (n % 256).chr }
34
+
35
+ @pid = Process.pid & 0xffff
36
+
37
+ super(host, port, timeout)
38
+ @port = nil # This value is not used in ICMP pings.
39
+ end
40
+
41
+ # Sets the number of bytes sent in the ping method.
42
+ #
43
+ def data_size=(size)
44
+ @data_size = size
45
+ @data = ''
46
+ 0.upto(size){ |n| @data << (n % 256).chr }
47
+ end
48
+
49
+ # Associates the local end of the socket connection with the given
50
+ # +host+ and +port+. The default port is 0.
51
+ #
52
+ def bind(host, port = 0)
53
+ @bind_host = host
54
+ @bind_port = port
55
+ end
56
+
57
+ # Pings the +host+ specified in this method or in the constructor. If a
58
+ # host was not specified either here or in the constructor, an
59
+ # ArgumentError is raised.
60
+ #
61
+ def ping(host = @host)
62
+ super(host)
63
+ bool = false
64
+
65
+ socket = Socket.new(
66
+ Socket::PF_INET,
67
+ Socket::SOCK_RAW,
68
+ Socket::IPPROTO_ICMP
69
+ )
70
+
71
+ if @bind_host
72
+ saddr = Socket.pack_sockaddr_in(@bind_port, @bind_host)
73
+ socket.bind(saddr)
74
+ end
75
+
76
+ @seq = (@seq + 1) % 65536
77
+ pstring = 'C2 n3 A' << @data_size.to_s
78
+ timeout = @timeout
79
+
80
+ checksum = 0
81
+ msg = [ICMP_ECHO, ICMP_SUBCODE, checksum, @pid, @seq, @data].pack(pstring)
82
+ checksum = checksum(msg)
83
+ msg = [ICMP_ECHO, ICMP_SUBCODE, checksum, @pid, @seq, @data].pack(pstring)
84
+
85
+ start_time = Time.now
86
+
87
+ begin
88
+ saddr = Socket.pack_sockaddr_in(0, host)
89
+ rescue Exception
90
+ return bool
91
+ end
92
+
93
+ socket.send(msg, 0, saddr) # Send the message
94
+
95
+ begin
96
+ Timeout.timeout(@timeout){
97
+ io_array = select([socket], nil, nil, timeout)
98
+
99
+ if io_array.nil? || io_array[0].empty?
100
+ return false
101
+ end
102
+
103
+ pid = nil
104
+ seq = nil
105
+
106
+ data, sender = socket.recvfrom(1500)
107
+ port, host = Socket.unpack_sockaddr_in(sender)
108
+ type, subcode = data[20, 2].unpack('C2')
109
+
110
+ case type
111
+ when ICMP_ECHOREPLY
112
+ if data.length >= 28
113
+ pid, seq = data[24, 4].unpack('n3')
114
+ end
115
+ else
116
+ if data.length > 56
117
+ pid, seq = data[52, 4].unpack('n3')
118
+ end
119
+ end
120
+
121
+ if pid == @pid && seq == @seq && type == ICMP_ECHOREPLY
122
+ bool = true
123
+ end
124
+ }
125
+ rescue Exception => err
126
+ @exception = err
127
+ ensure
128
+ socket.close if socket
129
+ end
130
+
131
+ # There is no duration if the ping failed
132
+ @duration = Time.now - start_time if bool
133
+
134
+ return bool
135
+ end
136
+
137
+ alias ping? ping
138
+ alias pingecho ping
139
+
140
+ private
141
+
142
+ # Perform a checksum on the message. This is the sum of all the short
143
+ # words and it folds the high order bits into the low order bits.
144
+ #
145
+ def checksum(msg)
146
+ length = msg.length
147
+ num_short = length / 2
148
+ check = 0
149
+
150
+ msg.unpack("n#{num_short}").each do |short|
151
+ check += short
152
+ end
153
+
154
+ if length % 2 > 0
155
+ check += msg[length-1, 1].unpack('C') << 8
156
+ end
157
+
158
+ check = (check >> 16) + (check & 0xffff)
159
+ return (~((check >> 16) + check) & 0xffff)
160
+ end
161
+ end
162
+
163
+ # Alias for consistency with other ping related classes
164
+ PingICMP = Ping::ICMP
165
+ end
@@ -0,0 +1,81 @@
1
+ require 'socket'
2
+ require 'timeout'
3
+
4
+ module Net
5
+ class Ping
6
+ VERSION = '1.2.2'
7
+
8
+ # The host to ping. In the case of Ping::HTTP, this is the URI.
9
+ attr_accessor :host
10
+
11
+ # The port to ping. This is set to the echo port (7) by default. The
12
+ # Ping::HTTP class defaults to port 80.
13
+ #
14
+ attr_accessor :port
15
+
16
+ # The maximum time a ping attempt is made.
17
+ attr_accessor :timeout
18
+
19
+ # If a ping fails, this value is set to the error that occurred which
20
+ # caused it to fail.
21
+ #
22
+ attr_reader :exception
23
+
24
+ # This value is set if a ping succeeds, but some other condition arose
25
+ # during the ping attempt which merits warning, e.g a redirect in the
26
+ # case of Ping::HTTP#ping.
27
+ #
28
+ attr_reader :warning
29
+
30
+ # The number of seconds (returned as a Float) that it took to ping
31
+ # the host. This is not a precise value, but rather a good estimate
32
+ # since there is a small amount of internal calculation that is added
33
+ # to the overall time.
34
+ #
35
+ attr_reader :duration
36
+
37
+ # The default constructor for the Net::Ping class. Accepts an optional
38
+ # +host+, +port+ and +timeout+. The port defaults to your echo port, or
39
+ # 7 if that happens to be undefined. The default timeout is 5 seconds.
40
+ #
41
+ # The host, although optional in the constructor, must be specified at
42
+ # some point before the Net::Ping#ping method is called, or else an
43
+ # ArgumentError will be raised.
44
+ #
45
+ # Yields +self+ in block context.
46
+ #
47
+ # This class is not meant to be instantiated directly. It is strictly
48
+ # meant as an interface for subclasses.
49
+ #
50
+ def initialize(host=nil, port=nil, timeout=5)
51
+ @host = host
52
+ @port = port || Socket.getservbyname('echo') || 7
53
+ @timeout = timeout
54
+ @exception = nil
55
+ @warning = nil
56
+ @duration = nil
57
+
58
+ yield self if block_given?
59
+ end
60
+
61
+ # The default interface for the Net::Ping#ping method. Each subclass
62
+ # should call super() before continuing with their own implementation in
63
+ # order to ensure that the @exception and @warning instance variables
64
+ # are reset.
65
+ #
66
+ # If +host+ is nil here, then it will use the host specified in the
67
+ # constructor. If the +host+ is nil and there was no host specified
68
+ # in the constructor then an ArgumentError is raised.
69
+ #--
70
+ # The @duration should be set in the subclass' ping method.
71
+ #
72
+ def ping(host = @host)
73
+ raise ArgumentError, 'no host specified' unless host
74
+ @exception = nil
75
+ @warning = nil
76
+ end
77
+
78
+ alias ping? ping
79
+ alias pingecho ping
80
+ end
81
+ end