Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

161 lines
4.2 KiB

  1. /*++
  2. Copyright(c) 2001 Microsoft Corporation
  3. Module Name:
  4. NLB Manager
  5. File Name:
  6. nlbhost_ping.cpp
  7. Abstract:
  8. Implementation of Ping-related functionality of class NLBHost
  9. This code is adapted from the "ping" utility.
  10. History:
  11. 03/31/01 JosephJ Created
  12. --*/
  13. #include "stdafx.h"
  14. #include "ipexport.h"
  15. #include "icmpapi.h"
  16. #include "private.h"
  17. #if 0
  18. struct IPErrorTable {
  19. IP_STATUS Error; // The IP Error
  20. DWORD ErrorNlsID; // NLS string ID
  21. } ErrorTable[] =
  22. {
  23. { IP_BUF_TOO_SMALL, PING_BUF_TOO_SMALL},
  24. { IP_DEST_NET_UNREACHABLE, PING_DEST_NET_UNREACHABLE},
  25. { IP_DEST_HOST_UNREACHABLE, PING_DEST_HOST_UNREACHABLE},
  26. { IP_DEST_PROT_UNREACHABLE, PING_DEST_PROT_UNREACHABLE},
  27. { IP_DEST_PORT_UNREACHABLE, PING_DEST_PORT_UNREACHABLE},
  28. { IP_NO_RESOURCES, PING_NO_RESOURCES},
  29. { IP_BAD_OPTION, PING_BAD_OPTION},
  30. { IP_HW_ERROR, PING_HW_ERROR},
  31. { IP_PACKET_TOO_BIG, PING_PACKET_TOO_BIG},
  32. { IP_REQ_TIMED_OUT, PING_REQ_TIMED_OUT},
  33. { IP_BAD_REQ, PING_BAD_REQ},
  34. { IP_BAD_ROUTE, PING_BAD_ROUTE},
  35. { IP_TTL_EXPIRED_TRANSIT, PING_TTL_EXPIRED_TRANSIT},
  36. { IP_TTL_EXPIRED_REASSEM, PING_TTL_EXPIRED_REASSEM},
  37. { IP_PARAM_PROBLEM, PING_PARAM_PROBLEM},
  38. { IP_SOURCE_QUENCH, PING_SOURCE_QUENCH},
  39. { IP_OPTION_TOO_BIG, PING_OPTION_TOO_BIG},
  40. { IP_BAD_DESTINATION, PING_BAD_DESTINATION},
  41. { IP_NEGOTIATING_IPSEC, PING_NEGOTIATING_IPSEC},
  42. { IP_GENERAL_FAILURE, PING_GENERAL_FAILURE}
  43. };
  44. #endif // 0
  45. UINT
  46. NLBHost::mfn_ping(
  47. VOID
  48. )
  49. {
  50. UINT Status = ERROR_SUCCESS;
  51. LONG inaddr;
  52. char rgchBindString[1024];
  53. mfn_Log(L"NLBHost -- pinging (%s).", (LPCWSTR) m_BindString);
  54. //
  55. // Convert to ANSI.
  56. //
  57. //
  58. // Resolve to an IP address...
  59. //
  60. inaddr = inet_addr(m_BindString);
  61. if (inaddr == -1L)
  62. {
  63. struct hostent *hostp = NULL;
  64. hostp = gethostbyname(m_BindString);
  65. if (hostp) {
  66. unsigned char *pc = (unsigned char *) & inaddr;
  67. // If we find a host entry, set up the internet address
  68. inaddr = *(long *)hostp->h_addr;
  69. mfn_Log(
  70. L"NLBHost -- resolved to IP address %d.%d.%d.%d.",
  71. pc[0],
  72. pc[1],
  73. pc[2],
  74. pc[3]
  75. );
  76. } else {
  77. // Neither dotted, not name.
  78. Status = WSAGetLastError();
  79. mfn_Log(L"NLBHost -- could not resolve bind address.");
  80. goto end;
  81. }
  82. }
  83. //
  84. // Send Icmp echo.
  85. //
  86. HANDLE IcmpHandle;
  87. IcmpHandle = IcmpCreateFile();
  88. if (IcmpHandle == INVALID_HANDLE_VALUE) {
  89. Status = GetLastError();
  90. mfn_Log(L"Unable to contact IP driver, error code %d.",Status);
  91. goto end;
  92. }
  93. const int Count = 4;
  94. const int Timeout = 1000;
  95. const int MinInterval = 500;
  96. for (int i = 0; i < Count; i++)
  97. {
  98. static BYTE SendBuffer[32];
  99. BYTE RcvBuffer[1024];
  100. int numberOfReplies;
  101. numberOfReplies = IcmpSendEcho2(IcmpHandle,
  102. 0,
  103. NULL,
  104. NULL,
  105. inaddr,
  106. SendBuffer,
  107. sizeof(SendBuffer),
  108. NULL,
  109. RcvBuffer,
  110. sizeof(RcvBuffer),
  111. Timeout
  112. );
  113. if (numberOfReplies == 0) {
  114. int errorCode = GetLastError();
  115. mfn_Log(L"ICMP Error %d", errorCode );
  116. // TODO: look at ping sources for proper error reporting
  117. // (host unreachable, etc...)
  118. if (i < (Count - 1)) {
  119. Sleep(MinInterval);
  120. }
  121. }
  122. else
  123. {
  124. mfn_Log(L"Ping succeeded.");
  125. Status = ERROR_SUCCESS;
  126. break;
  127. }
  128. }
  129. end:
  130. return Status;
  131. }