diff --git a/CHANGELOG b/CHANGELOG
index 5935ec271..9afbb1d02 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -3,9 +3,16 @@
o [NSE] When receiving raw packets from Pcap, the packet capture time
is now available to scripts as an additional return value from
pcap_receive(). It is returned as the floating point number of
- seconds since the epoch. The qscan.nse script was updated to use
- this more accurate data instead of using the clock_ms() function
- (which returns the current time). [Kris]
+ seconds since the epoch. [Kris]
+
+o [NSE] Added the nmap.clock() function which returns the current time
+ as floating point seconds since the epoch. Convenience functions
+ clock_ms() and clock_us() were added to stdnse to return the current
+ time in milliseconds and microseconds, respectively. [Kris]
+
+o [NSE] The qscan.nse script was updated to use the more accurate
+ timing data from pcap_receive() and clock() to provide microsecond
+ resolution for round-trip times. [Kris]
o [Zenmap] Fixed a crash that would happen after opening the search
window, entering a relative date criterion such as "after:-7", and
diff --git a/nse_nmaplib.cc b/nse_nmaplib.cc
index ad0b64a48..d1895d2ec 100644
--- a/nse_nmaplib.cc
+++ b/nse_nmaplib.cc
@@ -177,6 +177,15 @@ static int l_clock_ms (lua_State *L)
return 1;
}
+static int l_clock (lua_State *L)
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ /* floating point seconds since Epoch */
+ lua_pushnumber(L, TIMEVAL_SECS(tv));
+ return 1;
+}
+
/* The actual mutex returned by the nmap.mutex function.
* This function has 4 upvalues:
* (1) Table (array) of waiting threads.
@@ -672,6 +681,7 @@ int luaopen_nmap (lua_State *L)
{"new_dnet", l_dnet_new},
{"get_interface_link", l_dnet_get_interface_link},
{"clock_ms", l_clock_ms},
+ {"clock", l_clock},
{"log_write", l_log_write},
{"new_try", l_new_try},
{"verbosity", l_get_verbosity},
diff --git a/nse_nsock.cc b/nse_nsock.cc
index a4a4b9470..aeed77648 100644
--- a/nse_nsock.cc
+++ b/nse_nsock.cc
@@ -1823,7 +1823,7 @@ int ncap_restore_lua(ncap_request * nr)
lua_pushnumber(L, nr->packetsz);
lua_pushlstring(L, (char *) nr->r_layer2, nr->r_layer2_len);
lua_pushlstring(L, (char *) nr->r_layer3, nr->r_layer3_len);
- lua_pushnumber(L, (double) nr->recvtime.tv_sec + (double) nr->recvtime.tv_usec / 1000000);
+ lua_pushnumber(L, TIMEVAL_SECS(nr->recvtime));
} else
{
lua_pushnil(L);
diff --git a/nselib/nmap.luadoc b/nselib/nmap.luadoc
index cdbca5cd6..55bbbd469 100644
--- a/nselib/nmap.luadoc
+++ b/nselib/nmap.luadoc
@@ -146,6 +146,12 @@ function set_port_state(host, port, state)
-- "tcpwrapped", or "incomplete".
function set_port_version(host, port, probestate)
+--- Returns the current date and time in seconds.
+-- @return The number of seconds since the epoch (on most systems this is
+-- 01/01/1970) as a floating point value.
+-- @usage local now = nmap.clock()
+function clock()
+
--- Returns the current date and time in milliseconds.
-- @return The number of milliseconds since the epoch (on most systems this is
-- 01/01/1970).
diff --git a/nselib/stdnse.lua b/nselib/stdnse.lua
index 9bc043ae4..68691d930 100644
--- a/nselib/stdnse.lua
+++ b/nselib/stdnse.lua
@@ -389,6 +389,18 @@ function format_difftime(t2, t1)
return sign .. s
end
+--- Returns the current time in milliseconds since the epoch
+-- @return The current time in milliseconds since the epoch
+function clock_ms()
+ return nmap.clock() * 1000
+end
+
+--- Returns the current time in microseconds since the epoch
+-- @return The current time in microseconds since the epoch
+function clock_us()
+ return nmap.clock() * 1000000
+end
+
---Get the indentation symbols at a given level.
local function format_get_indent(indent, at_end)
local str = ""
diff --git a/scripts/qscan.nse b/scripts/qscan.nse
index f12820aa9..8ee27e2ee 100644
--- a/scripts/qscan.nse
+++ b/scripts/qscan.nse
@@ -29,13 +29,14 @@ description = [[
--
-- @output
-- | qscan:
--- | PORT FAMILY MEAN (ms) STDDEV LOSS (%)
--- | 21 0 2.70 1.25 0.0%
--- | 22 0 2.50 0.53 0.0%
--- | 23 1 4.80 0.63 0.0%
--- | 25 0 2.40 0.52 0.0%
--- | 80 0 2.40 0.70 0.0%
--- |_443 0 2.40 0.52 0.0%
+-- | PORT FAMILY MEAN (us) STDDEV LOSS (%)
+-- | 21 0 2082.70 460.72 0.0%
+-- | 22 0 2211.70 886.69 0.0%
+-- | 23 1 4631.90 606.67 0.0%
+-- | 24 0 1922.40 336.90 0.0%
+-- | 25 0 2017.30 404.31 0.0%
+-- | 80 1 4180.80 856.98 0.0%
+-- |_443 0 2013.30 368.91 0.0%
--
-- 03/17/2010
@@ -46,6 +47,7 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"safe", "discovery"}
+require 'stdnse'
require 'bin'
require 'packet'
require 'tab'
@@ -229,7 +231,7 @@ local report = function(stats)
tab.add(outtab, 1, "PORT")
tab.add(outtab, 2, "FAMILY")
- tab.add(outtab, 3, "MEAN (ms)")
+ tab.add(outtab, 3, "MEAN (us)")
tab.add(outtab, 4, "STDDEV")
tab.add(outtab, 5, "LOSS (%)")
@@ -404,7 +406,7 @@ action = function(host)
pcap:pcap_register(bin.pack('AA=S=S', tcp.ip_bin_src, tcp.ip_bin_dst, tcp.tcp_sport, tcp.tcp_dport))
- start = nmap.clock_ms()
+ start = stdnse.clock_us()
try(sock:ip_send(tcp.buf))
@@ -414,10 +416,10 @@ action = function(host)
if not stop then
-- probably a timeout, just grab current time
- stop = nmap.clock_ms()
+ stop = stdnse.clock_us()
else
- -- we gotta use msecs
- stop = stop * 1000
+ -- we use usecs
+ stop = stop * 1000000
end
rtt = stop - start