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

📄 flow_cache.c

📁 入侵检测SNORT.最近更新的基于网络检测的IDS.希望能给大家带来方便.
💻 C
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************** * * Copyright (C) 2003-2008 Sourcefire, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as * published by the Free Software Foundation.  You may not use, modify or * distribute this program under any other version of the GNU General * Public License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ****************************************************************************/ /** * @file   flow_cache.c * @author Chris Green <cmg@sourcefire.com> * @date   Fri Jun 20 09:04:51 2003 *  * @brief  where flows are stored *  * The FlowCache is a memory-capped storage area for the FLOW * datatype.  It is inspired by spp_conversation, ipaudit, stream4 and * frag2.  * * * Each FLOW is uniquely identified by the 5-tuple (ipproto,sip,dip,sport,dport) * * Currently we only support IPV4 but new protocols will only require * the addition of additional protocol specific hash tables.  Ideally, * the API will stay the same and just do a switch on the key type to * support the various address families. * * This is meant to centralize the state management routines so that * it's easy to just worry about higher level protocols in other * modules. * * This is built on top of sfxhash currently and relies on it for * memory management. flow_hash.c contains the hashing keys  *  */#define FLOW_PERF_FIX#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include "flow_cache.h"#include "flow_callback.h"#include "flow_hash.h"#include "bitop_funcs.h"#include "sf_types.h"/* helper functions */static int flowcache_anrfree( void *key, void *data);static int flowcache_usrfree( void *key, void *data);/* minor optimization functions */static INLINE int flowcache_mru(FLOWCACHE *flowcachep, FLOW **flowpp);static INLINE int flowcache_lru(FLOWCACHE *flowcachep, FLOW **flowpp);/* statistics functions */static INLINE int FCS_find(FLOWCACHE *flowcachecp, FLOWKEY *keyp);static INLINE int FCS_revfind(FLOWCACHE *flowcachecp, FLOWKEY *keyp);static INLINE int FCS_new(FLOWCACHE *flowcachecp, FLOWKEY *keyp);static INLINE int FCS_find_success(FLOWCACHE *flowcachecp, FLOWKEY *keyp);static INLINE int FCS_find_fail(FLOWCACHE *flowcachecp, FLOWKEY *keyp);int flowcache_init(FLOWCACHE *flowcachep, unsigned int rows,                   int memcap, int datasize, FLOWHASHID hashid){    int ret;    int real_datasize = 0;        if(!flowcachep)    {        return FLOW_ENULL;    }    if(datasize < 0)    {        return FLOW_ENULL;    }    if(memcap <= (int)(datasize + sizeof(FLOW) + sizeof(SFXHASH_NODE)))    {        /* come on man, you gotta give me enough memory to store 1. */        return FLOW_EINVALID;    }    if(rows < 1)        return FLOW_EINVALID;    /* zero out the struct for all the additional data strctures */    memset(flowcachep, 0, sizeof(FLOWCACHE));    /*    **  If we have a datasize, then we need to decrement by 1 because    **  the FLOWDATA already has one byte.    */    if(datasize)    {        real_datasize = datasize - 1;    }    /*    **  datasize-1 because there is already 1 byte in the FLOWDATA    **  structure.    */    flowcachep->ipv4_table =        sfxhash_new(rows,                         /* # of nodes in HT*/                    sizeof(FLOWKEY),              /* size of the key  */                    sizeof(FLOW) + real_datasize, /* data size */                    memcap,                       /* max memory */                    1,                            /* auto recover nodes */                    flowcache_anrfree,            /* autorecovery function */                    flowcache_usrfree,            /* data free function*/                    1);                           /* recycle old nodes */    if(flowcachep->ipv4_table == NULL)    {        return FLOW_ENOMEM;    }    /* set our hash function to something that understands ipv4 flowkeys */    switch(hashid)    {    case HASH1:        ret = sfxhash_set_keyops(flowcachep->ipv4_table,                                 flowkey_hashfcn1,                                 flowkeycmp_fcn);        break;    case HASH2:        ret = sfxhash_set_keyops(flowcachep->ipv4_table,                                 flowkey_hashfcn2,                                 flowkeycmp_fcn);        break;    default:        ret = FLOW_EINVALID;    }    /* if setting the hash function or setting the comparison function fails,       abort */    if(ret != 0)    {        sfxhash_delete(flowcachep->ipv4_table);        return FLOW_BADJUJU;    }    flowcachep->max_flowbits_bytes = (unsigned int)datasize;    return FLOW_SUCCESS;}int flowcache_destroy(FLOWCACHE *flowcachep){    if(!flowcachep)    {        return FLOW_ENULL;    }    sfxhash_delete(flowcachep->ipv4_table);    flowcachep->ipv4_table = NULL;        return FLOW_SUCCESS;}unsigned flowcache_overhead_blocks(FLOWCACHE *fcp){    return sfxhash_overhead_blocks(fcp->ipv4_table);}int flowcache_releaseflow(FLOWCACHE *flowcachep, FLOW **flowpp){    FLOWKEY *key;    FLOWKEY search_key;        if(!flowcachep || !flowpp || !(*flowpp))    {        return FLOW_ENULL;    }    /** @todo remove any associated data with the flow */    key = &(*flowpp)->key;        flowkey_normalize(&search_key, key);    if(sfxhash_remove(flowcachep->ipv4_table, &search_key) != 0)    {        return FLOW_NOTFOUND;    }    /* we've successfully removed the node from the table */        *flowpp = NULL;    return FLOW_SUCCESS;}int init_flowdata(FLOWCACHE *fcp, FLOW *flowp){    if(!flowp || !fcp)        return 1;    if(boInitStaticBITOP(&(flowp->data.boFlowbits), fcp->max_flowbits_bytes,                          flowp->data.flowb))    {        return 1;    }    return 0;}int flowcache_newflow(FLOWCACHE *flowcachep, FLOWKEY *keyp, FLOW **flowpp){    static int run_once = 1;#ifdef FLOW_PERF_FIX    FLOW *newflow = NULL;    SFXHASH_NODE *new_node = NULL;#else    static FLOW zeroflow;#endif    static FLOWKEY searchkey;    int ret;        if(!flowcachep || !keyp || !flowpp)    {        return FLOW_ENULL;    }    FCS_new(flowcachep, keyp);        if(run_once)    {        /* all the time that we're running this, we're actually going           to be filling in the key, and having zero'd out counters */ #ifndef FLOW_PERF_FIX        memset(&zeroflow, 0, sizeof(FLOW));#endif        memset(&searchkey, 0, sizeof(FLOWKEY));                run_once = 0;    }    flowkey_normalize(&searchkey, keyp);   #ifdef FLOW_PERF_FIX    /* This just eliminates a memcpy. */    /* Since we're using auto node recovery, we should get a node back     * here that has a data pointer. */    /* flow_init resets the internal key & stats to zero. */    new_node = sfxhash_get_node(flowcachep->ipv4_table, &searchkey);    if (new_node && new_node->data)    {        newflow = new_node->data;            if(flow_init(newflow, keyp->protocol,                     keyp->init_address, keyp->init_port,                     keyp->resp_address, keyp->resp_port))        {            return FLOW_ENULL;        }        ret = SFXHASH_OK;    }    else    {        ret = SFXHASH_NOMEM;    }#else    if(flow_init(&zeroflow, keyp->protocol,                 keyp->init_address, keyp->init_port,                 keyp->resp_address, keyp->resp_port))    {        return FLOW_ENULL;    }    ret = sfxhash_add(flowcachep->ipv4_table, &searchkey, &zeroflow);#endif    switch(ret)    {    case SFXHASH_OK:        if(flowcache_mru(flowcachep,flowpp) != FLOW_SUCCESS)        {            /* something's wrong because we just added this thing!\n */            flow_printf("Unable to find a key I just added!\n");            return FLOW_BADJUJU;        }        if(init_flowdata(flowcachep, *flowpp))        {            return FLOW_BADJUJU;        }        return FLOW_SUCCESS;            case SFXHASH_NOMEM:        return FLOW_ENOMEM;    case SFXHASH_INTABLE:    default:        return FLOW_EINVALID;    }}/**  * Get the most recently used flow from the cache *  * @param flowcachep flow cache to operate on * @param flowp where to put the flow *  * @return FLOW_SUCCESS on success */static INLINE int flowcache_mru(FLOWCACHE *flowcachep, FLOW **flowpp){    if(!flowcachep  || !flowpp)        return FLOW_EINVALID;    *flowpp = sfxhash_mru(flowcachep->ipv4_table);    if(*flowpp == NULL)        return FLOW_NOTFOUND;

⌨️ 快捷键说明

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