⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ping.cpp

📁 一个非常漂亮的802.1x客户端源代码
💻 CPP
字号:
// Ping.cpp: implementation of the CPing class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Mento Supplicant.h"
#include "Ping.h"
#include <winsock.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#define PING_TIMES	2

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CPing::CPing()
{
	m_iError = 0;
	m_sError = "没有错误发生";
	m_sHost = "localhost";
	m_iInterval = 2;
}

CPing::~CPing()
{

}

// Ping()
// Calls SendEchoRequest() and
// RecvEchoReply() and prints results
int CPing::DoPing(LPCSTR pstrHost)
{
	SOCKET	  rawSocket;
	LPHOSTENT lpHost;
	struct    sockaddr_in saDest;
	struct    sockaddr_in saSrc;
	DWORD	  dwTimeSent;
	DWORD	  dwElapsed;
	u_char    cTTL;
	int       nRet;

    WSADATA wsaData;
    WORD wVersionRequested = MAKEWORD(1,1);

	// Init WinSock
    nRet = WSAStartup(wVersionRequested, &wsaData);
    if (nRet)
    {
		ReportError(PING_INIT_ERROR," ** 初始化WinSock出错!!");
		return PING_INIT_ERROR;
    }

	// Check version
	if (wsaData.wVersion != wVersionRequested)
	{
		ReportError(VERSION_NOT_SUPPORT," ** 该WinSock版本不支持!!");
		return VERSION_NOT_SUPPORT;
	}

	// Create a Raw socket
	rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
	if (rawSocket == SOCKET_ERROR) 
	{
		ReportError( PING_SOCKET_ERROR, " ** 打开ping连接错误!" );
		return PING_SOCKET_ERROR;
	}

	// Lookup host
	lpHost = gethostbyname(pstrHost);

/*	if (lpHost == NULL)
	{
		ReportError(PING_HOST_NOTFOUND, " ** Host %s NOT found!!", m_sHost);
		return PING_HOST_NOTFOUND;
	}
//*/
	// Setup destination socket address
	saDest.sin_addr.s_addr = *((u_long FAR *) (lpHost->h_addr));
	saDest.sin_family = AF_INET;
	saDest.sin_port = 0;

	// Tell the user what we're doing
	ReportError(PING_WORKING, "正在用 %d 字节的数据ping %s [%s].",
				REQ_DATASIZE,
				pstrHost,
				inet_ntoa(saDest.sin_addr));

	// Ping multiple times
	// Send ICMP echo request
	SendEchoRequest(rawSocket, &saDest);

	// Use select() to wait for data to be received
	nRet = WaitForEchoReply(rawSocket);
	if (nRet == SOCKET_ERROR)
	{
		ReportError( PING_SOCKET_ERROR, " ** Ping时发生Socket错误!!" );
		return PING_SOCKET_ERROR;
	}
	if (!nRet)
	{
		ReportError( PING_TIMEOUT_ERROR, " ** 超时错误!!" );
		return PING_TIMEOUT_ERROR;
	}

	// Receive reply
	dwTimeSent = RecvEchoReply(rawSocket, &saSrc, &cTTL);

	// Calculate elapsed time
	dwElapsed = GetTickCount() - dwTimeSent;
/*		sMsg.Format("\nReply from: %s: bytes=%d time=%ldms TTL=%d", 
               inet_ntoa(saSrc.sin_addr), 
			   REQ_DATASIZE,
               dwElapsed,
               cTTL);
		AfxMessageBox(sMsg);*/
	
	nRet = closesocket(rawSocket);
	if (nRet == SOCKET_ERROR)
	{
		ReportError( PING_SOCKET_ERROR, " ** Socket关闭错误!!" );
		return PING_SOCKET_ERROR;
	}

	// Free WinSock
    WSACleanup();

	ReportError(PING_SUCCESS, " !! 成功 !!");
	return PING_SUCCESS;
}


// SendEchoRequest()
// Fill in echo request header
// and send to destination
int CPing::SendEchoRequest(SOCKET s,LPSOCKADDR_IN lpstToAddr) 
{
	static ECHOREQUEST echoReq;
	static nId = 1;
	static 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) 
		ReportError(PING_CONNECTION_ERROR, " ** 发送ping包出错!!");
	return (nRet);
}


// RecvEchoReply()
// Receive incoming data
// and parse out fields
DWORD CPing::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) 
		ReportError(PING_CONNECTION_ERROR," ** 接收ping包响应出错!!");

	// return time sent and IP TTL
	*pTTL = echoReply.ipHdr.TTL;
	return(echoReply.echoRequest.dwTime);
}
/*
int ErrLog(int iErrLevel , char* sFormat , ... )
{
	va_list vlInputVar;
	char sOutput[80];

	va_start( vlInputVar , sFormat );
	vsprintf( sOutput , sFormat , vlInputVar );
	if(iErrLevel>=1000)
		puts( sOutput );
	else
		puts("The error level is too small!\n");

	return 0;
}
*/
// What happened?
void CPing::ReportError(int iErrorNo, char *sFormat, ... )
{
	va_list arg_ptr;
	CString format;

	m_iError = iErrorNo;
	va_start(arg_ptr, format);
	sMsg.FormatV( sFormat, arg_ptr );
}


// WaitForEchoReply()
// Use select() to determine when
// data is waiting to be read
int CPing::WaitForEchoReply(SOCKET s)
{
	struct timeval Timeout;
	fd_set readfds;

	readfds.fd_count = 1;
	readfds.fd_array[0] = s;
	Timeout.tv_sec = m_iInterval;
    Timeout.tv_usec = 0;

	return(select(1, &readfds, NULL, NULL, &Timeout));
}


//
// Mike Muuss' in_cksum() function
// and his comments from the original
// ping program
//
// * Author -
// *	Mike Muuss
// *	U. S. Army Ballistic Research Laboratory
// *	December, 1983

/*
 *			I N _ C K S U M
 *
 * Checksum routine for Internet Protocol family headers (C Version)
 *
 */
u_short CPing::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);
}

void CPing::SetInterval(int IInterval)
{
	m_iInterval = IInterval;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -