From 019557382b8f1e959fa914900c2cd1940fe5ed90 Mon Sep 17 00:00:00 2001 From: dmiller Date: Tue, 30 Apr 2024 16:39:21 +0000 Subject: [PATCH] mass_dns: Allow multiple addresses for each A/AAAA lookup --- nmap_dns.cc | 61 +++++++++++++++++++++++++++++---------------------- nmap_dns.h | 5 +++-- traceroute.cc | 4 ++-- 3 files changed, 40 insertions(+), 30 deletions(-) diff --git a/nmap_dns.cc b/nmap_dns.cc index ec92ef414..b7f7f7130 100644 --- a/nmap_dns.cc +++ b/nmap_dns.cc @@ -490,7 +490,8 @@ static void put_dns_packet_on_wire(request *req) { plen = DNS::Factory::buildSimpleRequest(reqt.name, reqt.type, packet, maxlen); break; case DNS::PTR: - plen = DNS::Factory::buildReverseRequest(reqt.ss, packet, maxlen); + assert(reqt.ssv.size() > 0); + plen = DNS::Factory::buildReverseRequest(reqt.ssv.front(), packet, maxlen); break; default: break; @@ -568,6 +569,7 @@ static int deal_with_timedout_reads() { total_reqs--; records.erase(tpreq->id); delete tpreq; + tpreq = NULL; // **** OR We start at the back of this server's queue //servItemp->to_process.push_back(tpreq); @@ -607,6 +609,7 @@ static void process_request(int action, info &reqinfo) { } else { delete tpreq; + tpreq = NULL; } break; @@ -636,7 +639,7 @@ static bool process_result(const std::string &name, const DNS::Record *rr, info return false; } a_rec = static_cast(rr); - memcpy(&reqt->ss, &a_rec->value, sizeof(struct sockaddr_storage)); + reqt->ssv.push_back(a_rec->value); if (o.debugging >= TRACE_DEBUG_LEVEL) { log_write(LOG_STDOUT, "mass_dns: OK MATCHED <%s> to <%s>\n", @@ -645,7 +648,7 @@ static bool process_result(const std::string &name, const DNS::Record *rr, info } break; case DNS::PTR: - ss = &reqt->ss; + ss = &reqt->ssv.front(); if (!already_matched) { if (!DNS::Factory::ptrToIp(name, ip) || !sockaddr_storage_equal(&ip, ss)) { @@ -666,15 +669,7 @@ static bool process_result(const std::string &name, const DNS::Record *rr, info break; } - process_request(ACTION_FINISHED, reqinfo); - - do_possible_writes(); - - // Close DNS servers if we're all done so that we kill - // all events and return from nsock_loop immediateley - if (total_reqs == 0) - close_dns_servers(); - return 1; + return true; } // Nsock read handler. One nsock read for each DNS server exists at each @@ -744,18 +739,14 @@ static void read_evt_handler(nsock_pool nsp, nsock_event evt, void *) { DNS::Request *reqt = reqinfo.tpreq->targ; for(std::list::const_iterator it = p.answers.begin(); - it != p.answers.end() && !processing_successful; ++it ) + it != p.answers.end(); ++it ) { const DNS::Answer &a = *it; if(a.record_class == DNS::CLASS_IN) { if (reqt->type == a.record_type) { processing_successful = process_result(a.name, a.record, reqinfo, a.name == alias); - if (processing_successful) { - output_summary(); - stat_ok++; - } - else if (o.debugging) { + if (!processing_successful && o.debugging) { log_write(LOG_STDOUT, "mass_dns: Mismatched record for request %s\n", reqt->repr()); } } @@ -795,6 +786,17 @@ static void read_evt_handler(nsock_pool nsp, nsock_event evt, void *) { } } } + else { + output_summary(); + stat_ok++; + process_request(ACTION_FINISHED, reqinfo); + } + do_possible_writes(); + + // Close DNS servers if we're all done so that we kill + // all events and return from nsock_loop immediateley + if (total_reqs == 0) + close_dns_servers(); } @@ -1077,7 +1079,8 @@ static bool system_resolve(DNS::Request &reqt) switch (reqt.type) { case DNS::PTR: - if (getnameinfo((const struct sockaddr *) &reqt.ss, + assert(reqt.ssv.size() > 0); + if (getnameinfo((const struct sockaddr *) &reqt.ssv.front(), sizeof(sockaddr_storage), hostname, sizeof(hostname), NULL, 0, NI_NAMEREQD) == 0) { reqt.name = hostname; @@ -1089,11 +1092,11 @@ static bool system_resolve(DNS::Request &reqt) case DNS::A: ai_result = resolve_all(reqt.name.c_str(), af); for (ai = ai_result; ai != NULL; ai = ai->ai_next) { - if (ai->ai_addr->sa_family == af && ai->ai_addrlen <= sizeof(reqt.ss)) { - memcpy(&reqt.ss, ai->ai_addr, ai->ai_addrlen); - return true; + if (ai->ai_addr->sa_family == af && ai->ai_addrlen <= sizeof(struct sockaddr_storage)) { + reqt.ssv.push_back(*(struct sockaddr_storage *)ai->ai_addr); } } + return true; break; default: error("System DNS resolution of %s could not be performed.\n", reqt.repr()); @@ -1134,10 +1137,12 @@ static void nmap_mass_dns_core(DNS::Request *requests, int num_requests) { for (int i=0; i < num_requests; i++) { DNS::Request &reqt = requests[i]; + assert(reqt.type == DNS::PTR || reqt.type == DNS::A || reqt.type == DNS::AAAA); // See if it's cached if (reqt.type == DNS::PTR) { - if (host_cache.lookup(reqt.ss, reqt.name)) { + assert(reqt.ssv.size() > 0); + if (host_cache.lookup(reqt.ssv.front(), reqt.name)) { continue; } } @@ -1299,8 +1304,7 @@ void nmap_mass_rdns(Target ** targets, int num_targets) { if (!(target->flags & HOST_UP) && !o.always_resolve) continue; DNS::Request &reqt = requests[i]; - size_t sslen = sizeof(struct sockaddr_storage); - target->TargetSockAddr(&reqt.ss, &sslen); + reqt.ssv.push_back(*target->TargetSockAddr()); reqt.type = DNS::PTR; } nmap_mass_dns(requests, num_targets); @@ -1782,7 +1786,12 @@ const char *DNS::Request::repr() return name.c_str(); break; case DNS::PTR: - return inet_ntop_ez(&ss, sizeof(ss)); + if (ssv.size() > 0) { + return inet_ntop_ez(&ssv.front(), sizeof(struct sockaddr_storage)); + } + else { + return "Uninitialized PTR request"; + } break; default: return "Invalid request"; diff --git a/nmap_dns.h b/nmap_dns.h index 9e0e1c165..440edea66 100644 --- a/nmap_dns.h +++ b/nmap_dns.h @@ -69,6 +69,7 @@ class Target; #include #include +#include #define DNS_LABEL_MAX_LENGTH 63 #define DNS_NAME_MAX_LENGTH 255 @@ -250,9 +251,9 @@ public: struct Request { RECORD_TYPE type; - struct sockaddr_storage ss; + std::vector ssv; std::string name; - Request() : type(NONE), name() {ss.ss_family = AF_UNSPEC;} + Request() : type(NONE), ssv(), name() {} const char *repr(); // string representation }; } diff --git a/traceroute.cc b/traceroute.cc index a1f9af0d1..f356a39ca 100644 --- a/traceroute.cc +++ b/traceroute.cc @@ -1350,7 +1350,7 @@ void TracerouteState::resolve_hops() { nmap_mass_dns. */ DNS::Request *requests = new DNS::Request[n]; for (i = 0, addr_iter = addrs.begin(); i < n; i++, addr_iter++) { - memcpy(&requests[i].ss, &*addr_iter, sizeof(*addr_iter)); + requests[i].ssv.push_back(*addr_iter); requests[i].type = DNS::PTR; } nmap_mass_dns(requests, n); @@ -1358,7 +1358,7 @@ void TracerouteState::resolve_hops() { for (i = 0; i < n; i++) { std::string &hostname = requests[i].name; if (!hostname.empty()) - name_map[requests[i].ss] = hostname.c_str(); + name_map[requests[i].ssv.front()] = hostname.c_str(); } /* Finally, copy the names into the hops. */ for (host_iter = hosts.begin(); host_iter != hosts.end(); host_iter++) {