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