mirror of
https://github.com/nmap/nmap.git
synced 2025-12-07 13:11:28 +00:00
Handle uppercase PTR records. Fixes #2068
This commit is contained in:
@@ -1,5 +1,9 @@
|
|||||||
#Nmap Changelog ($Id$); -*-text-*-
|
#Nmap Changelog ($Id$); -*-text-*-
|
||||||
|
|
||||||
|
o [GH#2068] Fix reverse-DNS handling of PTR records that are not lowercase.
|
||||||
|
Nmap was failing to identify reverse-DNS names when the DNS server delivered
|
||||||
|
them like ".IN-ADDR.ARPA". [Lucas Nussbaum, Daniel Miller]
|
||||||
|
|
||||||
o [NSE][GH#1999][GH#2005] IKE library was not properly populating the protocol
|
o [NSE][GH#1999][GH#2005] IKE library was not properly populating the protocol
|
||||||
number in aggressive mode requests. [luc-x41]
|
number in aggressive mode requests. [luc-x41]
|
||||||
|
|
||||||
|
|||||||
107
nmap_dns.cc
107
nmap_dns.cc
@@ -1414,53 +1414,94 @@ bool DNS::Factory::ipToPtr(const sockaddr_storage &ip, std::string &ptr)
|
|||||||
|
|
||||||
bool DNS::Factory::ptrToIp(const std::string &ptr, sockaddr_storage &ip)
|
bool DNS::Factory::ptrToIp(const std::string &ptr, sockaddr_storage &ip)
|
||||||
{
|
{
|
||||||
std::string ip_str;
|
const char *cptr = ptr.c_str();
|
||||||
|
const char *p = NULL;
|
||||||
|
|
||||||
size_t pos = ptr.rfind(IPV6_PTR_DOMAIN);
|
memset(&ip, 0, sizeof(sockaddr_storage));
|
||||||
if(pos != std::string::npos)
|
|
||||||
|
// Check whether the name ends with the IPv4 PTR domain
|
||||||
|
if (NULL != (p = strcasestr(cptr + ptr.length() + 1 - sizeof(C_IPV4_PTR_DOMAIN), C_IPV4_PTR_DOMAIN)))
|
||||||
{
|
{
|
||||||
u8 counter = 0;
|
struct sockaddr_in *ip4 = (struct sockaddr_in *)&ip;
|
||||||
for (std::string::const_reverse_iterator it = ptr.rend()-pos; it != ptr.rend(); ++it)
|
u8 place_value[] = {1, 10, 100};
|
||||||
|
u8 *v = (u8 *) &(ip4->sin_addr.s_addr);
|
||||||
|
size_t place = 0;
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
p--;
|
||||||
|
while (i < sizeof(ip4->sin_addr.s_addr))
|
||||||
{
|
{
|
||||||
const char &c = *it;
|
if (*p == '.')
|
||||||
if(c != '.')
|
|
||||||
{
|
{
|
||||||
ip_str += c;
|
place = 0;
|
||||||
if(++counter==4) counter=0, ip_str+=':';
|
p--;
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
|
if (p < cptr)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
u8 n = *p;
|
||||||
|
if (n >= '0' && n <= '9') { // 0-9
|
||||||
|
n -= 0x30;
|
||||||
|
}
|
||||||
|
else { // invalid
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
v[i] += n * place_value[place];
|
||||||
|
place++;
|
||||||
|
p--;
|
||||||
}
|
}
|
||||||
|
ip.ss_family = AF_INET;
|
||||||
std::string::iterator it = ip_str.end()-1;
|
|
||||||
if( *it == ':') ip_str.erase(it);
|
|
||||||
}
|
}
|
||||||
|
// If not, check IPv6
|
||||||
std::string mptr = '.' + ptr;
|
else if (NULL != (p = strcasestr(cptr + ptr.length() + 1 - sizeof(C_IPV6_PTR_DOMAIN), C_IPV6_PTR_DOMAIN)))
|
||||||
pos = mptr.rfind(IPV4_PTR_DOMAIN);
|
|
||||||
if(pos != std::string::npos)
|
|
||||||
{
|
{
|
||||||
|
struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *)&ip;
|
||||||
|
u8 alt = 0;
|
||||||
|
size_t i=0;
|
||||||
|
|
||||||
std::string octet;
|
p--;
|
||||||
std::string::const_reverse_iterator crend = mptr.rend();
|
while (i < sizeof(ip6->sin6_addr.s6_addr))
|
||||||
for (std::string::const_reverse_iterator it = crend-pos; it != crend; ++it)
|
|
||||||
{
|
{
|
||||||
const char &c = *it;
|
if (*p == '.')
|
||||||
if(c == '.')
|
|
||||||
{
|
{
|
||||||
std::reverse(octet.begin(), octet.end());
|
p--;
|
||||||
ip_str += octet + '.';
|
|
||||||
octet.clear();
|
|
||||||
}
|
}
|
||||||
else octet += c;
|
if (p < cptr)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
u8 n = *p;
|
||||||
|
if (n < 0x3A) { // 0-9
|
||||||
|
n -= 0x30;
|
||||||
|
}
|
||||||
|
else if (n < 0x47) { // A-F
|
||||||
|
n -= 0x37;
|
||||||
|
}
|
||||||
|
else if (n < 0x67) { // a-f
|
||||||
|
n -= 0x57;
|
||||||
|
}
|
||||||
|
else { // invalid
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (n < 0) { // invalid
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (alt == 0) { // high nibble
|
||||||
|
ip6->sin6_addr.s6_addr[i] += n << 4;
|
||||||
|
alt = 1;
|
||||||
|
}
|
||||||
|
else { // low nibble
|
||||||
|
ip6->sin6_addr.s6_addr[i] += n;
|
||||||
|
alt = 0;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
p--;
|
||||||
}
|
}
|
||||||
|
ip.ss_family = AF_INET6;
|
||||||
std::string::iterator it = ip_str.end()-1;
|
|
||||||
if( *it == '.') ip_str.erase(it);
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
if(ip_str.empty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return sockaddr_storage_inet_pton(ip_str.c_str(), &ip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t DNS::Factory::buildSimpleRequest(const std::string &name, RECORD_TYPE rt, u8 *buf, size_t maxlen)
|
size_t DNS::Factory::buildSimpleRequest(const std::string &name, RECORD_TYPE rt, u8 *buf, size_t maxlen)
|
||||||
|
|||||||
@@ -201,8 +201,10 @@ typedef enum {
|
|||||||
|
|
||||||
const u8 COMPRESSED_NAME = 0xc0;
|
const u8 COMPRESSED_NAME = 0xc0;
|
||||||
|
|
||||||
const std::string IPV4_PTR_DOMAIN = ".in-addr.arpa";
|
#define C_IPV4_PTR_DOMAIN ".in-addr.arpa"
|
||||||
const std::string IPV6_PTR_DOMAIN = ".ip6.arpa";
|
#define C_IPV6_PTR_DOMAIN ".ip6.arpa"
|
||||||
|
const std::string IPV4_PTR_DOMAIN = C_IPV4_PTR_DOMAIN;
|
||||||
|
const std::string IPV6_PTR_DOMAIN = C_IPV6_PTR_DOMAIN;
|
||||||
|
|
||||||
class Factory
|
class Factory
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user