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