Class: Ronin::Support::Network::IPRange::Glob

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/ronin/support/network/ip_range/glob.rb

Overview

Represents an IP-glob range.

Examples

ip_range = IPRange::Glob.new('10.0.1-3.*/24')
ip_range.each { |ip| puts ip }
# 10.0.1.0
# 10.0.1.1
# ...
# 10.0.1.254
# 10.0.1.255
# ...
# 10.0.2.0
# 10.0.2.1
# ...
# 10.0.2.254
# 10.0.2.255
# ...
# 10.0.3.0
# 10.0.3.1
# ...
# 10.0.3.254
# 10.0.3.255

Since:

  • 1.0.0

Constant Summary collapse

IPV4_REGEX =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Regular expression that matches IPv4-glob ranges.

Since:

  • 1.1.0

/\A#{ipv4_addr}\z/
IPV6_REGEX =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Regular expression that matches IPv6-glob ranges.

Since:

  • 1.1.0

/\A(?:
  (?:#{ipv6_octet_list}:){6}#{ipv4_addr}|
  (?:#{ipv6_octet_list}:){5}#{ipv6_octet_list}:#{ipv4_addr}|
  (?:#{ipv6_octet_list}:){5}:#{ipv6_octet_list}:#{ipv4_addr}|
  (?:#{ipv6_octet_list}:){1,1}(?::#{ipv6_octet_list}){1,4}:#{ipv4_addr}|
  (?:#{ipv6_octet_list}:){1,2}(?::#{ipv6_octet_list}){1,3}:#{ipv4_addr}|
  (?:#{ipv6_octet_list}:){1,3}(?::#{ipv6_octet_list}){1,2}:#{ipv4_addr}|
  (?:#{ipv6_octet_list}:){1,4}(?::#{ipv6_octet_list}){1,1}:#{ipv4_addr}|
  :(?::#{ipv6_octet_list}){1,5}:#{ipv4_addr}|
  (?:(?:#{ipv6_octet_list}:){1,5}|:):#{ipv4_addr}|
  (?:#{ipv6_octet_list}:){1,1}(?::#{ipv6_octet_list}){1,6}|
  (?:#{ipv6_octet_list}:){1,2}(?::#{ipv6_octet_list}){1,5}|
  (?:#{ipv6_octet_list}:){1,3}(?::#{ipv6_octet_list}){1,4}|
  (?:#{ipv6_octet_list}:){1,4}(?::#{ipv6_octet_list}){1,3}|
  (?:#{ipv6_octet_list}:){1,5}(?::#{ipv6_octet_list}){1,2}|
  (?:#{ipv6_octet_list}:){1,6}(?::#{ipv6_octet_list}){1,1}|
  #{ipv6_octet_list}(?::#{ipv6_octet_list}){7}|
  :(?::#{ipv6_octet_list}){1,7}|
  (?:(?:#{ipv6_octet_list}:){1,7}|:):
)\z/x
REGEX =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Regular expression to match IP-glob ranges.

Since:

  • 1.1.0

/#{IPV4_REGEX}|#{IPV6_REGEX}/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Enumerable

#map_hash

Constructor Details

#initialize(string) ⇒ Glob

Initializes and parses the IP-glob range.

Parameters:

  • string (String)

    The IP-glob string to parse.

Raises:

  • (ArgumentError)

    The IP-glob string was neither a valid IPv4 or IPv6 glob address.

Since:

  • 1.0.0



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/ronin/support/network/ip_range/glob.rb', line 121

def initialize(string)
  @string = string

  case string
  when IPV4_REGEX
    @version   = 4
    @base      = 10
    @formatter = method(:format_ipv4_address)

    separator   = '.'
    octet_range = (0..255)
  when IPV6_REGEX
    @version   = 6
    @base      = 16
    @formatter = method(:format_ipv6_address)

    separator   = ':'
    octet_range = (0..0xffff)
  else
    raise(ArgumentError,"invalid IP-glob range: #{string.inspect}")
  end

  @ranges = string.split(separator).map do |segment|
    if    segment == '*'        then octet_range
    elsif segment.include?(',') then parse_list(segment)
    elsif segment.include?('-') then parse_range(segment)
    else                             [segment]
    end
  end
end

Instance Attribute Details

#stringString (readonly)

The IP glob string.

Returns:

Since:

  • 1.0.0



110
111
112
# File 'lib/ronin/support/network/ip_range/glob.rb', line 110

def string
  @string
end

Class Method Details

.each(string) {|ip| ... } ⇒ self

Enumerates over the IP-glob range.

Examples:

Enumerate through a IPv4 glob range:

IPRange::Glob.each('10.0.1-3.*') { |ip| puts ip }
# 10.0.1.0
# 10.0.1.1
# ...
# 10.0.1.254
# 10.0.1.255
# ...
# 10.0.2.0
# 10.0.2.1
# ...
# 10.0.2.254
# 10.0.2.255
# ...
# 10.0.3.0
# 10.0.3.1
# ...
# 10.0.3.254
# 10.0.3.255

Enumerate through a globbed IPv6 range:

IPRange::Glob.each('::ff::02-0a::c3') { |ip| puts ip }

Parameters:

  • string (String)

    The IP-glob string to parse and enumerate over.

Yields:

  • (ip)

    The block which will be passed each IP address contained within the IP address range.

Yield Parameters:

  • ip (String)

    An IP address within the IP address range.

Returns:

  • (self)

Since:

  • 1.0.0



205
206
207
# File 'lib/ronin/support/network/ip_range/glob.rb', line 205

def self.each(string,&block)
  new(string).each(&block)
end

.parse(string) ⇒ Glob

Alias for new.

Parameters:

  • string (String)

    The IP-glob string to parse.

Returns:

  • (Glob)

    The parsed IP-glob range.

See Also:

Since:

  • 1.0.0



163
164
165
# File 'lib/ronin/support/network/ip_range/glob.rb', line 163

def self.parse(string)
  new(string)
end

Instance Method Details

#==(other) ⇒ Boolean

Compares the IP glob range to another IP range.

Parameters:

  • other (Object)

    The other IP range.

Returns:

  • (Boolean)

Since:

  • 1.1.0



252
253
254
# File 'lib/ronin/support/network/ip_range/glob.rb', line 252

def ==(other)
  other.kind_of?(self.class) && @string == other.string
end

#===(other) ⇒ Boolean

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

Parameters:

Returns:

  • (Boolean)

Since:

  • 1.1.0



266
267
268
269
270
271
272
273
# File 'lib/ronin/support/network/ip_range/glob.rb', line 266

def ===(other)
  case other
  when Enumerable
    other.all? { |ip| include?(ip) }
  else
    false
  end
end

#each {|ip| ... } ⇒ self

Enumerates over the IP-glob range.

Examples:

Enumerate through a IPv4 glob range:

ip_range = IPRange::Glob.new('10.0.1-3.*')
ip_range.each { |ip| puts ip }
# 10.0.1.0
# 10.0.1.1
# ...
# 10.0.1.254
# 10.0.1.255
# ...
# 10.0.2.0
# 10.0.2.1
# ...
# 10.0.2.254
# 10.0.2.255
# ...
# 10.0.3.0
# 10.0.3.1
# ...
# 10.0.3.254
# 10.0.3.255

Enumerate through a globbed IPv6 range:

ip_range = IPRange::Glob.new('::ff::02-0a::c3')
ip_range.each { |ip| puts ip }

Yields:

  • (ip)

    The block which will be passed each IP address contained within the IP address range.

Yield Parameters:

  • ip (String)

    An IP address within the IP address range.

Returns:

  • (self)

Since:

  • 1.0.0



312
313
314
315
316
317
318
319
320
321
# File 'lib/ronin/support/network/ip_range/glob.rb', line 312

def each
  return enum_for(__method__) unless block_given?

  # cycle through the address ranges
  @ranges.comprehension do |address|
    yield @formatter.call(address)
  end

  return self
end

#firstString

The first address in the IP glob range.

Returns:

  • (String)

    The first IP address in the IP glob range.

Since:

  • 1.1.0



331
332
333
# File 'lib/ronin/support/network/ip_range/glob.rb', line 331

def first
  @formatter.call(@ranges.map(&:first))
end

#include?(ip) ⇒ Boolean

Determines whether the IP address exists within the IP range.

Parameters:

Returns:

  • (Boolean)

    Indicates whether the IP address exists within the IP range.

Since:

  • 1.1.0



238
239
240
# File 'lib/ronin/support/network/ip_range/glob.rb', line 238

def include?(ip)
  super(ip.to_s)
end

#inspectString

Inspects the IP-glob range.

Returns:

Since:

  • 1.0.0



374
375
376
# File 'lib/ronin/support/network/ip_range/glob.rb', line 374

def inspect
  "#<#{self.class}: #{@string}>"
end

#ipv4?Boolean

Determines if the IP-glob range is IPv4.

Returns:

  • (Boolean)

Since:

  • 1.0.0



214
215
216
# File 'lib/ronin/support/network/ip_range/glob.rb', line 214

def ipv4?
  @version == 4
end

#ipv6?Boolean

Determines if the IP-glob range is IPv6.

Returns:

  • (Boolean)

Since:

  • 1.0.0



223
224
225
# File 'lib/ronin/support/network/ip_range/glob.rb', line 223

def ipv6?
  @version == 6
end

#lastString

The last address in the IP glob range.

Returns:

  • (String)

    The last IP address in the IP glob range.

Since:

  • 1.1.0



343
344
345
# File 'lib/ronin/support/network/ip_range/glob.rb', line 343

def last
  @formatter.call(@ranges.map(&:last))
end

#sizeInteger

Calculates the size of the IP glob range.

Returns:

Since:

  • 1.1.0



354
355
356
357
358
# File 'lib/ronin/support/network/ip_range/glob.rb', line 354

def size
  @ranges.reduce(1) do |total,parts|
    total * parts.size
  end
end

#to_sString

Converts the IP-glob range back into a String.

Returns:

Since:

  • 1.0.0



365
366
367
# File 'lib/ronin/support/network/ip_range/glob.rb', line 365

def to_s
  @string
end