From 486ff13e3a9b24cb1ad60ce6e5e630ddf0b56137 Mon Sep 17 00:00:00 2001 From: david Date: Tue, 24 Feb 2009 00:23:54 +0000 Subject: [PATCH] Add the --stats-every option. See http://seclists.org/nmap-dev/2009/q1/0404.html. --- CHANGELOG | 5 +++++ NmapOps.cc | 1 + NmapOps.h | 2 ++ docs/refguide.xml | 17 +++++++++++++++++ nmap.cc | 6 ++++++ nmap_tty.cc | 28 ++++++++++++++++++++++++++++ 6 files changed, 59 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index dbb33d852..32fd692e4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,10 @@ # Nmap Changelog ($Id$); -*-text-*- +o The new --stats-every option takes a time interval that controls how + often timing status updates are printed. It's intended to be used + when Nmap is run by another program as a subprocess. Thanks to + Aleksandar Petrinic for the initial implementation. [David] + o [Ncat] The syntax accepted by the --allow, --deny, --allowfile, and --denyfile options is now the same as Nmap's target specifications. Additionally any errors in the allow or deny specifications are diff --git a/NmapOps.cc b/NmapOps.cc index 54c3e068e..7aca68d70 100644 --- a/NmapOps.cc +++ b/NmapOps.cc @@ -222,6 +222,7 @@ void NmapOps::Initialize() { verbose = 0; min_packet_send_rate = 0.0; /* Unset. */ max_packet_send_rate = 0.0; /* Unset. */ + stats_interval = 0.0; /* Unset. */ randomize_hosts = 0; sendpref = PACKET_SEND_NOPREF; spoofsource = 0; diff --git a/NmapOps.h b/NmapOps.h index 467ad415b..b6dd8b132 100644 --- a/NmapOps.h +++ b/NmapOps.h @@ -184,6 +184,8 @@ class NmapOps { float min_packet_send_rate; /* The requested maximum packet sending rate, or 0.0 if unset. */ float max_packet_send_rate; + /* The requested auto stats printing interval, or 0.0 if unset. */ + float stats_interval; int randomize_hosts; int spoofsource; /* -S used */ int fastscan; diff --git a/docs/refguide.xml b/docs/refguide.xml index dac87bd56..21e1bf5ef 100644 --- a/docs/refguide.xml +++ b/docs/refguide.xml @@ -3402,6 +3402,23 @@ even if this option is not specified. + + + (Print periodic timing stats) + + + + + Periodically prints a timing status message after each + interval of time. The time is a + specification of the kind described in + ; so for example, use + --stats-every 10s to get a status update + every 10 seconds. Updates are printed to interactive output + (the screen) and XML output. + + + diff --git a/nmap.cc b/nmap.cc index b86871606..f5ee686e9 100644 --- a/nmap.cc +++ b/nmap.cc @@ -674,6 +674,8 @@ int nmap_main(int argc, char *argv[]) { {"min-rate", required_argument, 0, 0}, {"max_rate", required_argument, 0, 0}, {"max-rate", required_argument, 0, 0}, + {"stats_every", required_argument, 0, 0}, + {"stats-every", required_argument, 0, 0}, {0, 0, 0, 0} }; @@ -937,6 +939,10 @@ int nmap_main(int argc, char *argv[]) { } else if(optcmp(long_options[option_index].name, "max-rate") == 0) { if (sscanf(optarg, "%f", &o.max_packet_send_rate) != 1 || o.max_packet_send_rate <= 0.0) fatal("Argument to --max-rate must be a positive floating-point number"); + } else if(optcmp(long_options[option_index].name, "stats-every") == 0) { + l = tval2msecs(optarg); + if (l < 0) fatal("Argument to --stats-every cannot be negative."); + o.stats_interval = (double) l / 1000.0; } else { fatal("Unknown long option (%s) given@#!$#$", long_options[option_index].name); } diff --git a/nmap_tty.cc b/nmap_tty.cc index 5d2f24d57..ed087fb25 100644 --- a/nmap_tty.cc +++ b/nmap_tty.cc @@ -116,6 +116,7 @@ #include #include "nmap_tty.h" +#include "utils.h" #include "NmapOps.h" extern NmapOps o; @@ -240,6 +241,8 @@ void tty_init() print a status message */ bool keyWasPressed() { + /* Where we keep the automatic stats printing schedule. */ + static struct timeval stats_time = { 0 }; int c; if (o.noninteractive) @@ -282,5 +285,30 @@ bool keyWasPressed() return true; } } + + /* Check if we need to print a status update according to the --stats-every + option. */ + if (o.stats_interval != 0.0) { + struct timeval now; + + gettimeofday(&now, NULL); + if (stats_time.tv_sec == 0) { + /* Initialize the scheduled stats time. */ + stats_time = *o.getStartTime(); + TIMEVAL_ADD(stats_time, stats_time, (time_t) (o.stats_interval * 1000000)); + } + + if (TIMEVAL_AFTER(now, stats_time)) { + /* Advance to the next print time. */ + TIMEVAL_ADD(stats_time, stats_time, (time_t) (o.stats_interval * 1000000)); + /* If it's still in the past, catch it up to the present. */ + if (TIMEVAL_AFTER(now, stats_time)) + stats_time = now; + printStatusMessage(); + /* Instruct the caller to print status too. */ + return true; + } + } + return false; }