mysimpsnifferdlg.cpp

来自「一个关于局域网简单抓包工具」· C++ 代码 · 共 1,943 行 · 第 1/5 页

CPP
1,943
字号
		//设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包
		dwValue = 1; 
		if( ioctlsocket(SockRaw, SIO_RCVALL, &dwValue) != 0 ) 
		{
			closesocket( SockRaw ) ;
			AfxMessageBox( "Start! ioctlsocket SIO_RCVALL error!" ) ;
			exit(1);
		} 

		//GetParamSet();
		//需要监测的源/目的IP地址 变量赋值
		char *pSrcIP = NULL;		// 源地址过滤
		char *pDstIP = NULL;		// 目的地址过滤
		int  iSrcp = 0, iDstp = 0;	// 检测的源目的端口号
		CString szStr;
		if(((CButton*)GetDlgItem(IDC_CHK_SrcIP))->GetCheck())
		{
			((CEdit*)GetDlgItem(IDC_IPAddr_Src))->GetWindowText(szStr);
			pSrcIP = szStr.GetBuffer(szStr.GetLength());
		}else
			pSrcIP = NULL;
		if(((CButton*)GetDlgItem(IDC_CHK_DstIP))->GetCheck())
		{
			((CEdit*)GetDlgItem(IDC_IPAddr_Dst))->GetWindowText(szStr);
			pDstIP = szStr.GetBuffer(szStr.GetLength());
		}else
			pDstIP = NULL; 

		if(((CButton*)GetDlgItem(IDC_CHK_PORT))->GetCheck())
		{
			((CEdit*)GetDlgItem(IDC_EDIT_PORT))->GetWindowText(szStr);
			iSrcp = atol(szStr);
			if((iSrcp<1) || (iSrcp>65535)) 
			{
				AfxMessageBox("端口号应该在1--65535之间!");
				//((CEdit*)GetDlgItem(IDC_EDIT_PORT))->SetFocus();
				return;
			}
		}

		//GETSETPARAM *pGetParam = (GETSETPARAM *) malloc(sizeof(GETSETPARAM));
		GETSETPARAM *pGetParam = new GETSETPARAM;   
		pGetParam->pDialog  = this;
		pGetParam->iSrcPort = iSrcp;
		pGetParam->iDstPort = iSrcp;	//iDstp; 监测目的端口暂时未设计
		if(pSrcIP!=NULL) 
			strcpy(pGetParam->SrcIP,pSrcIP);
		else
			strcpy(pGetParam->SrcIP,"0.0.0.0");
		if(pDstIP!=NULL) 
			strcpy(pGetParam->DstIP,pDstIP);
		else
			strcpy(pGetParam->DstIP,"0.0.0.0");

		CButton* pPflag = (CButton*)GetDlgItem(IDC_ProtoTCP);
		if(pPflag->GetCheck()) 
			pGetParam->bTCP = true;
		else
			pGetParam->bTCP = false;
		pPflag = (CButton*)GetDlgItem(IDC_ProtoUDP);
		if(pPflag->GetCheck()) 
			pGetParam->bUDP = true;
		else
			pGetParam->bUDP = false;
		pPflag = (CButton*)GetDlgItem(IDC_ProtoICMP);
		if(pPflag->GetCheck()) 
			pGetParam->bICMP = true;
		else
			pGetParam->bICMP = false;

		bStop = false; 
		m_start.SetWindowText("结束(&T)");

		// 开启线程接收数据并处理
		AfxBeginThread(threadFunc_Catch,(LPVOID)pGetParam);//,0,0,0,NULL);
		//AfxBeginThread(threadFunc,(LPVOID)this);
	}else{
		m_start.SetWindowText("开始(&S)");
	    bStop = true; 
		
		//设置SOCK_RAW为SIO_RCVALL,停止接收 
		dwValue = 0; 
		if( ioctlsocket(SockRaw, SIO_RCVALL, &dwValue) != 0 ) 
		{
			closesocket( SockRaw ) ;
			AfxMessageBox( "Stop! ioctlsocket SIO_RCVALL error!" ) ;
			exit(1);
		} 
	} 
}

void CMySimpSnifferDlg::ReceiveData()
{
	int iErrorCode;

//	GetParamSet();		// 获得参数设置 -- 控制操作

	if(!bStop) 
	{
		memset(RecvBuf, 0, sizeof(RecvBuf));
		iErrorCode = recv(SockRaw, RecvBuf, sizeof(RecvBuf), 0);
		if( iErrorCode == SOCKET_ERROR ) 
		{
			closesocket(SockRaw);
			exit(1);
		}
		if( *RecvBuf ) 
			iErrorCode = DecodeIPPack(RecvBuf, iErrorCode);
	}
}

UINT threadFunc( LPVOID p )
{
 	CMySimpSnifferDlg *pDlg = static_cast<CMySimpSnifferDlg *>(p) ;
	MSG   msg ;
	int iErrorCode;
	char  Buf[MAX_PACK_LEN];

    PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); // Force to make the queue
 	pDlg->m_threadID = GetCurrentThreadId();

	//pDlg->GetParamSet();		// 获得参数设置 -- 控制操作

	while( !pDlg->bStop )
	{
		if( PeekMessage( &msg , 0 , WM_CLOSE,WM_CLOSE,PM_NOREMOVE ) )
		{
			closesocket( pDlg->SockRaw );
			pDlg->m_threadID = 0 ;
			// Only after you see Next message you can press on Start button 
			pDlg->m_start.EnableWindow(TRUE); 
			break;
		}
		//pDlg->ReceiveData();	//用以下代码代替

		memset(Buf, 0, sizeof(Buf));
		iErrorCode = recv(pDlg->SockRaw, Buf, sizeof(Buf), 0);
		if( iErrorCode == SOCKET_ERROR ) continue;

		if( *Buf )	//if( iErrorCode > 0 ) 
		{
			iErrorCode = pDlg->DecodeIPPack(Buf, iErrorCode);
 		}else{
			AfxMessageBox( "No data on network" ) ;
			continue ;
		}

		/*
		memset(pDlg->RecvBuf, 0, sizeof(pDlg->RecvBuf));
		iErrorCode = recv(pDlg->SockRaw, pDlg->RecvBuf, sizeof(pDlg->RecvBuf), 0);
		if( iErrorCode == SOCKET_ERROR ) continue;

		if( *pDlg->RecvBuf )	//if( iErrorCode > 0 ) 
		{
			iErrorCode = pDlg->DecodeIPPack(pDlg->RecvBuf, iErrorCode);
 		}else{
			AfxMessageBox( "No data on network" ) ;
			continue ;
		}
		free(pDlg->RecvBuf); */
		Sleep( 100 ) ; //  Polling each 100 millisecond 
	}
	return TRUE ;
}

UINT threadFunc_Catch( LPVOID pthreadArg )
{
	GETSETPARAM *pParam = (GETSETPARAM *)pthreadArg;
	CMySimpSnifferDlg *pDlg = (CMySimpSnifferDlg *)(pParam->pDialog);

	MSG   msg ;

	IP_HEADER		*pIpHead;		// IP头结构指针
	TCP_HEADER		*pTCPHead;
	UDP_HEADER		*pUDPHead;
//	ICMP_HEADER		*pICMPHead;
//	IGMP_HEADER		*pIGMPHead;

	char  buf[MAX_PACK_LEN] ;//, *bufwork;
	int   iRet;

	in_addr inSrc,inDst;	// 在winsock2.h文件中定义的结构体
							// 也可以用SOCKADDR_IN定义: SOCKADDR_IN saSource, saDest;

	char  *pSrcIP, *pDstIP;		//源、目的IP地址指针
	char  szSrcIP[MAX_ADDR_LEN], szDstIP[MAX_ADDR_LEN];	//szSrcIP[16], szDstIP[16];
	char  *pSrcIpFilter=NULL, *pDstIpFilter=NULL;	//监测的源、目的IP地址指针

	int	  iIphLen, iData_len;	//IP头长度,数据长度

	int   SrcPort, DstPort;				//源、目的端口号
	int   iSrcPFilter=0, iDstPFilter=0;	//监测的源、目的端口号
	BYTE  *pdata = NULL;

	bool  bUDP;		// 是否关注UDP报文
	bool  bTCP;		// 是否关注TCPP报文
	bool  bICMP;	// 是否关注ICMP报文

	pSrcIpFilter = pParam->SrcIP;
	pDstIpFilter = pParam->DstIP;
	iSrcPFilter = pParam->iSrcPort;
	iDstPFilter = pParam->iDstPort;
	bTCP  = pParam->bTCP;
	bUDP  = pParam->bUDP;
	bICMP = pParam->bICMP;

	PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE)	; // Force to make the queue
	pDlg->m_threadID = GetCurrentThreadId();

	while( !pDlg->bStop )
	{
		if( PeekMessage( &msg , 0 , WM_CLOSE,WM_CLOSE,PM_NOREMOVE ) )
		{
			closesocket( pDlg->SockRaw ) ;
			pDlg->m_threadID = 0 ;
			// Only after you see Next message you can press on Start button 
			pDlg->m_start.EnableWindow(TRUE) ; 
			break ;
		} 
		//接收数据
		ZeroMemory(buf,sizeof(buf));
		memset( buf , 0 , sizeof(buf) ) ;
		iRet = 	recv( pDlg->SockRaw , buf , sizeof(buf) , 0 );	//iRet为接收的数据包的长度(一定小于MAX_PACK_LEN即65535)
		if( iRet == SOCKET_ERROR )	//出错等待而不是退出
			continue ;
		else{
			if( *buf )	//如果buf中有数据
			{	//Check IP here
				//bufwork = buf ;
				pIpHead = (IP_HEADER *)buf;//work;
				WORD iLen = ntohs(pIpHead->ip_len) ;

				int  iSrcFilter = 0, iDstFilter = 0;
				if((strcmp(pSrcIpFilter,"0.0.0.0")!=0) && (strcmp(pDstIpFilter,"0.0.0.0")!=0)) //源、目的都给定IP
				{
					inSrc.S_un.S_addr = pIpHead->ip_srcIP;
					pSrcIP = inet_ntoa( inSrc );
					strcpy( szSrcIP , pSrcIP );		//源IP地址
					inDst.S_un.S_addr = pIpHead->ip_dstIP;
					pDstIP = inet_ntoa( inDst );
					strcpy( szDstIP , pDstIP );		//目的IP地址  
					if(strcmp(pSrcIpFilter,pSrcIP)!=0) //否
						iSrcFilter = 1;
					else
						iSrcFilter = 0;
					if(strcmp(pDstIpFilter,pDstIP)!=0) //否
						iDstFilter = 1;
					else
						iDstFilter = 0;
					if(iSrcFilter + iDstFilter == 2) continue;	//点到点if(iSrcFilter + iDstFilter != 0) continue;
				}else if((strcmp(pSrcIpFilter,"0.0.0.0")!=0) && (strcmp(pDstIpFilter,"0.0.0.0")==0)) 
				{ //源给定、目的不定
					inDst.S_un.S_addr = pIpHead->ip_dstIP;
					pDstIP = inet_ntoa( inDst );
					strcpy( szDstIP , pDstIP );		//目的IP地址  
					inSrc.S_un.S_addr = pIpHead->ip_srcIP;
					pSrcIP = inet_ntoa( inSrc );
					strcpy( szSrcIP , pSrcIP );		//源IP地址
					if(strcmp(pSrcIpFilter,pSrcIP)!=0) continue;
				}else if((strcmp(pSrcIpFilter,"0.0.0.0")==0) && (strcmp(pDstIpFilter,"0.0.0.0")!=0)) 
				{ //源不定、目的给定
					inSrc.S_un.S_addr = pIpHead->ip_srcIP;
					pSrcIP = inet_ntoa( inSrc );
					strcpy( szSrcIP , pSrcIP );		//源IP地址

					inDst.S_un.S_addr = pIpHead->ip_dstIP;
					pDstIP = inet_ntoa( inDst );
					strcpy( szDstIP , pDstIP );		//目的IP地址  
					if(strcmp(pDstIpFilter,pDstIP)!=0) continue;
				}else{
					inSrc.S_un.S_addr = pIpHead->ip_srcIP;
					pSrcIP = inet_ntoa( inSrc );
					strcpy( szSrcIP , pSrcIP );		//源IP地址
					inDst.S_un.S_addr = pIpHead->ip_dstIP;
					pDstIP = inet_ntoa( inDst );
					strcpy( szDstIP , pDstIP );		//目的IP地址  
				}

				CString str, strProto, strSourPort, strDestPort, strData, strSize;

				strProto = pDlg->CheckProtocol( pIpHead->ip_proto );
				iIphLen = pIpHead->ip_verlen & 0xf;
				iIphLen *= 4;							//计算IP头长度	iIphLen = IP_HLEN(pIpHead);
				iData_len  = ntohs(pIpHead->ip_len);	//总长
				iData_len -= iIphLen;					//用户数据长度(仅去掉了IP头)
				switch(pIpHead->ip_proto)
				{
				case IPPROTO_TCP:
					{
						if(!bTCP) continue;
						pTCPHead=(TCP_HEADER *)(buf+iIphLen);
						SrcPort = ntohs(pTCPHead->tcp_SrcPort);
						DstPort = ntohs(pTCPHead->tcp_DstPort);
						if( ((iSrcPFilter>0) && (iSrcPFilter!=SrcPort)) && ((iDstPFilter>0) && (iDstPFilter!=DstPort)) ) continue;
						pDlg->SetListCtrlData(IPPROTO_TCP,(char *)buf);
						break;
					}
				case IPPROTO_UDP:
					{
						if(!bUDP) continue;
						pUDPHead=(UDP_HEADER *)(buf+iIphLen);
						SrcPort = ntohs(pUDPHead->udp_Srcport);
						DstPort = ntohs(pUDPHead->udp_Dstport);
						if( ((iSrcPFilter>0) && (iSrcPFilter!=SrcPort)) && ((iDstPFilter>0) && (iDstPFilter!=DstPort)) ) continue;
						pDlg->SetListCtrlData(IPPROTO_UDP,(char *)buf);
						break;
					}
				case IPPROTO_ICMP:
					{
						if(!bICMP) continue;
						//pICMPHead=(ICMP_HEADER *)(buf+iIphLen);
						pDlg->SetListCtrlData(IPPROTO_ICMP,(char *)buf);
						break;
					}
				case IPPROTO_IGMP:
					{
						//pIGMPHead=(IGMP_HEADER *)(buf+iIphLen);
						pDlg->SetListCtrlData(IPPROTO_IGMP,(char *)buf);
						break;
					}
				}//end switch
			}else{
				//AfxMessageBox( "本局域网中没有传输的数据!" ) ;
				continue ;
			}
		}
		//Sleep( 100 ) ; //  Polling each 100 millisecond  	
	} 
	return true;
}

// IP解包程序
int CMySimpSnifferDlg::DecodeIPPack(char *buf, int iBufSize)
{
  	IP_HEADER * pIpheader;
  	SOCKADDR_IN saSource, saDest;

  	pIpheader = (IP_HEADER *)buf;

	//协议类别
  	m_iProtocol = pIpheader->ip_proto;		
  	strncpy(m_szProtocol, CheckProtocol(m_iProtocol), MAX_PROTO_TEXT_LEN);
  	
  	if((m_iProtocol == IPPROTO_TCP) && (!m_ParamTCP))
  		return true;
  	if((m_iProtocol == IPPROTO_UDP) && (!m_ParamUDP))
  		return true;
  	if((m_iProtocol == IPPROTO_ICMP) && (!m_ParamICMP))
  		return true; 
  
  	//源IP地址
  	saSource.sin_addr.s_addr = pIpheader->ip_srcIP;
  	strncpy(m_szSrcIP, inet_ntoa(saSource.sin_addr), MAX_ADDR_LEN);
  	//对指定源IP地址监测
	//AfxMessageBox(m_strFromIpFilter);
	if(m_strFromIpFilter)
  		if(strcmp(m_strFromIpFilter,m_szSrcIP)) 
		{
			//AfxMessageBox(m_strFromIpFilter);
			//exit(1);
			return true;
		}

  	//目的IP地址
  	saDest.sin_addr.s_addr = pIpheader->ip_dstIP;
  	strncpy(m_szDstIP, inet_ntoa(saDest.sin_addr), MAX_ADDR_LEN);
	//对指定目的IP地址监测
	if(m_strDestIpFilter)
  		if(strcmp(m_strDestIpFilter,m_szDstIP)) return true;

  	m_iTTL = pIpheader->ip_ttl;
  
  	//计算IP首部的长度
  	int iIphLen = sizeof(unsigned long) * (pIpheader->ip_verlen & 0xf);	// #define	IP_HLEN(pip)	((pip->ip_verlen & 0xf)<<2)

	//TRACE("协议: %s\r\n",m_szProtocol);
	//TRACE("IP首部的长度: %d\r\n",iIphLen);
  	//根据协议类型分别调用相应的解包程序
  	switch(m_iProtocol)
  	{
  		case IPPROTO_TCP :
  			DecodeTCPPack(buf+iIphLen, iBufSize);
  			break;
  		case IPPROTO_UDP :
  			DecodeUDPPack(buf+iIphLen, iBufSize);
  			break;
  		case IPPROTO_ICMP :
  			DecodeICMPPack(buf+iIphLen, iBufSize);
  			break;

⌨️ 快捷键说明

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