#include "suricata-common.h"
#include "detect.h"
+#include "detect-hostbits.h"
#include "detect-flowbits.h"
#include "detect-flowint.h"
#include "detect-parse.h"
#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
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.
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,
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
*
SCSigProcessUserDataForFlowvar(sw);
SCSigProcessUserDataForFlowint(sw);
SCSigProcessUserDataForPktvar(sw);
+ SCSigProcessUserDataForHostbits(sw);
return sw;
}
SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowintCompare);
SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare);
SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare);
+ SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByHostbitsCompare);
SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare);
}