]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1390 in SNORT/snort3 from flowbit_reload to master
authorTom Peters (thopeter) <thopeter@cisco.com>
Thu, 18 Oct 2018 02:29:02 +0000 (22:29 -0400)
committerTom Peters (thopeter) <thopeter@cisco.com>
Thu, 18 Oct 2018 02:29:02 +0000 (22:29 -0400)
Squashed commit of the following:

commit b18573f72a4fc5665a88369debda99da7b69694b
Author: mdagon <mdagon@cisco.com>
Date:   Mon Oct 8 15:37:13 2018 -0400

    ips_flowbits: move static structures to snort config

src/ips_options/ips_flowbits.cc
src/ips_options/ips_flowbits.h
src/main/snort.cc
src/main/snort_config.cc
src/main/snort_config.h

index 02516ce205b8df1c6b96d94967c05fe9202f99f3..ba7539359423235808fdc66287ef2053aaae7bc9 100644 (file)
@@ -105,41 +105,57 @@ typedef enum
 }Flowbits_eval;
 
 /**
-**  This structure is the context ptr for each detection option
+**  This class is the context ptr for each detection option
 **  on a rule.  The id is associated with a FLOWBITS_OBJECT id.
 **
 **  The type element track only one operation.
 */
-struct FLOWBITS_OP
+class FLOWBITS_OP
 {
-    uint16_t* ids;
-    uint8_t num_ids;
-    uint8_t type;         /* Set, Unset, Invert, IsSet, IsNotSet, Reset  */
-    Flowbits_eval eval;   /* and , or, all, any*/
-    char* name;
-    char* group;
-    uint32_t group_id;
+public:
+    uint16_t* ids = nullptr;
+    uint8_t num_ids = 0;
+    uint8_t type = 0;         /* Set, Unset, Invert, IsSet, IsNotSet, Reset  */
+    Flowbits_eval eval = FLOWBITS_AND;   /* and , or, all, any*/
+    char* name = nullptr;
+    char* group = nullptr;
+    uint32_t group_id = 0;
+    ~FLOWBITS_OP();
 };
 
-typedef struct _FLOWBITS_GRP
+FLOWBITS_OP::~FLOWBITS_OP()
+{
+    if (ids != nullptr)
+        snort_free(ids);
+    if (name != nullptr)
+        snort_free(name);
+    if (group != nullptr)
+        snort_free(group);
+}
+
+struct FLOWBITS_GRP
 {
     uint16_t count;
     uint16_t max_id;
     char* name;
     uint32_t group_id;
     BitOp* GrpBitOp;
-} FLOWBITS_GRP;
-
-static std::forward_list<const FLOWBITS_OP*> op_list;
-
-static GHash* flowbits_hash = nullptr;
-static GHash* flowbits_grp_hash = nullptr;
-static SF_QUEUE* flowbits_bit_queue = nullptr;
+};
 
-static unsigned flowbits_count = 0;
-static unsigned flowbits_grp_count = 0;
-static int flowbits_toggle = 1;
+struct FlowBitState
+{
+    std::forward_list<const FLOWBITS_OP*> op_list;
+    GHash* flowbits_hash = nullptr;
+    GHash* flowbits_grp_hash = nullptr;
+    SF_QUEUE* flowbits_bit_queue = nullptr;
+    unsigned flowbits_count = 0;
+    unsigned flowbits_grp_count = 0;
+    int flowbits_toggle = 1;
+};
 
+// Forward declarations
+static void FlowItemFree(void* d);
+static void FlowBitsGrpFree(void* d);
 static IpsOption::EvalStatus check_flowbits(
     uint8_t type, uint8_t evalType, uint16_t* ids, uint16_t num_ids,
     char* group, Packet* p);
@@ -148,8 +164,8 @@ class FlowBitsOption : public IpsOption
 {
 public:
     FlowBitsOption(FLOWBITS_OP* c) :
-        IpsOption(s_name, RULE_OPTION_TYPE_FLOWBIT)
-    { config = c; }
+        IpsOption(s_name, RULE_OPTION_TYPE_FLOWBIT), config(c)
+    { }
 
     ~FlowBitsOption() override;
 
@@ -171,14 +187,7 @@ private:
 
 FlowBitsOption::~FlowBitsOption()
 {
-    if (config->ids)
-        snort_free(config->ids);
-    if (config->name)
-        snort_free(config->name);
-    if (config->group)
-        snort_free(config->group);
-
-    snort_free(config);
+    delete config;
 }
 
 uint32_t FlowBitsOption::hash() const
@@ -231,10 +240,10 @@ bool FlowBitsOption::operator==(const IpsOption& ips) const
 
     const FlowBitsOption& rhs = (const FlowBitsOption&)ips;
 
-    if ( (config->num_ids != rhs.config->num_ids) or
-        (config->eval != rhs.config->eval) or
-        (config->type != rhs.config->type) or
-        (config->group_id != rhs.config->group_id) )
+    if ( (config->num_ids != rhs.config->num_ids)or
+            (config->eval != rhs.config->eval) or
+            (config->type != rhs.config->type) or
+            (config->group_id != rhs.config->group_id) )
         return false;
 
     for ( int i = 0; i < config->num_ids; i++ )
@@ -255,7 +264,6 @@ IpsOption::EvalStatus FlowBitsOption::eval(Cursor&, Packet* p)
     if (!flowbits)
         return NO_MATCH;
 
-
     return check_flowbits(flowbits->type, (uint8_t)flowbits->eval,
         flowbits->ids, flowbits->num_ids, flowbits->group, p);
 }
@@ -264,7 +272,7 @@ IpsOption::EvalStatus FlowBitsOption::eval(Cursor&, Packet* p)
 // helper methods
 //-------------------------------------------------------------------------
 
-static inline BitOp* get_flow_bitop(const Packet* p)
+static inline BitOp* get_flow_bitop(const Packet* p, FlowBitState* flowbit_state)
 {
     Flow* flow = p->flow;
 
@@ -272,12 +280,12 @@ static inline BitOp* get_flow_bitop(const Packet* p)
         return nullptr;
 
     if ( !flow->bitop )
-        flow->bitop = new BitOp(flowbits_count);
+        flow->bitop = new BitOp(flowbit_state->flowbits_count);
 
     return flow->bitop;
 }
 
-static inline int clear_group_bit(BitOp* bitop, char* group)
+static inline int clear_group_bit(BitOp* bitop, char* group, FlowBitState* flowbit_state)
 {
     if ( !group )
         return 0;
@@ -285,7 +293,7 @@ static inline int clear_group_bit(BitOp* bitop, char* group)
     // FIXIT-M why is the hash lookup done at runtime for flowbits groups?
     // a pointer to flowbis_grp should be in flowbits config data
     // this *should* be safe but iff splay mode is disabled
-    auto flowbits_grp = (FLOWBITS_GRP*)ghash_find(flowbits_grp_hash, group);
+    auto flowbits_grp = (FLOWBITS_GRP*)ghash_find(flowbit_state->flowbits_grp_hash, group);
 
     if ( !flowbits_grp )
         return 0;
@@ -304,12 +312,12 @@ static inline int clear_group_bit(BitOp* bitop, char* group)
     return 1;
 }
 
-static inline int toggle_group_bit(BitOp* bitop, char* group)
+static inline int toggle_group_bit(BitOp* bitop, char* group, FlowBitState* flowbit_state)
 {
     if ( !group  )
         return 0;
 
-    auto flowbits_grp = (FLOWBITS_GRP*)ghash_find(flowbits_grp_hash, group);
+    auto flowbits_grp = (FLOWBITS_GRP*)ghash_find(flowbit_state->flowbits_grp_hash, group);
 
     if ( !flowbits_grp )
         return 0;
@@ -329,10 +337,10 @@ static inline int toggle_group_bit(BitOp* bitop, char* group)
 }
 
 static inline int set_xbits_to_group(
-    BitOp* bitop, uint16_t* ids, uint16_t num_ids, char* group)
+    BitOp* bitop, uint16_t* ids, uint16_t num_ids, char* group, FlowBitState* flowbit_state)
 {
     unsigned int i;
-    if (!clear_group_bit(bitop, group))
+    if (!clear_group_bit(bitop, group, flowbit_state))
         return 0;
     for (i = 0; i < num_ids; i++)
         bitop->set(ids[i]);
@@ -341,7 +349,7 @@ static inline int set_xbits_to_group(
 
 static inline int is_set_flowbits(
     BitOp* bitop, uint8_t eval, uint16_t* ids,
-    uint16_t num_ids, char* group)
+    uint16_t num_ids, char* group, FlowBitState* flowbit_state)
 {
     unsigned int i;
     FLOWBITS_GRP* flowbits_grp;
@@ -366,7 +374,7 @@ static inline int is_set_flowbits(
         return 0;
 
     case FLOWBITS_ALL:
-        flowbits_grp = (FLOWBITS_GRP*)ghash_find(flowbits_grp_hash, group);
+        flowbits_grp = (FLOWBITS_GRP*)ghash_find(flowbit_state->flowbits_grp_hash, group);
         if ( flowbits_grp == nullptr )
             return 0;
         for ( i = 0; i <= (unsigned int)(flowbits_grp->max_id >>3); i++ )
@@ -379,7 +387,7 @@ static inline int is_set_flowbits(
         return 1;
 
     case FLOWBITS_ANY:
-        flowbits_grp = (FLOWBITS_GRP*)ghash_find(flowbits_grp_hash, group);
+        flowbits_grp = (FLOWBITS_GRP*)ghash_find(flowbit_state->flowbits_grp_hash, group);
         if ( flowbits_grp == nullptr )
             return 0;
         for ( i = 0; i <= (unsigned int)(flowbits_grp->max_id >>3); i++ )
@@ -402,8 +410,10 @@ static IpsOption::EvalStatus check_flowbits(
     int result = 0;
     int i;
 
-    BitOp* bitop = get_flow_bitop(p);
+    FlowBitState* flowbit_state = SnortConfig::get_conf()->flowbit_state;
+    assert(flowbit_state != nullptr);
 
+    BitOp* bitop = get_flow_bitop(p, flowbit_state);
     if (!bitop)
         return IpsOption::NO_MATCH;
 
@@ -416,12 +426,12 @@ static IpsOption::EvalStatus check_flowbits(
         break;
 
     case FLOWBITS_SETX:
-        result = set_xbits_to_group(bitop, ids, num_ids, group);
+        result = set_xbits_to_group(bitop, ids, num_ids, group, flowbit_state);
         break;
 
     case FLOWBITS_UNSET:
         if (eval == FLOWBITS_ALL )
-            clear_group_bit(bitop, group);
+            clear_group_bit(bitop, group, flowbit_state);
         else
         {
             for (i = 0; i < num_ids; i++)
@@ -434,13 +444,13 @@ static IpsOption::EvalStatus check_flowbits(
         if (!group)
             bitop->reset();
         else
-            clear_group_bit(bitop, group);
+            clear_group_bit(bitop, group, flowbit_state);
         result = 1;
         break;
 
     case FLOWBITS_ISSET:
 
-        if (is_set_flowbits(bitop,(uint8_t)eval, ids, num_ids, group))
+        if (is_set_flowbits(bitop,(uint8_t)eval, ids, num_ids, group, flowbit_state))
         {
             result = 1;
         }
@@ -452,7 +462,7 @@ static IpsOption::EvalStatus check_flowbits(
         break;
 
     case FLOWBITS_ISNOTSET:
-        if (!is_set_flowbits(bitop, (uint8_t)eval, ids, num_ids, group))
+        if (!is_set_flowbits(bitop, (uint8_t)eval, ids, num_ids, group, flowbit_state))
         {
             result = 1;
         }
@@ -464,7 +474,7 @@ static IpsOption::EvalStatus check_flowbits(
 
     case FLOWBITS_TOGGLE:
         if (group)
-            toggle_group_bit(bitop, group);
+            toggle_group_bit(bitop, group, flowbit_state);
         else
         {
             for (i = 0; i < num_ids; i++)
@@ -512,20 +522,44 @@ static IpsOption::EvalStatus check_flowbits(
 //-------------------------------------------------------------------------
 // public methods
 //-------------------------------------------------------------------------
+void flowbits_ginit(SnortConfig* sc)
+{
+    sc->flowbit_state = new FlowBitState;
+    sc->flowbit_state->flowbits_hash = ghash_new(10000, 0, 0, FlowItemFree);
+
+    if ( !sc->flowbit_state->flowbits_hash )
+        FatalError("Could not create flowbits hash.\n");
 
-void FlowbitResetCounts()
+    // this is used during parse time and runtime so do NOT
+    // enable splay mode (which is NOT useful here anyway)
+    sc->flowbit_state->flowbits_grp_hash = ghash_new(10000, 0, 0, FlowBitsGrpFree);
+
+    if ( !sc->flowbit_state->flowbits_grp_hash )
+        FatalError("could not create flowbits group hash.\n");
+
+    sc->flowbit_state->flowbits_bit_queue = sfqueue_new();
+
+    if ( !sc->flowbit_state->flowbits_bit_queue )
+        FatalError("could not create flowbits bit queue.\n");
+}
+
+void flowbits_gterm(SnortConfig* sc)
 {
-    if ( !flowbits_hash )
+    FlowBitState* flowbit_state = sc->flowbit_state;
+    if (flowbit_state == nullptr)
         return;
 
-    for (GHashNode* n = ghash_findfirst(flowbits_hash);
-        n != nullptr;
-        n = ghash_findnext(flowbits_hash))
-    {
-        FLOWBITS_OBJECT* fb = (FLOWBITS_OBJECT*)n->data;
-        fb->set = 0;
-        fb->isset = 0;
-    }
+    if ( flowbit_state->flowbits_hash )
+        ghash_delete(flowbit_state->flowbits_hash);
+
+    if ( flowbit_state->flowbits_grp_hash )
+        ghash_delete(flowbit_state->flowbits_grp_hash);
+
+    if ( flowbit_state->flowbits_bit_queue )
+        sfqueue_free_all(flowbit_state->flowbits_bit_queue, nullptr);
+
+    delete flowbit_state;
+    flowbit_state = nullptr;
 }
 
 int FlowBits_SetOperation(void* option_data)
@@ -559,7 +593,8 @@ static bool validateName(char* name)
     return true;
 }
 
-static FLOWBITS_OBJECT* getFlowBitItem(char* flowbitName, FLOWBITS_OP* flowbits)
+static FLOWBITS_OBJECT* getFlowBitItem(char* flowbitName, FLOWBITS_OP* flowbits,
+    FlowBitState* flowbit_state)
 {
     FLOWBITS_OBJECT* flowbits_item;
 
@@ -569,33 +604,35 @@ static FLOWBITS_OBJECT* getFlowBitItem(char* flowbitName, FLOWBITS_OP* flowbits)
             s_name, ALLOWED_SPECIAL_CHARS);
     }
 
-    flowbits_item = (FLOWBITS_OBJECT*)ghash_find(flowbits_hash, flowbitName);
+    flowbits_item = (FLOWBITS_OBJECT*)ghash_find(flowbit_state->flowbits_hash, flowbitName);
 
     if (flowbits_item == nullptr)
     {
         flowbits_item = (FLOWBITS_OBJECT*)snort_calloc(sizeof(FLOWBITS_OBJECT));
 
-        if (sfqueue_count(flowbits_bit_queue) > 0)
+        if (sfqueue_count(flowbit_state->flowbits_bit_queue) > 0)
         {
-            flowbits_item->id = (uint16_t)(uintptr_t)sfqueue_remove(flowbits_bit_queue);
+            flowbits_item->id = (uint16_t)(uintptr_t)sfqueue_remove(
+                flowbit_state->flowbits_bit_queue);
         }
         else
         {
-            flowbits_item->id = flowbits_count++;
+            flowbits_item->id = flowbit_state->flowbits_count++;
 
-            if ( !flowbits_count )
+            if ( !flowbit_state->flowbits_count )
             {
                 ParseError("The number of flowbit IDs in the current ruleset exceeds "
-                    "the maximum number of IDs that are allowed (%u).", flowbits_count-1);
+                    "the maximum number of IDs that are allowed (%u).",
+                    flowbit_state->flowbits_count-1);
             }
         }
 
-        int hstatus = ghash_add(flowbits_hash, flowbitName, flowbits_item);
+        int hstatus = ghash_add(flowbit_state->flowbits_hash, flowbitName, flowbits_item);
 
         if (hstatus != GHASH_OK)
             ParseError("Could not add flowbits key (%s) to hash.",flowbitName);
     }
-    flowbits_item->toggle = flowbits_toggle;
+    flowbits_item->toggle = flowbit_state->flowbits_toggle;
     flowbits_item->types |= flowbits->type;
 
     switch (flowbits->type)
@@ -619,7 +656,7 @@ static FLOWBITS_OBJECT* getFlowBitItem(char* flowbitName, FLOWBITS_OP* flowbits)
 }
 
 static void processFlowbits(
-    char* flowbits_names, FLOWBITS_OP* flowbits)
+    char* flowbits_names, FLOWBITS_OP* flowbits, FlowBitState* flowbit_state)
 {
     char** toks;
     int num_toks;
@@ -647,7 +684,7 @@ static void processFlowbits(
         flowbits->num_ids = num_toks;
         for (i = 0; i < num_toks; i++)
         {
-            flowbits_item = getFlowBitItem(toks[i], flowbits);
+            flowbits_item = getFlowBitItem(toks[i], flowbits, flowbit_state);
             flowbits->ids[i] = flowbits_item->id;
         }
         flowbits->eval = FLOWBITS_OR;
@@ -660,7 +697,7 @@ static void processFlowbits(
         flowbits->num_ids = num_toks;
         for (i = 0; i < num_toks; i++)
         {
-            flowbits_item = getFlowBitItem(toks[i], flowbits);
+            flowbits_item = getFlowBitItem(toks[i], flowbits, flowbit_state);
             flowbits->ids[i] = flowbits_item->id;
         }
         flowbits->eval = FLOWBITS_AND;
@@ -676,7 +713,7 @@ static void processFlowbits(
     }
     else
     {
-        flowbits_item = getFlowBitItem(flowbits_name, flowbits);
+        flowbits_item = getFlowBitItem(flowbits_name, flowbits, flowbit_state);
         flowbits->ids = (uint16_t*)snort_calloc(sizeof(*(flowbits->ids)));
         flowbits->num_ids = 1;
         flowbits->ids[0] = flowbits_item->id;
@@ -764,7 +801,7 @@ static void validateFlowbitsSyntax(FLOWBITS_OP* flowbits)
     }
 }
 
-static FLOWBITS_GRP* getFlowBitGroup(char* groupName)
+static FLOWBITS_GRP* getFlowBitGroup(char* groupName, FlowBitState* flowbit_state)
 {
     FLOWBITS_GRP* flowbits_grp = nullptr;
 
@@ -778,44 +815,42 @@ static FLOWBITS_GRP* getFlowBitGroup(char* groupName)
             s_name, ALLOWED_SPECIAL_CHARS);
     }
 
-    flowbits_grp = (FLOWBITS_GRP*)ghash_find(flowbits_grp_hash, groupName);
+    flowbits_grp = (FLOWBITS_GRP*)ghash_find(flowbit_state->flowbits_grp_hash, groupName);
 
     if ( !flowbits_grp )
     {
         // new group defined, add (bitop set later once we know size)
         flowbits_grp = (FLOWBITS_GRP*)snort_calloc(sizeof(*flowbits_grp));
-        int hstatus = ghash_add(flowbits_grp_hash, groupName, flowbits_grp);
+        int hstatus = ghash_add(flowbit_state->flowbits_grp_hash, groupName, flowbits_grp);
 
         if (hstatus != GHASH_OK)
             ParseAbort("Could not add flowbits group (%s) to hash.\n",groupName);
 
-        flowbits_grp_count++;
-        flowbits_grp->group_id = flowbits_grp_count;
+        flowbit_state->flowbits_grp_count++;
+        flowbits_grp->group_id = flowbit_state->flowbits_grp_count;
         flowbits_grp->name = snort_strdup(groupName);
     }
 
     return flowbits_grp;
 }
 
-static void processFlowBitsWithGroup(char* flowbitsName, char* groupName, FLOWBITS_OP* flowbits)
+static void processFlowBitsWithGroup(char* flowbitsName, char* groupName, FLOWBITS_OP* flowbits,
+    FlowBitState* flowbit_state)
 {
-    FLOWBITS_GRP* flowbits_grp;
-
-    flowbits_grp = getFlowBitGroup(groupName);
-    processFlowbits(flowbitsName, flowbits);
-
+    processFlowbits(flowbitsName, flowbits, flowbit_state);
     if (groupName && !(flowbits->group))
     {
         flowbits->group = snort_strdup(groupName);
+        FLOWBITS_GRP* flowbits_grp = getFlowBitGroup(groupName, flowbit_state);
         flowbits->group_id = flowbits_grp->group_id;
     }
     validateFlowbitsSyntax(flowbits);
 
     if ( flowbits->group )
-        op_list.push_front(flowbits);
+        flowbit_state->op_list.push_front(flowbits);
 }
 
-static FLOWBITS_OP* flowbits_parse(const char* data)
+static FLOWBITS_OP* flowbits_parse(const char* data, SnortConfig* sc)
 {
     char** toks;
     int num_toks;
@@ -824,7 +859,7 @@ static FLOWBITS_OP* flowbits_parse(const char* data)
     char* flowbitsName = nullptr;
     FLOWBITS_GRP* flowbits_grp;
 
-    FLOWBITS_OP* flowbits = (FLOWBITS_OP*)snort_calloc(sizeof(*flowbits));
+    FLOWBITS_OP* flowbits = new FLOWBITS_OP;
 
     toks = mSplit(data, ",", 0, &num_toks, 0);
 
@@ -837,6 +872,9 @@ static FLOWBITS_OP* flowbits_parse(const char* data)
         ParseAbort("%s: too many arguments.", s_name);
     }
 
+    FlowBitState* flowbit_state = sc->flowbit_state;
+    assert(flowbit_state != nullptr);
+
     typeName = toks[0];
 
     if (!strcasecmp("set",typeName))
@@ -889,7 +927,7 @@ static FLOWBITS_OP* flowbits_parse(const char* data)
         {
             /*Save the group name*/
             groupName = snort_strdup(toks[1]);
-            flowbits_grp = getFlowBitGroup(groupName);
+            flowbits_grp = getFlowBitGroup(groupName, flowbit_state);
             flowbits->group = groupName;
             flowbits->group_id = flowbits_grp->group_id;
         }
@@ -920,7 +958,7 @@ static FLOWBITS_OP* flowbits_parse(const char* data)
     {
         groupName = toks[2];
     }
-    processFlowBitsWithGroup(flowbitsName, groupName, flowbits);
+    processFlowBitsWithGroup(flowbitsName, groupName, flowbits, flowbit_state);
 
     mSplitFree(&toks, num_toks);
     return flowbits;
@@ -936,52 +974,53 @@ static void update_group(FLOWBITS_GRP* flowbits_grp, int id)
     flowbits_grp->GrpBitOp->set(id);
 }
 
-static void init_groups()
+static void init_groups(FlowBitState* flowbit_state)
 {
-    if ( !flowbits_hash or !flowbits_grp_hash )
+    if ( !flowbit_state->flowbits_hash or !flowbit_state->flowbits_grp_hash )
         return;
 
-    for ( GHashNode* n = ghash_findfirst(flowbits_grp_hash);
+    for ( GHashNode* n = ghash_findfirst(flowbit_state->flowbits_grp_hash);
         n != nullptr;
-        n= ghash_findnext(flowbits_grp_hash) )
+        n= ghash_findnext(flowbit_state->flowbits_grp_hash) )
     {
         FLOWBITS_GRP* fbg = (FLOWBITS_GRP*)n->data;
-        fbg->GrpBitOp = new BitOp(flowbits_count);
+        fbg->GrpBitOp = new BitOp(flowbit_state->flowbits_count);
         fbg->GrpBitOp->reset();
     }
 
-    while ( !op_list.empty() )
+    while ( !flowbit_state->op_list.empty() )
     {
-        const FLOWBITS_OP* fbop = op_list.front();
-        FLOWBITS_GRP* fbg = (FLOWBITS_GRP*)ghash_find(flowbits_grp_hash, fbop->group);
+        const FLOWBITS_OP* fbop = flowbit_state->op_list.front();
+        FLOWBITS_GRP* fbg = (FLOWBITS_GRP*)ghash_find(flowbit_state->flowbits_grp_hash,
+            fbop->group);
         assert(fbg);
 
         for ( int i = 0; i < fbop->num_ids; ++i )
             update_group(fbg, fbop->ids[i]);
 
-        op_list.pop_front();
+        flowbit_state->op_list.pop_front();
     }
 }
 
-static void FlowBitsVerify()
+static void FlowBitsVerify(FlowBitState* flowbit_state)
 {
     GHashNode* n;
     unsigned num_flowbits = 0;
     unsigned unchecked = 0, unset = 0;
 
-    if (flowbits_hash == nullptr)
+    if (flowbit_state->flowbits_hash == nullptr)
         return;
 
-    for (n = ghash_findfirst(flowbits_hash);
+    for (n = ghash_findfirst(flowbit_state->flowbits_hash);
         n != nullptr;
-        n= ghash_findnext(flowbits_hash))
+        n= ghash_findnext(flowbit_state->flowbits_hash))
     {
         FLOWBITS_OBJECT* fb = (FLOWBITS_OBJECT*)n->data;
 
-        if (fb->toggle != flowbits_toggle)
+        if (fb->toggle != flowbit_state->flowbits_toggle)
         {
-            sfqueue_add(flowbits_bit_queue, (NODE_DATA)(uintptr_t)fb->id);
-            ghash_remove(flowbits_hash, n->key);
+            sfqueue_add(flowbit_state->flowbits_bit_queue, (NODE_DATA)(uintptr_t)fb->id);
+            ghash_remove(flowbit_state->flowbits_hash, n->key);
             continue;
         }
 
@@ -1004,9 +1043,9 @@ static void FlowBitsVerify()
 
         num_flowbits++;
     }
-    assert(num_flowbits == flowbits_count);
+    assert(num_flowbits == flowbit_state->flowbits_count);
 
-    flowbits_toggle ^= 1;
+    flowbit_state->flowbits_toggle ^= 1;
 
     if ( !num_flowbits )
         return;
@@ -1026,58 +1065,13 @@ static void FlowItemFree(void* d)
 static void FlowBitsGrpFree(void* d)
 {
     FLOWBITS_GRP* data = (FLOWBITS_GRP*)d;
-    if(data->GrpBitOp)
+    if (data->GrpBitOp)
         delete data->GrpBitOp;
     if (data->name)
         snort_free(data->name);
     snort_free(data);
 }
 
-//-------------------------------------------------------------------------
-// api methods
-//-------------------------------------------------------------------------
-
-static void flowbits_ginit(SnortConfig*)
-{
-    flowbits_hash = ghash_new(10000, 0, 0, FlowItemFree);
-
-    if ( !flowbits_hash )
-        FatalError("Could not create flowbits hash.\n");
-
-    // this is used during parse time and runtime so do NOT
-    // enable splay mode (which is NOT useful here anyway)
-    flowbits_grp_hash = ghash_new(10000, 0, 0, FlowBitsGrpFree);
-
-    if ( !flowbits_grp_hash )
-        FatalError("could not create flowbits group hash.\n");
-
-    flowbits_bit_queue = sfqueue_new();
-
-    if ( !flowbits_bit_queue )
-        FatalError("could not create flowbits bit queue.\n");
-}
-
-static void flowbits_gterm(SnortConfig*)
-{
-    if ( flowbits_hash )
-    {
-        ghash_delete(flowbits_hash);
-        flowbits_hash = nullptr;
-    }
-
-    if ( flowbits_grp_hash )
-    {
-        ghash_delete(flowbits_grp_hash);
-        flowbits_grp_hash = nullptr;
-    }
-
-    if ( flowbits_bit_queue )
-    {
-        sfqueue_free_all(flowbits_bit_queue, nullptr);
-        flowbits_bit_queue = nullptr;
-    }
-}
-
 //-------------------------------------------------------------------------
 // module
 //-------------------------------------------------------------------------
@@ -1106,6 +1100,7 @@ public:
 
     bool begin(const char*, int, SnortConfig*) override;
     bool set(const char*, Value&, SnortConfig*) override;
+    bool end(const char*, int, SnortConfig*) override;
 
     ProfileStats* get_profile() const override
     { return &flowBitsPerfStats; }
@@ -1113,8 +1108,11 @@ public:
     Usage get_usage() const override
     { return DETECT; }
 
+    FLOWBITS_OP* get_data();
+
 public:
     string args;
+    FLOWBITS_OP* fbop = nullptr;
 };
 
 bool FlowbitsModule::begin(const char*, int, SnortConfig*)
@@ -1139,6 +1137,19 @@ bool FlowbitsModule::set(const char*, Value& v, SnortConfig*)
     return true;
 }
 
+bool FlowbitsModule::end(const char*, int, SnortConfig* sc)
+{
+    fbop = flowbits_parse(args.c_str(), sc);
+    return true;
+}
+
+FLOWBITS_OP* FlowbitsModule::get_data()
+{
+    FLOWBITS_OP* tmp = fbop;
+    fbop = nullptr;
+    return tmp;
+}
+
 //-------------------------------------------------------------------------
 // api methods
 //-------------------------------------------------------------------------
@@ -1150,13 +1161,17 @@ static Module* mod_ctor()
 
 static void mod_dtor(Module* m)
 {
-    delete m;
+    FlowbitsModule* fb = (FlowbitsModule*)m;
+    if (fb->fbop)
+        delete fb->fbop;
+
+    delete fb;
 }
 
 static IpsOption* flowbits_ctor(Module* p, OptTreeNode*)
 {
     FlowbitsModule* m = (FlowbitsModule*)p;
-    FLOWBITS_OP* fbop = flowbits_parse(m->args.c_str());
+    FLOWBITS_OP* fbop = m->get_data();
     return new FlowBitsOption(fbop);
 }
 
@@ -1165,11 +1180,11 @@ static void flowbits_dtor(IpsOption* p)
     delete p;
 }
 
-// FIXIT-M updating statics during reload is bad, mkay?
-static void flowbits_verify(SnortConfig*)
+static void flowbits_verify(SnortConfig* sc)
 {
-    init_groups();
-    FlowBitsVerify();
+    FlowBitState* flowbit_state = sc->flowbit_state;
+    init_groups(flowbit_state);
+    FlowBitsVerify(flowbit_state);
 }
 
 #if 0
@@ -1203,8 +1218,8 @@ static const IpsApi flowbits_api =
     },
     OPT_TYPE_DETECTION,
     0, 0,
-    flowbits_ginit,
-    flowbits_gterm,
+    nullptr,
+    nullptr,
     nullptr,
     nullptr,
     flowbits_ctor,
index 986b794156872ea42887c5ed84c081c6e5696125..798e3ec4fb3a03906ad8ca871d7fe2b9687572c2 100644 (file)
 #ifndef IPS_FLOWBITS_H
 #define IPS_FLOWBITS_H
 
-void FlowbitResetCounts();
+#include "main/snort_config.h"
+namespace snort
+{
+struct SnortConfig;
+}
+
+void flowbits_ginit(snort::SnortConfig*);
+void flowbits_gterm(snort::SnortConfig*);
 int FlowBits_SetOperation(void*);
 
 #endif
index d064e7f651bc9ade71384e6c73146a0f84ff3aa7..e8ca576923b1c6c766fe6d9be5ef5485d06d6a15 100644 (file)
@@ -583,8 +583,6 @@ SnortConfig* Snort::get_reload_config(const char* fname)
         return nullptr;
     }
 
-    FlowbitResetCounts();  // FIXIT-L updates global hash, put in sc
-
     if ((sc->file_mask != 0) && (sc->file_mask != SnortConfig::get_conf()->file_mask))
         umask(sc->file_mask);
 
index a040a580402e13741fb05bb73a0aef7aada3f4dc..f80d320c19eb9cc1d0c74857db4c112bd7c48e8a 100644 (file)
@@ -37,6 +37,7 @@
 #include "filters/sfthreshold.h"
 #include "hash/xhash.h"
 #include "helpers/process.h"
+#include "ips_options/ips_flowbits.h"
 #include "latency/latency_config.h"
 #include "log/messages.h"
 #include "managers/event_manager.h"
@@ -201,6 +202,7 @@ void SnortConfig::init(const SnortConfig* const other_conf, ProtocolReference* p
 
         memset(evalOrder, 0, sizeof(evalOrder));
         proto_ref = new ProtocolReference(protocol_reference);
+        flowbits_ginit(this);
     }
     else
     {
@@ -286,6 +288,8 @@ SnortConfig::~SnortConfig()
         MpseManager::stop_search_engine(fast_pattern_config->get_search_api());
     }
     delete fast_pattern_config;
+    flowbits_gterm(this);
 
     delete policy_map;
     InspectorManager::delete_config(this);
index ffe361a98524ab8337c01150e9398565fcc415b8..cec6857539f3ba7c5b729c5363c282c01239ff23 100644 (file)
@@ -137,6 +137,7 @@ class ThreadConfig;
 struct ReferenceSystemNode;
 struct VarNode;
 struct _IntelPmHandles;
+struct FlowBitState;
 
 namespace snort
 {
@@ -278,6 +279,7 @@ public:
     ThresholdConfig* threshold_config = nullptr;
     RateFilterConfig* rate_filter_config = nullptr;
     DetectionFilterConfig* detection_filter_config = nullptr;
+    FlowBitState* flowbit_state = nullptr; 
 
     //------------------------------------------------------
     // FIXIT-L command line only stuff, add to conf / module