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