Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

Трассировка пути до определенного IP-адреса (Traceroute)

01.01.2007

Трассировка пути до определенного IP адреса (как tracert.exe в Windows)

Пример использования модуля:

procedure TForm1.Button1Click(Sender: TObject); 
var RT : TTraceRoute; 
begin 
 RT := TTraceRoute.Create; 
 RT.Trace('192.168.5.12', ListBox1.Items); 
 RT.Free; 
end; 

В ListBox1 выведется путь в таком формате:

IP;TIME;TTL;STATUS

Сам модуль:

unit TraceRt; 
interface 
 
// =========================================================================== 
// TRACEROUTE Class 
// Mike Heydon Dec 2003 
// 
// Method 
// Trace(IpAddress : string; ResultList : TStrings) 
//             Returns semi-colon delimited list of ip routes to target 
//             format .. IP ADDRESS; PING TIME MS; TIME TO LIVE; STATUS 
// 
// Properties 
//             IcmpTimeOut : integer (Default = 5000ms) 
//             IcmpMaxHops : integer (Default = 40) 
// =========================================================================== 
 
uses Forms, Windows, Classes, SysUtils, IdIcmpClient; 
 
type 
    TTraceRoute = class(TObject) 
    protected 
      procedure ProcessResponse(Status : TReplyStatus); 
      procedure AddRoute(AResponseTime : DWORD; 
                         AStatus: TReplyStatus; const AInfo: string ); 
    private 
      FIcmpTimeOut, 
      FIcmpMaxHops : integer; 
      FResults : TStringList; 
      FICMP : TIdIcmpClient; 
      FPingStart : cardinal; 
      FCurrentTTL : integer; 
      procedure PingTarget; 
    public 
      constructor Create; 
      procedure Trace(const AIpAddress : string; AResultList : TStrings); 
      property IcmpTimeOut : integer read FIcmpTimeOut write FIcmpTimeOut; 
      property IcmpMaxHops : integer read FIcmpMaxHops write FIcmpMaxHops; 
    end; 
 
// --------------------------------------------------------------------------- 
implementation 
 
// ======================================== 
// Create the class and set defaults 
// ======================================== 
 
constructor TTraceRoute.Create; 
begin 
 IcmpTimeOut := 5000; 
 IcmpMaxHops := 40; 
end; 
 
 
// ============================================= 
// Use Indy component to ping hops to target 
// ============================================= 
 
procedure TTraceRoute.PingTarget; 
var wOldMode : DWORD; 
begin 
 Application.ProcessMessages; 
 inc(FCurrentTTL); 
 
 if FCurrentTTL < FIcmpMaxHops then begin 
   FICMP.TTL  := FCurrentTTL; 
   FICMP.ReceiveTimeout := FIcmpTimeOut; 
   FPingStart := GetTickCount; 
   wOldMode := SetErrorMode(SEM_FAILCRITICALERRORS); 
 
   try 
     FICMP.Ping; 
     ProcessResponse(FICMP.ReplyStatus); 
   except 
     FResults.Add('0.0.0.0;0;0;ERROR'); 
   end; 
 
   SetErrorMode(wOldMode); 
 end 
 else 
   FResults.Add('0.0.0.0;0;0;MAX HOPS EXCEEDED'); 
end; 
 
 
// ============================================================ 
// Add the ping reply status data to the returned stringlist 
// ============================================================ 
 
procedure TTraceRoute.AddRoute(AResponseTime : DWORD; 
                              AStatus: TReplyStatus; 
                              const AInfo: string ); 
begin 
 FResults.Add(AStatus.FromIPAddress + ';' + 
              IntToStr(GetTickCount - AResponseTime) + ';' + 
              IntToStr(AStatus.TimeToLive) + ';' + AInfo); 
end; 
 
 
// ============================================================ 
// Process the ping reply status record and add to stringlist 
// ============================================================ 
 
procedure TTraceRoute.ProcessResponse(Status : TReplyStatus); 
begin 
 case Status.ReplyStatusType of 
   // Last Leg - Terminate Trace 
   rsECHO : AddRoute(FPingStart,Status,'OK'); 
 
   // More Hops to go - Continue Pinging 
   rsErrorTTLExceeded :  begin 
                           AddRoute(FPingStart,Status,'OK'); 
                           PingTarget; 
                         end; 
 
   // Error conditions - Terminate Trace 
   rsTimeOut : AddRoute(FPingStart,Status,'TIMEOUT'); 
   rsErrorUnreachable : AddRoute(FPingStart,Status,'UNREACHABLE'); 
   rsError : AddRoute(FPingStart,Status,'ERROR'); 
 end; 
end; 
 
// ====================================================== 
// Trace route to target IP address 
// Results returned in semi-colon delimited stringlist 
// IP; TIME MS; TIME TO LIVE; STATUS 
// ====================================================== 
 
procedure TTraceRoute.Trace(const AIpAddress : string; 
                           AResultList : TStrings); 
begin 
 FICMP := TIdIcmpClient.Create(nil); 
 FICMP.Host := AIpAddress; 
 FResults := TStringList(AResultList); 
 FResults.Clear; 
 FCurrentTTL := 0; 
 PingTarget; 
 FICMP.Free; 
end; 
 
{eof} 
end. 

Автор: p0s0l

Взято с Vingrad.ru https://forum.vingrad.ru