]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
refactored cmd line parsing
authorRuss Combs <rucombs@cisco.com>
Thu, 21 Aug 2014 03:17:14 +0000 (23:17 -0400)
committerRuss Combs <rucombs@cisco.com>
Thu, 21 Aug 2014 03:17:14 +0000 (23:17 -0400)
38 files changed:
ChangeLog
src/detection/detection_util.cc
src/filters/sfthd.cc
src/framework/module.h
src/framework/parameter.cc
src/framework/parameter.h
src/log/CMakeLists.txt
src/log/Makefile.am
src/log/log_text.cc
src/log/log_text.h
src/log/text_log.cc [moved from src/log/sf_textlog.cc with 99% similarity]
src/log/text_log.h [moved from src/log/sf_textlog.h with 97% similarity]
src/loggers/alert_csv.cc
src/loggers/alert_fast.cc
src/loggers/alert_full.cc
src/loggers/alert_test.cc
src/main/CMakeLists.txt
src/main/Makefile.am
src/main/help.cc [new file with mode: 0644]
src/main/help.h [new file with mode: 0644]
src/main/modules.cc
src/main/snort.cc
src/main/snort_module.cc [new file with mode: 0644]
src/main/snort_module.h [new file with mode: 0644]
src/managers/ips_manager.cc
src/packet_io/trough.cc
src/packet_io/trough.h
src/parser/CMakeLists.txt
src/parser/Makefile.am
src/parser/arg_list.cc [new file with mode: 0644]
src/parser/arg_list.h [new file with mode: 0644]
src/parser/cmd_line.cc
src/parser/cmd_line.h
src/parser/config_file.cc
src/parser/config_file.h
src/time/profiler.cc
src/utils/util.cc
src/utils/util.h

index 5c98e63585ab993effdfaa719e475296cbb1a8f3..eee88a35946eeb3a55af7be4b829d54570556dfb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
 115
 -- remove share.h
 -- misc FIXITs
+-- refactored cmd line parsing and moved options to SnortModule
 
 114
 -- more FIXIT cleanup
index 30ef68d3726f2bac989f25a58ec5c85e24df154e..f698ab7cf6b0a38e17c8644a3772167858c63dd5 100644 (file)
@@ -24,7 +24,7 @@
 #include <time.h>
 
 #include "snort.h"
-#include "sf_textlog.h"
+#include "log/text_log.h"
 #include "actions/actions.h"
 
 THREAD_LOCAL uint32_t http_mask;
index 62cb955cd2b36e0710d2b3da78d4e8dab247d7f7..68bce11f536a48184456a9072b0bccbf43edcf30 100644 (file)
@@ -627,16 +627,17 @@ the current event should be logged or dropped.
  --- Local and Global Thresholding is setup here  ---
 
 */
-int sfthd_create_threshold(SnortConfig *sc,
-                           ThresholdObjects *thd_objs,
-                           unsigned gen_id,
-                           unsigned sig_id,
-                           int tracking,
-                           int type,
-                           int priority,
-                           int count,
-                           int seconds,
-                           sfip_var_t* ip_address)
+int sfthd_create_threshold(
+    SnortConfig *sc,
+    ThresholdObjects *thd_objs,
+    unsigned gen_id,
+    unsigned sig_id,
+    int tracking,
+    int type,
+    int priority,
+    int count,
+    int seconds,
+    sfip_var_t* ip_address)
 {
     //allocate memory fpr sfthd_array if needed.
     PolicyId policyId = get_network_policy()->policy_id;
index df19baabcf04aa24d7233d29aeb6611996844a78..94e547580e3555bfadde87f47cd8aeaffd2918f1 100644 (file)
@@ -19,6 +19,7 @@
 // module.h author Russ Combs <rucombs@cisco.com>
 
 // FIXIT 
+// -- add lua module default
 // -- add set_default method
 // -- add trace param(s)
 // -- add memcap related
@@ -121,8 +122,8 @@ public:
     virtual void reset_stats();
 
 protected:
-    Module(const char* s);
-    Module(const char* s, const Parameter* p, bool is_list = false);
+    Module(const char*);
+    Module(const char*, const Parameter*, bool is_list = false);
 
 private:
     friend class ModuleManager;
index 02fae34c055d0bdeda0fdb42586a1c7706936943..85e5959cd93046af911ab3a13afd17a1765d0af7 100644 (file)
@@ -348,3 +348,14 @@ const char* Parameter::get_type() const
     return pt2str[type];
 }
 
+const Parameter* Parameter::find(const Parameter* p, const char* s)
+{
+    while ( p->name )
+    {
+        if ( !strcmp(p->name, s) || !strcmp(p->name, "*") )
+            return p;
+        ++p;
+    }
+    return nullptr;
+}
+
index 2aba31a7f20ec7eca154d5573f15ee2981795c00..148e2c82f135715cf1d4df2d6654500ccde6b139 100644 (file)
@@ -56,6 +56,11 @@ struct Parameter
     const char* get_type() const;
 
     bool validate(class Value&) const;
+
+    bool is_positional() const
+    { return ( name && *name == '~' ); };
+
+    static const Parameter* find(const Parameter*, const char*);
 };
 
 #endif
index 1555236e2078377722048da284365b7373e7948e..0123be83eb2830ac19b744ce2dcf13ee9c384dd8 100644 (file)
@@ -13,8 +13,8 @@ add_library ( log STATIC
     messages.cc
     obfuscation.cc 
     obfuscation.h 
-    sf_textlog.cc 
-    sf_textlog.h
+    text_log.cc 
+    text_log.h
 )
 
 set_default_visibility_compile_flag( log )
index 8759febbff236da7103dc7716ea5babc0571a9c6..a53080127166fe4643c4ce8c795e40b280c429c3 100644 (file)
@@ -10,13 +10,13 @@ obfuscation.h
 
 liblog_a_SOURCES = \
 log.cc \
+log.h \
 log_text.cc \
+log_text.h \
 messages.cc \
 obfuscation.cc \
-sf_textlog.cc \
-log.h \
-log_text.h \
-sf_textlog.h
+text_log.cc \
+text_log.h
 
 liblog_a_CXXFLAGS = $(AM_CXXFLAGS) -fvisibility=default
 
index f213a036e1e162f4fad31f073c5f43807e71de2a..67b920ae83ac45d210bca85b52c4add80873c966 100644 (file)
@@ -43,7 +43,7 @@
 #include "util_net.h"
 #include "protocols/packet.h"
 #include "snort.h"
-#include "sf_textlog.h"
+#include "log/text_log.h"
 #include "snort_bounds.h"
 #include "obfuscation.h"
 #include "detection_util.h"
index 8d7af09031522e63f546aebff9396a0173e2570b..21d73e7b3bbee60633ef09a70016fc50e8b9c957 100644 (file)
@@ -38,7 +38,7 @@
 #endif
 
 #include <stdint.h>
-#include "sf_textlog.h"
+#include "log/text_log.h"
 
 struct Packet;
 
similarity index 99%
rename from src/log/sf_textlog.cc
rename to src/log/text_log.cc
index 0a7d45749e60dca0fb6a3378e262456379ef4fea..63e85dac2a465bce638bc1c33844ce9a2fdd9dcf 100644 (file)
  ****************************************************************************/
 
 /**
- * @file   sf_textlog.c
+ * @file   log/text_log.c
  * @author Russ Combs <rcombs@sourcefire.com>
  * @date
  *
  * @brief  implements buffered text stream for logging
  */
 
-#include "sf_textlog.h"
+#include "text_log.h"
 
 #include <stdarg.h>
 #include <stdio.h>
similarity index 97%
rename from src/log/sf_textlog.h
rename to src/log/text_log.h
index f4576e4ac5da38cf12efa6756c17e3225cb9883c..7bfb7f4efacf337b399ca972dcc7490ac7dcf215 100644 (file)
@@ -1,6 +1,6 @@
 /****************************************************************************
  *
-** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+ * Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
  * Copyright (C) 2003-2013 Sourcefire, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
@@ -21,7 +21,7 @@
  ****************************************************************************/
 
 /**
- * @file   sf_textlog.h
+ * @file   text_log.h
  * @author Russ Combs <rcombs@sourcefire.com>
  * @date   Fri Jun 27 10:34:37 2003
  *
index 454b0a8d8b0161e914dd6f45c73c25ba51a32d05..a0f09c9d22b6e79927a514f3c05d0c40d4a21039 100644 (file)
@@ -39,8 +39,8 @@
 #include "util.h"
 #include "log.h"
 #include "snort.h"
-#include "sf_textlog.h"
-#include "log_text.h"
+#include "log/text_log.h"
+#include "log/log_text.h"
 
 #define LOG_BUFFER (4*K_BYTES)
 
index 6da897147801fb87c2673e149c0e7dabe8c78119..1fe276265b4c9d71a013a9b22c93ab314b8dd439 100644 (file)
@@ -54,9 +54,8 @@
 #include "util.h"
 #include "mstring.h"
 #include "packet_io/active.h"
-#include "sf_textlog.h"
-#include "log_text.h"
-#include "sf_textlog.h"
+#include "log/text_log.h"
+#include "log/log_text.h"
 #include "snort.h"
 #include "packet_io/sfdaq.h"
 #include "packet_io/intf.h"
index 7cd5eb22a0ec35c40c79fcea00d1e90b6136e7d0..1c8b576a858b26db9440beab22add961592ed201 100644 (file)
@@ -53,8 +53,8 @@
 #include "util.h"
 #include "mstring.h"
 #include "snort.h"
-#include "sf_textlog.h"
-#include "log_text.h"
+#include "log/text_log.h"
+#include "log/log_text.h"
 #include "packet_io/sfdaq.h"
 #include "packet_io/intf.h"
 
index 83da6a9d0f7f055214804f535ecb2e54e3a0e37b..37af2e82bd8ead9cc6fda71a3dfd846a3980c985 100644 (file)
@@ -37,7 +37,7 @@
 #include "parser.h"
 #include "util.h"
 #include "log/log_text.h"
-#include "log/sf_textlog.h"
+#include "log/text_log.h"
 #include "mstring.h"
 #include "snort.h"
 
index c8a5cd4dba0c40cc539c0a8fa49cd9ba2ad06a3b..f138321d140a90174b53144386ac02496ea9e8d1 100644 (file)
@@ -9,6 +9,8 @@ add_library (main STATIC
     analyzer.h
     analyzer.cc 
     build.h
+    help.cc
+    help.h
     modules.cc
     modules.h
     policy.h
@@ -20,6 +22,8 @@ add_library (main STATIC
     snort_debug.cc
     snort_config.h
     snort_config.cc
+    snort_module.h
+    snort_module.cc
     thread.cc 
        ${INCLUDES}
 )
index 426d2c2b029cb085d806d5421e1d90dc09b464d1..67e4e47a18cdd03fa902e90abbf79df1bd14f37e 100644 (file)
@@ -13,6 +13,8 @@ libmain_a_SOURCES = \
 analyzer.cc \
 analyzer.h \
 build.h \
+help.cc \
+help.h \
 modules.cc \
 modules.h \
 policy.cc \
@@ -24,6 +26,8 @@ snort.h \
 snort_config.cc \
 snort_config.h \
 snort_debug.cc \
+snort_module.cc \
+snort_module.h \
 thread.cc
 
 AM_CXXFLAGS = @AM_CXXFLAGS@
diff --git a/src/main/help.cc b/src/main/help.cc
new file mode 100644 (file)
index 0000000..a192cad
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+** Copyright (C) 2013-2013 Sourcefire, Inc.
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License Version 2 as
+** published by the Free Software Foundation.  You may not use, modify or
+** distribute this program under any other version of the GNU General
+** Public License.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include "help.h"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <syslog.h>
+#include <iostream>
+#include <string>
+using namespace std;
+
+#include "config_file.h"
+#include "parser.h"
+#include "vars.h"
+#include "detection/detect.h"
+#include "helpers/process.h"
+#include "main/analyzer.h"
+#include "main/shell.h"
+#include "main/snort_module.h"
+#include "managers/event_manager.h"
+#include "managers/so_manager.h"
+#include "managers/inspector_manager.h"
+#include "managers/module_manager.h"
+#include "managers/plugin_manager.h"
+#include "packet_io/trough.h"
+#include "packet_io/sfdaq.h"
+#include "packet_io/intf.h"
+#include "parser/parser.h"
+#include "utils/util.h"
+#include "helpers/markup.h"
+#include "framework/module.h"
+#include "framework/parameter.h"
+
+static const char* snort_help =
+"Snort has several options to get more help:\n"
+"\n"
+"--help this overview of help\n"
+"--help-builtin [<module prefix>] output matching builtin rules\n"
+"--help-buffers output available inspection buffers\n"
+"--help-commands [<module prefix>] output matching commands\n"
+"--help-config [<module prefix>] output matching config options\n"
+"--help-gids [<module prefix>] output matching generators\n"
+"--help-module <module> output description of given module\n"
+"--help-options [<option prefix>] output matching command line options\n"
+"--help-signals dump available control signals\n"
+"--list-modules list all known modules\n"
+"--list-plugins list all known modules\n"
+"--markup output help in asciidoc compatible format\n"
+"\n"
+"--help* and --list* options preempt other processing so should be last on the\n"
+"command line since any following options are ignored.  To ensure options like\n"
+"--plugin-path take effect, place them ahead of the help or list options.\n"
+"\n"
+"Options that filter output based on a matching prefix, such as --help-config\n"
+"won't output anything if there is no match.  If no prefix is given, everything\n"
+"matches.\n"
+"\n"
+"Parameters are given with this format:\n"
+"\n"
+"    type name = default: help { range }\n"
+"\n"
+"+ For Lua configuration (not IPS rules), if the name ends with [] it is a\n"
+"  list item and can be repeated.\n"
+"+ For IPS rules only, names starting with ~ indicate positional parameters.\n"
+"  The name does not appear in the rule.\n"
+"+ IPS rules may also have a wild card parameter, which is indicated by a *.\n"
+"  Only used for metadata that Snort ignores.\n"
+;
+
+//-------------------------------------------------------------------------
+
+// FIXIT must use SnortModule params
+void help_args(const char* pfx)
+{
+    Module* m = get_snort_module();
+    const Parameter* p = m->get_parameters();
+    unsigned n = pfx ? strlen(pfx) : 0;
+
+    while ( p->name )
+    {
+        if ( p->help && (!n || !strncasecmp(p->name, pfx, n)) )
+        {
+            cout << Markup::item();
+            cout << Markup::emphasis_on();
+
+            //const char* prefix = strlen(p->name) > 1 ? "--" : "-";
+            //cout << prefix << p->name;
+            cout << p->name;
+            cout << Markup::emphasis_off();
+
+            cout << " " << p->help;
+            cout << endl;
+        }
+        ++p;
+    }
+}
+
+void help_basic(SnortConfig*, const char*)
+{
+    fprintf(stdout, "Snort help: %s", snort_help);
+    exit(0);
+}
+
+void help_usage(SnortConfig*, const char* val)
+{
+    fprintf(stdout, "USAGE: %s [-options] <filter options>\n", "snort");
+    help_args(val);
+    exit(1);
+}
+
+void help_options(SnortConfig*, const char* val)
+{
+    help_args(val);
+    exit(0);
+}
+
+void help_signals(SnortConfig*, const char*)
+{
+    help_signals();
+    exit(0);
+}
+
+enum HelpType {
+    HT_CFG, HT_CMD, HT_GID, HT_IPS, HT_MOD,
+    HT_BUF, HT_LST, HT_PLG, HT_DDR, HT_DBR
+};
+
+static void show_help(SnortConfig* sc, const char* val, HelpType ht)
+{
+    snort_conf = new SnortConfig;
+    PluginManager::load_plugins(sc->plugin_path);
+    ModuleManager::init();
+
+    switch ( ht )
+    {
+    case HT_CFG:
+        ModuleManager::show_configs(val);
+        break;
+    case HT_CMD:
+        ModuleManager::show_commands(val);
+        break;
+    case HT_GID:
+        ModuleManager::show_gids(val);
+        break;
+    case HT_IPS:
+        ModuleManager::show_rules(val);
+        break;
+    case HT_MOD:
+        ModuleManager::show_module(val);
+        break;
+    case HT_BUF:
+        InspectorManager::dump_buffers();
+        break;
+    case HT_LST:
+        ModuleManager::list_modules();
+        break;
+    case HT_PLG:
+        PluginManager::list_plugins();
+        break;
+    case HT_DDR:
+        SoManager::dump_rule_stubs(val);
+        break;
+    case HT_DBR:
+        ModuleManager::dump_rules(val);
+        break;
+    }
+    ModuleManager::term();
+    PluginManager::release_plugins();
+    delete snort_conf;
+    exit(0);
+}
+
+void help_config(SnortConfig* sc, const char* val)
+{
+    show_help(sc, val, HT_CFG);
+}
+
+void help_commands(SnortConfig* sc, const char* val)
+{
+    show_help(sc, val, HT_CMD);
+}
+
+void config_markup(SnortConfig*, const char*)
+{
+    Markup::enable();
+}
+
+void help_gids(SnortConfig* sc, const char* val)
+{
+    show_help(sc, val, HT_GID);
+}
+
+void help_buffers(SnortConfig* sc, const char* val)
+{
+    show_help(sc, val, HT_BUF);
+}
+
+void help_builtin(SnortConfig* sc, const char* val)
+{
+    show_help(sc, val, HT_IPS);
+}
+
+void help_module(SnortConfig* sc, const char* val)
+{
+    show_help(sc, val, HT_MOD);
+}
+
+void list_modules(SnortConfig* sc, const char* val)
+{
+    show_help(sc, val, HT_LST);
+}
+
+void list_plugins(SnortConfig* sc, const char* val)
+{
+    show_help(sc, val, HT_PLG);
+}
+
+void dump_builtin_rules(SnortConfig* sc, const char* val)
+{
+    show_help(sc, val, HT_DBR);
+}
+
+void dump_dynamic_rules(SnortConfig* sc, const char* val)
+{
+    show_help(sc, val, HT_DDR);
+}
+
+void help_version(SnortConfig*, const char*)
+{
+    DisplayBanner();
+    exit(0);
+}
+
+void list_interfaces(SnortConfig*, const char*)
+{
+    DisplayBanner();
+    PrintAllInterfaces();
+    exit(0);
+}
+
+void list_daqs(SnortConfig* sc, const char* val)
+{
+    if ( val )
+        ConfigDaqDir(sc, val);
+
+    DAQ_Load(sc);
+    DAQ_PrintTypes(stdout);
+    DAQ_Unload();
+    exit(0);
+}
+
diff --git a/src/main/help.h b/src/main/help.h
new file mode 100644 (file)
index 0000000..f1e1906
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License Version 2 as
+** published by the Free Software Foundation.  You may not use, modify or
+** distribute this program under any other version of the GNU General
+** Public License.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+// help.h author Russ Combs <rucombs@cisco.com>
+
+#ifndef HELP_H
+#define HELP_H
+
+struct SnortConfig;
+
+void config_markup(SnortConfig*, const char*);
+
+void help_args(const char* pfx);
+void help_basic(SnortConfig*, const char*);
+void help_usage(SnortConfig*, const char*);
+void help_options(SnortConfig*, const char*);
+void help_signals(SnortConfig*, const char*);
+void help_config(SnortConfig* sc, const char*);
+void help_commands(SnortConfig* sc, const char*);
+void help_gids(SnortConfig* sc, const char*);
+void help_buffers(SnortConfig* sc, const char*);
+void help_builtin(SnortConfig* sc, const char*);
+void help_module(SnortConfig* sc, const char*);
+void help_version(SnortConfig*, const char*);
+
+void list_modules(SnortConfig* sc, const char*);
+void list_plugins(SnortConfig* sc, const char*);
+void list_interfaces(SnortConfig*, const char*);
+void list_daqs(SnortConfig* sc, const char*);
+
+void dump_builtin_rules(SnortConfig* sc, const char*);
+void dump_dynamic_rules(SnortConfig* sc, const char*);
+
+#endif
+
index f5585aee4109b059c0e07945f4477fc30e6c587e..aec9b175ab8eeb03fc47a6f9e0e7572025e227cb 100644 (file)
@@ -36,6 +36,7 @@ using namespace std;
 #include "main.h"
 #include "snort.h"
 #include "snort_config.h"
+#include "snort_module.h"
 #include "parser/parser.h"
 #include "parser/parse_conf.h"
 #include "parser/config_file.h"
@@ -942,7 +943,7 @@ bool DaqModule::set(const char*, Value& v, SnortConfig* sc)
             ConfigDecodeDataLink(sc, "");
     }
     else if ( v.is("snaplen") )
-        ConfigPacketSnaplen(sc, v.get_string());
+        sc->pkt_snaplen = v.get_long();
 
     else
         return false;
@@ -1624,33 +1625,6 @@ bool RuleStateModule::end(const char*, int idx, SnortConfig* sc)
     return true;
 }
 
-//-------------------------------------------------------------------------
-// snort module
-//-------------------------------------------------------------------------
-
-static const Command snort_cmds[] =
-{
-    { "show_plugins", main_dump_plugins, "show available plugins" },
-    { "dump_stats", main_dump_stats, "show summary statistics" },
-    { "rotate_stats", main_rotate_stats, "roll perfmonitor log files" },
-    { "reload_config", main_reload_config, "load new configuration" },
-    { "reload_attributes", main_reload_attributes, "load a new hosts.xml" },
-    { "process", main_process, "process given pcap" },
-    { "pause", main_pause, "suspend packet processing" },
-    { "resume", main_resume, "continue packet processing" },
-    { "quit", main_quit, "shutdown and dump-stats" },
-    { "help", main_help, "this output" },
-    { nullptr, nullptr, nullptr }
-};
-
-class SnortModule : public Module
-{
-public:
-    SnortModule() : Module("snort") { };
-    const Command* get_commands() const { return snort_cmds; };
-    bool set(const char*, Value&, SnortConfig*) { return false; };
-};
-
 //-------------------------------------------------------------------------
 // hosts module
 //-------------------------------------------------------------------------
@@ -1857,13 +1831,11 @@ bool XXXModule::set(const char*, Value& v, SnortConfig* sc)
 
 void module_init()
 {
-    // make sure parameters can be set regardless of sequence
+    // parameters must be settable regardless of sequence
     // since Lua calls this by table hash key traversal
     // (which is effectively random)
     // so module interdependencies must come after this phase
-    //
-    // this module is special :)
-    ModuleManager::add_module(new SnortModule);
+    ModuleManager::add_module(get_snort_module());
 
     // these modules are not policy specific
     ModuleManager::add_module(new ClassificationsModule);
index 2cc89c8e23fd0e060def5e76ece0f85ee2957c5f..c45c8cfd2fd6379ee90f84f38acf858efa02f10d 100644 (file)
@@ -99,7 +99,7 @@ using namespace std;
 #include "control/idle_processing.h"
 #include "file_api/file_service.h"
 #include "flow/flow_control.h"
-#include "log/sf_textlog.h"
+#include "log/text_log.h"
 #include "log/log_text.h"
 #include "time/periodic.h"
 #include "parser/config_file.h"
@@ -312,7 +312,7 @@ static void SnortInit(int argc, char **argv)
 #endif
 
     /* chew up the command line */
-    snort_cmd_line_conf = ParseCmdLine(argc, argv);
+    snort_cmd_line_conf = parse_cmd_line(argc, argv);
     snort_conf = snort_cmd_line_conf;
 
     /* Tell 'em who wrote it, and what "it" is */
@@ -488,6 +488,9 @@ void snort_setup(int argc, char* argv[])
     InitGroups(ScUid(), ScGid());
     SnortUnprivilegedInit();
 
+    if ( get_parse_errors() )
+        FatalError("see prior %d errors\n", get_parse_errors());
+
     set_quick_exit(false);
 }
 
@@ -577,7 +580,6 @@ static void SnortCleanup()
 #endif
 
     CleanupProtoNames();
-    cmd_line_term();
     ModuleManager::term();
     PluginManager::release_plugins();
     Shell::term();
diff --git a/src/main/snort_module.cc b/src/main/snort_module.cc
new file mode 100644 (file)
index 0000000..03c20d0
--- /dev/null
@@ -0,0 +1,659 @@
+/*
+** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License Version 2 as
+** published by the Free Software Foundation.  You may not use, modify or
+** distribute this program under any other version of the GNU General
+** Public License.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+// snort_module.cc author Russ Combs <rucombs@cisco.com>
+
+#include "snort_module.h"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <string.h>
+
+#include <string>
+using namespace std;
+
+#include "main.h"
+#include "snort.h"
+#include "help.h"
+#include "shell.h"
+#include "snort_config.h"
+#include "detection/detect.h"
+#include "framework/module.h"
+#include "framework/parameter.h"
+#include "managers/module_manager.h"
+#include "parser/config_file.h"
+#include "parser/parser.h"
+#include "parser/vars.h"
+#include "packet_io/trough.h"
+
+#ifdef UNIT_TEST
+#include "test/unit_test.h"
+#endif
+
+//-------------------------------------------------------------------------
+// commands
+//-------------------------------------------------------------------------
+
+static const Command snort_cmds[] =
+{
+    { "show_plugins", main_dump_plugins, "show available plugins" },
+    { "dump_stats", main_dump_stats, "show summary statistics" },
+    { "rotate_stats", main_rotate_stats, "roll perfmonitor log files" },
+    { "reload_config", main_reload_config, "load new configuration" },
+    { "reload_attributes", main_reload_attributes, "load a new hosts.xml" },
+    { "process", main_process, "process given pcap" },
+    { "pause", main_pause, "suspend packet processing" },
+    { "resume", main_resume, "continue packet processing" },
+    { "quit", main_quit, "shutdown and dump-stats" },
+    { "help", main_help, "this output" },
+    { nullptr, nullptr, nullptr }
+};
+
+//-------------------------------------------------------------------------
+// parameters
+//-------------------------------------------------------------------------
+
+static const Parameter snort_params[] =
+{
+    { "-?", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "show usage" },
+
+    { "-A", Parameter::PT_STRING, nullptr, nullptr, 
+      "<mode> set alert mode: none, cmg, or alert_*" },
+
+    { "-B", Parameter::PT_IMPLIED, nullptr, nullptr, 
+      "<mask> obfuscated IP addresses in alerts and packet dumps using CIDR mask" },
+
+    { "-C", Parameter::PT_IMPLIED, nullptr, nullptr, 
+      "print out payloads with character data only (no hex)" },
+
+    { "-c", Parameter::PT_STRING, nullptr, nullptr, 
+      "<conf> use this configuration" },
+
+    { "-D", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "run Snort in background (daemon) mode" },
+
+    { "-d", Parameter::PT_IMPLIED, nullptr, nullptr, 
+      "dump the Application Layer" },
+
+    { "-E", Parameter::PT_IMPLIED, nullptr, nullptr, 
+      "enable daemon restart" },
+
+    { "-e", Parameter::PT_IMPLIED, nullptr, nullptr, 
+      "display the second layer header info" },
+
+    { "-f", Parameter::PT_IMPLIED, nullptr, nullptr, 
+      "turn off fflush() calls after binary log writes" },
+
+    { "-G", Parameter::PT_INT, "0:65535", nullptr, 
+      "<0xid> (same as --logid)" },
+
+    { "-g", Parameter::PT_STRING, nullptr, nullptr, 
+      "<gname> run snort gid as <gname> group (or gid) after initialization" },
+
+    { "-H", Parameter::PT_IMPLIED, nullptr, nullptr, 
+      "make hash tables deterministic" },
+
+    { "-i", Parameter::PT_STRING, nullptr, nullptr, 
+      "<iface>... list of interfaces" },
+
+    { "-j", Parameter::PT_PORT, nullptr, nullptr,
+      "<port> to listen for telnet connections" },
+
+    { "-K", Parameter::PT_ENUM, "none|text|pcap", "none", 
+      "<mode> logging mode" },
+
+    { "-k", Parameter::PT_ENUM, "all|noip|notcp|noudp|noicmp|none", "all", 
+      "<mode> checksum mode (all,noip,notcp,noudp,noicmp,none)" },
+
+    { "-l", Parameter::PT_STRING, nullptr, nullptr, 
+      "<ld> log to directory <ld>" },
+
+    { "-M", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "log messages to syslog (not alerts)" },
+
+    { "-m", Parameter::PT_INT, "0:", nullptr, 
+      "<umask> set umask = <umask>" },
+
+    { "-n", Parameter::PT_INT, "0:", nullptr, 
+      "<count> stop after count packets" },
+
+    { "-O", Parameter::PT_IMPLIED, nullptr, nullptr, 
+      "obfuscate the logged IP addresses" },
+
+    { "-Q", Parameter::PT_IMPLIED, nullptr, nullptr, 
+      "enable inline mode operation" },
+
+    { "-q", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "quiet mode - Don't show banner and status report" },
+
+    { "-r", Parameter::PT_STRING, nullptr, nullptr, 
+      "<pcap>... (same as --pcap-list)" },
+
+    { "-S", Parameter::PT_STRING, nullptr, nullptr, 
+      "<n=v> set rules file variable n equal to value v" },
+
+    { "-s", Parameter::PT_INT, "68:65535", nullptr, 
+      "<snap> (same as --snaplen)" },
+
+    { "-T", Parameter::PT_IMPLIED, nullptr, nullptr, 
+      "test and report on the current Snort configuration" },
+
+    { "-t", Parameter::PT_STRING, nullptr, nullptr, 
+      "<dir> chroots process to <dir> after initialization" },
+
+    { "-U", Parameter::PT_IMPLIED, nullptr, nullptr, 
+      "use UTC for timestamps" },
+
+    { "-u", Parameter::PT_STRING, nullptr, nullptr, 
+      "<uname> run snort as <uname> or <uid> after initialization" },
+
+    { "-V", Parameter::PT_IMPLIED, nullptr, nullptr, 
+      "(same as --version)" },
+
+    { "-v", Parameter::PT_IMPLIED, nullptr, nullptr, 
+      "be verbose" },
+
+    { "-W", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "lists available interfaces" },
+
+#if defined(DLT_IEEE802_11)
+    { "-w", Parameter::PT_IMPLIED, nullptr, nullptr, 
+      "dump 802.11 management and control frames" },
+#endif
+
+    { "-X", Parameter::PT_IMPLIED, nullptr, nullptr, 
+      "dump the raw packet data starting at the link layer" },
+
+    { "-x", Parameter::PT_IMPLIED, nullptr, nullptr, 
+      "same as --conf-error-out" },
+
+    { "-y", Parameter::PT_IMPLIED, nullptr, nullptr, 
+      "include year in timestamp in the alert and log files" },
+
+    { "-z", Parameter::PT_INT, "1:", nullptr,
+      "<count> maximum number of packet threads (same as --max-packet-threads)" },
+
+    { "--alert-before-pass", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "process alert, drop, sdrop, or reject before pass; "
+       "default is pass before alert, drop,..." },
+
+    { "--bpf", Parameter::PT_STRING, nullptr, nullptr,
+      "<filter options> are standard BPF options, as seen in TCPDump" },
+
+    { "--conf-error-out", Parameter::PT_IMPLIED, nullptr, nullptr, 
+      "output error instead of warning if duplicate rules are found (same as -x)" },
+
+    { "--create-pidfile", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "create PID file, even when not in Daemon mode" },
+
+    { "--daq", Parameter::PT_STRING, nullptr, nullptr,
+      "<type> select packet acquisition module (default is pcap)" },
+
+    { "--daq-dir", Parameter::PT_STRING, nullptr, nullptr,
+      "<dir> tell snort where to find desired DAQ" },
+
+    { "--daq-list", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "list packet acquisition modules available in optional dir, default is static modules only" },
+
+    { "--daq-mode", Parameter::PT_STRING, nullptr, nullptr,
+      "<mode> select the DAQ operating mode" },
+
+    { "--daq-var", Parameter::PT_STRING, nullptr, nullptr,
+      "<name=value> specify extra DAQ configuration variable" },
+
+    { "--dump-builtin-rules", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "creates stub rule files of all loaded rules libraries" },
+
+    { "--dump-dynamic-rules", Parameter::PT_STRING, nullptr, nullptr,
+      "<path> creates stub rule files of all loaded rules libraries" },
+
+    { "--dirty-pig", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "don't flush packets and release memory on shutdown" },
+
+    { "--enable-inline-test", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "enable Inline-Test Mode Operation" },
+
+    { "--help", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "overview of help" },
+
+    { "--help-builtin", Parameter::PT_STRING, nullptr, nullptr,
+      "<module prefix> output matching builtin rules" },
+
+    { "--help-buffers", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "output available inspection buffers" },
+
+    { "--help-commands", Parameter::PT_STRING, nullptr, nullptr,
+      "[<module prefix>] output matching commands" },
+
+    { "--help-config", Parameter::PT_STRING, nullptr, nullptr,
+      "[<module prefix>] output matching config options" },
+
+    { "--help-gids", Parameter::PT_STRING, nullptr, nullptr,
+      "[<module prefix>] output matching generators" },
+
+    { "--help-module", Parameter::PT_STRING, nullptr, nullptr,
+      "<module> output description of given module" },
+
+    { "--help-options", Parameter::PT_STRING, nullptr, nullptr,
+      "<option prefix> output matching command line option quick help" },
+
+    { "--help-signals", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "dump available control signals" },
+
+    { "--list-modules", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "list all known modules" },
+
+    { "--list-plugins", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "list all known plugins" },
+
+    { "--lua", Parameter::PT_STRING, nullptr, nullptr,
+      "<chunk> extend/override conf with chunk; may be repeated" },
+
+    { "--logid", Parameter::PT_INT, "0:65535", nullptr,
+      "<0xid> log Identifier to uniquely id events for multiple snorts (same as -G)" },
+
+    { "--markup", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "output help in asciidoc compatible format" },
+
+    { "--max-packet-threads", Parameter::PT_INT, "0:", nullptr,
+      "<count> configure maximum number of packet threads (same as -z)" },
+
+    { "--nostamps", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "don't include timestamps in log file names" },
+
+    { "--nolock-pidfile", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "do not try to lock Snort PID file" },
+
+    { "--pause", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "load config and wait for further commands before processing packets", },
+
+    { "--pcap-file", Parameter::PT_STRING, nullptr, nullptr,
+      "<file> file that contains a list of pcaps to read - read mode is implied" },
+
+    { "--pcap-list", Parameter::PT_STRING, nullptr, nullptr,
+      "<list> a space separated list of pcaps to read - read mode is implied" },
+
+    { "--pcap-dir", Parameter::PT_STRING, nullptr, nullptr,
+      "<dir> a directory to recurse to look for pcaps - read mode is implied" },
+
+    { "--pcap-filter", Parameter::PT_STRING, nullptr, nullptr,
+      "<filter> filter to apply when getting pcaps from file or directory" },
+
+    { "--pcap-loop", Parameter::PT_INT, "-1:", nullptr,
+      "<count> read all pcaps <count> times;  0 will read until Snort is terminated" },
+
+    { "--pcap-no-filter", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "reset to use no filter when getting pcaps from file or directory" },
+
+    { "--pcap-reload", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "if reading multiple pcaps, reload snort config between pcaps" },
+
+    { "--pcap-reset", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "reset Snort after each pcap" },
+
+    { "--pcap-show", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "print a line saying what pcap is currently being read" },
+
+    { "--plugin-path", Parameter::PT_STRING, nullptr, nullptr,
+      "<path> where to find plugins" },
+
+    { "--process-all-events", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "process all action groups" },
+
+    { "--rule", Parameter::PT_STRING, nullptr, nullptr,
+      "<rules> to be added to configuration; may be repeated" },
+
+    { "--script-path", Parameter::PT_STRING, nullptr, nullptr,
+      "<path> where to find luajit scripts" },
+
+    { "--shell", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "enable the interactive command line", },
+
+    { "--skip", Parameter::PT_INT, "0:", nullptr,
+      "<n> skip 1st n packets", },
+
+    { "--snaplen", Parameter::PT_INT, "68:65535", nullptr,
+      "<snap> set snaplen of packet (same as -s)", },
+
+    { "--treat-drop-as-alert", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "converts drop, sdrop, and reject rules into alert rules during startup" },
+
+    { "--treat-drop-as-ignore", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "use drop, sdrop, and reject rules to ignore session traffic when not inline" },
+
+#ifdef UNIT_TEST
+    { "--unit-test", Parameter::PT_STRING, nullptr, nullptr,
+      "<verbosity> run unit tests with given libcheck output mode" },
+#endif
+    { "--version", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "show version number (same as -V)" },
+
+    { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
+};
+
+//-------------------------------------------------------------------------
+// module
+//-------------------------------------------------------------------------
+
+class SnortModule : public Module
+{
+public:
+    SnortModule() : Module("snort", snort_params)
+    { };
+
+    const Command* get_commands() const
+    { return snort_cmds; };
+
+    bool set(const char*, Value&, SnortConfig*);
+};
+
+bool SnortModule::set(const char*, Value& v, SnortConfig* sc)
+{
+    if ( v.is("-?") )
+        help_usage(sc, v.get_string());
+
+    else if ( v.is("-A") )
+        config_alert_mode(sc, v.get_string());
+
+    else if ( v.is("-B") )
+        ConfigObfuscationMask(sc, v.get_string());
+
+    else if ( v.is("-C") )
+        ConfigDumpCharsOnly(sc, v.get_string());
+
+    else if ( v.is("-c") )
+        config_conf(sc, v.get_string());
+
+    else if ( v.is("-D") )
+        config_daemon(sc, v.get_string());
+
+    else if ( v.is("-d") )
+        ConfigDumpPayload(sc, v.get_string());
+
+    else if ( v.is("-E") )
+    {
+        sc->run_flags |= RUN_FLAG__DAEMON_RESTART;
+        config_daemon(sc, v.get_string());
+    }
+
+    else if ( v.is("-e") )
+        ConfigDecodeDataLink(sc, v.get_string());
+
+    else if ( v.is("-f") )
+        sc->output_flags |= OUTPUT_FLAG__LINE_BUFFER;
+
+    else if ( v.is("-G") || v.is("--logid") )
+        sc->event_log_id = v.get_long() << 16;
+
+    else if ( v.is("-g") )
+        ConfigSetGid(sc, v.get_string());
+
+    else if ( v.is("-H") )
+        sc->run_flags |= RUN_FLAG__STATIC_HASH;
+
+    else if ( v.is("-i") )
+        Trough_Multi(SOURCE_LIST, v.get_string());
+
+    else if ( v.is("-j") )
+        sc->remote_control = v.get_long();
+
+    else if ( v.is("-K") )
+        config_log_mode(sc, v.get_string());
+
+    else if ( v.is("-k") )
+        ConfigChecksumMode(sc, v.get_string());
+
+    else if ( v.is("-l") )
+        ConfigLogDir(sc, v.get_string());
+
+    else if ( v.is("-M") )
+        config_syslog(sc, v.get_string());
+
+    else if ( v.is("-m") )
+        ConfigUmask(sc, v.get_string());
+
+    else if ( v.is("-n") )
+        sc->pkt_cnt = v.get_long();
+
+    else if ( v.is("-O") )
+        ConfigObfuscate(sc, v.get_string());
+
+    else if ( v.is("-Q") )
+        sc->run_flags |= RUN_FLAG__INLINE;
+
+    else if ( v.is("-q") )
+        ConfigQuiet(sc, v.get_string());
+
+    else if ( v.is("-r") || v.is("--pcap-list") )
+    {
+        Trough_Multi(SOURCE_LIST, v.get_string());
+        sc->run_flags |= RUN_FLAG__READ;
+    }
+    else if ( v.is("-S") )
+        config_set_var(sc, v.get_string());
+
+    else if ( v.is("-s") )
+        sc->pkt_snaplen = v.get_long();
+
+    else if ( v.is("-T") )
+        sc->run_flags |= RUN_FLAG__TEST;
+
+    else if ( v.is("-t") )
+        ConfigChrootDir(sc, v.get_string());
+
+    else if ( v.is("-U") )
+        ConfigUtc(sc, v.get_string());
+
+    else if ( v.is("-u") )
+        ConfigSetUid(sc, v.get_string());
+
+    else if ( v.is("-V") )
+        help_version(sc, v.get_string());
+
+    else if ( v.is("-v") )
+        ConfigVerbose(sc, v.get_string());
+
+    else if ( v.is("-W") )
+        list_interfaces(sc, v.get_string());
+
+#if defined(DLT_IEEE802_11)
+    else if ( v.is("-w") )
+        sc->output_flags |= OUTPUT_FLAG__SHOW_WIFI_MGMT;
+#endif
+
+    else if ( v.is("-X") )
+        ConfigDumpPayloadVerbose(sc, v.get_string());
+
+    else if ( v.is("-x") || v.is("--conf-error-out") )
+        sc->run_flags |= RUN_FLAG__CONF_ERROR_OUT;
+
+    else if ( v.is("-y") )
+        ConfigShowYear(sc, v.get_string());
+
+    else if ( v.is("-z") || v.is("--max-packet-threads") )
+    {
+        sc->max_threads = v.get_long();
+        if ( !sc->max_threads )
+            sc->max_threads = -1; // max
+    }
+    else if ( v.is("--alert-before-pass") )
+        ConfigAlertBeforePass(sc, v.get_string());
+
+    else if ( v.is("--bpf") )
+        sc->bpf_filter = SnortStrdup(v.get_string());
+
+    else if ( v.is("--create-pidfile") )
+        ConfigCreatePidFile(sc, v.get_string());
+
+    else if ( v.is("--daq") )
+        ConfigDaqType(sc, v.get_string());
+
+    else if ( v.is("--daq-dir") )
+        ConfigDaqDir(sc, v.get_string());
+
+    else if ( v.is("--daq-list") )
+        list_daqs(sc, v.get_string());
+
+    else if ( v.is("--daq-mode") )
+        ConfigDaqMode(sc, v.get_string());
+
+    else if ( v.is("--daq-var") )
+        ConfigDaqVar(sc, v.get_string());
+
+    else if ( v.is("--dump-builtin-rules") )
+       dump_builtin_rules(sc, v.get_string());
+
+    else if ( v.is("--dump-dynamic-rules") )
+       dump_dynamic_rules(sc, v.get_string());
+
+    else if ( v.is("--dirty-pig") )
+        ConfigDirtyPig(sc, v.get_string());
+
+    else if ( v.is("--enable-inline-test") )
+        sc->run_flags |= RUN_FLAG__INLINE_TEST;
+
+    else if ( v.is("--help") )
+        help_basic(sc, v.get_string());
+
+    else if ( v.is("--help-builtin") )
+        help_builtin(sc, v.get_string());
+
+    else if ( v.is("--help-buffers") )
+        help_buffers(sc, v.get_string());
+
+    else if ( v.is("--help-commands") )
+        help_commands(sc, v.get_string());
+
+    else if ( v.is("--help-config") )
+        help_config(sc, v.get_string());
+
+    else if ( v.is("--help-gids") )
+        help_gids(sc, v.get_string());
+
+    else if ( v.is("--help-module") )
+        help_module(sc, v.get_string());
+
+    else if ( v.is("--help-options") )
+        help_options(sc, v.get_string());
+
+    else if ( v.is("--help-signals") )
+        help_signals(sc, v.get_string());
+
+    else if ( v.is("--list-modules") )
+        list_modules(sc, v.get_string());
+
+    else if ( v.is("--list-plugins") )
+        list_plugins(sc, v.get_string());
+
+    else if ( v.is("--lua") )
+        Shell::set_overrides(v.get_string());
+
+    else if ( v.is("--markup") )
+        config_markup(sc, v.get_string());
+
+    else if ( v.is("--nostamps") )
+        ConfigNoLoggingTimestamps(sc, v.get_string());
+
+    else if ( v.is("--nolock-pidfile") )
+        sc->run_flags |= RUN_FLAG__NO_LOCK_PID_FILE;
+
+    else if ( v.is("--pause") )
+        sc->run_flags |= RUN_FLAG__PAUSE;
+
+    else if ( v.is("--pcap-file") )
+    {
+        Trough_Multi(SOURCE_FILE_LIST, v.get_string());
+        sc->run_flags |= RUN_FLAG__READ;
+    }
+    else if ( v.is("--pcap-dir") )
+    {
+        Trough_Multi(SOURCE_DIR, v.get_string());
+        sc->run_flags |= RUN_FLAG__READ;
+    }
+    else if ( v.is("--pcap-filter") )
+        Trough_SetFilter(v.get_string());
+
+    else if ( v.is("--pcap-loop") )
+        Trough_SetLoopCount(v.get_long());
+
+    else if ( v.is("--pcap-no-filter") )
+        Trough_SetFilter(NULL);
+
+    else if ( v.is("--pcap-reload") )
+        sc->run_flags |= RUN_FLAG__PCAP_RELOAD;
+
+    else if ( v.is("--pcap-reset") )
+        sc->run_flags |= RUN_FLAG__PCAP_RESET;
+
+    else if ( v.is("--pcap-show") )
+        sc->run_flags |= RUN_FLAG__PCAP_SHOW;
+
+    else if ( v.is("--plugin-path") )
+        ConfigPluginPath(sc, v.get_string());
+
+    else if ( v.is("--process-all-events") )
+        ConfigProcessAllEvents(sc, v.get_string());
+
+    else if ( v.is("--rule") )
+        parser_append_rules(v.get_string());
+
+    else if ( v.is("--script-path") )
+        ConfigScriptPath(sc, v.get_string());
+
+    else if ( v.is("--shell") )
+        sc->run_flags |= RUN_FLAG__SHELL;
+
+    else if ( v.is("--skip") )
+        sc->pkt_skip = v.get_long();
+
+    else if ( v.is("--snaplen") )
+        sc->pkt_snaplen = v.get_long();
+
+    else if ( v.is("--treat-drop-as-alert") )
+        ConfigTreatDropAsAlert(sc, v.get_string());
+
+    else if ( v.is("--treat-drop-as-ignore") )
+        ConfigTreatDropAsIgnore(sc, v.get_string());
+
+#ifdef UNIT_TEST
+    else if ( v.is("--unit-test") )
+        unit_test_mode(v.get_string());
+#endif
+    else if ( v.is("--version") )
+        help_version(sc, v.get_string());
+
+    else
+        return false;
+
+    return true;
+}
+
+//-------------------------------------------------------------------------
+// singleton
+//-------------------------------------------------------------------------
+
+static SnortModule snort_module;
+
+Module* get_snort_module()
+{ return &snort_module; }
+
diff --git a/src/main/snort_module.h b/src/main/snort_module.h
new file mode 100644 (file)
index 0000000..921b2b1
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License Version 2 as
+** published by the Free Software Foundation.  You may not use, modify or
+** distribute this program under any other version of the GNU General
+** Public License.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+// snort_module.cc author Russ Combs <rucombs@cisco.com>
+
+#ifndef SNORT_MODULE_H
+#define SNORT_MODULE_H
+
+class Module* get_snort_module();
+
+#endif
+
index a5ed59b09af8d1478112dac8a1a8802bc0c7d1e8..b4b735db25c185ac1095b1cacd0139acd1cbdeaa 100644 (file)
@@ -105,31 +105,14 @@ void IpsManager::delete_option(IpsOption* ips)
         api->dtor(ips);
 }
 
-    
 //-------------------------------------------------------------------------
 
-static bool is_positional(const Parameter* p)
-{
-    return ( p->name && *p->name == '~' );
-}
-
-static const Parameter* find_arg(const Parameter* p, const char* s)
-{
-    while ( p->name )
-    {
-        if ( !strcmp(p->name, s) || !strcmp(p->name, "*") )
-            return p;
-        ++p;
-    }
-    return nullptr;
-}
-
 static bool set_arg(
     Module* m, const Parameter* p, 
     const char* opt, const char* val, SnortConfig* sc)
 {
-    if ( !is_positional(p) )
-        p = find_arg(p, opt);
+    if ( !p->is_positional() )
+        p = Parameter::find(p, opt);
 
     if ( !p )
         return false;
@@ -160,7 +143,6 @@ static bool set_arg(
         if ( m->set(p->name, v, sc) )
             return true;
     }
-
     return false;
 }
 
@@ -216,7 +198,7 @@ bool IpsManager::option_set(
 
     assert(!strcmp(current_keyword, key));
 
-    if ( !*val && is_positional(current_params) )
+    if ( !*val && current_params->is_positional() )
     {
         val = opt;  // eg: gid:116; key="gid" and opt="116"
         opt = "";
@@ -225,7 +207,7 @@ bool IpsManager::option_set(
     if ( !set_arg(current_module, current_params, opt, val, sc) )
         ParseError("invalid argument %s:%s = %s\n", key, opt, val);
 
-    if ( is_positional(current_params) )
+    if ( current_params->is_positional() )
         ++current_params;
 
     return true;
index 52d61b6bcc80601cbdaf21fbcb3be4e1e1986e3e..c6bfa96852c3f496d98646d28c32ddfe6a0df22f 100644 (file)
@@ -388,10 +388,11 @@ static int GetPcaps(SF_LIST *pol, SF_QUEUE *pcap_queue)
     return 0;
 }
 
+long Trough_GetLoopCount()
+{ return pcap_loop_count; }
+
 void Trough_SetLoopCount(long int c)
-{
-    pcap_loop_count = c;
-}
+{ pcap_loop_count = c; }
 
 void Trough_SetFilter (const char* f)
 {
index d9b354a2c035244eafcc221cc398719a45290d67..9a02d23d5b624d028559a71108e7e71ae9e43b85 100644 (file)
@@ -29,6 +29,7 @@ enum SourceType
 };
 
 void Trough_SetLoopCount(long int);
+long Trough_GetLoopCount();
 void Trough_SetFilter(const char*);
 void Trough_Multi(SourceType, const char* list);
 void Trough_SetUp(void);
index 2f3052ff5b35c4d06692b740a4cd2f1c9257be92..0382a656391d6d5764f8569f982f74768526734a 100644 (file)
@@ -1,6 +1,8 @@
 
 
 add_library (parser STATIC 
+    arg_list.cc 
+    arg_list.h 
     parser.cc 
     parser.h 
     parse_byte_code.cc 
index beb8238587f10903eeaa8306e43828efb6510f10..54de8e30f2929a97d20560c3e33b0253ae7982c7 100644 (file)
@@ -3,6 +3,7 @@ AUTOMAKE_OPTIONS=foreign no-dependencies
 noinst_LIBRARIES = libparser.a
 
 libparser_a_SOURCES = \
+arg_list.cc arg_list.h \
 parser.cc parser.h \
 parse_byte_code.cc parse_byte_code.h \
 parse_conf.cc parse_conf.h \
diff --git a/src/parser/arg_list.cc b/src/parser/arg_list.cc
new file mode 100644 (file)
index 0000000..02a76f6
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License Version 2 as
+** published by the Free Software Foundation.  You may not use, modify or
+** distribute this program under any other version of the GNU General
+** Public License.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+// arg_list.cc author Russ Combs <rucombs@cisco.com>
+
+#include "arg_list.h"
+
+#include "string.h"
+
+void ArgList::dump()
+{
+    for ( int i = 0; i < argc; ++i )
+        printf("argv[%d]='%s'\n", i, argv[i]);
+}
+
+// FIXIT this chokes on -n -4 because it thinks
+// -4 is another arg instead of an option to -n
+bool ArgList::get_arg(const char*& key, const char*& val)
+{
+    while ( ++idx < argc )
+    {
+        char* s = argv[idx];
+
+        if ( arg )
+        {
+            key = arg;
+            if ( s[0] != '-' )
+                val = s;
+            else
+            {
+                val = "";
+                --idx;
+            }
+            arg = nullptr;
+            return true;
+        }
+        if ( s[0] != '-' )
+        {
+            key = "";
+            val = s;
+            return true;
+        }
+        if ( s[1] != '-' )
+        {
+            s += 1; 
+            if ( strlen(s) > 1 )
+            {
+                buf.assign(s, 1);
+                key = buf.c_str();
+                val = s + 1;
+                return true;
+            }
+            else if ( strlen(s) > 0 )
+                arg = s;
+            else
+                arg = "-";
+        }
+        else
+        {
+            s += 2;
+            char* eq = strchr(s, '=');
+
+            if ( eq )
+            {
+                buf.assign(s, eq-s);
+                key=buf.c_str();
+                val = eq + 1;
+                return true;
+            }
+            else
+                arg = s;
+        }
+    }
+    if ( arg )
+    {
+        key = arg;
+        val = "";
+        arg = nullptr;
+        return true;
+    }
+    return false;
+}
+
diff --git a/src/parser/arg_list.h b/src/parser/arg_list.h
new file mode 100644 (file)
index 0000000..f59ca96
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License Version 2 as
+** published by the Free Software Foundation.  You may not use, modify or
+** distribute this program under any other version of the GNU General
+** Public License.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+// arg_list.h author Russ Combs <rucombs@cisco.com>
+
+#ifndef ARG_LIST_H
+#define ARG_LIST_H
+
+#include <string>
+
+class ArgList
+{
+public:
+    ArgList(int c, char* v[])
+    { argc = c; argv = v; reset(); };
+
+    void reset()
+    { idx = 0; arg = nullptr; };
+
+    bool get_arg(const char*& key, const char*& val);
+    void dump();
+
+private:
+    char** argv;
+    int argc, idx;
+    const char* arg;
+    std::string buf;
+};
+
+#endif
+
index ceba073cfc886820cfd5253098546298989b7969..05e2b47183726f347ad2d3ab0765f78dd49851d3 100644 (file)
@@ -1,6 +1,5 @@
 /*
 ** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
-** Copyright (C) 2013-2013 Sourcefire, Inc.
 **
 ** This program is free software; you can redistribute it and/or modify
 ** it under the terms of the GNU General Public License Version 2 as
@@ -17,6 +16,7 @@
 ** along with this program; if not, write to the Free Software
 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
+// cmd_line.cc author Russ Combs <rucombs@cisco.com>
 
 #include "cmd_line.h"
 
 using namespace std;
 
 #include "config_file.h"
-#include "parser.h"
 #include "vars.h"
 #include "detection/detect.h"
 #include "helpers/process.h"
 #include "main/analyzer.h"
+#include "main/snort.h"
+#include "main/snort_module.h"
 #include "main/shell.h"
+#include "framework/module.h"
+#include "framework/parameter.h"
 #include "managers/event_manager.h"
 #include "managers/so_manager.h"
 #include "managers/inspector_manager.h"
@@ -44,984 +47,112 @@ using namespace std;
 #include "packet_io/trough.h"
 #include "packet_io/sfdaq.h"
 #include "packet_io/intf.h"
+#include "parser/arg_list.h"
 #include "parser/parser.h"
 #include "utils/util.h"
 #include "helpers/markup.h"
 
-#define LOG_NONE  "none"
-#define LOG_TEXT  "text"
-#define LOG_PCAP  "pcap"
-
-#define ALERT_NONE    "none"
-#define ALERT_CMG     "cmg"
-#define ALERT_JH      "jh"
-#define ALERT_DJR     "djr"
-#define ALERT_AJK     "ajk"
-
-#define OUTPUT_AJK  "unified2"
-#define OUTPUT_CMG  "alert_fast"
-#define OUTPUT_LOG  "alert_syslog"
-#define OUTPUT_PCAP "log_tcpdump"
-
-static char* lua_conf = nullptr;
-static char* snort_conf_dir = nullptr;
-
-const char* get_snort_conf() { return lua_conf; }
-const char* get_snort_conf_dir() { return snort_conf_dir; }
-
-static void help_args(const char* pfx);
-
-static const char* snort_help =
-"Snort has several options to get more help:\n"
-"\n"
-"--help this overview of help\n"
-"--help-builtin [<module prefix>] output matching builtin rules\n"
-"--help-buffers output available inspection buffers\n"
-"--help-commands [<module prefix>] output matching commands\n"
-"--help-config [<module prefix>] output matching config options\n"
-"--help-gids [<module prefix>] output matching generators\n"
-"--help-module <module> output description of given module\n"
-"--help-options [<option prefix>] output matching command line options\n"
-"--help-signals dump available control signals\n"
-"--list-modules list all known modules\n"
-"--list-plugins list all known modules\n"
-"--markup output help in asciidoc compatible format\n"
-"\n"
-"--help* and --list* options preempt other processing so should be last on the\n"
-"command line since any following options are ignored.  To ensure options like\n"
-"--plugin-path take effect, place them ahead of the help or list options.\n"
-"\n"
-"Options that filter output based on a matching prefix, such as --help-config\n"
-"won't output anything if there is no match.  If no prefix is given, everything\n"
-"matches.\n"
-"\n"
-"Parameters are given with this format:\n"
-"\n"
-"    type name = default: help { range }\n"
-"\n"
-"+ For Lua configuration (not IPS rules), if the name ends with [] it is a\n"
-"  list item and can be repeated.\n"
-"+ For IPS rules only, names starting with ~ indicate positional parameters.\n"
-"  The name does not appear in the rule.\n"
-"+ IPS rules may also have a wild card parameter, which is indicated by a *.\n"
-"  Only used for metadata that Snort ignores.\n"
-;
-
-//-------------------------------------------------------------------------
-// private methods
 //-------------------------------------------------------------------------
 
-static void SetSnortConfDir(const char* file)
+static void check_flags(SnortConfig* sc)
 {
-    /* extract the config directory from the config filename */
-    if ( file )
+    if ((sc->run_flags & RUN_FLAG__TEST) &&
+        (sc->run_flags & RUN_FLAG__DAEMON))
     {
-        const char *path_sep = strrchr(file, '/');
-
-        /* is there a directory seperator in the filename */
-        if (path_sep != NULL)
-        {
-            path_sep++;  /* include path separator */
-            snort_conf_dir = SnortStrndup(file, path_sep - file);
-        }
-        else
-        {
-            snort_conf_dir = SnortStrdup("./");
-        }
-
-        DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Config file = %s, config dir = "
-                    "%s\n", file, snort_conf_dir););
+        FatalError("Cannot use test mode and daemon mode together.\n"
+                   "To verify configuration, run first in test "
+                   "mode and then restart in daemon mode.\n");
     }
-}
-
-//-------------------------------------------------------------------------
-// arg foo
-//-------------------------------------------------------------------------
 
-class ArgList
-{
-public:
-    ArgList(int c, char* v[])
-    { argc = c; argv = v; reset(); };
-
-    void reset()
-    { idx = 0; arg = nullptr; };
-
-    bool get_arg(const char*& key, const char*& val);
-    void dump();
-
-private:
-    char** argv;
-    int argc, idx;
-    const char* arg;
-    string buf;
-};
-
-void ArgList::dump()
-{
-    for ( int i = 0; i < argc; ++i )
-        printf("argv[%d]='%s'\n", i, argv[i]);
-}
-
-// FIXIT this chokes on -n -4 because it thinks
-// -4 is another arg instead of an option to -n
-bool ArgList::get_arg(const char*& key, const char*& val)
-{
-    while ( ++idx < argc )
-    {
-        char* s = argv[idx];
-
-        if ( arg )
-        {
-            key = arg;
-            if ( s[0] != '-' )
-                val = s;
-            else
-            {
-                val = "";
-                --idx;
-            }
-            arg = nullptr;
-            return true;
-        }
-        if ( s[0] != '-' )
-        {
-            key = "";
-            val = s;
-            return true;
-        }
-        if ( s[1] != '-' )
-        {
-            s += 1; 
-            if ( strlen(s) > 1 )
-            {
-                buf.assign(s, 1);
-                key = buf.c_str();
-                val = s + 1;
-                return true;
-            }
-            else if ( strlen(s) > 0 )
-                arg = s;
-            else
-                arg = "-";
-        }
-        else
-        {
-            s += 2;
-            char* eq = strchr(s, '=');
-
-            if ( eq )
-            {
-                buf.assign(s, eq-s);
-                key=buf.c_str();
-                val = eq + 1;
-                return true;
-            }
-            else
-                arg = s;
-        }
-    }
-    if ( arg )
+    if ((sc->run_flags & RUN_FLAG__INLINE) &&
+            (sc->run_flags & RUN_FLAG__INLINE_TEST))
     {
-        key = arg;
-        val = "";
-        arg = nullptr;
-        return true;
+        FatalError("Cannot use inline adapter mode and inline test "
+                "mode together. \n");
     }
-    return false;
-}
-
-//-------------------------------------------------------------------------
-// config methods
-//-------------------------------------------------------------------------
-
-static long int loop_count = 0;
-
-static void config_syslog(SnortConfig* sc, const char*)
-{
-    static bool syslog_configured = false;
-
-    if (syslog_configured)
-        return;
-
-    /* If daemon or logging to syslog use "snort" as identifier and
-     * start logging there now */
-    openlog("snort", LOG_PID | LOG_CONS, LOG_DAEMON);
 
-    sc->logging_flags |= LOGGING_FLAG__SYSLOG;
-    syslog_configured = true;
-}
-
-static void config_daemon(SnortConfig* sc, const char* val)
-{
-    static bool daemon_configured = false;
-
-    if (daemon_configured)
-        return;
-
-    /* If daemon or logging to syslog use "snort" as identifier and
-     * start logging there now */
-    openlog("snort", LOG_PID | LOG_CONS, LOG_DAEMON);
-
-    ConfigDaemon(sc, val);
-    daemon_configured = true;
-}
-
-static void config_daemon_restart(SnortConfig* sc, const char* val)
-{
-    sc->run_flags |= RUN_FLAG__DAEMON_RESTART;
-    config_daemon(sc, val);
-}
-
-//-------------------------------------------------------------------------
-
-static void help_basic(SnortConfig*, const char*)
-{
-    fprintf(stdout, "Snort help: %s", snort_help);
-    exit(0);
-}
-
-static void help_usage(SnortConfig*, const char* val)
-{
-    fprintf(stdout, "USAGE: %s [-options] <filter options>\n", "snort");
-    help_args(val);
-    exit(1);
-}
-
-static void help_options(SnortConfig*, const char* val)
-{
-    help_args(val);
-    exit(0);
-}
-
-static void help_signals(SnortConfig*, const char*)
-{
-    help_signals();
-    exit(0);
-}
-
-enum HelpType {
-    HT_CFG, HT_CMD, HT_GID, HT_IPS, HT_MOD,
-    HT_BUF, HT_LST, HT_PLG, HT_DDR, HT_DBR
-};
-
-static void show_help(SnortConfig* sc, const char* val, HelpType ht)
-{
-    snort_conf = new SnortConfig;
-    PluginManager::load_plugins(sc->plugin_path);
-    ModuleManager::init();
-
-    switch ( ht )
+    if (Trough_GetLoopCount() && !(sc->run_flags & RUN_FLAG__READ))
     {
-    case HT_CFG:
-        ModuleManager::show_configs(val);
-        break;
-    case HT_CMD:
-        ModuleManager::show_commands(val);
-        break;
-    case HT_GID:
-        ModuleManager::show_gids(val);
-        break;
-    case HT_IPS:
-        ModuleManager::show_rules(val);
-        break;
-    case HT_MOD:
-        ModuleManager::show_module(val);
-        break;
-    case HT_BUF:
-        InspectorManager::dump_buffers();
-        break;
-    case HT_LST:
-        ModuleManager::list_modules();
-        break;
-    case HT_PLG:
-        PluginManager::list_plugins();
-        break;
-    case HT_DDR:
-        SoManager::dump_rule_stubs(val);
-        break;
-    case HT_DBR:
-        ModuleManager::dump_rules(val);
-        break;
+        FatalError("--pcap-loop can only be used in combination with pcaps "
+                   "on the command line.\n");
     }
-    ModuleManager::term();
-    PluginManager::release_plugins();
-    delete snort_conf;
-    exit(0);
-}
-
-static void help_config(SnortConfig* sc, const char* val)
-{
-    show_help(sc, val, HT_CFG);
-}
-
-static void help_commands(SnortConfig* sc, const char* val)
-{
-    show_help(sc, val, HT_CMD);
-}
 
-static void config_markup(SnortConfig*, const char*)
-{
-    Markup::enable();
-}
-
-static void help_gids(SnortConfig* sc, const char* val)
-{
-    show_help(sc, val, HT_GID);
-}
-
-static void help_buffers(SnortConfig* sc, const char* val)
-{
-    show_help(sc, val, HT_BUF);
-}
-
-static void help_builtin(SnortConfig* sc, const char* val)
-{
-    show_help(sc, val, HT_IPS);
-}
-
-static void help_module(SnortConfig* sc, const char* val)
-{
-    show_help(sc, val, HT_MOD);
-}
-
-static void list_modules(SnortConfig* sc, const char* val)
-{
-    show_help(sc, val, HT_LST);
-}
-
-static void list_plugins(SnortConfig* sc, const char* val)
-{
-    show_help(sc, val, HT_PLG);
-}
-
-static void dump_builtin_rules(SnortConfig* sc, const char* val)
-{
-    show_help(sc, val, HT_DBR);
-}
-
-static void dump_dynamic_rules(SnortConfig* sc, const char* val)
-{
-    show_help(sc, val, HT_DDR);
-}
-
-static void config_lua(SnortConfig*, const char* val)
-{
-    Shell::set_overrides(val);
-}
-
-#ifdef UNIT_TEST
-#include "test/unit_test.h"
-static void config_unit_test(SnortConfig*, const char* val)
-{
-    unit_test_mode(val);
-}
-#endif
-
-static void config_version(SnortConfig*, const char*)
-{
-    DisplayBanner();
-    exit(0);
-}
-
-static void config_show_interfaces(SnortConfig*, const char*)
-{
-    DisplayBanner();
-    PrintAllInterfaces();
-    exit(0);
-}
-
-static void config_daq_list(SnortConfig* sc, const char* val)
-{
-    if ( val )
-        ConfigDaqDir(sc, val);
-
-    DAQ_Load(sc);
-    DAQ_PrintTypes(stdout);
-    DAQ_Unload();
-    exit(0);
-}
-
-static void config_nolock_pid_file(SnortConfig* sc, const char*)
-{
-    sc->run_flags |= RUN_FLAG__NO_LOCK_PID_FILE;
-}
-
-static void config_pause(SnortConfig* sc, const char*)
-{
-    sc->run_flags |= RUN_FLAG__PAUSE;
-}
-
-static void config_alert_mode(SnortConfig* sc, const char* val)
-{
-    if (strcasecmp(val, ALERT_NONE) == 0)
-    {
-        sc->output_flags |= OUTPUT_FLAG__NO_ALERT;
-        EventManager::enable_alerts(false);
-    }
-    else if ((strcasecmp(val, ALERT_CMG) == 0) ||
-             (strcasecmp(val, ALERT_JH) == 0) ||
-             (strcasecmp(val, ALERT_DJR) == 0))
-    {
-        sc->output = OUTPUT_CMG;
-        sc->output_flags |= OUTPUT_FLAG__SHOW_DATA_LINK;
-        sc->output_flags |= OUTPUT_FLAG__APP_DATA;
-    }
-    else if (strcasecmp(val, ALERT_AJK) == 0)
+    if ((sc->run_flags & RUN_FLAG__PCAP_RELOAD) &&
+        !(sc->run_flags & RUN_FLAG__READ))
     {
-        sc->output = OUTPUT_AJK;
+        FatalError("--pcap-reload can only be used in combination with pcaps "
+                   "on the command line.\n");
     }
-    else
-        sc->output = val;
 }
 
-static void config_conf(SnortConfig*, const char* val)
-{
-    lua_conf = SnortStrdup(val);
-    SetSnortConfDir(lua_conf);
-    set_main_hook(snort_inspect);
-}
+//-------------------------------------------------------------------------
 
-static void config_line_buffer(SnortConfig* sc, const char*)
+static bool set_arg(
+    Module* m, const Parameter* p,
+    const char* key, const char* val, SnortConfig* sc)
 {
-    sc->output_flags |= OUTPUT_FLAG__LINE_BUFFER;
-}
+    Value v(key);
+    bool ok = true;
 
-static void config_log_id(SnortConfig* sc, const char* val)
-{
-    char *endptr;
-    sc->event_log_id = SnortStrtoul(val, &endptr, 0);
+    if ( p->type == Parameter::PT_IMPLIED )
+        v.set(true);
 
-    if ((errno == ERANGE) || (*endptr != '\0') ||
-        (sc->event_log_id > UINT16_MAX))
+    else if ( p->type == Parameter::PT_INT )
     {
-        FatalError("Snort log identifier invalid: %s.  It must "
-                   "be between 0 and %u.\n", val, UINT16_MAX);
-    }
-
-    /* Forms upper 2 bytes.  Lower two bytes are the event id */
-    sc->event_log_id <<= 16;
-
-}
-
-static void config_static_hash(SnortConfig* sc, const char*)
-{
-    sc->run_flags |= RUN_FLAG__STATIC_HASH;
-}
-
-static void config_remote_control(SnortConfig* sc, const char* val)
-{
-    sc->remote_control = atoi(val);  // FIXIT add to conf?
-}
-
-static void config_iface(SnortConfig*, const char* val)
-{
-    Trough_Multi(SOURCE_LIST, val);
-}
+        char* end = nullptr;
+        long n = strtol(val, &end, 0);
 
-static void config_log_mode(SnortConfig* sc, const char* val)
-{
-    if (strcasecmp(val, LOG_NONE) == 0)
-    {
-        sc->output_flags |= OUTPUT_FLAG__NO_LOG;
-        set_main_hook(snort_ignore);
-        EventManager::enable_logs(false);
-    }
-    else if (strcasecmp(val, LOG_TEXT) == 0)
-    {
-        set_main_hook(snort_print);
-    }
-    else if (strcasecmp(val, LOG_PCAP) == 0)
-    {
-        sc->output = OUTPUT_PCAP;
-        set_main_hook(snort_log);
+        if ( !*end )
+            v.set(n);
+        else
+            ok = false;
     }
     else
-    {
-        FatalError("Unknown -K option: %s\n", val);
-    }
-}
+        v.set(val);
 
-static void config_inline(SnortConfig* sc, const char*)
-{
-    sc->run_flags |= RUN_FLAG__INLINE;
-}
-
-static void config_inline_test(SnortConfig* sc, const char*)
-{
-    sc->run_flags |= RUN_FLAG__INLINE_TEST;
-}
-
-
-static void config_test_mode(SnortConfig* sc, const char*)
-{
-    sc->run_flags |= RUN_FLAG__TEST;
-}
-
-#if defined(DLT_IEEE802_11)
-static void config_show_wifi_mgt(SnortConfig* sc, const char*)
-{
-    sc->output_flags |= OUTPUT_FLAG__SHOW_WIFI_MGMT;
-}
-#endif
-static void config_conf_error_out(SnortConfig* sc, const char*)
-{
-    sc->run_flags |= RUN_FLAG__CONF_ERROR_OUT;
-}
-
-static void config_max_threads(SnortConfig* sc, const char* val)
-{
-    sc->max_threads = atoi(val);
-    if ( !sc->max_threads )
-        sc->max_threads = -1; // max
-}
-
-static void config_trough_file(SnortConfig* sc, const char* val)
-{
-    Trough_Multi(SOURCE_FILE_LIST, val);
-    sc->run_flags |= RUN_FLAG__READ;
-}
-
-static void config_trough_list(SnortConfig* sc, const char* val)
-{
-    Trough_Multi(SOURCE_LIST, val);
-    sc->run_flags |= RUN_FLAG__READ;
-}
-
-static void config_trough_dir(SnortConfig* sc, const char* val)
-{
-    Trough_Multi(SOURCE_DIR, val);
-    sc->run_flags |= RUN_FLAG__READ;
-}
-
-static void config_pcap_loop(SnortConfig*, const char* val)
-{
-    char *endptr;
-    loop_count = SnortStrtol(val, &endptr, 0);
-
-    if ((errno == ERANGE) || (*endptr != '\0') ||
-        (loop_count < 0) || (loop_count > 2147483647))
+    if ( ok && p->validate(v) )
     {
-        FatalError("Valid values for --pcap-loop are between 0 and 2147483647\n");
-    }
+        v.set(p);
 
-    if (loop_count == 0)
-        Trough_SetLoopCount(-1);
-    else
-        Trough_SetLoopCount(loop_count);
-}
-
-static void config_pcap_reset(SnortConfig* sc, const char*)
-{
-    sc->run_flags |= RUN_FLAG__PCAP_RESET;
-}
-
-static void config_pcap_reload(SnortConfig* sc, const char*)
-{
-    sc->run_flags |= RUN_FLAG__PCAP_RELOAD;
-}
-
-static void config_pcap_filter(SnortConfig*, const char* val)
-{
-    Trough_SetFilter(val);
-}
-
-static void config_pcap_no_filter(SnortConfig*, const char*)
-{
-    Trough_SetFilter(NULL);
-}
-
-
-static void config_rule(SnortConfig*, const char* r)
-{
-    parser_append_rules(r);
-}
-
-static void config_pcap_show(SnortConfig* sc, const char*)
-{
-    sc->run_flags |= RUN_FLAG__PCAP_SHOW;
-}
-
-static void config_shell(SnortConfig* sc, const char*)
-{
-    sc->run_flags |= RUN_FLAG__SHELL;
-}
-
-static void config_bpf(SnortConfig* sc, const char* val)
-{
-    sc->bpf_filter = SnortStrdup(val);
+        if ( m->set(p->name, v, sc) )
+            return true;
+    }
+    return false;
 }
 
-static void config_pkt_count(SnortConfig* sc, const char* val)
-{
-    sc->pkt_cnt = strtol(val, nullptr, 0);
-}
+//-------------------------------------------------------------------------
 
-static void config_skip(SnortConfig* sc, const char* val)
+static bool is_special(const char* key)
 {
-    sc->pkt_skip = strtol(val, nullptr, 0);
+    return ( strlen(key) == 1 && strchr("MEDq", *key) );
 }
 
-static void config_ignore(SnortConfig*, const char*)
-{ /* for basic opts already handled as spec opts */ }
-
-typedef void (*ParseConfigFunc)(SnortConfig *, const char* val);
-
-struct ConfigFunc
-{
-    const char *name;
-    ParseConfigFunc parse_func;
-    const char* help;
-};
-
-static ConfigFunc spec_opts[] =
-{
-    // stuff we need to do asap for maximum effect
-    { "M", config_syslog, "" },
-    { "E", config_daemon_restart, "" },
-    { "D", config_daemon, "" },
-    { "q", ConfigQuiet, "" },
-
-    // stuff we do now because we are going to quit anyway
-    { "W", config_show_interfaces, "" },
-    { "?", help_usage, "" },
-
-    { nullptr, nullptr, nullptr }
-};
-
-static ConfigFunc basic_opts[] =
-{
-    { "?", config_ignore,  // spec opt
-      "show usage" },
-
-    { "A", config_alert_mode, 
-      "<mode> set alert mode: none, cmg, or alert_*" },
-
-    { "B", ConfigObfuscationMask, 
-      "<mask> obfuscated IP addresses in alerts and packet dumps using CIDR mask" },
-
-    { "C", ConfigDumpCharsOnly, 
-      "print out payloads with character data only (no hex)" },
-
-    { "c", config_conf, 
-      "<conf> use this configuration" },
-
-    { "D", config_ignore, // spec opt
-      "run Snort in background (daemon) mode" },
-
-    { "d", ConfigDumpPayload, 
-      "dump the Application Layer" },
-
-    { "E", config_ignore, nullptr },  // spec opt
-
-    { "e", ConfigDecodeDataLink, 
-      "display the second layer header info" },
-
-    { "f", config_line_buffer, 
-      "turn off fflush() calls after binary log writes" },
-
-    { "G", config_log_id, 
-      "<0xid> (same as --logid)" },
-
-    { "g", ConfigSetGid, 
-      "<gname> run snort gid as <gname> group (or gid) after initialization" },
-
-    { "H", config_static_hash, 
-      "make hash tables deterministic" },
-
-    { "i", config_iface, 
-      "<iface>... list of interfaces" },
-
-    { "j", config_remote_control,
-      "set port to listen for telnet connections" },
-
-    { "K", config_log_mode, 
-      "<mode> logging mode (none(default), text, or pcap)" },
-
-    { "k", ConfigChecksumMode, 
-      "<mode> checksum mode (all,noip,notcp,noudp,noicmp,none)" },
-
-    { "l", ConfigLogDir, 
-      "<ld> log to directory <ld>" },
-
-    { "M", config_ignore, // spec opt
-      "log messages to syslog (not alerts)" },
-
-    { "m", ConfigUmask, 
-      "<umask> set umask = <umask>" },
-
-    { "n", config_pkt_count, 
-      "stop after n packets" },
-
-    { "O", ConfigObfuscate, 
-      "obfuscate the logged IP addresses" },
-
-    { "Q", config_inline, 
-      "enable inline mode operation" },
-
-    { "q", config_ignore, // spec opt
-      "quiet mode - Don't show banner and status report" },
-
-    { "r", config_trough_list, 
-      "<pcap>... (same as --pcap-list)" },
-
-    { "S", config_set_var, 
-      "<n=v> set rules file variable n equal to value v" },
-
-    { "s", ConfigPacketSnaplen, 
-      "<snap> (same as --snaplen)" },
-
-    { "T", config_test_mode, 
-      "test and report on the current Snort configuration" },
-
-    { "t", ConfigChrootDir, 
-      "<dir> chroots process to <dir> after initialization" },
-
-    { "U", ConfigUtc, 
-      "use UTC for timestamps" },
-
-    { "u", ConfigSetUid, 
-      "<uname> run snort uid as <uname> user (or uid) after initialization" },
-
-    { "V", config_version, 
-      "(same as --version)" },
-
-    { "v", ConfigVerbose, 
-      "be verbose" },
-
-    { "W", config_ignore, // spec opt
-      "lists available interfaces" },
-
-#if defined(DLT_IEEE802_11)
-    { "w", config_show_wifi_mgt, 
-      "dump 802.11 management and control frames" },
-#endif
-
-    { "X", ConfigDumpPayloadVerbose, 
-      "dump the raw packet data starting at the link layer" },
-
-    { "x", config_conf_error_out, 
-      "same as --conf-error-out" },
-
-    { "y", ConfigShowYear, 
-      "include year in timestamp in the alert and log files" },
-
-    { "z", config_max_threads,
-      "configure maximum number of packet threads (same as --max-packet-threads)" },
-
-    { "alert-before-pass", ConfigAlertBeforePass,
-      "process alert, drop, sdrop, or reject before pass; "
-       "default is pass before alert, drop,..." },
-
-    { "bpf", config_bpf,
-      "<filter options> are standard BPF options, as seen in TCPDump" },
-
-    { "conf-error-out", config_conf_error_out, 
-      "output error instead of warning if duplicate rules are found (same as -x)" },
-
-    { "create-pidfile", ConfigCreatePidFile,
-      "create PID file, even when not in Daemon mode" },
-
-    { "daq", ConfigDaqType,
-      "<type> select packet acquisition module (default is pcap)" },
-
-    { "daq-dir", ConfigDaqDir,
-      "<dir> tell snort where to find desired DAQ" },
-
-    { "daq-list", config_daq_list,
-      "list packet acquisition modules available in optional dir, default is static modules only" },
-
-    { "daq-mode", ConfigDaqMode,
-      "<mode> select the DAQ operating mode" },
-
-    { "daq-var", ConfigDaqVar,
-      "<name=value> specify extra DAQ configuration variable" },
-
-    { "dump-builtin-rules", dump_builtin_rules,
-      "creates stub rule files of all loaded rules libraries" },
-
-    { "dump-dynamic-rules", dump_dynamic_rules,
-      "<path> creates stub rule files of all loaded rules libraries" },
-
-    { "dirty-pig", ConfigDirtyPig,
-      "don't flush packets and release memory on shutdown" },
-
-    { "enable-inline-test", config_inline_test,
-      "enable Inline-Test Mode Operation" },
-
-    { "help", help_basic,
-      "overview of help" },
-
-    { "help-builtin", help_builtin,
-      "<module prefix> output matching builtin rules" },
-
-    { "help-buffers", help_buffers,
-      "output available inspection buffers" },
-
-    { "help-commands", help_commands,
-      "[<module prefix>] output matching commands" },
-
-    { "help-config", help_config,
-      "[<module prefix>] output matching config options" },
-
-    { "help-gids", help_gids,
-      "[<module prefix>] output matching generators" },
-
-    { "help-module", help_module,
-      "<module> output description of given module" },
-
-    { "help-options", help_options,
-      "<option prefix> output matching command line option quick help" },
-
-    { "help-signals", help_signals,
-      "dump available control signals" },
-
-    { "list-modules", list_modules,
-      "list all known modules" },
-
-    { "list-plugins", list_plugins,
-      "list all known plugins" },
-
-    { "lua", config_lua,
-      "<chunk> extend/override conf with chunk; may be repeated" },
-
-    { "logid", config_log_id,
-      "<0xid> log Identifier to uniquely id events for multiple snorts (same as -G)" },
-
-    { "markup", config_markup,
-      "output help in asciidoc compatible format" },
-
-    { "max-packet-threads", config_max_threads,
-      "configure maximum number of packet threads (same as -z)" },
-
-    { "nostamps", ConfigNoLoggingTimestamps,
-      "don't include timestamps in log file names" },
-
-    { "nolock-pidfile", config_nolock_pid_file,
-      "do not try to lock Snort PID file" },
-
-    { "pause", config_pause,
-      "load config and wait for further commands before processing packets", },
-
-    { "pcap-file", config_trough_file,
-      "<file> file that contains a list of pcaps to read - read mode is implied" },
-
-    { "pcap-list", config_trough_list,
-      "<list> a space separated list of pcaps to read - read mode is implied" },
-
-    { "pcap-dir", config_trough_dir,
-      "<dir> a directory to recurse to look for pcaps - read mode is implied" },
-
-    { "pcap-filter", config_pcap_filter,
-      "<filter> filter to apply when getting pcaps from file or directory" },
-
-    { "pcap-loop", config_pcap_loop,
-      "<count> read all pcaps <count> times;  0 will read until Snort is terminated" },
-
-    { "pcap-no-filter", config_pcap_no_filter,
-      "reset to use no filter when getting pcaps from file or directory" },
-
-    { "pcap-reload", config_pcap_reload,
-      "if reading multiple pcaps, reload snort config between pcaps" },
-
-    { "pcap-reset", config_pcap_reset,
-      "reset Snort after each pcap" },
-
-    { "pcap-show", config_pcap_show,
-      "print a line saying what pcap is currently being read" },
-
-    { "plugin-path", ConfigPluginPath,
-      "where to find plugins" },
-
-    { "process-all-events", ConfigProcessAllEvents,
-      "process all action groups" },
-
-    { "rule", config_rule,
-      "add this line to rules configuration; may be repeated" },
-
-    { "script-path", ConfigScriptPath,
-      "where to find luajit scripts" },
-
-    { "shell", config_shell,
-      "enable the interactive command line", },
-
-    { "skip", config_skip,
-      "<n> skip 1st n packets", },
-
-    { "snaplen", ConfigPacketSnaplen,
-      "<snap> set snaplen of packet (same as -s)", },
-
-    { "treat-drop-as-alert", ConfigTreatDropAsAlert,
-      "converts drop, sdrop, and reject rules into alert rules during startup" },
-
-    { "treat-drop-as-ignore", ConfigTreatDropAsIgnore,
-      "use drop, sdrop, and reject rules to ignore session traffic when not inline" },
-
-#ifdef UNIT_TEST
-    { "unit-test", config_unit_test,
-      "<verbosity> run unit tests with given libcheck output mode" },
-#endif
-    { "version", config_version,
-      "show version number (same as -V)" },
-
-    { nullptr, nullptr, nullptr }
-};
-
-static void help_args(const char* pfx)
+static void set(
+    const char* key, const char* val, SnortConfig* sc, bool all)
 {
-    ConfigFunc* p = basic_opts;
-    unsigned n = pfx ? strlen(pfx) : 0;
+    if ( !all == !is_special(key) )
+        return;
 
-    while ( p->name )
-    {
-        if ( p->help && (!n || !strncasecmp(p->name, pfx, n)) )
-        {
-            cout << Markup::item();
-            cout << Markup::emphasis_on();
+    string k = "-";
+    if (strlen(key) > 1)
+        k += "-";
+    k += key;
+    key = k.c_str();
 
-            const char* prefix = strlen(p->name) > 1 ? "--" : "-";
-            cout << prefix << p->name;
-            cout << Markup::emphasis_off();
+    Module* m = get_snort_module();
+    const Parameter* p = m->get_parameters();
+    p = Parameter::find(p, key);
 
-            cout << " " << p->help;
-            cout << endl;
-        }
-        ++p;
-    }
+    if ( !p )
+        ParseError("unknown option %s %s\n", key, val);
+    
+    else if ( !set_arg(m, p, k.c_str(), val, sc) )
+        ParseError("can't set %s %s\n", key, val);
 }
 
-static void check_flags(SnortConfig* sc)
-{
-    if ((sc->run_flags & RUN_FLAG__TEST) &&
-        (sc->run_flags & RUN_FLAG__DAEMON))
-    {
-        FatalError("Cannot use test mode and daemon mode together.\n"
-                   "To verify configuration, run first in test "
-                   "mode and then restart in daemon mode.\n");
-    }
-
-    if ((sc->run_flags & RUN_FLAG__INLINE) &&
-            (sc->run_flags & RUN_FLAG__INLINE_TEST))
-    {
-        FatalError("Cannot use inline adapter mode and inline test "
-                "mode together. \n");
-    }
-
-    if (loop_count && !(sc->run_flags & RUN_FLAG__READ))
-    {
-        FatalError("--pcap-loop can only be used in combination with pcaps "
-                   "on the command line.\n");
-    }
-
-    if ((sc->run_flags & RUN_FLAG__PCAP_RELOAD) &&
-        !(sc->run_flags & RUN_FLAG__READ))
-    {
-        FatalError("--pcap-reload can only be used in combination with pcaps "
-                   "on the command line.\n");
-    }
-}
+//-------------------------------------------------------------------------
 
-SnortConfig* ParseCmdLine(int argc, char* argv[])
+SnortConfig* parse_cmd_line(int argc, char* argv[])
 {
     SnortConfig* sc = SnortConfNew();
 
@@ -1030,32 +161,13 @@ SnortConfig* ParseCmdLine(int argc, char* argv[])
 
     // get special options first
     while ( al.get_arg(key, val) )
-    {
-        ConfigFunc* p = spec_opts;
-
-        while ( p->name && strcmp(p->name, key) )
-            ++p;
-
-        if ( p->name )
-            p->parse_func(sc, val);
-    }
+        set(key, val, sc, false);
 
     // now get the rest
     al.reset();
 
     while ( al.get_arg(key, val) )
-    {
-        ConfigFunc* p = basic_opts;
-
-        while ( p->name && strcmp(p->name, key) )
-            ++p;
-
-        if ( !p->name )
-            FatalError("unknown arg '%s %s'\n", key, val);
-
-        else
-            p->parse_func(sc, val);
-    }
+        set(key, val, sc, true);
 
     check_flags(sc);
     return sc;
@@ -1075,14 +187,3 @@ void set_daemon_args(int argc, char* argv[])
     }
 }
 
-//-------------------------------------------------------------------------
-
-void cmd_line_term()
-{
-    if (lua_conf != NULL)
-        free(lua_conf);
-
-    if (snort_conf_dir != NULL)
-        free(snort_conf_dir);
-}
-
index f3cb4450e8dc51a174d8ae5505612292a8217d67..971ad5949154860bcbc1e9abeb0f092dc927063d 100644 (file)
@@ -1,6 +1,5 @@
 /*
 ** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
-** Copyright (C) 2013-2013 Sourcefire, Inc.
 **
 ** This program is free software; you can redistribute it and/or modify
 ** it under the terms of the GNU General Public License Version 2 as
 ** along with this program; if not, write to the Free Software
 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
+// cmd_line.h author Russ Combs <rucombs@cisco.com>
 
 #ifndef CMD_LINE_H
 #define CMD_LINE_H
 
-#include "snort.h"
+struct SnortConfig* parse_cmd_line(int argc, char* argv[]);
 
 void set_daemon_args(int argc, char* argv[]);
-void cmd_line_term();
-
-const char* get_snort_conf();
-const char* get_snort_conf_dir();
-
-SnortConfig* ParseCmdLine(int argc, char* argv[]);
 
 #endif
 
index 32f608f65f651d9ff22a78632a93e4ffaf603bf1..76d501740ca5ec207eb062bc8148a82b0f4722a7 100644 (file)
@@ -36,6 +36,7 @@
 #include <pcap.h>
 #include <grp.h>
 #include <pwd.h>
+#include <syslog.h>
 
 #ifdef HAVE_DUMBNET_H
 #include <dumbnet.h>
@@ -56,8 +57,9 @@
 #include "ips_options/ips_flowbits.h"
 #include "file_api/file_service_config.h"
 #include "packet_io/sfdaq.h"
-
 #include "target_based/sftarget_reader.h"
+#include "managers/event_manager.h"
+#include "detection/detect.h"
 
 // FIXIT defines should be avoided here - the actual option
 // may be from command line (a-b) or from config file (a_b)
 # define CONFIG_OPT__PROFILE_RULES                  "profile_rules"
 #endif
 
+#define LOG_NONE  "none"
+#define LOG_TEXT  "text"
+#define LOG_PCAP  "pcap"
+
+#define ALERT_NONE    "none"
+#define ALERT_CMG     "cmg"
+#define ALERT_JH      "jh"
+#define ALERT_DJR     "djr"
+#define ALERT_AJK     "ajk"
+
+#define OUTPUT_AJK  "unified2"
+#define OUTPUT_CMG  "alert_fast"
+//#define OUTPUT_LOG  "alert_syslog"  // FIXIT should use?
+#define OUTPUT_PCAP "log_tcpdump"
+
+static std::string lua_conf;
+static std::string snort_conf_dir;
+
+const char* get_snort_conf()
+{ return lua_conf.c_str(); }
+
+const char* get_snort_conf_dir()
+{ return snort_conf_dir.c_str(); }
+
 void ConfigAlertBeforePass(SnortConfig *sc, const char*)
 {
     sc->run_flags |= RUN_FLAG__ALERT_BEFORE_PASS;
@@ -383,35 +409,6 @@ void ConfigObfuscationMask(SnortConfig *sc, const char *args)
     sfip_pton(args, &sc->obfuscation_net);
 }
 
-#define MIN_SNAPLEN  68
-#define MAX_SNAPLEN  UINT16_MAX
-
-void ConfigPacketSnaplen(SnortConfig *sc, const char *args)
-{
-    char *endptr;
-    uint32_t snaplen;
-
-    if ( !args )
-        return;
-
-    snaplen = SnortStrtoul(args, &endptr, 0);
-
-    if ((errno == ERANGE) || (*endptr != '\0') ||
-        ((snaplen != 0) && (snaplen < MIN_SNAPLEN)) ||
-        (snaplen > MAX_SNAPLEN) )
-    {
-        ParseError("invalid snaplen: %s.  Snaplen must be between "
-                   "%u and %u inclusive or 0 for default = %u.",
-                   args, MIN_SNAPLEN, MAX_SNAPLEN, DAQ_GetSnapLen());
-        return;
-    }
-
-    sc->pkt_snaplen = snaplen;
-
-    DEBUG_WRAP(DebugMessage(DEBUG_INIT,
-        "Snap length of packets set to: %d\n", sc->pkt_snaplen););
-}
-
 PolicyMode GetPolicyMode(PolicyMode mode)
 {
     switch ( mode )
@@ -576,6 +573,8 @@ void ConfigShowYear(SnortConfig *sc, const char*)
     DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Enabled year in timestamp\n"););
 }
 
+// FIXIT-L who is calling this?  get rid of SnortStrtoul() etc. when
+// all are modularized
 void ConfigSoRuleMemcap(SnortConfig *sc, const char *args)
 {
     char *endptr;
@@ -687,3 +686,106 @@ void ConfigScriptPath(SnortConfig *sc, const char *args)
         sc->script_path = SnortStrdup(args);
 }
 
+void config_syslog(SnortConfig* sc, const char*)
+{
+    static bool syslog_configured = false;
+
+    if (syslog_configured)
+        return;
+
+    /* If daemon or logging to syslog use "snort" as identifier and
+     * start logging there now */
+    openlog("snort", LOG_PID | LOG_CONS, LOG_DAEMON);
+
+    sc->logging_flags |= LOGGING_FLAG__SYSLOG;
+    syslog_configured = true;
+}
+
+void config_daemon(SnortConfig* sc, const char* val)
+{
+    static bool daemon_configured = false;
+
+    if (daemon_configured)
+        return;
+
+    /* If daemon or logging to syslog use "snort" as identifier and
+     * start logging there now */
+    openlog("snort", LOG_PID | LOG_CONS, LOG_DAEMON);
+
+    ConfigDaemon(sc, val);
+    daemon_configured = true;
+}
+
+void config_alert_mode(SnortConfig* sc, const char* val)
+{
+    if (strcasecmp(val, ALERT_NONE) == 0)
+    {
+        sc->output_flags |= OUTPUT_FLAG__NO_ALERT;
+        EventManager::enable_alerts(false);
+    }
+    else if ((strcasecmp(val, ALERT_CMG) == 0) ||
+             (strcasecmp(val, ALERT_JH) == 0) ||
+             (strcasecmp(val, ALERT_DJR) == 0))
+    {
+        sc->output = OUTPUT_CMG;
+        sc->output_flags |= OUTPUT_FLAG__SHOW_DATA_LINK;
+        sc->output_flags |= OUTPUT_FLAG__APP_DATA;
+    }
+    else if (strcasecmp(val, ALERT_AJK) == 0)
+    {
+        sc->output = OUTPUT_AJK;
+    }
+    else
+        sc->output = val;
+}
+
+void config_log_mode(SnortConfig* sc, const char* val)
+{
+    if (strcasecmp(val, LOG_NONE) == 0)
+    {
+        sc->output_flags |= OUTPUT_FLAG__NO_LOG;
+        set_main_hook(snort_ignore);
+        EventManager::enable_logs(false);
+    }
+    else if (strcasecmp(val, LOG_TEXT) == 0)
+    {
+        set_main_hook(snort_print);
+    }
+    else if (strcasecmp(val, LOG_PCAP) == 0)
+    {
+        sc->output = OUTPUT_PCAP;
+        set_main_hook(snort_log);
+    }
+    else
+    {
+        FatalError("Unknown -K option: %s\n", val);
+    }
+}
+
+void config_conf(SnortConfig*, const char* val)
+{
+    lua_conf = val;
+    SetSnortConfDir(lua_conf.c_str());
+    set_main_hook(snort_inspect);
+}
+
+void SetSnortConfDir(const char* file)
+{
+    /* extract the config directory from the config filename */
+    if ( file )
+    {
+        const char *path_sep = strrchr(file, '/');
+
+        /* is there a directory seperator in the filename */
+        if (path_sep != NULL)
+        {
+            path_sep++;  /* include path separator */
+            snort_conf_dir.assign(file, path_sep - file);
+        }
+        else
+        {
+            snort_conf_dir = "./";
+        }
+    }
+}
+
index d2e9f3560228a7d1ad91b17a059609195af9b02f..08ef4b4a321c38ec85925de56cf174b2212c86a1 100644 (file)
@@ -1,6 +1,5 @@
 /*
 ** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
-** Copyright (C) 2013-2013 Sourcefire, Inc.
 **
 ** This program is free software; you can redistribute it and/or modify
 ** it under the terms of the GNU General Public License Version 2 as
 #ifndef CONFIG_FILE_H
 #define CONFIG_FILE_H
 
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "main/policy.h"
+
+struct SnortConfig;
 
-#include "main/snort_config.h"
-#include "snort_types.h"
-#include "snort.h"
+const char* get_snort_conf();
+const char* get_snort_conf_dir();
 
-void ConfigAutogenPreprocDecoderRules(SnortConfig*);
 void ConfigAlertBeforePass(SnortConfig*, const char*);
 void ConfigChecksumDrop(SnortConfig*, const char*);
 void ConfigChecksumMode(SnortConfig*, const char*);
@@ -37,11 +34,9 @@ void ConfigChrootDir(SnortConfig*, const char*);
 void ConfigCreatePidFile(SnortConfig*, const char*);
 void ConfigDaemon(SnortConfig*, const char*);
 void ConfigDecodeDataLink(SnortConfig*, const char*);
-void ConfigDetectionFilter(SnortConfig*, const char*);
 void ConfigDumpCharsOnly(SnortConfig*, const char*);
 void ConfigDumpPayload(SnortConfig*, const char*);
 void ConfigDumpPayloadVerbose(SnortConfig*, const char*);
-void ConfigGTPDecoding(SnortConfig*sc, const char*args);
 void ConfigLogDir(SnortConfig*, const char*);
 void ConfigDaqType(SnortConfig*, const char*);
 void ConfigDaqMode(SnortConfig*, const char*);
@@ -52,36 +47,31 @@ void ConfigNoLog(SnortConfig*, const char*);
 void ConfigNoLoggingTimestamps(SnortConfig*, const char*);
 void ConfigObfuscate(SnortConfig*, const char*);
 void ConfigObfuscationMask(SnortConfig*, const char*);
-void ConfigPacketSnaplen(SnortConfig*, const char*);
-void ConfigPolicyVersion(SnortConfig*, const char* base, const char* target);
-#ifdef PERF_PROFILING
-void _ConfigProfilePreprocs(SnortConfig*, const char*);
-void _ConfigProfileRules(SnortConfig*, const char*);
-void ConfigProfilePreprocs(SnortConfig*, const char*);
-void ConfigProfileRules(SnortConfig*, const char*);
-#endif
 void ConfigQuiet(SnortConfig*, const char*);
-void ConfigSetGid(SnortConfig*, const char*);
-void ConfigSetUid(SnortConfig*, const char*);
 void ConfigShowYear(SnortConfig*, const char*);
 void ConfigSoRuleMemcap(SnortConfig*, const char*);
-#ifdef TIMESTATS
-void ConfigTimestatsInterval(SnortConfig*, const char*);
-#endif
 void ConfigTreatDropAsAlert(SnortConfig*, const char*);
 void ConfigTreatDropAsIgnore(SnortConfig*, const char*);
 void ConfigProcessAllEvents(SnortConfig*, const char*);
-void ConfigUmask(SnortConfig*, const char*);
 void ConfigUtc(SnortConfig*, const char*);
 void ConfigVerbose(SnortConfig*, const char*);
-void ConfigControlSocketDirectory(SnortConfig*, const char*);
-void ConfigTunnelVerdicts(SnortConfig*, const char*);
-void ConfigProfiling(SnortConfig*);
 void ConfigPluginPath(SnortConfig*, const char*);
 void ConfigScriptPath(SnortConfig*, const char*);
 void ConfigDstMac(SnortConfig*, const char*);
+
+void ConfigGTPDecoding(SnortConfig*sc, const char*args);
+void ConfigSetGid(SnortConfig*, const char*);
+void ConfigSetUid(SnortConfig*, const char*);
+void ConfigUmask(SnortConfig*, const char*);
+void ConfigTunnelVerdicts(SnortConfig*, const char*);
+void ConfigProfiling(SnortConfig*);
 PolicyMode GetPolicyMode(PolicyMode);
-void ConfigIgnorePorts(SnortConfig*, int protocol, const char* ports);
+void config_syslog(SnortConfig* sc, const char*);
+void config_daemon(SnortConfig* sc, const char*);
+void config_alert_mode(SnortConfig* sc, const char*);
+void config_log_mode(SnortConfig* sc, const char*);
+void config_conf(SnortConfig*, const char*);
+void SetSnortConfDir(const char*);
 
 #endif
 
index 50ccdea7e6d226fc1bfdfb0a3d94a943a2586104..792622aab475491a289ba4e19e04368d6d94af41 100644 (file)
@@ -47,7 +47,7 @@ using namespace std;
 #include "treenodes.h"
 #include "treenodes.h"
 #include "snort_types.h"
-#include "sf_textlog.h"
+#include "log/text_log.h"
 #include "detection_options.h"
 #include "fpdetect.h"
 #include "framework/module.h"
index 54a3f488cebc80b5178d573b7faec26afd383c4f..28a900cb77987e7742c55de4b3bdd2859279247a 100644 (file)
@@ -275,17 +275,6 @@ void strip(char *data)
     }
 }
 
-/****************************************************************************
- *
- * Function: CreatePidFile(char *)
- *
- * Purpose:  Creates a PID file
- *
- * Arguments: Interface opened.
- *
- * Returns: void function
- *
- ****************************************************************************/
 static FILE *pid_lockfile = NULL;
 static FILE *pid_file = NULL;
 
@@ -318,8 +307,9 @@ void CreatePidFile(pid_t pid)
             if (fcntl(lock_fd, F_SETLK, &lock) == -1)
             {
                 ClosePidFile();
-                FatalError("Failed to Lock PID File \"%s\" for PID \"%d\"\n",
+                ParseError("Failed to Lock PID File \"%s\" for PID \"%d\"\n",
                     snort_conf->pid_filename, (int)pid);
+                return;
             }
         }
     }
@@ -383,31 +373,27 @@ void SetUidGid(int user_id, int group_id)
     if ((group_id != -1) && (getgid() != (gid_t)group_id))
     {
         if ( !DAQ_Unprivileged() )
-        {
-            LogMessage("WARNING: cannot set uid and gid - %s DAQ does not"
+            ParseError("WARNING: cannot set uid and gid - %s DAQ does not"
                 " support unprivileged operation.\n", DAQ_GetType());
-            return;
-        }
 
-        if (setgid(group_id) < 0)
-            FatalError("Cannot set gid: %d\n", group_id);
+        else if (setgid(group_id) < 0)
+            ParseError("Cannot set gid: %d\n", group_id);
 
-        LogMessage("Set gid to %d\n", group_id);
+        else
+            LogMessage("Set gid to %d\n", group_id);
     }
 
     if ((user_id != -1) && (getuid() != (uid_t)user_id))
     {
         if ( !DAQ_Unprivileged() )
-        {
-            LogMessage("WARNING: cannot set uid and gid - %s DAQ does not"
+            ParseError("WARNING: cannot set uid and gid - %s DAQ does not"
                 " support unprivileged operation.\n", DAQ_GetType());
-            return;
-        }
 
-        if (setuid(user_id) < 0)
-            FatalError("Can not set uid: %d\n", user_id);
+        else if (setuid(user_id) < 0)
+            ParseError("Can not set uid: %d\n", user_id);
 
-        LogMessage("Set uid to %d\n", user_id);
+        else
+            LogMessage("Set uid to %d\n", user_id);
     }
 }
 
@@ -436,7 +422,7 @@ void InitGroups(int user_id, int group_id)
 
             if (initgroups(username, group_id) < 0)
             {
-                FatalError("Can not initgroups(%s,%d)", username, group_id);
+                ParseError("Can not initgroups(%s,%d)", username, group_id);
             }
 
             free(username);
@@ -518,20 +504,32 @@ char *read_infile(char *fname)
     fd = open(fname, O_RDONLY);
 
     if(fd < 0)
-        FatalError("can't open %s: %s\n", fname, get_error(errno));
+    {
+        ParseError("can't open %s: %s\n", fname, get_error(errno));
+        return nullptr;
+    }
 
     if(fstat(fd, &buf) < 0)
-        FatalError("can't stat %s: %s\n", fname, get_error(errno));
+    {
+        ParseError("can't stat %s: %s\n", fname, get_error(errno));
+        return nullptr;
+    }
 
     cp = (char *)SnortAlloc(((u_int)buf.st_size + 1) * sizeof(char));
 
     cc = read(fd, cp, (int) buf.st_size);
 
     if(cc < 0)
-        FatalError("read %s: %s\n", fname, get_error(errno));
+    {
+        ParseError("read %s: %s\n", fname, get_error(errno));
+        return nullptr;
+    }
 
     if(cc != buf.st_size)
-        FatalError("short read %s (%d != %d)\n", fname, cc, (int) buf.st_size);
+    {
+        ParseError("short read %s (%d != %d)\n", fname, cc, (int) buf.st_size);
+        return nullptr;
+    }
 
     cp[(int) buf.st_size] = '\0';
 
@@ -576,11 +574,11 @@ void CheckLogDir(void)
         return;
 
     if (stat(snort_conf->log_dir, &st) == -1)
-        FatalError("Stat check on log dir failed: %s.\n", get_error(errno));
+        ParseError("Stat check on log dir failed: %s.\n", get_error(errno));
 
-    if (!S_ISDIR(st.st_mode) || (access(snort_conf->log_dir, W_OK) == -1))
+    else if (!S_ISDIR(st.st_mode) || (access(snort_conf->log_dir, W_OK) == -1))
     {
-        FatalError("Can not get write access to logging directory \"%s\". "
+        ParseError("Can not get write access to logging directory \"%s\". "
                    "(directory doesn't exist or permissions are set incorrectly "
                    "or it is not a directory at all)\n",
                    snort_conf->log_dir);
@@ -870,31 +868,6 @@ const char *SnortStrcasestr(const char *s, int slen, const char *substr)
     return s;
 }
 
-void * SnortAlloc2(size_t size, const char *format, ...)
-{
-    void *tmp;
-
-    tmp = (void *)calloc(size, sizeof(char));
-
-    if(tmp == NULL)
-    {
-        va_list ap;
-        char buf[STD_BUF];
-
-        buf[STD_BUF - 1] = '\0';
-
-        va_start(ap, format);
-
-        vsnprintf(buf, STD_BUF - 1, format, ap);
-
-        va_end(ap);
-
-        FatalError("%s", buf);
-    }
-
-    return tmp;
-}
-
 /**
  * Chroot and adjust the snort_conf->log_dir reference
  *
@@ -909,14 +882,16 @@ void SetChroot(char *directory, char **logstore)
 
     if(!directory || !logstore)
     {
-        FatalError("Null parameter passed\n");
+        ParseError("Null parameter passed\n");
+        return;
     }
 
     logdir = *logstore;
 
     if(logdir == NULL || *logdir == '\0')
     {
-        FatalError("Null log directory\n");
+        ParseError("Null log directory\n");
+        return;
     }
 
     DEBUG_WRAP(DebugMessage(DEBUG_INIT,"SetChroot: %s\n",
@@ -936,8 +911,9 @@ void SetChroot(char *directory, char **logstore)
     /* change to the directory */
     if(chdir(directory) != 0)
     {
-        FatalError("SetChroot: Can not chdir to \"%s\": %s\n", directory,
+        ParseError("SetChroot: Can not chdir to \"%s\": %s\n", directory,
                    get_error(errno));
+        return;
     }
 
     /* always returns an absolute pathname */
@@ -945,7 +921,8 @@ void SetChroot(char *directory, char **logstore)
 
     if(absdir == NULL)
     {
-        FatalError("NULL Chroot found\n");
+        ParseError("NULL Chroot found\n");
+        return;
     }
 
     abslen = strlen(absdir);
@@ -955,8 +932,9 @@ void SetChroot(char *directory, char **logstore)
     /* make the chroot call */
     if(chroot(absdir) < 0)
     {
-        FatalError("Can not chroot to \"%s\": absolute: %s: %s\n",
+        ParseError("Can not chroot to \"%s\": absolute: %s: %s\n",
                    directory, absdir, get_error(errno));
+        return;
     }
 
     DEBUG_WRAP(DebugMessage(DEBUG_INIT,"chroot success (%s ->", absdir););
@@ -965,8 +943,9 @@ void SetChroot(char *directory, char **logstore)
     /* change to "/" in the new directory */
     if(chdir("/") < 0)
     {
-        FatalError("Can not chdir to \"/\" after chroot: %s\n",
+        ParseError("Can not chdir to \"/\" after chroot: %s\n",
                    get_error(errno));
+        return;
     }
 
     DEBUG_WRAP(DebugMessage(DEBUG_INIT,"chdir success (%s)\n",
@@ -975,7 +954,8 @@ void SetChroot(char *directory, char **logstore)
 
     if(strncmp(absdir, logdir, strlen(absdir)))
     {
-        FatalError("Absdir is not a subset of the logdir");
+        ParseError("Absdir is not a subset of the logdir");
+        return;
     }
 
     if(abslen >= strlen(logdir))
@@ -1140,91 +1120,6 @@ char *fasthex(const u_char *xdata, int length)
     return retbuf;
 }
 
-/*
- *   Fatal Integer Parser
- *   Ascii to Integer conversion with fatal error support
- */
-long int xatol(const char *s , const char *etext)
-{
-    long int val;
-    char *endptr;
-    const char *default_error = "xatol() error\n";
-
-    if (etext == NULL)
-        etext = default_error;
-
-    if (s == NULL)
-        FatalError("%s: String is NULL\n", etext);
-
-    while (isspace((int)*s))
-        s++;
-
-    if (strlen(s) == 0)
-        FatalError("%s: String is empty\n", etext);
-
-
-    /*
-     *  strtoul - errors on win32 : ERANGE (VS 6.0)
-     *            errors on linux : ERANGE, EINVAL
-     *               (for EINVAL, unsupported base which won't happen here)
-     */
-    val = SnortStrtol(s, &endptr, 0);
-
-    if ((errno == ERANGE) || (*endptr != '\0'))
-        FatalError("%s: Invalid integer input: %s\n", etext, s);
-
-    return val;
-}
-
-/*
- *   Fatal Integer Parser
- *   Ascii to Integer conversion with fatal error support
- */
-unsigned long int xatou(const char *s , const char *etext)
-{
-    unsigned long int val;
-    char *endptr;
-    const char *default_error = "xatou() error\n";
-
-    if (etext == NULL)
-        etext = default_error;
-
-    if (s == NULL)
-        FatalError("%s: String is NULL\n", etext);
-
-    while (isspace((int)*s))
-        s++;
-
-    if (strlen(s) == 0)
-        FatalError("%s: String is empty\n", etext);
-
-    if (*s == '-')
-    {
-        FatalError("%s: Invalid unsigned integer - negative sign found, "
-                   "input: %s\n", etext, s);
-    }
-
-
-    /*
-     *  strtoul - errors on win32 : ERANGE (VS 6.0)
-     *            errors on linux : ERANGE, EINVAL
-     */
-    val = SnortStrtoul(s, &endptr, 0);
-
-    if ((errno == ERANGE) || (*endptr != '\0'))
-        FatalError("%s: Invalid integer input: %s\n", etext, s);
-
-    return val;
-}
-
-unsigned long int xatoup(const char *s , const char *etext)
-{
-    unsigned long int val = xatou(s, etext);
-    if ( !val )
-        FatalError("%s: must be > 0\n", etext);
-    return val;
-}
-
 int CheckValueInRange(const char *value_str, const char *option,
         unsigned long lo, unsigned long hi, unsigned long *value)
 {
index b2946aa4328101f1636625bc2e8ffc565baa842b..0b9e19583bdc5be7ce5ed162db3ff0c95536a9cd 100644 (file)
@@ -105,7 +105,6 @@ const char *SnortStrcasestr(const char *s, int slen, const char *substr);
 int CheckValueInRange(const char *value_str, const char *option,
         unsigned long lo, unsigned long hi, unsigned long *value);
 
-void *SnortAlloc2(size_t, const char *, ...);
 char *CurrentWorkingDir(void);
 char *GetAbsolutePath(char *dir);
 char *StripPrefixDir(char *prefix, char *dir);
@@ -124,9 +123,6 @@ void SetNoCores(void);
 ***********************************************************/
 char *hex(const u_char *, int);
 char *fasthex(const u_char *, int);
-long int xatol(const char *, const char *);
-unsigned long int xatou(const char *, const char *);
-unsigned long int xatoup(const char *, const char *); // return > 0
 
 static inline void* SnortAlloc (unsigned long size)
 {