📄 pingthread.cpp
字号:
// 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 + -