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)



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/ip/address.rb', line 161

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.



196
197
198
# File 'lib/ip/address.rb', line 196

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

Instance Method Details

#==(other) ⇒ Object

An IP Address is equal if the ip address match



277
278
279
280
281
282
283
284
285
286
# File 'lib/ip/address.rb', line 277

def ==(other)
  case other
    when String,Integer,Bignum
      self.long_address == self.class.new(other).long_address
    when self.class
      self.long_address == other.long_address
    else
      false
  end
end

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



216
217
218
# File 'lib/ip/address.rb', line 216

def long_address
  return format_address
end

#octet_as_hex(index) ⇒ Object

returns an octet in its hexidecimal representation.



204
205
206
# File 'lib/ip/address.rb', line 204

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

#packObject

Returns a 128-bit integer representing the address.



270
271
272
# File 'lib/ip/address.rb', line 270

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



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# File 'lib/ip/address.rb', line 233

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