public static string ConstructCommandLine(int packetSize, int timeout, string address, bool ipv4, int ttl = 0, PingFragmentOptions fragmentOption = PingFragmentOptions.Default) { var sb = new StringBuilder(); sb.Append("-c 1"); // Just send a single ping ("count = 1") //if timeout is zero then some ping implementations can stuck infinitely if endpoint is unreachable if (timeout == 0) { timeout = 1; } // Pass timeout argument to ping utility // BusyBox, Linux: ping and ping6 requires -W flag which accepts timeout in SECONDS. // FreeBSD: ping requires -W flag which accepts timeout in MILLISECONDS; // ping6 requires -x which accepts timeout in MILLISECONDS // OSX: ping requires -W flag which accepts timeout in MILLISECONDS; ping6 doesn't support timeout if (OperatingSystem.IsFreeBSD()) { if (ipv4) { sb.Append(" -W "); } else { sb.Append(" -x "); } } else if (OperatingSystem.IsMacOS()) { if (ipv4) { sb.Append(" -W "); } else { goto skipped_timeout; } } else { sb.Append(" -W "); const int millisInSecond = 1000; timeout = Math.DivRem(timeout, millisInSecond, out int remainder); if (remainder != 0) { timeout += 1; } } sb.Append(timeout); skipped_timeout: // The command-line flags for "Do-not-fragment" and "TTL" are not standard. // In fact, they are different even between ping and ping6 on the same machine. // The ping utility is not flexible enough to specify an exact payload. // But we can at least send the right number of bytes. if (ttl > 0) { if (OperatingSystem.IsFreeBSD() || OperatingSystem.IsMacOS()) { // OSX and FreeBSD use -h to set hop limit for IPv6 and -m ttl for IPv4 if (ipv4) { sb.Append(" -m "); } else { sb.Append(" -h "); } } else { // Linux uses -t ttl for both IPv4 & IPv6 sb.Append(" -t "); } sb.Append(ttl); } if (fragmentOption != PingFragmentOptions.Default) { if (OperatingSystem.IsFreeBSD() || OperatingSystem.IsMacOS()) { // The bit is off by default on OSX & FreeBSD if (fragmentOption == PingFragmentOptions.Dont) { sb.Append(" -D "); } } else if (!s_isBusybox.Value) // busybox implementation does not support fragmentation option. { // Linux has three state option with default to use PMTU. // When explicit option is used we set it explicitly to one or the other. if (fragmentOption == PingFragmentOptions.Do) { sb.Append(" -M do "); } else { sb.Append(" -M dont "); } } } // ping and ping6 do not report timing information unless at least 16 bytes are sent. if (packetSize < 16) { packetSize = 16; } sb.Append(" -s "); sb.Append(packetSize); sb.Append(' '); sb.Append(address); return(sb.ToString()); }
public static string ConstructCommandLine(int packetSize, string address, bool ipv4, int ttl = 0, PingFragmentOptions fragmentOption = PingFragmentOptions.Default) { StringBuilder sb = new StringBuilder(); sb.Append("-c 1"); // Just send a single ping ("count = 1") // The command-line flags for "Do-not-fragment" and "TTL" are not standard. // In fact, they are different even between ping and ping6 on the same machine. // The ping utility is not flexible enough to specify an exact payload. // But we can at least send the right number of bytes. if (ttl > 0) { if (s_isBSD) { // OSX and FreeBSD use -h to set hop limit for IPv6 and -m ttl for IPv4 if (ipv4) { sb.Append(" -m "); } else { sb.Append(" -h "); } } else { // Linux uses -t ttl for both IPv4 & IPv6 sb.Append(" -t "); } sb.Append(ttl); } if (fragmentOption != PingFragmentOptions.Default) { if (s_isBSD) { // The bit is off by default on OSX & FreeBSD if (fragmentOption == PingFragmentOptions.Dont) { sb.Append(" -D "); } } else if (!s_isBusybox.Value) // busybox implementation does not support fragmentation option. { // Linux has three state option with default to use PMTU. // When explicit option is used we set it explicitly to one or the other. if (fragmentOption == PingFragmentOptions.Do) { sb.Append(" -M do "); } else { sb.Append(" -M dont "); } } } // ping and ping6 do not report timing information unless at least 16 bytes are sent. if (packetSize < 16) { packetSize = 16; } sb.Append(" -s "); sb.Append(packetSize); sb.Append(' '); sb.Append(address); return(sb.ToString()); }