binder =
{
- -- these protocols do not yet have wizard support
+ -- port bindings required for protocols without wizard support
{ when = { proto = 'udp', ports = '53' }, use = { type = 'dns' } },
{ when = { proto = 'tcp', ports = '111' }, use = { type = 'rpc_decode' } },
{ when = { proto = 'tcp', ports = '502' }, use = { type = 'modbus' } },
{ when = { proto = 'tcp', ports = '2123 2152 3386' }, use = { type = 'gtp' } },
+ { when = { proto = 'tcp', service = 'dcerpc' }, use = { type = 'dce_tcp' } },
+ { when = { proto = 'udp', service = 'dcerpc' }, use = { type = 'dce_udp' } },
+
+ { when = { service = 'netbios-ssn' }, use = { type = 'dce_smb' } },
{ when = { service = 'dce_http_server' }, use = { type = 'dce_http_server' } },
{ when = { service = 'dce_http_proxy' }, use = { type = 'dce_http_proxy' } },
- { when = { service = 'dce_smb' }, use = { type = 'dce_smb' } },
- { when = { service = 'dce_udp' }, use = { type = 'dce_udp' } },
- { when = { service = 'dce_tcp' }, use = { type = 'dce_tcp' } },
+
{ when = { service = 'dnp3' }, use = { type = 'dnp3' } },
{ when = { service = 'dns' }, use = { type = 'dns' } },
{ when = { service = 'ftp' }, use = { type = 'ftp_server' } },
http_methods = -- build from default_http_methods
{
- 'OPTIONS', 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'TRACE', 'CONNECT',
+ 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'TRACE', 'CONNECT',
'VERSION_CONTROL', 'REPORT', 'CHECKOUT', 'CHECKIN', 'UNCHECKOUT',
'MKWORKSPACE', 'UPDATE', 'LABEL', 'MERGE', 'BASELINE_CONTROL',
'MKACTIVITY', 'ORDERPATCH', 'ACL', 'PATCH', 'BIND', 'LINK',
'MOVE', 'LOCK', 'UNLOCK', 'SEARCH', 'BCOPY', 'BDELETE', 'BMOVE',
'BPROPFIND', 'BPROPPATCH', 'NOTIFY', 'POLL', 'SUBSCRIBE',
'UNSUBSCRIBE', 'X_MS_ENUMATTS',
-}
-
-ftp_commands = -- build from ftp_default_cmds
-{
- 'ABOR', 'ACCT', 'ADAT', 'ALLO', 'APPE', 'AUTH', 'CCC', 'CDUP', 'CEL',
- 'CLNT', 'CMD', 'CONF', 'CWD', 'DELE', 'ENC', 'EPRT', 'EPSV', 'ESTA',
- 'ESTP', 'FEAT', 'HELP', 'LANG', 'LIST', 'LPRT', 'LPSV', 'MACB', 'MAIL',
- 'MDTM', 'MIC', 'MKD', 'MLSD', 'MLST', 'MODE', 'NLST', 'NOOP', 'OPTS',
- 'PASS', 'PASV', 'PBSZ', 'PORT', 'PROT', 'PWD', 'QUIT', 'REIN', 'REST',
- 'RETR', 'RMD', 'RNFR', 'RNTO', 'SDUP', 'SITE', 'SIZE', 'SMNT', 'STAT',
- 'STOR', 'STOU', 'STRU', 'SYST', 'TEST', 'TYPE', 'USER', 'XCUP', 'XCRC',
- 'XCWD', 'XMAS', 'XMD5', 'XMKD', 'XPWD', 'XRCP', 'XRMD', 'XRSQ', 'XSEM',
- 'XSEN', 'XSHA1', 'XSHA256'
+ --'OPTIONS',
}
sip_methods =
{
- 'INVITE', 'CANCEL', 'ACK', 'BYE', 'REGISTER', 'OPTIONS', 'REFER', 'SUBSCRIBE',
+ 'INVITE', 'CANCEL', 'ACK', 'BYE', 'REGISTER', 'REFER', 'SUBSCRIBE',
'UPDATE', 'JOIN', 'INFO', 'MESSAGE', 'NOTIFY', 'PRACK'
+ --'OPTIONS',
}
telnet_commands =
spells =
{
{ service = 'ftp', proto = 'tcp', client_first = false,
- to_server = ftp_commands, to_client = { '220*FTP' } },
+ to_client = { '220*FTP' } },
{ service = 'http', proto = 'tcp', client_first = true,
to_server = http_methods, to_client = { 'HTTP/' } },
{ service = 'imap', proto = 'tcp', client_first = false,
- to_server = { 'LOGIN', 'AUTHENTICATE', 'STARTTLS' },
- to_client = { '** OK', '** BYE' } },
+ to_client = { '** OK', '** BYE', '** PREAUTH' } },
{ service = 'pop3', proto = 'tcp', client_first = false,
- to_server = { 'USER', 'APOP' },
to_client = { '+OK', '-ERR' } },
- { service = 'sip', proto = 'tcp', client_first = true,
+ { service = 'sip', client_first = true,
to_server = sip_methods, to_client = { 'SIP/' } },
- { service = 'smtp', proto = 'tcp', client_first = false,
+ { service = 'smtp', proto = 'tcp', client_first = true,
to_server = { 'HELO', 'EHLO' },
to_client = { '220*SMTP', '220*MAIL' } },
break;
}
}
-
rval = node->evaluate(node->option_data, cursor, p);
}
-
break;
case RULE_OPTION_TYPE_FLOWBIT:
if ( node->evaluate )
{
- flowbits_setoperation =
- FlowBits_SetOperation(node->option_data);
+ flowbits_setoperation = FlowBits_SetOperation(node->option_data);
if ( flowbits_setoperation )
// set to match so we don't bail early
else
rval = node->evaluate(node->option_data, cursor, eval_data->p);
}
-
break;
default:
if ( node->evaluate )
rval = node->evaluate(node->option_data, cursor, p);
-
break;
}
{
for ( int i = 0; i < node->num_children; ++i )
{
- detection_option_tree_node_t* child_node =
- node->children[i];
-
- dot_node_state_t* child_state =
- child_node->state + get_instance_id();
+ detection_option_tree_node_t* child_node = node->children[i];
+ dot_node_state_t* child_state = child_node->state + get_instance_id();
for ( int j = 0; j < NUM_IPS_OPTIONS_VARS; ++j )
SetVarValueByIndex(tmp_byte_extract_vars[j], (int8_t)j);
{
if ( child_state->result == (int)IpsOption::NO_MATCH )
{
- if ( !child_node->is_relative )
+ if ( child_node->option_type == RULE_OPTION_TYPE_CONTENT )
{
- if ( child_node->option_type == RULE_OPTION_TYPE_CONTENT )
+ if ( !child_node->is_relative )
{
// If it's a non-relative content or pcre, no reason
// to check again. Only increment result once.
continue;
}
- }
- else if ( child_node->option_type == RULE_OPTION_TYPE_CONTENT )
- {
- // Check for an unbounded relative search. If this
- // failed before, it's going to fail again so don't
- // go down this path again
- IpsOption* opt = (IpsOption*)node->option_data;
- PatternMatchData* pmd = opt->get_pattern(0, RULE_WO_DIR);
-
- if ( pmd->is_unbounded() )
+ else
{
- // Only increment result once. Should hit this
- // condition on first loop iteration
- if (loop_count == 1)
- ++result;
-
- continue;
+ // Check for an unbounded relative search. If this
+ // failed before, it's going to fail again so don't
+ // go down this path again
+ IpsOption* opt = (IpsOption*)child_node->option_data;
+ PatternMatchData* pmd = opt->get_pattern(0, RULE_WO_DIR);
+
+ if ( pmd and pmd->is_unbounded() )
+ {
+ // Only increment result once. Should hit this
+ // condition on first loop iteration
+ if (loop_count == 1)
+ ++result;
+
+ continue;
+ }
}
}
}
#define SOAPI_VERSION ((BASE_API_VERSION << 16) | 0)
//-------------------------------------------------------------------------
-// rule format is: header ( <stub opts>; soid:<tag>; <detect opts>; )
-// <stub opts> must include sid
-// <detect opts> may include so opts like so:<key>;
+// rule format is: header ( [<stub opts>;] soid:<tag>; [<remaining opts>;] )
+// <remaining opts> may include so opts like so:<key>;
// ctor(<key>) returns eval func and optional data
// data is freed with dtor(data)
}
else
{
+ unsigned len = btd->relative_flag ? c.length() : c.size();
+
+ if ( len > btd->bytes_to_compare )
+ len = btd->bytes_to_compare;
+
payload_bytes_grabbed = string_extract(
- btd->bytes_to_compare, btd->base,
- start_ptr, c.buffer(), c.endo(), &value);
+ len, btd->base, start_ptr, c.buffer(), c.endo(), &value);
if ( payload_bytes_grabbed < 0 )
{
SoModule* m = (SoModule*)p;
const char* name = m->name.c_str();
+ if ( !otn->soid )
+ {
+ ParseError("no soid before so:%s", name);
+ return nullptr;
+ }
SoEvalFunc func = SoManager::get_so_eval(otn->soid, name, &data);
if ( !func )
static const Parameter s_params[] =
{
{ "~", Parameter::PT_STRING, nullptr, nullptr,
- "SO rule ID has <gid>|<sid> format, like 3|12345" },
+ "SO rule ID is unique key, eg <gid>_<sid>_<rev> like 3_45678_9" },
{ nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
};
public:
PolicyId policy_id;
- PolicyMode policy_mode = POLICY_MODE__INLINE_TEST;
+ PolicyMode policy_mode = POLICY_MODE__MAX;
uint32_t user_policy_id = 0;
uuid_t uuid{};
uint32_t user_policy_id = 0;
uuid_t uuid{};
- PolicyMode policy_mode;
+ PolicyMode policy_mode = POLICY_MODE__MAX;
bool enable_builtin_rules;
std::string include;
}
}
-static void init_policy_mode(IpsPolicy* p)
+static PolicyMode init_policy_mode(PolicyMode mode)
{
- switch ( p->policy_mode )
+ switch ( mode )
{
case POLICY_MODE__PASSIVE:
if ( SnortConfig::adaptor_inline_test_mode() )
- p->policy_mode = POLICY_MODE__INLINE_TEST;
+ return POLICY_MODE__INLINE_TEST;
break;
case POLICY_MODE__INLINE:
if ( SnortConfig::adaptor_inline_test_mode() )
- p->policy_mode = POLICY_MODE__INLINE_TEST;
+ return POLICY_MODE__INLINE_TEST;
else if (!SnortConfig::adaptor_inline_mode())
{
ParseWarning(WARN_DAQ, "adapter is in passive mode; switching policy mode to tap.");
- p->policy_mode = POLICY_MODE__PASSIVE;
+ return POLICY_MODE__PASSIVE;
}
break;
case POLICY_MODE__MAX:
if ( SnortConfig::adaptor_inline_mode() )
- p->policy_mode = POLICY_MODE__INLINE;
+ return POLICY_MODE__INLINE;
else
- p->policy_mode = POLICY_MODE__PASSIVE;
+ return POLICY_MODE__PASSIVE;
break;
}
+ return mode;
}
static void init_policies(SnortConfig* sc)
{
for ( auto p : sc->policy_map->ips_policy )
- init_policy_mode(p);
+ p->policy_mode = init_policy_mode(p->policy_mode);
+
+ for ( auto p : sc->policy_map->inspection_policy )
+ p->policy_mode = init_policy_mode(p->policy_mode);
}
//-------------------------------------------------------------------------
it->second.clear();
}
+#ifndef REG_TEST
for ( RefMap::iterator it = ref_map.begin(); it != ref_map.end(); ++it )
- {
dlclose(it->first);
- }
+#endif
}
//-------------------------------------------------------------------------
if ( !api )
return nullptr;
+ if ( !api->length )
+ return ")"; // plain stub is full rule
+
const char* rule = revert(api->rule, api->length);
if ( !rule )
static void get_var(const string& s, string& v)
{
v.clear();
- size_t pos = s.find("soid");
+ size_t pos = s.find("soid:");
if ( pos == string::npos )
return;
- pos = s.find('|', pos+1);
-
- if ( pos == string::npos )
- return;
+ pos += 5;
- size_t end = s.find(';', ++pos);
+ size_t end = s.find(';', pos);
if ( end == string::npos )
return;
string var;
get_var(text, var);
- cout << "const uint8_t rule_" << var;
+ cout << "static const uint8_t rule_" << var;
cout << "[] =" << endl;
cout << "{" << endl << " ";
cout << hex << uppercase;
cout << dec;
cout << "};" << endl;
- cout << "const unsigned rule_" << var << "_len = ";
+ cout << "static const unsigned rule_" << var << "_len = ";
cout << data.size() << ";" << endl;
}
string var;
get_var(text, var);
- cout << "const uint8_t rule_" << var;
+ cout << "static const uint8_t rule_" << var;
cout << "[] =" << endl;
cout << "{" << endl << " ";
cout << hex << uppercase;
cout << dec;
cout << "};" << endl;
- cout << "const unsigned rule_" << var;
+ cout << "static const unsigned rule_" << var;
cout << "_len = 0;" << endl;
}
void MemoryCap::print()
{
+ if ( !MemoryModule::is_active() )
+ return;
+
const MemoryConfig& config = *SnortConfig::get_conf()->memory;
if ( SnortConfig::log_verbose() or s_tracker.allocations )
// memory module
// -----------------------------------------------------------------------------
+bool MemoryModule::configured = false;
+
MemoryModule::MemoryModule() :
Module(s_name, s_help, s_params)
{ }
return true;
}
+
+bool MemoryModule::end(const char*, int, SnortConfig*)
+{
+ configured = true;
+ return true;
+}
+
+bool MemoryModule::is_active()
+{ return configured; }
+
MemoryModule();
bool set(const char*, Value&, SnortConfig*) override;
+ bool end(const char*, int, SnortConfig*) override;
Usage get_usage() const override
{ return GLOBAL; }
+
+ static bool is_active();
+
+private:
+ static bool configured;
};
#endif
while ( p->name )
{
- test_pegs.push_back(*p);
add_test_peg(*p);
+ test_pegs.push_back(*p);
p++;
}
while ( p->name )
{
- test_pegs.push_back(*p);
add_test_peg(*p);
+ test_pegs.push_back(*p);
p++;
}
if ( !(t_flags & nf) )
return false;
+ if ( get_inspection_policy()->policy_mode != POLICY_MODE__INLINE )
+ return false;
+
NetworkPolicy* nap = get_network_policy();
return ( (nap->normal_mask & nf) != 0 );
}
-// FIXIT-L should return OFF if flag isn't set. Stream will need to handle that condition
NormMode Normalize_GetMode(NormFlags nf)
{
if (Normalize_IsEnabled(nf))
enum NormMode : int8_t
{
- NORM_MODE_ON,
NORM_MODE_TEST,
+ NORM_MODE_ON,
NORM_MODE_MAX
};
if ( c2s_splitter->cutover_inspector() && s2c_splitter->cutover_inspector() )
{
dce_http_proxy_stats.http_proxy_sessions++;
- dce_http_bind(flow, "dce_tcp");
+ dce_http_bind(flow, "dcerpc");
}
else
dce_http_proxy_stats.http_proxy_session_failures++;
if ( splitter->cutover_inspector())
{
dce_http_server_stats.http_server_sessions++;
- dce_http_bind(flow, "dce_tcp");
+ dce_http_bind(flow, "dcerpc");
}
else
dce_http_server_stats.http_server_session_failures++;
IT_SERVICE,
(uint16_t)PktType::PDU,
nullptr, // buffers
- "dce_smb",
+ "netbios-ssn",
dce2_smb_init,
nullptr, // pterm
nullptr, // tinit
IT_SERVICE,
(uint16_t)PktType::PDU,
nullptr, // buffers
- "dce_tcp",
+ "dcerpc",
dce2_tcp_init,
nullptr, // pterm
nullptr, // tinit
IT_SERVICE,
(uint16_t)PktType::UDP,
nullptr, // buffers
- "dce_udp",
+ "dcerpc",
dce2_udp_init,
nullptr, // pterm
nullptr, // tinit
namespace HttpEnums
{
static const int MAX_OCTETS = 63780;
-static const int DATA_BLOCK_SIZE = 16384;
-static const int FINAL_BLOCK_SIZE = 24576;
static const int GZIP_BLOCK_SIZE = 2048;
static const int FINAL_GZIP_BLOCK_SIZE = 2304; // compromise value, too big causes gzip overruns
// too small leaves too many little end sections
{
case CMP_NONE:
{
- session_data->section_size_target[source_id] = DATA_BLOCK_SIZE + random_increment;
- session_data->section_size_max[source_id] = FINAL_BLOCK_SIZE;
+ unsigned max_pdu = SnortConfig::get_conf()->max_pdu;
+ session_data->section_size_target[source_id] = max_pdu + random_increment;
+ session_data->section_size_max[source_id] = max_pdu + (max_pdu >> 1);
break;
}
case CMP_GZIP:
// map between service and curse details
static vector<CurseDetails> curse_map
{
- // service_name alg is_tcp
- { "dce_udp", dce_udp_curse, false },
- { "dce_tcp", dce_tcp_curse, true },
- { "dce_smb", dce_smb_curse, true },
+ // name service alg is_tcp
+ { "dce_udp", "dcerpc", dce_udp_curse, false },
+ { "dce_tcp", "dcerpc", dce_tcp_curse, true },
+ { "dce_smb", "netbios-ssn", dce_smb_curse, true },
};
bool CurseBook::add_curse(const char* key)
{
for (const CurseDetails& curse : curse_map)
{
- if (curse.service == key)
+ if (curse.name == key)
{
if (curse.is_tcp)
tcp_curses.push_back(&curse);
struct CurseDetails
{
+ std::string name;
std::string service;
curse_alg alg;
bool is_tcp;
#include "config.h"
#endif
+#include <cassert>
+
#include "magic.h"
using namespace std;
return q;
++i;
}
+ return p->any;
}
- break;
+ return p->value.empty() ? nullptr : p;
}
return p;
}
const uint8_t* data, unsigned len, const MagicPage*& p) const
{
// FIXIT-L make configurable upper bound to limit globbing
- unsigned max = 16;
+ unsigned max = 64;
+ assert(p);
if ( len > max )
len = max;
p = find_spell(data, len, p, 0);
- if ( !p->value.empty() )
+ if ( p and !p->value.empty() )
return p->value.c_str();
return nullptr;
StreamSplitter* get_splitter(bool) override;
void reset(Wand&, bool tcp, bool c2s);
+ bool finished(Wand&);
bool cast_spell(Wand&, Flow*, const uint8_t*, unsigned);
bool spellbind(const MagicPage*&, Flow*, const uint8_t*, unsigned);
bool cursebind(vector<CurseServiceTracker>&, Flow*, const uint8_t*, unsigned);
if ( wizard->cast_spell(wand, f, data, len) )
++tstats.tcp_hits;
+ else if ( wizard->finished(wand) )
+ return ABORT;
+
+ // ostensibly continue but splitter will be swapped out upon hit
return SEARCH;
}
return false;
}
+bool Wizard::finished(Wand& w)
+{
+ if ( w.hex or w.spell )
+ return false;
+
+ // FIXTHIS-L how to know curses are done?
+ if ( !w.curse_tracker.empty() )
+ return false;
+
+ return true;
+}
+
//-------------------------------------------------------------------------
// api stuff
//-------------------------------------------------------------------------
{
Profile profile(streamSizePerfStats);
- if (!pkt->flow || !pkt->ptrs.tcph)
+ if ( !pkt->flow || pkt->flow->pkt_type != PktType::TCP )
return NO_MATCH;
- Flow* lwssn = (Flow*)pkt->flow;
- TcpSession* tcpssn = (TcpSession*)lwssn->session;
+ TcpSession* tcpssn = (TcpSession*)pkt->flow->session;
uint32_t client_size;
uint32_t server_size;
{ "overlap_limit", Parameter::PT_INT, "0:255", "0",
"maximum number of allowed overlapping segments per session" },
- { "max_pdu", Parameter::PT_INT, "1460:65535", "16384",
+ { "max_pdu", Parameter::PT_INT, "1460:32768", "16384",
"maximum reassembled PDU size" },
{ "policy", Parameter::PT_ENUM, TCP_POLICIES, "bsd",
}
else
{
- // remove data on SYN
listener->normalizer->trim_syn_payload(tsd);
-
- if (Normalize_GetMode(NORM_TCP_TRIM_SYN) != NORM_MODE_ON)
- {
- DebugMessage(DEBUG_STREAM_STATE, "Got data on SYN packet, not processing it\n");
- tel.set_tcp_event(EVENT_DATA_ON_SYN);
- pkt_action_mask |= ACTION_BAD_PKT;
- }
+ DebugMessage(DEBUG_STREAM_STATE, "Got data on SYN packet, not processing it\n");
+ tel.set_tcp_event(EVENT_DATA_ON_SYN);
+ pkt_action_mask |= ACTION_BAD_PKT;
}
}
void UserTracker::term()
{
if ( splitter )
+ {
delete splitter;
+ splitter = nullptr;
+ }
for ( auto* p : seg_list )
snort_free(p);
if (val < 1460)
{
- data_api.add_comment("option change: 'paf_max [0:63780]' --> 'max_pdu [1460:63780]'");
+ data_api.add_comment("option change: 'paf_max [0:63780]' --> 'max_pdu [1460:32768]'");
val = 1460;
}
+ else if (val > 32768)
+ {
+ data_api.add_comment("option change: 'paf_max [0:63780]' --> 'max_pdu [1460:32768]'");
+ val = 32768;
+ }
data_api.add_comment("stream_tcp.max_pdu = " + std::to_string(val));
#endif
#include "data/data_types/dt_rule.h"
#include "data/data_types/dt_table.h"
#include "helpers/s2l_util.h"
+#include "helpers/util_binder.h"
#include "init_state.h"
TableDelegation table_delegation =
bool Converter::convert_conf_mult_files = true;
bool Converter::bind_wizard = false;
-Converter::Converter()
- : table_api(&top_table_api, table_delegation),
+Converter::Converter() :
+ table_api(&top_table_api, table_delegation),
state(nullptr),
error(false),
multiline_state(false)
-{
-}
+{ }
Converter::~Converter()
{
if ( bind_wizard )
{
- // FIXIT-H this should create wizard = { } but need wizard = default_wizard
- //table_api.open_top_level_table("wizard");
- //table_api.close_table();
+ // add wizard = default_wizard before binder
data_api.set_variable("wizard", "default_wizard", false);
+ // add binding for wizard at bottom of table
auto& wiz = make_binder();
wiz.set_use_type("wizard");
+ wiz.set_priority(Binder::MAX_PRIORITY);
}
add_bindings();
void print_binding(bool should_print)
{ printed = !should_print; }
+ static const unsigned MAX_PRIORITY = UINT_MAX;
+
void set_priority(unsigned);
unsigned get_priority();
bool printed = false; // ensures that the binding is added once,
// by either the destructor or user
- unsigned priority = UINT_MAX;
+ unsigned priority = MAX_PRIORITY;
int when_ips_policy_id = -1;
std::string when_service;
if (!protos_set)
{
- const std::vector<std::string> default_protos = { "ftp", "telnet",
- "smtp", "nameserver", "dns", "http",
- "pop3", "sunrpc", "dcerpc",
- "netbios-ssn", "imap", "login", "shell",
- "mssql", "oracle", "cvs",
- "mysql" };
+ const std::vector<std::string> default_protos =
+ { "ftp", "telnet", "smtp", "nameserver", "dns", "http",
+ "pop3", "sunrpc", "dcerpc", "netbios-ssn", "imap",
+ "login", "shell", "mssql", "oracle", "cvs", "mysql" };
for (const std::string& s : default_protos)
{
pattern += pcre_str.substr(0, pattern_end + 1);
options = pcre_str.substr(pattern_end + 1, std::string::npos);
new_opts = "";
+ bool relative = false;
for (char c : options )
{
case 'A':
case 'E':
case 'G':
- case 'R':
case 'O':
case '"': // end of reg_ex
new_opts += c;
break;
+ case 'R':
+ relative = true;
+ new_opts += c;
+ break;
default:
{
std::string dlt_opt = "unknown option - '";
}
rule_api.add_option("pcre", pattern + new_opts);
- rule_api.set_curr_options_buffer(buffer);
+
+ if ( !relative )
+ rule_api.set_curr_options_buffer(buffer);
+
return set_next_rule_state(data_stream);
}
else if (dir == "client")
{
- rule_api.add_suboption("to_client");
+ rule_api.add_suboption("to_server");
static bool printed_client = false;
if (!printed_client)
{
printed_client = true;
- rule_api.add_comment("stream_size: option change: 'client'"
- " --> 'to_client'");
+ rule_api.add_comment("stream_size: option change: 'client' --> 'to_server'");
}
}
else if (dir == "server")
{
- rule_api.add_suboption("to_server");
+ rule_api.add_suboption("to_client");
static bool printed_server = false;
if (!printed_server)
{
printed_server = true;
- rule_api.add_comment("stream_size: option change: 'server'"
- " --> 'to_server'");
+ rule_api.add_comment("stream_size: option change: 'server' --> 'to_client'");
}
}
else
std::string value;
args = util::get_rule_option_args(data_stream);
+
+ size_t ltgt = args.find("<>");
+
+ if ( ltgt != std::string::npos )
+ {
+ rule_api.add_comment("urilen: option change: '<>' --> '<=>'");
+ args.insert(ltgt+1, "=");
+ }
std::istringstream arg_stream(args);
// if there are no arguments, the option had a colon before a semicolon.