Class: NetAddr::IPv6
- Inherits:
-
Object
- Object
- NetAddr::IPv6
- Defined in:
- lib/ipv6.rb
Overview
IPv6 represents a single IPv6 address.
Instance Attribute Summary collapse
-
#addr ⇒ Object
readonly
addr is the Integer representation of this IP address.
Class Method Summary collapse
-
.parse(ip) ⇒ Object
parse will create an IPv6 from its string representation (ie. “1::”).
Instance Method Summary collapse
-
#cmp(other) ⇒ Object
cmp compares equality with another IPv6.
-
#initialize(i) ⇒ IPv6
constructor
Create an IPv6 from an Integer.
-
#ipv4(pl = 96) ⇒ Object
ipv4 generates an IPv4 from an IPv6 address.
-
#long ⇒ Object
long returns the IPv6 as a string in long (uncompressed) format.
-
#next ⇒ Object
next returns the next consecutive IPv6 or nil if the address space is exceeded.
-
#prev ⇒ Object
prev returns the preceding IPv6 or nil if this is 0.0.0.0.
-
#to_net ⇒ Object
to_net returns the IPv6 as a IPv6Net.
-
#to_s ⇒ Object
to_s returns the IPv6 as a String in zero-compressed format (per rfc5952).
-
#version ⇒ Object
version returns “6” for IPv6.
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
#addr ⇒ Object (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
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 |
#ipv4(pl = 96) ⇒ Object
ipv4 generates an IPv4 from an IPv6 address. The IPv4 address is generated based on the mechanism described by RFC 6052. The argument pl (prefix length) should be one of: 32, 40, 48, 56, 64, or 96. Default is 96 unless one of the supported values is provided.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/ipv6.rb', line 45 def ipv4(pl=96) if (pl == 32) i = (@addr >> 64) # get bits 32-63 into position return IPv4.new(i & NetAddr::F32) elsif (pl == 40) i = (@addr >> 48) & 0xff # get the last 8 bits into position i2 = (@addr & 0xffffff0000000000000000) >> 56 # get first 24 bits into position return IPv4.new(i | i2) elsif (pl == 48) i = (@addr >> 40) & 0xffff # get the last 16 bits into position i2 = (@addr & 0xffff0000000000000000) >> 48 # get first 16 bits into position return IPv4.new(i | i2) elsif (pl == 56) i = (@addr >> 32) & 0xffffff # get the last 24 bits into position i2 = (@addr & 0xff0000000000000000) >> 40 # get first 8 bits into position return IPv4.new(i | i2) elsif (pl == 64) i = (@addr >> 24) # get the 32 bits into position return IPv4.new(i & NetAddr::F32) end return IPv4.new(@addr & NetAddr::F32) end |
#long ⇒ Object
long returns the IPv6 as a string in long (uncompressed) format
69 70 71 72 73 74 75 76 |
# File 'lib/ipv6.rb', line 69 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 |
#next ⇒ Object
next returns the next consecutive IPv6 or nil if the address space is exceeded
79 80 81 82 83 84 |
# File 'lib/ipv6.rb', line 79 def next() if (self.addr == NetAddr::F128) return nil end return IPv6.new(self.addr + 1) end |
#prev ⇒ Object
prev returns the preceding IPv6 or nil if this is 0.0.0.0
87 88 89 90 91 92 |
# File 'lib/ipv6.rb', line 87 def prev() if (self.addr == 0) return nil end return IPv6.new(self.addr - 1) end |
#to_net ⇒ Object
to_net returns the IPv6 as a IPv6Net
95 96 97 |
# File 'lib/ipv6.rb', line 95 def to_net() NetAddr::IPv6Net.new(self,nil) end |
#to_s ⇒ Object
to_s returns the IPv6 as a String in zero-compressed format (per rfc5952).
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/ipv6.rb', line 100 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 zero fields in a row. # per https://tools.ietf.org/html/rfc5952#section-4.2.2 we must not compress just a single 16-bit zero field. if (finalLen > 1) head = hexStr[0,finalStart].join(":") tailStart = finalStart + finalLen tail = hexStr[tailStart..7].join(":") return head + "::" + tail end return hexStr.join(":") end |
#version ⇒ Object
version returns “6” for IPv6
140 141 142 |
# File 'lib/ipv6.rb', line 140 def version() return 6 end |