netaddr 1.5.1 → 2.0.3

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