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.

@@ -1,440 +0,0 @@
1
- module NetAddr
2
- private
3
-
4
- # CIDR METHODS
5
-
6
- #==============================================================================#
7
- # cidr_build()
8
- #==============================================================================#
9
-
10
- # create either a CIDRv4 or CIDRv6 object
11
- #
12
- def cidr_build(version, ip, netmask=nil, tag={}, wildcard_mask=nil, wildcard_mask_bit_flipped=false)
13
- return( NetAddr::CIDRv4.new(ip, netmask, tag, wildcard_mask, wildcard_mask_bit_flipped) ) if (version == 4)
14
- return( NetAddr::CIDRv6.new(ip, netmask, tag, wildcard_mask, wildcard_mask_bit_flipped) )
15
- end
16
- module_function :cidr_build
17
-
18
- #==============================================================================#
19
- # cidr_compare()
20
- #==============================================================================#
21
-
22
- # compare 2 CIDR objects
23
- #
24
- #return:
25
- #* 1 if the cidr1 contains cidr2
26
- #* 0 if the cidr1 and cidr2 are equal
27
- #* -1 if cidr1 is a subnet of cidr2
28
- #* nil if the two are unrelated
29
- #
30
- def cidr_compare(cidr1,cidr2)
31
- comparasin = nil
32
- if ( cidr1.to_i(:network) == cidr2.to_i(:network) )
33
- # same network, check netmask
34
- if (cidr1.to_i(:netmask) == cidr2.to_i(:netmask) )
35
- comparasin = 0
36
- elsif(cidr1.to_i(:netmask) < cidr2.to_i(:netmask))
37
- comparasin = 1
38
- elsif(cidr1.to_i(:netmask) > cidr2.to_i(:netmask))
39
- comparasin = -1
40
- end
41
-
42
- elsif( (cidr2.to_i(:network) | cidr1.to_i(:hostmask)) == (cidr1.to_i(:network) | cidr1.to_i(:hostmask)) )
43
- # cidr1 contains cidr2
44
- comparasin = 1
45
-
46
- elsif( (cidr2.to_i(:network) | cidr2.to_i(:hostmask)) == (cidr1.to_i(:network) | cidr2.to_i(:hostmask)) )
47
- # cidr2 contains cidr1
48
- comparasin = -1
49
- end
50
-
51
- return(comparasin)
52
- end
53
- module_function :cidr_compare
54
-
55
- #==============================================================================#
56
- # cidr_gt_lt()
57
- #==============================================================================#
58
-
59
- # given a pair of CIDRs, determine if first is greater than or less than the second
60
- #
61
- # return 1 if cidr1 > cidr2
62
- # return 0 if cidr1 == cidr2
63
- # return -1 if cidr1 < cidr2
64
- #
65
- def cidr_gt_lt(cidr1,cidr2)
66
- gt_lt = 1
67
- if(cidr1.to_i(:network) < cidr2.to_i(:network))
68
- gt_lt = -1
69
- elsif (cidr1.to_i(:network) == cidr2.to_i(:network))
70
- if (cidr1.to_i(:netmask) < cidr2.to_i(:netmask))
71
- gt_lt = -1
72
- elsif (cidr1.to_i(:netmask) == cidr2.to_i(:netmask))
73
- gt_lt = 0
74
- end
75
- end
76
-
77
- return(gt_lt)
78
- end
79
- module_function :cidr_gt_lt
80
-
81
- #==============================================================================#
82
- # cidr_fill_in()
83
- #==============================================================================#
84
-
85
- #Given a list of subnets of supernet, return a new list with any
86
- #holes (missing subnets) filled in.
87
- #
88
- def cidr_fill_in(supernet,list)
89
- # sort our cidr's and see what is missing
90
- complete_list = []
91
- expected = supernet.to_i(:network)
92
- all_f = supernet.all_f
93
-
94
- NetAddr.cidr_sort(list).each do |cidr|
95
- network = cidr.to_i(:network)
96
- bitstep = (all_f + 1) - cidr.to_i(:netmask)
97
-
98
- if (network > expected) # missing space at beginning of supernet, so fill in the hole
99
- num_ips_missing = network - expected
100
- sub_list = cidr_make_subnets_from_base_and_ip_count(supernet,expected,num_ips_missing)
101
- complete_list.concat(sub_list)
102
- elsif (network < expected)
103
- next
104
- end
105
-
106
- complete_list.push(cidr)
107
- expected = network + bitstep
108
- end
109
-
110
- # if expected is not the next subnet, then we're missing subnets
111
- # at the end of the cidr
112
- next_sub = supernet.next_subnet(:Objectify => true).to_i(:network)
113
- if (expected != next_sub)
114
- num_ips_missing = next_sub - expected
115
- sub_list = cidr_make_subnets_from_base_and_ip_count(supernet,expected,num_ips_missing)
116
- complete_list.concat(sub_list)
117
- end
118
-
119
- return(complete_list)
120
- end
121
- module_function :cidr_fill_in
122
-
123
- #==============================================================================#
124
- # cidr_find_in_list()
125
- #==============================================================================#
126
-
127
- # evaluate cidr against list of cidrs.
128
- #
129
- # return entry from list if entry is supernet of cidr (first matching entry)
130
- # return index # of entry if entry is a duplicate of cidr
131
- # return nil if no match found
132
- #
133
- def cidr_find_in_list(cidr,list)
134
- return(nil) if (list.length == 0)
135
-
136
- match = nil
137
- low = 0
138
- high = list.length - 1
139
- index = low + ( (high-low)/2 )
140
- while ( low <= high)
141
- cmp = cidr_gt_lt(cidr,list[index])
142
- if ( cmp == -1 )
143
- high = index - 1
144
-
145
- elsif ( cmp == 1 )
146
- if (cidr_compare(cidr,list[index]) == -1)
147
- match = list[index]
148
- break
149
- end
150
- low = index + 1
151
-
152
- else
153
- match = index
154
- break
155
- end
156
- index = low + ( (high-low)/2 )
157
- end
158
- return(match)
159
- end
160
- module_function :cidr_find_in_list
161
-
162
- #==============================================================================#
163
- # cidr_make_subnets_from_base_and_ip_count()
164
- #==============================================================================#
165
-
166
- # Make CIDR addresses from a base addr and an number of ip's to encapsulate.
167
- #
168
- #===Arguments:
169
- # * cidr
170
- # * base ip as integer
171
- # * number of ip's required
172
- #
173
- #===Returns:
174
- # * array of NetAddr::CIDR objects
175
- #
176
- def cidr_make_subnets_from_base_and_ip_count(cidr,base_addr,ip_count)
177
- list = []
178
- until (ip_count == 0)
179
- mask = cidr.all_f
180
- multiplier = 0
181
- bitstep = 0
182
- last_addr = base_addr
183
- done = false
184
- until (done == true)
185
- if (bitstep < ip_count && (base_addr & mask == last_addr & mask) )
186
- multiplier += 1
187
- elsif (bitstep > ip_count || (base_addr & mask != last_addr & mask) )
188
- multiplier -= 1
189
- done = true
190
- else
191
- done = true
192
- end
193
- bitstep = 2**multiplier
194
- mask = cidr.all_f << multiplier & cidr.all_f
195
- last_addr = base_addr + bitstep - 1
196
- end
197
-
198
- list.push(NetAddr.cidr_build(cidr.version,base_addr,mask))
199
- ip_count -= bitstep
200
- base_addr += bitstep
201
- end
202
-
203
- return(list)
204
- end
205
- module_function :cidr_make_subnets_from_base_and_ip_count
206
-
207
- #==============================================================================#
208
- # cidr_sort()
209
- #==============================================================================#
210
-
211
- # given a list of NetAddr::CIDRs, return them as a sorted list
212
- #
213
- def cidr_sort(list, desc=false)
214
- # uses simple quicksort algorithm
215
- sorted_list = []
216
- if (list.length < 1)
217
- sorted_list = list
218
- else
219
- less_list = []
220
- greater_list = []
221
- equal_list = []
222
- pivot = list[rand(list.length)]
223
- if (desc)
224
- list.each do |x|
225
- if ( pivot.to_i(:network) < x.to_i(:network) )
226
- less_list.push(x)
227
- elsif ( pivot.to_i(:network) > x.to_i(:network) )
228
- greater_list.push(x)
229
- else
230
- if ( pivot.to_i(:netmask) < x.to_i(:netmask) )
231
- greater_list.push(x)
232
- elsif ( pivot.to_i(:netmask) > x.to_i(:netmask) )
233
- less_list.push(x)
234
- else
235
- equal_list.push(x)
236
- end
237
- end
238
- end
239
- else
240
- list.each do |x|
241
- gt_lt = cidr_gt_lt(pivot,x)
242
- if (gt_lt == 1)
243
- less_list.push(x)
244
- elsif (gt_lt == -1)
245
- greater_list.push(x)
246
- else
247
- equal_list.push(x)
248
- end
249
- end
250
- end
251
-
252
- sorted_list.concat( cidr_sort(less_list, desc) )
253
- sorted_list.concat(equal_list)
254
- sorted_list.concat( cidr_sort(greater_list, desc) )
255
- end
256
-
257
- return(sorted_list)
258
- end
259
- module_function :cidr_sort
260
-
261
- #==============================================================================#
262
- # cidr_summarize()
263
- #==============================================================================#
264
-
265
- # given a list of NetAddr::CIDRs (of the same version) summarize them
266
- #
267
- # return a hash, with the key = summary address and val = array of original cidrs
268
- #
269
- def cidr_summarize(subnet_list)
270
- all_f = subnet_list[0].all_f
271
- version = subnet_list[0].version
272
- subnet_list = cidr_sort(subnet_list)
273
-
274
- # continue summarization attempts until sorted_list stops getting shorter
275
- sorted_list = subnet_list.dup
276
- sorted_list_len = sorted_list.length
277
- while (1)
278
- summarized_list = []
279
- until (sorted_list.length == 0)
280
- cidr = sorted_list.shift
281
- network, netmask = cidr.to_i(:network), cidr.to_i(:netmask)
282
- supermask = (netmask << 1) & all_f
283
- supernet = supermask & network
284
-
285
- if (network == supernet && sorted_list.length > 0)
286
- # network is lower half of supernet, so see if we have the upper half
287
- bitstep = (all_f + 1) - netmask
288
- expected = network + bitstep
289
- next_cidr = sorted_list.shift
290
- next_network, next_netmask = next_cidr.to_i(:network), next_cidr.to_i(:netmask)
291
-
292
- if ( (next_network == expected) && (next_netmask == netmask) )
293
- # we do indeed have the upper half. store new supernet.
294
- summarized_list.push( cidr_build(version,supernet,supermask) )
295
- else
296
- # we do not have the upper half. put next_cidr back into sorted_list
297
- # and store only the original network
298
- sorted_list.unshift(next_cidr)
299
- summarized_list.push(cidr)
300
- end
301
- else
302
- # network is upper half of supernet, so save original network only
303
- summarized_list.push(cidr)
304
- end
305
-
306
- end
307
-
308
- sorted_list = summarized_list.dup
309
- break if (sorted_list.length == sorted_list_len)
310
- sorted_list_len = sorted_list.length
311
- end
312
-
313
- # clean up summarized_list
314
- unique_list = {}
315
- summarized_list.reverse.each do |supernet|
316
- next if ( unique_list.has_key?(supernet.desc) )
317
- # remove duplicates
318
- unique_list[supernet.desc] = supernet
319
-
320
- # remove any summary blocks that are children of other summary blocks
321
- index = 0
322
- until (index >= summarized_list.length)
323
- subnet = summarized_list[index]
324
- if (subnet && cidr_compare(supernet,subnet) == 1 )
325
- unique_list.delete(subnet.desc)
326
- end
327
- index += 1
328
- end
329
- end
330
- summarized_list = unique_list.values
331
-
332
- # map original blocks to their summaries
333
- summarized_list.each do |supernet|
334
- supernet.tag[:Subnets] = []
335
- index = 0
336
- until (index >= subnet_list.length)
337
- subnet = subnet_list[index]
338
- if (subnet && cidr_compare(supernet,subnet) == 1 )
339
- subnet_list[index] = nil
340
- supernet.tag[:Subnets].push(subnet)
341
- end
342
- index += 1
343
- end
344
- end
345
-
346
- return( NetAddr.cidr_sort(summarized_list) )
347
- end
348
- module_function :cidr_summarize
349
-
350
- #==============================================================================#
351
- # cidr_supernets()
352
- #==============================================================================#
353
-
354
- # given a list of NetAddr::CIDRs (of the same version), return only the 'top level' blocks (i.e. blocks not
355
- # contained by other blocks
356
-
357
- def cidr_supernets(subnet_list)
358
- summary_list = []
359
- subnet_list = netmask_sort(subnet_list)
360
- subnet_list.each do |child|
361
- is_parent = true
362
- summary_list.each do |parent|
363
- if (NetAddr.cidr_compare(parent,child) == 1)
364
- is_parent = false
365
- parent.tag[:Subnets].push(child)
366
- end
367
- end
368
-
369
- if (is_parent)
370
- child.tag[:Subnets] = []
371
- summary_list.push(child)
372
- end
373
- end
374
-
375
- return(summary_list)
376
- end
377
- module_function :cidr_supernets
378
-
379
- #==============================================================================#
380
- # netmask_sort()
381
- #==============================================================================#
382
-
383
- # given a list of NetAddr::CIDRs, return them as a sorted (by netmask) list
384
- #
385
- def netmask_sort(list, desc=false)
386
- # uses simple quicksort algorithm
387
- sorted_list = []
388
- if (list.length < 1)
389
- sorted_list = list
390
- else
391
- less_list = []
392
- greater_list = []
393
- equal_list = []
394
- pivot = list[rand(list.length)]
395
- if (desc)
396
- list.each do |x|
397
- if ( pivot.to_i(:netmask) < x.to_i(:netmask) )
398
- less_list.push(x)
399
- elsif ( pivot.to_i(:netmask) > x.to_i(:netmask) )
400
- greater_list.push(x)
401
- else
402
- if ( pivot.to_i(:network) < x.to_i(:network) )
403
- greater_list.push(x)
404
- elsif ( pivot.to_i(:network) > x.to_i(:network) )
405
- less_list.push(x)
406
- else
407
- equal_list.push(x)
408
- end
409
- end
410
- end
411
- else
412
- list.each do |x|
413
- if ( pivot.to_i(:netmask) < x.to_i(:netmask) )
414
- greater_list.push(x)
415
- elsif ( pivot.to_i(:netmask) > x.to_i(:netmask) )
416
- less_list.push(x)
417
- else
418
- if ( pivot.to_i(:network) < x.to_i(:network) )
419
- greater_list.push(x)
420
- elsif ( pivot.to_i(:network) > x.to_i(:network) )
421
- less_list.push(x)
422
- else
423
- equal_list.push(x)
424
- end
425
- end
426
- end
427
- end
428
-
429
- sorted_list.concat( netmask_sort(less_list, desc) )
430
- sorted_list.concat(equal_list)
431
- sorted_list.concat( netmask_sort(greater_list, desc) )
432
- end
433
-
434
- return(sorted_list)
435
- end
436
- module_function :netmask_sort
437
-
438
- end # module NetAddr
439
-
440
- __END__