class Ronin::Support::Network::IPRange::CIDR

Represents CIDR notation IP ranges.

## Examples

cidr = Network::IP::CIDR.new('10.0.0.1/24')
cidr.each { |ip puts }
# 10.0.0.0
# 10.0.0.1
# ...
# 10.0.0.254
# 10.0.0.255

@api public

@since 1.0.0

Constants

IPV4_REGEX

Regular expression that matches IPv4 CIDR ranges.

@api private

@since 1.1.0

IPV6_REGEX

Regular expression that matches IPv6 CIDR ranges.

@api private

@since 1.1.0

MASKS

Socket families and IP address masks

REGEX

Regular expression to match IP-glob ranges.

@api private

@since 1.1.0

SIZES

Socket families and IP address sizes

Attributes

string[R]

The CIDR IP range string.

@return [String]

Public Class Methods

each(string,&block) click to toggle source

Enumerates over each IP address that is included in the addresses netmask. Supports both IPv4 and IPv6 addresses.

@param [String] string

The CIDR range string to parse and enumerate over.

@yield [ip]

The block which will be passed every IP address covered be the
netmask of the IPAddr object.

@yieldparam [String] ip

An IP address.

@example

IPRange::CIDR.each('10.0.0.1/24') { |ip| puts ip }
# 10.0.0.0
# 10.0.0.1
# ...
# 10.0.0.254
# 10.0.0.255
# File lib/ronin/support/network/ip_range/cidr.rb, line 211
def self.each(string,&block)
  new(string).each(&block)
end
new(string,family=Socket::AF_UNSPEC) click to toggle source

Initializes and parses the CIDR range.

@param [String] string

The CIDR range string to parse.

@param [Integer] family

The address family for the CIDR range. This is mainly for
backwards compatibility with `IPAddr#initialize`.

@raise [ArgumentError]

The CIDR range string was not a valid IPv4 or IPv6 CIDR range.
Calls superclass method
# File lib/ronin/support/network/ip_range/cidr.rb, line 107
def initialize(string,family=Socket::AF_UNSPEC)
  unless (string =~ IPV4_REGEX || string =~ IPV6_REGEX)
    raise(ArgumentError,"invalid CIDR range: #{string.inspect}")
  end

  super(string,family)

  @string = string
end
parse(string) click to toggle source

Alias for {#initialize new}.

@param [String] string

The CIDR range string to parse.

@return [CIDR]

The parsed CIDR range.

@see initialize

# File lib/ronin/support/network/ip_range/cidr.rb, line 130
def self.parse(string)
  new(string)
end
range(first,last) click to toggle source

Calcualtes the CIDR range between two IP addresses.

@param [String, IPAddr] first

The first IP address in the CIDR range.

@param [String, IPAddr] last

The last IP Address in the CIDR range.

@return [CIDR]

The CIDR range between the two IP addresses.

@example

IPRange::CIDR.range("1.1.1.1","1.1.1.255")
# => #<Ronin::Support::Network::IPRange::CIDR: 1.1.1.1/24>
# File lib/ronin/support/network/ip_range/cidr.rb, line 162
def self.range(first,last)
  first_ip = case first
             when IPAddr then first
             else             IPAddr.new(first)
             end

  last_ip = case last
            when IPAddr then last
            else             IPAddr.new(last)
            end

  unless (first_ip.family == last_ip.family)
    raise(ArgumentError,"must specify two IPv4 or IPv6 addresses: #{first.inspect} #{last.inspect}")
  end

  num_bits  = SIZES.fetch(first_ip.family)
  diff_bits = first_ip.to_i ^ last_ip.to_i

  if diff_bits > 0
    prefix_length = num_bits - Math.log2(diff_bits).ceil

    return new("#{first_ip}/#{prefix_length}")
  else
    return new(first_ip.to_s)
  end
end

Public Instance Methods

==(other) click to toggle source

Compares the CIDR range to another IP range.

@param [Object] other

The other IP range.

@return [Boolean]

@since 1.1.0

# File lib/ronin/support/network/ip_range/cidr.rb, line 247
def ==(other)
  other.kind_of?(self.class) &&
    family == other.family &&
    to_i   == other.to_i
end
===(other) click to toggle source

Determines if the given IP range is a sub-set of the IP CIDR range.

@param [CIDR, Glob, Enumerable<String>] other

The other IP range.

@return [Boolean]

@since 1.1.0

# File lib/ronin/support/network/ip_range/cidr.rb, line 263
def ===(other)
  case other
  when CIDR
    include?(other.first) && include?(other.last)
  when Enumerable
    other.all? { |ip| include?(ip) }
  else
    false
  end
end
each() { |_to_string(addr | i)| ... } click to toggle source

Iterates over each IP address that is included in the addresses netmask. Supports both IPv4 and IPv6 addresses.

@yield [ip]

The block which will be passed every IP address covered be the
netmask of the IPAddr object.

@yieldparam [String] ip

An IP address.

@return [self]

@example

cidr = IPAddr.new('10.1.1.1/24')
cidr.each { |ip| puts ip }
# 10.0.0.0
# 10.0.0.1
# ...
# 10.0.0.254
# 10.0.0.255
# File lib/ronin/support/network/ip_range/cidr.rb, line 296
def each
  return enum_for(__method__) unless block_given?

  family_mask = MASKS[@family]

  (0..((~@mask_addr) & family_mask)).each do |i|
    yield _to_string(@addr | i)
  end

  return self
end
first() click to toggle source

The first IP address of the CIDR Range.

@return [String]

# File lib/ronin/support/network/ip_range/cidr.rb, line 313
def first
  _to_string(@addr)
end
include?(ip) click to toggle source

Determines if the given IP belongs to the IP CIDR range.

@param [IP, IPAddr, String] ip

The IP to test.

@return [Boolean]

Specifies whether the IP is or is not within the IP CIDR range.

@since 1.1.0

# File lib/ronin/support/network/ip_range/cidr.rb, line 226
def include?(ip)
  ip = IPAddr.new(ip) unless ip.kind_of?(IPAddr)

  family_mask = MASKS[@family]
  start_addr  = @addr
  end_addr    = @addr | (~@mask_addr & family_mask)
  ip_addr     = ip.to_i

  return (ip_addr >= start_addr) && (ip_addr <= end_addr)
end
inspect() click to toggle source

Inspects the CIDR range.

@return [String]

# File lib/ronin/support/network/ip_range/cidr.rb, line 351
def inspect
  "#<#{self.class}: #{@string}>"
end
last() click to toggle source

The last IP address of the CIDR range.

@return [String]

# File lib/ronin/support/network/ip_range/cidr.rb, line 322
def last
  _to_string(@addr | ~@mask_addr)
end
size() click to toggle source

Calculates the size of the CIDR range.

@return [Integer]

@since 1.1.0

# File lib/ronin/support/network/ip_range/cidr.rb, line 333
def size
  2**(SIZES.fetch(family) - prefix)
end
to_s() click to toggle source

Converts the CIDR range back into a String.

@return [String]

# File lib/ronin/support/network/ip_range/cidr.rb, line 342
def to_s
  @string
end