1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 04:31:29 +00:00

mass_dns: Allow multiple addresses for each A/AAAA lookup

This commit is contained in:
dmiller
2024-04-30 16:39:21 +00:00
parent bf2acde232
commit 019557382b
3 changed files with 40 additions and 30 deletions

View File

@@ -490,7 +490,8 @@ static void put_dns_packet_on_wire(request *req) {
plen = DNS::Factory::buildSimpleRequest(reqt.name, reqt.type, packet, maxlen); plen = DNS::Factory::buildSimpleRequest(reqt.name, reqt.type, packet, maxlen);
break; break;
case DNS::PTR: 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; break;
default: default:
break; break;
@@ -568,6 +569,7 @@ static int deal_with_timedout_reads() {
total_reqs--; total_reqs--;
records.erase(tpreq->id); records.erase(tpreq->id);
delete tpreq; delete tpreq;
tpreq = NULL;
// **** OR We start at the back of this server's queue // **** OR We start at the back of this server's queue
//servItemp->to_process.push_back(tpreq); //servItemp->to_process.push_back(tpreq);
@@ -607,6 +609,7 @@ static void process_request(int action, info &reqinfo) {
} }
else { else {
delete tpreq; delete tpreq;
tpreq = NULL;
} }
break; break;
@@ -636,7 +639,7 @@ static bool process_result(const std::string &name, const DNS::Record *rr, info
return false; return false;
} }
a_rec = static_cast<const DNS::A_Record *>(rr); a_rec = static_cast<const DNS::A_Record *>(rr);
memcpy(&reqt->ss, &a_rec->value, sizeof(struct sockaddr_storage)); reqt->ssv.push_back(a_rec->value);
if (o.debugging >= TRACE_DEBUG_LEVEL) if (o.debugging >= TRACE_DEBUG_LEVEL)
{ {
log_write(LOG_STDOUT, "mass_dns: OK MATCHED <%s> to <%s>\n", 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; break;
case DNS::PTR: case DNS::PTR:
ss = &reqt->ss; ss = &reqt->ssv.front();
if (!already_matched) { if (!already_matched) {
if (!DNS::Factory::ptrToIp(name, ip) || if (!DNS::Factory::ptrToIp(name, ip) ||
!sockaddr_storage_equal(&ip, ss)) { !sockaddr_storage_equal(&ip, ss)) {
@@ -666,15 +669,7 @@ static bool process_result(const std::string &name, const DNS::Record *rr, info
break; break;
} }
process_request(ACTION_FINISHED, reqinfo); return true;
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;
} }
// Nsock read handler. One nsock read for each DNS server exists at each // 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; DNS::Request *reqt = reqinfo.tpreq->targ;
for(std::list<DNS::Answer>::const_iterator it = p.answers.begin(); for(std::list<DNS::Answer>::const_iterator it = p.answers.begin();
it != p.answers.end() && !processing_successful; ++it ) it != p.answers.end(); ++it )
{ {
const DNS::Answer &a = *it; const DNS::Answer &a = *it;
if(a.record_class == DNS::CLASS_IN) if(a.record_class == DNS::CLASS_IN)
{ {
if (reqt->type == a.record_type) { if (reqt->type == a.record_type) {
processing_successful = process_result(a.name, a.record, reqinfo, a.name == alias); processing_successful = process_result(a.name, a.record, reqinfo, a.name == alias);
if (processing_successful) { if (!processing_successful && o.debugging) {
output_summary();
stat_ok++;
}
else if (o.debugging) {
log_write(LOG_STDOUT, "mass_dns: Mismatched record for request %s\n", reqt->repr()); 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) { switch (reqt.type) {
case DNS::PTR: 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(sockaddr_storage), hostname,
sizeof(hostname), NULL, 0, NI_NAMEREQD) == 0) { sizeof(hostname), NULL, 0, NI_NAMEREQD) == 0) {
reqt.name = hostname; reqt.name = hostname;
@@ -1089,11 +1092,11 @@ static bool system_resolve(DNS::Request &reqt)
case DNS::A: case DNS::A:
ai_result = resolve_all(reqt.name.c_str(), af); ai_result = resolve_all(reqt.name.c_str(), af);
for (ai = ai_result; ai != NULL; ai = ai->ai_next) { for (ai = ai_result; ai != NULL; ai = ai->ai_next) {
if (ai->ai_addr->sa_family == af && ai->ai_addrlen <= sizeof(reqt.ss)) { if (ai->ai_addr->sa_family == af && ai->ai_addrlen <= sizeof(struct sockaddr_storage)) {
memcpy(&reqt.ss, ai->ai_addr, ai->ai_addrlen); reqt.ssv.push_back(*(struct sockaddr_storage *)ai->ai_addr);
return true;
} }
} }
return true;
break; break;
default: default:
error("System DNS resolution of %s could not be performed.\n", reqt.repr()); 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++) for (int i=0; i < num_requests; i++)
{ {
DNS::Request &reqt = 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 // See if it's cached
if (reqt.type == DNS::PTR) { 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; continue;
} }
} }
@@ -1299,8 +1304,7 @@ void nmap_mass_rdns(Target ** targets, int num_targets) {
if (!(target->flags & HOST_UP) && !o.always_resolve) continue; if (!(target->flags & HOST_UP) && !o.always_resolve) continue;
DNS::Request &reqt = requests[i]; DNS::Request &reqt = requests[i];
size_t sslen = sizeof(struct sockaddr_storage); reqt.ssv.push_back(*target->TargetSockAddr());
target->TargetSockAddr(&reqt.ss, &sslen);
reqt.type = DNS::PTR; reqt.type = DNS::PTR;
} }
nmap_mass_dns(requests, num_targets); nmap_mass_dns(requests, num_targets);
@@ -1782,7 +1786,12 @@ const char *DNS::Request::repr()
return name.c_str(); return name.c_str();
break; break;
case DNS::PTR: 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; break;
default: default:
return "Invalid request"; return "Invalid request";

View File

@@ -69,6 +69,7 @@ class Target;
#include <algorithm> #include <algorithm>
#include <sstream> #include <sstream>
#include <vector>
#define DNS_LABEL_MAX_LENGTH 63 #define DNS_LABEL_MAX_LENGTH 63
#define DNS_NAME_MAX_LENGTH 255 #define DNS_NAME_MAX_LENGTH 255
@@ -250,9 +251,9 @@ public:
struct Request struct Request
{ {
RECORD_TYPE type; RECORD_TYPE type;
struct sockaddr_storage ss; std::vector<struct sockaddr_storage> ssv;
std::string name; std::string name;
Request() : type(NONE), name() {ss.ss_family = AF_UNSPEC;} Request() : type(NONE), ssv(), name() {}
const char *repr(); // string representation const char *repr(); // string representation
}; };
} }

View File

@@ -1350,7 +1350,7 @@ void TracerouteState::resolve_hops() {
nmap_mass_dns. */ nmap_mass_dns. */
DNS::Request *requests = new DNS::Request[n]; DNS::Request *requests = new DNS::Request[n];
for (i = 0, addr_iter = addrs.begin(); i < n; i++, addr_iter++) { 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; requests[i].type = DNS::PTR;
} }
nmap_mass_dns(requests, n); nmap_mass_dns(requests, n);
@@ -1358,7 +1358,7 @@ void TracerouteState::resolve_hops() {
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
std::string &hostname = requests[i].name; std::string &hostname = requests[i].name;
if (!hostname.empty()) 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. */ /* Finally, copy the names into the hops. */
for (host_iter = hosts.begin(); host_iter != hosts.end(); host_iter++) { for (host_iter = hosts.begin(); host_iter != hosts.end(); host_iter++) {