ruby-nmap 0.9.3 → 1.0.0
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.
- checksums.yaml +5 -5
- data/.document +1 -0
- data/.editorconfig +11 -0
- data/.github/workflows/ruby.yml +31 -0
- data/ChangeLog.md +122 -67
- data/Gemfile +11 -5
- data/LICENSE.txt +1 -1
- data/README.md +88 -50
- data/Rakefile +8 -3
- data/UPGRADING.md +47 -0
- data/gemspec.yml +6 -6
- data/lib/nmap/command.rb +765 -0
- data/lib/nmap/version.rb +1 -1
- data/lib/nmap/xml/address.rb +38 -0
- data/lib/nmap/xml/cpe/url.rb +80 -0
- data/lib/nmap/xml/cpe.rb +47 -0
- data/lib/nmap/xml/hop.rb +22 -0
- data/lib/nmap/xml/host.rb +546 -0
- data/lib/nmap/xml/host_script.rb +26 -0
- data/lib/nmap/xml/hostname.rb +44 -0
- data/lib/nmap/xml/ip_id_sequence.rb +26 -0
- data/lib/nmap/xml/os.rb +131 -0
- data/lib/nmap/xml/os_class.rb +86 -0
- data/lib/nmap/xml/os_match.rb +22 -0
- data/lib/nmap/xml/port.rb +114 -0
- data/lib/nmap/xml/postscript.rb +26 -0
- data/lib/nmap/xml/prescript.rb +26 -0
- data/lib/nmap/xml/run_stat.rb +22 -0
- data/lib/nmap/xml/scan.rb +38 -0
- data/lib/nmap/xml/scan_task.rb +55 -0
- data/lib/nmap/xml/scanner.rb +22 -0
- data/lib/nmap/xml/script.rb +110 -0
- data/lib/nmap/xml/scripts.rb +33 -0
- data/lib/nmap/xml/sequence.rb +52 -0
- data/lib/nmap/xml/service.rb +172 -0
- data/lib/nmap/xml/status.rb +22 -0
- data/lib/nmap/xml/tcp_sequence.rb +48 -0
- data/lib/nmap/xml/tcp_ts_sequence.rb +26 -0
- data/lib/nmap/xml/traceroute.rb +73 -0
- data/lib/nmap/xml/uptime.rb +22 -0
- data/lib/nmap/xml.rb +46 -44
- data/ruby-nmap.gemspec +38 -83
- data/spec/command_spec.rb +726 -0
- data/spec/fixtures/down_host_scan.xml +16 -0
- data/spec/{local_scan.xml → fixtures/local_scan.xml} +1 -1
- data/spec/{scan.xml → fixtures/scan.xml} +1 -1
- data/spec/spec_helper.rb +2 -2
- data/spec/{address_spec.rb → xml/address_spec.rb} +2 -2
- data/spec/{cpe → xml/cpe}/url_spec.rb +1 -1
- data/spec/{cpe_examples.rb → xml/cpe_examples.rb} +1 -1
- data/spec/{hop_spec.rb → xml/hop_spec.rb} +2 -2
- data/spec/{host_script_spec.rb → xml/host_script_spec.rb} +2 -2
- data/spec/{host_spec.rb → xml/host_spec.rb} +12 -8
- data/spec/{hostname_spec.rb → xml/hostname_spec.rb} +2 -2
- data/spec/{ip_id_sequence_spec.rb → xml/ip_id_sequence_spec.rb} +3 -3
- data/spec/{os_class_spec.rb → xml/os_class_spec.rb} +3 -3
- data/spec/{os_match_spec.rb → xml/os_match_spec.rb} +2 -2
- data/spec/{os_spec.rb → xml/os_spec.rb} +3 -3
- data/spec/{port_spec.rb → xml/port_spec.rb} +10 -5
- data/spec/{postscript_spec.rb → xml/postscript_spec.rb} +2 -2
- data/spec/{prescript_spec.rb → xml/prescript_spec.rb} +2 -2
- data/spec/{run_stat_spec.rb → xml/run_stat_spec.rb} +2 -2
- data/spec/{scan_spec.rb → xml/scan_spec.rb} +2 -2
- data/spec/{scan_task_spec.rb → xml/scan_task_spec.rb} +6 -6
- data/spec/{scanner_spec.rb → xml/scanner_spec.rb} +3 -3
- data/spec/xml/script_spec.rb +137 -0
- data/spec/xml/scripts_examples.rb +19 -0
- data/spec/{sequence_examples.rb → xml/sequence_examples.rb} +1 -0
- data/spec/{service_spec.rb → xml/service_spec.rb} +31 -5
- data/spec/{status_spec.rb → xml/status_spec.rb} +4 -3
- data/spec/{tcp_sequence_spec.rb → xml/tcp_sequence_spec.rb} +3 -3
- data/spec/{tcp_ts_sequence_spec.rb → xml/tcp_ts_sequence_spec.rb} +3 -3
- data/spec/{traceroute_spec.rb → xml/traceroute_spec.rb} +3 -3
- data/spec/{uptime_spec.rb → xml/uptime_spec.rb} +2 -2
- data/spec/xml_spec.rb +93 -45
- metadata +78 -99
- data/.travis.yml +0 -14
- data/lib/nmap/address.rb +0 -34
- data/lib/nmap/cpe/url.rb +0 -78
- data/lib/nmap/cpe.rb +0 -45
- data/lib/nmap/hop.rb +0 -20
- data/lib/nmap/host.rb +0 -586
- data/lib/nmap/host_script.rb +0 -18
- data/lib/nmap/hostname.rb +0 -42
- data/lib/nmap/ip_id_sequence.rb +0 -24
- data/lib/nmap/os.rb +0 -127
- data/lib/nmap/os_class.rb +0 -82
- data/lib/nmap/os_match.rb +0 -18
- data/lib/nmap/port.rb +0 -99
- data/lib/nmap/postscript.rb +0 -16
- data/lib/nmap/prescript.rb +0 -16
- data/lib/nmap/program.rb +0 -102
- data/lib/nmap/run_stat.rb +0 -20
- data/lib/nmap/scan.rb +0 -34
- data/lib/nmap/scan_task.rb +0 -50
- data/lib/nmap/scanner.rb +0 -18
- data/lib/nmap/scripts.rb +0 -71
- data/lib/nmap/sequence.rb +0 -50
- data/lib/nmap/service.rb +0 -170
- data/lib/nmap/status.rb +0 -18
- data/lib/nmap/task.rb +0 -381
- data/lib/nmap/tcp_sequence.rb +0 -46
- data/lib/nmap/tcp_ts_sequence.rb +0 -22
- data/lib/nmap/traceroute.rb +0 -71
- data/lib/nmap/uptime.rb +0 -20
- data/spec/scripts_examples.rb +0 -35
- data/spec/task_spec.rb +0 -150
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
require 'nmap/xml/status'
|
|
2
|
+
require 'nmap/xml/address'
|
|
3
|
+
require 'nmap/xml/hostname'
|
|
4
|
+
require 'nmap/xml/os'
|
|
5
|
+
require 'nmap/xml/port'
|
|
6
|
+
require 'nmap/xml/ip_id_sequence'
|
|
7
|
+
require 'nmap/xml/tcp_sequence'
|
|
8
|
+
require 'nmap/xml/tcp_ts_sequence'
|
|
9
|
+
require 'nmap/xml/uptime'
|
|
10
|
+
require 'nmap/xml/traceroute'
|
|
11
|
+
require 'nmap/xml/host_script'
|
|
12
|
+
|
|
13
|
+
require 'nokogiri'
|
|
14
|
+
require 'time'
|
|
15
|
+
|
|
16
|
+
module Nmap
|
|
17
|
+
class XML
|
|
18
|
+
#
|
|
19
|
+
# Wraps a `host` XML element.
|
|
20
|
+
#
|
|
21
|
+
# @since 1.0.0
|
|
22
|
+
#
|
|
23
|
+
class Host
|
|
24
|
+
|
|
25
|
+
include Enumerable
|
|
26
|
+
|
|
27
|
+
#
|
|
28
|
+
# Creates a new Host object.
|
|
29
|
+
#
|
|
30
|
+
# @param [Nokogiri::XML::Node] node
|
|
31
|
+
# The XML node that contains the host information.
|
|
32
|
+
#
|
|
33
|
+
def initialize(node)
|
|
34
|
+
@node = node
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
#
|
|
38
|
+
# The time the host was first scanned.
|
|
39
|
+
#
|
|
40
|
+
# @return [Time]
|
|
41
|
+
# The time the host was first scanned.
|
|
42
|
+
#
|
|
43
|
+
# @since 0.1.2
|
|
44
|
+
#
|
|
45
|
+
def start_time
|
|
46
|
+
@start_time ||= Time.at(@node['starttime'].to_i)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
#
|
|
50
|
+
# The time the host was last scanned.
|
|
51
|
+
#
|
|
52
|
+
# @return [Time]
|
|
53
|
+
# The time the host was last scanned.
|
|
54
|
+
#
|
|
55
|
+
# @since 0.1.2
|
|
56
|
+
#
|
|
57
|
+
def end_time
|
|
58
|
+
@end_time ||= Time.at(@node['endtime'].to_i)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
#
|
|
62
|
+
# Parses the status of the host.
|
|
63
|
+
#
|
|
64
|
+
# @return [Status]
|
|
65
|
+
# The status of the host.
|
|
66
|
+
#
|
|
67
|
+
def status
|
|
68
|
+
unless @status
|
|
69
|
+
status = @node.at_xpath('status')
|
|
70
|
+
|
|
71
|
+
@status = Status.new(
|
|
72
|
+
status['state'].to_sym,
|
|
73
|
+
status['reason'],
|
|
74
|
+
status['reason_ttl'].to_i
|
|
75
|
+
)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
return @status
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
#
|
|
82
|
+
# Parses each address of the host.
|
|
83
|
+
#
|
|
84
|
+
# @yield [addr]
|
|
85
|
+
# Each parsed address will be pass to a given block.
|
|
86
|
+
#
|
|
87
|
+
# @yieldparam [Address] addr
|
|
88
|
+
# A address of the host.
|
|
89
|
+
#
|
|
90
|
+
# @return [Host, Enumerator]
|
|
91
|
+
# The host.
|
|
92
|
+
# If no block was given, an enumerator will be returned.
|
|
93
|
+
#
|
|
94
|
+
def each_address
|
|
95
|
+
return enum_for(__method__) unless block_given?
|
|
96
|
+
|
|
97
|
+
@node.xpath("address[@addr]").each do |addr|
|
|
98
|
+
address = Address.new(
|
|
99
|
+
addr['addrtype'].to_sym,
|
|
100
|
+
addr['addr'],
|
|
101
|
+
addr['vendor']
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
yield address
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
return self
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
#
|
|
111
|
+
# Parses the addresses of the host.
|
|
112
|
+
#
|
|
113
|
+
# @return [Array<Host>]
|
|
114
|
+
# The addresses of the host.
|
|
115
|
+
#
|
|
116
|
+
def addresses
|
|
117
|
+
each_address.to_a
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
#
|
|
121
|
+
# Parses the MAC address of the host.
|
|
122
|
+
#
|
|
123
|
+
# @return [String]
|
|
124
|
+
# The MAC address of the host.
|
|
125
|
+
#
|
|
126
|
+
def mac
|
|
127
|
+
@mac ||= if (addr = @node.at_xpath("address[@addrtype='mac']"))
|
|
128
|
+
addr['addr']
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
#
|
|
133
|
+
# Parses the MAC vendor of the host.
|
|
134
|
+
#
|
|
135
|
+
# @return [String]
|
|
136
|
+
# The Mac Vendor of the host.
|
|
137
|
+
#
|
|
138
|
+
# @since 0.8.0
|
|
139
|
+
#
|
|
140
|
+
def vendor
|
|
141
|
+
@vendor ||= if (vendor = @node.at_xpath("address/@vendor"))
|
|
142
|
+
vendor.inner_text
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
#
|
|
147
|
+
# Parses the IPv4 address of the host.
|
|
148
|
+
#
|
|
149
|
+
# @return [String]
|
|
150
|
+
# The IPv4 address of the host.
|
|
151
|
+
#
|
|
152
|
+
def ipv4
|
|
153
|
+
@ipv4 ||= if (addr = @node.at_xpath("address[@addrtype='ipv4']"))
|
|
154
|
+
addr['addr']
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
#
|
|
159
|
+
# Parses the IPv6 address of the host.
|
|
160
|
+
#
|
|
161
|
+
# @return [String]
|
|
162
|
+
# The IPv6 address of the host.
|
|
163
|
+
#
|
|
164
|
+
def ipv6
|
|
165
|
+
@ipv6 ||= if (addr = @node.at_xpath("address[@addrtype='ipv6']"))
|
|
166
|
+
addr['addr']
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
#
|
|
171
|
+
# The IP address of the host.
|
|
172
|
+
#
|
|
173
|
+
# @return [String]
|
|
174
|
+
# The IPv4 or IPv6 address of the host.
|
|
175
|
+
#
|
|
176
|
+
def ip
|
|
177
|
+
ipv6 || ipv4
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
#
|
|
181
|
+
# The address of the host.
|
|
182
|
+
#
|
|
183
|
+
# @return [String]
|
|
184
|
+
# The IP or MAC address of the host.
|
|
185
|
+
#
|
|
186
|
+
def address
|
|
187
|
+
ip || mac
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
#
|
|
191
|
+
# Parses the hostnames of the host.
|
|
192
|
+
#
|
|
193
|
+
# @yield [host]
|
|
194
|
+
# Each parsed hostname will be passed to the given block.
|
|
195
|
+
#
|
|
196
|
+
# @yieldparam [Hostname] host
|
|
197
|
+
# A hostname of the host.
|
|
198
|
+
#
|
|
199
|
+
# @return [Host, Enumerator]
|
|
200
|
+
# The host.
|
|
201
|
+
# If no block was given, an enumerator will be returned.
|
|
202
|
+
#
|
|
203
|
+
def each_hostname
|
|
204
|
+
return enum_for(__method__) unless block_given?
|
|
205
|
+
|
|
206
|
+
@node.xpath("hostnames/hostname[@name]").each do |host|
|
|
207
|
+
yield Hostname.new(host['type'],host['name'])
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
return self
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
#
|
|
214
|
+
# Parses the hostnames of the host.
|
|
215
|
+
#
|
|
216
|
+
# @return [Array<Hostname>]
|
|
217
|
+
# The hostnames of the host.
|
|
218
|
+
#
|
|
219
|
+
def hostnames
|
|
220
|
+
each_hostname.to_a
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
#
|
|
224
|
+
# The primary hostname of the host.
|
|
225
|
+
#
|
|
226
|
+
# @return [Hostname, nil]
|
|
227
|
+
#
|
|
228
|
+
# @since 0.8.0
|
|
229
|
+
#
|
|
230
|
+
def hostname
|
|
231
|
+
each_hostname.first
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
#
|
|
235
|
+
# Parses the OS guessing information of the host.
|
|
236
|
+
#
|
|
237
|
+
# @yield [os]
|
|
238
|
+
# If a block is given, it will be passed the OS guessing information.
|
|
239
|
+
#
|
|
240
|
+
# @yieldparam [OS] os
|
|
241
|
+
# The OS guessing information.
|
|
242
|
+
#
|
|
243
|
+
# @return [OS]
|
|
244
|
+
# The OS guessing information.
|
|
245
|
+
#
|
|
246
|
+
def os
|
|
247
|
+
@os ||= if (os = @node.at_xpath('os'))
|
|
248
|
+
OS.new(os)
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
yield @os if (@os && block_given?)
|
|
252
|
+
return @os
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
#
|
|
256
|
+
# Parses the Uptime analysis of the host.
|
|
257
|
+
#
|
|
258
|
+
# @yield [uptime]
|
|
259
|
+
# If a block is given, it will be passed the resulting object
|
|
260
|
+
#
|
|
261
|
+
# @yieldparam [Uptime]
|
|
262
|
+
# Uptime value.
|
|
263
|
+
#
|
|
264
|
+
# @return [Uptime]
|
|
265
|
+
# The parsed object.
|
|
266
|
+
#
|
|
267
|
+
# @since 0.7.0
|
|
268
|
+
#
|
|
269
|
+
def uptime
|
|
270
|
+
@uptime ||= if (uptime = @node.at_xpath('uptime'))
|
|
271
|
+
Uptime.new(
|
|
272
|
+
uptime['seconds'].to_i,
|
|
273
|
+
Time.parse(uptime['lastboot'])
|
|
274
|
+
)
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
yield @uptime if (@uptime && block_given?)
|
|
278
|
+
return @uptime
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
#
|
|
282
|
+
# Parses the TCP Sequence number analysis of the host.
|
|
283
|
+
#
|
|
284
|
+
# @yield [sequence]
|
|
285
|
+
# If a block is given, it will be passed the resulting object
|
|
286
|
+
#
|
|
287
|
+
# @yieldparam [TcpSequence] sequence
|
|
288
|
+
# TCP Sequence number analysis.
|
|
289
|
+
#
|
|
290
|
+
# @return [TcpSequence]
|
|
291
|
+
# The parsed object.
|
|
292
|
+
#
|
|
293
|
+
def tcp_sequence
|
|
294
|
+
@tcp_sequence ||= if (seq = @node.at_xpath('tcpsequence'))
|
|
295
|
+
TcpSequence.new(seq)
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
yield @tcp_sequence if (@tcp_sequence && block_given?)
|
|
299
|
+
return @tcp_sequence
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
#
|
|
303
|
+
# Parses the IPID sequence number analysis of the host.
|
|
304
|
+
#
|
|
305
|
+
# @yield [ipidsequence]
|
|
306
|
+
# If a block is given, it will be passed the resulting object
|
|
307
|
+
#
|
|
308
|
+
# @yieldparam [IpIdSequence] ipidsequence
|
|
309
|
+
# IPID Sequence number analysis.
|
|
310
|
+
#
|
|
311
|
+
# @return [IpIdSequence]
|
|
312
|
+
# The parsed object.
|
|
313
|
+
#
|
|
314
|
+
def ip_id_sequence
|
|
315
|
+
@ip_id_sequence ||= if (seq = @node.at_xpath('ipidsequence'))
|
|
316
|
+
IpIdSequence.new(seq)
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
yield @ip_id_sequence if (@ip_id_sequence && block_given?)
|
|
320
|
+
return @ip_id_sequence
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
#
|
|
324
|
+
# Parses the TCP Timestamp sequence number analysis of the host.
|
|
325
|
+
#
|
|
326
|
+
# @yield [tcptssequence]
|
|
327
|
+
# If a block is given, it will be passed the resulting object
|
|
328
|
+
#
|
|
329
|
+
# @yieldparam [TcpTsSequence] tcptssequence
|
|
330
|
+
# TCP Timestamp Sequence number analysis.
|
|
331
|
+
#
|
|
332
|
+
# @return [TcpTsSequence]
|
|
333
|
+
# The parsed object.
|
|
334
|
+
#
|
|
335
|
+
def tcp_ts_sequence
|
|
336
|
+
@tcp_ts_sequence ||= if (seq = @node.at_xpath('tcptssequence'))
|
|
337
|
+
TcpTsSequence.new(seq)
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
yield @tcp_ts_sequence if (@tcp_ts_sequence && block_given?)
|
|
341
|
+
return @tcp_ts_sequence
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
#
|
|
345
|
+
# Parses the scanned ports of the host.
|
|
346
|
+
#
|
|
347
|
+
# @yield [port]
|
|
348
|
+
# Each scanned port of the host.
|
|
349
|
+
#
|
|
350
|
+
# @yieldparam [Port] port
|
|
351
|
+
# A scanned port of the host.
|
|
352
|
+
#
|
|
353
|
+
# @return [Host, Enumerator]
|
|
354
|
+
# The host.
|
|
355
|
+
# If no block was given, an enumerator will be returned.
|
|
356
|
+
#
|
|
357
|
+
def each_port
|
|
358
|
+
return enum_for(__method__) unless block_given?
|
|
359
|
+
|
|
360
|
+
@node.xpath("ports/port").each do |port|
|
|
361
|
+
yield Port.new(port)
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
return self
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
#
|
|
368
|
+
# Parses the scanned ports of the host.
|
|
369
|
+
#
|
|
370
|
+
# @return [Array<Port>]
|
|
371
|
+
# The scanned ports of the host.
|
|
372
|
+
#
|
|
373
|
+
def ports
|
|
374
|
+
each_port.to_a
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
#
|
|
378
|
+
# Parses the open ports of the host.
|
|
379
|
+
#
|
|
380
|
+
# @yield [port]
|
|
381
|
+
# Each open port of the host.
|
|
382
|
+
#
|
|
383
|
+
# @yieldparam [Port] port
|
|
384
|
+
# An open scanned port of the host.
|
|
385
|
+
#
|
|
386
|
+
# @return [Host, Enumerator]
|
|
387
|
+
# The host.
|
|
388
|
+
# If no block was given, an enumerator will be returned.
|
|
389
|
+
#
|
|
390
|
+
def each_open_port
|
|
391
|
+
return enum_for(__method__) unless block_given?
|
|
392
|
+
|
|
393
|
+
@node.xpath("ports/port[state/@state='open']").each do |port|
|
|
394
|
+
yield Port.new(port)
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
return self
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
#
|
|
401
|
+
# Parses the open ports of the host.
|
|
402
|
+
#
|
|
403
|
+
# @return [Array<Port>]
|
|
404
|
+
# The open ports of the host.
|
|
405
|
+
#
|
|
406
|
+
def open_ports
|
|
407
|
+
each_open_port.to_a
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
#
|
|
411
|
+
# Parses the TCP ports of the host.
|
|
412
|
+
#
|
|
413
|
+
# @yield [port]
|
|
414
|
+
# Each TCP port of the host.
|
|
415
|
+
#
|
|
416
|
+
# @yieldparam [Port] port
|
|
417
|
+
# An TCP scanned port of the host.
|
|
418
|
+
#
|
|
419
|
+
# @return [Host, Enumerator]
|
|
420
|
+
# The host.
|
|
421
|
+
# If no block was given, an enumerator will be returned.
|
|
422
|
+
#
|
|
423
|
+
def each_tcp_port
|
|
424
|
+
return enum_for(__method__) unless block_given?
|
|
425
|
+
|
|
426
|
+
@node.xpath("ports/port[@protocol='tcp']").each do |port|
|
|
427
|
+
yield Port.new(port)
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
return self
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
#
|
|
434
|
+
# Parses the TCP ports of the host.
|
|
435
|
+
#
|
|
436
|
+
# @return [Array<Port>]
|
|
437
|
+
# The TCP ports of the host.
|
|
438
|
+
#
|
|
439
|
+
def tcp_ports
|
|
440
|
+
each_tcp_port.to_a
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
#
|
|
444
|
+
# Parses the UDP ports of the host.
|
|
445
|
+
#
|
|
446
|
+
# @yield [port]
|
|
447
|
+
# Each UDP port of the host.
|
|
448
|
+
#
|
|
449
|
+
# @yieldparam [Port] port
|
|
450
|
+
# An UDP scanned port of the host.
|
|
451
|
+
#
|
|
452
|
+
# @return [Host, Enumerator]
|
|
453
|
+
# The host.
|
|
454
|
+
# If no block was given, an enumerator will be returned.
|
|
455
|
+
#
|
|
456
|
+
def each_udp_port
|
|
457
|
+
return enum_for(__method__) unless block_given?
|
|
458
|
+
|
|
459
|
+
@node.xpath("ports/port[@protocol='udp']").each do |port|
|
|
460
|
+
yield Port.new(port)
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
return self
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
#
|
|
467
|
+
# Parses the UDP ports of the host.
|
|
468
|
+
#
|
|
469
|
+
# @return [Array<Port>]
|
|
470
|
+
# The UDP ports of the host.
|
|
471
|
+
#
|
|
472
|
+
def udp_ports
|
|
473
|
+
each_udp_port.to_a
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
#
|
|
477
|
+
# Parses the open ports of the host.
|
|
478
|
+
#
|
|
479
|
+
# @see each_open_port
|
|
480
|
+
#
|
|
481
|
+
def each(&block)
|
|
482
|
+
each_open_port(&block)
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
#
|
|
486
|
+
# The NSE scripts ran against the host.
|
|
487
|
+
#
|
|
488
|
+
# @return [HostScript, nil]
|
|
489
|
+
# Contains the host script output and data.
|
|
490
|
+
#
|
|
491
|
+
# @since 0.9.0
|
|
492
|
+
#
|
|
493
|
+
def host_script
|
|
494
|
+
@host_script ||= if (hostscript = @node.at_xpath('hostscript'))
|
|
495
|
+
HostScript.new(hostscript)
|
|
496
|
+
end
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
#
|
|
500
|
+
# Parses the traceroute information, if present.
|
|
501
|
+
#
|
|
502
|
+
# @yield [traceroute]
|
|
503
|
+
# If a block is given, it will be passed the traceroute information.
|
|
504
|
+
#
|
|
505
|
+
# @yieldparam [Traceroute] traceroute
|
|
506
|
+
# The traceroute information.
|
|
507
|
+
#
|
|
508
|
+
# @return [Traceroute]
|
|
509
|
+
# The traceroute information.
|
|
510
|
+
#
|
|
511
|
+
# @since 0.7.0
|
|
512
|
+
#
|
|
513
|
+
def traceroute
|
|
514
|
+
@traceroute ||= if (trace = @node.at_xpath('trace'))
|
|
515
|
+
Traceroute.new(trace)
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
yield @traceroute if (@traceroute && block_given?)
|
|
519
|
+
return @traceroute
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
#
|
|
523
|
+
# Converts the host to a String.
|
|
524
|
+
#
|
|
525
|
+
# @return [String]
|
|
526
|
+
# The hostname or address of the host.
|
|
527
|
+
#
|
|
528
|
+
# @see address
|
|
529
|
+
#
|
|
530
|
+
def to_s
|
|
531
|
+
(hostname || address).to_s
|
|
532
|
+
end
|
|
533
|
+
|
|
534
|
+
#
|
|
535
|
+
# Inspects the host.
|
|
536
|
+
#
|
|
537
|
+
# @return [String]
|
|
538
|
+
# The inspected host.
|
|
539
|
+
#
|
|
540
|
+
def inspect
|
|
541
|
+
"#<#{self.class}: #{self}>"
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
end
|
|
545
|
+
end
|
|
546
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'nmap/xml/scripts'
|
|
2
|
+
|
|
3
|
+
module Nmap
|
|
4
|
+
class XML
|
|
5
|
+
#
|
|
6
|
+
# Represents the `hostscript` element.
|
|
7
|
+
#
|
|
8
|
+
# @since 1.0.0
|
|
9
|
+
#
|
|
10
|
+
class HostScript
|
|
11
|
+
|
|
12
|
+
include Scripts
|
|
13
|
+
|
|
14
|
+
#
|
|
15
|
+
# Initializes the HostScript object.
|
|
16
|
+
#
|
|
17
|
+
# @param [Nokogiri::XML::Node] node
|
|
18
|
+
# The XML node that contains the host information.
|
|
19
|
+
#
|
|
20
|
+
def initialize(node)
|
|
21
|
+
@node = node
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module Nmap
|
|
2
|
+
class XML
|
|
3
|
+
#
|
|
4
|
+
# Represents a hostname.
|
|
5
|
+
#
|
|
6
|
+
# @since 1.0.0
|
|
7
|
+
#
|
|
8
|
+
class Hostname < Struct.new(:type, :name)
|
|
9
|
+
|
|
10
|
+
#
|
|
11
|
+
# Determines if the hostname was specified by the user.
|
|
12
|
+
#
|
|
13
|
+
# @return [Boolean]
|
|
14
|
+
#
|
|
15
|
+
# @since 0.8.0
|
|
16
|
+
#
|
|
17
|
+
def user?
|
|
18
|
+
self.type == 'user'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
#
|
|
22
|
+
# Determines if the hostname is a DNS `PTR`.
|
|
23
|
+
#
|
|
24
|
+
# @return [Boolean]
|
|
25
|
+
#
|
|
26
|
+
# @since 0.8.0
|
|
27
|
+
#
|
|
28
|
+
def ptr?
|
|
29
|
+
self.type == 'PTR'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
# Converts the hostname to a String.
|
|
34
|
+
#
|
|
35
|
+
# @return [String]
|
|
36
|
+
# The name of the host.
|
|
37
|
+
#
|
|
38
|
+
def to_s
|
|
39
|
+
self.name.to_s
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'nmap/xml/sequence'
|
|
2
|
+
|
|
3
|
+
module Nmap
|
|
4
|
+
class XML
|
|
5
|
+
#
|
|
6
|
+
# Represents an IP ID.
|
|
7
|
+
#
|
|
8
|
+
# @since 1.0.0
|
|
9
|
+
#
|
|
10
|
+
class IpIdSequence < Sequence
|
|
11
|
+
|
|
12
|
+
#
|
|
13
|
+
# Converts the IpidSequence class to a String.
|
|
14
|
+
#
|
|
15
|
+
# @return [String]
|
|
16
|
+
# The String form of the object.
|
|
17
|
+
#
|
|
18
|
+
# @since 0.5.0
|
|
19
|
+
#
|
|
20
|
+
def to_s
|
|
21
|
+
"description=#{description.inspect} values=#{values.inspect}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|