We need you!

We're working hard on the next version of Developer Fusion. Let us know what you think we should be up to!

Members

Technology Zones

Articles

Hosted By

MaximumASP

Info

Rated
Read 124,668 times

Contents

Related Categories

How to PING - Wrapping Up

randy

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.

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

Comments

  • Re: [4628] How to PING

    Posted by usul on 31 Jul 2007

    You can also see a screencast how to ping .

  • Re: network utilities - HELP needed

    Posted by Konio on 28 Mar 2006

    hfhg

  • network utilities - HELP needed

    Posted by Konio on 30 Nov 2005

    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 (so...

  • Includes

    Posted by thesun on 14 Nov 2005

    What is the name of library to include ?

    #include ???

    In the icmp.h and ping.cpp

    Thanks

  • PIng plotter in C#

    Posted by Gulfam on 14 Oct 2004

    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 ...