📄 spp_frag3.c
字号:
if(isdigit((int)toks[i+1][0])) { context->min_ttl = atoi(toks[i+1]); increment = 2; } else { LogMessage("WARNING %s(%d) => Bad Min TTL " "size, setting to default (%d\n", file_name, file_line, FRAG3_MIN_TTL); context->min_ttl = FRAG3_MIN_TTL; } } else if(!strcasecmp(index, "detect_anomalies")) { context->frag3_alerts |= FRAG3_DETECT_ANOMALIES; } else if(!strcasecmp(index, "policy")) { if (i+1 >= num_toks) FatalError("%s(%d) => policy requires a policy " "identifier argument\n", file_name, file_line); context->frag_policy = FragPolicyIdFromName(toks[i+1]); if ((context->frag_policy == FRAG_POLICY_DEFAULT) && (strcasecmp(toks[i+1], "bsd"))) { FatalError("%s(%d) => Bad policy name \"%s\"\n", file_name, file_line, toks[i+1]); } increment = 2; } else if(!strcasecmp(index, "bind_to")) { if (i+1 < num_toks) { context->bound_addrs = IpAddrSetParse(toks[i+1]); increment = 2; } else { FatalError("%s(%d) => bind_to requires an IP list or " "CIDR block argument\n", file_name, file_line); } } else { FatalError("%s(%d) => Invalid Frag3 engine option (%s)\n", file_name, file_line, index); } i += increment; } mSplitFree(&toks, num_toks); if(context->bound_addrs == NULL) { /* allocate and initializes the IpAddrSet at the same time * set to "any" */ context->bound_addrs = (IpAddrSet *) SnortAlloc(sizeof(IpAddrSet)); } } return;}/** * Main runtime entry point for Frag3 * * @param p Current packet to process. * @param context Context for this defrag engine * * @return none */void Frag3Defrag(Packet *p, void *context){ FRAGKEY fkey; /* fragkey for this packet */ FragTracker *ft; /* FragTracker to process the packet on */ Frag3Context *f3context = NULL; /* engine context */ int engineIndex; int insert_return = 0; /* return value from the insert function */ PROFILE_VARS; /* * check to make sure this preprocessor should run */ if( (p == NULL) || !IPH_IS_VALID(p) || !p->frag_flag || (p->csum_flags & CSE_IP) || (p->packet_flags & PKT_REBUILT_FRAG) || /* XXX IPv6 fragmentation not yet supported */ IS_IP6(p)) { return; } /* Find an engine context for this packet */ for (engineIndex = 0; engineIndex < numFrag3Contexts; engineIndex++) { f3context = frag3ContextList[engineIndex]; /* * Does this engine context handle fragments to this IP address? */ if(IpAddrSetContains(f3context->bound_addrs, GET_DST_ADDR(p))) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "[FRAG3] Found engine context in IpAddrSet\n");); break; } else { f3context = NULL; } } if (!f3context) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "[FRAG3] Could not find Frag3 engine context " "for IP %s\n", inet_ntoa(GET_SRC_ADDR(p)));); return; } /* Ugly HACK -- if frag offset is 0 & UDP, let that packet go * through the rest of the system. This results in the * first packet going through detection. If we do see * the rest of the frags, the contents of that first frag * will go through again with the defrag'd (built) packet. */ if ((p->frag_offset != 0) || (GET_IPH_PROTO(p) != IPPROTO_UDP)) { /* * This packet is fragmented, will either be dropped * or payload included in a rebuilt packet later. Don't * process it further. */ DisableDetect(p); SetPreprocBit(p, PP_SFPORTSCAN); SetPreprocBit(p, PP_PERFMONITOR); otn_tmp = NULL; }#if 0 /* * fragments with IP options are bad, m'kay? */ if(p->ip_options_len) { EventAnomIpOpts(f3context); f3stats.discards++; return; }#endif /* * pkt's not going to make it to the target, bail */ if(GET_IPH_TTL(p) < f3context->min_ttl) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "[FRAG3] Fragment discarded due to low TTL " "[0x%X->0x%X], TTL: %d " "Offset: %d Length: %d\n", ntohl(p->iph->ip_src.s_addr), ntohl(p->iph->ip_dst.s_addr), GET_IPH_TTL(p), p->frag_offset, p->dsize);); f3stats.discards++; return; } f3stats.total++; UpdateIPFragStats(&(sfPerf.sfBase), p->pkth->caplen); PREPROC_PROFILE_START(frag3PerfStats); DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "\n++++++++++++++++++++++++++++++++++++++++++++++\n");); DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "[**] [FRAG3] Inspecting fragment...\n");); DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "[FRAG3] Got frag packet (mem use: %ld frag " "trackers: %d p->pkt_flags: 0x%X " "prealloc nodes in use: %lu/%lu)\n", mem_in_use, sfxhash_count(f_cache), p->packet_flags, prealloc_nodes_in_use, global_config.static_frags);); /* zero the frag key */ memset(&fkey, 0, sizeof(FRAGKEY));#if 0 /* * Check the memcap and clear some space if we're over the memcap */ if(mem_in_use > global_config.memcap) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "memcap exceeded (%ld bytes in use), " "calling Frag3Prune()\n", mem_in_use);); Frag3Prune(); }#endif pkttime = (struct timeval *) &p->pkth->ts; /* * try to get the tracker that this frag should go with */ if((ft = Frag3GetTracker(p, &fkey)) == NULL) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Adding New FragTracker...\n");); /* * first frag for this packet, start a new tracker */ Frag3NewTracker(p, &fkey, f3context); DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "[FRAG3] mem use: %ld frag " "trackers: %d prealloc " "nodes in use: %lu/%lu\n", mem_in_use, sfxhash_count(f_cache), prealloc_nodes_in_use, global_config.static_frags);); /* * all done, return control to Snort */ PREPROC_PROFILE_END(frag3PerfStats); return; } DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Found frag tracker\n");); /* * insert the fragment into the FragTracker */ if((insert_return = Frag3Insert(p, ft, &fkey, f3context)) != FRAG_INSERT_OK) { /* * we can pad this switch out for a variety of entertaining behaviors * later if we're so inclined */ switch(insert_return) { case FRAG_INSERT_FAILED:#ifdef DEBUG if(!pv.quiet_flag) { LogMessage("WARNING: Insert into Fraglist failed, " "(offset: %u)\n", p->frag_offset); }#endif PREPROC_PROFILE_END(frag3PerfStats); return; case FRAG_INSERT_TTL: DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "[FRAG3] Fragment discarded due to large TTL Delta " "[0x%X->0x%X], TTL: %d orig TTL: %d " "Offset: %d Length: %d\n", ntohl(p->iph->ip_src.s_addr), ntohl(p->iph->ip_dst.s_addr), GET_IPH_TTL(p), ft->ttl, p->frag_offset, p->dsize);); f3stats.discards++; PREPROC_PROFILE_END(frag3PerfStats); return; case FRAG_INSERT_ATTACK: case FRAG_INSERT_ANOMALY: f3stats.discards++; PREPROC_PROFILE_END(frag3PerfStats); return; case FRAG_INSERT_TIMEOUT:#ifdef DEBUG if(!pv.quiet_flag) { LogMessage("WARNING: Insert into Fraglist failed due to timeout, " "(offset: %u)\n", p->frag_offset); }#endif PREPROC_PROFILE_END(frag3PerfStats); return; default: break; } } p->fragtracker = (void *)ft; /* * check to see if it's reassembly time */ if(Frag3IsComplete(ft)) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "[*] Fragment is complete, rebuilding!\n");); /* * if the frag completes but it's bad we're just going to drop it * instead of wasting time on putting it back together */ if(!(ft->frag_flags & FRAG_BAD)) { Frag3Rebuild(ft, p); if (p->frag_offset != 0 || (GET_IPH_PROTO(p) != IPPROTO_UDP && ft->frag_flags & FRAG_REBUILT)) { /* Need to reset some things here because the * rebuilt packet will have reset the do_detect * flag when it hits Preprocess. */ do_detect_content = do_detect = 0; otn_tmp = NULL; /* And unset the frag tracker for this packet since * we're going to blow it away in a few usecs... */ p->fragtracker = NULL; } } Frag3RemoveTracker(&fkey, ft); } DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "[FRAG3] Dumped fragtracker (mem use: %ld frag " "trackers: %d prealloc " "nodes in use: %lu/%lu)\n", mem_in_use, sfxhash_count(f_cache), prealloc_nodes_in_use, global_config.static_frags);); PREPROC_PROFILE_END(frag3PerfStats); return;}/** * Check to see if a FragTracker has timed out * * @param current_time Time at this moment * @param start_time Time to compare current_time to * @param f3context Engine context * * @return status * @retval FRAG_TIMEOUT Current time diff is greater than the current * context's timeout value * @retval FRAG_TIME_OK Current time diff is within the context's prune * window */static INLINE int CheckTimeout(struct timeval *current_time, struct timeval *start_time, Frag3Context *f3context){ struct timeval tv_diff; /* storage struct for the difference between current_time and start_time */ TIMERSUB(current_time, start_time, &tv_diff); if(tv_diff.tv_sec >= f3context->frag_timeout) { return FRAG_TIMEOUT; } return FRAG_TIME_OK;}/** * Time-related expiration of fragments from the system. Checks the current * FragTracker for timeout, then walks up the LRU list looking to see if * anyone should have timed out. * * @param p Current packet (contains pointer to the current timestamp) * @param ft FragTracker to check for a timeout * @param fkey FragKey of the current FragTracker for sfxhash lookup * @param f3context Context of the defrag engine, contains the timeout value * * @return status * @retval FRAG_TRACKER_TIMEOUT The current FragTracker has timed out * @retval FRAG_OK The current FragTracker has not timed out */static int Frag3Expire( Packet *p, FragTracker *ft, FRAGKEY *fkey, Frag3Context *f3context){#if 0 struct timeval *fttime; /* FragTracker timestamp */ struct timeval *pkttime; /* packet timestamp */ FragTracker *tmpft; /* temp pointer for moving thru the LRU queue */#endif /* * Check the FragTracker that was passed in first */ if(CheckTimeout( pkttime, &(ft)->frag_time, f3context) == FRAG_TIMEOUT) { /* * Oops, we've timed out, whack the FragTracker */#ifdef DEBUG_FRAG3 if (DEBUG_FRAG & GetDebugLevel()) LogMessage("(spp_frag3) Current Fragment dropped due to timeout! " "[0x%08X->0x%08X ID: %d]\n", ft->sip, ft->dip, ft->id);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -