1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 12:41:29 +00:00

Look out, world, here comes the Nmap massping migration!

This is the merging of the code that was previously in
/nmap-exp/david/nmap-massping-migration. These are all the big changes
that get rid of massping in favor of doing host discovery using
ultra_scan.

For now, there is a toggle that turns these new changes off. Undefine
NEW_MASSPING in targets.cc to go back to the old code. All of that will
be deleted eventually.

There are likely a few more changes that will be made to this system in
the near future. Those will be made in
/nmap-exp/david/nmap-massping-migration and merged back.

Don't release this just yet, because I'm going to make a few more
commits real quick to remove some debugging stuff.

(Note to self: this merge back was from r5693 in
/nmap-exp/david/nmap-massping-migration.)
This commit is contained in:
david
2007-08-27 23:58:23 +00:00
parent 04428edd29
commit 302547375b
9 changed files with 1438 additions and 356 deletions

View File

@@ -21,7 +21,7 @@ export LIBLUA_LIBS = @LIBLUA_LIBS@
CC = @CC@ CC = @CC@
CXX = @CXX@ CXX = @CXX@
CCOPT = CCOPT =
DBGFLAGS = DBGFLAGS = -O0 -g -pg -ftest-coverage -fprofile-arcs
LIBPCAPDIR = @libpcapdir@ LIBPCAPDIR = @libpcapdir@
LIBPCREDIR = @LIBPCREDIR@ LIBPCREDIR = @LIBPCREDIR@
export LIBDNETDIR = @LIBDNETDIR@ export LIBDNETDIR = @LIBDNETDIR@

View File

@@ -288,7 +288,7 @@ bool NmapOps::UDPScan() {
bool NmapOps::RawScan() { bool NmapOps::RawScan() {
if (ackscan|finscan|idlescan|ipprotscan|maimonscan|nullscan|osscan|synscan|udpscan|windowscan|xmasscan) if (ackscan|finscan|idlescan|ipprotscan|maimonscan|nullscan|osscan|synscan|udpscan|windowscan|xmasscan)
return true; return true;
if (o.pingtype & (PINGTYPE_ICMP_PING|PINGTYPE_ICMP_MASK|PINGTYPE_ICMP_TS|PINGTYPE_TCP_USE_ACK|PINGTYPE_RAWTCP|PINGTYPE_UDP)) if (o.pingtype & (PINGTYPE_ICMP_PING|PINGTYPE_ICMP_MASK|PINGTYPE_ICMP_TS|PINGTYPE_TCP_USE_ACK|PINGTYPE_UDP))
return true; return true;
return false; return false;

27
nmap.cc
View File

@@ -470,7 +470,7 @@ int nmap_main(int argc, char *argv[]) {
short quashargv = 0; short quashargv = 0;
char **host_exp_group; char **host_exp_group;
char *idleProxy = NULL; /* The idle host used to "Proxy" an Idlescan */ char *idleProxy = NULL; /* The idle host used to "Proxy" an Idlescan */
int num_host_exp_groups = 0; int num_host_exp_groups;
char *machinefilename = NULL, *kiddiefilename = NULL, char *machinefilename = NULL, *kiddiefilename = NULL,
*normalfilename = NULL, *xmlfilename = NULL; *normalfilename = NULL, *xmlfilename = NULL;
HostGroupState *hstate = NULL; HostGroupState *hstate = NULL;
@@ -1480,10 +1480,6 @@ int nmap_main(int argc, char *argv[]) {
if (ports->prot_count) if (ports->prot_count)
shortfry(ports->prots, ports->prot_count); shortfry(ports->prots, ports->prot_count);
} }
/* Time to create a hostgroup state object filled with all the requested
machines */
host_exp_group = (char **) safe_malloc(o.ping_group_sz * sizeof(char *));
/* lets load our exclude list */ /* lets load our exclude list */
if ((NULL != excludefd) || (NULL != exclude_spec)) { if ((NULL != excludefd) || (NULL != exclude_spec)) {
@@ -1498,17 +1494,6 @@ int nmap_main(int argc, char *argv[]) {
free(exclude_spec); free(exclude_spec);
} }
while(num_host_exp_groups < o.ping_group_sz &&
(host_spec = grab_next_host_spec(inputfd, argc, fakeargv))) {
host_exp_group[num_host_exp_groups++] = strdup(host_spec);
// For purposes of random scan
if (o.max_ips_to_scan && o.max_ips_to_scan <= o.numhosts_scanned + num_host_exp_groups)
break;
}
// if (num_host_exp_groups == 0)
// fatal("No target machines/networks specified!");
#ifndef NOLUA #ifndef NOLUA
if(o.scriptupdatedb) { if(o.scriptupdatedb) {
script_updatedb(); script_updatedb();
@@ -1516,6 +1501,12 @@ int nmap_main(int argc, char *argv[]) {
o.max_ips_to_scan = o.numhosts_scanned; o.max_ips_to_scan = o.numhosts_scanned;
} }
#endif #endif
/* Time to create a hostgroup state object filled with all the requested
machines. The list is initially empty. It is refilled inside the loop
whenever it is empty. */
host_exp_group = (char **) safe_malloc(o.ping_group_sz * sizeof(char *));
num_host_exp_groups = 0;
hstate = new HostGroupState(o.ping_group_sz, o.randomize_hosts, hstate = new HostGroupState(o.ping_group_sz, o.randomize_hosts,
host_exp_group, num_host_exp_groups); host_exp_group, num_host_exp_groups);
@@ -1524,7 +1515,7 @@ int nmap_main(int argc, char *argv[]) {
ideal_scan_group_sz = determineScanGroupSize(o.numhosts_scanned, ports); ideal_scan_group_sz = determineScanGroupSize(o.numhosts_scanned, ports);
while(Targets.size() < ideal_scan_group_sz) { while(Targets.size() < ideal_scan_group_sz) {
o.current_scantype = HOST_DISCOVERY; o.current_scantype = HOST_DISCOVERY;
currenths = nexthost(hstate, exclude_group, ports, &(o.pingtype)); currenths = nexthost(hstate, exclude_group, ports, o.pingtype);
if (!currenths) { if (!currenths) {
/* Try to refill with any remaining expressions */ /* Try to refill with any remaining expressions */
/* First free the old ones */ /* First free the old ones */
@@ -1545,7 +1536,7 @@ int nmap_main(int argc, char *argv[]) {
host_exp_group, num_host_exp_groups); host_exp_group, num_host_exp_groups);
/* Try one last time -- with new expressions */ /* Try one last time -- with new expressions */
currenths = nexthost(hstate, exclude_group, ports, &(o.pingtype)); currenths = nexthost(hstate, exclude_group, ports, o.pingtype);
if (!currenths) if (!currenths)
break; break;
} }

3
nmap.h
View File

@@ -333,6 +333,7 @@ void *realloc();
#define UC(b) (((int)b)&0xff) #define UC(b) (((int)b)&0xff)
#define SA struct sockaddr /*Ubertechnique from R. Stevens */ #define SA struct sockaddr /*Ubertechnique from R. Stevens */
#define HOST_UNKNOWN 0
#define HOST_UP 1 #define HOST_UP 1
#define HOST_DOWN 2 #define HOST_DOWN 2
#define HOST_FIREWALLED 4 #define HOST_FIREWALLED 4
@@ -346,7 +347,7 @@ void *realloc();
#define PINGTYPE_TCP 16 #define PINGTYPE_TCP 16
#define PINGTYPE_TCP_USE_ACK 32 #define PINGTYPE_TCP_USE_ACK 32
#define PINGTYPE_TCP_USE_SYN 64 #define PINGTYPE_TCP_USE_SYN 64
#define PINGTYPE_RAWTCP 128 /* # define PINGTYPE_RAWTCP 128 used to be here, but was never used. */
#define PINGTYPE_CONNECTTCP 256 #define PINGTYPE_CONNECTTCP 256
#define PINGTYPE_UDP 512 #define PINGTYPE_UDP 512
#define PINGTYPE_ARP 1024 #define PINGTYPE_ARP 1024

File diff suppressed because it is too large Load Diff

View File

@@ -109,7 +109,7 @@
/* 3rd generation Nmap scanning function. Handles most Nmap port scan types */ /* 3rd generation Nmap scanning function. Handles most Nmap port scan types */
void ultra_scan(std::vector<Target *> &Targets, struct scan_lists *ports, void ultra_scan(std::vector<Target *> &Targets, struct scan_lists *ports,
stype scantype); stype scantype, struct timeout_info *to = NULL);
/* Handles the "positive-response" scans (where we get a response /* Handles the "positive-response" scans (where we get a response
telling us that the port is open based on the probe. This includes telling us that the port is open based on the probe. This includes

View File

@@ -111,6 +111,10 @@
#include "nmap_tty.h" #include "nmap_tty.h"
#include "utils.h" #include "utils.h"
/* If defined, use the new massping that uses ultra_scan instead of the old
standalone function. */
#define NEW_MASSPING
using namespace std; using namespace std;
extern NmapOps o; extern NmapOps o;
enum pingstyle { pingstyle_unknown, pingstyle_rawtcp, pingstyle_rawudp, pingstyle_connecttcp, enum pingstyle { pingstyle_unknown, pingstyle_rawtcp, pingstyle_rawudp, pingstyle_connecttcp,
@@ -144,6 +148,7 @@ char *readhoststate(int state) {
return NULL; return NULL;
} }
#ifndef NEW_MASSPING
/* Internal function to update the state of machine (up/down/etc) based on /* Internal function to update the state of machine (up/down/etc) based on
ping results */ ping results */
static int hostupdate(Target *hostbatch[], Target *target, static int hostupdate(Target *hostbatch[], Target *target,
@@ -252,11 +257,11 @@ static int hostupdate(Target *hostbatch[], Target *target,
} }
return 0; return 0;
} }
#endif // NEW_MASSPING
/* Conducts an ARP ping sweep of the given hosts to determine which ones /* Conducts an ARP ping sweep of the given hosts to determine which ones
are up on a local ethernet network */ are up on a local ethernet network */
static void arpping(Target *hostbatch[], int num_hosts, static void arpping(Target *hostbatch[], int num_hosts) {
struct scan_lists *ports) {
/* First I change hostbatch into a vector<Target *>, which is what ultra_scan /* First I change hostbatch into a vector<Target *>, which is what ultra_scan
takes. I remove hosts that cannot be ARP scanned (such as localhost) */ takes. I remove hosts that cannot be ARP scanned (such as localhost) */
vector<Target *> targets; vector<Target *> targets;
@@ -288,7 +293,7 @@ static void arpping(Target *hostbatch[], int num_hosts,
targets.push_back(hostbatch[targetno]); targets.push_back(hostbatch[targetno]);
} }
if (!targets.empty()) if (!targets.empty())
ultra_scan(targets, ports, PING_SCAN_ARP); ultra_scan(targets, NULL, PING_SCAN_ARP);
return; return;
} }
@@ -380,11 +385,11 @@ static int hostInExclude(struct sockaddr *checksock, size_t checksocklen,
} }
#ifndef NEW_MASSPING
static int get_ping_results(int sd, pcap_t *pd, Target *hostbatch[], static int get_ping_results(int sd, pcap_t *pd, Target *hostbatch[],
int pingtype, struct timeval *time, int pingtype, struct timeval *time,
struct pingtune *pt, struct timeout_info *to, struct pingtune *pt, struct timeout_info *to,
int id, struct pingtech *ptech, int id, struct pingtech *ptech) {
struct scan_lists *ports) {
fd_set fd_r, fd_x; fd_set fd_r, fd_x;
struct timeval myto, tmpto, start, rcvdtime; struct timeval myto, tmpto, start, rcvdtime;
unsigned int bytes; unsigned int bytes;
@@ -1272,6 +1277,7 @@ while(pt->block_unaccounted) {
return 0; return 0;
} }
#endif // NEW_MASSPING
/* loads an exclude file into an exclude target list (mdmcl) */ /* loads an exclude file into an exclude target list (mdmcl) */
@@ -1434,8 +1440,42 @@ int dumpExclude(TargetGroup *exclude_group) {
return 1; return 1;
} }
static void massping(Target *hostbatch[], int num_hosts, #ifdef NEW_MASSPING
struct scan_lists *ports, int pingtype) { static void massping(Target *hostbatch[], int num_hosts, int pingtype) {
static struct timeout_info group_to = { 0, 0, 0 };
static char prev_device_name[16] = "";
const char *device_name;
std::vector<Target *> targets;
int i;
/* Get the name of the interface used to send to this group. We assume the
device used to send to the first target is used to send to all of them. */
device_name = NULL;
if (num_hosts > 0)
device_name = hostbatch[0]->deviceName();
if (device_name == NULL)
device_name = "";
/* group_to is a static variable that keeps track of group timeout values
between invocations of this function. We reuse timeouts as long as this
invocation uses the same device as the previous one. Otherwise we
reinitialize the timeouts. */
if (group_to.srtt == 0 || group_to.rttvar == 0 || group_to.timeout == 0
|| strcmp(prev_device_name, device_name) != 0) {
initialize_timeout_info(&group_to);
Strncpy(prev_device_name, device_name, sizeof(prev_device_name));
}
for (i = 0; i < num_hosts; i++) {
initialize_timeout_info(&hostbatch[i]->to);
targets.push_back(hostbatch[i]);
}
/* ultra_scan gets pingtype from o.pingtype. */
ultra_scan(targets, NULL, PING_SCAN, &group_to);
}
#else
static void massping(Target *hostbatch[], int num_hosts, int pingtype) {
static struct timeout_info to = {0,0,0}; static struct timeout_info to = {0,0,0};
static double gsize = (double) LOOKAHEAD; static double gsize = (double) LOOKAHEAD;
int hostnum; int hostnum;
@@ -1675,7 +1715,7 @@ static void massping(Target *hostbatch[], int num_hosts,
} }
if(ptech.icmpscan || ptech.rawicmpscan || ptech.rawtcpscan || ptech.rawudpscan) { if(ptech.icmpscan || ptech.rawicmpscan || ptech.rawtcpscan || ptech.rawudpscan) {
get_ping_results(sd, pd, hostbatch, pingtype, time, &pt, &to, id, get_ping_results(sd, pd, hostbatch, pingtype, time, &pt, &to, id,
&ptech, ports); &ptech);
} }
if (ptech.connecttcpscan) { if (ptech.connecttcpscan) {
get_connecttcpscan_results(&tqi, hostbatch, time, &pt, &to); get_connecttcpscan_results(&tqi, hostbatch, time, &pt, &to);
@@ -1719,9 +1759,10 @@ static void massping(Target *hostbatch[], int num_hosts,
gsize = pt.group_size; gsize = pt.group_size;
return; return;
} }
#endif // NEW_MASSPING
Target *nexthost(HostGroupState *hs, TargetGroup *exclude_group, Target *nexthost(HostGroupState *hs, TargetGroup *exclude_group,
struct scan_lists *ports, int *pingtype) { struct scan_lists *ports, int pingtype) {
int hidx = 0; int hidx = 0;
int i; int i;
struct sockaddr_storage ss; struct sockaddr_storage ss;
@@ -1760,9 +1801,9 @@ do {
3) We are doing a raw-mode portscan or osscan OR 3) We are doing a raw-mode portscan or osscan OR
4) We are on windows and doing ICMP ping */ 4) We are on windows and doing ICMP ping */
if (o.isr00t && o.af() == AF_INET && if (o.isr00t && o.af() == AF_INET &&
((*pingtype & (PINGTYPE_TCP|PINGTYPE_UDP|PINGTYPE_ARP)) || o.RawScan() ((pingtype & (PINGTYPE_TCP|PINGTYPE_UDP|PINGTYPE_ARP)) || o.RawScan()
#ifdef WIN32 #ifdef WIN32
|| (*pingtype & (PINGTYPE_ICMP_PING|PINGTYPE_ICMP_MASK|PINGTYPE_ICMP_TS)) || (pingtype & (PINGTYPE_ICMP_PING|PINGTYPE_ICMP_MASK|PINGTYPE_ICMP_TS))
#endif // WIN32 #endif // WIN32
)) { )) {
hs->hostbatch[hidx]->TargetSockAddr(&ss, &sslen); hs->hostbatch[hidx]->TargetSockAddr(&ss, &sslen);
@@ -1834,7 +1875,7 @@ if (hs->randomize) {
if (hs->hostbatch[0]->ifType() == devt_ethernet && if (hs->hostbatch[0]->ifType() == devt_ethernet &&
hs->hostbatch[0]->directlyConnected() && hs->hostbatch[0]->directlyConnected() &&
o.sendpref != PACKET_SEND_IP_STRONG) { o.sendpref != PACKET_SEND_IP_STRONG) {
arpping(hs->hostbatch, hs->current_batch_sz, ports); arpping(hs->hostbatch, hs->current_batch_sz);
arpping_done = true; arpping_done = true;
} }
@@ -1852,7 +1893,7 @@ if (hs->randomize) {
/* TODO: Maybe I should allow real ping scan of directly connected /* TODO: Maybe I should allow real ping scan of directly connected
ethernet hosts? */ ethernet hosts? */
/* Then we do the mass ping (if required - IP-level pings) */ /* Then we do the mass ping (if required - IP-level pings) */
if ((*pingtype == PINGTYPE_NONE && !arpping_done) || hs->hostbatch[0]->ifType() == devt_loopback) { if ((pingtype == PINGTYPE_NONE && !arpping_done) || hs->hostbatch[0]->ifType() == devt_loopback) {
for(i=0; i < hs->current_batch_sz; i++) { for(i=0; i < hs->current_batch_sz; i++) {
if (!hs->hostbatch[i]->timedOut(&now)) { if (!hs->hostbatch[i]->timedOut(&now)) {
initialize_timeout_info(&hs->hostbatch[i]->to); initialize_timeout_info(&hs->hostbatch[i]->to);
@@ -1861,10 +1902,10 @@ if (hs->randomize) {
} }
} }
} else if (!arpping_done) } else if (!arpping_done)
if (*pingtype & PINGTYPE_ARP) /* A host that we can't arp scan ... maybe localhost */ if (pingtype & PINGTYPE_ARP) /* A host that we can't arp scan ... maybe localhost */
massping(hs->hostbatch, hs->current_batch_sz, ports, DEFAULT_PING_TYPES); massping(hs->hostbatch, hs->current_batch_sz, DEFAULT_PING_TYPES);
else else
massping(hs->hostbatch, hs->current_batch_sz, ports, *pingtype); massping(hs->hostbatch, hs->current_batch_sz, pingtype);
if (!o.noresolve) nmap_mass_rdns(hs->hostbatch, hs->current_batch_sz); if (!o.noresolve) nmap_mass_rdns(hs->hostbatch, hs->current_batch_sz);

View File

@@ -155,8 +155,7 @@ struct tcpqueryinfo {
}; };
struct pingtech { struct pingtech {
unsigned int icmpscan: 1, unsigned int rawicmpscan: 1,
rawicmpscan: 1,
connecttcpscan: 1, connecttcpscan: 1,
rawtcpscan: 1, rawtcpscan: 1,
rawudpscan: 1; rawudpscan: 1;
@@ -166,7 +165,7 @@ struct pingtech {
/* Ports is the list of ports the user asked to be scanned (0 terminated), /* Ports is the list of ports the user asked to be scanned (0 terminated),
you can just pass NULL (it is only a stupid optimization that needs it) */ you can just pass NULL (it is only a stupid optimization that needs it) */
Target *nexthost(HostGroupState *hs, TargetGroup *exclude_group, Target *nexthost(HostGroupState *hs, TargetGroup *exclude_group,
struct scan_lists *ports, int *pingtype); struct scan_lists *ports, int pingtype);
/* loads an exclude file into a excluded target list */ /* loads an exclude file into a excluded target list */
TargetGroup* load_exclude(FILE *fExclude, char *szExclude); TargetGroup* load_exclude(FILE *fExclude, char *szExclude);
/* a debugging routine to dump an exclude list to stdout. */ /* a debugging routine to dump an exclude list to stdout. */

View File

@@ -917,6 +917,9 @@ pcap_t *my_pcap_open_live(const char *device, int snaplen, int promisc,
pcap_t *pt; pcap_t *pt;
char pcapdev[128]; char pcapdev[128];
int failed = 0; int failed = 0;
assert(device != NULL);
#ifdef WIN32 #ifdef WIN32
/* Nmap normally uses device names obtained through dnet for interfaces, but Pcap has its own /* Nmap normally uses device names obtained through dnet for interfaces, but Pcap has its own
naming system. So the conversion is done here */ naming system. So the conversion is done here */
@@ -1839,10 +1842,16 @@ int pcap_select(pcap_t *p, struct timeval *timeout)
FD_ZERO(&rfds); FD_ZERO(&rfds);
FD_SET(fd, &rfds); FD_SET(fd, &rfds);
ret = select(fd + 1, &rfds, NULL, NULL, timeout); do {
errno = 0;
if (ret == -1) ret = select(fd + 1, &rfds, NULL, NULL, timeout);
fatal("Your system does not support select()ing on pcap devices (%s). PLEASE REPORT THIS ALONG WITH DETAILED SYSTEM INFORMATION TO THE nmap-dev MAILING LIST!", strerror(errno)); if (ret == -1) {
if (errno == EINTR)
error("%s: %s", __func__, strerror(errno));
else
fatal("Your system does not support select()ing on pcap devices (%s). PLEASE REPORT THIS ALONG WITH DETAILED SYSTEM INFORMATION TO THE nmap-dev MAILING LIST!", strerror(errno));
}
} while (ret == -1);
return ret; return ret;
} }