diff --git a/src/app-layer-dns-common.c b/src/app-layer-dns-common.c index 46925b9994..28ee04df2a 100644 --- a/src/app-layer-dns-common.c +++ b/src/app-layer-dns-common.c @@ -78,10 +78,11 @@ void *DNSGetTx(void *alstate, uint64_t tx_id) { DNSTransaction *tx = NULL; TAILQ_FOREACH(tx, &dns_state->tx_list, next) { - SCLogDebug("tx->tx_num %u, tx_id %"PRIu64, tx->tx_num, tx_id); + SCLogDebug("tx->tx_num %u, tx_id %"PRIu64, tx->tx_num, (tx_id+1)); if ((tx_id+1) != tx->tx_num) continue; + SCLogDebug("returning tx %p", tx); return tx; } diff --git a/src/app-layer-protos.c b/src/app-layer-protos.c index 7e8abeae23..bbeb103a86 100644 --- a/src/app-layer-protos.c +++ b/src/app-layer-protos.c @@ -49,6 +49,7 @@ const char *TmModuleAlprotoToString(int proto) CASE_CODE (ALPROTO_DCERPC); CASE_CODE (ALPROTO_DCERPC_UDP); + CASE_CODE (ALPROTO_DNS); CASE_CODE (ALPROTO_DNS_UDP); CASE_CODE (ALPROTO_DNS_TCP); diff --git a/src/detect-dns-query.c b/src/detect-dns-query.c index 38acf1eaa6..49aebfa9fa 100644 --- a/src/detect-dns-query.c +++ b/src/detect-dns-query.c @@ -95,6 +95,41 @@ static int DetectDnsQuerySetup(DetectEngineCtx *de_ctx, Signature *s, char *str) ALPROTO_DNS, NULL); } +/** + * \brief Run the pattern matcher against the queries + * + * \param f locked flow + * \param dns_state initialized dns state + * + * \warning Make sure the flow/state is locked + * \todo what should we return? Just the fact that we matched? + */ +uint32_t DetectDnsQueryInspectMpm(DetectEngineThreadCtx *det_ctx, Flow *f, + DNSState *dns_state, uint8_t flags, void *txv, + uint64_t tx_id) +{ + SCEnter(); + + DNSTransaction *tx = (DNSTransaction *)txv; + DNSQueryEntry *query = NULL; + uint8_t *buffer; + uint16_t buffer_len; + uint32_t cnt = 0; + + TAILQ_FOREACH(query, &tx->query_list, next) { + SCLogDebug("tx %p query %p", tx, query); + + buffer = (uint8_t *)((uint8_t *)query + sizeof(DNSQueryEntry)); + buffer_len = query->len; + + cnt += DnsQueryPatternSearch(det_ctx, + buffer, buffer_len, + flags); + } + + SCReturnUInt(cnt); +} + #ifdef UNITTESTS /** \test simple google.com query matching */ static int DetectDnsQueryTest01(void) { diff --git a/src/detect-dns-query.h b/src/detect-dns-query.h index c894b878db..7560523128 100644 --- a/src/detect-dns-query.h +++ b/src/detect-dns-query.h @@ -24,6 +24,10 @@ #ifndef __DETECT_DNS_QUERY_H__ #define __DETECT_DNS_QUERY_H__ +#include "app-layer-dns-common.h" + void DetectDnsQueryRegister (void); +uint32_t DetectDnsQueryInspectMpm(DetectEngineThreadCtx *det_ctx, Flow *f, + DNSState *dns_state, uint8_t flags, void *txv, uint64_t tx_id); #endif /* __DETECT_DNS_QUERY_H__ */ diff --git a/src/detect-engine-analyzer.c b/src/detect-engine-analyzer.c index 0fcee2aac9..7840562b24 100644 --- a/src/detect-engine-analyzer.c +++ b/src/detect-engine-analyzer.c @@ -430,6 +430,8 @@ static void EngineAnalysisRulesPrintFP(Signature *s) fprintf(rule_engine_analysis_FD, "http stat msg content"); else if (list_type == DETECT_SM_LIST_HUADMATCH) fprintf(rule_engine_analysis_FD, "http user agent content"); + else if (list_type == DETECT_SM_LIST_DNSQUERY_MATCH) + fprintf(rule_engine_analysis_FD, "dns query name content"); fprintf(rule_engine_analysis_FD, "\" buffer.\n"); diff --git a/src/detect-engine-dns.c b/src/detect-engine-dns.c index e904838557..946f7412fe 100644 --- a/src/detect-engine-dns.c +++ b/src/detect-engine-dns.c @@ -70,6 +70,8 @@ int DetectEngineInspectDnsQueryName(ThreadVars *tv, uint16_t buffer_len; int r = 0; + SCLogDebug("start"); + TAILQ_FOREACH(query, &tx->query_list, next) { SCLogDebug("tx %p query %p", tx, query); det_ctx->discontinue_matching = 0; diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index 62e405e9c7..bc125ffadf 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -689,6 +689,36 @@ uint32_t HttpHRHPatternSearch(DetectEngineThreadCtx *det_ctx, SCReturnUInt(ret); } +/** + * \brief DNS query match -- searches for one pattern per signature. + * + * \param det_ctx Detection engine thread ctx. + * \param hrh Buffer to inspect. + * \param hrh_len buffer length. + * \param flags Flags + * + * \retval ret Number of matches. + */ +uint32_t DnsQueryPatternSearch(DetectEngineThreadCtx *det_ctx, + uint8_t *buffer, uint32_t buffer_len, + uint8_t flags) +{ + SCEnter(); + + uint32_t ret; + + if (flags & STREAM_TOSERVER) { + if (det_ctx->sgh->mpm_dnsquery_ctx_ts == NULL) + SCReturnUInt(0); + + ret = mpm_table[det_ctx->sgh->mpm_dnsquery_ctx_ts->mpm_type]. + Search(det_ctx->sgh->mpm_dnsquery_ctx_ts, &det_ctx->mtcu, + &det_ctx->pmq, buffer, buffer_len); + } + + SCReturnUInt(ret); +} + /** \brief Pattern match -- searches for only one pattern per signature. * * \param det_ctx detection engine thread ctx @@ -1109,6 +1139,15 @@ void PatternMatchDestroyGroup(SigGroupHead *sh) { } } + /* dns query */ + if (sh->mpm_dnsquery_ctx_ts != NULL) { + if (!sh->mpm_dnsquery_ctx_ts->global) { + mpm_table[sh->mpm_dnsquery_ctx_ts->mpm_type].DestroyCtx(sh->mpm_dnsquery_ctx_ts); + SCFree(sh->mpm_dnsquery_ctx_ts); + } + sh->mpm_dnsquery_ctx_ts = NULL; + } + return; } @@ -1510,6 +1549,7 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx, case DETECT_SM_LIST_HUADMATCH: case DETECT_SM_LIST_HHHDMATCH: case DETECT_SM_LIST_HRHHDMATCH: + case DETECT_SM_LIST_DNSQUERY_MATCH: { MpmCtx *mpm_ctx_ts = NULL; MpmCtx *mpm_ctx_tc = NULL; @@ -1635,6 +1675,15 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx, sig_flags |= SIG_FLAG_MPM_HTTP; if (cd->flags & DETECT_CONTENT_NEGATED) sig_flags |= SIG_FLAG_MPM_HTTP_NEG; + } else if (sm_list == DETECT_SM_LIST_DNSQUERY_MATCH) { + if (s->flags & SIG_FLAG_TOSERVER) + mpm_ctx_ts = sgh->mpm_dnsquery_ctx_ts; + if (s->flags & SIG_FLAG_TOCLIENT) + mpm_ctx_tc = NULL; + sgh_flags = SIG_GROUP_HEAD_MPM_DNSQUERY; + sig_flags |= SIG_FLAG_MPM_DNS; + if (cd->flags & DETECT_CONTENT_NEGATED) + sig_flags |= SIG_FLAG_MPM_DNS_NEG; } if (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) { @@ -2028,6 +2077,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) uint32_t has_co_hrhhd = 0; //uint32_t cnt = 0; uint32_t sig = 0; + /* sgh has at least one sig with dns_query */ + int has_co_dnsquery = 0; /* see if this head has content and/or uricontent */ for (sig = 0; sig < sh->sig_cnt; sig++) { @@ -2093,6 +2144,10 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) if (s->sm_lists[DETECT_SM_LIST_HRHHDMATCH] != NULL) { has_co_hrhhd = 1; } + + if (s->sm_lists[DETECT_SM_LIST_DNSQUERY_MATCH] != NULL) { + has_co_dnsquery = 1; + } } /* intialize contexes */ @@ -2376,6 +2431,24 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) MpmInitCtx(sh->mpm_hrhhd_ctx_tc, de_ctx->mpm_matcher, -1); } + if (has_co_dnsquery) { + if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { + sh->mpm_dnsquery_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_dnsquery, 0); + } else { + sh->mpm_dnsquery_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0); + } + if (sh->mpm_dnsquery_ctx_ts == NULL) { + SCLogDebug("sh->mpm_hrhhd_ctx == NULL. This should never happen"); + exit(EXIT_FAILURE); + } + +#ifndef __SC_CUDA_SUPPORT__ + MpmInitCtx(sh->mpm_dnsquery_ctx_ts, de_ctx->mpm_matcher, -1); +#else + MpmInitCtx(sh->mpm_dnsquery_ctx_ts, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle); +#endif + } + if (has_co_packet || has_co_stream || has_co_uri || @@ -2390,7 +2463,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) has_co_hrud || has_co_huad || has_co_hhhd || - has_co_hrhhd) { + has_co_hrhhd || + has_co_dnsquery) { PatternMatchPreparePopulateMpm(de_ctx, sh); @@ -2779,6 +2853,17 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) } } } + if (sh->mpm_dnsquery_ctx_ts != NULL) { + if (sh->mpm_dnsquery_ctx_ts->pattern_cnt == 0) { + MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_dnsquery_ctx_ts); + sh->mpm_dnsquery_ctx_ts = NULL; + } else { + if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { + if (mpm_table[sh->mpm_dnsquery_ctx_ts->mpm_type].Prepare != NULL) + mpm_table[sh->mpm_dnsquery_ctx_ts->mpm_type].Prepare(sh->mpm_dnsquery_ctx_ts); + } + } + } //} /* if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) */ } else { MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_other_ctx); @@ -2814,6 +2899,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) sh->mpm_hhhd_ctx_ts = NULL; MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hrhhd_ctx_ts); sh->mpm_hrhhd_ctx_ts = NULL; + MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_dnsquery_ctx_ts); + sh->mpm_dnsquery_ctx_ts = NULL; MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_tcp_ctx_tc); sh->mpm_proto_tcp_ctx_tc = NULL; diff --git a/src/detect-engine-mpm.h b/src/detect-engine-mpm.h index 7fc385d100..fdfd70472c 100644 --- a/src/detect-engine-mpm.h +++ b/src/detect-engine-mpm.h @@ -51,6 +51,7 @@ uint32_t HttpStatCodePatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, uint32_t HttpUAPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, uint8_t); uint32_t HttpHHPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, uint8_t); uint32_t HttpHRHPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, uint8_t); +uint32_t DnsQueryPatternSearch(DetectEngineThreadCtx *det_ctx, uint8_t *buffer, uint32_t buffer_len, uint8_t flags); void PacketPatternCleanup(ThreadVars *, DetectEngineThreadCtx *); void StreamPatternCleanup(ThreadVars *t, DetectEngineThreadCtx *det_ctx, StreamMsg *smsg); diff --git a/src/detect-engine-state.c b/src/detect-engine-state.c index 738cd7645e..f3c630b1dc 100644 --- a/src/detect-engine-state.c +++ b/src/detect-engine-state.c @@ -275,7 +275,10 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, } tx_id = AppLayerTransactionGetInspectId(f, flags); + SCLogDebug("tx_id %"PRIu64, tx_id); total_txs = AppLayerGetTxCnt(alproto, alstate); + SCLogDebug("total_txs %"PRIu64, total_txs); + for (; tx_id < total_txs; tx_id++) { total_matches = 0; tx = AppLayerGetTx(alproto, alstate, tx_id); diff --git a/src/detect-engine.c b/src/detect-engine.c index 72727d77c7..1dd22c6cfb 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -222,6 +222,22 @@ void DetectEngineRegisterAppInspectionEngines(void) DE_STATE_FLAG_DNSQUERY_INSPECT, 0, DetectEngineInspectDnsQueryName }, + /* specifically for UDP, register again + * allows us to use the alproto w/o translation + * in the detection engine */ + { ALPROTO_DNS_UDP, + DETECT_SM_LIST_DNSQUERY_MATCH, + DE_STATE_FLAG_DNSQUERY_INSPECT, + DE_STATE_FLAG_DNSQUERY_INSPECT, + 0, + DetectEngineInspectDnsQueryName }, + /* dito for TCP */ + { ALPROTO_DNS_TCP, + DETECT_SM_LIST_DNSQUERY_MATCH, + DE_STATE_FLAG_DNSQUERY_INSPECT, + DE_STATE_FLAG_DNSQUERY_INSPECT, + 0, + DetectEngineInspectDnsQueryName }, }; struct tmp_t data_toclient[] = { diff --git a/src/detect-fast-pattern.c b/src/detect-fast-pattern.c index 6131028739..87240ba0d0 100644 --- a/src/detect-fast-pattern.c +++ b/src/detect-fast-pattern.c @@ -134,6 +134,8 @@ void SupportFastPatternForSigMatchTypes(void) SupportFastPatternForSigMatchList(DETECT_SM_LIST_HSCDMATCH, 3); SupportFastPatternForSigMatchList(DETECT_SM_LIST_HSMDMATCH, 3); + SupportFastPatternForSigMatchList(DETECT_SM_LIST_DNSQUERY_MATCH, 2); + #if 0 SCFPSupportSMList *tmp = sm_fp_support_smlist_list; while (tmp != NULL) { @@ -221,14 +223,16 @@ static int DetectFastPatternSetup(DetectEngineCtx *de_ctx, Signature *s, char *a s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH] == NULL && s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH] == NULL && s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH] == NULL && - s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH] == NULL) { + s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH] == NULL && + s->sm_lists_tail[DETECT_SM_LIST_DNSQUERY_MATCH] == NULL) { SCLogWarning(SC_WARN_COMPATIBILITY, "fast_pattern found inside the " "rule, without a preceding content based keyword. " "Currently we provide fast_pattern support for content, " "uricontent, http_client_body, http_server_body, http_header, " "http_raw_header, http_method, http_cookie, " "http_raw_uri, http_stat_msg, http_stat_code, " - "http_user_agent, http_host or http_raw_host option"); + "http_user_agent, http_host, http_raw_host or " + "dns_query option"); return -1; } @@ -246,7 +250,8 @@ static int DetectFastPatternSetup(DetectEngineCtx *de_ctx, Signature *s, char *a DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]); + DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], + DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_DNSQUERY_MATCH]); if (pm == NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "fast_pattern found inside " "the rule, without a content context. Please use a " diff --git a/src/detect.c b/src/detect.c index 2845722977..a54698f742 100644 --- a/src/detect.c +++ b/src/detect.c @@ -46,6 +46,7 @@ #include "detect-engine-payload.h" #include "detect-engine-dcepayload.h" #include "detect-engine-uri.h" +#include "detect-dns-query.h" #include "detect-engine-state.h" #include "detect-engine-analyzer.h" @@ -527,7 +528,7 @@ static inline int SigMatchSignaturesBuildMatchArrayAddSignature(DetectEngineThre } /* check for a pattern match of the one pattern in this sig. */ - if (likely(s->flags & (SIG_FLAG_MPM_PACKET|SIG_FLAG_MPM_STREAM|SIG_FLAG_MPM_HTTP))) + if (likely(s->flags & (SIG_FLAG_MPM_PACKET|SIG_FLAG_MPM_STREAM|SIG_FLAG_MPM_HTTP|SIG_FLAG_MPM_DNS))) { /* filter out sigs that want pattern matches, but * have no matches */ @@ -546,6 +547,10 @@ static inline int SigMatchSignaturesBuildMatchArrayAddSignature(DetectEngineThre if (!(s->flags & SIG_FLAG_MPM_HTTP_NEG)) { return 0; } + } else if (s->flags & SIG_FLAG_MPM_DNS) { + if (!(s->flags & SIG_FLAG_MPM_DNS_NEG)) { + return 0; + } } } } @@ -1077,6 +1082,27 @@ static inline void DetectMpmPrefilter(DetectEngineCtx *de_ctx, FLOWLOCK_UNLOCK(p->flow); } + /* all dns based mpms */ + else if (alproto == ALPROTO_DNS_TCP && alstate != NULL) { + if (p->flowflags & FLOW_PKT_TOSERVER) { + if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_DNSQUERY) { + FLOWLOCK_RDLOCK(p->flow); + + uint64_t idx = AppLayerTransactionGetInspectId(p->flow, flags); + uint64_t total_txs = AppLayerGetTxCnt(alproto, alstate); + for (; idx < total_txs; idx++) { + void *tx = AppLayerGetTx(alproto, alstate, idx); + if (tx == NULL) + continue; + + PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_DNSQUERY); + DetectDnsQueryInspectMpm(det_ctx, p->flow, alstate, flags, tx, idx); + PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_DNSQUERY); + } + FLOWLOCK_UNLOCK(p->flow); + } + } + } if (smsg != NULL && (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_STREAM)) { PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_STREAM); @@ -1110,6 +1136,28 @@ static inline void DetectMpmPrefilter(DetectEngineCtx *de_ctx, *sms_runflags |= SMS_USED_PM; } } + + /* UDP DNS inspection is independent of est or not */ + if (alproto == ALPROTO_DNS_UDP && alstate != NULL) { + if (p->flowflags & FLOW_PKT_TOSERVER) { + SCLogDebug("mpm inspection"); + if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_DNSQUERY) { + FLOWLOCK_RDLOCK(p->flow); + uint64_t idx = AppLayerTransactionGetInspectId(p->flow, flags); + uint64_t total_txs = AppLayerGetTxCnt(alproto, alstate); + for (; idx < total_txs; idx++) { + void *tx = AppLayerGetTx(alproto, alstate, idx); + if (tx == NULL) + continue; + SCLogDebug("tx %p",tx); + PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_DNSQUERY); + DetectDnsQueryInspectMpm(det_ctx, p->flow, alstate, flags, tx, idx); + PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_DNSQUERY); + } + FLOWLOCK_UNLOCK(p->flow); + } + } + } } #ifdef DEBUG diff --git a/src/detect.h b/src/detect.h index 35ff5d3b34..f7263318b1 100644 --- a/src/detect.h +++ b/src/detect.h @@ -271,6 +271,9 @@ typedef struct DetectPort_ { #define SIG_FLAG_TLSSTORE (1<<21) +#define SIG_FLAG_MPM_DNS (1<<22) +#define SIG_FLAG_MPM_DNS_NEG (1<<23) + /* signature init flags */ #define SIG_FLAG_INIT_DEONLY 1 /**< decode event only signature */ #define SIG_FLAG_INIT_PACKET (1<<1) /**< signature has matches against a packet (as opposed to app layer) */ @@ -689,6 +692,7 @@ typedef struct DetectEngineCtx_ { int32_t sgh_mpm_context_hhhd; int32_t sgh_mpm_context_hrhhd; int32_t sgh_mpm_context_app_proto_detect; + int32_t sgh_mpm_context_dnsquery; /* the max local id used amongst all sigs */ int32_t byte_extract_max_local_id; @@ -905,6 +909,7 @@ typedef struct SigTableElmt_ { #define SIG_GROUP_HEAD_HAVEFILEMAGIC (1 << 20) #define SIG_GROUP_HEAD_HAVEFILEMD5 (1 << 21) #define SIG_GROUP_HEAD_HAVEFILESIZE (1 << 22) +#define SIG_GROUP_HEAD_MPM_DNSQUERY (1 << 23) typedef struct SigGroupHeadInitData_ { /* list of content containers @@ -965,6 +970,7 @@ typedef struct SigGroupHead_ { MpmCtx *mpm_huad_ctx_ts; MpmCtx *mpm_hhhd_ctx_ts; MpmCtx *mpm_hrhhd_ctx_ts; + MpmCtx *mpm_dnsquery_ctx_ts; MpmCtx *mpm_proto_tcp_ctx_tc; MpmCtx *mpm_proto_udp_ctx_tc; diff --git a/src/suricata-common.h b/src/suricata-common.h index c3f116854a..a7555ec80e 100644 --- a/src/suricata-common.h +++ b/src/suricata-common.h @@ -288,6 +288,7 @@ typedef enum PacketProfileDetectId_ { PROF_DETECT_MPM_HUAD, PROF_DETECT_MPM_HHHD, PROF_DETECT_MPM_HRHHD, + PROF_DETECT_MPM_DNSQUERY, PROF_DETECT_IPONLY, PROF_DETECT_RULES, PROF_DETECT_STATEFUL, diff --git a/src/util-profiling.c b/src/util-profiling.c index 8be6a0f46a..7399116f2e 100644 --- a/src/util-profiling.c +++ b/src/util-profiling.c @@ -871,6 +871,7 @@ const char * PacketProfileDetectIdToString(PacketProfileDetectId id) CASE_CODE (PROF_DETECT_MPM_HSMD); CASE_CODE (PROF_DETECT_MPM_HSCD); CASE_CODE (PROF_DETECT_MPM_HUAD); + CASE_CODE (PROF_DETECT_MPM_DNSQUERY); CASE_CODE (PROF_DETECT_IPONLY); CASE_CODE (PROF_DETECT_RULES); CASE_CODE (PROF_DETECT_PREFILTER);