mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 12:41:29 +00:00
memory releasing patch from Marek
This commit is contained in:
15
CHANGELOG
15
CHANGELOG
@@ -13,8 +13,23 @@ o Updated the Windows installer to give an option checkbox for
|
|||||||
performing the Nmap performance registry changes. The default is to
|
performing the Nmap performance registry changes. The default is to
|
||||||
do so. Thanks to Adam Vartanian (flooey(a)gmail.com) for the patch.
|
do so. Thanks to Adam Vartanian (flooey(a)gmail.com) for the patch.
|
||||||
|
|
||||||
|
o Nmap now provides progress statistics in the XML output in verbose
|
||||||
|
mode. Here are some examples of the format (etc is "estimated time
|
||||||
|
until completion) and times are in unix time_t (seconds since 1970) format:
|
||||||
|
<taskbegin task="SYN Stealth Scan" time="1151384685" />
|
||||||
|
<taskprogress task="SYN Stealth Scan" time="1151384715"
|
||||||
|
percent="13.85" remaining="187" etc="1151384902" />
|
||||||
|
<taskend task="SYN Stealth Scan" time="1151384776" />
|
||||||
|
<taskbegin task="Service scan" time="1151384776" />
|
||||||
|
<taskend task="Service scan" time="1151384788" />
|
||||||
|
Thanks to Adam Vartanian (flooey(a)gmail.com) for the patch.
|
||||||
|
|
||||||
o Applied several code cleanup patches from Marek Majkowski.
|
o Applied several code cleanup patches from Marek Majkowski.
|
||||||
|
|
||||||
|
o Added --release-memory option, which causes Nmap to release all
|
||||||
|
accessible memory buffers before quitting (rather than let the OS do
|
||||||
|
it). This is only useful for debugging memory leaks.
|
||||||
|
|
||||||
o Fixed a bug related to bogus completion time estimates when you
|
o Fixed a bug related to bogus completion time estimates when you
|
||||||
request an estimate (through runtime interaction) right when Nmap is
|
request an estimate (through runtime interaction) right when Nmap is
|
||||||
starting.a subsystem (such as a port scan or version detection).
|
starting.a subsystem (such as a port scan or version detection).
|
||||||
|
|||||||
@@ -300,6 +300,7 @@ class NmapOps {
|
|||||||
stype current_scantype;
|
stype current_scantype;
|
||||||
bool noninteractive;
|
bool noninteractive;
|
||||||
|
|
||||||
|
bool release_memory; /* suggest to release memory before quitting. used to find memory leaks. */
|
||||||
private:
|
private:
|
||||||
int max_rtt_timeout;
|
int max_rtt_timeout;
|
||||||
int min_rtt_timeout;
|
int min_rtt_timeout;
|
||||||
|
|||||||
10
charpool.cc
10
charpool.cc
@@ -122,6 +122,16 @@ static int cp_init(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cp_free(void) {
|
||||||
|
int ccp;
|
||||||
|
for(ccp=0; ccp <= currentcharpool; ccp++)
|
||||||
|
if(charpool[ccp]){
|
||||||
|
free(charpool[ccp]);
|
||||||
|
charpool[ccp] = NULL;
|
||||||
|
}
|
||||||
|
currentcharpool = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void cp_grow(void) {
|
static inline void cp_grow(void) {
|
||||||
/* Doh! We've got to make room */
|
/* Doh! We've got to make room */
|
||||||
if (++currentcharpool > 15) {
|
if (++currentcharpool > 15) {
|
||||||
|
|||||||
@@ -107,4 +107,7 @@
|
|||||||
|
|
||||||
void *cp_alloc(int sz);
|
void *cp_alloc(int sz);
|
||||||
char *cp_strdup(const char *src);
|
char *cp_strdup(const char *src);
|
||||||
|
|
||||||
|
void cp_free(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
<!ENTITY % attr_numeric "CDATA" >
|
<!ENTITY % attr_numeric "CDATA" >
|
||||||
<!ENTITY % attr_ipaddr "CDATA" >
|
<!ENTITY % attr_ipaddr "CDATA" >
|
||||||
<!ENTITY % attr_numeric "CDATA" >
|
<!ENTITY % attr_numeric "CDATA" >
|
||||||
|
<!ENTITY % attr_percent "CDATA" >
|
||||||
<!ENTITY % attr_type "(ipv4 | ipv6 | mac)" >
|
<!ENTITY % attr_type "(ipv4 | ipv6 | mac)" >
|
||||||
|
|
||||||
<!ENTITY % host_states "(up|down|unknown|skipped)" >
|
<!ENTITY % host_states "(up|down|unknown|skipped)" >
|
||||||
@@ -71,7 +72,7 @@
|
|||||||
<!-- This element was started in nmap.c:nmap_main().
|
<!-- This element was started in nmap.c:nmap_main().
|
||||||
It represents to the topmost element of the output document.
|
It represents to the topmost element of the output document.
|
||||||
-->
|
-->
|
||||||
<!ELEMENT nmaprun (scaninfo*, verbose, debugging, host*, runstats) >
|
<!ELEMENT nmaprun (scaninfo*, verbose, debugging, ((taskbegin, taskprogress*, taskend) | host)*, runstats) >
|
||||||
<!ATTLIST nmaprun
|
<!ATTLIST nmaprun
|
||||||
scanner (nmap) #REQUIRED
|
scanner (nmap) #REQUIRED
|
||||||
args CDATA #IMPLIED
|
args CDATA #IMPLIED
|
||||||
@@ -98,13 +99,37 @@
|
|||||||
<!ELEMENT debugging EMPTY >
|
<!ELEMENT debugging EMPTY >
|
||||||
<!ATTLIST debugging level %attr_numeric; #IMPLIED >
|
<!ATTLIST debugging level %attr_numeric; #IMPLIED >
|
||||||
|
|
||||||
|
<!-- this element is written in timing.c:beginOrEndTask() -->
|
||||||
|
<!ELEMENT taskbegin EMPTY >
|
||||||
|
<!ATTLIST taskbegin
|
||||||
|
task CDATA #REQUIRED
|
||||||
|
time %attr_numeric; #REQUIRED
|
||||||
|
>
|
||||||
|
|
||||||
|
<!-- this element is written in timing.c:printStats() -->
|
||||||
|
<!ELEMENT taskprogress EMPTY >
|
||||||
|
<!ATTLIST taskprogress
|
||||||
|
task CDATA #REQUIRED
|
||||||
|
time %attr_numeric; #REQUIRED
|
||||||
|
percent %attr_percent; #REQUIRED
|
||||||
|
remaining %attr_numeric; #REQUIRED
|
||||||
|
etc %attr_numeric; #REQUIRED
|
||||||
|
>
|
||||||
|
|
||||||
|
<!-- this element is written in timing.c:beginOrEndTask() -->
|
||||||
|
<!ELEMENT taskend EMPTY >
|
||||||
|
<!ATTLIST taskend
|
||||||
|
task CDATA #REQUIRED
|
||||||
|
time %attr_numeric; #REQUIRED
|
||||||
|
>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
this element is started in nmap.c:nmap_main() and filled by
|
this element is started in nmap.c:nmap_main() and filled by
|
||||||
output.c:write_host_status(), output.c:printportoutput(), and
|
output.c:write_host_status(), output.c:printportoutput(), and
|
||||||
output.c:printosscanoutput()
|
output.c:printosscanoutput()
|
||||||
-->
|
-->
|
||||||
<!ELEMENT host ( status, address , (address | hostnames |
|
<!ELEMENT host ( status, address , (address | hostnames |
|
||||||
smurf | ports | os | uptime |
|
smurf | ports | os | distance | uptime |
|
||||||
tcpsequence | ipidsequence | tcptssequence )* ) >
|
tcpsequence | ipidsequence | tcptssequence )* ) >
|
||||||
|
|
||||||
|
|
||||||
@@ -202,6 +227,11 @@
|
|||||||
fingerprint CDATA #REQUIRED
|
fingerprint CDATA #REQUIRED
|
||||||
>
|
>
|
||||||
|
|
||||||
|
<!ELEMENT distance EMPTY >
|
||||||
|
<!ATTLIST distance
|
||||||
|
value %attr_numeric; #REQUIRED
|
||||||
|
>
|
||||||
|
|
||||||
<!ELEMENT uptime EMPTY >
|
<!ELEMENT uptime EMPTY >
|
||||||
<!ATTLIST uptime
|
<!ATTLIST uptime
|
||||||
seconds %attr_numeric; #REQUIRED
|
seconds %attr_numeric; #REQUIRED
|
||||||
|
|||||||
14
idle_scan.cc
14
idle_scan.cc
@@ -965,6 +965,9 @@ void idle_scan(Target *target, u16 *portarray, int numports,
|
|||||||
int portidx = 0; /* Used for splitting the port array into chunks */
|
int portidx = 0; /* Used for splitting the port array into chunks */
|
||||||
int portsleft;
|
int portsleft;
|
||||||
time_t starttime;
|
time_t starttime;
|
||||||
|
char scanname[32];
|
||||||
|
snprintf(scanname, sizeof(scanname), "Idlescan against %s", target->NameIP());
|
||||||
|
ScanProgressMeter SPM(scanname);
|
||||||
|
|
||||||
if (numports == 0) return; /* nothing to scan for */
|
if (numports == 0) return; /* nothing to scan for */
|
||||||
if (!proxyName) fatal("Idlescan requires a proxy host");
|
if (!proxyName) fatal("Idlescan requires a proxy host");
|
||||||
@@ -988,9 +991,6 @@ void idle_scan(Target *target, u16 *portarray, int numports,
|
|||||||
initialize_idleproxy(&proxy, proxyName, target->v4hostip());
|
initialize_idleproxy(&proxy, proxyName, target->v4hostip());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (o.debugging || o.verbose) {
|
|
||||||
log_write(LOG_STDOUT, "Initiating Idlescan against %s\n", target->NameIP());
|
|
||||||
}
|
|
||||||
starttime = time(NULL);
|
starttime = time(NULL);
|
||||||
|
|
||||||
/* If we don't have timing infoz for the new target, we'll use values
|
/* If we don't have timing infoz for the new target, we'll use values
|
||||||
@@ -1019,11 +1019,9 @@ void idle_scan(Target *target, u16 *portarray, int numports,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (o.verbose) {
|
char additional_info[14];
|
||||||
long timediff = time(NULL) - starttime;
|
snprintf(additional_info, sizeof(additional_info), "%d ports", numports);
|
||||||
log_write(LOG_STDOUT, "The Idlescan took %ld %s to scan %d ports.\n",
|
SPM.endTask(NULL, additional_info);
|
||||||
timediff, (timediff == 1)? "second" : "seconds", numports);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now we go through the ports which were not determined were scanned
|
/* Now we go through the ports which were not determined were scanned
|
||||||
but not determined to be open, and add them in the "closed" state */
|
but not determined to be open, and add them in the "closed" state */
|
||||||
|
|||||||
45
nmap.cc
45
nmap.cc
@@ -109,6 +109,7 @@
|
|||||||
#include "NmapOps.h"
|
#include "NmapOps.h"
|
||||||
#include "MACLookup.h"
|
#include "MACLookup.h"
|
||||||
#include "nmap_tty.h"
|
#include "nmap_tty.h"
|
||||||
|
#include "nmap_dns.h"
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include "winfix.h"
|
#include "winfix.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -491,6 +492,8 @@ int nmap_main(int argc, char *argv[]) {
|
|||||||
{"debug", optional_argument, 0, 'd'},
|
{"debug", optional_argument, 0, 'd'},
|
||||||
{"help", no_argument, 0, 'h'},
|
{"help", no_argument, 0, 'h'},
|
||||||
{"iflist", no_argument, 0, 0},
|
{"iflist", no_argument, 0, 0},
|
||||||
|
{"release_memory", no_argument, 0, 0},
|
||||||
|
{"release-memory", no_argument, 0, 0},
|
||||||
{"max_parallelism", required_argument, 0, 'M'},
|
{"max_parallelism", required_argument, 0, 'M'},
|
||||||
{"max-parallelism", required_argument, 0, 'M'},
|
{"max-parallelism", required_argument, 0, 'M'},
|
||||||
{"min_parallelism", required_argument, 0, 0},
|
{"min_parallelism", required_argument, 0, 0},
|
||||||
@@ -640,6 +643,8 @@ int nmap_main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
} else if (strcmp(long_options[option_index].name, "iflist") == 0 ) {
|
} else if (strcmp(long_options[option_index].name, "iflist") == 0 ) {
|
||||||
iflist = true;
|
iflist = true;
|
||||||
|
} else if (strcmp(long_options[option_index].name, "release-memory") == 0 ) {
|
||||||
|
o.release_memory = true;
|
||||||
} else if (optcmp(long_options[option_index].name, "min-parallelism") == 0 ) {
|
} else if (optcmp(long_options[option_index].name, "min-parallelism") == 0 ) {
|
||||||
o.min_parallelism = atoi(optarg);
|
o.min_parallelism = atoi(optarg);
|
||||||
if (o.min_parallelism < 1) fatal("Argument to --min-parallelism must be at least 1!");
|
if (o.min_parallelism < 1) fatal("Argument to --min-parallelism must be at least 1!");
|
||||||
@@ -1626,23 +1631,35 @@ int nmap_main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
printfinaloutput();
|
printfinaloutput();
|
||||||
|
|
||||||
if (ports) {
|
free_scan_lists(ports);
|
||||||
free(ports->tcp_ports);
|
|
||||||
free(ports->udp_ports);
|
|
||||||
free(ports->prots);
|
|
||||||
free(ports);
|
|
||||||
}
|
|
||||||
|
|
||||||
eth_close_cached();
|
eth_close_cached();
|
||||||
|
|
||||||
/* Free fake argv */
|
if(o.release_memory || o.interactivemode) {
|
||||||
for(i=0; i < argc; i++)
|
/* Free fake argv */
|
||||||
free(fakeargv[i]);
|
for(i=0; i < argc; i++)
|
||||||
free(fakeargv);
|
free(fakeargv[i]);
|
||||||
|
free(fakeargv);
|
||||||
|
|
||||||
|
nmap_free_mem();
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Free some global memory allocations.
|
||||||
|
// This is used for detecting memory leaks.
|
||||||
|
void nmap_free_mem() {
|
||||||
|
PortList::freePortMap();
|
||||||
|
cp_free();
|
||||||
|
free_dns_servers();
|
||||||
|
free_etchosts();
|
||||||
|
if(o.reference_FPs){
|
||||||
|
free_fingerprint_file(o.reference_FPs);
|
||||||
|
o.reference_FPs = NULL;
|
||||||
|
}
|
||||||
|
AllProbes::service_scan_free();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Reads in a (normal or machine format) Nmap log file and gathers enough
|
/* Reads in a (normal or machine format) Nmap log file and gathers enough
|
||||||
state to allow Nmap to continue where it left off. The important things
|
state to allow Nmap to continue where it left off. The important things
|
||||||
@@ -1927,6 +1944,14 @@ struct scan_lists *getpts(char *origexpr) {
|
|||||||
return ports;
|
return ports;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free_scan_lists(struct scan_lists *ports) {
|
||||||
|
if (ports) {
|
||||||
|
free(ports->tcp_ports);
|
||||||
|
free(ports->udp_ports);
|
||||||
|
free(ports->prots);
|
||||||
|
free(ports);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void printinteractiveusage() {
|
void printinteractiveusage() {
|
||||||
printf(
|
printf(
|
||||||
|
|||||||
3
nmap.h
3
nmap.h
@@ -452,6 +452,7 @@ int ftp_anon_connect(struct ftpinfo *ftp);
|
|||||||
/* port manipulators */
|
/* port manipulators */
|
||||||
void getprobepts(char *expr);
|
void getprobepts(char *expr);
|
||||||
struct scan_lists *getpts(char *expr); /* someone stole the name getports()! */
|
struct scan_lists *getpts(char *expr); /* someone stole the name getports()! */
|
||||||
|
void free_scan_lists(struct scan_lists *ports);
|
||||||
int getidentinfoz(struct in_addr target, u16 localport, u16 remoteport,
|
int getidentinfoz(struct in_addr target, u16 localport, u16 remoteport,
|
||||||
char *owner, int ownersz);
|
char *owner, int ownersz);
|
||||||
|
|
||||||
@@ -467,6 +468,8 @@ int listen_icmp(int icmpsock, unsigned short outports[],
|
|||||||
/* Renamed main so that interactive mode could preprocess when neccessary */
|
/* Renamed main so that interactive mode could preprocess when neccessary */
|
||||||
int nmap_main(int argc, char *argv[]);
|
int nmap_main(int argc, char *argv[]);
|
||||||
|
|
||||||
|
void nmap_free_mem();
|
||||||
|
|
||||||
/* general helper functions */
|
/* general helper functions */
|
||||||
int parse_targets(struct targets *targets, char *h);
|
int parse_targets(struct targets *targets, char *h);
|
||||||
char *statenum2str(int state);
|
char *statenum2str(int state);
|
||||||
|
|||||||
36
nmap_dns.cc
36
nmap_dns.cc
@@ -816,6 +816,21 @@ static void add_dns_server(char *ipaddrs) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free_dns_servers() {
|
||||||
|
std::list<dns_server *>::iterator servI;
|
||||||
|
dns_server *tpserv;
|
||||||
|
|
||||||
|
for(servI = servs.begin(); servI != servs.end();servI++){
|
||||||
|
tpserv = *servI;
|
||||||
|
if(tpserv){
|
||||||
|
if(tpserv->hostname)
|
||||||
|
free(tpserv->hostname);
|
||||||
|
delete tpserv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
servs.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Creates a new nsi for each DNS server
|
// Creates a new nsi for each DNS server
|
||||||
void connect_dns_servers() {
|
void connect_dns_servers() {
|
||||||
@@ -969,6 +984,23 @@ static void parse_etchosts(char *fname) {
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free_etchosts() {
|
||||||
|
host_elem *he;
|
||||||
|
std::list<host_elem *>::iterator hi;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i=0; i < HASH_TABLE_SIZE; i++){
|
||||||
|
for(hi = etchosts[i].begin(); hi != etchosts[i].end(); hi++) {
|
||||||
|
he = *hi;
|
||||||
|
if(he) {
|
||||||
|
free(he->name);
|
||||||
|
delete he;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
etchosts[i].clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *lookup_etchosts(u32 ip) {
|
static char *lookup_etchosts(u32 ip) {
|
||||||
std::list<host_elem *>::iterator hostI;
|
std::list<host_elem *>::iterator hostI;
|
||||||
@@ -1058,6 +1090,7 @@ static void nmap_mass_rdns_core(Target **targets, int num_targets) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SPM->endTask(NULL, NULL);
|
||||||
delete SPM;
|
delete SPM;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -1137,6 +1170,8 @@ static void nmap_mass_rdns_core(Target **targets, int num_targets) {
|
|||||||
nsock_loop(dnspool, timeout);
|
nsock_loop(dnspool, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SPM->endTask(NULL, NULL);
|
||||||
|
|
||||||
delete SPM;
|
delete SPM;
|
||||||
|
|
||||||
close_dns_servers();
|
close_dns_servers();
|
||||||
@@ -1172,6 +1207,7 @@ static void nmap_mass_rdns_core(Target **targets, int num_targets) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SPM->endTask(NULL, NULL);
|
||||||
delete SPM;
|
delete SPM;
|
||||||
|
|
||||||
cname_reqs.clear();
|
cname_reqs.clear();
|
||||||
|
|||||||
@@ -98,3 +98,7 @@
|
|||||||
#include "Target.h"
|
#include "Target.h"
|
||||||
|
|
||||||
void nmap_mass_rdns(Target ** targets, int num_targets);
|
void nmap_mass_rdns(Target ** targets, int num_targets);
|
||||||
|
void free_dns_servers();
|
||||||
|
|
||||||
|
void free_etchosts();
|
||||||
|
|
||||||
|
|||||||
27
osscan.cc
27
osscan.cc
@@ -1925,6 +1925,33 @@ FingerPrint *parse_single_fingerprint(char *fprint_orig) {
|
|||||||
return FP;
|
return FP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void free_fingerprint_file(FingerPrint **FPs) {
|
||||||
|
FingerPrint **current;
|
||||||
|
FingerPrint *c, *d;
|
||||||
|
struct AVal *avc;
|
||||||
|
struct AVal *avd;
|
||||||
|
|
||||||
|
for(current = FPs; *current != NULL; current++){
|
||||||
|
for(c = *current; c; c=d){
|
||||||
|
d = c->next;
|
||||||
|
if(c->name)
|
||||||
|
free((void*)c->name); //strdup
|
||||||
|
if(c->results){
|
||||||
|
for(avc = c->results; avc; avc = avd) {
|
||||||
|
avd = avc->next;
|
||||||
|
if(avc->attribute)
|
||||||
|
free(avc->attribute);
|
||||||
|
}
|
||||||
|
free(c->results);
|
||||||
|
}
|
||||||
|
free(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(FPs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FingerPrint **parse_fingerprint_file(char *fname) {
|
FingerPrint **parse_fingerprint_file(char *fname) {
|
||||||
FingerPrint **FPs;
|
FingerPrint **FPs;
|
||||||
FingerPrint *current;
|
FingerPrint *current;
|
||||||
|
|||||||
2
osscan.h
2
osscan.h
@@ -131,6 +131,8 @@ FingerPrint *parse_single_fingerprint(char *fprint_orig);
|
|||||||
FingerPrint **parse_fingerprint_file(char *fname);
|
FingerPrint **parse_fingerprint_file(char *fname);
|
||||||
FingerPrint **parse_fingerprint_reference_file(char *dbname);
|
FingerPrint **parse_fingerprint_reference_file(char *dbname);
|
||||||
|
|
||||||
|
void free_fingerprint_file(FingerPrint **FPs);
|
||||||
|
|
||||||
/* Compares 2 fingerprints -- a referenceFP (can have expression
|
/* Compares 2 fingerprints -- a referenceFP (can have expression
|
||||||
attributes) with an observed fingerprint (no expressions). If
|
attributes) with an observed fingerprint (no expressions). If
|
||||||
verbose is nonzero, differences will be printed. The comparison
|
verbose is nonzero, differences will be printed. The comparison
|
||||||
|
|||||||
11
portlist.cc
11
portlist.cc
@@ -582,6 +582,17 @@ void PortList::setPortEntry(u16 portno, u8 protocol, Port *port) {
|
|||||||
port_list[proto][mapped_pno] = port;
|
port_list[proto][mapped_pno] = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Just free memory used by PortList::port_map[]. Should be done somewhere
|
||||||
|
* before closing nmap. */
|
||||||
|
void PortList::freePortMap(){
|
||||||
|
int proto;
|
||||||
|
for(proto=0; proto < PORTLIST_PROTO_MAX; proto++)
|
||||||
|
if(port_map[proto]){
|
||||||
|
free(port_map[proto]);
|
||||||
|
port_map[proto] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
u16 *PortList::port_map[PORTLIST_PROTO_MAX];
|
u16 *PortList::port_map[PORTLIST_PROTO_MAX];
|
||||||
int PortList::port_list_count[PORTLIST_PROTO_MAX];
|
int PortList::port_list_count[PORTLIST_PROTO_MAX];
|
||||||
|
|||||||
@@ -268,6 +268,9 @@ class PortList {
|
|||||||
/* Set ports that will be scanned for each protocol. This function
|
/* Set ports that will be scanned for each protocol. This function
|
||||||
* must be called before any PortList object will be created. */
|
* must be called before any PortList object will be created. */
|
||||||
static void initializePortMap(int protocol, u16 *ports, int portcount);
|
static void initializePortMap(int protocol, u16 *ports, int portcount);
|
||||||
|
/* Free memory used by port_map. It should be done somewhere before quitting*/
|
||||||
|
static void PortList::freePortMap();
|
||||||
|
|
||||||
/* Add a new port to this list. If the state has changed, it is
|
/* Add a new port to this list. If the state has changed, it is
|
||||||
OK to call this function to effect the change */
|
OK to call this function to effect the change */
|
||||||
int addPort(u16 portno, u8 protocol, char *owner, int state);
|
int addPort(u16 portno, u8 protocol, char *owner, int state);
|
||||||
|
|||||||
@@ -3358,7 +3358,6 @@ static void startTimeOutClocks(vector<Target *> &Targets) {
|
|||||||
void ultra_scan(vector<Target *> &Targets, struct scan_lists *ports,
|
void ultra_scan(vector<Target *> &Targets, struct scan_lists *ports,
|
||||||
stype scantype) {
|
stype scantype) {
|
||||||
UltraScanInfo *USI = NULL;
|
UltraScanInfo *USI = NULL;
|
||||||
time_t starttime;
|
|
||||||
o.current_scantype = scantype;
|
o.current_scantype = scantype;
|
||||||
|
|
||||||
if (Targets.size() == 0) {
|
if (Targets.size() == 0) {
|
||||||
@@ -3377,14 +3376,11 @@ void ultra_scan(vector<Target *> &Targets, struct scan_lists *ports,
|
|||||||
|
|
||||||
if (o.verbose) {
|
if (o.verbose) {
|
||||||
char targetstr[128];
|
char targetstr[128];
|
||||||
struct tm *tm;
|
|
||||||
bool plural = (Targets.size() != 1);
|
bool plural = (Targets.size() != 1);
|
||||||
if (!plural) {
|
if (!plural) {
|
||||||
(*(Targets.begin()))->NameIP(targetstr, sizeof(targetstr));
|
(*(Targets.begin()))->NameIP(targetstr, sizeof(targetstr));
|
||||||
} else snprintf(targetstr, sizeof(targetstr), "%d hosts", (int) Targets.size());
|
} else snprintf(targetstr, sizeof(targetstr), "%d hosts", (int) Targets.size());
|
||||||
starttime = USI->now.tv_sec;
|
log_write(LOG_STDOUT, "Scanning %s [%d port%s%s]\n", targetstr, USI->gstats->numprobes, (USI->gstats->numprobes != 1)? "s" : "", plural? "/host" : "");
|
||||||
tm = localtime(&starttime);
|
|
||||||
log_write(LOG_STDOUT, "Initiating %s against %s [%d port%s%s] at %02d:%02d\n", scantype2str(scantype), targetstr, USI->gstats->numprobes, (USI->gstats->numprobes != 1)? "s" : "", plural? "/host" : "", tm->tm_hour, tm->tm_min);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
begin_sniffer(USI, Targets);
|
begin_sniffer(USI, Targets);
|
||||||
@@ -3433,17 +3429,15 @@ void ultra_scan(vector<Target *> &Targets, struct scan_lists *ports,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (o.verbose) {
|
if (o.verbose) {
|
||||||
|
char additional_info[128];
|
||||||
if (USI->gstats->num_hosts_timedout == 0)
|
if (USI->gstats->num_hosts_timedout == 0)
|
||||||
log_write(LOG_STDOUT, "The %s took %.2fs to scan %lu total %s.\n",
|
snprintf(additional_info, sizeof(additional_info), "%lu total %s",
|
||||||
scantype2str(scantype),
|
|
||||||
TIMEVAL_MSEC_SUBTRACT(USI->now, USI->SPM->begin) / 1000.0,
|
|
||||||
(unsigned long) USI->gstats->numprobes * Targets.size(),
|
(unsigned long) USI->gstats->numprobes * Targets.size(),
|
||||||
(scantype == PING_SCAN_ARP)? "hosts" : "ports");
|
(scantype == PING_SCAN_ARP)? "hosts" : "ports");
|
||||||
else log_write(LOG_STDOUT, "Finished %s in %.2fs, but %d %s timed out.\n",
|
else snprintf(additional_info, sizeof(additional_info), "%d %s timed out",
|
||||||
scantype2str(scantype),
|
|
||||||
TIMEVAL_MSEC_SUBTRACT(USI->now, USI->SPM->begin) / 1000.0,
|
|
||||||
USI->gstats->num_hosts_timedout,
|
USI->gstats->num_hosts_timedout,
|
||||||
(USI->gstats->num_hosts_timedout == 1)? "host" : "hosts");
|
(USI->gstats->num_hosts_timedout == 1)? "host" : "hosts");
|
||||||
|
USI->SPM->endTask(NULL, additional_info);
|
||||||
}
|
}
|
||||||
delete USI;
|
delete USI;
|
||||||
USI = NULL;
|
USI = NULL;
|
||||||
@@ -3629,7 +3623,6 @@ void pos_scan(Target *target, u16 *portarray, int numports, stype scantype) {
|
|||||||
struct scanstats ss;
|
struct scanstats ss;
|
||||||
int senddelay = 0;
|
int senddelay = 0;
|
||||||
int rpcportsscanned = 0;
|
int rpcportsscanned = 0;
|
||||||
bool printedinitialmsg = false;
|
|
||||||
int tries = 0;
|
int tries = 0;
|
||||||
time_t starttime;
|
time_t starttime;
|
||||||
struct timeval starttm;
|
struct timeval starttm;
|
||||||
@@ -3643,6 +3636,8 @@ void pos_scan(Target *target, u16 *portarray, int numports, stype scantype) {
|
|||||||
struct serviceDeductions sd;
|
struct serviceDeductions sd;
|
||||||
bool doingOpenFiltered = false;
|
bool doingOpenFiltered = false;
|
||||||
|
|
||||||
|
ScanProgressMeter *SPM = NULL;
|
||||||
|
|
||||||
if (target->timedOut(NULL))
|
if (target->timedOut(NULL))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -3759,11 +3754,10 @@ void pos_scan(Target *target, u16 *portarray, int numports, stype scantype) {
|
|||||||
|
|
||||||
// This initial message is way down here because we don't want to print it if
|
// This initial message is way down here because we don't want to print it if
|
||||||
// no RPC ports need scanning.
|
// no RPC ports need scanning.
|
||||||
if (o.verbose && !printedinitialmsg) {
|
if (!SPM) {
|
||||||
struct tm *tm = localtime(&starttime);
|
char scanname[32];
|
||||||
assert(tm);
|
snprintf(scanname, sizeof(scanname), "%s against %s", scantype2str(scantype), target->NameIP());
|
||||||
log_write(LOG_STDOUT, "Initiating %s against %s at %02d:%02d\n", scantype2str(scantype), target->NameIP(hostname, sizeof(hostname)), tm->tm_hour, tm->tm_min);
|
SPM = new ScanProgressMeter(scanname);
|
||||||
printedinitialmsg = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while(pil.testinglist != NULL) /* While we have live queries or more ports to scan */
|
while(pil.testinglist != NULL) /* While we have live queries or more ports to scan */
|
||||||
@@ -3919,13 +3913,18 @@ void pos_scan(Target *target, u16 *portarray, int numports, stype scantype) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
numports = rpcportsscanned;
|
numports = rpcportsscanned;
|
||||||
if (o.verbose && numports > 0) {
|
if (SPM && o.verbose && (numports > 0)) {
|
||||||
gettimeofday(&now, NULL);
|
char scannedportsstr[14];
|
||||||
log_write(LOG_STDOUT, "The %s took %.2fs to scan %d ports on %s.\n", scantype2str(scantype), TIMEVAL_MSEC_SUBTRACT(now, starttm) / 1000.0, numports, target->NameIP());
|
snprintf(scannedportsstr, sizeof(scannedportsstr), "%d %s", numports, (numports > 1)? "ports" : "port");
|
||||||
|
SPM->endTask(NULL, scannedportsstr);
|
||||||
}
|
}
|
||||||
posscan_timedout:
|
posscan_timedout:
|
||||||
target->stopTimeOutClock(NULL);
|
target->stopTimeOutClock(NULL);
|
||||||
free(scan);
|
free(scan);
|
||||||
close_rpc_query_sockets();
|
close_rpc_query_sockets();
|
||||||
|
if (SPM) {
|
||||||
|
delete SPM;
|
||||||
|
SPM = NULL;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -305,6 +305,7 @@ void ServiceProbeMatch::InitMatch(const char *matchtext, int lineno) {
|
|||||||
const char *pcre_errptr = NULL;
|
const char *pcre_errptr = NULL;
|
||||||
int pcre_erroffset = 0;
|
int pcre_erroffset = 0;
|
||||||
unsigned int tmpbuflen = 0;
|
unsigned int tmpbuflen = 0;
|
||||||
|
char **curr_tmp = NULL;
|
||||||
|
|
||||||
if (isInitialized) fatal("Sorry ... ServiceProbeMatch::InitMatch does not yet support reinitializion");
|
if (isInitialized) fatal("Sorry ... ServiceProbeMatch::InitMatch does not yet support reinitializion");
|
||||||
if (!matchtext || !*matchtext)
|
if (!matchtext || !*matchtext)
|
||||||
@@ -414,13 +415,27 @@ void ServiceProbeMatch::InitMatch(const char *matchtext, int lineno) {
|
|||||||
tmptemplate[tmpbuflen] = '\0';
|
tmptemplate[tmpbuflen] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modechar == 'p') product_template = tmptemplate;
|
switch(modechar){
|
||||||
else if (modechar == 'v') version_template = tmptemplate;
|
case 'p': curr_tmp = &product_template; break;
|
||||||
else if (modechar == 'i') info_template = tmptemplate;
|
case 'v': curr_tmp = &version_template; break;
|
||||||
else if (modechar == 'h') hostname_template = tmptemplate;
|
case 'i': curr_tmp = &info_template; break;
|
||||||
else if (modechar == 'o') ostype_template = tmptemplate;
|
case 'h': curr_tmp = &hostname_template; break;
|
||||||
else if (modechar == 'd') devicetype_template = tmptemplate;
|
case 'o': curr_tmp = &ostype_template; break;
|
||||||
else fatal("ServiceProbeMatch::InitMatch: Unknown template specifier '%c' on line %d of nmap-service-probes", modechar, lineno);
|
case 'd': curr_tmp = &devicetype_template; break;
|
||||||
|
default:
|
||||||
|
fatal("ServiceProbeMatch::InitMatch: Unknown template specifier '%c' on line %d of nmap-service-probes", modechar, lineno);
|
||||||
|
}
|
||||||
|
if(*curr_tmp){
|
||||||
|
if(o.debugging)
|
||||||
|
error("WARNING: Template \"%c/%s/\" replaced with \"%c/%s/\" on line %d of nmap-service-probes",
|
||||||
|
modechar,
|
||||||
|
*curr_tmp,
|
||||||
|
modechar,
|
||||||
|
tmptemplate,
|
||||||
|
lineno);
|
||||||
|
free(*curr_tmp);
|
||||||
|
}
|
||||||
|
*curr_tmp = tmptemplate;
|
||||||
|
|
||||||
matchtext = p + 1;
|
matchtext = p + 1;
|
||||||
}
|
}
|
||||||
@@ -1133,17 +1148,26 @@ void parse_nmap_service_probes(AllProbes *AP) {
|
|||||||
parse_nmap_service_probe_file(AP, filename);
|
parse_nmap_service_probe_file(AP, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
static AllProbes *service_scan_init(void)
|
AllProbes *AllProbes::global_AP;
|
||||||
|
AllProbes *AllProbes::service_scan_init(void)
|
||||||
{
|
{
|
||||||
static AllProbes *AP;
|
if(global_AP)
|
||||||
|
return global_AP;
|
||||||
|
global_AP = new AllProbes();
|
||||||
|
parse_nmap_service_probes(global_AP);
|
||||||
|
|
||||||
if (AP) return AP;
|
return global_AP;
|
||||||
AP = new AllProbes();
|
|
||||||
parse_nmap_service_probes(AP);
|
|
||||||
|
|
||||||
return AP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AllProbes::service_scan_free(void)
|
||||||
|
{
|
||||||
|
if(global_AP){
|
||||||
|
delete global_AP;
|
||||||
|
global_AP = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// If the buf (of length buflen) matches one of the regexes in this
|
// If the buf (of length buflen) matches one of the regexes in this
|
||||||
// ServiceProbe, returns the details of the match (service name,
|
// ServiceProbe, returns the details of the match (service name,
|
||||||
// version number if applicable, and whether this is a "soft" match.
|
// version number if applicable, and whether this is a "soft" match.
|
||||||
@@ -1175,8 +1199,12 @@ AllProbes::~AllProbes() {
|
|||||||
vector<ServiceProbe *>::iterator vi;
|
vector<ServiceProbe *>::iterator vi;
|
||||||
|
|
||||||
// Delete all the ServiceProbe's inside the probes vector
|
// Delete all the ServiceProbe's inside the probes vector
|
||||||
for(vi = probes.begin(); vi != probes.end(); vi++)
|
for(vi = probes.begin(); vi != probes.end(); vi++) {
|
||||||
delete *vi;
|
delete *vi;
|
||||||
|
}
|
||||||
|
if(nullProbe)
|
||||||
|
delete nullProbe;
|
||||||
|
free_scan_lists(excludedports);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tries to find the probe in this AllProbes class which have the
|
// Tries to find the probe in this AllProbes class which have the
|
||||||
@@ -2338,7 +2366,7 @@ int service_scan(vector<Target *> &Targets) {
|
|||||||
if (Targets.size() == 0)
|
if (Targets.size() == 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
AP = service_scan_init();
|
AP = AllProbes::service_scan_init();
|
||||||
|
|
||||||
|
|
||||||
// Now I convert the targets into a new ServiceGroup
|
// Now I convert the targets into a new ServiceGroup
|
||||||
@@ -2361,16 +2389,15 @@ int service_scan(vector<Target *> &Targets) {
|
|||||||
starttime = time(NULL);
|
starttime = time(NULL);
|
||||||
if (o.verbose) {
|
if (o.verbose) {
|
||||||
char targetstr[128];
|
char targetstr[128];
|
||||||
struct tm *tm = localtime(&starttime);
|
|
||||||
bool plural = (Targets.size() != 1);
|
bool plural = (Targets.size() != 1);
|
||||||
if (!plural) {
|
if (!plural) {
|
||||||
(*(Targets.begin()))->NameIP(targetstr, sizeof(targetstr));
|
(*(Targets.begin()))->NameIP(targetstr, sizeof(targetstr));
|
||||||
} else snprintf(targetstr, sizeof(targetstr), "%u hosts", (unsigned) Targets.size());
|
} else snprintf(targetstr, sizeof(targetstr), "%u hosts", (unsigned) Targets.size());
|
||||||
|
|
||||||
log_write(LOG_STDOUT, "Initiating service scan against %u %s on %s at %02d:%02d\n",
|
log_write(LOG_STDOUT, "Scanning %u %s on %s\n",
|
||||||
(unsigned) SG->services_remaining.size(),
|
(unsigned) SG->services_remaining.size(),
|
||||||
(SG->services_remaining.size() == 1)? "service" : "services",
|
(SG->services_remaining.size() == 1)? "service" : "services",
|
||||||
targetstr, tm->tm_hour, tm->tm_min);
|
targetstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lets create a nsock pool for managing all the concurrent probes
|
// Lets create a nsock pool for managing all the concurrent probes
|
||||||
@@ -2399,18 +2426,16 @@ int service_scan(vector<Target *> &Targets) {
|
|||||||
nsp_delete(nsp);
|
nsp_delete(nsp);
|
||||||
|
|
||||||
if (o.verbose) {
|
if (o.verbose) {
|
||||||
gettimeofday(&now, NULL);
|
char additional_info[128];
|
||||||
if (SG->num_hosts_timedout == 0)
|
if (SG->num_hosts_timedout == 0)
|
||||||
log_write(LOG_STDOUT, "The service scan took %.2fs to scan %u %s on %u %s.\n",
|
snprintf(additional_info, sizeof(additional_info), "%u %s on %u %s",
|
||||||
TIMEVAL_MSEC_SUBTRACT(now, starttv) / 1000.0,
|
|
||||||
(unsigned) SG->services_finished.size(),
|
(unsigned) SG->services_finished.size(),
|
||||||
(SG->services_finished.size() == 1)? "service" : "services",
|
(SG->services_finished.size() == 1)? "service" : "services",
|
||||||
(unsigned) Targets.size(), (Targets.size() == 1)? "host" : "hosts");
|
(unsigned) Targets.size(), (Targets.size() == 1)? "host" : "hosts");
|
||||||
else log_write(LOG_STDOUT,
|
else snprintf(additional_info, sizeof(additional_info), "%u %s timed out",
|
||||||
"Finished service scan in %.2fs, but %d %s timed out.\n",
|
|
||||||
TIMEVAL_MSEC_SUBTRACT(now, starttv) / 1000.0,
|
|
||||||
SG->num_hosts_timedout,
|
SG->num_hosts_timedout,
|
||||||
(SG->num_hosts_timedout == 1)? "host" : "hosts");
|
(SG->num_hosts_timedout == 1)? "host" : "hosts");
|
||||||
|
SG->SPM->endTask(NULL, additional_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Yeah - done with the service scan. Now I go through the results
|
// Yeah - done with the service scan. Now I go through the results
|
||||||
|
|||||||
@@ -332,6 +332,11 @@ public:
|
|||||||
|
|
||||||
int isExcluded(unsigned short port, int proto);
|
int isExcluded(unsigned short port, int proto);
|
||||||
struct scan_lists *excludedports;
|
struct scan_lists *excludedports;
|
||||||
|
|
||||||
|
static AllProbes *service_scan_init(void);
|
||||||
|
static void service_scan_free(void);
|
||||||
|
protected:
|
||||||
|
static AllProbes *global_AP;
|
||||||
};
|
};
|
||||||
|
|
||||||
/********************** PROTOTYPES ***********************************/
|
/********************** PROTOTYPES ***********************************/
|
||||||
|
|||||||
@@ -794,7 +794,6 @@ static int get_ping_results(int sd, pcap_t *pd, Target *hostbatch[],
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int sendconnecttcpquery(Target *hostbatch[], struct tcpqueryinfo *tqi,
|
static int sendconnecttcpquery(Target *hostbatch[], struct tcpqueryinfo *tqi,
|
||||||
Target *target, int probe_port_num, u16 seq,
|
Target *target, int probe_port_num, u16 seq,
|
||||||
struct timeval *time, struct pingtune *pt,
|
struct timeval *time, struct pingtune *pt,
|
||||||
|
|||||||
1
tcpip.cc
1
tcpip.cc
@@ -2118,6 +2118,7 @@ void set_pcap_filter(const char *device,
|
|||||||
fatal("Error compiling our pcap filter: %s\n", pcap_geterr(pd));
|
fatal("Error compiling our pcap filter: %s\n", pcap_geterr(pd));
|
||||||
if (pcap_setfilter(pd, &fcode) < 0 )
|
if (pcap_setfilter(pd, &fcode) < 0 )
|
||||||
fatal("Failed to set the pcap filter: %s\n", pcap_geterr(pd));
|
fatal("Failed to set the pcap filter: %s\n", pcap_geterr(pd));
|
||||||
|
pcap_freecode(&fcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The 'dev' passed in must be at least 32 bytes long */
|
/* The 'dev' passed in must be at least 32 bytes long */
|
||||||
|
|||||||
49
timing.cc
49
timing.cc
@@ -243,6 +243,7 @@ ScanProgressMeter::ScanProgressMeter(char *stypestr) {
|
|||||||
last_print_test = begin;
|
last_print_test = begin;
|
||||||
memset(&last_print, 0, sizeof(last_print));
|
memset(&last_print, 0, sizeof(last_print));
|
||||||
memset(&last_est, 0, sizeof(last_print));
|
memset(&last_est, 0, sizeof(last_print));
|
||||||
|
beginOrEndTask(&begin, NULL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScanProgressMeter::~ScanProgressMeter() {
|
ScanProgressMeter::~ScanProgressMeter() {
|
||||||
@@ -382,19 +383,57 @@ bool ScanProgressMeter::printStats(double perc_done,
|
|||||||
// If we're less than 1% done we probably don't have enough
|
// If we're less than 1% done we probably don't have enough
|
||||||
// data for decent timing estimates. Also with perc_done == 0
|
// data for decent timing estimates. Also with perc_done == 0
|
||||||
// these elements will be nonsensical.
|
// these elements will be nonsensical.
|
||||||
if (perc_done < 0.01)
|
if (perc_done < 0.01) {
|
||||||
log_write(LOG_STDOUT, "%s Timing: About %.2f%% done\n",
|
log_write(LOG_STDOUT, "%s Timing: About %.2f%% done\n",
|
||||||
scantypestr, perc_done * 100);
|
scantypestr, perc_done * 100);
|
||||||
else
|
log_flush(LOG_STDOUT);
|
||||||
|
} else {
|
||||||
log_write(LOG_STDOUT, "%s Timing: About %.2f%% done; ETC: %02d:%02d (%li:%02li:%02li remaining)\n",
|
log_write(LOG_STDOUT, "%s Timing: About %.2f%% done; ETC: %02d:%02d (%li:%02li:%02li remaining)\n",
|
||||||
scantypestr, perc_done * 100, ltime->tm_hour, ltime->tm_min, sec_left / 3600,
|
scantypestr, perc_done * 100, ltime->tm_hour, ltime->tm_min, sec_left / 3600,
|
||||||
(sec_left % 3600) / 60, sec_left % 60);
|
(sec_left % 3600) / 60, sec_left % 60);
|
||||||
|
log_write(LOG_XML, "<taskprogress task=\"%s\" time=\"%lu\" percent=\"%.2f\" remaining=\"%li\" etc=\"%lu\" />\n",
|
||||||
log_flush(LOG_STDOUT);
|
scantypestr, (unsigned long) now->tv_sec,
|
||||||
|
perc_done * 100, sec_left, (unsigned long) last_est.tv_sec);
|
||||||
|
log_flush(LOG_STDOUT|LOG_XML);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Indicates that the task is beginning or ending, and that a message should
|
||||||
|
be generated if appropriate. Returns whether a message was printed.
|
||||||
|
now may be NULL, if the caller doesn't have the current time handy.
|
||||||
|
additional_info may be NULL if no additional information is necessary. */
|
||||||
|
bool ScanProgressMeter::beginOrEndTask(const struct timeval *now, const char *additional_info, bool beginning) {
|
||||||
|
struct timeval tvtmp;
|
||||||
|
struct tm *tm;
|
||||||
|
time_t tv_sec;
|
||||||
|
|
||||||
|
if (!o.verbose) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!now) {
|
||||||
|
gettimeofday(&tvtmp, NULL);
|
||||||
|
now = (const struct timeval *) &tvtmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
tv_sec = now->tv_sec;
|
||||||
|
tm = localtime(&tv_sec);
|
||||||
|
if (beginning) {
|
||||||
|
log_write(LOG_STDOUT, "Initiating %s at %02d:%02d", scantypestr, tm->tm_hour, tm->tm_min);
|
||||||
|
if (additional_info) {
|
||||||
|
log_write(LOG_STDOUT, " (%s)", additional_info);
|
||||||
|
}
|
||||||
|
log_write(LOG_STDOUT, "\n");
|
||||||
|
log_write(LOG_XML, "<taskbegin task=\"%s\" time=\"%lu\" />\n", scantypestr, (unsigned long) now->tv_sec);
|
||||||
|
} else {
|
||||||
|
log_write(LOG_STDOUT, "Completed %s at %02d:%02d, %.2fs elapsed", scantypestr, tm->tm_hour, tm->tm_min, TIMEVAL_MSEC_SUBTRACT(*now, begin) / 1000.0);
|
||||||
|
if (additional_info) {
|
||||||
|
log_write(LOG_STDOUT, " (%s)", additional_info);
|
||||||
|
}
|
||||||
|
log_write(LOG_STDOUT, "\n");
|
||||||
|
log_write(LOG_XML, "<taskend task=\"%s\" time=\"%lu\" />\n", scantypestr, (unsigned long) now->tv_sec);
|
||||||
|
}
|
||||||
|
log_flush(LOG_STDOUT|LOG_XML);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
5
timing.h
5
timing.h
@@ -154,12 +154,17 @@ class ScanProgressMeter {
|
|||||||
/* Prints an estimate of when this scan will complete. */
|
/* Prints an estimate of when this scan will complete. */
|
||||||
bool printStats(double perc_done, const struct timeval *now);
|
bool printStats(double perc_done, const struct timeval *now);
|
||||||
|
|
||||||
|
/* Prints that this task is complete. */
|
||||||
|
bool endTask(const struct timeval *now, const char *additional_info) { return beginOrEndTask(now, additional_info, false); }
|
||||||
|
|
||||||
struct timeval begin; /* When this ScanProgressMeter was instantiated */
|
struct timeval begin; /* When this ScanProgressMeter was instantiated */
|
||||||
private:
|
private:
|
||||||
struct timeval last_print_test; /* Last time printStatsIfNeccessary was called */
|
struct timeval last_print_test; /* Last time printStatsIfNeccessary was called */
|
||||||
struct timeval last_print; /* The most recent time the ETC was printed */
|
struct timeval last_print; /* The most recent time the ETC was printed */
|
||||||
char *scantypestr;
|
char *scantypestr;
|
||||||
struct timeval last_est; /* The latest PRINTED estimate */
|
struct timeval last_est; /* The latest PRINTED estimate */
|
||||||
|
|
||||||
|
bool beginOrEndTask(const struct timeval *now, const char *additional_info, bool beginning);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* NMAP_TIMING_H */
|
#endif /* NMAP_TIMING_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user