From: Victor Julien Date: Thu, 2 May 2013 10:01:07 +0000 (+0200) Subject: DNS: add support for per TX decoder events. X-Git-Tag: suricata-2.0beta1~67 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=571b8ac186505d01789ac3eb22df9919e13d32c4;p=thirdparty%2Fsuricata.git DNS: add support for per TX decoder events. --- diff --git a/src/app-layer-dns-common.c b/src/app-layer-dns-common.c index 28ee04df2a..84f944e06a 100644 --- a/src/app-layer-dns-common.c +++ b/src/app-layer-dns-common.c @@ -42,6 +42,16 @@ void DNSAppLayerDecoderEventsRegister(int alproto) { AppLayerDecoderEventsModuleRegister(alproto, dns_decoder_event_table); } +AppLayerDecoderEvents *DNSGetEvents(void *state, uint64_t id) { + DNSState *dns_state = (DNSState *)state; + DNSTransaction *tx; + TAILQ_FOREACH(tx, &dns_state->tx_list, next) { + if (tx->tx_num == (id+1)) + return tx->decoder_events; + } + return NULL; +} + void *DNSStateAlloc(void) { void *s = SCMalloc(sizeof(DNSState)); if (unlikely(s == NULL)) @@ -104,6 +114,16 @@ int DNSGetAlstateProgressCompletionStatus(uint8_t direction) { return (direction == 0) ? 0 : 1; } +void DNSSetEvent(DNSState *s, uint8_t e) { + if (s && s->curr) { + SCLogDebug("s->curr->decoder_events %p", s->curr->decoder_events); + AppLayerDecoderEventsSetEventRaw(s->curr->decoder_events, e); + SCLogDebug("s->curr->decoder_events %p", s->curr->decoder_events); + } else { + SCLogDebug("couldn't set event %u", e); + } +} + /** \internal * \brief Allocate a DNS TX * \retval tx or NULL */ @@ -175,20 +195,18 @@ DNSTransaction *DNSTransactionFindByTxId(const DNSState *dns_state, const uint16 * \retval 0 ok * \retval -1 error */ -int DNSValidateRequestHeader(Flow *f, const DNSHeader *dns_header) { +int DNSValidateRequestHeader(DNSState *dns_state, const DNSHeader *dns_header) { uint16_t flags = ntohs(dns_header->flags); if ((flags & 0x8000) != 0) { SCLogDebug("not a request 0x%04x", flags); - if (f != NULL) - AppLayerDecoderEventsSetEvent(f, DNS_DECODER_EVENT_NOT_A_REQUEST); + DNSSetEvent(dns_state, DNS_DECODER_EVENT_NOT_A_REQUEST); goto bad_data; } if ((flags & 0x0040) != 0) { SCLogDebug("Z flag not 0, 0x%04x", flags); - if (f != NULL) - AppLayerDecoderEventsSetEvent(f, DNS_DECODER_EVENT_Z_FLAG_SET); + DNSSetEvent(dns_state, DNS_DECODER_EVENT_Z_FLAG_SET); goto bad_data; } @@ -204,18 +222,18 @@ bad_data: * \retval 0 ok * \retval -1 error */ -int DNSValidateResponseHeader(Flow *f, const DNSHeader *dns_header) { +int DNSValidateResponseHeader(DNSState *dns_state, const DNSHeader *dns_header) { uint16_t flags = ntohs(dns_header->flags); if ((flags & 0x8000) == 0) { SCLogDebug("not a response 0x%04x", flags); - AppLayerDecoderEventsSetEvent(f, DNS_DECODER_EVENT_NOT_A_RESPONSE); + DNSSetEvent(dns_state, DNS_DECODER_EVENT_NOT_A_RESPONSE); goto bad_data; } if ((flags & 0x0040) != 0) { SCLogDebug("Z flag not 0, 0x%04x", flags); - AppLayerDecoderEventsSetEvent(f, DNS_DECODER_EVENT_Z_FLAG_SET); + DNSSetEvent(dns_state, DNS_DECODER_EVENT_Z_FLAG_SET); goto bad_data; } diff --git a/src/app-layer-dns-common.h b/src/app-layer-dns-common.h index 9dda7603c8..3d899e4957 100644 --- a/src/app-layer-dns-common.h +++ b/src/app-layer-dns-common.h @@ -132,6 +132,8 @@ typedef struct DNSTransaction_ { TAILQ_HEAD(, DNSAnswerEntry_) answer_list; /**< list for answers */ TAILQ_HEAD(, DNSAnswerEntry_) authority_list; /**< list for authority records */ + AppLayerDecoderEvents *decoder_events; /**< per tx events */ + TAILQ_ENTRY(DNSTransaction_) next; } DNSTransaction; @@ -162,11 +164,13 @@ DNSTransaction *DNSTransactionAlloc(const uint16_t tx_id); void DNSTransactionFree(DNSTransaction *tx); DNSTransaction *DNSTransactionFindByTxId(const DNSState *dns_state, const uint16_t tx_id); +void DNSSetEvent(DNSState *s, uint8_t e); void *DNSStateAlloc(void); void DNSStateFree(void *s); +AppLayerDecoderEvents *DNSGetEvents(void *state, uint64_t id); -int DNSValidateRequestHeader(Flow *f, const DNSHeader *dns_header); -int DNSValidateResponseHeader(Flow *f, const DNSHeader *dns_header); +int DNSValidateRequestHeader(DNSState *, const DNSHeader *dns_header); +int DNSValidateResponseHeader(DNSState *, const DNSHeader *dns_header); void DNSStoreQueryInState(DNSState *dns_state, const uint8_t *fqdn, const uint16_t fqdn_len, const uint16_t type, const uint16_t class, const uint16_t tx_id); diff --git a/src/app-layer-dns-tcp.c b/src/app-layer-dns-tcp.c index a48ff4eff5..f1d0237655 100644 --- a/src/app-layer-dns-tcp.c +++ b/src/app-layer-dns-tcp.c @@ -175,7 +175,7 @@ static void BufferReset(DNSState *dns_state) { static int DNSRequestParseData(Flow *f, DNSState *dns_state, const uint8_t *input, const uint32_t input_len) { DNSHeader *dns_header = (DNSHeader *)input; - if (DNSValidateRequestHeader(f, dns_header) < 0) + if (DNSValidateRequestHeader(dns_state, dns_header) < 0) goto bad_data; //SCLogInfo("ID %04x", ntohs(dns_header->tx_id)); @@ -350,7 +350,7 @@ bad_data: static int DNSReponseParseData(Flow *f, DNSState *dns_state, const uint8_t *input, const uint32_t input_len) { DNSHeader *dns_header = (DNSHeader *)input; - if (DNSValidateResponseHeader(f, dns_header) < 0) + if (DNSValidateResponseHeader(dns_state, dns_header) < 0) goto bad_data; DNSTransaction *tx = NULL; @@ -361,10 +361,6 @@ static int DNSReponseParseData(Flow *f, DNSState *dns_state, const uint8_t *inpu break; } } - if (!found) { - SCLogDebug("DNS_DECODER_EVENT_UNSOLLICITED_RESPONSE"); - AppLayerDecoderEventsSetEvent(f, DNS_DECODER_EVENT_UNSOLLICITED_RESPONSE); - } uint16_t q; const uint8_t *data = input + sizeof(DNSHeader); @@ -439,6 +435,11 @@ static int DNSReponseParseData(Flow *f, DNSState *dns_state, const uint8_t *inpu } } + if (!found) { + SCLogDebug("DNS_DECODER_EVENT_UNSOLLICITED_RESPONSE"); + DNSSetEvent(dns_state, DNS_DECODER_EVENT_UNSOLLICITED_RESPONSE); + } + SCReturnInt(1); bad_data: insufficient_data: @@ -621,6 +622,7 @@ void RegisterDNSTCPParsers(void) { DNSStateFree); AppLayerRegisterTransactionIdFuncs(ALPROTO_DNS_TCP, DNSStateUpdateTransactionId, DNSStateTransactionFree); + AppLayerRegisterGetEventsFunc(ALPROTO_DNS_TCP, DNSGetEvents); AppLayerRegisterGetTx(ALPROTO_DNS_TCP, DNSGetTx); diff --git a/src/app-layer-dns-udp.c b/src/app-layer-dns-udp.c index e0743b2cc2..253ec16836 100644 --- a/src/app-layer-dns-udp.c +++ b/src/app-layer-dns-udp.c @@ -71,7 +71,7 @@ static int DNSUDPRequestParse(Flow *f, void *dstate, DNSHeader *dns_header = (DNSHeader *)input; SCLogDebug("DNS %p", dns_header); - if (DNSValidateRequestHeader(f, dns_header) < 0) + if (DNSValidateRequestHeader(dns_state, dns_header) < 0) goto bad_data; uint16_t q; @@ -183,12 +183,7 @@ static int DNSUDPResponseParse(Flow *f, void *dstate, break; } } - if (!found) { - SCLogDebug("DNS_DECODER_EVENT_UNSOLLICITED_RESPONSE"); - AppLayerDecoderEventsSetEvent(f, DNS_DECODER_EVENT_UNSOLLICITED_RESPONSE); - } - - if (DNSValidateResponseHeader(f, dns_header) < 0) + if (DNSValidateResponseHeader(dns_state, dns_header) < 0) goto bad_data; uint16_t q; @@ -272,11 +267,16 @@ static int DNSUDPResponseParse(Flow *f, void *dstate, } } + if (!found) { + SCLogDebug("DNS_DECODER_EVENT_UNSOLLICITED_RESPONSE"); + DNSSetEvent(dns_state, DNS_DECODER_EVENT_UNSOLLICITED_RESPONSE); + } + SCReturnInt(1); bad_data: insufficient_data: - AppLayerDecoderEventsSetEvent(f, DNS_DECODER_EVENT_MALFORMED_DATA); + DNSSetEvent(dns_state, DNS_DECODER_EVENT_MALFORMED_DATA); SCReturnInt(-1); } @@ -345,6 +345,7 @@ void RegisterDNSUDPParsers(void) { DNSStateFree); AppLayerRegisterTransactionIdFuncs(ALPROTO_DNS_UDP, DNSStateUpdateTransactionId, DNSStateTransactionFree); + AppLayerRegisterGetEventsFunc(ALPROTO_DNS_UDP, DNSGetEvents); AppLayerRegisterGetTx(ALPROTO_DNS_UDP, DNSGetTx);