?? ping.cpp
字號(hào):
// 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éi)有錯(cuò)誤發(fā)生";
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出錯(cuò)!!");
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, " ** 打開(kāi)ping連接錯(cuò)誤!" );
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 字節(jié)的數(shù)據(jù)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時(shí)發(fā)生Socket錯(cuò)誤!!" );
return PING_SOCKET_ERROR;
}
if (!nRet)
{
ReportError( PING_TIMEOUT_ERROR, " ** 超時(shí)錯(cuò)誤!!" );
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關(guān)閉錯(cuò)誤!!" );
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, " ** 發(fā)送ping包出錯(cuò)!!");
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包響應(yīng)出錯(cuò)!!");
// 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;
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -