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:
61
nmap_dns.cc
61
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);
|
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";
|
||||||
|
|||||||
@@ -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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user