www.pudn.com > zhuabao.rar > PacketReplayDoc.cpp


// PacketReplayDoc.cpp : implementation of the CPacketReplayDoc class 
// 
 
#include "stdafx.h" 
#include "PacketReplay.h" 
#include "PacketReplayDoc.h" 
 
 
#include "PacketReplayView.h"// 
 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CPacketReplayDoc 
 
IMPLEMENT_DYNCREATE(CPacketReplayDoc, CDocument) 
 
BEGIN_MESSAGE_MAP(CPacketReplayDoc, CDocument) 
	//{{AFX_MSG_MAP(CPacketReplayDoc) 
	ON_COMMAND(ID_SET, OnSet) 
	ON_COMMAND(ID_REPLAY, OnReplay) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CPacketReplayDoc construction/destruction 
extern int	mAllProto; 
extern int	mAllDestIP; 
extern int	mAllSourIP; 
extern int	mAllSourPort; 
extern int	mAllDestPort; 
extern int	mDestPort; 
extern int	mSourPort; 
extern CString m_strDIP; 
extern CString m_strSIP; 
 
CPacketReplayDoc::CPacketReplayDoc() 
{ 
	// TODO: add one-time construction code here 
	psend=new CSend(); 
	m_data.RemoveAll(); 
	alldevs=NULL; 
	d=NULL; 
	adhandle=NULL; 
	m_nDeviceCount=0; 
	m_nPacketNum=0; 
	m_ThreadHandle=NULL; 
} 
 
CPacketReplayDoc::~CPacketReplayDoc() 
{ 
} 
 
BOOL CPacketReplayDoc::OnNewDocument() 
{ 
	if (!CDocument::OnNewDocument()) 
		return FALSE; 
 
	// TODO: add reinitialization code here 
	// (SDI documents will reuse this document) 
 
	return TRUE; 
} 
 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CPacketReplayDoc serialization 
 
void CPacketReplayDoc::Serialize(CArchive& ar) 
{ 
	if (ar.IsStoring()) 
	{ 
		// TODO: add storing code here 
	} 
	else 
	{ 
		// TODO: add loading code here 
	} 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CPacketReplayDoc diagnostics 
 
#ifdef _DEBUG 
void CPacketReplayDoc::AssertValid() const 
{ 
	CDocument::AssertValid(); 
} 
 
void CPacketReplayDoc::Dump(CDumpContext& dc) const 
{ 
	CDocument::Dump(dc); 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CPacketReplayDoc commands 
//获取设备列表,统计网卡个数 
int CPacketReplayDoc::InitPacp() 
{ 
	//获取设备列表 
	if(pcap_findalldevs(&alldevs,errbuf)==-1) 
		return -1; 
	for(d=alldevs;d;d=d->next) 
	{ 
		m_nDeviceCount++; 
	} 
	return 1; 
} 
//在这个线程里捕获数据 
DWORD WINAPI MyCaptureThread(LPVOID lpParameter) 
{ 
 
	CPacketReplayDoc* pthis=(CPacketReplayDoc*)lpParameter; 
	if(pthis->adhandle==NULL) 
	{ 
		MessageBox(NULL,"线程中adhandle句柄错误!","提示",MB_OK); 
		return -1; 
	} 
	int res; 
	//用全局变量 
	struct pcap_pkthdr *header; 
	const u_char *pkt_data; //指向常量的指针 
	while((res=pcap_next_ex(pthis->adhandle,&header,&pkt_data))>=0) 
	{ 
		if(res==0) 
		{ 
			//time out 
			continue; 
		} 
		else 
		{ 
			//处理捕获的数据包 
			int a=pthis->SavePacket(header,pkt_data); //保存数据 
			//通知View更新列表控件 先获得视图的指针 
			if(a==1) 
			{ 
			POSITION curTemplatePos=pthis->GetFirstViewPosition();  
			CPacketReplayView* pView=(CPacketReplayView*)(pthis->GetNextView(curTemplatePos)); 
			pView->UpdateList();//通知视图更新列表 
			} 
		} 
//		if(pthis->dumpfile!=NULL) 
//		{ 
//			pcap_dump((unsigned char*)pthis->dumpfile,header,pkt_data); 
//		} 
	} 
	MessageBox(NULL,"捕获线程结束!","提示",MB_OK); 
 
	return 1; 
} 
//开始捕获数据包  index表示网卡的编号 
int CPacketReplayDoc::StartCapture(int index) 
{ 
	if(InitPacp()==-1) 
		return -1; 
	d=alldevs; 
	for(int i=0;inext; 
	//跳转到需要捕获数据包的设备了  
	//if(d->description) 
		//MessageBox(NULL,d->description,"tip",MB_OK); 
 
	//打开设备  
	adhandle=pcap_open_live(d->name, //网络设备名 
		65535, //数据包的捕获部分长度 
		1, //混合模式 1 打开混合模式 0关闭混合模式 
		1000,//读超时值 
		errbuf);//错误信息缓存区 
	if(adhandle==NULL) 
	{ 
		MessageBox(NULL,errbuf,"错误",MB_OK); 
		pcap_freealldevs(alldevs); 
		return -1; 
	} 
	 
	//检查是否为以太网 
	if(pcap_datalink(adhandle)!=DLT_EN10MB) 
	{ 
		MessageBox(NULL,"这不适合于非以太网的网络!","错误",MB_OK); 
		pcap_freealldevs(alldevs); 
		return -1; 
	} 
 
	//取得网络接口的子网掩码 
	if(d->addresses!=NULL) 
	{ 
		netmask=((struct sockaddr_in*)(d->addresses->netmask))->sin_addr.S_un.S_addr; 
	} 
	else 
	{ 
		netmask=0xffffff; 
	} 
 
	pcap_freealldevs(alldevs);	 
	 
	//这里应该创建一个线程来处理 捕获数据 
	LPDWORD ThreadID=NULL; 
	m_ThreadHandle=CreateThread(NULL,0,MyCaptureThread,this,0,ThreadID); 
	if(m_ThreadHandle==NULL) 
	{ 
		int code=GetLastError(); 
		CString str; 
		str.Format("创建线程错误,代码为%d.",code); 
		MessageBox(NULL,str,"错误",MB_OK); 
		return -1; 
	} 
	return 1; 
	 
} 
 
 
//-------------------------------------------------------------------------------------- 
//分析刚捕获到的数据包 
int CPacketReplayDoc::SavePacket(struct pcap_pkthdr *header,const u_char *pkt_data) 
{ 
	if(header==NULL || pkt_data==NULL) 
	{ 
		return -1; 
	} 
	DataPacket* pdata=new DataPacket; 
	if(pdata==NULL) 
	{ 
		AfxMessageBox("由于内存空间有限,无法再保存数据包!"); 
		return -1; 
	} 
/* 
	tcp_header* tt; 
	u_char uc[24]={255,19,0x30,0x29,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00}; 
	tt=(tcp_header*)uc; 
	char str[10]; 
	sprintf(str,"%d",tt->dport); 
	AfxMessageBox(str); 
*/ 
 
/* 
	u_char uc[2]={255,19}; 
	u_short * s=(u_short *)uc; 
	char str[5]; 
	sprintf(str,"%X",*s); 
	AfxMessageBox(str); 
*/ 
 
/* 
	int a,b; 
	CString s; 
	a=header->caplen; 
	b=header->len; 
	s.Format("caplen is %d,len is %d",a,b); 
	AfxMessageBox(s); 
*/ 
 
 
	//分析并保存数据	 
	pdata->len=header->len;//保存长度 
	pdata->data = new u_char[header->len]; 
	memcpy(pdata->data, pkt_data, header->len); 
	 
	mac_header* mach; 
	ip_header* ih; 
	tcp_header* tcph; 
	udp_header* udph; 
	icmp_header* icmph; 
//MAC	 
	mach=(mac_header*)pkt_data; //mac头 
	for(int i=0;i<6;i++) 
	{ 
		pdata->mach.sadd[i]=mach->sadd[i]; 
		pdata->mach.dadd[i]=mach->dadd[i]; 
	} 
	pdata->mach.mac_type=mach->mac_type; 
 
//IP 
	ih=(ip_header*)(pkt_data+ARP_HEAD_LEN);//ip头 
	int iplen=(ih->ver_ihl & 0xf)*4; 
 
	pdata->iph.crc = ih->crc; 
	pdata->iph.daddr=ih->daddr; 
	pdata->iph.flags_fo=ih->flags_fo; 
	pdata->iph.identification=ih->identification; 
	pdata->iph.op_pad=ih->op_pad; 
	pdata->iph.proto=ih->proto; 
	pdata->iph.saddr=ih->saddr; 
	pdata->iph.tlen=ih->tlen; 
	pdata->iph.tos=ih->tos; 
	pdata->iph.ttl=ih->ttl; 
	pdata->iph.ver_ihl=ih->ver_ihl; 
//TCP 或 UDP 
	tcp_header* ptemp=NULL; 
	udp_header* pudptemp=NULL; 
	icmp_header* icmptemp=NULL; 
	switch(ih->proto) 
	{ 
	case TCP_PROTO: //如果是TCP 
		tcph=(tcp_header*)((u_char*)ih + iplen); 
		ptemp=new tcp_header; 
		ptemp->an=tcph->an; 
		ptemp->check_sum=tcph->check_sum; 
		ptemp->dport=tcph->dport; 
		ptemp->option=tcph->option; 
		ptemp->other=tcph->other; 
		ptemp->sn=tcph->sn; 
		ptemp->sport=tcph->sport; 
		ptemp->urgent_pointer=tcph->urgent_pointer; 
		ptemp->window_size=tcph->window_size; 
		pdata->pTCP_UDP =ptemp; 
		strcpy(pdata->strPacketType,"TCP"); 
		break; 
 
	case UDP_PROTO://如果是UDP 
		udph=(udp_header*)((u_char*)ih + iplen); 
		pudptemp=new udp_header; 
		pudptemp->crc=udph->crc; 
		pudptemp->dport=udph->dport; 
		pudptemp->len=udph->len; 
		pudptemp->sport=udph->sport; 
		pdata->pTCP_UDP=pudptemp; 
		strcpy(pdata->strPacketType,"UDP"); 
		break; 
 
	case ICMP_PROTO://如果是ICMP 
		icmph=(icmp_header*)((u_char*)ih + iplen); 
		icmptemp = new icmp_header; 
		icmptemp->chksum=icmph->chksum; 
		icmptemp->identifer=icmph->identifer; 
		icmptemp->sequence=icmph->sequence; 
		icmptemp->type=icmph->type; 
		pdata->pTCP_UDP=icmptemp; 
		strcpy(pdata->strPacketType,"ICMP"); 
		break; 
		 
	default: 
		pdata->pTCP_UDP=NULL; 
		strcpy(pdata->strPacketType,"Other"); 
		break; 
	} 
 
	int proto=0,Sip=0,Dip=0,Sport=0,Dport=0; 
	CString str; 
 
	//过滤协议类型 
	if(mAllProto==0) proto=1; 
	else if(mAllProto==1&&strcmp(pdata->strPacketType,"TCP")==0) proto=1; 
	else if(mAllProto==2&&strcmp(pdata->strPacketType,"UDP")==0) proto=1; 
	else if(mAllProto==3&&strcmp(pdata->strPacketType,"ICMP")==0) proto=1; 
	else if(mAllProto==4&&strcmp(pdata->strPacketType,"Other")==0) proto=1; 
	else proto=0; 
	//过滤源IP	 
	str.Format("%d.%d.%d.%d",pdata->iph.saddr.byte1,pdata->iph.saddr.byte2,pdata->iph.saddr.byte3,pdata->iph.saddr.byte4); 
	if(mAllSourIP==0) Sip=1; 
	else if(strcmp(str,m_strSIP)==0) Sip=1; 
	else Sip=0; 
	//过滤目的IP 
	str.Format("%d.%d.%d.%d",pdata->iph.daddr.byte1,pdata->iph.daddr.byte2,pdata->iph.daddr.byte3,pdata->iph.daddr.byte4); 
	if(mAllDestIP==0) Dip=1; 
	else if(strcmp(str,m_strDIP)==0) Dip=1; 
	else Dip=0; 
	//----------------------------------------------------------------------- 
	u_short sport,dport; 
	CString strSP,strDP; 
	if(strcmp(pdata->strPacketType,"TCP")==0) 
	{		 
		tcp_header* tcph=(tcp_header*)(pdata->pTCP_UDP); 
		sport=ntohs(tcph->sport); 
		dport=ntohs(tcph->dport); 
		strSP.Format("%d",sport); 
		strDP.Format("%d",dport); 
	} 
	else if(strcmp(pdata->strPacketType,"UDP")==0) 
	{ 
		udp_header* duph=(udp_header*)(pdata->pTCP_UDP); 
		sport=ntohs(duph->sport); 
		dport=ntohs(duph->dport); 
		strSP.Format("%d",sport); 
		strDP.Format("%d",dport); 
	} 
	else  
	{ 
		strSP.Format("-"); 
		strDP.Format("-"); 
	} 
	//过滤源端口 
	 
	if(mAllSourPort==0)Sport=1; 
	else  
	{ 
		str.Format("%d",mSourPort); 
		if(strcmp(strSP,str)==0)Sport=1; 
		else Sport=0; 
	} 
	//过滤目的端口 
	if(mAllDestPort==0)Dport=1; 
	else  
	{ 
		str.Format("%d",mDestPort); 
		if(strcmp(strDP,str)==0)Dport=1; 
		else Dport=0; 
	} 
	if(proto==1&&Sip==1&&Dip==1&&Sport==1&&Dport==1) 
	{	 
		m_data.AddTail(pdata); //保存数据 
		return 1;; 
	} 
	else  
	{ 
		delete pdata; 
		return -1; 
	} 
} 
 
 
//------------------------------------------------------------------------------------- 
//作为框架和视图类的中介,对树的真正更新在视图类中完成 
void CPacketReplayDoc::UpdateTree(int index) 
{ 
	//获得视图的指针 
	POSITION curTemplatePos=this->GetFirstViewPosition();  
	CPacketReplayView* pView=(CPacketReplayView*)(this->GetNextView(curTemplatePos)); 
	//通知视图更新树 
	pView->UpdateTree(m_nPacketNum-index-1); 
} 
 
void CPacketReplayDoc::UpdateEdit(int index) 
{ 
	//获得视图的指针 
	POSITION curTemplatePos=this->GetFirstViewPosition();  
	CPacketReplayView* pView=(CPacketReplayView*)(this->GetNextView(curTemplatePos)); 
	//通知视图更新编辑控件 
	pView->UpdateEdit(m_nPacketNum-index-1); 
} 
 
//分析已经保存的数据 目的是在列表中显示 
int CPacketReplayDoc::AnalyzeData(DataPacket *pdata) 
{ 
	if(pdata==NULL) 
	{ 
		AfxMessageBox("无效的数据指针!"); 
		return -1; 
	} 
	//数据 
	u_char* buf=pdata->data; 
	int datalen=pdata->len; 
 
/* 
	int iphead=(pdata->iph.ver_ihl&0xf) * 4; 
	buf=buf+ARP_HEAD_LEN+iphead; 
	datalen=datalen-ARP_HEAD_LEN-iphead; 
*/ 
 
	//序号 
	//itoa(m_nPacketNum,m_strIndex,10); 
	sprintf(m_strIndex,"%.4d",m_nPacketNum); 
	 
	//总长度 
 
	//itoa(ntohs(pdata->iph.tlen),m_strSize,10); 
	//sprintf(m_strSize,"%X",ntohs(pdata->iph.tlen)); 
 
	//IP头长 
	sprintf(m_strIPLen,"%d",(pdata->iph.ver_ihl & 0xf)*4); 
 
	//标识 
	sprintf(m_strID,"%X",ntohs(pdata->iph.identification)); 
 
    //TTL 
	//sprintf(m_strTTL,"%X",(pdata->iph.ttl)); 
	 
	//类型 
	strcpy(m_strProto,pdata->strPacketType); 
 
	//源IP和目的IP 
	sprintf(m_strSourIP,"%d.%d.%d.%d",pdata->iph.saddr.byte1,pdata->iph.saddr.byte2,pdata->iph.saddr.byte3,pdata->iph.saddr.byte4); 
	sprintf(m_strDestIP,"%d.%d.%d.%d",pdata->iph.daddr.byte1,pdata->iph.daddr.byte2,pdata->iph.daddr.byte3,pdata->iph.daddr.byte4); 
	 
	//源端口和目的端口 
	u_short sport,dport; 
	if(strcmp(pdata->strPacketType,"TCP")==0) 
	{		 
		tcp_header* tcph=(tcp_header*)(pdata->pTCP_UDP); 
		sport=ntohs(tcph->sport); 
		dport=ntohs(tcph->dport); 
		sprintf(m_strSourPort,"%d",sport); 
		sprintf(m_strDestPort,"%d",dport); 
	} 
	else if(strcmp(pdata->strPacketType,"UDP")==0) 
	{ 
		udp_header* duph=(udp_header*)(pdata->pTCP_UDP); 
		sport=ntohs(duph->sport); 
		dport=ntohs(duph->dport); 
		sprintf(m_strSourPort,"%d",sport); 
		sprintf(m_strDestPort,"%d",dport); 
	} 
	else  
	{ 
		sprintf(m_strSourPort,"-"); 
		sprintf(m_strDestPort,"-"); 
	} 
	 
		 
	//TCP解析 
	if(strcmp(pdata->strPacketType,"TCP")==0) 
	{ 
		tcp_header* ptcp=(tcp_header*)(pdata->pTCP_UDP); 
 
		//序列号 
		sprintf(m_strSN,"%X",ntohl(ptcp->sn)); 
 
		//确认号 
		sprintf(m_strAN,"%X",ntohl(ptcp->an)); 
 
		//窗口大小 
		//sprintf(m_strWindow,"%X",ntohs(ptcp->window_size)); 
 
		//紧急指针 
		//sprintf(m_strUrgPoint,"%X",ntohs(ptcp->urgent_pointer)); 
 
		//数据偏移 
		u_short others=ntohs(ptcp->other); 
	    sprintf(m_strDataOff,"%d",((others & 0xf000)>>12)*4); 
		//sprintf(m_strFIN,"%X",(others & 0x0001)); 
		//sprintf(m_strSYN,"%X",(others & 0x0002)>>1); 
		//sprintf(m_strRST,"%X",(others & 0x0004)>>2); 
		//sprintf(m_strPSH,"%X",(others & 0x0008)>>3); 
		//sprintf(m_strACK,"%X",(others & 0x0010)>>4); 
		//sprintf(m_strURG,"%X",(others & 0x0020)>>5); 
/* 
		int tcphead=((others & 0xf000)>>12)*4; 
		buf+=tcphead; 
		datalen-=tcphead; 
*/ 
	} 
	else 
	{	 
		sprintf(m_strDataOff,"-"); 
		sprintf(m_strSN,"-"); 
		sprintf(m_strAN,"-"); 
		//sprintf(m_strWindow,"-"); 
		//sprintf(m_strUrgPoint,"-"); 
 
		//sprintf(m_strFIN,"-"); 
		//sprintf(m_strSYN,"-"); 
		//sprintf(m_strRST,"-"); 
		//sprintf(m_strPSH,"-"); 
		//sprintf(m_strACK,"-"); 
		//sprintf(m_strURG,"-"); 
/*	 
		if(strcmp(pdata->strPacketType,"UDP")==0) 
		{ 
			buf+=UDP_HEAD_LEN; 
			datalen-=UDP_HEAD_LEN; 
		} 
		else if(strcmp(pdata->strPacketType,"ICMP")==0) 
		{ 
			buf+=ICMP_HEAD_LEN; 
			datalen-=ICMP_HEAD_LEN; 
		} 
		else 
		{ 
		} 
*/	 
	 } 
	CString str,str2; 
	for(int i=0;ipTCP_UDP; 
			delete p; 
		} 
		m_data.RemoveAll(); 
	}	 
	m_nPacketNum=0; 
} 
//------------------------------------------------------------------------------ 
void CPacketReplayDoc::OnSet()  
{ 
	// TODO: Add your command handler code here 
	set.DoModal(); 
} 
 
void CPacketReplayDoc::OnReplay()  
{ 
	//TODO: Add your command handler code here 
	if(psend->GetSafeHwnd()==0) 
		psend->Create(CSend::IDD); 
	else psend->SetFocus(); 
}