|
|
|
|
@ -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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|