Library tutorials & articles

How to PING

Wrapping Up

I wrapped the ICMP code in a class named appropriately enough Icmp. I also created an IcmpException class that I use to capture and send exceptions down the call stack.

//////////////////////////////////////////////////////////////////////
//
// icmp.h: implementation of the Icmp class.
// Copyright 2001 by KBCafe
//
//////////////////////////////////////////////////////////////////////

#ifndef KBCAFE_ICMP_H
#define KBCAFE_ICMP_H

#include
#include
#include
#include
#include
#include

namespace
{

    class WSAInit
    {
        public:
        WSAInit()
        {
            WORD w = MAKEWORD(1,1);
            WSADATA wsadata;
            ::WSAStartup(w, &wsadata);
        };

        ~WSAInit()
        {
            ::WSACleanup();
        };

    } instance;
};
namespace kbcafe
{

    class IcmpException : public std:: exception
    {
        std:: string m_str;
        public:
        IcmpException()
        {
            m_str = "ICMP exception.\ tWSAGetLastError = "
            +::WSAGetLastError();
        }

        IcmpException(const std:: string &str)
        {
            std::stringstream ss;
            ss << "ICMP exception:"
            << str
            << "\ tWSAGetLastError = "
            << ::WSAGetLastError();
            m_str = ss.str();
        }

        virtual const char * what() const throw()
        {
            return m_str.c_str();
        }
    };

    class Icmp
    {
        static void SendEmptyEcho(const std:: string &strAddress);
    };

    inline void Icmp:: SendEmptyEcho(const std:: string &strAddress)
    {
        hostent * host;
        in_addr inaddr;
        inaddr.s_addr = ::inet_addr(strAddress.c_str());
        if (inaddr.s_addr == INADDR_NONE)
        {
            host = ::gethostbyname(strAddress.c_str());
        }
        else
        {
            host = ::gethostbyaddr((const char *)&inaddr,
            sizeof(inaddr), AF_INET);
        }

        if (host == NULL)
        {
            throw IcmpException("invalid SMTP server");
        }

        HANDLE icmphandle = IcmpCreateFile();
        char reply[sizeof(icmp_echo_reply)+8];
        icmp_echo_reply* iep = (icmp_echo_reply*)&reply;
        iep->RoundTripTime = 0xffffffff;

        DWORD dw = IcmpSendEcho(icmphandle,
            *((u_long*) host->h_addr_list[0]),
            0,0, NULL,
            reply, sizeof(icmp_echo_reply)+8,5000);

        if (dw == 0)
        {
            throw IcmpException("send echo failed");
        }

        IcmpCloseHandle(icmphandle);
        return;
    }

};
#endif

When initially testing the class, I found that it would not work for me. It was Friday, so I knew it had to be one of the Friday reasons, like my brain was fried. True enough it was.

I forgot to initialize the socket library. So, I cut and paste my trusty WSAInit class and I was back off to the races. The WSAInit class has a performance consequence in that it causes the socket initialization code to be called each time the header file is included in a source listing. This performance inhibiter should only occur at startup, but if you need a quicker startup, then moving the WSAInit class to a source listing might help a bit. Finally, I wrote a little script to test my new ICMP code. I conveniently named the code PING.

// ping.cpp : Defines the entry point for the console application.
//

#include
#include "kbcafe/icmp.h"

int main(int argc, char* argv[])
{
    if (argc != 2)
    {
        std::cerr << "Usage:\t ping [address]";
        return 1;
    }

    try
    {
        kbcafe::Icmp::SendEmptyEcho(argv[1]);
        std::cout << "Success" << std::endl;
    }
    catch(kbcafe::IcmpException &e)
    {
        std::cerr << e.what();
    }

    return 0;
}

This PING utility is not nearly as useful as the one shipped with most OSes, but at least you know how this utility was coded. Try it out, it's not bad.

You can read more about the ICMP protocol in RFC 792.

Comments

  1. 31 Jul 2007 at 09:43
    You can also see a screencast how to ping .

  2. 28 Mar 2006 at 17:36

    hfhg

  3. 30 Nov 2005 at 18:13
    Hi Everyone.I'm kind a newbie in C++ but recently I got a special task and I need to develop a ping plotter, a route tracer and a netstat utility in C++. I would really appreciate any kind of help (some source code or anything). Thx...
  4. 14 Nov 2005 at 18:26

    What is the name of library to include ?


    include ???



    In the icmp.h and ping.cpp


    Thanks

  5. 14 Oct 2004 at 20:37
    HI everyone,
    i need to develop a ping plotter + a route tracer in c # but the problem is i am a newbie and dont know much so how do i go about this or if any source code is available for pining in c # would be grateful
  6. 01 Jan 1999 at 00:00

    This thread is for discussions of How to PING.

Leave a comment

Sign in or Join us (it's free).

Randy Charles Morin Randy's article are Copyright 1998-2003 Randy Charles Morin

Want to stay in touch with what's going on? Follow us on twitter!