//Additional Dependencies: Ws2_32.lib, Iphlpapi.lib
//Additional Include Directories: ..PlatformSDK\Misc\Icmp
#include <windows.h>
#include <winsock.h>
#include <conio.h>
#include <Iphlpapi.h>
#include <Icmpapi.h>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <climits>
#include "st.h"
using namespace std;
void ping(char *destination, int n);
#ifdef NO_MAIN
extern "C" {
int ping_main(int argc, char* argv[]);
}
int ping_main(int argc, char* argv[])
#else 
int main(int argc, char* argv[])
#endif
{
    printf("start ping...\n");
    char* host = "localhost";
    int n = 10;
    for(int i = 1;  i < argc; i++) {
        if(strcmp(argv[i], "-n") == 0) {
            i++;
            if(i < argc) {
                n = atoi(argv[i]);
            }
        }
        else if(strcmp(argv[i], "-v") == 0) {
            cout << "Matt Coan Ping..." << endl;
            cout << "Program Author: Matthew W. Coan (matthewcoan1976@hotmail.com)" << endl;
            cout << "Build Date: " << __DATE__ << " " << __TIME__ << endl;
        }
        else {
            host = argv[i];
        }
    }
    ping(host, n);
    return 0;
}
void ping(char *destination, int n)
{
    WSADATA wsaData;
#ifndef NO_MAIN
    WSAStartup(0x0202, &wsaData);
#endif
    hostent* remoteHost;
    remoteHost = gethostbyname(destination);
    if (WSAGetLastError() != 0)
    {
        cout << "Ping request could not find host " 
            << destination 
            << ".\n Please check the name and try again.\n" << endl;
#ifndef NO_MAIN
        WSACleanup();
#endif
        return;
    }
    HANDLE hIcmpFile = IcmpCreateFile();
    if (hIcmpFile==INVALID_HANDLE_VALUE)
    {
        cout << "IcmpCreateFile failed with error code: " 
            << (long)GetLastError() << endl;
#ifndef NO_MAIN
        WSACleanup();
#endif
        return;
    }
    IPAddr* ipaddr = (IPAddr*)(remoteHost->h_addr_list[0]);
    cout << "Pinging " << destination << " ["
        << inet_ntoa(*((in_addr*)(ipaddr))) 
        << "]\n" << endl;
    LPVOID ReplyBuffer = (VOID*) new char[sizeof(ICMP_ECHO_REPLY)];
    for (int i=0; i<n; i++)
    {
        if (IcmpSendEcho(hIcmpFile, *ipaddr,
            0,0,NULL, ReplyBuffer,sizeof(ICMP_ECHO_REPLY),1000)==0)
        {
            cout << "IcmpSendEcho failed with error code: " 
                << (__int64)GetLastError() << endl;
        }
        else
        {
            PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
            in_addr ipreplied;
            ipreplied.S_un.S_addr=pEchoReply->Address;
            cout << "Reply from " << inet_ntoa(ipreplied)
                << ": bytes=" << pEchoReply->DataSize
                << " time=" << (__int64)pEchoReply->RoundTripTime << "ms" << endl;
        }
        Sleep(500);
    }
    cout << endl;
    delete [] ReplyBuffer;
    IcmpCloseHandle(hIcmpFile);
#ifndef NO_MAIN
    WSACleanup();
#endif
}
