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.

399 lines
8.1 KiB

  1. ///////////////////////////////
  2. // File: tcp.cpp
  3. //
  4. // Description:
  5. // #include statements
  6. //
  7. #include <windows.h>
  8. #include <stdio.h>
  9. #include <winsock.h>
  10. #include "tcp.h"
  11. #include "util.h"
  12. #include "rw_common.h"
  13. #define RW_TCP_NOT_INITILIZED 0
  14. #define RW_TCP_INITILIZED 1
  15. #define RW_ICMP_NOT_INITILIZED 0
  16. #define RW_ICMP_INITILIZED 1
  17. static int siTcpStatus = RW_TCP_NOT_INITILIZED;
  18. static HINSTANCE hIcmp= NULL;
  19. static WSADATA wsa;
  20. int ResolveHostByThread(LPSTR pHost);
  21. int ResolveHostByAddrThread(LPSTR pHost);
  22. #define GET_HOST_TOUT (15 * 1000)
  23. #define PING_TOUT (15 * 1000)
  24. static struct hostent *gphostent= NULL;
  25. BOOL InitForTcp()
  26. {
  27. BOOL bRet= FALSE;
  28. if( siTcpStatus == RW_TCP_INITILIZED )
  29. return TRUE;
  30. if (! WSAStartup(0x0101, &wsa )) {
  31. siTcpStatus = RW_TCP_INITILIZED;
  32. bRet= TRUE;
  33. }
  34. return bRet;
  35. }
  36. BOOL InitForIcmp()
  37. {
  38. if(hIcmp)
  39. return TRUE;
  40. hIcmp = LoadLibrary( _T("ICMP.DLL") ); // Load ICMP.DLL and store globally
  41. if( ! hIcmp )
  42. { // Whine if unable to load the DLL
  43. DisplayMessage("Unable to locate ICMP.DLL");
  44. return( FALSE );
  45. }
  46. return TRUE;
  47. }
  48. void CloseForTcpIcmp()
  49. {
  50. if (hIcmp)
  51. FreeLibrary(hIcmp); // When app is closed, free the ICMP DLL
  52. if(siTcpStatus == RW_TCP_INITILIZED)
  53. WSACleanup(); // And clean up sockets
  54. hIcmp = NULL;
  55. siTcpStatus = RW_TCP_NOT_INITILIZED;
  56. }
  57. //
  58. // Tries to get the host name and pings using ICMP
  59. // returns
  60. // RWZ_PINGSTATUS_NOTCPIP : if no socket library or get hostname fails
  61. // RWZ_PINGSTATUS_SUCCESS : if gethostname and ping is successful
  62. // RWZ_PINGSTATUS_FAIL : if gethostname is succesful and ping via icmp fails
  63. DWORD PingHost()
  64. {
  65. DWORD dwRet= 0;
  66. char szIPAddress[80];
  67. dwRet = RWZ_PINGSTATUS_NOTCPIP;
  68. if(!InitForTcp()) {
  69. return dwRet; // Tcp is not installed
  70. }
  71. memset(szIPAddress, '\0', 80);
  72. if (!gethostname(szIPAddress, 80))
  73. {
  74. if (Ping(szIPAddress)){
  75. dwRet = RWZ_PINGSTATUS_SUCCESS;
  76. }else {
  77. dwRet = RWZ_PINGSTATUS_FAIL;
  78. }
  79. }
  80. return dwRet;
  81. }
  82. BOOL Ping(LPSTR szIPAddress)
  83. {
  84. BOOL bRet= FALSE;
  85. if( !InitForIcmp())
  86. return bRet;
  87. if(!InitForTcp()) {
  88. return FALSE; // Tcp is not installed
  89. }
  90. static struct sockaddr_in saDestAddr;
  91. char szBuffer[64];
  92. DWORD *dwIPAddr, dwStatus;
  93. HANDLE hIP;
  94. struct hostent *phostent;
  95. PIP_ECHO_REPLY pIpe;
  96. if(!ResolveHostByThread(szIPAddress)) {
  97. gphostent = gethostbyname(szIPAddress);
  98. phostent = gphostent;
  99. }else {
  100. phostent= NULL;
  101. }
  102. if( ! phostent ){
  103. RW_DEBUG << "\n Resolving by Address " << flush;
  104. int iError;
  105. iError = 0;
  106. iError = WSAGetLastError ();
  107. RW_DEBUG << "\n Get Host By Name Error " << iError << flush;
  108. if(iError){
  109. WSASetLastError (0);
  110. //return 0;
  111. }
  112. saDestAddr.sin_addr.s_addr = inet_addr(szIPAddress);
  113. if( saDestAddr.sin_addr.s_addr !=INADDR_NONE ) {
  114. if(!ResolveHostByAddrThread((LPSTR)&saDestAddr.sin_addr.s_addr)) {
  115. gphostent = gethostbyaddr((LPSTR)&saDestAddr.sin_addr.s_addr,4, PF_INET) ;
  116. phostent = gphostent;
  117. }else {
  118. phostent= NULL;
  119. }
  120. }
  121. if(!phostent)
  122. {
  123. DisplayMessage(szIPAddress , "Unable to obtain an IP address for %s");
  124. return bRet;
  125. }
  126. }
  127. dwIPAddr = (DWORD *)( *phostent->h_addr_list );
  128. ICMPCREATEFILE pIcmpCreateFile;
  129. pIcmpCreateFile = (ICMPCREATEFILE) GetProcAddress(hIcmp, "IcmpCreateFile");
  130. if (NULL == pIcmpCreateFile)
  131. {
  132. DisplayMessage("IcmpCreateFile GetProc Error", "");
  133. return FALSE;
  134. }
  135. ICMPCLOSEHANDLE pIcmpCloseHandle;
  136. pIcmpCloseHandle = (ICMPCLOSEHANDLE) GetProcAddress(hIcmp, "IcmpCloseHandle");
  137. if (NULL == pIcmpCloseHandle)
  138. {
  139. DisplayMessage("IcmpCloseHandle GetProc Error", "");
  140. return bRet;
  141. }
  142. ICMPSENDECHO pIcmpSendEcho;
  143. pIcmpSendEcho = (ICMPSENDECHO) GetProcAddress(hIcmp, "IcmpSendEcho");
  144. if (NULL == pIcmpSendEcho)
  145. {
  146. DisplayMessage("IcmpSendEcho GetProc Error", "");
  147. return bRet;
  148. }
  149. if( ! pIcmpCreateFile || ! pIcmpCloseHandle || ! pIcmpSendEcho )
  150. {
  151. DisplayMessage("Unable to locate required API functions", "");
  152. return bRet;
  153. }
  154. hIP = pIcmpCreateFile();
  155. if( hIP == INVALID_HANDLE_VALUE )
  156. {
  157. DisplayMessage("Unable to open PING service");
  158. return bRet;
  159. }
  160. memset( szBuffer, '\xAA', 64 );
  161. pIpe = (PIP_ECHO_REPLY)LocalAlloc(LPTR, sizeof(IP_ECHO_REPLY) + 64);
  162. if (pIpe)
  163. {
  164. pIpe->Data = szIPAddress;
  165. pIpe->DataSize = 64;
  166. dwStatus = pIcmpSendEcho( hIP, *dwIPAddr, szBuffer, 64, NULL, pIpe,
  167. sizeof(IP_ECHO_REPLY) + 64, PING_TOUT );
  168. if(dwStatus)
  169. {
  170. bRet = TRUE;
  171. }
  172. LocalFree(pIpe);
  173. pIcmpCloseHandle(hIP);
  174. }
  175. return bRet;
  176. }
  177. BOOL CheckHostName(LPSTR szIISServer)
  178. {
  179. // WSAStartup() is already called
  180. if(!InitForTcp()) {
  181. return FALSE; // Tcp is not installed
  182. }
  183. struct hostent *phostent;
  184. if(!ResolveHostByThread(szIISServer)) {
  185. phostent = gphostent;
  186. }else {
  187. phostent= NULL;
  188. }
  189. if (phostent == NULL)
  190. return FALSE;
  191. else
  192. return TRUE;
  193. // WSACleanup() will be called later
  194. }
  195. //
  196. // Returns 1 if there is an Error
  197. // 0 if Successful
  198. DWORD GetHostThread(void *vp)
  199. {
  200. DWORD dwIsError=1;
  201. LPSTR szHost;
  202. szHost = (LPSTR) vp;
  203. int iError = 0;
  204. gphostent = gethostbyname(szHost);
  205. if( ! gphostent ){
  206. iError = WSAGetLastError ();
  207. if(iError) {
  208. WSASetLastError (0); // Reset the error
  209. }
  210. }
  211. else {
  212. dwIsError =0;
  213. }
  214. ExitThread(dwIsError);
  215. return dwIsError;
  216. }
  217. //
  218. // This function returns Calls the gethostbyname and
  219. // returns 0 if Successful and 1 if failure
  220. // the return
  221. //
  222. //
  223. int ResolveHostByThread(LPSTR pHost)
  224. {
  225. int iRet=0;
  226. DWORD dwThreadExitCode;
  227. DWORD dwCreationFlags=0; // Start CREATE_SUSPENDED
  228. DWORD ThreadId;
  229. RW_DEBUG << "\nResolve " << pHost << flush;
  230. HANDLE hParent = CreateThread(NULL,
  231. 0,
  232. (LPTHREAD_START_ROUTINE) GetHostThread,
  233. (void *) pHost,
  234. dwCreationFlags,
  235. &ThreadId );
  236. DWORD dwRet = WaitForSingleObject(hParent,GET_HOST_TOUT);
  237. switch(dwRet) {
  238. case WAIT_ABANDONED :
  239. iRet = 1; // Error In Get Host Name
  240. break;
  241. case WAIT_OBJECT_0 :
  242. RW_DEBUG << "\n\tResolved ( 1 Error, 0 Ok) ";
  243. if( GetExitCodeThread(hParent,&dwThreadExitCode) ) {
  244. iRet = (int) dwThreadExitCode;
  245. }
  246. else {
  247. }
  248. RW_DEBUG << iRet;
  249. break;
  250. case WAIT_TIMEOUT :
  251. RW_DEBUG << "\n\t*** Error Resolving " << flush;
  252. iRet = 1; // Error In Get Host Name
  253. TerminateThread(hParent,0);
  254. break;
  255. default:
  256. break;
  257. }
  258. return iRet;
  259. }
  260. //
  261. // Returns 1 if there is an Error
  262. // 0 if Successful
  263. DWORD GetHostByAddrThread(void *vp)
  264. {
  265. DWORD dwIsError=1;
  266. LPSTR szAddr;
  267. int iError = 0;
  268. szAddr = (LPSTR) vp;
  269. gphostent = gethostbyaddr(szAddr,
  270. 4, PF_INET) ;
  271. if( ! gphostent ){
  272. iError = WSAGetLastError ();
  273. if(iError) {
  274. WSASetLastError (0); // Reset the error
  275. }
  276. }
  277. else {
  278. dwIsError =0;
  279. }
  280. return dwIsError;
  281. }
  282. //
  283. // This function returns Calls the gethostbyaddr and
  284. // returns 0 if Successful and 1 if failure
  285. // the return
  286. //
  287. //
  288. int ResolveHostByAddrThread(LPSTR pHost)
  289. {
  290. int iRet=0;
  291. DWORD dwThreadExitCode;
  292. DWORD dwCreationFlags=0; // Start CREATE_SUSPENDED
  293. DWORD ThreadId;
  294. RW_DEBUG << "\nResolve " << pHost << " By Address " << flush;
  295. HANDLE hParent = CreateThread(NULL,
  296. 0,
  297. (LPTHREAD_START_ROUTINE) GetHostByAddrThread,
  298. (void *) pHost,
  299. dwCreationFlags,
  300. &ThreadId );
  301. DWORD dwRet = WaitForSingleObject(hParent,GET_HOST_TOUT);
  302. switch(dwRet) {
  303. case WAIT_ABANDONED :
  304. iRet = 1; // Error In Get Host Name
  305. break;
  306. case WAIT_OBJECT_0 :
  307. RW_DEBUG << "\n\tResolved ( 1 Error, 0 Ok) ";
  308. if( GetExitCodeThread(hParent,&dwThreadExitCode) ) {
  309. iRet = (int) dwThreadExitCode;
  310. }
  311. else {
  312. }
  313. RW_DEBUG << iRet << flush;
  314. break;
  315. case WAIT_TIMEOUT :
  316. RW_DEBUG << "\n\t*** Error Resolving " << flush;
  317. iRet = 1; // Error In Get Host Name
  318. TerminateThread(hParent,0);
  319. break;
  320. default:
  321. break;
  322. }
  323. return iRet;
  324. }