int RegisterPreprocessorRuleOption( struct _SnortConfig *sc, char *optionName, PreprocOptionInit initFunc, PreprocOptionEval evalFunc, PreprocOptionCleanup cleanupFunc, PreprocOptionHash hashFunc, PreprocOptionKeyCompare keyCompareFunc, PreprocOptionOtnHandler otnHandler, PreprocOptionFastPatternFunc fpFunc ) { int ret; PreprocessorOptionInfo *optionInfo; if (sc == NULL) { FatalError("%s(%d) Snort conf for parsing is NULL.\n", __FILE__, __LINE__); } if (sc->preproc_rule_options == NULL) { FatalError("Preprocessor Rule Option storage not initialized\n"); } optionInfo = sfghash_find(sc->preproc_rule_options, optionName); if (optionInfo != NULL) { DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "Duplicate Preprocessor Rule Option '%s'\n", optionName););
int DynamicElementInitialize(Rule *rule, DynamicElement *element) { void *memoryLocation; if (!rule->ruleData) { DynamicEngineFatalMessage("Runtime rule data location '%s' for rule [%d:%d] is unknown\n", element->refId, rule->info.genID, rule->info.sigID); } switch (element->dynamicType) { case DYNAMIC_TYPE_INT_REF: memoryLocation = sfghash_find((SFGHASH*)rule->ruleData, element->refId); if (memoryLocation) { element->data.dynamicInt = memoryLocation; } else { element->data.dynamicInt = NULL; DynamicEngineFatalMessage("Runtime rule data location '%s' for rule [%d:%d] is unknown\n", element->refId, rule->info.genID, rule->info.sigID); //return -1; } break; case DYNAMIC_TYPE_INT_STATIC: default: /* nothing to do, its static */ break; } return 0; }
int CursorInfoInitialize(Rule *rule, CursorInfo *cursor) { void *memoryLocation; /* Initialize byte_extract pointers */ if (cursor->offset_refId) { if (!rule->ruleData) { DynamicEngineFatalMessage("ByteExtract variable '%s' in rule [%d:%d] is used before it is defined.\n", cursor->offset_refId, rule->info.genID, rule->info.sigID); } memoryLocation = sfghash_find((SFGHASH*)rule->ruleData, cursor->offset_refId); if (memoryLocation) { cursor->offset_location = memoryLocation; } else { DynamicEngineFatalMessage("ByteExtract variable '%s' in rule [%d:%d] is used before it is defined.\n", cursor->offset_refId, rule->info.genID, rule->info.sigID); } } return 0; }
tAppId hostPortAppCacheFind(const snort_ip *snort_ip, uint16_t port, uint16_t protocol) { tHostPortKey hk; copySnortIpToIpv6Network(&hk.ip, snort_ip); hk.port = port; hk.proto = protocol; return (tAppId)sfghash_find(hostPortCache, &hk); }
OptTreeNode * OtnLookup(SFGHASH *otn_map, uint32_t gid, uint32_t sid) { OptTreeNode * otn; OtnKey key; if (otn_map == NULL) return NULL; key.gid = gid; key.sid = sid; otn = (OptTreeNode *)sfghash_find(otn_map, &key); return otn; }
OptTreeNode * SoRuleOtnLookup(SFGHASH *so_rule_otn_map, uint32_t gid, uint32_t sid) { OptTreeNode *otn = NULL; OtnKey key; if (so_rule_otn_map == NULL) return NULL; key.gid = gid; key.sid = sid; soidOTN = otn = (OptTreeNode *)sfghash_find(so_rule_otn_map, &key); return otn; }
/* Initialize a byteExtract structure. */ int ByteExtractInitialize(Rule *rule, ByteExtract *extractData) { int ret = 0; void *memoryLocation; if (rule->ruleData == NULL) { /* Initialize the hash table */ /* XXX: 3 rows ought to suffice for now... */ /* 3 rows, * 0 bytes key size (ie, its a string), * user provided keys, * free func -- data is pointer to int */ rule->ruleData = (void *)sfghash_new(3, 0, 1, free); } memoryLocation = sfghash_find((SFGHASH*)rule->ruleData, extractData->refId); if (memoryLocation) { /* Cannot re-use refId */ DynamicEngineFatalMessage("Cannot re-use ByteExtract location '%s' for rule [%d:%d]\n", extractData->refId, rule->info.genID, rule->info.sigID); //return -1; } memoryLocation = calloc(sizeof(u_int32_t), 1); if (memoryLocation == NULL) { DynamicEngineFatalMessage("Failed to allocate memory\n"); } ret = sfghash_add((SFGHASH*)rule->ruleData, extractData->refId, memoryLocation); if (ret != SFGHASH_OK) { free(memoryLocation); /* Some error, couldn't allocate hash entry */ return -2; } extractData->memoryLocation = memoryLocation; return 0; }
/* XXX XXX Probably need to do this during swap time since the * proto_reference_table is accessed during runtime */ int16_t AddProtocolReference(const char *protocol) { SFTargetProtocolReference *reference; if (!protocol) return SFTARGET_UNKNOWN_PROTOCOL; if (!proto_reference_table) { InitializeProtocolReferenceTable(); } reference = sfghash_find(proto_reference_table, (void *)protocol); if (reference) { DEBUG_WRAP( DebugMessage(DEBUG_ATTRIBUTE, "Protocol Reference for %s exists as %d\n", protocol, reference->ordinal);); return reference->ordinal; }
/* Test a an event against the threshold database. Events without thresholding * objects are automatically loggable. * * @param pContext Threshold table pointer * @param gid Generator Id from the event * @param sid Signature Id from the event * @param sip Event/Packet Src IP address * @param dip Event/Packet Dst IP address * @param curTime Current Event/Packet time * @param op operation of type SFRF_COUNT_OPERATION * * @return -1 if packet is within dos_threshold and therefore action is allowed. * >=0 if packet violates a dos_threshold and therefore new_action should * replace rule action. new_action value is returned. */ int SFRF_TestThreshold( RateFilterConfig *config, unsigned gid, unsigned sid, snort_ip_p sip, snort_ip_p dip, time_t curTime, SFRF_COUNT_OPERATION op ) { SFGHASH *genHash; tSFRFSidNode* pSidNode; tSFRFConfigNode* cfgNode; int newStatus = -1; int status = -1; tSFRFGenHashKey key; tSfPolicyId policy_id = getRuntimePolicy(); #ifdef SFRF_DEBUG printf("--%d-%d-%d: %s() entering\n", 0, gid, sid, __func__); fflush(stdout); #endif if ( gid >= SFRF_MAX_GENID ) return status; /* bogus gid */ // Some events (like 'TCP connection closed' raised by preprocessor may // not have any configured threshold but may impact thresholds for other // events (like 'TCP connection opened' _updateDependentThresholds(config, gid, sid, sip, dip, curTime); /* * Get the hash table for this gid */ genHash = config->genHash [ gid ]; if ( !genHash ) { #ifdef SFRF_DEBUG printf("--SFRF_DEBUG: %d-%d-%d: no hash table entry for gid\n", 0, gid, sid); fflush(stdout); #endif return status; } /* * Check for any Permanent sid objects for this gid */ key.sid = sid; key.policyId = policy_id; pSidNode = (tSFRFSidNode*)sfghash_find( genHash, (void*)&key ); if ( !pSidNode ) { #ifdef SFRF_DEBUG printf("--SFRF_DEBUG: %d-%d-%d: no DOS THD object\n", 0, gid, sid); fflush(stdout); #endif return status; } /* No List of Threshold objects - bail and log it */ if ( !pSidNode->configNodeList ) { #ifdef SFRF_DEBUG printf("--SFRF_DEBUG: %d-%d-%d: No user configuration\n", 0, gid, sid); fflush(stdout); #endif return status; } /* For each permanent thresholding object, test/add/update the config object */ /* We maintain a list of thd objects for each gid+sid */ /* each object has it's own unique thd_id */ for ( cfgNode = (tSFRFConfigNode*)sflist_first(pSidNode->configNodeList); cfgNode != 0; cfgNode = (tSFRFConfigNode*)sflist_next(pSidNode->configNodeList) ) { switch (cfgNode->tracking) { case SFRF_TRACK_BY_SRC: if ( SFRF_AppliesTo(cfgNode, sip) ) { newStatus = SFRF_TestObject(cfgNode, sip, curTime, op); } break; case SFRF_TRACK_BY_DST: if ( SFRF_AppliesTo(cfgNode, dip) ) { newStatus = SFRF_TestObject(cfgNode, dip, curTime, op); } break; case SFRF_TRACK_BY_RULE: { snort_ip cleared; IP_CLEAR(cleared); newStatus = SFRF_TestObject(cfgNode, IP_ARG(cleared), curTime, op); } break; default: // error case break; } #ifdef SFRF_DEBUG printf("--SFRF_DEBUG: %d-%d-%d: Time %d, rate limit blocked: %d\n", cfgNode->tid, gid, sid, (unsigned)curTime, newStatus); fflush(stdout); #endif // rate limit is reached if ( newStatus >= 0 && (status == -1) ) { status = newStatus; } } // rate limit not reached return status; }
/* Add a permanent threshold object to the threshold table. Multiple * objects may be defined for each gid and sid pair. Internally * a unique threshold id is generated for each pair. * * Threshold objects track the number of events seen during the time * interval specified by seconds. Depending on the type of threshold * object and the count value, the thresholding object determines if * the current event should be logged or dropped. * * @param pContext Threshold object from SFRF_ContextNew() * @param cfgNode Permanent Thresholding Object * * @return @retval 0 successfully added the thresholding object, !0 otherwise */ int SFRF_ConfigAdd(SnortConfig *sc, RateFilterConfig *rf_config, tSFRFConfigNode *cfgNode) { SFGHASH* genHash; int nrows; int hstatus; tSFRFSidNode* pSidNode; tSFRFConfigNode* pNewConfigNode; tSFRFGenHashKey key = {0,0}; tSfPolicyId policy_id = getParserPolicy(sc); // Auto init - memcap must be set 1st, which is not really a problem if ( rf_hash == NULL ) { SFRF_New(rf_config->memcap); if ( rf_hash == NULL ) return -1; } if ((rf_config == NULL) || (cfgNode == NULL)) return -1; if ( (cfgNode->sid == 0 ) || (cfgNode->gid == 0) ) return -1; if ( cfgNode->gid >= SFRF_MAX_GENID ) return -1; if ( cfgNode->count < 1 ) return -1; if ( cfgNode->timeout == 0 ) { if ( rf_config->noRevertCount >= SFRF_NO_REVERT_LIMIT ) return -1; rf_config->noRevertCount++; } /* Check for an existing 'gid' entry, if none found then create one. */ /* Get the hash table for this gid */ genHash = rf_config->genHash[cfgNode->gid]; if ( !genHash ) { if ( cfgNode->gid == 1 )/* patmatch rules gid, many rules */ { nrows= SFRF_GEN_ID_1_ROWS; } else /* other gid's */ { nrows= SFRF_GEN_ID_ROWS; } /* Create the hash table for this gid */ genHash = sfghash_new( nrows, sizeof(tSFRFGenHashKey), 0, SFRF_SidNodeFree ); if ( !genHash ) return -2; rf_config->genHash[cfgNode->gid] = genHash; } key.sid = cfgNode->sid; key.policyId = policy_id; /* Check if sid is already in the table - if not allocate and add it */ pSidNode = (tSFRFSidNode*)sfghash_find( genHash, (void*)&key ); if ( !pSidNode ) { /* Create the pSidNode hash node data */ pSidNode = (tSFRFSidNode*)calloc(1,sizeof(tSFRFSidNode)); if ( !pSidNode ) return -3; pSidNode->gid = cfgNode->gid; pSidNode->sid = cfgNode->sid; pSidNode->configNodeList = sflist_new(); if ( !pSidNode->configNodeList ) { free(pSidNode); return -4; } /* Add the pSidNode to the hash table */ hstatus = sfghash_add( genHash, (void*)&key, pSidNode ); if ( hstatus ) { sflist_free(pSidNode->configNodeList); free(pSidNode); return -5; } } /* Create a tSFRFConfigNode for this tSFRFSidNode (Object) */ pNewConfigNode = (tSFRFConfigNode*)calloc(1,sizeof(tSFRFConfigNode)); if ( !pNewConfigNode ) { sflist_free(pSidNode->configNodeList); free(pSidNode); return -6; } *pNewConfigNode = *cfgNode; rf_config->count++; /* Copy the node parameters, with unique internally assigned tid */ pNewConfigNode->tid = rf_config->count; if ( pNewConfigNode->tid == 0 ) { // tid overflow. rare but possible free(pNewConfigNode); sflist_free(pSidNode->configNodeList); free(pSidNode); return -6; } #ifdef SFRF_DEBUG printf("--%d-%d-%d: Threshold node added to tail of list\n", pNewConfigNode->tid, pNewConfigNode->gid, pNewConfigNode->sid); fflush(stdout); #endif sflist_add_tail(pSidNode->configNodeList,pNewConfigNode); return 0; }
/*! Add a permanent threshold object to the threshold table. Multiple objects may be defined for each gen_id and sig_id pair. Internally a unique threshold id is generated for each pair. Threshold objects track the number of events seen during the time interval specified by seconds. Depending on the type of threshold object and the count value, the thresholding object determines if the current event should be logged or dropped. @param thd Threshold object from sfthd_new() @param gen_id Generator id @param sig_id Signauture id @param tracking Selects tracking by src ip or by dst ip @param type Thresholding type: Limit, Threshold, or Limt+Threshold, Suppress @param priority Assigns a relative priority to this object, higher numbers imply higher priority @param count Number of events @param seconds Time duration over which this threshold object acts. @param ip IP address, for supression @param ip-mask IP mask, applied with ip_mask, for supression @return integer @retval 0 successfully added the thresholding object @retval !0 failed */ static int sfthd_create_threshold_local(SnortConfig *sc, ThresholdObjects *thd_objs, THD_NODE* config) { SFGHASH * sfthd_hash; THD_ITEM * sfthd_item; THD_NODE * sfthd_node; tThdItemKey key; int nrows; int hstatus; tSfPolicyId policy_id = getParserPolicy(sc); if (thd_objs == NULL ) return -1; if( config->gen_id >= THD_MAX_GENID ) return -1; #ifdef CRIPPLE return 0; #endif /* Check for an existing 'gen_id' entry, if none found create one. */ if (thd_objs->sfthd_array[config->gen_id] == NULL) { if( config->gen_id == 1 )/* patmatch rules gen_id, many rules */ { nrows= THD_GEN_ID_1_ROWS; } else /* other gen_id's */ { nrows= THD_GEN_ID_ROWS; } /* Create the hash table for this gen_id */ sfthd_hash = sfghash_new( nrows, sizeof(tThdItemKey), 0, sfthd_item_free ); if( !sfthd_hash ) { return -2; } thd_objs->sfthd_array[config->gen_id] = sfthd_hash; } else { /* Get the hash table for this gen_id */ sfthd_hash = thd_objs->sfthd_array[config->gen_id]; } if (sfthd_hash == NULL) return -2; key.sig_id = config->sig_id; key.policyId = policy_id; /* Check if sig_id is already in the table - if not allocate and add it */ sfthd_item = (THD_ITEM*)sfghash_find( sfthd_hash, (void*)&key ); if( !sfthd_item ) { /* Create the sfthd_item hash node data */ sfthd_item = (THD_ITEM*)calloc(1,sizeof(THD_ITEM)); if( !sfthd_item ) { return -3; } sfthd_item->gen_id = config->gen_id; sfthd_item->sig_id = config->sig_id; sfthd_item->policyId = policy_id; sfthd_item->sfthd_node_list = sflist_new(); if(!sfthd_item->sfthd_node_list) { free(sfthd_item); return -4; } /* Add the sfthd_item to the hash table */ hstatus = sfghash_add( sfthd_hash, (void*)&key, sfthd_item ); if( hstatus ) { sflist_free(sfthd_item->sfthd_node_list); free(sfthd_item); return -5; } } /* * Test that we only have one Limit/Threshold/Both Object at the tail, * we can have multiple suppression nodes at the head */ if( sfthd_item->sfthd_node_list->count > 0 ) { THD_NODE * p; if( !sfthd_item->sfthd_node_list->tail) { /* can you say paranoid- if there is a count, there should be a tail */ return -10; } p = (THD_NODE*)sfthd_item->sfthd_node_list->tail->ndata; if(p) /* just to be safe- if thers a tail, there is is node data */ { if( p->type != THD_TYPE_SUPPRESS && config->type != THD_TYPE_SUPPRESS ) { #ifdef THD_DEBUG printf("THD_DEBUG: Could not add a 2nd Threshold object, " "you can only have 1 per sid: gid=%u, sid=%u\n", config->gen_id, config->sig_id); #endif /* cannot add more than one threshold per sid in version 3.0, wait for 3.2 and CIDR blocks */ return THD_TOO_MANY_THDOBJ; } } } /* Create a THD_NODE for this THD_ITEM (Object) */ sfthd_node = (THD_NODE*)calloc(1,sizeof(THD_NODE)); if( !sfthd_node ) { return -6; } /* Limit priorities to force supression nodes to highest priority */ if( config->priority >= THD_PRIORITY_SUPPRESS ) { config->priority = THD_PRIORITY_SUPPRESS - 1; } /* Copy the node parameters */ sfthd_node->thd_id = config->thd_id; sfthd_node->gen_id = config->gen_id; sfthd_node->sig_id = config->sig_id; sfthd_node->tracking = config->tracking; /* by_src, by_dst */ sfthd_node->type = config->type; sfthd_node->priority = config->priority; sfthd_node->count = config->count; sfthd_node->seconds = config->seconds; sfthd_node->ip_address= config->ip_address; if( config->type == THD_TYPE_SUPPRESS ) { sfthd_node->priority = THD_PRIORITY_SUPPRESS; } /* If sfthd_node list is empty - add as head node */ if( !sfthd_item->sfthd_node_list->count ) { #ifdef THD_DEBUG printf("Threshold node added to head of list\n");fflush(stdout); #endif sflist_add_head(sfthd_item->sfthd_node_list,sfthd_node); } /* else add the sfthd_node using priority to determine where in the list it belongs 3.0 we can have only 1 threshold object but several suppression objects plus a single threshold object is ok. Blocking multiple threshold objects is done above. Suppressions have the highest priority and are at the front of the list, the tail node is either a supprssion node or the only pure thresholding node. */ else { SF_LNODE* lnode; /* Walk the list and insert based on priorities if suppress */ for( lnode = sflist_first_node(sfthd_item->sfthd_node_list); lnode; lnode = sflist_next_node(sfthd_item->sfthd_node_list) ) { THD_NODE* sfthd_n = (THD_NODE*)lnode->ndata; /* check if the new node is higher priority */ if( sfthd_node->priority > sfthd_n->priority ) { /* insert before current node */ #ifdef THD_DEBUG printf("Threshold node added after based on priority\n");fflush(stdout); #endif sflist_add_before(sfthd_item->sfthd_node_list,lnode,sfthd_node); return 0; } /* last node, just insert it here */ if( !lnode->next ) { /* if last node, insert at end of list */ #ifdef THD_DEBUG printf("Threshold node added to tail\n");fflush(stdout); #endif sflist_add_tail(sfthd_item->sfthd_node_list,sfthd_node); return 0; } } } return 0; }
/*! * * Test a an event against the threshold database. * Events without thresholding objects are automatically * loggable. * * @param thd Threshold table pointer * @param gen_id Generator Id from the event * @param sig_id Signature Id from the event * @param sip Event/Packet Src IP address * @param dip Event/Packet Dst IP address * @param curtime Current Event/Packet time * * @return integer * @retval 0 : Event is loggable * @retval !0 : Event should not be logged (-1 suppressed, 1 filtered) * */ int sfthd_test_threshold( ThresholdObjects *thd_objs, THD_STRUCT *thd, unsigned gen_id, unsigned sig_id, snort_ip_p sip, snort_ip_p dip, long curtime ) { tThdItemKey key; SFGHASH * sfthd_hash; THD_ITEM * sfthd_item; THD_NODE * sfthd_node; THD_NODE * g_thd_node = NULL; #ifdef THD_DEBUG int cnt; #endif int status=0; tSfPolicyId policy_id = getRuntimePolicy(); if ((thd_objs == NULL) || (thd == NULL)) return 0; #ifdef CRIPPLE return 0; #endif #ifdef THD_DEBUG printf("sfthd_test_threshold...\n");fflush(stdout); #endif if( gen_id >= THD_MAX_GENID ) { #ifdef THD_DEBUG printf("THD_DEBUG: invalid gen_id=%u\n",gen_id); fflush(stdout); #endif return 0; /* bogus gen_id */ } /* * Get the hash table for this gen_id */ sfthd_hash = thd_objs->sfthd_array[gen_id]; if (sfthd_hash == NULL) { #ifdef THD_DEBUG printf("THD_DEBUG: no hash table entry for gen_id=%u\n",gen_id); fflush(stdout); #endif goto global_test; /* return 0; */ /* no threshold objects for this gen_id, log it ! */ } key.sig_id = sig_id; key.policyId = policy_id; /* * Check for any Permanent sig_id objects for this gen_id */ sfthd_item = (THD_ITEM *)sfghash_find(sfthd_hash, (void*)&key); if (sfthd_item == NULL) { #ifdef THD_DEBUG printf("THD_DEBUG: no THD objects for gen_id=%u, sig_id=%u\n",gen_id,sig_id); fflush(stdout); #endif /* no matching permanent sig_id objects so, log it ! */ goto global_test; } /* No List of Threshold objects - bail and log it */ if (sfthd_item->sfthd_node_list == NULL) { goto global_test; } /* For each permanent thresholding object, test/add/update the thd object */ /* We maintain a list of thd objects for each gen_id+sig_id */ /* each object has it's own unique thd_id */ /* Suppression nodes have a very high priority, so they are tested 1st */ #ifdef THD_DEBUG cnt=0; #endif for (sfthd_node = (THD_NODE *)sflist_first(sfthd_item->sfthd_node_list); sfthd_node != NULL; sfthd_node = (THD_NODE *)sflist_next(sfthd_item->sfthd_node_list)) { #ifdef THD_DEBUG cnt++; printf("THD_DEBUG: gen_id=%u sig_id=%u testing thd_id=%d thd_type=%d\n", gen_id, sig_id, sfthd_node->thd_id, sfthd_node->type); fflush(stdout); #endif /* * Test SUPPRESSION and THRESHOLDING */ status = sfthd_test_local(thd->ip_nodes, sfthd_node, sip, dip, curtime ); if( status < 0 ) /* -1 == Don't log and stop looking */ { #ifdef THD_DEBUG printf("THD_DEBUG: gen_id=%u sig_id=%u, UnLoggable\n\n",gen_id, sig_id,cnt); fflush(stdout); #endif return (status < -1) ? 1 : -1; /* !0 == Don't log it*/ } else if( status == 0 ) /* Log it and stop looking */ { #ifdef THD_DEBUG printf("THD_DEBUG: gen_id=%u sig_id=%u tested %d THD_NODE's, " "Loggable\n\n",sfthd_item->gen_id, sfthd_item->sig_id,cnt); fflush(stdout); #endif return 0; /* 0 == Log the event */ } /* status > 0 : Log it later but Keep looking * check the next threshold object for a blocking action ... */ } /* * Test for a global threshold object * we're here cause ther were no threshold objects for this gen_id/sig_id pair */ global_test: #ifdef THD_DEBUG printf("THD_DEBUG-GLOBAL: doing global object test\n"); #endif if (thd_objs->sfthd_garray && thd_objs->sfthd_garray[policy_id]) { g_thd_node = thd_objs->sfthd_garray[policy_id][gen_id]; } if( g_thd_node ) { status = sfthd_test_global( thd->ip_gnodes, g_thd_node, gen_id, sig_id, sip, dip, curtime ); if( status < 0 ) /* -1 == Don't log and stop looking */ { #ifdef THD_DEBUG printf("THD_DEBUG-GLOBAL: gen_id=%u sig_id=%u THD_NODE's, " "UnLoggable\n\n",gen_id, sig_id); fflush(stdout); #endif return (status < -1) ? 1 : -1; /* !0 == Don't log it*/ } /* Log it ! */ #ifdef THD_DEBUG printf("THD_DEBUG-GLOBAL: gen_id=%u sig_id=%u THD_NODE's, " "Loggable\n\n",gen_id, sig_id); fflush(stdout); #endif } else { #ifdef THD_DEBUG printf("THD_DEBUG-GLOBAL: no Global THD Object for gen_id=%u, " "sig_id=%u\n\n",gen_id, sig_id); fflush(stdout); #endif } return 0; /* Default: Log it if we did not block the logging action */ }
/* * Hash test program */ int main ( int argc, char ** argv ) { int i; SFGHASH * t; SFGHASH_NODE * n, *m; char str[256],*p; int num=100; if( argc > 1 ) num = atoi(argv[1]); sfatom_init(); /* Create a Hash Table */ t = sfghash_new( 1000, 0 , GH_COPYKEYS , myfree ); /* Add Nodes to the Hash Table */ for(i=0;i<num;i++) { snprintf(str, sizeof(str), "KeyWord%d",i+1); str[sizeof(str) - 1] = '\0'; sfghash_add( t, str, strupr(strdup(str)) ); sfatom_add( str, strupr(strdup(str)) ); } /* Find and Display Nodes in the Hash Table */ printf("\n** FIND KEY TEST\n"); for(i=0;i<num;i++) { snprintf(str, sizeof(str), "KeyWord%d",i+1); str[sizeof(str) - 1] = '\0'; p = (char*) sfghash_find( t, str ); printf("Hash-key=%*s, data=%*s\n", strlen(str),str, strlen(str), p ); p = (char*) sfatom_find( str ); printf("Atom-key=%*s, data=%*s\n", strlen(str),str, strlen(str), p ); } /* Display All Nodes in the Hash Table */ printf("\n** FINDFIRST / FINDNEXT TEST\n"); for( n = sfghash_findfirst(t); n; n = sfghash_findnext(t) ) { printf("hash-findfirst/next: key=%s, data=%s\n", n->key, n->data ); // hashing code frees user data using 'myfree' above .... if( sfghash_remove(t,n->key) ) printf("Could not remove the key node\n"); else printf("key node removed\n"); } for( n = sfatom_findfirst(); n; n = sfatom_findnext() ) { printf("atom-findfirst/next: key=%s, data=%s\n", n->key, n->data ); free( n->data ); //since atom data is not freed automatically } /* Free the table and it's user data */ printf("****sfghash_delete\n"); sfghash_delete( t ); printf("****sfatom_reset\n"); sfatom_reset(); printf("\nnormal pgm finish\n\n"); return 0; }
/* * Initialize Boyer-Moore-Horspool data for single pattern comparisons * * returns: 0 -> success * !0 -> error,failed */ int BoyerContentSetup(Rule *rule, ContentInfo *content) { void *memoryLocation; /* XXX: need to precompile the B-M stuff */ if( !content->patternByteForm || !content->patternByteFormLength ) return 0; content->boyer_ptr = hbm_prep(content->patternByteForm, content->patternByteFormLength, content->flags & CONTENT_NOCASE); if( !content->boyer_ptr ) { /* error doing compilation. */ _ded.errMsg("Failed to setup pattern match for dynamic rule [%d:%d]\n", rule->info.genID, rule->info.sigID); return -1; } /* Initialize byte_extract pointers */ if (content->offset_refId) { if (!rule->ruleData) { DynamicEngineFatalMessage("ByteExtract variable '%s' in rule [%d:%d] is used before it is defined.\n", content->offset_refId, rule->info.genID, rule->info.sigID); } memoryLocation = sfghash_find((SFGHASH*)rule->ruleData, content->offset_refId); if (memoryLocation) { content->offset_location = memoryLocation; } else { DynamicEngineFatalMessage("ByteExtract variable '%s' in rule [%d:%d] is used before it is defined.\n", content->offset_refId, rule->info.genID, rule->info.sigID); } } if (content->depth_refId) { if (!rule->ruleData) { DynamicEngineFatalMessage("ByteExtract variable '%s' in rule [%d:%d] is used before it is defined.\n", content->depth_refId, rule->info.genID, rule->info.sigID); } memoryLocation = sfghash_find((SFGHASH*)rule->ruleData, content->depth_refId); if (memoryLocation) { content->depth_location = memoryLocation; } else { DynamicEngineFatalMessage("ByteExtract variable '%s' in rule [%d:%d] is used before it is defined.\n", content->depth_refId, rule->info.genID, rule->info.sigID); } } return 0; }
int ByteDataInitialize(Rule *rule, ByteData *byte) { void *memoryLocation=NULL; unsigned int ii, byte_math_flag=0; RuleOption *option; for(ii=0;rule->options[ii] != NULL; ii++) { option = rule->options[ii]; if(option->optionType==OPTION_TYPE_BYTE_MATH) byte_math_flag=1; } /* Initialize byte_extract pointers */ if (byte->offset_refId) { if (!rule->ruleData && !byte_math_var_check) { DynamicEngineFatalMessage("ByteExtract variable '%s' in rule [%d:%d] is used before it is defined.\n", byte->offset_refId, rule->info.genID, rule->info.sigID); } if (rule->ruleData) memoryLocation = sfghash_find((SFGHASH*)rule->ruleData, byte->offset_refId); if (memoryLocation) { byte->offset_location = memoryLocation; } else { if (!byte_math_var_check && (strcmp(bm_variable_name,byte->offset_refId))) { DynamicEngineFatalMessage("ByteExtract variable '%s' in rule [%d:%d] is used before it is defined.\n", byte->offset_refId, rule->info.genID, rule->info.sigID); } } } if (byte->value_refId) { if (!rule->ruleData && !byte_math_var_check) { DynamicEngineFatalMessage("ByteExtract variable '%s' in rule [%d:%d] is used before it is defined.\n", byte->value_refId, rule->info.genID, rule->info.sigID); } if (rule->ruleData) memoryLocation = sfghash_find((SFGHASH*)rule->ruleData, byte->value_refId); if (memoryLocation) { byte->value_location = memoryLocation; } else { if (!byte_math_var_check && (strcmp(bm_variable_name,byte->value_refId))) { DynamicEngineFatalMessage("ByteExtract or byte_math variable '%s' in rule [%d:%d] is used before it is defined.\n", byte->value_refId, rule->info.genID, rule->info.sigID); } } } if (byte_math_flag && byte->refId && byte_math_var_check ) { DynamicEngineFatalMessage("refId field should be NULL for other than Byte_Math options\n"); } if (byte_math_flag && byte->refId) { if (bm_variable_name) free(bm_variable_name); bm_variable_name = strdup(byte->refId); if (bm_variable_name) byte_math_var_check=1; } byte_math_var_free(byte); return 0; }
void * sfatom_find(char * str) { return (void*) sfghash_find( g_atom, str ); }