flow_cache.c
来自「snort-2.1.0入侵检测」· C语言 代码 · 共 568 行 · 第 1/2 页
C
568 行
/** * @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 * */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include "flow_cache.h"#include "flow_callback.h"#include "flow_hash.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, FLOWHASHID hashid){ int ret; if(!flowcachep) { return FLOW_ENULL; } if(memcap <= (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)); /* what size should we do? */ flowcachep->ipv4_table = sfxhash_new(rows, /* # of nodes in HT*/ sizeof(FLOWKEY), /* size of the key */ sizeof(FLOW), /* data size */ memcap, /* how much memory is alloted */ 1, /* auto recover nodes */ flowcache_anrfree, /* autorecovery function */ flowcache_usrfree, /* free function for the data */ 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; } 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 flowcache_newflow(FLOWCACHE *flowcachep, FLOWKEY *keyp, FLOW **flowpp){ static int run_once = 1; static FLOW zeroflow; 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 */ memset(&zeroflow, 0, sizeof(FLOW)); memset(&searchkey, 0, sizeof(FLOWKEY)); run_once = 0; } flowkey_normalize(&searchkey, keyp); 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); 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; } 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 sucess */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; return FLOW_SUCCESS;}/** * Get the least recently used flow from the cache * * @param flowcachep flow cache to operate on * @param flowp where to put the flow * * @return FLOW_SUCCESS on sucess */static INLINE int flowcache_lru(FLOWCACHE *flowcachep, FLOW **flowpp){ if(!flowcachep || !flowpp) return FLOW_EINVALID; *flowpp = sfxhash_lru(flowcachep->ipv4_table); if(*flowpp == NULL) return FLOW_NOTFOUND; return FLOW_SUCCESS;}/** * Look for the data in the flow tables. * * @param flowcachep cache to look in * @param keyp pointer to searching key data * @param flowpp pointer to set with this module * @param direction pass back argument (FROM_INITIATOR or FROM_RESPONDER) * * @return FLOW_SUCCESS on success, FLOW_NOTFOUND when not found, else usage error */int flowcache_find(FLOWCACHE *flowcachep, FLOWKEY *keyp, FLOW **flowpp, int *direction){ FLOWKEY search_key; FLOW *fp; int way; if(!flowcachep || !keyp || !flowpp || !direction) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?