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

📄 dealpacket.c

📁 Linux环境下mail监控程序的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		if (stream_node->bcc!=NULL)			free(stream_node->bcc);		if (stream_node->subject!=NULL)			free(stream_node->subject);	}	free(stream_node);}void smtp_thread(void){	//doLog(0, "begin smtp_thread()\n");	time_t now = 0;	tcp_stream_node *stream_node = NULL;	tcp_stream_node *prev_node = NULL;	while (SMTP_THREAD_STATUS)	{		sleep(1);		now = time(NULL);		stream_node = tcp_stream_head;		//doLog(0, "find a stream()\n");		if (stream_node == NULL)		{			//doLog(0, "stream() is null\n");			continue;		}		if (now - stream_node->etime >= CHK_END_TIME)		{			//doLog(0, "find a close stream()\n");			close(stream_node->req_stream.fp);			if (stream_node->req_stream.bflag<=0 || stream_node->req_stream.eflag<=0)			{				//if (stream_node->req_stream.bflag<=0)				//	doLog(0, "未开始\n");				//if (stream_node->req_stream.eflag<=0)				//	doLog(0, "未结束\n");				//doLog(0, "删除文件: %s\n", stream_node->req_stream.path);				remove(stream_node->req_stream.path);			}			else			{				analysis_smtp(stream_node);				write_database(stream_node);			}						pthread_mutex_lock(&smtp_mutex);			tcp_stream_head = tcp_stream_head->next;			free_stream_node(stream_node);			pthread_mutex_unlock(&smtp_mutex);						continue;		}		//doLog(0, "stream() no close\n");		prev_node = stream_node;		for (stream_node = stream_node->next; stream_node != NULL; )		{			if (now - stream_node->etime < CHK_END_TIME)			{				prev_node = stream_node;				stream_node = stream_node->next;				continue;			}			//doLog(0, "find a close stream()\n");			close(stream_node->req_stream.fp);						if (stream_node->req_stream.bflag<=0 || stream_node->req_stream.eflag<=0)			{				//if (stream_node->req_stream.bflag<=0)				//	doLog(0, "未开始\n");				//if (stream_node->req_stream.eflag<=0)				//	doLog(0, "未结束\n");				//doLog(0, "删除文件: %s\n", stream_node->req_stream.path);				remove(stream_node->req_stream.path);			}			else			{				analysis_smtp(stream_node);				write_database(stream_node);			}			pthread_mutex_lock(&smtp_mutex);			prev_node->next = stream_node->next;			free_stream_node(stream_node);			stream_node = prev_node->next;			pthread_mutex_unlock(&smtp_mutex);		}	}	//doLog(0, "end smtp_thread()\n");}int deal_packet(const char *packet, int len){	struct ether_header *peth = NULL;	struct iphdr *pip = NULL;	struct tcphdr *ptcp = NULL;	u_int16_t flags = 0;	u_int16_t head_len = 0;	u_int16_t data_len = 0;	time_t now = 0;	char *temp=NULL;	char *str_temp=NULL;	char *re_temp=NULL;	peth = (struct ether_header *)packet;	pip = (struct iphdr *)(packet + sizeof(struct ether_header)); //pip指向ip层的包头	ptcp = (struct tcphdr *)((char *)pip + sizeof(struct iphdr)); //ptcp指向tcp头部		//0x003f = 111111 B	flags = *((char *)ptcp + 13) & 0x003f;	//source+dest+seq+ack_seq+1=13	head_len = pip->ihl*4 + ptcp->doff*4;	data_len = ntohs(pip->tot_len) - head_len;	now = time(NULL);		//doLog(0, "data_len = %d, flags = 0X%04x\n", data_len, flags);		//0x0010 = 010000 B	if (data_len == 0 && flags == 0x0010)//没有携带数据的ACK包	{		u_int32_t hash = pip->saddr + pip->daddr + ntohs(ptcp->source) + ntohs(ptcp->dest);		tcp_stream_node *stream_node = find_node_by_hash(tcp_stream_head, hash);		if (stream_node == NULL)		{			//doLog(0, "can't find the tcp_stream_node, lost this packet.\n");			return ACCEPT;		}		if ((stream_node->req_stream.source != ntohs(ptcp->source)) && (stream_node->res_stream.source != ntohs(ptcp->source)))		{			//doLog(0, "to determine req_stream or res_stream wrong!\n");			return ACCEPT;		}		stream_node->etime = now;		return ACCEPT;	}	//0x0002 = 000010 B	if (flags == 0x0002)//SYN请求包	{		//doLog(0, "it's the SYN packet, lost it.\n");		return ACCEPT;	}	//0x0012 = 010010 B	else if (flags == 0x0012)//SYN应答包	{		//smtp首先由客户端向服务端的25端口发起连接请求,然后由服务端25端口应答客户端,如果SYN应答包中源端口不为25则代表该连接不是SMTP连接		if (ntohs(ptcp->source)!=25)		{			return ACCEPT;		}				u_int32_t hash = pip->saddr + pip->daddr + ntohs(ptcp->source) + ntohs(ptcp->dest);				tcp_stream_node *stream_node = find_node_by_hash(tcp_stream_head, hash);		if (stream_node != NULL)		{			//应该覆盖原来内容????????????????????			//doLog(0, "has found the tcp_stream_node, lost this packet.\n");			return ACCEPT;		}		//doLog(0, "begin create a new tcp_stream_node.\n");		stream_node = (tcp_stream_node *)malloc(sizeof(tcp_stream_node));				//doLog(0, "malloc new tcp_stream_node.\n");				memset(stream_node, 0, sizeof(tcp_stream_node));		stream_node->hash = hash;		stream_node->saddr = pip->daddr;		stream_node->daddr = pip->saddr;		stream_node->seq_beg = ntohl(ptcp->ack_seq);		stream_node->stime = now;		stream_node->etime = now;				stream_node->req_stream.source = ntohs(ptcp->dest);		stream_node->req_stream.dest = ntohs(ptcp->source);		stream_node->res_stream.source = ntohs(ptcp->source);		stream_node->res_stream.dest = ntohs(ptcp->dest);				memcpy(stream_node->smac, peth->ether_dhost, ETH_ALEN);		memcpy(stream_node->dmac, peth->ether_shost, ETH_ALEN);			memset(stream_node->req_stream.path, 0, PATH_MAXLEN);		sprintf(stream_node->req_stream.path, "%s\%u_%ld.eml", TEMP_PATH, hash, stream_node->stime);		//doLog(0, "create a new wfile .\n");		//doLog(0, "path : %s\n", stream_node->req_stream.path);		stream_node->req_stream.fp = open(stream_node->req_stream.path, O_WRONLY | O_CREAT);				if (stream_node->req_stream.fp < 0 )		{			free_stream_node(stream_node);			return ACCEPT;		}		//doLog(0, "wfile create over.\n");		stream_node->req_stream.bflag = 0;		stream_node->req_stream.eflag = 0;		stream_node->req_stream.e_b = 0;		stream_node->mail_len = 0;		stream_node->next = NULL;		pthread_mutex_lock(&smtp_mutex);		stream_node->next = tcp_stream_head;		tcp_stream_head = stream_node;			//加锁???????????????		pthread_mutex_unlock(&smtp_mutex);		//doLog(0, "create tcp_stream_node ok.\n");		return ACCEPT;	}	//0x0012 = 000001 B	else if (flags & 0x0001)//FIN包	{		u_int32_t hash = pip->saddr + pip->daddr + ntohs(ptcp->source) + ntohs(ptcp->dest);		tcp_stream_node *stream_node = find_node_by_hash(tcp_stream_head, hash);		if (stream_node == NULL)		{			//doLog(0, "can't find the tcp_stream_node, lost this packet.\n");			return ACCEPT;		}		if ((stream_node->req_stream.source != ntohs(ptcp->source)) && (stream_node->res_stream.source != ntohs(ptcp->source)))		{			//doLog(0, "to determine req_stream or res_stream wrong!\n");			return ACCEPT;		}		stream_node->etime = now;		return ACCEPT;	}	//0x0004 = 000100 B	else if (flags & 0x0004)		//RST包	{		u_int32_t hash = pip->saddr + pip->daddr + ntohs(ptcp->source) + ntohs(ptcp->dest);		tcp_stream_node *stream_node = find_node_by_hash(tcp_stream_head, hash);		if (stream_node == NULL)		{			//doLog(0, "can't find the tcp_stream_node, lost this packet.\n");			return ACCEPT;		}		if ((stream_node->req_stream.source != ntohs(ptcp->source)) && (stream_node->res_stream.source != ntohs(ptcp->source)))		{			//doLog(0, "to determine req_stream or res_stream wrong!\n");			return ACCEPT;		}		stream_node->etime = now;		return ACCEPT;	}	//0x0010 = 010000 B	else if (flags & 0x0010)// 携带数据的ACK包	{				u_int32_t hash = pip->saddr + pip->daddr + ntohs(ptcp->source) + ntohs(ptcp->dest);		tcp_stream_node *stream_node = find_node_by_hash(tcp_stream_head, hash);		u_int32_t t_seq = ntohl(ptcp->seq)-stream_node->seq_beg;		u_int32_t len = 0;		if (stream_node == NULL)		{			//doLog(0, "can't find the tcp_stream_node, lost this packet.\n");			return ACCEPT;		}		//tcp_stream *stream = NULL;		if (stream_node->req_stream.source == ntohs(ptcp->source))		{			//doLog(0, "source: %d, dest: %d, seq: %u, data_len: %d, flags = 0X%02x\n", ntohs(ptcp->source), ntohs(ptcp->dest), t_seq, data_len, flags);					stream_node->etime = now;						temp = (char *)pip+head_len;			if (stream_node->req_stream.bflag == 0)			{				if (data_len > 11)//命令 RCPT TO: xxxx\r\n 的长度				{					//命令 MAIL FROM: xxxx\r\n 					if ((str_temp=strstr(temp, "MAIL FROM: "))!=0)					{						memset(stream_node->from, 0, sizeof(stream_node->from));						memcpy(stream_node->from, str_temp+11, data_len-13);						//doLog(0, "MAIL FORM: %s  ----------\n", stream_node->from);					}					else if ((str_temp=strstr(temp, "RCPT TO: "))!=0)					{						if (stream_node->rcpt_to==NULL)						{							len = strlen(str_temp)-2+1;//去掉最后两位0x0d 0x0a							re_temp = (char *)malloc(len);							memset(re_temp, 0, len);							memcpy(re_temp, str_temp+9, data_len-11);							//strcpy(re_temp, str_temp);							stream_node->rcpt_to = re_temp;							re_temp = NULL;							//doLog(0, "RCPT TO: %s  ----------\n", stream_node->rcpt_to);						}						else						{							len = strlen(stream_node->rcpt_to)+1+strlen(str_temp)-2+1;							re_temp = (char *)malloc(len);							memset(re_temp, 0, len);							strcpy(re_temp, stream_node->rcpt_to);							strcat(re_temp, ",");							memcpy(re_temp+strlen(stream_node->rcpt_to)+1, str_temp+9, data_len-11);							//strcat(re_temp, str_temp);							free(stream_node->rcpt_to);							stream_node->rcpt_to = re_temp;							re_temp=NULL;							//doLog(0, "RCPT TO: %s  ----------\n", stream_node->rcpt_to);						}					}				}			}			//命令 Data\r\n 			if (temp[0]==0x44 || temp[0]==0x64 )//TCP数据部分第1位数据为: D 或 d			{				if (temp[1]==0x41 || temp[1]==0x61 )//TCP数据部分第2位数据为: A 或 a				{					if (temp[2]==0x54 || temp[2]==0x74 )//TCP数据部分第3位数据为: T 或 t					{						if (temp[3]==0x41 || temp[3]==0x61 )//TCP数据部分第4位数据为: A 或 a						{							if (temp[4]==0x0d)//TCP数据部分第5位数据为: 0x0d							{								if (temp[5]==0x0a)//TCP数据部分第6位数据为: 0x0a								{									stream_node->req_stream.bflag = t_seq + data_len;									//doLog(0, "数据部分开始号: %u\n", stream_node->req_stream.bflag);									return ACCEPT;								}							}												}										}										}			}			//  \r\n.\r\n 结束标记出现在数据包的开始部分			if (temp[0]==0x0d )//TCP数据部分第1位数据为: 0x0d			{				if (temp[1]==0x0a )//TCP数据部分第2位数据为: 0x0a				{					if (temp[2]==0x2e )//TCP数据部分第3位数据为: 0x2e					{						if (temp[3]==0x0d )//TCP数据部分第4位数据为: 0x0d						{							if (temp[4]==0x0a )//TCP数据部分第5位数据为: 0x0a							{								stream_node->req_stream.eflag = t_seq;								stream_node->req_stream.e_b = 0;								stream_node->mail_len = stream_node->req_stream.eflag - stream_node->req_stream.bflag;								//doLog(0, "发现不带数据的结束包, 数据部分结束号: %u\n", stream_node->req_stream.eflag);								return ACCEPT;							}												}										}										}			}			//  \r\f.\r\f	结束标记出现在数据包的结束部分			if (data_len > 5)			{				if (temp[data_len-5]==0x0d)//TCP数据部分倒数第5位数据为: 0x0d				{					if (temp[data_len-4]==0x0a )//TCP数据部分倒数第4位数据为: 0x0a					{						if (temp[data_len-3]==0x2e )//TCP数据部分倒数第3位数据为: 0x2e						{							if (temp[data_len-2]==0x0d )//TCP数据部分倒数第2位数据为: 0x0d							{								if (temp[data_len-1]==0x0a )//TCP数据部分倒数第1位数据为: 0x0a								{									stream_node->req_stream.eflag = t_seq;									stream_node->req_stream.e_b = 1;									//doLog(0, "发现带数据的结束包, 数据部分结束号: %u\n", stream_node->req_stream.eflag);								}													}											}											}				}			}					if (stream_node->req_stream.bflag > 0)			{				//doLogAsHex(0, "SMTP包: ", temp, data_len);				if (stream_node->req_stream.eflag == 0)				{					//doLog(0, "未结束.\n");					lseek(stream_node->req_stream.fp, t_seq- stream_node->req_stream.bflag, SEEK_SET);					write(stream_node->req_stream.fp, temp, data_len);				}				else if (stream_node->req_stream.eflag > 0)				{					//doLog(0, "已经结束, stream_node->req_stream.eflag = %u \n", stream_node->req_stream.eflag);					if ( t_seq == stream_node->req_stream.bflag && stream_node->req_stream.e_b == 1)//结束标记出现在第一个邮件内容数据包中					{						//doLog(0, "结束标记出现在第一个邮件内容数据包中.\n");						lseek(stream_node->req_stream.fp, 0, SEEK_SET);						write(stream_node->req_stream.fp, temp, data_len-5);						stream_node->mail_len = data_len - 5;					}					else if (t_seq > stream_node->req_stream.bflag && t_seq < stream_node->req_stream.eflag)					{						//doLog(0, "在开始和结束中间的包.\n");						lseek(stream_node->req_stream.fp, t_seq- stream_node->req_stream.bflag, SEEK_SET);						write(stream_node->req_stream.fp, temp, data_len);					}					else if (t_seq > stream_node->req_stream.bflag && t_seq == stream_node->req_stream.eflag)//结束包					{						if (stream_node->req_stream.e_b == 1)//结束标记出现在邮件内容的最后						{							//doLog(0, "结束标记出现在邮件内容的最后.\n");							lseek(stream_node->req_stream.fp, t_seq- stream_node->req_stream.bflag, SEEK_SET);							write(stream_node->req_stream.fp, temp, data_len-5);							stream_node->mail_len = stream_node->req_stream.eflag + data_len - 5 - stream_node->req_stream.bflag;						}					}				}			}		}		else if (stream_node->res_stream.source == ntohs(ptcp->source))		{			stream_node->etime = now;			return ACCEPT;		}		else		{			//doLog(0, "to determine req_stream or res_stream wrong!\n");			return ACCEPT;		}		return ACCEPT;	}	else	{		//doLog(0, "flags wrong!\n");		return ACCEPT;	}	return ACCEPT;	}tcp_stream_node *find_node_by_hash(tcp_stream_node *tcp_stream_head, u_int32_t hash){	tcp_stream_node *cur_node = tcp_stream_head;	for (; cur_node != NULL; cur_node = cur_node->next)	{		if (cur_node->hash == hash)		{			break;		}	}	return cur_node;}

⌨️ 快捷键说明

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