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

📄 spp_frag3.c

📁 著名的入侵检测系统snort的最新版本的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif        /*         * Don't remove the tracker.         * Remove all of the packets that are stored therein.         *         * If the existing tracker times out because of a delay         * relative to the timeout         */        //Frag3RemoveTracker(fkey, ft);        Frag3DeleteTracker(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 - GET_IPH_HLEN(p) * 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->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 = GET_IPH_PROTO(p);    /*     * 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;}/** * Handle IP Options in fragmented packets. * * @param ft Current frag tracker for this packet * @param p Current packet to check for options * @param context In case we get an anomaly * * @return status * @retval 0 on an error * @retval 1 on success */static int Frag3HandleIPOptions(FragTracker *ft,                                Packet *p){    unsigned int i = 0;          /* counter */    if(p->frag_offset == 0)    {        /*         * This is the first packet.  If it has IP options,         * save them off, so we can set them on the reassembled packet.         */        if (p->ip_options_len)        {            ft->ip_options_len = p->ip_options_len;            ft->ip_option_count = p->ip_option_count;            ft->ip_options_data = SnortAlloc(p->ip_options_len);            memcpy(ft->ip_options_data, p->ip_options_data, p->ip_options_len);        }    }    else    {        /* check that options match those from other non-offset 0 packets */        /* XXX: could check each individual option here, but that         * would be performance ugly.  So, we'll just check that the         * option counts match.  Alert if invalid, but still include in         * reassembly.         */        if (ft->copied_ip_option_count)        {            if (ft->copied_ip_option_count != p->ip_option_count)            {                EventAnomIpOpts(ft->context);            }        }        else        {            ft->copied_ip_option_count = p->ip_option_count;            for (i = 0;i< p->ip_option_count && i < IP_OPTMAX; i++)            {                /* Is the high bit set?  If not, weird anomaly. */                if (!(p->ip_options[i].code & 0x80))                    EventAnomIpOpts(ft->context);            }        }    }    return 1;}int FragGetPolicy(Packet *p, Frag3Context *f3context){#ifdef TARGET_BASED    int frag_policy;    /* Not caching this host_entry in the frag tracker so we can     * swap the table out after processing this packet if we need     * to.  */    HostAttributeEntry *host_entry = SFAT_LookupHostEntryByDst(p);    if (host_entry && (isFragPolicySet(host_entry) == POLICY_SET))    {        frag_policy = getFragPolicy(host_entry);        if (frag_policy != SFAT_UNKNOWN_FRAG_POLICY)        {            DEBUG_WRAP(DebugMessage(DEBUG_FRAG,                "FragGetPolicy: Policy Map Entry: %s %s %s %d(%s)\n",                host_entry->hostInfo.vendor.value.s_value,                host_entry->hostInfo.operatingSystem.value.s_value,                host_entry->hostInfo.version.value.s_value,                frag_policy, frag_policy_names[frag_policy]););            return frag_policy;        }    }#endif    DEBUG_WRAP(DebugMessage(DEBUG_FRAG,        "FragGetPolicy: Using configured default %d(%s)\n",        f3context->frag_policy, frag_policy_names[f3context->frag_policy]););    return f3context->frag_policy;}/** * Didn't find a FragTracker in the hash table, create a new one and put it * into the f_cache * * @param p Current packet to fill in FragTracker fields * @param fkey FragKey struct to use for table insertion * * @return status * @retval 0 on an error * @retval 1 on success */static int Frag3NewTracker(Packet *p, FRAGKEY *fkey, Frag3Context *f3context){    FragTracker *tmp;    Frag3Frag *f = NULL;    //int ret = 0;    const u_int8_t *fragStart;    u_int16_t fragLength;    u_int16_t frag_end;    SFXHASH_NODE *hnode;    fragStart = (u_int8_t *)p->iph + GET_IPH_HLEN(p) * 4;    /* 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 - GET_IPH_HLEN(p) * 4;#ifdef DEBUG    if (p->actual_ip_len != ntohs(GET_IPH_LEN(p)))    {        DEBUG_WRAP(DebugMessage(DEBUG_FRAG,               "IP Actual Length (%d) != specified length (%d), "               "truncated packet (%d)?\n",                p->actual_ip_len, ntohs(GET_IPH_LEN(p)), snaplen););    }#endif    /* Just to double check */    if (fragLength > snaplen)    {        DEBUG_WRAP(DebugMessage(DEBUG_FRAG,                    "Overly large fragment %d 0x%x 0x%x %d\n",                    fragLength, GET_IPH_LEN(p), GET_IPH_OFF(p),                    p->frag_offset << 3););        /* Ah, crap.  Return that tracker. */        return 0;    }    /* Get a node from the hash table */    hnode = sfxhash_get_node(f_cache, fkey);    if (!hnode)    {        DEBUG_WRAP(DebugMessage(DEBUG_FRAG,                    "Frag3NewTracker: sfxhash_get_node() failed\n"););        return 0;    }    else    {        if (hnode->data)        {            tmp = hnode->data;            memset(tmp, 0, sizeof(FragTracker));        }        else        {            DEBUG_WRAP(DebugMessage(DEBUG_FRAG,                    "Frag3NewTracker: sfxhash_get_node() failed\n"););            return 0;        }    }    /*      * setup the frag tracker      */    tmp->sip = fkey->sip;    tmp->dip = fkey->dip;    tmp->id = fkey->id;    tmp->protocol = fkey->proto;    tmp->ttl = GET_IPH_TTL(p); /* store the first ttl we got */    tmp->calculated_size = 0;    tmp->alerted = 0;    tmp->frag_flags = 0;    tmp->frag_bytes = 0;    tmp->frag_pkts = 0;    tmp->frag_time.tv_sec = p->pkth->ts.tv_sec;    tmp->frag_time.tv_usec = p->pkth->ts.tv_usec;    tmp->alert_count = 0;    tmp->ip_options_len = 0;    tmp->ip_option_count = 0;    tmp->ip_options_data = NULL;    tmp->copied_ip_options_len = 0;    tmp->copied_ip_option_count = 0;    tmp->context = f3context;    tmp->ordinal = 0;    tmp->frag_policy = FragGetPolicy(p, f3context);    /*      * get our first fragment storage struct      */    if(!global_config.use_prealloc)    {        if(mem_in_use > global_config.memcap)        {            if (Frag3Prune(tmp) == 0)            {                DEBUG_WRAP(DebugMessage(DEBUG_FRAG,                    "Frag3NewTra

⌨️ 快捷键说明

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