mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Generalize nmap_mass_rdns to support more than just Targets and PTR requests
This commit is contained in:
243
nmap_dns.cc
243
nmap_dns.cc
@@ -219,7 +219,7 @@ struct dns_server {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct request {
|
struct request {
|
||||||
Target *targ;
|
DNS::Request *targ;
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
int tries;
|
int tries;
|
||||||
int servers_tried;
|
int servers_tried;
|
||||||
@@ -447,7 +447,7 @@ static void do_possible_writes() {
|
|||||||
|
|
||||||
if (tpreq) {
|
if (tpreq) {
|
||||||
if (o.debugging >= TRACE_DEBUG_LEVEL)
|
if (o.debugging >= TRACE_DEBUG_LEVEL)
|
||||||
log_write(LOG_STDOUT, "mass_rdns: TRANSMITTING for <%s> (server <%s>)\n", tpreq->targ->targetipstr() , servI->hostname.c_str());
|
log_write(LOG_STDOUT, "mass_rdns: TRANSMITTING for <%s> (server <%s>)\n", tpreq->targ->repr(), servI->hostname.c_str());
|
||||||
stat_trans++;
|
stat_trans++;
|
||||||
put_dns_packet_on_wire(tpreq);
|
put_dns_packet_on_wire(tpreq);
|
||||||
}
|
}
|
||||||
@@ -483,8 +483,19 @@ static void put_dns_packet_on_wire(request *req) {
|
|||||||
req->id = DNS::Factory::progressiveId;
|
req->id = DNS::Factory::progressiveId;
|
||||||
req->curr_server->write_busy = 1;
|
req->curr_server->write_busy = 1;
|
||||||
req->curr_server->reqs_on_wire++;
|
req->curr_server->reqs_on_wire++;
|
||||||
|
DNS::Request &reqt = *req->targ;
|
||||||
|
|
||||||
plen = DNS::Factory::buildReverseRequest(*req->targ->TargetSockAddr(), packet, maxlen);
|
switch(reqt.type) {
|
||||||
|
case DNS::A:
|
||||||
|
case DNS::AAAA:
|
||||||
|
plen = DNS::Factory::buildSimpleRequest(reqt.name, reqt.type, packet, maxlen);
|
||||||
|
break;
|
||||||
|
case DNS::PTR:
|
||||||
|
plen = DNS::Factory::buildReverseRequest(reqt.ss, packet, maxlen);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(&now, nsock_gettimeofday(), sizeof(struct timeval));
|
memcpy(&now, nsock_gettimeofday(), sizeof(struct timeval));
|
||||||
TIMEVAL_MSEC_ADD(timeout, now, read_timeouts[read_timeout_index][req->tries]);
|
TIMEVAL_MSEC_ADD(timeout, now, read_timeouts[read_timeout_index][req->tries]);
|
||||||
@@ -551,7 +562,7 @@ static int deal_with_timedout_reads() {
|
|||||||
// FIXME: Find a good compromise
|
// FIXME: Find a good compromise
|
||||||
|
|
||||||
// **** We've already tried all servers... give up
|
// **** We've already tried all servers... give up
|
||||||
if (o.debugging >= TRACE_DEBUG_LEVEL) log_write(LOG_STDOUT, "mass_rdns: *DR*OPPING <%s>\n", tpreq->targ->targetipstr());
|
if (o.debugging >= TRACE_DEBUG_LEVEL) log_write(LOG_STDOUT, "mass_rdns: *DR*OPPING <%s>\n", tpreq->targ->repr());
|
||||||
|
|
||||||
output_summary();
|
output_summary();
|
||||||
stat_dropped++;
|
stat_dropped++;
|
||||||
@@ -579,60 +590,67 @@ static int deal_with_timedout_reads() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// After processing a DNS response, we search through the IPs we're
|
static void process_request(int action, info &reqinfo) {
|
||||||
// looking for and update their results as necessary.
|
request *tpreq = reqinfo.tpreq;
|
||||||
// Returns non-zero if this matches a query we're looking for
|
dns_server *server = reqinfo.server;
|
||||||
static int process_result(const sockaddr_storage &ip, const std::string &result, int action, u16 id)
|
|
||||||
{
|
|
||||||
request *tpreq;
|
|
||||||
std::map<u16, info>::iterator infoI;
|
|
||||||
dns_server *server;
|
|
||||||
|
|
||||||
infoI = records.find(id);
|
switch (action) {
|
||||||
|
case ACTION_SYSTEM_RESOLVE:
|
||||||
if( infoI != records.end() ){
|
case ACTION_FINISHED:
|
||||||
|
|
||||||
tpreq = infoI->second.tpreq;
|
|
||||||
server = infoI->second.server;
|
|
||||||
|
|
||||||
if( !result.empty() && !sockaddr_storage_equal(&ip, tpreq->targ->TargetSockAddr()) )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (action == ACTION_SYSTEM_RESOLVE || action == ACTION_FINISHED)
|
|
||||||
{
|
|
||||||
server->capacity += CAPACITY_UP_STEP;
|
server->capacity += CAPACITY_UP_STEP;
|
||||||
check_capacities(&*server);
|
check_capacities(&*server);
|
||||||
|
records.erase(tpreq->id);
|
||||||
if(!result.empty())
|
|
||||||
{
|
|
||||||
tpreq->targ->setHostName(result.c_str());
|
|
||||||
host_cache.add(* tpreq->targ->TargetSockAddr(), result);
|
|
||||||
}
|
|
||||||
|
|
||||||
records.erase(infoI);
|
|
||||||
server->in_process.remove(tpreq);
|
server->in_process.remove(tpreq);
|
||||||
server->reqs_on_wire--;
|
server->reqs_on_wire--;
|
||||||
|
|
||||||
total_reqs--;
|
total_reqs--;
|
||||||
|
if (action == ACTION_SYSTEM_RESOLVE) {
|
||||||
|
deferred_reqs.push_back(tpreq);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
delete tpreq;
|
||||||
|
}
|
||||||
|
|
||||||
if (action == ACTION_SYSTEM_RESOLVE) deferred_reqs.push_back(tpreq);
|
break;
|
||||||
if (action == ACTION_FINISHED) delete tpreq;
|
case ACTION_TIMEOUT:
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy(&tpreq->timeout, nsock_gettimeofday(), sizeof(struct timeval));
|
memcpy(&tpreq->timeout, nsock_gettimeofday(), sizeof(struct timeval));
|
||||||
deal_with_timedout_reads();
|
deal_with_timedout_reads();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// After processing a DNS response, we search through the IPs we're
|
||||||
|
// looking for and update their results as necessary.
|
||||||
|
static int process_result(const sockaddr_storage &ip, const std::string &result, int action, info &reqinfo)
|
||||||
|
{
|
||||||
|
assert(action == ACTION_FINISHED);
|
||||||
|
request *tpreq = reqinfo.tpreq;
|
||||||
|
|
||||||
|
if (!result.empty())
|
||||||
|
{
|
||||||
|
if (!sockaddr_storage_equal(&ip, &tpreq->targ->ss))
|
||||||
|
{
|
||||||
|
if (o.debugging)
|
||||||
|
log_write(LOG_STDOUT, "mass_rdns: Mismatched record for ID %d\n", tpreq->id);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
do_possible_writes();
|
|
||||||
|
|
||||||
// Close DNS servers if we're all done so that we kill
|
tpreq->targ->name = result;
|
||||||
// all events and return from nsock_loop immediateley
|
host_cache.add(tpreq->targ->ss, result);
|
||||||
if (total_reqs == 0)
|
|
||||||
close_dns_servers();
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
process_request(action, 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
@@ -666,29 +684,30 @@ static void read_evt_handler(nsock_pool nsp, nsock_event evt, void *) {
|
|||||||
DNS_HAS_ERR(f, DNS::ERR_NOT_IMPLEMENTED) || DNS_HAS_ERR(f, DNS::ERR_REFUSED))
|
DNS_HAS_ERR(f, DNS::ERR_NOT_IMPLEMENTED) || DNS_HAS_ERR(f, DNS::ERR_REFUSED))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Check for matching request
|
||||||
|
std::map<u16, info>::iterator infoI = records.find(p.id);
|
||||||
|
if (infoI == records.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
info &reqinfo = infoI->second;
|
||||||
|
|
||||||
if (DNS_HAS_ERR(f, DNS::ERR_NAME))
|
if (DNS_HAS_ERR(f, DNS::ERR_NAME))
|
||||||
{
|
{
|
||||||
sockaddr_storage discard;
|
process_request(ACTION_FINISHED, reqinfo);
|
||||||
if(process_result(discard, "", ACTION_FINISHED, p.id))
|
if (o.debugging >= TRACE_DEBUG_LEVEL)
|
||||||
{
|
log_write(LOG_STDOUT, "mass_rdns: NXDOMAIN <id = %d>\n", p.id);
|
||||||
if (o.debugging >= TRACE_DEBUG_LEVEL)
|
output_summary();
|
||||||
log_write(LOG_STDOUT, "mass_rdns: NXDOMAIN <id = %d>\n", p.id);
|
stat_nx++;
|
||||||
output_summary();
|
|
||||||
stat_nx++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DNS_HAS_ERR(f, DNS::ERR_SERVFAIL))
|
if (DNS_HAS_ERR(f, DNS::ERR_SERVFAIL))
|
||||||
{
|
{
|
||||||
sockaddr_storage discard;
|
process_request(ACTION_TIMEOUT, reqinfo);
|
||||||
if (process_result(discard, "", ACTION_TIMEOUT, p.id))
|
if (o.debugging >= TRACE_DEBUG_LEVEL)
|
||||||
{
|
log_write(LOG_STDOUT, "mass_rdns: SERVFAIL <id = %d>\n", p.id);
|
||||||
if (o.debugging >= TRACE_DEBUG_LEVEL)
|
stat_sf++;
|
||||||
log_write(LOG_STDOUT, "mass_rdns: SERVFAIL <id = %d>\n", p.id);
|
|
||||||
stat_sf++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -717,7 +736,7 @@ static void read_evt_handler(nsock_pool nsp, nsock_event evt, void *) {
|
|||||||
// Or if we can get an IP from reversing the .arpa PTR address
|
// Or if we can get an IP from reversing the .arpa PTR address
|
||||||
|| DNS::Factory::ptrToIp(a.name, ip))
|
|| DNS::Factory::ptrToIp(a.name, ip))
|
||||||
{
|
{
|
||||||
if ((processing_successful = process_result(ip, ptr->value, ACTION_FINISHED, p.id)))
|
if ((processing_successful = process_result(ip, ptr->value, ACTION_FINISHED, reqinfo)))
|
||||||
{
|
{
|
||||||
if (o.debugging >= TRACE_DEBUG_LEVEL)
|
if (o.debugging >= TRACE_DEBUG_LEVEL)
|
||||||
{
|
{
|
||||||
@@ -757,19 +776,17 @@ static void read_evt_handler(nsock_pool nsp, nsock_event evt, void *) {
|
|||||||
if (!processing_successful) {
|
if (!processing_successful) {
|
||||||
if (DNS_HAS_FLAG(f, DNS::TRUNCATED)) {
|
if (DNS_HAS_FLAG(f, DNS::TRUNCATED)) {
|
||||||
// TODO: TCP fallback, or only use system resolver if user didn't specify --dns-servers
|
// TODO: TCP fallback, or only use system resolver if user didn't specify --dns-servers
|
||||||
process_result(ip, "", ACTION_SYSTEM_RESOLVE, p.id);
|
process_request(ACTION_SYSTEM_RESOLVE, reqinfo);
|
||||||
}
|
}
|
||||||
else if (!alias.empty()) {
|
else if (!alias.empty()) {
|
||||||
if (o.debugging >= TRACE_DEBUG_LEVEL)
|
if (o.debugging >= TRACE_DEBUG_LEVEL)
|
||||||
{
|
{
|
||||||
char ipstr[INET6_ADDRSTRLEN];
|
log_write(LOG_STDOUT, "mass_rdns: CNAME for <%s> not processed.\n", reqinfo.tpreq->targ->repr());
|
||||||
sockaddr_storage_iptop(&ip, ipstr);
|
|
||||||
log_write(LOG_STDOUT, "mass_rdns: CNAME for <%s> not processed.\n", ipstr);
|
|
||||||
}
|
}
|
||||||
// TODO: Send a PTR request for alias instead. Meanwhile, we'll just fall
|
// TODO: Send a PTR request for alias instead. Meanwhile, we'll just fall
|
||||||
// back to using system resolver. Alternative: report the canonical name
|
// back to using system resolver. Alternative: report the canonical name
|
||||||
// (alias), but that's not very useful.
|
// (alias), but that's not very useful.
|
||||||
process_result(ip, "", ACTION_SYSTEM_RESOLVE, p.id);
|
process_request(ACTION_SYSTEM_RESOLVE, reqinfo);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (o.debugging >= TRACE_DEBUG_LEVEL) {
|
if (o.debugging >= TRACE_DEBUG_LEVEL) {
|
||||||
@@ -1056,12 +1073,11 @@ static void init_servs(void) {
|
|||||||
|
|
||||||
|
|
||||||
// Actual main loop
|
// Actual main loop
|
||||||
static void nmap_mass_rdns_core(Target **targets, int num_targets) {
|
static void nmap_mass_dns_core(DNS::Request *requests, int num_requests) {
|
||||||
|
|
||||||
std::list<request *>::iterator reqI;
|
std::list<request *>::iterator reqI;
|
||||||
request *tpreq;
|
request *tpreq;
|
||||||
int timeout;
|
int timeout;
|
||||||
const char *tpname;
|
|
||||||
int i;
|
int i;
|
||||||
char spmobuf[1024];
|
char spmobuf[1024];
|
||||||
|
|
||||||
@@ -1082,21 +1098,17 @@ static void nmap_mass_rdns_core(Target **targets, int num_targets) {
|
|||||||
total_reqs = 0;
|
total_reqs = 0;
|
||||||
|
|
||||||
// Set up the request structure
|
// Set up the request structure
|
||||||
for (int i=0; i < num_targets; i++)
|
for (int i=0; i < num_requests; i++)
|
||||||
{
|
{
|
||||||
Target *target = targets[i];
|
DNS::Request &reqt = requests[i];
|
||||||
if (!(target->flags & HOST_UP) && !o.always_resolve) continue;
|
|
||||||
|
|
||||||
// See if it's cached
|
// See if it's cached
|
||||||
std::string res;
|
if (host_cache.lookup(reqt.ss, reqt.name)) {
|
||||||
if (host_cache.lookup(*target->TargetSockAddr(), res)) {
|
|
||||||
tpname = res.c_str();
|
|
||||||
target->setHostName(tpname);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
tpreq = new request;
|
tpreq = new request;
|
||||||
tpreq->targ = target;
|
tpreq->targ = &reqt;
|
||||||
tpreq->tries = 0;
|
tpreq->tries = 0;
|
||||||
tpreq->servers_tried = 0;
|
tpreq->servers_tried = 0;
|
||||||
|
|
||||||
@@ -1165,12 +1177,12 @@ static void nmap_mass_rdns_core(Target **targets, int num_targets) {
|
|||||||
|
|
||||||
tpreq = *reqI;
|
tpreq = *reqI;
|
||||||
|
|
||||||
if (getnameinfo((const struct sockaddr *)tpreq->targ->TargetSockAddr(),
|
if (getnameinfo((const struct sockaddr *)&tpreq->targ->ss,
|
||||||
sizeof(struct sockaddr_storage), hostname,
|
sizeof(struct sockaddr_storage), hostname,
|
||||||
sizeof(hostname), NULL, 0, NI_NAMEREQD) == 0) {
|
sizeof(hostname), NULL, 0, NI_NAMEREQD) == 0) {
|
||||||
stat_ok++;
|
stat_ok++;
|
||||||
stat_cname++;
|
stat_cname++;
|
||||||
tpreq->targ->setHostName(hostname);
|
tpreq->targ->name = hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete tpreq;
|
delete tpreq;
|
||||||
@@ -1185,35 +1197,26 @@ static void nmap_mass_rdns_core(Target **targets, int num_targets) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nmap_system_rdns_core(Target **targets, int num_targets) {
|
static void nmap_system_dns_core(DNS::Request requests[], int num_requests) {
|
||||||
char hostname[FQDN_LEN + 1] = "";
|
char hostname[FQDN_LEN + 1] = "";
|
||||||
char spmobuf[1024];
|
char spmobuf[1024];
|
||||||
int i;
|
|
||||||
|
|
||||||
for (int i=0; i < num_targets; i++)
|
|
||||||
{
|
|
||||||
Target *currenths = targets[i];
|
|
||||||
|
|
||||||
if (((currenths->flags & HOST_UP) || o.always_resolve) && !o.noresolve) stat_actual++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
stat_actual = num_requests;
|
||||||
Snprintf(spmobuf, sizeof(spmobuf), "System DNS resolution of %d host%s.", stat_actual, stat_actual-1 ? "s" : "");
|
Snprintf(spmobuf, sizeof(spmobuf), "System DNS resolution of %d host%s.", stat_actual, stat_actual-1 ? "s" : "");
|
||||||
SPM = new ScanProgressMeter(spmobuf);
|
SPM = new ScanProgressMeter(spmobuf);
|
||||||
|
|
||||||
for (int i=0; i < num_targets; i++)
|
for (int i=0; i < num_requests; i++)
|
||||||
{
|
{
|
||||||
Target *currenths = targets[i];
|
DNS::Request &reqt = requests[i];
|
||||||
|
|
||||||
if (keyWasPressed())
|
if (keyWasPressed())
|
||||||
SPM->printStats((double) i / stat_actual, NULL);
|
SPM->printStats((double) i / stat_actual, NULL);
|
||||||
|
|
||||||
if (((currenths->flags & HOST_UP) || o.always_resolve) && !o.noresolve) {
|
if (getnameinfo((const struct sockaddr *)&reqt.ss,
|
||||||
if (getnameinfo((struct sockaddr *)currenths->TargetSockAddr(),
|
sizeof(sockaddr_storage), hostname,
|
||||||
sizeof(sockaddr_storage), hostname,
|
sizeof(hostname), NULL, 0, NI_NAMEREQD) == 0) {
|
||||||
sizeof(hostname), NULL, 0, NI_NAMEREQD) == 0) {
|
stat_ok++;
|
||||||
stat_ok++;
|
reqt.name = hostname;
|
||||||
currenths->setHostName(hostname);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1224,7 +1227,7 @@ static void nmap_system_rdns_core(Target **targets, int num_targets) {
|
|||||||
|
|
||||||
// Publicly available function. Basically just a wrapper so we
|
// Publicly available function. Basically just a wrapper so we
|
||||||
// can record time information, restart statistics, etc.
|
// can record time information, restart statistics, etc.
|
||||||
void nmap_mass_rdns(Target **targets, int num_targets) {
|
void nmap_mass_dns(DNS::Request requests[], int num_requests) {
|
||||||
|
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
|
|
||||||
@@ -1233,9 +1236,9 @@ void nmap_mass_rdns(Target **targets, int num_targets) {
|
|||||||
stat_actual = stat_ok = stat_nx = stat_sf = stat_trans = stat_dropped = stat_cname = 0;
|
stat_actual = stat_ok = stat_nx = stat_sf = stat_trans = stat_dropped = stat_cname = 0;
|
||||||
|
|
||||||
if (o.mass_dns)
|
if (o.mass_dns)
|
||||||
nmap_mass_rdns_core(targets, num_targets);
|
nmap_mass_dns_core(requests, num_requests);
|
||||||
else
|
else
|
||||||
nmap_system_rdns_core(targets, num_targets);
|
nmap_system_dns_core(requests, num_requests);
|
||||||
|
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, NULL);
|
||||||
|
|
||||||
@@ -1263,6 +1266,29 @@ void nmap_mass_rdns(Target **targets, int num_targets) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void nmap_mass_rdns(Target ** targets, int num_targets) {
|
||||||
|
/* Second, make an array of pointer to DNS::Request to suit the interface of
|
||||||
|
nmap_mass_rdns. */
|
||||||
|
DNS::Request *requests = new DNS::Request[num_targets];
|
||||||
|
for (int i = 0; i < num_targets; i++) {
|
||||||
|
Target *target = targets[i];
|
||||||
|
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.type = DNS::PTR;
|
||||||
|
}
|
||||||
|
nmap_mass_dns(requests, num_targets);
|
||||||
|
for (int i = 0; i < num_targets; i++) {
|
||||||
|
std::string &name = requests[i].name;
|
||||||
|
if (!name.empty()) {
|
||||||
|
targets[i]->setHostName(name.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete[] requests;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns a list of known DNS servers
|
// Returns a list of known DNS servers
|
||||||
std::list<std::string> get_dns_servers() {
|
std::list<std::string> get_dns_servers() {
|
||||||
init_servs();
|
init_servs();
|
||||||
@@ -1695,3 +1721,22 @@ size_t DNS::Packet::parseFromBuffer(const u8 *buf, size_t maxlen)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *DNS::Request::repr()
|
||||||
|
{
|
||||||
|
switch(type) {
|
||||||
|
case DNS::NONE:
|
||||||
|
return "Uninitialized request";
|
||||||
|
break;
|
||||||
|
case DNS::A:
|
||||||
|
case DNS::AAAA:
|
||||||
|
return name.c_str();
|
||||||
|
break;
|
||||||
|
case DNS::PTR:
|
||||||
|
return inet_ntop_ez(&ss, sizeof(ss));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return "Invalid request";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
11
nmap_dns.h
11
nmap_dns.h
@@ -122,6 +122,7 @@ typedef enum {
|
|||||||
} ERRORS;
|
} ERRORS;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
NONE = 0,
|
||||||
A = 1,
|
A = 1,
|
||||||
CNAME = 5,
|
CNAME = 5,
|
||||||
PTR = 12,
|
PTR = 12,
|
||||||
@@ -244,8 +245,18 @@ public:
|
|||||||
std::list<Answer> answers;
|
std::list<Answer> answers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Request
|
||||||
|
{
|
||||||
|
RECORD_TYPE type;
|
||||||
|
struct sockaddr_storage ss;
|
||||||
|
std::string name;
|
||||||
|
Request() : type(NONE), name() {}
|
||||||
|
const char *repr(); // string representation
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void nmap_mass_dns(DNS::Request requests[], int num_requests);
|
||||||
void nmap_mass_rdns(Target ** targets, int num_targets);
|
void nmap_mass_rdns(Target ** targets, int num_targets);
|
||||||
|
|
||||||
std::list<std::string> get_dns_servers();
|
std::list<std::string> get_dns_servers();
|
||||||
|
|||||||
@@ -1333,7 +1333,6 @@ void TracerouteState::resolve_hops() {
|
|||||||
std::set<sockaddr_storage, lt_sockaddr_storage>::iterator addr_iter;
|
std::set<sockaddr_storage, lt_sockaddr_storage>::iterator addr_iter;
|
||||||
std::vector<HostState *>::iterator host_iter;
|
std::vector<HostState *>::iterator host_iter;
|
||||||
std::map<sockaddr_storage, const char *, lt_sockaddr_storage> name_map;
|
std::map<sockaddr_storage, const char *, lt_sockaddr_storage> name_map;
|
||||||
Target **targets;
|
|
||||||
Hop *hop;
|
Hop *hop;
|
||||||
int i, n;
|
int i, n;
|
||||||
|
|
||||||
@@ -1347,43 +1346,32 @@ void TracerouteState::resolve_hops() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
n = addrs.size();
|
n = addrs.size();
|
||||||
/* Second, make an array of pointer to Target to suit the interface of
|
/* Second, make an array of pointer to DNS::Request to suit the interface of
|
||||||
nmap_mass_rdns. */
|
nmap_mass_dns. */
|
||||||
targets = (Target **) safe_malloc(sizeof(*targets) * n);
|
DNS::Request *requests = new DNS::Request[n];
|
||||||
i = 0;
|
for (i = 0, addr_iter = addrs.begin(); i < n; i++, addr_iter++) {
|
||||||
addr_iter = addrs.begin();
|
memcpy(&requests[i].ss, &*addr_iter, sizeof(*addr_iter));
|
||||||
while (i < n) {
|
requests[i].type = DNS::PTR;
|
||||||
targets[i] = new Target();
|
|
||||||
targets[i]->setTargetSockAddr(&*addr_iter, sizeof(*addr_iter));
|
|
||||||
targets[i]->flags = HOST_UP;
|
|
||||||
i++;
|
|
||||||
addr_iter++;
|
|
||||||
}
|
}
|
||||||
nmap_mass_rdns(targets, n);
|
nmap_mass_dns(requests, n);
|
||||||
/* Third, make a map from addresses to names for easy lookup. */
|
/* Third, make a map from addresses to names for easy lookup. */
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
struct sockaddr_storage ss;
|
std::string &hostname = requests[i].name;
|
||||||
size_t ss_len;
|
if (!hostname.empty())
|
||||||
const char *hostname = targets[i]->HostName();
|
name_map[requests[i].ss] = hostname.c_str();
|
||||||
if (*hostname == '\0')
|
|
||||||
hostname = NULL;
|
|
||||||
ss_len = sizeof(ss);
|
|
||||||
targets[i]->TargetSockAddr(&ss, &ss_len);
|
|
||||||
name_map[ss] = hostname;
|
|
||||||
}
|
}
|
||||||
/* 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++) {
|
||||||
for (hop = (*host_iter)->hops; hop != NULL; hop = hop->parent) {
|
for (hop = (*host_iter)->hops; hop != NULL; hop = hop->parent) {
|
||||||
if (hop->addr.ss_family != AF_UNSPEC) {
|
if (hop->addr.ss_family != AF_UNSPEC) {
|
||||||
const char *hostname = name_map[hop->addr];
|
std::map<sockaddr_storage, const char *, lt_sockaddr_storage>::const_iterator it;
|
||||||
if (hostname != NULL)
|
it = name_map.find(hop->addr);
|
||||||
hop->hostname = hostname;
|
if (it != name_map.end())
|
||||||
|
hop->hostname = it->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < n; i++)
|
delete [] requests;
|
||||||
delete targets[i];
|
|
||||||
free(targets);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TracerouteState::transfer_hops() {
|
void TracerouteState::transfer_hops() {
|
||||||
|
|||||||
Reference in New Issue
Block a user