Page 1 of 1

Traceroute

Posted: Fri Feb 16, 2007 12:18 am
by peterb
Code updated for 5.20+

Here is a source code for tracert.

Code: Select all

EchoMessage.s = "echo" 
ResultSize.l = SizeOf(ICMP_ECHO_REPLY) + Len(EchoMessage) 
*Result = AllocateMemory(ResultSize) 
*Echo.ICMP_ECHO_REPLY = *Result

ip_option.IP_OPTION_INFORMATION
  
sIPAddress.s = "216.239.59.103" ; www.google.com
    
If Len(sIPAddress ) > 0 
  hFile.l     = IcmpCreateFile_() 
  IPAddress.l = inet_addr_(sIPAddress)

  For ttl_int = 1 To 255

    ip_option\Ttl = ttl_int

    Echo_Result.l = 0
    counter.l     = 0
        
    While Echo_Result = 0 And counter < 3
      counter + 1
      Echo_Result = IcmpSendEcho_(hFile, IPAddress, EchoMessage, Len(EchoMessage), ip_option, *Result, ResultSize, 1500) 
         
      If Echo_Result = 1
        Debug "address : " + IPString(*Echo\Address)
        Debug "rtt     : " + StrU(*Echo\RoundTripTime, 2)
        
        If *Echo\Status = 0 : Break 2 : EndIf
      EndIf
 
    Wend
        
    If Echo_Result = 0
      Debug ("unknown address")
    EndIf

    Debug "-----------------------------"

  Next

  IcmpCloseHandle_(hFile) 

EndIf 
    
End 

Posted: Fri Feb 16, 2007 3:11 am
by Tommeh
Awesome, Thanks very much

When i saw the title i thought you had just captured the output from cmd's tracert command but this is very good, now we just need to add a dns hostname resolver and we will be all set :)

I could find quiet a few uses for this, again good work!

Re: Traceroute

Posted: Fri Feb 16, 2007 6:07 am
by NoahPhense
nice ..

- np

Posted: Fri Feb 16, 2007 8:26 am
by dige
Cool, thank you!
And like Tommeh said, a DNS resolve would be nice. :D

Now with IP address name.

Posted: Fri Feb 16, 2007 8:49 am
by peterb
Version with IP address name

Code: Select all


EchoMessage.s = "echo" 
ResultSize.l = SizeOf(ICMP_ECHO_REPLY) + Len(EchoMessage) 
*Result = AllocateMemory(ResultSize) 
*Echo.ICMP_ECHO_REPLY = *Result

ip_option.IP_OPTION_INFORMATION
  
sIPAddress.s = "216.239.59.103" ; www.google.com

If InitNetwork()
      
  If Len(sIPAddress ) > 0 
    hFile.l     = IcmpCreateFile_() 
    IPAddress.l = inet_addr_(sIPAddress)
  
    For ttl_int = 1 To 255
  
      ip_option\Ttl = ttl_int
  
      Echo_Result.l = 0
      counter.l     = 0
          
      While Echo_Result = 0 And counter < 3
        counter + 1
        Echo_Result = IcmpSendEcho_(hFile, IPAddress, EchoMessage, Len(EchoMessage), ip_option, *Result, ResultSize, 1500) 
        
        If Echo_Result = 1
          Debug "address : " + IPString(*Echo\Address)
          Debug "rtt     : " + StrU(*Echo\RoundTripTime, 2)
          
          bip = *Echo\Address
          *retval = gethostbyaddr_(@bip, 4, #AF_INET) 
          If *retval > 0 
            Debug  "name    : " + PeekS(PeekL(*retval)) 
  
          EndIf 
          
          If *Echo\Status = 0 : Break 2 : EndIf
        EndIf
   
      Wend
          
      If Echo_Result = 0
        Debug ("unknown address")
      EndIf
  
      Debug "-----------------------------"
  
    Next
  
    IcmpCloseHandle_(hFile) 
  
  EndIf 
EndIf

End 


Posted: Fri Feb 16, 2007 9:10 am
by dige
Excellent!

Posted: Fri Feb 16, 2007 10:01 am
by dige
here is a litte gui around : PB-TraceRoute .. have fun

Code: Select all

; 16/02/2007 TraceRoute by peterb, Gui by dige

;- Window Constants
Enumeration
  #hWnd
EndEnumeration

;- Gadget Constants
Enumeration
  #hWnd_LI_Route
  #hWnd_T_IP
  #hWnd_IP_ToTrace
  #hWnd_T_Hops
  #hWnd_S_Hops
  #hWnd_CX_DNS
  #hWnd_B_Start
EndEnumeration

Procedure TraceRoute ( sIPAddress.s, MaxHops.l, DNS.b )
  Protected dummy.s, EchoMessage.s
  
  EchoMessage  = "echo"
  ResultSize.l = SizeOf(ICMP_ECHO_REPLY) + Len(EchoMessage)
  *Result = AllocateMemory(ResultSize)
  *Echo.ICMP_ECHO_REPLY = *Result
  ip_option.IP_OPTION_INFORMATION
  
  If sIPAddress
    ClearGadgetItemList( #hWnd_LI_Route )
    
    hFile.l     = IcmpCreateFile_()
    IPAddress.l = inet_addr_(sIPAddress)
      
    For ttl_int = 1 To MaxHops
      
      ip_option\Ttl = ttl_int
      
      Echo_Result.l = 0
      counter.l     = 0
      
      While Echo_Result = 0 And counter < 3
        counter + 1
        Echo_Result = IcmpSendEcho_(hFile, IPAddress, EchoMessage, Len(EchoMessage), ip_option, *Result, ResultSize, 1500)
        
        If Echo_Result = 1
          Count + 1
          dummy = Str(Count) + Chr(10) + StrU(*Echo\RoundTripTime, 2) + Chr(10)
          dummy + IPString(*Echo\Address) + Chr(10)
          
          If DNS
            bip = *Echo\Address
            *retval = gethostbyaddr_(@bip, 4, #AF_INET)
            If *retval > 0
              dummy + PeekS(PeekL(*retval))
            EndIf
          EndIf
          
          AddGadgetItem( #hWnd_LI_Route, -1, dummy )
          
          If *Echo\Status = 0 : Break 2 : EndIf
        EndIf
        
        Repeat
          Event = WindowEvent()
          If Event = #PB_Event_Gadget And EventGadget() = #hWnd_B_Start
            Break 3
          EndIf
        Until Not Event
        
      Wend
      
      If Echo_Result = 0
        dummy = Str(Count) + Chr(10) + StrU(*Echo\RoundTripTime, 2) + Chr(10)
        dummy + IPString(*Echo\Address) + Chr(10) + "Unknown Address"
        AddGadgetItem( #hWnd_LI_Route, -1, dummy )
      EndIf
      
      
    Next
      
    IcmpCloseHandle_(hFile)
  EndIf
EndProcedure
Procedure Open_hWnd()
  If OpenWindow(#hWnd, 356, 307, 514, 275, "PB Trace-Route",  #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered )
    If CreateGadgetList(WindowID(#hWnd))
      
      ;-
      ListIconGadget(#hWnd_LI_Route, 5, 5, 505, 240, "Nr.", 50, #PB_ListIcon_GridLines)
      AddGadgetColumn(#hWnd_LI_Route, 1, "RTT", 80)
      AddGadgetColumn(#hWnd_LI_Route, 2, "IP", 100)
      AddGadgetColumn(#hWnd_LI_Route, 3, "Name", 265)
      TextGadget(#hWnd_T_IP, 5, 255, 15, 15, "IP:")
      IPAddressGadget(#hWnd_IP_ToTrace, 25, 250, 125, 20)
      TextGadget(#hWnd_T_Hops, 175, 255, 55, 15, "Max. Hops:")
      StringGadget(#hWnd_S_Hops, 230, 250, 35, 20, "32", #PB_String_Numeric)
      SendMessage_(GadgetID(#hWnd_S_Hops), #EM_LIMITTEXT, 255, 0)
      CheckBoxGadget(#hWnd_CX_DNS, 285, 250, 45, 20, "DNS")
      ButtonGadget(#hWnd_B_Start, 345, 250, 165, 20, "Start Tracing")
      
    EndIf
  EndIf
EndProcedure

Open_hWnd()

If Not InitNetwork()
  DisableGadget( #hWnd_IP_ToTrace, #True )
  DisableGadget( #hWnd_B_Start, #True )
EndIf

IP = inet_addr_(GetClipboardText())
If IP <> -1
  SetGadgetState( #hWnd_IP_ToTrace, IP )
EndIf

SetGadgetState( #hWnd_CX_DNS, #True )

Repeat
  Event = WaitWindowEvent()
  
  If Event = #PB_Event_CloseWindow : Break
  ElseIf Event = #PB_Event_Gadget
    Select EventGadget()
      Case #hWnd_B_Start
        DisableGadget( #hWnd_IP_ToTrace, #True )
        SetGadgetText( #hWnd_B_Start, "Stop Tracing" )
        TraceRoute ( GetGadgetText(#hWnd_IP_ToTrace), Val(GetGadgetText(#hWnd_S_Hops)), GetGadgetState(#hWnd_CX_DNS))
        DisableGadget( #hWnd_IP_ToTrace, #False )
        SetGadgetText( #hWnd_B_Start, "Start Tracing" )
    EndSelect
  EndIf
ForEver

End

Posted: Fri Feb 16, 2007 1:00 pm
by Psychophanta
thank you peterb
and dige. 8)

Great !

Posted: Sat Feb 17, 2007 3:32 pm
by DominiqueB
Could you add the ability to do the same thing with the
adress: www.google.com instead of the ip ?
By adding a litle text field next to the ip adress one...

Thank's

Re: Great !

Posted: Sat Feb 17, 2007 7:58 pm
by Psychophanta
DominiqueB wrote:Could you add the ability to do the same thing with the
adress: www.google.com instead of the ip ?
By adding a litle text field next to the ip adress one...

Thank's
I use this function in the source below:

Code: Select all

Procedure.s GetIPAddress(servername.s,port.l); <- Obtener la IP dado el nombre de dominio (por la forma PB sin API externa):
  Protected connectionID.l=OpenNetworkConnection(servername,port)
  If connectionID=0:MessageRequester("error","Error opening connection"):ProcedureReturn "":EndIf
  servername.s=IPString(GetClientIP(connectionID))
  CloseNetworkConnection(connectionID)
  ProcedureReturn servername.s
EndProcedure
which is valid also for Linux for example.
But there are other using sockets which is faster, like:

Code: Select all

Procedure.s GetIpAddr(ComputerName.s); <- obtiene la IP de un nombre de host (convierte hostname en IP)
  If ComputerName
    If WSAStartup_($0101,wsa.WSADATA)=#NOERROR ; Try to access Windows sockets stuff...
      *host.HOSTENT=gethostbyname_(ComputerName) ; Get host information for named computer...
      WSACleanup_() ; Close Windows sockets stuff...
      If *host
        ProcedureReturn PeekS(inet_ntoa_(PeekL(PeekL(*host\h_addr_list))))
      EndIf
    EndIf
  EndIf
  ProcedureReturn "Unable to get IP"
EndProcedure
Here you have the source:

Code: Select all

; 16/02/2007 TraceRoute by peterb, Gui by dige and "Domain Name to IP" added by Psychophanta

;- Window Constants
Enumeration
  #hWnd
EndEnumeration
;- Gadget Constants
Enumeration
  #hWnd_LI_Route
  #hWnd_T_IP
  #hWnd_IP_ToTrace
  #hWnd_DN_ToTrace
  #hWnd_IP_or_DN
  #hWnd_T_Hops
  #hWnd_S_Hops
  #hWnd_CX_DNS
  #hWnd_B_Start
EndEnumeration
Procedure.s GetIPAddress(servername.s,port.l); <- Obtener la IP dado el nombre de dominio (por la forma PB sin API externa):
  Protected connectionID.l=OpenNetworkConnection(servername,port)
  If connectionID=0:MessageRequester("error","Error opening connection"):ProcedureReturn "":EndIf
  servername.s=IPString(GetClientIP(connectionID))
  CloseNetworkConnection(connectionID)
  ProcedureReturn servername.s
EndProcedure
Procedure TraceRoute ( sIPAddress.s, MaxHops.l, DNS.b )
  Protected dummy.s, EchoMessage.s
  EchoMessage  = "echo"
  ResultSize.l = SizeOf(ICMP_ECHO_REPLY) + Len(EchoMessage)
  *Result = AllocateMemory(ResultSize)
  *Echo.ICMP_ECHO_REPLY = *Result
  ip_option.IP_OPTION_INFORMATION
  If sIPAddress
    ClearGadgetItemList( #hWnd_LI_Route )
    hFile.l     = IcmpCreateFile_()
    IPAddress.l = inet_addr_(sIPAddress)
    For ttl_int = 1 To MaxHops
      ip_option\Ttl = ttl_int
      Echo_Result.l = 0
      counter.l     = 0
      While Echo_Result = 0 And counter < 3
        counter + 1
        Echo_Result = IcmpSendEcho_(hFile, IPAddress, EchoMessage, Len(EchoMessage), ip_option, *Result, ResultSize, 1500)
        If Echo_Result = 1
          Count + 1
          dummy = Str(Count) + Chr(10) + StrU(*Echo\RoundTripTime, 2) + Chr(10)
          dummy + IPString(*Echo\Address) + Chr(10)
          If DNS
            bip = *Echo\Address
            *retval = gethostbyaddr_(@bip, 4, #AF_INET)
            If *retval > 0
              dummy + PeekS(PeekL(*retval))
            EndIf
          EndIf
          AddGadgetItem( #hWnd_LI_Route, -1, dummy )
          If *Echo\Status = 0 : Break 2 : EndIf
        EndIf
        Repeat
          Event = WindowEvent()
          If Event = #PB_Event_Gadget And EventGadget() = #hWnd_B_Start
            Break 3
          EndIf
        Until Not Event
      Wend
      If Echo_Result = 0
        dummy = Str(Count) + Chr(10) + StrU(*Echo\RoundTripTime, 2) + Chr(10)
        dummy + IPString(*Echo\Address) + Chr(10) + "Unknown Address"
        AddGadgetItem( #hWnd_LI_Route, -1, dummy )
      EndIf
    Next
    IcmpCloseHandle_(hFile)
  EndIf
EndProcedure
Procedure Open_hWnd()
  If OpenWindow(#hWnd, 356, 307, 514, 275, "PB Trace-Route",  #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered )
    If CreateGadgetList(WindowID(#hWnd))
      ListIconGadget(#hWnd_LI_Route, 5, 5, 505, 240, "Nr.", 50, #PB_ListIcon_GridLines)
      AddGadgetColumn(#hWnd_LI_Route, 1, "RTT", 80)
      AddGadgetColumn(#hWnd_LI_Route, 2, "IP", 100)
      AddGadgetColumn(#hWnd_LI_Route, 3, "Name", 265)
      TextGadget(#hWnd_T_IP, 5, 255, 18, 15, "IP:")
      IPAddressGadget(#hWnd_IP_ToTrace, 25, 250, 145, 20)
      CheckBoxGadget(#hWnd_IP_or_DN, 180, 250, 75, 20, "IP or DN")
      TextGadget(#hWnd_T_Hops, 260, 255, 55, 15, "Max. Hops:")
      StringGadget(#hWnd_S_Hops, 315, 250, 35, 20, "32", #PB_String_Numeric)
      SendMessage_(GadgetID(#hWnd_S_Hops), #EM_LIMITTEXT, 255, 0)
      CheckBoxGadget(#hWnd_CX_DNS, 365, 250, 75, 20, "Show DNS")
      ButtonGadget(#hWnd_B_Start, 445, 250, 65, 20, "Start Tracing")
    EndIf
  EndIf
EndProcedure
Open_hWnd()
If InitNetwork()=0
  DisableGadget( #hWnd_IP_ToTrace, #True )
  DisableGadget( #hWnd_B_Start, #True )
EndIf
IP = inet_addr_(GetClipboardText())
If IP <> -1
  SetGadgetState( #hWnd_IP_ToTrace, IP )
EndIf
SetGadgetState( #hWnd_CX_DNS, #True )
Repeat
  Event = WaitWindowEvent()
  If Event = #PB_Event_CloseWindow : Break
  ElseIf Event = #PB_Event_Gadget
    Select EventGadget()
      Case #hWnd_B_Start
        If GetGadgetState(#hWnd_IP_or_DN)
          SetGadgetState(#hWnd_IP_or_DN,0)
          SetGadgetText(#hWnd_T_IP,"IP:")
          If CreateGadgetList(WindowID(#hWnd)):IPAddressGadget(#hWnd_IP_ToTrace, 25, 250, 145, 20):EndIf
          SetGadgetState(#hWnd_IP_ToTrace,inet_addr_(GetIPAddress(GetGadgetText(#hWnd_DN_ToTrace),80)))
          FreeGadget(#hWnd_DN_ToTrace)
        EndIf
        DisableGadget(#hWnd_IP_ToTrace,#True)
        SetGadgetText(#hWnd_B_Start,"Stop Tracing")
        TraceRoute(GetGadgetText(#hWnd_IP_ToTrace),Val(GetGadgetText(#hWnd_S_Hops)), GetGadgetState(#hWnd_CX_DNS))
        DisableGadget(#hWnd_IP_ToTrace,#False)
        SetGadgetText(#hWnd_B_Start,"Start Tracing")
      Case #hWnd_IP_or_DN
        If GetGadgetState(#hWnd_IP_or_DN)
          FreeGadget(#hWnd_IP_ToTrace)
          SetGadgetText(#hWnd_T_IP,"DN:")
          If CreateGadgetList(WindowID(#hWnd)):StringGadget(#hWnd_DN_ToTrace, 25, 250, 145, 20,""):EndIf
        Else:DN$=""
          FreeGadget(#hWnd_DN_ToTrace)
          SetGadgetText(#hWnd_T_IP,"IP:")
          If CreateGadgetList(WindowID(#hWnd)):IPAddressGadget(#hWnd_IP_ToTrace, 25, 250, 145, 20):EndIf
        EndIf
    EndSelect
  EndIf
ForEver
End
;Example of usage:
If InitNetwork()=0:MessageRequester("Error","Can't initialize the network",0):End:EndIf
Debug GetIPAddress("www.terra.es",80)

Thank's

Posted: Sun Feb 18, 2007 11:16 pm
by DominiqueB
Thank's a lot, it works great !

Dominique

Posted: Mon Feb 19, 2007 1:54 am
by yrreti
Thanks also.
Nice little program. :wink:

Posted: Mon Feb 19, 2007 3:47 am
by freak
If you are willing to go Win2k and newer only, you can also use this one for the
dns lookups: http://www.purebasic.fr/english/viewtop ... 886#182886

It is of course faster than first establishing a connection before getting the IP.
The reverse lookup also seems faster than the gethostbyaddr_() used in the trace, so it could speed it up a bit more.