Skip to content

Commit

Permalink
[ruby/ipaddr] Consider IPv4-mapped IPv6 addresses private if IPv4 add…
Browse files Browse the repository at this point in the history
…ress is private

Fixes [Bug #19479]

ruby/ipaddr@7faa0768d3
  • Loading branch information
jeremyevans authored and matzbot committed Jun 22, 2023
1 parent 711cabe commit de51a4a
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
10 changes: 8 additions & 2 deletions lib/ipaddr.rb
Expand Up @@ -263,15 +263,21 @@ def loopback?
# 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
@addr & 0xff000000 == 0x0a000000 || # 10.0.0.0/8
@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
Expand Down
20 changes: 20 additions & 0 deletions test/test_ipaddr.rb
Expand Up @@ -426,6 +426,26 @@ def test_private?
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?
Expand Down

0 comments on commit de51a4a

Please sign in to comment.