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

📄 pingthread.cpp

📁 你想看自己的 IP及其内容吗? 现在有一个能查看IP网络状态(连接
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// PingThread.cpp : implementation file
//

#include "stdafx.h"
#include "nettools.h"
#include "PingParmList.h"
#include "winsock.h"
#include "ipexport.h"
#include "PingThread.h"






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

struct IPErrors
{
	CHAR   msg[30];
};
                  

struct IPErrors ErrorCodes[23] =
{
	{"OK"},
	{"Buffer too small"},            
    {"Dest Net Unreachable"},
	{"Dest Host Unreachable"},
    {"Dest Prot Unreachable"},
    {"Dest Port Unreachable"},
    {"No Resources"},
	{"Bad IP Option"},
	{"Hardware Error"},
	{"Packet Too Big"},
	{"Request Timed Out"},
	{"Bad Request"},
	{"Bad Route"},
	{"TTL Expired Transit"},
	{"TTL Expired Re-Assembly"},
	{"Parameter Problem"},
	{"Source Quench"},
	{"Option Too Large"},
	{"Bad Destination"},
	{"Address Deleted"},
	{"Spec MTU Change"},
	{"MTU Change"},
	{"Unload"}
};
    

//
//  The Main Thread Procedure
//
UINT CPingThreadProc(LPVOID lparam)
{
	BOOL bPingThreadComplete;
	CPingThreadParmList *lpPingParms;
	CPingThread *mythread;

	lpPingParms = (CPingThreadParmList*)lparam;
	mythread = (CPingThread*)lpPingParms->m_mythread;
	
	while (TRUE)
	{

	
		bPingThreadComplete = FALSE;

		// Wait until the main application thread asks this thread to do
		// something.

		if (WaitForSingleObject(lpPingParms->m_hEventStartPing,
								INFINITE) != WAIT_OBJECT_0)
			break;

		// Exit the thread if the main application sets the "kill"
		// event. The main application will set the "start event
		// before setting the "kill" event.

		if (WaitForSingleObject(lpPingParms->m_hEventKillPing, 0)
			== WAIT_OBJECT_0)
			break; // Terminate this thread by existing the proc.

		// Reset event to indicate "not done", that is, in progress.
		//ResetEvent(lpPingParms->m_hEventPingDone);

		// Run PING!!
		if (lpPingParms->opt_tracert)
			bPingThreadComplete = 
			    mythread->RunTracert(lpPingParms);
		else
			bPingThreadComplete = 
			    mythread->RunPing(lpPingParms);
			

		// Set event to indicate that we're done (i.e., no longer in progres),
		// even if perhaps interrupted by "kill" event.
		SetEvent(lpPingParms->m_hEventPingDone);
		
		// tell main app we're done this request
		::PostMessage(lpPingParms->m_hwndNotifyPingDone,
			WM_USER_PING_DONE, 0, (LONG)lpPingParms);
	}

	// tell main app this thread has terminated.
	SetEvent(lpPingParms->m_hEventPingDead);

	return 0;

		
	

	
	
}

/////////////////////////////////////////////////////////////////////////////
// CPingThread

IMPLEMENT_DYNCREATE(CPingThread, CWinThread)

CPingThread::CPingThread()
{
}

CPingThread::~CPingThread()
{
}

BOOL CPingThread::InitInstance()
{
	
	// start winsock
	WSADATA wsaData;
	WORD version;
	version = MAKEWORD(2,1);
	if (WSAStartup(version,&wsaData))
		return FALSE;
	//
	// load icmp dll
	//
	Icmpdll = LoadLibrary("ICMP.DLL");
	if (Icmpdll == NULL)
		return FALSE;

	IcmpCreateFile = 
	(ICMPCREATEFILE) GetProcAddress(Icmpdll,"IcmpCreateFile");

	IcmpCloseHandle =
	(ICMPCLOSEHANDLE) GetProcAddress(Icmpdll,"IcmpCloseHandle");

	IcmpSendEcho = 
		(ICMPSENDECHO) GetProcAddress(Icmpdll,"IcmpSendEcho");



	
	return TRUE;
}


BEGIN_MESSAGE_MAP(CPingThread, CWinThread)
	//{{AFX_MSG_MAP(CPingThread)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPingThread message handlers



void CPingThread::Kill()
{
	bKill = TRUE;
	
}


BOOL CPingThread::Start()
{
	BOOL rc = TRUE;
	bKill = FALSE;
	rc = CreateThread();
	if (!rc)
		return rc;

	rc = InitInstance();
	if (!rc)
		return rc;

	return rc;


}

BOOL CPingThread::Running()
{
	DWORD Status;
	::GetExitCodeThread(m_hThread,&Status);
	if (Status == STILL_ACTIVE)
		return TRUE;
	else
		return FALSE;


}

HANDLE CPingThread::Icmp_Open()
{
	HANDLE File;
	File = (*IcmpCreateFile)();
	if (File != INVALID_HANDLE_VALUE)
		return File;
	else
	{
		File = 0;
		return File;
	}

}

BOOL CPingThread::Icmp_Close(HANDLE h)
{
	BOOL rc;
	rc = (*IcmpCloseHandle)(h);
	return rc;

}

BOOL CPingThread::Icmp_Sendto(CPingThreadParmList *lppingvars,
							  CHAR *OUTBuf,
							  CHAR *INBuf,
							  struct ipopt_info *lpIpopt,
							  ULONG sendaddr,
							  INT maxoutbuffsize,
							  INT maxinbuffsize)
{
	u_short i;
	char c;

	
	//DWORD NumberOfEchoReplies;
   	memset(OUTBuf,0,maxoutbuffsize);
	c=' ';   /* first char: space */
	for (i=0;
		   ((i < (lppingvars->opt_packetlen_val)) && (i < maxoutbuffsize)); 
		i++) 
	{
		OUTBuf[i] = c;
		c++;
		if (c > '~')	/* go up to ASCII 126, then back to 32 */
			c= ' ';
	}

	
    
	

	memset(INBuf,0,maxinbuffsize);
	NumberOfEchoReplies = (*IcmpSendEcho)
						(PingSocket,sendaddr,OUTBuf,
						 lppingvars->opt_packetlen_val,
						 lpIpopt,
						 INBuf,
						 maxinbuffsize,
						 lppingvars->opt_timeout_val);

	
	
	
	return TRUE;
	

}

BOOL CPingThread::Icmp_SetOpts(CPingThreadParmList *lppingvars,
							   struct ipopt_info *lpIpopt,
							   UCHAR *optdata,
							   INT optsize)
{
	BOOL HaveOpts = FALSE;
	int numrrdata;
	
	memset(lpIpopt,0,IPOPT_INFO_LEN);
	
	struct in_addr rr_inaddr;
	UCHAR *routes;

	


	if (lppingvars->opt_timeout_val == 0)  // Timeout value specified?
	{
		//set default timeout
		lppingvars->opt_timeout_val = 5000;
				
	}
	
	//
	// the remaining options if set require us to set  
	// a pointer to the options for the sendecho else
	// the pointer should be set to null
	//

	if (lppingvars->opt_ttl_val != 0)  // TTL value specified?
	{
		//set TTL if specified
		lpIpopt->Ttl = lppingvars->opt_ttl_val;
		HaveOpts = TRUE;
		
		
	}
	
	
	if (lppingvars->opt_tos_val != 0) // TOS value specified?
	{
		//set TOS if specified
		lpIpopt->Tos = lppingvars->opt_tos_val;
		if (lpIpopt->Ttl == 0)
			lpIpopt->Ttl = 255;
		HaveOpts = TRUE;
		
		
	}

	if (lppingvars->opt_dontfragment) // dont Frag?
	{
		//set dont frag 
		lpIpopt->Flags |= IP_FLAG_DF;
		HaveOpts = TRUE;
		
		
	}


	if (lppingvars->opt_rroute_val != 0) // Record Route?
	{
		memset(optdata,0xff,optsize);		
		memset(optdata,0,3+(4*lppingvars->opt_rroute_val));
		optdata[IPOPT_OPTVAL] = IP_OPT_RR;
		optdata[IPOPT_OLEN] = 3+(4*lppingvars->opt_rroute_val);
		optdata[IPOPT_OFFSET] = IPOPT_MINOFF;
		lpIpopt->OptionsData = optdata;
		lpIpopt->OptionsSize = optdata[IPOPT_OLEN];
		if (lpIpopt->Ttl == 0)
			lpIpopt->Ttl = lppingvars->opt_rroute_val;
		HaveOpts = TRUE;
	}

	if (lppingvars->opt_timestamp_val != 0) // ts?
	{
		memset(optdata,0xff,optsize);		
		memset(optdata,0,
			   4+(8*lppingvars->opt_timestamp_val));
		optdata[IPOPT_OPTVAL] = IP_OPT_TS;
		optdata[IPOPT_OLEN] = 4+(8*lppingvars->opt_timestamp_val);
		optdata[IPOPT_OFFSET] = (IPOPT_MINOFF + 1);
		optdata[IPOPT_TSFLAGS] = IP_OPT_TS_REGADDR;
		lpIpopt->OptionsData = optdata;
		lpIpopt->OptionsSize = optdata[IPOPT_OLEN];
		if (lpIpopt->Ttl == 0)
			lpIpopt->Ttl = 255;
		HaveOpts = TRUE;


	}
	

	if (lppingvars->opt_rrloose || lppingvars->opt_rrstrict)
	{
		numrrdata = lppingvars->opt_rrdata.GetSize();
		memset(optdata,0xff,optsize);		
		memset(optdata,0,3+(4*numrrdata));
		optdata[IPOPT_OLEN] = 3+(4*numrrdata);
		optdata[IPOPT_OFFSET] = IPOPT_MINOFF;
		routes =  optdata+3; 
		for (int x = 0;x<numrrdata;x++)
		{
			GetAddr(lppingvars->opt_rrdata[x],&rr_inaddr);
			*routes = rr_inaddr.s_net;
			*(routes+1) = rr_inaddr.s_host;
			*(routes+2) = rr_inaddr.s_lh;
			*(routes+3) = rr_inaddr.s_impno;
			routes += 4; 

		}
		if (lppingvars->opt_rrloose)
			optdata[IPOPT_OPTVAL] = IP_OPT_LSRR;
		else
			optdata[IPOPT_OPTVAL] = IP_OPT_SSRR;

		lpIpopt->Ttl = numrrdata;

		
	}




	if (!HaveOpts)
		return FALSE;
		
		
	return TRUE;

}

ULONG CPingThread::GetAddr(LPCTSTR szHost,struct in_addr *inaddr)
{
	LPHOSTENT lpstHost = NULL;
	struct in_addr stinaddr;
	u_long lAddr = INADDR_ANY;

	if (*szHost)
	{
		//lAddr = inet_addr(szHost);
		stinaddr.s_addr = inet_addr(szHost);
		if ((stinaddr.s_addr == INADDR_NONE) &&
			(strcmp(szHost,"255.255.255.255")))
		{
			lpstHost = gethostbyname(szHost);
			if (lpstHost)
			{
				lAddr = *((u_long *) (lpstHost->h_addr));
				if (inaddr)
					inaddr->s_addr = *((u_long *) (lpstHost->h_addr));
			}
			else
			{
				lAddr = INADDR_ANY;
				if (inaddr)
					inaddr->s_addr = INADDR_ANY;

			}
		}
		else
		{
			lAddr = stinaddr.s_addr;
			if (inaddr)
				inaddr->s_addr = stinaddr.s_addr;

		}
			
	}
	
	return (lAddr);

}

BOOL CPingThread::RunPing(CPingThreadParmList *lppingvars)
{
	
	BOOL Sendok;
	struct ipopt_info IpoptInfo;
	struct ipopt_info *lpIpoptInfo;
	struct icmp_reply *EchoReply;
	INT RRsize = 3+4*PING_NROUTES+1;
	UCHAR RRSpace[3+4*PING_NROUTES+1];
	
	IPAddr SendToAddr;
	CHAR achINBuf[PNGINBUFSIZE];
	CHAR achOUTBuf[PNGOUTBUFSIZE];
	
	PingSocket = Icmp_Open();
	if (PingSocket == 0)
	{
		PrintLine("Ping: Error - ICMP Open Failed",lppingvars);
		return FALSE;
	}

	SendToAddr = GetAddr(lppingvars->hostname);
	EchoReply = (struct icmp_reply *)achINBuf;
	EchoReply->RoundTripTime = 0xffffffff;

	lpIpoptInfo = &IpoptInfo; // point to ip options

	if (!Icmp_SetOpts(lppingvars,lpIpoptInfo,RRSpace,RRsize))
		lpIpoptInfo = NULL;
	
	bKill = FALSE;
	int numpacks;
	numpacks = lppingvars->opt_numpackets_val;
	
	if (lppingvars->opt_interrupt)  // allow 100 pings no options
	{
		numpacks = 100;
		lpIpoptInfo = NULL;
	}

	for (int x = 0;x <= numpacks;x++)
	{
		if (bKill)
		{
			PrintLine("Ping Interrupted!",lppingvars);
			return FALSE;
		}
		Sendok = Icmp_Sendto(lppingvars,achOUTBuf,achINBuf,
							lpIpoptInfo,SendToAddr,
							PNGOUTBUFSIZE,
							PNGINBUFSIZE);
		
		if (!ProcessReply(lppingvars,(struct icmp_reply *)achINBuf))
		{
	
			Icmp_Close(PingSocket);
			return FALSE;
		}
		
	

⌨️ 快捷键说明

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