def allocate_rfc3531(netmask, options=nil)
short = false
objectify = false
strategy = :leftmost
raise ArgumentError, "Expected Integer for argument (netmask), but #{max.class} received." if ( !netmask.kind_of?(Integer) )
raise BoundaryError, "Netmask (#{netmask}) is invalid for a version #{self.version} address." if (netmask > @address_len)
raise BoundaryError, "Netmask (#{netmask}) cannot be less than #{self.bits}." if (netmask < self.bits)
known_args = [:Objectify, :Short, :Strategy]
if (options)
if (!options.kind_of? Hash)
raise ArgumentError, "Expected Hash, but #{options.class} provided."
end
NetAddr.validate_args(options.keys,known_args)
if( options.has_key?(:Objectify) && options[:Objectify] == true )
objectify = true
end
if( options.has_key?(:Short) && options[:Short] == true )
short = true
end
if( options.has_key?(:Strategy))
strategy = options[:Strategy]
raise ArgumentError, "Argument :Strategy must be either :leftmost or :centermost." if (strategy != :leftmost && strategy != :centermost)
end
end
subnet_bits = netmask - self.bits
net_lshift = @address_len - netmask
new_mask = NetAddr.bits_to_mask(netmask,self.version)
cidr_list = []
if (strategy == :leftmost)
(0..(2**subnet_bits)-1).each do |num|
mirror = NetAddr.binary_mirror(num, subnet_bits)
if (!objectify)
my_ip_s = NetAddr.ip_int_to_str(@network | (mirror << net_lshift), @version)
my_ip_s = NetAddr.shorten(my_ip_s) if (short && @version == 6)
cidr_list.push( my_ip_s << '/' << netmask.to_s )
else
cidr_list.push( NetAddr.cidr_build(@version, @network | (mirror << net_lshift), new_mask ) )
end
end
else
round = 1
bit_count = 1
lshift = subnet_bits/2
lshift -= 1 if (subnet_bits & 1 == 0)
unique = {}
until (bit_count > subnet_bits)
(0..2**bit_count-1).each do |num|
shifted = num << lshift
if ( !unique.has_key?(shifted) )
if (!objectify)
my_ip_s = NetAddr.ip_int_to_str(@network | (shifted << net_lshift), @version)
my_ip_s = NetAddr.shorten(my_ip_s) if (short && @version == 6)
cidr_list.push( my_ip_s << '/' << netmask.to_s )
else
cidr_list.push( NetAddr.cidr_build(@version, @network | (shifted << net_lshift), new_mask ) )
end
unique[shifted] = true
end
end
lshift -= 1 if (round & 1 == 0)
round += 1
bit_count += 1
end
end
return(cidr_list)
end