Traceroute mit ICMP (indy)



  • hallo,

    will einen ganz normalen traceroute durchführen (wie in der konsole).

    habe folgendes dazu in einem delphi-forum gelesen:

    Es wird in einer schleife solange gepingt und der TTL (hop) immer um eines erhöht bis als Meldung ein rsEcho kommt.
    Wenn als Meldung rsErrorTTLExceeded kommt weiss Du das der Ping
    bei einem Router angekommen ist der dir seine eigene IP zurücksendet.

    Naja, schaue dir das Demo einfach mal an.

    leider gibt es wohl beim bcb 6.0 prof kein example dazu, deshalb habe ich versucht, aus diesen angaben folgenden quelltext zu "basteln".

    ICMP->Host = Adresse;
      ICMP->TTL = 0;
      while(!rsEcho)
       {
        ICMP->TTL += 1;
        ICMP->Ping();
        Application->ProcessMessages();
       }
    

    Zum Ausgeben im Memo, habe ich die Beispielsfunktion unter Indy > Ping genommen:

    void __fastcall TForm1::ICMPReply(TComponent *ASender,
          const TReplyStatus &AReplyStatus)
    {
        AnsiString sTime, result[5];
    
         // TODO: Check for error on ping reply (ReplyStatus->MsgType?)
         if(AReplyStatus.MsRoundTripTime == 0)
         {
              sTime = "<1";
         }
         else
         {
              sTime = "=";
         }
    
         result[0] = IntToStr(AReplyStatus.BytesReceived);
         result[1] = AReplyStatus.FromIpAddress;
         result[2] = IntToStr((int)AReplyStatus.SequenceId);
         result[3] = IntToStr((int)AReplyStatus.TimeToLive);
         result[4] = sTime;
         result[5] = IntToStr(AReplyStatus.MsRoundTripTime);
    
         Memo1->Lines->Add(result[0] + " bytes from " + result[1] +
                                ": icmp_seq=" + result[2] + " ttl=" + result[3] +
                                " time" + result[4] + result[5] + " ms");
    
    }
    

    in der ausgabe werden wahrscheinlich die areplystatus.xxxxxx nicht stimmen (weil ein traceroute sieht ja anders aus) - die frage ist nur, wie schaffe ich es dann mit dieser indykomponenter (oder alternative?) ein traceroute zu erzeugen.

    grüße

    hagbard



  • Der Beitrag bezog sich sicherlich auf die Beispiele von der Indy-Website (Downloads -> Indy 8).

    void __fastcall TfrmMain::acTraceExecute(TObject *Sender)
    {
     char *s=new char[256];//used because BCB4 AnsiString Sprintf is different than bcb5 sprintf
      int TTL;
      bool Reached;
     TListItem* aItem;
    
      TTL = 0;
      Reached = false;
      lvTrace->Items->Clear();
      do
       { TTL++;
        IdIcmpClient->Host = ResolvedHost;
        IdIcmpClient->TTL = TTL;
        IdIcmpClient->ReceiveTimeout = 5000;
        IdIcmpClient->Ping();
        aItem =lvTrace->Items->Add();
        aItem->SubItems->Clear();
        aItem->SubItems->Append(AnsiString(TTL));
        switch (IdIcmpClient->ReplyStatus.ReplyStatusType)
        {
        case  rsEcho:
        {
            aItem->SubItems->Add(IdIcmpClient->ReplyStatus.FromIpAddress);
            sprintf(s,"Reached in : %d ms",IdIcmpClient->ReplyStatus.MsRoundTripTime);
            aItem->SubItems->Add(s);
            Reached = true;
            break;
         }
         case rsError:
            {
            aItem->SubItems->Add(IdIcmpClient->ReplyStatus.FromIpAddress);
            aItem->SubItems->Add("Unknown error.");
            break;
            }
         case rsTimeOut:
         {
            aItem->SubItems->Add("?.?.?.?");
            aItem->SubItems->Add("Timed out.");
            break;
         }
         case rsErrorUnreachable:
         { aItem->SubItems->Add(IdIcmpClient->ReplyStatus.FromIpAddress);
           sprintf(s,"Destination network unreachable %d",IdIcmpClient->ReplyStatus.MsRoundTripTime);
           aItem->SubItems->Add(s);
            break;
         }
          case rsErrorTTLExceeded:
            {
            aItem->SubItems->Add(IdIcmpClient->ReplyStatus.FromIpAddress);
            sprintf(s,"TTL=%d",IdIcmpClient->ReplyStatus.TimeToLive);
            aItem->SubItems->Add(s);
            break;
          }
        }; // case
        Application->ProcessMessages();
       }
      while  ((!Reached)&& (TTL < StrToInt(seMaxHops->Text))&&(!Stopped));
    delete []s;
    }
    


  • vielen dank für das posting!

    jetzt noch eine frage, ich komme eine fehlermeldung bei folgender zeile:

    aItem =lvTrace->Items->Add();
    

    das problem ist, ich weiß nicht was lvTrace ist?
    Dachte, es sei eine Listbox, mit dem lieg ich aber wohl falsch (wegen der fehlermeldung).

    danke.

    grüße

    hagbard



  • Eigentlich wollte ich gar keinen Code posten, das hab ich nun davon. 😮 😉
    Lad dir doch die Beispiele herunter!

    lvTrace ist ein ListView.

    PS. Falls das nicht klar geworden war: o.g. Code stammt aus besagten Beispielen von der Website.



  • vielen Dank,

    ich sollte auch am Abend mein Hirn einschalten ;).
    solche mods würd ich mir in so manch anderem forum auch wünschen!

    grüße

    hagbard


Log in to reply