diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/ndpi_protocols.h | 1 | ||||
-rw-r--r-- | src/include/ndpi_typedefs.h | 4 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 3 | ||||
-rw-r--r-- | src/lib/ndpi_utils.c | 2 | ||||
-rw-r--r-- | src/lib/protocols/dns.c | 99 | ||||
-rw-r--r-- | src/lib/protocols/mdns_proto.c | 153 |
6 files changed, 81 insertions, 181 deletions
diff --git a/src/include/ndpi_protocols.h b/src/include/ndpi_protocols.h index e0ea5a906..c3f8bfa51 100644 --- a/src/include/ndpi_protocols.h +++ b/src/include/ndpi_protocols.h @@ -102,7 +102,6 @@ void init_mail_imap_dissector(struct ndpi_detection_module_struct *ndpi_struct, void init_mail_pop_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_mail_smtp_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_maplestory_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); -void init_mdns_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_megaco_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_mgpc_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); void init_mining_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask); diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index a1d843c83..beef59fee 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -1283,10 +1283,6 @@ struct ndpi_flow_struct { } telnet; struct { - char answer[96]; - } mdns; - - struct { char version[32]; } ubntac2; diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index c74b4ec17..fe3ebbf9e 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -3077,9 +3077,6 @@ void ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *n /* NETBIOS */ init_netbios_dissector(ndpi_str, &a, detection_bitmask); - /* MDNS */ - init_mdns_dissector(ndpi_str, &a, detection_bitmask); - /* IPP */ init_ipp_dissector(ndpi_str, &a, detection_bitmask); diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c index 897096b70..1a8459c34 100644 --- a/src/lib/ndpi_utils.c +++ b/src/lib/ndpi_utils.c @@ -1172,7 +1172,7 @@ int ndpi_dpi2json(struct ndpi_detection_module_struct *ndpi_struct, case NDPI_PROTOCOL_MDNS: ndpi_serialize_start_of_block(serializer, "mdns"); - ndpi_serialize_string_string(serializer, "answer", flow->protos.mdns.answer); + ndpi_serialize_string_string(serializer, "answer", (const char*)flow->host_server_name); ndpi_serialize_end_of_block(serializer); break; diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c index 03ac7b9d2..12c6d0338 100644 --- a/src/lib/protocols/dns.c +++ b/src/lib/protocols/dns.c @@ -27,15 +27,47 @@ #include "ndpi_api.h" - #define FLAGS_MASK 0x8000 -// #define DNS_DEBUG 1 +/* #define DNS_DEBUG 1 */ + +#define DNS_PORT 53 +#define LLMNR_PORT 5355 +#define MDNS_PORT 5353 static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); /* *********************************************** */ +static u_int16_t checkPort(u_int16_t port) { + switch(port) { + case DNS_PORT: + return(NDPI_PROTOCOL_DNS); + break; + case LLMNR_PORT: + return(NDPI_PROTOCOL_LLMNR); + break; + case MDNS_PORT: + return(NDPI_PROTOCOL_MDNS); + break; + } + + return(0); +} + +/* *********************************************** */ + +static u_int16_t checkDNSSubprotocol(u_int16_t sport, u_int16_t dport) { + u_int16_t rc = checkPort(sport); + + if(rc == 0) + return(checkPort(dport)); + else + return(rc); +} + +/* *********************************************** */ + static u_int16_t get16(int *i, const u_int8_t *payload) { u_int16_t v = *(u_int16_t*)&payload[*i]; @@ -108,7 +140,7 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct, NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET); return(1 /* invalid */); } - + if(*is_query) { /* DNS Request */ if((dns_header->num_queries > 0) && (dns_header->num_queries <= NDPI_MAX_DNS_REQUESTS) @@ -182,7 +214,7 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct, if((x+12) <= flow->packet.payload_packet_len) { x += 6; data_len = get16(&x, flow->packet.payload); - + if((x + data_len) <= flow->packet.payload_packet_len) { // printf("[rsp_type: %u][data_len: %u]\n", rsp_type, data_len); @@ -190,7 +222,7 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct, x += data_len; continue; /* Skip CNAME */ } - + if((((rsp_type == 0x1) && (data_len == 4)) /* A */ #ifdef NDPI_DETECTION_SUPPORT_IPV6 || ((rsp_type == 0x1c) && (data_len == 16)) /* AAAA */ @@ -200,11 +232,11 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct, } } } - + break; } } - + if((flow->packet.detected_protocol_stack[0] == NDPI_PROTOCOL_DNS) || (flow->packet.detected_protocol_stack[1] == NDPI_PROTOCOL_DNS)) { /* Request already set the protocol */ @@ -212,10 +244,8 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct, } else { /* We missed the request */ u_int16_t s_port = flow->packet.udp ? ntohs(flow->packet.udp->source) : ntohs(flow->packet.tcp->source); - - ndpi_set_detected_protocol(ndpi_struct, flow, - (s_port == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS, - NDPI_PROTOCOL_UNKNOWN); + + ndpi_set_detected_protocol(ndpi_struct, flow, checkPort(s_port), NDPI_PROTOCOL_UNKNOWN); } } } @@ -256,15 +286,18 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st return; } - if((s_port == 53 || d_port == 53 || d_port == 5355) + if(((s_port == DNS_PORT) || (d_port == DNS_PORT) + || (s_port == MDNS_PORT) || (d_port == MDNS_PORT) + || (d_port == LLMNR_PORT)) && (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(ndpi_struct, flow, &dns_header, payload_offset, &is_query); ndpi_protocol ret; + u_int num_queries, idx; - ret.master_protocol = NDPI_PROTOCOL_UNKNOWN; - ret.app_protocol = (d_port == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS; + ret.master_protocol = NDPI_PROTOCOL_UNKNOWN; + ret.app_protocol = (d_port == LLMNR_PORT) ? NDPI_PROTOCOL_LLMNR : ((d_port == MDNS_PORT) ? NDPI_PROTOCOL_MDNS : NDPI_PROTOCOL_DNS); if(invalid) { NDPI_EXCLUDE_PROTO(ndpi_struct, flow); @@ -274,7 +307,35 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st /* extract host name server */ max_len = sizeof(flow->host_server_name)-1; off = sizeof(struct ndpi_dns_packet_header) + payload_offset; - + + /* Before continuing let's dissect the following queries to see if they are valid */ + for(idx=off, num_queries=0; (num_queries < dns_header.num_queries) && (idx < flow->packet.payload_packet_len);) { + u_int8_t name_len = flow->packet.payload[idx]; + +#ifdef DNS_DEBUG + printf("[DNS] [name_len: %u]\n", name_len); +#endif + + if(name_len == 0) { + /* End of query */ + num_queries++; + idx += 5; + continue; + } + + if((name_len+idx) >= flow->packet.payload_packet_len) { + /* Invalid */ +#ifdef DNS_DEBUG + printf("[DNS] Invalid query len [%u >= %u]\n", + (name_len+idx), + flow->packet.payload_packet_len); +#endif + NDPI_SET_BIT(flow->risk, NDPI_MALFORMED_PACKET); + break; + } else + idx += name_len+1; + } + while(j < max_len && off < flow->packet.payload_packet_len && flow->packet.payload[off] != '\0') { uint8_t c, cl = flow->packet.payload[off++]; @@ -288,7 +349,7 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st while(j < max_len && cl != 0) { u_int32_t shift; - + c = flow->packet.payload[off++]; shift = ((u_int32_t) 1) << (c & 0x1f); flow->host_server_name[j++] = tolower((dns_validchar[c >> 5] & shift) ? c : '_'); @@ -297,12 +358,12 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st } flow->host_server_name[j] = '\0'; - + if(j > 0) { ndpi_protocol_match_result ret_match; ndpi_check_dga_name(ndpi_struct, flow, (char*)flow->host_server_name, 1); - + ret.app_protocol = ndpi_match_host_subprotocol(ndpi_struct, flow, (char *)flow->host_server_name, strlen((const char*)flow->host_server_name), @@ -313,7 +374,7 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st flow->category = ret_match.protocol_category; if(ret.app_protocol == NDPI_PROTOCOL_UNKNOWN) - ret.master_protocol = (d_port == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS; + ret.master_protocol = checkDNSSubprotocol(s_port, d_port); else ret.master_protocol = NDPI_PROTOCOL_DNS; } diff --git a/src/lib/protocols/mdns_proto.c b/src/lib/protocols/mdns_proto.c deleted file mode 100644 index 2b75f19ec..000000000 --- a/src/lib/protocols/mdns_proto.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * mdns.c - * - * Copyright (C) 2016-20 - ntop.org - * - * This file is part of nDPI, an open source deep packet inspection - * library based on the OpenDPI and PACE technology by ipoque GmbH - * - * nDPI is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * nDPI is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with nDPI. If not, see <http://www.gnu.org/licenses/>. - * - */ -#include "ndpi_protocol_ids.h" - -#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_MDNS - -#include "ndpi_api.h" - -#define NDPI_MAX_MDNS_REQUESTS 128 - -PACK_ON -struct mdns_header { - u_int16_t transaction_id, flags, questions, answers, authority_rr, additional_rr; -} PACK_OFF; - -/** - MDNS header is similar to dns header - - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - | ID = 0x0000 | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - | FLAGS | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - | QDCOUNT | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - | ANCOUNT | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - | NSCOUNT | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ - | ARCOUNT | - +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -*/ - - -static void ndpi_int_mdns_add_connection(struct ndpi_detection_module_struct - *ndpi_struct, struct ndpi_flow_struct *flow) { - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MDNS, NDPI_PROTOCOL_UNKNOWN); -} - -static int ndpi_int_check_mdns_payload(struct ndpi_detection_module_struct - *ndpi_struct, struct ndpi_flow_struct *flow) { - struct ndpi_packet_struct *packet = &flow->packet; - struct mdns_header *h = (struct mdns_header*)packet->payload; - u_int16_t questions = ntohs(h->questions), answers = ntohs(h->answers); - - if((questions > NDPI_MAX_MDNS_REQUESTS) - || (answers > NDPI_MAX_MDNS_REQUESTS)) - return(0); - - if((packet->payload[2] & 0x80) == 0) { - NDPI_LOG_INFO(ndpi_struct, "found MDNS with question query\n"); - return 1; - } else if((packet->payload[2] & 0x80) != 0) { - char answer[256]; - int i, j, len; - - for(i=13, j=0; (i < packet->payload_packet_len) && (i < (sizeof(answer)-1)) && (packet->payload[i] != 0); i++) - answer[j++] = (packet->payload[i] < 13) ? '.' : packet->payload[i]; - - answer[j] = '\0'; - - /* printf("==> [%d] %s\n", j, answer); */ - - len = ndpi_min(sizeof(flow->protos.mdns.answer)-1, j); - strncpy(flow->protos.mdns.answer, (const char *)answer, len); - flow->protos.mdns.answer[len] = '\0'; - - NDPI_LOG_INFO(ndpi_struct, "found MDNS with answer query\n"); - return 1; - } - - return 0; -} - -void ndpi_search_mdns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) -{ - struct ndpi_packet_struct *packet = &flow->packet; - NDPI_LOG_DBG(ndpi_struct, "search MDNS\n"); - - /** - information from http://www.it-administrator.de/lexikon/multicast-dns.html - */ - - /* check if UDP packet */ - if(packet->udp != NULL) { - /* read destination port */ - u_int16_t sport = ntohs(packet->udp->source); - u_int16_t dport = ntohs(packet->udp->dest); - - /* check standard MDNS ON port 5353 */ - if(((dport == 5353) || (sport == 5353)) - && (packet->payload_packet_len >= 12)) { - if(packet->iph != NULL) { - if(ndpi_int_check_mdns_payload(ndpi_struct, flow) == 1) { - ndpi_int_mdns_add_connection(ndpi_struct, flow); - return; - } - } -#ifdef NDPI_DETECTION_SUPPORT_IPV6 - if(packet->iphv6 != NULL) { - u_int32_t daddr_0 = packet->iphv6->ip6_dst.u6_addr.u6_addr32[0]; - - if(daddr_0 == htonl(0xff020000) /* && daddr[1] == 0 && daddr[2] == 0 && daddr[3] == htonl(0xfb) */) { - - NDPI_LOG_INFO(ndpi_struct, "found MDNS with destination address ff02::fb\n"); - - if(ndpi_int_check_mdns_payload(ndpi_struct, flow) == 1) { - ndpi_int_mdns_add_connection(ndpi_struct, flow); - return; - } - } - } -#endif - } - } - - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); -} - - -void init_mdns_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) -{ - ndpi_set_bitmask_protocol_detection("MDNS", ndpi_struct, detection_bitmask, *id, - NDPI_PROTOCOL_MDNS, - ndpi_search_mdns, - NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); - - *id += 1; -} - |