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

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)



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/ip/address.rb', line 140

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
    puts octets
    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

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”



188
189
190
# File 'lib/ip/address.rb', line 188

def long_address
  return format_address
end

#octet_as_hex(index) ⇒ Object

returns an octet in its hexidecimal representation.



176
177
178
# File 'lib/ip/address.rb', line 176

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

#packObject

Returns a 128-bit integer representing the address.



242
243
244
# File 'lib/ip/address.rb', line 242

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::”



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/ip/address.rb', line 205

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