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

📄 mysubnet.cpp

📁 动态的发现某个路由器的所有子网的拓扑结构
💻 CPP
字号:
// MySubNet.cpp: implementation of the CMySubNet class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MySnmp.h"
#include "MySubNet.h"
#include <winsock2.h> 
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#define NOT -1 //还没有搜索
#define DOING 0 //正在搜索活动主机
#define FINISH 1 //已经完成搜索活动主机
//////////////////////////////////////////////////////////////////////////
typedef struct 
{
	unsigned char Ttl; // Time To Live
	unsigned char Tos; // Type Of Service
	unsigned char Flags; // IP header flags
	unsigned char OptionsSize; // Size in bytes of options data
	unsigned char *OptionsData; // Pointer to options data
}IP_OPTION_INFORMATION, * PIP_OPTION_INFORMATION;
typedef struct 
{
	DWORD Address; // Replying address
	unsigned long Status; // Reply status
	unsigned long RoundTripTime; // RTT in milliseconds
	unsigned short DataSize; // Echo data size
	unsigned short Reserved; // Reserved for system use
	void *Data; // Pointer to the echo data
	IP_OPTION_INFORMATION Options; // Reply options
} IP_ECHO_REPLY, * PIP_ECHO_REPLY;
//////////////////////////////////////////////////////////////////////////

//全局函数,搜索该子网的活动主机
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
	CMySubNet* pSub=(CMySubNet*)lpParameter;
	pSub->m_nState=DOING;//表示正在搜索
	pSub->m_nActiveNumber; //该子网的活动主机数量
	while(pSub->m_nCurrentIndex<=pSub->m_nMaxNumber)
	{
		char IP[20];
		pSub->GetIpAddress(pSub->m_nCurrentIndex,IP);
		if(pSub->IsActive(IP))
		{
			TRACE("%s 是活动的. \n",IP);
			pSub->m_nActiveNumber++;
			//pSub->UpdateList();
			CString strActive(IP);
			pSub->AddActiveHost(strActive); //添加到活动主机数组中
		}
		else
		{
			TRACE("%s 不活动. \n",IP);
		}
		pSub->m_nCurrentIndex++;
	}
	//搜索完整个子网,将该子网的状态设为已经完成搜索
	pSub->m_nState=FINISH;
	pSub->UpdateList();
	return 1;
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMySubNet::CMySubNet()
{
	m_nState=NOT;
	m_nCurrentIndex=0;
	m_nActiveNumber=0;
	m_pList=NULL;
	m_pDlg=NULL;
	m_pActiveHostDlg=NULL;
}

CMySubNet::~CMySubNet()
{

}
//获取该子网的最大主机数
void CMySubNet::GetMaxNumber()
{
	int nFields[4];
	m_nMaxNumber=1;
	int nCount=0;
	ChangeIPToInts(m_Mask,nFields[0],nFields[1],nFields[2],nFields[3]);
	for(int i=0;i<=3;i++)
	{
		if(nFields[i]<255)
		{
			for(int j=0;j<=7;j++)
			{
				if(nFields[i]%2 ==0)
					nCount++;
				nFields[i]/=2;
			}
		}
	}
	for(i=0;i<nCount;i++)
		m_nMaxNumber*=2;
}
//从ip地址中提取四个整数
void CMySubNet::ChangeIPToInts(CString strIP, int &nField1, int &nField2, int &nField3, int &nField4)
{
	int nPos1,nPos2,nPos3;
	int i;
	char temp[5];
	nPos1=strIP.Find('.',0);
	for(i=0;i<nPos1;i++)
	{
		temp[i]=strIP[i];
	}
	temp[i]='\0';
	nField1=atoi(temp);
	
	nPos2=strIP.Find('.',nPos1+1);
	for(i=nPos1+1;i<nPos2;i++)
	{
		temp[i-nPos1-1]=strIP[i];
	}
	temp[i-nPos1-1]='\0';
	nField2=atoi(temp);
	
	nPos3=strIP.Find('.',nPos2+1);
	for(i=nPos2+1;i<nPos3;i++)
	{
		temp[i-nPos2-1]=strIP[i];
	}
	temp[i-nPos2-1]='\0';
	nField3=atoi(temp);
	
	for(i=nPos3+1;i<strIP.GetLength();i++)
	{
		temp[i-nPos3-1]=strIP[i];
	}
	temp[i-nPos3-1]='\0';
	nField4=atoi(temp);
}
//搜索该子网内的活动主机
void CMySubNet::SearchActiveHosts()
{
	m_nState=DOING;//正在搜索状态
	this->GetMaxNumber(); //获取该子网的可能最大主机数
	DWORD dID;
	m_hThread=NULL;
	m_hThread=CreateThread(NULL,0,ThreadProc,this,0,&dID);
	if(m_hThread==NULL)
	{
		AfxMessageBox("创建搜索线程错误!");
		return;
	}
}
//停止搜索活动主机
BOOL CMySubNet::StopSearing()
{
	if(m_hThread!=NULL)
	{
		if(!TerminateThread(m_hThread,-1))
			return FALSE;
	}
	return TRUE;
}

void CMySubNet::GetIpAddress(int i, char *IP)
{
	if(i<0)
		return;
	int n1,n2,n3,n4;
	ChangeIPToInts(m_Address,n1,n2,n3,n4);
	n4+=i;
	int nRet;
	if(n4>255)
	{
		nRet=n4/255;
		n4=n4%255;
		n3+=nRet;
	}
	if(n3>255)
	{
		nRet=n3/255;
		n3=n3%255;
		n2+=nRet;
	}
	if(n2>255)
	{
		nRet=n2/255;
		n2=n2%255;
		n1+=nRet;
	}
	if(n1>255)
	{
		return;
	}
	sprintf(IP,"%d.%d.%d.%d",n1,n2,n3,n4);
}
//开启定时器
BOOL CMySubNet::SetTimer()
{
	UINT m_ID=::SetTimer(NULL,411,1000,(TIMERPROC)TimerProc);
	if(m_ID==0)
	{
		TRACE("定时器设定失败!");
		return FALSE;
	}
	TRACE("定时器已经设定.\n");
	return TRUE;
}

CALLBACK CMySubNet::TimerProc(HWND hwnd,UINT uMsg,UINT_PTR idEvent,DWORD dwTime)
{
	MessageBeep(-1);
}

BOOL CMySubNet::IsActive(char *ip)
{
	WSAData wsaData;
	BOOL bRet;
	if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) 
	{
		return FALSE;
	}

	struct hostent* phe;
	phe=gethostbyname(ip);
	if(phe==NULL)
	{
		return FALSE;
	}
	HINSTANCE hIcmp=LoadLibrary("ICMP.dll");
	if(hIcmp==0)
	{
		return FALSE;
	}

	typedef HANDLE (WINAPI* pfnHV)(VOID);
	typedef BOOL (WINAPI* pfnBH)(HANDLE);
	typedef DWORD (WINAPI* pfnDHDPWPipPDD)(HANDLE, DWORD, LPVOID, WORD,PIP_OPTION_INFORMATION, LPVOID, DWORD, DWORD); 

	pfnHV pIcmpCreateFile;
	pfnBH pIcmpCloseHandle;
	pfnDHDPWPipPDD pIcmpSendEcho;

	pIcmpCreateFile = (pfnHV)GetProcAddress(hIcmp, "IcmpCreateFile");
	pIcmpCloseHandle = (pfnBH)GetProcAddress(hIcmp, "IcmpCloseHandle");
	pIcmpSendEcho = (pfnDHDPWPipPDD)GetProcAddress(hIcmp, "IcmpSendEcho");
	if(pIcmpCreateFile==NULL)
	{
		return FALSE;
	}
	if(pIcmpCloseHandle==NULL)
	{
		return FALSE;
	}
	if(pIcmpSendEcho==NULL)
	{
		return FALSE;
	}

	HANDLE hIP=pIcmpCreateFile();
	if(hIP==INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}

	char acPingBuffer[64];
	memset(acPingBuffer, '\xAA', sizeof(acPingBuffer));
	PIP_ECHO_REPLY pIpe = (PIP_ECHO_REPLY)GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT,
sizeof(IP_ECHO_REPLY) + sizeof(acPingBuffer)); 
	if(pIpe==0)
	{
		return FALSE;
	}
	pIpe->Data = acPingBuffer;
	pIpe->DataSize = sizeof(acPingBuffer);

	DWORD dwStatus = pIcmpSendEcho(hIP, *((DWORD*)phe->h_addr_list[0]), 
acPingBuffer, sizeof(acPingBuffer), NULL, pIpe, 
sizeof(IP_ECHO_REPLY) + sizeof(acPingBuffer), 1000);
	if(dwStatus!=0)
	{
		bRet=TRUE;
	}
	else
	{
		bRet=FALSE;
	}
	GlobalFree(pIpe);
	FreeLibrary(hIcmp);
	WSACleanup();
	return bRet;
}

void CMySubNet::AddActiveHost(CString strActive)
{
	if(strActive.IsEmpty())
		return;
	BOOL bAdd=TRUE;
	int nCount=m_ActiveHosts.GetSize();
	for(int i=0;i<nCount;i++)
	{
		CString strTemp=m_ActiveHosts.GetAt(i);
		if(strTemp==strActive)
		{
			bAdd=FALSE;
			break;
		}
	}
	if(bAdd)
		m_ActiveHosts.Add(strActive);
}

void CMySubNet::ShowSubNetInfo(CListCtrl *pList)
{
	m_pList=pList;
	m_nListItem=-1;
	if(m_pList!=NULL && m_pList->IsWindowVisible())
	{
		char buf[10];
		int count=m_pList->GetItemCount();
		sprintf(buf,"%d",count);
		int nItem=m_pList->InsertItem(count,buf);
		m_nListItem=nItem;

		m_pList->SetItemText(nItem,0,m_Address);
		m_pList->SetItemText(nItem,1,m_Mask);

		if(m_nState==0)
		{
			m_pList->SetItemText(nItem,2,"正在搜索活动主机......");
		}
		else if(m_nState==1)
		{
			m_pList->SetItemText(nItem,2,"活动主机搜索完毕!");
		}
		if(m_nState==0)
			return;
		//活动主机数量
		char chNumber[10];
		itoa(m_nActiveNumber,chNumber,10);
		m_pList->SetItemText(nItem,3,chNumber);
	}
}

void CMySubNet::UpdateList()
{
	if(m_pList!=NULL && m_pList->IsWindowVisible())
	{
		//////////////////////////////////////////////////////////////////////////
		for(int i=0;i<m_pList->GetItemCount();i++)
		{
			char IP[20];
			m_pList->GetItemText(i,0,IP,sizeof(IP));
			if(m_Address==IP)
				break;
		}
		m_nListItem=i;
		//////////////////////////////////////////////////////////////////////////
		
		if(m_nState==0)
		{
			m_pList->SetItemText(m_nListItem,2,"正在搜索活动主机......");
		}
		else if(m_nState==1)
		{
			m_pList->SetItemText(m_nListItem,2,"活动主机搜索完毕!");
		}
		if(m_nState==0)
			return;
		//活动主机数量
		char chNumber[10];
		itoa(m_nActiveNumber,chNumber,10);
		m_pList->SetItemText(m_nListItem,3,chNumber);
	}
}

⌨️ 快捷键说明

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