using namespace snort;
THREAD_LOCAL AppIdDebug* appidDebug = nullptr;
-void AppIdDebug::activate(const uint32_t* ip1, const uint32_t* ip2, uint16_t port1, uint16_t port2, IpProtocol protocol,
- uint16_t address_space_id, const AppIdSession* session, bool log_all_sessions)
+void AppIdDebug::activate(const uint32_t* ip1, const uint32_t* ip2, uint16_t port1,
+ uint16_t port2, IpProtocol protocol, const int version, uint16_t address_space_id,
+ const AppIdSession* session, bool log_all_sessions)
{
- if ((log_all_sessions) ||
- (enabled && (info.protocol == IpProtocol::PROTO_NOT_SET || info.protocol == protocol) &&
- (((!info.sport || info.sport == port1) && (!info.dport || info.dport == port2) &&
- (!info.sip_flag || memcmp(&info.sip, ip1, sizeof(info.sip)) == 0) &&
- (!info.dip_flag || memcmp(&info.dip, ip2, sizeof(info.dip)) == 0)) ||
- ((!info.sport || info.sport == port2) && (!info.dport || info.dport == port1) &&
- (!info.sip_flag || memcmp(&info.sip, ip2, sizeof(info.sip)) == 0) &&
- (!info.dip_flag || memcmp(&info.dip, ip1, sizeof(info.dip)) == 0)))))
+ if (!( log_all_sessions or
+ ( info.proto_match(protocol) and
+ ( (info.port_match(port1, port2) and info.ip_match(ip1, ip2)) or
+ (info.port_match(port2, port1) and info.ip_match(ip2, ip1)) ) ) ))
{
- active = true;
- int af;
- const struct in6_addr* sip;
- const struct in6_addr* dip;
- unsigned offset;
- uint16_t sport = 0;
- uint16_t dport = 0;
- char sipstr[INET6_ADDRSTRLEN];
- char dipstr[INET6_ADDRSTRLEN];
+ active = false;
+ return;
+ }
+ active = true;
+ int af = (version == 6)? AF_INET6 : AF_INET;
+ const ip::snort_in6_addr* sip;
+ const ip::snort_in6_addr* dip;
+ uint16_t sport = 0;
+ uint16_t dport = 0;
+ char sipstr[INET6_ADDRSTRLEN];
+ char dipstr[INET6_ADDRSTRLEN];
- if (!session)
- {
- sip = (const struct in6_addr*)ip1;
- dip = (const struct in6_addr*)ip2;
- sport = port1;
- dport = port2;
- }
- else if (session->common.initiator_port)
- {
- if (session->common.initiator_port == port1)
- {
- sip = (const struct in6_addr*)ip1;
- dip = (const struct in6_addr*)ip2;
- sport = port1;
- dport = port2;
- }
- else
- {
- sip = (const struct in6_addr*)ip2;
- dip = (const struct in6_addr*)ip1;
- sport = port2;
- dport = port1;
- }
- }
- else if (memcmp(session->common.initiator_ip.get_ip6_ptr(), ip1, sizeof(struct in6_addr)) == 0)
+ if (!session)
+ {
+ sip = (const ip::snort_in6_addr*)ip1;
+ dip = (const ip::snort_in6_addr*)ip2;
+ sport = port1;
+ dport = port2;
+ }
+ else if (session->common.initiator_port)
+ {
+ if (session->common.initiator_port == port1)
{
- sip = (const struct in6_addr*)ip1;
- dip = (const struct in6_addr*)ip2;
+ sip = (const ip::snort_in6_addr*)ip1;
+ dip = (const ip::snort_in6_addr*)ip2;
sport = port1;
dport = port2;
}
else
{
- sip = (const struct in6_addr*)ip2;
- dip = (const struct in6_addr*)ip1;
+ sip = (const ip::snort_in6_addr*)ip2;
+ dip = (const ip::snort_in6_addr*)ip1;
sport = port2;
dport = port1;
}
- sipstr[0] = 0;
- if (sip->s6_addr32[0] || sip->s6_addr32[1] || sip->s6_addr16[4] || (sip->s6_addr16[5] && sip->s6_addr16[5] != 0xFFFF))
- {
- af = AF_INET6;
- offset = 0;
- }
- else
- {
- af = AF_INET;
- offset = 12;
- }
- inet_ntop(af, &sip->s6_addr[offset], sipstr, sizeof(sipstr));
- dipstr[0] = 0;
- if (dip->s6_addr32[0] || dip->s6_addr32[1] || dip->s6_addr16[4] || (dip->s6_addr16[5] && dip->s6_addr16[5] != 0xFFFF))
- {
- af = AF_INET6;
- offset = 0;
- }
- else
- {
- af = AF_INET;
- offset = 12;
- }
- inet_ntop(af, &dip->s6_addr[offset], dipstr, sizeof(dipstr));
-
- snprintf(debug_session, sizeof(debug_session), "%s %hu -> %s %hu %hhu AS=%hu ID=%u",
- sipstr, sport, dipstr, dport, static_cast<uint8_t>(protocol), address_space_id, instance_id);
+ }
+ else if (memcmp(session->common.initiator_ip.get_ip6_ptr(),
+ ip1, sizeof(ip::snort_in6_addr)) == 0)
+ {
+ sip = (const ip::snort_in6_addr*)ip1;
+ dip = (const ip::snort_in6_addr*)ip2;
+ sport = port1;
+ dport = port2;
}
else
- active = false;
+ {
+ sip = (const ip::snort_in6_addr*)ip2;
+ dip = (const ip::snort_in6_addr*)ip1;
+ sport = port2;
+ dport = port1;
+ }
+ snort_inet_ntop(af, &sip->u6_addr32[(af == AF_INET)? 3 : 0], sipstr, sizeof(sipstr));
+ snort_inet_ntop(af, &dip->u6_addr32[(af == AF_INET)? 3 : 0], dipstr, sizeof(dipstr));
+
+ snprintf(debug_session, sizeof(debug_session), "%s %hu -> %s %hu %hhu AS=%hu ID=%u",
+ sipstr, sport, dipstr, dport, static_cast<uint8_t>(protocol),
+ address_space_id, get_instance_id());
}
void AppIdDebug::activate(const Flow *flow, const AppIdSession* session, bool log_all_sessions)
return;
}
const FlowKey* key = flow->key;
+
+ // FIXIT-H FlowKey does not yet support different address families for src and dst IPs
+ // (e.g., IPv4 src and IPv6 dst, or vice-versa). Once it is supported, we need to pass
+ // two key->version here to create the proper debug_session string.
activate(key->ip_l, key->ip_h, key->port_l, key->port_h, (IpProtocol)(key->ip_protocol),
- key->addressSpaceId, session, log_all_sessions);
+ key->version, key->addressSpaceId, session, log_all_sessions);
}
-void AppIdDebug::set_constraints(const char *desc, const AppIdDebugSessionConstraints* constraints)
+void AppIdDebug::set_constraints(const char *desc,
+ const AppIdDebugSessionConstraints* constraints)
{
if (constraints)
{
- int saf;
- int daf;
char sipstr[INET6_ADDRSTRLEN];
char dipstr[INET6_ADDRSTRLEN];
- memcpy(&info, constraints, sizeof(info));
- if (!info.sip.s6_addr32[0] && !info.sip.s6_addr32[1] && !info.sip.s6_addr16[4] &&
- info.sip.s6_addr16[5] == 0xFFFF)
- {
- saf = AF_INET;
- }
- else
- saf = AF_INET6;
- if (!info.dip.s6_addr32[0] && !info.dip.s6_addr32[1] && !info.dip.s6_addr16[4] &&
- info.dip.s6_addr16[5] == 0xFFFF)
- {
- daf = AF_INET;
- }
- else
- daf = AF_INET6;
- sipstr[0] = 0;
- inet_ntop(saf, saf == AF_INET ? &info.sip.s6_addr32[3] : info.sip.s6_addr32, sipstr, sizeof(sipstr));
- dipstr[0] = 0;
- inet_ntop(daf, daf == AF_INET ? &info.dip.s6_addr32[3] : info.dip.s6_addr32, dipstr, sizeof(dipstr));
+ info.set(*constraints);
+ info.sip.ntop(sipstr, sizeof(sipstr));
+ info.dip.ntop(dipstr, sizeof(dipstr));
LogMessage("Debugging %s with %s-%hu and %s-%hu %hhu\n", desc,
- sipstr, info.sport, dipstr, info.dport, static_cast<uint8_t>(info.protocol));
+ sipstr, info.sport, dipstr, info.dport, static_cast<uint8_t>(info.protocol));
enabled = true;
}
{
LogMessage("Debugging %s disabled\n", desc);
enabled = false;
+ active = false;
}
}
#ifndef APPID_DEBUG_H
#define APPID_DEBUG_H
-#include <netinet/in.h>
+#include <string.h>
+#include "protocols/ipv6.h"
#include "protocols/protocol_ids.h"
#include "main/thread.h"
+#include "sfip/sf_ip.h"
class AppIdSession;
namespace snort
struct AppIdDebugSessionConstraints
{
- struct in6_addr sip;
- int sip_flag;
- struct in6_addr dip;
- int dip_flag;
+ snort::SfIp sip;
+ int sip_flag = 0;
+ snort::SfIp dip;
+ int dip_flag = 0;
uint16_t sport;
uint16_t dport;
IpProtocol protocol = IpProtocol::PROTO_NOT_SET;
+ bool proto_match(IpProtocol& proto)
+ {
+ return (protocol == IpProtocol::PROTO_NOT_SET or protocol == proto);
+ }
+ bool port_match(uint16_t p1, uint16_t p2)
+ {
+ return (!sport or sport == p1) and (!dport or dport == p2);
+ }
+ bool ip_match(const uint32_t* ip1, const uint32_t* ip2)
+ {
+ return
+ ((!sip_flag or !memcmp(sip.get_ip6_ptr(), ip1, sizeof(snort::ip::snort_in6_addr))) and
+ (!dip_flag or !memcmp(dip.get_ip6_ptr(), ip2, sizeof(snort::ip::snort_in6_addr))));
+ }
+ void set(const AppIdDebugSessionConstraints& src);
};
+inline void AppIdDebugSessionConstraints::set(const AppIdDebugSessionConstraints& src)
+{
+ if ((sip_flag = src.sip_flag))
+ sip.set(src.sip);
+ if ((dip_flag = src.dip_flag))
+ dip.set(src.dip);
+ sport = src.sport;
+ dport = src.dport;
+ protocol = src.protocol;
+}
+
class AppIdDebug
{
public:
- AppIdDebug(unsigned instance_id) : instance_id(instance_id) { }
+ AppIdDebug() = default;
- void activate(const uint32_t* ip1, const uint32_t* ip2, uint16_t port1, uint16_t port2, IpProtocol protocol,
- uint16_t address_space_id, const AppIdSession* session, bool log_all_sessions);
+ void activate(const uint32_t* ip1, const uint32_t* ip2, uint16_t port1, uint16_t port2,
+ IpProtocol protocol, const int version, uint16_t address_space_id,
+ const AppIdSession* session, bool log_all_sessions);
void activate(const snort::Flow *flow, const AppIdSession* session, bool log_all_sessions);
void set_constraints(const char *desc, const AppIdDebugSessionConstraints* constraints);
bool enabled = false;
bool active = false;
AppIdDebugSessionConstraints info = { };
- unsigned instance_id;
char debug_session[APPID_DEBUG_SESSION_ID_SIZE];
};
return;
}
- appidDebug->activate(p->flow, asd, inspector.get_appid_config()->mod_config->log_all_sessions);
+ if (appidDebug->is_enabled())
+ appidDebug->activate(p->flow, asd, inspector.get_appid_config()->mod_config->log_all_sessions);
if ( is_packet_ignored(asd, p, direction) )
return;
http_matchers->finalize();
ssl_detector_process_patterns();
dns_host_detector_process_patterns();
+ appidDebug = new AppIdDebug();
+ if (active_config->mod_config and active_config->mod_config->log_all_sessions)
+ appidDebug->set_enabled(true);
}
void AppIdInspector::tterm()
LuaDetectorManager::terminate();
AppIdDiscovery::release_plugins();
delete HttpPatternMatchers::get_instance();
+ delete appidDebug;
+ appidDebug = nullptr;
}
void AppIdInspector::eval(Packet* p)
static void appid_inspector_tinit()
{
- uint32_t snort_instance = get_instance_id();
- appidDebug = new AppIdDebug(snort_instance);
-
AppIdPegCounts::init_pegs();
}
static void appid_inspector_tterm()
{
AppIdPegCounts::cleanup_pegs();
-
- delete appidDebug;
- appidDebug = nullptr;
}
static Inspector* appid_inspector_ctor(Module* m)
{
if (cs)
{
- memcpy(&constraints, cs, sizeof(constraints));
+ constraints.set(*cs);
enable = true;
}
}
const char* dipstr = luaL_optstring(L, 4, nullptr);
int dport = luaL_optint(L, 5, 0);
- SfIp sip, dip;
+ AppIdDebugSessionConstraints constraints = { };
if (sipstr)
{
- if (sip.set(sipstr) != SFIP_SUCCESS)
+ if (constraints.sip.set(sipstr) != SFIP_SUCCESS)
LogMessage("Invalid source IP address provided: %s\n", sipstr);
+ else if (constraints.sip.is_set())
+ constraints.sip_flag = true;
}
if (dipstr)
{
- if (dip.set(dipstr) != SFIP_SUCCESS)
+ if (constraints.dip.set(dipstr) != SFIP_SUCCESS)
LogMessage("Invalid destination IP address provided: %s\n", dipstr);
+ else if (constraints.dip.is_set())
+ constraints.dip_flag = true;
}
- AppIdDebugSessionConstraints constraints = { };
-
if (proto)
constraints.protocol = (IpProtocol) proto;
- if (sip.is_set())
- {
- memcpy(&constraints.sip, sip.get_ip6_ptr(), sizeof(constraints.sip));
- constraints.sip_flag = true;
- }
-
- if (dip.is_set())
- {
- memcpy(&constraints.dip, dip.get_ip6_ptr(), sizeof(constraints.dip));
- constraints.dip_flag = true;
- }
-
constraints.sport = sport;
constraints.dport = dport;
// Mocks
+unsigned get_instance_id() { return 3; }
+
class AppIdInspector
{
public:
// Utility functions
static void SetConstraints(IpProtocol protocol, // use IpProtocol::PROTO_NOT_SET for "any"
- const char* sipstr, uint16_t sport,
- const char* dipstr, uint16_t dport,
- AppIdDebugSessionConstraints& constraints)
+ const char* sipstr, uint16_t sport, const char* dipstr, uint16_t dport,
+ AppIdDebugSessionConstraints& constraints)
{
SfIp sip, dip;
if (sipstr)
- sip.set(sipstr);
- if (dipstr)
- dip.set(dipstr);
-
- constraints.protocol = protocol;
- if (sip.is_set())
{
- memcpy(&constraints.sip, sip.get_ip6_ptr(), sizeof(constraints.sip));
- constraints.sip_flag = true;
+ constraints.sip.set(sipstr);
+ if (constraints.sip.is_set())
+ constraints.sip_flag = true;
}
- if (dip.is_set())
+ if (dipstr)
{
- memcpy(&constraints.dip, dip.get_ip6_ptr(), sizeof(constraints.dip));
- constraints.dip_flag = true;
+ constraints.dip.set(dipstr);
+ if (constraints.dip.is_set())
+ constraints.dip_flag = true;
}
+
+ constraints.protocol = protocol;
constraints.sport = sport;
constraints.dport = dport;
}
{
void setup() override
{
- appidDebug = new AppIdDebug(3);
+ appidDebug = new AppIdDebug();
}
void teardown() override
session.common.initiator_ip = sip;
// activate()
appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
- protocol, address_space_id, &session, false);
+ protocol, 4, address_space_id, &session, false);
CHECK_EQUAL(appidDebug->is_active(), true);
// get_debug_session()
session.common.initiator_ip = dip;
// activate()
appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
- protocol, address_space_id, &session, false);
+ protocol, 4, address_space_id, &session, false);
CHECK_EQUAL(appidDebug->is_active(), true);
// get_debug_session()
{
// set_constraints()
AppIdDebugSessionConstraints constraints = { };
- SetConstraints(IpProtocol::UDP, "2001:db8:85a3::8a2e:370:7334", 1234, "2001:db8:85a3::8a2e:370:7335", 443, constraints);
+ SetConstraints(IpProtocol::UDP, "2001:db8:85a3::8a2e:370:7334", 1234,
+ "2001:db8:85a3::8a2e:370:7335", 443, constraints);
appidDebug->set_constraints("appid", &constraints);
CHECK_EQUAL(appidDebug->is_enabled(), true);
session.common.initiator_ip = sip;
// activate()
appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
- protocol, address_space_id, &session, false);
+ protocol, 6, address_space_id, &session, false);
CHECK_EQUAL(appidDebug->is_active(), true);
// get_debug_session()
- const char* str = "2001:db8:85a3::8a2e:370:7334 1234 -> 2001:db8:85a3::8a2e:370:7335 443 17 AS=100 ID=3";
+ const char* str = "2001:0db8:85a3:0000:0000:8a2e:0370:7334 1234 -> "
+ "2001:0db8:85a3:0000:0000:8a2e:0370:7335 443 17 AS=100 ID=3";
CHECK_TRUE(strcmp(appidDebug->get_debug_session(), str) == 0);
}
session.common.initiator_ip = sip;
// activate()
appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
- protocol, address_space_id, &session, false);
+ protocol, 4, address_space_id, &session, false);
CHECK_EQUAL(appidDebug->is_active(), true);
// get_debug_session()
session.common.initiator_ip = dip;
// activate()
appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
- protocol, address_space_id, &session, false);
+ protocol, 4, address_space_id, &session, false);
CHECK_EQUAL(appidDebug->is_active(), true);
// get_debug_session()
uint16_t address_space_id = 0;
// activate()
appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
- protocol, address_space_id,
- nullptr, false); // null session
+ protocol, 4, address_space_id, nullptr, false); // null session
CHECK_EQUAL(appidDebug->is_active(), false); // not active
}
session.common.initiator_ip = sip;
// activate()
appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
- protocol, address_space_id, &session, false);
+ protocol, 4, address_space_id, &session, false);
CHECK_EQUAL(appidDebug->is_active(), false); // not active (no match)
}
session.common.initiator_ip = sip;
// activate()
appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
- protocol, address_space_id, &session, false);
+ protocol, 4, address_space_id, &session, false);
CHECK_EQUAL(appidDebug->is_active(), true);
// get_debug_session()
session.common.initiator_ip = sip;
// activate()
appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
- protocol, address_space_id, &session, false);
+ protocol, 4, address_space_id, &session, false);
CHECK_EQUAL(appidDebug->is_active(), true);
// get_debug_session()
session.common.initiator_ip = sip;
// activate()
appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
- protocol, address_space_id, &session, false);
+ protocol, 4, address_space_id, &session, false);
CHECK_EQUAL(appidDebug->is_active(), true);
// get_debug_session()
session.common.initiator_ip = sip;
// activate()
appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
- protocol, address_space_id, &session, false);
+ protocol, 4, address_space_id, &session, false);
CHECK_EQUAL(appidDebug->is_active(), true);
// get_debug_session()
CHECK_TRUE(strcmp(appidDebug->get_debug_session(), str) == 0);
}
-// Clear constraints (disables it so it won't activate).
-TEST(appid_debug, clear_constraints_test)
-{
- // set_constraints()
- appidDebug->set_constraints("appid", nullptr); // clear constraints
- CHECK_EQUAL(appidDebug->is_enabled(), false); // disabled
-
- SfIp sip;
- SfIp dip;
- AppIdInspector inspector;
- AppIdSession session(IpProtocol::PROTO_NOT_SET, nullptr, 0, inspector);
- // This packet...
- sip.set("10.1.2.3");
- dip.set("10.9.8.7");
- uint16_t sport = 48620;
- uint16_t dport = 80;
- IpProtocol protocol = IpProtocol::TCP;
- uint16_t address_space_id = 0;
- // The session...
- session.common.initiator_port = sport;
- session.common.initiator_ip = sip;
- // activate()
- appidDebug->activate(sip.get_ip6_ptr(), dip.get_ip6_ptr(), sport, dport,
- protocol, address_space_id, &session, false);
- CHECK_EQUAL(appidDebug->is_active(), false); // won't activate (since disabled)
-}
-
int main(int argc, char** argv)
{
int rc = CommandLineTestRunner::RunAllTests(argc, argv);