ip 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,54 @@
1
+ #
2
+ # IP::Range - Calculates a range of IP addresses, and returns an
3
+ # Array of IP::Address objects.
4
+ #
5
+ # Usage::
6
+ #
7
+ # IP::Range['10.0.0.1', '10.0.0.2'] => IP::Address objects between
8
+ # 10.0.0.1 and 10.0.0.2 (inclusive)
9
+ #
10
+ # IP::Range can also take two IP::Address objects.
11
+ #
12
+ # Will throw a IP::AddressException if for some reason addresses
13
+ # cannot be parsed.
14
+ #
15
+
16
+ class IP::Range
17
+
18
+ #
19
+ # See the documentation for IP::Range for more information on this
20
+ # method.
21
+ #
22
+
23
+ def self.[](addr1, addr2)
24
+ raw1, raw2 = [nil, nil]
25
+ tmpip = nil
26
+
27
+ if addr1.kind_of? String
28
+ addr1 = IP::Address::Util.string_to_ip(addr1)
29
+ elsif ! addr1.kind_of? IP::Address
30
+ raise IP::AddressException.new("IP Address is not type String or IP::Address")
31
+ end
32
+
33
+ if addr2.kind_of? String
34
+ addr2 = IP::Address::Util.string_to_ip(addr2)
35
+ elsif ! addr2.kind_of? IP::Address
36
+ raise IP::AddressException.new("IP Address is not type String or IP::Address")
37
+ end
38
+
39
+ if addr2.class.name != addr1.class.name
40
+ raise IP::AddressException.new("First and Second IP in range are not of the same type")
41
+ end
42
+
43
+ raw1 = addr1.pack
44
+ raw2 = addr2.pack
45
+
46
+ range = []
47
+
48
+ # use the class we were given to force certain results, instead
49
+ # of relying on the fairly inaccurate unpack facility.
50
+ range = (raw1..raw2).collect { |x| addr1.class.new(x) }
51
+
52
+ return range
53
+ end
54
+ end
@@ -0,0 +1,144 @@
1
+ #
2
+ # General utility functions used by other IP classes.
3
+ #
4
+
5
+ module IP::Address::Util
6
+ #
7
+ # Pack an object into a long integer used for calculation. Returns a
8
+ # 'FixNum' type. Can take both IP::Address::IPv4 and
9
+ # IP::Address::IPv6 objects.
10
+ #
11
+
12
+ def pack(ip)
13
+ return ip.pack
14
+ end
15
+
16
+ module_function :pack
17
+
18
+ #
19
+ # This routine takes an array of integers which are intended to be
20
+ # an IP address, and joins them into a single integer used for easy
21
+ # calculation.
22
+ #
23
+ # IPv4 and IPv6 objects are packed into the same size, a 128-bit
24
+ # integer. This is done for easier processing within the library.
25
+ #
26
+
27
+ def raw_pack(array)
28
+ ret = 0
29
+ myip = array.reverse
30
+ 8.times { |x| ret = ret | myip[x] << 16*x }
31
+ return ret
32
+ end
33
+
34
+ module_function :raw_pack
35
+
36
+ #
37
+ # Take an 'Integer' type and return an IP::Address object.
38
+ #
39
+ # This routine will 'guess' at what version of IP addressing you
40
+ # want, returning the oldest type possible (IPv4 addresses will
41
+ # return IP::Address::IPv4 objects).
42
+ #
43
+ # In almost all cases, you'll want to use the type-specific
44
+ # routines, which merely involve passing an Integer to the
45
+ # constructor for each class.
46
+ #
47
+ def unpack(ip)
48
+ ret = raw_unpack(ip)
49
+
50
+ # any IPv6 address should meet this criteria.
51
+ if ret[2..8].any? { |x| x > 0 }
52
+ return IP::Address::IPv6.new(ip)
53
+ end
54
+
55
+ return IP::Address::IPv4.new(ip)
56
+ end
57
+
58
+ module_function :unpack
59
+
60
+ #
61
+ # Take a 'FixNum' and return it's in-place octet
62
+ # representation. This is mostly a helper method for the unpack
63
+ # routines.
64
+ #
65
+
66
+ def raw_unpack(ip)
67
+ ret = []
68
+ 8.times { |x| ret.push((ip >> 16*x) & 0xFFFF) }
69
+ return ret
70
+ end
71
+
72
+ module_function :raw_unpack
73
+
74
+ #
75
+ # Returns a short subnet mask - works for all IP::Address objects.
76
+ #
77
+ # ex:
78
+ # short_netmask(IP::Address::IPv4.new("255.255.255.255")) => 32
79
+ # short_netmask(IP::Address::IPv6.new("2001:0DB8:0000:CD30:0000:0000:0000:0000")) => 60
80
+ #
81
+
82
+ def short_netmask(ip)
83
+ #
84
+ # This method handles 128-bit integers better for both types of
85
+ # addresses, even though it is a bit slower.
86
+ #
87
+ # TODO: there really is probably a better way to do this.
88
+ #
89
+
90
+ s = ip.pack.to_s(2)
91
+
92
+ pad = 0
93
+
94
+ case ip.class.object_id
95
+ when IP::Address::IPv6.object_id
96
+ pad = 128
97
+ when IP::Address::IPv4.object_id
98
+ pad = 32
99
+ end
100
+
101
+ s = ("0" * (pad - s.length)) + s
102
+
103
+ return s.rindex("1") + 1
104
+ end
105
+
106
+ module_function :short_netmask
107
+
108
+ def long_netmask(short)
109
+ warn "This function is deprecated, please use IP::Address::Util.long_netmask_ipv4 instead."
110
+ return long_netmask_ipv4(short)
111
+ end
112
+
113
+ module_function :long_netmask
114
+
115
+ #
116
+ # Given a CIDR-notation "short" netmask, returns a IP::Address object containing
117
+ # the equivalent "long" netmask.
118
+ #
119
+ # ex:
120
+ # long_netmask(32) => IP::Address object of "255.255.255.255"
121
+ # long_netmask(28) => IP::Address object of "255.255.255.240"
122
+ #
123
+
124
+ def long_netmask_ipv4(short)
125
+ raw = (0xFFFFFFFF << (32 - short)) & 0xFFFFFFFF
126
+ return IP::Address::Util.unpack(raw)
127
+ end
128
+
129
+ module_function :long_netmask_ipv4
130
+
131
+ #
132
+ # This takes a string which supposedly contains an IP address, and
133
+ # tries to figure out if it is a IPv6 or IPv4 address. Returns a
134
+ # constructed object of the proper type.
135
+ #
136
+
137
+ def string_to_ip(s)
138
+ return IP::Address::IPv6.new(s) if s.match(/:/)
139
+ return IP::Address::IPv4.new(s)
140
+ end
141
+
142
+ module_function :string_to_ip
143
+
144
+ end
data/test/ip.rb CHANGED
@@ -7,8 +7,9 @@ class CIDRTest < Test::Unit::TestCase
7
7
  return "IP::CIDR tests"
8
8
  end
9
9
 
10
- def test_init
10
+ def test_init_generic
11
11
  a = nil
12
+
12
13
  begin
13
14
  IP::CIDR.new(Hash.new)
14
15
  a = false
@@ -16,52 +17,112 @@ class CIDRTest < Test::Unit::TestCase
16
17
  a = true
17
18
  end
18
19
 
19
- assert(a, "data types test #1")
20
+ assert(a, "only accepts string")
21
+
22
+ begin
23
+ IP::CIDR.new("foomatic_wootmaster/32")
24
+ a = false
25
+ rescue IP::AddressException => e
26
+ a = true
27
+ end
20
28
 
29
+ assert(a, "ensures we have a IP address")
30
+ end
31
+
32
+ def test_init_ipv6
33
+ a = nil
34
+
21
35
  begin
22
- IP::CIDR.new("10.0.0.1")
36
+ IP::CIDR.new("F00F:DEAD:BEEF::")
23
37
  a = false
24
38
  rescue IP::AddressException => e
25
39
  a = true
26
40
  end
41
+
42
+ assert(a, "no subnet")
43
+
44
+ begin
45
+ IP::CIDR.new("F00F:DEAD:BEEF::/")
46
+ a = false
47
+ rescue IP::AddressException => e
48
+ a = true
49
+ end
50
+
51
+ assert(a, "subnet marker, no integer")
27
52
 
28
- assert(a, "data types test #2")
53
+ begin
54
+ IP::CIDR.new("F00F:DEAD:BEEF::/asdf/32")
55
+ a = false
56
+ rescue IP::AddressException => e
57
+ a = true
58
+ end
59
+
60
+ assert(a, "'two' subnets")
61
+
62
+ begin
63
+ IP::CIDR.new("F00F:DEAD:BEEF::/foomatic_wootmaster")
64
+ a = false
65
+ rescue IP::AddressException => e
66
+ a = true
67
+ end
68
+
69
+ assert(a, "junk subnet")
70
+
71
+ begin
72
+ IP::CIDR.new("F00F:DEAD:BEEF::/255.255.255.255")
73
+ a = false
74
+ rescue IP::AddressException => e
75
+ a = true
76
+ end
77
+
78
+ assert(a, "ipv4 long subnet on ipv6")
79
+
80
+ cidr = IP::CIDR.new("F00F:DEAD:BEEF::0001/128")
81
+
82
+ # this sort of indirectly tests the ipv6 address manipulation.
83
+ assert(cidr.ip.short_address == "F00F:DEAD:BEEF::1", "ipv6 object constructed clean")
84
+ assert(cidr.mask == 128, "mask is set properly")
85
+ assert(cidr.cidr == "F00F:DEAD:BEEF::0001/128", "original CIDR preserved")
86
+ end
87
+
88
+ def test_init_ipv4
89
+ a = nil
29
90
 
30
91
  begin
31
- IP::CIDR.new("10.0.0.1/")
92
+ IP::CIDR.new("10.0.0.1")
32
93
  a = false
33
94
  rescue IP::AddressException => e
34
95
  a = true
35
96
  end
36
97
 
37
- assert(a, "data types test #3")
98
+ assert(a, "ipv4 data validation test #1")
38
99
 
39
100
  begin
40
- IP::CIDR.new("10.0.0.1/asdf/32")
101
+ IP::CIDR.new("10.0.0.1/")
41
102
  a = false
42
103
  rescue IP::AddressException => e
43
104
  a = true
44
105
  end
45
-
46
- assert(a, "data type test #4")
106
+
107
+ assert(a, "ipv4 data validation test #2")
47
108
 
48
109
  begin
49
- IP::CIDR.new("10.0.0.1/foomatic_wootmaster")
110
+ IP::CIDR.new("10.0.0.1/asdf/32")
50
111
  a = false
51
112
  rescue IP::AddressException => e
52
113
  a = true
53
114
  end
54
115
 
55
- assert(a, "data types test #5")
56
-
116
+ assert(a, "ipv4 data validation test #3")
117
+
57
118
  begin
58
- IP::CIDR.new("foomatic_wootmaster/32")
119
+ IP::CIDR.new("10.0.0.1/foomatic_wootmaster")
59
120
  a = false
60
121
  rescue IP::AddressException => e
61
122
  a = true
62
123
  end
63
-
64
- assert(a, "data types test #6")
124
+
125
+ assert(a, "ipv4 data validation test #4")
65
126
 
66
127
  begin
67
128
  IP::CIDR.new("10.0.0.1/255")
@@ -70,54 +131,94 @@ class CIDRTest < Test::Unit::TestCase
70
131
  a = true
71
132
  end
72
133
 
73
- assert(a, "data types test #7")
134
+ assert(a, "ipv4 data validation test #5")
74
135
 
75
136
  cidr = IP::CIDR.new("10.0.0.1/32")
76
137
 
77
- assert(cidr.ip.ip_address == "10.0.0.1", "data integrity test #1")
78
- assert(cidr.mask == 32, "data integrity test #2")
79
- assert(cidr.cidr == "10.0.0.1/32", "data integrity test #3")
138
+ assert(cidr.ip.ip_address == "10.0.0.1", "ipv4 data integrity test #1")
139
+ assert(cidr.mask == 32, "ipv4 data integrity test #2")
140
+ assert(cidr.cidr == "10.0.0.1/32", "ipv4 data integrity test #3")
80
141
 
81
142
  cidr = IP::CIDR.new("10.0.0.1/255.255.255.255")
82
143
 
83
- assert(cidr.ip.ip_address == "10.0.0.1", "data integrity test #4")
84
- assert(cidr.mask == 32, "data integrity test #5")
85
- assert(cidr.cidr == "10.0.0.1/255.255.255.255", "data integrity test #6")
144
+ assert(cidr.ip.ip_address == "10.0.0.1", "ipv4 data integrity test #4")
145
+ assert(cidr.mask == 32, "ipv4 data integrity test #5")
146
+ assert(cidr.cidr == "10.0.0.1/255.255.255.255", "ipv4 data integrity test #6")
86
147
  end
87
148
 
88
149
  def test_netmasks
89
- cidr = IP::CIDR.new("10.0.0.1/32")
90
- assert(cidr.short_netmask == 32, "netmask test #1")
91
- assert(cidr.long_netmask.ip_address == "255.255.255.255", "netmask test #2")
150
+ a = nil
92
151
 
93
- cidr = IP::CIDR.new("10.0.0.1/255.255.255.241")
94
- assert(cidr.short_netmask == 29, "netmask test #3")
95
- assert(cidr.long_netmask.ip_address == "255.255.255.248", "netmask test #4")
152
+ cidr = IP::CIDR.new("10.0.0.1/32")
153
+ assert(cidr.short_netmask == 32, "ipv4 netmask test #1")
154
+ assert(cidr.long_netmask.ip_address == "255.255.255.255", "ipv4 netmask test #2")
155
+
156
+ cidr = IP::CIDR.new("10.0.0.1/255.255.255.248")
157
+ assert(cidr.short_netmask == 29, "ipv4 netmask test #3")
158
+ assert(cidr.long_netmask.ip_address == "255.255.255.248", "ipv4 netmask test #4")
159
+
160
+ cidr = IP::CIDR.new("F00F:DEAD::/16")
161
+ assert(cidr.short_netmask == 16, "ipv6 has proper short netmask")
162
+
163
+ begin
164
+ cidr.long_netmask
165
+ a = false
166
+ rescue IP::AddressException => e
167
+ a = true
168
+ end
169
+
170
+ assert(a, "ipv6 cannot use a long netmask")
96
171
  end
97
172
 
98
173
  def test_first_last
99
174
  cidr = IP::CIDR.new("10.0.0.2/24")
100
- assert(cidr.first_ip.ip_address == "10.0.0.0", "first/last test #1")
101
- assert(cidr.last_ip.ip_address == "10.0.0.255", "first/last test #2")
175
+ assert(cidr.first_ip.ip_address == "10.0.0.0", "ipv4 first/last test #1")
176
+ assert(cidr.last_ip.ip_address == "10.0.0.255", "ipv4 first/last test #2")
102
177
  end
103
178
 
104
179
  def test_range
105
180
  cidr = IP::CIDR.new("10.0.0.2/24")
106
- assert(cidr.range.find_all { |x| x.ip_address == "10.0.0.1" }.length == 1, "range test #1")
107
- assert(cidr.range.find_all { |x| x.ip_address == "10.0.1.0" }.length == 0, "range test #2")
181
+ assert(cidr.range.find_all { |x| x.ip_address == "10.0.0.1" }.length == 1, "ipv4 range test #1")
182
+ assert(cidr.range.find_all { |x| x.ip_address == "10.0.1.0" }.length == 0, "ipv4 range test #2")
183
+
184
+ cidr = IP::CIDR.new("::0001/120")
185
+ assert(cidr.range.find_all { |x| x.ip_address == "0:0:0:0:0:0:0:00FF" }.length == 1, "ipv6 range test (included)")
186
+ assert(cidr.range.find_all { |x| x.ip_address ==" 0:0:0:0:0:0:0:0F00" }.length == 0, "ipv6 range test (not included)")
108
187
  end
109
188
 
110
189
  def test_overlaps
111
190
  cidr = IP::CIDR.new("10.0.0.2/24")
112
191
  cidr2 = IP::CIDR.new("10.0.0.1/29")
113
192
 
114
- assert(cidr.overlaps?(cidr2), "overlaps test #1")
193
+ assert(cidr.overlaps?(cidr2), "ipv4 overlaps test #1")
115
194
 
116
195
  cidr2 = IP::CIDR.new("10.0.0.1/16")
117
196
 
118
- assert(cidr2.overlaps?(cidr), "overlaps test #2")
119
- assert(cidr.overlaps?(cidr2), "overlaps test #3")
197
+ assert(cidr2.overlaps?(cidr), "ipv4 overlaps test #2")
198
+ assert(cidr.overlaps?(cidr2), "ipv4 overlaps test #3")
199
+
200
+ cidr = IP::CIDR.new("F00F:DEAD::/16")
201
+ cidr2 = IP::CIDR.new("F00F:BEEF::/16")
202
+
203
+ assert(cidr.overlaps?(cidr2), "ipv6 #overlaps? reports correctly #1")
204
+ assert(cidr2.overlaps?(cidr), "ipv6 #overlaps? reports correctly #2")
205
+ end
206
+
207
+ def test_includes
208
+ cidr = IP::CIDR.new("10.0.0.2/24")
209
+ ip = IP::Address::IPv4.new("10.0.0.1")
210
+
211
+ assert(cidr.includes?(ip), "ipv4 #includes? reports correctly (included)")
212
+ ip = IP::Address::IPv4.new("10.0.1.0")
213
+ assert(!cidr.includes?(ip), "ipv4 #includes? reports correctly (not included)")
214
+
215
+ cidr = IP::CIDR.new("FF00::/16")
216
+ ip = IP::Address::IPv6.new("FF00::DEAD")
217
+ assert(cidr.includes?(ip), "ipv6 #includes? reports correctly (included)")
218
+ ip = IP::Address::IPv6.new("F000::DEAD")
219
+ assert(!cidr.includes?(ip), "ipv6 #includes? reports correctly (not included)")
120
220
  end
221
+
121
222
  end
122
223
 
123
224
  class RangeTest < Test::Unit::TestCase
@@ -125,7 +226,75 @@ class RangeTest < Test::Unit::TestCase
125
226
  return "IP::Range tests"
126
227
  end
127
228
 
128
- def test_range
229
+ def test_range_generic
230
+ a = nil
231
+ begin
232
+ IP::Range[Hash.new, ""]
233
+ a = false
234
+ rescue Exception => e
235
+ a = true
236
+ end
237
+
238
+ assert(a, "generic data types test #1")
239
+
240
+ begin
241
+ IP::Range["", Hash.new]
242
+ a = false
243
+ rescue Exception => e
244
+ a = true
245
+ end
246
+
247
+ assert(a, "generic data types test #2")
248
+
249
+ begin
250
+ IP::Range[IP::Address::IPv6.new("F00F::"), IP::Address::IPv4.new("10.0.0.1")]
251
+ a = false
252
+ rescue Exception => e
253
+ a = true
254
+ end
255
+
256
+ assert(a, "generic data types test #3")
257
+
258
+ begin
259
+ IP::Range[IP::Address::IPv4.new("10.0.0.1"), IP::Address::IPv6.new("F00F::")]
260
+ a = false
261
+ rescue Exception => e
262
+ a = true
263
+ end
264
+
265
+ assert(a, "generic data types test #4")
266
+ end
267
+
268
+ def test_range_ipv6
269
+ a = nil
270
+
271
+ begin
272
+ IP::Range["::0001", "::00F0"]
273
+ a = true
274
+ rescue Exception => e
275
+ a = false
276
+ end
277
+
278
+ assert(a, "ipv6 data types test #1")
279
+
280
+ begin
281
+ IP::Range[IP::Address::IPv6.new("::0001"), IP::Address::IPv6.new("::00F0")]
282
+ a = true
283
+ rescue Exception => e
284
+ a = false
285
+ end
286
+
287
+ assert(a, "ipv6 data types test #2")
288
+
289
+ range = IP::Range["::0001", "::0010"]
290
+
291
+ assert(range.find_all { |x| x.short_address == "::1" }.length == 1, "ipv6 range check #1")
292
+ assert(range.find_all { |x| x.short_address == "::0010" }.length == 1, "ipv6 range check #2")
293
+ assert(range.find_all { |x| x.short_address == "::000A" }.length == 1, "ipv6 range check #3")
294
+ assert(range.find_all { |x| x.short_address == "::0011" }.length == 0, "ipv6 range check #4")
295
+ end
296
+
297
+ def test_range_ipv4
129
298
  a = nil
130
299
  begin
131
300
  IP::Range["10.0.0.1", "10.0.0.2"]
@@ -134,37 +303,205 @@ class RangeTest < Test::Unit::TestCase
134
303
  a = false
135
304
  end
136
305
 
137
- assert(a, "data types test #1")
306
+ assert(a, "ipv4 data types test #1")
138
307
 
139
308
  begin
140
- IP::Range[IP::Address.new("10.0.0.1"), IP::Address.new("10.0.0.2")]
309
+ IP::Range[IP::Address::IPv4.new("10.0.0.1"), IP::Address::IPv4.new("10.0.0.2")]
141
310
  a = true
142
311
  rescue Exception => e
143
312
  a = false
144
313
  end
145
314
 
146
- assert(a, "data types test #2")
315
+ assert(a, "ipv4 data types test #2")
147
316
 
148
317
  range = IP::Range["10.0.0.1", "10.0.0.10"]
149
318
 
150
- assert(range.find_all { |x| x.ip_address == "10.0.0.1" }.length == 1, "range check #1")
151
- assert(range.find_all { |x| x.ip_address == "10.0.0.10" }.length == 1, "range check #2")
152
- assert(range.find_all { |x| x.ip_address == "10.0.0.7" }.length == 1, "range check #3")
153
- assert(range.find_all { |x| x.ip_address == "10.0.0.11" }.length == 0, "range check #4")
319
+ assert(range.find_all { |x| x.ip_address == "10.0.0.1" }.length == 1, "ipv4 range check #1")
320
+ assert(range.find_all { |x| x.ip_address == "10.0.0.10" }.length == 1, "ipv4 range check #2")
321
+ assert(range.find_all { |x| x.ip_address == "10.0.0.7" }.length == 1, "ipv4 range check #3")
322
+ assert(range.find_all { |x| x.ip_address == "10.0.0.11" }.length == 0, "ipv4 range check #4")
323
+ end
154
324
 
325
+ end
326
+
327
+ class IPv6AddressTest < Test::Unit::TestCase
328
+ def name
329
+ return "IP::Address::IPv6 tests"
330
+ end
331
+
332
+ def test_init
333
+ a = nil
334
+
335
+ # test the good data first...
336
+
337
+ begin
338
+ IP::Address::IPv6.new("0000:0000:0000:0000:0000:0000:0000:0001")
339
+ a = true
340
+ rescue IP::AddressException => e
341
+ a = false
342
+ end
343
+
344
+ assert(a, "full address")
345
+
346
+ begin
347
+ IP::Address::IPv6.new("::0001")
348
+ a = true
349
+ rescue IP::AddressException => e
350
+ a = false
351
+ end
352
+
353
+ assert(a, "wildcard address, wildcard left")
354
+
355
+ begin
356
+ IP::Address::IPv6.new("FF00::")
357
+ a = true
358
+ rescue IP::AddressException => e
359
+ a = false
360
+ end
361
+
362
+ assert(a, "wildcard address, wildcard right")
363
+
364
+ begin
365
+ IP::Address::IPv6.new("FF00::0001")
366
+ a = true
367
+ rescue IP::AddressException => e
368
+ a = false
369
+ end
370
+
371
+ assert(a, "wildcard address, wildcard center")
372
+
373
+ begin
374
+ IP::Address::IPv6.new("FF00:BEEF::0001")
375
+ a = true
376
+ rescue IP::AddressException => e
377
+ a = false
378
+ end
379
+
380
+ assert(a, "wildcard address, wildcard center with two leading")
381
+
382
+ begin
383
+ IP::Address::IPv6.new("FF00::BEEF:0001")
384
+ a = true
385
+ rescue IP::AddressException => e
386
+ a = false
387
+ end
388
+
389
+ assert(a, "wildcard address, wildcard center with two trailing")
390
+
391
+ begin
392
+ IP::Address::IPv6.new("::1.2.3.4")
393
+ a = true
394
+ rescue IP::AddressException => e
395
+ puts e
396
+ a = false
397
+ end
398
+
399
+ assert(a, "IPv4 address in IPv6, wildcard left")
400
+
401
+ begin
402
+ IP::Address::IPv6.new("FFFF::1.2.3.4")
403
+ a = true
404
+ rescue IP::AddressException => e
405
+ a = false
406
+ end
407
+
408
+ assert(a, "IPv4 in IPv6, data on wildcard @ left")
409
+
410
+ begin
411
+ IP::Address::IPv6.new("FFFF:0000:0000:0000:0000:0000:1.2.3.4")
412
+ a = true
413
+ rescue IP::AddressException => e
414
+ a = false
415
+ end
416
+
417
+ assert(a, "IPv4 in IPv6, no wildcard")
418
+
419
+ # now, the tests that should fail
420
+
421
+ begin
422
+ IP::Address::IPv6.new("FF00:BEEF:")
423
+ a = false
424
+ rescue IP::AddressException => e
425
+ a = true
426
+ end
427
+
428
+ assert(a, "not enough octets")
429
+
430
+ begin
431
+ IP::Address::IPv6.new("FF00::BEEF::")
432
+ a = false
433
+ rescue IP::AddressException => e
434
+ a = true
435
+ end
436
+
437
+ assert(a, "double wildcard no trailer")
438
+
439
+ begin
440
+ IP::Address::IPv6.new("FF00::BEEF::DEAD")
441
+ a = false
442
+ rescue IP::AddressException => e
443
+ a = true
444
+ end
445
+
446
+ assert(a, "double wildcard w/ trailer")
447
+
448
+ begin
449
+ IP::Address::IPv6.new("HF00::0001")
450
+ a = false
451
+ rescue IP::AddressException => e
452
+ a = true
453
+ end
454
+
455
+ assert(a, "invalid hexidecimal")
456
+
457
+ begin
458
+ IP::Address::IPv6.new("1.2.3.4::0001")
459
+ a = false
460
+ rescue IP::AddressException => e
461
+ a = true
462
+ end
463
+
464
+ assert(a, "invalid IPv4 in IPv6")
465
+
466
+ end
467
+
468
+ def test_accessors
469
+ ip = IP::Address::IPv6.new("F00F::DEAD:BEEF")
470
+
471
+ assert(ip[0] == 61455 && ip.octet(0) == 61455, "#octet is integer representation, #[] is #octet")
472
+ assert(ip.octet_as_hex(0) == "F00F", "octet converts to hex properly")
473
+ assert(ip.ip_address == "F00F::DEAD:BEEF", '#ip_address preserves original address')
474
+ end
475
+
476
+ def test_address
477
+ ip = IP::Address::IPv6.new("F00F::DEAD:BEEF")
478
+ assert(ip.short_address == "F00F::DEAD:BEEF", 'wildcard left - #short_address returns a compressed version')
479
+ assert(ip.long_address == "F00F:0:0:0:0:0:DEAD:BEEF", 'wildcard left - #long_address returns the right thing')
480
+
481
+ ip = IP::Address::IPv6.new("F00F:DEAD::BEEF")
482
+ assert(ip.short_address == "F00F:DEAD::BEEF", 'wildcard right - #short_address returns a compressed version')
483
+ assert(ip.long_address == "F00F:DEAD:0:0:0:0:0:BEEF", 'wildcard right - #long_address returns the right thing')
484
+
485
+ ip = IP::Address::IPv6.new("F00F:DEAD:0:0:0:0:0:BEEF")
486
+ assert(ip.short_address == "F00F:DEAD::BEEF", 'no wildcard - #short_address returns a compressed version')
487
+ assert(ip.long_address == "F00F:DEAD:0:0:0:0:0:BEEF", 'no wildcard - #long_address returns the right thing')
488
+
489
+ ip = IP::Address::IPv6.new("F00F::DEAD:BEEF:0:0")
490
+ assert(ip.short_address == "F00F:0:0:0:DEAD:BEEF::", '#short_address returns a compressed version with wildcard @ right')
155
491
  end
156
492
 
157
493
  end
158
494
 
159
- class AddressTest < Test::Unit::TestCase
495
+
496
+ class IPv4AddressTest < Test::Unit::TestCase
160
497
  def name
161
- return "IP::Address tests"
498
+ return "IP::Address::IPv4 tests"
162
499
  end
163
500
 
164
501
  def test_init
165
502
  ip = nil
166
503
  begin
167
- ip = IP::Address.new(Hash.new)
504
+ ip = IP::Address::IPv4.new(Hash.new)
168
505
  rescue IP::AddressException => e
169
506
  assert(true, "init test #1")
170
507
  end
@@ -174,7 +511,7 @@ class AddressTest < Test::Unit::TestCase
174
511
  ip = nil
175
512
 
176
513
  begin
177
- ip = IP::Address.new("asdf")
514
+ ip = IP::Address::IPv4.new("asdf")
178
515
  rescue IP::AddressException => e
179
516
  assert(true, "init test #2")
180
517
  end
@@ -183,7 +520,7 @@ class AddressTest < Test::Unit::TestCase
183
520
  ip = nil
184
521
 
185
522
  begin
186
- ip = IP::Address.new("0.0.0")
523
+ ip = IP::Address::IPv4.new("0.0.0")
187
524
  rescue IP::AddressException => e
188
525
  assert(true, "init test #3")
189
526
  end
@@ -192,7 +529,7 @@ class AddressTest < Test::Unit::TestCase
192
529
  ip = nil
193
530
 
194
531
  begin
195
- ip = IP::Address.new("256.255.255.255")
532
+ ip = IP::Address::IPv4.new("256.255.255.255")
196
533
  rescue IP::AddressException => e
197
534
  assert(true, "init test #4")
198
535
  end
@@ -201,7 +538,7 @@ class AddressTest < Test::Unit::TestCase
201
538
 
202
539
  ip = nil
203
540
  begin
204
- ip = IP::Address.new("255.255.255.255aaaa")
541
+ ip = IP::Address::IPv4.new("255.255.255.255aaaa")
205
542
  rescue IP::AddressException => e
206
543
  assert(true, "init test #5")
207
544
  end
@@ -210,7 +547,7 @@ class AddressTest < Test::Unit::TestCase
210
547
 
211
548
  ip = nil
212
549
  begin
213
- ip = IP::Address.new("255.255.255.")
550
+ ip = IP::Address::IPv4.new("255.255.255.")
214
551
  rescue IP::AddressException => e
215
552
  assert(true, "init test #6")
216
553
  end
@@ -220,7 +557,7 @@ class AddressTest < Test::Unit::TestCase
220
557
  end
221
558
 
222
559
  def test_accessor
223
- ip = IP::Address.new("10.1.2.3")
560
+ ip = IP::Address::IPv4.new("10.1.2.3")
224
561
  assert(ip.ip_address == "10.1.2.3", "accessor test #1")
225
562
  assert(ip.octets[0] == 10, "accessor test #2")
226
563
  assert(ip.octets[3] == 3, "accessor test #3")
@@ -248,46 +585,19 @@ class UtilTest < Test::Unit::TestCase
248
585
 
249
586
  def test_pack_unpack
250
587
  address = "10.0.0.1"
251
- assert(IP::Address::Util.unpack(IP::Address::Util.pack(IP::Address.new(address))).ip_address == address, "pack/unpack test")
588
+ assert(IP::Address::Util.unpack(IP::Address::Util.pack(IP::Address::IPv4.new(address))).ip_address == address, "pack/unpack test")
252
589
  end
253
590
 
254
591
  def test_short_netmask
255
- ip = IP::Address.new("255.255.255.255")
592
+ ip = IP::Address::IPv4.new("255.255.255.255")
256
593
  assert(IP::Address::Util.short_netmask(ip) == 32, "Short Netmask Test #1")
257
- ip = IP::Address.new("255.255.255.241")
594
+ ip = IP::Address::IPv4.new("255.255.255.248")
258
595
  assert(IP::Address::Util.short_netmask(ip) == 29, "Short Netmask Test #2")
259
-
260
- nm = nil
261
-
262
- begin
263
- nm = IP::Address::Util.short_netmask(IP::Address.new("255.255.0.255"))
264
- rescue IP::BoundaryException => e
265
- assert(true, "Short Netmask BoundaryException Check #1")
266
- end
267
-
268
- assert(false, "Short Netmask BoundaryException Check #1") if nm
269
-
270
- nm = nil
271
-
272
- begin
273
- nm = IP::Address::Util.short_netmask(IP::Address.new("255.255.240.255"))
274
- rescue IP::BoundaryException => e
275
- assert(true, "Short Netmask BoundaryException check #2")
276
- end
277
-
278
- assert(false, "Short Netmask BoundaryException check #2") if nm
279
596
  end
280
597
 
281
598
  def test_long_netmask
282
- assert(IP::Address::Util.long_netmask(32).ip_address == "255.255.255.255", "Long Netmask Test #1")
283
- assert(IP::Address::Util.long_netmask(29).ip_address == "255.255.255.248", "Long Netmask Test #2")
284
- end
285
-
286
- def test_binary_vector
287
- assert(IP::Address::Util.binary_vector(255).length == 8, "Binary Vector Test #1")
288
- assert(IP::Address::Util.binary_vector(240).find_all { |x| x == 1 }.length == 4, "Binary Vector Test #2")
289
- assert(IP::Address::Util.binary_vector(241).find_all { |x| x == 1 }.length == 5, "Binary Vector Test #3")
290
- assert(IP::Address::Util.binary_vector(240)[0] == 1, "Binary Vector Test #4")
599
+ assert(IP::Address::Util.long_netmask_ipv4(32).ip_address == "255.255.255.255", "Long Netmask Test #1")
600
+ assert(IP::Address::Util.long_netmask_ipv4(29).ip_address == "255.255.255.248", "Long Netmask Test #2")
291
601
  end
292
602
 
293
603
  end