@ -492,32 +492,6 @@ void DetectFlowbitFree (DetectEngineCtx *de_ctx, void *ptr)
SCFree ( fd ) ;
}
struct FBAnalyzer {
struct FBAnalyze * array ;
uint32_t array_size ;
} ;
struct FBAnalyze {
uint16_t cnts [ DETECT_FLOWBITS_CMD_MAX ] ;
uint16_t state_cnts [ DETECT_FLOWBITS_CMD_MAX ] ;
uint32_t * set_sids ;
uint32_t set_sids_idx ;
uint32_t set_sids_size ;
uint32_t * isset_sids ;
uint32_t isset_sids_idx ;
uint32_t isset_sids_size ;
uint32_t * isnotset_sids ;
uint32_t isnotset_sids_idx ;
uint32_t isnotset_sids_size ;
uint32_t * unset_sids ;
uint32_t unset_sids_idx ;
uint32_t unset_sids_size ;
} ;
extern bool rule_engine_analysis_set ;
static void DetectFlowbitsAnalyzeDump ( const DetectEngineCtx * de_ctx ,
struct FBAnalyze * array , uint32_t elements ) ;
@ -526,10 +500,10 @@ static void FBAnalyzerArrayFree(struct FBAnalyze *array, const uint32_t array_si
{
if ( array ) {
for ( uint32_t i = 0 ; i < array_size ; i + + ) {
SCFree ( array [ i ] . set_ s ids) ;
SCFree ( array [ i ] . unset_ s ids) ;
SCFree ( array [ i ] . isset_ s ids) ;
SCFree ( array [ i ] . isnotset_ s ids) ;
SCFree ( array [ i ] . set_ i ids) ;
SCFree ( array [ i ] . unset_ i ids) ;
SCFree ( array [ i ] . isset_ i ids) ;
SCFree ( array [ i ] . isnotset_ i ids) ;
}
SCFree ( array ) ;
}
@ -544,18 +518,18 @@ static void FBAnalyzerFree(struct FBAnalyzer *fba)
}
}
# define MAX_ S IDS 8
static bool CheckExpand ( const uint32_t sids_idx, uint32_t * * sids , uint32_t * s ids_size)
# define MAX_ I IDS 8
static bool CheckExpand ( const uint32_t iids_idx, uint32_t * * iids , uint32_t * i ids_size)
{
if ( sids_idx > = * s ids_size) {
const uint32_t old_size = * s ids_size;
const uint32_t new_size = MAX ( 2 * old_size , MAX_ S IDS) ;
if ( iids_idx > = * i ids_size) {
const uint32_t old_size = * i ids_size;
const uint32_t new_size = MAX ( 2 * old_size , MAX_ I IDS) ;
void * ptr = SCRealloc ( * s ids, new_size * sizeof ( uint32_t ) ) ;
void * ptr = SCRealloc ( * i ids, new_size * sizeof ( uint32_t ) ) ;
if ( ptr = = NULL )
return false ;
* s ids_size = new_size ;
* s ids = ptr ;
* i ids_size = new_size ;
* i ids = ptr ;
}
return true ;
}
@ -582,16 +556,16 @@ static int DetectFlowbitsAnalyzeSignature(const Signature *s, struct FBAnalyzer
fa - > state_cnts [ fb - > cmd ] + = has_state ;
if ( fb - > cmd = = DETECT_FLOWBITS_CMD_ISSET ) {
if ( ! CheckExpand ( fa - > isset_ sids_idx, & fa - > isset_sids , & fa - > isset_s ids_size) )
if ( ! CheckExpand ( fa - > isset_ iids_idx, & fa - > isset_iids , & fa - > isset_i ids_size) )
return - 1 ;
fa - > isset_ sids[ fa - > isset_s ids_idx] = s - > iid ;
fa - > isset_ s ids_idx+ + ;
fa - > isset_ iids[ fa - > isset_i ids_idx] = s - > iid ;
fa - > isset_ i ids_idx+ + ;
} else if ( fb - > cmd = = DETECT_FLOWBITS_CMD_ISNOTSET ) {
if ( ! CheckExpand (
fa - > isnotset_ sids_idx, & fa - > isnotset_sids , & fa - > isnotset_s ids_size) )
fa - > isnotset_ iids_idx, & fa - > isnotset_iids , & fa - > isnotset_i ids_size) )
return - 1 ;
fa - > isnotset_ sids[ fa - > isnotset_s ids_idx] = s - > iid ;
fa - > isnotset_ s ids_idx+ + ;
fa - > isnotset_ iids[ fa - > isnotset_i ids_idx] = s - > iid ;
fa - > isnotset_ i ids_idx+ + ;
}
}
if ( fb - > or_list_size = = 0 ) {
@ -600,16 +574,16 @@ static int DetectFlowbitsAnalyzeSignature(const Signature *s, struct FBAnalyzer
fa - > state_cnts [ fb - > cmd ] + = has_state ;
if ( fb - > cmd = = DETECT_FLOWBITS_CMD_ISSET ) {
if ( ! CheckExpand ( fa - > isset_ sids_idx, & fa - > isset_sids , & fa - > isset_s ids_size) )
if ( ! CheckExpand ( fa - > isset_ iids_idx, & fa - > isset_iids , & fa - > isset_i ids_size) )
return - 1 ;
fa - > isset_ sids[ fa - > isset_s ids_idx] = s - > iid ;
fa - > isset_ s ids_idx+ + ;
fa - > isset_ iids[ fa - > isset_i ids_idx] = s - > iid ;
fa - > isset_ i ids_idx+ + ;
} else if ( fb - > cmd = = DETECT_FLOWBITS_CMD_ISNOTSET ) {
if ( ! CheckExpand (
fa - > isnotset_ sids_idx, & fa - > isnotset_sids , & fa - > isnotset_s ids_size) )
fa - > isnotset_ iids_idx, & fa - > isnotset_iids , & fa - > isnotset_i ids_size) )
return - 1 ;
fa - > isnotset_ sids[ fa - > isnotset_s ids_idx] = s - > iid ;
fa - > isnotset_ s ids_idx+ + ;
fa - > isnotset_ iids[ fa - > isnotset_i ids_idx] = s - > iid ;
fa - > isnotset_ i ids_idx+ + ;
}
}
}
@ -624,15 +598,15 @@ static int DetectFlowbitsAnalyzeSignature(const Signature *s, struct FBAnalyzer
fa - > state_cnts [ fb - > cmd ] + = has_state ;
if ( fb - > cmd = = DETECT_FLOWBITS_CMD_SET ) {
if ( ! CheckExpand ( fa - > set_ sids_idx, & fa - > set_sids , & fa - > set_s ids_size) )
if ( ! CheckExpand ( fa - > set_ iids_idx, & fa - > set_iids , & fa - > set_i ids_size) )
return - 1 ;
fa - > set_ sids[ fa - > set_s ids_idx] = s - > iid ;
fa - > set_ s ids_idx+ + ;
fa - > set_ iids[ fa - > set_i ids_idx] = s - > iid ;
fa - > set_ i ids_idx+ + ;
} else if ( fb - > cmd = = DETECT_FLOWBITS_CMD_UNSET ) {
if ( ! CheckExpand ( fa - > unset_ sids_idx, & fa - > unset_sids , & fa - > unset_s ids_size) )
if ( ! CheckExpand ( fa - > unset_ iids_idx, & fa - > unset_iids , & fa - > unset_i ids_size) )
return - 1 ;
fa - > unset_ sids[ fa - > unset_s ids_idx] = s - > iid ;
fa - > unset_ s ids_idx+ + ;
fa - > unset_ iids[ fa - > unset_i ids_idx] = s - > iid ;
fa - > unset_ i ids_idx+ + ;
}
}
return 0 ;
@ -679,10 +653,10 @@ int DetectFlowbitsAnalyze(DetectEngineCtx *de_ctx)
if ( array [ i ] . cnts [ DETECT_FLOWBITS_CMD_ISSET ] & &
array [ i ] . cnts [ DETECT_FLOWBITS_CMD_SET ] = = 0 ) {
const Signature * s = de_ctx - > sig_array [ array [ i ] . isset_ s ids[ 0 ] ] ;
const Signature * s = de_ctx - > sig_array [ array [ i ] . isset_ i ids[ 0 ] ] ;
SCLogWarning ( " flowbit '%s' is checked but not "
" set. Checked in %u and %u other sigs " ,
varname , s - > id , array [ i ] . isset_ s ids_idx - 1 ) ;
varname , s - > id , array [ i ] . isset_ i ids_idx - 1 ) ;
}
if ( array [ i ] . state_cnts [ DETECT_FLOWBITS_CMD_ISSET ] & &
array [ i ] . state_cnts [ DETECT_FLOWBITS_CMD_SET ] = = 0 )
@ -709,26 +683,26 @@ int DetectFlowbitsAnalyze(DetectEngineCtx *de_ctx)
array [ i ] . state_cnts [ DETECT_FLOWBITS_CMD_UNSET ] ,
array [ i ] . state_cnts [ DETECT_FLOWBITS_CMD_ISNOTSET ] ,
array [ i ] . state_cnts [ DETECT_FLOWBITS_CMD_ISSET ] ) ;
for ( uint32_t x = 0 ; x < array [ i ] . set_ s ids_idx; x + + ) {
SCLogDebug ( " SET flowbit %s/%u: SID %u" , varname , i ,
de_ctx - > sig_array [ array [ i ] . set_ s ids[ x ] ] - > id ) ;
for ( uint32_t x = 0 ; x < array [ i ] . set_ i ids_idx; x + + ) {
SCLogDebug ( " SET flowbit %s/%u: sid %u" , varname , i ,
de_ctx - > sig_array [ array [ i ] . set_ i ids[ x ] ] - > id ) ;
}
if ( to_state ) {
for ( uint32_t x = 0 ; x < array [ i ] . isset_ s ids_idx; x + + ) {
Signature * s = de_ctx - > sig_array [ array [ i ] . isset_ s ids[ x ] ] ;
SCLogDebug ( " GET flowbit %s/%u: SID %u" , varname , i , s - > id ) ;
for ( uint32_t x = 0 ; x < array [ i ] . isset_ i ids_idx; x + + ) {
Signature * s = de_ctx - > sig_array [ array [ i ] . isset_ i ids[ x ] ] ;
SCLogDebug ( " GET flowbit %s/%u: sid %u" , varname , i , s - > id ) ;
s - > init_data - > init_flags | = SIG_FLAG_INIT_STATE_MATCH ;
s - > init_data - > is_rule_state_dependant = true ;
const uint32_t sids_array_size = array [ i ] . set_s ids_idx;
if ( s ids_array_size = = 0 )
const uint32_t iids_array_size = array [ i ] . set_i ids_idx;
if ( i ids_array_size = = 0 )
continue ;
// save information about flowbits that affect this rule's state
if ( s - > init_data - > rule_state_dependant_sids_array = = NULL ) {
s - > init_data - > rule_state_dependant_sids_array =
SCCalloc ( s ids_array_size, sizeof ( uint32_t ) ) ;
SCCalloc ( i ids_array_size, sizeof ( uint32_t ) ) ;
if ( s - > init_data - > rule_state_dependant_sids_array = = NULL ) {
SCLogError ( " Failed to allocate memory for rule_state_dependant_ids " ) ;
goto error ;
@ -740,14 +714,14 @@ int DetectFlowbitsAnalyze(DetectEngineCtx *de_ctx)
SCLogError ( " Failed to allocate memory for rule_state_variable_idx " ) ;
goto error ;
}
s - > init_data - > rule_state_dependant_sids_size = s ids_array_size;
s - > init_data - > rule_state_dependant_sids_size = i ids_array_size;
SCLogDebug ( " alloc'ed array for rule dependency and fbs idx array, sid %u, "
" sizes are %u and %u " ,
s - > id , s - > init_data - > rule_state_dependant_sids_size ,
s - > init_data - > rule_state_flowbits_ids_size ) ;
} else {
uint32_t new_array_size =
s - > init_data - > rule_state_dependant_sids_size + s ids_array_size;
s - > init_data - > rule_state_dependant_sids_size + i ids_array_size;
void * tmp_ptr = SCRealloc ( s - > init_data - > rule_state_dependant_sids_array ,
new_array_size * sizeof ( uint32_t ) ) ;
if ( tmp_ptr = = NULL ) {
@ -772,10 +746,10 @@ int DetectFlowbitsAnalyze(DetectEngineCtx *de_ctx)
s - > init_data - > rule_state_flowbits_ids_size = new_fb_array_size ;
}
for ( uint32_t idx = 0 ; idx < s - > init_data - > rule_state_dependant_sids_size ; idx + + ) {
if ( idx < array [ i ] . set_ s ids_idx) {
if ( idx < array [ i ] . set_ i ids_idx) {
s - > init_data - > rule_state_dependant_sids_array
[ s - > init_data - > rule_state_dependant_sids_idx ] =
de_ctx - > sig_array [ array [ i ] . set_ s ids[ idx ] ] - > id ;
de_ctx - > sig_array [ array [ i ] . set_ i ids[ idx ] ] - > id ;
s - > init_data - > rule_state_dependant_sids_idx + + ;
}
}
@ -785,8 +759,9 @@ int DetectFlowbitsAnalyze(DetectEngineCtx *de_ctx)
s - > init_data - > rule_state_flowbits_ids_size + = 1 ;
// flowbit info saving for rule made stateful rule work finished
SCLogDebug ( " made SID %u stateful because it depends on "
" stateful rules that set flowbit %s " , s - > id , varname ) ;
SCLogDebug ( " made sid %u stateful because it depends on "
" stateful rules that set flowbit %s " ,
s - > id , varname ) ;
}
}
}
@ -865,17 +840,17 @@ static struct FBAnalyzer DetectFlowbitsAnalyzeForGroup(
array [ i ] . state_cnts [ DETECT_FLOWBITS_CMD_UNSET ] ,
array [ i ] . state_cnts [ DETECT_FLOWBITS_CMD_ISNOTSET ] ,
array [ i ] . state_cnts [ DETECT_FLOWBITS_CMD_ISSET ] ) ;
for ( uint32_t x = 0 ; x < array [ i ] . set_ s ids_idx; x + + ) {
SCLogDebug ( " SET flowbit %s/%u: SID %u" , varname , i ,
de_ctx - > sig_array [ array [ i ] . set_ s ids[ x ] ] - > id ) ;
for ( uint32_t x = 0 ; x < array [ i ] . set_ i ids_idx; x + + ) {
SCLogDebug ( " SET flowbit %s/%u: sid %u" , varname , i ,
de_ctx - > sig_array [ array [ i ] . set_ i ids[ x ] ] - > id ) ;
}
for ( uint32_t x = 0 ; x < array [ i ] . isset_ s ids_idx; x + + ) {
Signature * s = de_ctx - > sig_array [ array [ i ] . isset_ s ids[ x ] ] ;
SCLogDebug ( " GET flowbit %s/%u: SID %u" , varname , i , s - > id ) ;
for ( uint32_t x = 0 ; x < array [ i ] . isset_ i ids_idx; x + + ) {
Signature * s = de_ctx - > sig_array [ array [ i ] . isset_ i ids[ x ] ] ;
SCLogDebug ( " GET flowbit %s/%u: sid %u" , varname , i , s - > id ) ;
if ( to_state ) {
s - > init_data - > init_flags | = SIG_FLAG_INIT_STATE_MATCH ;
SCLogDebug ( " made SID %u stateful because it depends on "
SCLogDebug ( " made sid %u stateful because it depends on "
" stateful rules that set flowbit %s " ,
s - > id , varname ) ;
}
@ -912,8 +887,8 @@ static void DetectFlowbitsAnalyzeDump(const DetectEngineCtx *de_ctx,
// sets
if ( e - > cnts [ DETECT_FLOWBITS_CMD_SET ] ) {
SCJbOpenArray ( js , " sets " ) ;
for ( uint32_t i = 0 ; i < e - > set_ s ids_idx; i + + ) {
const Signature * s = de_ctx - > sig_array [ e - > set_ s ids[ i ] ] ;
for ( uint32_t i = 0 ; i < e - > set_ i ids_idx; i + + ) {
const Signature * s = de_ctx - > sig_array [ e - > set_ i ids[ i ] ] ;
SCJbAppendUint ( js , s - > id ) ;
}
SCJbClose ( js ) ;
@ -921,8 +896,8 @@ static void DetectFlowbitsAnalyzeDump(const DetectEngineCtx *de_ctx,
// gets
if ( e - > cnts [ DETECT_FLOWBITS_CMD_ISSET ] ) {
SCJbOpenArray ( js , " isset " ) ;
for ( uint32_t i = 0 ; i < e - > isset_ s ids_idx; i + + ) {
const Signature * s = de_ctx - > sig_array [ e - > isset_ s ids[ i ] ] ;
for ( uint32_t i = 0 ; i < e - > isset_ i ids_idx; i + + ) {
const Signature * s = de_ctx - > sig_array [ e - > isset_ i ids[ i ] ] ;
SCJbAppendUint ( js , s - > id ) ;
}
SCJbClose ( js ) ;
@ -930,8 +905,8 @@ static void DetectFlowbitsAnalyzeDump(const DetectEngineCtx *de_ctx,
// isnotset
if ( e - > cnts [ DETECT_FLOWBITS_CMD_ISNOTSET ] ) {
SCJbOpenArray ( js , " isnotset " ) ;
for ( uint32_t i = 0 ; i < e - > isnotset_ s ids_idx; i + + ) {
const Signature * s = de_ctx - > sig_array [ e - > isnotset_ s ids[ i ] ] ;
for ( uint32_t i = 0 ; i < e - > isnotset_ i ids_idx; i + + ) {
const Signature * s = de_ctx - > sig_array [ e - > isnotset_ i ids[ i ] ] ;
SCJbAppendUint ( js , s - > id ) ;
}
SCJbClose ( js ) ;
@ -939,8 +914,8 @@ static void DetectFlowbitsAnalyzeDump(const DetectEngineCtx *de_ctx,
// unset
if ( e - > cnts [ DETECT_FLOWBITS_CMD_UNSET ] ) {
SCJbOpenArray ( js , " unset " ) ;
for ( uint32_t i = 0 ; i < e - > unset_ s ids_idx; i + + ) {
const Signature * s = de_ctx - > sig_array [ e - > unset_ s ids[ i ] ] ;
for ( uint32_t i = 0 ; i < e - > unset_ i ids_idx; i + + ) {
const Signature * s = de_ctx - > sig_array [ e - > unset_ i ids[ i ] ] ;
SCJbAppendUint ( js , s - > id ) ;
}
SCJbClose ( js ) ;
@ -1180,15 +1155,15 @@ static uint32_t NextMultiple(const uint32_t v, const uint32_t m)
/** \internal
* \ brief adds sids for ' isset ' prefilter flowbits
* \ retval int 1 if we added s id( s ) , 0 if we didn ' t , - 1 on error */
* \ retval int 1 if we added i id( s ) , 0 if we didn ' t , - 1 on error */
// TODO skip sids that aren't set by this sgh
// TODO skip sids that doesn't have a isset in the same direction
static int AddIsset S idsForBit( const DetectEngineCtx * de_ctx , const struct FBAnalyzer * fba ,
static int AddIsset I idsForBit( const DetectEngineCtx * de_ctx , const struct FBAnalyzer * fba ,
const DetectFlowbitsData * fb , PrefilterFlowbit * add )
{
int added = 0 ;
for ( uint32_t i = 0 ; i < fba - > array [ fb - > idx ] . isset_ s ids_idx; i + + ) {
const uint32_t sig_iid = fba - > array [ fb - > idx ] . isset_ s ids[ i ] ;
for ( uint32_t i = 0 ; i < fba - > array [ fb - > idx ] . isset_ i ids_idx; i + + ) {
const uint32_t sig_iid = fba - > array [ fb - > idx ] . isset_ i ids[ i ] ;
const Signature * s = de_ctx - > sig_array [ sig_iid ] ;
SCLogDebug ( " flowbit: %u => considering sid %u (iid:%u) " , fb - > idx , s - > id , s - > iid ) ;
@ -1264,15 +1239,15 @@ static int AddBitSet(const DetectEngineCtx *de_ctx, struct FBAnalyzer *fba,
return - 1 ;
add - > id = fb - > idx ;
add - > rule_id_size = NextMultiple ( fba - > array [ fb - > idx ] . isset_ s ids_idx, BLOCK_SIZE ) ;
add - > rule_id_size = NextMultiple ( fba - > array [ fb - > idx ] . isset_ i ids_idx, BLOCK_SIZE ) ;
add - > rule_id = SCCalloc ( 1 , add - > rule_id_size * sizeof ( uint32_t ) ) ;
if ( add - > rule_id = = NULL ) {
SCFree ( add ) ;
return - 1 ;
}
if ( AddIsset S idsForBit( de_ctx , fba , fb , add ) ! = 1 ) {
SCLogDebug ( " no s ids added" ) ;
if ( AddIsset I idsForBit( de_ctx , fba , fb , add ) ! = 1 ) {
SCLogDebug ( " no i ids added" ) ;
SCFree ( add - > rule_id ) ;
SCFree ( add ) ;
return 0 ;
@ -1283,11 +1258,11 @@ static int AddBitSet(const DetectEngineCtx *de_ctx, struct FBAnalyzer *fba,
} else {
SCLogDebug ( " found! pfb %p id %u " , pfb , pfb - > id ) ;
int r = AddIsset S idsForBit( de_ctx , fba , fb , pfb ) ;
int r = AddIsset I idsForBit( de_ctx , fba , fb , pfb ) ;
if ( r < 0 ) {
return - 1 ;
} else if ( r = = 0 ) {
SCLogDebug ( " no s ids added" ) ;
SCLogDebug ( " no i ids added" ) ;
return 0 ;
}
}
@ -1340,8 +1315,8 @@ static int PrefilterSetupFlowbits(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
continue ;
}
if ( fb_analysis . array [ fb - > idx ] . isnotset_ s ids_idx | |
fb_analysis . array [ fb - > idx ] . unset_ s ids_idx) {
if ( fb_analysis . array [ fb - > idx ] . isnotset_ i ids_idx | |
fb_analysis . array [ fb - > idx ] . unset_ i ids_idx) {
SCLogDebug ( " flowbit %u not supported: unset in use " , fb - > idx ) ;
continue ;
}
@ -1373,8 +1348,8 @@ static int PrefilterSetupFlowbits(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
}
const DetectFlowbitsData * fb = ( DetectFlowbitsData * ) s - > init_data - > prefilter_sm - > ctx ;
if ( fb_analysis . array [ fb - > idx ] . isnotset_ s ids_idx | |
fb_analysis . array [ fb - > idx ] . unset_ s ids_idx) {
if ( fb_analysis . array [ fb - > idx ] . isnotset_ i ids_idx | |
fb_analysis . array [ fb - > idx ] . unset_ i ids_idx) {
SCLogDebug ( " flowbit %u not supported: unset in use " , fb - > idx ) ;
s - > init_data - > prefilter_sm = NULL ;
s - > flags & = ~ SIG_FLAG_PREFILTER ;