首页  编辑  

跟踪目的地经过的IP地址

Tags: /超级猛料/Network.网络通讯/TCP_IP/   Date Created:

Trace 命令可以实现跟踪目的地经过的IP地址.请问Trace如何实现的?

回复人:forgot2000 | 忘记2000年

program TraceRoute;

uses

 Forms,

 MainForm in 'MainForm.pas' {TraceRouteForm},

 ICMP_Define in 'ICMP_Define.pas';

{$R *.RES}

begin

 Application.Initialize;

 Application.CreateForm(TTraceRouteForm, TraceRouteForm);

 Application.Run;

end.

//ICMP_Define.PAS

unit ICMP_Define;

interface

uses winsock;

type

DWORD=LongWord;

THandle=LongWord;

THostTraceMultiReply=record

                dwError : DWORD; //GetLastError for this host

Address : in_addr; //The IP address of the replier

       minRTT  : DWORD;  //Minimum round trip time in milliseconds

                avgRTT  : DWORD;  //Average round trip time in milliseconds

                maxRTT  : DWORD;  //Maximum round trip time in milliseconds

                end;

THostTraceSingleReply=record

                     dwError:DWORD;  //GetLastError for this replier

            Address:in_addr;  //The IP address of the replier

            RTT:DWORD; //Round Trip time in milliseconds for this replier

                     end;

PIPOptionInformation = ^TIPOptionInformation;

TIPOptionInformation =

 record

       TTL: Byte;

    TOS: Byte;

       Flags: Byte;

    OptionsSize: Byte;

       OptionsData: PChar;

 end;

PIcmpEchoReply = ^TIcmpEchoReply;

TIcmpEchoReply =

 record

       Address: DWORD;

       Status: DWORD;

       RTT: DWORD;

       DataSize:Word;

       Reserved: Word;

       Data: Pointer;

       Options: TIPOptionInformation;

 end;

const

   ULONG_MAX=1024;

function IcmpCreateFile():THandle;stdcall external 'ICMP.dll';

function IcmpCloseHandle(Handle:THandle):Boolean;stdcall external 'ICMP.dll';

function IcmpSendEcho(Handle:THandle;DestAddr:DWORD;

        RequestData: Pointer;RequestSize: Word;RequestOptions: PIPOptionInformation;

        ReplyBuffer: Pointer;ReplySize: DWORD;Timeout: DWORD): DWORD;stdcall external 'ICMP.dll';

   

implementation

end.

//主菜单

unit MainForm;

interface

uses

 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

 StdCtrls,Winsock,ICMP_Define;

type

 TTraceRouteForm = class(TForm)

   Label1: TLabel;

   edtIP: TEdit;

   btnTracert: TButton;

   memResult: TMemo;

   procedure btnTracertClick(Sender: TObject);

   procedure FormCreate(Sender: TObject);

 private

   { Private declarations }

 public

   { Public declarations }

   procedure Tracert(dwAddr:DWORD;dwPingsPerHost:DWORD);

   function Ping(dwAddr:DWORD;TimeOut:Word;var htsr:THostTraceSingleReply;nTTL:Byte):boolean;

 end;

var

 TraceRouteForm: TTraceRouteForm;

implementation

{$R *.DFM}

procedure TTraceRouteForm.btnTracertClick(Sender: TObject);

var

  WSAData:TWSAData;

  dwAddr:DWORD;

  hp:phostent;

begin

    //init winsock dll

    if (WSAStartup(MAKEWORD(2,0),WSAData)<>0) then

       raise Exception.Create('Winsock Version Error');

    ZeroMemory(Addr(dwAddr),sizeof(dwAddr));

    //resolve IP

    //convert form dotted address

    dwAddr:=inet_addr(pchar(edtIP.text));

    if (dwAddr=INADDR_NONE) then

       begin

            hp:=gethostbyname(pchar(edtIP.Text));

            if hp=NIL then

               begin

                    memResult.Lines.Add('Failed to resolve host IP');

                    Exit//Failed to resolve host;

               end

            else

                CopyMemory(Addr(dwAddr),hp.h_addr^,hp.h_length);

       end;

    memResult.Lines.Add(Format('Resolve Target: %d.%d.%d.%d',[LoByte(LoWord(dwAddr)),

                                                              HiByte(LoWord(dwAddr)),

                                                              LoByte(HiWord(dwAddr)),

                                                              HiByte(HiWord(dwAddr))]));

    //trace route

    //icmp function must be declared.

    Tracert(dwAddr,1);

    //release winsock dll

    WSACleanUP;

end;

procedure TTraceRouteForm.Tracert(dwAddr:DWORD;dwPingsPerHost:DWORD);

var

    dwTimeOut : DWORD;

        nHops : Byte;

       nPings : Byte;

 bReachedHost : Boolean;

          i,j : Byte;

         htrr : THostTraceMultiReply;

         htsr : THostTraceSingleReply;

     totalRTT : DWORD;

   bPingError : Boolean;

Top

回复人:forgot2000 | 忘记2000年

begin

    //set init value

    dwTimeOut:=3000;//this value changed according the net condition

    nHops:=30;

    nPings:=3;

    bReachedHost:=false;

    //update show.

    memResult.Lines.Add(Format('Tracing route to %s '#13#10'over a maximum of %d hpos',

                                [edtIP.Text,nHops]));

    for i:=1 to nHops do

        begin

             if bReachedHost then

                begin

                     memResult.Lines.Add('Trace Complete');

                     Break;

                end;

             htrr.dwError := 0;

             htrr.minRTT  := ULONG_MAX;

             htrr.avgRTT  := 0;

             htrr.maxRTT  := 0;

             //Iterate through all the pings for each host

             totalRTT := 0;

             htsr.Address.S_addr := 0;

             htsr.dwError := 0;

             bPingError:=false;

             for j:=1 to dwPingsPerHost do

                 begin

                      if bPingError Then break;

                      if (Ping(dwAddr,dwTimeOut,htsr,i))then

                              if (htsr.dwError=0)then

                                 begin

                                      inc(totalRTT,htsr.RTT);//acumulate total time

                                      //Store away the RTT etc

                                      if (htsr.RTT<htrr.minRTT)then htrr.minRTT:=htsr.RTT;

                                      if (htsr.RTT>htrr.maxRTT)then htrr.maxRTT:=htsr.RTT;

                                 end //if (htsr.dwError=0)then

                              else //if (htsr.dwError=0)then

                                   begin

                                        htrr.dwError:=htsr.dwError;

                                        bPingError:=true;

                                   end

                      else//if (Ping(dwAddr,dwTimeOut,htsr,i))then

                             begin//ping failed

                                  memResult.Lines.Add(inttostr(i)+' Ping failed');

                             end;

                 end;// for j:=1 to dwPingsPerHost do

             htrr.Address := htsr.Address;

             if (htrr.dwError = 0)then

                htrr.avgRTT := Round(totalRTT / dwPingsPerHost)

             else

                 begin

                      htrr.minRTT := 0;

                      htrr.avgRTT := 0;

                      htrr.maxRTT := 0;

                 end;

             //show trace result here

             if htrr.dwError=0 then

                begin

                memResult.Lines.Add(Format('%d  %d ms  %d ms  %d ms  %d.%d.%d.%d'#13#10,

                [i,

                htrr.minRTT,

                htrr.avgRTT,

                htrr.maxRTT,

                ord(htrr.Address.S_un_b.s_b1),

                ord(htrr.Address.S_un_b.s_b2),

                ord(htrr.Address.S_un_b.s_b3),

                ord(htrr.Address.S_un_b.s_b4)]));

                memResult.update;

                end

             else

                 memResult.Lines.Add(Format('%d    Error:%d',[i,htrr.dwError]));

             memResult.Update;

             if (dwaddr=htrr.Address.S_addr)then

             //reach the final host

                bReachedHost:=true;

        end;// of for i:=1 to nHops do

end;

function TTraceRouteForm.Ping(dwAddr:DWORD;TimeOut:Word;var htsr:THostTraceSingleReply;nTTL:Byte):boolean;

var

     IPOpt:TIPOptionInformation;// IP Options for packet to send

     pReqData,pRevData:PChar;

     pIPE:PIcmpEchoReply;// ICMP Echo reply buffer

     FSize: DWORD;

     BufferSize:DWORD;

     temp:Integer;

     hICMP:THandle;

begin

       Result:=false;

       hICMP:=IcmpCreateFile();

       if hICMP=INVALID_HANDLE_VALUE then

          begin

               //Could not get a valid icmp handle

               exit;

          end;

       FSize := 40; //package size

       BufferSize := SizeOf(TICMPEchoReply) + FSize;

       GetMem(pRevData,FSize);

       GetMem(pIPE,BufferSize);

       //set up the option structure

       ZeroMemory(@IPOpt,SizeOf(TIPOptionInformation));

       IPOpt.TTL:=nTTL;

       FillChar(pIPE^, SizeOf(pIPE^),0);

       pIPE^.Data := pRevData;

       GetMem(pReqData,5);//data package size = 5 byte

       FillChar(pReqData^,5,65);

       temp:=IcmpSendEcho(hICMP, dwAddr, pReqData, 5,

                   @IPOpt,pIPE, BufferSize, TimeOut);

       if temp=0 then

            begin

                 htsr.dwError:=GetLastError();

            end

       else

           begin

                //ping success,copy info to return structure;

                htsr.Address.S_addr:=pIPE^.Address;

                htsr.RTT:=pIPE^.RTT;

                Result:=true;

           end;

       //Free up the memory we allocated

       FreeMem(pRevData);

       FreeMem(pIPE);

       //Close the ICMP handle

       IcmpCloseHandle(hIcmp);

end;

procedure TTraceRouteForm.FormCreate(Sender: TObject);

begin

   //update view

   MemResult.Font.Color:=clHighlightText;

   MemResult.Font.Name:='Terminal';

   MemResult.Font.Size:=10;

   MemResult.Color:= clNone;

end;

end.