netaddr 1.5.1 → 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,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__
data/lib/eui.rb DELETED
@@ -1,463 +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
- #=EUI - Extended Unique Identifier
10
- #
11
- #A class & series of methods for creating and manipulating Extended Unique Identifier
12
- #(EUI) addresses. Two types of address formats are supported EUI-48 and EUI-64. The
13
- #most common use for this class will be to manipulate MAC addresses (which are essentially
14
- #a type of EUI-48 address).
15
- #
16
- #EUI addresses are separated into two parts, the
17
- #Organizationally Unique Identifier (OUI) and the Extended Identifier (EI). The OUI
18
- #is assigned by the IEEE and is used to identify a particular hardware manufacturer.
19
- #The EI is assigned by the hardware manufacturer as a per device unique address.
20
- #
21
- #Probably the most useful feature of this class, and thus the reason it was created,
22
- #is to help automate certain address assignments within IP. For example, IPv6
23
- #Link Local addresses use MAC addresses for IP auto-assignment and multicast MAC addresses
24
- #are determined based on the multicast IP address.
25
- #
26
- class EUI
27
-
28
- private_class_method :new
29
-
30
- #==============================================================================#
31
- # initialize()
32
- #==============================================================================#
33
-
34
- #===Synopsis
35
- # This method performs absolutely no error checking, and is meant to be used only by
36
- # other internal methods for the sake of the speedier creation of EUI objects.
37
- # Please consider using #create unless you know what you are doing with 100% certainty.
38
- #
39
- # Example:
40
- # NetAddr::EUI48.new('aabbccddeeff')
41
- #
42
- #===Arguments:
43
- #* EUI as a String or Integer. Strings should contain no formatting characters.
44
- #
45
- def initialize(eui)
46
-
47
- if (eui.kind_of?(Integer))
48
- @eui_i = eui
49
- @eui = eui.to_s(16)
50
- if ( self.kind_of?(NetAddr::EUI48) )
51
- @eui = '0' * (12 - @eui.length) << @eui if (@eui.length < 12)
52
- else
53
- @eui = '0' * (16 - @eui.length) << @eui if (@eui.length < 16)
54
- end
55
-
56
- elsif(eui.kind_of?(String))
57
- @eui = eui
58
- @eui_i = eui.to_i(16)
59
- else
60
- raise ArgumentError, "Expected String or Integer, but #{eui.class} provided."
61
- end
62
-
63
- # set ei & oui
64
- if ( self.kind_of?(NetAddr::EUI48) )
65
- @ei = @eui.slice(6..11)
66
- else
67
- @ei = @eui.slice(6..15)
68
- end
69
-
70
- @oui = @eui.slice(0..5)
71
-
72
- end
73
-
74
- #==============================================================================#
75
- # create()
76
- #==============================================================================#
77
-
78
- #===Synopsis
79
- #Create a new EUI48 or EUI64 object.
80
- #
81
- # Example:
82
- # addr = NetAddr::EUI.create('aa-bb-cc-dd-ee-ff')
83
- # addr = NetAddr::EUI.create('aa:bb:cc:dd:ee:ff')
84
- # addr = NetAddr::EUI.create('aabb.ccdd.eeff')
85
- # addr = NetAddr::EUI.create('aa-bb-cc-dd-ee-ff-00-01')
86
- #
87
- #===Arguments
88
- #* eui = EUI as a String
89
- #
90
- #===Returns
91
- #* EUI48 or EUI64 object
92
- #
93
- def EUI.create(eui)
94
- if (!eui.kind_of? String)
95
- raise ArgumentError, "Expected String, but #{eui.class} provided."
96
- end
97
-
98
- # validate
99
- NetAddr.validate_eui(eui)
100
-
101
- # remove formatting characters
102
- eui.gsub!(/[\.\:\-]/, '')
103
-
104
- if (eui.length == 12)
105
- eui = NetAddr::EUI48.new(eui)
106
- else
107
- eui = NetAddr::EUI64.new(eui)
108
- end
109
-
110
- return(eui)
111
- end
112
-
113
- #==============================================================================#
114
- # address()
115
- #==============================================================================#
116
-
117
- #===Synopsis
118
- # Returns EUI address. The default address format is xxxx.xxxx.xxxx
119
- #
120
- # Example:
121
- # addr = NetAddr::EUI.create('aabb.ccdd.eeff')
122
- # addr.address(:Delimiter => '-') => "aa-bb-cc-dd-ee-ff"
123
- # addr.address(:Delimiter => ':') => "aa:bb:cc:dd:ee:ff"
124
- #
125
- #===Arguments:
126
- #* options = Hash with the following fields:
127
- # :Delimiter -- delimitation character. valid values are (- : .)
128
- #
129
- #===Returns:
130
- #* String
131
- #
132
- def address(options=nil)
133
- known_args = [:Delimiter]
134
- delimiter = '-'
135
-
136
- if (options)
137
- if (!options.kind_of? Hash)
138
- raise ArgumentError, "Expected Hash, but #{options.class} provided."
139
- end
140
- NetAddr.validate_args(options.keys,known_args)
141
-
142
- if (options.has_key?(:Delimiter))
143
- delimiter = options[:Delimiter]
144
- delimiter = '-' if (delimiter != ':' && delimiter != '.')
145
- end
146
- end
147
-
148
- if (delimiter == '-' || delimiter == ':')
149
- addr = octets.join(delimiter)
150
- elsif (delimiter == '.')
151
- toggle = 0
152
- octets.each do |x|
153
- if (!addr)
154
- addr = x
155
- toggle = 1
156
- elsif (toggle == 0)
157
- addr = addr << '.' << x
158
- toggle = 1
159
- else
160
- addr = addr << x
161
- toggle = 0
162
- end
163
- end
164
- end
165
-
166
- return(addr)
167
- end
168
-
169
- #==============================================================================#
170
- # ei()
171
- #==============================================================================#
172
-
173
- #===Synopsis
174
- #Returns Extended Identifier portion of an EUI address (the vendor assigned ID).
175
- #The default address format is xx-xx-xx
176
- #
177
- # Example:
178
- # addr = NetAddr::EUI.create('aabb.ccdd.eeff')
179
- # addr.ei(:Delimiter => '-') => "dd-ee-ff"
180
- #
181
- #===Arguments:
182
- #* options = Hash with the following fields:
183
- # :Delimiter -- delimitation character. valid values are (-, and :)
184
- #
185
- #===Returns:
186
- #* String
187
- #
188
- def ei(options=nil)
189
- known_args = [:Delimiter]
190
- delimiter = '-'
191
-
192
- if (options)
193
- if (!options.kind_of? Hash)
194
- raise ArgumentError, "Expected Hash, but #{options.class} provided."
195
- end
196
- NetAddr.validate_args(options.keys,known_args)
197
-
198
- if (options.has_key?(:Delimiter))
199
- if (options[:Delimiter] == ':')
200
- delimiter = options[:Delimiter]
201
- end
202
- end
203
- end
204
-
205
- if ( self.kind_of?(NetAddr::EUI48) )
206
- ei = octets[3..5].join(delimiter)
207
- else
208
- ei = octets[3..7].join(delimiter)
209
- end
210
-
211
- return(ei)
212
- end
213
-
214
- #==============================================================================#
215
- # link_local()
216
- #==============================================================================#
217
-
218
- #===Synopsis
219
- # Provide an IPv6 Link Local address based on the current EUI address.
220
- #
221
- # Example:
222
- # addr = NetAddr::EUI.create('aabb.ccdd.eeff')
223
- # addr.link_local() => "fe80:0000:0000:0000:aabb:ccff:fedd:eeff"
224
- #
225
- #===Arguments:
226
- #* options = Hash with the following fields:
227
- # :Short -- if true, return IPv6 addresses in short-hand notation
228
- # :Objectify -- if true, return CIDR objects
229
- #
230
- #===Returns:
231
- #* CIDR address String or an NetAddr::CIDR object
232
- #
233
- def link_local(options=nil)
234
- return( self.to_ipv6('fe80::/64', options) )
235
- end
236
-
237
- #==============================================================================#
238
- # oui()
239
- #==============================================================================#
240
-
241
- #===Synopsis
242
- #Returns Organizationally Unique Identifier portion of an EUI address (the vendor ID).
243
- #The default address format is xx-xx-xx.
244
- #
245
- # Example:
246
- # addr = NetAddr::EUI.create('aabb.ccdd.eeff')
247
- # addr.oui(:Delimiter => '-') => "aa-bb-cc"
248
- #
249
- #===Arguments:
250
- #* options = Hash with the following fields:
251
- # :Delimiter -- delimitation character. valid values are (-, and :)
252
- #
253
- #===Returns:
254
- #* String
255
- #
256
- def oui(options=nil)
257
- known_args = [:Delimiter]
258
- delimiter = '-'
259
-
260
- if (options)
261
- if (!options.kind_of? Hash)
262
- raise ArgumentError, "Expected Hash, but #{options.class} provided."
263
- end
264
- NetAddr.validate_args(options.keys,known_args)
265
-
266
- if (options.has_key?(:Delimiter))
267
- if (options[:Delimiter] == ':')
268
- delimiter = options[:Delimiter]
269
- end
270
- end
271
- end
272
- oui = octets[0..2].join(delimiter)
273
-
274
- return(oui)
275
- end
276
-
277
- #==============================================================================#
278
- # to_i()
279
- #==============================================================================#
280
-
281
- #===Synopsis
282
- #Returns the EUI as an Integer.
283
- #
284
- # Example:
285
- # addr = NetAddr::EUI.create('aabb.ccdd.eeff')
286
- # addr.to_i => 187723572702975
287
- #
288
- #===Arguments:
289
- #* none
290
- #
291
- #===Returns:
292
- #* Integer
293
- #
294
- def to_i()
295
- return(@eui_i)
296
- end
297
-
298
- #==============================================================================#
299
- # to_ipv6
300
- #==============================================================================#
301
-
302
- #===Synopsis
303
- # Given a valid IPv6 subnet, return an IPv6 address based on the current EUI.
304
- #
305
- # Example:
306
- # addr = NetAddr::EUI.create('aabb.ccdd.eeff')
307
- # addr.to_ipv6('3ffe::/64') => "3ffe:0000:0000:0000:a8bb:ccff:fedd:eeff"
308
- #
309
- #===Arguments:
310
- #* options = Hash with the following fields:
311
- # :Short -- if true, return IPv6 addresses in short-hand notation
312
- # :Objectify -- if true, return CIDR objects
313
- #
314
- #===Returns:
315
- #* IPv6 address String or an NetAddr::CIDRv6 object
316
- #
317
- def to_ipv6(cidr, options=nil)
318
- known_args = [:Short, :Objectify]
319
- objectify = false
320
- short = false
321
-
322
- if ( !cidr.kind_of?(NetAddr::CIDR) )
323
- begin
324
- cidr = NetAddr::CIDR.create(cidr)
325
- rescue Exception => error
326
- raise ArgumentError, "CIDR raised the following errors: #{error}"
327
- end
328
- elsif (cidr.kind_of?(NetAddr::CIDRv4) )
329
- raise ArgumentError, "Expected CIDRv6, but #{cidr.class} provided."
330
- end
331
-
332
- if (cidr.bits > 64)
333
- raise ValidationError, "Prefix length of provided CIDR must be /64 or less but was #{cidr.netmask}."
334
- end
335
-
336
- if (options)
337
- if (!options.kind_of? Hash)
338
- raise ArgumentError, "Expected Hash, but #{options.class} provided."
339
- end
340
- NetAddr.validate_args(options.keys,known_args)
341
-
342
- if (options.has_key?(:Objectify) && options[:Objectify] == true)
343
- objectify = true
344
- end
345
-
346
- if (options.has_key?(:Short) && options[:Short] == true)
347
- short = true
348
- end
349
- end
350
-
351
- # get integer equiv of addr. conver eui48 to eui64 if needed
352
- if ( self.kind_of?(NetAddr::EUI48) )
353
- eui_i = self.to_eui64.to_i
354
- else
355
- eui_i = self.to_i
356
- end
357
-
358
- # toggle u/l bit
359
- eui_i = eui_i ^ 0x0200000000000000
360
-
361
- # create ipv6 address
362
- ipv6 = cidr.to_i | eui_i
363
-
364
- if (!objectify)
365
- ipv6 = NetAddr.i_to_ip(ipv6, :Version => 6)
366
- ipv6 = NetAddr.shorten(ipv6) if (short)
367
- else
368
- ipv6 = NetAddr::CIDRv6.new(ipv6)
369
- end
370
-
371
- return(ipv6)
372
- end
373
-
374
- #==============================================================================#
375
- # to_s()
376
- #==============================================================================#
377
-
378
- #===Synopsis
379
- #Returns the EUI as an unformatted String.
380
- #
381
- # Example:
382
- # addr = NetAddr::EUI.create('aabb.ccdd.eeff')
383
- # addr.to_s => "aabbccddeeff"
384
- #
385
- #===Arguments:
386
- #* none
387
- #
388
- #===Returns:
389
- #* String
390
- #
391
- def to_s()
392
- return(@eui)
393
- end
394
-
395
- private
396
-
397
- #==============================================================================#
398
- # octets()
399
- #==============================================================================#
400
-
401
- #Returns array with each element representing a single octet of the eui.
402
- #
403
- def octets()
404
- return(@octets) if (@octets)
405
-
406
- @octets = []
407
- str = ''
408
- @eui.each_byte do |chr|
409
- str = str << chr
410
- if (str.length == 2)
411
- @octets.push(str)
412
- str = ''
413
- end
414
- end
415
-
416
- return(@octets)
417
- end
418
-
419
- end
420
-
421
-
422
-
423
- # EUI-48 Address - Inherits all methods from NetAddr::EUI.
424
- # Addresses of this class have a 24-bit OUI and a 24-bit EI.
425
- class EUI48 < EUI
426
-
427
- public_class_method :new
428
-
429
- #==============================================================================#
430
- # to_eui64()
431
- #==============================================================================#
432
-
433
- #===Synopsis
434
- #Return an EUI64 address based on the current EUI48 address.
435
- #
436
- # Example:
437
- # addr = NetAddr::EUI.create('aabb.ccdd.eeff')
438
- # addr.to_eui64 => NetAddr::EUI64
439
- #
440
- #===Arguments:
441
- #* none
442
- #
443
- #===Returns:
444
- #* NetAddr::EUI64 object
445
- #
446
- def to_eui64()
447
- eui = @oui + 'fffe' + @ei
448
- return( NetAddr::EUI64.new(eui.to_i(16)) )
449
- end
450
-
451
- end
452
-
453
-
454
-
455
- # EUI-64 Address - Inherits all methods from NetAddr::EUI.
456
- # Addresses of this class have a 24-bit OUI and a 40-bit EI.
457
- class EUI64 < EUI
458
- public_class_method :new
459
- end
460
-
461
-
462
- end # module NetAddr
463
- __END__