/* icmp */ PROTO_BIT__ICMP,
/* tcp */ PROTO_BIT__TCP | PROTO_BIT__PDU,
/* udp */ PROTO_BIT__UDP,
- /* user */ PROTO_BIT__PDU
+ /* file */ PROTO_BIT__FILE | PROTO_BIT__PDU
};
return proto_bits[rtn_idx->snort_protocol_id] & p->proto_bits;
}
bool enabled() const
{ return (flags & ENABLED) != 0; }
- bool user_mode()
+ bool user_mode() const
{ return (flags & USER_MODE) != 0; }
+
+ bool any_src_port() const
+ { return (flags & ANY_SRC_PORT) != 0; }
+
+ bool any_dst_port() const
+ { return (flags & ANY_DST_PORT) != 0; }
+
+ bool any_any_port() const
+ { return any_src_port() and any_dst_port(); }
};
// one of these for each rule
class LenOption : public IpsOption
{
public:
- LenOption(const RangeCheck& c) :
+ LenOption(const RangeCheck& c, bool r) :
IpsOption(s_name, RULE_OPTION_TYPE_BUFFER_USE)
- { config = c; }
+ { config = c; relative = r; }
uint32_t hash() const override;
bool operator==(const IpsOption&) const override;
private:
RangeCheck config;
+ bool relative;
};
//-------------------------------------------------------------------------
return false;
const LenOption& rhs = (const LenOption&)ips;
- return ( config == rhs.config );
+ return ( config == rhs.config and relative == rhs.relative );
}
IpsOption::EvalStatus LenOption::eval(Cursor& c, Packet*)
{
RuleProfile profile(lenCheckPerfStats);
+ unsigned n = relative ? c.length() : c.size();
- if ( config.eval(c.length()) )
+ if ( config.eval(n) )
return MATCH;
return NO_MATCH;
static const Parameter s_params[] =
{
{ "~range", Parameter::PT_INTERVAL, RANGE, nullptr,
- "check that length of current buffer is in given range" },
+ "check that total length of current buffer is in given range" },
+
+ { "relative", Parameter::PT_IMPLIED, nullptr, nullptr,
+ "use remaining length (from current position) instead of total length" },
{ nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
};
public:
RangeCheck data;
+ bool relative = false;
};
bool LenModule::begin(const char*, int, SnortConfig*)
bool LenModule::set(const char*, Value& v, SnortConfig*)
{
- if ( !v.is("~range") )
+ if ( v.is("~range") )
+ return data.validate(v.get_string(), RANGE);
+
+ if ( v.is("relative") )
+ relative = true;
+
+ else
return false;
- return data.validate(v.get_string(), RANGE);
+ return true;
}
//-------------------------------------------------------------------------
static IpsOption* len_ctor(Module* p, OptTreeNode*)
{
LenModule* m = (LenModule*)p;
- return new LenOption(m->data);
+ return new LenOption(m->data, m->relative);
}
static void len_dtor(IpsOption* p)
add_service_to_otn(sc, otn, "pop3");
add_service_to_otn(sc, otn, "imap");
add_service_to_otn(sc, otn, "smtp");
- add_service_to_otn(sc, otn, "user");
+ add_service_to_otn(sc, otn, "file");
return;
}
prc = &svcCnt;
}
- /* Count rules with both src and dst specific ports */
- if (!(rtn->flags & RuleTreeNode::ANY_DST_PORT) && !(rtn->flags & RuleTreeNode::ANY_SRC_PORT))
- {
+ if ( !rtn->any_src_port() and !rtn->any_dst_port() )
prc->both++;
- }
/* If not an any-any rule test for port bleedover, if we are using a
* single rule group, don't bother */
- if (!fp->get_single_rule_group() &&
- (rtn->flags & (RuleTreeNode::ANY_DST_PORT|RuleTreeNode::ANY_SRC_PORT)) != (RuleTreeNode::ANY_DST_PORT|RuleTreeNode::ANY_SRC_PORT))
+ if ( !fp->get_single_rule_group() and !rtn->any_any_port() )
{
int dst_cnt = 0;
int src_cnt = 0;
- if (!(rtn->flags & RuleTreeNode::ANY_SRC_PORT))
+ if ( !rtn->any_src_port() )
{
src_cnt = PortObjectPortCount(rtn->src_portobject);
if (src_cnt >= fp->get_bleed_over_port_limit())
large_port_group = 1;
}
- if (!(rtn->flags & RuleTreeNode::ANY_DST_PORT))
+ if ( !rtn->any_dst_port() )
{
dst_cnt = PortObjectPortCount(rtn->dst_portobject);
if (dst_cnt >= fp->get_bleed_over_port_limit())
* any-any port rules...
* If we have an any-any rule or a large port group or
* were using a single rule group we make it an any-any rule. */
- if (((rtn->flags & (RuleTreeNode::ANY_DST_PORT|RuleTreeNode::ANY_SRC_PORT)) == (RuleTreeNode::ANY_DST_PORT|RuleTreeNode::ANY_SRC_PORT)) ||
- large_port_group || fp->get_single_rule_group())
+ if ( rtn->any_any_port() or large_port_group or fp->get_single_rule_group() )
{
if (snort_protocol_id == SNORT_PROTO_IP)
{
- /* Add the IP rules to the higher level app protocol groups, if they apply
- * to those protocols. All IP rules should have any-any port descriptors
- * and fall into this test. IP rules that are not tcp/udp/icmp go only into the
- * IP table */
- switch ( otn->snort_protocol_id )
- {
- case SNORT_PROTO_IP: /* Add to all ip proto any port tables */
- PortObjectAddRule(port_tables->icmp.any, otn->ruleIndex);
- icmpCnt.any++;
-
- PortObjectAddRule(port_tables->tcp.any, otn->ruleIndex);
- tcpCnt.any++;
-
- PortObjectAddRule(port_tables->udp.any, otn->ruleIndex);
- udpCnt.any++;
- break;
-
- case SNORT_PROTO_ICMP:
- PortObjectAddRule(port_tables->icmp.any, otn->ruleIndex);
- icmpCnt.any++;
- break;
-
- case SNORT_PROTO_TCP:
- PortObjectAddRule(port_tables->tcp.any, otn->ruleIndex);
- tcpCnt.any++;
- break;
-
- case SNORT_PROTO_UDP:
- PortObjectAddRule(port_tables->udp.any, otn->ruleIndex);
- udpCnt.any++;
- break;
-
- default:
- break;
- }
+ PortObjectAddRule(port_tables->icmp.any, otn->ruleIndex);
+ icmpCnt.any++;
+
+ PortObjectAddRule(port_tables->tcp.any, otn->ruleIndex);
+ tcpCnt.any++;
+
+ PortObjectAddRule(port_tables->udp.any, otn->ruleIndex);
+ udpCnt.any++;
}
/* For all protocols-add to the any any group */
PortObjectAddRule(aaObject, otn->ruleIndex);
}
/* add rule index to dst table if we have a specific dst port or port list */
- if (!(rtn->flags & RuleTreeNode::ANY_DST_PORT))
+ if ( !rtn->any_dst_port() )
{
prc->dst++;
}
/* add rule index to src table if we have a specific src port or port list */
- if (!(rtn->flags & RuleTreeNode::ANY_SRC_PORT))
+ if ( !rtn->any_src_port() )
{
prc->src++;
PortObject* pox = PortTableFindInputPortObjectPorts(srcTable, rtn->src_portobject);
else
{
- PortToFunc(rtn, (rtn->flags & RuleTreeNode::ANY_DST_PORT) ? 1 : 0, 0, DST);
- PortToFunc(rtn, (rtn->flags & RuleTreeNode::ANY_SRC_PORT) ? 1 : 0, 0, SRC);
+ PortToFunc(rtn, (rtn->any_dst_port() ? 1 : 0), 0, DST);
+ PortToFunc(rtn, (rtn->any_src_port() ? 1 : 0), 0, SRC);
AddrToFunc(rtn, SRC);
AddrToFunc(rtn, DST);
}
- if ( rtn->snort_protocol_id < SNORT_PROTO_MAX )
+ if ( rtn->snort_protocol_id < SNORT_PROTO_FILE )
AddRuleFuncToList(CheckProto, rtn);
+ else
+ rtn->flags |= RuleTreeNode::USER_MODE;
AddRuleFuncToList(RuleListEnd, rtn);
}
{
Profile profile(file_ssn_stats);
- p->flow->ssn_state.snort_protocol_id = SNORT_PROTO_USER;
+ p->flow->ssn_state.snort_protocol_id = SNORT_PROTO_FILE;
StreamFileConfig* c = get_file_cfg(p->flow->ssn_server);
FileFlows* file_flows = FileFlows::get_file_flows(p->flow);
ok = ( add("icmp") == SNORT_PROTO_ICMP ) and ok;
ok = ( add("tcp") == SNORT_PROTO_TCP ) and ok;
ok = ( add("udp") == SNORT_PROTO_UDP ) and ok;
- ok = ( add("user") == SNORT_PROTO_USER ) and ok;
+ ok = ( add("file") == SNORT_PROTO_FILE ) and ok;
assert(ok);
}
else
SNORT_PROTO_ICMP,
SNORT_PROTO_TCP,
SNORT_PROTO_UDP,
- SNORT_PROTO_USER,
+ SNORT_PROTO_FILE,
SNORT_PROTO_MAX
};
CHECK( is_service_protocol(t3) );
}
-// Builtin Protocols (ip, icmp, tcp, udp, user)
+// Builtin Protocols (ip, icmp, tcp, udp, file)
//
// Verify normal behaviour of the builtin protocols.
// 1. Check the builtin protocols match the hardcoded ID's
CHECK( is_builtin_protocol(udp) );
CHECK( !is_service_protocol(udp) );
- SnortProtocolId user = refs.add("user");
- CHECK( user == SNORT_PROTO_USER );
- CHECK( !is_network_protocol(user) );
- CHECK( is_builtin_protocol(user) );
- CHECK( is_service_protocol(user) );
+ SnortProtocolId file = refs.add("file");
+ CHECK( file == SNORT_PROTO_FILE );
+ CHECK( !is_network_protocol(file) );
+ CHECK( is_builtin_protocol(file) );
+ CHECK( is_service_protocol(file) );
}
// Find none