Class: IPAddrRangeSet
- Inherits:
-
Object
- Object
- IPAddrRangeSet
- Defined in:
- lib/ipaddr_range_set.rb,
lib/ipaddr_range_set.rb
Constant Summary collapse
- ArgErrorClass =
In ruby 2.0, they introduced IPAddr::InvalidAddressError, before that it was just ArgumentError. Let’s throw it if we’ve got it to be consistent.
(defined? IPAddr::InvalidAddressError) ? IPAddr::InvalidAddressError : ArgumentError
- IPv4Local =
Constant ranges for local/non-routable/private addresses
IPAddrRangeSet.new("10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16")
- IPv4Loopback =
who knew it’s not just 127.0.0.1? Check the spec, it’s this:
IPAddrRangeSet.new("127.0.0.0/8")
- IPv6Local =
IPAddrRangeSet.new("fc00::/7")
- IPv6Loopback =
IPAddrRangeSet.new("::1")
- LocalAddresses =
IPv4Local + IPv4Loopback + IPv6Local + IPv6Loopback
Instance Method Summary collapse
-
#add(*new_segments) ⇒ Object
Returns a NEW IPAddrRangeSet composed of union of receiver, and additional segments(s) given as arguments.
-
#include?(ip_addr) ⇒ Boolean
(also: #cover?, #===)
Does the range set include the argument? Can pass in IPAddr or string IP addr (that will be used as arg to IPAddr.new).
-
#initialize(*segments_list) ⇒ IPAddrRangeSet
constructor
Zero or more segment arguments, which can be input in a variety of of formats.
-
#union(other_set) ⇒ Object
(also: #+)
Returns a NEW IPAddrRangeSet composed of union of segments in receiver and argument.
Constructor Details
#initialize(*segments_list) ⇒ IPAddrRangeSet
Zero or more segment arguments, which can be input in a variety of of formats. range = IPAddrRangeSet.new(
'220.1.10.3', # a single IPv4 as a string
'2001:db8::10', # a single IPv6 as a string
'8.0.0.0/24', # IPv4 as CIDR, works for IPv6 CIDR too
'8.*.*.*', # informal splat notation, only for IPv4
'8.8.0.0'..'8.8.2.255', # arbitrary range, works for IPv6 too.
IPAddr.new(whatever), # arbitrary existing IPAddr object
(ip_addr..ip_addr), # range of arbitrary IPAddr objects.
IPAddrRangeSet::LocalAddresses # An existing IPAddrRangeSet
)
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/ipaddr_range_set.rb', line 24 def initialize(*segments_list) segments_list.each do |segment| if IPAddrRangeSet === segment # just absorb em segments.concat segment.segments next end if IPAddr === segment segment.freeze segments << segment next end if Range === segment first = segment.first last = segment.last first = IPAddr.new(first) unless first.kind_of? IPAddr last = IPAddr.new(last) unless last.kind_of? IPAddr segments << Range.new(first, last, segment.exclude_end?).freeze next end segment = segment.to_str # special splat processing? eg '124.*.*.*' ipv4 only. # Convert to ordinary 'a.b.c.d/m' CIDR notation. if segment.include?('*') && segment =~ /(\d{1,3}|\*\.){3}\d{1,3}|\*/ octets = segment.split('.') if (octets.rindex {|o| o =~ /\d+/}) > octets.rindex("*") raise ArgErrorClass.new("Invalid splat range, all *s have to come before all concrete octets") end splats = 0 base = octets.collect do |o| if o == '*' splats += 1 '0' else o end end.join(".") prefix_size = 32 - (8 * splats) segments << IPAddr.new("#{base}/#{prefix_size}") next end segments << IPAddr.new(segment) end end |
Instance Method Details
#add(*new_segments) ⇒ Object
Returns a NEW IPAddrRangeSet composed of union of receiver, and additional segments(s) given as arguments. IPAddrRangeSet is immutable.
117 118 119 |
# File 'lib/ipaddr_range_set.rb', line 117 def add(*new_segments) return self + IPAddrRangeSet.new(*new_segments) end |
#include?(ip_addr) ⇒ Boolean Also known as: cover?, ===
Does the range set include the argument? Can pass in IPAddr or string IP addr (that will be used as arg to IPAddr.new)
Aliased as #=== (for case/when!) and cover?
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/ipaddr_range_set.rb', line 87 def include?(ip_addr) ip_addr = IPAddr.new(ip_addr) unless ip_addr.kind_of? IPAddr segments.each do |segment| # important to use cover? and not include? on Ranges, to avoid # terribly inefficient check. But if segment is an IPAddr, you want include? if segment.respond_to?(:cover?) return true if segment.cover? ip_addr else return true if segment.include? ip_addr end end return false end |
#union(other_set) ⇒ Object Also known as: +
Returns a NEW IPAddrRangeSet composed of union of segments in receiver and argument. Aliased as ‘+`
IPAddrRangeSets are immutable.
109 110 111 |
# File 'lib/ipaddr_range_set.rb', line 109 def union(other_set) self.class.new(self, other_set) end |