Class: IP::V6

Inherits:
IP
  • Object
show all
Defined in:
lib/ip/base.rb,
lib/ip/socket.rb

Constant Summary collapse

PROTO =
"v6".freeze
ADDR_BITS =
128
MASK =
(1 << ADDR_BITS) - 1
AF =
Socket::AF_INET6

Constants inherited from IP

PROTO_TO_CLASS

Instance Attribute Summary

Attributes inherited from IP

#ctx, #pfxlen

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from IP

#&, #+, #-, #<=>, #^, #af, #broadcast, #eql?, from_cpal, #hash, #initialize, #inspect, #mask, #mask!, #netmask, #network, #offset, #offset?, orig_new, #proto, #reset_pfxlen!, #size, #succ!, #to_a, #to_addrlen, #to_ah, #to_cpal, #to_cphl, #to_hex, #to_i, #to_range, #to_s, #to_sockaddr, #wildmask, #|, #~

Constructor Details

This class inherits a constructor from IP

Class Method Details

.parse(str) ⇒ Object

Parse a string; return an V6 instance if it’s a valid IPv6 address, nil otherwise – FIXME: allow larger variations of mapped addrs like 0:0:0:0:ffff:1.2.3.4 ++



287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/ip/base.rb', line 287

def self.parse(str)
  case str
  when /\A\[?::(ffff:)?(\d+\.\d+\.\d+\.\d+)\]?(?:\/(\d+))?(?:@(.*))?\z/i
    mapped = $1
    pfxlen = ($3 || 128).to_i
    ctx = $4
    return nil if pfxlen > 128
    v4 = (V4.parse($2) || return).to_i
    v4 |= 0xffff00000000 if mapped
    new(v4, pfxlen, ctx)
  when /\A\[?([0-9a-f:]+)\]?(?:\/(\d+))?(?:@(.*))?\z/i
    addr = $1
    pfxlen = ($2 || 128).to_i
    return nil if pfxlen > 128
    ctx = $3
    return nil if pfxlen > 128
    if addr =~ /\A(.*?)::(.*)\z/
      left, right = $1, $2
      l = left.split(':')
      r = right.split(':')
      rest = 8 - l.length - r.length
      return nil if rest < 0
    else
      l = addr.split(':')
      r = []
      rest = 0
      return nil if l.length != 8
    end
    out = ""
    l.each { |quad| return nil if quad.length>4; out << quad.rjust(4,"0") }
    rest.times { out << "0000" }
    r.each { |quad| return nil if quad.length>4; out << quad.rjust(4,"0") }
    new(out, pfxlen, ctx)
  else
    nil
  end
end

Instance Method Details

#ipv4_compat?Boolean

Returns:

  • (Boolean)


344
345
346
# File 'lib/ip/base.rb', line 344

def ipv4_compat?
  @addr > 1 && (@addr >> 32) == 0
end

#ipv4_mapped?Boolean

Returns:

  • (Boolean)


340
341
342
# File 'lib/ip/base.rb', line 340

def ipv4_mapped?
  (@addr >> 32) == 0xffff
end

#nativeObject

Convert an IPv6 mapped/compat address to a V4 native address



349
350
351
352
# File 'lib/ip/base.rb', line 349

def native
  return self unless (ipv4_mapped? || ipv4_compat?) && (@pfxlen >= 96)
  V4.new(@addr & V4::MASK, @pfxlen - 96, @ctx)
end

#to_addrObject

Return just the address part as a String in compact decimal form



326
327
328
329
330
331
332
333
334
335
336
337
338
# File 'lib/ip/base.rb', line 326

def to_addr
  if ipv4_compat?
    "::#{native.to_addr}"
  elsif ipv4_mapped?
    "::ffff:#{native.to_addr}"
  else
    res = to_hex.scan(/..../).join(':')
    res.gsub!(/\b0{1,3}/,'')
    res.gsub!(/(\A|:)(0:)+/,'::')
    res.gsub!(/::0\z/, '::')
    res
  end
end