public static async Task SendAsyncs_ReuseInstance_Hostname() { IPAddress localIpAddress = await TestSettings.GetLocalIPAddress(); using (Ping p = new Ping()) { TaskCompletionSource <bool> tcs = null; PingCompletedEventArgs ea = null; p.PingCompleted += (s, e) => { ea = e; tcs.TrySetResult(true); }; Action reset = () => { ea = null; tcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); }; // Several normal iterations for (int i = 0; i < 3; i++) { reset(); p.SendAsync(TestSettings.LocalHost, null); await tcs.Task; Assert.NotNull(ea); PingResultValidator(ea.Reply, localIpAddress); } // Several canceled iterations for (int i = 0; i < 3; i++) { reset(); p.SendAsync(TestSettings.LocalHost, null); p.SendAsyncCancel(); // will block until operation can be started again await tcs.Task; bool cancelled = ea.Cancelled; Exception error = ea.Error; PingReply reply = ea.Reply; Assert.True(cancelled ^ (error != null) ^ (reply != null), "Cancelled: " + cancelled + (error == null ? "" : (Environment.NewLine + "Error Message: " + error.Message + Environment.NewLine + "Error Inner Exception: " + error.InnerException)) + (reply == null ? "" : (Environment.NewLine + "Reply Address: " + reply.Address + Environment.NewLine + "Reply Status: " + reply.Status))); } } }
public void SendPingWithIPAddressAndTimeoutAndBufferAndPingOptions() { IPAddress localIpAddress = TestSettings.GetLocalIPAddress(); var options = new PingOptions(); byte[] buffer = TestSettings.PayloadAsBytes; SendBatchPing( (ping) => ping.Send(localIpAddress, TestSettings.PingTimeout, buffer, options), (pingReply) => { PingResultValidator(pingReply, localIpAddress); Assert.Equal(buffer, pingReply.Buffer); Assert.InRange(pingReply.RoundtripTime, 0, long.MaxValue); }); }
[PlatformSpecific(TestPlatforms.AnyUnix)] // Tests un-priviledged Ping support on Unix public static async Task PacketSizeIsRespected(int payloadSize) { IPAddress localAddress = await TestSettings.GetLocalIPAddress(); bool ipv4 = localAddress.AddressFamily == AddressFamily.InterNetwork; string arguments = UnixCommandLinePing.ConstructCommandLine(payloadSize, localAddress.ToString(), ipv4); string utilityPath = (localAddress.AddressFamily == AddressFamily.InterNetwork) ? UnixCommandLinePing.Ping4UtilityPath : UnixCommandLinePing.Ping6UtilityPath; ProcessStartInfo psi = new ProcessStartInfo(utilityPath, arguments); psi.RedirectStandardError = true; psi.RedirectStandardOutput = true; Process p = Process.Start(psi); string pingOutput = p.StandardOutput.ReadToEnd(); Assert.True(p.WaitForExit(TestSettings.PingTimeout), "Ping process did not exit in " + TestSettings.PingTimeout + " ms."); if (p.ExitCode == 1 || p.ExitCode == 2) { // Workaround known OSX bug in ping6 utility. Assert.Equal(utilityPath, UnixCommandLinePing.Ping6UtilityPath); Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.OSX)); return; } 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) { throw new Exception($"Ping output was <{pingOutput}>", e); } }
public async Task SendPingAsyncWithIPAddressAndTimeoutAndBufferAndPingOptions() { IPAddress localIpAddress = await TestSettings.GetLocalIPAddress(); var options = new PingOptions(); byte[] buffer = TestSettings.PayloadAsBytes; await SendBatchPingAsync( (ping) => ping.SendPingAsync(localIpAddress, TestSettings.PingTimeout, buffer, options), (pingReply) => { Assert.Equal(IPStatus.Success, pingReply.Status); Assert.True(pingReply.Address.Equals(localIpAddress)); Assert.Equal(buffer, pingReply.Buffer); Assert.InRange(pingReply.RoundtripTime, 0, long.MaxValue); }); }
public void SendPingWithIPAddress_AddressAsString(AddressFamily addressFamily) { IPAddress localIpAddress = TestSettings.GetLocalIPAddress(addressFamily); if (localIpAddress == null) { // No local address for given address family. return; } SendBatchPing( (ping) => ping.Send(localIpAddress.ToString()), (pingReply) => { PingResultValidator(pingReply, localIpAddress); }); }
public async Task SendPingAsync_InvalidArgs() { IPAddress localIpAddress = await TestSettings.GetLocalIPAddress(); Ping p = new Ping(); // Null address Assert.Throws <ArgumentNullException>("address", () => { p.SendPingAsync((IPAddress)null); }); Assert.Throws <ArgumentNullException>("hostNameOrAddress", () => { p.SendPingAsync((string)null); }); Assert.Throws <ArgumentNullException>("address", () => { p.SendAsync((IPAddress)null, null); }); Assert.Throws <ArgumentNullException>("hostNameOrAddress", () => { p.SendAsync((string)null, null); }); Assert.Throws <ArgumentNullException>("address", () => { p.Send((IPAddress)null); }); Assert.Throws <ArgumentNullException>("hostNameOrAddress", () => { p.Send((string)null); }); // Invalid address Assert.Throws <ArgumentException>("address", () => { p.SendPingAsync(IPAddress.Any); }); Assert.Throws <ArgumentException>("address", () => { p.SendPingAsync(IPAddress.IPv6Any); }); Assert.Throws <ArgumentException>("address", () => { p.SendAsync(IPAddress.Any, null); }); Assert.Throws <ArgumentException>("address", () => { p.SendAsync(IPAddress.IPv6Any, null); }); Assert.Throws <ArgumentException>("address", () => { p.Send(IPAddress.Any); }); Assert.Throws <ArgumentException>("address", () => { p.Send(IPAddress.IPv6Any); }); // Negative timeout Assert.Throws <ArgumentOutOfRangeException>("timeout", () => { p.SendPingAsync(localIpAddress, -1); }); Assert.Throws <ArgumentOutOfRangeException>("timeout", () => { p.SendPingAsync(TestSettings.LocalHost, -1); }); Assert.Throws <ArgumentOutOfRangeException>("timeout", () => { p.SendAsync(localIpAddress, -1, null); }); Assert.Throws <ArgumentOutOfRangeException>("timeout", () => { p.SendAsync(TestSettings.LocalHost, -1, null); }); Assert.Throws <ArgumentOutOfRangeException>("timeout", () => { p.Send(localIpAddress, -1); }); Assert.Throws <ArgumentOutOfRangeException>("timeout", () => { p.Send(TestSettings.LocalHost, -1); }); // Null byte[] Assert.Throws <ArgumentNullException>("buffer", () => { p.SendPingAsync(localIpAddress, 0, null); }); Assert.Throws <ArgumentNullException>("buffer", () => { p.SendPingAsync(TestSettings.LocalHost, 0, null); }); Assert.Throws <ArgumentNullException>("buffer", () => { p.SendAsync(localIpAddress, 0, null, null); }); Assert.Throws <ArgumentNullException>("buffer", () => { p.SendAsync(TestSettings.LocalHost, 0, null, null); }); Assert.Throws <ArgumentNullException>("buffer", () => { p.Send(localIpAddress, 0, null); }); Assert.Throws <ArgumentNullException>("buffer", () => { p.Send(TestSettings.LocalHost, 0, null); }); // Too large byte[] Assert.Throws <ArgumentException>("buffer", () => { p.SendPingAsync(localIpAddress, 1, new byte[65501]); }); Assert.Throws <ArgumentException>("buffer", () => { p.SendPingAsync(TestSettings.LocalHost, 1, new byte[65501]); }); Assert.Throws <ArgumentException>("buffer", () => { p.SendAsync(localIpAddress, 1, new byte[65501], null); }); Assert.Throws <ArgumentException>("buffer", () => { p.SendAsync(TestSettings.LocalHost, 1, new byte[65501], null); }); Assert.Throws <ArgumentException>("buffer", () => { p.Send(localIpAddress, 1, new byte[65501]); }); Assert.Throws <ArgumentException>("buffer", () => { p.Send(TestSettings.LocalHost, 1, new byte[65501]); }); }
public static async Task SendAsyncs_ReuseInstance_Hostname() { IPAddress localIpAddress = await TestSettings.GetLocalIPAddress(); using (Ping p = new Ping()) { TaskCompletionSource <bool> tcs = null; PingCompletedEventArgs ea = null; p.PingCompleted += (s, e) => { ea = e; tcs.TrySetResult(true); }; Action reset = () => { ea = null; tcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); }; // Several normal iterations for (int i = 0; i < 3; i++) { reset(); p.SendAsync(TestSettings.LocalHost, null); await tcs.Task; 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++) { reset(); p.SendAsync(TestSettings.LocalHost, null); p.SendAsyncCancel(); // will block until operation can be started again } await tcs.Task; Assert.True(ea.Cancelled ^ (ea.Error != null) ^ (ea.Reply != null)); } }
public void SendPingWithIPAddressAndTimeoutAndBufferAndPingOptions_Unix(AddressFamily addressFamily) { IPAddress localIpAddress = TestSettings.GetLocalIPAddress(addressFamily); if (localIpAddress == null) { // No local address for given address family. return; } byte[] buffer = GetPingPayload(localIpAddress.AddressFamily); SendBatchPing( (ping) => ping.Send(localIpAddress, TestSettings.PingTimeout, buffer, new PingOptions()), (pingReply) => { PingResultValidator(pingReply, localIpAddress); Assert.Equal(buffer, 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. if (OperatingSystem.IsMacOS()) { Assert.Equal(IPStatus.PacketTooBig, pingReply.Status); } } }
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 async Task SendPingAsyncWithHostAndTimeoutAndBufferAndPingOptions_Unix() { IPAddress localIpAddress = await TestSettings.GetLocalIPAddress(); byte[] buffer = TestSettings.PayloadAsBytes; await SendBatchPingAsync( (ping) => ping.SendPingAsync(TestSettings.LocalHost, TestSettings.PingTimeout, buffer, new PingOptions()), (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 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.GetLocalIPAddress(); 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); } }