📄 dealpacket.c
字号:
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 + -