netaddr 1.5.3 → 2.0.1

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