From 8e0d7ecb5304c7106a4540fa7d70ecf7ac752bf2 Mon Sep 17 00:00:00 2001 From: Tietew Date: Mon, 24 Jun 2019 17:38:28 +0900 Subject: [PATCH] Make correct mask when converting IPv4 <=> IPv6 --- lib/ipaddr.rb | 9 +++++++++ test/test_ipaddr.rb | 28 ++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/lib/ipaddr.rb b/lib/ipaddr.rb index acd699c..781945c 100644 --- a/lib/ipaddr.rb +++ b/lib/ipaddr.rb @@ -478,10 +478,16 @@ def set(addr, *family) if addr < 0 || addr > IN4MASK raise InvalidAddressError, "invalid address: #{@addr}" end + if @family == Socket::AF_INET6 + mask = @mask_addr & IN4MASK + end when Socket::AF_INET6 if addr < 0 || addr > IN6MASK raise InvalidAddressError, "invalid address: #{@addr}" end + if @family == Socket::AF_INET + mask = (IN6MASK ^ IN4MASK) | @mask_addr + end else raise AddressFamilyError, "unsupported address family" end @@ -489,6 +495,9 @@ def set(addr, *family) if family[0] @family = family[0] end + if mask + @mask_addr = mask + end return self end diff --git a/test/test_ipaddr.rb b/test/test_ipaddr.rb index cc2bb71..0e83067 100644 --- a/test/test_ipaddr.rb +++ b/test/test_ipaddr.rb @@ -129,11 +129,25 @@ def test_ipv4_compat assert_equal("192.168.1.2", b.to_s) assert_equal(Socket::AF_INET, b.family) assert_equal(false, b.ipv4_compat?) + assert_equal(32, b.prefix) + + a = IPAddr.new("::192.168.0.0/112") + b = a.native + assert_equal("192.168.0.0", b.to_s) + assert_equal(Socket::AF_INET, b.family) + assert_equal(16, b.prefix) a = IPAddr.new("192.168.1.2") b = a.ipv4_compat assert_equal("::192.168.1.2", b.to_s) assert_equal(Socket::AF_INET6, b.family) + assert_equal(128, b.prefix) + + a = IPAddr.new("192.168.0.0/16") + b = a.ipv4_compat + assert_equal("::192.168.0.0", b.to_s) + assert_equal(Socket::AF_INET6, b.family) + assert_equal(112, b.prefix) end def test_ipv4_mapped @@ -146,11 +160,25 @@ def test_ipv4_mapped assert_equal("192.168.1.2", b.to_s) assert_equal(Socket::AF_INET, b.family) assert_equal(false, b.ipv4_mapped?) + assert_equal(32, b.prefix) + + a = IPAddr.new("::ffff:192.168.0.0/112") + b = a.native + assert_equal("192.168.0.0", b.to_s) + assert_equal(Socket::AF_INET, b.family) + assert_equal(16, b.prefix) a = IPAddr.new("192.168.1.2") b = a.ipv4_mapped assert_equal("::ffff:192.168.1.2", b.to_s) assert_equal(Socket::AF_INET6, b.family) + assert_equal(128, b.prefix) + + a = IPAddr.new("192.168.0.0/16") + b = a.ipv4_mapped + assert_equal("::ffff:192.168.0.0", b.to_s) + assert_equal(Socket::AF_INET6, b.family) + assert_equal(112, b.prefix) end def test_reverse