会员: 密码:  免费注册 | 忘记密码 | 会员登录 网页功能: 加入收藏 设为首页 网站搜索  
技术文档 > Delphi
跟踪目的地经过的IP地址
发表日期:2003-05-28 00:00:00作者: 出处:  

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.

返回顶部】 【打印本页】 【关闭窗口

关于我们 / 给我留言 / 版权举报 / 意见建议 / 网站编程QQ群   
Copyright ©2003- 2024 Lihuasoft.net webmaster(at)lihuasoft.net 加载时间 0.00408