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

📄 ipcontroldoc.cpp

📁 入侵检测系统
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// IPControlDoc.cpp : implementation of the CIPControlDoc class
//

#include "stdafx.h"
#include "IPControl.h"
#include "IPControlDoc.h"
#include "IPControlView.h"
#include <WINSOCK2.H>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define HAVE_REMOTE
/////////////////////////////////////////////////////////////////////////////
// CIPControlDoc
extern CIPControlApp theApp;
IMPLEMENT_DYNCREATE(CIPControlDoc, CDocument)

BEGIN_MESSAGE_MAP(CIPControlDoc, CDocument)
	//{{AFX_MSG_MAP(CIPControlDoc)
	ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
	ON_COMMAND(ID_FILE_SAVE, OnFileSave)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CIPControlDoc construction/destruction

CIPControlDoc::CIPControlDoc()
{
	// TODO: add one-time construction code here
	m_data.RemoveAll();
	alldevs=NULL;
	d=NULL;
	adhandle=NULL;
	m_nDeviceCount=0;
	m_nPackerNum=0;
	m_ThreadHandle=NULL;

	memset(filename,0,sizeof(filename));
}

CIPControlDoc::~CIPControlDoc()
{
	CleanData();
}

BOOL CIPControlDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)

	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CIPControlDoc serialization

void CIPControlDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}

/////////////////////////////////////////////////////////////////////////////
// CIPControlDoc diagnostics

#ifdef _DEBUG
void CIPControlDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CIPControlDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CIPControlDoc commands
//获取设备列表,统计网卡个数
int CIPControlDoc::InitPacp()
{
	//获取设备列表
	if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL,&alldevs,errbuf)==-1)
		return -1;
	for(d=alldevs;d;d=d->next)
	{
		m_nDeviceCount++;
	}
	return 1;
}
//分析刚捕获到的数据包
int CIPControlDoc::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;
	}
	//分析并保存数据
	struct tm *ltime;
	ltime=localtime(&header->ts.tv_sec);
	char timestr[16];
	strftime(timestr,sizeof(timestr),"%H:%M:%S",ltime);
	memset(pdata->strTime,0,sizeof(pdata->strTime));
	strcpy(pdata->strTime,timestr); //保存时间
	
	pdata->len=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+14);//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;
	}
	m_data.AddTail(pdata); //保存数据
	return 1;
}
//在这个线程里捕获数据
DWORD WINAPI MyCaptureThread(LPVOID lpParameter)
{
	CIPControlDoc* pthis=(CIPControlDoc*)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
		{
			//处理捕获的数据包
			pthis->SavePacket(header,pkt_data); //保存数据
			//通知View更新列表控件 先获得视图的指针
			POSITION curTemplatePos=pthis->GetFirstViewPosition(); 
			CIPControlView* pView=(CIPControlView*)(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 CIPControlDoc::StartCapture(int index)
{   
	if(InitPacp()==-1)
		return -1;
	d=alldevs;
	for(int i=0;i<index-1 && d!=NULL;i++)
		d=d->next;
	//跳转到需要捕获数据包的设备了 
	//if(d->description)
		//MessageBox(NULL,d->description,"tip",MB_OK);

	//打开设备 
	adhandle=pcap_open(d->name, //网络设备名
		65536, //数据包的捕获部分长度
		PCAP_OPENFLAG_PROMISCUOUS, //混合模式 1 打开混合模式 0关闭混合模式
		1000,//读超时值
		NULL,
		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);	
	//打开文件,准备保存数据
	CFileFind file;
	if(!file.FindFile("SavedData"))
	{
		CreateDirectory("SavedData",NULL);
	}
	time_t nowtime;
	time(&nowtime);
	struct tm *ltime;
	ltime=localtime(&nowtime);
	char thistime[30];
	strftime(thistime,sizeof(thistime),"%Y.%m.%d.%H.%M.%S",ltime);
	
	strcpy(filename,"SavedData\\");
	strcat(filename,thistime);
	strcat(filename,".log");
	dumpfile=pcap_dump_open(adhandle,filename); //打开要保存数据的文件
	if(dumpfile==NULL)
	{
		AfxMessageBox("打开文件错误!");
	}

	//这里应该创建一个线程来处理 捕获数据
	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 CIPControlDoc::StopCapture()
{
	if(m_ThreadHandle==NULL)
	{
		return 0;
	}
	if(TerminateThread(m_ThreadHandle,-1)==0)
	{		
		return -1;
	}
	m_ThreadHandle=NULL;
	if(dumpfile!=NULL)
	{
		pcap_dump_close(dumpfile); //关闭文件
		dumpfile=NULL;
	}
	return 1;
}

//作为筐架和视图类的中介,对树的真正更新在视图类中完成
void CIPControlDoc::UpdateTree(int index)
{
	//获得视图的指针
	POSITION curTemplatePos=this->GetFirstViewPosition(); 
	CIPControlView* pView=(CIPControlView*)(this->GetNextView(curTemplatePos));
	//通知视图更新树
	pView->UpdateTree(m_nPackerNum-index-1);
}

void CIPControlDoc::UpdateEdit(int index)
{
	//获得视图的指针
	POSITION curTemplatePos=this->GetFirstViewPosition(); 
	CIPControlView* pView=(CIPControlView*)(this->GetNextView(curTemplatePos));
	//通知视图更新编辑筐
	pView->UpdateEdit(m_nPackerNum-index-1);
}

//分析已经保存的数据 目的是在列表中显示
int CIPControlDoc::AnalyzeData(DataPacket *pdata)
{
	if(pdata==NULL)
	{
		AfxMessageBox("无效的数据指针!");
		return -1;
	}
	//在这里分析
	itoa(m_nPackerNum,m_strPacketIndex,10); //序号
	strcpy(m_strTime,pdata->strTime); //时间
	itoa(pdata->len,m_strLen,10); //长度
	
	memset(m_strSourMAC,0,sizeof(m_strSourMAC));
	memset(m_strDestMAC,0,sizeof(m_strDestMAC));
	//源MAC 和目的MAC
	for(int i=0;i<6;i++)
	{
		char sm[3];
		if(i!=5)
		{
			sprintf(sm,"%X.",pdata->mach.sadd[i]);
			strcat(m_strSourMAC,sm);

			sprintf(sm,"%X.",pdata->mach.dadd[i]);
			strcat(m_strDestMAC,sm);
		}
		else
		{
			sprintf(sm,"%X",pdata->mach.sadd[i]);
			strcat(m_strSourMAC,sm);
			
			sprintf(sm,"%X",pdata->mach.dadd[i]);
			strcat(m_strDestMAC,sm);
		}
	}

	//类型
	strcpy(m_strPacketType,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_tcpsn,"%d",tcph->sn);
		sprintf(m_tcpan,"%d",tcph->an);
		sprintf(m_tcpother,"%d",tcph->other);
		sprintf(m_tcpwindow_size,"%d",tcph->window_size);
		sprintf(m_tcpcheck_sum,"%d",tcph->check_sum);
		sprintf(m_tcpurgent_pointer,"%d",tcph->urgent_pointer);
		sprintf(m_tcpoption,"%d",tcph->option);
	}
	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_udplen,"%d",duph->len);
		sprintf(m_udpcrc,"%d",duph->crc);
	}
	else if(strcmp(pdata->strPacketType,"ICMP")==0)
	{   icmp_header* icmph=(icmp_header*)(pdata->pTCP_UDP);
	    sprintf(m_icmptype,"%X",icmph->type);
		sprintf(m_icmpidentifer,"%d",icmph->identifer);
		sprintf(m_icmpsequence,"%d",icmph->sequence);
		sprintf(m_icmpchksum,"%d",icmph->chksum);
		sport=0;
		dport=0;

	}
	else
	{
		sport=0;
		dport=0;
	}
	//源端口和目的端口
	sprintf(m_strSport,"%d",sport);
	sprintf(m_strDport,"%d",dport);
	sprintf(m_mactype,"%d",pdata->mach.mac_type);
	sprintf(m_ver_ihl,"%d",pdata->iph.ver_ihl);
	sprintf(m_tos,"%d",pdata->iph.tos);
	sprintf(m_tlen,"%d",pdata->iph.tlen);
	sprintf(m_identification,"%d",pdata->iph.identification);
	sprintf(m_flags_fo,"%d",pdata->iph.flags_fo);
	sprintf(m_ttl,"%d",pdata->iph.ttl);
	sprintf(m_proto,"%d",pdata->iph.proto);
	sprintf(m_crc,"%d",pdata->iph.crc);
	sprintf(m_op_pad,"%d",pdata->iph.op_pad);
	
    if(strcmp(pdata->strPacketType,"TCP")==0)
	{m_pRecordset.CreateInstance("ADODB.Recordset");
	 m_pRecordset->Open("SELECT * FROM tcp",_variant_t((IDispatch*)theApp.m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText);
    try
	{
		m_pRecordset->AddNew();
		m_pRecordset->PutCollect("ID", _variant_t(m_strPacketIndex));
		m_pRecordset->PutCollect("TIME", _variant_t(m_strTime));
		m_pRecordset->PutCollect("LENGTH", _variant_t(m_strLen));
		m_pRecordset->PutCollect("SMAC", _variant_t(m_strSourMAC));
		m_pRecordset->PutCollect("DMAC", _variant_t(m_strDestMAC));
		m_pRecordset->PutCollect("SIP", _variant_t(m_strSourIP));
		m_pRecordset->PutCollect("DIP", _variant_t(m_strDestIP));
		m_pRecordset->PutCollect("SPORT", _variant_t(m_strSport));
		m_pRecordset->PutCollect("DPORT", _variant_t(m_strDport));
		m_pRecordset->PutCollect("VER", _variant_t(m_ver_ihl));
		m_pRecordset->PutCollect("TOS", _variant_t(m_tos));
		m_pRecordset->PutCollect("TLEN", _variant_t(m_tlen));
		m_pRecordset->PutCollect("IDEN", _variant_t(m_identification));
		m_pRecordset->PutCollect("FLAG", _variant_t(m_flags_fo));
		m_pRecordset->PutCollect("TTL", _variant_t(m_ttl));
		m_pRecordset->PutCollect("PROTO", _variant_t(m_proto));
		m_pRecordset->PutCollect("CRC", _variant_t(m_crc));
		m_pRecordset->PutCollect("OP_PAD", _variant_t(m_op_pad));
		m_pRecordset->PutCollect("SN", _variant_t(m_tcpsn));
		m_pRecordset->PutCollect("AN", _variant_t(m_tcpan));
		m_pRecordset->PutCollect("OTHER", _variant_t(m_tcpother));
		m_pRecordset->PutCollect("WINDOW_SIZE", _variant_t(m_tcpwindow_size));
		m_pRecordset->PutCollect("CHECK_SUM", _variant_t(m_tcpcheck_sum));
		m_pRecordset->PutCollect("URGENT_POINTER", _variant_t(m_tcpurgent_pointer));
		m_pRecordset->PutCollect("OPTION", _variant_t(m_tcpoption));
		m_pRecordset->Update();
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}
	}
	else if(strcmp(pdata->strPacketType,"UDP")==0)
	{m_pRecordset.CreateInstance("ADODB.Recordset");
	 m_pRecordset->Open("SELECT * FROM udp",_variant_t((IDispatch*)theApp.m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText);
    try
	{
		m_pRecordset->AddNew();
		m_pRecordset->PutCollect("ID", _variant_t(m_strPacketIndex));
		m_pRecordset->PutCollect("TIME", _variant_t(m_strTime));
		m_pRecordset->PutCollect("LENGTH", _variant_t(m_strLen));
		m_pRecordset->PutCollect("SMAC", _variant_t(m_strSourMAC));
		m_pRecordset->PutCollect("DMAC", _variant_t(m_strDestMAC));
		m_pRecordset->PutCollect("SIP", _variant_t(m_strSourIP));
		m_pRecordset->PutCollect("DIP", _variant_t(m_strDestIP));
		m_pRecordset->PutCollect("SPORT", _variant_t(m_strSport));
		m_pRecordset->PutCollect("DPORT", _variant_t(m_strDport));
		m_pRecordset->PutCollect("VER", _variant_t(m_ver_ihl));
		m_pRecordset->PutCollect("TOS", _variant_t(m_tos));
		m_pRecordset->PutCollect("TLEN", _variant_t(m_tlen));
		m_pRecordset->PutCollect("IDEN", _variant_t(m_identification));
		m_pRecordset->PutCollect("FLAG", _variant_t(m_flags_fo));
		m_pRecordset->PutCollect("TTL", _variant_t(m_ttl));
		m_pRecordset->PutCollect("PROTO", _variant_t(m_proto));
		m_pRecordset->PutCollect("CRC", _variant_t(m_crc));
		m_pRecordset->PutCollect("OP_PAD", _variant_t(m_op_pad));
		m_pRecordset->PutCollect("LEN", _variant_t(m_udplen));
		m_pRecordset->PutCollect("UDPCRC", _variant_t(m_udpcrc));
		m_pRecordset->Update();
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}
	}
	else if(strcmp(pdata->strPacketType,"ICMP")==0)
	{m_pRecordset.CreateInstance("ADODB.Recordset");
	 m_pRecordset->Open("SELECT * FROM icmp",_variant_t((IDispatch*)theApp.m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText);
    try
	{

⌨️ 快捷键说明

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