コード例 #1
0
ファイル: ping.cpp プロジェクト: bigmacd/common
Ping::~Ping()
{
  if (mHandle != INVALID_HANDLE_VALUE)
    IcmpCloseHandle(mHandle);
  if (mIpAddress != NULL)
    delete [] mIpAddress;
}
コード例 #2
0
ファイル: net_ka.c プロジェクト: kevinmark/gw6c-5_1
void NetKeepaliveDestroy( void )
{
	shutdown(ka.keepalive_fd, SHUT_RDWR);

#ifdef WIN32
	if( hHandle != NULL )
  {
		IcmpCloseHandle(hHandle);
    hHandle = NULL;
  }

	if( hEvent != NULL )
  {
		CloseHandle(hEvent);
    hEvent = NULL;
  }

  // Free IP Helper API DLL handle, and invalidate function pointers.
  if( hndliphlp != NULL )
  {
    IcmpCreateFile      = NULL;
    IcmpCloseHandle     = NULL;
    IcmpSendEcho2       = NULL;
    IcmpParseReplies    = NULL;
    Icmp6CreateFile     = NULL;
    Icmp6SendEcho2      = NULL;
    Icmp6ParseReplies   = NULL;

    FreeLibrary( hndliphlp );
  }
#endif

	CLOSESOCKET(ka.keepalive_fd);
	memset(&ka, 0, sizeof(struct NetKeepAlive));
}
コード例 #3
0
ファイル: Ping.cpp プロジェクト: AlfiyaZi/rainmeter
DWORD WINAPI NetworkThreadProc(void* pParam)
{
	// NOTE: Do not use CRT functions (since thread was created by CreateThread())!

	MeasureData* measure = (MeasureData*)pParam;
	const DWORD bufferSize = sizeof(ICMP_ECHO_REPLY) + 32;
	BYTE buffer[bufferSize];

	double value = 0.0;
	HANDLE hIcmpFile = IcmpCreateFile();
	if (hIcmpFile != INVALID_HANDLE_VALUE)
	{
		IcmpSendEcho(hIcmpFile, measure->destAddr, NULL, 0, NULL, buffer, bufferSize, measure->timeout);
		IcmpCloseHandle(hIcmpFile);

		ICMP_ECHO_REPLY* reply = (ICMP_ECHO_REPLY*)buffer;
		value = (reply->Status != IP_SUCCESS) ? measure->timeoutValue : reply->RoundTripTime;

		if (!measure->finishAction.empty())
		{
			RmExecute(measure->skin, measure->finishAction.c_str());
		}
	}

	HMODULE module = NULL;

	EnterCriticalSection(&g_CriticalSection);
	if (measure->threadActive)
	{
		measure->value = value;
		measure->threadActive = false;
	}
	else
	{
		// Thread is not attached to an existing measure any longer, so delete
		// unreferenced data.
		delete measure;

		DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT;
		GetModuleHandleEx(flags, (LPCWSTR)DllMain, &module);
	}
	LeaveCriticalSection(&g_CriticalSection);

	if (module)
	{
		// Decrement the ref count and possibly unload the module if this is
		// the last instance.
		FreeLibraryAndExitThread(module, 0);
	}

	return 0;
}
コード例 #4
0
ファイル: ping.c プロジェクト: ofilin/remcam2
int ping(unsigned int host, int *timeout, int *err, int packetcount)
{
	HANDLE icmp;
	int status = 0;
	ICMP_ECHO_REPLY *reply;
	int replylen;
	int i;

	if((icmp = IcmpCreateFile()) != INVALID_HANDLE_VALUE)
	{
		replylen = sizeof(ICMP_ECHO_REPLY) + 32;
		
		if((reply = malloc(replylen)))
		{
			for(i = 0; i < packetcount; ++i)
			{
				if(IcmpSendEcho(
					icmp,
					(IPAddr)htonl(host),
					NULL,
					0,
					NULL,
					reply,
					(DWORD)replylen,
					(DWORD)*timeout))
				{
					if(reply->Status == IP_SUCCESS)
					{
						*timeout = reply->RoundTripTime;
						status = 1;
					}
				}

				if(status)
				{
					break;
				}
			}
			free(reply);
		}

		IcmpCloseHandle(icmp);
	}
	else
	{
		*err = 1;
	}


	return status;
}
コード例 #5
0
ファイル: icmp.cpp プロジェクト: 0xmono/miranda-ng
bool ICMP::ping(char *host, ICMP_ECHO_REPLY &reply)
{
	if (!functions_loaded)
		return false;

	HOSTENT *rec;
	IP_OPTION_INFORMATION ipoi;

	unsigned long address = inet_addr(host);
	if (address == INADDR_NONE)
	{
		rec = gethostbyname(host);
		if (rec != NULL)
			address = *(unsigned long *)(*rec->h_addr_list);
		else
			return false;
	}

	ipoi.Ttl = 255;
	ipoi.Tos = 0;
	ipoi.Flags = 0;
	ipoi.OptionsSize = 0;
	ipoi.OptionsData = 0;
	
	reply.Status = 0;

	hIP = IcmpCreateFile();
	if (hIP == INVALID_HANDLE_VALUE)
		return false;

	DWORD rep_cnt = IcmpSendEcho2(hIP, 0, 0, 0, address, data, sizeof(data), 0, buff, BUFFER_SIZE, timeout);
	if (rep_cnt == 0)
	{
		DWORD code = GetLastError();
		if (code != 11010)
		{
			char winmsg[512], msg[1024];
			FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, 0, code, 0, winmsg, 512, 0);
			mir_snprintf(msg, 1024, "Ping error (%d): %s", code, winmsg);
			PUShowMessage(msg, SM_NOTIFY);
			return false;
		}
	}
	memcpy(&reply, buff, sizeof(ICMP_ECHO_REPLY));

	IcmpCloseHandle(hIP);

	return (reply.Status == 0);
}
コード例 #6
0
ファイル: main.cpp プロジェクト: smakonin/mccPing
long _stdcall ping(char *error, char *host)
{
	IPAddr ip;
	WORD w = MAKEWORD(1,1);
	WSADATA wsadata;

	strset(error, 0);
	
	WSAStartup(w, &wsadata);
	
	hostent* phostent;
	if( host[0] <= '9')
		ip = (IPAddr)inet_addr(host);
	else
	{
		phostent = gethostbyname(host);
		if(!phostent)
		{
			strcpy(error, "Unable to resolve host name.");
			return -1;
		}
		ip = *(DWORD*)(*phostent->h_addr_list);
	}
	
	HANDLE icmphandle = IcmpCreateFile();
	
	char reply[sizeof(icmp_echo_reply)+8];
	
	icmp_echo_reply* iep = (icmp_echo_reply*)&reply;
	iep->RoundTripTime = 0xffffffff;
	
	IcmpSendEcho(icmphandle,ip,0,0,NULL,reply,sizeof(icmp_echo_reply)+8,PING_TIMEOUT);
	
	IcmpCloseHandle(icmphandle);
	
	WSACleanup();

	if(iep->RoundTripTime == PING_TIMEOUT)
	{
		strcpy(error, "Timeout.");
		return -1;
	}

	return iep->RoundTripTime;
}
コード例 #7
0
ファイル: DP_RepMain.cpp プロジェクト: P3tr0viCh/DP_Rep
bool TMain::Ping(String HostName) {
	bool Result;

	HANDLE hIcmpFile;
	unsigned long ipaddr;
	DWORD dwRetVal;
	char SendData[32]    = "Data Buffer";
	LPVOID ReplyBuffer;
	DWORD ReplySize;

	ipaddr = inet_addr(AnsiString(HostName).c_str());
	Result = ipaddr != INADDR_NONE;
	if (Result) {

		hIcmpFile = IcmpCreateFile();
		Result    = hIcmpFile != INVALID_HANDLE_VALUE;
		if (Result) {

			ReplySize   = sizeof(ICMP_ECHO_REPLY)+sizeof(SendData);
			ReplyBuffer = (VOID*) malloc(ReplySize);

			Result = ReplyBuffer != NULL;
			if (Result) {

				dwRetVal = IcmpSendEcho(hIcmpFile, ipaddr, SendData,
					sizeof(SendData), NULL, ReplyBuffer, ReplySize, 1000);

				Result = dwRetVal != 0;
				if (Result) {
					PICMP_ECHO_REPLY pEchoReply =
						(PICMP_ECHO_REPLY) ReplyBuffer;

					Result = pEchoReply->Status == IP_SUCCESS;
				}
			}

			IcmpCloseHandle(hIcmpFile);
		}
	}

	return Result;
}
コード例 #8
0
ファイル: IcmpImpl.cpp プロジェクト: siliace/Bull
        Duration IcmpImpl::ping(const IpAddressV4& address, const Duration& timeout)
        {
            HANDLE icmpHandle = IcmpCreateFile();

            Expect(icmpHandle != INVALID_HANDLE_VALUE, Throw(Win32Error, "Failed to create ICMP handler"));

            ByteArray request(32);
            IPAddr addr = address.toInt();
            ByteArray response(sizeof(ICMP_ECHO_REPLY) + request.getCapacity());

            DWORD retval = IcmpSendEcho(icmpHandle, addr, &request[0], request.getCapacity(), nullptr, &response[0], response.getCapacity(), timeout.asMilliseconds());

            Expect(retval > 0, Throw(Win32Error, "Failed to send ICMP request"));

            const ICMP_ECHO_REPLY* reply = reinterpret_cast<const ICMP_ECHO_REPLY*>(response.getBuffer());

            Duration duration = Duration::milliseconds(reply->RoundTripTime);

            IcmpCloseHandle(icmpHandle);

            return duration;
        }
コード例 #9
0
ファイル: icmpecho.cpp プロジェクト: kagajubo/IPCStreamViewer
DWORD CIcmpEcho::PingHost(unsigned long ulIP, int iPingTimeout)
{
    //Task 1:	Open ICMP Handle
    //Task 2:	Create Structure to receive ping reply
    //Task 3:	SendPing (SendEcho)
    //Task 4:	Close ICMP Handle
    //Task 5:	Return RoundTripTime

    unsigned long ip = ulIP;

    HANDLE icmphandle = IcmpCreateFile();

    char reply[sizeof(icmp_echo_reply)+8];

    icmp_echo_reply* iep=(icmp_echo_reply*)&reply;
    iep->RoundTripTime = 0xffffffff;

    IcmpSendEcho(icmphandle,ip,0,0,NULL,reply,sizeof(icmp_echo_reply)+8,iPingTimeout);

    IcmpCloseHandle(icmphandle);

    return iep->RoundTripTime;

}
コード例 #10
0
int main(int argc, char **argv){
    if( argc<2){
        printf("Usage: %s <ip address>\n", argv[0]);
        return 1;
    }
    
    if( IsDebuggerPresent()){
        HANDLE iphlpapi=LoadLibrary("iphlpapi.dll");
        if( !iphlpapi){
            perror("iphlpapi.dll");
            return 1;
        }
        FARPROC IcmpSendEcho=GetProcAddress(iphlpapi, "IcmpSendEcho");
        FARPROC IcmpCreateFile=GetProcAddress(iphlpapi, "IcmpCreateFile");
        FARPROC IcmpCloseHandle=GetProcAddress(iphlpapi, "IcmpCloseHandle");
        if( (IcmpSendEcho && IcmpCreateFile && IcmpCloseHandle)==0){
            perror("icmp functions");
            return 1;
        }
        
        unsigned long ipaddr=INADDR_NONE, params[2];
        HANDLE hIcmpFile;
        char data[32], *reply;
        int replySize=sizeof(ICMP_ECHO_REPLY)+sizeof(data);
        
        if( (ipaddr=inet_addr(argv[1]))==INADDR_NONE){
            perror("Illegal IP address!");
            return 1;
        }
        
        if( (hIcmpFile=(HANDLE)IcmpCreateFile())==INVALID_HANDLE_VALUE){
            perror("IcmpCreateFile");
            return 1;
        }
        
        reply=(char *)malloc(replySize);
        ZeroMemory(data, sizeof(data));
        params[0]=PARAM;
        params[1]=(unsigned long)GetProcAddress(iphlpapi, "IcmpSendEcho2Ex");
        
        RaiseException(EXCEPTION_BREAKPOINT, 0, 2, params);
        puts("Exception raised!");
        IcmpSendEcho(hIcmpFile, ipaddr, data, sizeof(data), NULL, reply, replySize, 1000);
        puts("This line should never be shown...");
        IcmpCloseHandle(hIcmpFile);
        return 0;
    }
    
    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    HANDLE hProcess, hThread;
    DEBUG_EVENT debugEvent;
    EXCEPTION_RECORD *ExceptionRecord=&debugEvent.u.Exception.ExceptionRecord;
    CONTEXT context;
    FARPROC IcmpSendEcho2Ex=NULL;
    char path[256], args[512], originalByte[1];
    
    ZeroMemory(?, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&si, sizeof(STARTUPINFO));
    ZeroMemory(&debugEvent, sizeof(DEBUG_EVENT));
    ZeroMemory(&context, sizeof(CONTEXT));
    ZeroMemory(path, sizeof(path));
    ZeroMemory(args, sizeof(args));
    si.cb=sizeof(STARTUPINFO);
    si.dwFlags=STARTF_USESHOWWINDOW;
    si.wShowWindow=SW_HIDE;
    context.ContextFlags=CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
    
    GetModuleFileName(NULL, path, sizeof(path)-1);
    snprintf(args, sizeof(args)-1, "%s %s", path, argv[1]);
    
    if( !CreateProcess(
        NULL,
        args,
        NULL,
        NULL,
        FALSE,
        DEBUG_PROCESS,
        NULL,
        NULL,
        &si,
        ?
    )){
       perror("CreateProcess");
       return 1;
    }
    
    if( (hProcess=OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId))==NULL){
       perror("OpenProcess");
       return 1;
    }
    
    HANDLE kernel32=LoadLibrary("kernel32.dll");
    FARPROC DebugSetProcessKillOnExit=GetProcAddress(kernel32, "DebugSetProcessKillOnExit");
    FARPROC DebugActiveProcessStop=GetProcAddress(kernel32, "DebugActiveProcessStop");
    FARPROC OpenThread=GetProcAddress(kernel32, "OpenThread");
    CloseHandle(kernel32);
    DebugSetProcessKillOnExit(TRUE);
    
    while(WaitForDebugEvent(&debugEvent, INFINITE) && debugEvent.dwDebugEventCode!=EXIT_PROCESS_DEBUG_EVENT){
             if( debugEvent.dwDebugEventCode==EXCEPTION_DEBUG_EVENT && ExceptionRecord->ExceptionCode==EXCEPTION_BREAKPOINT){
                 if( ExceptionRecord->NumberParameters>1 && ExceptionRecord->ExceptionInformation[0]==PARAM){
                     IcmpSendEcho2Ex=(FARPROC)ExceptionRecord->ExceptionInformation[1];
                     printf("IcmpSendEcho2Ex %p\n", IcmpSendEcho2Ex);
                     if( !BreakpointSet(hProcess, IcmpSendEcho2Ex, &originalByte)){
                         perror("BreakpointSet");
                         break;
                     }
                 }
                 else if( ExceptionRecord->ExceptionAddress==IcmpSendEcho2Ex){
                      printf("EIP %p\n", IcmpSendEcho2Ex);
                      if( !BreakpointRetrieve(hProcess, IcmpSendEcho2Ex, &originalByte)){
                          perror("BreakpointRetrieve");
                          break;
                      }
                      if((hThread=(HANDLE)OpenThread(THREAD_ALL_ACCESS, FALSE, debugEvent.dwThreadId))==NULL) puts("OpenThread");
                      if(!GetThreadContext(hThread, &context)) puts("GetThreadContext");
                      context.Eip -= 1;
                      if(!SetThreadContext(hThread, &context)) puts("SetThreadContext");
                      CreateThread(NULL, 0, (void *)Terminate, hProcess, 0, NULL);
                 }
             }
             else if( debugEvent.dwDebugEventCode==EXCEPTION_DEBUG_EVENT){
                  puts("Exception!");
                  DebugActiveProcessStop(debugEvent.dwProcessId);
                  break;
             }
             ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, DBG_CONTINUE);
             ZeroMemory(&debugEvent, sizeof(DEBUG_EVENT));
    }
    
    return 0;
}
コード例 #11
0
ファイル: IGPing.cpp プロジェクト: Bitlsoft/Imagenius_SDK
bool Ping(std::wstring sServerIP)
{
	// Obtain an ICMP handle.
	HANDLE hIcmp = IcmpCreateFile();	
	if (!hIcmp) {
		_ASSERTE (0 && L" IGPing::Ping() Failed - ICMP error");
		return false;
	}
	// Parse the IP address in the Edit.
	size_t szNextDot = sServerIP.find (L'.');
	int addr1 = ::_wtoi (sServerIP.substr (0, szNextDot++).c_str());
	size_t szNextNum = szNextDot;
	szNextDot = sServerIP.find (L'.', szNextNum);
	int addr2 = ::_wtoi (sServerIP.substr (szNextNum, szNextDot++).c_str());
	szNextNum = szNextDot;
	szNextDot = sServerIP.find (L'.', szNextNum);
	int addr3 = ::_wtoi (sServerIP.substr (szNextNum, szNextDot++).c_str());
	szNextNum = szNextDot;
	szNextDot = sServerIP.find (L'.', szNextNum);
	int addr4 = ::_wtoi (sServerIP.substr (szNextNum, szNextDot).c_str());
	// Make an int out of the IP address.
	int addr = MAKELONG(
		MAKEWORD(addr1, addr2),
		MAKEWORD(addr3, addr4));
	// Allocate a buffer for the reply info.
	int size = sizeof(icmp_echo_reply) + 8;
	char* buff = new char[size];
	bool bSuccess = false;
	// Send the echo request three times to
	// emulate what the PING program does.
	for (int i=0;i<3;i++) {
		// Call IcmpSendEcho().
		DWORD res = IcmpSendEcho(hIcmp,
			addr, 0, 0, 0, buff, size, 1500);
		// Prepare to report the status.
		icmp_echo_reply reply;
		memcpy(&reply, buff, sizeof(reply));
		if (!res) {
			//sServerIP += ErrorStrings[reply.Status - 11000];
			_ASSERTE (0 && L" IGPing::Ping() Failed - ICMP error");
			continue;
		}		
		// If the status is non-zero then show the
		// corresponding error message from the
		// ErrorStrings array to the user.
		if (reply.Status > 0)
		{/*
			sServerIP += IGPING_ERROR;
			sServerIP += L" - ";
			sServerIP += ErrorStrings[reply.Status - 11000];*/
			_ASSERTE (0 && L" IGPing::Ping() Failed - ICMP error");
			continue;
		}
		else {
			// Build a string to report the results.
			/*
			std::string rtt = reply.RoundTripTime;
			std::string ttl = reply.Options.Ttl;
			std::string S = "Reply from " + IPEdit->Text +
			" time=" + rtt +"ms TTL=" + ttl + "ms";*/
			bSuccess = true;
			break;
		}
		// Pause a second and then loop.
		Sleep(1000);
	}
	// Close the ICMP handle.
	IcmpCloseHandle(hIcmp);
	return bSuccess;
}
コード例 #12
0
ファイル: crossbear.cpp プロジェクト: UCASREN/Crossbear
/*!
 * \brief
 * This function pings an IPv4-Address with a specified Time-To-Live-value.
 * 
 * \param ai
 * The AddrInfo-representation of the TargetIP
 * 
 * \param ttl
 * The Time-To-Live-value to perform the ping with
 * 
 * \param out
 * The Buffer into which the result of the ping-command will be written
 * 
 * \param outSize
 * The maximum number of characters that can be written into "out"
 * 
 * \returns
 * True if the execution succeded and false otherwise. The following will be written in "out": "TARGET "+TargetIP if the target was reached, "HOP "+HopIP if an intermediate Host was reached or "NO_REPLY" if an execution error occurred. If an internal error occured, a message describing that error will be written.
 *
 * \remarks
 * ai will be Freed
 */
bool ping4(struct addrinfoW *ai, int ttl, WCHAR * out, int  outSize){
	
		// Create a handle to a hIcmpFile (required by IcmpSendEcho2)
		HANDLE hIcmpFile = IcmpCreateFile();
		if (hIcmpFile == INVALID_HANDLE_VALUE) {
			outPutWstring(std::wstring(L"IcmpCreatefile returned error: ")+getFormatedLastError(),out,outSize);

			// Free all allocated resources
			FreeAddrInfoW(ai);
			return false;
		}

		// Build the payload of the ICMP-request (mustn't be empty)
		char SendData[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345";

		// Allocate space for a single reply
		DWORD ReplySize = sizeof (ICMP_ECHO_REPLY) + sizeof (SendData) + 8 + sizeof(IO_STATUS_BLOCK);
		LPVOID ReplyBuffer = (VOID *) malloc(ReplySize);

		// Convert the IP-Address into the correct format
		IPAddr ipaddr;
		memcpy(&ipaddr, &((sockaddr_in *)ai->ai_addr)->sin_addr, sizeof(ipaddr));

		// Create a IP_OPTION_INFORMATION and set its TTL-field so IcmpSendEcho2 will perform a ping with the correct TTL
		IP_OPTION_INFORMATION ipopts;
		memset(&ipopts,0,sizeof(ipopts));
		ipopts.Ttl = (unsigned char)ttl;

		//Try to perform the actual ping
		DWORD dwRetVal = IcmpSendEcho2(hIcmpFile, NULL, NULL, NULL,  ipaddr, SendData, sizeof (SendData), &ipopts, ReplyBuffer, ReplySize, 1000);
		if (dwRetVal == 0) {

			// In case it failed: Did it fail because of a timeout or because of a serious problem?
			bool success = false;
			DWORD lastError = GetLastError();
			if(IP_REQ_TIMED_OUT == lastError || IP_DEST_NET_UNREACHABLE ==  lastError ){
				// If it failed because of a Timeout return "NO_REPLY"
				outPutWstring(std::wstring(L"NO_REPLY"),out,outSize);
				success = true;
			}
			else{
				// If it failed because of a serious problem return a detailed description about the failure
				outPutWstring(std::wstring(L"Call to IcmpSendEcho2 failed: ")+getFormatedLastError(),out,outSize);
			}

			// Free all allocated resources
			FreeAddrInfoW(ai);
			free(ReplyBuffer);
			IcmpCloseHandle(hIcmpFile);
			return success;
		}

		// Parse the reply on the ICMP-request
		PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY) ReplyBuffer;

		// Extract the address of the replying host
		struct in_addr ReplyAddr;
		ReplyAddr.S_un.S_addr = pEchoReply->Address;
		std::wstring hopName = s2ws(std::string(inet_ntoa(ReplyAddr)));

		// Switch according to status of reply
		ULONG status = pEchoReply->Status;

		if(status == IP_SUCCESS){
			// Ping reached the target
			outPutWstring(std::wstring(L"TARGET ")+ hopName,out,outSize);
		}
		else if(status == IP_TTL_EXPIRED_TRANSIT || status == IP_TTL_EXPIRED_REASSEM){
			// Ping got a reply from a hop on the way to target
			outPutWstring(std::wstring(L"HOP ")+ hopName,out,outSize);
		}
		else{
			// Something didn't work
			outPutWstring(std::wstring(L"NO_REPLY"),out,outSize);
		}

		// Free all allocated resources
		free(ReplyBuffer);
		FreeAddrInfoW(ai);
		IcmpCloseHandle(hIcmpFile);
		return true;

}
コード例 #13
0
ファイル: crossbear.cpp プロジェクト: UCASREN/Crossbear
/*!
 * \brief
 * This function pings an IPv6-Address with a specified Time-To-Live-value.
 * 
 * \param ai
 * The AddrInfo-representation of the TargetIP
 * 
 * \param ttl
 * The Time-To-Live-value to perform the ping with
 * 
 * \param out
 * The Buffer into which the result of the ping-command will be written
 * 
 * \param outSize
 * The maximum number of characters that can be written into "out"
 * 
 * \returns
 * True if the execution succeded and false otherwise. The following will be written in "out": "TARGET "+TargetIP if the target was reached, "HOP "+HopIP if an intermediate Host was reached or "NO_REPLY" if an execution error occurred. If an internal error occured, a message describing that error will be written.
 *
 * \remarks
 * ai will be Freed
 */
bool ping6(struct addrinfoW *ai, int ttl, WCHAR * out, int  outSize){
	// Create a handle to a hIcmpFile (required by Icmp6SendEcho2)
		HANDLE hIcmpFile = Icmp6CreateFile();
		if (hIcmpFile == INVALID_HANDLE_VALUE) {
			outPutWstring(std::wstring(L"Icmp6Createfile returned error: ")+getFormatedLastError(),out,outSize);

			// Free all allocated resources
			FreeAddrInfoW(ai);
			return false;
		}

		// A ICMP-request using IPv6 requires a source address: Get the system's IPv6 addresses
		ADDRINFOW hints;
		memset(&hints,0,sizeof(ADDRINFOW));
		hints.ai_family = AF_INET6;
		struct addrinfoW *lai;
		if(! (0==GetAddrInfoW(L"",NULL,&hints,&lai))){
			outPutWstring(std::wstring(L"Invalid Socket (Localhost) : ")+getFormatedLastError(),out,outSize);

			// Free all allocated resources
			FreeAddrInfoW(ai);
			IcmpCloseHandle(hIcmpFile);
			return false;
		}

		// Out of all of the system's IPv6-addresses: get a global IPv6 IP-Address for localhost
		struct addrinfoW *sourceGlobal = lai;
		while(sourceGlobal != NULL){
			sockaddr_in6 * a = (sockaddr_in6 *)sourceGlobal->ai_addr;
			if(IN6_IS_ADDR_GLOBAL(&a->sin6_addr)) break;
			sourceGlobal = sourceGlobal->ai_next;
		}

		// If there is none then there is no way to perform an ICMP-request on a IPv6-address -> abbort!
		if(sourceGlobal == NULL){
			outPutWstring(std::wstring(L"No global IPv6 interface found on localhost: ")+getFormatedLastError(),out,outSize);

			// Free all allocated resources
			FreeAddrInfoW(ai);
			FreeAddrInfoW(lai);
			IcmpCloseHandle(hIcmpFile);
			return false;
		}


		// Build the payload of the ICMP-request (mustn't be empty)
		char SendData[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345";

		// Allocate space for a single reply
		DWORD ReplySize = sizeof (ICMPV6_ECHO_REPLY) + sizeof (SendData) + 8 + sizeof(IO_STATUS_BLOCK);
		LPVOID ReplyBuffer = (VOID *) malloc(ReplySize);

		// Create a IP_OPTION_INFORMATION and set its TTL-field so Icmp6SendEcho2 will perform a ping with the correct TTL
		IP_OPTION_INFORMATION ipopts;
		memset(&ipopts,0,sizeof(ipopts));
		ipopts.Ttl = (unsigned char)ttl;

		//Try to perform the actual ping
		DWORD dwRetVal = Icmp6SendEcho2(hIcmpFile, NULL, NULL, NULL,(sockaddr_in6 *)sourceGlobal->ai_addr,  (sockaddr_in6 *)ai->ai_addr, SendData, sizeof (SendData), &ipopts, ReplyBuffer, ReplySize, 1000);
		if (dwRetVal == 0) {

			// In case it failed: Did it fail because of a timeout or because of a serious problem?
			bool success = false;
			DWORD lastError = GetLastError();
			if(IP_REQ_TIMED_OUT == lastError || IP_DEST_NET_UNREACHABLE ==  lastError ){
				// If it failed because of a Timeout return "NO_REPLY"
				outPutWstring(std::wstring(L"NO_REPLY"),out,outSize);
				success = true;
			}
			else{
				// If it failed because of a serious problem return a detailed description about the failure
				outPutWstring(std::wstring(L"Call to Icmp6SendEcho2 failed: ")+getFormatedLastError(),out,outSize);
			}

			// Free all allocated resources
			FreeAddrInfoW(ai);
			FreeAddrInfoW(lai);
			free(ReplyBuffer);
			IcmpCloseHandle(hIcmpFile);
			return success;
		}

		// Parse the reply on the ICMP-request
		PICMPV6_ECHO_REPLY pEchoReply = (PICMPV6_ECHO_REPLY) ReplyBuffer;

		/*
		 * Extract the address of the replying host
		 */
		// First: copy the reply data into a sockaddr_in6-struckture
		PIPV6_ADDRESS_EX pIP6Addr = &pEchoReply->Address;;
		sockaddr_in6 sock6;
		sock6.sin6_family = AF_INET6;
		sock6.sin6_flowinfo = pIP6Addr->sin6_flowinfo;
		sock6.sin6_port = pIP6Addr->sin6_port;
		sock6.sin6_scope_id = pIP6Addr->sin6_scope_id;
		memcpy(&sock6.sin6_addr, pIP6Addr->sin6_addr,sizeof(IN6_ADDR));

		// Second: convert it into human readable version
		WCHAR  ip6AddressString[256];
		DWORD bufferLenght = 256;
		if(0 != WSAAddressToStringW((LPSOCKADDR)&sock6,sizeof(sockaddr_in6),NULL,ip6AddressString,&bufferLenght)){
			outPutWstring(std::wstring(L"Call to WSAAddressToStringW failed: ")+getFormatedLastError(),out,outSize);

			// Free all allocated resources
			FreeAddrInfoW(ai);
			FreeAddrInfoW(lai);
			free(ReplyBuffer);
			IcmpCloseHandle(hIcmpFile);
			return false;
		}

		// Third: convert it into a wstring
		std::wstring hopName = std::wstring(ip6AddressString);

		/*
		 * Switch according to status of reply
		 */
		ULONG status = pEchoReply->Status;

		if(status == IP_SUCCESS){ 
			// Ping reached the target
			outPutWstring(std::wstring(L"TARGET ")+ hopName,out,outSize);
		}
		else if(status == IP_TTL_EXPIRED_TRANSIT || status == IP_TTL_EXPIRED_REASSEM){ 
			// Ping got a reply from a hop on the way to target
			outPutWstring(std::wstring(L"HOP ")+ hopName,out,outSize);
		}
		else{ 
			// Something didn't work
			outPutWstring(std::wstring(L"NO_REPLY"),out,outSize);
		}

		// Free all allocated resources
		free(ReplyBuffer);
		FreeAddrInfoW(ai);
		FreeAddrInfoW(lai);
		IcmpCloseHandle(hIcmpFile);
		return true;
}
コード例 #14
0
ファイル: ping.c プロジェクト: Moteesh/reactos
int
wmain(int argc, WCHAR *argv[])
{
    WSADATA wsaData;
    ULONG i;
    DWORD StrLen = 46;
    int Status;

    /* Initialize the Console Standard Streams */
    ConInitStdStreams();

    IpOptions.Ttl = 128;

    if (!ParseCmdLine(argc, argv))
        return 1;

    if (!SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE))
    {
        DPRINT("Failed to set control handler: %lu\n", GetLastError());
        return 1;
    }

    Status = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (Status != 0)
    {
        ConResPrintf(StdErr, IDS_WINSOCK_FAIL, Status);
        return 1;
    }

    if (!ResolveTarget(TargetName))
    {
        WSACleanup();
        return 1;
    }

    if (WSAAddressToStringW(Target->ai_addr, (DWORD)Target->ai_addrlen, NULL, Address, &StrLen) != 0)
    {
        DPRINT("WSAAddressToStringW failed: %d\n", WSAGetLastError());
        FreeAddrInfoW(Target);
        WSACleanup();
        return 1;
    }

    if (Family == AF_INET6)
        hIcmpFile = Icmp6CreateFile();
    else
        hIcmpFile = IcmpCreateFile();


    if (hIcmpFile == INVALID_HANDLE_VALUE)
    {
        DPRINT("IcmpCreateFile failed: %lu\n", GetLastError());
        FreeAddrInfoW(Target);
        WSACleanup();
        return 1;
    }

    if (*CanonName)
        ConResPrintf(StdOut, IDS_PINGING_HOSTNAME, CanonName, Address);
    else
        ConResPrintf(StdOut, IDS_PINGING_ADDRESS, Address);

    ConResPrintf(StdOut, IDS_PING_SIZE, RequestSize);

    Ping();

    i = 1;
    while (i < PingCount)
    {
        Sleep(1000);
        Ping();

        if (!PingForever)
            i++;
    }

    PrintStats();

    IcmpCloseHandle(hIcmpFile);
    FreeAddrInfoW(Target);
    WSACleanup();

    return 0;
}
コード例 #15
0
// Ping test
BOOL PingTest(LPCWSTR strIpAddr, ICMP_ECHO_REPLY& reply)
{
    CString strIP       = strIpAddr;
    LPWSTR  addr        = strIP.GetBuffer(strIP.GetLength());
	CHAR    cIPString[128] = {'\0',};

    WideCharToMultiByte(CP_ACP, 0, addr, -1, cIPString, sizeof(cIPString), NULL, NULL);

    IPAddr		ipaddr;	 
	WSADATA		wsadata;
	HANDLE		hIcmp;

    BOOL        bResult = FALSE;

    if(strlen(cIPString))
	{
		// start winsock, requesting min version of 1.01
		WSAStartup(0x0101, &wsadata );
		
		//*******************************************************************
		// Now we ping the IP address resolved above
		//*******************************************************************
		
		// convert the IP char string to a IPAddr representation
		ipaddr = inet_addr((const char*)cIPString);
		
		if(ipaddr == INADDR_NONE)
		{
			AfxMessageBox(TEXT("Invalid Host or IP Entered"));
			WriteFileLog(1, _T("[PING] Invalid Host or IP Entered\r\n") );
		}
		else
		{
			INT		iPacketSize		= 0;
			
            // ping test을 위한 핸들 생성
			hIcmp = IcmpCreateFile();
			
			if(hIcmp == INVALID_HANDLE_VALUE)
			{
				AfxMessageBox(TEXT("Could not create ICMP handle"));
				WriteFileLog(1, _T("[PING] Could not create ICMP handle\r\n") );
			}
			else
			{
				LPVOID	lpData			= NULL;
				LPVOID	lpRevBuffer		= NULL;

				// determine the size of the data packet to send
				iPacketSize = 32;
				
				// allocate memory for the ping function call return and packet size
				lpData = LocalAlloc(LPTR, iPacketSize);
				lpRevBuffer = LocalAlloc(LPTR, sizeof(ICMP_ECHO_REPLY) * iPacketSize);
				
				if(lpData && lpRevBuffer)
				{
					// send the ping
					if( NULL == IcmpSendEcho( hIcmp,
                                              ipaddr,
                                              lpData,
                                              iPacketSize,
                                              NULL,
                                              lpRevBuffer,
                                              (sizeof(ICMP_ECHO_REPLY) * iPacketSize),
                                              1000))
					{					
                        // ping test 실패
                        bResult = FALSE;
						WriteFileLog(1, _T("[PING] IcmpSendEcho Failed(%d)\r\n"), GetLastError() );
					}
					else
					{
                        // ping test 성공
                        //&reply = (ICMP_ECHO_REPLY*)lpRevBuffer;
                        memcpy(&reply, lpRevBuffer, sizeof(ICMP_ECHO_REPLY));
                        bResult = TRUE;
					}
				}

				free(lpData);
				free(lpRevBuffer);
				IcmpCloseHandle(hIcmp);
			}					
		}
		WSACleanup();
	}
	else
	{
		WriteFileLog(1, _T("[PING] Invalid IP Address\r\n") );
	}

    return bResult;
}
コード例 #16
0
int Database::ping(std::string domain)
{
	Poco::Net::HostEntry hostEntry = Poco::Net::DNS::hostByName(domain);
	Poco::Net::HostEntry::AddressList addresses = hostEntry.addresses();
	std::string address = addresses[0].toString();

	std::cout << domain << std::endl;
	std::cout << address << std::endl;

	// Declare and initialize variables
	int ms = -1;
	HANDLE hIcmpFile;
	unsigned long ipaddr = INADDR_NONE;
	DWORD dwRetVal = 0;
	DWORD dwError = 0;
	char SendData[] = "Data Buffer";
	LPVOID ReplyBuffer = NULL;
	DWORD ReplySize = 0;

	//std::cout << "test1" << std::endl;

	ipaddr = inet_addr(address.c_str());
	if (ipaddr == INADDR_NONE)
	{
		//std::cout << "test2 - fail" << std::endl;
		return -1;
	}

	//std::cout << "test2" << std::endl;

	hIcmpFile = IcmpCreateFile();
	if (hIcmpFile == INVALID_HANDLE_VALUE) {
		//std::cout << "test3 - fail" << std::endl;
		//printf("\tUnable to open handle.\n");
		//printf("IcmpCreatefile returned error: %ld\n", GetLastError());
		return -1;
	}
	// Allocate space for at a single reply
	ReplySize = sizeof(ICMP_ECHO_REPLY)+sizeof(SendData)+8;
	ReplyBuffer = (VOID *)malloc(ReplySize);
	if (ReplyBuffer == NULL) {
		//std::cout << "test4 - fail" << std::endl;
		//printf("\tUnable to allocate memory for reply buffer\n");
		return -1;
	}
	else {
		dwRetVal = IcmpSendEcho2(hIcmpFile, NULL, NULL, NULL, ipaddr, SendData, sizeof(SendData), NULL, ReplyBuffer, ReplySize, 1000);
		if (dwRetVal != 0)
		{
			PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
			struct in_addr ReplyAddr;
			ReplyAddr.S_un.S_addr = pEchoReply->Address;
			//printf("\tSent icmp message to %s\n", argv[1]);
			if (dwRetVal > 1) {
				//printf("\tReceived %ld icmp message responses\n", dwRetVal);
				//printf("\tInformation from the first response:\n");
			}
			else {
				//printf("\tReceived %ld icmp message response\n", dwRetVal);
				//printf("\tInformation from this response:\n");
			}
			//printf("\t  Received from %s\n", inet_ntoa(ReplyAddr));
			//printf("\t  Status = %ld  ", pEchoReply->Status);
			switch (pEchoReply->Status) {
			case IP_DEST_HOST_UNREACHABLE:
				//printf("(Destination host was unreachable)\n");
				break;
			case IP_DEST_NET_UNREACHABLE:
				//printf("(Destination Network was unreachable)\n");
				break;
			case IP_REQ_TIMED_OUT:
				//printf("(Request timed out)\n");
				break;
			default:
				//printf("\n");
				break;
			}

			//std::cout << "test6" << std::endl;
			//printf("\t  Roundtrip time = %ld milliseconds\n",
			//	pEchoReply->RoundTripTime);
			ms = pEchoReply->RoundTripTime;
		}
		else {
			//printf("Call to IcmpSendEcho2 failed.\n");
			dwError = GetLastError();
			switch (dwError) {
			case IP_BUF_TOO_SMALL:
				printf("\tReplyBufferSize to small\n");
				break;
			case IP_REQ_TIMED_OUT:
				printf("\tRequest timed out\n");
				break;
			default:
				printf("\tExtended error returned: %ld\n", dwError);
				break;
			}
		}
	}

	//Cleanup Memory
	IcmpCloseHandle(hIcmpFile);
	free(ReplyBuffer);

	//Return Ping
	return ms;
}
コード例 #17
0
ファイル: icmp.cpp プロジェクト: ACanadianKernel/pcsx2
void icmp_close()
{
    IcmpCloseHandle(hIP);
}
コード例 #18
0
ファイル: ping.c プロジェクト: glenrgordon/processhacker2
NTSTATUS NetworkPingThreadStart(
    _In_ PVOID Parameter
    )
{
    HANDLE icmpHandle = INVALID_HANDLE_VALUE;
    ULONG icmpCurrentPingMs = 0;
    ULONG icmpReplyCount = 0;
    ULONG icmpReplyLength = 0;
    PVOID icmpReplyBuffer = NULL;
    PPH_BYTES icmpEchoBuffer = NULL;
    IP_OPTION_INFORMATION pingOptions =
    {
        255,         // Time To Live
        0,           // Type Of Service
        IP_FLAG_DF,  // IP header flags
        0            // Size of options data
    };

    PNETWORK_OUTPUT_CONTEXT context = (PNETWORK_OUTPUT_CONTEXT)Parameter;

    __try
    {
        // Create ICMP echo buffer.
        if (context->PingSize > 0 && context->PingSize != 32)
        {
            PPH_STRING randString;

            randString = PhCreateStringEx(NULL, context->PingSize * 2 + 2);

            // Create a random string to fill the buffer.
            PhGenerateRandomAlphaString(randString->Buffer, (ULONG)randString->Length / sizeof(WCHAR));

            icmpEchoBuffer = PhConvertUtf16ToMultiByte(randString->Buffer);
            PhDereferenceObject(randString);
        }
        else
        {
            PPH_STRING version;

            // We're using a default length, query the PH version and use the previous buffer format.
            version = PhGetPhVersion();

            if (version)
            {
                icmpEchoBuffer = FormatAnsiString("processhacker_%S_0x0D06F00D_x1", version->Buffer);
                PhDereferenceObject(version);
            }
        }

        if (context->IpAddress.Type == PH_IPV6_NETWORK_TYPE)
        {
            SOCKADDR_IN6 icmp6LocalAddr = { 0 };
            SOCKADDR_IN6 icmp6RemoteAddr = { 0 };
            PICMPV6_ECHO_REPLY2 icmp6ReplyStruct = NULL;

            // Create ICMPv6 handle.
            if ((icmpHandle = Icmp6CreateFile()) == INVALID_HANDLE_VALUE)
                __leave;

            // Set Local IPv6-ANY address.
            icmp6LocalAddr.sin6_addr = in6addr_any;
            icmp6LocalAddr.sin6_family = AF_INET6;

            // Set Remote IPv6 address.
            icmp6RemoteAddr.sin6_addr = context->IpAddress.In6Addr;
            icmp6RemoteAddr.sin6_port = _byteswap_ushort((USHORT)context->NetworkItem->RemoteEndpoint.Port);

            // Allocate ICMPv6 message.
            icmpReplyLength = ICMP_BUFFER_SIZE(sizeof(ICMPV6_ECHO_REPLY), icmpEchoBuffer);
            icmpReplyBuffer = PhAllocate(icmpReplyLength);
            memset(icmpReplyBuffer, 0, icmpReplyLength);

            InterlockedIncrement(&context->PingSentCount);

            // Send ICMPv6 ping...
            icmpReplyCount = Icmp6SendEcho2(
                icmpHandle,
                NULL,
                NULL,
                NULL,
                &icmp6LocalAddr,
                &icmp6RemoteAddr,
                icmpEchoBuffer->Buffer,
                (USHORT)icmpEchoBuffer->Length,
                &pingOptions,
                icmpReplyBuffer,
                icmpReplyLength,
                context->MaxPingTimeout
                );

            icmp6ReplyStruct = (PICMPV6_ECHO_REPLY2)icmpReplyBuffer;
            if (icmpReplyCount > 0 && icmp6ReplyStruct)
            {
                BOOLEAN icmpPacketSignature = FALSE;

                if (icmp6ReplyStruct->Status != IP_SUCCESS)
                {
                    InterlockedIncrement(&context->PingLossCount);
                }

                if (_memicmp(
                    icmp6ReplyStruct->Address.sin6_addr,
                    context->IpAddress.In6Addr.u.Word,
                    sizeof(icmp6ReplyStruct->Address.sin6_addr)
                    ) != 0)
                {
                    InterlockedIncrement(&context->UnknownAddrCount);
                }

                icmpPacketSignature = _memicmp(
                    icmpEchoBuffer->Buffer,
                    icmp6ReplyStruct->Data,
                    icmpEchoBuffer->Length
                    ) == 0;

                if (!icmpPacketSignature)
                {
                    InterlockedIncrement(&context->HashFailCount);
                }

                icmpCurrentPingMs = icmp6ReplyStruct->RoundTripTime;
            }
            else
            {
                InterlockedIncrement(&context->PingLossCount);
            }
        }
        else
        {
            IPAddr icmpLocalAddr = 0;
            IPAddr icmpRemoteAddr = 0;
            PICMP_ECHO_REPLY icmpReplyStruct = NULL;

            // Create ICMPv4 handle.
            if ((icmpHandle = IcmpCreateFile()) == INVALID_HANDLE_VALUE)
                __leave;

            // Set Local IPv4-ANY address.
            icmpLocalAddr = in4addr_any.s_addr;

            // Set Remote IPv4 address.
            icmpRemoteAddr = context->IpAddress.InAddr.s_addr;

            // Allocate ICMPv4 message.
            icmpReplyLength = ICMP_BUFFER_SIZE(sizeof(ICMP_ECHO_REPLY), icmpEchoBuffer);
            icmpReplyBuffer = PhAllocate(icmpReplyLength);
            memset(icmpReplyBuffer, 0, icmpReplyLength);

            InterlockedIncrement(&context->PingSentCount);

            // Send ICMPv4 ping...
            icmpReplyCount = IcmpSendEcho2Ex(
                icmpHandle,
                NULL,
                NULL,
                NULL,
                icmpLocalAddr,
                icmpRemoteAddr,
                icmpEchoBuffer->Buffer,
                (USHORT)icmpEchoBuffer->Length,
                &pingOptions,
                icmpReplyBuffer,
                icmpReplyLength,
                context->MaxPingTimeout
                );

            icmpReplyStruct = (PICMP_ECHO_REPLY)icmpReplyBuffer;

            if (icmpReplyStruct && icmpReplyCount > 0)
            {
                BOOLEAN icmpPacketSignature = FALSE;

                if (icmpReplyStruct->Status != IP_SUCCESS)
                {
                    InterlockedIncrement(&context->PingLossCount);
                }

                if (icmpReplyStruct->Address != context->IpAddress.InAddr.s_addr)
                {
                    InterlockedIncrement(&context->UnknownAddrCount);
                }

                if (icmpReplyStruct->DataSize == icmpEchoBuffer->Length)
                {
                    icmpPacketSignature = _memicmp(
                        icmpEchoBuffer->Buffer,
                        icmpReplyStruct->Data,
                        icmpReplyStruct->DataSize
                        ) == 0;
                }

                icmpCurrentPingMs = icmpReplyStruct->RoundTripTime;

                if (!icmpPacketSignature)
                {
                    InterlockedIncrement(&context->HashFailCount);
                }
            }
            else
            {
                InterlockedIncrement(&context->PingLossCount);
            }
        }

        InterlockedIncrement(&context->PingRecvCount);

        if (context->PingMinMs == 0 || icmpCurrentPingMs < context->PingMinMs)
            context->PingMinMs = icmpCurrentPingMs;
        if (icmpCurrentPingMs > context->PingMaxMs)
            context->PingMaxMs = icmpCurrentPingMs;

        context->CurrentPingMs = icmpCurrentPingMs;

        PhAddItemCircularBuffer_ULONG(&context->PingHistory, icmpCurrentPingMs);
    }
    __finally
    {
        if (icmpEchoBuffer)
        {
            PhDereferenceObject(icmpEchoBuffer);
        }

        if (icmpHandle != INVALID_HANDLE_VALUE)
        {
            IcmpCloseHandle(icmpHandle);
        }

        if (icmpReplyBuffer)
        {
            PhFree(icmpReplyBuffer);
        }
    }

    PostMessage(context->WindowHandle, WM_PING_UPDATE, 0, 0);

    return STATUS_SUCCESS;
}
コード例 #19
-1
ファイル: ping.c プロジェクト: lei720/processhacker2
static NTSTATUS PhNetworkPingThreadStart(
    _In_ PVOID Parameter
    )
{
    HANDLE icmpHandle = INVALID_HANDLE_VALUE;
    ULONG icmpCurrentPingMs = 0;
    ULONG icmpCurrentPingTtl = 0;
    ULONG icmpReplyCount = 0;
    ULONG icmpReplyLength = 0;
    PVOID icmpReplyBuffer = NULL;
    PPH_STRING phVersion = NULL;
    PPH_BYTES icmpEchoBuffer = NULL;
    IP_OPTION_INFORMATION pingOptions =
    {
        255,         // Time To Live
        0,           // Type Of Service
        IP_FLAG_DF,  // IP header flags
        0            // Size of options data
    };

    PNETWORK_OUTPUT_CONTEXT context = (PNETWORK_OUTPUT_CONTEXT)Parameter;

    __try
    {
        // Query PH version.
        if ((phVersion = PhGetPhVersion()) == NULL)
            __leave;

        // Create ICMP echo buffer.
        if ((icmpEchoBuffer = PhFormatAnsiString("processhacker_%S_0x0D06F00D_x1", phVersion->Buffer)) == NULL)
            __leave;

        if (context->IpAddress.Type == PH_IPV6_NETWORK_TYPE)
        {
            SOCKADDR_IN6 icmp6LocalAddr = { 0 };
            SOCKADDR_IN6 icmp6RemoteAddr = { 0 };
            PICMPV6_ECHO_REPLY icmp6ReplyStruct = NULL;

            // Create ICMPv6 handle.
            if ((icmpHandle = Icmp6CreateFile()) == INVALID_HANDLE_VALUE)
                __leave;

            // Set Local IPv6-ANY address.
            icmp6LocalAddr.sin6_addr = in6addr_any;
            icmp6LocalAddr.sin6_family = AF_INET6;

            // Set Remote IPv6 address.
            icmp6RemoteAddr.sin6_addr = context->IpAddress.In6Addr;
            icmp6RemoteAddr.sin6_port = _byteswap_ushort((USHORT)context->NetworkItem->RemoteEndpoint.Port);

            // Allocate ICMPv6 message.
            icmpReplyLength = ICMP_BUFFER_SIZE(sizeof(ICMPV6_ECHO_REPLY), icmpEchoBuffer);
            icmpReplyBuffer = PhAllocate(icmpReplyLength);
            memset(icmpReplyBuffer, 0, icmpReplyLength);

            InterlockedIncrement(&context->PingSentCount);

            // Send ICMPv6 ping...
            icmpReplyCount = Icmp6SendEcho2(
                icmpHandle,
                NULL,
                NULL,
                NULL,
                &icmp6LocalAddr,
                &icmp6RemoteAddr,
                icmpEchoBuffer->Buffer,
                (USHORT)icmpEchoBuffer->Length,
                &pingOptions,
                icmpReplyBuffer,
                icmpReplyLength,
                context->MaxPingTimeout
                );

            icmp6ReplyStruct = (PICMPV6_ECHO_REPLY)icmpReplyBuffer;
            if (icmpReplyCount > 0 && icmp6ReplyStruct)
            {
                BOOLEAN icmpPacketSignature = FALSE;

                if (icmp6ReplyStruct->Status != IP_SUCCESS)
                {
                    InterlockedIncrement(&context->PingLossCount);
                }

                if (_memicmp(
                    icmp6ReplyStruct->Address.sin6_addr,
                    context->IpAddress.In6Addr.u.Word,
                    sizeof(icmp6ReplyStruct->Address.sin6_addr)
                    ) != 0)
                {
                    InterlockedIncrement(&context->UnknownAddrCount);
                }

                //if (icmp6ReplyStruct->DataSize == icmpEchoBuffer->MaximumLength)
                //{
                //    icmpPacketSignature = (_memicmp(
                //        icmpEchoBuffer->Buffer,
                //        icmp6ReplyStruct->Data,
                //        icmp6ReplyStruct->DataSize
                //        ) == 0);
                //}

                //if (icmpPacketSignature != TRUE)
                //{
                //    InterlockedIncrement(&context->HashFailCount);
                //}

                icmpCurrentPingMs = icmp6ReplyStruct->RoundTripTime;
                //icmpCurrentPingTtl = icmp6ReplyStruct->Options.Ttl;
            }
            else
            {
                InterlockedIncrement(&context->PingLossCount);
            }
        }
        else
        {
            IPAddr icmpLocalAddr = 0;
            IPAddr icmpRemoteAddr = 0;
            PICMP_ECHO_REPLY icmpReplyStruct = NULL;

            // Create ICMPv4 handle.
            if ((icmpHandle = IcmpCreateFile()) == INVALID_HANDLE_VALUE)
                __leave;

            // Set Local IPv4-ANY address.
            icmpLocalAddr = in4addr_any.s_addr;

            // Set Remote IPv4 address.
            icmpRemoteAddr = context->IpAddress.InAddr.s_addr;

            // Allocate ICMPv4 message.
            icmpReplyLength = ICMP_BUFFER_SIZE(sizeof(ICMP_ECHO_REPLY), icmpEchoBuffer);
            icmpReplyBuffer = PhAllocate(icmpReplyLength);
            memset(icmpReplyBuffer, 0, icmpReplyLength);

            InterlockedIncrement(&context->PingSentCount);

            // Send ICMPv4 ping...
            //if (WindowsVersion > WINDOWS_VISTA)
            //{
            //    // Vista SP1 and up we can specify the source address:
            //    icmpReplyCount = IcmpSendEcho2Ex(
            //        icmpHandle,
            //        NULL,
            //        NULL,
            //        NULL,
            //        icmpLocalAddr,
            //        icmpRemoteAddr,
            //        icmpEchoBuffer->Buffer,
            //        icmpEchoBuffer->MaximumLength,
            //        &pingOptions,
            //        icmpReplyBuffer,
            //        icmpReplyLength,
            //        context->MaxPingTimeout
            //        );
            //}

            icmpReplyCount = IcmpSendEcho2(
                icmpHandle,
                NULL,
                NULL,
                NULL,
                icmpRemoteAddr,
                icmpEchoBuffer->Buffer,
                (USHORT)icmpEchoBuffer->Length,
                &pingOptions,
                icmpReplyBuffer,
                icmpReplyLength,
                context->MaxPingTimeout
                );

            icmpReplyStruct = (PICMP_ECHO_REPLY)icmpReplyBuffer;

            if (icmpReplyStruct && icmpReplyCount > 0)
            {
                BOOLEAN icmpPacketSignature = FALSE;

                if (icmpReplyStruct->Status != IP_SUCCESS)
                {
                    InterlockedIncrement(&context->PingLossCount);
                }

                if (icmpReplyStruct->Address != context->IpAddress.InAddr.s_addr)
                {
                    InterlockedIncrement(&context->UnknownAddrCount);
                }

                if (icmpReplyStruct->DataSize == icmpEchoBuffer->Length)
                {
                    icmpPacketSignature = (_memicmp(
                        icmpEchoBuffer->Buffer,
                        icmpReplyStruct->Data,
                        icmpReplyStruct->DataSize
                        ) == 0);
                }

                icmpCurrentPingMs = icmpReplyStruct->RoundTripTime;
                icmpCurrentPingTtl = icmpReplyStruct->Options.Ttl;

                if (!icmpPacketSignature)
                {
                    InterlockedIncrement(&context->HashFailCount);
                }
            }
            else
            {
                InterlockedIncrement(&context->PingLossCount);
            }
        }

        InterlockedIncrement(&context->PingRecvCount);

        if (context->PingMinMs == 0 || icmpCurrentPingMs < context->PingMinMs)
            context->PingMinMs = icmpCurrentPingMs;
        if (icmpCurrentPingMs > context->PingMaxMs)
            context->PingMaxMs = icmpCurrentPingMs;

        context->CurrentPingMs = icmpCurrentPingMs;

        PhAddItemCircularBuffer_ULONG(&context->PingHistory, icmpCurrentPingMs);
    }
    __finally
    {
        if (phVersion)
        {
            PhDereferenceObject(phVersion);
        }

        if (icmpEchoBuffer)
        {
            PhDereferenceObject(icmpEchoBuffer);
        }

        if (icmpHandle != INVALID_HANDLE_VALUE)
        {
            IcmpCloseHandle(icmpHandle);
        }

        if (icmpReplyBuffer)
        {
            PhFree(icmpReplyBuffer);
        }
    }

    PostMessage(context->WindowHandle, WM_PING_UPDATE, 0, 0);

    return STATUS_SUCCESS;
}