ronin-nmap 0.1.0.rc1

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.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.document +4 -0
  3. data/.github/workflows/ruby.yml +47 -0
  4. data/.gitignore +14 -0
  5. data/.rspec +1 -0
  6. data/.rubocop.yml +15 -0
  7. data/.ruby-version +1 -0
  8. data/.yardopts +1 -0
  9. data/COPYING.txt +165 -0
  10. data/ChangeLog.md +10 -0
  11. data/Gemfile +42 -0
  12. data/README.md +238 -0
  13. data/Rakefile +43 -0
  14. data/bin/ronin-nmap +32 -0
  15. data/data/completions/ronin-nmap +79 -0
  16. data/data/templates/script.rb.erb +58 -0
  17. data/gemspec.yml +42 -0
  18. data/lib/ronin/nmap/cli/command.rb +40 -0
  19. data/lib/ronin/nmap/cli/commands/completion.rb +61 -0
  20. data/lib/ronin/nmap/cli/commands/convert.rb +108 -0
  21. data/lib/ronin/nmap/cli/commands/dump.rb +293 -0
  22. data/lib/ronin/nmap/cli/commands/grep.rb +378 -0
  23. data/lib/ronin/nmap/cli/commands/import.rb +79 -0
  24. data/lib/ronin/nmap/cli/commands/new.rb +226 -0
  25. data/lib/ronin/nmap/cli/commands/print.rb +133 -0
  26. data/lib/ronin/nmap/cli/commands/scan.rb +233 -0
  27. data/lib/ronin/nmap/cli/filtering_options.rb +355 -0
  28. data/lib/ronin/nmap/cli/importable.rb +68 -0
  29. data/lib/ronin/nmap/cli/port_list.rb +102 -0
  30. data/lib/ronin/nmap/cli.rb +50 -0
  31. data/lib/ronin/nmap/converter.rb +114 -0
  32. data/lib/ronin/nmap/converters/csv.rb +162 -0
  33. data/lib/ronin/nmap/converters/json.rb +562 -0
  34. data/lib/ronin/nmap/converters.rb +54 -0
  35. data/lib/ronin/nmap/exceptions.rb +47 -0
  36. data/lib/ronin/nmap/importer.rb +369 -0
  37. data/lib/ronin/nmap/root.rb +28 -0
  38. data/lib/ronin/nmap/version.rb +26 -0
  39. data/lib/ronin/nmap.rb +223 -0
  40. data/man/ronin-nmap-completion.1 +76 -0
  41. data/man/ronin-nmap-completion.1.md +78 -0
  42. data/man/ronin-nmap-convert.1 +33 -0
  43. data/man/ronin-nmap-convert.1.md +36 -0
  44. data/man/ronin-nmap-dump.1 +141 -0
  45. data/man/ronin-nmap-dump.1.md +119 -0
  46. data/man/ronin-nmap-grep.1 +33 -0
  47. data/man/ronin-nmap-grep.1.md +36 -0
  48. data/man/ronin-nmap-import.1 +52 -0
  49. data/man/ronin-nmap-import.1.md +57 -0
  50. data/man/ronin-nmap-new.1 +81 -0
  51. data/man/ronin-nmap-new.1.md +73 -0
  52. data/man/ronin-nmap-print.1 +61 -0
  53. data/man/ronin-nmap-print.1.md +63 -0
  54. data/man/ronin-nmap-scan.1 +86 -0
  55. data/man/ronin-nmap-scan.1.md +84 -0
  56. data/man/ronin-nmap.1 +58 -0
  57. data/man/ronin-nmap.1.md +57 -0
  58. data/ronin-nmap.gemspec +62 -0
  59. data/scripts/setup +161 -0
  60. metadata +168 -0
@@ -0,0 +1,162 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-nmap - A Ruby library for automating nmap and importing nmap scans.
4
+ #
5
+ # Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
6
+ #
7
+ # ronin-nmap is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-nmap is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-nmap. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'csv'
22
+
23
+ module Ronin
24
+ module Nmap
25
+ module Converters
26
+ #
27
+ # Handles converting nmap XML into CSV.
28
+ #
29
+ # @api private
30
+ #
31
+ module CSV
32
+ #
33
+ # Converts parsed nmap XML into CSV.
34
+ #
35
+ # @param [::Nmap::XML] xml
36
+ #
37
+ # @param [IO, StringIO] output
38
+ # The output to write the CSV to.
39
+ #
40
+ def self.convert(xml,output)
41
+ xml_to_csv(xml,output)
42
+ end
43
+
44
+ #
45
+ # Converts parsed XML to CSV.
46
+ #
47
+ # @param [::Nmap::XML] xml
48
+ # The parsed nmap XML to convert to CSV.
49
+ #
50
+ # @param [IO, StringIO] output
51
+ # The output to write the CSV to.
52
+ #
53
+ def self.xml_to_csv(xml,output)
54
+ xml_to_rows(xml) do |row|
55
+ output << ::CSV.generate_line(row)
56
+ end
57
+ end
58
+
59
+ # CSV rows header.
60
+ HEADER = %w[host.start_time host.end_time host.status host.ip port.protocol port.number port.status port.reason port.reason_ttl service.name service.ssl service.protocol service.produce service.version service.extra_info service.hostnmae service.os_type service.device_type service.fingerprint_method service.fingerprint service.confidence]
61
+
62
+ #
63
+ # Converts parsed nmap XML to a series of rows.
64
+ #
65
+ # @param [::Nmap::XML] xml
66
+ # The parsed nmap XML.
67
+ #
68
+ # @yield [row]
69
+ # The given block will be passed each row.
70
+ #
71
+ # @yieldparam [Array] row
72
+ # A row to be converted to CSV.
73
+ #
74
+ def self.xml_to_rows(xml)
75
+ yield HEADER
76
+
77
+ xml.each_host do |host|
78
+ each_host_rows(host) do |row|
79
+ yield row
80
+ end
81
+ end
82
+ end
83
+
84
+ #
85
+ # Converts a nmap XML host into a series of rows.
86
+ #
87
+ # @param [::Nmap::XML] host
88
+ # The nmap XML host object.
89
+ #
90
+ # @yield [row]
91
+ # The given block will be passed each row.
92
+ #
93
+ # @yieldparam [Array] row
94
+ # A row to be converted to CSV.
95
+ #
96
+ def self.each_host_rows(host)
97
+ host_row = [
98
+ host.start_time,
99
+ host.end_time,
100
+ host.status,
101
+ host.ip
102
+ ]
103
+
104
+ host.each_port do |port|
105
+ yield(host_row + port_to_row(port))
106
+ end
107
+ end
108
+
109
+ #
110
+ # Converts a nmap XML port into a row.
111
+ #
112
+ # @param [::Nmap::Port] port
113
+ # The nmap XML port object.
114
+ #
115
+ # @return [Array]
116
+ # The row of values that represents the port.
117
+ #
118
+ def self.port_to_row(port)
119
+ row = [
120
+ port.protocol,
121
+ port.number,
122
+ port.state,
123
+ port.reason,
124
+ port.reason_ttl
125
+ ]
126
+
127
+ if (service = port.service)
128
+ row.concat(service_to_row(service))
129
+ end
130
+
131
+ return row
132
+ end
133
+
134
+ #
135
+ # Converts a nmap XML service into a series of rows.
136
+ #
137
+ # @param [::Nmap::Service] service
138
+ # The nmap XML service object.
139
+ #
140
+ # @return [Array]
141
+ # The row of values that represents the service.
142
+ #
143
+ def self.service_to_row(service)
144
+ [
145
+ service.name,
146
+ service.ssl?,
147
+ service.protocol,
148
+ service.product,
149
+ service.version,
150
+ service.extra_info,
151
+ service.hostname,
152
+ service.os_type,
153
+ service.device_type,
154
+ service.fingerprint_method,
155
+ service.fingerprint,
156
+ service.confidence
157
+ ]
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,562 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # ronin-nmap - A Ruby library for automating nmap and importing nmap scans.
4
+ #
5
+ # Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
6
+ #
7
+ # ronin-nmap is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # ronin-nmap is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with ronin-nmap. If not, see <https://www.gnu.org/licenses/>.
19
+ #
20
+
21
+ require 'json'
22
+
23
+ module Ronin
24
+ module Nmap
25
+ module Converters
26
+ #
27
+ # Handles converting nmap XML into JSON.
28
+ #
29
+ # @api private
30
+ #
31
+ module JSON
32
+ #
33
+ # Converts parsed nmap XML to JSON.
34
+ #
35
+ # @param [::Nmap::XML] xml
36
+ # The parsed nmap XML.
37
+ #
38
+ # @param [IO, StringIO] output
39
+ # The output stream to write the JSON to.
40
+ #
41
+ def self.convert(xml,output)
42
+ xml_to_json(xml,output)
43
+ end
44
+
45
+ #
46
+ # Converts parsed nmap XML to JSON.
47
+ #
48
+ # @param [::Nmap::XML] xml
49
+ # The parsed nmap XML.
50
+ #
51
+ # @param [IO, StringIO] output
52
+ # The output stream to write the JSON to.
53
+ #
54
+ def self.xml_to_json(xml,output)
55
+ ::JSON.dump(xml_as_json(xml),output)
56
+ end
57
+
58
+ #
59
+ # Converts the parsed nmap XML into a JSON representation.
60
+ #
61
+ # @param [::Nmap::XML] xml
62
+ # The parsed nmap XML.
63
+ #
64
+ # @return [Hash{Symbol => Object}]
65
+ # The JSON representation.
66
+ #
67
+ def self.xml_as_json(xml)
68
+ hash = {
69
+ scanner: scanner_as_json(xml.scanner),
70
+ version: xml.version,
71
+ scan_info: xml.scan_info.map(&method(:scan_info_as_json)),
72
+ run_stats: xml.each_run_stat.map(&method(:run_stat_as_json)),
73
+ verbose: xml.verbose,
74
+ debugging: xml.debugging,
75
+ tasks: xml.each_task.map(&method(:scan_task_as_json))
76
+ }
77
+
78
+ if xml.prescript
79
+ hash[:prescript] = prescript_as_json(xml.prescript)
80
+ end
81
+
82
+ if xml.postscript
83
+ hash[:postscript] = postscript_as_json(xml.postscript)
84
+ end
85
+
86
+ hash[:hosts] = xml.each_host.map(&method(:host_as_json))
87
+ return hash
88
+ end
89
+
90
+ #
91
+ # Converts a `Nmap::XML::Scanner` object into JSON representation.
92
+ #
93
+ # @param [::Nmap::XML::Scanner] scanner
94
+ # The `Nmap::XML::Scanner` object.
95
+ #
96
+ # @return [Hash{Symbol => Object}]
97
+ # The JSON representation.
98
+ #
99
+ def self.scanner_as_json(scanner)
100
+ {
101
+ name: scanner.name,
102
+ version: scanner.version,
103
+ args: scanner.arguments,
104
+ start: scanner.start_time
105
+ }
106
+ end
107
+
108
+ #
109
+ # Converts a `Nmap::XML::ScanInfo` object into JSON representation.
110
+ #
111
+ # @param [::Nmap::XML::ScanInfo] scan_info
112
+ # The `Nmap::XML::ScanInfo` object.
113
+ #
114
+ # @return [Hash{Symbol => Object}]
115
+ # The JSON representation.
116
+ #
117
+ def self.scan_info_as_json(scan_info)
118
+ {
119
+ type: scan_info.type,
120
+ protocol: scan_info.protocol,
121
+ services: scan_info.services.map do |ports|
122
+ case ports
123
+ when Range then "#{ports.begin}-#{ports.end}"
124
+ else ports
125
+ end
126
+ end
127
+ }
128
+ end
129
+
130
+ #
131
+ # Converts the `Nmap::XML::RunStat` object into JSON representation.
132
+ #
133
+ # @param [::Nmap::XML::RunStat] run_stat
134
+ # The `Nmap::XML::RunStat` object.
135
+ #
136
+ # @return [Hash{Symbol => Object}]
137
+ # The JSON representation.
138
+ #
139
+ def self.run_stat_as_json(run_stat)
140
+ {
141
+ end_time: run_stat.end_time,
142
+ elapsed: run_stat.elapsed,
143
+ summary: run_stat.summary,
144
+ exit_status: run_stat.exit_status
145
+ }
146
+ end
147
+
148
+ #
149
+ # Converts the `Nmap::XML::ScanTask` object into JSON representation.
150
+ #
151
+ # @param [::Nmap::XML::ScanTask] scan_task
152
+ # The `Nmap::XML::ScanTask` object.
153
+ #
154
+ # @return [Hash{Symbol => Object}]
155
+ # The JSON representation.
156
+ #
157
+ def self.scan_task_as_json(scan_task)
158
+ {
159
+ name: scan_task.name,
160
+ start_time: scan_task.start_time,
161
+ end_time: scan_task.end_time,
162
+ extra_info: scan_task.extra_info
163
+ }
164
+ end
165
+
166
+ #
167
+ # Converts the `Nmap::XML::Host` object into JSON representation.
168
+ #
169
+ # @param [::Nmap::XML::Host] host
170
+ # The `Nmap::XML::Host` object.
171
+ #
172
+ # @return [Hash{Symbol => Object}]
173
+ # The JSON representation.
174
+ #
175
+ def self.host_as_json(host)
176
+ hash = {
177
+ start_time: host.start_time,
178
+ end_time: host.end_time,
179
+ status: status_as_json(host.status),
180
+ addresses: host.each_address.map(&method(:address_as_json)),
181
+ hostnames: host.each_hostname.map(&method(:hostname_as_json))
182
+ }
183
+
184
+ if (os = host.os)
185
+ hash[:os] = os_as_json(os)
186
+ end
187
+
188
+ if (uptime = host.uptime)
189
+ hash[:uptime] = uptime_as_json(uptime)
190
+ end
191
+
192
+ if (tcp_sequence = host.tcp_sequence)
193
+ hash[:tcp_sequence] = tcp_sequence_as_json(tcp_sequence)
194
+ end
195
+
196
+ if (ip_id_sequence = host.ip_id_sequence)
197
+ hash[:ip_id_sequence] = ip_id_sequence_as_json(ip_id_sequence)
198
+ end
199
+
200
+ if (tcp_ts_sequence = host.tcp_ts_sequence)
201
+ hash[:tcp_ts_sequence] = tcp_ts_sequence_as_json(tcp_ts_sequence)
202
+ end
203
+
204
+ hash[:ports] = host.each_port.map(&method(:port_as_json))
205
+
206
+ if (host_script = host.host_script)
207
+ hash[:host_script] = host_script_as_json(host_script)
208
+ end
209
+
210
+ if (traceroute = host.traceroute)
211
+ hash[:traceroute] = traceroute_as_json(traceroute)
212
+ end
213
+
214
+ return hash
215
+ end
216
+
217
+ #
218
+ # Converts the `Nmap::XML::Status` object into JSON representation.
219
+ #
220
+ # @param [::Nmap::XML::Status] status
221
+ # The `Nmap::XML::Status` object.
222
+ #
223
+ # @return [Hash{Symbol => Object}]
224
+ # The JSON representation.
225
+ #
226
+ def self.status_as_json(status)
227
+ {
228
+ state: status.state,
229
+ reason: status.reason,
230
+ reason_ttl: status.reason_ttl
231
+ }
232
+ end
233
+
234
+ #
235
+ # Converts the `Nmap::XML::Address` object into JSON representation.
236
+ #
237
+ # @param [::Nmap::XML::Address] address
238
+ # The `Nmap::XML::Address` object.
239
+ #
240
+ # @return [Hash{Symbol => Object}]
241
+ # The JSON representation.
242
+ #
243
+ def self.address_as_json(address)
244
+ {
245
+ type: address.type,
246
+ addr: address.addr,
247
+ vendor: address.vendor
248
+ }
249
+ end
250
+
251
+ #
252
+ # Converts the `Nmap::XML::Hostname` object into JSON representation.
253
+ #
254
+ # @param [::Nmap::XML::Hostname] hostname
255
+ # The `Nmap::XML::Hostname` object.
256
+ #
257
+ # @return [Hash{Symbol => Object}]
258
+ # The JSON representation.
259
+ #
260
+ def self.hostname_as_json(hostname)
261
+ {
262
+ type: hostname.type,
263
+ name: hostname.name
264
+ }
265
+ end
266
+
267
+ #
268
+ # Converts the `Nmap::XML::OS` object into JSON representation.
269
+ #
270
+ # @param [::Nmap::XML::OS] os
271
+ # The `Nmap::XML::OS` object.
272
+ #
273
+ # @return [Hash{Symbol => Object}]
274
+ # The JSON representation.
275
+ #
276
+ def self.os_as_json(os)
277
+ hash = {
278
+ os_classes: os.each_class.map(&method(:os_class_as_json)),
279
+ os_matches: os.each_match.map(&method(:os_match_as_json)),
280
+ ports_used: os.ports_used
281
+ }
282
+
283
+ if (fingerprint = os.fingerprint)
284
+ hash[:fingerprint] = fingerprint
285
+ end
286
+
287
+ return hash
288
+ end
289
+
290
+ #
291
+ # Converts the `Nmap::XML::OSClass` object into JSON representation.
292
+ #
293
+ # @param [::Nmap::XML::OSClass] os_class
294
+ # The `Nmap::XML::OSClass` object.
295
+ #
296
+ # @return [Hash{Symbol => Object}]
297
+ # The JSON representation.
298
+ #
299
+ def self.os_class_as_json(os_class)
300
+ hash = {}
301
+
302
+ if (type = os_class.type)
303
+ hash[:type] = type
304
+ end
305
+
306
+ hash[:vendor] = os_class.vendor
307
+ hash[:family] = os_class.family
308
+
309
+ if (gen = os_class.gen)
310
+ hash[:gen] = gen
311
+ end
312
+
313
+ hash[:accuracy] = os_class.accuracy
314
+ return hash
315
+ end
316
+
317
+ #
318
+ # Converts the `Nmap::XML::OSMatch` object into JSON representation.
319
+ #
320
+ # @param [::Nmap::XML::OSMatch] os_match
321
+ # The `Nmap::XML::OSMatch` object.
322
+ #
323
+ # @return [Hash{Symbol => Object}]
324
+ # The JSON representation.
325
+ #
326
+ def self.os_match_as_json(os_match)
327
+ {
328
+ name: os_match.name,
329
+ accuracy: os_match.accuracy
330
+ }
331
+ end
332
+
333
+ #
334
+ # Converts the ``Nmap::XML::Uptime object into JSON representation.
335
+ #
336
+ # @param [::Nmap::XML::Uptime] uptime
337
+ # The `Nmap::XML::Uptime` object.
338
+ #
339
+ # @return [Hash{Symbol => Object}]
340
+ # The JSON representation.
341
+ #
342
+ def self.uptime_as_json(uptime)
343
+ {
344
+ seconds: uptime.seconds,
345
+ last_boot: uptime.last_boot
346
+ }
347
+ end
348
+
349
+ #
350
+ # Converts the `Nmap::XML::TcpSequence` object into JSON representation.
351
+ #
352
+ # @param [::Nmap::XML::TcpSequence] tcp_sequence
353
+ # The `Nmap::XML::TcpSequence` object.
354
+ #
355
+ # @return [Hash{Symbol => Object}]
356
+ # The JSON representation.
357
+ #
358
+ def self.tcp_sequence_as_json(tcp_sequence)
359
+ hash = sequence_as_json(tcp_sequence)
360
+
361
+ hash[:index] = tcp_sequence.index
362
+ hash[:difficulty] = tcp_sequence.difficulty
363
+
364
+ return hash
365
+ end
366
+
367
+ #
368
+ # Converts the `Nmap::XML::IpIdSequence` object into JSON
369
+ # representation.
370
+ #
371
+ # @param [::Nmap::XML::IpIdSequence] ip_id_sequence
372
+ # The `Nmap::XML::IpIdSequence` object.
373
+ #
374
+ # @return [Hash{Symbol => Object}]
375
+ # The JSON representation.
376
+ #
377
+ def self.ip_id_sequence_as_json(ip_id_sequence)
378
+ sequence_as_json(ip_id_sequence)
379
+ end
380
+
381
+ #
382
+ # Converts the `Nmap::XML::TcpTsSequence` object into JSON
383
+ # representation.
384
+ #
385
+ # @param [::Nmap::XML::TcpTsSequence] tcp_ts_sequence
386
+ # The `Nmap::XML::TcpTsSequence` object.
387
+ #
388
+ # @return [Hash{Symbol => Object}]
389
+ # The JSON representation.
390
+ #
391
+ def self.tcp_ts_sequence_as_json(tcp_ts_sequence)
392
+ sequence_as_json(tcp_ts_sequence)
393
+ end
394
+
395
+ #
396
+ # Converts the `Nmap::XML::Sequence` object into JSON representation.
397
+ #
398
+ # @param [::Nmap::XML::Sequence] sequence
399
+ # The `Nmap::XML::Sequence` object.
400
+ #
401
+ # @return [Hash{Symbol => Object}]
402
+ # The JSON representation.
403
+ #
404
+ def self.sequence_as_json(sequence)
405
+ {
406
+ description: sequence.description,
407
+ values: sequence.values
408
+ }
409
+ end
410
+
411
+ #
412
+ # Converts the `Nmap::XML::Port` object into JSON representation.
413
+ #
414
+ # @param [::Nmap::XML::Port] port
415
+ # The `Nmap::XML::Port` object.
416
+ #
417
+ # @return [Hash{Symbol => Object}]
418
+ # The JSON representation.
419
+ #
420
+ def self.port_as_json(port)
421
+ hash = {
422
+ protocol: port.protocol,
423
+ number: port.number,
424
+ state: port.state,
425
+ reason: port.reason,
426
+ reason_ttl: port.reason_ttl
427
+ }
428
+
429
+ if (service = port.service)
430
+ hash[:service] = service_as_json(service)
431
+ end
432
+
433
+ hash[:scripts] = scripts_as_json(port)
434
+ return hash
435
+ end
436
+
437
+ #
438
+ # Converts the `Nmap::XML::Serivce` object into JSON representation.
439
+ #
440
+ # @param [::Nmap::XML::Serivce] service
441
+ # The `Nmap::XML::Serivce` object.
442
+ #
443
+ # @return [Hash{Symbol => Object}]
444
+ # The JSON representation.
445
+ #
446
+ def self.service_as_json(service)
447
+ {
448
+ name: service.name,
449
+ ssl: service.ssl?,
450
+ protocol: service.protocol,
451
+ product: service.product,
452
+ version: service.version,
453
+ extra_info: service.extra_info,
454
+ hostname: service.hostname,
455
+ os_type: service.os_type,
456
+ device_type: service.device_type,
457
+ fingerprint_method: service.fingerprint_method,
458
+ fingerprint: service.fingerprint,
459
+ confidence: service.confidence
460
+ }
461
+ end
462
+
463
+ #
464
+ # Converts the `Nmap::XML::HostScript` object into JSON representation.
465
+ #
466
+ # @param [::Nmap::XML::HostScript] host_script
467
+ # The `Nmap::XML::HostScript` object.
468
+ #
469
+ # @return [Hash{String => Object}]
470
+ # The JSON representation.
471
+ #
472
+ def self.host_script_as_json(host_script)
473
+ scripts_as_json(host_script)
474
+ end
475
+
476
+ #
477
+ # Converts the object, which includes `Nmap::XML::Scripts` module, into
478
+ # JSON representation.
479
+ #
480
+ # @param [Object<::Nmap::XML::Scripts>] has_scripts
481
+ # The object including the `Nmap::XML::Scripts` module.
482
+ #
483
+ # @return [Hash{String => Object}]
484
+ # The JSON representation.
485
+ #
486
+ def self.scripts_as_json(has_scripts)
487
+ hash = {}
488
+
489
+ has_scripts.scripts.each do |id,script|
490
+ hash[id] = script_as_json(script)
491
+ end
492
+
493
+ return hash
494
+ end
495
+
496
+ #
497
+ # Converts the `Nmap::XML::Script` object into JSON representation.
498
+ #
499
+ # @param [::Nmap::XML::Script] script
500
+ # The `Nmap::XML::Script` object.
501
+ #
502
+ # @return [Hash{Symbol => Object}]
503
+ # The JSON representation.
504
+ #
505
+ def self.script_as_json(script)
506
+ hash = {
507
+ id: script.id,
508
+ output: script.output
509
+ }
510
+
511
+ if (data = script.data)
512
+ hash[:data] = data
513
+ end
514
+
515
+ return hash
516
+ end
517
+
518
+ #
519
+ # Converts the `Nmap::XML::Traceroute` object into JSON representation.
520
+ #
521
+ # @param [::Nmap::XML::Traceroute] traceroute
522
+ # The `Nmap::XML::Traceroute` object.
523
+ #
524
+ # @return [Hash{Symbol => Object}]
525
+ # The JSON representation.
526
+ #
527
+ def self.traceroute_as_json(traceroute)
528
+ hash = {}
529
+
530
+ if (port = traceroute.port)
531
+ hash[:port] = port
532
+ end
533
+
534
+ if (protocol = traceroute.protocol)
535
+ hash[:protocol] = protocol
536
+ end
537
+
538
+ hash[:traceroute] = traceroute.map(&method(:hop_as_json))
539
+ return hash
540
+ end
541
+
542
+ #
543
+ # Converts an `Nmap::XML::Hop` object into JSON representation.
544
+ #
545
+ # @param [::Nmap::XML::Hop] hop
546
+ # The `Nmap::XML::Hop` object.
547
+ #
548
+ # @return [Hash{Symbol => Object}]
549
+ # The JSON representation.
550
+ #
551
+ def self.hop_as_json(hop)
552
+ {
553
+ addr: hop.addr,
554
+ host: hop.host,
555
+ ttl: hop.ttl,
556
+ rtt: hop.rtt
557
+ }
558
+ end
559
+ end
560
+ end
561
+ end
562
+ end