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:
@@ -21,7 +21,7 @@ export LIBLUA_LIBS = @LIBLUA_LIBS@
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
CCOPT =
|
||||
DBGFLAGS =
|
||||
DBGFLAGS = -O0 -g -pg -ftest-coverage -fprofile-arcs
|
||||
LIBPCAPDIR = @libpcapdir@
|
||||
LIBPCREDIR = @LIBPCREDIR@
|
||||
export LIBDNETDIR = @LIBDNETDIR@
|
||||
|
||||
@@ -288,7 +288,7 @@ bool NmapOps::UDPScan() {
|
||||
bool NmapOps::RawScan() {
|
||||
if (ackscan|finscan|idlescan|ipprotscan|maimonscan|nullscan|osscan|synscan|udpscan|windowscan|xmasscan)
|
||||
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 false;
|
||||
|
||||
27
nmap.cc
27
nmap.cc
@@ -470,7 +470,7 @@ int nmap_main(int argc, char *argv[]) {
|
||||
short quashargv = 0;
|
||||
char **host_exp_group;
|
||||
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,
|
||||
*normalfilename = NULL, *xmlfilename = NULL;
|
||||
HostGroupState *hstate = NULL;
|
||||
@@ -1481,10 +1481,6 @@ int nmap_main(int argc, char *argv[]) {
|
||||
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 */
|
||||
if ((NULL != excludefd) || (NULL != exclude_spec)) {
|
||||
exclude_group = load_exclude(excludefd, exclude_spec);
|
||||
@@ -1498,17 +1494,6 @@ int nmap_main(int argc, char *argv[]) {
|
||||
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
|
||||
if(o.scriptupdatedb) {
|
||||
script_updatedb();
|
||||
@@ -1517,6 +1502,12 @@ int nmap_main(int argc, char *argv[]) {
|
||||
}
|
||||
#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,
|
||||
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);
|
||||
while(Targets.size() < ideal_scan_group_sz) {
|
||||
o.current_scantype = HOST_DISCOVERY;
|
||||
currenths = nexthost(hstate, exclude_group, ports, &(o.pingtype));
|
||||
currenths = nexthost(hstate, exclude_group, ports, o.pingtype);
|
||||
if (!currenths) {
|
||||
/* Try to refill with any remaining expressions */
|
||||
/* First free the old ones */
|
||||
@@ -1545,7 +1536,7 @@ int nmap_main(int argc, char *argv[]) {
|
||||
host_exp_group, num_host_exp_groups);
|
||||
|
||||
/* 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)
|
||||
break;
|
||||
}
|
||||
|
||||
3
nmap.h
3
nmap.h
@@ -333,6 +333,7 @@ void *realloc();
|
||||
#define UC(b) (((int)b)&0xff)
|
||||
#define SA struct sockaddr /*Ubertechnique from R. Stevens */
|
||||
|
||||
#define HOST_UNKNOWN 0
|
||||
#define HOST_UP 1
|
||||
#define HOST_DOWN 2
|
||||
#define HOST_FIREWALLED 4
|
||||
@@ -346,7 +347,7 @@ void *realloc();
|
||||
#define PINGTYPE_TCP 16
|
||||
#define PINGTYPE_TCP_USE_ACK 32
|
||||
#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_UDP 512
|
||||
#define PINGTYPE_ARP 1024
|
||||
|
||||
1603
scan_engine.cc
1603
scan_engine.cc
File diff suppressed because it is too large
Load Diff
@@ -109,7 +109,7 @@
|
||||
|
||||
/* 3rd generation Nmap scanning function. Handles most Nmap port scan types */
|
||||
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
|
||||
telling us that the port is open based on the probe. This includes
|
||||
|
||||
73
targets.cc
73
targets.cc
@@ -111,6 +111,10 @@
|
||||
#include "nmap_tty.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;
|
||||
extern NmapOps o;
|
||||
enum pingstyle { pingstyle_unknown, pingstyle_rawtcp, pingstyle_rawudp, pingstyle_connecttcp,
|
||||
@@ -144,6 +148,7 @@ char *readhoststate(int state) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef NEW_MASSPING
|
||||
/* Internal function to update the state of machine (up/down/etc) based on
|
||||
ping results */
|
||||
static int hostupdate(Target *hostbatch[], Target *target,
|
||||
@@ -252,11 +257,11 @@ static int hostupdate(Target *hostbatch[], Target *target,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif // NEW_MASSPING
|
||||
|
||||
/* Conducts an ARP ping sweep of the given hosts to determine which ones
|
||||
are up on a local ethernet network */
|
||||
static void arpping(Target *hostbatch[], int num_hosts,
|
||||
struct scan_lists *ports) {
|
||||
static void arpping(Target *hostbatch[], int num_hosts) {
|
||||
/* 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) */
|
||||
vector<Target *> targets;
|
||||
@@ -288,7 +293,7 @@ static void arpping(Target *hostbatch[], int num_hosts,
|
||||
targets.push_back(hostbatch[targetno]);
|
||||
}
|
||||
if (!targets.empty())
|
||||
ultra_scan(targets, ports, PING_SCAN_ARP);
|
||||
ultra_scan(targets, NULL, PING_SCAN_ARP);
|
||||
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[],
|
||||
int pingtype, struct timeval *time,
|
||||
struct pingtune *pt, struct timeout_info *to,
|
||||
int id, struct pingtech *ptech,
|
||||
struct scan_lists *ports) {
|
||||
int id, struct pingtech *ptech) {
|
||||
fd_set fd_r, fd_x;
|
||||
struct timeval myto, tmpto, start, rcvdtime;
|
||||
unsigned int bytes;
|
||||
@@ -1272,6 +1277,7 @@ while(pt->block_unaccounted) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif // NEW_MASSPING
|
||||
|
||||
|
||||
/* loads an exclude file into an exclude target list (mdmcl) */
|
||||
@@ -1434,8 +1440,42 @@ int dumpExclude(TargetGroup *exclude_group) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void massping(Target *hostbatch[], int num_hosts,
|
||||
struct scan_lists *ports, int pingtype) {
|
||||
#ifdef NEW_MASSPING
|
||||
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 double gsize = (double) LOOKAHEAD;
|
||||
int hostnum;
|
||||
@@ -1675,7 +1715,7 @@ static void massping(Target *hostbatch[], int num_hosts,
|
||||
}
|
||||
if(ptech.icmpscan || ptech.rawicmpscan || ptech.rawtcpscan || ptech.rawudpscan) {
|
||||
get_ping_results(sd, pd, hostbatch, pingtype, time, &pt, &to, id,
|
||||
&ptech, ports);
|
||||
&ptech);
|
||||
}
|
||||
if (ptech.connecttcpscan) {
|
||||
get_connecttcpscan_results(&tqi, hostbatch, time, &pt, &to);
|
||||
@@ -1719,9 +1759,10 @@ static void massping(Target *hostbatch[], int num_hosts,
|
||||
gsize = pt.group_size;
|
||||
return;
|
||||
}
|
||||
#endif // NEW_MASSPING
|
||||
|
||||
Target *nexthost(HostGroupState *hs, TargetGroup *exclude_group,
|
||||
struct scan_lists *ports, int *pingtype) {
|
||||
struct scan_lists *ports, int pingtype) {
|
||||
int hidx = 0;
|
||||
int i;
|
||||
struct sockaddr_storage ss;
|
||||
@@ -1760,9 +1801,9 @@ do {
|
||||
3) We are doing a raw-mode portscan or osscan OR
|
||||
4) We are on windows and doing ICMP ping */
|
||||
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
|
||||
|| (*pingtype & (PINGTYPE_ICMP_PING|PINGTYPE_ICMP_MASK|PINGTYPE_ICMP_TS))
|
||||
|| (pingtype & (PINGTYPE_ICMP_PING|PINGTYPE_ICMP_MASK|PINGTYPE_ICMP_TS))
|
||||
#endif // WIN32
|
||||
)) {
|
||||
hs->hostbatch[hidx]->TargetSockAddr(&ss, &sslen);
|
||||
@@ -1834,7 +1875,7 @@ if (hs->randomize) {
|
||||
if (hs->hostbatch[0]->ifType() == devt_ethernet &&
|
||||
hs->hostbatch[0]->directlyConnected() &&
|
||||
o.sendpref != PACKET_SEND_IP_STRONG) {
|
||||
arpping(hs->hostbatch, hs->current_batch_sz, ports);
|
||||
arpping(hs->hostbatch, hs->current_batch_sz);
|
||||
arpping_done = true;
|
||||
}
|
||||
|
||||
@@ -1852,7 +1893,7 @@ if (hs->randomize) {
|
||||
/* TODO: Maybe I should allow real ping scan of directly connected
|
||||
ethernet hosts? */
|
||||
/* 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++) {
|
||||
if (!hs->hostbatch[i]->timedOut(&now)) {
|
||||
initialize_timeout_info(&hs->hostbatch[i]->to);
|
||||
@@ -1861,10 +1902,10 @@ if (hs->randomize) {
|
||||
}
|
||||
}
|
||||
} else if (!arpping_done)
|
||||
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);
|
||||
if (pingtype & PINGTYPE_ARP) /* A host that we can't arp scan ... maybe localhost */
|
||||
massping(hs->hostbatch, hs->current_batch_sz, DEFAULT_PING_TYPES);
|
||||
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);
|
||||
|
||||
|
||||
@@ -155,8 +155,7 @@ struct tcpqueryinfo {
|
||||
};
|
||||
|
||||
struct pingtech {
|
||||
unsigned int icmpscan: 1,
|
||||
rawicmpscan: 1,
|
||||
unsigned int rawicmpscan: 1,
|
||||
connecttcpscan: 1,
|
||||
rawtcpscan: 1,
|
||||
rawudpscan: 1;
|
||||
@@ -166,7 +165,7 @@ struct pingtech {
|
||||
/* 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) */
|
||||
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 */
|
||||
TargetGroup* load_exclude(FILE *fExclude, char *szExclude);
|
||||
/* a debugging routine to dump an exclude list to stdout. */
|
||||
|
||||
13
tcpip.cc
13
tcpip.cc
@@ -917,6 +917,9 @@ pcap_t *my_pcap_open_live(const char *device, int snaplen, int promisc,
|
||||
pcap_t *pt;
|
||||
char pcapdev[128];
|
||||
int failed = 0;
|
||||
|
||||
assert(device != NULL);
|
||||
|
||||
#ifdef WIN32
|
||||
/* Nmap normally uses device names obtained through dnet for interfaces, but Pcap has its own
|
||||
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_SET(fd, &rfds);
|
||||
|
||||
do {
|
||||
errno = 0;
|
||||
ret = select(fd + 1, &rfds, NULL, NULL, timeout);
|
||||
|
||||
if (ret == -1)
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user