inline bool match_constraints(const snort::PacketConstraints& cs,
const snort::SfIp& sip, const snort::SfIp& dip, uint16_t sport,
- uint16_t dport)
+ uint16_t dport, uint32_t tenant_id)
{
using SetBits = snort::PacketConstraints::SetBits;
- return (!(cs.set_bits & SetBits::SRC_PORT) or (sport == cs.src_port)) and
+ bool res = (!(cs.set_bits & SetBits::SRC_PORT) or (sport == cs.src_port)) and
(!(cs.set_bits & SetBits::DST_PORT) or (dport == cs.dst_port)) and
(!(cs.set_bits & SetBits::SRC_IP) or (sip == cs.src_ip)) and
(!(cs.set_bits & SetBits::DST_IP) or (dip == cs.dst_ip));
+
+ if (res && tenant_id && !cs.tenants.empty())
+ {
+ auto it = std::find_if(cs.tenants.cbegin(), cs.tenants.cend(),
+ [tenant_id](uint32_t t){ return t == tenant_id; });
+
+ if (it == cs.tenants.cend())
+ return false;
+ }
+
+ return res;
}
} // namespace
using namespace snort;
+PacketConstraints::PacketConstraints(const PacketConstraints& other) :
+ ip_proto(other.ip_proto), src_port(other.src_port), dst_port(other.dst_port),
+ src_ip(other.src_ip), dst_ip(other.dst_ip), set_bits(other.set_bits),
+ match(other.match), tenants(other.tenants)
+{}
+
+PacketConstraints& PacketConstraints::operator=(const PacketConstraints& other)
+{
+ if (this == &other)
+ return *this;
+
+ ip_proto = other.ip_proto;
+ src_port = other.src_port;
+ dst_port = other.dst_port;
+ src_ip = other.src_ip;
+ dst_ip = other.dst_ip;
+ set_bits = other.set_bits;
+ match = other.match;
+ tenants = other.tenants;
+
+ return *this;
+}
+
bool PacketConstraints::operator==(const PacketConstraints& other) const
{
return set_bits == other.set_bits
and ( !(set_bits & SRC_PORT) or src_port == other.src_port )
and ( !(set_bits & DST_PORT) or dst_port == other.dst_port )
and ( !(set_bits & SRC_IP) or src_ip == other.src_ip )
- and ( !(set_bits & DST_IP) or dst_ip == other.dst_ip );
+ and ( !(set_bits & DST_IP) or dst_ip == other.dst_ip )
+ and ( tenants == other.tenants );
}
bool PacketConstraints::packet_match(const Packet& p) const
const auto sp = p.ptrs.sp;
const auto dp = p.ptrs.dp;
- return match_constraints(*this, sip, dip, sp, dp) or
- match_constraints(*this, dip, sip, dp, sp);
+ return match_constraints(*this, sip, dip, sp, dp, p.pkth->tenant_id) or
+ match_constraints(*this, dip, sip, dp, sp, p.pkth->tenant_id);
}
bool PacketConstraints::flow_match(const Flow& f) const
return false;
return match_constraints(*this, f.client_ip, f.server_ip, f.client_port,
- f.server_port);
+ f.server_port, f.tenant);
}
#ifdef UNIT_TEST
{
SECTION("all unset")
{
- const PacketConstraints exp = { IpProtocol::TCP, 10, 20,
- SfIp(), SfIp(), 0 };
- const PacketConstraints act = { IpProtocol::UDP, 30, 40,
- SfIp(), SfIp(), 0 };
+ const PacketConstraints exp = PacketConstraints(IpProtocol::TCP, 10, 20,
+ SfIp(), SfIp(), 0, true);
+ const PacketConstraints act = PacketConstraints(IpProtocol::UDP, 30, 40,
+ SfIp(), SfIp(), 0, true);
CHECK( exp == act );
}
{
const uint32_t ip1 = 0x01010101;
const uint32_t ip2 = 0x02020202;
- const PacketConstraints exp = { IpProtocol::PROTO_NOT_SET, 10, 20,
+ const PacketConstraints exp = PacketConstraints(IpProtocol::PROTO_NOT_SET, 10, 20,
SfIp(&ip1, AF_INET), SfIp(&ip2, AF_INET),
- (uint8_t)~PacketConstraints::SetBits::DST_IP };
- const PacketConstraints act = { IpProtocol::PROTO_NOT_SET, 10, 20,
+ (uint8_t)~PacketConstraints::SetBits::DST_IP, true);
+ const PacketConstraints act = PacketConstraints(IpProtocol::PROTO_NOT_SET, 10, 20,
SfIp(&ip1, AF_INET), SfIp(),
- (uint8_t)~PacketConstraints::SetBits::DST_IP };
+ (uint8_t)~PacketConstraints::SetBits::DST_IP, true);
CHECK( exp == act );
}
const uint32_t ip1 = 0x01010101;
const uint32_t ip2 = 0x02020202;
const uint32_t ip3 = 0x03030303;
- const PacketConstraints exp = { IpProtocol::PROTO_NOT_SET, 0, 0,
- SfIp(&ip1, AF_INET), SfIp(&ip2, AF_INET), (uint8_t)-1 };
- const PacketConstraints act = { IpProtocol::PROTO_NOT_SET, 0, 0,
- SfIp(&ip3, AF_INET), SfIp(&ip2, AF_INET), (uint8_t)-1};
+ const PacketConstraints exp = PacketConstraints(IpProtocol::PROTO_NOT_SET, 0, 0,
+ SfIp(&ip1, AF_INET), SfIp(&ip2, AF_INET), (uint8_t)-1, true);
+ const PacketConstraints act = PacketConstraints(IpProtocol::PROTO_NOT_SET, 0, 0,
+ SfIp(&ip3, AF_INET), SfIp(&ip2, AF_INET), (uint8_t)-1, true);
CHECK( !(exp == act) );
}
SECTION("equal")
{
+ std::vector<uint32_t> tenants1;
+ tenants1.push_back(100);
+ tenants1.push_back(200);
+
+ std::vector<uint32_t> tenants2;
+ tenants2.push_back(100);
+ tenants2.push_back(200);
+
const uint32_t ip1 = 0x01010101;
const uint32_t ip2 = 0x02020202;
- const PacketConstraints exp = { IpProtocol::PROTO_NOT_SET, 0, 0,
- SfIp(&ip1, AF_INET), SfIp(&ip2, AF_INET), (uint8_t)-1 };
- const PacketConstraints act = { IpProtocol::PROTO_NOT_SET, 0, 0,
- SfIp(&ip1, AF_INET), SfIp(&ip2, AF_INET), (uint8_t)-1 };
+ PacketConstraints exp = PacketConstraints(IpProtocol::PROTO_NOT_SET, 0, 0,
+ SfIp(&ip1, AF_INET), SfIp(&ip2, AF_INET), (uint8_t)-1, true);
+ exp.tenants = tenants1;
+ PacketConstraints act = PacketConstraints(IpProtocol::PROTO_NOT_SET, 0, 0,
+ SfIp(&ip1, AF_INET), SfIp(&ip2, AF_INET), (uint8_t)-1, true);
+ act.tenants = tenants2;
CHECK( exp == act );
}
}
cs.src_ip = sip;
cs.dst_ip = dip;
- CHECK( true == match_constraints(cs, sip, dip, sport, dport) );
+ std::vector<uint32_t> tenants;
+ tenants.push_back(100);
+ tenants.push_back(200);
+ cs.tenants = tenants;
+
+ CHECK( true == match_constraints(cs, sip, dip, sport, dport, 100) );
}
SECTION("backwards")
cs.src_ip = sip;
cs.dst_ip = dip;
- CHECK( false == match_constraints(cs, dip, sip, dport, sport) );
+ CHECK( false == match_constraints(cs, dip, sip, dport, sport, 0) );
}
SECTION("any ip")
cs.src_port = sport;
cs.dst_port = dport;
- CHECK( true == match_constraints(cs, sip, dip, sport, dport) );
+ CHECK( true == match_constraints(cs, sip, dip, sport, dport, 0) );
}
SECTION("any port")
cs.src_ip = sip;
cs.dst_ip = dip;
- CHECK( true == match_constraints(cs, sip, dip, sport, dport) );
+ CHECK( true == match_constraints(cs, sip, dip, sport, dport, 0) );
}
SECTION("any src")
cs.dst_port = dport;
cs.dst_ip = dip;
- CHECK( true == match_constraints(cs, sip, dip, sport, dport) );
+ CHECK( true == match_constraints(cs, sip, dip, sport, dport, 0) );
}
}
using namespace snort;
+static void StrToVector(const std::string& s,
+ char delim,
+ std::vector<uint32_t>& elems)
+{
+ std::istringstream ss(s);
+ std::string item;
+ while (std::getline(ss, item, delim))
+ {
+ size_t pos;
+ uint32_t i = std::stoul(item, &pos);
+ elems.push_back(i);
+ }
+}
+
static int enable(lua_State*);
static int disable(lua_State*);
{"src_port", Parameter::PT_INT, "0:65535", nullptr, "source port filter"},
{"dst_ip", Parameter::PT_STRING, nullptr, nullptr, "destination IP address filter"},
{"dst_port", Parameter::PT_INT, "0:65535", nullptr, "destination port filter"},
+ {"tenants", Parameter::PT_STRING, nullptr, nullptr, "tenants filter"},
{nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr}
};
class PacketTracerDebug : public AnalyzerCommand
{
public:
- PacketTracerDebug(PacketConstraints* cs);
+ PacketTracerDebug(const PacketConstraints* cs);
bool execute(Analyzer&, void**) override;
const char *stringify() override { return "PACKET_TRACER_DEBUG"; }
bool enable = false;
};
-PacketTracerDebug::PacketTracerDebug(PacketConstraints* cs)
+PacketTracerDebug::PacketTracerDebug(const PacketConstraints* cs)
{
if (cs)
{
- memcpy(&constraints, cs, sizeof(constraints));
+ constraints = *cs;
enable = true;
}
}
const char *dipstr = luaL_optstring(L, 4, nullptr);
int dport = luaL_optint(L, 5, 0);
+ const char *tenantsstr = luaL_optstring(L, 6, nullptr);
+
SfIp sip, dip;
sip.clear();
dip.clear();
PacketConstraints constraints = {};
+ if (tenantsstr)
+ StrToVector(tenantsstr, ',', constraints.tenants);
+
if (proto and (IpProtocol)proto < IpProtocol::PROTO_NOT_SET)
{
constraints.ip_proto = (IpProtocol)proto;
SECTION("ip_proto")
{
PROTO_OPTION(ip_proto, 6);
- const PacketConstraints exp = { IpProtocol::TCP, 0, 0,
- SfIp(), SfIp(), PacketConstraints::IP_PROTO };
+ const PacketConstraints exp = PacketConstraints(IpProtocol::TCP, 0, 0,
+ SfIp(), SfIp(), PacketConstraints::IP_PROTO, true);
CHECK(true == tp.set_constraints(ip_proto));
tp.finalize_constraints();
{
ADDR_OPTION(src_ip, "10.1.2.3");
const uint32_t exp_ip = 0x0302010a;
- const PacketConstraints exp = { IpProtocol::PROTO_NOT_SET, 0, 0,
- SfIp(&exp_ip, AF_INET), SfIp(), PacketConstraints::SRC_IP };
+ const PacketConstraints exp = PacketConstraints(IpProtocol::PROTO_NOT_SET, 0, 0,
+ SfIp(&exp_ip, AF_INET), SfIp(), PacketConstraints::SRC_IP, true);
CHECK(true == tp.set_constraints(src_ip));
tp.finalize_constraints();
SECTION("src_port")
{
- const PacketConstraints exp = { IpProtocol::PROTO_NOT_SET, 100, 0,
- SfIp(), SfIp(), PacketConstraints::SRC_PORT };
+ const PacketConstraints exp = PacketConstraints(IpProtocol::PROTO_NOT_SET, 100, 0,
+ SfIp(), SfIp(), PacketConstraints::SRC_PORT, true);
PORT_OPTION(src_port, 100);
CHECK(true == tp.set_constraints(src_port));
{
ADDR_OPTION(dst_ip, "10.3.2.1");
const uint32_t exp_ip = 0x0102030a;
- const PacketConstraints exp = { IpProtocol::PROTO_NOT_SET, 0, 0,
- SfIp(), SfIp(&exp_ip, AF_INET), PacketConstraints::DST_IP };
+ const PacketConstraints exp = PacketConstraints(IpProtocol::PROTO_NOT_SET, 0, 0,
+ SfIp(), SfIp(&exp_ip, AF_INET), PacketConstraints::DST_IP, true);
CHECK(true == tp.set_constraints(dst_ip));
tp.finalize_constraints();
SECTION("dst_port")
{
PORT_OPTION(dst_port, 200);
- const PacketConstraints exp = { IpProtocol::PROTO_NOT_SET, 0, 200,
- SfIp(), SfIp(), PacketConstraints::DST_PORT };
+ const PacketConstraints exp = PacketConstraints(IpProtocol::PROTO_NOT_SET, 0, 200,
+ SfIp(), SfIp(), PacketConstraints::DST_PORT, true);
CHECK(true == tp.set_constraints(dst_port));
tp.finalize_constraints();