1 //--------------------------------------------------------------------------
2 // Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 //
4 // This program is free software; you can redistribute it and/or modify it
5 // under the terms of the GNU General Public License Version 2 as published
6 // by the Free Software Foundation.  You may not use, modify or distribute
7 // this program under any other version of the GNU General Public License.
8 //
9 // This program is distributed in the hope that it will be useful, but
10 // WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License along
15 // with this program; if not, write to the Free Software Foundation, Inc.,
16 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 //--------------------------------------------------------------------------
18 // module.h author Russ Combs <rucombs@cisco.com>
19 
20 // FIXIT-M add trace param(s)
21 // FIXIT-M add memcap related
22 // FIXIT-L add set_default method
23 
24 #ifndef MODULE_H
25 #define MODULE_H
26 
27 // Module provides a data-driven way to manage much of Snort++.  For
28 // example, it provides an interface to configured components.  There is at
29 // most one instance of a Module at any time.  A given module instance is
30 // used to configure all related components.  As such it stores data only
31 // for the sake of constructing the next component instance.
32 //
33 // Module will set all parameter defaults immediately after calling
34 // begin() so defaults should not be explicitly set in begin() or a ctor
35 // called by begin, except as needed for infrastructure and sanity.
36 //
37 // Note that there are no internal default lists.  Put appropriate default
38 // lists in snort_defaults.lua or some such.  Each list item, however, will
39 // have any defaults applied.
40 
41 #include <cassert>
42 #include <string>
43 #include <vector>
44 
45 #include "framework/counts.h"
46 #include "framework/parameter.h"
47 #include "framework/value.h"
48 #include "main/snort_types.h"
49 #include "utils/stats.h"
50 
51 struct lua_State;
52 
53 namespace snort
54 {
55 class ModuleManager;
56 class Trace;
57 struct ProfileStats;
58 struct SnortConfig;
59 struct TraceOption;
60 
61 using LuaCFunction = int(*)(lua_State*);
62 
63 struct Command
64 {
65     const char* name;
66     LuaCFunction func;
67     const Parameter* params;
68     const char* help;
69 
70     std::string get_arg_list() const;
71 };
72 
73 struct RuleMap
74 {
75     unsigned sid;
76     const char* msg;
77 };
78 
79 class SO_PUBLIC Module
80 {
81 public:
82     virtual ~Module() = default;
83 
84     // configuration:
85     // for lists (tables with numeric indices):
86     // int == 0 is list container
87     // int > 0 is list item
begin(const char *,int,SnortConfig *)88     virtual bool begin(const char*, int, SnortConfig*)
89     { return true; }
90 
end(const char *,int,SnortConfig *)91     virtual bool end(const char*, int, SnortConfig*)
92     { return true; }
93 
set(const char *,Value &,SnortConfig *)94     virtual bool set(const char*, Value&, SnortConfig*)
95     { return true; }
96 
set_trace(const Trace *)97     virtual void set_trace(const Trace*) const { }
98 
get_trace_options()99     virtual const TraceOption* get_trace_options() const
100     { return nullptr; }
101 
102     // used to match parameters with $var names like <gid:sid> for rule_state
matches(const char *,std::string &)103     virtual bool matches(const char* /*param_name*/, std::string& /*lua_name*/)
104     { return false; }
105 
106     // ips events:
get_gid()107     virtual unsigned get_gid() const
108     { return 0; }
109 
get_name()110     const char* get_name() const
111     { return name ? name : params->name; }
112 
is_table()113     bool is_table() const
114     { return (name != nullptr); }
115 
is_list()116     bool is_list() const
117     { return list; }
118 
get_type()119     Parameter::Type get_type() const
120     {
121         if ( is_list() )
122             return Parameter::PT_LIST;
123         else if ( is_table() )
124             return Parameter::PT_TABLE;
125         else
126             return params->type;
127     }
128 
get_help()129     const char* get_help() const
130     { return help; }
131 
get_parameters()132     const Parameter* get_parameters() const
133     { return params; }
134 
get_commands()135     virtual const Command* get_commands() const
136     { return nullptr; }
137 
get_rules()138     virtual const RuleMap* get_rules() const
139     { return nullptr; }
140 
get_pegs()141     virtual const PegInfo* get_pegs() const
142     { return nullptr; }
143 
counts_need_prep()144     virtual bool counts_need_prep() const
145     { return false; }
146 
prep_counts()147     virtual void prep_counts() { }
148 
149     // counts and profile are thread local
get_counts()150     virtual PegCount* get_counts() const
151     { return nullptr; }
152 
153     virtual PegCount get_global_count(const char* name) const;
154 
get_num_counts()155     virtual int get_num_counts() const
156     { return num_counts; }
157 
get_profile()158     virtual ProfileStats* get_profile() const
159     { return nullptr; }
160 
161     // implement above -or- below
get_profile(unsigned,const char * &,const char * &)162     virtual ProfileStats* get_profile(
163         unsigned /*index*/, const char*& /*name*/, const char*& /*parent*/) const
164     { return nullptr; }
165 
get_defaults()166     virtual const char* get_defaults() const
167     { return nullptr; }
168 
global_stats()169     virtual bool global_stats() const
170     { return false; }
171 
172     virtual void sum_stats(bool accumulate_now_stats);
173     virtual void show_interval_stats(IndexVec&, FILE*);
174     virtual void show_stats();
175     virtual void reset_stats();
show_dynamic_stats()176     virtual void show_dynamic_stats() {}
177     void clear_global_active_counters();
178 
179     // Wrappers to check that lists are not tables
180     bool verified_begin(const char*, int, SnortConfig*);
181     bool verified_set(const char*, Value&, SnortConfig*);
182     bool verified_end(const char*, int, SnortConfig*);
183 
184     enum Usage
185     {
186         GLOBAL,
187         CONTEXT,
188         INSPECT,
189         DETECT
190     };
191 
get_usage()192     virtual Usage get_usage() const
193     { return CONTEXT; }
194 
is_bindable()195     virtual bool is_bindable() const
196     { return false; }
197 
198 protected:
199     Module(const char* name, const char* help);
200     Module(const char* name, const char* help, const Parameter*, bool is_list = false);
201 
set_params(const Parameter * p)202     void set_params(const Parameter* p)
203     { params = p; }
204 
205 private:
206     friend ModuleManager;
207     void init(const char*, const char* = nullptr);
208 
209     std::vector<PegCount> counts;
210     int num_counts = -1;
211 
212     const char* name;
213     const char* help;
214 
215     const Parameter* params;
216     bool list;
217     int table_level = 0;
218 
set_peg_count(int index,PegCount value)219     void set_peg_count(int index, PegCount value)
220     {
221         assert(index < num_counts);
222         counts[index] = value;
223     }
224 
set_max_peg_count(int index,PegCount value)225     void set_max_peg_count(int index, PegCount value)
226     {
227         assert(index < num_counts);
228         if(value > counts[index])
229             counts[index] = value;
230     }
231 
add_peg_count(int index,PegCount value)232     void add_peg_count(int index, PegCount value)
233     {
234         assert(index < num_counts);
235         counts[index] += value;
236     }
237 };
238 }
239 #endif
240 
241