Skip to content

Commit

Permalink
Added regexs for matching IP-glob ranges (ex: 1.1-10.1,2,4.*) (closes
Browse files Browse the repository at this point in the history
#473).

* Added `Network::IPRange::Glob::IPV4_REGEX`.
* Added `Network::IPRange::Glob::IPV6_REGEX`.
* Raise an `ArgumentError` if `IPRange::Glob#initialize` is given an
  invalid IP-glob string.
  • Loading branch information
postmodern committed Feb 9, 2024
1 parent 85c8385 commit 70f2d1f
Show file tree
Hide file tree
Showing 2 changed files with 359 additions and 5 deletions.
57 changes: 52 additions & 5 deletions lib/ronin/support/network/ip_range/glob.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,48 @@ class Glob

include Enumerable

ipv4_octet = /(?:\d{1,2}|1\d{2}|2[1-4]\d|25[0-5])/
ipv4_octet_range = /#{ipv4_octet}(?:-#{ipv4_octet})?/
ipv4_octet_list = /(?:#{ipv4_octet_range}(?:,#{ipv4_octet_range})*|\*)/
ipv4_addr = /#{ipv4_octet_list}\.#{ipv4_octet_list}\.#{ipv4_octet_list}\.#{ipv4_octet_list}/

# Regex that matches IPv4 globbed addresses.
#
# @api private
#
# @since 1.1.0
IPV4_REGEX = /\A#{ipv4_addr}\z/

ipv6_octet = /[0-9a-fA-F]{1,4}/
ipv6_octet_range = /#{ipv6_octet}(?:-#{ipv6_octet})?/
ipv6_octet_list = /(?:#{ipv6_octet_range}(?:,#{ipv6_octet_range})*|\*)/

# Regex that matches IPv6 globbed addresses.
#
# @api private
#
# @since 1.1.0
IPV6_REGEX = /\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

# The IP glob string.
#
# @return [String]
Expand All @@ -66,22 +108,27 @@ class Glob
# @param [String] string
# The IP-glob string to parse.
#
# @raise [ArgumentError]
# The IP-glob string was neither a valid IPv4 or IPv6 glob address.
#
def initialize(string)
@string = string

if @string.include?(':') # IPv6
case string
when IPV6_REGEX
@version = 6
@separator = ':'
@base = 16
@formatter = method(:format_ipv6_address)
else # IPv4
when IPV4_REGEX
@version = 4
@separator = '.'
@base = 10
@formatter = method(:format_ipv4_address)
else
raise(ArgumentError,"invalid IP-glob address: #{string.inspect}")
end

@ranges = @string.split(@separator).map do |segment|
@string = string
@ranges = string.split(@separator).map do |segment|
case segment
when '*' then (1..254)
when /,/ then parse_list(segment)
Expand Down
Loading

0 comments on commit 70f2d1f

Please sign in to comment.