Class: NetAddr::EUI64

Inherits:
Object
  • Object
show all
Defined in:
lib/eui64.rb

Overview

EUI64 (Extended Unique Identifier 64-bit, or EUI-64) represents a 64-bit hardware address.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(i) ⇒ EUI64

Create an EUI64 from an Integer. Must be between 0 and 2**64-1. Throws ValidationError on error.



11
12
13
14
15
16
17
18
# File 'lib/eui64.rb', line 11

def initialize(i)
	if (!i.kind_of?(Integer))
		raise ValidationError, "Expected an Integer for 'i' but got a #{i.class}."
	elsif ( (i < 0) || (i > 2**64-1) )
		raise ValidationError, "#{i} is out of bounds for EUI64."
	end
	@addr = i
end

Instance Attribute Details

#addrObject (readonly)

addr is the Integer representation of this EUI



7
8
9
# File 'lib/eui64.rb', line 7

def addr
  @addr
end

Class Method Details

.parse(addr) ⇒ Object

Parse an EUI-64 string into an EUI64 type. This will successfully parse most of the typically used formats such as:

  • aa-bb-cc-dd-ee-ff-00-11

  • aa:bb:cc:dd:ee:ff:00:11

  • aabb.ccdd.eeff.0011

  • aabbccddeeff0011

Although, in truth, its not picky about the exact format as long as it contains exactly 16 hex characters with the optional delimiting characters ‘-’, ‘:’, or ‘.’.



30
31
32
33
34
35
36
37
38
# File 'lib/eui64.rb', line 30

def EUI64.parse(addr)
	addr = addr.strip.gsub(/[\-\:\.]/,"")
	if (addr.length != 16)
		raise ValidationError, "Must contain exactly 16 hex characters with optional delimiters."
	elsif (addr =~ /[^0-9a-fA-F\:]/)
		raise ValidationError, "#{addr} contains invalid characters."
	end
	return EUI64.new(addr.to_i(16))
end

Instance Method Details

#bytesObject

bytes returns a list containing each byte of the EUI64 as a String.



41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/eui64.rb', line 41

def bytes()
	return [
		(@addr >> 56 & 0xff).to_s(16).rjust(2, "0"),
		(@addr >> 48 & 0xff).to_s(16).rjust(2, "0"),
		(@addr >> 40 & 0xff).to_s(16).rjust(2, "0"),
		(@addr >> 32 & 0xff).to_s(16).rjust(2, "0"),
		(@addr >> 24 & 0xff).to_s(16).rjust(2, "0"),
		(@addr >> 16 & 0xff).to_s(16).rjust(2, "0"),
		(@addr >> 8 & 0xff).to_s(16).rjust(2, "0"),
		(@addr & 0xff).to_s(16).rjust(2, "0"),
		]
end

#to_ipv6(net) ⇒ Object

to_ipv6 generates an IPv6 address from this EUI64 address and the provided IPv6Net. Nil will be returned if net is not a /64.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/eui64.rb', line 56

def to_ipv6(net)
	if (!net.kind_of?(IPv6Net))
		raise ArgumentError, "Expected an IPv6Net object for 'net' but got a #{net.class}."
	end
	
	if (net.netmask.prefix_len != 64)
		return nil
	end
	
	# set u/l bit to 0
	hostId = @addr ^ 0x0200000000000000
	ipAddr = net.network.addr | hostId
	return IPv6.new(ipAddr)
end

#to_sObject



71
72
73
# File 'lib/eui64.rb', line 71

def to_s()
	return self.bytes.join("-")
end