[ruby/ipaddr] Consider IPv4-mapped IPv6 addresses private if IPv4 address is private

Fixes [Bug #19479]

https://github.com/ruby/ipaddr/commit/7faa0768d3
This commit is contained in:
Jeremy Evans 2023-06-22 09:11:03 -07:00 committed by git
parent 711cabec26
commit de51a4a13e
2 changed files with 28 additions and 2 deletions

View File

@ -263,7 +263,8 @@ class IPAddr
# Returns true if the ipaddr is a private address. IPv4 addresses
# in 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16 as defined in RFC
# 1918 and IPv6 Unique Local Addresses in fc00::/7 as defined in RFC
# 4193 are considered private.
# 4193 are considered private. Private IPv4 addresses in the
# IPv4-mapped IPv6 address range are also considered private.
def private?
case @family
when Socket::AF_INET
@ -271,7 +272,12 @@ class IPAddr
@addr & 0xfff00000 == 0xac100000 || # 172.16.0.0/12
@addr & 0xffff0000 == 0xc0a80000 # 192.168.0.0/16
when Socket::AF_INET6
@addr & 0xfe00_0000_0000_0000_0000_0000_0000_0000 == 0xfc00_0000_0000_0000_0000_0000_0000_0000
@addr & 0xfe00_0000_0000_0000_0000_0000_0000_0000 == 0xfc00_0000_0000_0000_0000_0000_0000_0000 ||
(@addr & 0xffff_0000_0000 == 0xffff_0000_0000 && (
@addr & 0xff000000 == 0x0a000000 || # ::ffff:10.0.0.0/8
@addr & 0xfff00000 == 0xac100000 || # ::ffff::172.16.0.0/12
@addr & 0xffff0000 == 0xc0a80000 # ::ffff::192.168.0.0/16
))
else
raise AddressFamilyError, "unsupported address family"
end

View File

@ -426,6 +426,26 @@ class TC_Operator < Test::Unit::TestCase
assert_equal(true, IPAddr.new('fc84:8bf7:e905::1').private?)
assert_equal(true, IPAddr.new('fd84:8bf7:e905::1').private?)
assert_equal(false, IPAddr.new('fe84:8bf7:e905::1').private?)
assert_equal(false, IPAddr.new('::ffff:0.0.0.0').private?)
assert_equal(false, IPAddr.new('::ffff:127.0.0.1').private?)
assert_equal(false, IPAddr.new('::ffff:8.8.8.8').private?)
assert_equal(true, IPAddr.new('::ffff:10.0.0.0').private?)
assert_equal(true, IPAddr.new('::ffff:10.255.255.255').private?)
assert_equal(false, IPAddr.new('::ffff:11.255.1.1').private?)
assert_equal(false, IPAddr.new('::ffff:172.15.255.255').private?)
assert_equal(true, IPAddr.new('::ffff:172.16.0.0').private?)
assert_equal(true, IPAddr.new('::ffff:172.31.255.255').private?)
assert_equal(false, IPAddr.new('::ffff:172.32.0.0').private?)
assert_equal(false, IPAddr.new('::ffff:190.168.0.0').private?)
assert_equal(true, IPAddr.new('::ffff:192.168.0.0').private?)
assert_equal(true, IPAddr.new('::ffff:192.168.255.255').private?)
assert_equal(false, IPAddr.new('::ffff:192.169.0.0').private?)
assert_equal(false, IPAddr.new('::ffff:169.254.0.1').private?)
end
def test_link_local?