Ping a computer using TCP stacks

.

This class addresses a common problem: how to ping a computer from a Win95 machine using the MS-TCP stacks. This will also work for NT 3.51 and 4.0. To make the problem more complex, MS did not include a mechanism for doing this in it's Winsock implementation.

The way around the problem is in using the ICMP DLL. This workaround is highly discouraged by Microsoft, but until Winsock 2.0, there was no other way to do a simple ping.

The problem: given a computer name, or given an IP address, ping the computer and return the ping response time. This requires access to the ICMP DLL, and to some of the socket structures provided in CSocket. Also, the class is derived from CSocket for future extension purposes.

Please note that to run this you'll need to get the ICMPAPI.H, ICMP.LIB, and IPEXPORT.H files from Microsoft, and place the lib and include files in your build settings. They are available on the Microsoft Developers Network CD's, and I believe on the Microsoft Web site as well.

The class includes four public functions:

unsigned long ResolveIP(CString strIP)
unsigned long ResolveName(CString strHostName)
CString GetIP(unsigned long ulIP)
DWORD PingHost(unsigned long ulIP, int iPingTimeout)

ResolveIP takes a CString IP address (i.e. "123.123.123.123"), and returns it's byte-ordered network address.

ResolveName takes a CString host name (i.e. ComputerName), resolves the name through DNS or WINS, and then returns the byte-ordered network address. Note that this uses a blocking GetHostByName.

GetIP takes the byte-ordered network address, and returns the IP address as a CString (i.e. "123.123.123.123").

PingHost takes the byte-ordered network address, a timeout integer, pings the address, and returns the ping response time.

/*
//------------------------------------------------------------------------------------------------------------------
//icmpecho.h
//------------------------------------------------------------------------------------------------------------------
*
class CIcmpEcho : public CSocket
{
// Attributes
public:

// Operations
public:
	CIcmpEcho();
	virtual ~CIcmpEcho();

	unsigned long ResolveIP(CString strIP);
	unsigned long ResolveName(CString strHostName);

	DWORD PingHost(unsigned long ulIP, int iPingTimeout);

	CString GetIP(unsigned long ulIP);

// Overrides
public:
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CIcmpEcho)
	//}}AFX_VIRTUAL

	// Generated message map functions
	//{{AFX_MSG(CIcmpEcho)
		// NOTE - the ClassWizard will add and remove member functions here.
	//}}AFX_MSG

// Implementation
protected:
};
/////////////////////////////////////////////////////////////////////////////







/*
//------------------------------------------------------------------------------------------------------------------
//icmpecho.cpp
//------------------------------------------------------------------------------------------------------------------
*
// IcmpEcho.cpp : implementation file
//

#include "IcmpEcho.h"

extern "C" {
#include "ipexport.h"
#include "icmpapi.h"
}

#define PING_TIMEOUT 100

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CIcmpEcho

CIcmpEcho::CIcmpEcho()
{
}

CIcmpEcho::~CIcmpEcho()
{
}


// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CIcmpEcho, CSocket)
	//{{AFX_MSG_MAP(CIcmpEcho)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif	// 0

/////////////////////////////////////////////////////////////////////////////
// CIcmpEcho member functions
unsigned long CIcmpEcho::ResolveIP(CString strIP)
{
	//Task 1:	Given IP Address i.e. "111.111.111.111",
	//	Return Network byte ordered address (ulIP)

	unsigned long ulIP;

	ulIP =(IPAddr)inet_addr(strIP);

	return ulIP;
}

unsigned long CIcmpEcho::ResolveName(CString strHostName)
{
	//Task 1:	Resolve HostName (through DNS or WINS, whichever appropriate)
	//Task 2:	Return network byte ordered address (ulIP)

	unsigned long ulIP;
	hostent* phostent;

	phostent = gethostbyname(strHostName);
	
	if (phostent == NULL)
		return 0;

	ulIP = *(DWORD*)(*phostent->h_addr_list);

	return ulIP;

}

DWORD CIcmpEcho::PingHost(unsigned long ulIP, int iPingTimeout)
{
	//Task 1:	Open ICMP Handle
	//Task 2:	Create Structure to receive ping reply
	//Task 3:	SendPing (SendEcho)
	//Task 4:	Close ICMP Handle
	//Task 5:	Return RoundTripTime

	unsigned long ip = ulIP;

	HANDLE icmphandle = IcmpCreateFile();

	char reply[sizeof(icmp_echo_reply)+8];

	icmp_echo_reply* iep=(icmp_echo_reply*)&reply;
	iep->RoundTripTime = 0xffffffff;

	IcmpSendEcho(icmphandle,ip,0,0,NULL,reply,sizeof(icmp_echo_reply)+8,iPingTimeout);

	IcmpCloseHandle(icmphandle);

	return iep->RoundTripTime;

}

CString CIcmpEcho::GetIP(unsigned long ulIP)
{
	//Task 1:	Given a host order ulIP Address
	//	Return a IP address in format of xxx.xxx.xxx.xxx

	LPSTR szAddr;

	struct in_addr inetAddr;
	
	inetAddr.s_addr = (IPAddr)ulIP;

	szAddr = inet_ntoa(inetAddr);

	CString csIP = szAddr;

	return csIP;

}



Comments

  • adding icmp.lib in Unicode creates problems

    Posted by Legacy on 01/06/2004 12:00am

    Originally posted by: Digh


    Could not link icmp.lib in the Unicode based Vc code.

    when tried #pragma comment it gives link error " cannot open file icmp.lib"

    can any one please help out?

    thanks,
    digh

    Reply
  • When making exe everything work, when making DLL no

    Posted by Legacy on 09/19/2002 12:00am

    Originally posted by: Andy

    Hi !

    When I created exe file (running) in which I used icmp.lib, everything worked ok, but when I wanted create .DLL ping doesn't work.

    I need DLL so I can link it to Java via JNI (Java Native Interface), but it seems that icmp.lib is not linked in.
    Error produced on CreateIcmpFile(0 is 127, which means Specified Procedure Could not be found.

    Does anybody have any idea how can I solve this problem?

    Andy

    Reply
  • The cause for the failure of a computer when ping fails

    Posted by Legacy on 09/01/2002 12:00am

    Originally posted by: Prasad

    Thats great. But can u pl. guide me how to find out what caused the node to fail in anetwork when threr is no response for ping from the computer.

    Thanks
    Prasad

    Reply
  • Bug related to the return value.

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

    Originally posted by: Justin Oh

    I found a bug in the code.
    
    

    DWORD CIcmpEcho::PingHost(unsigned long ulIP, int iPingTimeout)
    {
    .
    .
    .
    return iep->RoundTripTime; // Bug

    }


    Although an invalid IP address is inputed, "iep->RoundTripTime" is filled with valid value.

    Therefore, you should check error. I modified the code as follows;

    DWORD CIcmpEcho::PingHost(unsigned long ulIP, int iPingTimeout)
    {
    //Task 1: Open ICMP Handle
    //Task 2: Create Structure to receive ping reply
    //Task 3: SendPing (SendEcho)
    //Task 4: Close ICMP Handle
    //Task 5: Return RoundTripTime

    unsigned long ip = ulIP;

    HANDLE icmphandle = IcmpCreateFile();

    char reply[sizeof(icmp_echo_reply)+8];

    icmp_echo_reply* iep=(icmp_echo_reply*)&reply;
    iep->RoundTripTime = 0xffffffff;

    IcmpSendEcho(icmphandle,ip,0,0,NULL,reply,sizeof(icmp_echo_reply)+8,iPingTimeout);

    IcmpCloseHandle(icmphandle);

    /////////////////////////////////////////////
    // Error check
    switch( iep->Status )
    {
    case IP_SUCCESS: //Error free
    break;
    case IP_REQ_TIMED_OUT: //Timeout
    //Timeout handling
    //iep->RoundTripTime = 0xffffffff;
    break;
    default: //Error
    //Error handling
    //iep->RoundTripTime = 0;
    break;
    }

    return iep->RoundTripTime;

    }

    You can also check the error codes by GetLastError() after calling IcmpSendEcho() and find error codes from the "IPEXPORT.H" file.

    Reply
  • Not working for Windows '95

    Posted by Legacy on 07/23/2001 12:00am

    Originally posted by: albert

    Hello,

    I tried the code and it works just fine under windows NT, but for windows '95 the functioncall PingHost returns -1.

    Who had the same problem, and how was it solved???

    regards

    Reply
  • ResolveName not working on NT

    Posted by Legacy on 01/29/2000 12:00am

    Originally posted by: Mike English

    I am able to get ResolveIP to work just fine using my local IP address on a local network. When I use my computer name, however, ResolveName always returns 0.0.0.0. My operating system is Windows NT 4.0 with SP5. The code I use to check the address is:

    CIcmpEcho iEcho ;
    unsigned long lId ;
    DWORD dwTime ;
    CString sMsg ;
    CString sIP ;
    CString sText ;

    m_editBox.GetWindowText( sText ) ;
    if ( sText.Left(1) >= "0" && sText.Left(1) <= "9" )
    {
    // resolve IP address
    lId = iEcho.ResolveIP( sText ) ;
    }
    else
    {
    // resolve name
    lId = iEcho.ResolveName( sText ) ;
    }
    sIP = iEcho.GetIP( lId ) ;
    dwTime = iEcho.PingHost( lId, 1000 ) ;
    sMsg.Format( "Address Was: %s \r\n Time Was: %i", sIP, dwTime ) ;
    AfxMessageBox( sMsg ) ;

    Reply
  • Can you do this (Ping) using any other language ?

    Posted by Legacy on 10/18/1999 12:00am

    Originally posted by: Gauri

    Can you do it using any other language e.g Java? How?

    Reply
  • Unresolved externals?

    Posted by Legacy on 05/13/1999 12:00am

    Originally posted by: Z.J. Chao

    I have added the source code and icmp headers in my empty project created by AppWizard. Also I added the headers <afxwin.h> and <afxsock.h>. But it cannot be linked correctly. The error shows as:
    msvcrtd.lib(crtexe.obj) : error LNK2001: unresolved external symbol _main
    Debug/icmp.exe : fatal error LNK1120: 1 unresolved externals
    How can I solve this problem? Thanks very much.

    Reply
  • 3 unresolved symbols after solving precompiled header...

    Posted by Legacy on 04/27/1999 12:00am

    Originally posted by: Peter Sieg

    First I received a problem with precomiled header...
    After guessing around with the #include stuff, everything
    compiled fine. Nut now I have unresolved symbols?
    --------------------Configuration: ping - Win32 Debug--------------------
    Linking...
    icmpecho.obj : error LNK2001: unresolved external symbol _IcmpCloseHandle@4
    icmpecho.obj : error LNK2001: unresolved external symbol _IcmpSendEcho@32
    icmpecho.obj : error LNK2001: unresolved external symbol _IcmpCreateFile@0
    Debug/ping.exe : fatal error LNK1120: 3 unresolved externals
    Error executing link.exe.

    I have downloaded the header files and icmp.lib and placed
    them in the msdevstd\include (*.h) and ..\lib (icmp.lib)

    I have also tried to enter the lib under settings and get
    ..invalid file...?

    Someone know a way to get to an successful link?
    I know, that the symbols are defined in icmp.lib/dll!

    I am using VC++4.0 under NT4.0 SP3.
    My e-mail: Peter.Sieg.PS@hr-gmbh.de


    Reply
  • Where is the icmpapi.h and ipexport.h

    Posted by Legacy on 01/23/1999 12:00am

    Originally posted by: lixuewen

    I can't find the icmpapi.h and ipexport.h. Would you like upload these
    
    files? thanks!

    Reply
  • Loading, Please Wait ...

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

Top White Papers and Webcasts

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • 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