I have done some poking around and managed to do a trace with the Win32 API instead of Indy. The Win32 API is quite straight forward and has a function for just ICMP Echo: IcmpSendEcho.
You need to use the optional RequestOptions to set the TTL from 1 and increase for each call until you either reach your hop limit or get a success back.
The Indy component just doesn't seem to return on errors, only on a success or timeout (ms not TTL).
I have boiled down my code to a minimum (not tested although).
IP_OPTION_INFORMATION Options;
IPAddr Host; // Host address to ping
char SendData[32] = "Echo";
HANDLE hIcmp;
LPVOID ReplyBuffer;
DWORD ReplySize;
PICMP_ECHO_REPLY pEchoReply;
int TTL = 0;
int Timeout = 5000; // 5 seconds timeout
bool done = false;
// Prepare ICMP operation
Host = inet_addr("74.125.232.95"); // Google server
hIcmp = IcmpCreateFile();
if (hIcmp == INVALID_HANDLE_VALUE) {
return psICMPFailure;
}
// Prepare ISMP reply buffer
ReplySize = sizeof(ICMP_ECHO_REPLY) + 32;
ReplyBuffer = (VOID*) malloc(ReplySize);
while (!done && TTL++<30) {
// Prepare options
Options.Ttl = TTL;
Options.Tos = 0;
Options.Flags = IP_FLAG_DF;
Options.OptionsSize = 0;
Options.OptionsData = NULL;
// PING
IcmpSendEcho(hIcmp,Host,SendData,sizeof(SendData),&Options,ReplyBuffer,ReplySize, Timeout);
// get result
pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
// Do something like adding the Host IP to a list
// Check ICMP status
done = (pEchoReply->Status == 0);
}
// Cleanup
IcmpCloseHandle(hIcmp);
free(ReplyBuffer);