⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spp_frag3.c

📁 Linux snort-2.4.4源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
                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         */        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:                if(!pv.quiet_flag)                {                    LogMessage("WARNING: Insert into Fraglist failed, "                            "(offset: %u)\n", p->frag_offset);                }                return;            case FRAG_INSERT_TTL:                LogMessage(                        "[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),                         p->iph->ip_ttl, ft->ttl, p->frag_offset,                         p->dsize);                f3stats.discards++;                return;            case FRAG_INSERT_ATTACK:            case FRAG_INSERT_ANOMALY:                f3stats.discards++;                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                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) || (p->iph->ip_proto != IPPROTO_UDP))            {                /* Need to reset some things here because the                 * rebuilt packet will have reset the do_detect                 * flag when it hits Preprocess.                 */                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););    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);#endif        Frag3RemoveTracker(fkey, ft);        f3stats.timeouts++;        sfPerf.sfBase.iFragTimeouts++;        return FRAG_TRACKER_TIMEOUT;    }#if 0    /*     * This doesn't really need to be done here!!!     * We'll blow them away when we prune for memory reasons.     */    /*      * The current FragTracker hasn't timed out, check the LRU FragTrackers to     * see if any of them need to go.     */    if((tmpft = (FragTracker*)sfxhash_lru(f_cache)))    {        fttime = &tmpft->frag_time;        pkttime = (struct timeval *) &p->pkth->ts;        while(tmpft && CheckTimeout(pkttime,fttime,f3context)==FRAG_TIMEOUT)        {            LogMessage("(spp_frag3) Fragment dropped due to timeout! "                    "[0x%08X->0x%08X ID: %d]\n", tmpft->sip, tmpft->dip,                     tmpft->id);            sfxhash_free_node(f_cache, sfxhash_lru_node(f_cache));            f3stats.timeouts++;            sfPerf.sfBase.iFragTimeouts++;            if((tmpft = (FragTracker*)(sfxhash_lru(f_cache))))            {                fttime = &tmpft->frag_time;            }        }    }#endif    /*     * set the current FragTracker's timeout on our way out the door...     */    /* XXX Uh, I shouldn't be doing this should I???? */    //ft->frag_time.tv_sec = p->pkth->ts.tv_sec;    //ft->frag_time.tv_usec = p->pkth->ts.tv_usec;    return FRAG_OK;}/** * Check to see if we've got the first or last fragment on a FragTracker and * set the appropriate frag_flags * * @param p Packet to get the info from * @param ft FragTracker to set the flags on  * * @return none */static int INLINE Frag3CheckFirstLast(Packet *p, FragTracker *ft){    u_int16_t fragLength;    int retVal = FRAG_FIRSTLAST_OK;    u_int16_t endOfThisFrag;    /* set the frag flag if this is the first fragment */    if(p->mf && p->frag_offset == 0)    {        ft->frag_flags |= FRAG_GOT_FIRST;        DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Got first frag\n"););    }    else if((!p->mf) && (p->frag_offset > 0)) /* set for last frag too */    {        /* Use the actual length here, because packet may have been        * truncated.  Don't want to try to copy more than we actually        * captured. */        fragLength = p->actual_ip_len - IP_HLEN(p->iph) * 4;        endOfThisFrag = (p->frag_offset << 3) + fragLength;        if (ft->frag_flags & FRAG_GOT_LAST)        {            DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Got last frag again!\n"););            switch (ft->context->frag_policy)            {                case FRAG_POLICY_BSD:                case FRAG_POLICY_LINUX:                case FRAG_POLICY_BSD_RIGHT:                case FRAG_POLICY_LAST:                case FRAG_POLICY_WINDOWS:                case FRAG_POLICY_FIRST:                    if (ft->calculated_size > endOfThisFrag)                    {                       /* Already have a 'last frag' with a higher                        * end point.  Leave it as is.                        *                        * Some OS's do not respond at all -- we'll                        * still try to rebuild anyway in that case,                        * because there is really something wrong                        * and we should look at it.                        */                        retVal = FRAG_LAST_DUPLICATE;                    }                    break;                case FRAG_POLICY_SOLARIS:                    if (ft->calculated_size > endOfThisFrag)                    {                       /* Already have a 'last frag' with a higher                        * end point.  Leave it as is.                        *                        * Some OS's do not respond at all -- we'll                        * still try to rebuild anyway in that case,                        * because there is really something wrong                        * and we should look at it.                        */                        retVal = FRAG_LAST_DUPLICATE;                    }                    else                    {                        /* Solaris does some weird stuff here... */                        /* Usually, Solaris takes the higher end point.                         * But in one strange case (when it hasn't seen                         * any frags beyond the existing last frag), it                         * actually appends that new last frag to the                         * end of the previous last frag, regardless of                         * the offset.  Effectively, it adjusts the                         * offset of the new last frag to immediately                         * after the existing last frag.                         */                        /* XXX: how to handle that case? punt?  */                        retVal = FRAG_LAST_OFFSET_ADJUST;                    }                    break;            }        }        ft->frag_flags |= FRAG_GOT_LAST;        /*         * If this is the last frag (and we don't have a frag that already         * extends beyond this one), set the size that we're expecting.         */        if ((ft->calculated_size < endOfThisFrag) &&            (retVal != FRAG_LAST_OFFSET_ADJUST))        {            ft->calculated_size = endOfThisFrag;            DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Got last frag, Bytes: %d, "                    "Calculated size: %d\n",                    ft->frag_bytes,                    ft->calculated_size););        }    }    DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Frag Status: %s:%s\n",                 ft->frag_flags&FRAG_GOT_FIRST?"FIRST":"No FIRST",                 ft->frag_flags&FRAG_GOT_LAST?"LAST":"No LAST"););    return retVal; }/** * Lookup a FragTracker in the f_cache sfxhash table based on an input key * * @param p The current packet to get the key info from * @param fkey Pointer to a container for the FragKey * * @return Pointer to the FragTracker in the hash bucket or NULL if there is  *         no fragment in the hash bucket */static FragTracker *Frag3GetTracker(Packet *p, FRAGKEY *fkey){    FragTracker *returned; /* FragTracker ptr returned by the lookup */    /*      * we have to setup the key first, downstream functions depend on     * it being setup here     */    fkey->sip = p->iph->ip_src.s_addr;    fkey->dip = p->iph->ip_dst.s_addr;    fkey->id = p->iph->ip_id;    fkey->proto = p->iph->ip_proto;    /*     * if the hash table is empty we're done     */    if(sfxhash_count(f_cache) == 0)        return NULL;    DEBUG_WRAP(DebugMessage(DEBUG_FRAG,                 "[*] Looking up FragTracker using key:\n"););#ifdef DEBUG_FRAG3    PrintFragKey(fkey);#endif    returned = (FragTracker *) sfxhash_find(f_cache, fkey);    DEBUG_WRAP(DebugMessage(DEBUG_FRAG,                 "Frag3GetTracker returning %p for\n", returned););    return returned;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -