Class: NetAddr::IPv6

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

Overview

IPv6 represents a single IPv6 address.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(i) ⇒ IPv6

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



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

def initialize(i)
	if (!i.kind_of?(Integer))
		raise ValidationError, "Expected an Integer for 'i' but got a #{i.class}."
	elsif ( (i < 0) || (i > NetAddr::F128) )
		raise ValidationError, "#{i} is out of bounds for IPv6."
	end
	@addr = i
end

Instance Attribute Details

#addrObject (readonly)

addr is the Integer representation of this IP address



6
7
8
# File 'lib/ipv6.rb', line 6

def addr
  @addr
end

Class Method Details

.parse(ip) ⇒ Object

parse will create an IPv6 from its string representation (ie. “1::”). Throws ValidationError on error.



21
22
23
24
25
# File 'lib/ipv6.rb', line 21

def IPv6.parse(ip)
	ip.strip!
	i = Util.parse_IPv6(ip)
	return IPv6.new(i)
end

Instance Method Details

#cmp(other) ⇒ Object

cmp compares equality with another IPv6. Return:

  • 1 if this IPv6 is numerically greater

  • 0 if the two are equal

  • -1 if this IPv6 is numerically less



31
32
33
34
35
36
37
38
39
40
41
# File 'lib/ipv6.rb', line 31

def cmp(other)
	if (!other.kind_of?(IPv6))
		raise ArgumentError, "Expected an IPv6 object for 'other' but got a #{other.class}."
	end
	if (self.addr > other.addr)
		return 1
	elsif (self.addr < other.addr)
		return -1
	end
	return 0
end

#longObject

long returns the IPv6 as a string in long (uncompressed) format



44
45
46
47
48
49
50
51
# File 'lib/ipv6.rb', line 44

def long()
	words = []
	7.downto(0) do |x|
		word = (@addr >> 16*x) & 0xffff 
		words.push( word.to_s(16).rjust(4, "0") )
	end
	return words.join(':')
end

#nextObject

next returns the next consecutive IPv6 or nil if the address space is exceeded



54
55
56
57
58
59
# File 'lib/ipv6.rb', line 54

def next()
	if (self.addr == NetAddr::F128)
		return nil
	end
	return IPv6.new(self.addr + 1)
end

#prevObject

prev returns the preceding IPv6 or nil if this is 0.0.0.0



62
63
64
65
66
67
# File 'lib/ipv6.rb', line 62

def prev()
	if (self.addr == 0)
		return nil
	end
	return IPv6.new(self.addr - 1)
end

#to_netObject

to_net returns the IPv6 as a IPv6Net



70
71
72
# File 'lib/ipv6.rb', line 70

def to_net()
	NetAddr::IPv6Net.new(self,nil)
end

#to_sObject

to_s returns the IPv6 as a String in zero-compressed format (per rfc5952).



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/ipv6.rb', line 75

def to_s()
	hexStr = ["","","","","","","",""]
	zeroStart, consec0, finalStart, finalLen = -1,0,-1,0
	8.times do |i|
		# capture 2-byte word
		shift = 112 - 16*i
		wd = (self.addr >> shift) & 0xffff
		hexStr[i] = wd.to_s(16)
		
		# capture count of consecutive zeros
		if (wd == 0)
			if (zeroStart == -1)
				zeroStart = i
			end
			consec0 += 1
		end
		
		# test for longest consecutive zeros when non-zero encountered or we're at the end
		if (wd != 0 || i == 7)
			if (consec0 > finalStart+finalLen-1)
				finalStart = zeroStart
				finalLen = consec0
			end
			zeroStart = -1
			consec0 = 0
		end
	end
	
	# compress if we've found a series of 0 words in a row
	if (finalStart != -1)
		head = hexStr[0,finalStart].join(":")
		tailStart = finalStart + finalLen 
		tail = hexStr[tailStart..7].join(":")
		return head + "::" + tail
	end
	return hexStr.join(":")
end