hostbits: implement sigorder

Like with flowbits, make sure that 'set's are evaluated before
'isset's, etc.
pull/1422/head
Victor Julien 11 years ago
parent 5c880377ae
commit d67fd306f8

@ -25,6 +25,7 @@
#include "suricata-common.h"
#include "detect.h"
#include "detect-hostbits.h"
#include "detect-flowbits.h"
#include "detect-flowint.h"
#include "detect-parse.h"
@ -58,6 +59,11 @@
#define DETECT_FLOWINT_TYPE_SET_READ 3
#define DETECT_FLOWINT_TYPE_SET 4
#define DETECT_HOSTBITS_NOT_USED 1
#define DETECT_HOSTBITS_TYPE_READ 2
#define DETECT_HOSTBITS_TYPE_SET_READ 3
#define DETECT_HOSTBITS_TYPE_SET 4
/**
* \brief Registers a keyword-based, signature ordering function
@ -340,6 +346,75 @@ static inline int SCSigGetPktvarType(Signature *sig)
return type;
}
/**
* \brief Returns the hostbit type set for this signature. If more than one
* hostbit has been set for the same rule, we return the hostbit 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 hostbit has been set for the rule, we return 0, which indicates
* the least value amongst hostbit types.
*
* \param sig Pointer to the Signature from which the hostbit value has to be
* returned.
*
* \retval hostbits The hostbits type for this signature if it is set; if it is
* not set, return 0
*/
static inline int SCSigGetHostbitsType(Signature *sig)
{
DetectHostbitsData *fb = NULL;
int hostbits_user_type = DETECT_HOSTBITS_NOT_USED;
int read = 0;
int write = 0;
SigMatch *sm = sig->sm_lists[DETECT_SM_LIST_MATCH];
while (sm != NULL) {
if (sm->type == DETECT_HOSTBITS) {
fb = (DetectHostbitsData *)sm->ctx;
if (fb->cmd == DETECT_HOSTBITS_CMD_ISNOTSET ||
fb->cmd == DETECT_HOSTBITS_CMD_ISSET) {
read++;
} else {
#ifdef DEBUG
BUG_ON(1);
#endif
}
}
sm = sm->next;
}
sm = sig->sm_lists[DETECT_SM_LIST_POSTMATCH];
while (sm != NULL) {
if (sm->type == DETECT_HOSTBITS) {
fb = (DetectHostbitsData *)sm->ctx;
if (fb->cmd == DETECT_HOSTBITS_CMD_SET ||
fb->cmd == DETECT_HOSTBITS_CMD_UNSET ||
fb->cmd == DETECT_HOSTBITS_CMD_TOGGLE) {
write++;
} else {
#ifdef DEBUG
BUG_ON(1);
#endif
}
}
sm = sm->next;
}
if (read > 0 && write == 0) {
hostbits_user_type = DETECT_HOSTBITS_TYPE_READ;
} else if (read == 0 && write > 0) {
hostbits_user_type = DETECT_HOSTBITS_TYPE_SET;
} else if (read > 0 && write > 0) {
hostbits_user_type = DETECT_HOSTBITS_TYPE_SET_READ;
}
SCLogDebug("Sig %s typeval %d", sig->msg, hostbits_user_type);
return hostbits_user_type;
}
/**
* \brief Processes the flowbits data for this signature and caches it for
* future use. This is needed to optimize the sig_ordering module.
@ -381,6 +456,18 @@ static inline void SCSigProcessUserDataForPktvar(SCSigSignatureWrapper *sw)
sw->user[SC_RADIX_USER_DATA_PKTVAR] = SCSigGetPktvarType(sw->sig);
}
/**
* \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 SCSigProcessUserDataForHostbits(SCSigSignatureWrapper *sw)
{
sw->user[SC_RADIX_USER_DATA_HOSTBITS] = SCSigGetHostbitsType(sw->sig);
}
/* Return 1 if sw1 comes before sw2 in the final list. */
static int SCSigLessThan(SCSigSignatureWrapper *sw1,
SCSigSignatureWrapper *sw2,
@ -528,6 +615,20 @@ static int SCSigOrderByFlowintCompare(SCSigSignatureWrapper *sw1,
sw2->user[SC_RADIX_USER_DATA_FLOWINT];
}
/**
* \brief Orders an incoming Signature based on its hostbits 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 hostbits
*/
static int SCSigOrderByHostbitsCompare(SCSigSignatureWrapper *sw1,
SCSigSignatureWrapper *sw2)
{
return sw1->user[SC_RADIX_USER_DATA_HOSTBITS] -
sw2->user[SC_RADIX_USER_DATA_HOSTBITS];
}
/**
* \brief Orders an incoming Signature based on its priority type
*
@ -564,6 +665,7 @@ static inline SCSigSignatureWrapper *SCSigAllocSignatureWrapper(Signature *sig)
SCSigProcessUserDataForFlowvar(sw);
SCSigProcessUserDataForFlowint(sw);
SCSigProcessUserDataForPktvar(sw);
SCSigProcessUserDataForHostbits(sw);
return sw;
}
@ -643,6 +745,7 @@ void SCSigRegisterSignatureOrderingFuncs(DetectEngineCtx *de_ctx)
SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowintCompare);
SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByHostbitsCompare);
SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
}

@ -33,6 +33,7 @@ typedef enum{
SC_RADIX_USER_DATA_FLOWVAR,
SC_RADIX_USER_DATA_PKTVAR,
SC_RADIX_USER_DATA_FLOWINT,
SC_RADIX_USER_DATA_HOSTBITS,
SC_RADIX_USER_DATA_MAX
} SCRadixUserDataType;

Loading…
Cancel
Save