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 01fe0d2be9261e..d9f28d0754d279 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;