tools/snort2lua/Makefile \
tools/snort2lua/config_states/Makefile \
tools/snort2lua/data/Makefile \
++tools/snort2lua/data/data_types/Makefile \
tools/snort2lua/keyword_states/Makefile \
tools/snort2lua/output_states/Makefile \
tools/snort2lua/preprocessor_states/Makefile \
else
{
if ( otn->num_detection_opts )
-- ParseError("builtin rules do not support detection options");
++ ParseError("%d:%d builtin rules do not support detection options",
++ otn->sigInfo.generator, otn->sigInfo.id);
otn->sigInfo.text_rule = false;
builtin_rule_count++;
add_executable( snort2lua
conversion_state.h
-- option_parser.h
++ conversion_defines.h
init_state.h
snort2lua.cc
init_state.cc
snort2lua_SOURCES = \
conversion_state.h \
--option_parser.h \
init_state.h \
snort2lua.cc \
init_state.cc
snort2lua_LDADD = \
--utils/libsnort2lua_utils.a \
--data/libdata.a \
keyword_states/libkeyword_states.a \
preprocessor_states/libpreprocessor_states.a \
output_states/liboutput_states.a \
config_states/libconfig_states.a \
--rule_states/librule_states.a
++rule_states/librule_states.a \
++utils/libsnort2lua_utils.a \
++data/libdata.a \
++data/data_types/libdata_types.a
snort2lua_CFLAGS = @CFLAGS@ $(AM_CFLAGS)
noinst_LIBRARIES = libdata.a
libdata_a_SOURCES = \
--dt_comment.h \
--dt_comment.cc \
dt_data.h \
dt_data.cc \
--dt_include.h \
--dt_include.cc \
--dt_option.h \
--dt_option.cc \
--dt_table.h \
--dt_table.cc \
--dt_rule.h \
--dt_rule.cc \
--dt_rule_option.h \
--dt_rule_option.cc \
--dt_rule_suboption.h \
--dt_rule_suboption.cc \
--dt_var.h \
--dt_var.cc
++dt_rule_api.h \
++dt_rule_api.cc \
++dt_table_api.h \
++dt_table_api.cc
++SUBDIRS = \
++data_types
AM_CXXFLAGS = @AM_CXXFLAGS@
--- /dev/null
--- /dev/null
++AUTOMAKE_OPTIONS=foreign no-dependencies
++
++
++noinst_LIBRARIES = libdata_types.a
++
++libdata_types_a_SOURCES = \
++dt_comment.h \
++dt_comment.cc \
++dt_include.h \
++dt_include.cc \
++dt_option.h \
++dt_option.cc \
++dt_table.h \
++dt_table.cc \
++dt_rule.h \
++dt_rule.cc \
++dt_rule_option.h \
++dt_rule_option.cc \
++dt_rule_suboption.h \
++dt_rule_suboption.cc \
++dt_var.h \
++dt_var.cc
++
++
++AM_CXXFLAGS = @AM_CXXFLAGS@
--- /dev/null
+/*
+** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+ * Copyright (C) 2002-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.
+ */
+// rule_threshold.cc author Josh Rosenbaum <jrosenba@cisco.com>
+
+#include <sstream>
+#include <vector>
+
+#include "conversion_state.h"
+#include "utils/converter.h"
+#include "rule_states/rule_api.h"
+#include "utils/s2l_util.h"
+
+namespace rules
+{
+
+namespace {
+
+
+class React : public ConversionState
+{
+public:
+ React() : ConversionState() {};
+ virtual ~React() {};
+ virtual bool convert(std::istringstream& data);
+};
+
+} // namespace
+
+bool React::convert(std::istringstream& data_stream)
+{
+ std::string args;
+ std::string tmp;
+ std::streamoff pos = data_stream.tellg();
+ bool retval = true;
+
+ args = util::get_rule_option_args(data_stream);
+
+ // if there are no arguments, the option had a colon before a semicolon.
+ // we are therefore done with this rule.
+ if (!args.empty())
+ {
+ // a colon will have been parsed when retrieving the keyword.
+ // Therefore, if a colon is present, we are in the next rule option.
+ if (args.find(":") != std::string::npos)
+ {
+ data_stream.seekg(pos);
+ }
+ else
+ {
+ // since we still can't be sure if we passed the resp buffer,
+ // check the next option and ensure it matches
+ std::istringstream arg_stream(args);
+ util::get_string(arg_stream, tmp, ",");
+
+ if (!tmp.compare("msg") ||
+ !tmp.compare("warn") ||
+ !tmp.compare("block") ||
+ !tmp.compare(0, 5, "proxy"))
+ {
+ // Now that we have confirmed this is a vlid option, parse it!!
+ table_api.open_table("react");
+ bool find_msg = false;
+
+ do
+ {
+ // FIXIT-1J If reject params are legitimately strings, these MUST
+ // change so users don't think 'reset_dest=false' turns
+ // the option off
+
+ if (!tmp.compare("warn"))
+ table_api.add_deleted_comment("warn");
+
+ else if (!tmp.compare("block"))
+ table_api.add_deleted_comment("block");
+
+ else if (!tmp.compare(0, 5, "proxy"))
+ table_api.add_deleted_comment(tmp);
+
+ else if (!tmp.compare("msg"))
+ find_msg = true;
+
+ else
+ {
+ rule_api.bad_rule(data_stream, "resp: " + tmp);
+ retval = false;
+ }
+
+
+ } while (util::get_string(arg_stream, tmp, ","));
+
+
+ // get this rule's msg
+ if (find_msg)
+ {
+ std::string msg = util::rule_option_find_val(data_stream, "msg");
+
+ if (!msg.empty())
++ {
++ if (msg.front() == '"' && msg.back() == '"')
++ {
++ msg.erase(msg.begin());
++ msg.pop_back();
++ }
++
+ table_api.add_option("msg", msg);
++ }
+
+#if 0
+ // save the current position
+ const std::streamoff curr_pos = data_stream.tellg();
+
+ if (curr_pos == -1)
+ data_stream.clear();
+ std::string rule_keyword;
+
+ data_stream.seekg(0);
+ std::getline(data_stream, rule_keyword, '(');
+ std::streamoff tmp_pos = data_stream.tellg();
+
+ while(std::getline(data_stream, rule_keyword, ':'))
+ {
+ std::size_t semi_colon_pos = rule_keyword.find(';');
+ if (semi_colon_pos != std::string::npos)
+ {
+ // found an option without a colon, so set stream
+ // to semi-colon
+ std::streamoff off = 1 + (std::streamoff)(tmp_pos) +
+ (std::streamoff)(semi_colon_pos);
+ data_stream.seekg(off);
+ rule_keyword = rule_keyword.substr(0, semi_colon_pos);
+ }
+
+ // now, lets get the next option.
+ util::trim(rule_keyword);
+
+ if (!rule_keyword.compare("msg"))
+ {
+ std::string val = util::get_rule_option_args(data_stream);
+ table_api.add_option("msg", val);
+ break;
+ }
+ else if (semi_colon_pos == std::string::npos)
+ std::getline(data_stream, rule_keyword, ';');
+
+
+ tmp_pos = data_stream.tellg();
+ }
+
+ // if we're at the end of the rule, don't clear
+ if (curr_pos != -1)
+ data_stream.clear();
+
+
+ data_stream.seekg(curr_pos);
+#endif
+ }
+ table_api.close_table(); // "react"
+ }
+ else
+ {
+ data_stream.seekg(pos);
+ }
+
+
+ }
+ }
+
+ // create this table to ensure reject is instatiated
+ table_api.open_table("react");
+ table_api.close_table();
+
+ // Finally, update the rule type
+ rule_api.update_rule_type("react");
+ return set_next_rule_state(data_stream) && retval;
+}
+
+/**************************
+ ******* A P I ***********
+ **************************/
+
+
+static ConversionState* ctor()
+{ return new React(); }
+
+static const ConvertMap rule_react =
+{
+ "react",
+ ctor,
+};
+
+const ConvertMap* react_map = &rule_react;
+
+} // namespace rules
--- /dev/null
- // FIXIT-1J If reject params are legitimately strings, these MUST
- // change so users don't think 'reset_dest=false' turns
- // the option off
+/*
+** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+ * Copyright (C) 2002-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.
+ */
+// rule_threshold.cc author Josh Rosenbaum <jrosenba@cisco.com>
+
+#include <sstream>
+#include <vector>
+
+#include "conversion_state.h"
+#include "utils/converter.h"
+#include "rule_states/rule_api.h"
+#include "utils/s2l_util.h"
+
+namespace rules
+{
+
+namespace {
+
+
+class Resp : public ConversionState
+{
+public:
+ Resp() : ConversionState() {};
+ virtual ~Resp() {};
+ virtual bool convert(std::istringstream& data);
++private:
++ void add_diff_comment(std::string, std::string);
+};
+
+} // namespace
+
++
++void Resp::add_diff_comment(std::string old_v, std::string new_v)
++{
++ table_api.add_diff_option_comment("rule_type - resp:" + old_v,
++ "reject - " + new_v);
++}
++
+bool Resp::convert(std::istringstream& data_stream)
+{
+ std::string args;
+ std::string tmp;
+ std::streamoff pos = data_stream.tellg();
+ bool retval = true;
+
+ args = util::get_rule_option_args(data_stream);
+
+ // if there are no arguments, the option had a colon before a semicolon.
+ // we are therefore done with this rule.
+ if (!args.empty())
+ {
+ // a colon will have been parsed when retrieving the keyword.
+ // Therefore, if a colon is present, we are in the next rule option.
+ if (args.find(":") != std::string::npos)
+ {
+ data_stream.seekg(pos);
+ }
+ else
+ {
+ // since we still can't be sure if we passed the resp buffer,
+ // check the next option and ensure it matches
+ std::istringstream arg_stream(args);
+ util::get_string(arg_stream, tmp, ",");
+
+ if (!tmp.compare("reset_dest") ||
+ !tmp.compare("reset_both") ||
+ !tmp.compare("rst_snd") ||
+ !tmp.compare("rst_rcv") ||
+ !tmp.compare("rst_all") ||
+ !tmp.compare("icmp_net") ||
+ !tmp.compare("icmp_host") ||
+ !tmp.compare("icmp_all") ||
+ !tmp.compare("reset_source") ||
+ !tmp.compare("icmp_port"))
+ {
+ // Now that we have confirmed this is a vlid option, parse it!!
+ table_api.open_table("reject");
+
+ do
+ {
- table_api.add_option("reset_dest", "true");
++ // FIXIT-?J Once bindings added for reject, this MUST change!
+
+ if (!tmp.compare("reset_dest"))
- table_api.add_option("reset_both", "true");
++ {
++ add_diff_comment("reset_dest", "reset: dest");
++ table_api.add_option("reset", "dest");
++ }
++
++ else if (!tmp.compare("rst_rcv"))
++ {
++ add_diff_comment("rst_rcv", "reset: dest");
++ table_api.add_option("reset", "dest");
++ }
+
+ else if (!tmp.compare("reset_both"))
- else if (!tmp.compare("rst_snd"))
- table_api.add_option("rst_snd", "true");
++ {
++ add_diff_comment("reset_both", "reset: both");
++ table_api.add_option("reset", "both");
++ }
+
- else if (!tmp.compare("rst_rcv"))
- table_api.add_option("rst_rcv", "true");
++ else if (!tmp.compare("rst_all"))
++ {
++ add_diff_comment("rst_all", "reset: both");
++ table_api.add_option("reset", "both");
++ }
+
- else if (!tmp.compare("rst_all"))
- table_api.add_option("rst_all", "true");
++ else if (!tmp.compare("rst_snd"))
++ {
++ add_diff_comment("rst_snd", "reset: source");
++ table_api.add_option("reset", "source");
++ }
+
- table_api.add_option("icmp_net", "true");
++ else if (!tmp.compare("reset_source"))
++ {
++ add_diff_comment("reset_source", "reset: source");
++ table_api.add_option("reset", "source");
++ }
+
+ else if (!tmp.compare("icmp_net"))
- table_api.add_option("icmp_host", "true");
++ {
++ add_diff_comment("icmp_net", "control: network");
++ table_api.add_option("control", "network");
++ }
+
+ else if (!tmp.compare("icmp_host"))
- table_api.add_option("icmp_all", "true");
-
- else if (!tmp.compare("reset_source"))
- table_api.add_option("reset_source", "true");
++ {
++ add_diff_comment("icmp_host", "control: host");
++ table_api.add_option("control", "host");
++ }
+
+ else if (!tmp.compare("icmp_all"))
- table_api.add_option("icmp_port", "true");
++ {
++ add_diff_comment("icmp_all", "control: all");
++ table_api.add_option("control", "all");
++ }
+
+ else if (!tmp.compare("icmp_port"))
++ {
++ add_diff_comment("icmp_port", "control: port");
++ table_api.add_option("control", "port");
++ }
+
+ else
+ {
+ rule_api.bad_rule(data_stream, "resp: " + tmp);
+ retval = false;
+ }
+
+
+ } while (util::get_string(arg_stream, tmp, ","));
+
+
+ table_api.close_table(); // "reject"
+ }
+ else
+ {
+ data_stream.seekg(pos);
+ }
+ }
+ }
+
+ // create this table to ensure reject is instatiated
+ table_api.open_table("reject");
+ table_api.close_table();
+
+ // Finally, update the rule type
+ rule_api.update_rule_type("reject");
+ return set_next_rule_state(data_stream) && retval;
+}
+
+/**************************
+ ******* A P I ***********
+ **************************/
+
+
+static ConversionState* ctor()
+{ return new Resp(); }
+
+static const ConvertMap rule_resp =
+{
+ "resp",
+ ctor,
+};
+
+const ConvertMap* resp_map = &rule_resp;
+
+} // namespace rules
#include "utils/converter.h"
#include "init_state.h"
#include "utils/s2l_util.h"
-#include "option_parser.h"
-
-
-/****************************************************
- ************ OPTION INFORMATION *****************
- ****************************************************/
-
-namespace
-{
-
-struct Arg: public option::Arg
-{
- static void printError(const char* msg1, const option::Option& opt, const char* msg2)
- {
- fprintf(stderr, "%s", msg1);
- fwrite(opt.name, (std::size_t)opt.namelen, 1, stderr);
- fprintf(stderr, "%s", msg2);
- }
-
- static option::ArgStatus Unknown(const option::Option& option, bool msg)
- {
- if (msg) printError("Unknown option '", option, "'\n");
- return option::ARG_ILLEGAL;
- }
-
- static option::ArgStatus Required(const option::Option& option, bool msg)
- {
- if (option.arg != 0)
- return option::ARG_OK;
-
- if (msg) printError("Option '", option, "' requires an argument\n");
- return option::ARG_ILLEGAL;
- }
-
- static option::ArgStatus NonEmpty(const option::Option& option, bool msg)
- {
- if (option.arg != 0 && option.arg[0] != 0)
- return option::ARG_OK;
-
- if (msg) printError("Option '", option, "' requires a non-empty argument\n");
- return option::ARG_ILLEGAL;
- }
-
- static option::ArgStatus Numeric(const option::Option& option, bool msg)
- {
- char* endptr = 0;
- if (option.arg != 0 && strtol(option.arg, &endptr, 10)){};
- if (endptr != option.arg && *endptr == 0)
- return option::ARG_OK;
-
- if (msg) printError("Option '", option, "' requires a numeric argument\n");
- return option::ARG_ILLEGAL;
- }
-};
-
-static const char* help_str = " --help, -h\t\tprint usage and exit";
-static const char* conf_file_str = " --conf-file, -c\t\toriginal snort configuration file. Specify as many files as you would like";
-static const char* output_file_str = " --output-file, -o \t\tdefault = snort.lua. The new Snort++ configuration file name.";
-static const char* rule_file_str = " --rules-file, -r \t\tWrite all rules to this file. If not specified, rules will be in default output";
-static const char* error_file_str = " --error-file, -e \t\tSpecify the reject file. Use with '-a' or '--all' to print errors to this file. Default = snort.rej";
-static const char* all_str = " --all, -a\t\tOutput all data, including errors and differences. (default only prints the new snort.lua.rej file";
-static const char* parse_includes_str = " --parse_includes, -p\t\tWhen parsing specified input files, follow and parse any 'include <file>'";
-static const char* dont_parse_includes_str = " --parse-input-files, -i\t\tOnly parse specified input files. do NOT follow any 'include <file> when parsing.";
-static const char* parse_mult_str = " --mult-rule-files, -m\t\tWhen parsing include file named 'file', write rules to file.rules (parse_includes must be turn on)";
-static const char* parse_single_str = " --single-rule-files, -s\t\tWhen parsing include files, pull all data into specified rule files";
-static const char* parse_mult_conf_str = " --mult-conf-files, -n\t\tWhen parsing include file named 'file', write conf data to file.lua (parse_includes must be turn on)";
-static const char* parse_single_conf_str = " --single-conf-files, -t\t\tWhen parsing include files, pull all data into specified output files";
-static const char* differences_str = " --output-differences, -d\t\tlua syntax aside, output to specified files the differences between your Snort and Snort++ configuration";
-static const char* quiet_str = " --output-quiet, -d\t\tdon't print to standard out. only output lua and rule syntax to specified files (no comments, errors, or reject)";
-
-enum OptionType
-{
- OPT_ENABLE,
- OPT_DIABLE
-};
-
-enum OptionInline
-{
- OPT_MULT_FILES,
- OPT_SING_FILE,
-};
-
-enum PrintType
-{
- PRINT_ALL,
- PRINT_DIFFERENCES,
- PRINT_QUIET,
-};
-
-enum OptionIndex {
- HELP,
- CONF_FILE,
- OUTPUT_FILE,
- RULE_FILE,
- ERROR_FILE,
- PARSE_INCLUDES,
- MULT_RULE_FILES,
- MULT_CONF_FILES,
- PRINT_MODE,
- UNKNOWN,
-};
-
-const option::Descriptor usage[] =
-{
- {HELP, 0, "h", "help", Arg::None, help_str },
- {CONF_FILE, 0, "c", "conf-file", Arg::Required, conf_file_str},
- {OUTPUT_FILE, 0, "o", "output-file", Arg::Required, output_file_str },
- {RULE_FILE, 0, "r", "rules-file", Arg::Required, rule_file_str },
- {ERROR_FILE, 0, "e", "error-file", Arg::Required, error_file_str },
- {PARSE_INCLUDES, OPT_MULT_FILES, "p", "parse-includes", Arg::None, parse_includes_str },
- {PARSE_INCLUDES, OPT_SING_FILE, "i", "parse-input-files", Arg::None, dont_parse_includes_str },
- {MULT_RULE_FILES, OPT_MULT_FILES, "m", "mult-rule-files", Arg::None, parse_mult_str },
- {MULT_RULE_FILES, OPT_SING_FILE, "s", "single-rule-file", Arg::None, parse_single_str },
- {MULT_CONF_FILES, OPT_MULT_FILES, "n", "mult-conf-files", Arg::None, parse_mult_conf_str },
- {MULT_CONF_FILES, OPT_SING_FILE, "t", "mult-conf-files", Arg::None, parse_single_conf_str },
- {PRINT_MODE, PRINT_QUIET, "q", "output-quiet", Arg::None, quiet_str },
- {PRINT_MODE, PRINT_DIFFERENCES, "d", "output-differences", Arg::None, differences_str },
- {PRINT_MODE, PRINT_ALL, "a", "all", Arg::None, all_str },
- {UNKNOWN, 0, "", "", option::Arg::None, ""},
- {0,0,0,0,0,0}
-};
-
-} // anonymous
+#include "utils/parse_cmd_line.h"
- #if 0
- #include "option_parser.h"
-
-
- /****************************************************
- ************ OPTION INFORMATION *****************
- ****************************************************/
-
- namespace
- {
-
- struct Arg: public option::Arg
- {
- static void printError(const char* msg1, const option::Option& opt, const char* msg2)
- {
- fprintf(stderr, "%s", msg1);
- fwrite(opt.name, (std::size_t)opt.namelen, 1, stderr);
- fprintf(stderr, "%s", msg2);
- }
-
- static option::ArgStatus Unknown(const option::Option& option, bool msg)
- {
- if (msg) printError("Unknown option '", option, "'\n");
- return option::ARG_ILLEGAL;
- }
-
- static option::ArgStatus Required(const option::Option& option, bool msg)
- {
- if (option.arg != 0)
- return option::ARG_OK;
-
- if (msg) printError("Option '", option, "' requires an argument\n");
- return option::ARG_ILLEGAL;
- }
-
- static option::ArgStatus NonEmpty(const option::Option& option, bool msg)
- {
- if (option.arg != 0 && option.arg[0] != 0)
- return option::ARG_OK;
-
- if (msg) printError("Option '", option, "' requires a non-empty argument\n");
- return option::ARG_ILLEGAL;
- }
-
- static option::ArgStatus Numeric(const option::Option& option, bool msg)
- {
- char* endptr = 0;
- if (option.arg != 0 && strtol(option.arg, &endptr, 10)){};
- if (endptr != option.arg && *endptr == 0)
- return option::ARG_OK;
-
- if (msg) printError("Option '", option, "' requires a numeric argument\n");
- return option::ARG_ILLEGAL;
- }
- };
-
- static const char* help_str = " --help, -h\t\tprint usage and exit";
- static const char* conf_file_str = " --conf-file, -c\t\toriginal snort configuration file. Specify as many files as you would like";
- static const char* output_file_str = " --output-file, -o \t\tdefault = snort.lua. The new Snort++ configuration file name.";
- static const char* rule_file_str = " --rules-file, -r \t\tWrite all rules to this file. If not specified, rules will be in default output";
- static const char* error_file_str = " --error-file, -e \t\tSpecify the reject file. Use with '-a' or '--all' to print errors to this file. Default = snort.rej";
- static const char* all_str = " --all, -a\t\tOutput all data, including errors and differences. (default only prints the new snort.lua.rej file";
- static const char* parse_includes_str = " --parse_includes, -p\t\tWhen parsing specified input files, follow and parse any 'include <file>'";
- static const char* dont_parse_includes_str = " --parse-input-files, -i\t\tOnly parse specified input files. do NOT follow any 'include <file> when parsing.";
- static const char* parse_mult_str = " --mult-rule-files, -m\t\tWhen parsing include file named 'file', write rules to file.rules (parse_includes must be turn on)";
- static const char* parse_single_str = " --single-rule-files, -s\t\tWhen parsing include files, pull all data into specified rule files";
- static const char* parse_mult_conf_str = " --mult-conf-files, -n\t\tWhen parsing include file named 'file', write conf data to file.lua (parse_includes must be turn on)";
- static const char* parse_single_conf_str = " --single-conf-files, -t\t\tWhen parsing include files, pull all data into specified output files";
- static const char* differences_str = " --output-differences, -d\t\tlua syntax aside, output to specified files the differences between your Snort and Snort++ configuration";
- static const char* quiet_str = " --output-quiet, -d\t\tdon't print to standard out. only output lua and rule syntax to specified files (no comments, errors, or reject)";
-
- enum OptionType
- {
- OPT_ENABLE,
- OPT_DIABLE
- };
-
- enum OptionInline
- {
- OPT_MULT_FILES,
- OPT_SING_FILE,
- };
-
- enum PrintType
- {
- PRINT_ALL,
- PRINT_DIFFERENCES,
- PRINT_QUIET,
- };
-
- enum OptionIndex {
- HELP,
- CONF_FILE,
- OUTPUT_FILE,
- RULE_FILE,
- ERROR_FILE,
- PARSE_INCLUDES,
- MULT_RULE_FILES,
- MULT_CONF_FILES,
- PRINT_MODE,
- UNKNOWN,
- };
-
- const option::Descriptor usage[] =
- {
- {HELP, 0, "h", "help", Arg::None, help_str },
- {CONF_FILE, 0, "c", "conf-file", Arg::Required, conf_file_str},
- {OUTPUT_FILE, 0, "o", "output-file", Arg::Required, output_file_str },
- {RULE_FILE, 0, "r", "rules-file", Arg::Required, rule_file_str },
- {ERROR_FILE, 0, "e", "error-file", Arg::Required, error_file_str },
- {PARSE_INCLUDES, OPT_MULT_FILES, "p", "parse-includes", Arg::None, parse_includes_str },
- {PARSE_INCLUDES, OPT_SING_FILE, "i", "parse-input-files", Arg::None, dont_parse_includes_str },
- {MULT_RULE_FILES, OPT_MULT_FILES, "m", "mult-rule-files", Arg::None, parse_mult_str },
- {MULT_RULE_FILES, OPT_SING_FILE, "s", "single-rule-file", Arg::None, parse_single_str },
- {MULT_CONF_FILES, OPT_MULT_FILES, "n", "mult-conf-files", Arg::None, parse_mult_conf_str },
- {MULT_CONF_FILES, OPT_SING_FILE, "t", "mult-conf-files", Arg::None, parse_single_conf_str },
- {PRINT_MODE, PRINT_QUIET, "q", "output-quiet", Arg::None, quiet_str },
- {PRINT_MODE, PRINT_DIFFERENCES, "d", "output-differences", Arg::None, differences_str },
- {PRINT_MODE, PRINT_ALL, "a", "all", Arg::None, all_str },
- {UNKNOWN, 0, "", "", option::Arg::None, ""},
- {0,0,0,0,0,0}
- };
-
- } // anonymous
-
- #endif
-
/*********************************************
************** MAIN FILES *****************
*********************************************/
--static bool quiet_mode = false;
--
static void print_line(std::string s)
{
-- if (!quiet_mode)
++ if (!data_api.is_quiet_mode())
std::cout << s << std::endl;
}
--static void mult_include_errors(std::string opt_type, std::string file_name)
--{
-- print_line("Multiple options provided!! Ignoring option " +
-- opt_type + ": " + file_name);
--}
--
--
int main (int argc, char* argv[])
{
- std::string output_file = std::string();
- std::string error_file = std::string();
- std::string rule_file = std::string();
- bool rule_file_specifed = false;
- bool fail = false;;
- Converter cv;
- LuaData ld;
-
- // increment past the program name
- argc -= (argc > 0) ? 1 : 0;
- argv += (argc > 0) ? 1 : 0;
-
- // Parse all options
- option::Stats stats(usage, argc, argv);
- option::Option* options = new option::Option[stats.options_max];
- option::Option* buffer = new option::Option[stats.buffer_max];
- option::Parser parse(true, usage, argc, argv, options, buffer);
-
-
-
- if (options[HELP])
- {
- option::printUsage(std::cout, usage);
- return 0;
- }
-
-
- // Determines type of printing to output. Since Quiet mode referrs
- // to both output and standard out, parse this option first.
- if (options[PRINT_MODE])
- {
- std::string mode = std::string();
-
- switch(options[PRINT_MODE].last()->type())
- {
- case PRINT_ALL:
- quiet_mode = false;
- ld.set_default_print();
- mode = "all";
- break;
- case PRINT_QUIET:
- quiet_mode = true;
- ld.set_quiet_print();
- mode = "quiet";
- break;
- case PRINT_DIFFERENCES:
- quiet_mode = false;
- ld.set_difference_print();
- mode = "differences";
- break;
- }
-
- if (options[PRINT_MODE].count() > 1)
- print_line("Multiple print modes provided. "
- "Running in " + mode + " mode");
- }
- else
- {
- quiet_mode = true;
- ld.set_quiet_print();
- }
+ bool fail = false;
- #if 0
- bool rule_file_specifed = false;
- // increment past the program name
- argc -= (argc > 0) ? 1 : 0;
- argv += (argc > 0) ? 1 : 0;
-
-
- // Parse all options
- option::Stats stats(usage, argc, argv);
- option::Option* options = new option::Option[stats.options_max];
- option::Option* buffer = new option::Option[stats.buffer_max];
- option::Parser parse(true, usage, argc, argv, options, buffer);
-
-
-
- if (options[HELP])
- {
- option::printUsage(std::cout, usage);
- return 0;
- }
-
-
- // Determines type of printing to output. Since Quiet mode referrs
- // to both output and standard out, parse this option first.
- if (options[PRINT_MODE])
- {
- std::string mode = std::string();
-
- switch(options[PRINT_MODE].last()->type())
- {
- case PRINT_ALL:
- quiet_mode = false;
- data_api.set_default_print();
- mode = "all";
- break;
- case PRINT_QUIET:
- quiet_mode = true;
- data_api.set_quiet_print();
- mode = "quiet";
- break;
- case PRINT_DIFFERENCES:
- quiet_mode = false;
- data_api.set_difference_print();
- mode = "differences";
- break;
- }
-
- if (options[PRINT_MODE].count() > 1)
- print_line("Multiple print modes provided. "
- "Running in " + mode + " mode");
- }
- else
- {
- quiet_mode = true;
- data_api.set_quiet_print();
- }
-
-- // Get the output file. Warn the user if they provided multiple
-- // files
-- if (options[OUTPUT_FILE])
-- {
-- option::Option* tmp = options[OUTPUT_FILE];
-- while (!tmp->isLast())
-- {
-- mult_include_errors("output-file", tmp->arg);
-- tmp = tmp->next();
-- }
-- output_file = tmp->arg;
-- print_line("writing output to " + output_file);
-- }
-- else
-- {
-- print_line("No output files provided! Writing to: snort.lua");
-- output_file = "snort.lua";
-- }
--
--
-- // Get the specified rule file. Warn the user if they provided
-- // multiple file name.
-- if (options[RULE_FILE])
-- {
-- option::Option* tmp = options[RULE_FILE];
-- while (!tmp->isLast())
-- {
-- mult_include_errors("rule-file", tmp->arg);
-- tmp = tmp->next();
-- }
-- rule_file = tmp->arg;
-- print_line("writing rules to " + rule_file);
-- }
-- else
-- {
-- print_line("Rule file not provided!! Writing rules to " + output_file);
-- rule_file = output_file;
-- }
--
-- // Get the error/reject file. Warn the user if they provided multiple
-- // files
-- if (options[ERROR_FILE])
-- {
-- option::Option* tmp = options[ERROR_FILE];
-- while (!tmp->isLast())
-- {
-- mult_include_errors("error-file", tmp->arg);
-- tmp = tmp->next();
-- }
-- error_file = tmp->arg;
-- print_line("writing errors to " + error_file);
-- }
-- else
-- {
-- print_line("Rejects file not provided!! Writing rejects to snort.lua.rej");
-- error_file = "snort.lua.rej";
- }
-
-
- // tell the converter to parse all 'include' files
- if (options[PARSE_INCLUDES])
- {
- if (options[PARSE_INCLUDES].last()->type() == OPT_MULT_FILES)
- cv.set_parse_includes(true);
- else
- cv.set_parse_includes(false);
- }
-
- // assuming we are parsing includes, should we pull all of the rules into
- // the specified rule file or keep all rule files seperate
- if (options[MULT_RULE_FILES])
- {
- if (options[MULT_RULE_FILES].last()->type() == OPT_MULT_FILES)
- cv.set_convert_rules_mult_files(true);
- else
- cv.set_convert_rules_mult_files(false);
- }
-
- // assuming we are parsing includes, should we pull all of the configuration details
- // in the specified output file or keep all rule files seperate
- if (options[MULT_CONF_FILES])
- {
- if (options[MULT_CONF_FILES].last()->type() == OPT_MULT_FILES)
- cv.set_convert_conf_mult_files(true);
- else
- cv.set_convert_conf_mult_files(false);
- }
-
- if (options[UNKNOWN])
- {
-
- }
-
-
- if (!options[CONF_FILE])
- {
- option::printUsage(std::cout, usage);
- std::cout << std::endl << "At least one input file required." << std::endl << std::endl;
- return -1;
-- }
- #endif
-
- // tell the converter to parse all 'include' files
- if (options[PARSE_INCLUDES])
+ if (!parser::parse_cmd_line(argc, argv))
{
- if (options[PARSE_INCLUDES].last()->type() == OPT_MULT_FILES)
- cv.set_parse_includes(true);
- else
- cv.set_parse_includes(false);
+ print_line("ERROR: Invalid command line options provided!");
+ return -1;
}
- // assuming we are parsing includes, should we pull all of the rules into
- // the specified rule file or keep all rule files seperate
- if (options[MULT_RULE_FILES])
- {
- if (options[MULT_RULE_FILES].last()->type() == OPT_MULT_FILES)
- cv.set_convert_rules_mult_files(true);
- else
- cv.set_convert_rules_mult_files(false);
- }
+ // Defaults are set in parse_cmd_line.cc
+ const std::string output_file = parser::get_out_file();
+ const std::string error_file = parser::get_error_file();
+ const std::string rule_file = parser::get_rule_file();
+ const std::string conf_file = parser::get_conf();
- // assuming we are parsing includes, should we pull all of the configuration details
- // in the specified output file or keep all rule files seperate
- if (options[MULT_CONF_FILES])
+ // configuration file is required and no default is provided
+ if (conf_file.empty())
{
- if (options[MULT_CONF_FILES].last()->type() == OPT_MULT_FILES)
- cv.set_convert_conf_mult_files(true);
- else
- cv.set_convert_conf_mult_files(false);
+ print_line("ERROR: Snort configuration file required!!");
+ print_line(" Use either '-c' or '--conf-file' option");
+ return -1;
}
- if (options[UNKNOWN])
- {
-
- }
+ cv.initialize(&init_state_ctor);
+ // MAIN LOOP!! walk through every input file and begin converting!
+// option::Option* opt = options[CONF_FILE];
- if (!options[CONF_FILE])
+ if (cv.convert_file(conf_file) < 0)
{
- option::printUsage(std::cout, usage);
- std::cout << std::endl << "At least one input file required." << std::endl << std::endl;
- return -1;
+ print_line("Failed Conversion of file " + conf_file);
+ fail = true;
}
+// } while ((opt = opt->next()));
-
-
-
- cv.initialize(&init_state_ctor, &ld);
-
- // MAIN LOOP!! walk through every input file and begin converting!
- option::Option* opt = options[CONF_FILE];
- do {
- if (cv.convert_file(std::string(opt->arg)) < 0)
- {
- print_line("Failed Conversion of file " + std::string(opt->arg));
- fail = true;
- }
- } while ((opt = opt->next()));
-
-
+ // keep track whether we're printing rules into a seperate file.
+ bool rule_file_specifed = false;
// if no rule file is specified (or the same output and rule file specified),
// rules will be printed in the 'default_rules' variable. Set that up
set (TEST_CONF_LUA "${CMAKE_CURRENT_BINARY_DIR}/snort.lua")
set (TEST_CONF_REJ "${CMAKE_CURRENT_BINARY_DIR}/snort.rej")
-
-add_test (NAME ctest_snort2lua
- COMMAND $<TARGET_FILE:snort2lua> -c ${TEST_CONF_CONF} -o ${TEST_CONF_LUA} -e ${TEST_CONF_REJ} -a -p -s -t
- WORKING_DIRECTORY ${CMAKE_CURENT_BINARY_DIR})
++# so Snort++ won't choke on block.html
++execute_process (COMMAND {${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/block.html})
+
+add_test (
+ NAME ctest_snort2lua_conf
+ COMMAND $<TARGET_FILE:snort2lua>
+ -c ${TEST_CONF_CONF}
+ -o ${TEST_CONF_LUA}
+ -e ${TEST_CONF_REJ}
+ -a -s -t # output everything, right rules and data to a single out file
+ WORKING_DIRECTORY ${CMAKE_CURENT_BINARY_DIR})
add_test (NAME ctest_snort_conf COMMAND $<TARGET_FILE:snort> -c ${TEST_CONF_LUA})
# adding dependcies
config min_ttl: 5
config new_ttl: 8
config nolog
--config react: block.html
++config react: @CMAKE_CURRENT_BINARY_DIR@/block.html
config logdir: @CMAKE_CURRENT_BINARY_DIR@/
config dirty_pig:
config enable_gtp
# Why is this failing section
--alert tcp any 80 -> any any (msg:"content detected in chunk"; file_data;content:"nt network testing facility";within:30; sid:1;)
++alert tcp any 80 -> any any (msg:"content detected in chunk"; file_data;content:"nt network testing facility";within:30; sid:1000039;)
content:"jedi request"; nocase; offset:4; depth:20; rawbytes; \
content:"jedi request2"; nocase; distance:150; http_cookie; http_header; \
content:"jedi request3"; within:150; http_client_body; \
-- sid:7033; gid:116; rev:6;)
++ sid:1000060; gid:1189; rev:6;)
alert tcp $HOME_NET any -> $EXTERNAL_NET [80,443,8200] (msg:"APP-DETECT GoToMyPC local service running"; \
content:"http_raw_uri"; http_raw_uri; \
content:"http_stat_code"; http_stat_code; \
content:"http_stat_msg"; http_stat_msg; \
-- sid:7034; gid:116; rev:6;)
++ sid:7034; gid:1189; rev:6;)
alert tcp any any -> any any (msg:"la di da"; \
content:"fast_parttern"; fast_pattern:only ; \
-- sid:7035; gid:116; rev:6;)
++ sid:7035; gid:1189; rev:6;)
alert tcp any any -> any any (msg:"fast_pattern offset length"; \
content:"fast_parttern"; fast_pattern:1,5; \
-- sid:7036; gid:116; rev:6;)
++ sid:7036; gid:1189; rev:6;)
alert tcp $HOME_NET any -> $EXTERNAL_NET [80,443,8200] (msg:"uricontent"; \
uricontent:"jedi request"; nocase; offset:4; depth:20; \
-- sid:7037; gid:116; rev:6;)
++ sid:7037; gid:1189; rev:6;)
alert tcp $HOME_NET any -> $EXTERNAL_NET [80,443,8200] (msg:"uricontent"; \
uricontent:"jedi request"; nocase; within:30; distance:50; \
-- sid:7038; gid:116; rev:6;)
++ sid:7038; gid:1189; rev:6;)
alert tcp any any <> any 80 (msg:"MD5 Alert"; \
-- protected_content:"293C9EA246FF9985DC6F62A650F78986"; hash:md5; offset:0; length:4; gid:116; sid:2)
++ protected_content:"293C9EA246FF9985DC6F62A650F78986"; hash:md5; offset:0; length:4; gid:1189; sid:1000040)
alert tcp any any <> any 80 (msg:"SHA256 Alert"; \
protected_content:"56D6F32151AD8474F40D7B939C2161EE2BBF10023F4AF1DBB3E13260EBDC6342"; \
-- hash:sha256; offset:0; length:4; gid:2; sid:3)
++ hash:sha256; offset:0; length:4; gid:2; sid:1000041)
--alert tcp $HOME_NET any -> $EXTERNAL_NET [80,443,8200] (msg:"APP-DETECT GoToMyPC local service running"; flow:to_server,established; content:"jedi request"; nocase; sid:7033; rev:6;)
++alert tcp $HOME_NET any -> $EXTERNAL_NET [80,443,8200] (msg:"APP-DETECT GoToMyPC local service running"; flow:to_server,established; content:"jedi request"; nocase; sid:7033; rev:6; gid:1189 )
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"WEB-CLIENT csv file download request"; flow:to_server, established; content:"GET"; nocase; uricontent:".csv"; nocase; flowbits:set,csv.download; flowbits:noalert; metadata:service http; reference:cve,2008-0112; reference:url,www.microsoft.com/technet/security/Bulletin/MS08-014.mspx; classtype:misc-activity; sid:13584; rev:2;)
alert tcp $EXTERNAL_NET any -> $HOME_NET 3389 (msg:"APP-DETECT remote desktop protocol attempted administrator connection request"; content:"|E0|"; depth:1; offset:5; content:"mstshash=Administr"; distance:0; nocase; reference:bugtraq,14259; reference:cve,2005-1218; reference:url,technet.microsoft.com/en-us/security/bulletin/MS05-041; classtype:misc-activity; sid:4060; rev:8;)
--alert ( msg:"DECODE_ICMP4_DST_BROADCAST"; sid:416; gid:116; rev:1; metadata:rule-type decode, service http, rule-flushing enabled; classtype:misc-activity; )
--alert ( msg:"DECODE_ICMP4_TYPE_OTHER"; sid:418; gid:116; rev:1; metadata:rule-type decode; classtype:misc-activity; )
++alert ( msg:"DECODE_ICMP4_DST_BROADCAST"; sid:1000042; gid:1189; rev:1; metadata:rule-type decode, service http, rule-flushing enabled; classtype:misc-activity; )
++alert ( msg:"DECODE_ICMP4_TYPE_OTHER"; sid:1000043; gid:1189; rev:1; metadata:rule-type decode; classtype:misc-activity; )
drop tcp $EXTERNAL_NET 554 -> $HOME_NET any (msg:"MULTIMEDIA Windows Media Player malicious playlist buffer overflow attempt"; sid:14252; gid:3; rev:9; classtype:attempted-user; flowbits:isset,file.wmp_playlist; reference:cve,2008-2253; reference:url,technet.microsoft.com/en-us/security/bulletin/MS08-054; metadata: engine shared, soid 3|14252, policy balanced-ips drop, policy security-ips drop;)
# Fragbits
--alert ip $EXTERNAL_NET any -> $HOME_NET any (msg:"DOS IGMP dos attack"; fragbits:M+; ip_proto:2; reference:bugtraq,514; reference:cve,1999-0918; reference:url,www.microsoft.com/technet/security/bulletin/MS99-034.mspx; classtype:attempted-dos; sid:272; rev:11;)
++alert ip $EXTERNAL_NET any -> $HOME_NET any (msg:"DOS IGMP dos attack"; fragbits:M+; ip_proto:2; reference:bugtraq,514; reference:cve,1999-0918; reference:url,www.microsoft.com/technet/security/bulletin/MS99-034.mspx; classtype:attempted-dos; sid:1000044; rev:11;)
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"ET SCAN NMAP -f -sF"; fragbits:!M; dsize:0; flags:F,12; ack:0; window:2048; classtype:attempted-recon; reference:url,doc.emergingthreats.net/2000543; reference:url,www.emergingthreats.net/cgi-bin/cvsweb.cgi/sigs/SCAN/SCAN_NMAP; sid:2000543; rev:6;)
alert tcp any any -> any any (msg:"test base64_decode"; asn1: bitstring_overflow; sid:1000010; gid:1189)
--alert tcp any any <> any any (msg:"blahblahblah";file_data:mime;sid:1)
--alert tcp any any <> any any (file_data:mime;msg:"blahblahblah";sid:1)
++alert tcp any any <> any any (msg:"blahblahblah";file_data:mime;sid:1000045)
++alert tcp any any <> any any (file_data:mime;msg:"blahblahblah";sid:1000046)
rule_state 1000001 1189 enabled drop
rule_state 1000004 1189, enabled sdrop
--alert tcp any any -> any 80 ( sid:3; threshold:type limit, track by_src, count 1 , seconds 60; gid: 119; )
--alert tcp any any -> any 80 ( sid:400; gid:119; threshold:type limit, track by_src, count 1 , seconds 60 )
--alert tcp any any -> any 80 ( threshold:type limit, track by_src, count 1 , seconds 60; sid:1; gid:119 )
--alert tcp any any -> any 80 ( threshold:type limit, track by_src, count 1 , seconds 60; sid:2; gid:119 )
--alert tcp any any -> any 80 ( threshold:type limit, track by_src, count 1 , seconds 60; content:"blah"; gid:119; sid:4 )
++alert tcp any any -> any 80 ( sid:1000047; threshold:type limit, track by_src, count 1 , seconds 60; gid: 119; )
++alert tcp any any -> any 80 ( sid:1000048; gid:1189; threshold:type limit, track by_src, count 1 , seconds 60 )
++alert tcp any any -> any 80 ( threshold:type limit, track by_src, count 1 , seconds 60; sid:1000049; gid:1189 )
++alert tcp any any -> any 80 ( threshold:type limit, track by_src, count 1 , seconds 60; sid:1000050; gid:1189 )
++alert tcp any any -> any 80 ( threshold:type limit, track by_src, count 1 , seconds 60; content:"blah"; gid:1189; sid:1000051 )
include @CMAKE_CURRENT_LIST_DIR@/file_magic.conf
-#alert tcp any any -> any any (msg:"pdf"; file_type:PDF; sid:2; flow:established,to_client;)
+
- #alert tcp any any -> any any (msg:"pdf"; file_type:PDF; sid:2; flow:established,to_client;)
++#alert tcp any any -> any any (msg:"pdf"; file_type:PDF; sid:1000051; flow:established,to_client;)
+
+
+
+
- alert tcp any any <> any any ( sid:1; msg:"x"; resp:reset_source; )
++alert tcp any any <> any any ( sid:1000052; msg:"x"; resp:reset_source; )
+
+alert tcp any any <> any 80 ( sid:1000020; msg:"x"; react; )
+alert tcp any any <> any 80 ( sid:1000021; msg:"x"; react:; )
+alert tcp any any <> any 80 ( sid:1000022; msg:"x"; react:msg; )
+alert tcp any any <> any 80 ( sid:1000023; react; msg:"x"; )
+alert tcp any any <> any 80 ( sid:1000024; react:msg; msg:"x"; )
+alert tcp any any <> any any ( sid:1000027; msg:"x"; resp:reset_dest; )
+alert tcp any any <> any any ( sid:1000026; msg:"x"; resp:reset_both; )
+alert tcp any any <> any any ( sid:1000028; msg:"x"; resp:rst_snd; )
+alert tcp any any <> any any ( sid:1000029; msg:"x"; resp:rst_rcv; )
+alert tcp any any <> any any ( sid:1000030; msg:"x"; resp:rst_all; )
+alert tcp any any <> any any ( sid:1000031; msg:"x"; resp:icmp_net; )
+alert tcp any any <> any any ( sid:1000032; msg:"x"; resp:icmp_host; )
+alert tcp any any <> any any ( sid:1000033; msg:"x"; resp:icmp_port; )
+alert tcp any any <> any any ( sid:1000034; msg:"x"; resp:icmp_all; )
+alert tcp any any <> any any ( sid:1000035; msg:"x"; resp:reset_source, reset_dest, reset_both; )
+alert tcp any any <> any any ( sid:1000036; msg:"x"; resp:rst_snd, rst_rcv, rst_all; )
+alert tcp any any <> any any ( sid:1000037; msg:"x"; resp:icmp_net, icmp_host, icmp_port, icmp_all; )
+alert tcp any any <> any any ( sid:1000038; msg:"x"; resp:reset_source, reset_dest, reset_both, reset_dest; )
libsnort2lua_utils_a_SOURCES = \
converter.h \
converter.cc \
++parse_cmd_line.h \
++parse_cmd_line.cc \
s2l_util.h \
s2l_util.cc
--- /dev/null
- const bool rule_file_provided();
+/*
+** 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.
+*/
+
+#ifndef UTILS_PARSE_CMD_LINE_H
+#define UTILS_PARSE_CMD_LINE_H
+
+#include <string>
+
+namespace parser
+{
+
+/*
+ * This file is directly copied (and then edited)
+ * from Snrot++'s cmd_line.h
+ */
+
+bool parse_cmd_line(int argc, char* argv[]);
+
+const std::string get_conf();
+const std::string get_conf_dir();
+const std::string get_error_file();
+const std::string get_out_file();
+const std::string get_rule_file();
+
+} // namespace parser
+
+#endif
+