public async Task SendPingAsyncWithHostAndTimeoutAndBufferAndPingOptions_Unix() { IPAddress[] localIpAddresses = await TestSettings.GetLocalIPAddressesAsync(); byte[] buffer = TestSettings.PayloadAsBytes; await SendBatchPingAsync( (ping) => ping.SendPingAsync(TestSettings.LocalHost, TestSettings.PingTimeout, buffer, new PingOptions()), (pingReply) => { PingResultValidator(pingReply, localIpAddresses); // Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. if (Capability.CanUseRawSockets(pingReply.Address.AddressFamily)) { Assert.Equal(buffer, pingReply.Buffer); } else { Assert.Equal(Array.Empty <byte>(), pingReply.Buffer); } }); }
public void SendPingWithIPAddressAndTimeoutAndBuffer_Unix() { byte[] buffer = TestSettings.PayloadAsBytes; IPAddress localIpAddress = TestSettings.GetLocalIPAddress(); SendBatchPing( (ping) => ping.Send(localIpAddress, TestSettings.PingTimeout, buffer), (pingReply) => { PingResultValidator(pingReply, localIpAddress); // Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. if (Capability.CanUseRawSockets(localIpAddress.AddressFamily)) { Assert.Equal(buffer, pingReply.Buffer); } else { Assert.Equal(Array.Empty <byte>(), pingReply.Buffer); } }); }
public static async Task SendAsyncs_ReuseInstance_Hostname() { IPAddress localIpAddress = await TestSettings.GetLocalIPAddress(); using (Ping p = new Ping()) { var mres = new ManualResetEventSlim(); PingCompletedEventArgs ea = null; p.PingCompleted += (s, e) => { ea = e; mres.Set(); }; // Several normal iterations for (int i = 0; i < 3; i++) { ea = null; mres.Reset(); p.SendAsync(TestSettings.LocalHost, null); mres.Wait(); Assert.NotNull(ea); Assert.Equal(IPStatus.Success, ea.Reply.Status); Assert.True(ea.Reply.Address.Equals(localIpAddress)); } // Several canceled iterations for (int i = 0; i < 3; i++) { ea = null; mres.Reset(); p.SendAsync(TestSettings.LocalHost, null); p.SendAsyncCancel(); // will block until operation can be started again } mres.Wait(); Assert.True(ea.Cancelled ^ (ea.Error != null) ^ (ea.Reply != null)); } }
public void SendPingWithHostAndTimeoutAndBuffer_Unix() { IPAddress[] localIpAddresses = TestSettings.GetLocalIPAddresses(); byte[] buffer = TestSettings.PayloadAsBytes; SendBatchPing( (ping) => ping.Send(TestSettings.LocalHost, TestSettings.PingTimeout, buffer), (pingReply) => { PingResultValidator(pingReply, localIpAddresses); // Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. if (Capability.CanUseRawSockets(pingReply.Address.AddressFamily) || PlatformDetection.IsOSXLike) { Assert.Equal(buffer, pingReply.Buffer); } else { Assert.Equal(Array.Empty <byte>(), pingReply.Buffer); } }); }
public async Task SendPingAsyncWithIPAddressAndTimeoutAndBuffer_Unix() { byte[] buffer = TestSettings.PayloadAsBytes; IPAddress localIpAddress = await TestSettings.GetLocalIPAddressAsync(); await SendBatchPingAsync( (ping) => ping.SendPingAsync(localIpAddress, TestSettings.PingTimeout, buffer), (pingReply) => { PingResultValidator(pingReply, localIpAddress); // Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. if (Capability.CanUseRawSockets(localIpAddress.AddressFamily) || PlatformDetection.IsOSXLike) { Assert.Equal(buffer, pingReply.Buffer); } else { Assert.Equal(Array.Empty <byte>(), pingReply.Buffer); } }); }
public async Task SendPingWithIPAddressAndBigSize() { IPAddress localIpAddress = TestSettings.GetLocalIPAddress(); using (Ping p = new Ping()) { // Assert.DoesNotThrow PingReply pingReply = await p.SendPingAsync(localIpAddress, TestSettings.PingTimeout, new byte[10001]); // Depending on platform the call may either succeed, report timeout or report too big packet. It // should not throw wrapped SocketException though which is what this test guards. // // On Windows 10 the maximum ping size seems essentially limited to 65500 bytes and thus any buffer // size on the loopback ping succeeds. On macOS anything bigger than 8184 will report packet too // big error. On Linux/Unix the result differs for privileged and unprivileged processes and may // change with different platform versions. if (OperatingSystem.IsMacOS()) { Assert.Equal(IPStatus.PacketTooBig, pingReply.Status); } } }
public async Task SendPingAsyncWithHostAndTimeoutAndBuffer_Unix() { IPAddress localIpAddress = await TestSettings.GetLocalIPAddress(); byte[] buffer = TestSettings.PayloadAsBytes; await SendBatchPingAsync( (ping) => ping.SendPingAsync(TestSettings.LocalHost, TestSettings.PingTimeout, buffer), (pingReply) => { Assert.Equal(IPStatus.Success, pingReply.Status); Assert.True(pingReply.Address.Equals(localIpAddress)); // Non-root pings cannot send arbitrary data in the buffer, and do not receive it back in the PingReply. if (Capability.CanUseRawSockets()) { Assert.Equal(buffer, pingReply.Buffer); } else { Assert.Equal(Array.Empty <byte>(), pingReply.Buffer); } }); }
[PlatformSpecific(TestPlatforms.AnyUnix)] // Tests un-priviledged Ping support on Unix public static async Task PacketSizeIsRespected(int payloadSize) { IPAddress localAddress = await TestSettings.GetLocalIPAddressAsync(); bool ipv4 = localAddress.AddressFamily == AddressFamily.InterNetwork; string arguments = UnixCommandLinePing.ConstructCommandLine(payloadSize, localAddress.ToString(), ipv4); string utilityPath = (localAddress.AddressFamily == AddressFamily.InterNetwork) ? UnixCommandLinePing.Ping4UtilityPath : UnixCommandLinePing.Ping6UtilityPath; var p = new Process(); p.StartInfo.FileName = utilityPath; p.StartInfo.Arguments = arguments; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; var stdOutLines = new List <string>(); p.OutputDataReceived += new DataReceivedEventHandler( delegate(object sendingProcess, DataReceivedEventArgs outputLine) { stdOutLines.Add(outputLine.Data); }); p.StartInfo.RedirectStandardError = true; var stdErrLines = new List <string>(); p.ErrorDataReceived += new DataReceivedEventHandler( delegate(object sendingProcess, DataReceivedEventArgs errorLine) { stdErrLines.Add(errorLine.Data); }); p.Start(); p.BeginOutputReadLine(); p.BeginErrorReadLine(); // There are multiple issues with ping6 in macOS 10.12 (Sierra), see https://github.com/dotnet/corefx/issues/26358. bool isPing6OnMacSierra = utilityPath.Equals(UnixCommandLinePing.Ping6UtilityPath) && RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && !PlatformDetection.IsMacOsHighSierraOrHigher; string pingOutput; if (!p.WaitForExit(TestSettings.PingTimeout)) { // Workaround known issues with ping6 in macOS 10.12 if (isPing6OnMacSierra) { return; } pingOutput = string.Join("\n", stdOutLines); string stdErr = string.Join("\n", stdErrLines); throw new Exception( $"[{utilityPath} {arguments}] process did not exit in {TestSettings.PingTimeout} ms.\nStdOut:[{pingOutput}]\nStdErr:[{stdErr}]"); } // Ensure standard output and error are flushed p.WaitForExit(); pingOutput = string.Join("\n", stdOutLines); var exitCode = p.ExitCode; if (exitCode != 0) { // Workaround known issues with ping6 in macOS 10.12 if (isPing6OnMacSierra) { return; } string stdErr = string.Join("\n", stdErrLines); throw new Exception( $"[{utilityPath} {arguments}] process exit code is {exitCode}.\nStdOut:[{pingOutput}]\nStdErr:[{stdErr}]"); } try { // Validate that the returned data size is correct. // It should be equal to the bytes we sent plus the size of the ICMP header. int receivedBytes = ParseReturnedPacketSize(pingOutput); int expected = Math.Max(16, payloadSize) + IcmpHeaderLengthInBytes; Assert.Equal(expected, receivedBytes); // Validate that we only sent one ping with the "-c 1" argument. int numPingsSent = ParseNumPingsSent(pingOutput); Assert.Equal(1, numPingsSent); long rtt = UnixCommandLinePing.ParseRoundTripTime(pingOutput); Assert.InRange(rtt, 0, long.MaxValue); } catch (Exception e) { string stdErr = string.Join("\n", stdErrLines); throw new Exception( $"Parse error for [{utilityPath} {arguments}] process exit code is {exitCode}.\nStdOut:[{pingOutput}]\nStdErr:[{stdErr}]", e); } }
[PlatformSpecific(TestPlatforms.AnyUnix)] // Tests un-priviledged Ping support on Unix public static async Task PacketSizeIsRespected(int payloadSize) { var stdOutLines = new List <string>(); var stdErrLines = new List <string>(); Process p = ConstructPingProcess(await TestSettings.GetLocalIPAddressAsync(), payloadSize, 1000); p.StartInfo.RedirectStandardOutput = true; p.OutputDataReceived += delegate(object sendingProcess, DataReceivedEventArgs outputLine) { stdOutLines.Add(outputLine.Data); }; p.StartInfo.RedirectStandardError = true; p.ErrorDataReceived += delegate(object sendingProcess, DataReceivedEventArgs errorLine) { stdErrLines.Add(errorLine.Data); }; p.Start(); p.BeginOutputReadLine(); p.BeginErrorReadLine(); string pingOutput; if (!p.WaitForExit(TestSettings.PingTimeout)) { pingOutput = string.Join("\n", stdOutLines); string stdErr = string.Join("\n", stdErrLines); throw new Exception( $"[{p.StartInfo.FileName} {p.StartInfo.Arguments}] process did not exit in {TestSettings.PingTimeout} ms.\nStdOut:[{pingOutput}]\nStdErr:[{stdErr}]"); } // Ensure standard output and error are flushed p.WaitForExit(); pingOutput = string.Join("\n", stdOutLines); var exitCode = p.ExitCode; if (exitCode != 0) { string stdErr = string.Join("\n", stdErrLines); throw new Exception( $"[{p.StartInfo.FileName} {p.StartInfo.Arguments}] process exit code is {exitCode}.\nStdOut:[{pingOutput}]\nStdErr:[{stdErr}]"); } try { // Validate that the returned data size is correct. // It should be equal to the bytes we sent plus the size of the ICMP header. int receivedBytes = ParseReturnedPacketSize(pingOutput); int expected = Math.Max(16, payloadSize) + IcmpHeaderLengthInBytes; Assert.Equal(expected, receivedBytes); // Validate that we only sent one ping with the "-c 1" argument. int numPingsSent = ParseNumPingsSent(pingOutput); Assert.Equal(1, numPingsSent); long rtt = UnixCommandLinePing.ParseRoundTripTime(pingOutput); Assert.InRange(rtt, 0, long.MaxValue); } catch (Exception e) { string stdErr = string.Join("\n", stdErrLines); throw new Exception( $"Parse error for [{p.StartInfo.FileName} {p.StartInfo.Arguments}] process exit code is {exitCode}.\nStdOut:[{pingOutput}]\nStdErr:[{stdErr}]", e); } }