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 // mpse_manager.cc author Russ Combs <rucombs@cisco.com>
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "mpse_manager.h"
25
26 #include <cassert>
27 #include <list>
28
29 #include "detection/fp_config.h"
30 #include "framework/mpse.h"
31 #include "log/messages.h"
32 #include "main/snort_config.h"
33
34 #include "module_manager.h"
35
36 using namespace snort;
37 using namespace std;
38
39 typedef list<const MpseApi*> EngineList;
40 static EngineList s_engines;
41
42 //-------------------------------------------------------------------------
43 // engine plugins
44 //-------------------------------------------------------------------------
45
add_plugin(const MpseApi * api)46 void MpseManager::add_plugin(const MpseApi* api)
47 {
48 s_engines.emplace_back(api);
49 }
50
release_plugins()51 void MpseManager::release_plugins()
52 {
53 s_engines.clear();
54 }
55
dump_plugins()56 void MpseManager::dump_plugins()
57 {
58 Dumper d("Search Engines");
59
60 for ( auto* p : s_engines )
61 d.dump(p->base.name, p->base.version);
62 }
63
64 //-------------------------------------------------------------------------
65
instantiate(const MpseApi *,Module *,SnortConfig *)66 void MpseManager::instantiate(const MpseApi*, Module*, SnortConfig*)
67 {
68 // nothing to do here
69 // see
70 }
71
get_api(const char * keyword)72 static const MpseApi* get_api(const char* keyword)
73 {
74 for ( auto* p : s_engines )
75 if ( !strcasecmp(p->base.name, keyword) )
76 return p;
77
78 return nullptr;
79 }
80
get_search_api(const char * name)81 const MpseApi* MpseManager::get_search_api(const char* name)
82 {
83 const MpseApi* api = ::get_api(name);
84
85 if ( api and api->init )
86 api->init();
87
88 return api;
89 }
90
get_search_engine(const SnortConfig * sc,const MpseApi * api,const MpseAgent * agent)91 Mpse* MpseManager::get_search_engine(
92 const SnortConfig* sc, const MpseApi* api, const MpseAgent* agent)
93 {
94 Module* mod = ModuleManager::get_module(api->base.name);
95 Mpse* eng = api->ctor(sc, mod, agent);
96 eng->set_api(api);
97 return eng;
98 }
99
delete_search_engine(Mpse * eng)100 void MpseManager::delete_search_engine(Mpse* eng)
101 {
102 const MpseApi* api = eng->get_api();
103 api->dtor(eng);
104 }
105
106 //-------------------------------------------------------------------------
107
108 // the summary info is totaled by type for all instances
print_mpse_summary(const MpseApi * api)109 void MpseManager::print_mpse_summary(const MpseApi* api)
110 {
111 assert(api);
112 if ( api->print )
113 api->print();
114 }
115
activate_search_engine(const MpseApi * api,SnortConfig * sc)116 void MpseManager::activate_search_engine(const MpseApi* api, SnortConfig* sc)
117 {
118 assert(api);
119 if ( api->activate )
120 api->activate(sc);
121 }
122
setup_search_engine(const MpseApi * api,SnortConfig * sc)123 void MpseManager::setup_search_engine(const MpseApi* api, SnortConfig* sc)
124 {
125 assert(api);
126 if ( api->setup )
127 api->setup(sc);
128 }
129
start_search_engine(const MpseApi * api)130 void MpseManager::start_search_engine(const MpseApi* api)
131 {
132 assert(api);
133 if ( api->start )
134 api->start();
135 }
136
stop_search_engine(const MpseApi * api)137 void MpseManager::stop_search_engine(const MpseApi* api)
138 {
139 assert(api);
140 if ( api->stop )
141 api->stop();
142 }
143
is_async_capable(const MpseApi * api)144 bool MpseManager::is_async_capable(const MpseApi* api)
145 {
146 assert(api);
147 return (api->flags & MPSE_ASYNC) != 0;
148 }
149
is_regex_capable(const MpseApi * api)150 bool MpseManager::is_regex_capable(const MpseApi* api)
151 {
152 assert(api);
153 return (api->flags & MPSE_REGEX) != 0;
154 }
155
is_poll_capable(const MpseApi * api)156 bool MpseManager::is_poll_capable(const MpseApi* api)
157 {
158 assert(api);
159 return (api->poll);
160 }
161
parallel_compiles(const MpseApi * api)162 bool MpseManager::parallel_compiles(const MpseApi* api)
163 {
164 assert(api);
165 return (api->flags & MPSE_MTBLD) != 0;
166 }
167
168 // was called during drop stats but actually commented out
169 // FIXIT-M this one has to accumulate across threads
170 #if 0
171 void MpseManager::print_qinfo()
172 {
173 sfksearch_print_qinfo();
174 acsmx2_print_qinfo();
175 }
176 #endif
177
178 #ifdef PIGLET
179
instantiate(const char * name,Module * m,SnortConfig * sc)180 MpseWrapper* MpseManager::instantiate(const char* name, Module* m, SnortConfig* sc)
181 {
182 auto api = ::get_api(name);
183
184 if ( !api || !api->ctor )
185 return nullptr;
186
187 auto p = api->ctor(sc, m, nullptr);
188
189 if ( !p )
190 return nullptr;
191
192 return new MpseWrapper(api, p);
193 }
194
195 #endif
196
197