289 lines
6.1 KiB
Plaintext
289 lines
6.1 KiB
Plaintext
#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);
|
|
|
|
}
|
|
|