[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 497
  • 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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

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