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