typedef std::bitset<65536> PortBitSet;
typedef std::bitset<4096> VlanBitSet;
typedef std::bitset<256> ByteBitSet;
+typedef std::bitset<64> ZoneBitSet;
#endif
}
}
+void Value::get_bits(ZoneBitSet& list) const
+{
+ list.reset();
+ std::size_t len = str.size();
+ assert(len == list.size());
+
+ for ( std::size_t n = 0; n < len; ++n )
+ {
+ if ( str[n] == '1' )
+ list.set(n);
+ }
+}
+
void Value::get_bits(VlanBitSet& list) const
{
list.reset();
void get_bits(PortBitSet&) const;
void get_bits(VlanBitSet&) const;
void get_bits(ByteBitSet&) const;
+ void get_bits(ZoneBitSet&) const;
void lower()
{ std::transform(str.begin(), str.end(), str.begin(), ::tolower); }
{ "dst_ports", Parameter::PT_BIT_LIST, "65535", nullptr,
"list of destination ports" },
- { "src_zone", Parameter::PT_INT, "0:max31", nullptr,
+ { "zones", Parameter::PT_BIT_LIST, "63", nullptr,
+ "zones" },
+
+ { "src_zone", Parameter::PT_BIT_LIST, "63", nullptr,
"source zone" },
- { "dst_zone", Parameter::PT_INT, "0:max31", nullptr,
+ { "dst_zone", Parameter::PT_BIT_LIST, "63", nullptr,
"destination zone" },
{ "role", Parameter::PT_ENUM, "client | server | any", "any",
work->when.split_ports = true;
}
+ else if ( v.is("zones") )
+ {
+ v.get_bits(work->when.src_zones);
+ unsplit_zones = true;
+ }
else if ( v.is("src_zone") )
- work->when.src_zone = v.get_int32();
-
+ {
+ v.get_bits(work->when.src_zones);
+ work->when.split_zones = true;
+ }
else if ( v.is("dst_zone") )
- work->when.dst_zone = v.get_int32();
+ {
+ v.get_bits(work->when.dst_zones);
+ work->when.split_zones = true;
+ }
else if ( v.is("role") )
work->when.role = (BindWhen::Role)v.get_uint8();
work = new Binding;
unsplit_nets = false;
unsplit_ports = false;
+ unsplit_zones = false;
use_name_count = 0;
use_type_count = 0;
}
static void split_ports_warning()
{ ParseWarning(WARN_CONF, "src_ports and dst_ports override ports"); }
+static void split_zones_warning()
+{ ParseWarning(WARN_CONF, "src_zones and dst_zones override zones"); }
+
bool BinderModule::end(const char* fqn, int idx, SnortConfig* sc)
{
if ( idx && !strcmp(fqn, BIND_NAME) )
if ( unsplit_ports && work->when.split_ports )
split_ports_warning();
+ if ( unsplit_zones && work->when.split_zones )
+ split_zones_warning();
+
if ( use_type_count > 1 || use_name_count > 1 )
file_name_type_error();
std::vector<Binding*> bindings;
bool unsplit_nets;
bool unsplit_ports;
+ bool unsplit_zones;
unsigned use_name_count;
unsigned use_type_count;
when.src_ports.set();
when.dst_ports.set();
+ when.split_zones = false;
+ when.src_zones.set();
+ when.dst_zones.set();
+
when.protos = PROTO_BIT__ANY_TYPE;
when.vlans.set();
when.ifaces.reset();
- when.src_zone = DAQ_PKTHDR_UNKNOWN;
- when.dst_zone = DAQ_PKTHDR_UNKNOWN;
-
when.ips_id = 0;
when.ips_id_user = 0;
when.role = BindWhen::BR_EITHER;
{ return when_val.test(traffic_val); });
}
-inline Binding::DirResult Binding::check_zone(
- const Packet* p, const Binding::DirResult dr) const
+inline bool Binding::check_zone(const Packet* p) const
{
- if ( !p )
+ if ( when.split_zones or !p )
+ return true;
+
+ if (p->pkth->egress_group == DAQ_PKTHDR_UNKNOWN or
+ p->pkth->ingress_group == DAQ_PKTHDR_UNKNOWN)
+ return true;
+
+ assert(((unsigned)p->pkth->ingress_group) < when.src_zones.size());
+ assert(((unsigned)p->pkth->egress_group) < when.dst_zones.size());
+
+ if (when.src_zones.test((unsigned)p->pkth->ingress_group) or
+ when.dst_zones.test((unsigned)p->pkth->egress_group))
+ return true;
+ return false;
+}
+
+inline Binding::DirResult Binding::check_split_zone(const Packet* p, const Binding::DirResult dr) const
+{
+ if ( !when.split_zones )
return dr;
- return directional_match(when.src_zone, when.dst_zone,
- p->pkth->ingress_group, p->pkth->egress_group, dr,
- [](int32_t when_val, int32_t zone)
- { return when_val == DAQ_PKTHDR_UNKNOWN or when_val == zone; });
+ int src_zone;
+ int dst_zone;
+
+ if ( p )
+ {
+ src_zone = p->pkth->ingress_group;
+ dst_zone = p->pkth->egress_group;
+ }
+ else
+ return dr;
+
+ return directional_match(when.src_zones, when.dst_zones, src_zone, dst_zone, dr,
+ [](const ZoneBitSet& when_val, int traffic_val)
+ { return traffic_val == DAQ_PKTHDR_UNKNOWN ? true : when_val.test(traffic_val); });
}
bool Binding::check_all(const Flow* flow, Packet* p) const
if ( dir == Binding::DR_NO_MATCH )
return false;
+ dir = check_split_zone(p, dir);
+ if ( dir == Binding::DR_NO_MATCH )
+ return false;
+
if ( !check_service(flow) )
return false;
- dir = check_zone(p, dir);
- if ( dir == Binding::DR_NO_MATCH )
+ if ( !check_zone(p) )
return false;
return true;
PortBitSet src_ports;
PortBitSet dst_ports;
- int32_t src_zone;
- int32_t dst_zone;
+ bool split_zones;
+ ZoneBitSet src_zones;
+ ZoneBitSet dst_zones;
};
struct BindUse
bool check_proto(const snort::Flow*) const;
bool check_port(const snort::Flow*) const;
DirResult check_split_port(const snort::Flow*, const snort::Packet*, const DirResult) const;
+ bool check_zone(const snort::Packet*) const;
+ DirResult check_split_zone(const snort::Packet*, const DirResult) const;
bool check_service(const snort::Flow*) const;
- DirResult check_zone(const snort::Packet*, const DirResult) const;
};
#endif
for ( const auto& p : ports )
table_api.add_list("ports", p);
- if ( has_src_zone() )
- table_api.add_option("src_zone", std::stoi(when_src_zone));
+ for ( const auto& p : when_src_zone )
+ table_api.add_list("src_zone", p);
- if ( has_dst_zone() )
- table_api.add_option("dst_zone", std::stoi(when_dst_zone));
+ for ( const auto& p : when_dst_zone )
+ table_api.add_list("dst_zone", p);
+
+ for ( const auto& p : zones )
+ table_api.add_list("zones", p);
if ( has_proto() )
table_api.add_option("proto", when_proto);
{ ports.push_back(port); }
void Binder::set_when_src_zone(const std::string& zone)
-{ when_src_zone = zone; }
+{ when_src_zone.push_back(zone); }
void Binder::set_when_dst_zone(const std::string& zone)
-{ when_dst_zone = zone; }
+{ when_dst_zone.push_back(zone); }
+
+void Binder::add_when_zone(const std::string& zone)
+{ zones.push_back(zone); }
void Binder::clear_ports()
{ ports.clear(); }
binders.back()->add_when_port("a");
if ( i & (1 << 11) )
- binders.back()->set_when_proto("a");
+ binders.back()->add_when_zone("a");
if ( i & (1 << 12) )
+ binders.back()->set_when_proto("a");
+
+ if ( i & (1 << 13) )
binders.back()->set_when_role("a");
}
void add_when_src_net(const std::string&);
void add_when_dst_net(const std::string&);
void add_when_port(const std::string&);
+ void add_when_zone(const std::string&);
void add_when_src_port(const std::string&);
void add_when_dst_port(const std::string&);
void set_when_src_zone(const std::string&);
std::vector<std::string> ports;
std::vector<std::string> src_ports;
std::vector<std::string> dst_ports;
- std::string when_src_zone;
- std::string when_dst_zone;
+ std::vector<std::string> when_src_zone;
+ std::vector<std::string> when_dst_zone;
+ std::vector<std::string> zones;
std::string use_type;
std::string use_name;