def remainder(addr, options=nil)
known_args = [:Objectify, :Short]
short = nil
objectify = nil
if (options)
raise ArgumentError, "Hash expected for argument 'options' but " +
"#{options.class} provided." if (!options.kind_of?(Hash) )
NetAddr.validate_args(options.keys,known_args)
if( options.has_key?(:Short) && options[:Short] == true )
short = true
end
if( options.has_key?(:Objectify) && options[:Objectify] == true )
objectify = true
end
end
if ( !addr.kind_of?(NetAddr::CIDR) )
begin
addr = NetAddr::CIDR.create(addr)
rescue Exception => error
raise ArgumentError, "Argument 'addr' raised the following " +
"errors: #{error}"
end
end
if ( addr.version != @version )
raise VersionError, "#{addr.desc(:Short => true)} is of a different " +
"IP version than #{self.desc(:Short => true)}."
end
if ( self.contains?(addr) != true )
raise BoundaryError, "#{addr.desc(:Short => true)} does not fit " +
"within the bounds of #{self.desc(:Short => true)}."
end
new_mask = self.bits + 1
lower_network = self.to_i(:network)
upper_network = self.to_i(:network) + 2**(@address_len - new_mask)
new_subnets = []
until(new_mask > addr.bits)
if (addr.to_i(:network) < upper_network)
match = lower_network
non_match = upper_network
else
match = upper_network
non_match = lower_network
end
if (!objectify)
non_match = NetAddr.ip_int_to_str(non_match, @version)
non_match = NetAddr.shorten(non_match) if (short && @version == 6)
new_subnets.unshift("#{non_match}/#{new_mask}")
else
new_subnets.unshift( NetAddr.cidr_build(@version, non_match, NetAddr.bits_to_mask(new_mask,version) ) )
end
new_mask = new_mask + 1
lower_network = match
upper_network = match + 2**(@address_len - new_mask)
end
return(new_subnets)
end