📄 ipcontroldoc.cpp
字号:
// 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 + -