class ServiceAppDescriptor : public ApplicationDescriptor
{
public:
- ServiceAppDescriptor() = default;
+ ServiceAppDescriptor()
+ {
+ service_ip.clear();
+ }
+
~ServiceAppDescriptor() override
{
AppIdServiceSubtype* tmp_subtype = subtype;
delete tmp_subtype;
tmp_subtype = subtype;
}
+ service_ip.clear();
+ service_port = 0;
+ service_group = DAQ_PKTHDR_UNKNOWN;
}
void update_stats(AppId id, bool increment = true) override;
return subtype;
}
+ void set_service_ip(const snort::SfIp& ip)
+ {
+ service_ip = ip;
+ }
+
+ const snort::SfIp& get_service_ip() const
+ {
+ return service_ip;
+ }
+
+ bool is_service_ip_set() const
+ {
+ return service_ip.is_set();
+ }
+
+ void set_service_port(uint16_t port)
+ {
+ service_port = port;
+ }
+
+ uint16_t get_service_port() const
+ {
+ return service_port;
+ }
+
+ void set_service_group(int16_t group)
+ {
+ service_group = group;
+ }
+
+ int16_t get_service_group() const
+ {
+ return service_group;
+ }
+
private:
AppId port_service_id = APP_ID_NONE;
bool deferred = false;
using ApplicationDescriptor::set_id;
std::string my_vendor;
AppIdServiceSubtype* subtype = nullptr;
+ snort::SfIp service_ip;
+ uint16_t service_port = 0;
+ int16_t service_group = DAQ_PKTHDR_UNKNOWN;
};
class ClientAppDescriptor : public ApplicationDescriptor
asd->set_session_flags(APPID_SESSION_SYN_RST);
if (asd->is_service_ip_set())
- std::tie(ip, port, group) = asd->get_service_info();
+ std::tie(ip, port, group) = asd->get_server_info();
else
{
ip = p->ptrs.ip_api.get_src();
odp_ctxt_version(odp_ctxt.get_version()),
tp_appid_ctxt(pkt_thread_tp_appid_ctxt)
{
- service_ip.clear();
-
appid_stats.total_sessions++;
}
APPID_SESSION_UDP_REVERSED | APPID_SESSION_MID |
APPID_SESSION_OOO) and flow)
{
+ const SfIp& svc_ip = api.service.get_service_ip();
ServiceDiscoveryState* sds =
- AppIdServiceState::get(&service_ip, protocol, service_port, service_group,
- asid, is_decrypted());
+ AppIdServiceState::get(&svc_ip, protocol, api.service.get_service_port(),
+ api.service.get_service_group(), asid, is_decrypted());
if (sds)
{
- if (flow->server_ip.fast_eq6(service_ip))
+ if (flow->server_ip.fast_eq6(svc_ip))
sds->set_service_id_failed(*this, &flow->client_ip,
STATE_ID_INCONCLUSIVE_SERVICE_WEIGHT);
else
{
api.service.reset();
tp_app_id = APP_ID_NONE;
- service_ip.clear();
- service_port = 0;
service_disco_state = APPID_DISCO_STATE_NONE;
service_detector = nullptr;
service_search_state = SESSION_SERVICE_SEARCH_STATE::START;
api.service.set_id(APP_ID_NONE, odp_ctxt);
api.service.set_port_service_id(APP_ID_NONE);
api.service.reset();
- service_ip.clear();
- service_port = 0;
service_disco_state = APPID_DISCO_STATE_NONE;
service_detector = nullptr;
free_flow_data_by_mask(APPID_SESSION_DATA_SERVICE_MODSTATE_BIT);
if (service_detector)
return -1;
service_detector = service;
- service_port = port;
+ set_service_port(port);
return 0;
}
{
if (direction == APP_ID_FROM_INITIATOR)
{
- service_ip = *p->ptrs.ip_api.get_dst();
- service_port = p->ptrs.dp;
+ set_service_ip(*p->ptrs.ip_api.get_dst());
+ set_service_port(p->ptrs.dp);
}
else
{
- service_ip = *p->ptrs.ip_api.get_src();
- service_port = p->ptrs.sp;
+ set_service_ip(*p->ptrs.ip_api.get_src());
+ set_service_port(p->ptrs.sp);
}
service_disco_state = APPID_DISCO_STATE_FINISHED;
api.initiator_ip = ip;
}
+ void set_service_ip(const snort::SfIp& ip)
+ {
+ api.service.set_service_ip(ip);
+ }
+
+ void set_service_port(uint16_t port)
+ {
+ api.service.set_service_port(port);
+ }
+
void set_tls_host(const AppidChangeBits& change_bits)
{
if (tsession and change_bits[APPID_TLSHOST_BIT])
return tp_appid_ctxt;
}
- void set_service_info(const snort::SfIp& ip, uint16_t port, int16_t group = DAQ_PKTHDR_UNKNOWN)
+ void set_server_info(const snort::SfIp& ip, uint16_t port, int16_t group = DAQ_PKTHDR_UNKNOWN)
{
- service_ip = ip;
- service_port = port;
- service_group = group;
+ api.service.set_service_ip(ip);
+ api.service.set_service_port(port);
+ api.service.set_service_group(group);
}
- std::tuple<const snort::SfIp*, uint16_t, int16_t> get_service_info() const
+ std::tuple<const snort::SfIp*, uint16_t, int16_t> get_server_info() const
{
- return std::make_tuple(&service_ip, service_port, service_group);
+ return std::make_tuple(&api.service.get_service_ip(), api.service.get_service_port(),
+ api.service.get_service_group());
}
uint16_t get_service_port() const
{
- return service_port;
+ return api.service.get_service_port();
}
bool is_service_ip_set() const
{
- return service_ip.is_set();
+ return api.service.is_service_ip_set();
}
void set_user_logged_in()
AppId tp_app_id = APP_ID_NONE;
AppId tp_payload_app_id = APP_ID_NONE;
- snort::SfIp service_ip;
- uint16_t service_port = 0;
- int16_t service_group = DAQ_PKTHDR_UNKNOWN;
-
uint16_t my_inferred_svcs_ver = 0;
snort::AppIdSessionApi& api;
static uint16_t inferred_svcs_ver;
return &initiator_ip;
}
+const SfIp& AppIdSessionApi::get_service_ip() const
+{
+ return service.get_service_ip();
+}
+
+uint16_t AppIdSessionApi::get_service_port() const
+{
+ return service.get_service_port();
+}
+
const AppIdDnsSession* AppIdSessionApi::get_dns_session() const
{
return dsession;
const char* get_client_info(uint32_t stream_index = 0) const;
uint64_t get_appid_session_attribute(uint64_t flag) const;
const SfIp* get_initiator_ip() const;
+ const SfIp& get_service_ip() const;
+ uint16_t get_service_port() const;
const AppIdDnsSession* get_dns_session() const;
const AppIdHttpSession* get_http_session(uint32_t stream_index = 0) const;
const char* get_tls_host() const;
if (!asd.is_service_ip_set())
{
uint16_t port = asd.get_service_port();
- asd.set_service_info(*(pkt->ptrs.ip_api.get_src()),
+ asd.set_server_info(*(pkt->ptrs.ip_api.get_src()),
port ? port : pkt->ptrs.sp, pkt->get_ingress_group());
}
return APPID_SUCCESS;
}
}
- asd.set_service_info(*ip, port, group);
+ asd.set_server_info(*ip, port, group);
ServiceDiscoveryState* sds = AppIdServiceState::add(ip, asd.protocol, port,
group, asd.asid, asd.is_decrypted());
/* Get packet info. */
auto proto = asd.protocol;
if ( asd.is_service_ip_set() )
- std::tie(ip, port, group) = asd.get_service_info();
+ std::tie(ip, port, group) = asd.get_server_info();
else
{
if ( dir == APP_ID_FROM_RESPONDER )
port = p->ptrs.dp;
group = p->get_egress_group();
}
- asd.set_service_info(*ip, port, group);
+ asd.set_server_info(*ip, port, group);
}
if ( asd.service_search_state == SESSION_SERVICE_SEARCH_STATE::START )
sds->set_service(service);
sds->set_reset_time(0);
if ( !asd.is_service_ip_set() )
- asd.set_service_info(*ip, port, group);
+ asd.set_server_info(*ip, port, group);
return APPID_SUCCESS;
}
port = pkt->ptrs.sp;
if (!asd.is_service_ip_set())
- asd.set_service_info(*ip, port, group);
+ asd.set_server_info(*ip, port, group);
if ( !sds )
{
protocol(proto), api(*(new AppIdSessionApi(this, *ip))), odp_ctxt(stub_odp_ctxt)
{
odp_ctxt_version = odp_ctxt.get_version();
- service_port = APPID_UT_SERVICE_PORT;
+ set_service_port(APPID_UT_SERVICE_PORT);
AppidChangeBits change_bits;
set_client_user(APPID_UT_ID, APPID_UT_USERNAME, change_bits);
tsession = new TlsSession;
- service_ip.pton(AF_INET, APPID_UT_SERVICE_IP_ADDR);
+ SfIp svc_ip;
+ svc_ip.pton(AF_INET, APPID_UT_SERVICE_IP_ADDR);
+ set_service_ip(svc_ip);
api.initiator_ip.pton(AF_INET, APPID_UT_INITIATOR_IP_ADDR);
netbios_name = snort_strdup(APPID_UT_NETBIOS_NAME);
APPID_SESSION_SERVICE_DETECTED);
asd.clear_session_flags(APPID_SESSION_CONTINUE);
if (direction == APP_ID_FROM_INITIATOR)
- asd.set_service_info(*(p->ptrs.ip_api.get_dst()), p->ptrs.dp,
+ asd.set_server_info(*(p->ptrs.ip_api.get_dst()), p->ptrs.dp,
p->get_egress_group());
else
- asd.set_service_info(*(p->ptrs.ip_api.get_src()), p->ptrs.sp,
+ asd.set_server_info(*(p->ptrs.ip_api.get_src()), p->ptrs.sp,
p->get_ingress_group());
}
}
const auto& appid_session_api = appid_event->get_appid_session_api();
AppId service = appid_session_api.get_service_app_id();
bool newservice = false;
+ bool is_client = false;
+ uint16_t port = p->flow->server_port;
if ( appid_change_bits[APPID_SERVICE_BIT] or appid_change_bits[APPID_CLIENT_BIT] or
appid_change_bits[APPID_PAYLOAD_BIT] )
appid_session_api.get_app_id(nullptr, &client, &payload, nullptr, nullptr);
if ( appid_change_bits[APPID_SERVICE_BIT] and service > APP_ID_NONE )
+ {
+ if (service == APP_ID_DHCP)
+ {
+ const SfIp& service_ip = appid_session_api.get_service_ip();
+ if (p->flow->client_ip.fast_eq6(service_ip))
+ is_client = true;
+ port = appid_session_api.get_service_port();
+ }
newservice = discover_service(p, rna_flow, proto, conf, logger,
- p->flow->server_port, service);
+ port, service, is_client);
+ }
if ( appid_change_bits[APPID_CLIENT_BIT] and client > APP_ID_NONE
and service > APP_ID_NONE )
const char* version;
const AppIdServiceSubtype* subtype;
appid_session_api.get_service_info(vendor, version, subtype);
- update_service_info(p, rna_flow, proto, vendor, version, logger, conf, service);
+ update_service_info(p, rna_flow, proto, port, vendor, version, logger, conf, service, is_client);
}
else if ( newservice and appid_change_bits[APPID_SERVICE_BIT]
and service > APP_ID_NONE )
{
- update_service_info(p, rna_flow, proto, nullptr, nullptr, logger, conf, service);
+ update_service_info(p, rna_flow, proto, port, nullptr, nullptr, logger, conf, service, is_client);
}
if ( conf->enable_banner_grab and p->is_from_server() and
}
bool RnaAppDiscovery::discover_service(const Packet* p, RNAFlow* rna_flow, IpProtocol proto,
- RnaConfig* conf, RnaLogger& logger, uint16_t port, AppId service)
+ RnaConfig* conf, RnaLogger& logger, uint16_t port, AppId service, bool is_client)
{
- RnaTracker htp = get_server_rna_tracker(p, rna_flow);
+ RnaTracker htp;
+ SfIp ip = p->flow->server_ip;
+ if (!is_client)
+ htp = get_server_rna_tracker(p, rna_flow);
+ else
+ {
+ htp = get_client_rna_tracker(p, rna_flow);
+ ip = p->flow->client_ip;
+ }
if ( !htp or !htp->is_visible() )
return false;
{
if ( proto == IpProtocol::TCP )
logger.log(RNA_EVENT_NEW, NEW_TCP_SERVICE, p, &htp,
- (const struct in6_addr*) p->flow->server_ip.get_ip6_ptr(),
- htp->get_last_seen_mac(), &ha);
+ (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(), &ha);
else
logger.log(RNA_EVENT_NEW, NEW_UDP_SERVICE, p, &htp,
- (const struct in6_addr*) p->flow->server_ip.get_ip6_ptr(),
- htp->get_last_seen_mac(), &ha);
+ (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(), &ha);
ha.hits = 0; // hit count is reset after logs are written
htp->update_service(ha);
crt->get_last_seen_mac(), &hc);
}
-void RnaAppDiscovery::update_service_info(const Packet* p, RNAFlow* rna_flow, IpProtocol proto,
- const char* vendor, const char* version, RnaLogger& logger, RnaConfig* conf, AppId service)
+void RnaAppDiscovery::update_service_info(const Packet* p, RNAFlow* rna_flow, IpProtocol proto, uint16_t port,
+ const char* vendor, const char* version, RnaLogger& logger, RnaConfig* conf, AppId service, bool is_client)
{
- RnaTracker htp = get_server_rna_tracker(p, rna_flow);
+ RnaTracker htp;
+ SfIp ip = p->flow->server_ip;
+ if (!is_client)
+ htp = get_server_rna_tracker(p, rna_flow);
+ else
+ {
+ htp = get_client_rna_tracker(p, rna_flow);
+ ip = p->flow->client_ip;
+ }
+
if ( !htp or !htp->is_visible() )
return;
htp->update_last_seen();
- HostApplication ha(p->flow->server_port, proto, service, false);
+ HostApplication ha(port, proto, service, false);
if ( !htp->update_service_info(ha, vendor, version, conf->max_host_service_info) )
return;
if ( proto == IpProtocol::TCP )
logger.log(RNA_EVENT_CHANGE, CHANGE_TCP_SERVICE_INFO, p, &htp,
- (const struct in6_addr*) p->flow->server_ip.get_ip6_ptr(), htp->get_last_seen_mac(),
- &ha);
+ (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(), &ha);
else
logger.log(RNA_EVENT_CHANGE, CHANGE_UDP_SERVICE_INFO, p, &htp,
- (const struct in6_addr*) p->flow->server_ip.get_ip6_ptr(), htp->get_last_seen_mac(),
- &ha);
+ (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(), &ha);
ha.hits = 0;
htp->update_service(ha);
static void process(AppidEvent*, DiscoveryFilter&, RnaConfig*, RnaLogger&);
static bool discover_service(const snort::Packet*, RNAFlow*, IpProtocol, RnaConfig*,
- RnaLogger&, uint16_t, AppId service = APP_ID_NONE);
+ RnaLogger&, uint16_t, AppId service = APP_ID_NONE, bool is_client = false);
static void discover_payload(const snort::Packet*, RNAFlow*, IpProtocol, RnaConfig*,
RnaLogger&, AppId service, AppId payload, AppId client);
static void discover_banner(const snort::Packet*, RNAFlow*, IpProtocol, RnaLogger&, AppId);
private:
- static void update_service_info(const snort::Packet*, RNAFlow*, IpProtocol,
- const char* vendor, const char* version, RnaLogger&, RnaConfig*, AppId service);
+ static void update_service_info(const snort::Packet*, RNAFlow*, IpProtocol, uint16_t,
+ const char* vendor, const char* version, RnaLogger&, RnaConfig*, AppId service, bool is_client = false);
static void analyze_user_agent_fingerprint(const snort::Packet*, RNAFlow*, const char* host,
const char* uagent, RnaLogger&, snort::UaFpProcessor&);