netaddr 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of netaddr might be problematic. Click here for more details.

data/changelog ADDED
@@ -0,0 +1,27 @@
1
+
2
+ ==Version
3
+ *1.2.0*
4
+
5
+
6
+ ===Known Issues
7
+
8
+ * users may directly modify CIDR objects stored within a Tree,
9
+ essentially invalidating the structure of that Tree
10
+
11
+
12
+ ===Changes
13
+
14
+ * CIDRv4#new and CIDRv6#new methods have been changed for the sake of speed improvements.
15
+ Please use the CIDR#create method instead.
16
+ * changes to CIDR#wildcard_mask
17
+ * bug fix with validate_eui method
18
+ * bug fix with validate_ip_addr
19
+ * bug fix and *vast* simplification of NetAddr.merge
20
+
21
+
22
+ ===New Features
23
+
24
+ * speed improvements
25
+ * added CIDR#set_wildcard_mask
26
+ * added <=>, >, <, == methods to CIDR
27
+ * NetAddr.merge now reports which CIDR addresses were used to create new summary addresses
data/lib/cidr.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  =begin rdoc
2
2
  Copyleft (c) 2006 Dustin Spinhirne (www.spinhirne.com)
3
-
3
+
4
4
  Licensed under the same terms as Ruby, No Warranty is provided.
5
5
  =end
6
6
 
@@ -50,10 +50,13 @@ private_class_method :new
50
50
 
51
51
  # Hash of custom tags. Should be in the format tag => value.
52
52
  attr_reader :tag
53
-
53
+
54
54
  # Integer of either 32 or 128 bits in length, with all bits set to 1
55
55
  attr_reader :all_f
56
56
 
57
+ # Integer representing number of bits in this CIDR address
58
+ attr_reader :address_len
59
+
57
60
  # Hash of custom tags. Should be in the format tag => value.
58
61
  #
59
62
  # Example:
@@ -67,6 +70,52 @@ private_class_method :new
67
70
  @tag = new_tag
68
71
  end
69
72
 
73
+ #==============================================================================#
74
+ # initialize()
75
+ #==============================================================================#
76
+
77
+ # This method performs absolutely no error checking, and is meant to be used only by
78
+ # other internal methods for the sake of the speedier creation of CIDR objects.
79
+ # Please consider using #create unless you know what you are doing with 100% certainty.
80
+ #
81
+ #===Arguments:
82
+ #* ip - Integer representing an ip address
83
+ #* netmask - Integer representing a binary mask
84
+ #* tag - Hash used to append custom tags to CIDR
85
+ #* wildcard_mask - Integer representing a binary mask
86
+ #* wildcard_mask_bit_flipped - indicates whether or not the wildcard_mask is bit-flipped or not
87
+ #
88
+ def initialize(ip, netmask=nil, tag={}, wildcard_mask=nil, wildcard_mask_bit_flipped=false)
89
+ @ip = ip
90
+
91
+ if ( self.kind_of?(NetAddr::CIDRv4) )
92
+ @version = 4
93
+ @address_len = 32
94
+ else
95
+ @version = 6
96
+ @address_len = 128
97
+ end
98
+ @all_f = 2**@address_len - 1
99
+
100
+ if (netmask)
101
+ @netmask = netmask
102
+ else
103
+ @netmask = 2**@address_len - 1
104
+ end
105
+
106
+ @network = (@ip & @netmask)
107
+ @hostmask = @netmask ^ @all_f
108
+ @tag = tag
109
+
110
+ if (!wildcard_mask)
111
+ @wildcard_mask = @netmask
112
+ else
113
+ @wildcard_mask = wildcard_mask
114
+ @wildcard_mask = ~@wildcard_mask if (wildcard_mask_bit_flipped)
115
+ end
116
+
117
+ end
118
+
70
119
  #==============================================================================#
71
120
  # create()
72
121
  #==============================================================================#
@@ -78,87 +127,292 @@ private_class_method :new
78
127
  #:PackedNetmask takes precedence over netmask given within CIDR addresses.
79
128
  #Version will be auto-detected if not specified.
80
129
  #
81
- # cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
82
- # cidr4 = NetAddr::CIDR.create('192.168.1.1 255.255.255.0')
83
- # cidr4_2 = NetAddr::CIDR.create(0x0a010001,
84
- # :PackedNetmask => 0xffffff00
85
- # :Version => 4)
86
- # cidr4_3 = NetAddr::CIDRv4.new('192.168.1.1',
87
- # :WildcardMask => ['0.7.0.255', :inversed])
88
- # cidr4_4 = NetAddr::CIDRv4.new('192.168.5.0',
89
- # :WildcardMask => ['255.248.255.0'])
90
- # cidr6 = NetAddr::CIDR.create('fec0::/64')
91
- # cidr6 = NetAddr::CIDR.create('fec0::/64',
92
- # :Tag => {'interface' => 'g0/1'})
93
- # cidr6_2 = NetAddr::CIDR.create('::ffff:192.168.1.1/96')
130
+ # NetAddr::CIDR.create('192.168.1.1/24')
131
+ # NetAddr::CIDR.create('192.168.1.1 255.255.255.0')
132
+ # NetAddr::CIDR.create(0x0a010001,
133
+ # :PackedNetmask => 0xffffff00
134
+ # :Version => 4)
135
+ # NetAddr::CIDR.create('192.168.1.1',
136
+ # :WildcardMask => ['0.7.0.255', true])
137
+ # NetAddr::CIDR.create('192.168.1.1',
138
+ # :WildcardMask => [0x000007ff, true]
139
+ # NetAddr::CIDR.create('192.168.5.0',
140
+ # :WildcardMask => ['255.248.255.0'])
141
+ # NetAddr::CIDR.create('fec0::/64')
142
+ # NetAddr::CIDR.create('fec0::/64',
143
+ # :Tag => {'interface' => 'g0/1'})
144
+ # NetAddr::CIDR.create('::ffff:192.168.1.1/96')
94
145
  #
95
146
  #===Arguments:
96
- #* CIDR address as a String, or a packed IP address as an Integer
97
- #* Optional Hash with the following keys:
98
- # :PackedNetmask -- Integer representation of an IP Netmask (optional)
99
- # :Version -- IP version - Integer (optional)
100
- # :Tag -- Custom descriptor tag - Hash, tag => value. (optional)
147
+ #* addr = CIDR address as a String, or a packed IP address as an Integer
148
+ #* options = Hash with the following keys:
149
+ # :PackedNetmask -- Integer representation of an IP Netmask
150
+ # :Version -- IP version - Integer
151
+ # :Tag -- Custom descriptor tag - Hash, tag => value.
101
152
  # :WildcardMask -- 2 element Array. First element contains a special bit mask used for
102
- # advanced IP pattern matching. The second element should be :inversed if this
103
- # bit mask is in inverse format. (optional)
153
+ # advanced IP pattern matching. The second element should be set to True if this
154
+ # bit mask is bit flipped.
104
155
  #
105
156
  def CIDR.create(addr, options=nil)
106
157
  known_args = [:PackedNetmask, :Version, :Tag, :WildcardMask]
107
- cidr = nil
108
- packed_ip = nil
109
- version = nil
110
-
111
- # validate addr arg
112
- if (addr.kind_of?(String))
113
- cidr = addr
114
- elsif (addr.kind_of?(Integer))
115
- packed_ip = addr
116
- else
117
- raise ArgumentError, "String or Integer expected for argument 'addr' but #{addr.class} provided."
118
- end
158
+ ip, netmask, tag = nil, nil, {}
159
+ version, wildcard_mask ,wildcard_mask_bit_flipped = nil, nil, false
160
+ packed_netmask, all_f = nil, nil
119
161
 
120
162
  # validate options
121
- if (options)
163
+ if (options)
122
164
  raise ArgumentError, "Hash expected for argument 'options' but " +
123
165
  "#{options.class} provided." if (!options.kind_of?(Hash) )
124
166
  NetAddr.validate_args(options.keys,known_args)
167
+
168
+ if (options.has_key?(:PackedNetmask))
169
+ packed_netmask = options[:PackedNetmask]
170
+ raise ArgumentError, "Expected Integer, but #{packed_netmask.class} " +
171
+ "provided for option :PackedNetmask." if (!packed_netmask.kind_of?(Integer))
172
+ end
173
+
174
+ if (options.has_key?(:Tag))
175
+ tag = options[:Tag]
176
+ if (!tag.kind_of? Hash)
177
+ raise ArgumentError, "Expected Hash, but #{tag.class} provided for option :Tag."
178
+ end
179
+ end
180
+
125
181
  if (options.has_key?(:Version))
126
182
  version = options[:Version]
127
- options.delete(:Version)
128
183
  if (version != 4 && version != 6)
129
184
  raise VersionError, ":Version should be 4 or 6, but was '#{version}'."
130
185
  end
131
186
  end
187
+
188
+ if (options.has_key?(:WildcardMask))
189
+ if (!options[:WildcardMask].kind_of?(Array))
190
+ raise ArgumentError, "Expected Array, but #{options[:WildcardMask].class} provided for option :WildcardMask."
191
+ end
192
+
193
+ wildcard_mask = options[:WildcardMask][0]
194
+ if (!wildcard_mask.kind_of?(String) && !wildcard_mask.kind_of?(Integer))
195
+ raise ArgumentError, "Expected String or Integer, but #{wildcard_mask.class} provided for wildcard mask."
196
+ end
197
+ wildcard_mask_bit_flipped = true if (options[:WildcardMask][1] && options[:WildcardMask][1].kind_of?(TrueClass))
198
+ end
132
199
  end
133
200
 
134
- # attempt to determine version if not provided
135
- if (!version)
136
- if (packed_ip)
137
- if (packed_ip < 2**32)
138
- version = 4
139
- else
140
- version = 6
201
+ # validate addr arg & set version if not provided by user
202
+ if (addr.kind_of?(String))
203
+ version = NetAddr.detect_ip_version(addr) if (!version)
204
+
205
+ # if extended netmask provided. should only apply to ipv4
206
+ if (version == 4 && addr =~ /.+\s+.+/ )
207
+ addr,netmask = addr.split(' ')
208
+ end
209
+
210
+ # if netmask part of ip, then separate ip & mask.
211
+ if (addr =~ /\//)
212
+ ip,netmask = addr.split(/\//)
213
+ if (!ip || !netmask)
214
+ raise ArgumentError, "CIDR address is improperly formatted. Missing netmask after '/' character."
141
215
  end
142
216
  else
143
- if (cidr =~ /\./ && cidr !~ /:/)
217
+ ip = addr
218
+ end
219
+
220
+ NetAddr.validate_ip_str(ip,version)
221
+ ip = NetAddr.ip_str_to_int(ip,version)
222
+
223
+ elsif (addr.kind_of?(Integer))
224
+ ip = addr
225
+ if (!version)
226
+ if (ip < 2**32)
144
227
  version = 4
145
- elsif (cidr =~ /:/)
228
+ else
146
229
  version = 6
147
230
  end
148
231
  end
232
+ NetAddr.validate_ip_int(ip,version)
233
+
234
+ else
235
+ raise ArgumentError, "String or Integer expected for argument 'addr' but #{addr.class} provided."
149
236
  end
150
237
 
151
- # create CIDRvX object
152
- if (version == 4)
153
- return(NetAddr::CIDRv4.new(addr, options))
154
- elsif (version == 6)
155
- return(NetAddr::CIDRv6.new(addr, options))
238
+ # set all_f based on version
239
+ all_f = 2**32-1
240
+ all_f = 2**128-1 if (version == 6)
241
+
242
+ # set netmask. packed_netmask takes precedence. set to all_f if no netmask provided
243
+ if (packed_netmask)
244
+ NetAddr.validate_netmask_int(packed_netmask,version,true)
245
+ netmask = packed_netmask
246
+ elsif (netmask)
247
+ NetAddr.validate_netmask_str(netmask,version)
248
+ netmask = NetAddr.netmask_str_to_int(netmask, version)
156
249
  else
157
- raise ArgumentError, "IP version omitted or could not be detected."
250
+ netmask = all_f
251
+ end
252
+
253
+ # set wildcard mask if not provided, or validate if provided.
254
+ if (wildcard_mask)
255
+ begin
256
+ if (wildcard_mask.kind_of?(String))
257
+ NetAddr.validate_ip_str(wildcard_mask,version)
258
+ wildcard_mask = NetAddr.ip_str_to_int(wildcard_mask, version)
259
+ else (wildcard_mask.kind_of?(Integer))
260
+ NetAddr.validate_ip_int(wildcard_mask,version)
261
+ end
262
+ rescue Exception => error
263
+ raise ValidationError, "Provided wildcard mask failed validation: #{error}"
264
+ end
265
+ end
266
+
267
+ return( NetAddr.cidr_build(version, ip, netmask, tag, wildcard_mask, wildcard_mask_bit_flipped) )
268
+ end
269
+
270
+ #==============================================================================#
271
+ # <=>()
272
+ #==============================================================================#
273
+
274
+ #===Synopsis
275
+ #Compare the sort order of the current CIDR with a provided CIDR and return:
276
+ #* 1 if the current CIDR is greater than the provided CIDR
277
+ #* 0 if the current CIDR and the provided CIDR are equal (base address and netmask are equal)
278
+ #* -1 if the current CIDR is less than the provided CIDR
279
+ #
280
+ #===Arguments:
281
+ #* CIDR address or NetAddr::CIDR object
282
+ #
283
+ #===Returns:
284
+ #* Integer
285
+ #
286
+ def <=>(cidr)
287
+ if (!cidr.kind_of?(NetAddr::CIDR))
288
+ begin
289
+ cidr = NetAddr::CIDR.create(cidr)
290
+ rescue Exception => error
291
+ raise ArgumentError, "Provided argument raised the following " +
292
+ "errors: #{error}"
293
+ end
294
+ end
295
+
296
+ if (cidr.version != @version)
297
+ raise VersionError, "Attempted to compare a version #{cidr.version} CIDR " +
298
+ "with a version #{@version} CIDR."
158
299
  end
159
300
 
301
+ # compare
302
+ comparasin = NetAddr.cidr_gt_lt(self,cidr)
303
+
304
+ return(comparasin)
160
305
  end
161
306
 
307
+ #==============================================================================#
308
+ # >()
309
+ #==============================================================================#
310
+
311
+ #===Synopsis
312
+ #Compare the sort order of the current CIDR with a provided CIDR and return true
313
+ #if current CIDR is greater than provided CIDR.
314
+ #
315
+ #===Arguments:
316
+ #* CIDR address or NetAddr::CIDR object
317
+ #
318
+ #===Returns:
319
+ #* true or false
320
+ #
321
+ def >(cidr)
322
+ if (!cidr.kind_of?(NetAddr::CIDR))
323
+ begin
324
+ cidr = NetAddr::CIDR.create(cidr)
325
+ rescue Exception => error
326
+ raise ArgumentError, "Provided argument raised the following " +
327
+ "errors: #{error}"
328
+ end
329
+ end
330
+
331
+ if (cidr.version != @version)
332
+ raise VersionError, "Attempted to compare a version #{cidr.version} CIDR " +
333
+ "with a version #{@version} CIDR."
334
+ end
335
+
336
+ # compare
337
+ gt = false
338
+ gt = true if ( NetAddr.cidr_gt_lt(self,cidr) == 1)
339
+
340
+ return(gt)
341
+ end
342
+
343
+ #==============================================================================#
344
+ # <()
345
+ #==============================================================================#
346
+
347
+ #===Synopsis
348
+ #Compare the sort order of the current CIDR with a provided CIDR and return true
349
+ #if current CIDR is less than provided CIDR.
350
+ #
351
+ #===Arguments:
352
+ #* CIDR address or NetAddr::CIDR object
353
+ #
354
+ #===Returns:
355
+ #* true or false
356
+ #
357
+ def <(cidr)
358
+ if (!cidr.kind_of?(NetAddr::CIDR))
359
+ begin
360
+ cidr = NetAddr::CIDR.create(cidr)
361
+ rescue Exception => error
362
+ raise ArgumentError, "Provided argument raised the following " +
363
+ "errors: #{error}"
364
+ end
365
+ end
366
+
367
+ if (cidr.version != @version)
368
+ raise VersionError, "Attempted to compare a version #{cidr.version} CIDR " +
369
+ "with a version #{@version} CIDR."
370
+ end
371
+
372
+ # compare
373
+ lt = false
374
+ lt = true if ( NetAddr.cidr_gt_lt(self,cidr) == -1)
375
+
376
+ return(lt)
377
+ end
378
+
379
+ #==============================================================================#
380
+ # ==()
381
+ #==============================================================================#
382
+
383
+ #===Synopsis
384
+ #Compare the sort order of the current CIDR with a provided CIDR and return true
385
+ #if current CIDR is equal to the provided CIDR.
386
+ #
387
+ #===Arguments:
388
+ #* CIDR address or NetAddr::CIDR object
389
+ #
390
+ #===Returns:
391
+ #* true or false
392
+ #
393
+ def ==(cidr)
394
+ if (!cidr.kind_of?(NetAddr::CIDR))
395
+ begin
396
+ cidr = NetAddr::CIDR.create(cidr)
397
+ rescue Exception => error
398
+ raise ArgumentError, "Provided argument raised the following " +
399
+ "errors: #{error}"
400
+ end
401
+ end
402
+
403
+ if (cidr.version != @version)
404
+ raise VersionError, "Attempted to compare a version #{cidr.version} CIDR " +
405
+ "with a version #{@version} CIDR."
406
+ end
407
+
408
+ # compare
409
+ eq = false
410
+ eq = true if ( NetAddr.cidr_gt_lt(self,cidr) == 0)
411
+
412
+ return(eq)
413
+ end
414
+ alias :eql? :==
415
+
162
416
  #==============================================================================#
163
417
  # arpa()
164
418
  #==============================================================================#
@@ -168,11 +422,6 @@ private_class_method :new
168
422
  #return either an in-addr.arpa. or ip6.arpa. string. The netmask will be used
169
423
  #to determine the length of the returned string.
170
424
  #
171
- # cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
172
- # cidr6 = NetAddr::CIDR.create('fec0::/64')
173
- # puts "arpa for #{cidr4.desc()} is #{cidr4.arpa}"
174
- # puts "arpa for #{cidr6.desc(:Short => true)} is #{cidr6.arpa}"
175
- #
176
425
  #===Arguments:
177
426
  #* none
178
427
  #
@@ -228,11 +477,6 @@ private_class_method :new
228
477
  #===Synopsis
229
478
  #Provide number of bits in Netmask.
230
479
  #
231
- # cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
232
- # cidr6 = NetAddr::CIDR.create('fec0::/64')
233
- # puts "cidr4 netmask in bits #{cidr4.bits()}"
234
- # puts "cidr6 netmask in bits #{cidr6.bits()}"
235
- #
236
480
  #===Arguments:
237
481
  #* none
238
482
  #
@@ -240,7 +484,7 @@ private_class_method :new
240
484
  #* Integer.
241
485
  #
242
486
  def bits()
243
- return(NetAddr.unpack_ip_netmask(@netmask))
487
+ return(NetAddr.mask_to_bits(@netmask))
244
488
  end
245
489
 
246
490
  #==============================================================================#
@@ -256,8 +500,8 @@ private_class_method :new
256
500
  #
257
501
  # cidr4 = NetAddr::CIDR.create('192.168.1.0/24')
258
502
  # cidr4_2 = NetAddr::CIDR.create('192.168.1.0/26')
259
- # comp1 = cidr4.cmp(cidr4_2)
260
- # comp2 = cidr4.cmp('192.168.1.0/26')
503
+ # cidr4.cmp(cidr4_2)
504
+ # cidr4.cmp('192.168.1.0/26')
261
505
  #
262
506
  #===Arguments:
263
507
  #* CIDR address or NetAddr::CIDR object
@@ -279,23 +523,9 @@ private_class_method :new
279
523
  raise VersionError, "Attempted to compare a version #{cidr.version} CIDR " +
280
524
  "with a version #{@version} CIDR."
281
525
  end
282
-
526
+
283
527
  # compare
284
- comparasin = nil
285
- if ( (@network == cidr.packed_network))
286
- if (@netmask == cidr.packed_netmask)
287
- comparasin = 0
288
- elsif(@netmask < cidr.packed_netmask)
289
- comparasin = 1
290
- elsif(@netmask > cidr.packed_netmask)
291
- comparasin = -1
292
- end
293
-
294
- elsif( (cidr.packed_network | @hostmask) == (@network | @hostmask) )
295
- comparasin = 1
296
- elsif( (cidr.packed_network | cidr.packed_hostmask) == (@network | cidr.packed_hostmask) )
297
- comparasin = -1
298
- end
528
+ comparasin = NetAddr.cidr_compare(self,cidr)
299
529
 
300
530
  return(comparasin)
301
531
  end
@@ -311,11 +541,11 @@ end
311
541
  # cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
312
542
  # cidr6 = NetAddr::CIDR.create('fec0::/64')
313
543
  # cidr6_2 = NetAddr::CIDR.create('fec0::/96')
314
- # puts "#{cidr4.desc} contains 192.168.1.2" if ( cidr4.contains?('192.168.1.2') )
315
- # puts "#{cidr6.desc} contains #{cidr6_2.desc(:Short => true)}" if ( cidr6.contains?(cidr6_2) )
544
+ # cidr4.contains?('192.168.1.2')
545
+ # cidr6.contains?(cidr6_2)
316
546
  #
317
547
  #===Arguments:
318
- #* CIDR address or NetAddr::CIDR object
548
+ #* cidr = CIDR address or NetAddr::CIDR object
319
549
  #
320
550
  #===Returns:
321
551
  #* true or false
@@ -331,27 +561,13 @@ end
331
561
  "errors: #{error}"
332
562
  end
333
563
  end
334
-
335
- network = cidr.packed_network
336
- netmask = cidr.packed_netmask
337
-
338
564
 
339
565
  if (cidr.version != @version)
340
566
  raise VersionError, "Attempted to compare a version #{cidr.version} CIDR " +
341
567
  "with a version #{@version} CIDR."
342
568
  end
343
569
 
344
- # if network == @network, then we have to go by netmask length
345
- # else we can tell by or'ing network and @network by @hostmask
346
- # and comparing the results
347
- if (network == @network)
348
- contains = true if (netmask > @netmask)
349
-
350
- else
351
- if ( (network | @hostmask) == (@network | @hostmask) )
352
- contains = true
353
- end
354
- end
570
+ contains = true if ( NetAddr.cidr_compare(self,cidr) == 1 )
355
571
 
356
572
  return(contains)
357
573
  end
@@ -365,15 +581,14 @@ end
365
581
  #
366
582
  # cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
367
583
  # cidr6 = NetAddr::CIDR.create('fec0::/64')
368
- # puts cidr4.desc(:IP => true)
369
- # puts "cidr4 description #{cidr4.desc()}"
370
- # puts "cidr6 description #{cidr6.desc()}"
371
- # puts "cidr6 short-hand description #{cidr6.desc(:Short => true)}"
584
+ # cidr4.desc(:IP => true)
585
+ # cidr4.desc()
586
+ # cidr6.desc(:Short => true)
372
587
  #
373
588
  #===Arguments:
374
- #* Optional hash with the following keys:
375
- # :IP -- if true, return the original ip/netmask passed during initialization (optional)
376
- # :Short -- if true, return IPv6 addresses in short-hand notation (optional)
589
+ #* options = Optional hash with the following keys:
590
+ # :IP -- if true, return the original ip/netmask passed during initialization
591
+ # :Short -- if true, return IPv6 addresses in short-hand notation
377
592
  #
378
593
  #===Returns:
379
594
  #* String
@@ -388,23 +603,23 @@ end
388
603
  raise ArgumentError, "Expected Hash, but #{options.class} provided."
389
604
  end
390
605
  NetAddr.validate_args(options.keys,known_args)
391
-
606
+
392
607
  if (options.has_key?(:Short) && options[:Short] == true)
393
608
  short = true
394
609
  end
395
-
610
+
396
611
  if (options.has_key?(:IP) && options[:IP] == true)
397
612
  orig_ip = true
398
613
  end
399
614
  end
400
-
615
+
401
616
  if (!orig_ip)
402
- ip = NetAddr.unpack_ip_addr(@network, :Version => @version)
617
+ ip = NetAddr.ip_int_to_str(@network, @version)
403
618
  else
404
- ip = NetAddr.unpack_ip_addr(@ip, :Version => @version)
619
+ ip = NetAddr.ip_int_to_str(@ip, @version)
405
620
  end
406
621
  ip = NetAddr.shorten(ip) if (short && @version == 6)
407
- mask = NetAddr.unpack_ip_netmask(@netmask)
622
+ mask = NetAddr.mask_to_bits(@netmask)
408
623
 
409
624
  return("#{ip}/#{mask}")
410
625
  end
@@ -418,17 +633,15 @@ end
418
633
  #
419
634
  # cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
420
635
  # cidr6 = NetAddr::CIDR.create('fec0::/64')
421
- # puts "first 4 cidr4 addresses (bitstep 32)"
422
- # cidr4.enumerate(:Limit => 4, :Bitstep => 32).each {|x| puts " #{x}"}
423
- # puts "first 4 cidr6 addresses (bitstep 32)"
424
- # cidr6.enumerate(:Limit => 4, :Bitstep => 32, :Objectify => true).each {|x| puts " #{x.desc}"}
636
+ # cidr4.enumerate(:Limit => 4, :Bitstep => 32)
637
+ # cidr6.enumerate(:Limit => 4, :Bitstep => 32, :Objectify => true)
425
638
  #
426
639
  #===Arguments:
427
- #* Optional Hash with the following keys:
428
- # :Bitstep -- enumerate in X sized steps - Integer (optional)
429
- # :Limit -- limit returned list to X number of items - Integer (optional)
430
- # :Objectify -- if true, return NetAddr::CIDR objects (optional)
431
- # :Short -- if true, return IPv6 addresses in short-hand notation (optional)
640
+ #* options = Hash with the following keys:
641
+ # :Bitstep -- enumerate in X sized steps - Integer
642
+ # :Limit -- limit returned list to X number of items - Integer
643
+ # :Objectify -- if true, return NetAddr::CIDR objects
644
+ # :Short -- if true, return IPv6 addresses in short-hand notation
432
645
  #
433
646
  #===Returns:
434
647
  #* Array of Strings, or Array of NetAddr::CIDR objects
@@ -445,7 +658,7 @@ end
445
658
  raise ArgumentError, "Expected Hash, but #{options.class} provided."
446
659
  end
447
660
  NetAddr.validate_args(options.keys,known_args)
448
-
661
+
449
662
  if( options.has_key?(:Bitstep) )
450
663
  bitstep = options[:Bitstep]
451
664
  end
@@ -457,7 +670,7 @@ end
457
670
  if( options.has_key?(:Limit) )
458
671
  limit = options[:Limit]
459
672
  end
460
-
673
+
461
674
  if( options.has_key?(:Short) && options[:Short] == true )
462
675
  short = true
463
676
  end
@@ -469,11 +682,11 @@ end
469
682
 
470
683
  until ( change_mask != (@hostmask | @network) )
471
684
  if (!objectify)
472
- my_ip_s = NetAddr.unpack_ip_addr(my_ip, :Version => @version)
685
+ my_ip_s = NetAddr.ip_int_to_str(my_ip, @version)
473
686
  my_ip_s = NetAddr.shorten(my_ip_s) if (short && @version == 6)
474
687
  list.push( my_ip_s )
475
688
  else
476
- list.push( NetAddr::CIDR.create(my_ip, :Version => @version) )
689
+ list.push( NetAddr.cidr_build(@version,my_ip) )
477
690
  end
478
691
  my_ip = my_ip + bitstep
479
692
  change_mask = @hostmask | my_ip
@@ -481,48 +694,9 @@ end
481
694
  limit = limit -1
482
695
  break if (limit == 0)
483
696
  end
484
- end
485
-
486
- return(list)
487
- end
488
-
489
- #==============================================================================#
490
- # eql?
491
- #==============================================================================#
492
-
493
- #===Synopsis
494
- #Return true if the current CIDR and the provided CIDR are equal
495
- #(base address and netmask are equal).
496
- #
497
- # cidr4 = NetAddr::CIDR.create('192.168.1.0/24')
498
- # cidr4.eql?('192.168.1.0/24')
499
- #
500
- #===Arguments:
501
- #* CIDR address or NetAddr::CIDR object
502
- #
503
- #===Returns:
504
- #* true or false
505
- #
506
- def eql?(cidr)
507
- is_eql = false
508
-
509
- if (!cidr.kind_of?(NetAddr::CIDR))
510
- begin
511
- cidr = NetAddr::CIDR.create(cidr)
512
- rescue Exception => error
513
- raise ArgumentError, "Provided argument raised the following " +
514
- "errors: #{error}"
515
- end
516
697
  end
517
-
518
- if (cidr.version != @version)
519
- raise VersionError, "Attempted to compare a version #{cidr.version} CIDR " +
520
- "with a version #{@version} CIDR."
521
- end
522
-
523
- is_eql = true if (self.packed_network == cidr.packed_network && self.packed_netmask == cidr.packed_netmask)
524
-
525
- return(is_eql)
698
+
699
+ return(list)
526
700
  end
527
701
 
528
702
  #==============================================================================#
@@ -534,13 +708,13 @@ end
534
708
  #holes (missing subnets) filled in.
535
709
  #
536
710
  # cidr4 = NetAddr::CIDR.create('192.168.1.0/24')
537
- # subnets = cidr4.fill_in(['192.168.1.0/27','192.168.1.64/26','192.168.1.128/25'])
711
+ # cidr4.fill_in(['192.168.1.0/27','192.168.1.64/26','192.168.1.128/25'])
538
712
  #
539
713
  #===Arguments:
540
- #* Array of CIDR addresses, or Array of NetAddr::CIDR objects
541
- #* Optional Hash with the following keys:
542
- # :Objectify -- if true, return NetAddr::CIDR objects (optional)
543
- # :Short -- if true, return IPv6 addresses in short-hand notation (optional)
714
+ #* list = Array of CIDR addresses, or Array of NetAddr::CIDR objects
715
+ #* options = Hash with the following keys:
716
+ # :Objectify -- if true, return NetAddr::CIDR objects
717
+ # :Short -- if true, return IPv6 addresses in short-hand notation
544
718
  #
545
719
  #===Returns:
546
720
  #* Array of CIDR Strings, or an Array of NetAddr::CIDR objects
@@ -553,17 +727,17 @@ end
553
727
 
554
728
  # validate list
555
729
  raise ArgumentError, "Array expected for argument 'list' but #{list.class} provided." if (!list.kind_of?(Array) )
556
-
730
+
557
731
  # validate options
558
- if (options)
732
+ if (options)
559
733
  raise ArgumentError, "Hash expected for argument 'options' but " +
560
734
  "#{options.class} provided." if (!options.kind_of?(Hash) )
561
735
  NetAddr.validate_args(options.keys,known_args)
562
-
736
+
563
737
  if (options.has_key?(:Short) && options[:Short] == true)
564
738
  short = true
565
739
  end
566
-
740
+
567
741
  if (options.has_key?(:Objectify) && options[:Objectify] == true)
568
742
  objectify = true
569
743
  end
@@ -584,7 +758,7 @@ end
584
758
  if (!obj.version == self.version)
585
759
  raise VersionError, "#{obj.desc(:Short => true)} is not a version #{self.version} address."
586
760
  end
587
-
761
+
588
762
  # make sure we contain the cidr
589
763
  if ( self.contains?(obj) == false )
590
764
  raise "#{obj.desc(:Short => true)} does not fit " +
@@ -592,37 +766,8 @@ end
592
766
  end
593
767
  cidr_list.push(obj)
594
768
  end
595
-
596
- # sort our cidr's and see what is missing
597
- complete_list = []
598
- expected = self.packed_network
599
- NetAddr.sort(cidr_list).each do |cidr|
600
- network = cidr.packed_network
601
- bitstep = (@all_f + 1) - cidr.packed_netmask
602
-
603
- if (network > expected)
604
- num_ips_missing = network - expected
605
- sub_list = make_subnets_from_base_and_ip_count(expected,num_ips_missing)
606
- complete_list.concat(sub_list)
607
- elsif (network < expected)
608
- next
609
- end
610
- complete_list.push(NetAddr::CIDR.create(network,
611
- :PackedNetmask => cidr.packed_netmask,
612
- :Version => self.version))
613
- expected = network + bitstep
614
- end
615
-
616
- # if expected is not the next subnet, then we're missing subnets
617
- # at the end of the cidr
618
- next_sub = self.next_subnet(:Objectify => true).packed_network
619
- if (expected != next_sub)
620
- num_ips_missing = next_sub - expected
621
- sub_list = make_subnets_from_base_and_ip_count(expected,num_ips_missing)
622
- complete_list.concat(sub_list)
623
- end
624
-
625
- # decide what to return
769
+
770
+ complete_list = NetAddr.cidr_fill_in(self,cidr_list)
626
771
  if (!objectify)
627
772
  subnets = []
628
773
  complete_list.each {|entry| subnets.push(entry.desc(:Short => short))}
@@ -639,13 +784,10 @@ end
639
784
  #===Synopsis
640
785
  #Provide original IP address passed during initialization.
641
786
  #
642
- # puts cidr4.ip()
643
- # puts cidr4.ip(:Objectify => true).desc
644
- #
645
787
  #===Arguments:
646
- #* Optional Hash with the following keys:
647
- # :Objectify -- if true, return NetAddr::CIDR object (optional)
648
- # :Short -- if true, return IPv6 addresses in short-hand notation (optional)
788
+ #* options = Hash with the following keys:
789
+ # :Objectify -- if true, return NetAddr::CIDR object
790
+ # :Short -- if true, return IPv6 addresses in short-hand notation
649
791
  #
650
792
  #===Returns:
651
793
  #* String or NetAddr::CIDR object.
@@ -654,30 +796,29 @@ end
654
796
  known_args = [:Objectify, :Short]
655
797
  objectify = false
656
798
  short = false
657
-
799
+
658
800
  if (options)
659
801
  if (!options.kind_of?(Hash))
660
802
  raise Argumenterror, "Expected Hash, but " +
661
803
  "#{options.class} provided."
662
804
  end
663
805
  NetAddr.validate_args(options.keys,known_args)
664
-
806
+
665
807
  if( options.has_key?(:Short) && options[:Short] == true )
666
808
  short = true
667
809
  end
668
-
810
+
669
811
  if( options.has_key?(:Objectify) && options[:Objectify] == true )
670
812
  objectify = true
671
813
  end
672
814
  end
673
815
 
674
-
675
-
816
+
676
817
  if (!objectify)
677
- ip = NetAddr.unpack_ip_addr(@ip, :Version => @version)
818
+ ip = NetAddr.ip_int_to_str(@ip, @version)
678
819
  ip = NetAddr.shorten(ip) if (short && @version == 6)
679
820
  else
680
- ip = NetAddr::CIDR.create(@ip, :Version => @version)
821
+ ip = NetAddr.cidr_build(@version,@ip)
681
822
  end
682
823
 
683
824
  return(ip)
@@ -692,10 +833,10 @@ end
692
833
  #the provided CIDR address or NetAddr::CIDR object.
693
834
  #
694
835
  # cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
695
- # puts "#{cidr4.desc} is contained within 192.168.0.0/23" if ( cidr4.is_contained?('192.168.0.0/23') )
836
+ # cidr4.is_contained?('192.168.0.0/23')
696
837
  #
697
838
  #===Arguments:
698
- #* CIDR address or NetAddr::CIDR object
839
+ #* cidr = CIDR address or NetAddr::CIDR object
699
840
  #
700
841
  #===Returns:
701
842
  #* true or false
@@ -711,27 +852,17 @@ end
711
852
  "errors: #{error}"
712
853
  end
713
854
  end
714
-
855
+
715
856
  if (cidr.version != @version)
716
857
  raise VersionError, "Attempted to compare a version #{cidr.version} CIDR " +
717
858
  "with a version #{@version} CIDR."
718
859
  end
719
-
860
+
720
861
  network = cidr.packed_network
721
862
  netmask = cidr.packed_netmask
722
863
  hostmask = cidr.packed_hostmask
723
864
 
724
- # if network == @network, then we have to go by netmask length
725
- # else we can tell by or'ing network and @network by hostmask
726
- # and comparing the results
727
- if (network == @network)
728
- is_contained = true if (@netmask > netmask)
729
-
730
- else
731
- if ( (network | hostmask) == (@network | hostmask) )
732
- is_contained = true
733
- end
734
- end
865
+ is_contained = true if ( NetAddr.cidr_compare(self,cidr) == -1 )
735
866
 
736
867
  return(is_contained)
737
868
  end
@@ -741,14 +872,12 @@ end
741
872
  #==============================================================================#
742
873
 
743
874
  #===Synopsis
744
- #Provide last IP address in this CIDR object.
745
- #
746
- # puts cidr4.last()
875
+ #Provide last IP address in this CIDR object.
747
876
  #
748
877
  #===Arguments:
749
- #* Optional Hash with the following keys:
750
- # :Objectify -- if true, return NetAddr::CIDR object (optional)
751
- # :Short -- if true, return IPv6 addresses in short-hand notation (optional)
878
+ #* options = Hash with the following keys:
879
+ # :Objectify -- if true, return NetAddr::CIDR object
880
+ # :Short -- if true, return IPv6 addresses in short-hand notation
752
881
  #
753
882
  #===Returns:
754
883
  #* String or NetAddr::CIDR object.
@@ -757,30 +886,30 @@ end
757
886
  known_args = [:Objectify, :Short]
758
887
  objectify = false
759
888
  short = false
760
-
889
+
761
890
  if (options)
762
891
  if (!options.kind_of?(Hash))
763
892
  raise Argumenterror, "Expected Hash, but " +
764
893
  "#{options.class} provided."
765
894
  end
766
895
  NetAddr.validate_args(options.keys,known_args)
767
-
896
+
768
897
  if( options.has_key?(:Short) && options[:Short] == true )
769
898
  short = true
770
899
  end
771
-
900
+
772
901
  if( options.has_key?(:Objectify) && options[:Objectify] == true )
773
902
  objectify = true
774
903
  end
775
904
 
776
905
  end
777
-
906
+
778
907
  packed_ip = @network | @hostmask
779
908
  if (!objectify)
780
- ip = NetAddr.unpack_ip_addr(packed_ip, :Version => @version)
909
+ ip = NetAddr.ip_int_to_str(packed_ip, @version)
781
910
  ip = NetAddr.shorten(ip) if (short && !objectify && @version == 6)
782
911
  else
783
- ip = NetAddr::CIDR.create(packed_ip, :Version => @version)
912
+ ip = NetAddr.cidr_build(@version,packed_ip)
784
913
  end
785
914
 
786
915
  return(ip)
@@ -791,18 +920,18 @@ end
791
920
  #==============================================================================#
792
921
 
793
922
  #===Synopsis
794
- #Given an IP address (or if a CIDR, then the original IP of that CIDR), determine
923
+ #Given an IP address (or if a NetAddr::CIDR object, then the original IP of that object), determine
795
924
  #if it falls within the range of addresses resulting from the combination of the
796
925
  #IP and Wildcard Mask of this CIDR.
797
926
  #
798
- # cidr4 = NetAddr.CIDRv4.new('10.0.0.0', :WildcardMask => ['0.7.0.255', :inversed])
927
+ # cidr4 = NetAddr.CIDRv4.create('10.0.0.0', :WildcardMask => ['0.7.0.255', true])
799
928
  # cidr4.matches?('10.0.0.22') -> true
800
929
  # cidr4.matches?('10.8.0.1') -> false
801
930
  # cidr4.matches?('10.1.0.1') -> true
802
931
  # cidr4.matches?('10.0.1.22') -> false
803
932
  #
804
933
  #===Arguments:
805
- #* IP address as a String or a CIDR object
934
+ #* ip = IP address as a String or a CIDR object
806
935
  #
807
936
  #===Returns:
808
937
  #* True or False
@@ -820,9 +949,7 @@ end
820
949
  packed = ip.packed_ip
821
950
  end
822
951
 
823
- mask = ~@wildcard_mask & @all_f
824
-
825
- return(true) if (@ip & mask == packed & mask)
952
+ return(true) if (@ip & @wildcard_mask == packed & @wildcard_mask)
826
953
  return(false)
827
954
  end
828
955
 
@@ -836,11 +963,11 @@ end
836
963
  #MAC address is based on original IP address passed during initialization.
837
964
  #
838
965
  # mcast = NetAddr::CIDR.create('224.0.0.6')
839
- # puts mcast.multicast_mac.address
966
+ # mcast.multicast_mac.address
840
967
  #
841
968
  #===Arguments:
842
- #* Optional Hash with the following keys:
843
- # :Objectify -- if true, return EUI objects (optional)
969
+ #* options = Hash with the following keys:
970
+ # :Objectify -- if true, return EUI objects
844
971
  #
845
972
  #===Returns:
846
973
  #* String or NetAddr::EUI48 object
@@ -848,18 +975,18 @@ end
848
975
  def multicast_mac(options=nil)
849
976
  known_args = [:Objectify]
850
977
  objectify = false
851
-
978
+
852
979
  if (options)
853
980
  if (!options.kind_of? Hash)
854
981
  raise ArgumentError, "Expected Hash, but #{options.class} provided."
855
982
  end
856
983
  NetAddr.validate_args(options.keys,known_args)
857
-
984
+
858
985
  if (options.has_key?(:Objectify) && options[:Objectify] == true)
859
986
  objectify = true
860
987
  end
861
988
  end
862
-
989
+
863
990
  if (@version == 4)
864
991
  if (@ip & 0xf0000000 == 0xe0000000)
865
992
  # map low order 23-bits of ip to 01:00:5e:00:00:00
@@ -875,9 +1002,9 @@ end
875
1002
  else
876
1003
  raise ValidationError, "#{self.ip} is not a valid multicast address. IPv6 multicast " +
877
1004
  "addresses should be in the range ff00::/8."
878
- end
1005
+ end
879
1006
  end
880
-
1007
+
881
1008
  eui = NetAddr::EUI48.new(mac)
882
1009
  eui = eui.address if (!objectify)
883
1010
 
@@ -891,8 +1018,6 @@ end
891
1018
  #===Synopsis
892
1019
  #Provide netmask in CIDR format (/yy).
893
1020
  #
894
- # puts cidr4.netmask()
895
- #
896
1021
  #===Arguments:
897
1022
  #* none
898
1023
  #
@@ -900,7 +1025,7 @@ end
900
1025
  #* String
901
1026
  #
902
1027
  def netmask()
903
- bits = NetAddr.unpack_ip_netmask(@netmask)
1028
+ bits = NetAddr.mask_to_bits(@netmask)
904
1029
  return("/#{bits}")
905
1030
  end
906
1031
 
@@ -911,12 +1036,10 @@ end
911
1036
  #===Synopsis
912
1037
  #Provide base network address.
913
1038
  #
914
- # puts cidr4.network()
915
- #
916
1039
  #===Arguments:
917
- #* Optional Hash with the following fields:
918
- # :Objectify -- if true, return NetAddr::CIDR object (optional)
919
- # :Short -- if true, return IPv6 addresses in short-hand notation (optional)
1040
+ #* options = Hash with the following fields:
1041
+ # :Objectify -- if true, return NetAddr::CIDR object
1042
+ # :Short -- if true, return IPv6 addresses in short-hand notation
920
1043
  #
921
1044
  #===Returns:
922
1045
  #* String or NetAddr::CIDR object.
@@ -925,29 +1048,29 @@ end
925
1048
  known_args = [:Objectify, :Short]
926
1049
  objectify = false
927
1050
  short = false
928
-
1051
+
929
1052
  if (options)
930
1053
  if (!options.kind_of?(Hash))
931
1054
  raise Argumenterror, "Expected Hash, but " +
932
1055
  "#{options.class} provided."
933
1056
  end
934
1057
  NetAddr.validate_args(options.keys,known_args)
935
-
1058
+
936
1059
  if( options.has_key?(:Short) && options[:Short] == true )
937
1060
  short = true
938
1061
  end
939
-
1062
+
940
1063
  if( options.has_key?(:Objectify) && options[:Objectify] == true )
941
1064
  objectify = true
942
1065
  end
943
1066
  end
944
1067
 
945
-
1068
+
946
1069
  if (!objectify)
947
- ip = NetAddr.unpack_ip_addr(@network, :Version => @version)
1070
+ ip = NetAddr.ip_int_to_str(@network, @version)
948
1071
  ip = NetAddr.shorten(ip) if (short && @version == 6)
949
1072
  else
950
- ip = NetAddr::CIDR.create(@network, :Version => @version)
1073
+ ip = NetAddr.cidr_build(@version,@network)
951
1074
  end
952
1075
 
953
1076
  return(ip)
@@ -965,14 +1088,14 @@ end
965
1088
  #
966
1089
  # cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
967
1090
  # cidr6 = NetAddr::CIDR.create('fec0::/64')
968
- # puts "cidr4 next subnet #{cidr4.next_subnet()}"
969
- # puts "cidr6 next subnet #{cidr6.next_subnet(:Short => true)}"
1091
+ # cidr4.next_subnet()
1092
+ # cidr6.next_subnet(:Short => true)}
970
1093
  #
971
1094
  #===Arguments:
972
- #* Optional Hash with the following keys:
973
- # :Bitstep -- step in X sized steps - Integer (optional)
974
- # :Objectify -- if true, return NetAddr::CIDR object (optional)
975
- # :Short -- if true, return IPv6 addresses in short-hand notation (optional)
1095
+ #* options = Hash with the following keys:
1096
+ # :Bitstep -- step in X sized steps - Integer
1097
+ # :Objectify -- if true, return NetAddr::CIDR object
1098
+ # :Short -- if true, return IPv6 addresses in short-hand notation
976
1099
  #
977
1100
  #===Returns:
978
1101
  #* String or NetAddr::CIDR object.
@@ -982,41 +1105,41 @@ end
982
1105
  bitstep = 1
983
1106
  objectify = false
984
1107
  short = false
985
-
1108
+
986
1109
  if (options)
987
1110
  if (!options.kind_of?(Hash))
988
1111
  raise Argumenterror, "Expected Hash, but " +
989
1112
  "#{options.class} provided."
990
1113
  end
991
1114
  NetAddr.validate_args(options.keys,known_args)
992
-
1115
+
993
1116
  if( options.has_key?(:Bitstep) )
994
1117
  bitstep = options[:Bitstep]
995
1118
  end
996
-
1119
+
997
1120
  if( options.has_key?(:Short) && options[:Short] == true )
998
1121
  short = true
999
1122
  end
1000
-
1123
+
1001
1124
  if( options.has_key?(:Objectify) && options[:Objectify] == true )
1002
1125
  objectify = true
1003
1126
  end
1004
1127
  end
1005
-
1128
+
1006
1129
  next_ip = @network + @hostmask + bitstep
1007
-
1130
+
1008
1131
  if (next_ip > @all_f)
1009
1132
  raise BoundaryError, "Returned IP is out of bounds for IPv#{@version}."
1010
1133
  end
1011
1134
 
1012
-
1135
+
1013
1136
  if (!objectify)
1014
- next_ip = NetAddr.unpack_ip_addr(next_ip, :Version => @version)
1137
+ next_ip = NetAddr.ip_int_to_str(next_ip, @version)
1015
1138
  next_ip = NetAddr.shorten(next_ip) if (short && @version == 6)
1016
1139
  else
1017
- next_ip = NetAddr::CIDR.create(next_ip, :Version => @version)
1140
+ next_ip = NetAddr.cidr_build(@version,next_ip)
1018
1141
  end
1019
-
1142
+
1020
1143
  return(next_ip)
1021
1144
  end
1022
1145
 
@@ -1030,14 +1153,14 @@ end
1030
1153
  #
1031
1154
  # cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
1032
1155
  # cidr6 = NetAddr::CIDR.create('fec0::/64')
1033
- # puts "cidr4 next subnet #{cidr4.next_subnet()}"
1034
- # puts "cidr6 next subnet #{cidr6.next_subnet(:Short => true)}"
1156
+ # cidr4.next_subnet()
1157
+ # cidr6.next_subnet(:Short => true)
1035
1158
  #
1036
1159
  #===Arguments:
1037
- #* Optional Hash with the following keys:
1038
- # :Bitstep -- step in X sized steps. - Integer (optional)
1039
- # :Objectify -- if true, return NetAddr::CIDR object (optional)
1040
- # :Short -- if true, return IPv6 addresses in short-hand notation (optional)
1160
+ #* options = Hash with the following keys:
1161
+ # :Bitstep -- step in X sized steps. - Integer
1162
+ # :Objectify -- if true, return NetAddr::CIDR object
1163
+ # :Short -- if true, return IPv6 addresses in short-hand notation
1041
1164
  #
1042
1165
  #===Returns:
1043
1166
  #* String or NetAddr::CIDR object.
@@ -1047,44 +1170,42 @@ end
1047
1170
  bitstep = 1
1048
1171
  objectify = false
1049
1172
  short = false
1050
-
1173
+
1051
1174
  if (options)
1052
1175
  if (!options.kind_of?(Hash))
1053
1176
  raise Argumenterror, "Expected Hash, but " +
1054
1177
  "#{options.class} provided."
1055
1178
  end
1056
1179
  NetAddr.validate_args(options.keys,known_args)
1057
-
1180
+
1058
1181
  if( options.has_key?(:Bitstep) )
1059
1182
  bitstep = options[:Bitstep]
1060
1183
  end
1061
-
1184
+
1062
1185
  if( options.has_key?(:Short) && options[:Short] == true )
1063
1186
  short = true
1064
1187
  end
1065
-
1188
+
1066
1189
  if( options.has_key?(:Objectify) && options[:Objectify] == true )
1067
1190
  objectify = true
1068
1191
  end
1069
1192
  end
1070
-
1071
- bitstep = bitstep * (2**(@max_bits - self.bits) )
1193
+
1194
+ bitstep = bitstep * (2**(@address_len - self.bits) )
1072
1195
  next_sub = @network + bitstep
1073
-
1196
+
1074
1197
  if (next_sub > @all_f)
1075
1198
  raise BoundaryError, "Returned subnet is out of bounds for IPv#{@version}."
1076
1199
  end
1077
-
1200
+
1078
1201
  if (!objectify)
1079
- next_sub = NetAddr.unpack_ip_addr(next_sub, :Version => @version)
1202
+ next_sub = NetAddr.ip_int_to_str(next_sub, @version)
1080
1203
  next_sub = NetAddr.shorten(next_sub) if (short && @version == 6)
1081
1204
  next_sub = next_sub << "/" << self.bits.to_s
1082
1205
  else
1083
- next_sub = NetAddr::CIDR.create(next_sub,
1084
- :PackedNetmask => self.packed_netmask,
1085
- :Version => @version)
1206
+ next_sub = NetAddr.cidr_build(@version,next_sub,self.packed_netmask)
1086
1207
  end
1087
-
1208
+
1088
1209
  return(next_sub)
1089
1210
  end
1090
1211
 
@@ -1096,14 +1217,14 @@ end
1096
1217
  #Provide the nth IP within this object.
1097
1218
  #
1098
1219
  # cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
1099
- # puts cidr4.nth(1)
1100
- # puts cidr4.nth(1, :Objectify => true
1220
+ # cidr4.nth(1)
1221
+ # cidr4.nth(1, :Objectify => true)
1101
1222
  #
1102
1223
  #===Arguments:
1103
- #* Index number as an Integer
1104
- #* Optional Hash with the following keys:
1105
- # :Objectify -- if true, return NetAddr::CIDR objects (optional)
1106
- # :Short -- if true, return IPv6 addresses in short-hand notation (optional)
1224
+ #* index = Index number as an Integer
1225
+ #* options = Hash with the following keys:
1226
+ # :Objectify -- if true, return NetAddr::CIDR objects
1227
+ # :Short -- if true, return IPv6 addresses in short-hand notation
1107
1228
  #
1108
1229
  #===Returns:
1109
1230
  #* String or NetAddr::CIDR object.
@@ -1116,7 +1237,7 @@ end
1116
1237
  # validate list
1117
1238
  raise ArgumentError, "Integer expected for argument 'index' but " +
1118
1239
  "#{index.class} provided." if (!index.kind_of?(Integer) )
1119
-
1240
+
1120
1241
  # validate options
1121
1242
  if (options)
1122
1243
  raise ArgumentError, "Hash expected for argument 'options' but #{options.class} provided." if (!options.kind_of?(Hash) )
@@ -1125,21 +1246,21 @@ end
1125
1246
  if( options.has_key?(:Short) && options[:Short] == true )
1126
1247
  short = true
1127
1248
  end
1128
-
1249
+
1129
1250
  if( options.has_key?(:Objectify) && options[:Objectify] == true )
1130
1251
  objectify = true
1131
1252
  end
1132
1253
  end
1133
-
1254
+
1134
1255
  my_ip = @network + index
1135
1256
  if ( (@hostmask | my_ip) == (@hostmask | @network) )
1136
-
1257
+
1137
1258
  if (!objectify)
1138
- my_ip = NetAddr.unpack_ip_addr(my_ip, :Version => @version)
1259
+ my_ip = NetAddr.ip_int_to_str(my_ip, @version)
1139
1260
  my_ip = NetAddr.shorten(my_ip) if (short && @version == 6)
1140
1261
  else
1141
- my_ip = NetAddr::CIDR.create(my_ip, :Version => @version)
1142
- end
1262
+ my_ip = NetAddr.cidr_build(@version,my_ip)
1263
+ end
1143
1264
 
1144
1265
  else
1145
1266
  raise BoundaryError, "Index of #{index} returns IP that is out of " +
@@ -1156,8 +1277,6 @@ end
1156
1277
  #===Synopsis
1157
1278
  #Provide an Integer representation of the Hostmask of this object.
1158
1279
  #
1159
- # puts cidr4.packed_hostmask().to_s(16)
1160
- #
1161
1280
  #===Arguments:
1162
1281
  #* none
1163
1282
  #
@@ -1175,8 +1294,6 @@ end
1175
1294
  #===Synopsis
1176
1295
  #Provide an Integer representation of the IP address of this object.
1177
1296
  #
1178
- # puts cidr4.packed_ip().to_s(16)
1179
- #
1180
1297
  #===Arguments:
1181
1298
  #* none
1182
1299
  #
@@ -1194,8 +1311,6 @@ end
1194
1311
  #===Synopsis
1195
1312
  #Provide an Integer representation of the Netmask of this object.
1196
1313
  #
1197
- # puts cidr4.packed_netmask().to_s(16)
1198
- #
1199
1314
  #===Arguments:
1200
1315
  #* none
1201
1316
  #
@@ -1213,11 +1328,9 @@ end
1213
1328
  #===Synopsis
1214
1329
  #Provide an Integer representation of the Network address of this object.
1215
1330
  #
1216
- # packed = cidr4.packed_network().to_s(16)
1217
- #
1218
1331
  #===Arguments:
1219
1332
  #* none
1220
- #
1333
+ #
1221
1334
  #===Returns:
1222
1335
  #* Integer
1223
1336
  #
@@ -1232,8 +1345,6 @@ end
1232
1345
  #===Synopsis
1233
1346
  #Provide an Integer representation of the IPv4 Wildcard Mask.
1234
1347
  #
1235
- # puts cidr4.packed_wildcard_mask()
1236
- #
1237
1348
  #===Arguments:
1238
1349
  #* none
1239
1350
  #
@@ -1254,17 +1365,17 @@ end
1254
1365
  #all addresses from the lower bound up will be returned.
1255
1366
  #
1256
1367
  # cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
1257
- # list = cidr4.range(0, 1)
1258
- # list = cidr4.range(0, 1, :Objectify => true)
1259
- # list = cidr4.range(0, nil, :Objectify => true)
1368
+ # cidr4.range(0, 1)
1369
+ # cidr4.range(0, 1, :Objectify => true)
1370
+ # cidr4.range(0, nil, :Objectify => true)
1260
1371
  #
1261
1372
  #===Arguments:
1262
- #* Lower range boundary index as an Integer
1263
- #* Upper range boundary index as an Integer
1264
- #* Optional Hash with the following keys:
1265
- # :Bitstep -- enumerate in X sized steps - Integer (optional)
1266
- # :Objectify -- if true, return NetAddr::CIDR objects (optional)
1267
- # :Short -- if true, return IPv6 addresses in short-hand notation (optional)
1373
+ #* lower = Lower range boundary index as an Integer
1374
+ #* upper = Upper range boundary index as an Integer
1375
+ #* options = Hash with the following keys:
1376
+ # :Bitstep -- enumerate in X sized steps - Integer
1377
+ # :Objectify -- if true, return NetAddr::CIDR objects
1378
+ # :Short -- if true, return IPv6 addresses in short-hand notation
1268
1379
  #
1269
1380
  #===Returns:
1270
1381
  #* Array of Strings, or Array of NetAddr::CIDR objects
@@ -1278,52 +1389,52 @@ end
1278
1389
  # validate indexes
1279
1390
  raise ArgumentError, "Integer expected for argument 'lower' " +
1280
1391
  "but #{lower.class} provided." if (!lower.kind_of?(Integer))
1281
-
1392
+
1282
1393
  raise ArgumentError, "Integer expected for argument 'upper' " +
1283
1394
  "but #{upper.class} provided." if (upper && !upper.kind_of?(Integer))
1284
-
1395
+
1285
1396
  upper = @hostmask if (upper.nil?)
1286
1397
  indexes = [lower,upper]
1287
1398
  indexes.sort!
1288
1399
  if ( (indexes[0] < 0) || (indexes[0] > self.size) )
1289
1400
  raise BoundaryError, "Index #{indexes[0]} is out of bounds for this CIDR."
1290
1401
  end
1291
-
1402
+
1292
1403
  if (indexes[1] >= self.size)
1293
1404
  raise BoundaryError, "Index #{indexes[1]} is out of bounds for this CIDR."
1294
1405
  end
1295
-
1406
+
1296
1407
  # validate options
1297
- if (options)
1408
+ if (options)
1298
1409
  raise ArgumentError, "Hash expected for argument 'options' but #{options.class} provided." if (!options.kind_of?(Hash) )
1299
1410
  NetAddr.validate_args(options.keys,known_args)
1300
-
1411
+
1301
1412
  if( options.has_key?(:Short) && options[:Short] == true )
1302
1413
  short = true
1303
1414
  end
1304
-
1415
+
1305
1416
  if( options.has_key?(:Objectify) && options[:Objectify] == true )
1306
1417
  objectify = true
1307
1418
  end
1308
-
1419
+
1309
1420
  if( options.has_key?(:Bitstep) )
1310
1421
  bitstep = options[:Bitstep]
1311
1422
  end
1312
1423
  end
1313
-
1424
+
1314
1425
  # make range
1315
1426
  start_ip = @network + indexes[0]
1316
1427
  end_ip = @network + indexes[1]
1317
1428
  my_ip = start_ip
1318
1429
  list = []
1319
- until (my_ip > end_ip)
1430
+ until (my_ip > end_ip)
1320
1431
  if (!objectify)
1321
- ip = NetAddr.unpack_ip_addr(my_ip, :Version => @version)
1432
+ ip = NetAddr.ip_int_to_str(my_ip, @version)
1322
1433
  ip = NetAddr.shorten(ip) if (short && @version == 6)
1323
1434
  else
1324
- ip = NetAddr::CIDR.create(:PackedIP => my_ip, :Version => @version)
1435
+ ip = NetAddr.cidr_build(@version,my_ip)
1325
1436
  end
1326
-
1437
+
1327
1438
  list.push(ip)
1328
1439
  my_ip += bitstep
1329
1440
  end
@@ -1341,14 +1452,15 @@ end
1341
1452
  #provide 192.168.0.64/26 as the portion to exclude, then 192.168.0.0/26,
1342
1453
  #and 192.168.0.128/25 will be returned as the remainders.
1343
1454
  #
1344
- # cidr4.remainder('192.168.1.32/27').each {|x| puts x}
1345
- # cidr4.remainder('192.168.1.32/27', :Objectify => true).each {|x| puts x.desc}
1455
+ # cidr4 = NetAddr::CIDR.create('192.168.1.0/24')
1456
+ # cidr4.remainder('192.168.1.32/27')
1457
+ # cidr4.remainder('192.168.1.32/27', :Objectify => true)
1346
1458
  #
1347
1459
  #===Arguments:
1348
- #* CIDR address or NetAddr::CIDR object
1349
- #* Optional Hash with the following keys:
1350
- # :Objectify -- if true, return NetAddr::CIDR objects (optional)
1351
- # :Short -- if true, return IPv6 addresses in short-hand notation (optional)
1460
+ #* addr = CIDR address or NetAddr::CIDR object
1461
+ #* options = Hash with the following keys:
1462
+ # :Objectify -- if true, return NetAddr::CIDR objects
1463
+ # :Short -- if true, return IPv6 addresses in short-hand notation
1352
1464
  #
1353
1465
  #===Returns:
1354
1466
  #* Array of Strings, or Array of NetAddr::CIDR objects
@@ -1357,22 +1469,22 @@ end
1357
1469
  known_args = [:Objectify, :Short]
1358
1470
  short = nil
1359
1471
  objectify = nil
1360
-
1472
+
1361
1473
  # validate options
1362
- if (options)
1474
+ if (options)
1363
1475
  raise ArgumentError, "Hash expected for argument 'options' but " +
1364
1476
  "#{options.class} provided." if (!options.kind_of?(Hash) )
1365
1477
  NetAddr.validate_args(options.keys,known_args)
1366
-
1478
+
1367
1479
  if( options.has_key?(:Short) && options[:Short] == true )
1368
1480
  short = true
1369
1481
  end
1370
-
1482
+
1371
1483
  if( options.has_key?(:Objectify) && options[:Objectify] == true )
1372
1484
  objectify = true
1373
- end
1485
+ end
1374
1486
  end
1375
-
1487
+
1376
1488
  if ( !addr.kind_of?(NetAddr::CIDR) )
1377
1489
  begin
1378
1490
  addr = NetAddr::CIDR.create(addr)
@@ -1381,13 +1493,13 @@ end
1381
1493
  "errors: #{error}"
1382
1494
  end
1383
1495
  end
1384
-
1385
-
1496
+
1497
+
1386
1498
  # make sure 'addr' is the same ip version
1387
1499
  if ( addr.version != @version )
1388
1500
  raise VersionError, "#{addr.desc(:Short => true)} is of a different " +
1389
1501
  "IP version than #{self.desc(:Short => true)}."
1390
- end
1502
+ end
1391
1503
 
1392
1504
  # make sure we contain 'to_exclude'
1393
1505
  if ( self.contains?(addr) != true )
@@ -1400,8 +1512,8 @@ end
1400
1512
  # we repeat, store the non-matching half
1401
1513
  new_mask = self.bits + 1
1402
1514
  lower_network = self.packed_network
1403
- upper_network = self.packed_network + 2**(@max_bits - new_mask)
1404
-
1515
+ upper_network = self.packed_network + 2**(@address_len - new_mask)
1516
+
1405
1517
  new_subnets = []
1406
1518
  until(new_mask > addr.bits)
1407
1519
  if (addr.packed_network < upper_network)
@@ -1412,22 +1524,19 @@ end
1412
1524
  non_match = lower_network
1413
1525
  end
1414
1526
 
1415
-
1416
1527
  if (!objectify)
1417
- non_match = NetAddr.unpack_ip_addr(non_match, :Version => @version)
1528
+ non_match = NetAddr.ip_int_to_str(non_match, @version)
1418
1529
  non_match = NetAddr.shorten(non_match) if (short && @version == 6)
1419
1530
  new_subnets.unshift("#{non_match}/#{new_mask}")
1420
1531
  else
1421
- new_subnets.unshift(NetAddr::CIDR.create(non_match,
1422
- :PackedNetmask => NetAddr.pack_ip_netmask(new_mask),
1423
- :Version => @version))
1532
+ new_subnets.unshift( NetAddr.cidr_build(@version, non_match, NetAddr.bits_to_mask(new_mask,version) ) )
1424
1533
  end
1425
-
1534
+
1426
1535
  new_mask = new_mask + 1
1427
1536
  lower_network = match
1428
- upper_network = match + 2**(@max_bits - new_mask)
1537
+ upper_network = match + 2**(@address_len - new_mask)
1429
1538
  end
1430
-
1539
+
1431
1540
  return(new_subnets)
1432
1541
  end
1433
1542
 
@@ -1441,24 +1550,22 @@ end
1441
1550
  #
1442
1551
  # cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
1443
1552
  # new_cidr = cidr4.resize(23)
1444
- # puts new_cidr.desc
1445
1553
  #
1446
1554
  #===Arguments:
1447
- #* Netmask as an Integer
1555
+ #* bits = Netmask as an Integer
1448
1556
  #
1449
1557
  #===Returns:
1450
1558
  #* NetAddr::CIDR object
1451
1559
  #
1452
1560
  def resize(bits)
1453
1561
  raise Argumenterror, "Integer or Hash expected, but " +
1454
- "#{bits.class} provided." if (!bits.kind_of?(Integer))
1455
-
1562
+ "#{bits.class} provided." if (!bits.kind_of?(Integer))
1563
+
1456
1564
  NetAddr.validate_ip_netmask(bits, :Version => @version)
1457
- netmask = NetAddr.pack_ip_netmask(bits, :Version => @version)
1565
+ netmask = NetAddr.bits_to_mask(bits, @version)
1458
1566
  network = @network & netmask
1459
-
1460
- cidr = NetAddr::CIDR.create(network, :PackedNetmask => netmask, :Version => @version)
1461
- return(cidr)
1567
+
1568
+ return( NetAddr.cidr_build(@version, network, netmask) )
1462
1569
  end
1463
1570
 
1464
1571
  #==============================================================================#
@@ -1471,11 +1578,10 @@ end
1471
1578
  #it no longer falls within the bounds of the CIDR.
1472
1579
  #
1473
1580
  # cidr4 = NetAddr::CIDR.create('192.168.1.1/24')
1474
- # new_cidr = cidr4.resize(23)
1475
- # puts new_cidr.desc
1581
+ # cidr4.resize!(23)
1476
1582
  #
1477
1583
  #===Arguments:
1478
- #* Netmask as an Integer
1584
+ #* bits = Netmask as an Integer
1479
1585
  #
1480
1586
  #===Returns:
1481
1587
  #* True
@@ -1483,22 +1589,60 @@ end
1483
1589
  def resize!(bits)
1484
1590
  raise Argumenterror, "Integer or Hash expected, but " +
1485
1591
  "#{bits.class} provided." if (!bits.kind_of?(Integer))
1486
-
1592
+
1487
1593
  NetAddr.validate_ip_netmask(bits, :Version => @version)
1488
1594
  netmask = NetAddr.pack_ip_netmask(bits, :Version => @version)
1489
-
1595
+
1490
1596
  @netmask = netmask
1491
1597
  @network = @network & netmask
1492
1598
  @hostmask = @netmask ^ @all_f
1493
-
1599
+
1494
1600
  # check @ip
1495
1601
  if ((@ip & @netmask) != (@network))
1496
1602
  @ip = @network
1497
1603
  end
1498
-
1604
+
1499
1605
  return(true)
1500
1606
  end
1501
1607
 
1608
+ #==============================================================================#
1609
+ # set_wildcard_mask()
1610
+ #==============================================================================#
1611
+
1612
+ #===Synopsis
1613
+ #Set the wildcard mask. Wildcard masks are typically used for matching
1614
+ #entries in an access-list.
1615
+ #
1616
+ # cidr4 = NetAddr::CIDR.create('192.168.1.0/24')
1617
+ # cidr4.set_wildcard_mask('0.0.0.255', true)
1618
+ # cidr4.set_wildcard_mask('255.255.255.0')
1619
+ #
1620
+ #===Arguments:
1621
+ #* mask = wildcard mask as a String or Integer
1622
+ #* bit_flipped = if set True then the wildcard mask is interpereted as bit-flipped.
1623
+ #
1624
+ #===Returns:
1625
+ #* nil
1626
+ #
1627
+ def set_wildcard_mask(mask, bit_flipped=false)
1628
+ packed = nil
1629
+ if (mask.kind_of?(Integer))
1630
+ NetAddr.validate_ip_int(mask,@version)
1631
+ packed = mask
1632
+ else
1633
+ begin
1634
+ NetAddr.validate_ip_str(mask,@version)
1635
+ packed = NetAddr.ip_str_to_int(mask, @version)
1636
+ rescue NetAddr::ValidationError
1637
+ raise NetAddr::ValidationError, "Wildcard Mask must be a valid IPv#{@version} address."
1638
+ end
1639
+ end
1640
+ packed = ~packed if (bit_flipped)
1641
+ @wildcard_mask = packed
1642
+
1643
+ return(nil)
1644
+ end
1645
+
1502
1646
  #==============================================================================#
1503
1647
  # size()
1504
1648
  #==============================================================================#
@@ -1506,8 +1650,6 @@ end
1506
1650
  #===Synopsis
1507
1651
  #Provide number of IP addresses within this CIDR.
1508
1652
  #
1509
- # puts cidr4.size()
1510
- #
1511
1653
  #===Arguments:
1512
1654
  #* none
1513
1655
  #
@@ -1523,9 +1665,9 @@ end
1523
1665
  #==============================================================================#
1524
1666
 
1525
1667
  #===Synopsis
1526
- #Subnet this CIDR. There are 2 ways to subnet:
1527
- # * By providing the netmask (in bits) of the new subnets in :Bits.
1528
- # * By providing the number of IP addresses needed in the new subnets in :IPCount
1668
+ #Create subnets for this CIDR. There are 2 ways to create subnets:
1669
+ # * By providing the netmask (in bits) of the new subnets with :Bits.
1670
+ # * By providing the number of IP addresses needed in the new subnets with :IPCount
1529
1671
  #
1530
1672
  #:NumSubnets is used to determine how the CIDR is subnetted. For example, if I request
1531
1673
  #the following operation:
@@ -1541,18 +1683,20 @@ end
1541
1683
  #If neither :Bits nor :IPCount is provided, then the current CIDR will be split in half.
1542
1684
  #If both :Bits and :IPCount are provided, then :Bits takes precedence.
1543
1685
  #
1544
- # cidr_list = cidr4.subnet(:Bits => 28, :NumSubnets => 3).each {|x| puts " #{x}"}
1545
- # cidr_list = cidr4.subnet(:IPCount => 19).each {|x| puts " #{x}"}
1546
- # cidr4.subnet(:Bits => 28).each {|x| puts " #{x}"} "
1547
- # cidr6.subnet(:Bits => 67, :NumSubnets => 4, :Short => true).each {|x| puts " #{x}"}
1686
+ # cidr4 = NetAddr::CIDR.create('192.168.1.0/24')
1687
+ # cidr6 = NetAddr::CIDR.create('fec0::/64')
1688
+ # cidr4.subnet(:Bits => 28, :NumSubnets => 3)
1689
+ # cidr4.subnet(:IPCount => 19)
1690
+ # cidr4.subnet(:Bits => 28)
1691
+ # cidr6.subnet(:Bits => 67, :NumSubnets => 4, :Short => true)
1548
1692
  #
1549
1693
  #===Arguments:
1550
- #* Optional Hash with the following keys:
1551
- # :Bits -- Netmask (in bits) of new subnets - Integer (optional)
1552
- # :IPCount -- Minimum number of IP's that new subnets should contain - Integer (optional)
1553
- # :NumSubnets -- Number of X sized subnets to return - Integer (optional)
1554
- # :Objectify -- if true, return NetAddr::CIDR objects (optional)
1555
- # :Short -- if true, return IPv6 addresses in short-hand notation (optional)
1694
+ #* options = Hash with the following keys:
1695
+ # :Bits -- Netmask (in bits) of new subnets - Integer
1696
+ # :IPCount -- Minimum number of IP's that new subnets should contain - Integer
1697
+ # :NumSubnets -- Number of X sized subnets to return - Integer
1698
+ # :Objectify -- if true, return NetAddr::CIDR objects
1699
+ # :Short -- if true, return IPv6 addresses in short-hand notation
1556
1700
  #
1557
1701
  #===Returns:
1558
1702
  #* Array of Strings, or Array of NetAddr::CIDR objects
@@ -1564,38 +1708,38 @@ end
1564
1708
  subnet_bits = my_mask + 1
1565
1709
  min_count = nil
1566
1710
  objectify = false
1567
- short = false
1568
-
1711
+ short = false
1712
+
1569
1713
  if (options)
1570
1714
  if (!options.kind_of? Hash)
1571
1715
  raise ArgumentError, "Expected Hash, but #{options.class} provided."
1572
1716
  end
1573
1717
  NetAddr.validate_args(options.keys,known_args)
1574
-
1718
+
1575
1719
  if ( options.has_key?(:IPCount) )
1576
- subnet_bits = NetAddr.minimum_size(options[:IPCount], :Version => @version)
1720
+ subnet_bits = NetAddr.ip_count_to_size(options[:IPCount], @version)
1577
1721
  end
1578
-
1722
+
1579
1723
  if ( options.has_key?(:Bits) )
1580
1724
  subnet_bits = options[:Bits]
1581
1725
  end
1582
-
1726
+
1583
1727
  if ( options.has_key?(:NumSubnets) )
1584
1728
  num_subnets = options[:NumSubnets]
1585
1729
  end
1586
-
1730
+
1587
1731
  if( options.has_key?(:Short) && options[:Short] == true )
1588
1732
  short = true
1589
1733
  end
1590
-
1734
+
1591
1735
  if( options.has_key?(:Objectify) && options[:Objectify] == true )
1592
1736
  objectify = true
1593
1737
  end
1594
-
1738
+
1595
1739
  end
1596
1740
 
1597
1741
  # get number of subnets possible with the requested subnet_bits
1598
- num_avail = 2**(subnet_bits - my_mask)
1742
+ num_avail = 2**(subnet_bits - my_mask)
1599
1743
 
1600
1744
  # get the number of bits in the next supernet and
1601
1745
  # make sure num_subnets is a power of 2
@@ -1606,10 +1750,10 @@ end
1606
1750
  end
1607
1751
  num_subnets = 2**bits_needed
1608
1752
  next_supernet_bits = subnet_bits - bits_needed
1609
-
1753
+
1610
1754
 
1611
1755
  # make sure subnet isnt bigger than available bits
1612
- if (subnet_bits > @max_bits)
1756
+ if (subnet_bits > @address_len)
1613
1757
  raise BoundaryError, "Requested subnet (#{subnet_bits}) does not fit " +
1614
1758
  "within the bounds of IPv#{@version}."
1615
1759
  end
@@ -1628,17 +1772,20 @@ end
1628
1772
 
1629
1773
  # list all 'subnet_bits' sized subnets of this cidr block
1630
1774
  # with a limit of num_subnets
1631
- bitstep = 2**(@max_bits - subnet_bits)
1632
- subnets = self.enumerate(:Bitstep => bitstep, :Limit => num_subnets)
1775
+ bitstep = 2**(@address_len - subnet_bits)
1776
+ subnets = self.enumerate(:Bitstep => bitstep, :Limit => num_subnets, :Objectify => true)
1633
1777
 
1634
1778
  # save our subnets
1635
1779
  new_subnets = []
1636
1780
  subnets.each do |subnet|
1637
1781
  if (!objectify)
1638
- subnet = NetAddr.shorten(subnet) if (short && @version == 6)
1639
- new_subnets.push("#{subnet}/#{subnet_bits}")
1640
- else
1641
- new_subnets.push(NetAddr::CIDR.create("#{subnet}/#{subnet_bits}", :Version => @version))
1782
+ if (short && @version == 6)
1783
+ new_subnets.push("#{subnet.network(:Short => true)}/#{subnet_bits}")
1784
+ else
1785
+ new_subnets.push("#{subnet.network}/#{subnet_bits}")
1786
+ end
1787
+ else
1788
+ new_subnets.push( NetAddr.cidr_build(@version, subnet.packed_network, NetAddr.bits_to_mask(subnet_bits,version) ) )
1642
1789
  end
1643
1790
  end
1644
1791
 
@@ -1648,15 +1795,13 @@ end
1648
1795
  next_supernet_ip = my_network + next_supernet_bitstep
1649
1796
  until (next_supernet_bits == my_mask)
1650
1797
  if (!objectify)
1651
- next_network = NetAddr.unpack_ip_addr(next_supernet_ip, :Version => @version)
1798
+ next_network = NetAddr.ip_int_to_str(next_supernet_ip, @version)
1652
1799
  next_network = NetAddr.shorten(next_network) if (short && @version == 6)
1653
1800
  new_subnets.push("#{next_network}/#{next_supernet_bits}")
1654
1801
  else
1655
- new_subnets.push(NetAddr::CIDR.create(next_supernet_ip,
1656
- :PackedNetmask => NetAddr.pack_ip_netmask(next_supernet_bits),
1657
- :Version => @version))
1802
+ new_subnets.push(NetAddr.cidr_build(@version, next_supernet_ip, NetAddr.bits_to_mask(next_supernet_bits,version) ) )
1658
1803
  end
1659
-
1804
+
1660
1805
  next_supernet_bits -= 1
1661
1806
  next_supernet_ip = next_supernet_ip + next_supernet_bitstep
1662
1807
  next_supernet_bitstep = next_supernet_bitstep << 1
@@ -1665,102 +1810,30 @@ end
1665
1810
  return(new_subnets)
1666
1811
  end
1667
1812
 
1668
-
1669
1813
  #==============================================================================#
1670
1814
  # wildcard_mask()
1671
1815
  #==============================================================================#
1672
1816
 
1673
1817
  #===Synopsis
1674
- #Set or return the wildcard mask. Wildcard masks are typically used for matching
1675
- #entries in an access-list.
1676
- #
1677
- # cidr4.wildcard_mask() -> reads the current wildcard mask
1678
- # cidr4.wildcard_mask('0.0.0.255', :inversed) -> sets wildcard mask using a reversed mask
1679
- # cidr4.wildcard_mask('255.255.255.0') -> sets wildcard mask using a standard mask
1818
+ #Return the wildcard mask.
1680
1819
  #
1681
1820
  #===Arguments:
1682
- #* wildcard mask as a String or Integer
1683
- #* the label :inversed if the mask is bit-flipped. (optional)
1821
+ #* bit_flipped = if set True then returned the bit-flipped version of the wildcard mask.
1684
1822
  #
1685
1823
  #===Returns:
1686
- #* nil
1824
+ #* String
1687
1825
  #
1688
- def wildcard_mask(mask=nil, inversed=nil)
1689
- if (mask)
1690
- if (mask.kind_of?(Integer))
1691
- packed = mask
1692
- else
1693
- packed = nil
1694
- begin
1695
- packed = NetAddr.pack_ip_addr(mask, :Version => @version)
1696
- rescue NetAddr::ValidationError
1697
- raise NetAddr::ValidationError, "Wildcard Mask must be a valid IPv#{@version} address."
1698
- end
1699
- end
1700
- packed = packed ^ @all_f if (inversed != :inversed)
1701
- @wildcard_mask = packed
1702
- ret_val = nil
1826
+ def wildcard_mask(bit_flipped=false)
1827
+ ret_val = nil
1828
+ if (!bit_flipped)
1829
+ ret_val = NetAddr.ip_int_to_str(@wildcard_mask, @version)
1703
1830
  else
1704
- if (inversed != :inversed)
1705
- ret_val = NetAddr.unpack_ip_addr(@wildcard_mask ^ @all_f, :Version => @version)
1706
- else
1707
- ret_val = NetAddr.unpack_ip_addr(@wildcard_mask, :Version => @version)
1708
- end
1831
+ ret_val = NetAddr.ip_int_to_str(~@wildcard_mask, @version)
1709
1832
  end
1710
1833
 
1711
1834
  return(ret_val)
1712
1835
  end
1713
1836
 
1714
-
1715
- # PRIVATE INSTANCE METHODS
1716
- private
1717
-
1718
-
1719
- #==============================================================================#
1720
- # make_subnets_from_base_and_ip_count()
1721
- #==============================================================================#
1722
-
1723
- # Make CIDR addresses from a base addr and an number of ip's to encapsulate.
1724
- #
1725
- #===Arguments:
1726
- # * base ip as packed integer
1727
- # * number of ip's required
1728
- #
1729
- #===Returns:
1730
- # * array of NetAddr::CIDR objects
1731
- #
1732
- def make_subnets_from_base_and_ip_count(base_addr,ip_count)
1733
- list = []
1734
- until (ip_count == 0)
1735
- mask = @all_f
1736
- multiplier = 0
1737
- bitstep = 0
1738
- last_addr = base_addr
1739
- done = false
1740
- until (done == true)
1741
- if (bitstep < ip_count && (base_addr & mask == last_addr & mask) )
1742
- multiplier += 1
1743
- elsif (bitstep > ip_count || (base_addr & mask != last_addr & mask) )
1744
- multiplier -= 1
1745
- done = true
1746
- else
1747
- done = true
1748
- end
1749
- bitstep = 2**multiplier
1750
- mask = @all_f << multiplier & @all_f
1751
- last_addr = base_addr + bitstep - 1
1752
- end
1753
-
1754
- list.push(NetAddr::CIDR.create(base_addr,
1755
- :PackedNetmask => mask,
1756
- :Version => self.version))
1757
- ip_count -= bitstep
1758
- base_addr += bitstep
1759
- end
1760
-
1761
- return(list)
1762
- end
1763
-
1764
1837
  end # end class CIDR
1765
1838
 
1766
1839
 
@@ -1771,154 +1844,14 @@ end # end class CIDR
1771
1844
  # Addresses of this class are composed of a 32-bit address space.
1772
1845
  class CIDRv4 < CIDR
1773
1846
 
1774
- public_class_method :new
1775
-
1776
- #==============================================================================#
1777
- # initialize()
1778
- #==============================================================================#
1779
-
1780
- #===Synopsis
1781
- #Return a CIDRv4 object.
1782
- #CIDR formatted netmasks take precedence over extended formatted ones.
1783
- #CIDR address defaults to a host network (/32) if netmask not provided.
1784
- #:PackedNetmask takes precedence over netmask given within CIDR address.
1785
- #
1786
- # cidr4 = NetAddr::CIDRv4.new('192.168.1.1/24')
1787
- # cidr4 = NetAddr::CIDRv4.new('192.168.1.1 255.255.255.0')
1788
- # cidr4_2 = NetAddr::CIDRv4.new(0x0a010001,
1789
- # :PackedNetmask => 0xffffff00)
1790
- # cidr4_3 = NetAddr::CIDRv4.new('192.168.1.1',
1791
- # :WildcardMask => ['0.7.0.255', :inversed])
1792
- # cidr4_4 = NetAddr::CIDRv4.new('192.168.5.0',
1793
- # :WildcardMask => ['255.248.255.0'])
1794
- # cidr4_5 = NetAddr::CIDRv4.new('192.168.1.1',
1795
- # :WildcardMask => 0x000700ff)
1796
- #
1797
- #===Arguments:
1798
- #* CIDR address as a String, or a packed IP address as an Integer
1799
- #* Optional Hash with the following keys:
1800
- # :PackedNetmask -- Integer representation of an IP Netmask (optional)
1801
- # :Tag -- Custom descriptor tag - Hash, tag => value. (optional)
1802
- # :WildcardMask -- 2 element Array. First element contains a special bit mask used for
1803
- # advanced IP pattern matching. The second element should be :inversed if this
1804
- # bit mask is in inverse format. (optional)
1805
- #
1806
- def initialize(addr, options=nil)
1807
- known_args = [:PackedNetmask, :Tag, :WildcardMask]
1808
- @tag = {}
1809
- @version = 4
1810
- @max_bits = 32
1811
- @all_f = 2**@max_bits - 1
1812
-
1813
- # validate addr arg
1814
- if (addr.kind_of?(String))
1815
- cidr = addr
1816
- elsif (addr.kind_of?(Integer))
1817
- packed_ip = addr
1818
- else
1819
- raise ArgumentError, "String or Integer expected for argument 'addr' but #{addr.class} provided."
1820
- end
1821
-
1822
- # validate options
1823
- if (options)
1824
- raise ArgumentError, "Hash expected for argument 'options' but " +
1825
- "#{options.class} provided." if (!options.kind_of?(Hash) )
1826
- NetAddr.validate_args(options.keys,known_args)
1827
-
1828
- if (options.has_key?(:PackedNetmask))
1829
- packed_netmask = options[:PackedNetmask]
1830
- raise ArgumentError, "Expected Integer, but #{packed_netmask.class} " +
1831
- "provided for option :PackedNetmask." if (!packed_netmask.kind_of?(Integer))
1832
- end
1833
-
1834
- if (options.has_key?(:Tag))
1835
- @tag = options[:Tag]
1836
- if (!@tag.kind_of? Hash)
1837
- raise ArgumentError, "Expected Hash, but #{@tag.class} provided for option :Tag."
1838
- end
1839
- end
1840
-
1841
- if (options.has_key?(:WildcardMask))
1842
- if (!options[:WildcardMask].kind_of?(Array))
1843
- raise ArgumentError, "Expected Array, but #{options[:WildcardMask].class} provided for option :WildcardMask."
1844
- end
1845
- wildcardmask = options[:WildcardMask][0]
1846
- inversed = false
1847
- inversed = true if (options[:WildcardMask][1] && options[:WildcardMask][1] == :inversed)
1848
-
1849
- if (wildcardmask.kind_of?(Integer))
1850
- begin
1851
- @wildcard_mask = wildcardmask
1852
- NetAddr.validate_ip_addr(@wildcard_mask, :Version => @version)
1853
- rescue NetAddr::ValidationError
1854
- raise NetAddr::ValidationError, ":WildcardMask must be a valid IPv#{@version} address."
1855
- end
1856
- else
1857
- begin
1858
- @wildcard_mask = NetAddr.pack_ip_addr(wildcardmask, :Version => @version)
1859
- rescue NetAddr::ValidationError
1860
- raise NetAddr::ValidationError, ":WildcardMask must be a valid IPv#{@version} address."
1861
- end
1862
- end
1863
-
1864
- @wildcard_mask = @wildcard_mask ^ @all_f if (inversed)
1865
- end
1866
- end
1867
-
1868
-
1869
- if (packed_ip)
1870
- # validate & store packed_ip
1871
- NetAddr.validate_ip_addr(packed_ip, :Version => @version)
1872
- @ip = packed_ip
1873
-
1874
- else
1875
- # if extended netmask provided. should only apply to ipv4
1876
- if (cidr =~ /.+\s+.+/ )
1877
- cidr,netmask = cidr.split(' ')
1878
- end
1879
-
1880
- # if netmask part of cidr, then over-ride any provided extended netmask.
1881
- if (cidr =~ /\//)
1882
- ip,netmask = cidr.split(/\//)
1883
- if (!ip || !netmask)
1884
- raise ArgumentError, "CIDR address is improperly formatted. Missing netmask after '/' character."
1885
- end
1886
- else
1887
- ip = cidr
1888
- end
1889
-
1890
- # pack ip
1891
- @ip = NetAddr.pack_ip_addr(ip, :Version => @version)
1892
- end
1893
-
1894
- # if no netmask or packed_netmask, then set
1895
- # else validate. packed_netmask takes precedence over netmask
1896
- if (!netmask && !packed_netmask)
1897
- @netmask = @all_f
1898
- else
1899
- if (packed_netmask)
1900
- NetAddr.validate_ip_netmask(packed_netmask, :Packed => true, :Version => @version)
1901
- @netmask = packed_netmask
1902
- else
1903
- NetAddr.validate_ip_netmask(netmask, :Version => @version)
1904
- @netmask = NetAddr.pack_ip_netmask(netmask, :Version => @version)
1905
- end
1906
- end
1907
-
1908
- # set @network & @hostmask
1909
- @network = (@ip & @netmask)
1910
- @hostmask = @netmask ^ @all_f
1911
- @wildcard_mask = @hostmask if (!@wildcard_mask)
1912
-
1913
- end
1914
-
1847
+ public_class_method :new
1915
1848
 
1916
1849
  #==============================================================================#
1917
1850
  # broadcast()
1918
1851
  #==============================================================================#
1919
1852
 
1920
1853
  # Alias for last
1921
- alias :broadcast :last
1854
+ alias :broadcast :last
1922
1855
 
1923
1856
  #==============================================================================#
1924
1857
  # hostmask_ext()
@@ -1927,8 +1860,6 @@ alias :broadcast :last
1927
1860
  #===Synopsis
1928
1861
  #Provide IPv4 Hostmask in extended format (y.y.y.y).
1929
1862
  #
1930
- # puts cidr4.hostmask_ext(
1931
- #
1932
1863
  #===Arguments:
1933
1864
  #* none
1934
1865
  #
@@ -1936,7 +1867,7 @@ alias :broadcast :last
1936
1867
  #* String
1937
1868
  #
1938
1869
  def hostmask_ext()
1939
- return(NetAddr.unpack_ip_addr(@hostmask, :Version => @version))
1870
+ return(NetAddr.ip_int_to_str(@hostmask, @version))
1940
1871
  end
1941
1872
 
1942
1873
  #==============================================================================#
@@ -1946,160 +1877,29 @@ alias :broadcast :last
1946
1877
  #===Synopsis
1947
1878
  #Provide IPv4 netmask in extended format (y.y.y.y).
1948
1879
  #
1949
- # puts cidr4.netmask_ext()
1950
- #
1951
1880
  #===Arguments:
1952
1881
  #* none
1953
1882
  #
1954
1883
  #===Returns:
1955
1884
  #* String
1956
1885
  #
1957
- def netmask_ext()
1958
- return(NetAddr.unpack_ip_addr(@netmask))
1886
+ def netmask_ext()
1887
+ return(NetAddr.ip_int_to_str(@netmask, 4))
1959
1888
  end
1960
1889
 
1961
1890
  end # end class CIDRv4
1962
-
1963
-
1964
- # IPv6 CIDR address - Inherits all methods from NetAddr::CIDR.
1965
- # Addresses of this class are composed of a 128-bit address space.
1966
- class CIDRv6 < CIDR
1967
-
1968
- public_class_method :new
1969
-
1970
- #==============================================================================#
1971
- # initialize()
1972
- #==============================================================================#
1973
-
1974
- #===Synopsis
1975
- #Return a CIDRv6 object.
1976
- #CIDR formatted netmasks take precedence over extended formatted ones.
1977
- #CIDR address defaults to a host network (/128) if netmask not provided.
1978
- #:PackedNetmask takes precedence over netmask given within CIDR address.
1979
- #
1980
- # cidr6 = NetAddr::CIDRv6.new('fec0::/64')
1981
- # cidr6 = NetAddr::CIDRv6.new('fec0::/64',
1982
- # :Tag => {'interface' => 'g0/1'})
1983
- # cidr6_2 = NetAddr::CIDRv6.new('::ffff:192.168.1.1/96')
1984
- # cidr6_3 = NetAddr::CIDRv6.new('fec0::',
1985
- # :WildcardMask => '0000:ffff::ffff')
1986
- #
1987
- #===Arguments:
1988
- #* CIDR address as a String, or a packed IP address as an Integer
1989
- #* Optional Hash with the following keys:
1990
- # :PackedNetmask -- Integer representation of an IP Netmask (optional)
1991
- # :Tag -- Custom descriptor tag - Hash, tag => value. (optional)
1992
- # :WildcardMask -- 2 element Array. First element contains a special bit mask used for
1993
- # advanced IP pattern matching. The second element should be :inversed if this
1994
- # bit mask is in inverse format. (optional)
1995
- #
1996
- def initialize(addr, options=nil)
1997
- known_args = [:PackedNetmask, :Tag, :WildcardMask]
1998
- @tag = {}
1999
- @version = 6
2000
- @max_bits = 128
2001
- @all_f = 2**@max_bits - 1
2002
-
2003
- # validate addr arg
2004
- if (addr.kind_of?(String))
2005
- cidr = addr
2006
- elsif (addr.kind_of?(Integer))
2007
- packed_ip = addr
2008
- else
2009
- raise ArgumentError, "String or Integer expected for argument 'addr' but #{addr.class} provided."
2010
- end
2011
-
2012
- # validate options
2013
- if (options)
2014
- raise ArgumentError, "Hash expected for argument 'options' but " +
2015
- "#{options.class} provided." if (!options.kind_of?(Hash) )
2016
- NetAddr.validate_args(options.keys,known_args)
2017
-
2018
- if (options.has_key?(:PackedNetmask))
2019
- packed_netmask = options[:PackedNetmask]
2020
- raise ArgumentError, "Expected Integer, but #{packed_netmask.class} " +
2021
- "provided for option :PackedNetmask." if (!packed_netmask.kind_of?(Integer))
2022
- end
2023
-
2024
- if (options.has_key?(:Tag))
2025
- @tag = options[:Tag]
2026
- if (!@tag.kind_of? Hash)
2027
- raise ArgumentError, "Expected Hash, but #{@tag.class} provided for option :Tag."
2028
- end
2029
- end
2030
-
2031
- if (options.has_key?(:WildcardMask))
2032
- if (!options[:WildcardMask].kind_of?(Array))
2033
- raise ArgumentError, "Expected Array, but #{options[:WildcardMask].class} provided for option :WildcardMask."
2034
- end
2035
- wildcardmask = options[:WildcardMask][0]
2036
- inversed = false
2037
- inversed = true if (options[:WildcardMask][1] && options[:WildcardMask][1] == :inversed)
2038
-
2039
- if (wildcardmask.kind_of?(Integer))
2040
- begin
2041
- @wildcard_mask = wildcardmask
2042
- NetAddr.validate_ip_addr(@wildcard_mask, :Version => @version)
2043
- rescue NetAddr::ValidationError
2044
- raise NetAddr::ValidationError, ":WildcardMask must be a valid IPv#{@version} address."
2045
- end
2046
- else
2047
- begin
2048
- @wildcard_mask = NetAddr.pack_ip_addr(wildcardmask, :Version => @version)
2049
- rescue NetAddr::ValidationError
2050
- raise NetAddr::ValidationError, ":WildcardMask must be a valid IPv#{@version} address."
2051
- end
2052
- end
2053
-
2054
- @wildcard_mask = @wildcard_mask ^ @all_f if (inversed)
2055
- end
2056
- end
2057
1891
 
2058
1892
 
2059
- if (packed_ip)
2060
- # validate & store packed_ip
2061
- NetAddr.validate_ip_addr(packed_ip, :Version => @version)
2062
- @ip = packed_ip
2063
-
2064
- else
2065
- # if ipv6 and extended netmask was provided, then raise exception
2066
- raise ArgumentError, "Garbage provided at end of IPv6 address." if (cidr =~ /.+\s+.+/ )
2067
1893
 
2068
- # get ip and netmask
2069
- if (cidr =~ /\//)
2070
- ip,netmask = cidr.split(/\//)
2071
- if (!ip || !netmask)
2072
- raise ArgumentError, "CIDR address is improperly formatted. Missing netmask after '/' character."
2073
- end
2074
- else
2075
- ip = cidr
2076
- end
2077
1894
 
2078
- # pack ip
2079
- @ip = NetAddr.pack_ip_addr(ip, :Version => @version)
2080
- end
2081
1895
 
2082
- # if no netmask or packed_netmask, then set
2083
- # else validate. packed_netmask takes precedence over netmask
2084
- if (!netmask && !packed_netmask)
2085
- @netmask = @all_f
2086
- else
2087
- if (packed_netmask)
2088
- NetAddr.validate_ip_netmask(packed_netmask, :Packed => true, :Version => @version)
2089
- @netmask = packed_netmask
2090
- else
2091
- NetAddr.validate_ip_netmask(netmask, :Version => @version)
2092
- @netmask = NetAddr.pack_ip_netmask(netmask, :Version => @version)
2093
- end
2094
- end
2095
1896
 
2096
- # set @network & @hostmask
2097
- @network = (@ip & @netmask)
2098
- @hostmask = @netmask ^ @all_f
2099
- @wildcard_mask = @hostmask if (!@wildcard_mask)
2100
1897
 
2101
- end
2102
1898
 
1899
+ # IPv6 CIDR address - Inherits all methods from NetAddr::CIDR.
1900
+ # Addresses of this class are composed of a 128-bit address space.
1901
+ class CIDRv6 < CIDR
1902
+ public_class_method :new
2103
1903
  end # end class CIDRv6
2104
1904
 
2105
1905
  end # module NetAddr