mirror of
https://github.com/nmap/nmap.git
synced 2025-12-09 06:01:28 +00:00
Better CNAME handling in mass_rdns.
If mass_rdns gets a CNAME and PTR for that name in one answer, parse both. This means that the majority of CNAME answers can now be handled without falling back to system resolver. A test of 40K random IPs produced 21 CNAME answers, 18 of which had an associated PTR that was correctly parsed in this way.
This commit is contained in:
33
nmap_dns.cc
33
nmap_dns.cc
@@ -757,6 +757,10 @@ static void read_evt_handler(nsock_pool nsp, nsock_event evt, void *) {
|
||||
|
||||
bool processing_successful = false;
|
||||
|
||||
sockaddr_storage ip;
|
||||
ip.ss_family = AF_UNSPEC;
|
||||
std::string alias;
|
||||
|
||||
for(std::list<DNS::Answer>::const_iterator it = p.answers.begin();
|
||||
it != p.answers.end() && !processing_successful; ++it )
|
||||
{
|
||||
@@ -769,8 +773,11 @@ static void read_evt_handler(nsock_pool nsp, nsock_event evt, void *) {
|
||||
{
|
||||
DNS::PTR_Record * ptr = static_cast<DNS::PTR_Record *>(a.record);
|
||||
|
||||
sockaddr_storage ip;
|
||||
if(DNS::Factory::ptrToIp(a.name, ip))
|
||||
if(
|
||||
// If CNAME answer filled in ip with a matching alias
|
||||
(ip.ss_family != AF_UNSPEC && a.name == alias )
|
||||
// Or if we can get an IP from reversing the .arpa PTR address
|
||||
|| DNS::Factory::ptrToIp(a.name, ip))
|
||||
{
|
||||
if ((processing_successful = process_result(ip, ptr->value, ACTION_FINISHED, p.id)))
|
||||
{
|
||||
@@ -790,16 +797,16 @@ static void read_evt_handler(nsock_pool nsp, nsock_event evt, void *) {
|
||||
}
|
||||
case DNS::CNAME:
|
||||
{
|
||||
sockaddr_storage ip;
|
||||
if(DNS::Factory::ptrToIp(a.name, ip))
|
||||
{
|
||||
DNS::CNAME_Record * cname = static_cast<DNS::CNAME_Record *>(a.record);
|
||||
alias = cname->value;
|
||||
if (o.debugging >= TRACE_DEBUG_LEVEL)
|
||||
{
|
||||
char ipstr[INET6_ADDRSTRLEN];
|
||||
sockaddr_storage_iptop(&ip, ipstr);
|
||||
log_write(LOG_STDOUT, "mass_rdns: CNAME found for <%s>\n", ipstr);
|
||||
log_write(LOG_STDOUT, "mass_rdns: CNAME found for <%s> to <%s>\n", ipstr, alias.c_str());
|
||||
}
|
||||
processing_successful = process_result(ip, "", ACTION_SYSTEM_RESOLVE, p.id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -811,8 +818,20 @@ static void read_evt_handler(nsock_pool nsp, nsock_event evt, void *) {
|
||||
|
||||
if (!processing_successful) {
|
||||
if (DNS_HAS_FLAG(f, DNS::TRUNCATED)) {
|
||||
sockaddr_storage discard;
|
||||
process_result(discard, "", ACTION_SYSTEM_RESOLVE, p.id);
|
||||
// TODO: TCP fallback, or only use system resolver if user didn't specify --dns-servers
|
||||
process_result(ip, "", ACTION_SYSTEM_RESOLVE, p.id);
|
||||
}
|
||||
else if (!alias.empty()) {
|
||||
if (o.debugging >= TRACE_DEBUG_LEVEL)
|
||||
{
|
||||
char ipstr[INET6_ADDRSTRLEN];
|
||||
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
|
||||
// back to using system resolver. Alternative: report the canonical name
|
||||
// (alias), but that's not very useful.
|
||||
process_result(ip, "", ACTION_SYSTEM_RESOLVE, p.id);
|
||||
}
|
||||
else {
|
||||
if (o.debugging >= TRACE_DEBUG_LEVEL) {
|
||||
|
||||
Reference in New Issue
Block a user