ICMP messages

How can you send ICMP messages and listen for ICMP messages?
I am trying to write a win95 version of unix traceroute.
cheers
Bruce
Bruce SandemanAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

chrisamblerCommented:
You need to load the ICMP DLL. For your .h file:

// === Structures Required by the ICMP.DLL ====================================

typedef struct {
   unsigned char Ttl;                                        // Time To Live
   unsigned char Tos;                                        // Type Of Service
   unsigned char Flags;                                      // IP header flags
   unsigned char OptionsSize;                  // Size in bytes of options data
   unsigned char *OptionsData;                       // Pointer to options data
} IP_OPTION_INFORMATION, * PIP_OPTION_INFORMATION;


typedef struct {
   DWORD Address;                                           // Replying address
   unsigned long  Status;                                       // Reply status
   unsigned long  RoundTripTime;                         // RTT in milliseconds
   unsigned short DataSize;                                   // Echo data size
   unsigned short Reserved;                          // Reserved for system use
   void *Data;                                      // Pointer to the echo data
   IP_OPTION_INFORMATION Options;                              // Reply options
} IP_ECHO_REPLY, * PIP_ECHO_REPLY;

typedef HANDLE(WINAPI *ICF)(VOID);
typedef BOOL(WINAPI *ICH)(HANDLE);
typedef DWORD(WINAPI *ISE)(HANDLE, DWORD, LPVOID, WORD, PIP_OPTION_INFORMATION, LPVOID, DWORD, DWORD);

HINSTANCE hIcmp;
ICF pIcmpCreateFile;
ICH pIcmpCloseHandle;
ISE pIcmpSendEcho;

Somewhere before you need the code, initialize the DLL as:

hIcmp = LoadLibrary("ICMP.DLL");
pIcmpCreateFile = (ICF)GetProcAddress(hIcmp, "IcmpCreateFile");
pIcmpCloseHandle = (ICH)GetProcAddress(hIcmp, "IcmpCloseHandle");
pIcmpSendEcho = (ISE)GetProcAddress(hIcmp, "IcmpSendEcho");

The following #defines will indicate the status of a PING,
using the ICMP protocol:

#define PING_ALIVE            0
#define PING_DEAD            1
#define PING_NODNS            2
#define PING_ERROR            255
#define PING_MODE_HOST            0
#define PING_MODE_ADDR            1

Here, then, is my code for a Ping. Mode is the mode of the
ping (either by host name or IP), host is the host name or
IP, response is the textual response given back, nsRet and
hostRet are nslookup-like return information strings.

int PingHost(int mode, CString &host, CString &response, CString &nsRet, CString &hostRet)
{
      char                  szBuffer[64];                  // Packet Buffer
      DWORD                  dwStatus;      
      struct hostent      *phostent;

      response = "";
      
      if (mode == PING_MODE_HOST)

            phostent = gethostbyname(host);

      else {

            char      hRead[4];
            int            o1, o2, o3, o4;

            sscanf(host, "%d.%d.%d.%d", &o1, &o2 ,&o3 ,&o4);

            hRead[0] = o1;
            hRead[1] = o2;
            hRead[2] = o3;
            hRead[3] = o4;

            phostent = gethostbyaddr(hRead, 4, PF_INET);
      }

      if (!phostent) {

            int err = WSAGetLastError();

            switch (err) {

                  case WSANOTINITIALISED :
                        response = "Startup Error"; break;
                  case WSAENETDOWN :
                        response = "Network Failure"; break;
                  case WSAHOST_NOT_FOUND :
                        response = "No Authority"; break;
                  case WSATRY_AGAIN :
                        response = "Server Fail"; break;
                  case WSANO_RECOVERY :
                        response = "Fatal Error"; break;
                  case WSANO_DATA :
                        response = "No Data Record"; break;
                  case WSAEINPROGRESS :
                        response = "Blocked"; break;
                  case WSAEINTR :
                        response = "Canceled"; break;
                  default :
                        response = "No Address Found"; break;
            }

            return PING_NODNS;
      }

      hostRet = phostent->h_name;

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

      if (!pIcmpCreateFile || !pIcmpCloseHandle || !pIcmpSendEcho) {

            response = "DLL Error";

            return PING_ERROR;
      }

      HANDLE hIP = pIcmpCreateFile();

      if (hIP == INVALID_HANDLE_VALUE) {

            response = "Handle Error";

            return PING_ERROR;
      }
      
      memset(szBuffer, '\xAA', 64);

      PIP_ECHO_REPLY pIpe = (PIP_ECHO_REPLY)GlobalAllocPtr(GHND, sizeof(IP_ECHO_REPLY) + 64);

      int retCode = PING_ALIVE;

      if (pIpe) {

            pIpe->Data = m_ns1.GetBuffer(128);
            pIpe->DataSize = 64;      

            dwStatus = pIcmpSendEcho(hIP, *dwIPAddr, szBuffer, 64, NULL, pIpe, sizeof(IP_ECHO_REPLY) + 64, 5000);

            if (dwStatus) {

                  char nsResp[80];
                  char nsSet[80];

                  sprintf(nsSet, "%d.%d.%d.%d",
                              LOBYTE(LOWORD(pIpe->Address)), HIBYTE(LOWORD(pIpe->Address)),
                              LOBYTE(HIWORD(pIpe->Address)), HIBYTE(HIWORD(pIpe->Address)));

                  nsRet = nsSet;

                  sprintf(nsResp, "%d/%d", pIpe->RoundTripTime, pIpe->Options.Ttl);

                  response = nsResp;

            } else {

                  response = "No Response";

                  retCode = PING_DEAD;
            }

            GlobalFreePtr(pIpe);

      } else {

            retCode = PING_ERROR;
      }
      
      pIcmpCloseHandle(hIP);

      return retCode;
}
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.