📄 snort_stream5_tcp.c
字号:
tdb->end_seq, st->r_win_base, tdb->seq, st->r_nxt_ack+Stream5GetWindow(st));); if(SEQ_GEQ(tdb->end_seq, st->r_win_base)) { if(SEQ_LT(tdb->seq, st->r_nxt_ack+Stream5GetWindow(st))) { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "seq is within window!\n");); return 1; } else { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "seq is past the end of the window!\n");); } } else { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "end_seq is before win_base\n");); } return 0;}static INLINE void UpdateSsn(StreamTracker *rcv, StreamTracker *snd, TcpDataBlock *tdb){ if(SEQ_GT(tdb->ack, rcv->l_unackd) && SEQ_GT(tdb->ack, rcv->l_nxt_seq)) rcv->l_unackd = tdb->ack; snd->l_unackd = tdb->seq; snd->l_nxt_seq = tdb->seq + 1; snd->r_win_base = tdb->ack; snd->l_window = tdb->win;}extern unsigned int num_preprocs;static void Stream5InitPacket(){ s5_pkt = (Packet *) SnortAlloc(sizeof(Packet)); s5_pkt->pkth = calloc(sizeof(SnortPktHeader)+ ETHERNET_HEADER_LEN + SPARC_TWIDDLE + IP_MAXPACKET, sizeof(char)); s5_pkt->pkt = ((u_int8_t *)s5_pkt->pkth) + sizeof(SnortPktHeader); s5_pkt->eh = (EtherHdr *)((u_int8_t *)s5_pkt->pkt + SPARC_TWIDDLE); s5_pkt->iph = (IPHdr *)((u_int8_t *)s5_pkt->eh + ETHERNET_HEADER_LEN); s5_pkt->tcph = (TCPHdr *)((u_int8_t *)s5_pkt->iph + IP_HEADER_LEN); s5_pkt->data = (u_int8_t *)s5_pkt->tcph + TCP_HEADER_LEN; /* s5_pkt->data is now pkt + * IPMAX_PACKET - (IP_HEADER_LEN + TCP_HEADER_LEN + ETHERNET_HEADER_LEN) * in size * * This is MAX_STREAM_SIZE */ s5_pkt->eh->ether_type = htons(0x0800); SET_IP_VER(s5_pkt->iph, 0x4); SET_IP_HLEN(s5_pkt->iph, 0x5); s5_pkt->iph->ip_proto = IPPROTO_TCP; s5_pkt->iph->ip_ttl = 0xF0; s5_pkt->iph->ip_len = 0x5; s5_pkt->iph->ip_tos = 0x10; SET_TCP_OFFSET(s5_pkt->tcph,0x5); s5_pkt->tcph->th_flags = TH_PUSH|TH_ACK; s5_pkt->preprocessor_bits = calloc(sizeof(BITOP), 1); boInitBITOP(s5_pkt->preprocessor_bits, num_preprocs + 1);}static INLINE void SetupTcpDataBlock(TcpDataBlock *tdb, Packet *p){ tdb->sip = ntohl(p->iph->ip_src.s_addr); tdb->dip = ntohl(p->iph->ip_dst.s_addr); tdb->seq = ntohl(p->tcph->th_seq); tdb->ack = ntohl(p->tcph->th_ack); tdb->win = ntohs(p->tcph->th_win); tdb->end_seq = tdb->seq + (u_int32_t) p->dsize; if(p->tcph->th_flags & TH_SYN) tdb->end_seq++; if(p->tcph->th_flags & TH_FIN) tdb->end_seq++; return;}static void Stream5DropSegment(StreamSegment *seg){ int dropped = 0; if(seg != NULL) { STREAM5_DEBUG_WRAP( DebugMessage(DEBUG_STREAM_STATE, "Dumping segment at seq %X, size %d, caplen %d\n", seg->seq, seg->size, seg->caplen);); if(seg->pkt != NULL) { s5_mem_in_use -= seg->caplen; dropped += seg->caplen; free(seg->pkt); } s5_mem_in_use -= sizeof(StreamSegment); dropped += sizeof(StreamSegment); free(seg); s5stats.tcp_streamsegs_released++; } STREAM5_DEBUG_WRAP( DebugMessage(DEBUG_STREAM_STATE, "Stream5DropSegment dropped %d bytes\n", dropped););}static void DeleteSeglist(StreamSegment *listhead){ StreamSegment *idx = listhead; StreamSegment *dump_me; int i = 0; STREAM5_DEBUG_WRAP( DebugMessage(DEBUG_STREAM_STATE, "In DeleteSeglist\n");); while(idx) { i++; dump_me = idx; idx = idx->next; Stream5DropSegment(dump_me); } STREAM5_DEBUG_WRAP( DebugMessage(DEBUG_STREAM_STATE, "Dropped %d segments\n", i););}INLINE int purge_alerts(StreamTracker *st, u_int32_t flush_seq){ int i; int new_count = 0; for (i=0;i<st->alert_count;i++) { u_int32_t alert_seq = ntohl(st->alerts[i].seq); if (alert_seq < flush_seq ) { st->alerts[i].sid = 0; st->alerts[i].gid = 0; st->alerts[i].seq = 0; } else { if (new_count != i) { st->alerts[new_count].sid = st->alerts[i].sid; st->alerts[new_count].gid = st->alerts[i].gid; st->alerts[new_count].seq = st->alerts[i].seq; } new_count++; } } st->alert_count = new_count; return new_count;}INLINE int purge_to_seq(StreamTracker *st, u_int32_t flush_seq){ StreamSegment *ss = NULL; StreamSegment *dump_me = NULL; int purged_bytes = 0; if(st->seglist == NULL) { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "setting st->seglist_base_seq to 0x%X\n", flush_seq);); st->seglist_base_seq = flush_seq; return 0; } ss = st->seglist; STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "In purge_to_seq, start seq = 0x%X end seq = 0x%X delta %d\n", ss->seq, flush_seq, flush_seq-ss->seq);); while(ss) { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "s: %X sz: %d\n", ss->seq, ss->size);); dump_me = ss; ss = ss->next; if(SEQ_LT(dump_me->seq, flush_seq)) { purged_bytes += Stream5SeglistDeleteNode(st, dump_me); } else break; } //st->seglist_base_seq = st->r_win_base; STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "setting st->seglist_base_seq to 0x%X\n", flush_seq);); st->seglist_base_seq = flush_seq; STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "st->seglist_base_seq set to 0x%X\n", st->seglist_base_seq);); purge_alerts(st, flush_seq); if (st->seglist == NULL) { st->seglist_tail = NULL; } return purged_bytes;}/* * purge a seglist up the the last ack received */INLINE int purge_ackd(StreamTracker *st){ return purge_to_seq(st, st->r_win_base);}/* * flush a seglist up to the last ack received, generate the pseudopacket * and fire it thru the system */INLINE int flush_ackd(TcpSession *ssn, StreamTracker *st, Packet *p, u_int32_t sip, u_int32_t dip, u_int16_t sp, u_int16_t dp, u_int32_t dir){ u_int32_t base_seq; u_int32_t footprint = 0; u_int16_t ip_len; u_int32_t bytes_processed = 0; int flushed_bytes; PROFILE_VARS; STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "In flush_ackd()\n");); if(st->seg_bytes_logical == 0) { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "bailing, no data\n");); return bytes_processed; } if(st->seglist == NULL || st->seglist_tail == NULL) { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "bailing, bad seglist ptr\n");); return bytes_processed; } if ((st->seg_count == 1) && !(st->flags & TF_FORCE_FLUSH)) { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "only 1 packet in seglist no need to flush\n");); return bytes_processed; } //PrintSeglist(st); PREPROC_PROFILE_START(s5TcpFlushPerfStats); s5_pkt->iph->ip_src.s_addr = sip; s5_pkt->iph->ip_dst.s_addr = dip; s5_pkt->tcph->th_sport = sp; s5_pkt->tcph->th_dport = dp; s5_pkt->sp = htons(sp); s5_pkt->dp = htons(dp); if(p->eh != NULL) { if (p->sp == s5_pkt->sp) { memcpy(s5_pkt->eh->ether_src, p->eh->ether_src, 6); memcpy(s5_pkt->eh->ether_dst, p->eh->ether_dst, 6); } else { memcpy(s5_pkt->eh->ether_src, p->eh->ether_dst, 6); memcpy(s5_pkt->eh->ether_dst, p->eh->ether_src, 6); } } s5_pkt->tcph->th_seq = htonl(st->seglist_base_seq); s5_pkt->tcph->th_ack = htonl(st->l_unackd); s5_pkt->tcph->th_win = htons(st->l_window); do { base_seq = st->seglist_base_seq; footprint = st->r_win_base - base_seq; if(footprint <= 0) { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "Negative footprint, bailing %d (0x%X - 0x%X)\n", footprint, st->r_win_base, base_seq);); PREPROC_PROFILE_END(s5TcpFlushPerfStats); return bytes_processed; } if(footprint < st->seg_bytes_logical) { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "Footprint less than queued bytes, " "win_base: 0x%X base_seq: 0x%X\n", st->r_win_base, base_seq);); } if(footprint > STREAM_MAX_PACKET) { /* this is as much as we can pack into a stream buffer */ footprint = STREAM_MAX_PACKET; } /* setup the pseudopacket payload */ flushed_bytes = FlushStream(st, p, s5_pkt->data, (int) footprint); if(flushed_bytes == -1) { /* couldn't put a stream together for whatever reason * should probably clean the seglist and bail... */ if(st->seglist) { STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "dumping entire seglist!\n");); DeleteSeglist(st->seglist); st->seglist_tail = NULL; } STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "setting st->seglist_base_seq to 0x%X\n", st->r_win_base);); st->seglist_base_seq = st->r_win_base; PREPROC_PROFILE_END(s5TcpFlushPerfStats); return bytes_processed; } if (flushed_bytes == 0) { /* No more ACK'd data... bail */ break; } s5_pkt->dsize = flushed_bytes; s5_pkt->pkth->caplen = footprint + IP_HEADER_LEN + TCP_HEADER_LEN + ETHERNET_HEADER_LEN; s5_pkt->pkth->len = s5_pkt->pkth->caplen; s5_pkt->pkth->ts.tv_sec = st->seglist->pkth.ts.tv_sec; s5_pkt->pkth->ts.tv_usec = st->seglist->pkth.ts.tv_usec; ip_len = (u_int16_t)footprint + IP_HEADER_LEN + TCP_HEADER_LEN; s5_pkt->iph->ip_len = htons(ip_len); sfPerf.sfBase.iStreamFlushes++; bytes_processed += s5_pkt->dsize; s5_pkt->packet_flags = (PKT_REBUILT_STREAM|PKT_STREAM_EST); s5_pkt->packet_flags |= dir; s5_pkt->ssnptr = (void *) ssn->lwSsn; //s5_pkt->streamptr = (void *) st; STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE, "setting st->seglist_base_seq to 0x%X\n", st->r_win_base);); if (st->flags & TF_MISSING_PKT) { st->seglist_base_seq = st->gap_seq; } else { st->seglist_base_seq = st->r_win_base; } if(s5_global_config.flags & STREAM5_CONFIG_SHOW_PACKETS) { //ClearDumpBuf(); printf("+++++++++++++++++++Stream Packet+++++++++++++++++++++\n"); PrintIPPkt(stdout, IPPROTO_TCP, s5_pkt); printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); //ClearDumpBuf(); } s5stats.tcp_rebuilt_packets++; PREPROC_PROFILE_TMPEND(s5TcpFlushPerfStats); {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -