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 // help.cc author Russ Combs <rucombs@cisco.com>
19 
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 
24 #include "help.h"
25 
26 #include <iostream>
27 
28 #include "framework/module.h"
29 #include "helpers/markup.h"
30 #include "helpers/process.h"
31 #include "managers/event_manager.h"
32 #include "managers/inspector_manager.h"
33 #include "managers/module_manager.h"
34 #include "managers/plugin_manager.h"
35 #include "managers/script_manager.h"
36 #include "managers/so_manager.h"
37 #include "packet_io/sfdaq.h"
38 #include "utils/util.h"
39 
40 #include "snort_config.h"
41 #include "snort_module.h"
42 
43 using namespace snort;
44 using namespace std;
45 
46 static constexpr const char* snort_help =
47     "\n"
48     "Snort has several options to get more help:\n"
49     "\n"
50     "-? list command line options (same as --help)\n"
51     "--help this overview of help\n"
52     "--help-commands [<module prefix>] output matching commands\n"
53     "--help-config [<module prefix>] output matching config options\n"
54     "--help-counts [<module prefix>] output matching peg counts\n"
55     "--help-limits print the int upper bounds denoted by max*\n"
56     "--help-module <module> output description of given module\n"
57     "--help-modules list all available modules with brief help\n"
58     "--help-modules-json dump description of all available modules in JSON format\n"
59     "--help-plugins list all available plugins with brief help\n"
60     "--help-options [<option prefix>] output matching command line options\n"
61     "--help-signals dump available control signals\n"
62     "--list-buffers output available inspection buffers\n"
63     "--list-builtin [<module prefix>] output matching builtin rules\n"
64     "--list-gids [<module prefix>] output matching generators\n"
65     "--list-modules [<module type>] list all known modules\n"
66     "--list-plugins list all known modules\n"
67     "--show-plugins list module and plugin versions\n"
68     "\n"
69     "--help* and --list* options preempt other processing so should be last on the\n"
70     "command line since any following options are ignored.  To ensure options like\n"
71     "--markup and --plugin-path take effect, place them ahead of the help or list\n"
72     "options.\n"
73     "\n"
74     "Options that filter output based on a matching prefix, such as --help-config\n"
75     "won't output anything if there is no match.  If no prefix is given, everything\n"
76     "matches.\n"
77     "\n"
78     "Report bugs to bugs@snort.org.\n";
79 
80 //-------------------------------------------------------------------------
81 
help_args(const char * pfx)82 void help_args(const char* pfx)
83 {
84     Module* m = get_snort_module();
85     const Parameter* p = m->get_parameters();
86     size_t n = pfx ? strlen(pfx) : 0;
87 
88     while ( p->name )
89     {
90         const char* name = p->name;
91         while ( *name == '-' )
92             name++;
93 
94         if ( p->help && (!n || !strncasecmp(name, pfx, n)) )
95         {
96             cout << Markup::item();
97 
98             cout << Markup::emphasis_on();
99             cout << p->name;
100             cout << Markup::emphasis_off();
101 
102             cout << " " << p->help;
103 
104             if ( const char* r = p->get_range() )
105             {
106                 if ( *r == '(' )
107                     cout << " " << r;
108                 else
109                     cout << " (" << r << ")";
110             }
111             cout << endl;
112         }
113         ++p;
114     }
115 }
116 
help_basic(SnortConfig *,const char *)117 [[noreturn]] void help_basic(SnortConfig*, const char*)
118 {
119     fprintf(stdout, "%s\n", snort_help);
120     exit(0);
121 }
122 
help_usage(SnortConfig *,const char * s)123 [[noreturn]] void help_usage(SnortConfig*, const char* s)
124 {
125     fprintf(stdout, "usage:\n");
126     fprintf(stdout, "    %s -?: list options\n", s);
127     fprintf(stdout, "    %s -V: output version\n", s);
128     fprintf(stdout, "    %s --help: help summary\n", s);
129     fprintf(stdout, "    %s [-options] -c conf [-T]: validate conf\n", s);
130     fprintf(stdout, "    %s [-options] -c conf -i iface: process live\n", s);
131     fprintf(stdout, "    %s [-options] -c conf -r pcap: process readback\n", s);
132     exit(0);
133 }
134 
help_options(SnortConfig *,const char * val)135 [[noreturn]] void help_options(SnortConfig*, const char* val)
136 {
137     help_args(val);
138     exit(0);
139 }
140 
help_signals(SnortConfig *,const char *)141 [[noreturn]] void help_signals(SnortConfig*, const char*)
142 {
143     help_signals();
144     exit(0);
145 }
146 
147 enum HelpType
148 {
149     HT_BUF, HT_CFG, HT_CMD, HT_DBR, HT_DDR,
150     HT_GID, HT_HMO, HT_HMO_JSON, HT_HPL, HT_DFL,
151     HT_IPS, HT_LST, HT_MOD, HT_PEG, HT_PLG
152 };
153 
show_help(SnortConfig * sc,const char * val,HelpType ht,const char * opts=nullptr)154 [[noreturn]] static void show_help(
155     SnortConfig* sc, const char* val, HelpType ht, const char* opts = nullptr)
156 {
157     SnortConfig::set_conf(new SnortConfig);
158     ScriptManager::load_scripts(sc->script_paths);
159     PluginManager::load_plugins(sc->plugin_path);
160     PluginManager::load_so_plugins(sc);
161     ModuleManager::init();
162 
163     switch ( ht )
164     {
165     case HT_BUF:
166         InspectorManager::dump_buffers();
167         break;
168     case HT_CFG:
169         ModuleManager::show_configs(val);
170         break;
171     case HT_CMD:
172         ModuleManager::show_commands(val);
173         break;
174     case HT_DBR:
175         ModuleManager::dump_rules(val, opts);
176         break;
177     case HT_DDR:
178         SoManager::dump_rule_stubs(val, sc);
179         break;
180     case HT_DFL:
181         ModuleManager::dump_defaults(val);
182         break;
183     case HT_GID:
184         ModuleManager::show_gids(val);
185         break;
186     case HT_HMO:
187         ModuleManager::show_modules();
188         break;
189     case HT_HMO_JSON:
190         ModuleManager::show_modules_json();
191         break;
192     case HT_HPL:
193         PluginManager::show_plugins();
194         break;
195     case HT_IPS:
196         ModuleManager::show_rules(val);
197         break;
198     case HT_LST:
199         ModuleManager::list_modules(val);
200         break;
201     case HT_MOD:
202         ModuleManager::show_module(val);
203         break;
204     case HT_PEG:
205         ModuleManager::show_pegs(val);
206         break;
207     case HT_PLG:
208         PluginManager::list_plugins();
209         break;
210     }
211     ModuleManager::term();
212     PluginManager::release_plugins();
213     ScriptManager::release_scripts();
214     delete SnortConfig::get_conf();
215     exit(0);
216 }
217 
help_config(SnortConfig * sc,const char * val)218 [[noreturn]] void help_config(SnortConfig* sc, const char* val)
219 {
220     show_help(sc, val, HT_CFG);
221 }
222 
help_commands(SnortConfig * sc,const char * val)223 [[noreturn]] void help_commands(SnortConfig* sc, const char* val)
224 {
225     show_help(sc, val, HT_CMD);
226 }
227 
config_markup(SnortConfig *,const char *)228 void config_markup(SnortConfig*, const char*)
229 {
230     Markup::enable();
231 }
232 
help_gids(SnortConfig * sc,const char * val)233 [[noreturn]] void help_gids(SnortConfig* sc, const char* val)
234 {
235     show_help(sc, val, HT_GID);
236 }
237 
help_buffers(SnortConfig * sc,const char * val)238 [[noreturn]] void help_buffers(SnortConfig* sc, const char* val)
239 {
240     show_help(sc, val, HT_BUF);
241 }
242 
help_builtin(SnortConfig * sc,const char * val)243 [[noreturn]] void help_builtin(SnortConfig* sc, const char* val)
244 {
245     show_help(sc, val, HT_IPS);
246 }
247 
help_counts(SnortConfig * sc,const char * val)248 [[noreturn]] void help_counts(SnortConfig* sc, const char* val)
249 {
250     show_help(sc, val, HT_PEG);
251 }
252 
help_limits(SnortConfig *,const char *)253 [[noreturn]] void help_limits(SnortConfig*, const char*)
254 {
255     fprintf(stdout, "limits:\n");
256     fprintf(stdout, "max31 = 2147483647\n");
257     fprintf(stdout, "max32 = 4294967295\n");
258     fprintf(stdout, "max53 = 9007199254740992\n");
259     fprintf(stdout, "maxSZ = %zu\n", (sizeof(size_t) == 4) ? 4294967295 : 9007199254740992);
260     exit(0);
261 }
262 
help_module(SnortConfig * sc,const char * val)263 [[noreturn]] void help_module(SnortConfig* sc, const char* val)
264 {
265     show_help(sc, val, HT_MOD);
266 }
267 
help_modules(SnortConfig * sc,const char * val)268 [[noreturn]] void help_modules(SnortConfig* sc, const char* val)
269 {
270     show_help(sc, val, HT_HMO);
271 }
272 
help_modules_json(SnortConfig * sc,const char * val)273 [[noreturn]] void help_modules_json(SnortConfig* sc, const char* val)
274 {
275     show_help(sc, val, HT_HMO_JSON);
276 }
277 
help_plugins(SnortConfig * sc,const char * val)278 [[noreturn]] void help_plugins(SnortConfig* sc, const char* val)
279 {
280     show_help(sc, val, HT_HPL);
281 }
282 
help_version(SnortConfig *)283 [[noreturn]] void help_version(SnortConfig*)
284 {
285     DisplayBanner();
286     exit(0);
287 }
288 
list_daqs(SnortConfig * sc)289 [[noreturn]] void list_daqs(SnortConfig* sc)
290 {
291     SFDAQ::load(sc->daq_config);
292     SFDAQ::print_types(cout);
293     SFDAQ::unload();
294     exit(0);
295 }
296 
list_modules(SnortConfig * sc,const char * val)297 [[noreturn]] void list_modules(SnortConfig* sc, const char* val)
298 {
299     show_help(sc, val, HT_LST);
300 }
301 
list_plugins(SnortConfig * sc,const char * val)302 [[noreturn]] void list_plugins(SnortConfig* sc, const char* val)
303 {
304     show_help(sc, val, HT_PLG);
305 }
306 
dump_defaults(SnortConfig * sc,const char * val)307 [[noreturn]] void dump_defaults(SnortConfig* sc, const char* val)
308 {
309     show_help(sc, val, HT_DFL);
310 }
311 
dump_builtin_rules(SnortConfig * sc,const char * val,const char * opts)312 [[noreturn]] void dump_builtin_rules(SnortConfig* sc, const char* val, const char* opts)
313 {
314     show_help(sc, val, HT_DBR, opts);
315 }
316 
dump_dynamic_rules(SnortConfig * sc,const char * val)317 [[noreturn]] void dump_dynamic_rules(SnortConfig* sc, const char* val)
318 {
319     show_help(sc, val, HT_DDR);
320 }
321 
dump_rule_hex(SnortConfig *,const char * val)322 [[noreturn]] void dump_rule_hex(SnortConfig*, const char* val)
323 {
324     SoManager::rule_to_hex(val);
325     exit(0);
326 }
327 
dump_rule_text(SnortConfig *,const char * val)328 [[noreturn]] void dump_rule_text(SnortConfig*, const char* val)
329 {
330     SoManager::rule_to_text(val);
331     exit(0);
332 }
333 
dump_version(SnortConfig *)334 [[noreturn]] void dump_version(SnortConfig*)
335 {
336     cout << VERSION << endl;
337     exit(0);
338 }
339 
340