Leaked source code of windows server 2003
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.

285 lines
7.3 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. ping.c
  5. Abstract:
  6. Packet INternet Groper utility for TCP/IP.
  7. Author:
  8. Numerous TCP/IP folks.
  9. Revision History:
  10. Who When What
  11. -------- -------- ----------------------------------------------
  12. WeihaiC 5-Dec-98. Moved from \nt\private\net\sockets\tcpcmd\ping
  13. MohsinA, 21-Oct-96. INADDR_NONE check to avoid broadcast.
  14. MohsinA, 13-Nov-96. Max packet size < 64K.
  15. Notes:
  16. --*/
  17. //:ts=4
  18. typedef unsigned long ULONG;
  19. typedef unsigned short ushort;
  20. typedef unsigned int UINT;
  21. typedef unsigned char UCHAR;
  22. #include "precomp.h"
  23. #include "icmpapi.h"
  24. #define NOGDI
  25. #define NOMINMAX
  26. #define MAX_BUFFER_SIZE (sizeof(ICMP_ECHO_REPLY) + 0xfff7 + MAX_OPT_SIZE)
  27. #define DEFAULT_BUFFER_SIZE (0x2000 - 8)
  28. #define DEFAULT_SEND_SIZE 32
  29. #define DEFAULT_COUNT 4
  30. #define DEFAULT_TTL 32
  31. #define DEFAULT_TOS 0
  32. #define DEFAULT_TIMEOUT 5000L
  33. #define MIN_INTERVAL 1000L
  34. #define TRUE 1
  35. #define FALSE 0
  36. #define STDOUT 1
  37. #define net_long(x) (((((ULONG)(x))&0xffL)<<24) | \
  38. ((((ULONG)(x))&0xff00L)<<8) | \
  39. ((((ULONG)(x))&0xff0000L)>>8) | \
  40. ((((ULONG)(x))&0xff000000L)>>24))
  41. WSADATA WsaData;
  42. // ========================================================================
  43. // Caveat: return 0 for invalid, else internet address.
  44. // I would prefer -1 for error. - MohsinA, 21-Nov-96.
  45. unsigned long
  46. get_pingee(char *ahstr, char **hstr, int *was_inaddr, int dnsreq)
  47. {
  48. struct hostent *hostp = NULL;
  49. long inaddr;
  50. if( strcmp( ahstr, "255.255.255.255" ) == 0 ){
  51. return 0L;
  52. }
  53. if ((inaddr = inet_addr(ahstr)) == -1L) {
  54. hostp = gethostbyname(ahstr);
  55. if (hostp) {
  56. /*
  57. * If we find a host entry, set up the internet address
  58. */
  59. inaddr = *(long *)hostp->h_addr;
  60. *was_inaddr = 0;
  61. } else {
  62. // Neither dotted, not name.
  63. return(0L);
  64. }
  65. } else {
  66. // Is dotted.
  67. *was_inaddr = 1;
  68. if (dnsreq == 1) {
  69. hostp = gethostbyaddr((char *)&inaddr,sizeof(inaddr),AF_INET);
  70. }
  71. }
  72. *hstr = hostp ? hostp->h_name : (char *)NULL;
  73. return(inaddr);
  74. }
  75. // ========================================================================
  76. BOOL Ping (LPTSTR pszServerName)
  77. {
  78. UINT i;
  79. int found_addr = 0;
  80. int dnsreq = 0;
  81. char *hostname = NULL;
  82. int was_inaddr;
  83. DWORD numberOfReplies;
  84. UINT Count = DEFAULT_COUNT;
  85. UCHAR TTL = DEFAULT_TTL;
  86. UCHAR FAR *Opt = (UCHAR FAR *)0; // Pointer to send options
  87. UINT OptLength = 0;
  88. int OptIndex = 0; // Current index into SendOptions
  89. int SRIndex = -1; // Where to put address, if source routing
  90. UCHAR TOS = DEFAULT_TOS;
  91. UCHAR Flags = 0;
  92. ULONG Timeout = DEFAULT_TIMEOUT;
  93. IP_OPTION_INFORMATION SendOpts;
  94. int EndOffset;
  95. DWORD errorCode;
  96. HANDLE IcmpHandle = NULL;
  97. struct in_addr addr;
  98. PICMP_ECHO_REPLY reply;
  99. BOOL sourceRouting = FALSE;
  100. char *SendBuffer = NULL;
  101. char *RcvBuffer = NULL;
  102. UINT RcvSize;
  103. UINT SendSize = DEFAULT_SEND_SIZE;
  104. BOOL bRet = FALSE;
  105. IPAddr address = 0; // was local to main earlier.
  106. char *arg;
  107. // ====================================================================
  108. #ifdef UNICODE
  109. LPSTR pszAnsiServerName = NULL;
  110. DWORD uSize;
  111. if (pszServerName && (uSize = WideCharToMultiByte(CP_ACP,
  112. 0,
  113. pszServerName,
  114. -1,
  115. NULL,
  116. 0,
  117. NULL,
  118. NULL))) {
  119. if (pszAnsiServerName = (LPSTR) LocalAlloc(LPTR, uSize)) {
  120. if (!WideCharToMultiByte (CP_ACP,
  121. 0,
  122. pszServerName,
  123. -1,
  124. pszAnsiServerName,
  125. uSize,
  126. NULL,
  127. NULL))
  128. goto CleanUp;
  129. }
  130. else
  131. goto CleanUp;
  132. }
  133. arg = pszAnsiServerName;
  134. #else
  135. arg = pszServerName;
  136. #endif
  137. if (WSAStartup( 0x0101, &WsaData))
  138. goto CleanUp;
  139. // Added check for INADDR_NONE, MohsinA, 21-Oct-96.
  140. address = get_pingee(arg, &hostname, &was_inaddr, dnsreq);
  141. if(!address || (address == INADDR_NONE) ){
  142. SetLastError (DNS_ERROR_INVALID_IP_ADDRESS);
  143. goto CleanUp;
  144. }
  145. IcmpHandle = IcmpCreateFile();
  146. if (IcmpHandle == INVALID_HANDLE_VALUE) {
  147. goto CleanUp;
  148. }
  149. if (! (SendBuffer = (char *) LocalAlloc(LMEM_FIXED, SendSize))) {
  150. goto CleanUp;
  151. }
  152. //
  153. // Calculate receive buffer size and try to allocate it.
  154. //
  155. if (SendSize <= DEFAULT_SEND_SIZE) {
  156. RcvSize = DEFAULT_BUFFER_SIZE;
  157. }
  158. else {
  159. RcvSize = MAX_BUFFER_SIZE;
  160. }
  161. if (! (RcvBuffer = (char *)LocalAlloc(LMEM_FIXED, RcvSize))) {
  162. goto CleanUp;
  163. }
  164. //
  165. // Initialize the send buffer pattern.
  166. //
  167. for (i = 0; i < SendSize; i++) {
  168. SendBuffer[i] = 'a' + (i % 23);
  169. }
  170. //
  171. // Initialize the send options
  172. //
  173. SendOpts.OptionsData = Opt;
  174. SendOpts.OptionsSize = (UCHAR)OptLength;
  175. SendOpts.Ttl = TTL;
  176. SendOpts.Tos = TOS;
  177. SendOpts.Flags = Flags;
  178. addr.s_addr = address;
  179. numberOfReplies = IcmpSendEcho(IcmpHandle,
  180. address,
  181. SendBuffer,
  182. (unsigned short) SendSize,
  183. &SendOpts,
  184. RcvBuffer,
  185. RcvSize,
  186. Timeout);
  187. if (numberOfReplies == 0) {
  188. errorCode = GetLastError();
  189. goto CleanUp;
  190. }
  191. else {
  192. reply = (PICMP_ECHO_REPLY) RcvBuffer;
  193. while (numberOfReplies--) {
  194. if (reply->Status == IP_SUCCESS) {
  195. bRet = TRUE;
  196. break;
  197. }
  198. reply++;
  199. }
  200. }
  201. CleanUp:
  202. #ifdef UNICODE
  203. if (pszAnsiServerName) {
  204. LocalFree(pszAnsiServerName);
  205. }
  206. #endif
  207. if (IcmpHandle) {
  208. IcmpCloseHandle(IcmpHandle);
  209. }
  210. if (SendBuffer) {
  211. LocalFree(SendBuffer);
  212. }
  213. if (RcvBuffer) {
  214. LocalFree(RcvBuffer);
  215. }
  216. return bRet;
  217. }