netaddr 1.0.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/lib/net_addr.rb ADDED
@@ -0,0 +1,26 @@
1
+ =begin rdoc
2
+ Copyright (c) 2006 Dustin Spinhirne (www.spinhirne.com)
3
+
4
+ Licensed under the same terms as Ruby, No Warranty is provided.
5
+ =end
6
+
7
+
8
+ require File.join(File.dirname(__FILE__), 'methods.rb')
9
+ require File.join(File.dirname(__FILE__), 'cidr.rb')
10
+ require File.join(File.dirname(__FILE__), 'tree.rb')
11
+ require File.join(File.dirname(__FILE__), 'eui.rb')
12
+
13
+ module NetAddr
14
+
15
+ class BoundaryError < StandardError #:nodoc:
16
+ end
17
+
18
+ class ValidationError < StandardError #:nodoc:
19
+ end
20
+
21
+ class VersionError < StandardError #:nodoc:
22
+ end
23
+
24
+ end # module NetAddr
25
+
26
+ __END__
data/lib/tree.rb ADDED
@@ -0,0 +1,880 @@
1
+ =begin rdoc
2
+ Copyright (c) 2006 Dustin Spinhirne (www.spinhirne.com)
3
+
4
+ Licensed under the same terms as Ruby, No Warranty is provided.
5
+ =end
6
+
7
+ module NetAddr
8
+
9
+ #=Tree
10
+ #
11
+ #A class & series of methods for creating and manipulating IP-based
12
+ #heirarchical trees. Both IPv4 and IPv6 are supported.
13
+ #
14
+ #A sample tree would look like:
15
+ # 192.168.1.0/24
16
+ # 192.168.1.0/26
17
+ # 192.168.1.0/27
18
+ # 192.168.1.0/28
19
+ # 192.168.1.16/29
20
+ # 192.168.1.16/30
21
+ # 192.168.1.24/30
22
+ # 192.168.1.25/32
23
+ # 192.168.1.28/30
24
+ # 192.168.1.32/27
25
+ # 192.168.1.64/26
26
+ # 192.168.1.64/27
27
+ # 192.168.1.128/26
28
+ # 192.168.1.192/26
29
+ #
30
+ class Tree
31
+
32
+ #==============================================================================#
33
+ # initialize()
34
+ #==============================================================================#
35
+
36
+ #===Synopsis
37
+ #Create a new Tree object.
38
+ #
39
+ # tree = NetAddr::Tree.new()
40
+ #
41
+ #===Arguments:
42
+ #* none
43
+ #
44
+ def initialize()
45
+ # root of our ordered IP tree
46
+ @root = NetStruct.new(nil, nil, [])
47
+ end
48
+
49
+ #==============================================================================#
50
+ # add!()
51
+ #==============================================================================#
52
+
53
+ #===Synopsis
54
+ # Add a CIDR address or NetAddr::CIDR object to the tree.
55
+ #
56
+ # tree.add!('192.168.1.0/24')
57
+ # cidr = NetAddr::CIDR.create(:CIDR => '192.168.1.0/24', :Tag => {:title => 'test net'}
58
+ # tree.add!(cidr)
59
+ #
60
+ #===Arguments:
61
+ #* String or NetAddr::CIDR object
62
+ #
63
+ #===Returns:
64
+ #* nil
65
+ #
66
+ def add!(new)
67
+ duplicate = false
68
+
69
+ # validate object
70
+ if ( !new.kind_of?(NetAddr::CIDR) )
71
+ begin
72
+ cidr = NetAddr::CIDR.create(new)
73
+ rescue Exception => error
74
+ raise ArgumentError, "Provided argument raised the following " +
75
+ "errors: #{error}"
76
+ end
77
+ else
78
+ cidr = new.dup
79
+ end
80
+
81
+ version = cidr.version
82
+ new_entry = NetStruct.new(cidr, nil, [])
83
+
84
+ # find cidr's parent
85
+ new_entry.parent = find_parent(cidr, @root)
86
+
87
+ # check parent for subnets of cidr
88
+ new_entry.parent.children.each do |old_entry|
89
+ if (old_entry.cidr.version == version)
90
+ comp = cidr.cmp(old_entry.cidr)
91
+ if (comp && comp == 1)
92
+ old_entry.parent = new_entry
93
+ new_entry.children.push(old_entry)
94
+ elsif (comp && comp == 0)
95
+ duplicate = true
96
+ break
97
+ end
98
+ end
99
+ end
100
+
101
+ if (!duplicate)
102
+ new_entry.children.each do |old_entry|
103
+ new_entry.parent.children.delete(old_entry)
104
+ end
105
+
106
+ # add new object as an ordered entry to parent.children
107
+ add_to_parent(new_entry,new_entry.parent)
108
+ end
109
+
110
+ return(nil)
111
+ end
112
+
113
+ #==============================================================================#
114
+ # ancestors()
115
+ #==============================================================================#
116
+
117
+ #===Synopsis
118
+ # Returns all the ancestors of the provided CIDR addresses.
119
+ #
120
+ # puts tree.ancestors('192.168.1.0/27')
121
+ #
122
+ #===Arguments:
123
+ #* String or NetAddr::CIDR object
124
+ #
125
+ #===Returns:
126
+ #* Array of NetAddr::CIDR objects
127
+ #
128
+ def ancestors(cidr)
129
+ # validate object
130
+ if ( !cidr.kind_of?(NetAddr::CIDR) )
131
+ begin
132
+ cidr = NetAddr::CIDR.create(cidr)
133
+ rescue Exception => error
134
+ raise ArgumentError, "Provided argument raised the following " +
135
+ "errors: #{error}"
136
+ end
137
+ end
138
+
139
+ list = []
140
+ parent = find_parent(cidr,@root)
141
+
142
+ until (parent == @root)
143
+ list.push(parent.cidr)
144
+ parent = parent.parent
145
+ end
146
+
147
+ return(list)
148
+ end
149
+
150
+ #==============================================================================#
151
+ # children()
152
+ #==============================================================================#
153
+
154
+ #===Synopsis
155
+ # Returns all the immediate children of the provided CIDR addresses.
156
+ #
157
+ # puts tree.children('192.168.1.0/24')
158
+ #
159
+ #===Arguments:
160
+ #* String or NetAddr::CIDR object
161
+ #
162
+ #===Returns:
163
+ #* Array of NetAddr::CIDR objects
164
+ #
165
+ def children(cidr)
166
+ # validate object
167
+ if ( !cidr.kind_of?(NetAddr::CIDR) )
168
+ begin
169
+ cidr = NetAddr::CIDR.create(cidr)
170
+ rescue Exception => error
171
+ raise ArgumentError, "Provided argument raised the following " +
172
+ "errors: #{error}"
173
+ end
174
+ end
175
+
176
+ list = []
177
+ find_me(cidr).children.each do |child|
178
+ list.push(child.cidr)
179
+ end
180
+
181
+ return(list)
182
+ end
183
+
184
+ #==============================================================================#
185
+ # descendants
186
+ #==============================================================================#
187
+
188
+ #===Synopsis
189
+ # Return all descendants of the provided CIDR address.
190
+ #
191
+ # descendants = tree.descendants('192.168.1.0/24')
192
+ #
193
+ #===Arguments:
194
+ #* String or NetAddr::CIDR object
195
+ #
196
+ #===Returns:
197
+ #* Array of NetAddr::CIDR objects
198
+ #
199
+ def descendants(cidr)
200
+ list = []
201
+
202
+ # validate object
203
+ if ( !cidr.kind_of?(NetAddr::CIDR) )
204
+ begin
205
+ cidr = NetAddr::CIDR.create(cidr)
206
+ rescue Exception => error
207
+ raise ArgumentError, "Provided argument raised the following " +
208
+ "errors: #{error}"
209
+ end
210
+ end
211
+
212
+ me = find_me(cidr)
213
+ dump_children(me).each {|x| list.push(x[:NetStruct].cidr)} if (me)
214
+
215
+ return(list)
216
+ end
217
+
218
+ #==============================================================================#
219
+ # delete!()
220
+ #==============================================================================#
221
+
222
+ #===Synopsis
223
+ # Remove the provided CIDR address from the tree.
224
+ #
225
+ # did_remove = tree.remove!('192.168.1.0/24')
226
+ #
227
+ #===Arguments:
228
+ #* String or NetAddr::CIDR object
229
+ #
230
+ #===Returns:
231
+ #* true on success or false on fail
232
+ #
233
+ def delete!(cidr)
234
+ removed = false
235
+
236
+ # validate object
237
+ if ( !cidr.kind_of?(NetAddr::CIDR) )
238
+ begin
239
+ cidr = NetAddr::CIDR.create(cidr)
240
+ rescue Exception => error
241
+ raise ArgumentError, "Provided argument raised the following " +
242
+ "errors: #{error}"
243
+ end
244
+ end
245
+
246
+ # find matching
247
+ me = find_me(cidr)
248
+
249
+ # remove
250
+ if (me)
251
+ parent = me.parent
252
+ children = me.children
253
+ parent.children.delete(me)
254
+ children.each {|x| add_to_parent(x,parent)}
255
+ removed = true
256
+ end
257
+
258
+ return(removed)
259
+ end
260
+
261
+ #==============================================================================#
262
+ # dump
263
+ #==============================================================================#
264
+
265
+ #===Synopsis
266
+ # Dump the contents of this tree.
267
+ #
268
+ # dumped = tree.dump()
269
+ #
270
+ #===Arguments:
271
+ #* none
272
+ #
273
+ #===Returns:
274
+ #* ordered array of hashes with the following fields:
275
+ # :CIDR => NetAddr::CIDR object
276
+ # :Depth => (depth level in tree)
277
+ #
278
+ def dump()
279
+ list = []
280
+ dumped = dump_children(@root)
281
+
282
+ dumped.each do |entry|
283
+ depth = entry[:Depth]
284
+ net_struct = entry[:NetStruct]
285
+ list.push({:Depth => depth, :CIDR => net_struct.cidr})
286
+ end
287
+
288
+ return(list)
289
+ end
290
+
291
+ #==============================================================================#
292
+ # exists?()
293
+ #==============================================================================#
294
+
295
+ #===Synopsis
296
+ # Has a CIDR address already been added to the tree?
297
+ #
298
+ # added = tree.exists?('192.168.1.0/24')
299
+ #
300
+ #===Arguments:
301
+ #* String or NetAddr::CIDR object
302
+ #
303
+ #===Returns:
304
+ #* true or false
305
+ #
306
+ def exists?(cidr)
307
+ found = false
308
+
309
+ # validate object
310
+ if ( !cidr.kind_of?(NetAddr::CIDR) )
311
+ begin
312
+ cidr = NetAddr::CIDR.create(cidr)
313
+ rescue Exception => error
314
+ raise ArgumentError, "Provided argument raised the following " +
315
+ "errors: #{error}"
316
+ end
317
+ end
318
+
319
+ found = true if (find_me(cidr))
320
+ return(found)
321
+ end
322
+
323
+ #==============================================================================#
324
+ # fill_in!()
325
+ #==============================================================================#
326
+
327
+ #===Synopsis
328
+ # Fill in the missing subnets of a particular CIDR.
329
+ #
330
+ # success = tree.fill_in!('192.168.1.0/24')
331
+ #
332
+ #===Arguments:
333
+ #* String or NetAddr::CIDR object
334
+ #
335
+ #===Returns:
336
+ #* true or false
337
+ #
338
+ def fill_in!(cidr)
339
+ filled = false
340
+
341
+ # validate object
342
+ if ( !cidr.kind_of?(NetAddr::CIDR) )
343
+ begin
344
+ cidr = NetAddr::CIDR.create(cidr)
345
+ rescue Exception => error
346
+ raise ArgumentError, "Provided argument raised the following " +
347
+ "errors: #{error}"
348
+ end
349
+ end
350
+
351
+ me = find_me(cidr)
352
+ if (me && me.children.length != 0)
353
+ list = []
354
+ me.children.each {|x| list.push(x.cidr)}
355
+ me.cidr.fill_in(list, :Objectify => true).each do |cidr|
356
+ self.add!(cidr)
357
+ end
358
+ filled = true
359
+ end
360
+ return(filled)
361
+ end
362
+
363
+ #==============================================================================#
364
+ # find()
365
+ #==============================================================================#
366
+
367
+ #===Synopsis
368
+ # Find and return a CIDR from within the tree.
369
+ #
370
+ # cidr = tree.find('192.168.1.0/24')
371
+ #
372
+ #===Arguments:
373
+ #* String or NetAddr::CIDR object
374
+ #
375
+ #===Returns:
376
+ #* NetAddr::CIDR object, or nil
377
+ #
378
+ def find(cidr)
379
+ if ( !cidr.kind_of?(NetAddr::CIDR) )
380
+ begin
381
+ cidr = NetAddr::CIDR.create(:CIDR => cidr)
382
+ rescue Exception => error
383
+ raise ArgumentError, "Provided argument raised the following " +
384
+ "errors: #{error}"
385
+ end
386
+ end
387
+
388
+ return(find_me(cidr).cidr)
389
+ end
390
+
391
+ #==============================================================================#
392
+ # find_space()
393
+ #==============================================================================#
394
+
395
+ #===Synopsis
396
+ # Find subnets that are of at least size X. Only subnets that are not themselves
397
+ # subnetted will be returned. :Subnet takes precedence over :IPCount
398
+ #
399
+ # subnets = tree.find_space(:IPCount => 16)
400
+ #
401
+ #===Arguments:
402
+ #* Minimum subnet size in bits, or a Hash with the following keys:
403
+ # :Subnet - minimum subnet size in bits for returned subnets
404
+ # :IPCount - minimum IP count per subnet required for returned subnets
405
+ # :Version - restrict results to IPvX
406
+ #
407
+ #===Returns:
408
+ #* Array of NetAddr::CIDR objects
409
+ #
410
+ def find_space(options)
411
+ known_args = [:Subnet, :IPCount, :Version]
412
+ version = nil
413
+ if (options.kind_of? Integer)
414
+ bits4 = options
415
+ bits6 = options
416
+ elsif (options.kind_of? Hash)
417
+ NetAddr.validate_args(options.keys,known_args)
418
+ if (options.has_key?(:Version))
419
+ version = options[:Version]
420
+ raise "IP version should be 4 or 6, but was #{version}." if (version != 4 && version !=6)
421
+ end
422
+
423
+ if (options.has_key?(:Subnet))
424
+ bits4 = options[:Subnet]
425
+ bits6 = options[:Subnet]
426
+ elsif(options.has_key?(:IPCount))
427
+ bits4 = NetAddr.minimum_size(options[:IPCount], :Version => 4)
428
+ bits6 = NetAddr.minimum_size(options[:IPCount], :Version => 6)
429
+ else
430
+ raise "Missing arguments: :Subnet/:IPCount"
431
+ end
432
+ else
433
+ raise "Integer or Hash expected, but #{options.class} provided."
434
+ end
435
+
436
+ list4 = []
437
+ list6 = []
438
+ dump_children(@root).each do |entry|
439
+ netstruct = entry[:NetStruct]
440
+ if (netstruct.cidr.version == 4)
441
+ if ( (netstruct.children.length == 0) && (netstruct.cidr.bits <= bits4) )
442
+ list4.push(netstruct.cidr)
443
+ end
444
+ else
445
+ if ( (netstruct.children.length == 0) && (netstruct.cidr.bits <= bits6) )
446
+ list6.push(netstruct.cidr)
447
+ end
448
+ end
449
+ end
450
+
451
+ list = []
452
+ if (!version)
453
+ list.concat(list4)
454
+ list.concat(list6)
455
+ else
456
+ list.concat(list4) if (version == 4)
457
+ list.concat(list6) if (version == 6)
458
+ end
459
+
460
+ return(list)
461
+ end
462
+
463
+ #==============================================================================#
464
+ # longest_match()
465
+ #==============================================================================#
466
+
467
+ #===Synopsis
468
+ #Find the longest matching branch of our tree to which a
469
+ #CIDR address belongs. Useful for performing 'routing table' style lookups.
470
+ #
471
+ # longest_match = tree.longest_match('192.168.1.1')
472
+ #
473
+ #===Arguments:
474
+ #* String or NetAddr::CIDR object
475
+ #
476
+ #===Returns:
477
+ #* NetAddr::CIDR object, or nil
478
+ #
479
+ def longest_match(cidr)
480
+ if ( !cidr.kind_of?(NetAddr::CIDR) )
481
+ begin
482
+ cidr = NetAddr::CIDR.create(cidr)
483
+ rescue Exception => error
484
+ raise ArgumentError, "Provided argument raised the following " +
485
+ "errors: #{error}"
486
+ end
487
+ end
488
+
489
+ found = find_me(cidr)
490
+ found = find_parent(cidr, @root) if !found
491
+
492
+ return(found.cidr)
493
+ end
494
+
495
+ #==============================================================================#
496
+ # merge_subnets!()
497
+ #==============================================================================#
498
+
499
+ #===Synopsis
500
+ # Merge (summarize) all subnets of the provided CIDR address.
501
+ #
502
+ # tree.merge_subnets!('192.168.1.0/24')
503
+ #
504
+ #===Arguments:
505
+ #* String or NetAddr::CIDR object
506
+ #
507
+ #===Returns:
508
+ #* true on success or false on fail
509
+ #
510
+ def merge_subnets!(cidr)
511
+ merged = false
512
+
513
+ # validate object
514
+ if ( !cidr.kind_of?(NetAddr::CIDR) )
515
+ begin
516
+ cidr = NetAddr::CIDR.create(cidr)
517
+ rescue Exception => error
518
+ raise ArgumentError, "Provided argument raised the following " +
519
+ "errors: #{error}"
520
+ end
521
+ end
522
+
523
+ me = find_me(cidr)
524
+
525
+ if (me)
526
+ to_merge = []
527
+ me.children.each {|x| to_merge.push(x.cidr)}
528
+ to_merge.each {|x| delete!(x)}
529
+
530
+ NetAddr.merge(to_merge).each {|x| add!(x)}
531
+ merged = true
532
+ end
533
+
534
+ return(merged)
535
+ end
536
+
537
+ #==============================================================================#
538
+ # prune!()
539
+ #==============================================================================#
540
+
541
+ #===Synopsis
542
+ # Remove all subnets of the provided CIDR address.
543
+ #
544
+ # did_prune = tree.prune!('192.168.1.0/24')
545
+ #
546
+ #===Arguments:
547
+ #* String or NetAddr::CIDR object
548
+ #
549
+ #===Returns:
550
+ #* true on success or false on fail
551
+ #
552
+ def prune!(cidr)
553
+ pruned = false
554
+
555
+ # validate object
556
+ if ( !cidr.kind_of?(NetAddr::CIDR) )
557
+ begin
558
+ cidr = NetAddr::CIDR.create(:CIDR => cidr)
559
+ rescue Exception => error
560
+ raise ArgumentError, "Provided argument raised the following " +
561
+ "errors: #{error}"
562
+ end
563
+ end
564
+
565
+ me = find_me(cidr)
566
+
567
+ if (me)
568
+ me.children.clear
569
+ pruned = true
570
+ end
571
+
572
+ return(pruned)
573
+ end
574
+
575
+ #==============================================================================#
576
+ # remove!()
577
+ #==============================================================================#
578
+
579
+ #===Synopsis
580
+ # Remove the provided CIDR address, and all of its subnets from the tree.
581
+ #
582
+ # did_remove = tree.remove!('192.168.1.0/24')
583
+ #
584
+ #===Arguments:
585
+ #* String or NetAddr::CIDR object
586
+ #
587
+ #===Returns:
588
+ #* true on success or false on fail
589
+ #
590
+ def remove!(cidr)
591
+ removed = false
592
+ found = nil
593
+
594
+ # validate object
595
+ if ( !cidr.kind_of?(NetAddr::CIDR) )
596
+ begin
597
+ cidr = NetAddr::CIDR.create(:CIDR => cidr)
598
+ rescue Exception => error
599
+ raise ArgumentError, "Provided argument raised the following " +
600
+ "errors: #{error}"
601
+ end
602
+ end
603
+
604
+ me = find_me(cidr)
605
+
606
+ if (me)
607
+ parent = me.parent
608
+ parent.children.delete(me)
609
+ removed = true
610
+ end
611
+
612
+ return(removed)
613
+ end
614
+
615
+ #==============================================================================#
616
+ # resize!()
617
+ #==============================================================================#
618
+
619
+ #===Synopsis
620
+ # Resize the provided CIDR address.
621
+ #
622
+ # resized = tree.resize!('192.168.1.0/24', 23)
623
+ #
624
+ #===Arguments:
625
+ #* CIDR address as a String or an NetAddr::CIDR object
626
+ #* Integer representing the bits of the new netmask
627
+ #
628
+ #===Returns:
629
+ #* true on success or false on fail
630
+ #
631
+ def resize!(cidr,bits)
632
+ resized = false
633
+
634
+ # validate cidr
635
+ if ( !cidr.kind_of?(NetAddr::CIDR) )
636
+ begin
637
+ cidr = NetAddr::CIDR.create(:CIDR => cidr)
638
+ rescue Exception => error
639
+ raise ArgumentError, "Provided argument raised the following " +
640
+ "errors: #{error}"
641
+ end
642
+ end
643
+
644
+ me = find_me(cidr)
645
+
646
+ if (me)
647
+ new = me.cidr.resize(bits)
648
+ delete!(me.cidr)
649
+ add!(new)
650
+ resized = true
651
+ end
652
+
653
+ return(resized)
654
+ end
655
+
656
+ #==============================================================================#
657
+ # root()
658
+ #==============================================================================#
659
+
660
+ #===Synopsis
661
+ # Returns the root of the provided CIDR address.
662
+ #
663
+ # puts tree.root('192.168.1.32/27')
664
+ #
665
+ #===Arguments:
666
+ #* String or NetAddr::CIDR object
667
+ #
668
+ #===Returns:
669
+ #* NetAddr::CIDR object
670
+ #
671
+ def root(cidr)
672
+ # validate object
673
+ if ( !cidr.kind_of?(NetAddr::CIDR) )
674
+ begin
675
+ cidr = NetAddr::CIDR.create(cidr)
676
+ rescue Exception => error
677
+ raise ArgumentError, "Provided argument raised the following " +
678
+ "errors: #{error}"
679
+ end
680
+ end
681
+
682
+ parent = find_parent(cidr,@root)
683
+
684
+ if (parent && parent != @root)
685
+ until (parent.parent == @root)
686
+ parent = parent.parent
687
+ end
688
+ end
689
+
690
+ return(parent.cidr)
691
+ end
692
+
693
+ #==============================================================================#
694
+ # show()
695
+ #==============================================================================#
696
+
697
+ #===Synopsis
698
+ # Print the tree in a nicely formatted string.
699
+ #
700
+ # puts tree.show()
701
+ #
702
+ #===Arguments:
703
+ #* none
704
+ #
705
+ #===Returns:
706
+ #* String
707
+ #
708
+ def show()
709
+ printed = ""
710
+ list = dump_children(@root)
711
+
712
+ list.each do |entry|
713
+ cidr = entry[:NetStruct].cidr
714
+ depth = entry[:Depth]
715
+
716
+ if (depth == 0)
717
+ indent = ""
718
+ else
719
+ indent = " " * (depth*3)
720
+ end
721
+
722
+ printed << "#{indent}#{cidr.desc(:Short => true)}\n"
723
+ end
724
+
725
+ return(printed)
726
+ end
727
+
728
+ #==============================================================================#
729
+ # siblings()
730
+ #==============================================================================#
731
+
732
+ #===Synopsis
733
+ # Return list of the sibling CIDRs of the provided CIDR address.
734
+ #
735
+ # puts tree.siblings('192.168.1.0/27')
736
+ #
737
+ #===Arguments:
738
+ #* String or NetAddr::CIDR object
739
+ #
740
+ #===Returns:
741
+ #* Array of NetAddr::CIDR objects
742
+ #
743
+ def siblings(cidr)
744
+ # validate object
745
+ if ( !cidr.kind_of?(NetAddr::CIDR) )
746
+ begin
747
+ cidr = NetAddr::CIDR.create(cidr)
748
+ rescue Exception => error
749
+ raise ArgumentError, "Provided argument raised the following " +
750
+ "errors: #{error}"
751
+ end
752
+ end
753
+
754
+ list = []
755
+ find_parent(cidr,@root).children.each do |entry|
756
+ if (!cidr.cmp(entry.cidr))
757
+ list.push(entry.cidr)
758
+ end
759
+ end
760
+
761
+ return(list)
762
+ end
763
+
764
+ #==============================================================================#
765
+ # supernets()
766
+ #==============================================================================#
767
+
768
+ #===Synopsis
769
+ # Return list of the top-level supernets of this tree.
770
+ #
771
+ # supernets = tree.supernets()
772
+ #
773
+ #===Arguments:
774
+ #* none
775
+ #
776
+ #===Returns:
777
+ #* Array of NetAddr::CIDR objects
778
+ #
779
+ def supernets()
780
+ supernets = []
781
+ @root.children.each {|x| supernets.push(x.cidr)}
782
+ return (supernets)
783
+ end
784
+
785
+
786
+ # PRIVATE INSTANCE METHODS
787
+ private
788
+
789
+ #==============================================================================#
790
+ # add_to_parent() private
791
+ #==============================================================================#
792
+
793
+ # Add NetStruct object to an array of NetStruct's
794
+ #
795
+ def add_to_parent(new_entry, parent)
796
+ index = 0
797
+ parent.children.each do
798
+ if(new_entry.cidr.packed_network < parent.children[index].cidr.packed_network)
799
+ break
800
+ end
801
+ index += 1
802
+ end
803
+
804
+ parent.children.insert(index, new_entry)
805
+
806
+ return()
807
+ end
808
+
809
+ #==============================================================================#
810
+ # dump_children() private
811
+ #==============================================================================#
812
+
813
+ # Dump contents of an Array of NetStruct objects
814
+ #
815
+ def dump_children(parent,depth=nil)
816
+ list = []
817
+ depth = 0 if (!depth)
818
+
819
+ parent.children.each do |entry|
820
+ list.push({:NetStruct => entry, :Depth => depth})
821
+
822
+ if (entry.children.length > 0)
823
+ list.concat( dump_children(entry, (depth+1) ) )
824
+ end
825
+ end
826
+
827
+ return(list)
828
+ end
829
+
830
+ #==============================================================================#
831
+ # find_me() private
832
+ #==============================================================================#
833
+
834
+ # Find the NetStruct to which a cidr belongs.
835
+ #
836
+ def find_me(cidr)
837
+ me = nil
838
+
839
+ # find matching
840
+ parent = find_parent(cidr,@root)
841
+ parent.children.each do |entry|
842
+ if (entry.cidr.version == cidr.version)
843
+ if (entry.cidr.cmp(cidr) == 0)
844
+ me = entry
845
+ break
846
+ end
847
+ end
848
+ end
849
+
850
+ return(me)
851
+ end
852
+
853
+ #==============================================================================#
854
+ # find_parent() private
855
+ #==============================================================================#
856
+
857
+ # Find the parent NetStruct to which a child NetStruct belongs.
858
+ #
859
+ def find_parent(cidr,parent)
860
+ version = cidr.version
861
+
862
+ parent.children.each do |entry|
863
+ if (entry.cidr.version == version && entry.cidr.contains?(cidr))
864
+ parent = entry
865
+
866
+ if (parent.children.length > 0)
867
+ search_results = find_parent(cidr,parent)
868
+ parent = search_results if (search_results)
869
+ end
870
+ break
871
+ end
872
+ end
873
+
874
+ return(parent)
875
+ end
876
+
877
+ end # class Tree
878
+
879
+ end # module NetAddr
880
+ __END__