/** Copyright (c) 2009 Open Information Security Foundation. * \author Anoop Saldanha */ #include #include #include #include #include "eidps-common.h" #include "detect.h" #include "detect-flowbits.h" #include "detect-engine-sigorder.h" #include "detect-pcre.h" #include "util-unittest.h" #include "util-debug.h" #define DETECT_FLOWVAR_NOT_USED 1 #define DETECT_FLOWVAR_TYPE_READ 2 #define DETECT_FLOWVAR_TYPE_SET 3 #define DETECT_PKTVAR_NOT_USED 1 #define DETECT_PKTVAR_TYPE_READ 2 #define DETECT_PKTVAR_TYPE_SET 3 /** * \brief Registers a keyword-based, signature ordering function * * \param de_ctx Pointer to the detection engine context from which the * signatures have to be ordered. * \param FuncPtr Pointer to the signature ordering function. The prototype of * the signature ordering function should accept a pointer to a * SCSigSignatureWrapper as its argument and shouldn't return * anything */ static void SCSigRegisterSignatureOrderingFunc(DetectEngineCtx *de_ctx, void (*FuncPtr)(DetectEngineCtx *de_ctx, SCSigSignatureWrapper *)) { SCSigOrderFunc *curr = NULL; SCSigOrderFunc *prev = NULL; SCSigOrderFunc *temp = NULL; curr = de_ctx->sc_sig_order_funcs; prev = curr; while (curr != NULL) { prev = curr; if (curr->FuncPtr == FuncPtr) break; curr = curr->next; } if (curr != NULL) return; if ( (temp = malloc(sizeof(SCSigOrderFunc))) == NULL) { printf("Error allocating memory\n"); exit(EXIT_FAILURE); } memset(temp, 0, sizeof(SCSigOrderFunc)); temp->FuncPtr = FuncPtr; if (prev == NULL) de_ctx->sc_sig_order_funcs = temp; else prev->next = temp; return; } /** * \brief Returns the flowbit type set for this signature. If more than one * flowbit has been set for the same rule, we return the flowbit type of * the maximum priority/value, where priority/value is maximum for the * ones that set the value and the lowest for ones that read the value. * If no flowbit has been set for the rule, we return 0, which indicates * the least value amongst flowbit types. * * \param sig Pointer to the Signature from which the flowbit value has to be * returned. * * \retval flowbits The flowbits type for this signature if it is set; if it is * not set, return 0 */ static inline int SCSigGetFlowbitsType(Signature *sig) { SigMatch *sm = sig->match; DetectFlowbitsData *fb = NULL; int flowbits = 0; while (sm != NULL) { if (sm->type == DETECT_FLOWBITS) { fb = (DetectFlowbitsData *)sm->ctx; if (flowbits < fb->cmd) flowbits = fb->cmd; } sm = sm->next; } return flowbits; } /** * \brief Returns whether the flowvar set for this rule, sets the flowvar or * reads the flowvar. If the rule sets the flowvar the function returns * DETECT_FLOWVAR_TYPE_SET(3), if it reads the flowvar the function * returns DETECT_FLOWVAR_TYPE_READ(2), and if flowvar is not used in this * rule the function returns DETECT_FLOWVAR_NOT_USED(1) * * \param sig Pointer to the Signature from which the flowvar type has to be * returned. * * \retval type DETECT_FLOWVAR_TYPE_SET(3) if the rule sets the flowvar, * DETECT_FLOWVAR_TYPE_READ(2) if it reads, and * DETECT_FLOWVAR_NOT_USED(1) if flowvar is not used. */ static inline int SCSigGetFlowvarType(Signature *sig) { SigMatch *sm = sig->match; DetectPcreData *pd = NULL; int type = DETECT_FLOWVAR_NOT_USED; while (sm != NULL) { pd = (DetectPcreData *)sm->ctx; if (sm->type == DETECT_PCRE && pd->flags & DETECT_PCRE_CAPTURE_FLOW) { type = DETECT_FLOWVAR_TYPE_SET; return type; } if (sm->type == DETECT_FLOWVAR) type = DETECT_FLOWVAR_TYPE_READ; sm = sm->next; } return type; } /** * \brief Returns whether the pktvar set for this rule, sets the flowvar or * reads the pktvar. If the rule sets the pktvar the function returns * DETECT_PKTVAR_TYPE_SET(3), if it reads the pktvar the function * returns DETECT_PKTVAR_TYPE_READ(2), and if pktvar is not used in this * rule the function returns DETECT_PKTVAR_NOT_USED(1) * * \param sig Pointer to the Signature from which the pktvar type has to be * returned. * * \retval type DETECT_PKTVAR_TYPE_SET(3) if the rule sets the flowvar, * DETECT_PKTVAR_TYPE_READ(2) if it reads, and * DETECT_PKTVAR_NOT_USED(1) if pktvar is not used. */ static inline int SCSigGetPktvarType(Signature *sig) { SigMatch *sm = sig->match; DetectPcreData *pd = NULL; int type = DETECT_PKTVAR_NOT_USED; while (sm != NULL) { pd = (DetectPcreData *)sm->ctx; if (sm->type == DETECT_PCRE && pd->flags & DETECT_PCRE_CAPTURE_PKT) { type = DETECT_PKTVAR_TYPE_SET; return type; } if (sm->type == DETECT_PKTVAR) type = DETECT_PKTVAR_TYPE_READ; sm = sm->next; } return type; } /** * \brief Processes the flowbits data for this signature and caches it for * future use. This is needed to optimize the sig_ordering module. * * \param sw The sigwrapper/signature for which the flowbits data has to be * cached */ static inline void SCSigProcessUserDataForFlowbits(SCSigSignatureWrapper *sw) { *((int *)(sw->user[SC_RADIX_USER_DATA_FLOWBITS])) = SCSigGetFlowbitsType(sw->sig); return; } /** * \brief Processes the flowvar data for this signature and caches it for * future use. This is needed to optimize the sig_ordering module. * * \param sw The sigwrapper/signature for which the flowvar data has to be * cached */ static inline void SCSigProcessUserDataForFlowvar(SCSigSignatureWrapper *sw) { *((int *)(sw->user[SC_RADIX_USER_DATA_FLOWVAR])) = SCSigGetFlowvarType(sw->sig); return; } /** * \brief Processes the pktvar data for this signature and caches it for * future use. This is needed to optimize the sig_ordering module. * * \param sw The sigwrapper/signature for which the pktvar data has to be * cached */ static inline void SCSigProcessUserDataForPktvar(SCSigSignatureWrapper *sw) { *((int *)(sw->user[SC_RADIX_USER_DATA_PKTVAR])) = SCSigGetPktvarType(sw->sig); return; } /** * \brief Orders an incoming Signature based on its action * * \param de_ctx Pointer to the detection engine context from which the * signatures have to be ordered. * \param sw The new signature that has to be ordered based on its action */ static void SCSigOrderByAction(DetectEngineCtx *de_ctx, SCSigSignatureWrapper *sw) { SCSigSignatureWrapper *min = NULL; SCSigSignatureWrapper *max = NULL; SCSigSignatureWrapper *prev = NULL; if (de_ctx->sc_sig_sig_wrapper == NULL) { de_ctx->sc_sig_sig_wrapper = sw; sw->min = NULL; sw->max = NULL; return; } min = sw->min; max = sw->max; if (min == NULL) min = de_ctx->sc_sig_sig_wrapper; else min = min->next; while (min != max) { prev = min; /* the sorting logic */ if (sw->sig->action <= min->sig->action) { min = min->next; continue; } if (min->prev == sw) break; if (sw->next != NULL) sw->next->prev = sw->prev; if (sw->prev != NULL) sw->prev->next = sw->next; if (de_ctx->sc_sig_sig_wrapper == sw) de_ctx->sc_sig_sig_wrapper = sw->next; sw->next = min; sw->prev = min->prev; if (min->prev != NULL) min->prev->next = sw; else de_ctx->sc_sig_sig_wrapper = sw; min->prev = sw; break; } if (min == max && prev != sw) { if (sw->next != NULL) { sw->next->prev = sw->prev; sw->prev->next = sw->next; } if (min == NULL) { prev->next = sw; sw->prev = prev; sw->next = NULL; } else { sw->prev = min->prev; sw->next = min; min->prev->next = sw; min->prev = sw; } } /* set the min signature for this keyword, for the next ordering function */ min = sw; while (min != sw->min) { if (min->sig->action != sw->sig->action) break; min = min->prev; } sw->min = min; /* set the max signature for this keyword + 1, for the next ordering func */ max = sw; while (max != sw->max) { if (max->sig->action != sw->sig->action) break; max = max->next; } sw->max = max; return; } /** * \brief Orders an incoming Signature based on its flowbits type * * \param de_ctx Pointer to the detection engine context from which the * signatures have to be ordered. * \param sw The new signature that has to be ordered based on its flowbits */ static void SCSigOrderByFlowbits(DetectEngineCtx *de_ctx, SCSigSignatureWrapper *sw) { SCSigSignatureWrapper *min = NULL; SCSigSignatureWrapper *max = NULL; SCSigSignatureWrapper *prev = NULL; if (de_ctx->sc_sig_sig_wrapper == NULL) { de_ctx->sc_sig_sig_wrapper = sw; sw->min = NULL; sw->max = NULL; return; } min = sw->min; max = sw->max; if (min == NULL) min = de_ctx->sc_sig_sig_wrapper; else min = min->next; while (min != max) { prev = min; /* the sorting logic */ if ( *((int *)(sw->user[SC_RADIX_USER_DATA_FLOWBITS])) <= *((int *)(min->user[SC_RADIX_USER_DATA_FLOWBITS])) ) { min = min->next; continue; } if (min->prev == sw) break; if (sw->next != NULL) sw->next->prev = sw->prev; if (sw->prev != NULL) sw->prev->next = sw->next; if (de_ctx->sc_sig_sig_wrapper == sw) de_ctx->sc_sig_sig_wrapper = sw->next; sw->next = min; sw->prev = min->prev; if (min->prev != NULL) min->prev->next = sw; else de_ctx->sc_sig_sig_wrapper = sw; min->prev = sw; break; } if (min == max && prev != sw) { if (sw->next != NULL) { sw->next->prev = sw->prev; sw->prev->next = sw->next; } if (min == NULL) { prev->next = sw; sw->prev = prev; sw->next = NULL; } else { sw->prev = min->prev; sw->next = min; min->prev->next = sw; min->prev = sw; } } /* set the min signature for this keyword, for the next ordering function */ min = sw; while (min != sw->min) { if ( *((int *)(sw->user[SC_RADIX_USER_DATA_FLOWBITS])) != *((int *)(min->user[SC_RADIX_USER_DATA_FLOWBITS])) ) break; min = min->prev; } sw->min = min; /* set the max signature for this keyword + 1, for the next ordering func */ max = sw; while (max != sw->max) { if ( *((int *)(sw->user[SC_RADIX_USER_DATA_FLOWBITS])) != *((int *)(max->user[SC_RADIX_USER_DATA_FLOWBITS])) ) break; max = max->next; } sw->max = max; return; } /** * \brief Orders an incoming Signature based on its flowvar type * * \param de_ctx Pointer to the detection engine context from which the * signatures have to be ordered. * \param sw The new signature that has to be ordered based on its flowvar */ static void SCSigOrderByFlowvar(DetectEngineCtx *de_ctx, SCSigSignatureWrapper *sw) { SCSigSignatureWrapper *min = NULL; SCSigSignatureWrapper *max = NULL; SCSigSignatureWrapper *prev = NULL; if (de_ctx->sc_sig_sig_wrapper == NULL) { de_ctx->sc_sig_sig_wrapper = sw; sw->min = NULL; sw->max = NULL; return; } min = sw->min; max = sw->max; if (min == NULL) min = de_ctx->sc_sig_sig_wrapper; else min = min->next; while (min != max) { prev = min; /* the sorting logic */ if ( *((int *)(sw->user[SC_RADIX_USER_DATA_FLOWVAR])) <= *((int *)(min->user[SC_RADIX_USER_DATA_FLOWVAR])) ) { min = min->next; continue; } if (min->prev == sw) break; if (sw->next != NULL) sw->next->prev = sw->prev; if (sw->prev != NULL) sw->prev->next = sw->next; if (de_ctx->sc_sig_sig_wrapper == sw) de_ctx->sc_sig_sig_wrapper = sw->next; sw->next = min; sw->prev = min->prev; if (min->prev != NULL) min->prev->next = sw; else de_ctx->sc_sig_sig_wrapper = sw; min->prev = sw; break; } if (min == max && prev != sw) { if (sw->next != NULL) { sw->next->prev = sw->prev; sw->prev->next = sw->next; } if (min == NULL) { prev->next = sw; sw->prev = prev; sw->next = NULL; } else { sw->prev = min->prev; sw->next = min; min->prev->next = sw; min->prev = sw; } } /* set the min signature for this keyword, for the next ordering function */ min = sw; while (min != sw->min) { if ( *((int *)(sw->user[SC_RADIX_USER_DATA_FLOWVAR])) != *((int *)(min->user[SC_RADIX_USER_DATA_FLOWVAR])) ) break; min = min->prev; } sw->min = min; /* set the max signature for this keyword + 1, for the next ordering func */ max = sw; while (max != sw->max) { if ( *((int *)(sw->user[SC_RADIX_USER_DATA_FLOWVAR])) != *((int *)(max->user[SC_RADIX_USER_DATA_FLOWVAR])) ) break; max = max->next; } sw->max = max; return; } /** * \brief Orders an incoming Signature based on its pktvar type * * \param de_ctx Pointer to the detection engine context from which the * signatures have to be ordered. * \param sw The new signature that has to be ordered based on its pktvar */ static void SCSigOrderByPktvar(DetectEngineCtx *de_ctx, SCSigSignatureWrapper *sw) { SCSigSignatureWrapper *min = NULL; SCSigSignatureWrapper *max = NULL; SCSigSignatureWrapper *prev = NULL; if (de_ctx->sc_sig_sig_wrapper == NULL) { de_ctx->sc_sig_sig_wrapper = sw; sw->min = NULL; sw->max = NULL; return; } min = sw->min; max = sw->max; if (min == NULL) min = de_ctx->sc_sig_sig_wrapper; else min = min->next; while (min != max) { prev = min; /* the sorting logic */ if ( *((int *)(sw->user[SC_RADIX_USER_DATA_PKTVAR])) <= *((int *)(min->user[SC_RADIX_USER_DATA_PKTVAR])) ) { min = min->next; continue; } if (min->prev == sw) break; if (sw->next != NULL) sw->next->prev = sw->prev; if (sw->prev != NULL) sw->prev->next = sw->next; if (de_ctx->sc_sig_sig_wrapper == sw) de_ctx->sc_sig_sig_wrapper = sw->next; sw->next = min; sw->prev = min->prev; if (min->prev != NULL) min->prev->next = sw; else de_ctx->sc_sig_sig_wrapper = sw; min->prev = sw; break; } if (min == max && prev != sw) { if (sw->next != NULL) { sw->next->prev = sw->prev; sw->prev->next = sw->next; } if (min == NULL) { prev->next = sw; sw->prev = prev; sw->next = NULL; } else { sw->prev = min->prev; sw->next = min; min->prev->next = sw; min->prev = sw; } } /* set the min signature for this keyword, for the next ordering function */ min = sw; while (min != sw->min) { if ( *((int *)(sw->user[SC_RADIX_USER_DATA_PKTVAR])) != *((int *)(min->user[SC_RADIX_USER_DATA_PKTVAR])) ) break; min = min->prev; } sw->min = min; /* set the max signature for this keyword + 1, for the next ordering func */ max = sw; while (max != sw->max) { if ( *((int *)(sw->user[SC_RADIX_USER_DATA_PKTVAR])) != *((int *)(max->user[SC_RADIX_USER_DATA_PKTVAR])) ) break; max = max->next; } sw->max = max; return; } /** * \brief Orders an incoming Signature based on its priority type * * \param de_ctx Pointer to the detection engine context from which the * signatures have to be ordered. * \param sw The new signature that has to be ordered based on its priority */ static void SCSigOrderByPriority(DetectEngineCtx *de_ctx, SCSigSignatureWrapper *sw) { SCSigSignatureWrapper *min = NULL; SCSigSignatureWrapper *max = NULL; SCSigSignatureWrapper *prev = NULL; if (de_ctx->sc_sig_sig_wrapper == NULL) { de_ctx->sc_sig_sig_wrapper = sw; sw->min = NULL; sw->max = NULL; return; } min = sw->min; max = sw->max; if (min == NULL) min = de_ctx->sc_sig_sig_wrapper; else min = min->next; while (min != max) { prev = min; /* the sorting logic */ if (sw->sig->prio >= min->sig->prio) { min = min->next; continue; } if (min->prev == sw) break; if (sw->next != NULL) sw->next->prev = sw->prev; if (sw->prev != NULL) sw->prev->next = sw->next; if (de_ctx->sc_sig_sig_wrapper == sw) de_ctx->sc_sig_sig_wrapper = sw->next; sw->next = min; sw->prev = min->prev; if (min->prev != NULL) min->prev->next = sw; else de_ctx->sc_sig_sig_wrapper = sw; min->prev = sw; break; } if (min == max && prev != sw) { if (sw->next != NULL) { sw->next->prev = sw->prev; sw->prev->next = sw->next; } if (min == NULL) { prev->next = sw; sw->prev = prev; sw->next = NULL; } else { sw->prev = min->prev; sw->next = min; min->prev->next = sw; min->prev = sw; } } /* set the min signature for this keyword, for the next ordering function */ min = sw; while (min != sw->min) { if (min->sig->prio != sw->sig->prio) break; min = min->prev; } sw->min = min; /* set the max signature for this keyword + 1, for the next ordering func */ max = sw; while (max != sw->max) { if (max->sig->prio != sw->sig->prio) break; max = max->next; } sw->max = max; return; } /** * \brief Creates a Wrapper around the Signature * * \param Pointer to the Signature to be wrapped * * \retval sw Pointer to the wrapper that holds the signature */ static inline SCSigSignatureWrapper *SCSigAllocSignatureWrapper(Signature *sig) { SCSigSignatureWrapper *sw = NULL; int i = 0; if ( (sw = malloc(sizeof(SCSigSignatureWrapper))) == NULL) { printf("Error allocating memory\n"); exit(EXIT_FAILURE); } memset(sw, 0, sizeof(SCSigSignatureWrapper)); sw->sig = sig; if ( (sw->user = malloc(SC_RADIX_USER_DATA_MAX * sizeof(int *))) == NULL) { printf("Error allocating memory\n"); exit(EXIT_FAILURE); } memset(sw->user, 0, SC_RADIX_USER_DATA_MAX * sizeof(int *)); for (i = 0; i < SC_RADIX_USER_DATA_MAX; i++) { if ( (sw->user[i] = malloc(sizeof(int))) == NULL) { printf("Error allocating memory\n"); exit(EXIT_FAILURE); } memset(sw->user[i], 0, sizeof(int)); } /* Process data from the signature into a cache for further use by the * sig_ordering module */ SCSigProcessUserDataForFlowbits(sw); SCSigProcessUserDataForFlowvar(sw); SCSigProcessUserDataForPktvar(sw); return sw; } /** * \brief Orders the signatures * * \param de_ctx Pointer to the Detection Engine Context that holds the * signatures to be ordered */ void SCSigOrderSignatures(DetectEngineCtx *de_ctx) { SCSigOrderFunc *funcs = NULL; Signature *sig = NULL; SCSigSignatureWrapper *sigw = NULL; int i = 0; #ifndef UNITTESTS SCLogInfo("ordering signatures in memory"); #endif sig = de_ctx->sig_list; while (sig != NULL) { i++; sigw = SCSigAllocSignatureWrapper(sig); funcs = de_ctx->sc_sig_order_funcs; while (funcs != NULL) { funcs->FuncPtr(de_ctx, sigw); funcs = funcs->next; } sig = sig->next; } #ifndef UNITTESTS printf("SCSigOrderSignatures: Total Signatures to be processed by the" "sigordering module: %d\n", i); #endif /* Re-order it in the Detection Engine Context sig_list */ de_ctx->sig_list = NULL; sigw = de_ctx->sc_sig_sig_wrapper; i = 0; while (sigw != NULL) { i++; if (de_ctx->sig_list == NULL) { sigw->sig->next = NULL; de_ctx->sig_list = sigw->sig; sig = de_ctx->sig_list; sigw = sigw->next; continue; } sigw->sig->next = NULL; sig->next = sigw->sig; sig = sig->next; sigw = sigw->next; } #ifndef UNITTESTS SCLogInfo("total signatures reordered by the sigordering module: %d", i); #endif return; } /** * \brief Lets you register the Signature ordering functions. The order in * which the functions are registered, show the priority. The first * function registered provides more priority than the function * registered after it. To add a new registration function, register * it by listing it in the correct position in the below sequence, * based on the priority you would want to offer to that keyword. * * \param de_ctx Pointer to the detection engine context from which the * signatures have to be ordered. */ void SCSigRegisterSignatureOrderingFuncs(DetectEngineCtx *de_ctx) { SCLogDebug("registering signature ordering functions"); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByAction); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbits); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvar); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvar); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriority); return; } /** * \brief De-registers all the signature ordering functions registered * * \param de_ctx Pointer to the detection engine context from which the * signatures were ordered. */ void SCSigSignatureOrderingModuleCleanup(DetectEngineCtx *de_ctx) { SCSigOrderFunc *funcs = NULL; SCSigSignatureWrapper *sigw = NULL; void *temp = NULL; /* clean the memory alloted to the signature ordering funcs */ funcs = de_ctx->sc_sig_order_funcs; while (funcs != NULL) { temp = funcs; funcs = funcs->next; free(temp); } de_ctx->sc_sig_order_funcs = NULL; /* clean the memory alloted to the signature wrappers */ sigw = de_ctx->sc_sig_sig_wrapper; while (sigw != NULL) { temp = sigw; sigw = sigw->next; free(temp); } de_ctx->sc_sig_sig_wrapper = NULL; return; } /* -------------------------------------Unittests-----------------------------*/ DetectEngineCtx *DetectEngineCtxInit(void); Signature *SigInit(DetectEngineCtx *, char *); void SigFree(Signature *); void DetectEngineCtxFree(DetectEngineCtx *); #ifdef UNITTESTS static int SCSigTestSignatureOrdering01(void) { SCSigOrderFunc *temp = NULL; int i = 0; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) goto end; SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByAction); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByAction); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByAction); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByAction); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByAction); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriority); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbits); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbits); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvar); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvar); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvar); temp = de_ctx->sc_sig_order_funcs; while (temp != NULL) { i++; temp = temp->next; } DetectEngineCtxFree(de_ctx); return (i == 5); end: return 0; } static int SCSigTestSignatureOrdering02(void) { int result = 1; Signature *prevsig = NULL, *sig = NULL; SCSigSignatureWrapper *sw = NULL; int prev_code = 0; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) goto end; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4;)"); if (sig == NULL) { goto end; } prevsig = sig; de_ctx->sig_list = sig; sig = SigInit(de_ctx, "drop tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "drop tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; flowvar:http_host,\"www.oisf.net\"; rev:4; priority:1; )"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "reject tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4; priority:1;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; content:\"220\"; offset:10; depth:4; classtype:non-standard-protocol; sid:2003055; rev:4; priority:3;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4; priority:3;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4; priority:2;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "reject tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; classtype:non-standard-protocol; sid:2003055; rev:4; priority:3; flowbits:set,TEST.one; flowbits:noalert;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "rejectsrc tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4;priority:3;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "rejectdst tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "rejectboth tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "reject tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4; pktvar:http_host,\"www.oisf.net\"; priority:2; flowbits:isnotset,TEST.two;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "reject tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4; priority:2; flowbits:set,TEST.two;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByAction); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbits); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvar); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvar); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriority); SCSigOrderSignatures(de_ctx); sw = de_ctx->sc_sig_sig_wrapper; #ifdef DEBUG printf("%d - ", sw->sig->action); printf("%d - ", SCSigGetFlowbitsType(sw->sig)); printf("%d - ", SCSigGetFlowvarType(sw->sig)); printf("%d - ", SCSigGetPktvarType(sw->sig)); printf("%d\n", sw->sig->prio); #endif prev_code = sw->sig->action; sw = sw->next; while (sw != NULL) { #ifdef DEBUG printf("%d - ", sw->sig->action); printf("%d - ", SCSigGetFlowbitsType(sw->sig)); printf("%d - ", SCSigGetFlowvarType(sw->sig)); printf("%d - ", SCSigGetPktvarType(sw->sig)); printf("%d\n", sw->sig->prio); #endif result &= (prev_code >= sw->sig->action); prev_code = sw->sig->action; sw = sw->next; } DetectEngineCtxFree(de_ctx); end: return result; } static int SCSigTestSignatureOrdering03(void) { int result = 1; Signature *prevsig = NULL, *sig = NULL; SCSigSignatureWrapper *sw = NULL; int prev_code = 0; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) goto end; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4; priority:3;)"); if (sig == NULL) { goto end; } prevsig = sig; de_ctx->sig_list = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4; priority:2;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; classtype:non-standard-protocol; sid:2003055; flowbits:unset,TEST.one; rev:4; priority:2;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; flowbits:isset,TEST.one; sid:2003055; rev:4; priority:1;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4; priority:2;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; flowbits:isnotset,TEST.one; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; sid:2003055; rev:4;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; flowbits:unset,TEST.one; classtype:non-standard-protocol; sid:2003055; rev:4; priority:3;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; flowbits:toggle,TEST.one; classtype:non-standard-protocol; sid:2003055; rev:4; priority:1; pktvar:http_host,\"www.oisf.net\";)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; classtype:non-standard-protocol; sid:2003055; rev:4; flowbits:set,TEST.one; flowbits:noalert; pktvar:http_host,\"www.oisf.net\";)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4; priority:3;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4; flowbits:isnotset,TEST.one;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4; flowbits:set,TEST.one;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByAction); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbits); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvar); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvar); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriority); SCSigOrderSignatures(de_ctx); sw = de_ctx->sc_sig_sig_wrapper; #ifdef DEBUG printf("%d\n", SCSigGetFlowbitsType(sw->sig)); #endif prev_code = SCSigGetFlowbitsType(sw->sig); sw = sw->next; while (sw != NULL) { #ifdef DEBUG printf("%d\n", SCSigGetFlowbitsType(sw->sig)); #endif result &= (prev_code >= SCSigGetFlowbitsType(sw->sig)); prev_code = SCSigGetFlowbitsType(sw->sig); sw = sw->next; } DetectEngineCtxFree(de_ctx); end: return result; } static int SCSigTestSignatureOrdering04(void) { int result = 1; Signature *prevsig = NULL, *sig = NULL; SCSigSignatureWrapper *sw = NULL; int prev_code = 0; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) goto end; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4;)"); if (sig == NULL) { goto end; } prevsig = sig; de_ctx->sig_list = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; content:\"220\"; offset:10; classtype:non-standard-protocol; sid:2003055; rev:4; priority:3;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; classtype:non-standard-protocol; sid:2003055; rev:4; priority:3;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; classtype:non-standard-protocol; sid:2003055; rev:4; priority:3; flowvar:http_host,\"www.oisf.net\";)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4;priority:3;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; classtype:non-standard-protocol; pktvar:http_host,\"www.oisf.net\"; sid:2003055; rev:4; priority:1; )"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4; flowvar:http_host,\"www.oisf.net\"; pktvar:http_host,\"www.oisf.net\"; priority:1;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4; priority:2; flowvar:http_host,\"www.oisf.net\";)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4; priority:2; flowvar:http_host,\"www.oisf.net\";)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByAction); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbits); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvar); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvar); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriority); SCSigOrderSignatures(de_ctx); sw = de_ctx->sc_sig_sig_wrapper; #ifdef DEBUG printf("%d - ", SCSigGetFlowvarType(sw->sig)); #endif prev_code = SCSigGetFlowvarType(sw->sig); sw = sw->next; while (sw != NULL) { #ifdef DEBUG printf("%d - ", SCSigGetFlowvarType(sw->sig)); #endif result &= (prev_code >= SCSigGetFlowvarType(sw->sig)); prev_code = SCSigGetFlowvarType(sw->sig); sw = sw->next; } DetectEngineCtxFree(de_ctx); end: return result; } static int SCSigTestSignatureOrdering05(void) { int result = 1; Signature *prevsig = NULL, *sig = NULL; SCSigSignatureWrapper *sw = NULL; int prev_code = 0; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) goto end; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4;)"); if (sig == NULL) { goto end; } prevsig = sig; de_ctx->sig_list = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; content:\"220\"; offset:10; classtype:non-standard-protocol; sid:2003055; rev:4; priority:3;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; classtype:non-standard-protocol; sid:2003055; rev:4; priority:3;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; classtype:non-standard-protocol; sid:2003055; rev:4; priority:3; pktvar:http_host,\"www.oisf.net\";)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4;priority:3;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4; pktvar:http_host,\"www.oisf.net\";)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4; priority:2; pktvar:http_host,\"www.oisf.net\";)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByAction); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbits); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvar); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvar); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriority); SCSigOrderSignatures(de_ctx); sw = de_ctx->sc_sig_sig_wrapper; #ifdef DEBUG printf("%d - ", SCSigGetPktvarType(sw->sig)); #endif prev_code = SCSigGetPktvarType(sw->sig); sw = sw->next; while (sw != NULL) { #ifdef DEBUG printf("%d - ", SCSigGetPktvarType(sw->sig)); #endif result &= (prev_code >= SCSigGetPktvarType(sw->sig)); prev_code = SCSigGetPktvarType(sw->sig); sw = sw->next; } DetectEngineCtxFree(de_ctx); end: return result; } static int SCSigTestSignatureOrdering06(void) { int result = 1; Signature *prevsig = NULL, *sig = NULL; SCSigSignatureWrapper *sw = NULL; int prev_code = 0; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) goto end; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4;)"); if (sig == NULL) { goto end; } prevsig = sig; de_ctx->sig_list = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; classtype:non-standard-protocol; sid:2003055; rev:4; priority:2;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; classtype:non-standard-protocol; sid:2003055; rev:4; priority:3;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; classtype:non-standard-protocol; sid:2003055; rev:4; priority:2;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4; priority:2;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4; priority:1;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4; priority:2;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; classtype:non-standard-protocol; sid:2003055; rev:4; priority:2;)"); if (sig == NULL) { goto end; } prevsig->next = sig; prevsig = sig; SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByAction); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbits); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvar); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvar); SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriority); SCSigOrderSignatures(de_ctx); sw = de_ctx->sc_sig_sig_wrapper; #ifdef DEBUG printf("%d - ", sw->sig->prio); #endif prev_code = sw->sig->prio; sw = sw->next; while (sw != NULL) { #ifdef DEBUG printf("%d - ", sw->sig->prio); #endif result &= (prev_code <= sw->sig->prio); prev_code = sw->sig->prio; sw = sw->next; } DetectEngineCtxFree(de_ctx); end: return result; } #endif void SCSigRegisterSignatureOrderingTests(void) { #ifdef UNITTESTS UtRegisterTest("SCSigTestSignatureOrdering01", SCSigTestSignatureOrdering01, 1); UtRegisterTest("SCSigTestSignatureOrdering02", SCSigTestSignatureOrdering02, 1); UtRegisterTest("SCSigTestSignatureOrdering03", SCSigTestSignatureOrdering03, 1); UtRegisterTest("SCSigTestSignatureOrdering04", SCSigTestSignatureOrdering04, 1); UtRegisterTest("SCSigTestSignatureOrdering05", SCSigTestSignatureOrdering05, 1); UtRegisterTest("SCSigTestSignatureOrdering06", SCSigTestSignatureOrdering06, 1); #endif }