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

📄 dealpacket.c

📁 Linux环境下mail监控程序的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		stream_node->pop3_state = POP3_UNKNOW;		stream_node->mail_list = NULL;		stream_node->next = NULL;		pthread_mutex_lock(&pop3_mutex);		stream_node->next = tcp_stream_head;		tcp_stream_head = stream_node;			//加锁???????????????		pthread_mutex_unlock(&pop3_mutex);		//doLog(0, "create a new pop3 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 = 0;		u_int32_t t_ack=0;		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;		}		temp = (char *)pip+head_len;		stream_node->etime = now;		if (stream_node->req_stream.source == ntohs(ptcp->source))//发往邮件服务器的数据		{								if (stream_node->link_state < POP3_LINKED)//未连接				return ACCEPT;			t_ack = ntohl(ptcp->ack_seq)-stream_node->ack_beg;			if ( strlen(temp)>7 )			{				if (temp[0]==0x52 || temp[0]==0x72)//TCP数据部分第1位数据为: R 或 r				{					if (temp[1]==0x45 || temp[1]==0x65)//TCP数据部分第2位数据为: E 或 e					{						if (temp[2]==0x54 || temp[2]==0x74)//TCP数据部分第3位数据为: T 或 t						{							if (temp[3]==0x52 || temp[3]==0x72)//TCP数据部分第4位数据为: R 或 r							{								if (temp[4]==0x20)//TCP数据部分第5位数据为: ' '空格								{									temp_mail = NULL;									//doLog(0, "len : %u\n", len);									//doLog(0, "find a new cmd : %s\n", temp);									get_id(temp, &temp_id);									//doLog(0, "find a cmd : RETR %u.\n", temp_id);									//检查该RETR命令是否为重发的命令									temp_mail = stream_node->mail_list;									while (temp_mail!=NULL)									{										//doLog(0, "id : %u, b_flag= %u, e_flag= %u\n", temp_mail->id, temp_mail->b_flag, temp_mail->e_flag);										if (temp_mail->id == temp_id )										{											stream_node->pop3_state = POP3_RETR;											return ACCEPT;										}										temp_mail = temp_mail->next;									}																		//该命令为一个新RETR命令									temp_mail = (pop3_mail *)malloc(sizeof(pop3_mail));																		memset(temp_mail, 0, sizeof(pop3_mail));																		temp_mail->id = temp_id;									temp_mail->mail_len = 0;									temp_mail->to = NULL;									temp_mail->cc = NULL;									temp_mail->ok_flag = t_ack;									temp_mail->b_flag = 0;									temp_mail->e_flag = 0;									temp_mail->next=NULL;																		temp_mail->fp_open = 0;									memset(temp_mail->path, 0, PATH_MAXLEN);									sprintf(temp_mail->path, "%s\%u_%ld_%u.eml", TEMP_PATH, hash, stream_node->stime, temp_mail->id);																		//doLog(0, "create a new wfile .\n");									//doLog(0, "path : %s\n", temp_mail->path);									temp_mail->fp = open(temp_mail->path, O_WRONLY | O_CREAT);																		if (temp_mail->fp < 0 )									{										free(temp_mail);										return ACCEPT;									}									temp_mail->fp_open = 1;																		//关闭由前一个RETR命令打开的文件									if (stream_node->mail_list!=NULL)									{										if (stream_node->mail_list->fp_open==1)										{											close(stream_node->mail_list->fp);											stream_node->mail_list->fp_open = 0;										}									}																		stream_node->pop3_state = POP3_RETR;									temp_mail->next = stream_node->mail_list;									stream_node->mail_list = temp_mail;									temp_mail = NULL;									//doLog(0, "wfile create over.\n");									return ACCEPT;								}							}						}					}				}			}									stream_node->pop3_state = POP3_UNKNOW;			return ACCEPT;		}		else if (stream_node->res_stream.source == ntohs(ptcp->source))//从邮件服务器的接收到数据		{			if (stream_node->link_state < POP3_LINKED)//未连接				return ACCEPT;						if (stream_node->pop3_state == POP3_UNKNOW)//未知状态				return ACCEPT;			t_seq = ntohl(ptcp->seq)-stream_node->ack_beg;			if (stream_node->pop3_state == POP3_RETR)//RETR状态			{				temp_mail = NULL;				temp_mail = stream_node->mail_list;								if (t_seq <  temp_mail->ok_flag)					return ACCEPT;								if (data_len < 3)					return ACCEPT;				//doLog(0, "t_seq = %u, ok_flag = %u\n", t_seq, temp_mail->ok_flag);				if (t_seq ==  temp_mail->ok_flag)				{					//doLog(0, "t_seq ==  temp_mail->ok_flag\n");					if (temp[0]==0x2b)//'+'					{						if (temp[1]==0x4f || temp[1]==0x6f)// 'O'或'o' 						{							if (temp[2]==0x4b || temp[2]==0x6b)//'K'或'k'							{								temp_mail->b_flag = t_seq + data_len;								//doLog(0,"RETR : +OK\n");								return ACCEPT;							}						}					}					else if (temp[0]==0x2d)//'-'					{						if (temp[1]==0x45 || temp[1]==0x65)// 'E'或'e' 						{							if (temp[2]==0x4b || temp[2]==0x6b)//'R'或'r'							{								if (temp[3]==0x4b || temp[3]==0x6b)//'R'或'r'								{									stream_node->mail_list = stream_node->mail_list->next;									free(temp_mail);									temp_mail = NULL;																stream_node->pop3_state = POP3_UNKNOW;									//doLog(0,"RETR : -ERR\n");									return ACCEPT;								}							}						}					}				}								if (t_seq <  temp_mail->b_flag)					return ACCEPT;				if (t_seq ==  temp_mail->b_flag)//第1个邮件内容数据包				{					if (data_len>=5)					{						if (temp[data_len-5] == 0x0d)//TCP数据部分的最后第5位						{							if (temp[data_len-4] == 0x0a)//TCP数据部分的最后第4位							{								if (temp[data_len-3] == 0x2e)//TCP数据部分的最后第3位								{									if (temp[data_len-2] == 0x0d)//TCP数据部分的最后第2位	'.'									{													if (temp[data_len-1] == 0x0a)//TCP数据部分的最后1位										{											lseek(temp_mail->fp, t_seq- temp_mail->b_flag, SEEK_SET);											write(temp_mail->fp, temp, data_len-3);											temp_mail->fp_open = 0;											close(temp_mail->fp);											temp_mail->e_flag = t_seq + data_len -3;											stream_node->pop3_state = POP3_UNKNOW;//该邮件已经接收完,将状态改为POP3_UNKNOW;											//doLog(0,"在第一个包中发现结束标记, b_flag=%u, e_flag=%u\n", temp_mail->b_flag, temp_mail->e_flag);											return ACCEPT;										}									}								}							}						}					}					lseek(temp_mail->fp, t_seq- temp_mail->b_flag, SEEK_SET);					write(temp_mail->fp, temp, data_len);					return ACCEPT;				}				else//后续邮件内容数据包				{					if (temp_mail->e_flag == 0)//还没发现结束包					{						if (temp[0]==0x2e && temp[1]==0x0d && temp[2]==0x0a)//结束包						{							temp_mail->e_flag = t_seq;							//doLog(0,"在数据包开头发现结束标记, b_flag= %u, e_flag= %u\n", temp_mail->b_flag, temp_mail->e_flag);							return ACCEPT;						}											//只有以0x2e 0x0d 0x0a开头的TCP数据包才表示该邮件已结束						if (temp[0]==0x2e)//TCP数据包的第1位为'.'						{							if (temp[1]!=0x0d || temp[2]!=0x0a)//TCP数据包的第2位不为0x0d或第3位不为0x0a							{								//doLog(0,"在数据包开头发现填充符\n");								data_len = data_len - 1;								temp = temp + 1;//去除填充字符'.'							}						}												if (data_len>=5)						{							//包含了数据的结束包							if (temp[data_len-5] == 0x0d)//TCP数据部分的最后第5位							{								if (temp[data_len-4] == 0x0a)//TCP数据部分的最后第4位								{									if (temp[data_len-3] == 0x2e)//TCP数据部分的最后第3位									{										if (temp[data_len-2] == 0x0d)//TCP数据部分的最后第2位	'.'										{														if (temp[data_len-1] == 0x0a)//TCP数据部分的最后1位											{												lseek(temp_mail->fp, t_seq- temp_mail->b_flag, SEEK_SET);												write(temp_mail->fp, temp, data_len-3);												temp_mail->e_flag = t_seq + data_len -3;												//doLog(0,"在数据包最后发现5个字符的结束标记, b_flag= %u, e_flag= %u\n", temp_mail->b_flag, temp_mail->e_flag);												return ACCEPT;											}										}									}								}							}						}						lseek(temp_mail->fp, t_seq- temp_mail->b_flag, SEEK_SET);						write(temp_mail->fp, temp, data_len);						return ACCEPT;					}					else//已经发现了结束包					{						//doLog(0,"已经结束,该包为重复包或迟来的包\n");						if (t_seq >= temp_mail->b_flag && t_seq < temp_mail->e_flag)						{							if (temp[0]==0x2e && temp[1]==0x0d && temp[2]==0x0a)//结束包							{								//doLog(0,"在数据包开头发现结束标记, b_flag= %u, e_flag= %u\n", temp_mail->b_flag, temp_mail->e_flag);								return ACCEPT;							}														//只有以0x2e 0x0d 0x0a开头的TCP数据包才表示该邮件已结束							if (temp[0]==0x2e)//TCP数据包的第1位为'.'							{								if (temp[1]!=0x0d || temp[2]!=0x0a)//TCP数据包的第2位不为0x0d或第3位不为0x0a								{									data_len = data_len - 1;									temp = temp + 1;//去除填充字符'.'								}							}							if (data_len>=5)							{								//包含了数据的结束包								if (temp[data_len-5] == 0x0d)//TCP数据部分的最后第5位								{									if (temp[data_len-4] == 0x0a)//TCP数据部分的最后第4位									{										if (temp[data_len-3] == 0x2e)//TCP数据部分的最后第3位										{											if (temp[data_len-2] == 0x0d)//TCP数据部分的最后第2位	'.'											{															if (temp[data_len-1] == 0x0a)//TCP数据部分的最后1位												{													lseek(temp_mail->fp, t_seq- temp_mail->b_flag, SEEK_SET);													write(temp_mail->fp, temp, data_len-3);													return ACCEPT;												}											}										}									}								}							}							lseek(temp_mail->fp, t_seq- temp_mail->b_flag, SEEK_SET);							write(temp_mail->fp, temp, data_len);							return ACCEPT;						}						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 + -