aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/protocols/dns.c157
1 files changed, 80 insertions, 77 deletions
diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c
index b9cd1a9cb..4e3ffb5ed 100644
--- a/src/lib/protocols/dns.c
+++ b/src/lib/protocols/dns.c
@@ -72,84 +72,57 @@ static u_int getNameLength(u_int i, const u_int8_t *payload, u_int payloadLen) {
static uint32_t dns_validchar[8] = {
0x00000000,0x03ff2000,0x87fffffe,0x07fffffe,0,0,0,0
};
-/* *********************************************** */
-
-void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
- int x, payload_offset;
- u_int8_t is_query;
- u_int16_t s_port = 0, d_port = 0;
-
- NDPI_LOG_DBG(ndpi_struct, "search DNS\n");
- if(flow->packet.udp != NULL) {
- s_port = ntohs(flow->packet.udp->source);
- d_port = ntohs(flow->packet.udp->dest);
- payload_offset = 0;
- } else if(flow->packet.tcp != NULL) /* pkt size > 512 bytes */ {
- s_port = ntohs(flow->packet.tcp->source);
- d_port = ntohs(flow->packet.tcp->dest);
- payload_offset = 2;
- } else {
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
- return;
- }
-
- x = payload_offset;
-
- if((s_port == 53 || d_port == 53 || d_port == 5355)
- && (flow->packet.payload_packet_len > sizeof(struct ndpi_dns_packet_header)+x)) {
- struct ndpi_dns_packet_header dns_header;
- int invalid = 0;
-
- memcpy(&dns_header, (struct ndpi_dns_packet_header*) &flow->packet.payload[x], sizeof(struct ndpi_dns_packet_header));
- dns_header.tr_id = ntohs(dns_header.tr_id);
- dns_header.flags = ntohs(dns_header.flags);
- dns_header.num_queries = ntohs(dns_header.num_queries);
- dns_header.num_answers = ntohs(dns_header.num_answers);
- dns_header.authority_rrs = ntohs(dns_header.authority_rrs);
- dns_header.additional_rrs = ntohs(dns_header.additional_rrs);
- x += sizeof(struct ndpi_dns_packet_header);
-
- /* 0x0000 QUERY */
- if((dns_header.flags & FLAGS_MASK) == 0x0000)
- is_query = 1;
- /* 0x8000 RESPONSE */
- else if((dns_header.flags & FLAGS_MASK) == 0x8000)
- is_query = 0;
- else
- invalid = 1;
+/* *********************************************** */
- if(!invalid) {
- int j = 0, max_len, off;
- if(is_query) {
- /* DNS Request */
- if((dns_header.num_queries > 0) && (dns_header.num_queries <= NDPI_MAX_DNS_REQUESTS)
- && (((dns_header.flags & 0x2800) == 0x2800 /* Dynamic DNS Update */)
- || ((dns_header.num_answers == 0) && (dns_header.authority_rrs == 0)))) {
- /* This is a good query */
-
- while(x < flow->packet.payload_packet_len) {
- if(flow->packet.payload[x] == '\0') {
- x++;
- flow->protos.dns.query_type = get16(&x, flow->packet.payload);
+static int search_valid_dns(struct ndpi_flow_struct *flow, struct ndpi_dns_packet_header *dns_header, int payload_offset, u_int8_t*is_query) {
+ int x = payload_offset;
+
+ memcpy(dns_header, (struct ndpi_dns_packet_header*) &flow->packet.payload[x], sizeof(struct ndpi_dns_packet_header));
+ dns_header->tr_id = ntohs(dns_header->tr_id);
+ dns_header->flags = ntohs(dns_header->flags);
+ dns_header->num_queries = ntohs(dns_header->num_queries);
+ dns_header->num_answers = ntohs(dns_header->num_answers);
+ dns_header->authority_rrs = ntohs(dns_header->authority_rrs);
+ dns_header->additional_rrs = ntohs(dns_header->additional_rrs);
+ x += sizeof(struct ndpi_dns_packet_header);
+
+ /* 0x0000 QUERY */
+ if((dns_header->flags & FLAGS_MASK) == 0x0000)
+ *is_query = 1;
+ /* 0x8000 RESPONSE */
+ else if((dns_header->flags & FLAGS_MASK) == 0x8000)
+ *is_query = 0;
+ else
+ return(1 /* invalid */);
+
+ if(*is_query) {
+ /* DNS Request */
+ if((dns_header->num_queries > 0) && (dns_header->num_queries <= NDPI_MAX_DNS_REQUESTS)
+ && (((dns_header->flags & 0x2800) == 0x2800 /* Dynamic DNS Update */)
+ || ((dns_header->num_answers == 0) && (dns_header->authority_rrs == 0)))) {
+ /* This is a good query */
+ while(x < flow->packet.payload_packet_len) {
+ if(flow->packet.payload[x] == '\0') {
+ x++;
+ flow->protos.dns.query_type = get16(&x, flow->packet.payload);
#ifdef DNS_DEBUG
- NDPI_LOG_DBG2(ndpi_struct, "query_type=%2d\n", flow->protos.dns.query_type);
+ NDPI_LOG_DBG2(ndpi_struct, "query_type=%2d\n", flow->protos.dns.query_type);
#endif
- break;
- } else
- x++;
- }
- } else
- invalid = 1;
- } else {
+ break;
+ } else
+ x++;
+ }
+ } else
+ return(1 /* invalid */);
+ } else {
/* DNS Reply */
+ flow->protos.dns.reply_code = dns_header->flags & 0x0F;
- flow->protos.dns.reply_code = dns_header.flags & 0x0F;
-
- if((dns_header.num_queries > 0) && (dns_header.num_queries <= NDPI_MAX_DNS_REQUESTS) /* Don't assume that num_queries must be zero */
- && (((dns_header.num_answers > 0) && (dns_header.num_answers <= NDPI_MAX_DNS_REQUESTS))
- || ((dns_header.authority_rrs > 0) && (dns_header.authority_rrs <= NDPI_MAX_DNS_REQUESTS))
- || ((dns_header.additional_rrs > 0) && (dns_header.additional_rrs <= NDPI_MAX_DNS_REQUESTS)))
+ if((dns_header->num_queries > 0) && (dns_header->num_queries <= NDPI_MAX_DNS_REQUESTS) /* Don't assume that num_queries must be zero */
+ && (((dns_header->num_answers > 0) && (dns_header->num_answers <= NDPI_MAX_DNS_REQUESTS))
+ || ((dns_header->authority_rrs > 0) && (dns_header->authority_rrs <= NDPI_MAX_DNS_REQUESTS))
+ || ((dns_header->additional_rrs > 0) && (dns_header->additional_rrs <= NDPI_MAX_DNS_REQUESTS)))
) {
/* This is a good reply: we dissect it both for request and response */
@@ -168,11 +141,11 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd
x += 4;
- if(dns_header.num_answers > 0) {
+ if(dns_header->num_answers > 0) {
u_int16_t rsp_type;
u_int16_t num;
- for(num = 0; num < dns_header.num_answers; num++) {
+ for(num = 0; num < dns_header->num_answers; num++) {
u_int16_t data_len;
if((x+6) >= flow->packet.payload_packet_len) {
@@ -207,8 +180,39 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd
}
}
} else
- invalid = 1;
- }
+ return(1 /* invalid */);
+ }
+
+ /* Valid */
+ return(0);
+}
+
+/* *********************************************** */
+
+void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+ int payload_offset;
+ u_int8_t is_query;
+ u_int16_t s_port = 0, d_port = 0;
+
+ NDPI_LOG_DBG(ndpi_struct, "search DNS\n");
+ if(flow->packet.udp != NULL) {
+ s_port = ntohs(flow->packet.udp->source);
+ d_port = ntohs(flow->packet.udp->dest);
+ payload_offset = 0;
+ } else if(flow->packet.tcp != NULL) /* pkt size > 512 bytes */ {
+ s_port = ntohs(flow->packet.tcp->source);
+ d_port = ntohs(flow->packet.tcp->dest);
+ payload_offset = 2;
+ } else {
+ NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ return;
+ }
+
+ if((s_port == 53 || d_port == 53 || d_port == 5355)
+ && (flow->packet.payload_packet_len > sizeof(struct ndpi_dns_packet_header)+payload_offset)) {
+ struct ndpi_dns_packet_header dns_header;
+ int j = 0, max_len, off;
+ int invalid = search_valid_dns(flow, &dns_header, payload_offset, &is_query);
if(invalid) {
NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
@@ -273,7 +277,6 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd
} else {
NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
}
- }
}
}