/////////////////////////////// // File: tcp.cpp // // Description: // #include statements // #include #include #include #include "tcp.h" #include "util.h" #include "rw_common.h" #define RW_TCP_NOT_INITILIZED 0 #define RW_TCP_INITILIZED 1 #define RW_ICMP_NOT_INITILIZED 0 #define RW_ICMP_INITILIZED 1 static int siTcpStatus = RW_TCP_NOT_INITILIZED; static HINSTANCE hIcmp= NULL; static WSADATA wsa; int ResolveHostByThread(LPSTR pHost); int ResolveHostByAddrThread(LPSTR pHost); #define GET_HOST_TOUT (15 * 1000) #define PING_TOUT (15 * 1000) static struct hostent *gphostent= NULL; BOOL InitForTcp() { BOOL bRet= FALSE; if( siTcpStatus == RW_TCP_INITILIZED ) return TRUE; if (! WSAStartup(0x0101, &wsa )) { siTcpStatus = RW_TCP_INITILIZED; bRet= TRUE; } return bRet; } BOOL InitForIcmp() { if(hIcmp) return TRUE; hIcmp = LoadLibrary( _T("ICMP.DLL") ); // Load ICMP.DLL and store globally if( ! hIcmp ) { // Whine if unable to load the DLL DisplayMessage("Unable to locate ICMP.DLL"); return( FALSE ); } return TRUE; } void CloseForTcpIcmp() { if (hIcmp) FreeLibrary(hIcmp); // When app is closed, free the ICMP DLL if(siTcpStatus == RW_TCP_INITILIZED) WSACleanup(); // And clean up sockets hIcmp = NULL; siTcpStatus = RW_TCP_NOT_INITILIZED; } // // Tries to get the host name and pings using ICMP // returns // RWZ_PINGSTATUS_NOTCPIP : if no socket library or get hostname fails // RWZ_PINGSTATUS_SUCCESS : if gethostname and ping is successful // RWZ_PINGSTATUS_FAIL : if gethostname is succesful and ping via icmp fails DWORD PingHost() { DWORD dwRet= 0; char szIPAddress[80]; dwRet = RWZ_PINGSTATUS_NOTCPIP; if(!InitForTcp()) { return dwRet; // Tcp is not installed } memset(szIPAddress, '\0', 80); if (!gethostname(szIPAddress, 80)) { if (Ping(szIPAddress)){ dwRet = RWZ_PINGSTATUS_SUCCESS; }else { dwRet = RWZ_PINGSTATUS_FAIL; } } return dwRet; } BOOL Ping(LPSTR szIPAddress) { BOOL bRet= FALSE; if( !InitForIcmp()) return bRet; if(!InitForTcp()) { return FALSE; // Tcp is not installed } static struct sockaddr_in saDestAddr; char szBuffer[64]; DWORD *dwIPAddr, dwStatus; HANDLE hIP; struct hostent *phostent; PIP_ECHO_REPLY pIpe; if(!ResolveHostByThread(szIPAddress)) { gphostent = gethostbyname(szIPAddress); phostent = gphostent; }else { phostent= NULL; } if( ! phostent ){ RW_DEBUG << "\n Resolving by Address " << flush; int iError; iError = 0; iError = WSAGetLastError (); RW_DEBUG << "\n Get Host By Name Error " << iError << flush; if(iError){ WSASetLastError (0); //return 0; } saDestAddr.sin_addr.s_addr = inet_addr(szIPAddress); if( saDestAddr.sin_addr.s_addr !=INADDR_NONE ) { if(!ResolveHostByAddrThread((LPSTR)&saDestAddr.sin_addr.s_addr)) { gphostent = gethostbyaddr((LPSTR)&saDestAddr.sin_addr.s_addr,4, PF_INET) ; phostent = gphostent; }else { phostent= NULL; } } if(!phostent) { DisplayMessage(szIPAddress , "Unable to obtain an IP address for %s"); return bRet; } } dwIPAddr = (DWORD *)( *phostent->h_addr_list ); ICMPCREATEFILE pIcmpCreateFile; pIcmpCreateFile = (ICMPCREATEFILE) GetProcAddress(hIcmp, "IcmpCreateFile"); if (NULL == pIcmpCreateFile) { DisplayMessage("IcmpCreateFile GetProc Error", ""); return FALSE; } ICMPCLOSEHANDLE pIcmpCloseHandle; pIcmpCloseHandle = (ICMPCLOSEHANDLE) GetProcAddress(hIcmp, "IcmpCloseHandle"); if (NULL == pIcmpCloseHandle) { DisplayMessage("IcmpCloseHandle GetProc Error", ""); return bRet; } ICMPSENDECHO pIcmpSendEcho; pIcmpSendEcho = (ICMPSENDECHO) GetProcAddress(hIcmp, "IcmpSendEcho"); if (NULL == pIcmpSendEcho) { DisplayMessage("IcmpSendEcho GetProc Error", ""); return bRet; } if( ! pIcmpCreateFile || ! pIcmpCloseHandle || ! pIcmpSendEcho ) { DisplayMessage("Unable to locate required API functions", ""); return bRet; } hIP = pIcmpCreateFile(); if( hIP == INVALID_HANDLE_VALUE ) { DisplayMessage("Unable to open PING service"); return bRet; } memset( szBuffer, '\xAA', 64 ); pIpe = (PIP_ECHO_REPLY)LocalAlloc(LPTR, sizeof(IP_ECHO_REPLY) + 64); if (pIpe) { pIpe->Data = szIPAddress; pIpe->DataSize = 64; dwStatus = pIcmpSendEcho( hIP, *dwIPAddr, szBuffer, 64, NULL, pIpe, sizeof(IP_ECHO_REPLY) + 64, PING_TOUT ); if(dwStatus) { bRet = TRUE; } LocalFree(pIpe); pIcmpCloseHandle(hIP); } return bRet; } BOOL CheckHostName(LPSTR szIISServer) { // WSAStartup() is already called if(!InitForTcp()) { return FALSE; // Tcp is not installed } struct hostent *phostent; if(!ResolveHostByThread(szIISServer)) { phostent = gphostent; }else { phostent= NULL; } if (phostent == NULL) return FALSE; else return TRUE; // WSACleanup() will be called later } // // Returns 1 if there is an Error // 0 if Successful DWORD GetHostThread(void *vp) { DWORD dwIsError=1; LPSTR szHost; szHost = (LPSTR) vp; int iError = 0; gphostent = gethostbyname(szHost); if( ! gphostent ){ iError = WSAGetLastError (); if(iError) { WSASetLastError (0); // Reset the error } } else { dwIsError =0; } ExitThread(dwIsError); return dwIsError; } // // This function returns Calls the gethostbyname and // returns 0 if Successful and 1 if failure // the return // // int ResolveHostByThread(LPSTR pHost) { int iRet=0; DWORD dwThreadExitCode; DWORD dwCreationFlags=0; // Start CREATE_SUSPENDED DWORD ThreadId; RW_DEBUG << "\nResolve " << pHost << flush; HANDLE hParent = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) GetHostThread, (void *) pHost, dwCreationFlags, &ThreadId ); DWORD dwRet = WaitForSingleObject(hParent,GET_HOST_TOUT); switch(dwRet) { case WAIT_ABANDONED : iRet = 1; // Error In Get Host Name break; case WAIT_OBJECT_0 : RW_DEBUG << "\n\tResolved ( 1 Error, 0 Ok) "; if( GetExitCodeThread(hParent,&dwThreadExitCode) ) { iRet = (int) dwThreadExitCode; } else { } RW_DEBUG << iRet; break; case WAIT_TIMEOUT : RW_DEBUG << "\n\t*** Error Resolving " << flush; iRet = 1; // Error In Get Host Name TerminateThread(hParent,0); break; default: break; } return iRet; } // // Returns 1 if there is an Error // 0 if Successful DWORD GetHostByAddrThread(void *vp) { DWORD dwIsError=1; LPSTR szAddr; int iError = 0; szAddr = (LPSTR) vp; gphostent = gethostbyaddr(szAddr, 4, PF_INET) ; if( ! gphostent ){ iError = WSAGetLastError (); if(iError) { WSASetLastError (0); // Reset the error } } else { dwIsError =0; } return dwIsError; } // // This function returns Calls the gethostbyaddr and // returns 0 if Successful and 1 if failure // the return // // int ResolveHostByAddrThread(LPSTR pHost) { int iRet=0; DWORD dwThreadExitCode; DWORD dwCreationFlags=0; // Start CREATE_SUSPENDED DWORD ThreadId; RW_DEBUG << "\nResolve " << pHost << " By Address " << flush; HANDLE hParent = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) GetHostByAddrThread, (void *) pHost, dwCreationFlags, &ThreadId ); DWORD dwRet = WaitForSingleObject(hParent,GET_HOST_TOUT); switch(dwRet) { case WAIT_ABANDONED : iRet = 1; // Error In Get Host Name break; case WAIT_OBJECT_0 : RW_DEBUG << "\n\tResolved ( 1 Error, 0 Ok) "; if( GetExitCodeThread(hParent,&dwThreadExitCode) ) { iRet = (int) dwThreadExitCode; } else { } RW_DEBUG << iRet << flush; break; case WAIT_TIMEOUT : RW_DEBUG << "\n\t*** Error Resolving " << flush; iRet = 1; // Error In Get Host Name TerminateThread(hParent,0); break; default: break; } return iRet; }