This patch reorganizes the way ping probes are handled internally.

Previously the ping probe data structures were stored in NmapOps,
now they will be stored in the scan_lists struct. All other changes
auxiliary to this reorganization.
This commit is contained in:
michael 2008-05-29 07:49:37 +00:00
parent 29d2b20c98
commit 9f1c28ad9c
15 changed files with 253 additions and 240 deletions

View file

@ -116,10 +116,6 @@ NmapOps::NmapOps() {
}
NmapOps::~NmapOps() {
if (ping_synprobes) free(ping_synprobes);
if (ping_ackprobes) free(ping_ackprobes);
if (ping_udpprobes) free(ping_udpprobes);
if (ping_protoprobes) free(ping_protoprobes);
if (datadir) free(datadir);
if (xsl_stylesheet) free(xsl_stylesheet);
}
@ -207,8 +203,6 @@ void NmapOps::Initialize() {
reference_FPs = NULL;
magic_port = 33000 + (get_random_uint() % 31000);
magic_port_set = 0;
num_ping_synprobes = num_ping_ackprobes = num_ping_udpprobes = num_ping_protoprobes = 0;
ping_synprobes = ping_ackprobes = ping_udpprobes = ping_protoprobes = NULL;
timing_level = 3;
max_parallelism = 0;
min_parallelism = 0;
@ -307,12 +301,7 @@ void NmapOps::ValidateOptions() {
#else
const char *privreq = "root privileges";
#endif
if (pingtype == PINGTYPE_UNKNOWN) {
if (isr00t && af() == AF_INET) pingtype = DEFAULT_PING_TYPES;
else pingtype = PINGTYPE_TCP; // if nonr00t or IPv6
getpts_simple(DEFAULT_TCP_PROBE_PORT_SPEC, SCAN_TCP_PORT, &o.ping_ackprobes, &o.num_ping_ackprobes);
assert(o.num_ping_ackprobes > 0);
}
/* Insure that at least one scantype is selected */
if (TCPScan() + UDPScan() + ipprotscan + listscan + pingscan == 0) {
@ -322,23 +311,6 @@ void NmapOps::ValidateOptions() {
// if (verbose) error("No tcp, udp, or ICMP scantype specified, assuming %s scan. Use -sP if you really don't want to portscan (and just want to see what hosts are up).", synscan? "SYN Stealth" : "vanilla tcp connect()");
}
if ((pingtype & PINGTYPE_TCP) && (!isr00t || af() != AF_INET)) {
/* We will have to do a connect() style ping */
if (num_ping_synprobes && num_ping_ackprobes) {
fatal("Cannot use both SYN and ACK ping probes if you are nonroot or using IPv6");
}
/* Pretend we wanted SYN probes all along. */
if (num_ping_ackprobes > 0) {
num_ping_synprobes = num_ping_ackprobes;
ping_synprobes = ping_ackprobes;
num_ping_ackprobes = 0;
ping_ackprobes = NULL;
}
pingtype &= ~PINGTYPE_TCP_USE_ACK;
pingtype |= PINGTYPE_TCP_USE_SYN;
}
if (pingtype != PINGTYPE_NONE && spoofsource) {
error("WARNING: If -S is being used to fake your source address, you may also have to use -e <interface> and -PN . If you are using it to specify your real source address, you can ignore this warning.");
}
@ -389,18 +361,6 @@ void NmapOps::ValidateOptions() {
}
/* We start with stuff users should not do if they are not root */
if (!isr00t) {
#ifndef WIN32 /* Win32 has perfectly fine ICMP socket support */
if (pingtype & (PINGTYPE_ICMP_PING|PINGTYPE_ICMP_MASK|PINGTYPE_ICMP_TS)) {
error("Warning: You are not root -- using TCP pingscan rather than ICMP");
pingtype = PINGTYPE_TCP;
if (num_ping_synprobes == 0)
{
getpts_simple(DEFAULT_TCP_PROBE_PORT_SPEC, SCAN_TCP_PORT, &o.ping_synprobes, &o.num_ping_synprobes);
assert(o.num_ping_synprobes > 0);
}
}
#endif
if (ackscan|finscan|idlescan|ipprotscan|maimonscan|nullscan|synscan|udpscan|windowscan|xmasscan) {
fatal("You requested a scan type which requires %s.", privreq);

View file

@ -190,15 +190,7 @@ class NmapOps {
FingerPrintDB *reference_FPs; /* Used in the new OS scan system. */
u16 magic_port;
unsigned short magic_port_set; /* Was this set by user? */
int num_ping_synprobes;
/* The "synprobes" are also used when doing a connect() ping */
u16 *ping_synprobes;
int num_ping_ackprobes;
u16 *ping_ackprobes;
int num_ping_udpprobes;
u16 *ping_udpprobes;
int num_ping_protoprobes;
u16 *ping_protoprobes;
/* Scan timing/politeness issues */
int timing_level; // 0-5, corresponding to Paranoid, Sneaky, Polite, Normal, Aggressive, Insane
int max_parallelism; // 0 means it has not been set

View file

@ -222,6 +222,17 @@ struct ipid_info {
* Each element is to point to an array of port/protocol numbers
*/
struct scan_lists {
/* The "synprobes" are also used when doing a connect() ping */
unsigned short *syn_ping_ports;
unsigned short *ack_ping_ports;
unsigned short *udp_ping_ports;
unsigned short *proto_ping_ports;
int syn_ping_count;
int ack_ping_count;
int udp_ping_count;
int proto_ping_count;
//the above fields are only used for host discovery
//the fields below are only used for port scanning
unsigned short *tcp_ports;
int tcp_count;
unsigned short *udp_ports;

View file

@ -284,7 +284,7 @@ static void initialize_proxy_struct(struct idle_proxy_info *proxy) {
the program */
#define NUM_IPID_PROBES 6
static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
const struct in_addr *first_target) {
const struct in_addr *first_target, const struct scan_lists * ports) {
int probes_sent = 0, probes_returned = 0;
int hardtimeout = 9000000; /* Generally don't wait more than 9 secs total */
unsigned int bytes, to_usec;
@ -331,10 +331,10 @@ static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
fatal("Invalid port number given in IP ID zombie specification: %s", proxyName);
}
} else {
if (o.num_ping_synprobes > 0) {
proxy->probe_port = o.ping_synprobes[0];
} else if (o.num_ping_ackprobes > 0) {
proxy->probe_port = o.ping_ackprobes[0];
if (ports->syn_ping_count > 0) {
proxy->probe_port = ports->syn_ping_ports[0];
} else if (ports->ack_ping_count > 0) {
proxy->probe_port = ports->ack_ping_ports[0];
} else {
u16 *ports;
int count;
@ -980,7 +980,7 @@ static int idle_treescan(struct idle_proxy_info *proxy, Target *target,
host using the given proxy -- the proxy is cached so that you can keep
calling this function with different targets */
void idle_scan(Target *target, u16 *portarray, int numports,
char *proxyName) {
char *proxyName, const struct scan_lists * ports) {
static char lastproxy[MAXHOSTNAMELEN + 1] = ""; /* The proxy used in any previous call */
static struct idle_proxy_info proxy;
@ -1011,7 +1011,7 @@ void idle_scan(Target *target, u16 *portarray, int numports,
/* If this is the first call, */
if (!*lastproxy) {
initialize_idleproxy(&proxy, proxyName, target->v4hostip());
initialize_idleproxy(&proxy, proxyName, target->v4hostip(), ports);
}
starttime = time(NULL);

View file

@ -116,6 +116,6 @@ class Target;
port is received (those scans are in pos_scan). Super_scan
includes scans such as FIN/XMAS/NULL/Maimon/UDP and IP Proto scans */
void idle_scan(Target *target, u16 *portarray, int numports,
char *proxy);
char *proxy, const struct scan_lists * ports);
#endif /* IDLE_SCAN_H */

206
nmap.cc
View file

@ -460,6 +460,44 @@ static char *grab_next_host_spec(FILE *inputfd, int argc, char **fakeargv) {
return host_spec;
}
void validate_scan_lists(scan_lists &ports, NmapOps &o){
if (o.pingtype == PINGTYPE_UNKNOWN) {
if (o.isr00t && o.pf() == PF_INET) o.pingtype = DEFAULT_PING_TYPES;
else o.pingtype = PINGTYPE_TCP; // if nonr00t or IPv6
getpts_simple(DEFAULT_TCP_PROBE_PORT_SPEC, SCAN_TCP_PORT, &ports.ack_ping_ports, &ports.ack_ping_count);
assert(ports.ack_ping_count > 0);
}
if (!o.isr00t || o.pf() != PF_INET) {
// We will have to do a connect() style ping
if (ports.syn_ping_count && ports.ack_ping_count) {
fatal("Cannot use both SYN and ACK ping probes if you are nonroot or using IPv6");
}
// Pretend we wanted SYN probes all along.
if (ports.ack_ping_count > 0) {
ports.syn_ping_count = ports.ack_ping_count;
ports.syn_ping_ports = ports.ack_ping_ports;
ports.ack_ping_count = 0;
ports.ack_ping_ports = NULL;
}
o.pingtype &= ~PINGTYPE_TCP_USE_ACK;
o.pingtype |= PINGTYPE_TCP_USE_SYN;
}
#ifndef WIN32 /* Win32 has perfectly fine ICMP socket support */
if (!o.isr00t) {
if (o.pingtype & (PINGTYPE_ICMP_PING|PINGTYPE_ICMP_MASK|PINGTYPE_ICMP_TS)) {
error("Warning: You are not root -- using TCP pingscan rather than ICMP");
o.pingtype = PINGTYPE_TCP;
if (ports.syn_ping_count == 0){
getpts_simple(DEFAULT_TCP_PROBE_PORT_SPEC, SCAN_TCP_PORT, &ports.syn_ping_ports, &ports.syn_ping_count);
assert(ports.syn_ping_count > 0);
}
}
}
#endif
}
int nmap_main(int argc, char *argv[]) {
char *p, *q;
int i, arg;
@ -478,7 +516,7 @@ int nmap_main(int argc, char *argv[]) {
struct tm *tm;
HostGroupState *hstate = NULL;
char *endptr = NULL;
struct scan_lists *ports = NULL;
struct scan_lists ports = { 0 };
TargetGroup *exclude_group = NULL;
Traceroute *troute = NULL;
char myname[MAXHOSTNAMELEN + 1];
@ -1034,76 +1072,76 @@ int nmap_main(int argc, char *argv[]) {
else if (*optarg == 'R')
o.pingtype |= PINGTYPE_ARP;
else if (*optarg == 'S') {
if (o.num_ping_synprobes > 0)
if (ports.syn_ping_count > 0)
fatal("Only one -PS option is allowed. Combine port ranges with commas.");
o.pingtype |= (PINGTYPE_TCP|PINGTYPE_TCP_USE_SYN);
if (*(optarg + 1) != '\0') {
getpts_simple(optarg + 1, SCAN_TCP_PORT, &o.ping_synprobes, &o.num_ping_synprobes);
if (o.num_ping_synprobes <= 0)
getpts_simple(optarg + 1, SCAN_TCP_PORT, &ports.syn_ping_ports, &ports.syn_ping_count);
if (ports.syn_ping_count <= 0)
fatal("Bogus argument to -PS: %s", optarg + 1);
} else {
getpts_simple(DEFAULT_TCP_PROBE_PORT_SPEC, SCAN_TCP_PORT, &o.ping_synprobes, &o.num_ping_synprobes);
assert(o.num_ping_synprobes > 0);
getpts_simple(DEFAULT_TCP_PROBE_PORT_SPEC, SCAN_TCP_PORT, &ports.syn_ping_ports, &ports.syn_ping_count);
assert(ports.syn_ping_count > 0);
}
}
else if (*optarg == 'T' || *optarg == 'A') {
if (o.num_ping_ackprobes > 0)
if (ports.ack_ping_count > 0)
fatal("Only one -PB, -PA, or -PT option is allowed. Combine port ranges with commas.");
/* NmapOps::ValidateOptions() takes care of changing this
to SYN if not root or if IPv6 */
/* validate_scan_lists takes case of changing this to
to SYN if not root or if IPv6. */
o.pingtype |= (PINGTYPE_TCP|PINGTYPE_TCP_USE_ACK);
if (*(optarg + 1) != '\0') {
getpts_simple(optarg + 1, SCAN_TCP_PORT, &o.ping_ackprobes, &o.num_ping_ackprobes);
if (o.num_ping_ackprobes <= 0)
getpts_simple(optarg + 1, SCAN_TCP_PORT, &ports.ack_ping_ports, &ports.ack_ping_count);
if (ports.ack_ping_count <= 0)
fatal("Bogus argument to -PA: %s", optarg + 1);
} else {
getpts_simple(DEFAULT_TCP_PROBE_PORT_SPEC, SCAN_TCP_PORT, &o.ping_ackprobes, &o.num_ping_ackprobes);
assert(o.num_ping_ackprobes > 0);
getpts_simple(DEFAULT_TCP_PROBE_PORT_SPEC, SCAN_TCP_PORT, &ports.ack_ping_ports, &ports.ack_ping_count);
assert(ports.ack_ping_count > 0);
}
}
else if (*optarg == 'U') {
if (o.num_ping_udpprobes > 0)
if (ports.udp_ping_count > 0)
fatal("Only one -PU option is allowed. Combine port ranges with commas.");
o.pingtype |= (PINGTYPE_UDP);
if (*(optarg + 1) != '\0') {
getpts_simple(optarg + 1, SCAN_UDP_PORT, &o.ping_udpprobes, &o.num_ping_udpprobes);
if (o.num_ping_udpprobes <= 0)
getpts_simple(optarg + 1, SCAN_UDP_PORT, &ports.udp_ping_ports, &ports.udp_ping_count);
if (ports.udp_ping_count <= 0)
fatal("Bogus argument to -PU: %s", optarg + 1);
} else {
getpts_simple(DEFAULT_UDP_PROBE_PORT_SPEC, SCAN_UDP_PORT, &o.ping_udpprobes, &o.num_ping_udpprobes);
assert(o.num_ping_udpprobes > 0);
getpts_simple(DEFAULT_UDP_PROBE_PORT_SPEC, SCAN_UDP_PORT, &ports.udp_ping_ports, &ports.udp_ping_count);
assert(ports.udp_ping_count > 0);
}
}
else if (*optarg == 'B') {
if (o.num_ping_ackprobes > 0)
if (ports.ack_ping_count > 0)
fatal("Only one -PB, -PA, or -PT option is allowed. Combine port ranges with commas.");
o.pingtype = DEFAULT_PING_TYPES;
if (*(optarg + 1) != '\0') {
getpts_simple(optarg + 1, SCAN_TCP_PORT, &o.ping_ackprobes, &o.num_ping_ackprobes);
if (o.num_ping_ackprobes <= 0)
getpts_simple(optarg + 1, SCAN_TCP_PORT, &ports.ack_ping_ports, &ports.ack_ping_count);
if (ports.ack_ping_count <= 0)
fatal("Bogus argument to -PB: %s", optarg + 1);
} else {
getpts_simple(DEFAULT_TCP_PROBE_PORT_SPEC, SCAN_TCP_PORT, &o.ping_ackprobes, &o.num_ping_ackprobes);
assert(o.num_ping_ackprobes > 0);
getpts_simple(DEFAULT_TCP_PROBE_PORT_SPEC, SCAN_TCP_PORT, &ports.ack_ping_ports, &ports.ack_ping_count);
assert(ports.ack_ping_count > 0);
}
} else if (*optarg == 'O') {
if (o.num_ping_protoprobes > 0)
if (ports.proto_ping_count > 0)
fatal("Only one -PO option is allowed. Combine port ranges with commas.");
o.pingtype |= PINGTYPE_PROTO;
if (*(optarg + 1) != '\0') {
getpts_simple(optarg + 1, SCAN_PROTOCOLS, &o.ping_protoprobes, &o.num_ping_protoprobes);
if (o.num_ping_protoprobes <= 0)
getpts_simple(optarg + 1, SCAN_PROTOCOLS, &ports.proto_ping_ports, &ports.proto_ping_count);
if (ports.proto_ping_count <= 0)
fatal("Bogus argument to -PO: %s", optarg + 1);
} else {
getpts_simple(DEFAULT_PROTO_PROBE_PORT_SPEC, SCAN_PROTOCOLS, &o.ping_protoprobes, &o.num_ping_protoprobes);
assert(o.num_ping_protoprobes > 0);
getpts_simple(DEFAULT_PROTO_PROBE_PORT_SPEC, SCAN_PROTOCOLS, &ports.proto_ping_ports, &ports.proto_ping_count);
assert(ports.proto_ping_count > 0);
}
} else {
fatal("Illegal Argument to -P, use -PN, -PO, -PI, -PB, -PE, -PM, -PP, -PA, -PU, -PT, or -PT80 (or whatever number you want for the TCP probe destination port)");
}
break;
case 'p':
if (ports || portlist)
if (portlist)
fatal("Only 1 -p option allowed, separate multiple ranges with commas.");
portlist = strdup(optarg);
break;
@ -1231,6 +1269,7 @@ int nmap_main(int argc, char *argv[]) {
if (o.osscan == OS_SCAN_DEFAULT)
o.reference_FPs = parse_fingerprint_reference_file("nmap-os-db");
validate_scan_lists(ports,o);
o.ValidateOptions();
// print ip options
@ -1287,22 +1326,19 @@ int nmap_main(int argc, char *argv[]) {
fatal("You cannot use -F (fast scan) with -p (explicit port selection) but see --top-ports and --port-ratio to fast scan a range of ports");
if (o.ipprotscan) {
if (portlist) ports = getpts(portlist);
else ports = getpts((char *) (o.fastscan ? "[P:0-]" : "0-")); // Default protocols to scan
if (portlist) getpts(portlist, &ports);
else getpts((char *) (o.fastscan ? "[P:0-]" : "0-"), &ports); // Default protocols to scan
} else {
ports = gettoppts(o.topportlevel, portlist);
gettoppts(o.topportlevel, portlist, &ports);
}
if (portlist && !ports)
fatal("Your port specification string is not parseable");
if (portlist) {
free(portlist);
portlist = NULL;
}
// Uncomment the following line to use the common lisp port spec test suite
//printf("port spec: (%d %d %d)\n", ports->tcp_count, ports->udp_count, ports->prot_count); exit(0);
//printf("port spec: (%d %d %d)\n", ports.tcp_count, ports.udp_count, ports.prot_count); exit(0);
#ifdef WIN32
if (o.sendpref & PACKET_SEND_IP) {
@ -1361,11 +1397,11 @@ int nmap_main(int argc, char *argv[]) {
* (such as OS ident scan) might break cause no ports were specified, but
* we've given our warning...
*/
if ((o.TCPScan()) && ports->tcp_count == 0)
if ((o.TCPScan()) && ports.tcp_count == 0)
error("WARNING: a TCP scan type was requested, but no tcp ports were specified. Skipping this scan type.");
if (o.UDPScan() && ports->udp_count == 0)
if (o.UDPScan() && ports.udp_count == 0)
error("WARNING: UDP scan was requested, but no udp ports were specified. Skipping this scan type.");
if (o.ipprotscan && ports->prot_count == 0)
if (o.ipprotscan && ports.prot_count == 0)
error("WARNING: protocol scan was requested, but no protocols were specified to be scanned. Skipping this scan type.");
/* Set up our array of decoys! */
@ -1448,7 +1484,7 @@ int nmap_main(int argc, char *argv[]) {
log_write(LOG_XML, "start=\"%lu\" startstr=\"%s\" version=\"%s\" xmloutputversion=\"1.02\">\n",
(unsigned long) timep, mytime, NMAP_VERSION);
output_xml_scaninfo_records(ports);
output_xml_scaninfo_records(&ports);
log_write(LOG_XML, "<verbose level=\"%d\" />\n<debugging level=\"%d\" />\n",
o.verbose, o.debugging);
@ -1456,7 +1492,7 @@ int nmap_main(int argc, char *argv[]) {
/* Before we randomize the ports scanned, lets output them to machine
parseable output */
if (o.verbose)
output_ports_to_machine_parseable_output(ports, o.TCPScan(), o.udpscan, o.ipprotscan);
output_ports_to_machine_parseable_output(&ports, o.TCPScan(), o.udpscan, o.ipprotscan);
/* more fakeargv junk, BTW malloc'ing extra space in argv[0] doesn't work */
if (quashargv) {
@ -1495,22 +1531,22 @@ int nmap_main(int argc, char *argv[]) {
/* Before we randomize the ports scanned, we must initialize PortList class. */
if (o.ipprotscan)
PortList::initializePortMap(IPPROTO_IP, ports->prots, ports->prot_count);
PortList::initializePortMap(IPPROTO_IP, ports.prots, ports.prot_count);
if (o.TCPScan())
PortList::initializePortMap(IPPROTO_TCP, ports->tcp_ports, ports->tcp_count);
PortList::initializePortMap(IPPROTO_TCP, ports.tcp_ports, ports.tcp_count);
if (o.UDPScan())
PortList::initializePortMap(IPPROTO_UDP, ports->udp_ports, ports->udp_count);
PortList::initializePortMap(IPPROTO_UDP, ports.udp_ports, ports.udp_count);
if (randomize) {
if (ports->tcp_count) {
shortfry(ports->tcp_ports, ports->tcp_count);
if (ports.tcp_count) {
shortfry(ports.tcp_ports, ports.tcp_count);
// move a few more common ports closer to the beginning to speed scan
random_port_cheat(ports->tcp_ports, ports->tcp_count);
random_port_cheat(ports.tcp_ports, ports.tcp_count);
}
if (ports->udp_count)
shortfry(ports->udp_ports, ports->udp_count);
if (ports->prot_count)
shortfry(ports->prots, ports->prot_count);
if (ports.udp_count)
shortfry(ports.udp_ports, ports.udp_count);
if (ports.prot_count)
shortfry(ports.prots, ports.prot_count);
}
/* lets load our exclude list */
@ -1544,10 +1580,10 @@ int nmap_main(int argc, char *argv[]) {
host_exp_group, num_host_exp_groups);
do {
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) {
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 */
@ -1568,7 +1604,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;
}
@ -1653,7 +1689,7 @@ int nmap_main(int argc, char *argv[]) {
/* ping scan traceroutes */
if(o.traceroute && o.pingscan) {
/* Assume that all targets in a group use the same device */
troute = new Traceroute(Targets[0]->deviceName(), Targets[0]->ifType());
troute = new Traceroute(Targets[0]->deviceName(), Targets[0]->ifType(), &ports);
troute->trace(Targets);
troute->resolveHops();
@ -1681,34 +1717,34 @@ int nmap_main(int argc, char *argv[]) {
// Ultra_scan sets o.scantype for us so we don't have to worry
if (o.synscan)
ultra_scan(Targets, ports, SYN_SCAN);
ultra_scan(Targets, &ports, SYN_SCAN);
if (o.ackscan)
ultra_scan(Targets, ports, ACK_SCAN);
ultra_scan(Targets, &ports, ACK_SCAN);
if (o.windowscan)
ultra_scan(Targets, ports, WINDOW_SCAN);
ultra_scan(Targets, &ports, WINDOW_SCAN);
if (o.finscan)
ultra_scan(Targets, ports, FIN_SCAN);
ultra_scan(Targets, &ports, FIN_SCAN);
if (o.xmasscan)
ultra_scan(Targets, ports, XMAS_SCAN);
ultra_scan(Targets, &ports, XMAS_SCAN);
if (o.nullscan)
ultra_scan(Targets, ports, NULL_SCAN);
ultra_scan(Targets, &ports, NULL_SCAN);
if (o.maimonscan)
ultra_scan(Targets, ports, MAIMON_SCAN);
ultra_scan(Targets, &ports, MAIMON_SCAN);
if (o.udpscan)
ultra_scan(Targets, ports, UDP_SCAN);
ultra_scan(Targets, &ports, UDP_SCAN);
if (o.connectscan)
ultra_scan(Targets, ports, CONNECT_SCAN);
ultra_scan(Targets, &ports, CONNECT_SCAN);
if (o.ipprotscan)
ultra_scan(Targets, ports, IPPROT_SCAN);
ultra_scan(Targets, &ports, IPPROT_SCAN);
/* These lame functions can only handle one target at a time */
for(targetno = 0; targetno < Targets.size(); targetno++) {
@ -1716,15 +1752,15 @@ int nmap_main(int argc, char *argv[]) {
if (o.idlescan) {
o.current_scantype = IDLE_SCAN;
keyWasPressed(); // Check if a status message should be printed
idle_scan(currenths, ports->tcp_ports,
ports->tcp_count, idleProxy);
idle_scan(currenths, ports.tcp_ports,
ports.tcp_count, idleProxy, &ports);
}
if (o.bouncescan) {
o.current_scantype = BOUNCE_SCAN;
keyWasPressed(); // Check if a status message should be printed
if (ftp.sd <= 0) ftp_anon_connect(&ftp);
if (ftp.sd > 0) bounce_scan(currenths, ports->tcp_ports,
ports->tcp_count, &ftp);
if (ftp.sd > 0) bounce_scan(currenths, ports.tcp_ports,
ports.tcp_count, &ftp);
}
}
@ -1742,7 +1778,7 @@ int nmap_main(int argc, char *argv[]) {
os_scan2(Targets);
if(o.traceroute) {
troute = new Traceroute(Targets[0]->deviceName(), Targets[0]->ifType());
troute = new Traceroute(Targets[0]->deviceName(), Targets[0]->ifType(), &ports);
troute->trace(Targets);
troute->resolveHops();
}
@ -1825,7 +1861,7 @@ int nmap_main(int argc, char *argv[]) {
printfinaloutput();
free_scan_lists(ports);
free_scan_lists(&ports);
eth_close_cached();
@ -2058,9 +2094,8 @@ void init_socket(int sd) {
static void getpts_aux(const char *origexpr, int nested, u8 *porttbl, int range_type,
int *portwarning, bool change_range_type = true);
struct scan_lists *getpts(const char *origexpr) {
void getpts(const char *origexpr, struct scan_lists *ports) {
u8 *porttbl;
struct scan_lists *ports;
int range_type = 0;
int portwarning = 0;
int i, tcpi, udpi, proti;
@ -2073,7 +2108,6 @@ struct scan_lists *getpts(const char *origexpr) {
range_type |= SCAN_PROTOCOLS;
porttbl = (u8 *) safe_zalloc(65536);
ports = (struct scan_lists *) safe_zalloc(sizeof(struct scan_lists));
getpts_aux(origexpr, // Pass on the expression
0, // Don't start off nested
@ -2116,15 +2150,12 @@ struct scan_lists *getpts(const char *origexpr) {
}
free(porttbl);
return ports;
}
/* This function is like getpts except that instead of returning several lists
of ports in a struct scan_lists, it allocates only one list and stores it in
the list and count arguments. For that reason, T:, U:, and P: restrictions
are not allowed and only one bit in range_type may be set. */
/* This function is like getpts except it only allocates space for and stores
values into one unsigned short array, instead of an entire scan_lists struct
For that reason, T:, U:, and P: restrictions are not allowed and only one
bit in range_type may be set. */
void getpts_simple(const char *origexpr, int range_type,
unsigned short **list, int *count) {
u8 *porttbl;
@ -2336,12 +2367,13 @@ static void getpts_aux(const char *origexpr, int nested, u8 *porttbl, int range_
}
void free_scan_lists(struct scan_lists *ports) {
if (ports) {
if (ports->tcp_ports) free(ports->tcp_ports);
if (ports->udp_ports) free(ports->udp_ports);
if (ports->prots) free(ports->prots);
free(ports);
}
if (ports->tcp_ports) free(ports->tcp_ports);
if (ports->udp_ports) free(ports->udp_ports);
if (ports->prots) free(ports->prots);
if (ports->syn_ping_ports) free(ports->syn_ping_ports);
if (ports->ack_ping_ports) free(ports->ack_ping_ports);
if (ports->udp_ping_ports) free(ports->udp_ping_ports);
if (ports->proto_ping_ports) free(ports->proto_ping_ports);
}
void printinteractiveusage() {

2
nmap.h
View file

@ -404,7 +404,7 @@ void printinteractiveusage();
int ftp_anon_connect(struct ftpinfo *ftp);
/* port manipulators */
struct scan_lists *getpts(const char *expr); /* someone stole the name getports()! */
void getpts(const char *expr, struct scan_lists * ports); /* someone stole the name getports()! */
void getpts_simple(const char *origexpr, int range_type,
unsigned short **list, int *count);
void free_scan_lists(struct scan_lists *ports);

View file

@ -1473,12 +1473,12 @@ unsigned int UltraScanInfo::numProbesPerHost()
numprobes = 0;
if (ptech.rawtcpscan) {
if (o.pingtype & PINGTYPE_TCP_USE_ACK)
numprobes += o.num_ping_ackprobes;
numprobes += ports->ack_ping_count;
if (o.pingtype & PINGTYPE_TCP_USE_SYN)
numprobes += o.num_ping_synprobes;
numprobes += ports->syn_ping_count;
}
if (ptech.rawudpscan)
numprobes += o.num_ping_udpprobes;
numprobes += ports->udp_ping_count;
if (ptech.rawicmpscan) {
if (o.pingtype & PINGTYPE_ICMP_PING)
numprobes++;
@ -1488,9 +1488,9 @@ unsigned int UltraScanInfo::numProbesPerHost()
numprobes++;
}
if (ptech.rawprotoscan)
numprobes += o.num_ping_protoprobes;
numprobes += ports->proto_ping_count;
if (ptech.connecttcpscan)
numprobes += o.num_ping_synprobes;
numprobes += ports->syn_ping_count;
} else assert(0); /* TODO: RPC scan */
return numprobes;
@ -1762,22 +1762,22 @@ static int get_next_target_probe(UltraScanInfo *USI, HostScanStats *hss,
pspec->type = PS_TCP;
pspec->proto = IPPROTO_TCP;
if ((o.pingtype & PINGTYPE_TCP_USE_ACK)
&& hss->next_ackportpingidx < o.num_ping_ackprobes) {
pspec->pd.tcp.dport = o.ping_ackprobes[hss->next_ackportpingidx++];
&& hss->next_ackportpingidx < USI->ports->ack_ping_count) {
pspec->pd.tcp.dport = USI->ports->ack_ping_ports[hss->next_ackportpingidx++];
pspec->pd.tcp.flags = TH_ACK;
return 0;
}
if ((o.pingtype & PINGTYPE_TCP_USE_SYN)
&& hss->next_synportpingidx < o.num_ping_synprobes) {
pspec->pd.tcp.dport = o.ping_synprobes[hss->next_synportpingidx++];
&& hss->next_synportpingidx < USI->ports->syn_ping_count) {
pspec->pd.tcp.dport = USI->ports->syn_ping_ports[hss->next_synportpingidx++];
pspec->pd.tcp.flags = TH_SYN;
return 0;
}
}
if (USI->ptech.rawudpscan && hss->next_udpportpingidx < o.num_ping_udpprobes) {
if (USI->ptech.rawudpscan && hss->next_udpportpingidx < USI->ports->udp_ping_count) {
pspec->type = PS_UDP;
pspec->proto = IPPROTO_UDP;
pspec->pd.udp.dport = o.ping_udpprobes[hss->next_udpportpingidx++];
pspec->pd.udp.dport = USI->ports->udp_ping_ports[hss->next_udpportpingidx++];
return 0;
}
if (USI->ptech.rawicmpscan) {
@ -1804,13 +1804,13 @@ static int get_next_target_probe(UltraScanInfo *USI, HostScanStats *hss,
}
if (USI->ptech.rawprotoscan) {
pspec->type = PS_PROTO;
pspec->proto = o.ping_protoprobes[hss->next_protoportpingidx++];
pspec->proto = USI->ports->proto_ping_ports[hss->next_protoportpingidx++];
return 0;
}
if (USI->ptech.connecttcpscan && hss->next_synportpingidx < o.num_ping_synprobes) {
if (USI->ptech.connecttcpscan && hss->next_synportpingidx < USI->ports->syn_ping_count) {
pspec->type = PS_CONNECTTCP;
pspec->proto = IPPROTO_TCP;
pspec->pd.tcp.dport = o.ping_synprobes[hss->next_synportpingidx++];
pspec->pd.tcp.dport = USI->ports->syn_ping_ports[hss->next_synportpingidx++];
pspec->pd.tcp.flags = TH_SYN;
return 0;
}
@ -1840,14 +1840,14 @@ int HostScanStats::freshPortsLeft() {
unsigned int num_probes = 0;
if (USI->ptech.rawtcpscan) {
if ((o.pingtype & PINGTYPE_TCP_USE_ACK)
&& next_ackportpingidx < o.num_ping_ackprobes)
num_probes += o.num_ping_ackprobes - next_ackportpingidx;
&& next_ackportpingidx < USI->ports->ack_ping_count)
num_probes += USI->ports->ack_ping_count - next_ackportpingidx;
if ((o.pingtype & PINGTYPE_TCP_USE_SYN)
&& next_synportpingidx < o.num_ping_synprobes)
num_probes += o.num_ping_synprobes - next_synportpingidx;
&& next_synportpingidx < USI->ports->syn_ping_count)
num_probes += USI->ports->syn_ping_count - next_synportpingidx;
}
if (USI->ptech.rawudpscan && next_udpportpingidx < o.num_ping_udpprobes)
num_probes += o.num_ping_udpprobes - next_udpportpingidx;
if (USI->ptech.rawudpscan && next_udpportpingidx < USI->ports->udp_ping_count)
num_probes += USI->ports->udp_ping_count - next_udpportpingidx;
if (USI->ptech.rawicmpscan) {
if ((o.pingtype & PINGTYPE_ICMP_PING) && !sent_icmp_ping)
num_probes++;
@ -1857,9 +1857,9 @@ int HostScanStats::freshPortsLeft() {
num_probes++;
}
if (USI->ptech.rawprotoscan)
num_probes += o.num_ping_protoprobes - next_protoportpingidx;
if (USI->ptech.connecttcpscan && next_synportpingidx < o.num_ping_synprobes)
num_probes += o.num_ping_synprobes - next_synportpingidx;
num_probes += USI->ports->proto_ping_count - next_protoportpingidx;
if (USI->ptech.connecttcpscan && next_synportpingidx < USI->ports->syn_ping_count)
num_probes += USI->ports->syn_ping_count - next_synportpingidx;
return num_probes;
}
assert(0);
@ -3150,6 +3150,10 @@ static void printAnyStats(UltraScanInfo *USI) {
USI->send_rate_meter.getOverallByteRate());
}
if (o.debugging > 2) {
log_write(LOG_PLAIN, "packet_ratio: %.2f %d/%d %.5f = 1 / %.5f\n", o.TimeSinceStartMS() / 1000.0, USI->gstats->probes_replied_to, USI->gstats->probes_sent, 1.0 / USI->gstats->cc_scale(), USI->gstats->cc_scale());
}
/* Now time to figure out how close we are to completion ... */
if (USI->SPM->mayBePrinted(&USI->now)) {
list<HostScanStats *>::iterator hostI;
@ -3351,7 +3355,7 @@ static bool do_one_select_round(UltraScanInfo *USI, struct timeval *stime) {
current_reason = ER_CONREFUSED;
break;
case EAGAIN:
log_write(LOG_STDOUT, "Machine %s MIGHT actually be listening on probe port %d\n", host->target->targetipstr(), o.ping_synprobes[probe->dport()]);
log_write(LOG_STDOUT, "Machine %s MIGHT actually be listening on probe port %d\n", host->target->targetipstr(), USI->ports->syn_ping_ports[probe->dport()]);
/* Fall through. */
#ifdef WIN32
case WSAENOTCONN:

View file

@ -1070,10 +1070,10 @@ void parse_nmap_service_probe_file(AllProbes *AP, char *filename) {
continue;
if (strncmp(line, "Exclude ", 8) == 0) {
if (AP->excludedports != NULL)
if (AP->excluded_seen)
fatal("Only 1 Exclude directive is allowed in the nmap-service-probes file");
AP->excludedports = getpts(line+8);
getpts(line+8, &AP->excludedports);
AP->excluded_seen = true;
continue;
}
@ -1191,7 +1191,8 @@ const struct MatchDetails *ServiceProbe::testMatch(const u8 *buf, int buflen) {
AllProbes::AllProbes() {
nullProbe = NULL;
excludedports = NULL;
excluded_seen = false;
memset(&excludedports, 0, sizeof(excludedports));
}
AllProbes::~AllProbes() {
@ -1203,7 +1204,7 @@ AllProbes::~AllProbes() {
}
if(nullProbe)
delete nullProbe;
free_scan_lists(excludedports);
free_scan_lists(&excludedports);
}
// Tries to find the probe in this AllProbes class which have the
@ -1235,14 +1236,14 @@ int AllProbes::isExcluded(unsigned short port, int proto) {
unsigned short *p=NULL;
int count=-1,i;
if (!excludedports) return 0;
if (!excluded_seen) return 0;
if (proto == IPPROTO_TCP) {
p = excludedports->tcp_ports;
count = excludedports->tcp_count;
p = excludedports.tcp_ports;
count = excludedports.tcp_count;
} else if (proto == IPPROTO_UDP) {
p = excludedports->udp_ports;
count = excludedports->udp_count;
p = excludedports.udp_ports;
count = excludedports.udp_count;
} else {
fatal("Bad proto number (%d) specified in %s", proto, __func__);
}

View file

@ -333,7 +333,8 @@ public:
void compileFallbacks();
int isExcluded(unsigned short port, int proto);
struct scan_lists *excludedports;
bool excluded_seen;
struct scan_lists excludedports;
static AllProbes *service_scan_init(void);
static void service_scan_free(void);

View file

@ -350,8 +350,9 @@ static int is_port_member(struct scan_lists *ptsdata, struct service_list *serv)
return 0;
}
// gettoppts() returns a scan_list with the most common ports scanned by
// Nmap according to the ratios specified in the nmap-services file.
// gettoppts() sets its third parameter, a scan_list, with the most
// common ports scanned by Nmap according to the ratios specified in
// the nmap-services file.
//
// If level is below 1.0 then we treat it as a minimum ratio and we
// add all ports with ratios above level.
@ -362,9 +363,10 @@ static int is_port_member(struct scan_lists *ptsdata, struct service_list *serv)
// This function doesn't support IP protocol scan so only call this
// function if o.TCPScan() || o.UDPScan()
struct scan_lists *gettoppts(double level, char *portlist) {
void gettoppts(double level, char *portlist, struct scan_lists * ports) {
int ti=0, ui=0;
struct scan_lists *sl, *ptsdata=NULL;
struct scan_lists ptsdata = { 0 };
bool ptsdata_initialized = false;
struct service_list *current;
if (!services_initialized && nmap_services_init() == -1)
@ -374,52 +376,58 @@ struct scan_lists *gettoppts(double level, char *portlist) {
if (level != -1)
fatal("Unable to use --top-ports or --port-ratio with an old style (no-ratio) services file");
if (portlist)
return getpts(portlist);
else if (o.fastscan)
return getpts("[-]");
else
return getpts("1-1024,[1025-]");
if (portlist){
getpts(portlist, ports);
return;
}else if (o.fastscan){
getpts("[-]", ports);
return;
}else{
getpts("1-1024,[1025-]", ports);
return;
}
}
// TOP PORT DEFAULTS
if (level == -1) {
if (portlist)
return getpts(portlist);
if (portlist){
getpts(portlist, ports);
return;
}
if (o.fastscan) level = 100;
else level = 0.01;
}
sl = (struct scan_lists *) safe_zalloc(sizeof(struct scan_lists));
if (portlist) ptsdata = getpts(portlist);
if (portlist){
getpts(portlist, &ptsdata);
ptsdata_initialized = true;
}
if (level < 1) {
for (current=sorted_services; current; current=current->next) {
if (ptsdata && !is_port_member(ptsdata, current)) continue;
if (ptsdata_initialized && !is_port_member(&ptsdata, current)) continue;
if (current->ratio >= level) {
if (o.TCPScan() && current->servent->s_proto[0] == 't') sl->tcp_count++;
else if (o.UDPScan() && current->servent->s_proto[0] == 'u') sl->udp_count++;
if (o.TCPScan() && current->servent->s_proto[0] == 't') ports->tcp_count++;
else if (o.UDPScan() && current->servent->s_proto[0] == 'u') ports->udp_count++;
} else break;
}
if (sl->tcp_count)
sl->tcp_ports = (unsigned short *)safe_zalloc(sl->tcp_count * sizeof(unsigned short));
if (ports->tcp_count)
ports->tcp_ports = (unsigned short *)safe_zalloc(ports->tcp_count * sizeof(unsigned short));
if (sl->udp_count)
sl->udp_ports = (unsigned short *)safe_zalloc(sl->udp_count * sizeof(unsigned short));
if (ports->udp_count)
ports->udp_ports = (unsigned short *)safe_zalloc(ports->udp_count * sizeof(unsigned short));
sl->prots = NULL;
ports->prots = NULL;
for (current=sorted_services;current;current=current->next) {
if (ptsdata && !is_port_member(ptsdata, current)) continue;
if (ptsdata_initialized && !is_port_member(&ptsdata, current)) continue;
if (current->ratio >= level) {
if (o.TCPScan() && current->servent->s_proto[0] == 't')
sl->tcp_ports[ti++] = ntohs(current->servent->s_port);
ports->tcp_ports[ti++] = ntohs(current->servent->s_port);
else if (o.UDPScan() && current->servent->s_proto[0] == 'u')
sl->udp_ports[ui++] = ntohs(current->servent->s_port);
ports->udp_ports[ui++] = ntohs(current->servent->s_port);
} else break;
}
} else if (level >= 1) {
@ -427,43 +435,45 @@ struct scan_lists *gettoppts(double level, char *portlist) {
fatal("Level argument to gettoppts (%g) is too large", level);
if (o.TCPScan()) {
sl->tcp_count = MIN((int) level, numtcpports);
sl->tcp_ports = (unsigned short *)safe_zalloc(sl->tcp_count * sizeof(unsigned short));
ports->tcp_count = MIN((int) level, numtcpports);
ports->tcp_ports = (unsigned short *)safe_zalloc(ports->tcp_count * sizeof(unsigned short));
}
if (o.UDPScan()) {
sl->udp_count = MIN((int) level, numudpports);
sl->udp_ports = (unsigned short *)safe_zalloc(sl->udp_count * sizeof(unsigned short));
ports->udp_count = MIN((int) level, numudpports);
ports->udp_ports = (unsigned short *)safe_zalloc(ports->udp_count * sizeof(unsigned short));
}
sl->prots = NULL;
ports->prots = NULL;
for (current=sorted_services;current && (ti < sl->tcp_count || ui < sl->udp_count);current=current->next) {
if (ptsdata && !is_port_member(ptsdata, current)) continue;
for (current=sorted_services;current && (ti < ports->tcp_count || ui < ports->udp_count);current=current->next) {
if (ptsdata_initialized && !is_port_member(&ptsdata, current)) continue;
if (o.TCPScan() && current->servent->s_proto[0] == 't' && ti < sl->tcp_count)
sl->tcp_ports[ti++] = ntohs(current->servent->s_port);
else if (o.UDPScan() && current->servent->s_proto[0] == 'u' && ui < sl->udp_count)
sl->udp_ports[ui++] = ntohs(current->servent->s_port);
if (o.TCPScan() && current->servent->s_proto[0] == 't' && ti < ports->tcp_count)
ports->tcp_ports[ti++] = ntohs(current->servent->s_port);
else if (o.UDPScan() && current->servent->s_proto[0] == 'u' && ui < ports->udp_count)
ports->udp_ports[ui++] = ntohs(current->servent->s_port);
}
if (ti < sl->tcp_count) sl->tcp_count = ti;
if (ui < sl->udp_count) sl->udp_count = ui;
if (ti < ports->tcp_count) ports->tcp_count = ti;
if (ui < ports->udp_count) ports->udp_count = ui;
} else
fatal("Argument to gettoppts (%g) should be a positive ratio below 1 or an integer of 1 or higher", level);
if (ptsdata) free_scan_lists(ptsdata);
if (ptsdata_initialized) {
free_scan_lists(&ptsdata);
ptsdata_initialized = false;
}
if (sl->tcp_count > 1)
qsort(sl->tcp_ports, sl->tcp_count, sizeof(unsigned short), &port_compare);
if (ports->tcp_count > 1)
qsort(ports->tcp_ports, ports->tcp_count, sizeof(unsigned short), &port_compare);
if (sl->udp_count > 1)
qsort(sl->udp_ports, sl->udp_count, sizeof(unsigned short), &port_compare);
if (ports->udp_count > 1)
qsort(ports->udp_ports, ports->udp_count, sizeof(unsigned short), &port_compare);
if (o.debugging && level < 1)
log_write(LOG_STDOUT, "PORTS: Using ports open on %g%% or more average hosts (TCP:%d, UDP:%d)\n", level*100, sl->tcp_count, sl->udp_count);
log_write(LOG_STDOUT, "PORTS: Using ports open on %g%% or more average hosts (TCP:%d, UDP:%d)\n", level*100, ports->tcp_count, ports->udp_count);
else if (o.debugging && level >= 1)
log_write(LOG_STDOUT, "PORTS: Using top %d ports found open (TCP:%d, UDP:%d)\n", (int) level, sl->tcp_count, sl->udp_count);
return sl;
log_write(LOG_STDOUT, "PORTS: Using top %d ports found open (TCP:%d, UDP:%d)\n", (int) level, ports->tcp_count, ports->udp_count);
}

View file

@ -130,6 +130,6 @@ struct service_list {
int addportsfromservmask(char *mask, u8 *porttbl, int range_type);
struct servent *nmap_getservbyport(int port, const char *proto);
struct scan_lists *gettoppts(double level, char *portlist);
void gettoppts(double level, char *portlist, struct scan_lists * ports);
#endif

View file

@ -429,7 +429,7 @@ int dumpExclude(TargetGroup *exclude_group) {
return 1;
}
static void massping(Target *hostbatch[], int num_hosts, int pingtype) {
static void massping(Target *hostbatch[], int num_hosts, struct scan_lists *ports, int pingtype) {
static struct timeout_info group_to = { 0, 0, 0 };
static char prev_device_name[16] = "";
const char *device_name;
@ -460,7 +460,7 @@ static void massping(Target *hostbatch[], int num_hosts, int pingtype) {
}
/* ultra_scan gets pingtype from o.pingtype. */
ultra_scan(targets, NULL, PING_SCAN, &group_to);
ultra_scan(targets, ports, PING_SCAN, &group_to);
}
Target *nexthost(HostGroupState *hs, TargetGroup *exclude_group,
@ -612,9 +612,9 @@ 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, DEFAULT_PING_TYPES);
massping(hs->hostbatch, hs->current_batch_sz, ports, DEFAULT_PING_TYPES);
else
massping(hs->hostbatch, hs->current_batch_sz, pingtype);
massping(hs->hostbatch, hs->current_batch_sz, ports, pingtype);
}
if (!o.noresolve) nmap_mass_rdns(hs->hostbatch, hs->current_batch_sz);

View file

@ -195,8 +195,9 @@ static char *hostStr (u32 ip);
* trace */
unsigned long commonPath[MAX_TTL + 1];
Traceroute::Traceroute (const char *device_name, devtype type) {
Traceroute::Traceroute (const char *device_name, devtype type, const scan_lists * ports) {
fd = -1;
scanlists = ports;
ethsd = NULL;
hops = NULL;
pd = NULL;
@ -332,11 +333,11 @@ Traceroute::getTracePort (u8 proto, Target * t) {
/* Use the first specified port for ping traceroutes */
if (o.pingscan) {
if (o.pingtype & PINGTYPE_TCP_USE_SYN)
return o.ping_synprobes[0];
return scanlists->syn_ping_ports[0];
else if (o.pingtype & PINGTYPE_TCP_USE_ACK)
return o.ping_ackprobes[0];
return scanlists->ack_ping_ports[0];
else if (o.pingtype & PINGTYPE_UDP)
return o.ping_udpprobes[0];
return scanlists->udp_ping_ports[0];
else
return 0;
}

View file

@ -328,7 +328,7 @@ class TraceGroup {
/* Public interface to traceroute functionality */
class Traceroute {
public:
Traceroute (const char *device_name, devtype type);
Traceroute (const char *device_name, devtype type, const scan_lists * probe_ports);
~Traceroute ();
/* perform the traceroute on a list of targets */
@ -344,6 +344,7 @@ class Traceroute {
std::map < u32, TraceGroup * >TraceGroups;
struct scan_info scaninfo;
const struct scan_lists * scanlists;
Target **hops;
pcap_t *pd;
eth_t *ethsd;