Creating a Multi-Threaded Trace Route

.

Environment: VC6, NT4/Win2K—should work on any 32-bit Windows operating system that has Winsock2 libraries.

Overview

Sample code for a network "ping" is relatively easy to find. CodeGuru has several good examples and the SDK sample code has another good example. So what about trace route? With a little research I discovered that doing a trace route is really no more difficult than a ping. With a few minor modifications to the ping sample, it is possible to do a multi-threaded trace route. Trace route is really just a ping with the "time-to-live" option set to any number from 1 to the number of hops it takes to get to the destination. So, if it takes 10 hops to get to the destination and the "time-to-live" option is set to 5, the IP address that gets returned is the address of the fifth router along the way. The logical question is: "How many hops does it take?" Well, you don't really know until you get there. Basically, you just increment the time-to-live option until the returned IP address matches the destination IP address. The router names can be obtained by a simple call to "gethostbyaddr".

To call this code "multi-threaded" is a bit of a misnomer. The execution of the pings and ultimately the trace route happens in a single thread; the user interface is in a separate thread. All that is accomplished by this approach is that the user may stop the processing and view updates asynchronously.

This code also relies heavily on the Winsock-2 library (ws2_32.lib).

An Outline of the Approach

  1. This process depends on three variables: destination address, returned address (coming back from ping), and ttl (time-to-live).
  2. Get the destination address by calling "gethostbyname". Set the returned address to 0 and ttl to 1.
  3. While the returned address is not equal to the destination address, do the following: call ping, increment the ttl, and get the name of the returned address.

The Sample Code, Implementing the Approach

int TRThread::RunThread(void)
{
  int result = 0; 

  ClearAllItems();
  InitSockLibrary();

  struct hostent *hHost;
  struct sockaddr_in sin;
 
  // get the IP address of the destination
  HOSTENT * ent = gethostbyname(m_address);
  if (CheckKillFlag())
  {
    return result;
  }

  if (ent && ent->h_addrtype == AF_INET)
  {
    in_addr * final_ptr = (struct in_addr*)ent->h_addr_list[0];
    unsigned long ipfinal = final_ptr->S_un.S_addr;

    // initialize returned IP address and time-to-live (ttl)
    int ttl = 1;
    unsigned long ipback = 0;
    unsigned long ms = 0;

    while (ipback != ipfinal){
      hHost = 0; TRDeviceItem * item = new TRDeviceItem;

      // By checking the "kill flag" often, we are trying to
      // provide a responsive and well behaved worker thread.
        if (CheckKillFlag())
        {
          break;
        }

      // send a ping to the destination address, knowing that it
      // will only make it thru (ttl) routers before getting sent
      // back.
        if (Ping(m_address,ttl,ipback,ms))
        {
          sin.sin_family = AF_INET;
          sin.sin_addr.S_un.S_addr = ipback;

        // get the name of the router that bounced the ping back
        // (ipback)
        hHost = gethostbyaddr((char*)&sin.sin_addr, 4, PF_INET);

        // set up an item for the linked list
        item->SetIPAddress((unsigned long)ipback);
        item->SetResponseTime(ms);

        // if the router information is not null, extract the
        // router name
        if (hHost)
        {
          item->SetName(hHost->h_name);
        }
      }
      ttl++;
      if (CheckKillFlag())
      {
        break;
      }

      // synchronize block, locking access to linked list before
      // changing anything
      Wait();
      {
        // add the item to the linked list
        if (m_first_item == 0)
        {
          m_first_item = m_current_item = item;
        }
        else
        {
          m_current_item->SetNextItem(item);
          m_current_item = item;
        }

        m_total_items++;
        result++;
      }
      Release();

      // The base class (WorkerThread) stores a synchronized
      // variable usually used to calculate the percentage of
      // work done. This time we are using that variable to
      // store the number of hops so far.
      SetTotal(m_total_items); // If we're over the maximum number
                               // of hops, let's break outta here.
      if (ttl > MAX_HOPS)
      {
        break;
      }
    }
  }

  return result;
}

Some Information about the Sample Project

The sample project is basically an SDI application with a ListView. The trace route executes in a thread class derived from WorkerThread and the view class uses a timer to check the thread for updates. To execute the program, simply type in a Web site or Internet address and click Trace.

Downloads

Download demo project - 31 Kb



About the Author

Andy McGovern

Andy McGovern - Software Developer/Engineer. Special interests: astronomy, image processing, orbital mechanics, mathematics. Currently work at the Johns Hopkins University Applied Physics Laboratory on the science operations team for the CRISM instrument on the Mars Reconnaissance Orbiter.

Comments

  • Problem

    Posted by hamza178 on 11/26/2004 02:36am

    When I Build the EXE file with visual C++5 an error occured like this: Cannot open include file: 'afxdtctl.h': No such file or directory So, please till me how to fix the problem

    • Something else

      Posted by hamza178 on 12/14/2004 05:51pm

      Please, I need a copy from the file afxdtctl.h because it does not exist in my Visual C++5 and here are the output after i compiled the TR project: ********************************************** Deleting intermediate files and output files for project 'TR - Win32 Debug'. --------------------Configuration: TR - Win32 Debug-------------------- Compiling resources... Compiling... Command line warning D4002 : ignoring unknown option '/ZI' Command line warning D4002 : ignoring unknown option '/GZ' StdAfx.cpp C:\tracert_sample\Sample\vc6\Tr\stdafx.h(19) : fatal error C1083: Cannot open include file: 'afxdtctl.h': No such file or directory Error executing cl.exe. TR.exe - 1 error(s), 2 warning(s) ******************************************** So please give me some advice on how to build this project. Is possible that because i am using VC5 the program who are built with VC6 can't work in VC5. I mean Should i Upgrade to VC6. With my Best regards hamza178 Note: I would like to thank you for trying to solve my problems. That is very kind of you.

      Reply
    • Easy Ping and Trace route

      Posted by hamza178 on 12/14/2004 05:43pm

      Hi, I am hamza178.
      I would like a very simple ping and trace route programs so that i can understand how these programs work. I need that for my graduation project. Please help me if you can.
      Here is my e-mail if you need it:
      hamza178@yahoo.com
      
      With my best wishes
      Hamza

      Reply
    • Problem

      Posted by andyf4i on 11/26/2004 11:55am

      That include file is not central to making the "ping" code work. Just go into the "StdAfx.h" for the project and remove that include. If that doesn't work just play around with the include files until you figure out what you need and don't need. The "ping" stuff depends mainly on the socket library so there is no fundamental reason it won't work in vc5 although it was originally created in vc6. If all else fails create a new GUI-dialog project in vc5 and add the trace-route files one by one, resolving the conflicts as you go...shouldn't take long. Good luck.

      Reply
    Reply
  • How to connect to remote client

    Posted by Legacy on 12/04/2003 12:00am

    Originally posted by: pankajvnaik

    i have seen lots of code to connect to remote computer
    but can some one tell me how can i directly connect to my friend's computer through internet.
    Does it requires me to pass through some site like yahoo.

    if your answer is yes that i can directly connect to my friends computer then what will be the procedure.

    did i have to find out his dynamic ip
    if yes then how can i find my dynamic ip

    basically iwant to directly establish connection with my friend using only telnet and his ip

    Reply
  • how to thorugh firewall

    Posted by Legacy on 07/30/2003 12:00am

    Originally posted by: somasekhar

    It is excellent. However as ping can't work through firewall. what changes need to be done to make it work over firewall?

    sekhar

    Reply
  • Great!!!

    Posted by Legacy on 04/24/2003 12:00am

    Originally posted by: kaula

    learning

    Reply
  • code is working fine

    Posted by Legacy on 02/20/2003 12:00am

    Originally posted by: Awadhesh Kumar Paswan

    this code is working fine.
    thanks a lot.

    Reply
  • IP displayed wrong

    Posted by Legacy on 11/06/2002 12:00am

    Originally posted by: MiMec

    The IP addresses are displayed wrong in the list (reversed, e.g. 1.2.3.4 => 4.3.2.1).

    Reply
  • You have memory leaks!!!

    Posted by Legacy on 11/05/2002 12:00am

    Originally posted by: Robert V. Krakora

    Run the program in debug mode in Visual Studio and look at the out put Window in Visual Studio when you close your application...

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: August 14, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT Data protection has long been considered "overhead" by many organizations in the past, many chalking it up to an insurance policy or an extended warranty you may never use. The realities of today make data protection a must-have, as we live in a data driven society. The digital assets we create, share, and collaborate with others on must be managed and protected for many purposes. Check out this upcoming eSeminar and join eVault Chief Technology …

  • Protecting business operations means shifting the priorities around availability from disaster recovery to business continuity. Enterprises are shifting their focus from recovery from a disaster to preventing the disaster in the first place. With this change in mindset, disaster recovery is no longer the first line of defense; the organizations with a smarter business continuity practice are less impacted when disasters strike. This SmartSelect will provide insight to help guide your enterprise toward better …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds