diff --git a/src/libraries/System.Net.Primitives/src/System/Net/IPAddress.cs b/src/libraries/System.Net.Primitives/src/System/Net/IPAddress.cs index 48f424407b400c..cf45264cf0d30d 100644 --- a/src/libraries/System.Net.Primitives/src/System/Net/IPAddress.cs +++ b/src/libraries/System.Net.Primitives/src/System/Net/IPAddress.cs @@ -86,6 +86,20 @@ private set } } + internal uint PrivateIPv4Address + { + get + { + Debug.Assert(IsIPv4 || IsIPv4MappedToIPv6); + if (IsIPv4) + { + return _addressOrScopeId; + } + uint address = (uint)_numbers[6] << 16 | (uint)_numbers[7]; + return (uint)HostToNetworkOrder(unchecked((int)address)); + } + } + private uint PrivateScopeId { get diff --git a/src/libraries/System.Net.Primitives/src/System/Net/IPNetwork.cs b/src/libraries/System.Net.Primitives/src/System/Net/IPNetwork.cs index 1c3a3acd42932e..b57cc93126aa1e 100644 --- a/src/libraries/System.Net.Primitives/src/System/Net/IPNetwork.cs +++ b/src/libraries/System.Net.Primitives/src/System/Net/IPNetwork.cs @@ -84,7 +84,7 @@ public bool Contains(IPAddress address) { ArgumentNullException.ThrowIfNull(address); - if (address.AddressFamily != BaseAddress.AddressFamily) + if (address.AddressFamily != BaseAddress.AddressFamily && (BaseAddress.AddressFamily != AddressFamily.InterNetwork || !address.IsIPv4MappedToIPv6)) { return false; } @@ -95,7 +95,7 @@ public bool Contains(IPAddress address) return true; } - if (address.AddressFamily == AddressFamily.InterNetwork) + if (address.AddressFamily == AddressFamily.InterNetwork || address.IsIPv4MappedToIPv6) { uint mask = uint.MaxValue << (32 - PrefixLength); if (BitConverter.IsLittleEndian) @@ -103,7 +103,7 @@ public bool Contains(IPAddress address) mask = BinaryPrimitives.ReverseEndianness(mask); } - return BaseAddress.PrivateAddress == (address.PrivateAddress & mask); + return BaseAddress.PrivateIPv4Address == (address.PrivateIPv4Address & mask); } else { diff --git a/src/libraries/System.Net.Primitives/tests/FunctionalTests/IPNetworkTest.cs b/src/libraries/System.Net.Primitives/tests/FunctionalTests/IPNetworkTest.cs index 6688b7a7864343..4c56e2d709e346 100644 --- a/src/libraries/System.Net.Primitives/tests/FunctionalTests/IPNetworkTest.cs +++ b/src/libraries/System.Net.Primitives/tests/FunctionalTests/IPNetworkTest.cs @@ -151,10 +151,12 @@ public void Contains_DifferentAddressFamily_ReturnsFalse() [Theory] [InlineData("0.0.0.0/0", "0.0.0.0", "127.127.127.127", "255.255.255.255")] // the whole IPv4 space + [InlineData("0.0.0.0/0", "0.0.0.0", "::ffff:127.127.127.127", "::ffff:255.255.255.255")] // the whole IPv4 space [InlineData("::/0", "::", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")] // the whole IPv6 space [InlineData("255.255.255.255/32", "255.255.255.255")] // single IPv4 address [InlineData("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")] // single IPv6 address [InlineData("255.255.255.0/24", "255.255.255.0", "255.255.255.255")] + [InlineData("255.255.255.0/24", "::ffff:255.255.255.0", "::ffff:255.255.255.255")] [InlineData("198.51.248.0/22", "198.51.248.0", "198.51.250.42", "198.51.251.255")] [InlineData("255.255.255.128/25", "255.255.255.128", "255.255.255.129", "255.255.255.255")] [InlineData("2a00::/13", "2a00::", "2a00::1", "2a01::", "2a07::", "2a07:ffff:ffff:ffff:ffff:ffff:ffff:ffff")]