can be found at mono/Ping.cs (line 339)
That calls the system ping command and checks the exit code:
if (!ping.WaitForExit (timeout) || (ping.HasExited && ping.ExitCode == 2)) status = IPStatus.TimedOut; else if (ping.ExitCode == 0) status = IPStatus.Success; else if (ping.ExitCode == 1) status = IPStatus.TtlExpired;
So TTL expired is set when there was no timeout, no error or success (exit code 2 or 0), and the exit code was 1.
If ping does not receive any reply packets at all it will exit with code 1. If a packet count and deadline are both specified, and fewer than count packets are received by the time the deadline has arrived, it will also exit with code 1. On other error it exits with code 2. Otherwise it exits with code 0. This makes it possible to use the exit code to see if a host is alive or not.
So a return value of 1 indicates that no response has been received (for various reasons) and the Mono implementation sets the TTL expired status in this case. I would expect that a time out status would be returned in such cases. But it seems that the timeout detection of the Mono implementation is not triggered here (e.g. because the ping command exits upon on it's own timeout before).
So there are two other possible solutions:
To treat a TTL expired as host not alive (but this will then ignore ignore real TTL expired detections)
Please fix ASAP this is very very annoying . It should be there a IPStatus for :
Destination Host Unreachable , Timeout , Destination Network Unreachable and ect ....