An ICMP Class For MFC

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

CIcmp – An ICMP Class For MFC


Overview of ICMP

    ICMP (Internet Control Message Protocol) messages are normally sent from destination
    hosts and gateways to a source host to report problems with the Internet. While not
    designed to make the Internet Protocol absolutely reliable, these control messages
    can provide feedback about problems with the Internet communication environment.

    ICMP messages report errors in the processing of datagrams, but should not report
    errors in received ICMP messages (i.e. – No ICMP messages are sent about ICMP
    messages). Also, ICMP messages are only sent regarding fragment zero datagrams.

    ICMP messages are an integral part of the Internet Protocol, and are designed to
    immediately follow the IP header fields of an Internet datagram.

    ICMP defines the following message types:

      Message Number

      Message Type

      Meaning

      0

      Echo Reply

      Reply to Echo Request

      3

      Destination Unreachable

      Network or Host unknown

      4

      Source Quench

      Message too long or arrived too soon

      5

      Redirect

      The host can be reached through a different gateway

      8

      Echo Request

      Requests gateway/host to return sent data

      11

      Time Exceeded

      TTL exceeded

      12

      Parameter Problem

      Bad parameter in message header

      13

      Timestamp

      Requests gateway/host time in mSec

      14

      Timestamp Reply

      Gateway/host time in mSec

      15

      Information Request

      Request host network number

      16

      Information Reply

      Host network number

CIcmp Class Requirements

    The CIcmp class, derived from the MFC CSocket class,
    was developed to fill the requirement for class-based access to RAW
    sockets to perform ICMP echo
    requests. This class was designed using Microsoft’s VisualC++ version 4.2 and
    MFC, and was tested on both a WindowsNT 4.0 Workstation and Server using
    WindowsNT Winsock 2. Because of its reliance upon WindowsNT Winsock 2 structures,
    it will not work on Windows95. A version which will work with Windows95 will be
    available soon.

    This version of the CIcmp class implements only the Echo Request
    message definition of RFC792. Refer to RFC792 – Internet Control Message
    Protocol, DARPA Internet Program, Protocol Specification
    for details.
    The CIcmp class can be easily expanded to support the complete RFC792
    specification.


Class Methods


    BOOL OpenNewSocket

      (HWND hWnd,

      unsigned int NotificationMessage,

      long NotifyEvents)

    BOOL OpenNewSocket

      (HWND hWnd,

      unsigned int NotificationMessage,

      long NotifyEvents,

      int AFamily,

      int AType,

      int AProtocol)

      Opens a SOCKET of type AType belonging to family
      AFamily and with protocol AProtocol.
      If AFamily, AType and AProtocol are not provided, opens
      a SOCKET connection to a RAW socket with ICMP protocol.

      hWnd is a handle (GetSafeHwnd) to the window containing the
      message processor which will process the asynchronous
      socket events, NotificationMessage is the user-defined message number
      to associate with socket events, and NotifyEvents is the mask giving the events to process.

      Sets icmpSocketError and icmpSocketErrorMod to indicate the type
      of error, and returns TRUE if successful, else FALSE.

      icmpSocketError and icmpSocketErrorMod are preserved until the next
      operation on this CIcmp object is performed.


    BOOL Connect

      (LPINT ReceiveTimeout,

      LPINT SendTimeout)

    BOOL Connect

      (LPINT ReceiveTimeout,

      LPINT SendTimeout,

      int AFamily,

      int AType,

      int AProtocol)

      Connects a CIcmp object to a socket
      of specified family (AFamily), type (AType) and
      protocol (AProtocol). If AFamily, AType
      and AProtocol are not provided, connects a CIcmp
      object to a RAW socket with ICMP protocol.

      ReceiveTimeout and SendTimeout specifies the receive
      and transmit timeouts.

      Sets icmpSocketError and icmpSocketErrorMod to indicate the type
      of error, and returns TRUE if successful, else FALSE.

      icmpSocketError and icmpSocketErrorMod are preserved until the next
      operation on this CIcmp object is performed.


    int CloseIcmpSocket(void)

      Closes a socket associated with a CIcmp object.

      Sets icmpSocketError and icmpSocketErrorMod to
      indicate the type
      of error, and returns the integer result of the operation.

      icmpSocketError and icmpSocketErrorMod are
      preserved until the next
      operation on this CIcmp object is performed.


    int SetAsynchNotification

      (HWND hWnd,

      unsigned int Message,

      long Events)

      Sets the window (process) to notify when a network event on the
      socket associated with the CIcmp object occurs.

      Message is the message number to send to the window,
      and Events is the event mask to notify on.

      Sets icmpSocketError and icmpSocketErrorMod to
      indicate the type
      of error, and returns the integer result of the operation.

      icmpSocketError and icmpSocketErrorMod
      are preserved until the next
      operation on this CIcmp object is performed.


    int SetTTL (int TTL)

      Set the TTL (Time-To-Live) option on the socket associated with a
      CIcmp object. The TTL value specifies the number of seconds
      an Internet datagram is to exist.

      Since each gateway encountered along the trip to the specified host
      decrements the TTL value by 1, TTL specifies the number of hops (gateways)
      to query before a response is returned. By incrementing the TTL from 1 to
      (number of hops to final destination), a TraceRoute function
      can be performed. In order to reach a designated host, TTL must be at
      least the number of gateways encountered on the way to the host, plus 1
      (for the host itself).

      Sets icmpSocketError and icmpSocketErrorMod to
      indicate the type of error, and returns the integer result of the
      operation.

      icmpSocketError and icmpSocketErrorMod are
      preserved until the next operation on this CIcmp object is performed.


    int Ping (LPSTR pIcmpBuffer, int IcmpBufferSize)

      Sends an ICMP Echo Request (ping) message to the host indicated
      in the CIcmp
      variable icmpSockAddr. The CIcmp variables
      icmpCurSeq and
      icmpCurId are sent in the buffer referenced by pIcmpBuffer. The
      referenced buffer must be large enough to hold DataLen bytes plus
      the size of the ICMP message header.

      The CIcmp variable icmpPingSentAt is set to the time value at the
      time the ping message is sent.

      Sets icmpSocketError and icmpSocketErrorMod to indicate the type
      of error, and returns the integer result of the operation.

      icmpSocketError and icmpSocketErrorMod are preserved until the next
      operation on this CIcmp object is performed.


    unsigned short IcmpChecksum (unsigned short FAR *lpBuf, int Len)

      Computes the ICMP checksum of the data in the buffer referenced
      by lpBuf for Len bytes.

      Returns an unsigned integer value of the computed checksum.


    unsigned long GetIPAddress (LPSTR iHostName)

      Returns the value of the IP address of the host pointed by
      iHostName as an unsigned long in network byte order, as described
      in inet_aton.

      Sets iHostName to the value of the host name returned in
      icmpHostEnt.

      Requires the message number to send to the window, and the events
      to notify on.

      Sets CIcmp variable icmpSockAddr fields appropriately,
      leaving the IP address in icmpSockAddr.sin_addr, and the
      type of address in
      icmpSockAddr.sin_family. Also sets icmpHostEnt fields appropriately

      Sets icmpSocketError and icmpSocketErrorMod to indicate the type
      of error, and returns the integer result of the operation.

      icmpSocketError and icmpSocketErrorMod are preserved until the next
      operation on this CIcmp object is performed.


    int Receive (LPSTR pIcmpBuffer, int IcmpBufferSize)

      Reads the socket associated with the CIcmp object and returns the
      number of bytes read, or SOCKET_ERROR, if an error occurs.

      pIcmpBuffer is the address of the buffer to store the incoming message
      and IcmpBufferSize is the integer buffer size. The buffer must be large
      enough to contain the incoming message. In the case of an ICMP Echo
      Reply
      , the size would be the size of the outgoing message plus
      the size of an ICMP header plus the size of an IP header.

      Sets icmpRcvLen to the length of the message received,
      icmpPingReceivedAt to the time the receive command is issued,
      icmpRoundTripTime to the difference between icmpPingSentAt
      and icmpPingReceivedAt, icmpCurSeq to the incoming
      sequence number and icmpCurId to the incoming id field.

      Sets rcvSockAddr fields appropriately.

      Sets icmpSocketError and icmpSocketErrorMod to indicate the type
      of error, and returns the integer result of the operation.

      icmpSocketError and icmpSocketErrorMod are preserved until the next
      operation on this CIcmp object is performed.


    void DisplayError (CString ErrorType, CString FunctionName)

      Displays the provided ErrorType message prior to the decoded error
      message in icmpSocketError and icmpSocketErrorMod.

      Sets the message box title to FunctionName.

      The message is displayed in a modal box, requiring an OK response
      before the thread containing this method can progress.


Class Variables

The CIcmp class contains the following public variables:


LPIcmpHeader pIcmpHeader

  • Pointer to an IcmpHeader structure;
  • Usually mapped to the current ICMP buffer.

LPIpHeader pIpHeader

  • Pointer to an IpHeader structure;
  • Usually mapped to the current receive buffer.

SOCKET icmpSocket

  • An asynchronous socket. See CSocket class for implementation;
  • Contains the current socket for this CIcmp object;
  • Default is INVALID_SOCKET for unopened/unassigned socket.

SOCKADDR_IN icmpSockAddr

  • Socket address structure for outgoing (send) socket communication;
  • Refer to SOCKADDR_IN structure in VisualC++ help or MFC documentation.

SOCKADDR_IN rcvSockAddr

  • Socket address structure for incoming (recvfrom) socket communication;
  • Refer to SOCKADDR_IN structure in VisualC++ help or MFC documentation.

DWORD icmpRoundTripTime

  • Time between sending a message and receiving the echo;
  • in mSec.

unsigned long icmpHostAddress

  • Host address in network byte order;
  • Maintained external to the CIcmp class;
  • see inet_aton for format.

DWORD icmpPingSentAt

  • System time when the last ICMP message was sent;
  • in mSec.

DWORD icmpPingReceivedAt

  • System time when the last ICMP message was received;
  • in mSec.

int icmpRcvLen

  • integer length of the last message received;
  • set by Receive.

int icmpHops

  • Number of hops (routers contacted) in a trace route operation;
  • Set to zero by Connect method;
  • Maintained external to class (by application program).

int icmpMaxHops

  • A limit set for trace route operations which fail to complete gracefully;
  • Defaults to 30 in the CIcmp constructor;
  • Maintained external to class (by application program).

int icmpCurSeq

  • Current ICMP message sequence number;
  • Set by application program before calling Ping;
  • Set by Receive after processing an incoming (recvfrom) message.

int icmpCurId

  • ICMP id field;
  • Set to current process id by Connect;
  • Assigned to outgoing ICMP message by Ping;
  • Set to incoming ICMP id field by Receive

int icmpPingTimer

  • send (Ping) timeout in mSec;
  • recvfrom (Receive) timeout in mSec.

int icmpSocketError

  • The WSAGetLastError for the last error which occurred;
  • Preserved until the next socket error occurs.

int icmpSocketErrorMod

  • The entry level in the processing routine at which icmpSocketError occurred;
  • Preserved until the next socket error occurs.


Installing the Class

    To use this class,

    1. Copy the files Icmp.cpp, Icmp.h and Icmp.rc
      to the same directory as your project;

    2. Include Icmp.cpp and Icmp.rc in your project. This will cause
      an error notification that only one .rc file can be active…ignore it,
      the following steps will fix it;

    3. Open the file Icmp.rc, select the string table, and highlight all of the
      messages;

    4. Copy the resource strings to the clipboard (copy button);
    5. Open the projects’ string table and paste
      the strings into the next available slot (paste button);

    6. Close both string tables and remove (delete) the
      file Icmp.rc from your project;

    7. Add Icmp.h to any modules in which you make reference to CIcmp
      or one
      of its’ methods or variables. This will normally take the form of

        #include “Icmp.h”

      in the header files in which the CIcmp object is declared.


EWDPing – A Demonstration of the CIcmp Class

    EWDPing is a sample program which illustrates the use of the CIcmp class.

    This program implements the ICMP Echo Request message (commonly
    known as PING) to check the on-line status of an Internet host, and uses TTL to
    trace the route to an Internet host.

    The .zip file contains the source for EWDPing as well as the source for
    the other custom classes used in the project:

      CIcmp

      An object class derived from the MFC CSocket object class to provide access to
      RAW sockets and ICMP (Internet Control Message Protocol) functions.

      CRegKey

      An object class to provide to WindowsNT/95 system registry objects.

      CSysTCPIP

      An object class to provide access to some of the TCP/IP related information
      stored in the system registry on Windows NT using Microsoft’s Winsock 2
      interface.

    The program also makes use of a system timer to prevent “hanging” on a
    non-responsive gateway.

    Documentation for the methods and variables are provided within the
    .zip file.

Download demo project – 151KB

Download source – 26KB

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read