diff --git a/lib/ipaddr.rb b/lib/ipaddr.rb index a6734455321f64..c1073ecd2bc4e1 100644 --- a/lib/ipaddr.rb +++ b/lib/ipaddr.rb @@ -471,6 +471,20 @@ def netmask _to_string(@mask_addr) end + # Returns the wildcard mask in string format e.g. 0.0.255.255 + def wildcard_mask + case @family + when Socket::AF_INET + mask = IN4MASK ^ @mask_addr + when Socket::AF_INET6 + mask = IN6MASK ^ @mask_addr + else + raise AddressFamilyError, "unsupported address family" + end + + _to_string(mask) + end + # Returns the IPv6 zone identifier, if present. # Raises InvalidAddressError if not an IPv6 address. def zone_id diff --git a/test/test_ipaddr.rb b/test/test_ipaddr.rb index 4829d9620cd202..e95b0d2d7a0086 100644 --- a/test/test_ipaddr.rb +++ b/test/test_ipaddr.rb @@ -263,6 +263,29 @@ def test_netmask assert_equal(a.netmask, "255.255.255.0") end + def test_wildcard_mask + a = IPAddr.new("192.168.1.2/1") + assert_equal(a.wildcard_mask, "127.255.255.255") + + a = IPAddr.new("192.168.1.2/8") + assert_equal(a.wildcard_mask, "0.255.255.255") + + a = IPAddr.new("192.168.1.2/16") + assert_equal(a.wildcard_mask, "0.0.255.255") + + a = IPAddr.new("192.168.1.2/24") + assert_equal(a.wildcard_mask, "0.0.0.255") + + a = IPAddr.new("192.168.1.2/32") + assert_equal(a.wildcard_mask, "0.0.0.0") + + a = IPAddr.new("3ffe:505:2::/48") + assert_equal(a.wildcard_mask, "0000:0000:0000:ffff:ffff:ffff:ffff:ffff") + + a = IPAddr.new("3ffe:505:2::/128") + assert_equal(a.wildcard_mask, "0000:0000:0000:0000:0000:0000:0000:0000") + end + def test_zone_id a = IPAddr.new("192.168.1.2") assert_raise(IPAddr::InvalidAddressError) { a.zone_id = '%ab0' }