err_t pxping_init(struct netif *netif, SOCKET sock4, SOCKET sock6) { OSVERSIONINFO osvi; int status; LWIP_UNUSED_ARG(sock4); LWIP_UNUSED_ARG(sock6); ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); status = GetVersionEx(&osvi); if (status == 0) { return ERR_ARG; } if (osvi.dwMajorVersion >= 6) { g_pxping.callback4 = (void *)pxping_icmp4_callback_apc; g_pxping.callback6 = (void *)pxping_icmp6_callback_apc; } else { g_pxping.callback4 = (void *)pxping_icmp4_callback_old; g_pxping.callback6 = (void *)pxping_icmp6_callback_old; } g_pxping.hdl4 = IcmpCreateFile(); if (g_pxping.hdl4 != INVALID_HANDLE_VALUE) { ping_proxy_accept(pxping_recv4, &g_pxping); } else { DPRINTF(("IcmpCreateFile: error %d\n", GetLastError())); } g_pxping.hdl6 = Icmp6CreateFile(); if (g_pxping.hdl6 != INVALID_HANDLE_VALUE) { ping6_proxy_accept(pxping_recv6, &g_pxping); } else { DPRINTF(("Icmp6CreateFile: error %d\n", GetLastError())); } if (g_pxping.hdl4 == INVALID_HANDLE_VALUE && g_pxping.hdl6 == INVALID_HANDLE_VALUE) { return ERR_ARG; } g_pxping.netif = netif; return ERR_OK; }
int NetKeepaliveInit(char *src, char *dst, int maximal_keepalive, int family) { struct timeval tv; #ifdef WIN32 hndliphlp = LoadLibrary("IPHLPAPI.DLL"); if (!hndliphlp) { Display(LOG_LEVEL_3, ELError, "NetKeepaliveInit", HEX_STR_CANT_CREATE_ICMP_HNDL_FILE); return 1; } if (family == AF_INET6) { // Try to load IPv6 // support functions // from iphlpapi // Icmp6CreateFile = (HANDLE (WINAPI *)(void)) GetProcAddress(hndliphlp, "Icmp6CreateFile"); IcmpCloseHandle = (BOOL (WINAPI *)(HANDLE)) GetProcAddress(hndliphlp, "IcmpCloseHandle"); Icmp6SendEcho2 = (DWORD (WINAPI *)(HANDLE, HANDLE, FARPROC, PVOID, struct sockaddr_in6*, struct sockaddr_in6*, LPVOID, WORD, PIP_OPTION_INFORMATION, LPVOID, DWORD, DWORD)) GetProcAddress(hndliphlp, "Icmp6SendEcho2"); Icmp6ParseReplies = (DWORD (WINAPI *)(LPVOID, DWORD)) GetProcAddress(hndliphlp, "Icmp6ParseReplies"); if( (Icmp6CreateFile == NULL) || (IcmpCloseHandle == NULL) || (Icmp6SendEcho2 == NULL) || (Icmp6ParseReplies == NULL) ) { Display(LOG_LEVEL_3, ELError, "NetKeepaliveInit", HEX_STR_CANT_CREATE_ICMP_HNDL_FILE); return 1; } hHandle = Icmp6CreateFile(); } #ifdef V4V6_SUPPORT else if (family == AF_INET) { // Try to load IPv4 // support functions // from iphlpapi // IcmpCreateFile = (HANDLE (WINAPI *)(VOID)) GetProcAddress(hndliphlp, "IcmpCreateFile"); IcmpCloseHandle = (BOOL (WINAPI *)(HANDLE)) GetProcAddress(hndliphlp, "IcmpCloseHandle"); IcmpSendEcho2 = (DWORD (WINAPI *)(HANDLE, HANDLE, FARPROC, PVOID, IPAddr, LPVOID, WORD, PIP_OPTION_INFORMATION, LPVOID, DWORD, DWORD)) GetProcAddress(hndliphlp, "IcmpSendEcho2"); IcmpParseReplies = (DWORD (WINAPI *)(LPVOID, DWORD)) GetProcAddress(hndliphlp, "IcmpParseReplies"); if ( (IcmpCreateFile == NULL) || (IcmpCloseHandle == NULL) || (IcmpSendEcho2 == NULL) || (IcmpParseReplies == NULL) ) { Display(LOG_LEVEL_3, ELError, "NetKeepaliveInit", HEX_STR_CANT_CREATE_ICMP_HNDL_FILE); return 1; } hHandle = IcmpCreateFile(); } #endif if (hHandle == INVALID_HANDLE_VALUE) { Display(LOG_LEVEL_3, ELError, "NetKeepaliveInit", HEX_STR_CANT_CREATE_ICMP_HNDL_FILE); return 1; } #endif /* Load the structure with passed in AND * initial values */ seqn = 0; if (strncpy(ka.host, dst, sizeof(ka.host)) == NULL) return 1; ka.maximal_keepalive = maximal_keepalive; ka.current_keepalive = KA_INITIAL_KEEPALIVE; ka.major_fuzz = (float) 0.60; ka.minor_fuzz = (float) 0.075; /* And initialize the next event */ /* Initial timeout is set to five seconds */ GETTIMEOFDAY(&tv, NULL); ka.next_event.tv_sec = tv.tv_sec + KA_INITIAL_KEEPALIVE; ka.next_event.tv_usec = tv.tv_usec; /* initialize the random source */ SRANDOM(tv.tv_usec); /* set the family */ ka.family = family; /* get a ping socket and a monitor socket */ if (family == AF_INET6) { INET_PTON(AF_INET6, dst, &ka.sa6.sin6_addr); ka.sa6.sin6_family = AF_INET6; INET_PTON(AF_INET6, src, &ka.sa6_local.sin6_addr); ka.sa6_local.sin6_family = AF_INET6; #ifndef WIN32 ka.keepalive_fd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); #endif } #ifdef V4V6_SUPPORT else if (family == AF_INET) { INET_PTON(AF_INET, dst, &ka.sa.sin_addr); ka.sa.sin_family = AF_INET; INET_PTON(AF_INET, src, &ka.sa_local.sin_addr); ka.sa_local.sin_family = AF_INET; #ifndef WIN32 ka.keepalive_fd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); #endif } #endif /* V4V6_SUPPORT */ ka.consecutive_timeout = 0; ka.still_up = 0; ka.doit = 1; ka.count = 0; ka.got_read = 0; ka.got_write = 0; ka.pinged = 1; /* ok, we are inialized */ ka.init = 1; Display(LOG_LEVEL_3, ELInfo, "NetKeepaliveInit", HEX_STR_KEEPALIVE_INITIALIZED, dst, maximal_keepalive); return 0; }
/*! * \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; }
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; }
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; }
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; }