To do a trace route we can read in the Indy documentation
"For Traceroute application, send ping echo requests with increased TTL values"
The problem is that the TTL property is protected and can't be set. Is this just another bug or do I really have to define a new class to make the TTL property public?
However, I did a new class (including the Ping work around):
class TPing : public TIdIcmpClient {
public:
__property TTL;
__fastcall TPing(TComponent* Owner) : TIdIcmpClient(Owner) {};
__fastcall Ping(unsigned int Id = 0) {
AnsiString Proxy = StringOfChar('X',PacketSize);
TIdIcmpClient::Ping(Proxy,Id);
}
};
If I set TTL to 5 and call Ping to google.com (I have checked that there is 6 TTL to google.com from my location).
So a TTL of 5 will generate an ICMP timeout message and according to the documentation, the last IP will be returned. But instead I get IP 0.0.0.0
. This is the member values of AReplyStatus
in the OnReply(TComponent *ASender, const TReplyStatus *AReplyStatus)
callback.
FByteReceived 0,
FFromIpAddress { u"0.0.0.0" },
FToIpAddress { u"0.0.0.0" },
FMsgType '\0',
FMsgCode '\0',
FSequenceId 3490U(0x0DA2),
FMsRoundTripTime 109,
FTimeToLive '\0',
FReplyStatus 2 /* rsTimeOut */,
FPacketNumber 0,
FHostName { NULL },
FMsg { NULL },
FRedirectTo { NULL }
If I change the TTL to 6 everything works as expected (google.com answers) and I get rsEcho in return.
So to clarify the question:
How can I do a traceroute (Incrementing TTL) to collect all the router IP addresses along the way?