📄 spp_frag2.c
字号:
ft.protocol = p->iph->ip_proto; returned = (FragTracker *) ubi_sptFind(FragRootPtr, (ubi_btItemPtr)&ft); DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "returning %p\n", returned);); return returned;}FragTracker *NewFragTracker(Packet *p){ FragTracker *tmp; F2SPControl sp; /* self preservation control data */ /* set the current frag tracker (none needed here) */ sp.ft = NULL; sp.cur_time = p->pkth->ts.tv_sec; /* self pres funcs need to know what time it is */ /* link the control data to the self pres data struct */ f2data.frag_sp_data.control = &sp; /* allocate space for a frag tracker */ //tmp = Frag2Alloc(NULL, p->pkth->ts.tv_sec, sizeof(FragTracker)); tmp = SPAlloc(sizeof(FragTracker), &(f2data.frag_sp_data)); /* set the frag tracker data fields */ tmp->sip = p->iph->ip_src.s_addr; tmp->dip = p->iph->ip_dst.s_addr; tmp->id = p->iph->ip_id; tmp->protocol = p->iph->ip_proto; tmp->fraglistPtr = &tmp->fraglist; tmp->ttl = p->iph->ip_ttl; /* store the first ttl we got */ /* initialize the fragment list */ (void)ubi_trInitTree(tmp->fraglistPtr, /* ptr to the tree head */ Frag2FragCompare, /* comparison function */ 0); /* dups ok */ /* insert the fragment into the frag list */ if(InsertFrag(p, tmp) != -1) { /* insert the frag tracker into the fragment tree */ if(ubi_sptInsert(FragRootPtr, (ubi_btNodePtr)tmp, (ubi_btNodePtr)tmp, NULL) == FALSE) { LogMessage("NewFragTracker: sptInsert() failed\n"); Frag2DeleteFrag(tmp); return NULL; } } else { f2data.frag_sp_data.mem_usage -= sizeof(FragTracker); free(tmp); return NULL; } pc.frag_trackers++; return tmp;}int InsertFrag(Packet *p, FragTracker *ft){ Frag2Frag *returned; Frag2Frag *newfrag; F2SPControl sp; sfPerf.sfBase.iFragInserts++; if(ft->frag_bytes + p->dsize > 70000) { /* only allow a minimum of overlap in the fragment system */ DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Exiting out because of memusage %d, %d", ft->frag_bytes, p->dsize);); SnortEventqAdd(GENERATOR_SPP_FRAG2, FRAG2_OVERSIZE_FRAG, 1, 0, 5, FRAG2_OVERSIZE_FRAG_STR, 0); DisableDetect(p); ft->alerted = 1; return -1; } /* set the frag flag if this is the first fragment */ if(p->mf && p->frag_offset == 0) { if(ft->frag_flags & FRAG_GOT_FIRST) { if(f2data.frag2_alerts) { SnortEventqAdd(GENERATOR_SPP_FRAG2, FRAG2_DUPFIRST, 1, 0, 5, FRAG2_DUPFIRST_STR, 0); p->packet_flags |= PKT_FRAG_ALERTED; } return -1; } else { ft->frag_flags |= FRAG_GOT_FIRST; } } else if(!p->mf && p->frag_offset > 0) { ft->frag_flags |= FRAG_GOT_LAST; ft->calculated_size = (p->frag_offset << 3) + p->dsize; DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Bytes: %d, Calculated size: %d\n", ft->frag_bytes, ft->calculated_size);); if(ft->calculated_size > 65516) { SnortEventqAdd(GENERATOR_SPP_FRAG2, FRAG2_OVERSIZE_FRAG, 1, 0, 5, FRAG2_OVERSIZE_FRAG_STR, 0); return -1; } } if(!(ft->frag_flags & FRAG_GOT_FIRST)) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "setting out of order!");); ft->frag_flags |= FRAG_OUTOFORDER; } ft->last_frag_time = p->pkth->ts.tv_sec; ft->frag_pkts++; ft->frag_bytes += p->dsize; DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "ft->frag_bytes: %u %u!\n", ft->frag_bytes, f2data.frag_sp_data.mem_usage);); sp.ft = ft; sp.cur_time = p->pkth->ts.tv_sec; f2data.frag_sp_data.control = &sp; //newfrag = (Frag2Frag *) Frag2Alloc(ft, p->pkth->ts.tv_sec, // sizeof(Frag2Frag)); newfrag = (Frag2Frag *) SPAlloc(sizeof(Frag2Frag), &(f2data.frag_sp_data)); //newfrag->data = (u_int8_t *) Frag2Alloc(ft, p->pkth->ts.tv_sec, p->dsize); newfrag->data = (u_int8_t *) SPAlloc(p->dsize, &(f2data.frag_sp_data)); memcpy(newfrag->data, p->data, p->dsize); newfrag->offset = p->frag_offset << 3; newfrag->size = p->dsize; returned = (Frag2Frag *) ubi_sptFind(ft->fraglistPtr, (ubi_btItemPtr)newfrag); if(returned != NULL) { if(f2data.frag2_alerts && !(p->packet_flags & PKT_FRAG_ALERTED)) { SnortEventqAdd(GENERATOR_SPP_FRAG2, FRAG2_OVERLAP, 1, 0, 5, FRAG2_OVERLAP_STR, 0); p->packet_flags |= PKT_FRAG_ALERTED; DisableDetect(p); } /* we favor old data */ f2data.frag_sp_data.mem_usage -= newfrag->size; free(newfrag->data); f2data.frag_sp_data.mem_usage -= sizeof(Frag2Frag); free(newfrag); return 0; } if(ubi_sptInsert(ft->fraglistPtr, (ubi_btNodePtr)newfrag, (ubi_btNodePtr)newfrag, NULL) == ubi_trFALSE) { LogMessage("InsertFrag: sptInsert failed\n"); /* * if there was a problem inserting the fragment into the fraglist * nuke it */ f2data.frag_sp_data.mem_usage -= newfrag->size; free(newfrag->data); f2data.frag_sp_data.mem_usage -= sizeof(Frag2Frag); free(newfrag); return -1; } return 0;}int FragIsComplete(FragTracker *ft, CompletionData *compdata){ compdata->complete = 1; sfPerf.sfBase.iFragCompletes++; if(ft->frag_flags & FRAG_REBUILT) { /* we probably put the frag together wrong. lets atleast tell people that */ DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "my frag is already rebuilt! %d\n", (ft->frag_flags & FRAG_OUTOFORDER));); compdata->outoforder = 1; } if((ft->frag_flags & (FRAG_GOT_FIRST|FRAG_GOT_LAST)) == (FRAG_GOT_FIRST|FRAG_GOT_LAST)) { /* global data for CompletionTraverse */ next_offset = 0; /* traverse the frag tree and see if they're all there.... */ (void)ubi_trTraverse(ft->fraglistPtr, CompletionTraverse, compdata); return compdata->complete; } else { return 0; }}void RebuildFrag(FragTracker *ft, Packet *p){ u_int8_t *rebuild_ptr; sfPerf.sfBase.iFragFlushes++; DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Rebuilding pkt [0x%X:%d 0x%X:%d]\n", p->iph->ip_src.s_addr, p->sp, p->iph->ip_dst.s_addr, p->dp); DebugMessage(DEBUG_FRAG, "Calculated size: %d\n", ft->calculated_size); DebugMessage(DEBUG_FRAG, "Frag Bytes: %d\n", ft->frag_bytes); ); if(ft->calculated_size > 65516) { LogMessage("WARNING: Dumping oversized fragment\n"); ZapFrag(ft); } /* set the timestamps on the rebuild packet from the last packet of the frag */ defrag_pkt->pkth->ts.tv_sec = p->pkth->ts.tv_sec; defrag_pkt->pkth->ts.tv_usec = p->pkth->ts.tv_usec; /* copy the packet data from the last packet of the frag */ SafeMemcpy(defrag_pkt->pkt, p->pkt, ETHERNET_HEADER_LEN + sizeof(IPHdr), defrag_pkt->pkt, defrag_pkt->pkt + DATASIZE); /* set the pointer to the beginning of the transport layer of the rebuilt * packet */ rebuild_ptr = defrag_pkt->pkt + ETHERNET_HEADER_LEN + sizeof(IPHdr); /* reset the ip header pointer */ defrag_pkt->iph = (IPHdr *) (defrag_pkt->pkt + ETHERNET_HEADER_LEN); /* clear the packet fragment fields */ defrag_pkt->iph->ip_off = 0x0000; defrag_pkt->frag_flag = 0; /* walk the fragment list and rebuild the packet */ f2data.stop_traverse = 0; (void)ubi_trTraverse(ft->fraglistPtr, RebuildTraverse, rebuild_ptr); f2data.stop_traverse = 0; /* set the new packet's capture length */ if((ETHERNET_HEADER_LEN + ft->calculated_size + sizeof(IPHdr)) > 65535) { /* don't let other pcap apps die when they process this file * -- yes this opens us up for 14 bytes at the end of the * giant packet. */#ifdef DONT_TRUNCATE defrag_pkt->pkth->caplen = 65535;#else /* DONT_TRUNCATE */ defrag_pkt->pkth->caplen = ETHERNET_HEADER_LEN + ft->calculated_size + sizeof(IPHdr);#endif /* DONT_TRUNCATE */ } else { defrag_pkt->pkth->caplen = ETHERNET_HEADER_LEN + ft->calculated_size + sizeof(IPHdr); } defrag_pkt->pkth->len = defrag_pkt->pkth->caplen; /* set the ip dgm length */ defrag_pkt->iph->ip_len = htons((u_short)(defrag_pkt->pkth->len - ETHERNET_HEADER_LEN)); /* tell the rest of the system that this is a rebuilt fragment */ defrag_pkt->packet_flags = PKT_REBUILT_FRAG; defrag_pkt->frag_flag = 0; defrag_pkt->iph->ip_csum = 0; /* calculate the ip checksum for the packet */ defrag_pkt->iph->ip_csum = in_chksum_ip((u_int16_t *)defrag_pkt->iph, sizeof(IPHdr)); pc.rebuilt_frags++;#ifdef DEBUG ClearDumpBuf(); //PrintNetData(stdout, defrag_pkt->pkt, defrag_pkt->pkth->caplen); ClearDumpBuf();#endif /* process the packet through the detection engine */ DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Processing rebuilt packet:\n");); UpdateIPReassStats(&(sfPerf.sfBase), defrag_pkt->pkth->caplen); ProcessPacket(NULL, defrag_pkt->pkth, defrag_pkt->pkt, NULL); DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Done with rebuilt packet, marking rebuilt...\n");); ft->frag_flags = ft->frag_flags | FRAG_REBUILT; /* dump the packet frags */ /* ZapFrag(ft); Now always done asynchronously because of the problem of detecting a full out frag assault after the fact ( fragroute t4 ) */ }void Frag2DeleteFrag(FragTracker *ft){ if(ft == NULL) { return; } sfPerf.sfBase.iFragDeletes++; (void)ubi_trKillTree(ft->fraglistPtr, KillFrag); f2data.frag_sp_data.mem_usage -= sizeof(FragTracker); free(ft);}int PruneFragCache(FragTracker *cft, u_int32_t time, u_int32_t mustdie){ FragTracker *ft; u_int32_t pruned = 0; if(ubi_trCount(FragRootPtr) == 0) return 0; ft = (FragTracker *) ubi_btFirst((ubi_btNodePtr)FragRootPtr); if(ft == NULL) return 0; if(time) { do { if((ft->frag_flags & FRAG_REBUILT) || ft->last_frag_time + f2data.frag_timeout < time) { FragTracker *savft = ft; sfPerf.sfBase.iFragTimeouts++; ft = (FragTracker *) ubi_btNext((ubi_btNodePtr)ft); if (savft != cft && ubi_trCount(FragRootPtr) > 1) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Pruning stale fragment\n");); ZapFrag(savft); pc.frag_timeout++; pruned++; } } else { if(ft !=NULL && ubi_trCount(FragRootPtr)) { ft = (FragTracker *) ubi_btNext((ubi_btNodePtr)ft); } else { return pruned; } } } while(ft != NULL); return pruned; } else { /* Make sure we don't free the root. */ while(mustdie-- && ubi_trCount(FragRootPtr) > 1) { /* * this code pulls a random leaf node from the frag tree for * deletion, allowing us to unpredicatably zap nodes which are * pretty stale anyway */ ft = (FragTracker *) ubi_btLeafNode((ubi_btNodePtr) FragRootPtr); if(ft != cft) { ZapFrag(ft); pc.frag_incomp++; } } return mustdie; } return 0;}/** * Remove a fragment tracker from the Fragment Tree * * @param ft fragment tracker to whack */void ZapFrag(FragTracker *ft){ FragTracker *killme; if(ft != NULL && FragRootPtr->count != 0) { killme = (FragTracker *) ubi_sptRemove(FragRootPtr, (ubi_btNodePtr) ft); if(killme != NULL) Frag2DeleteFrag(killme); }}void Frag2Restart(int signal, void *foo){ return;}void Frag2CleanExit(int signal, void *foo){ return;}void Frag2InitPkt(){ defrag_pkt->pkth = calloc(sizeof(SnortPktHeader), sizeof(char)); defrag_pkt->pkt = (u_int8_t *) calloc(DATASIZE + SPARC_TWIDDLE, sizeof(char)); /* kludge for alignment */ defrag_pkt->pkt += SPARC_TWIDDLE; if(defrag_pkt->pkth == NULL || defrag_pkt->pkt == NULL) { FatalError("Out of memory on Frag2InitPkt()\n"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -