ronin-support 0.4.1 → 0.5.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. data/ChangeLog.md +75 -32
  2. data/Gemfile +17 -18
  3. data/README.md +9 -10
  4. data/Rakefile +10 -2
  5. data/gemspec.yml +1 -1
  6. data/lib/ronin/binary.rb +21 -0
  7. data/lib/ronin/binary/hexdump.rb +20 -0
  8. data/lib/ronin/binary/hexdump/parser.rb +411 -0
  9. data/lib/ronin/binary/struct.rb +579 -0
  10. data/lib/ronin/binary/template.rb +437 -0
  11. data/lib/ronin/extensions/ip_addr.rb +17 -13
  12. data/lib/ronin/extensions/regexp.rb +45 -0
  13. data/lib/ronin/extensions/string.rb +3 -3
  14. data/lib/ronin/formatting/extensions/binary.rb +1 -0
  15. data/lib/ronin/formatting/extensions/binary/array.rb +63 -0
  16. data/lib/ronin/formatting/extensions/binary/base64.rb +106 -0
  17. data/lib/ronin/formatting/extensions/binary/file.rb +39 -6
  18. data/lib/ronin/formatting/extensions/binary/float.rb +65 -0
  19. data/lib/ronin/formatting/extensions/binary/integer.rb +56 -43
  20. data/lib/ronin/formatting/extensions/binary/string.rb +75 -187
  21. data/lib/ronin/formatting/extensions/text/string.rb +61 -0
  22. data/lib/ronin/fuzzing/extensions/string.rb +21 -8
  23. data/lib/ronin/fuzzing/fuzzing.rb +19 -17
  24. data/lib/ronin/network.rb +2 -1
  25. data/lib/ronin/network/dns.rb +57 -15
  26. data/lib/ronin/network/extensions.rb +0 -1
  27. data/lib/ronin/network/ftp.rb +145 -0
  28. data/lib/ronin/network/http/http.rb +13 -14
  29. data/lib/ronin/network/imap.rb +11 -10
  30. data/lib/ronin/network/mixins.rb +1 -0
  31. data/lib/ronin/network/mixins/ftp.rb +155 -0
  32. data/lib/ronin/network/mixins/ssl.rb +1 -1
  33. data/lib/ronin/network/mixins/tcp.rb +39 -6
  34. data/lib/ronin/network/mixins/udp.rb +121 -1
  35. data/lib/ronin/network/mixins/unix.rb +279 -0
  36. data/lib/ronin/network/pop3.rb +5 -5
  37. data/lib/ronin/network/proxy.rb +578 -0
  38. data/lib/ronin/network/smtp/email.rb +1 -1
  39. data/lib/ronin/network/smtp/smtp.rb +7 -8
  40. data/lib/ronin/network/ssl.rb +1 -6
  41. data/lib/ronin/network/tcp.rb +2 -305
  42. data/lib/ronin/network/tcp/proxy.rb +377 -0
  43. data/lib/ronin/network/tcp/tcp.rb +435 -0
  44. data/lib/ronin/network/telnet.rb +27 -23
  45. data/lib/ronin/network/udp.rb +2 -266
  46. data/lib/ronin/network/udp/proxy.rb +169 -0
  47. data/lib/ronin/network/udp/udp.rb +442 -0
  48. data/lib/ronin/network/unix.rb +287 -0
  49. data/lib/ronin/path.rb +2 -2
  50. data/lib/ronin/spec/ui/output.rb +1 -7
  51. data/lib/ronin/support.rb +1 -0
  52. data/lib/ronin/support/inflector.rb +3 -7
  53. data/lib/ronin/support/support.rb +2 -1
  54. data/lib/ronin/support/version.rb +1 -1
  55. data/lib/ronin/ui/output/helpers.rb +13 -15
  56. data/lib/ronin/ui/output/output.rb +2 -2
  57. data/lib/ronin/ui/output/terminal/color.rb +10 -4
  58. data/lib/ronin/wordlist.rb +92 -17
  59. data/ronin-support.gemspec +38 -109
  60. data/spec/binary/hexdump/helpers/hexdumps.rb +13 -0
  61. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/ascii.bin +0 -0
  62. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_decimal_shorts.txt +0 -0
  63. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_hex_bytes.txt +0 -0
  64. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_hex_shorts.txt +0 -0
  65. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_octal_bytes.txt +0 -0
  66. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_octal_shorts.txt +0 -0
  67. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_repeated.txt +0 -0
  68. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_decimal_bytes.txt +0 -0
  69. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_decimal_ints.txt +0 -0
  70. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_decimal_quads.txt +0 -0
  71. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_decimal_shorts.txt +0 -0
  72. data/spec/binary/hexdump/helpers/hexdumps/od_doubles.txt +17 -0
  73. data/spec/binary/hexdump/helpers/hexdumps/od_floats.txt +17 -0
  74. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_hex_bytes.txt +0 -0
  75. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_hex_ints.txt +0 -0
  76. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_hex_quads.txt +0 -0
  77. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_hex_shorts.txt +0 -0
  78. data/spec/binary/hexdump/helpers/hexdumps/od_named_chars.txt +17 -0
  79. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_octal_bytes.txt +0 -0
  80. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_octal_ints.txt +0 -0
  81. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_octal_quads.txt +0 -0
  82. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_octal_shorts.txt +0 -0
  83. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_repeated.txt +0 -0
  84. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/repeated.bin +0 -0
  85. data/spec/binary/hexdump/parser_spec.rb +302 -0
  86. data/spec/binary/struct_spec.rb +496 -0
  87. data/spec/binary/template_spec.rb +400 -0
  88. data/spec/extensions/ip_addr_spec.rb +58 -32
  89. data/spec/extensions/regexp_spec.rb +60 -0
  90. data/spec/extensions/string_spec.rb +1 -1
  91. data/spec/formatting/binary/array_spec.rb +22 -0
  92. data/spec/formatting/binary/base64_spec.rb +50 -0
  93. data/spec/formatting/binary/float_spec.rb +30 -0
  94. data/spec/formatting/binary/integer_spec.rb +54 -40
  95. data/spec/formatting/binary/string_spec.rb +69 -182
  96. data/spec/formatting/text/string_spec.rb +30 -0
  97. data/spec/network/dns_spec.rb +64 -0
  98. data/spec/network/ftp_spec.rb +65 -0
  99. data/spec/network/proxy_spec.rb +121 -0
  100. data/spec/network/shared/unix_server.rb +31 -0
  101. data/spec/network/tcp/proxy_spec.rb +116 -0
  102. data/spec/network/{tcp_spec.rb → tcp/tcp_spec.rb} +24 -1
  103. data/spec/network/telnet_spec.rb +67 -0
  104. data/spec/network/{udp_spec.rb → udp/udp_spec.rb} +24 -1
  105. data/spec/network/unix_spec.rb +183 -0
  106. data/spec/wordlist_spec.rb +74 -13
  107. metadata +129 -85
  108. data/spec/formatting/binary/helpers/hexdumps.rb +0 -16
@@ -0,0 +1,437 @@
1
+ #
2
+ # Copyright (c) 2006-2012 Hal Brodigan (postmodern.mod3 at gmail.com)
3
+ #
4
+ # This file is part of Ronin Support.
5
+ #
6
+ # Ronin Support is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Lesser General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Ronin Support is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public License
17
+ # along with Ronin Support. If not, see <http://www.gnu.org/licenses/>.
18
+ #
19
+
20
+ require 'set'
21
+
22
+ module Ronin
23
+ module Binary
24
+ #
25
+ # Provides a translation layer between C types and Ruby `Array#pack`
26
+ # codes.
27
+ #
28
+ # ## Types
29
+ #
30
+ # * `:uint8` (`C`) - unsigned 8-bit integer.
31
+ # * `:uint16` (`S`) - unsigned 16-bit integer.
32
+ # * `:uint32` (`L`) - unsigned 32-bit integer.
33
+ # * `:uint64` (`Q`) - unsigned 64-bit integer.
34
+ # * `:int8` (`c`) - signed 8-bit integer.
35
+ # * `:int16` (`s`) - signed 16-bit integer.
36
+ # * `:int32` (`l`) - signed 32-bit integer.
37
+ # * `:int64` (`q`) - signed 64-bit integer.
38
+ # * `:uint16_le` (`v`) - unsigned 16-bit integer, little endian.
39
+ # * `:uint32_le` (`V`) - unsigned 32-bit integer, little endian.
40
+ # * `:uint16_be` (`n`) - unsigned 16-bit integer, big endian.
41
+ # * `:uint32_be` (`N`) - unsigned 32-bit integer, big endian.
42
+ # * `:uchar` (`Z`) - unsigned character.
43
+ # * `:ushort` (`S!`) - unsigned short integer, native endian.
44
+ # * `:uint` (`I!`) - unsigned integer, native endian.
45
+ # * `:ulong` (`L!`) - unsigned long integer, native endian.
46
+ # * `:ulong_long` (`Q`) - unsigned quad integer, native endian.
47
+ # * `:char` (`Z`) - signed character.
48
+ # * `:short` (`s!`) - signed short integer, native endian.
49
+ # * `:int` (`i!`) - signed integer, native endian.
50
+ # * `:long` (`l!`) - signed long integer, native endian.
51
+ # * `:long_long` (`q`) - signed quad integer, native endian.
52
+ # * `:utf8` (`U`) - UTF8 character.
53
+ # * `:float` (`F`) - single-precision float, native format.
54
+ # * `:double` (`D`) - double-precision float, native format.
55
+ # * `:float_le` (`e`) - single-precision float, little endian.
56
+ # * `:double_le` (`E`) - double-precision float, little endian.
57
+ # * `:float_be` (`g`) - single-precision float, big endian.
58
+ # * `:double_be` (`G`) - double-precision float, big endian.
59
+ # * `:ubyte` (`C`) - unsigned byte.
60
+ # * `:byte` (`c`) - signed byte.
61
+ # * `:string` (`Z*`) - binary String, `\0` terminated.
62
+ #
63
+ # ### Ruby 1.9 specific types
64
+ #
65
+ # * `:uint16_le` (`S<`) - unsigned 16-bit integer, little endian.
66
+ # * `:uint32_le` (`L<`) - unsigned 32-bit integer, little endian.
67
+ # * `:uint64_le` (`Q<`) - unsigned 64-bit integer, little endian.
68
+ # * `:int16_le` (`s<`) - signed 16-bit integer, little endian.
69
+ # * `:int32_le` (`l<`) - signed 32-bit integer, little endian.
70
+ # * `:int64_le` (`q<`) - signed 64-bit integer, little endian.
71
+ # * `:uint16_be` (`S>`) - unsigned 16-bit integer, big endian.
72
+ # * `:uint32_be` (`L>`) - unsigned 32-bit integer, big endian.
73
+ # * `:uint64_be` (`Q>`) - unsigned 64-bit integer, big endian.
74
+ # * `:int16_be` (`s>`) - signed 16-bit integer, big endian.
75
+ # * `:int32_be` (`l>`) - signed 32-bit integer, big endian.
76
+ # * `:int64_be` (`q>`) - signed 64-bit integer, big endian.
77
+ # * `:ushort_le` (`S<`) - unsigned short integer, little endian.
78
+ # * `:uint_le` (`I<`) - unsigned integer, little endian.
79
+ # * `:ulong_le` (`L<`) - unsigned long integer, little endian.
80
+ # * `:ulong_long_le` (`Q<`) - unsigned quad integer, little endian.
81
+ # * `:short_le` (`s<`) - signed short integer, little endian.
82
+ # * `:int_le` (`i<`) - signed integer, little endian.
83
+ # * `:long_le` (`l<`) - signed long integer, little endian.
84
+ # * `:long_long_le` (`q<`) - signed quad integer, little endian.
85
+ # * `:ushort_be` (`S>`) - unsigned short integer, little endian.
86
+ # * `:uint_be` (`I>`) - unsigned integer, little endian.
87
+ # * `:ulong_be` (`L>`) - unsigned long integer, little endian.
88
+ # * `:ulong_long_be` (`Q>`) - unsigned quad integer, little endian.
89
+ # * `:short_be` (`s>`) - signed short integer, little endian.
90
+ # * `:int_be` (`i>`) - signed integer, little endian.
91
+ # * `:long_be` (`l>`) - signed long integer, little endian.
92
+ # * `:long_long_be` (`q>`) - signed quad integer, little endian.
93
+ #
94
+ # @see http://rubydoc.info/stdlib/core/Array:pack
95
+ #
96
+ # @api semipbulic
97
+ #
98
+ # @since 0.5.0
99
+ #
100
+ class Template
101
+
102
+ # Supported types and corresponding `Array#pack` codes.
103
+ TYPES = {
104
+ :uint8 => 'C',
105
+ :uint16 => 'S',
106
+ :uint32 => 'L',
107
+ :uint64 => 'Q',
108
+
109
+ :int8 => 'c',
110
+ :int16 => 's',
111
+ :int32 => 'l',
112
+ :int64 => 'q',
113
+
114
+ :uint16_le => 'v',
115
+ :uint32_le => 'V',
116
+ :uint16_be => 'n',
117
+ :uint32_be => 'N',
118
+
119
+ :uchar => 'Z',
120
+ :ushort => 'S!',
121
+ :uint => 'I!',
122
+ :ulong => 'L!',
123
+ :ulong_long => 'Q',
124
+
125
+ :char => 'Z',
126
+ :short => 's!',
127
+ :int => 'i!',
128
+ :long => 'l!',
129
+ :long_long => 'q',
130
+
131
+ :utf8 => 'U',
132
+
133
+ :float => 'F',
134
+ :double => 'D',
135
+
136
+ :float_le => 'e',
137
+ :double_le => 'E',
138
+
139
+ :float_be => 'g',
140
+ :double_be => 'G',
141
+
142
+ :ubyte => 'C',
143
+ :byte => 'c',
144
+ :string => 'Z*'
145
+ }
146
+
147
+ # Additional types, not available on Ruby 1.8:
148
+ if RUBY_VERSION > '1.9.'
149
+ TYPES.merge!(
150
+ :uint16_le => 'S<',
151
+ :uint32_le => 'L<',
152
+ :uint64_le => 'Q<',
153
+
154
+ :int16_le => 's<',
155
+ :int32_le => 'l<',
156
+ :int64_le => 'q<',
157
+
158
+ :uint16_be => 'S>',
159
+ :uint32_be => 'L>',
160
+ :uint64_be => 'Q>',
161
+
162
+ :int16_be => 's>',
163
+ :int32_be => 'l>',
164
+ :int64_be => 'q>',
165
+
166
+ :ushort_le => 'S!<',
167
+ :uint_le => 'I!<',
168
+ :ulong_le => 'L!<',
169
+ :ulong_long_le => 'Q<',
170
+
171
+ :short_le => 's!<',
172
+ :int_le => 'i!<',
173
+ :long_le => 'l!<',
174
+ :long_long_le => 'q<',
175
+
176
+ :ushort_be => 'S!>',
177
+ :uint_be => 'I!>',
178
+ :ulong_be => 'L!>',
179
+ :ulong_long_be => 'Q>',
180
+
181
+ :short_be => 's!>',
182
+ :int_be => 'i!>',
183
+ :long_be => 'l!>',
184
+ :long_long_be => 'q>'
185
+ )
186
+ end
187
+
188
+ # Integer types
189
+ INT_TYPES = Set[
190
+ :uint8,
191
+ :uint16,
192
+ :uint32,
193
+ :uint64,
194
+
195
+ :int8,
196
+ :int16,
197
+ :int32,
198
+ :int64,
199
+
200
+ :ubyte,
201
+ :ushort,
202
+ :uint,
203
+ :ulong,
204
+ :ulong_long,
205
+
206
+ :byte,
207
+ :short,
208
+ :int,
209
+ :long,
210
+ :long_long,
211
+
212
+ :uint16_le,
213
+ :uint32_le,
214
+ :uint64_le,
215
+
216
+ :int16_le,
217
+ :int32_le,
218
+ :int64_le,
219
+
220
+ :ushort_le,
221
+ :uint_le,
222
+ :ulong_le,
223
+ :ulong_long_le,
224
+
225
+ :short_le,
226
+ :int_le,
227
+ :long_le,
228
+ :long_long_le,
229
+
230
+ :uint16_be,
231
+ :uint32_be,
232
+ :uint64_be,
233
+
234
+ :int16_be,
235
+ :int32_be,
236
+ :int64_be,
237
+
238
+ :ushort_be,
239
+ :uint_be,
240
+ :ulong_be,
241
+ :ulong_long_be,
242
+
243
+ :short_be,
244
+ :int_be,
245
+ :long_be,
246
+ :long_long_be
247
+ ]
248
+
249
+ # Float types
250
+ FLOAT_TYPES = Set[
251
+ :float, :double,
252
+ :float_le, :double_le,
253
+ :float_be, :double_be
254
+ ]
255
+
256
+ # Character types
257
+ CHAR_TYPES = Set[:uchar, :char]
258
+
259
+ # String types
260
+ STRING_TYPES = CHAR_TYPES + Set[:string]
261
+
262
+ # Types which have little and big endian forms
263
+ ENDIAN_TYPES = Set[
264
+ :uint16, :uint32, :uint64,
265
+ :int16, :int32, :int64,
266
+ :ushort, :uint, :ulong, :ulong_long,
267
+ :short, :int, :long, :long_long,
268
+ :float, :double
269
+ ]
270
+
271
+ # The fields of the template
272
+ attr_reader :fields
273
+
274
+ #
275
+ # Creates a new Binary Template.
276
+ #
277
+ # @param [Array<type, (type, length)>] fields
278
+ # The types which the packer will use.
279
+ #
280
+ # @param [Hash] options
281
+ # Template options.
282
+ #
283
+ # @option options [:little, :big, :network] :endian
284
+ # The endianness to apply to types.
285
+ #
286
+ # @raise [ArgumentError]
287
+ # A given type is not known.
288
+ #
289
+ # @note
290
+ # The following types are **not supported** on Ruby 1.8:
291
+ #
292
+ # * `:uint16_le`
293
+ # * `:uint32_le`
294
+ # * `:uint64_le`
295
+ # * `:int16_le`
296
+ # * `:int32_le`
297
+ # * `:int64_le`
298
+ # * `:uint16_be`
299
+ # * `:uint32_be`
300
+ # * `:uint64_be`
301
+ # * `:int16_be`
302
+ # * `:int32_be`
303
+ # * `:int64_be`
304
+ # * `:ushort_le`
305
+ # * `:uint_le`
306
+ # * `:ulong_le`
307
+ # * `:ulong_long_le`
308
+ # * `:short_le`
309
+ # * `:int_le`
310
+ # * `:long_le`
311
+ # * `:long_long_le`
312
+ # * `:ushort_be`
313
+ # * `:uint_be`
314
+ # * `:ulong_be`
315
+ # * `:ulong_long_be`
316
+ # * `:short_be`
317
+ # * `:int_be`
318
+ # * `:long_be`
319
+ # * `:long_long_be`
320
+ #
321
+ # @example
322
+ # Template.new(:uint32, [:char, 100])
323
+ #
324
+ def initialize(fields,options={})
325
+ @fields = fields
326
+ @template = self.class.compile(@fields,options)
327
+ end
328
+
329
+ #
330
+ # Translates the type of the field.
331
+ #
332
+ # @param [Symbol] type
333
+ # The type to translate.
334
+ #
335
+ # @param [Hash] options
336
+ # Translation options.
337
+ #
338
+ # @option options [:little, :big, :network] :endian
339
+ # The endianness to apply to types.
340
+ #
341
+ # @return [Symbol]
342
+ # The translated type.
343
+ #
344
+ # @raise [ArgumentError]
345
+ # The value of `:endian` is unknown.
346
+ #
347
+ def self.translate(type,options={})
348
+ if (options[:endian] && ENDIAN_TYPES.include?(type))
349
+ type = case options[:endian]
350
+ when :little
351
+ :"#{type}_le"
352
+ when :big, :network
353
+ :"#{type}_be"
354
+ else
355
+ raise(ArgumentError,"unknown endianness: #{type}")
356
+ end
357
+ end
358
+
359
+ return type
360
+ end
361
+
362
+ #
363
+ # Compiles binary types into an `Array#pack` / `String#unpack`
364
+ # template.
365
+ #
366
+ # @param [Array<type, (type, length)>] types
367
+ # The types which the packer will use.
368
+ #
369
+ # @param [Hash] options
370
+ # Type options.
371
+ #
372
+ # @option options [:little, :big, :network] :endian
373
+ # The endianness to apply to types.
374
+ #
375
+ # @return [String]
376
+ # The `Array#pack` / `String#unpack` template.
377
+ #
378
+ # @raise [ArgumentError]
379
+ # A given type is not known.
380
+ #
381
+ def self.compile(types,options={})
382
+ string = ''
383
+
384
+ types.each do |(type,length)|
385
+ type = translate(type,options)
386
+
387
+ unless (code = TYPES[type])
388
+ raise(ArgumentError,"#{type.inspect} not supported")
389
+ end
390
+
391
+ string << code << length.to_s
392
+ end
393
+
394
+ return string
395
+ end
396
+
397
+ #
398
+ # Packs the data.
399
+ #
400
+ # @param [Array] data
401
+ # The data to pack.
402
+ #
403
+ # @return [String]
404
+ # The packed data.
405
+ #
406
+ def pack(*data)
407
+ data.pack(@template)
408
+ end
409
+
410
+ #
411
+ # Unpacks the string.
412
+ #
413
+ # @param [String] string
414
+ # The raw String to unpack.
415
+ #
416
+ # @return [Array]
417
+ # The unpacked data.
418
+ #
419
+ def unpack(string)
420
+ string.unpack(@template)
421
+ end
422
+
423
+ #
424
+ # Converts the template to a `Array#pack` template String.
425
+ #
426
+ # @return [String]
427
+ # The template String.
428
+ #
429
+ # @see http://rubydoc.info/stdlib/core/Array:pack
430
+ #
431
+ def to_s
432
+ @template
433
+ end
434
+
435
+ end
436
+ end
437
+ end
@@ -21,7 +21,6 @@ require 'ronin/extensions/resolv'
21
21
  require 'ronin/extensions/regexp'
22
22
 
23
23
  require 'ipaddr'
24
- require 'strscan'
25
24
  require 'combinatorics/list_comprehension'
26
25
 
27
26
  class IPAddr
@@ -56,7 +55,7 @@ class IPAddr
56
55
  # IPAddr.extract("Host: 127.0.0.1\n\rHost: 10.1.1.1\n\r")
57
56
  # # => ["127.0.0.1", "10.1.1.1"]
58
57
  #
59
- # @example Extract only IPv4 addresses from a large amount of text.
58
+ # @example Extract only IPv4 addresses from a large amount of text:
60
59
  # IPAddr.extract(text,:v4) do |ip|
61
60
  # puts ip
62
61
  # end
@@ -75,10 +74,8 @@ class IPAddr
75
74
  Regexp::IP
76
75
  end
77
76
 
78
- scanner = StringScanner.new(text)
79
-
80
- while scanner.skip_until(regexp)
81
- yield scanner.matched
77
+ text.scan(regexp) do |match|
78
+ yield match
82
79
  end
83
80
 
84
81
  return nil
@@ -107,7 +104,7 @@ class IPAddr
107
104
  # end
108
105
  #
109
106
  # @example Enumerate through a globbed IP range
110
- # IPAddr.each('10.1.1-5.*') do |ip|
107
+ # IPAddr.each('10.1.1-5,10-20.*') do |ip|
111
108
  # puts ip
112
109
  # end
113
110
  #
@@ -119,7 +116,9 @@ class IPAddr
119
116
  # @api public
120
117
  #
121
118
  def IPAddr.each(cidr_or_glob,&block)
122
- unless (cidr_or_glob.include?('*') || cidr_or_glob.include?('-'))
119
+ unless (cidr_or_glob.include?('*') ||
120
+ cidr_or_glob.include?(',') ||
121
+ cidr_or_glob.include?('-'))
123
122
  return IPAddr.new(cidr_or_glob).each(&block)
124
123
  end
125
124
 
@@ -154,12 +153,17 @@ class IPAddr
154
153
 
155
154
  ranges << if segment == '*'
156
155
  (1..254)
157
- elsif segment.include?('-')
158
- start, stop = segment.split('-',2)
159
-
160
- (start.to_i(base)..stop.to_i(base))
161
156
  else
162
- segment.to_i(base)
157
+ segment.split(',').map { |octet|
158
+ if octet.include?('-')
159
+ start, stop = octet.split('-',2)
160
+ start, stop = start.to_i(base), stop.to_i(base)
161
+
162
+ (start..stop).to_a
163
+ else
164
+ octet.to_i(base)
165
+ end
166
+ }.flatten
163
167
  end
164
168
  end
165
169