Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 491
  • Last Modified:

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
0
Bruce Sandeman
Asked:
Bruce Sandeman
1 Solution
 
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

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now