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

📄 biyeshejiview.cpp

📁 电子邮件系统数据包获取与还原技术的研究原码
💻 CPP
字号:
// biyeshejiView.cpp : implementation of the CBiyeshejiView class
//

#include "stdafx.h"
//#include <WinSock.h>
#include <direct.h>
#include "biyesheji.h"
#include "MainFrm.h"
#include "MailView.h"
#include "biyeshejiDoc.h"
#include "biyeshejiView.h"
#include ".\biyeshejiview.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define BUFFER_SIZE 65536
u_char buff[BUFFER_SIZE];
char path[256];
bool stop;//a flag of packet capture 
ip_datagram *ip_lt = NULL;
tcp_datagram *tcp_lt = NULL;

/////////////////////////////////////////////////////////////////////////////
// CBiyeshejiView

IMPLEMENT_DYNCREATE(CBiyeshejiView, CEditView)

BEGIN_MESSAGE_MAP(CBiyeshejiView, CEditView)
	//{{AFX_MSG_MAP(CBiyeshejiView)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CEditView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CEditView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CEditView::OnFilePrintPreview)
	ON_COMMAND(ID_START, OnStart)
	ON_COMMAND(ID_STOP, OnStop)
	ON_COMMAND(ID_MAILVIEW, OnMailview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBiyeshejiView construction/destruction

CBiyeshejiView::CBiyeshejiView()
{
	// TODO: add construction code here
	m_pCaptthread = NULL;
}

CBiyeshejiView::~CBiyeshejiView()
{
}

BOOL CBiyeshejiView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	BOOL bPreCreated = CEditView::PreCreateWindow(cs);
	cs.style &= ~(ES_AUTOHSCROLL|WS_HSCROLL);	// Enable word-wrapping

	return bPreCreated;
}

/////////////////////////////////////////////////////////////////////////////
// CBiyeshejiView drawing

void CBiyeshejiView::OnDraw(CDC* pDC)
{
	CBiyeshejiDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
}

/////////////////////////////////////////////////////////////////////////////
// CBiyeshejiView printing

BOOL CBiyeshejiView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default CEditView preparation
	return CEditView::OnPreparePrinting(pInfo);
}

void CBiyeshejiView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
	// Default CEditView begin printing.
	CEditView::OnBeginPrinting(pDC, pInfo);
}

void CBiyeshejiView::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo)
{
	// Default CEditView end printing
	CEditView::OnEndPrinting(pDC, pInfo);
}

void CBiyeshejiView::addstr(LPCTSTR str)
{
	CEdit &theEdit = GetEditCtrl();
	int len = theEdit.GetWindowTextLength();
	theEdit.SetSel(len,len);
	theEdit.ReplaceSel(str);
}
/////////////////////////////////////////////////////////////////////////////
// CBiyeshejiView diagnostics

#ifdef _DEBUG
void CBiyeshejiView::AssertValid() const
{
	CEditView::AssertValid();
}

void CBiyeshejiView::Dump(CDumpContext& dc) const
{
	CEditView::Dump(dc);
}

CBiyeshejiDoc* CBiyeshejiView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CBiyeshejiDoc)));
	return (CBiyeshejiDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CBiyeshejiView message handlers

void CBiyeshejiView::OnStart()
{
	if (m_pCaptthread == NULL)
	{		
		m_pCaptthread =AfxBeginThread((AFX_THREADPROC)capture_packet,this);
		stop = false;
		return;
	}
	 if (stop)
	{
		GetEditCtrl().Clear();
		m_pCaptthread->ResumeThread();
		stop = false;
		return;
	}
	m_pCaptthread =AfxBeginThread((AFX_THREADPROC)capture_packet,this);
	stop = false;
}

void CBiyeshejiView::OnStop()
{
	if (!stop)
	{
		m_pCaptthread->SuspendThread();
		stop = true;
	}
}

UINT capture_packet(LPVOID lpParam)
{
	CBiyeshejiView *view = (CBiyeshejiView*)lpParam;
	int num,res;
	u_int netmask;
	pcap_t *adhandle;
	pcap_if_t *d;
	char errbuf[PCAP_ERRBUF_SIZE];
	const u_char *pkt_data;

	char packet_filter[] = "ip[9] = 6";
	struct bpf_program fcode;
	struct pcap_pkthdr *header;
	CString name,str;

	CMainFrame *mWnd;
	mWnd =(CMainFrame*)(AfxGetApp()->m_pMainWnd);
	num = (mWnd->m_Adpter).GetCurSel();
	if (num == -1)
	{
		str = "fill adapter\r\n";
		view->addstr(str);
		return -1;
	}
	
	mWnd->m_Adpter.GetLBText(num,name);
	if ( (adhandle= pcap_open_live(name, // name of the device
		65536, // portion of the packet to capture.65536 grants that the whole packet will be captured on all the MACs.
		1, // promiscuous mode
		1000, // read timeout
		errbuf // error buffer
		) ) == NULL)
	{
		str = "Unable to open the adapter." + name + "is not supported by WinPcap\r\n";
		view->addstr(str);
		pcap_freealldevs(mWnd->alldevs);
		return -1;
	}
	/* Check the link layer. We support only Ethernet for simplicity. */
	if(pcap_datalink(adhandle) != DLT_EN10MB)
	{
		str = "This program works only on Ethernet networks.\r\n";
		view->addstr(str);
		pcap_freealldevs(mWnd->alldevs);
		return -1;
	}
	for (d=mWnd->alldevs; d; d=d->next)	
		if (d->name == name)
			break;
	/* Retrieve the mask of the first address of the interface */
	if (d->addresses != NULL)
		netmask = ((struct sockaddr_in*)(d->addresses->netmask))->sin_addr.S_un.S_addr;
	else
		netmask = 0xffffff;
	//compile the filter
	if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) < 0)
	{
		str = "Unable to compile the packet filter. Check the syntax.\r\n";
		view->addstr(str);
		pcap_freealldevs(mWnd->alldevs);
		return -1;
	}
	//set the filter
	if(pcap_setfilter(adhandle, &fcode)< 0)
	{
		str = "Error setting the filter.\r\n";
		view->addstr(str);
		pcap_freealldevs(mWnd->alldevs);
		return -1;
	}
	str = "listening on" + name + "\r\n";
	view->addstr(str);
	pcap_freealldevs(mWnd->alldevs);
	getcwd(path,256);

	/* start the capture */
	//pcap_loop(adhandle, 0, packet_handler, NULL);
	/* Retrieve the packets */
	while((res = pcap_next_ex( adhandle,&header, &pkt_data)) >= 0){
		if (res == 0)
			continue;
		packet_handler(NULL,NULL,pkt_data);
		/*if (stop)
		{
			view->addstr("stop!");
			return -1;
		}*/
	}
	if(res == -1){
		str.Format("Error reading the packets: %s\r\n", pcap_geterr(adhandle));
		view->addstr(str);
		return -1;
	}
	return 0;
}
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
	bool ip_whole = false;
	CString str;
	CBiyeshejiView* view;
	ip_header *iphead;
	u_char *ip_data;
	u_short ip_totallength,ip_headlength,ip_datalength,flagD,flagM,ip_offset;
	ip_address dst,src;

	ip_datagram *ip_pt=NULL,*ip_prev=NULL;
	ip_frag *temp=NULL,*prev=NULL,*head=NULL;

	view = (CBiyeshejiView*)(((CMainFrame*)(AfxGetApp()->m_pMainWnd))->GetActiveView());
	iphead = (ip_header *) (pkt_data +14);// ip header's position
	ip_headlength = IP_HL(iphead)*4;//ip header's length

	if (ip_headlength < 20) {
		str.Format("* Invalid IP header length: %u bytes\r\n", ip_headlength);
		view->addstr(str);
		return;
	}

	ip_totallength = ntohs(iphead->len);
	ip_data = (u_char*)iphead+ip_headlength;//data's position
	ip_datalength = ip_totallength-ip_headlength;
	flagD = (ntohs(iphead->flg_off)&IP_DF) >> 14;//flag DF
	flagM = (ntohs(iphead->flg_off)&IP_MF) >> 13;//flag MF
	ip_offset = (ntohs(iphead->flg_off)&IP_OFFMASK)*8;//offset
	src = iphead->saddr;
	dst = iphead->daddr;
	str.Format("ID %d,DF %d,MF %d,len %d,iph %d,off %d",ntohs(iphead->identification),flagD,flagM,ip_totallength,ip_headlength,ip_offset);
	view->addstr(str);

	if (flagD) 
		ip_whole = true;
	else 
		if (!ip_offset && !flagM) 
			ip_whole = true;

	if(ip_whole)
		tcp(src,dst,ip_datalength,ip_data);
	else 
	{
		temp = new ip_frag;
		temp->data = new u_char[ip_datalength+1];
		copy_data(ip_data,ip_datalength,temp->data);
		temp->next = NULL;
		temp->offset = ip_offset;
		temp->length = ip_datalength;
		temp->mf = flagM;
		if (!ip_lt)
		{
			ip_pt = new ip_datagram;
			ip_pt->frag = temp;
			ip_pt->ip_dst = iphead->saddr;
			ip_pt->ip_src = iphead->daddr;
			ip_pt->ip_id =ntohs(iphead->identification);
			ip_pt->next = NULL;
			ip_lt = ip_pt;
		}
		else
		{
			ip_pt = ip_lt;
			while (ip_pt)
			{
				if (compare_address(&ip_pt->ip_src,&src) &&
					compare_address(&ip_pt->ip_dst,&dst) &&
					ip_pt->ip_id == ntohs(iphead->identification) )
				{
					head = ip_pt->frag;
					while (head && (temp->offset > head->offset))
					{
						prev = head;
						head = head->next;	
					}
					if (ip_pt->frag == head)
					{
						temp->next = head;
						ip_pt->frag = temp;
					}
					else
					{
						prev->next = temp;
						temp->next = head;
					}	
					break;
				}
				ip_prev = ip_pt;
				ip_pt = ip_pt->next;
			}
			if (!ip_pt)
			{
				ip_pt = new ip_datagram;
				ip_pt->frag = temp;
				ip_pt->ip_dst = iphead->daddr;
				ip_pt->ip_src = iphead->saddr;
				ip_pt->ip_id =ntohs(iphead->identification);
				ip_pt->next = NULL;
				ip_prev->next = ip_pt;
			}
		}
		if (ip_data = check_ip(&src,&dst,&ip_datalength))
			tcp(src,dst,ip_datalength,ip_data);
	}

}

void copy_data(const u_char *src_data,int len,u_char *dst_data)
{
	for (int i=0; i<len; i++)
	{
		dst_data[i] = src_data[i];
	}
	dst_data[i] = '\0';

}

bool compare_address(const ip_address *address1,const ip_address *address2)
{
	if (address1->byte1==address2->byte1 &&
		address1->byte2==address2->byte2 &&
		address1->byte3==address2->byte3 &&
		address1->byte4==address2->byte4 )
		return true;
	return false;
}

u_char* check_ip(ip_address *src,ip_address *dst,u_short* off)
{
	ip_datagram *ip_pt=NULL,*ip_prev=NULL;
	ip_frag *temp,*head;
	u_short offset;

	ip_pt = ip_lt;
	while (ip_pt)
	{		
		//check
		head = ip_pt->frag;
		temp = head->next;
		if (!head->offset)
		{
			while (temp)
			{
				if (head->offset+head->length==temp->offset)
				{
					head = temp;
					temp = temp->next;
				}
				else
					break;
			}
			if (head->mf == 0 && !temp )
			{
				offset = 0;
				head = ip_pt->frag;
				while (head)
				{	for(int i=0;i<head->length;i++)
				buff[offset++] = head->data[i];
				temp = head;
				head=head->next;
				delete temp->data;
				temp->data = NULL;
				delete temp;
				temp = NULL;
				}
				buff[offset] = '\0';
				*src = ip_pt->ip_src;
				*dst = ip_pt->ip_dst;
				*off = offset;
				if (ip_pt == ip_lt)
					ip_lt = ip_pt->next;
				else
					ip_prev->next = ip_pt->next;
				ip_pt->frag = NULL;
				ip_pt->next = NULL;
				delete ip_pt;
				return buff;
			}
		}
		ip_prev = ip_pt;
		ip_pt = ip_pt->next;
	}
	return NULL;
}


void tcp(const ip_address src,const ip_address dst,int tcp_lenth,u_char* head)
{
	static int count=0;
	char fname[256];
	FILE * fp;

	tcp_datagram *tcp_pt=NULL,*tcp_prev=NULL;
	tcp_frag *tp=NULL,*pv=NULL,*hd=NULL;
	CBiyeshejiView *view;
	CString str;

	u_char SYN,ACK,FIN;
	u_char *tcp_data;
	tcp_header *tcphead;
	u_short sport,dport,tcp_headlength,tcp_datalength;
	
	view = (CBiyeshejiView*)(((CMainFrame*)(AfxGetApp()->m_pMainWnd))->GetActiveView());
	tcphead = (tcp_header *)head;
	tcp_headlength = TCP_OFF(tcphead) * 4;
	if (tcp_headlength < 20) 
	{
		str.Format("*Invalid TCP header length: %u bytes\r\n", tcp_headlength);
		view->addstr(str);
		return;
	}
	tcp_datalength = tcp_lenth-tcp_headlength;
	tcp_data = head+tcp_headlength;
	sport = ntohs( tcphead->sport );
	dport = ntohs( tcphead->dport );
	SYN = (tcphead->flags & TH_SYN)>>1;
	ACK = (tcphead->flags & TH_ACK)>>4;
	FIN = (tcphead->flags & TH_FIN);
	str.Format("*seq %u,SYN %d,ACK %d,FIN %d,",ntohl(tcphead->seq),SYN,ACK,FIN);
	view->addstr(str);
	str.Format("*%d.%d.%d.%d.%d -> %d.%d.%d.%d.%d\r\n",src.byte1,src.byte2,src.byte3,src.byte4,sport,dst.byte1,dst.byte2,dst.byte3,dst.byte4,dport);
	view->addstr(str);

	if (dport != 25 && dport != 110)
		return;

	if (SYN && !ACK)
	{
		if(!tcp_lt)
		{
			tcp_lt = new tcp_datagram;
			tcp_lt->begin_seq = ntohl(tcphead->seq);
			tcp_lt->ip_src = src;
			tcp_lt->ip_dst = dst;
			tcp_lt->sport = sport;
			tcp_lt->dport = dport;
			tcp_lt->frag = NULL;
			tcp_lt->next = NULL;
			tcp_lt->ocet_num = 0;
			tcp_lt->final_seq = -1;
		}
		else
		{
			tcp_pt = tcp_lt;
			while (tcp_pt)
			{
				tcp_prev = tcp_pt;
				tcp_pt = tcp_pt->next;
			}
			tcp_pt = new tcp_datagram;
			tcp_pt->begin_seq = ntohl(tcphead->seq);
			tcp_pt->ip_src = src;
			tcp_pt->ip_dst = dst;
			tcp_pt->sport = sport;
			tcp_pt->dport = dport;
			tcp_pt->frag = NULL;
			tcp_pt->next = NULL;
			tcp_pt->ocet_num = 0;
			tcp_pt->final_seq = -1;
			tcp_prev->next = tcp_pt;
		}
	}
	else
	{					
		tcp_pt = tcp_lt;
		while (tcp_pt)
		{	
			if (compare_address(&tcp_pt->ip_src,&src) &&
				compare_address(&tcp_pt->ip_dst,&dst) &&
				sport == tcp_pt->sport && dport == tcp_pt->dport )
			{
				if (FIN)
				{
					tcp_pt->final_seq = ntohl(tcphead->seq);
					break;
				}
				if (!tcp_datalength)
					break;

				tp =new tcp_frag;
				tp->data = new u_char[tcp_datalength+1];
				copy_data(tcp_data,tcp_datalength,tp->data);
				tp->next = NULL;
				tp->len = tcp_datalength;
				tp->seq = ntohl(tcphead->seq);

				hd = tcp_pt->frag;
				while (hd && tp->seq > hd->seq)
				{
					pv = hd;
					hd = hd->next;
				}
				if (hd && tp->seq == hd->seq)
				{
					tcp_pt->ocet_num -= hd->len;
					delete hd->data;
					hd->data = new u_char[tp->len+1];
					copy_data(tp->data,tp->len,hd->data);
					tcp_pt->ocet_num += tp->len;
					delete tp->data;
					tcp_data = NULL;
					delete tp;
					tp = NULL;
					break;
				}
				else
				{

					if (tcp_pt->frag == hd)
					{
						tp->next = hd;
						tcp_pt->frag = tp;
					}
					else
					{
						pv->next = tp;
						tp->next = hd;
					}
					tcp_pt->ocet_num = tcp_pt->ocet_num + tp->len;
					break;
				}
			}
			tcp_pt = tcp_pt->next;
		}
	}
	//check tcp list
	tcp_pt = tcp_lt;
	while (tcp_pt)
	{
		if (tcp_pt->begin_seq + 1 + tcp_pt->ocet_num == tcp_pt->final_seq)
		{
			hd = tcp_pt->frag;
			sprintf(fname,"%s\\mail%d.dat",path,count++);
			if ((fp=fopen(fname,"wb+"))==NULL)
			{
				printf("File cannot be opened\n");
				exit(-1);
			}
			while (hd)
			{
				fputs((char*)hd->data,fp);
				tp = hd;
				hd = hd->next;
				delete tp->data;
				tp->data = NULL;
				delete tp;
				tp = NULL;
			}
			fclose(fp);
			if (tcp_pt == tcp_lt)
				tcp_lt = tcp_pt->next;
			else
				tcp_prev->next = tcp_pt->next;
			tcp_pt->frag = NULL;
			tcp_pt->next = NULL;
			delete tcp_pt;
			break;
		}
		tcp_prev = tcp_pt;
		tcp_pt = tcp_pt->next;
	}
}
void CBiyeshejiView::OnMailview()
{
	CMailView *dlg = new CMailView;
	dlg->Create(IDD_MAILVIEW,NULL);
	dlg->ShowWindow(SW_SHOW);
}

⌨️ 快捷键说明

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