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, #divide_by_hosts, #divide_by_subnets, #eql?, #freeze, from_cpal, #hash, #initialize, #inspect, #is_in?, #mask, #mask!, #netmask, #network, #offset, #offset?, orig_new, #proto, #reset_pfxlen!, #size, #split, #succ, #succ!, #to_a, #to_addrlen, #to_ah, #to_b, #to_cpal, #to_cphl, #to_hex, #to_i, #to_irange, #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 ++



360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
# File 'lib/ip/base.rb', line 360

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)


438
439
440
# File 'lib/ip/base.rb', line 438

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

#ipv4_mapped?Boolean

Returns:

  • (Boolean)


434
435
436
# File 'lib/ip/base.rb', line 434

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

#nativeObject

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



443
444
445
446
# File 'lib/ip/base.rb', line 443

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



399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
# File 'lib/ip/base.rb', line 399

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

#to_addr_fullObject

Return just the address in non-compact form, required for reverse IP.



418
419
420
421
422
423
424
425
426
427
428
# File 'lib/ip/base.rb', line 418

def to_addr_full
  if ipv4_compat?
    "::#{native.to_addr}"
  elsif ipv4_mapped?
    "::ffff:#{native.to_addr}"
  elsif @addr.zero?
    "::"
  else
    return to_hex.scan(/..../).join(':')
  end
end

#to_arpaObject

return the arpa version of the address for reverse DNS: en.wikipedia.org/wiki/Reverse_DNS_lookup



430
431
432
# File 'lib/ip/base.rb', line 430

def to_arpa
  return self.to_addr_full.reverse.gsub(':','').split(//).join('.') + ".ip6.arpa"
end