net-ping 1.7.4-universal-mingw32 → 1.7.5-universal-mingw32

Sign up to get free protection for your applications and to get access to all the features.
data/lib/net/ping/icmp.rb CHANGED
@@ -1,179 +1,179 @@
1
- require File.join(File.dirname(__FILE__), 'ping')
2
-
3
- if File::ALT_SEPARATOR
4
- require 'win32/security'
5
- end
6
-
7
- # The Net module serves as a namespace only.
8
- module Net
9
-
10
- # The Net::Ping::ICMP class encapsulates an icmp ping.
11
- class Ping::ICMP < Ping
12
- ICMP_ECHOREPLY = 0 # Echo reply
13
- ICMP_ECHO = 8 # Echo request
14
- ICMP_SUBCODE = 0
15
-
16
- # You cannot set or change the port value. A value of 0 is always
17
- # used internally for ICMP pings.
18
- #
19
- undef_method :port=
20
-
21
- # Returns the data size, i.e. number of bytes sent on the ping. The
22
- # default size is 56.
23
- #
24
- attr_reader :data_size
25
-
26
- # Creates and returns a new Ping::ICMP object. This is similar to its
27
- # superclass constructor, but must be created with root privileges (on
28
- # UNIX systems), and the port value is ignored.
29
- #
30
- def initialize(host=nil, port=nil, timeout=5)
31
- raise 'requires root privileges' if Process.euid > 0
32
-
33
- if File::ALT_SEPARATOR
34
- unless Win32::Security.elevated_security?
35
- raise 'requires elevated security'
36
- end
37
- end
38
-
39
- @seq = 0
40
- @bind_port = 0
41
- @bind_host = nil
42
- @data_size = 56
43
- @data = ''
44
-
45
- 0.upto(@data_size){ |n| @data << (n % 256).chr }
46
-
47
- @ping_id = (Thread.current.object_id ^ Process.pid) & 0xffff
48
-
49
- super(host, port, timeout)
50
- @port = nil # This value is not used in ICMP pings.
51
- end
52
-
53
- # Sets the number of bytes sent in the ping method.
54
- #
55
- def data_size=(size)
56
- @data_size = size
57
- @data = ''
58
- 0.upto(size){ |n| @data << (n % 256).chr }
59
- end
60
-
61
- # Associates the local end of the socket connection with the given
62
- # +host+ and +port+. The default port is 0.
63
- #
64
- def bind(host, port = 0)
65
- @bind_host = host
66
- @bind_port = port
67
- end
68
-
69
- # Pings the +host+ specified in this method or in the constructor. If a
70
- # host was not specified either here or in the constructor, an
71
- # ArgumentError is raised.
72
- #
73
- def ping(host = @host)
74
- super(host)
75
- bool = false
76
-
77
- socket = Socket.new(
78
- Socket::PF_INET,
79
- Socket::SOCK_RAW,
80
- Socket::IPPROTO_ICMP
81
- )
82
-
83
- if @bind_host
84
- saddr = Socket.pack_sockaddr_in(@bind_port, @bind_host)
85
- socket.bind(saddr)
86
- end
87
-
88
- @seq = (@seq + 1) % 65536
89
- pstring = 'C2 n3 A' << @data_size.to_s
90
- timeout = @timeout
91
-
92
- checksum = 0
93
- msg = [ICMP_ECHO, ICMP_SUBCODE, checksum, @ping_id, @seq, @data].pack(pstring)
94
-
95
- checksum = checksum(msg)
96
- msg = [ICMP_ECHO, ICMP_SUBCODE, checksum, @ping_id, @seq, @data].pack(pstring)
97
-
98
- begin
99
- saddr = Socket.pack_sockaddr_in(0, host)
100
- rescue Exception
101
- socket.close unless socket.closed?
102
- return bool
103
- end
104
-
105
- start_time = Time.now
106
-
107
- socket.send(msg, 0, saddr) # Send the message
108
-
109
- begin
110
- Timeout.timeout(@timeout){
111
- while true
112
- io_array = select([socket], nil, nil, timeout)
113
-
114
- if io_array.nil? || io_array[0].empty?
115
- @exception = "timeout" if io_array.nil?
116
- return false
117
- end
118
-
119
- ping_id = nil
120
- seq = nil
121
-
122
- data = socket.recvfrom(1500).first
123
- type = data[20, 2].unpack('C2').first
124
-
125
- case type
126
- when ICMP_ECHOREPLY
127
- if data.length >= 28
128
- ping_id, seq = data[24, 4].unpack('n3')
129
- end
130
- else
131
- if data.length > 56
132
- ping_id, seq = data[52, 4].unpack('n3')
133
- end
134
- end
135
-
136
- if ping_id == @ping_id && seq == @seq && type == ICMP_ECHOREPLY
137
- bool = true
138
- break
139
- end
140
- end
141
- }
142
- rescue Exception => err
143
- @exception = err
144
- ensure
145
- socket.close if socket
146
- end
147
-
148
- # There is no duration if the ping failed
149
- @duration = Time.now - start_time if bool
150
-
151
- return bool
152
- end
153
-
154
- alias ping? ping
155
- alias pingecho ping
156
-
157
- private
158
-
159
- # Perform a checksum on the message. This is the sum of all the short
160
- # words and it folds the high order bits into the low order bits.
161
- #
162
- def checksum(msg)
163
- length = msg.length
164
- num_short = length / 2
165
- check = 0
166
-
167
- msg.unpack("n#{num_short}").each do |short|
168
- check += short
169
- end
170
-
171
- if length % 2 > 0
172
- check += msg[length-1, 1].unpack('C').first << 8
173
- end
174
-
175
- check = (check >> 16) + (check & 0xffff)
176
- return (~((check >> 16) + check) & 0xffff)
177
- end
178
- end
179
- end
1
+ require File.join(File.dirname(__FILE__), 'ping')
2
+
3
+ if File::ALT_SEPARATOR
4
+ require 'win32/security'
5
+ end
6
+
7
+ # The Net module serves as a namespace only.
8
+ module Net
9
+
10
+ # The Net::Ping::ICMP class encapsulates an icmp ping.
11
+ class Ping::ICMP < Ping
12
+ ICMP_ECHOREPLY = 0 # Echo reply
13
+ ICMP_ECHO = 8 # Echo request
14
+ ICMP_SUBCODE = 0
15
+
16
+ # You cannot set or change the port value. A value of 0 is always
17
+ # used internally for ICMP pings.
18
+ #
19
+ undef_method :port=
20
+
21
+ # Returns the data size, i.e. number of bytes sent on the ping. The
22
+ # default size is 56.
23
+ #
24
+ attr_reader :data_size
25
+
26
+ # Creates and returns a new Ping::ICMP object. This is similar to its
27
+ # superclass constructor, but must be created with root privileges (on
28
+ # UNIX systems), and the port value is ignored.
29
+ #
30
+ def initialize(host=nil, port=nil, timeout=5)
31
+ raise 'requires root privileges' if Process.euid > 0
32
+
33
+ if File::ALT_SEPARATOR
34
+ unless Win32::Security.elevated_security?
35
+ raise 'requires elevated security'
36
+ end
37
+ end
38
+
39
+ @seq = 0
40
+ @bind_port = 0
41
+ @bind_host = nil
42
+ @data_size = 56
43
+ @data = ''
44
+
45
+ 0.upto(@data_size){ |n| @data << (n % 256).chr }
46
+
47
+ @ping_id = (Thread.current.object_id ^ Process.pid) & 0xffff
48
+
49
+ super(host, port, timeout)
50
+ @port = nil # This value is not used in ICMP pings.
51
+ end
52
+
53
+ # Sets the number of bytes sent in the ping method.
54
+ #
55
+ def data_size=(size)
56
+ @data_size = size
57
+ @data = ''
58
+ 0.upto(size){ |n| @data << (n % 256).chr }
59
+ end
60
+
61
+ # Associates the local end of the socket connection with the given
62
+ # +host+ and +port+. The default port is 0.
63
+ #
64
+ def bind(host, port = 0)
65
+ @bind_host = host
66
+ @bind_port = port
67
+ end
68
+
69
+ # Pings the +host+ specified in this method or in the constructor. If a
70
+ # host was not specified either here or in the constructor, an
71
+ # ArgumentError is raised.
72
+ #
73
+ def ping(host = @host)
74
+ super(host)
75
+ bool = false
76
+
77
+ socket = Socket.new(
78
+ Socket::PF_INET,
79
+ Socket::SOCK_RAW,
80
+ Socket::IPPROTO_ICMP
81
+ )
82
+
83
+ if @bind_host
84
+ saddr = Socket.pack_sockaddr_in(@bind_port, @bind_host)
85
+ socket.bind(saddr)
86
+ end
87
+
88
+ @seq = (@seq + 1) % 65536
89
+ pstring = 'C2 n3 A' << @data_size.to_s
90
+ timeout = @timeout
91
+
92
+ checksum = 0
93
+ msg = [ICMP_ECHO, ICMP_SUBCODE, checksum, @ping_id, @seq, @data].pack(pstring)
94
+
95
+ checksum = checksum(msg)
96
+ msg = [ICMP_ECHO, ICMP_SUBCODE, checksum, @ping_id, @seq, @data].pack(pstring)
97
+
98
+ begin
99
+ saddr = Socket.pack_sockaddr_in(0, host)
100
+ rescue Exception
101
+ socket.close unless socket.closed?
102
+ return bool
103
+ end
104
+
105
+ start_time = Time.now
106
+
107
+ socket.send(msg, 0, saddr) # Send the message
108
+
109
+ begin
110
+ Timeout.timeout(@timeout){
111
+ while true
112
+ io_array = select([socket], nil, nil, timeout)
113
+
114
+ if io_array.nil? || io_array[0].empty?
115
+ @exception = "timeout" if io_array.nil?
116
+ return false
117
+ end
118
+
119
+ ping_id = nil
120
+ seq = nil
121
+
122
+ data = socket.recvfrom(1500).first
123
+ type = data[20, 2].unpack('C2').first
124
+
125
+ case type
126
+ when ICMP_ECHOREPLY
127
+ if data.length >= 28
128
+ ping_id, seq = data[24, 4].unpack('n3')
129
+ end
130
+ else
131
+ if data.length > 56
132
+ ping_id, seq = data[52, 4].unpack('n3')
133
+ end
134
+ end
135
+
136
+ if ping_id == @ping_id && seq == @seq && type == ICMP_ECHOREPLY
137
+ bool = true
138
+ break
139
+ end
140
+ end
141
+ }
142
+ rescue Exception => err
143
+ @exception = err
144
+ ensure
145
+ socket.close if socket
146
+ end
147
+
148
+ # There is no duration if the ping failed
149
+ @duration = Time.now - start_time if bool
150
+
151
+ return bool
152
+ end
153
+
154
+ alias ping? ping
155
+ alias pingecho ping
156
+
157
+ private
158
+
159
+ # Perform a checksum on the message. This is the sum of all the short
160
+ # words and it folds the high order bits into the low order bits.
161
+ #
162
+ def checksum(msg)
163
+ length = msg.length
164
+ num_short = length / 2
165
+ check = 0
166
+
167
+ msg.unpack("n#{num_short}").each do |short|
168
+ check += short
169
+ end
170
+
171
+ if length % 2 > 0
172
+ check += msg[length-1, 1].unpack('C').first << 8
173
+ end
174
+
175
+ check = (check >> 16) + (check & 0xffff)
176
+ return (~((check >> 16) + check) & 0xffff)
177
+ end
178
+ end
179
+ end
data/lib/net/ping/ping.rb CHANGED
@@ -1,89 +1,89 @@
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.7.4'
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
- @duration = nil
84
- end
85
-
86
- alias ping? ping
87
- alias pingecho ping
88
- end
89
- end
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.7.5'
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
+ @duration = nil
84
+ end
85
+
86
+ alias ping? ping
87
+ alias pingecho ping
88
+ end
89
+ end