Monday, May 14, 2007

Developing a Ping function in Visual C++ and using it in VB .Net / C#

In this article, I will explain how to create a function for checking the connectivity between two machines programatically. It will be implemented as a Visual C++ dll (Win32). Also, I will explain how to create VB .Net and C# wrappers for this dll, so that this dll can be accessed from these languages very easily.

Ping is a program that tests connectivity between two systems running TCP/IP, checking whether or not another host is reachable. The program, originally written by Mike Muuss (http://ftp.arl.mil/~mike/ping.html), uses ICMP echo request/reply messages, but does not use a transport layer (TCP or UDP). Ping also measures the round-trip time to the host.

The Internet Control Message Protocol (ICMP)

The ICMP protocol includes the so-called Echo request and Echo reply messages. A host sends an ICMP echo request message to a specified destination. Any machine that receives an echo request formulates an echo reply and returns it to the original sender. The echo request and associated reply can be used to test whether a destination is reachable and responding. In general you can use this functionality whenever you need some low-level, application-independent reachability info.

Microsoft has their own API for an ICMP.DLL that their ping and tracert applications use (which are both non-GUI text-based console applications). This is a proprietary API, and all function calls that involve network functions operate in blocking mode. They still include it with WinSock 2 implementations, and are documented for the Windows CE platform. For the details about ICMP API, please visit the site www.sockets.com/ms_icmp.htm.

Microsoft used to disclaim this API about as strongly as possible. The README.TXT that once accompanied it said:

[DISCLAIMER]

We have had requests in the past to expose the functions exported from icmp.dll. The files in this directory are provided for your convenience in building applications which make use of ICMPSendEcho(). Notice that the functions in icmp.dll are not considered part of the Win32 API and will not be supported in future releases. Once we have a more complete solution in the operating system, this DLL, and the functions it exports, will be dropped.

Despite this frightening warning, seems Microsoft changed their mind. It doesn't look like the API going away any time soon, as it remains available in new platforms. Fortunately, we have an alternative with raw sockets and setsockopt(IP_TTL) support in WinSock 2 implementations. I will try to create another version of this function, using this alternative.

The Technique

The ICMPSendEcho() function sends an ICMP echo request to the specified destination IP address and returns any replies received within the timeout specified. The API is synchronous, requiring the process to spawn a thread before calling the API to avoid blocking. An open IcmpHandle is required for the request to complete. IcmpCreateFile() and IcmpCloseHandle() functions are used to create and destroy the context handle.

No comments: