using namespace snort;
-JsonAllConfigOutput::JsonAllConfigOutput() :
- ConfigOutput(), json(std::cout)
-{ json.open_array(); }
-
-JsonAllConfigOutput::~JsonAllConfigOutput()
-{ json.close_array(); }
-
-void JsonAllConfigOutput::dump(const ConfigData& config_data)
-{
- json.open();
- json.put("filename", config_data.file_name);
- json.open("config");
-
- for ( const auto config_tree: config_data.config_trees )
- dump_modules(config_tree);
-
- json.close();
- json.close();
-}
-
-void JsonAllConfigOutput::dump_modules(const BaseConfigNode* node)
-{
- Parameter::Type type = node->get_type();
- if ( type == Parameter::PT_LIST )
- json.open_array(node->get_name().c_str());
- else if ( type == Parameter::PT_TABLE )
- {
- std::string name = node->get_name();
- name.empty() ? json.open() : json.open(name.c_str());
- }
- else
- dump_value(node);
-
- for ( const auto n : node->get_children() )
- dump_modules(n);
-
- if ( type == Parameter::PT_LIST )
- json.close_array();
- else if ( type == Parameter::PT_TABLE )
- json.close();
-}
-
-void JsonAllConfigOutput::dump_value(const BaseConfigNode* node)
+static void dump_value(JsonStream& json, const BaseConfigNode* node)
{
const Value* value = node->get_value();
if ( !value )
}
}
+static void dump_modules(JsonStream& json, const BaseConfigNode* node)
+{
+ Parameter::Type type = node->get_type();
+ if ( type == Parameter::PT_LIST )
+ json.open_array(node->get_name().c_str());
+ else if ( type == Parameter::PT_TABLE )
+ {
+ std::string name = node->get_name();
+ name.empty() ? json.open() : json.open(name.c_str());
+ }
+ else
+ dump_value(json, node);
+
+ for ( const auto n : node->get_children() )
+ dump_modules(json, n);
+
+ if ( type == Parameter::PT_LIST )
+ json.close_array();
+ else if ( type == Parameter::PT_TABLE )
+ json.close();
+}
+
+JsonAllConfigOutput::JsonAllConfigOutput() :
+ ConfigOutput(), json(std::cout)
+{ json.open_array(); }
+
+JsonAllConfigOutput::~JsonAllConfigOutput()
+{ json.close_array(); }
+
+void JsonAllConfigOutput::dump(const ConfigData& config_data)
+{
+ json.open();
+ json.put("filename", config_data.file_name);
+ json.open("config");
+
+ for ( const auto config_tree: config_data.config_trees )
+ dump_modules(json, config_tree);
+
+ json.close();
+ json.close();
+}
+
+void JsonTopConfigOutput::dump(const ConfigData& config_data)
+{
+ json.open();
+
+ for ( const auto config_tree: config_data.config_trees )
+ dump_modules(json, config_tree);
+
+ json.close();
+}
private:
void dump(const ConfigData&) override;
- void dump_modules(const BaseConfigNode* node);
- void dump_value(const BaseConfigNode* node);
+private:
+ JsonStream json;
+};
+
+class JsonTopConfigOutput : public ConfigOutput
+{
+public:
+ JsonTopConfigOutput() : ConfigOutput(), json(std::cout) {}
+
+private:
+ void dump(const ConfigData&) override;
private:
JsonStream json;
};
#endif // JSON_CONFIG_OUTPUT_H
-
void Shell::config_open_table(bool is_root_node, bool is_list, int idx,
const std::string& table_name, const Parameter* p)
{
+ if ( !s_config_output )
+ return;
+
Parameter::Type node_type = is_list ? Parameter::PT_LIST : Parameter::PT_TABLE;
if ( is_root_node )
add_config_root_node(table_name, node_type);
void Shell::add_config_child_node(const std::string& node_name, snort::Parameter::Type type)
{
- if ( !s_current_node )
+ if ( !s_config_output || !s_current_node )
return;
std::string name;
void Shell::add_config_root_node(const std::string& root_name, snort::Parameter::Type node_type)
{
+ if ( !s_config_output )
+ return;
+
Shell* sh = Shell::get_current_shell();
if ( !sh )
void Shell::update_current_config_node(const std::string& node_name)
{
- if ( !s_current_node )
+ if ( !s_config_output || !s_current_node )
return;
// node has been added during setting default options
void Shell::config_close_table()
{
+ if ( !s_config_output )
+ return;
+
if ( !s_close_table )
{
s_close_table = true;
void Shell::set_config_value(const std::string& fqn, const snort::Value& value)
{
- if ( !s_current_node )
+ if ( !s_config_output || !s_current_node )
return;
// lua interpreter does not call open_table for simple list items like (string) or
case DUMP_CONFIG_JSON_ALL:
output = new JsonAllConfigOutput();
break;
+ case DUMP_CONFIG_JSON_TOP:
+ output = new JsonTopConfigOutput();
+ break;
case DUMP_CONFIG_TEXT:
output = new TextConfigOutput();
break;
{
DUMP_CONFIG_NONE = 0,
DUMP_CONFIG_JSON_ALL,
+ DUMP_CONFIG_JSON_TOP,
DUMP_CONFIG_TEXT
};
{ "--dump-builtin-rules", Parameter::PT_STRING, "(optional)", nullptr,
"[<module prefix>] output stub rules for selected modules" },
- { "--dump-config", Parameter::PT_SELECT, "all", nullptr,
+ { "--dump-config", Parameter::PT_SELECT, "all | top", nullptr,
"dump config in json format" },
{ "--dump-config-text", Parameter::PT_IMPLIED, nullptr, nullptr,
sc->run_flags |= RUN_FLAG__TEST;
if ( v.get_as_string() == "all" )
sc->dump_config_type = DUMP_CONFIG_JSON_ALL;
+ else if ( v.get_as_string() == "top" )
+ sc->dump_config_type = DUMP_CONFIG_JSON_TOP;
}
else if ( v.is("--dump-config-text") )
static bool set_param(Module* mod, const char* fqn, Value& val)
{
- if ( s_config->dump_config_mode() )
- Shell::set_config_value(fqn, val);
+ Shell::set_config_value(fqn, val);
if ( !mod->verified_set(fqn, val, s_config) )
{
{
const Parameter* table_item_params = reinterpret_cast<const Parameter*>(p->range);
- if ( s_config->dump_config_mode() )
- Shell::add_config_child_node(get_sub_table(fqn), p->type);
+ Shell::add_config_child_node(get_sub_table(fqn), p->type);
if ( !begin(m, table_item_params, fqn.c_str(), idx, depth+1) )
return false;
}
++p;
}
- if ( s_config->dump_config_mode() )
- Shell::update_current_config_node();
+
+ Shell::update_current_config_node();
+
return true;
}
s_type.clear();
}
- if ( s_config->dump_config_mode() )
- Shell::config_close_table();
+ Shell::config_close_table();
}
SO_PUBLIC bool set_bool(const char* fqn, bool b)
bool parse_file_failed = false;
auto output = SnortConfig::get_conf()->create_config_output();
- Shell::set_config_output(output);
+ bool is_top = SnortConfig::get_conf()->dump_config_type == DUMP_CONFIG_JSON_TOP;
for ( unsigned i = 0; true; i++ )
{
sh = sc->policy_map->get_shell(i);
if ( !sh )
break;
+ auto shell_output = ( i != 0 && is_top ) ? nullptr : output;
+ Shell::set_config_output(shell_output);
set_policies(sc, sh);
if (!parse_file(sc, sh, is_fatal, (i == 0)))