]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
DNS: add support for per TX decoder events.
authorVictor Julien <victor@inliniac.net>
Thu, 2 May 2013 10:01:07 +0000 (12:01 +0200)
committerVictor Julien <victor@inliniac.net>
Thu, 27 Jun 2013 16:17:16 +0000 (18:17 +0200)
src/app-layer-dns-common.c
src/app-layer-dns-common.h
src/app-layer-dns-tcp.c
src/app-layer-dns-udp.c

index 28ee04df2afd29394710b925620d984829fe5ab8..84f944e06a12c11ec2c61332fc1640a8a6f68fa7 100644 (file)
@@ -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;
     }
 
index 9dda7603c8246fce7aa18ffd41e6aedc9786ca59..3d899e495780509ef39784bc57879a941ea18236 100644 (file)
@@ -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);
index a48ff4eff598f9af2f83ab966fca229c322a195c..f1d023765579f43dead2f8a744a489ca902b60c8 100644 (file)
@@ -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);
index e0743b2cc219fa89650372f816425670c60b4abf..253ec168364be5c99bc0db66c5db9ab9dab4c1d7 100644 (file)
@@ -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);