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?, #freeze, from_cpal, #hash, #initialize, #inspect, #mask, #mask!, #netmask, #network, #offset, #offset?, orig_new, #proto, #reset_pfxlen!, #size, #succ, #succ!, #to_a, #to_addrlen, #to_ah, #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 ++



303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
# File 'lib/ip/base.rb', line 303

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)


364
365
366
# File 'lib/ip/base.rb', line 364

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

#ipv4_mapped?Boolean

Returns:

  • (Boolean)


360
361
362
# File 'lib/ip/base.rb', line 360

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

#nativeObject

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



369
370
371
372
# File 'lib/ip/base.rb', line 369

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



342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
# File 'lib/ip/base.rb', line 342

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