#include "StdAfx.h" #include ".\myping.h" CMyPing::CMyPing(void) { } CMyPing::~CMyPing(void) { } int CMyPing::SendEchoRequest(SOCKET s,LPSOCKADDR_IN lpstToAddr) { static ECHOREQUEST echoReq; static int nId = 1; static int nSeq = 1; int nRet; // Fill in echo request echoReq.icmpHdr.Type = ICMP_ECHOREQ; echoReq.icmpHdr.Code = 0; echoReq.icmpHdr.Checksum = 0; echoReq.icmpHdr.ID = nId++; echoReq.icmpHdr.Seq = nSeq++; // Fill in some data to send for (nRet = 0; nRet < REQ_DATASIZE; nRet++) echoReq.cData[nRet] = ' '+nRet; // Save tick count when sent echoReq.dwTime = GetTickCount(); // Put data in packet and compute checksum echoReq.icmpHdr.Checksum = in_cksum((u_short *)&echoReq, sizeof(ECHOREQUEST)); // Send the echo request nRet = sendto(s, /* socket */ (LPSTR)&echoReq, /* buffer */ sizeof(ECHOREQUEST), 0, /* flags */ (LPSOCKADDR)lpstToAddr, /* destination */ sizeof(SOCKADDR_IN)); /* address length */ if (nRet == SOCKET_ERROR) WSAError("sendto()"); return (nRet); } DWORD CMyPing::RecvEchoReply(SOCKET s, LPSOCKADDR_IN lpsaFrom, u_char *pTTL) { ECHOREPLY echoReply; int nRet; int nAddrLen = sizeof(struct sockaddr_in); // Receive the echo reply nRet = recvfrom(s, // socket (LPSTR)&echoReply, // buffer sizeof(ECHOREPLY), // size of buffer 0, // flags (LPSOCKADDR)lpsaFrom, // From address &nAddrLen); // pointer to address len // Check return value if (nRet == SOCKET_ERROR) WSAError("recvfrom()"); // return time sent and IP TTL *pTTL = echoReply.ipHdr.TTL; return(echoReply.echoRequest.dwTime); } int CMyPing::WaitForEchoReply(SOCKET s) { struct timeval Timeout; fd_set readfds; readfds.fd_count = 1; readfds.fd_array[0] = s; Timeout.tv_sec = 1; Timeout.tv_usec = 0; return(select(1, &readfds, NULL, NULL, &Timeout)); } void CMyPing::WSAError(LPCSTR lpMsg) { CString strMsg; strMsg.Format("%s - WSAError: %ld",lpMsg,WSAGetLastError()); MessageBox(NULL,strMsg,"ERROR",MB_OK); } u_short CMyPing::in_cksum(u_short *addr, int len) { register int nleft = len; register u_short *w = addr; register u_short answer; register int sum = 0; /* * Our algorithm is simple, using a 32 bit accumulator (sum), * we add sequential 16 bit words to it, and at the end, fold * back all the carry bits from the top 16 bits into the lower * 16 bits. */ while( nleft > 1 ) { sum += *w++; nleft -= 2; } /* mop up an odd byte, if necessary */ if( nleft == 1 ) { u_short u = 0; *(u_char *)(&u) = *(u_char *)w ; sum += u; } /* * add back carry outs from top 16 bits to low 16 bits */ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ sum += (sum >> 16); /* add carry */ answer = ~sum; /* truncate to 16 bits */ return (answer); } BOOL CMyPing::Ping(UINT nRetries,LPCSTR pstrHost) { SOCKET rawSocket; LPHOSTENT lpHost; // UINT nLoop; int nRet; struct sockaddr_in saDest; // struct sockaddr_in saSrc; // DWORD dwTimeSent; // DWORD dwElapsed; // u_char cTTL; // CString str; WSADATA wsa; if (WSAStartup(MAKEWORD(1, 1), &wsa) != 0) return FALSE; // Create a Raw socket rawSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (rawSocket == SOCKET_ERROR) { WSAError("socket()"); WSACleanup(); return FALSE; } // Lookup host lpHost = gethostbyname(pstrHost); if (lpHost == NULL) { // str.Format("Host not found: %s", pstrHost); WSACleanup(); return FALSE; } // Setup destination socket address saDest.sin_addr.s_addr = *((u_long FAR *) (lpHost->h_addr)); saDest.sin_family = AF_INET; saDest.sin_port = htons(80); if (connect(rawSocket, (SOCKADDR*)&saDest, sizeof(saDest)) == SOCKET_ERROR) { DWORD error = WSAGetLastError(); closesocket(rawSocket); WSACleanup(); return FALSE; } /* // Tell the user what we're doing str.Format("Pinging %s [%s] with %d bytes of data:", pstrHost, inet_ntoa(saDest.sin_addr), REQ_DATASIZE); // Ping multiple times for (nLoop = 0; nLoop < nRetries; nLoop++) { // Send ICMP echo request SendEchoRequest(rawSocket, &saDest); Sleep(1000); nRet = WaitForEchoReply(rawSocket); if (nRet == SOCKET_ERROR) { WSAError("select()"); break; } if (!nRet) { str.Format("Request Timed Out"); WSACleanup(); return FALSE; } else { // Receive reply dwTimeSent = RecvEchoReply(rawSocket, &saSrc, &cTTL); // Calculate elapsed time dwElapsed = GetTickCount() - dwTimeSent; str.Format("Reply[%d] from: %s: bytes=%d time=%ldms TTL=%d", nLoop+1, inet_ntoa(saSrc.sin_addr), REQ_DATASIZE, dwElapsed/100, cTTL); WSACleanup(); return TRUE; } } */ nRet = closesocket(rawSocket); if (nRet == SOCKET_ERROR) WSAError("closesocket()"); WSACleanup(); return TRUE; } unsigned long conv_addr(const char *name) { struct hostent *he; int max; unsigned long retval; if ((retval = inet_addr(name)) != INADDR_NONE) return retval; he = gethostbyname(name); if (he == NULL) return INADDR_NONE; for (max = 0; he->h_addr_list[max]; max++) ; if (max == 1) return *((unsigned long *)(he->h_addr_list[0])); else return *((unsigned long *)(he->h_addr_list[rand() % max])); } BOOL CMyPing::Ping2(UINT nRetries,LPCSTR pstrHost) { return TRUE; LPHOSTENT lpHost; SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == INVALID_SOCKET) { return FALSE; } bool bRet = false; DWORD dwWritten; char s[1024]; lpHost = gethostbyname(pstrHost); sockaddr_in sa; sa.sin_family = AF_INET; sa.sin_addr.s_addr = *((u_long FAR *) (lpHost->h_addr)); sa.sin_port = htons(80); int nNonBlocking = 1; ioctlsocket(sock, FIONBIO, (u_long FAR*)&nNonBlocking); if (connect(sock, (SOCKADDR*)&sa, sizeof(sa)) ) { return TRUE; } else { return FALSE; } if (sock != INVALID_SOCKET) closesocket(sock); }