mirror of
https://github.com/nmap/nmap.git
synced 2026-01-16 19:39:03 +00:00
Fix --resume from IPv6 scans
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
#Nmap Changelog ($Id$); -*-text-*-
|
||||
|
||||
o Allow resuming IPv6 scans with --resume. The address parsing was assuming IPv4
|
||||
addresses, leading to "Unable to parse ip" error. In a related fix, MAC addresses
|
||||
will not be parsed as IP addresses when resuming from XML. [Daniel Miller]
|
||||
|
||||
o [GH#1622][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, Richard Schütz, Daniel Miller]
|
||||
|
||||
@@ -330,7 +330,7 @@ void NmapOps::Initialize() {
|
||||
scanflags = -1;
|
||||
defeat_rst_ratelimit = false;
|
||||
defeat_icmp_ratelimit = false;
|
||||
resume_ip.s_addr = 0;
|
||||
resume_ip.ss_family = AF_UNSPEC;
|
||||
osscan_limit = false;
|
||||
osscan_guess = false;
|
||||
numdecoys = 0;
|
||||
@@ -565,8 +565,8 @@ administrator privileges.";
|
||||
fatal("Option --defeat-icmp-ratelimit works only with a UDP scan (-sU)");
|
||||
}
|
||||
|
||||
if (resume_ip.s_addr && generate_random_ips)
|
||||
resume_ip.s_addr = 0;
|
||||
if (resume_ip.ss_family != AF_UNSPEC && generate_random_ips)
|
||||
resume_ip.ss_family = AF_UNSPEC;
|
||||
|
||||
if (magic_port_set && connectscan) {
|
||||
error("WARNING: -g is incompatible with the default connect() scan (-sT). Use a raw scan such as -sS if you want to set the source port.");
|
||||
|
||||
@@ -318,11 +318,11 @@ class NmapOps {
|
||||
when it changes the port's state because of ICMP response, as the latter
|
||||
might be rate-limited. Doing so we can get scan results faster. */
|
||||
|
||||
struct in_addr resume_ip; /* The last IP in the log file if user
|
||||
struct sockaddr_storage resume_ip; /* The last IP in the log file if user
|
||||
requested --restore . Otherwise
|
||||
restore_ip.s_addr == 0. Also
|
||||
target_struct_get will eventually set it
|
||||
to 0. */
|
||||
resume_ip.ss_family == AF_UNSPEC. Also
|
||||
Target::next_target will eventually set it
|
||||
to AF_UNSPEC. */
|
||||
|
||||
// Version Detection Options
|
||||
bool override_excludeports;
|
||||
|
||||
38
nmap.cc
38
nmap.cc
@@ -2347,7 +2347,9 @@ int gather_logfile_resumption_state(char *fname, int *myargc, char ***myargv) {
|
||||
char *filestr;
|
||||
s64 filelen;
|
||||
char nmap_arg_buffer[4096]; /* roughly aligned with arg_parse limit */
|
||||
struct in_addr lastip;
|
||||
struct sockaddr_storage *lastip = &o.resume_ip;
|
||||
int af = AF_INET; // default without -6 is ipv4
|
||||
size_t sslen;
|
||||
char *p, *q, *found, *lastipstr; /* I love C! */
|
||||
/* We mmap it read/write since we will change the last char to a newline if it is not already */
|
||||
filestr = mmapfile(fname, &filelen, O_RDWR);
|
||||
@@ -2427,6 +2429,15 @@ int gather_logfile_resumption_state(char *fname, int *myargc, char ***myargv) {
|
||||
fatal("Unable to parse supposed log file %s. Sorry", fname);
|
||||
}
|
||||
|
||||
for (int i=0; i < *myargc; i++) {
|
||||
if (!strncmp("-4", (*myargv)[i], 2)) {
|
||||
af = AF_INET;
|
||||
}
|
||||
else if (!strncmp("-6", (*myargv)[i], 2)) {
|
||||
af = AF_INET6;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now it is time to figure out the last IP that was scanned */
|
||||
q = p;
|
||||
found = NULL;
|
||||
@@ -2439,22 +2450,30 @@ int gather_logfile_resumption_state(char *fname, int *myargc, char ***myargv) {
|
||||
if (!q)
|
||||
fatal("Unable to parse supposed log file %s. Sorry", fname);
|
||||
*q = '\0';
|
||||
if (inet_pton(AF_INET, found, &lastip) == 0)
|
||||
fatal("Unable to parse supposed log file %s. Sorry", fname);
|
||||
if (resolve_numeric(found, 0, lastip, &sslen, af) != 0)
|
||||
fatal("Unable to parse ip (%s) in supposed log file %s. Sorry", found, fname);
|
||||
*q = ' ';
|
||||
} else {
|
||||
/* Let's see if it's an XML log (-oX) */
|
||||
q = p;
|
||||
found = NULL;
|
||||
while ((q = strstr(q, "\n<address addr=\"")))
|
||||
found = q = q + 16;
|
||||
while ((q = strstr(q, "\n<address addr=\""))) {
|
||||
q += 16;
|
||||
found = strchr(q, '"');
|
||||
if (!found)
|
||||
fatal("Unable to parse supposed log file %s. Sorry", fname);
|
||||
if ((af == AF_INET && !strncmp("\" addrtype=\"ipv4\"", found, 17))
|
||||
|| (af == AF_INET6 && !strncmp("\" addrtype=\"ipv6\"", found, 17))) {
|
||||
found = q;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
q = strchr(found, '"');
|
||||
if (!q)
|
||||
fatal("Unable to parse supposed log file %s. Sorry", fname);
|
||||
*q = '\0';
|
||||
if (inet_pton(AF_INET, found, &lastip) == 0)
|
||||
fatal("Unable to parse supposed log file %s. Sorry", fname);
|
||||
if (resolve_numeric(found, 0, lastip, &sslen, af) != 0)
|
||||
fatal("Unable to parse ip (%s) supposed log file %s. Sorry", found, fname);
|
||||
*q = '"';
|
||||
} else {
|
||||
/* OK, I guess (hope) it is a normal log then (-oN) */
|
||||
@@ -2482,16 +2501,15 @@ int gather_logfile_resumption_state(char *fname, int *myargc, char ***myargv) {
|
||||
lastipstr = strdup(p + 1);
|
||||
}
|
||||
*q = p ? ')' : '\n'; /* recover changed chars */
|
||||
if (inet_pton(AF_INET, lastipstr, &lastip) == 0)
|
||||
if (resolve_numeric(lastipstr, 0, lastip, &sslen, af) != 0)
|
||||
fatal("Unable to parse ip (%s) in supposed log file %s. Sorry", lastipstr, fname);
|
||||
free(lastipstr);
|
||||
} else {
|
||||
error("Warning: You asked for --resume but it doesn't look like any hosts in the log file were successfully scanned. Starting from the beginning.");
|
||||
lastip.s_addr = 0;
|
||||
lastip->ss_family = AF_UNSPEC;
|
||||
}
|
||||
}
|
||||
}
|
||||
o.resume_ip = lastip;
|
||||
|
||||
/* Ensure the log file ends with a newline */
|
||||
filestr[filelen - 1] = '\n';
|
||||
|
||||
@@ -526,10 +526,10 @@ tryagain:
|
||||
|
||||
/* If we are resuming from a previous scan, we have already finished scanning
|
||||
up to o.resume_ip. */
|
||||
if (ss.ss_family == AF_INET && o.resume_ip.s_addr) {
|
||||
if (o.resume_ip.s_addr == ((struct sockaddr_in *) &ss)->sin_addr.s_addr)
|
||||
if (o.resume_ip.ss_family != AF_UNSPEC) {
|
||||
if (!sockaddr_storage_cmp(&o.resume_ip, &ss))
|
||||
/* We will continue starting with the next IP. */
|
||||
o.resume_ip.s_addr = 0;
|
||||
o.resume_ip.ss_family = AF_UNSPEC;
|
||||
goto tryagain;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user