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

📄 capture.cpp

📁 电子邮件系统数据包获取与还原技术的研究原码
💻 CPP
字号:
#include "StdAfx.h"
#include "Capture.h"
#include ".\capture.h"
#include <winsock.h>

void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
	bool ip_whole = false;

	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;


	iphead = (ip_header *) (pkt_data +14);// ip header's position
	ip_headlength = IP_HL(iphead)*4;//ip header's length

	if (ip_headlength < 20) {
		printf("   * Invalid IP header length: %u bytes\n", ip_headlength);
		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;
	printf("ID %d,DF %d,MF %d,len %d,iph %d,off %d\n",ntohs(iphead->identification),flagD,flagM,ip_totallength,ip_headlength,ip_offset);

	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;

	u_char SYN,ACK,FIN;
	u_char *tcp_data;
	tcp_header *tcphead;
	u_short sport,dport,tcp_headlength,tcp_datalength;

	tcphead = (tcp_header *)head;
	tcp_headlength = TCP_OFF(tcphead) * 4;
	if (tcp_headlength < 20) 
	{
		printf("   * Invalid TCP header length: %u bytes\n", tcp_headlength);
		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);
	printf("seq %u,SYN %d,ACK %d,FIN %d,",ntohl(tcphead->seq),SYN,ACK,FIN);
	printf("%d.%d.%d.%d.%d -> %d.%d.%d.%d.%d\n",src.byte1,src.byte2,src.byte3,src.byte4,sport,dst.byte1,dst.byte2,dst.byte3,dst.byte4,dport);

	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)
				{
					delete hd->data;
					hd->data = new u_char[tp->len+1];
					copy_data(tp->data,tp->len,hd->data);
					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;
	}
}

⌨️ 快捷键说明

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