netaddr 1.5.1 → 2.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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__