netaddr 1.5.3 → 2.0.6

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