1 //--------------------------------------------------------------------------
2 // Copyright (C) 2016-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 // analyzer_command.cc author Michael Altizer <mialtize@cisco.com>
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "analyzer_command.h"
25
26 #include <cassert>
27
28 #include "control/control.h"
29 #include "framework/module.h"
30 #include "log/messages.h"
31 #include "managers/module_manager.h"
32 #include "protocols/packet_manager.h"
33 #include "target_based/host_attributes.h"
34 #include "utils/stats.h"
35
36 #include "analyzer.h"
37 #include "reload_tracker.h"
38 #include "snort.h"
39 #include "snort_config.h"
40 #include "swapper.h"
41
42 using namespace snort;
43
execute(Analyzer & analyzer,void **)44 bool ACStart::execute(Analyzer& analyzer, void**)
45 {
46 analyzer.start();
47 return true;
48 }
49
execute(Analyzer & analyzer,void **)50 bool ACRun::execute(Analyzer& analyzer, void**)
51 {
52 analyzer.run(paused);
53 paused = false;
54 return true;
55 }
56
execute(Analyzer & analyzer,void **)57 bool ACStop::execute(Analyzer& analyzer, void**)
58 {
59 analyzer.stop();
60 return true;
61 }
62
execute(Analyzer & analyzer,void **)63 bool ACPause::execute(Analyzer& analyzer, void**)
64 {
65 analyzer.pause();
66 return true;
67 }
68
execute(Analyzer & analyzer,void **)69 bool ACResume::execute(Analyzer& analyzer, void**)
70 {
71 analyzer.resume(msg_cnt);
72 return true;
73 }
74
execute(Analyzer & analyzer,void **)75 bool ACRotate::execute(Analyzer& analyzer, void**)
76 {
77 analyzer.rotate();
78 return true;
79 }
80
execute(Analyzer &,void **)81 bool ACGetStats::execute(Analyzer&, void**)
82 {
83 // FIXIT-P This incurs locking on all threads to retrieve stats. It
84 // could be reimplemented to optimize for large thread counts by
85 // retrieving stats in the command and accumulating in the main thread.
86 PacketManager::accumulate();
87 ModuleManager::accumulate();
88 return true;
89 }
90
~ACGetStats()91 ACGetStats::~ACGetStats()
92 {
93
94 // FIXIT-L This should track the owner so it can dump stats to the
95 // shell instead of the logs when initiated by a shell command
96 DropStats(ctrlcon);
97 LogRespond(ctrlcon, "==================================================\n"); // Marking End of stats
98
99 ModuleManager::clear_global_active_counters();
100 }
101
execute(Analyzer &,void **)102 bool ACResetStats::execute(Analyzer&, void**)
103 {
104 ModuleManager::reset_stats(requested_type);
105 return true;
106 }
107
ACResetStats(clear_counter_type_t requested_type_l)108 ACResetStats::ACResetStats(clear_counter_type_t requested_type_l) : requested_type(
109 requested_type_l) { }
110
ACSwap(Swapper * ps,ControlConn * ctrlcon)111 ACSwap::ACSwap(Swapper* ps, ControlConn *ctrlcon) : ps(ps), ctrlcon(ctrlcon)
112 { }
113
execute(Analyzer & analyzer,void ** ac_state)114 bool ACSwap::execute(Analyzer& analyzer, void** ac_state)
115 {
116 if (ps)
117 {
118 ps->apply(analyzer);
119
120 const SnortConfig* sc = ps->get_new_conf();
121 if ( sc )
122 {
123 std::list<ReloadResourceTuner*>* reload_tuners;
124
125 if ( !*ac_state )
126 {
127 reload_tuners = new std::list<ReloadResourceTuner*>(sc->get_reload_resource_tuners());
128 std::list<ReloadResourceTuner*>::iterator rtt = reload_tuners->begin();
129 while ( rtt != reload_tuners->end() )
130 {
131 if ( (*rtt)->tinit() )
132 ++rtt;
133 else
134 rtt = reload_tuners->erase(rtt);
135 }
136 *ac_state = reload_tuners;
137 }
138 else
139 reload_tuners = (std::list<ReloadResourceTuner*>*)*ac_state;
140
141 if ( !reload_tuners->empty() )
142 {
143 auto rrt = reload_tuners->front();
144 if ( analyzer.is_idling() )
145 {
146 if ( rrt->tune_idle_context() )
147 reload_tuners->pop_front();
148 }
149 else
150 {
151 if ( rrt->tune_packet_context() )
152 reload_tuners->pop_front();
153 }
154 }
155
156 // check for empty again and free list instance if we are done
157 if ( reload_tuners->empty() )
158 {
159 delete reload_tuners;
160 ps->finish(analyzer);
161 return true;
162 }
163
164 return false;
165 }
166 }
167
168 return true;
169 }
170
~ACSwap()171 ACSwap::~ACSwap()
172 {
173 if (ps)
174 {
175 SnortConfig* sc = ps->get_new_conf();
176 if ( sc )
177 sc->clear_reload_resource_tuner_list();
178 }
179 delete ps;
180 HostAttributesManager::swap_cleanup();
181
182 ReloadTracker::end(ctrlcon);
183 LogMessage("== reload complete\n");
184 if (ctrlcon && !ctrlcon->is_local())
185 ctrlcon->respond("== reload complete\n");
186 }
187
ACHostAttributesSwap(ControlConn * ctrlcon)188 ACHostAttributesSwap::ACHostAttributesSwap(ControlConn *ctrlcon)
189 : ctrlcon(ctrlcon)
190 { }
191
execute(Analyzer &,void **)192 bool ACHostAttributesSwap::execute(Analyzer&, void**)
193 {
194 HostAttributesManager::initialize();
195 return true;
196 }
197
~ACHostAttributesSwap()198 ACHostAttributesSwap::~ACHostAttributesSwap()
199 {
200 HostAttributesManager::swap_cleanup();
201 ReloadTracker::end(ctrlcon);
202 LogMessage("== reload host attributes complete\n");
203 if (ctrlcon && !ctrlcon->is_local())
204 ctrlcon->respond("== reload host attributes complete\n");
205 }
206
execute(Analyzer & analyzer,void **)207 bool ACDAQSwap::execute(Analyzer& analyzer, void**)
208 {
209 analyzer.reload_daq();
210 return true;
211 }
212
~ACDAQSwap()213 ACDAQSwap::~ACDAQSwap()
214 {
215 LogMessage("== daq module reload complete\n");
216 }
217
get_daq_instance(Analyzer & analyzer)218 SFDAQInstance* AnalyzerCommand::get_daq_instance(Analyzer& analyzer)
219 {
220 return analyzer.get_daq_instance();
221 }
222