diff --git a/CHANGELOG b/CHANGELOG index 0ecaea497..d3b8b120c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,10 @@ # Nmap Changelog ($Id$); -*-text-*- +o Fixed a bug in reverse name resolution: a name of "." would leave + the hostname unintialized, which would manifest as + Illegal character(s) in hostname -- replacing with '*' + errors. [Gisle Vanem] + o Merged nsock-engines from nmap-exp. This rewrite of the nsock library adds support for system-specific scalable IO notification facilities without breaking portability. This initial version comes with an epoll(7)-based engine diff --git a/nmap_dns.cc b/nmap_dns.cc index f8214fd4c..a9039ab45 100644 --- a/nmap_dns.cc +++ b/nmap_dns.cc @@ -600,22 +600,40 @@ static u32 parse_inaddr_arpa(unsigned char *buf, int maxlen) { // Turns a DNS packet encoded name (see the RFC) and turns it into // a normal decimal separated hostname. // ASSUMES NAME LENGTH/VALIDITY HAS ALREADY BEEN VERIFIED -static int encoded_name_to_normal(unsigned char *buf, char *output, int outputsize){ - while (buf[0]) { - if (buf[0] >= outputsize-1) return -1; - memcpy(output, buf+1, buf[0]); - outputsize -= buf[0]; - output += buf[0]; - buf += buf[0]+1; +static int encoded_name_to_normal(const unsigned char *buf, char *output, int outputsize) { + int len; + char *p; - if (buf[0]) { - *output++ = '.'; - outputsize--; - } else { - *output = '\0'; - } + p = output; + + /* Special case: keep the trailing dot only for the name ".". */ + if (buf[0] == 0) { + if (p + 2 > output + outputsize) + return -1; + *p++ = '.'; + *p++ = '\0'; + return 0; } + while ((len = buf[0]) != 0) { + /* Add a dot before every component but the first. */ + if (p > output) { + if (p + 1 > output + outputsize) + return -1; + *p++ = '.'; + } + + if (p + len > output + outputsize) + return -1; + memcpy(p, buf + 1, len); + p += len; + buf += 1 + len; + } + + if (p + 1 > output + outputsize) + return -1; + *p++ = '\0'; + return 0; }