diff --git a/TargetGroup.cc b/TargetGroup.cc index 7b49a475e..66aa1fd0c 100644 --- a/TargetGroup.cc +++ b/TargetGroup.cc @@ -198,6 +198,7 @@ int TargetGroup::parse_expr(const char * const target_expr, int af) { } } else netmask = 32; + resolvedname = hostexp; for(i=0; *(hostexp + i); i++) if (isupper((int) (unsigned char) *(hostexp +i)) || islower((int) (unsigned char) *(hostexp +i))) { @@ -206,11 +207,11 @@ int TargetGroup::parse_expr(const char * const target_expr, int af) { } if (netmask != 32 || namedhost) { targets_type = IPV4_NETMASK; - if (!inet_pton(AF_INET, target_net, &(startaddr))) { + if (!inet_pton(AF_INET, target_net, &(resolvedaddr))) { if ((target = gethostbyname(target_net))) { int count=0; - memcpy(&(startaddr), target->h_addr_list[0], sizeof(struct in_addr)); + memcpy(&(resolvedaddr), target->h_addr_list[0], sizeof(resolvedaddr)); while (target->h_addr_list[count]) count++; @@ -223,7 +224,7 @@ int TargetGroup::parse_expr(const char * const target_expr, int af) { } } if (netmask) { - unsigned long longtmp = ntohl(startaddr.s_addr); + unsigned long longtmp = ntohl(resolvedaddr.s_addr); startaddr.s_addr = longtmp & (unsigned long) (0 - (1<<(32 - netmask))); endaddr.s_addr = longtmp | (unsigned long) ((1<<(32 - netmask)) - 1); } else { @@ -510,6 +511,26 @@ int TargetGroup::return_last_host() { return 0; } +/* Returns true iff the given address is the one that was resolved to create + this target group; i.e., not one of the addresses derived from it with a + netmask. */ +bool TargetGroup::is_resolved_address(const struct sockaddr_storage *ss) +{ + const struct sockaddr_in *sin; + + if (targets_type != IPV4_NETMASK || ss->ss_family != AF_INET) + return false; + sin = (struct sockaddr_in *) ss; + + return sin->sin_addr.s_addr == htonl(startaddr.s_addr); +} + +/* Return a string of the name or address that was resolved for this group. */ +const char *TargetGroup::get_resolved_name(void) +{ + return resolvedname.c_str(); +} + /* Lookahead is the number of hosts that can be checked (such as ping scanned) in advance. Randomize causes each group of up to lookahead hosts to be internally shuffled around. diff --git a/TargetGroup.h b/TargetGroup.h index 6dfcd6ee8..36f8fe036 100644 --- a/TargetGroup.h +++ b/TargetGroup.h @@ -95,6 +95,8 @@ #ifndef TARGETGROUP_H #define TARGETGROUP_H +#include + #include "nmap.h" class TargetGroup { @@ -121,6 +123,12 @@ class TargetGroup { this if you have fetched at least 1 host since parse_expr() was called */ int return_last_host(); + /* Returns true iff the given address is the one that was resolved to create + this target group; i.e., not one of the addresses derived from it with a + netmask. */ + bool is_resolved_address(const struct sockaddr_storage *ss); + /* Return a string of the name or address that was resolved for this group. */ + const char *get_resolved_name(void); /* return the target type */ char get_targets_type() {return targets_type;}; /* get the netmask */ @@ -137,9 +145,11 @@ class TargetGroup { struct sockaddr_in6 ip6; #endif - /* These 4 are used for the '/mask' style of specifying target + /* These are used for the '/mask' style of specifying target net (IPV4_NETMASK) */ u32 netmask; + std::string resolvedname; + struct in_addr resolvedaddr; struct in_addr startaddr; struct in_addr currentaddr; struct in_addr endaddr; diff --git a/targets.cc b/targets.cc index cf31b3532..6c8e6a18c 100644 --- a/targets.cc +++ b/targets.cc @@ -458,11 +458,11 @@ do { hs->hostbatch[hidx] = new Target(); hs->hostbatch[hidx]->setTargetSockAddr(&ss, sslen); - /* put target expression in target if we have a named host without netmask */ - if ( hs->current_expression.get_targets_type() == TargetGroup::IPV4_NETMASK && - hs->current_expression.get_namedhost() && - !strchr( hs->target_expressions[hs->next_expression-1], '/' ) ) { - hs->hostbatch[hidx]->setTargetName(hs->target_expressions[hs->next_expression-1]); + /* Special handling for the resolved address (for example whatever + scanme.nmap.org resolves to in scanme.nmap.org/24). */ + if (hs->current_expression.is_resolved_address(&ss)) { + if (hs->current_expression.get_namedhost()) + hs->hostbatch[hidx]->setTargetName(hs->current_expression.get_resolved_name()); } /* We figure out the source IP/device IFF