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 + -
显示快捷键?