MFC C ++: IcmpSendEcho успешно возвращается, но состояние IP_DEST_HOST_UNREACHABLE, а RoundTripTime не является временем ожидания по умолчанию - PullRequest
0 голосов
/ 19 февраля 2019

Я использую IcmpSendEcho внутри своей программы, чтобы проверить, включен ли конкретный компьютер, соответствующий IP-адресу внутри моей внутренней сети.Это решение эффективно работает практически для всех наших клиентов, но у одного из них очень необычный случай.

Я, конечно, знаю, что это конкретный компьютер (кстати, бывает с несколькими компьютерами) включен и работает 24/7 , но поведение IcmpSendEcho меняется в течение дня, и я не понимаю, почему.

Во время интервала с 05:00 до 20:00, IcmpSendEcho на этом компьютере возвращает успешный эхо-запрос (IP_SUCCESS) с вероятным временем приема-передачи, но в течение временного интервала с 08:00 до 05:00 IcmpSendEcho возвращает ошибку IP_DEST_HOST_UNREACHABLE.Странная часть этого заключается в том, что время приема-передачи НЕ соответствует времени ожидания, назначенному функции IcmpSendEcho, но меньше.

Если я выполняю тест на компьютере, который переключаетсявыключен, мой код сообщает мне, что запрос IcmpSendEcho не выполнен, поэтому код переходит в другой блок инструкций.

Почему это происходит?В чем разница между запросом IcmpSendEcho, который не выполняется и выполняется, но с кодом ошибки, например IP_DEST_HOST_UNREACHABLE?

Спасибо за вашу помощь.

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);
  }
}

Очевидно, что любое улучшениеПриведенный выше код хорошо принят, еще раз спасибо.

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

Гоча.У маршрутизатора было правило, которое блокировало любой тип трафика от часа до другого часа.Очевидно, клиент не сказал мне об этом.Спасибо всем!

0 голосов
/ 20 февраля 2019

Проблема в том, как адрес разрешен.В случае, когда ПК находится в той же локальной сети, необходимо получить MAC-адрес на основе IP-адреса назначения.Он использует протокол ARP, который не может получить MAC-адрес, поэтому он не может отправить сообщение ICMP.Тогда это, вероятно, будет уважать время ожидания.Это сдастся во время ожидания.В другом случае, если вы отправляете ICMP-сообщение с эхо-запросом на узел, находящийся за пределами локальной сети, это сообщение будет маршрутизироваться через промежуточные маршрутизаторы (также может быть шлюзом).Таким образом, IP-пакет, передающий сообщение ICMP, оставит ваш компьютер для следующего перехода, где-то за пределами следующего перехода, маршрутизатор поймет, что не сможет направить этот пакет ICMP, и вернет сообщение ICMP DestinationUnreachable дляузел происхождения (ваш компьютер).Когда ping получает это сообщение, не имеет смысла ждать тайм-аут, он уже получил сообщение о том, что пункт назначения недоступен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...