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,400 @@
1
+ require 'spec_helper'
2
+ require 'ronin/binary/template'
3
+
4
+ describe Binary::Template do
5
+ describe "TYPES" do
6
+ subject { described_class::TYPES }
7
+
8
+ it("uint8 => C") { subject[:uint8].should == 'C' }
9
+ it("uint16 => S") { subject[:uint16].should == 'S' }
10
+ it("uint32 => L") { subject[:uint32].should == 'L' }
11
+ it("uint64 => Q") { subject[:uint64].should == 'Q' }
12
+ it("int8 => C") { subject[:int8].should == 'c' }
13
+ it("int16 => S") { subject[:int16].should == 's' }
14
+ it("int32 => L") { subject[:int32].should == 'l' }
15
+ it("int64 => Q") { subject[:int64].should == 'q' }
16
+ if RUBY_VERSION < '1.9.'
17
+ it("uint16_le => v") { subject[:uint16_le].should == 'v' }
18
+ it("uint32_le => V") { subject[:uint32_le].should == 'V' }
19
+ it("uint16_be => n") { subject[:uint16_be].should == 'n' }
20
+ it("uint32_be => N") { subject[:uint32_be].should == 'N' }
21
+ end
22
+ it("uchar => Z") { subject[:uchar].should == 'Z' }
23
+ it("ushort => S!") { subject[:ushort].should == 'S!'}
24
+ it("uint => I!") { subject[:uint].should == 'I!'}
25
+ it("ulong => L!") { subject[:ulong].should == 'L!'}
26
+ it("ulong_long => Q") { subject[:ulong_long].should == 'Q' }
27
+ it("char => Z") { subject[:char].should == 'Z' }
28
+ it("short => s!") { subject[:short].should == 's!'}
29
+ it("int => i!") { subject[:int].should == 'i!'}
30
+ it("long => l!") { subject[:long].should == 'l!'}
31
+ it("long_long => q") { subject[:long_long].should == 'q' }
32
+ it("utf8 => U") { subject[:utf8].should == 'U' }
33
+ it("float => F") { subject[:float].should == 'F' }
34
+ it("double => D") { subject[:double].should == 'D' }
35
+ it("float_le => e") { subject[:float_le].should == 'e' }
36
+ it("double_le => E") { subject[:double_le].should == 'E' }
37
+ it("float_be => g") { subject[:float_be].should == 'g' }
38
+ it("double_ge => G") { subject[:double_be].should == 'G' }
39
+ it("ubyte => C") { subject[:ubyte].should == 'C' }
40
+ it("byte => c") { subject[:byte].should == 'c' }
41
+ it("string => Z*") { subject[:string].should == 'Z*'}
42
+
43
+ if RUBY_VERSION > '1.9.'
44
+ context "Ruby 1.9" do
45
+ it("uint16_le => S<") { subject[:uint16_le].should == 'S<' }
46
+ it("uint32_le => L<") { subject[:uint32_le].should == 'L<' }
47
+ it("uint64_le => Q<") { subject[:uint64_le].should == 'Q<' }
48
+ it("int16_le => S<") { subject[:int16_le].should == 's<' }
49
+ it("int32_le => L<") { subject[:int32_le].should == 'l<' }
50
+ it("int64_le => Q<") { subject[:int64_le].should == 'q<' }
51
+ it("uint16_be => S>") { subject[:uint16_be].should == 'S>' }
52
+ it("uint32_be => L>") { subject[:uint32_be].should == 'L>' }
53
+ it("uint64_be => Q>") { subject[:uint64_be].should == 'Q>' }
54
+ it("int16_be => S>") { subject[:int16_be].should == 's>' }
55
+ it("int32_be => L>") { subject[:int32_be].should == 'l>' }
56
+ it("int64_be => Q>") { subject[:int64_be].should == 'q>' }
57
+ it("ushort_le => S!<") { subject[:ushort_le].should == 'S!<'}
58
+ it("uint_le => I!<") { subject[:uint_le].should == 'I!<'}
59
+ it("ulong_le => L!<") { subject[:ulong_le].should == 'L!<'}
60
+ it("ulong_long_le => L!<") { subject[:ulong_long_le].should == 'Q<' }
61
+ it("short_le => S!<") { subject[:short_le].should == 's!<'}
62
+ it("int_le => I!<") { subject[:int_le].should == 'i!<'}
63
+ it("long_le => L!<") { subject[:long_le].should == 'l!<'}
64
+ it("long_long_le => L!<") { subject[:long_long_le].should == 'q<' }
65
+ it("ushort_be => S!>") { subject[:ushort_be].should == 'S!>'}
66
+ it("uint_be => I!>") { subject[:uint_be].should == 'I!>'}
67
+ it("ulong_be => L!>") { subject[:ulong_be].should == 'L!>'}
68
+ it("ulong_long_be => L!>") { subject[:ulong_long_be].should == 'Q>' }
69
+ it("short_be => S!>") { subject[:short_be].should == 's!>'}
70
+ it("int_be => I!>") { subject[:int_be].should == 'i!>'}
71
+ it("long_be => L!>") { subject[:long_be].should == 'l!>'}
72
+ it("long_long_be => L!>") { subject[:long_long_be].should == 'q>' }
73
+ end
74
+ end
75
+ end
76
+
77
+ describe "translate" do
78
+ subject { described_class }
79
+
80
+ context "when given :endian" do
81
+ it "should translate endian-types" do
82
+ subject.translate(:uint, :endian => :little).should == :uint_le
83
+ end
84
+
85
+ it "should not translate non-endian-types" do
86
+ subject.translate(:string, :endian => :little).should == :string
87
+ end
88
+
89
+ it "should raise an ArgumentError for unknown endianness" do
90
+ lambda {
91
+ subject.translate(:uint, :endian => :foo)
92
+ }.should raise_error(ArgumentError)
93
+ end
94
+ end
95
+ end
96
+
97
+ describe "compile" do
98
+ let(:type) { :uint }
99
+ let(:code) { subject::TYPES[type] }
100
+
101
+ subject { described_class }
102
+
103
+ it "should translate types to their pack codes" do
104
+ subject.compile([type]).should == code
105
+ end
106
+
107
+ it "should support specifying the length of a field" do
108
+ subject.compile([[type, 10]]).should == "#{code}10"
109
+ end
110
+
111
+ it "should raise ArgumentError for unknown types" do
112
+ lambda {
113
+ subject.compile([:foo])
114
+ }.should raise_error(ArgumentError)
115
+ end
116
+ end
117
+
118
+ describe "#initialize" do
119
+ subject { described_class.new [:uint32, :string] }
120
+
121
+ it "should store the types" do
122
+ subject.fields.should == [
123
+ :uint32,
124
+ :string
125
+ ]
126
+ end
127
+
128
+ it "should raise ArgumentError for unknown types" do
129
+ lambda {
130
+ described_class.new [:foo]
131
+ }.should raise_error(ArgumentError)
132
+ end
133
+ end
134
+
135
+ ENDIANNESS = if [0x1234].pack('S') == "\x34\x12"
136
+ :little
137
+ else
138
+ :big
139
+ end
140
+
141
+ let(:byte) { 0x41 }
142
+ let(:char) { 'A' }
143
+
144
+ let(:bytes) { [104, 101, 108, 108, 111] }
145
+ let(:chars) { bytes.map(&:chr).join }
146
+ let(:string) { chars }
147
+
148
+ let(:uint8) { 0xff }
149
+ let(:uint16) { 0xffff }
150
+ let(:uint32) { 0xffffffff }
151
+ let(:uint64) { 0xffffffffffffffff }
152
+
153
+ let(:int8) { -1 }
154
+ let(:int16) { -1 }
155
+ let(:int32) { -1 }
156
+ let(:int32) { -1 }
157
+ let(:int64) { -1 }
158
+
159
+ describe "#pack" do
160
+ context ":byte" do
161
+ subject { described_class.new [:byte] }
162
+
163
+ it "should pack a signed byte" do
164
+ subject.pack(byte).should == char
165
+ end
166
+ end
167
+
168
+ context "[:byte, n]" do
169
+ let(:n) { string.length }
170
+ subject { described_class.new [[:byte, n]] }
171
+
172
+ it "should pack multiple signed characters" do
173
+ subject.pack(*bytes).should == chars
174
+ end
175
+ end
176
+
177
+ context ":char" do
178
+ subject { described_class.new [:char] }
179
+
180
+ it "should pack a signed character" do
181
+ subject.pack(char).should == char
182
+ end
183
+ end
184
+
185
+ context "[:char, n]" do
186
+ let(:n) { string.length }
187
+ subject { described_class.new [[:char, n]] }
188
+
189
+ it "should pack multiple signed characters" do
190
+ subject.pack(*chars).should == string
191
+ end
192
+
193
+ context "padding" do
194
+ let(:padding) { 10 }
195
+ subject { described_class.new [[:char, n + padding]] }
196
+
197
+ it "should pad the string with '\\0' characters" do
198
+ subject.pack(*chars).should == (string + ("\0" * padding))
199
+ end
200
+ end
201
+ end
202
+
203
+ context ":uint8" do
204
+ subject { described_class.new [:uint8] }
205
+
206
+ it "should pack an unsigned 8bit integer" do
207
+ subject.pack(uint8).should == "\xff"
208
+ end
209
+ end
210
+
211
+ context ":uint16" do
212
+ subject { described_class.new [:uint16] }
213
+
214
+ it "should pack an unsigned 16bit integer" do
215
+ subject.pack(uint16).should == "\xff\xff"
216
+ end
217
+ end
218
+
219
+ context ":uint32" do
220
+ subject { described_class.new [:uint32] }
221
+
222
+ it "should pack an unsigned 32bit integer" do
223
+ subject.pack(uint32).should == "\xff\xff\xff\xff"
224
+ end
225
+ end
226
+
227
+ context ":uint64" do
228
+ subject { described_class.new [:uint64] }
229
+
230
+ it "should pack an unsigned 64bit integer" do
231
+ subject.pack(uint64).should == "\xff\xff\xff\xff\xff\xff\xff\xff"
232
+ end
233
+ end
234
+
235
+ context ":int8" do
236
+ subject { described_class.new [:int8] }
237
+
238
+ it "should pack an signed 8bit integer" do
239
+ subject.pack(int8).should == "\xff"
240
+ end
241
+ end
242
+
243
+ context ":int16" do
244
+ subject { described_class.new [:int16] }
245
+
246
+ it "should pack an unsigned 16bit integer" do
247
+ subject.pack(int16).should == "\xff\xff"
248
+ end
249
+ end
250
+
251
+ context ":int32" do
252
+ subject { described_class.new [:int32] }
253
+
254
+ it "should pack an unsigned 32bit integer" do
255
+ subject.pack(int32).should == "\xff\xff\xff\xff"
256
+ end
257
+ end
258
+
259
+ context ":int64" do
260
+ subject { described_class.new [:int64] }
261
+
262
+ it "should pack an unsigned 64bit integer" do
263
+ subject.pack(int64).should == "\xff\xff\xff\xff\xff\xff\xff\xff"
264
+ end
265
+ end
266
+
267
+ context ":string" do
268
+ subject { described_class.new [:string] }
269
+
270
+ it "should pack a string" do
271
+ subject.pack(string).should == "#{string}\0"
272
+ end
273
+ end
274
+ end
275
+
276
+ describe "#unpack" do
277
+ context ":byte" do
278
+ subject { described_class.new [:byte] }
279
+
280
+ it "should unpack a signed byte" do
281
+ subject.unpack(char).should == [byte]
282
+ end
283
+ end
284
+
285
+ context "[:byte, n]" do
286
+ let(:n) { string.length }
287
+ subject { described_class.new [[:byte, n]] }
288
+
289
+ it "should pack multiple signed characters" do
290
+ subject.unpack(chars).should == bytes
291
+ end
292
+ end
293
+
294
+ context ":char" do
295
+ subject { described_class.new [:char] }
296
+
297
+ it "should unpack a signed character" do
298
+ subject.unpack(char).should == [char]
299
+ end
300
+ end
301
+
302
+ context "[:char, n]" do
303
+ let(:n) { string.length }
304
+ subject { described_class.new [[:char, n]] }
305
+
306
+ it "should unpack multiple signed characters" do
307
+ subject.unpack(string).should == [chars]
308
+ end
309
+
310
+ context "padding" do
311
+ let(:padding) { 10 }
312
+ subject { described_class.new [[:char, n + padding]] }
313
+
314
+ it "should strip '\\0' padding characters" do
315
+ subject.unpack(string + ("\0" * padding)).should == [chars]
316
+ end
317
+ end
318
+ end
319
+
320
+ context ":uint8" do
321
+ subject { described_class.new [:uint8] }
322
+
323
+ it "should unpack an unsigned 8bit integer" do
324
+ subject.unpack("\xff").should == [uint8]
325
+ end
326
+ end
327
+
328
+ context ":uint16" do
329
+ subject { described_class.new [:uint16] }
330
+
331
+ it "should unpack an unsigned 16bit integer" do
332
+ subject.unpack("\xff\xff").should == [uint16]
333
+ end
334
+ end
335
+
336
+ context ":uint32" do
337
+ subject { described_class.new [:uint32] }
338
+
339
+ it "should unpack an unsigned 32bit integer" do
340
+ subject.unpack("\xff\xff\xff\xff").should == [uint32]
341
+ end
342
+ end
343
+
344
+ context ":uint64" do
345
+ subject { described_class.new [:uint64] }
346
+
347
+ it "should unpack an unsigned 64bit integer" do
348
+ subject.unpack("\xff\xff\xff\xff\xff\xff\xff\xff").should == [uint64]
349
+ end
350
+ end
351
+
352
+ context ":int8" do
353
+ subject { described_class.new [:int8] }
354
+
355
+ it "should unpack an signed 8bit integer" do
356
+ subject.unpack("\xff").should == [int8]
357
+ end
358
+ end
359
+
360
+ context ":int16" do
361
+ subject { described_class.new [:int16] }
362
+
363
+ it "should unpack an unsigned 16bit integer" do
364
+ subject.unpack("\xff\xff").should == [int16]
365
+ end
366
+ end
367
+
368
+ context ":int32" do
369
+ subject { described_class.new [:int32] }
370
+
371
+ it "should unpack an unsigned 32bit integer" do
372
+ subject.unpack("\xff\xff\xff\xff").should == [int32]
373
+ end
374
+ end
375
+
376
+ context ":int64" do
377
+ subject { described_class.new [:int64] }
378
+
379
+ it "should unpack an unsigned 64bit integer" do
380
+ subject.unpack("\xff\xff\xff\xff\xff\xff\xff\xff").should == [int64]
381
+ end
382
+ end
383
+
384
+ context ":string" do
385
+ subject { described_class.new [:string] }
386
+
387
+ it "should unpack a string" do
388
+ subject.unpack("#{string}\0").should == [string]
389
+ end
390
+ end
391
+ end
392
+
393
+ describe "#to_s" do
394
+ subject { described_class.new [:uint32, :string] }
395
+
396
+ it "should return the pack format String" do
397
+ subject.to_s.should == "LZ*"
398
+ end
399
+ end
400
+ end
@@ -109,50 +109,76 @@ describe IPAddr do
109
109
  end
110
110
  end
111
111
 
112
- context "CIDR addresses" do
113
- let(:fixed_addr) { IPAddr.new('10.1.1.2') }
114
- let(:class_c) { IPAddr.new('10.1.1.2/24') }
112
+ describe "each" do
113
+ context "CIDR addresses" do
114
+ let(:fixed_addr) { IPAddr.new('10.1.1.2') }
115
+ let(:class_c) { IPAddr.new('10.1.1.2/24') }
115
116
 
116
- it "should only iterate over one IP address for an address" do
117
- addresses = fixed_addr.map { |ip| IPAddr.new(ip) }
117
+ it "should only iterate over one IP address for an address" do
118
+ addresses = fixed_addr.map { |ip| IPAddr.new(ip) }
118
119
 
119
- addresses.length.should == 1
120
- fixed_addr.should include(addresses.first)
121
- end
120
+ addresses.length.should == 1
121
+ fixed_addr.should include(addresses.first)
122
+ end
122
123
 
123
- it "should iterate over all IP addresses contained within the IP range" do
124
- class_c.each do |ip|
125
- class_c.should include(IPAddr.new(ip))
124
+ it "should iterate over all IP addresses contained within the IP range" do
125
+ class_c.each do |ip|
126
+ class_c.should include(IPAddr.new(ip))
127
+ end
126
128
  end
127
- end
128
129
 
129
- it "should return an Enumerator when no block is given" do
130
- class_c.each.all? { |ip|
131
- class_c.include?(IPAddr.new(ip))
132
- }.should == true
130
+ it "should return an Enumerator when no block is given" do
131
+ class_c.each.all? { |ip|
132
+ class_c.include?(IPAddr.new(ip))
133
+ }.should == true
134
+ end
133
135
  end
134
- end
135
136
 
136
- context "globbed addresses" do
137
- let(:ipv4_range) { '10.1.1-5.1' }
138
- let(:ipv6_range) { '::ff::02-0a::c3' }
137
+ context "globbed addresses" do
138
+ let(:ipv4_range) { '10.1.1-5.1' }
139
+ let(:ipv6_range) { '::ff::02-0a::c3' }
140
+
141
+ it "should expand '*' ranges" do
142
+ octets = IPAddr.each("10.1.1.*").map { |ip| ip.split('.',4).last }
139
143
 
140
- it "should iterate over all IP addresses in an IPv4 range" do
141
- IPAddr.each(ipv4_range) do |ip|
142
- ip.should =~ /^10\.1\.[1-5]\.1$/
144
+ octets.should == ('1'..'254').to_a
143
145
  end
144
- end
145
146
 
146
- it "should iterate over all IP addresses in an IPv6 range" do
147
- IPAddr.each(ipv6_range) do |ip|
148
- ip.should =~ /^::ff::0[2-9a]::c3$/
147
+ it "should expend 'i-j' ranges" do
148
+ octets = IPAddr.each("10.1.1.10-20").map { |ip| ip.split('.',4).last }
149
+
150
+ octets.should == ('10'..'20').to_a
149
151
  end
150
- end
151
152
 
152
- it "should return an Enumerator when no block is given" do
153
- ips = IPAddr.each(ipv4_range)
154
-
155
- ips.all? { |ip| ip =~ /^10\.1\.[1-5]\.1$/ }.should == true
153
+ it "should expand 'i,j,k' ranges" do
154
+ octets = IPAddr.each("10.1.1.1,2,3").map { |ip| ip.split('.',4).last }
155
+
156
+ octets.should == ['1', '2', '3']
157
+ end
158
+
159
+ it "should expand combination 'i,j-k' ranges" do
160
+ octets = IPAddr.each("10.1.1.1,3-4").map { |ip| ip.split('.',4).last }
161
+
162
+ octets.should == ['1', '3', '4']
163
+ end
164
+
165
+ it "should iterate over all IP addresses in an IPv4 range" do
166
+ IPAddr.each(ipv4_range) do |ip|
167
+ ip.should =~ /^10\.1\.[1-5]\.1$/
168
+ end
169
+ end
170
+
171
+ it "should iterate over all IP addresses in an IPv6 range" do
172
+ IPAddr.each(ipv6_range) do |ip|
173
+ ip.should =~ /^::ff::0[2-9a]::c3$/
174
+ end
175
+ end
176
+
177
+ it "should return an Enumerator when no block is given" do
178
+ ips = IPAddr.each(ipv4_range)
179
+
180
+ ips.all? { |ip| ip =~ /^10\.1\.[1-5]\.1$/ }.should == true
181
+ end
156
182
  end
157
183
  end
158
184