Rationale: This SO question demonstrates there is at least some need to manipulate netmasks into CIDR integers. The accepted answer contains a bug which can be easily eliminated by hard coding the 2 sets of netmasks into the IPAddr class - see my alternative answer.
Proposed solution: Define IPAddr::IPV4_SUBNET_MASKS and IPAddr::IPV6_SUBNET_MASKS as follows:
classIPAddrIPV4_SUBNET_MASKS=(0..32).map{ |n| IPAddr.new("0.0.0.0/#{n}").netmask}IPV6_SUBNET_MASKS=(0..128).map{ |n| IPAddr.new("0::/#{n}").netmask}end# Now a user can do the following to get a subnet mask from a CIDR integer:IPAddr::IPV4_SUBNET_MASKS[24]# => "255.255.255.0"IPAddr::IPV6_SUBNET_MASKS[64]# => "ffff:ffff:ffff:ffff:0000:0000:0000:0000"Optional: Add a predicate to check if an instance of IPAddr is a netmask:
classIPAddrdefnetmask?ifipv4?IPV4_SUBNET_MASKS.include?to_selseIPV6_SUBNET_MASKS.include?to_sendendendipaddr1=IPAddr.new'255.254.255.0'ipaddr1.netmask?# => falseipaddr2=IPAddr.new'255.255.255.0/24'ipaddr2.netmask?# => trueipaddr3=IPAddr.new'255.255.255.0'ipaddr3.netmask?# => true# And so on for IPv6 addresses
Rationale: This SO question demonstrates there is at least some need to manipulate netmasks into CIDR integers. The accepted answer contains a bug which can be easily eliminated by hard coding the 2 sets of netmasks into the
IPAddrclass - see my alternative answer.Proposed solution: Define
IPAddr::IPV4_SUBNET_MASKSandIPAddr::IPV6_SUBNET_MASKSas follows:Optional: Add a predicate to check if an instance of IPAddr is a netmask: