MFC C++ : IcmpSendEcho returns successfully, but status is IP_DEST_HOST_UNREACHABLE and RoundTripTime is not the default timeout time

  • Thread starter Thread starter Luca Corsini
  • Start date Start date
L

Luca Corsini

Guest
I use IcmpSendEcho inside my program to check if a specific pc corresponding to an IP address inside my internal network is on. This solution works effectively for almost all of our customers, but one of them has a very inusual case.

I certainly know that this specific computer (it happens with more than one computer, by the way) is on and operative 24/7, but the IcmpSendEcho behavior changes during the day and I don't understand why.

During the time slot 05:00 AM - 08:00 PM, IcmpSendEcho on this computer returns a successful echo request (IP_SUCCESS) with a plausible roundtrip time, but during the time slot 08:00 PM - 05:00 AM, IcmpSendEcho returns the error IP_DEST_HOST_UNREACHABLE. The strange part about this is that the roundtrip time DOES NOT correspond with the timeout time assigned to the IcmpSendEcho function, but is lower.

If i execute the test on a computer that is switched off, my code tells me that IcmpSendEcho request has failed, so the code goes to a different instruction block.

Why is this happening? What is the difference between the IcmpSendEcho request failing and succeeding but with an error code like IP_DEST_HOST_UNREACHABLE ?

Thank you for your help.


unsigned long ipaddr = inet_addr(CT2CA(myIpAddress));
HANDLE hIcmpFile;
hIcmpFile = IcmpCreateFile();
if (hIcmpFile == INVALID_HANDLE_VALUE) {
printf("\tUnable to open handle.\n");
printf("IcmpCreatefile returned error: %ld\n", GetLastError());
EDMLog::Error(_T("Unable to open handle. error code 001"));
errorCode = _T("001");
}
else {
char SendData[100];
for (int x = 0; x < 100; ++x) {
SendData[x] = 'A';
}
LPVOID ReplyBuffer = NULL;
DWORD ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);

ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);
ReplyBuffer = (VOID*)malloc(ReplySize);
if (ReplyBuffer == NULL) {
printf("\tUnable to allocate memory\n");
EDMLog::Error(_T("Unable to allocate memory. error code 001"));
errorCode = _T("001");
}
else {

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

printf("\tSent icmp message to %s\n", CT2CA(myIpAddress);
EDMLog::Information(_T("Test su indirizzo ") + myIpAddress);
if (dwRetVal != 0) {
/////////////////////////////////////
//HERE THE REQUEST IS SUCCESSFULL BUT THE ERROR CODE IS IP_DEST_HOST_UNREACHABLE
/////////////////////////////////////
PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
struct in_addr ReplyAddr;
ReplyAddr.S_un.S_addr = pEchoReply->Address;
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\n",
pEchoReply->Status);

switch (pEchoReply->Status) {
case IP_SUCCESS:
//GESTIONE PARTICOLARE PER GAROM
//errorCode.Format(_T("90%d"), i + 1);
//GESTIONE TRADIZIONALE
errorCode = _T("000");
EDMLog::Debug(_T("Test eseguito correttamente."));
break;
case IP_BUF_TOO_SMALL:
EDMLog::Error(_T("Buffer too small. error code 101"));
errorCode = _T("101");
break;
case IP_DEST_NET_UNREACHABLE:
EDMLog::Error(_T("DEST NET UNREACHABLE. error code 102"));
errorCode = _T("102");
break;
case IP_DEST_HOST_UNREACHABLE:
EDMLog::Error(_T("DEST HOST UNREACHABLE. error code 103"));
errorCode = _T("103");
break;
case IP_DEST_PROT_UNREACHABLE:
EDMLog::Error(_T("DEST PROT UNREACHABLE. error code 104"));
errorCode = _T("104");
break;
case IP_DEST_PORT_UNREACHABLE:
EDMLog::Error(_T("DEST PORT UNREACHABLE. error code 105"));
errorCode = _T("105");
break;
case IP_NO_RESOURCES:
EDMLog::Error(_T("IP NO RESOURCES. error code 106"));
errorCode = _T("106");
break;
case IP_BAD_OPTION:
EDMLog::Error(_T("IP BAD OPTION. error code 107"));
errorCode = _T("107");
break;
case IP_HW_ERROR:
EDMLog::Error(_T("IP HW ERROR. error code 108"));
errorCode = _T("108");
break;
case IP_PACKET_TOO_BIG:
EDMLog::Error(_T("IP PACKET TOO BIG. error code 109"));
errorCode = _T("109");
break;
case IP_REQ_TIMED_OUT:
EDMLog::Error(_T("IP REQ TIMED OUT. error code 110"));
errorCode = _T("110");
break;
case IP_BAD_REQ:
EDMLog::Error(_T("IP BAD REQ. error code 111"));
errorCode = _T("111");
break;
case IP_BAD_ROUTE:
EDMLog::Error(_T("IP BAD ROUTE. error code 112"));
errorCode = _T("112");
break;
case IP_TTL_EXPIRED_TRANSIT:
EDMLog::Error(_T("IP TTL EXPIRED TRANSIT. error code 113"));
errorCode = _T("113");
break;
case IP_TTL_EXPIRED_REASSEM:
EDMLog::Error(_T("IP TTL EXPIRED REASSEM. error code 114"));
errorCode = _T("114");
break;
case IP_PARAM_PROBLEM:
EDMLog::Error(_T("IP PARAM PROBLEM. error code 115"));
errorCode = _T("115");
break;
case IP_SOURCE_QUENCH:
EDMLog::Error(_T("IP SOURCE QUENCH. error code 116"));
errorCode = _T("116");
break;
case IP_OPTION_TOO_BIG:
EDMLog::Error(_T("IP OPTION TOO BIG. error code 117"));
errorCode = _T("117");
break;
case IP_BAD_DESTINATION:
EDMLog::Error(_T("IP BAD DESTINATION. error code 118"));
errorCode = _T("118");
break;
case IP_GENERAL_FAILURE:
EDMLog::Error(_T("IP GENERAL FAILURE. error code 150"));
errorCode = _T("150");
break;
}
printf("\t Roundtrip time = %ld milliseconds\n",
pEchoReply->RoundTripTime);

if ((int)(pEchoReply->RoundTripTime) == 0)
valore.Format(_T("%d"), 1);
else
valore.Format(_T("%d"),(int)(pEchoReply->RoundTripTime));
}
else {
/////////////////////////////////////
//HERE THE REQUEST IS NOT SUCCESSFUL (TIMEOUT)
/////////////////////////////////////

printf("\tCall to IcmpSendEcho failed.\n");
DWORD lastError = GetLastError();
printf("\tIcmpSendEcho returned error: %ld\n", lastError);



PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
struct in_addr ReplyAddr;
ReplyAddr.S_un.S_addr = pEchoReply->Address;
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\n",
pEchoReply->Status);

valore = _T("0");

switch (pEchoReply->Status) {
case IP_SUCCESS:
errorCode = _T("000");
EDMLog::Information(_T("Test eseguito correttamente."));
break;
case IP_BUF_TOO_SMALL:
EDMLog::Error(_T("Buffer too small. error code 101"));
errorCode = _T("101");
break;
case IP_DEST_NET_UNREACHABLE:
EDMLog::Error(_T("DEST NET UNREACHABLE. error code 102"));
errorCode = _T("102");
break;
case IP_DEST_HOST_UNREACHABLE:
EDMLog::Error(_T("DEST HOST UNREACHABLE. error code 103"));
errorCode = _T("103");
break;
case IP_DEST_PROT_UNREACHABLE:
EDMLog::Error(_T("DEST PROT UNREACHABLE. error code 104"));
errorCode = _T("104");
break;
case IP_DEST_PORT_UNREACHABLE:
EDMLog::Error(_T("DEST PORT UNREACHABLE. error code 105"));
errorCode = _T("105");
break;
case IP_NO_RESOURCES:
EDMLog::Error(_T("IP NO RESOURCES. error code 106"));
errorCode = _T("106");
break;
case IP_BAD_OPTION:
EDMLog::Error(_T("IP BAD OPTION. error code 107"));
errorCode = _T("107");
break;
case IP_HW_ERROR:
EDMLog::Error(_T("IP HW ERROR. error code 108"));
errorCode = _T("108");
break;
case IP_PACKET_TOO_BIG:
EDMLog::Error(_T("IP PACKET TOO BIG. error code 109"));
errorCode = _T("109");
break;
case IP_REQ_TIMED_OUT:
EDMLog::Error(_T("IP REQ TIMED OUT. error code 110"));
errorCode = _T("004");
valore = _T("10000");
break;
case IP_BAD_REQ:
EDMLog::Error(_T("IP BAD REQ. error code 111"));
errorCode = _T("111");
break;
case IP_BAD_ROUTE:
EDMLog::Error(_T("IP BAD ROUTE. error code 112"));
errorCode = _T("112");
break;
case IP_TTL_EXPIRED_TRANSIT:
EDMLog::Error(_T("IP TTL EXPIRED TRANSIT. error code 113"));
errorCode = _T("113");
break;
case IP_TTL_EXPIRED_REASSEM:
EDMLog::Error(_T("IP TTL EXPIRED REASSEM. error code 114"));
errorCode = _T("114");
break;
case IP_PARAM_PROBLEM:
EDMLog::Error(_T("IP PARAM PROBLEM. error code 115"));
errorCode = _T("115");
break;
case IP_SOURCE_QUENCH:
EDMLog::Error(_T("IP SOURCE QUENCH. error code 116"));
errorCode = _T("116");
break;
case IP_OPTION_TOO_BIG:
EDMLog::Error(_T("IP OPTION TOO BIG. error code 117"));
errorCode = _T("117");
break;
case IP_BAD_DESTINATION:
EDMLog::Error(_T("IP BAD DESTINATION. error code 118"));
errorCode = _T("118");
break;
case IP_GENERAL_FAILURE:
EDMLog::Error(_T("IP GENERAL FAILURE. error code 150"));
errorCode = _T("150");
break;
}
}

IcmpCloseHandle(hIcmpFile);
}
}

Continue reading...
 
Back
Top