Class: IP::Address::IPv6

Inherits:
IP::Address show all
Defined in:
lib/ip/address.rb

Instance Attribute Summary

Attributes inherited from IP::Address

#ip_address, #octets

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from IP::Address

#[]

Constructor Details

#initialize(ip_address) ⇒ IPv6

Construct a new IP::Address::IPv6 object.

It can be passed two different types for construction:

  • A string which contains a valid, RFC4291-compliant IPv6 address (all forms are supported, including the backwards-compatibility IPv4 methods)

  • A 128-bit integer which is a sum of all the octets, left-most octet being the highest 32-bit portion (see IP::Address::Util for help generating this value)



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/ip/address.rb', line 147

def initialize(ip_address)
  if ip_address.kind_of? Integer
    # unpack to generate a string, and parse that.
    # overwrites 'ip_address'
    # horribly inefficient, but general.
    
    raw = IP::Address::Util.raw_unpack(ip_address)
    
    ip_address = format_address(raw.reverse)
  end
  
  if ! ip_address.kind_of? String
    raise IP::AddressException.new("Fed IP address '#{ip_address}' is not String or Fixnum")
  end
  
  @ip_address = ip_address
  
  octets = parse_address(ip_address)
  
  if octets.length != 8
    raise IP::AddressException.new("IPv6 address '#{ip_address}' does not have 8 octets or a floating range specifier")
  end

  #
  # Now we check the contents of the address, to be sure we have
  # proper hexidecimal values
  #
  
  @octets = octets_atoi(octets)
end

Class Method Details

.parse(ip_address) ⇒ Object

parses an ip address and stores it as the current object.



182
183
184
# File 'lib/ip/address.rb', line 182

def IPv6.parse(ip_address)
  return IP::Address::IPv6.new(ip_address)
end

Instance Method Details

#long_addressObject

Returns an address with no floating range specifier.

Ex:

IP::Address::IPv6.new("DEAD::BEEF").long_address => "DEAD:0:0:0:0:0:0:BEEF"



202
203
204
# File 'lib/ip/address.rb', line 202

def long_address
  return format_address
end

#octet_as_hex(index) ⇒ Object

returns an octet in its hexidecimal representation.



190
191
192
# File 'lib/ip/address.rb', line 190

def octet_as_hex(index)
  return format_octet(self[index])
end

#packObject

Returns a 128-bit integer representing the address.



256
257
258
# File 'lib/ip/address.rb', line 256

def pack
  return IP::Address::Util.raw_pack(self.octets.dup)
end

#short_addressObject

Returns a shortened address using the

range specifier.

This will replace any sequential octets that are equal to '0' with '::'. It does this searching from right to left, looking for a sequence of them. Per specification, only one sequence can be replaced in this fashion. It will return a long address if it can't find something suitable.

Ex:

"DEAD:0:0:0:BEEF:0:0:0" => "DEAD:0:0:0:BEEF::"



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/ip/address.rb', line 219

def short_address
  octets = @octets.dup

  # short circuit: if less than 2 octets are equal to 0, don't
  # bother - return a long address.
  
  if octets.find_all { |x| x == 0 }.length < 2
    return format_address(octets)
  end

  filling = false
  
  left  = []
  right = []

  7.downto(0) do |x|
    if !filling and left.length == 0 and octets[x] == 0
      filling = true
    elsif filling
      if octets[x] != 0
        left.push(octets[x])
        filling = false
      end
    elsif left.length > 0
      left.push(octets[x])
    else
      right.push(octets[x])
    end
  end
  
  return format_address(left.reverse) + "::" + format_address(right.reverse)
  
end