DNS: add support for per TX decoder events.

pull/412/merge
Victor Julien 12 years ago
parent 9dc04d9fab
commit 571b8ac186

@ -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;
}

@ -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);

@ -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);

@ -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);

Loading…
Cancel
Save