From c6efaf4ef89902f0f2180dba9d5d7be9065d80bb Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Wed, 19 Dec 2018 10:28:16 -0800 Subject: [PATCH] avoid processing incorrect ICMP message on Unix (dotnet/corefx#34084) * use connect on unicast ping addresses to avoild processing incorrect responses * feedback from review Commit migrated from https://github.com/dotnet/corefx/commit/3172386e3e6f268b1811a831c6890665c3154f8a --- .../System/Net/NetworkInformation/Ping.Unix.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.Unix.cs b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.Unix.cs index 01fe0d2be9261..d9f28d0754d27 100644 --- a/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.Unix.cs +++ b/src/libraries/System.Net.Ping/src/System/Net/NetworkInformation/Ping.Unix.cs @@ -88,8 +88,10 @@ private SocketConfig GetSocketConfig(IPAddress address, byte[] buffer, int timeo private Socket GetRawSocket(SocketConfig socketConfig) { + IPEndPoint ep = (IPEndPoint)socketConfig.EndPoint; + // Setting Socket.DontFragment and .Ttl is not supported on Unix, so socketConfig.Options is ignored. - AddressFamily addrFamily = ((IPEndPoint)socketConfig.EndPoint).Address.AddressFamily; + AddressFamily addrFamily = ep.Address.AddressFamily; Socket socket = new Socket(addrFamily, SocketType.Raw, socketConfig.ProtocolType); socket.ReceiveTimeout = socketConfig.Timeout; socket.SendTimeout = socketConfig.Timeout; @@ -97,6 +99,17 @@ private Socket GetRawSocket(SocketConfig socketConfig) { socket.Ttl = (short)socketConfig.Options.Ttl; } + +#pragma warning disable 618 + // Disable warning about obsolete property. We could use GetAddressBytes but that allocates. + // IPv4 multicast address starts with 1110 bits so mask rest and test if we get correct value e.g. 0xe0. + if (!ep.Address.IsIPv6Multicast && !(addrFamily == AddressFamily.InterNetwork && (ep.Address.Address & 0xf0) == 0xe0)) + { + // If it is not multicast, use Connect to scope responses only to the target address. + socket.Connect(socketConfig.EndPoint); + } +#pragma warning restore 618 + return socket; } @@ -129,7 +142,7 @@ private bool TryGetPingReply(SocketConfig socketConfig, byte[] receiveBuffer, in { return false; } - + sw.Stop(); long roundTripTime = sw.ElapsedMilliseconds; int dataOffset = ipHeaderLength + IcmpHeaderLengthInBytes;