📄 snort_stream5_tcp.c
字号:
int event, tmp_do_detect, tmp_do_detect_content; PROFILE_VARS; PREPROC_PROFILE_START(s5TcpProcessRebuiltPerfStats); tmp_do_detect = do_detect; tmp_do_detect_content = do_detect_content; event = Preprocess(s5_pkt); do_detect = tmp_do_detect; do_detect_content = tmp_do_detect_content; PREPROC_PROFILE_END(s5TcpProcessRebuiltPerfStats); if(event) { //LogStream(s); } } PREPROC_PROFILE_TMPSTART(s5TcpFlushPerfStats); /* Reset alert tracking after flushing rebuilt packet */ /* Remove the packets & alerts that are beyond the high-end of * those packets flushed */ purge_to_seq(st, st->seglist_base_seq); } while (!(st->flags & TF_MISSING_PKT) && (st->seg_count > 1)); /* Grab the next random flush point */ //UpdateFlushMgr(&st->flush_mgr); /* tell them how many bytes we processed */ PREPROC_PROFILE_END(s5TcpFlushPerfStats); return bytes_processed;}/* * flush the client seglist up to the most recently acked segment */static int FlushStream(StreamTracker *st, Packet *p, u_int8_t *flushbuf, int size){ StreamSegment *ss = NULL; u_int32_t base_seq = st->seglist->seq; u_int32_t bytes_flushed = 0; u_int32_t bytes_queued = st->seg_bytes_logical; u_int32_t last = 0; u_int32_t last_seq = 0; u_int32_t segs = 0; u_int8_t *flushbuf_end; PROFILE_VARS; if(st->seg_count == 0 || st->seglist == NULL || st->seglist_tail == NULL) return -1; /* * since this is going into a pseudopacket the size can't ever be more than * 65495 (MAXPACKET - IP_HDRLEN - TCP_HDRLEN), bail if it is */ if(size > STREAM_MAX_PACKET) return -1; PREPROC_PROFILE_START(s5TcpBuildPacketPerfStats); flushbuf_end = flushbuf + STREAM_MAX_PACKET;#ifdef DEBUG_STREAM5 for(ss = st->seglist; ss; ss = ss->next) { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "seq: 0x%X offset: %d size: %d delta: %d\n", ss->seq, ss->seq-base_seq, ss->size, (ss->seq-base_seq) - last);); last = ss->seq-base_seq; segs++; } /* Uh, need to reset these here */ segs = 0; last = 0;#endif STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "flushing %lu bytes\n", size);); STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "Flushing stream, starting seq %X, r_win_base: %X " "base_seq: %X st->seglist: %p st->seglist->seq: %X\n", base_seq, st->r_win_base, base_seq, st->seglist, st->seglist->seq);); st->flags &= ~TF_MISSING_PKT; st->gap_seq = 0; for(ss = st->seglist; ss && SEQ_LT(ss->seq, st->r_win_base); ss = ss->next) { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "seq: 0x%X offset: %d size: %d\n", ss->seq, ss->seq-base_seq, ss->size);); /* Check for a gap/missing packet */ if (ss->next && (ss->seq + ss->size != ss->next->seq)) { st->flags |= TF_MISSING_PKT; st->gap_seq = ss->next->seq; break; } if(ss->urg_offset) { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "s: %p e: %p dlt: %lu off: %d d: %p sz: %d\n", flushbuf, flushbuf_end, flushbuf_end - flushbuf, ss->seq-base_seq, ss->data, ss->size);); /* * have to hop over the byte pointed to by the urg ptr * * XXX get this checked out by another pair of eyes, works on the * whiteboard... * * XXX fix this to not copy in the URG pointer data. Need * a few PCAPs to test with. Need to track urg_pointer * offsets to adjust true seq to correct value, sans UrgP * data. */ if(!SafeMemcpy(flushbuf+(ss->seq-base_seq), ss->data, ss->urg_offset-1, flushbuf, flushbuf_end)) { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "ERROR writing flushbuf attempting to " "write flushbuf out of range!\n");); } if(SafeMemcpy(flushbuf+(ss->seq-base_seq+(u_int32_t)ss->urg_offset), ss->data+ss->urg_offset+1, ss->size-ss->urg_offset, flushbuf, flushbuf_end)) { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "ERROR writing flushbuf attempting to " "write flushbuf out of range!\n");); } last = ss->size - 1; } else { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "s: %p e: %p dlt: %lu off: %d d: %p sz: %d\n", flushbuf, flushbuf_end, flushbuf_end - flushbuf, ss->seq-base_seq, ss->data, ss->size);); if(!SafeMemcpy(flushbuf+(ss->seq-base_seq), ss->data, ss->size, flushbuf, flushbuf_end)) { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "ERROR writing flushbuf attempting to " "write flushbuf out of range!\n");); } last = ss->size; } last_seq = ss->seq; bytes_flushed += ss->size; ss->buffered = 1; segs++; if(((ss->seq - base_seq) + ss->size) > (u_int32_t)(flushbuf_end - flushbuf)) break; } STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "flushed %d bytes on session (%lu)!\n", bytes_flushed, last_seq - base_seq + last);); STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"););#ifdef DEBUG// PrintHexDump(flushbuf, (last_seq - base_seq) + last, stdout);#endif STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");); bytes_queued -= bytes_flushed; STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "flushed %d bytes on stream, %d still queued, " "%d segs flushed\n", bytes_flushed, bytes_queued, segs);); //return (last_seq - base_seq) + last; PREPROC_PROFILE_END(s5TcpBuildPacketPerfStats); return bytes_flushed;}int Stream5FlushServer(Packet *p, Stream5LWSession *lwssn){ int flushed; TcpSession *tcpssn = NULL; StreamTracker *flushTracker = NULL; if (lwssn->proto_specific_data) tcpssn = (TcpSession *)lwssn->proto_specific_data->data; if (!tcpssn) return 0; flushTracker = &tcpssn->server; flushTracker->flags |= TF_FORCE_FLUSH; /* If this is a rebuilt packet, don't flush now because we'll * overwrite the packet being processed. */ if (p->packet_flags & PKT_REBUILT_STREAM) { /* We'll check & clear the TF_FORCE_FLUSH next time through */ return 0; } /* Need to convert the addresses to network order */ flushed = flush_ackd(tcpssn, flushTracker, p, htonl(tcpssn->server_ip), htonl(tcpssn->client_ip), htons(tcpssn->server_port), htons(tcpssn->client_port), PKT_FROM_SERVER); if (flushed) purge_ackd(flushTracker); flushTracker->flags &= ~TF_FORCE_FLUSH; return flushed;}int Stream5FlushClient(Packet *p, Stream5LWSession *lwssn){ int flushed; TcpSession *tcpssn = NULL; StreamTracker *flushTracker = NULL; if (lwssn->proto_specific_data) tcpssn = (TcpSession *)lwssn->proto_specific_data->data; if (!tcpssn) return 0; flushTracker = &tcpssn->client; flushTracker->flags |= TF_FORCE_FLUSH; /* If this is a rebuilt packet, don't flush now because we'll * overwrite the packet being processed. */ if (p->packet_flags & PKT_REBUILT_STREAM) { /* We'll check & clear the TF_FORCE_FLUSH next time through */ return 0; } /* Need to convert the addresses to network order */ flushed = flush_ackd(tcpssn, flushTracker, p, htonl(tcpssn->client_ip), htonl(tcpssn->server_ip), htons(tcpssn->client_port), htons(tcpssn->server_port), PKT_FROM_CLIENT); if (flushed) purge_ackd(flushTracker); flushTracker->flags &= ~TF_FORCE_FLUSH; return flushed;}int Stream5FlushListener(Packet *p, Stream5LWSession *lwssn){ TcpSession *tcpssn = NULL; StreamTracker *listener = NULL; int dir = 0; int flushed = 0; if (lwssn->proto_specific_data) tcpssn = (TcpSession *)lwssn->proto_specific_data->data; if (!tcpssn) return 0; /* figure out direction of this packet -- we should've already * looked at it, so the packet_flags are already set. */ if(p->packet_flags & PKT_FROM_SERVER) { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "Flushing listener on packet from server\n");); listener = &tcpssn->client; /* dir of flush is the data from the opposite side */ dir = PKT_FROM_SERVER; } else if (p->packet_flags & PKT_FROM_CLIENT) { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "Flushing listener on packet from client\n");); listener = &tcpssn->server; /* dir of flush is the data from the opposite side */ dir = PKT_FROM_CLIENT; } if (dir != 0) { listener->flags |= TF_FORCE_FLUSH; flushed = flush_ackd(tcpssn, listener, p, p->iph->ip_src.s_addr, p->iph->ip_dst.s_addr, p->tcph->th_sport, p->tcph->th_dport, dir); if (flushed) purge_ackd(listener); listener->flags &= ~TF_FORCE_FLUSH; } return flushed;}int Stream5FlushTalker(Packet *p, Stream5LWSession *lwssn){ TcpSession *tcpssn = NULL; StreamTracker *talker = NULL; int dir = 0; int flushed = 0; if (lwssn->proto_specific_data) tcpssn = (TcpSession *)lwssn->proto_specific_data->data; if (!tcpssn) { return 0; } /* figure out direction of this packet -- we should've already * looked at it, so the packet_flags are already set. */ if(p->packet_flags & PKT_FROM_SERVER) { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "Flushing talker on packet from server\n");); talker = &tcpssn->server; /* dir of flush is the data from the opposite side */ dir = PKT_FROM_CLIENT; } else if (p->packet_flags & PKT_FROM_CLIENT) { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "Flushing talker on packet from client\n");); talker = &tcpssn->client; /* dir of flush is the data from the opposite side */ dir = PKT_FROM_SERVER; } if (dir != 0) { talker->flags |= TF_FORCE_FLUSH; flushed = flush_ackd(tcpssn, talker, p, p->iph->ip_dst.s_addr, p->iph->ip_src.s_addr, p->tcph->th_dport, p->tcph->th_sport, dir); if (flushed) purge_ackd(talker); talker->flags &= ~TF_FORCE_FLUSH; } return flushed;}Stream5LWSession *GetLWTcpSession(SessionKey *key){ return GetLWSessionFromKey(tcp_lws_cache, key);}void TcpSessionCleanup(Stream5LWSession *lwssn){ TcpSession *tcpssn = NULL; if (lwssn->proto_specific_data) tcpssn = (TcpSession *)lwssn->proto_specific_data->data; if (!tcpssn) { /* Huh? */ return; } /* Flush ack'd data on both sides as necessary */ { Packet p; int flushed; DecoderFlags decoder_flags; if (!s5_tcp_cleanup) { /* Turn off decoder alerts since we're decoding stored * packets that we already alerted on. */ memcpy(&decoder_flags, &pv.decoder_flags, sizeof(DecoderFlags)); memset(&pv.decoder_flags, 0, sizeof(DecoderFlags)); } /* Flush the client */ if (tcpssn->client.seglist) {#ifdef GRE /* Hack so rebuilt/reinserted packet isn't counted toward GRE total * Right now, this only works if the delivery protocol is IP */ if (((IPHdr *)(tcpssn->client.seglist->pktOrig + E
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -