diff --git a/example/ndpiReader.c b/example/ndpiReader.c index 260d956d52e..7856ae1a0f6 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -1779,6 +1779,8 @@ static void printFlow(u_int32_t id, struct ndpi_flow_info *flow, u_int16_t threa if(flow->flow_extra_info[0] != '\0') fprintf(out, "[%s]", flow->flow_extra_info); + if(flow->dns.geolocation_iata_code[0] != '\0') fprintf(out, "[GeoLocation: %s]", flow->dns.geolocation_iata_code); + if((flow->src2dst_packets+flow->dst2src_packets) > 5) { if(flow->iat_c_to_s && flow->iat_s_to_c) { float data_ratio = ndpi_data_ratio(flow->src2dst_bytes, flow->dst2src_bytes); diff --git a/example/reader_util.c b/example/reader_util.c index d8c4b23f3b9..7144626cabd 100644 --- a/example/reader_util.c +++ b/example/reader_util.c @@ -1228,6 +1228,8 @@ void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_fl /* For consistency across platforms replace :0: with :: */ ndpi_patchIPv6Address(flow->info); } + if(flow->ndpi_flow->protos.dns.geolocation_iata_code[0] != '\0') + strcpy(flow->dns.geolocation_iata_code, flow->ndpi_flow->protos.dns.geolocation_iata_code); } /* MDNS */ else if(is_ndpi_proto(flow, NDPI_PROTOCOL_MDNS)) { diff --git a/example/reader_util.h b/example/reader_util.h index cce2431306b..9d63278a460 100644 --- a/example/reader_util.h +++ b/example/reader_util.h @@ -294,6 +294,10 @@ typedef struct ndpi_flow_info { char *username, *password; } telnet; + struct { + char geolocation_iata_code[4]; + } dns; + ndpi_multimedia_flow_type multimedia_flow_type; void *src_id, *dst_id; diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index f56fdab8fb2..15415526c00 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -1486,6 +1486,7 @@ struct ndpi_flow_struct { u_int8_t num_queries, num_answers, reply_code, is_query; u_int16_t query_type, query_class, rsp_type, edns0_udp_payload_size; ndpi_ip_addr_t rsp_addr; /* The first address in a DNS response packet (A and AAAA) */ + char geolocation_iata_code[4]; char ptr_domain_name[64 /* large enough but smaller than { } tls */]; } dns; diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c index 6e486440519..07358468d72 100644 --- a/src/lib/protocols/dns.c +++ b/src/lib/protocols/dns.c @@ -547,7 +547,8 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct, u_int16_t num; for(num = 0; num < dns_header->additional_rrs; num++) { - u_int16_t data_len; + u_int16_t data_len, rdata_len, opt_code, opt_len; + const unsigned char *opt; if((x+6) > packet->payload_packet_len) { break; @@ -576,6 +577,34 @@ static int search_valid_dns(struct ndpi_detection_module_struct *ndpi_struct, printf("[DNS] [response] edns0_udp_payload_size: %u\n", flow->protos.dns.edns0_udp_payload_size); #endif x += 6; + + rdata_len = ntohs(*((u_int16_t *)&packet->payload[x])); +#ifdef DNS_DEBUG + printf("[DNS] [response] rdata len: %u\n", rdata_len); +#endif + if(rdata_len > 0 && + x + 6 <= packet->payload_packet_len) { + opt_code = ntohs(*((u_int16_t *)&packet->payload[x + 2])); + opt_len = ntohs(*((u_int16_t *)&packet->payload[x + 4])); + opt = &packet->payload[x + 6]; + /* TODO: parse the TLV list */ + if(opt_code == 0x03 && + opt_len <= rdata_len + 4 && + opt_len > 6 && + x + 6 + opt_len <= packet->payload_packet_len) { +#ifdef DNS_DEBUG + printf("[DNS] NSID: [%.*s]\n", opt_len, opt); +#endif + if(memcmp(opt, "gpdns-", 6) == 0) { +#ifdef DNS_DEBUG + printf("[DNS] NSID Airport code [%.*s]\n", opt_len - 6, opt + 6); +#endif + memcpy(flow->protos.dns.geolocation_iata_code, opt + 6, + ndpi_min(opt_len - 6, (int)sizeof(flow->protos.dns.geolocation_iata_code) - 1)); + } + } + + } } else { x += 6; } diff --git a/tests/cfgs/default/pcap/dns-google-nsid.pcapng b/tests/cfgs/default/pcap/dns-google-nsid.pcapng new file mode 100644 index 00000000000..b5442483a96 Binary files /dev/null and b/tests/cfgs/default/pcap/dns-google-nsid.pcapng differ diff --git a/tests/cfgs/default/result/dns-google-nsid.pcapng.out b/tests/cfgs/default/result/dns-google-nsid.pcapng.out new file mode 100644 index 00000000000..979ce883a43 --- /dev/null +++ b/tests/cfgs/default/result/dns-google-nsid.pcapng.out @@ -0,0 +1,33 @@ +Guessed flow protos: 0 + +DPI Packets (UDP): 14 (2.00 pkts/flow) +Confidence DPI : 7 (flows) +Num dissector calls: 7 (1.00 diss/flow) +LRU cache ookla: 0/0/0 (insert/search/found) +LRU cache bittorrent: 0/0/0 (insert/search/found) +LRU cache zoom: 0/0/0 (insert/search/found) +LRU cache stun: 0/0/0 (insert/search/found) +LRU cache tls_cert: 0/0/0 (insert/search/found) +LRU cache mining: 0/0/0 (insert/search/found) +LRU cache msteams: 0/0/0 (insert/search/found) +LRU cache stun_zoom: 0/0/0 (insert/search/found) +Automa host: 12/8 (search/found) +Automa domain: 12/0 (search/found) +Automa tls cert: 0/0 (search/found) +Automa risk mask: 6/0 (search/found) +Automa common alpns: 0/0 (search/found) +Patricia risk mask: 6/0 (search/found) +Patricia risk: 0/0 (search/found) +Patricia protocols: 3/3 (search/found) + +DNS 6 952 3 +ntop 4 514 2 +Wikipedia 4 704 2 + + 1 UDP [2001:b07:a3d:c112:b332:20d:89ab:105e]:41624 <-> [2001:4860:4860::8844]:53 [proto: 5/DNS][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 2][cat: Network/14][1 pkts/106 bytes <-> 1 pkts/314 bytes][Goodput ratio: 41/80][0.01 sec][::][GeoLocation: mil][PLAIN TEXT (servers)][Plen Bins: 0,50,0,0,0,0,0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + 2 UDP [2a03:b0c0:2:d0::360:4001]:44924 <-> [2001:4860:4860::8888]:53 [proto: 5.176/DNS.Wikipedia][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 2][cat: Network/14][1 pkts/123 bytes <-> 1 pkts/256 bytes][Goodput ratio: 49/75][0.20 sec][Hostname/SNI: www.wikipedia.it][18.67.39.58][GeoLocation: ams][PLAIN TEXT (wikipedia)][Plen Bins: 0,50,0,0,0,0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + 3 UDP 192.168.1.29:62500 <-> 8.8.4.4:53 [proto: 5.176/DNS.Wikipedia][IP: 126/Google][ClearText][Confidence: DPI][DPI packets: 2][cat: Network/14][1 pkts/91 bytes <-> 1 pkts/234 bytes][Goodput ratio: 53/82][0.27 sec][Hostname/SNI: www.wikipedia.it][108.157.194.28][PLAIN TEXT (wikipedia)][Plen Bins: 0,50,0,0,0,0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + 4 UDP [2a03:b0c0:2:d0::360:4001]:43660 <-> [2001:4860:4860::8888]:53 [proto: 5/DNS][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 2][cat: Network/14][1 pkts/124 bytes <-> 1 pkts/169 bytes][Goodput ratio: 50/63][0.01 sec][Hostname/SNI: www.wireshark.org][104.26.10.240][GeoLocation: ams][PLAIN TEXT (wireshark)][Plen Bins: 0,50,0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + 5 UDP [2a03:b0c0:2:d0::360:4001]:46618 <-> [2001:4860:4860::8888]:53 [proto: 5.26/DNS.ntop][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 2][cat: Network/14][1 pkts/119 bytes <-> 1 pkts/164 bytes][Goodput ratio: 47/62][0.02 sec][Hostname/SNI: www.ntop.org][178.62.197.130][GeoLocation: ams][PLAIN TEXT (digitalocean)][Plen Bins: 0,50,0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + 6 UDP 192.168.1.29:51166 <-> 8.8.4.4:53 [proto: 5/DNS][IP: 126/Google][ClearText][Confidence: DPI][DPI packets: 2][cat: Network/14][1 pkts/92 bytes <-> 1 pkts/147 bytes][Goodput ratio: 54/71][0.02 sec][Hostname/SNI: www.wireshark.org][104.26.10.240][PLAIN TEXT (wireshark)][Plen Bins: 0,50,0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + 7 UDP 192.168.1.29:58580 <-> 8.8.4.4:53 [proto: 5.26/DNS.ntop][IP: 126/Google][ClearText][Confidence: DPI][DPI packets: 2][cat: Network/14][1 pkts/87 bytes <-> 1 pkts/144 bytes][Goodput ratio: 51/70][0.03 sec][Hostname/SNI: www.ntop.org][178.62.197.130][GeoLocation: mil][PLAIN TEXT (digitalocean)][Plen Bins: 0,50,0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]