1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 04:31:29 +00:00

Move date/time functions from stdnse to datetime. See #517

This commit is contained in:
dmiller
2018-08-27 22:00:10 +00:00
parent 9c3e676871
commit 46eca7f35f
35 changed files with 282 additions and 255 deletions

View File

@@ -2402,13 +2402,13 @@ PORT STATE SERVICE
<screen> <screen>
2012-09-07T23:37:42 2012-09-07T23:37:42
</screen> </screen>
The standard library function The library function
<code>stdnse.format_timestamp</code> code exists to format times <code>datetime.format_timestamp</code> code exists to format times
for structured output. It takes an optional time zone offset in for structured output. It takes an optional time zone offset in
seconds and automatically shifts the date to be correct within seconds and automatically shifts the date to be correct within
that offset. that offset.
<screen> <screen>
stdnse.format_timestamp(os.time(), 0) --> "2012-09-07T23:37:42+00:00" datetime.format_timestamp(os.time(), 0) --> "2012-09-07T23:37:42+00:00"
</screen> </screen>
</para> </para>
</sect3> </sect3>

View File

@@ -113,6 +113,7 @@
local bin = require "bin" local bin = require "bin"
local bit = require "bit" local bit = require "bit"
local datetime = require "datetime"
local ipOps = require "ipOps" local ipOps = require "ipOps"
local nmap = require "nmap" local nmap = require "nmap"
local os = require "os" local os = require "os"
@@ -1778,9 +1779,9 @@ Helper = {
local item = ( response.result.file ) and response.result.file or response.result.dir local item = ( response.result.file ) and response.result.file or response.result.dir
local diff = os.time{year=2000, month=1, day=1, hour=0} - os.time{year=1970, month=1, day=1, hour=0} local diff = os.time{year=2000, month=1, day=1, hour=0} - os.time{year=1970, month=1, day=1, hour=0}
local create = stdnse.format_timestamp(item.CreationDate + diff) local create = datetime.format_timestamp(item.CreationDate + diff)
local backup = stdnse.format_timestamp(item.BackupDate ) local backup = datetime.format_timestamp(item.BackupDate )
local modify = stdnse.format_timestamp(item.ModificationDate + diff ) local modify = datetime.format_timestamp(item.ModificationDate + diff )
return true, { create = create, backup = backup, modify = modify } return true, { create = create, backup = backup, modify = modify }
end, end,

View File

@@ -8,8 +8,19 @@
local stdnse = require "stdnse" local stdnse = require "stdnse"
local os = require "os" local os = require "os"
local math = require "math" local math = require "math"
local string = require "string"
_ENV = stdnse.module("datetime", stdnse.seeall) _ENV = stdnse.module("datetime", stdnse.seeall)
local difftime = os.difftime
local time = os.time
local date = os.date
local floor = math.floor
local fmod = math.fmod
local format = string.format
local match = string.match
--- Record a time difference between the scanner and the target --- Record a time difference between the scanner and the target
-- --
-- The skew will be recorded in the host's registry for later retrieval and -- The skew will be recorded in the host's registry for later retrieval and
@@ -24,10 +35,199 @@ function record_skew(host, timestamp, received)
skew_tab = skew_tab or {} skew_tab = skew_tab or {}
-- No srtt? I suppose we'll ignore it, but this could cause problems -- No srtt? I suppose we'll ignore it, but this could cause problems
local srtt = host.times and host.times.srtt or 0 local srtt = host.times and host.times.srtt or 0
local adjusted = os.difftime(math.floor(timestamp), math.floor(received)) - srtt / 2.0 local adjusted = difftime(floor(timestamp), floor(received)) - srtt / 2.0
skew_tab[#skew_tab + 1] = adjusted skew_tab[#skew_tab + 1] = adjusted
stdnse.debug2("record_skew: %s", adjusted) stdnse.debug2("record_skew: %s", adjusted)
host.registry.datetime_skew = skew_tab host.registry.datetime_skew = skew_tab
end end
-- Find the offset in seconds between local time and UTC. That is, if we
-- interpret a UTC date table as a local date table by passing it to os.time,
-- how much must be added to the resulting integer timestamp to make it
-- correct?
local function utc_offset(t)
-- What does the calendar say locally?
local localtime = date("*t", t)
-- What does the calendar say in UTC?
local gmtime = date("!*t", t)
-- Interpret both as local calendar dates and find the difference.
return difftime(time(localtime), time(gmtime))
end
--- Convert a date table into an integer timestamp.
--
-- Unlike os.time, this does not assume that the date table represents a local
-- time. Rather, it takes an optional offset number of seconds representing the
-- time zone, and returns the timestamp that would result using that time zone
-- as local time. If the offset is omitted or 0, the date table is interpreted
-- as a UTC date. For example, 4:00 UTC is the same as 5:00 UTC+1:
-- <code>
-- date_to_timestamp({year=1970,month=1,day=1,hour=4,min=0,sec=0}) --> 14400
-- date_to_timestamp({year=1970,month=1,day=1,hour=4,min=0,sec=0}, 0) --> 14400
-- date_to_timestamp({year=1970,month=1,day=1,hour=5,min=0,sec=0}, 1*60*60) --> 14400
-- </code>
-- And 4:00 UTC+1 is an earlier time:
-- <code>
-- date_to_timestamp({year=1970,month=1,day=1,hour=4,min=0,sec=0}, 1*60*60) --> 10800
-- </code>
function date_to_timestamp(date, offset)
offset = offset or 0
return time(date) + utc_offset(time(date)) - offset
end
local function format_tz(offset)
local sign, hh, mm
if not offset then
return ""
end
if offset < 0 then
sign = "-"
offset = -offset
else
sign = "+"
end
-- Truncate to minutes.
offset = floor(offset / 60)
hh = floor(offset / 60)
mm = floor(fmod(offset, 60))
return format("%s%02d:%02d", sign, hh, mm)
end
--- Format a date and time (and optional time zone) for structured output.
--
-- Formatting is done according to RFC 3339 (a profile of ISO 8601), except
-- that a time zone may be omitted to signify an unspecified local time zone.
-- Time zones are given as an integer number of seconds from UTC. Use
-- <code>0</code> to mark UTC itself. Formatted strings with a time zone look
-- like this:
-- <code>
-- format_timestamp(os.time(), 0) --> "2012-09-07T23:37:42+00:00"
-- format_timestamp(os.time(), 2*60*60) --> "2012-09-07T23:37:42+02:00"
-- </code>
-- Without a time zone they look like this:
-- <code>
-- format_timestamp(os.time()) --> "2012-09-07T23:37:42"
-- </code>
--
-- This function should be used for all dates emitted as part of NSE structured
-- output.
function format_timestamp(t, offset)
if type(t) == "table" then
return format(
"%d-%02d-%02dT%02d:%02d:%02d",
t.year, t.month, t.day, t.hour, t.min, t.sec
)
else
local tz_string = format_tz(offset)
offset = offset or 0
local status, result = pcall(date, "!%Y-%m-%dT%H:%M:%S", floor(t + offset))
if not status then
local tmp = floor(t + offset)
if tmp > 0xffffffff then
-- Maybe too far in the future?
local seconds_in_year = 31556926
local extra_years = (tmp - 0xffffffff) // seconds_in_year + 1
tmp = tmp - extra_years * seconds_in_year
status, result = pcall(date, "!*t", tmp)
if status then
-- seconds_in_year is imprecise, so we truncate to date only
result = format("%d-%02d-%02d", result.year + extra_years, result.month, result.day)
end
end
end
if not status then
return ("Invalid timestamp: %s"):format(t)
end
return result .. tz_string
end
end
--- Format a time interval into a string
--
-- String is in the same format as format_difftime
-- @param interval A time interval
-- @param unit The time unit division as a number. If <code>interval</code> is
-- in milliseconds, this is 1000 for instance. Default: 1 (seconds)
-- @return The time interval in string format
function format_time(interval, unit)
local sign = ""
if interval < 0 then
sign = "-"
interval = math.abs(interval)
end
unit = unit or 1
local precision = floor(math.log(unit, 10))
local sec = (interval % (60 * unit)) / unit
interval = interval // (60 * unit)
local min = interval % 60
interval = interval // 60
local hr = interval % 24
interval = interval // 24
local s = format("%.0fd%02.0fh%02.0fm%02.".. precision .."fs",
interval, hr, min, sec)
-- trim off leading 0 and "empty" units
return sign .. (match(s, "([1-9].*)") or format("%0.".. precision .."fs", 0))
end
--- Format the difference between times <code>t2</code> and <code>t1</code>
-- into a string
--
-- String is in one of the forms (signs may vary):
-- * 0s
-- * -4s
-- * +2m38s
-- * -9h12m34s
-- * +5d17h05m06s
-- * -2y177d10h13m20s
-- The string shows <code>t2</code> relative to <code>t1</code>; i.e., the
-- calculation is <code>t2</code> minus <code>t1</code>.
function format_difftime(t2, t1)
local d, s, sign, yeardiff
d = difftime(time(t2), time(t1))
if d > 0 then
sign = "+"
elseif d < 0 then
sign = "-"
t2, t1 = t1, t2
d = -d
else
sign = ""
end
-- t2 is always later than or equal to t1 here.
-- The year is a tricky case because it's not a fixed number of days
-- the way a day is a fixed number of hours or an hour is a fixed
-- number of minutes. For example, the difference between 2008-02-10
-- and 2009-02-10 is 366 days because 2008 was a leap year, but it
-- should be printed as 1y0d0h0m0s, not 1y1d0h0m0s. We advance t1 to be
-- the latest year such that it is still before t2, which means that its
-- year will be equal to or one less than t2's. The number of years
-- skipped is stored in yeardiff.
if t2.year > t1.year then
local tmpyear = t1.year
-- Put t1 in the same year as t2.
t1.year = t2.year
d = difftime(time(t2), time(t1))
if d < 0 then
-- Too far. Back off one year.
t1.year = t2.year - 1
d = difftime(time(t2), time(t1))
end
yeardiff = t1.year - tmpyear
t1.year = tmpyear
else
yeardiff = 0
end
local s = format_time(d)
if yeardiff == 0 then return sign .. s end
-- Years.
s = format("%dy", yeardiff) .. s
return sign .. s
end
return _ENV return _ENV

View File

@@ -15,6 +15,7 @@
-- o Added WPAD action -- o Added WPAD action
local bin = require "bin" local bin = require "bin"
local datetime = require "datetime"
local ipOps = require "ipOps" local ipOps = require "ipOps"
local math = require "math" local math = require "math"
local nmap = require "nmap" local nmap = require "nmap"
@@ -226,7 +227,7 @@ local function read_time(data, pos, length)
end end
pos, result = bin.unpack(">I", data, pos) pos, result = bin.unpack(">I", data, pos)
return pos, stdnse.format_time(result) return pos, datetime.format_time(result)
end end
---Read a list of static routes. Each of them are a pair of IP addresses, a destination and a ---Read a list of static routes. Each of them are a pair of IP addresses, a destination and a

View File

@@ -23,6 +23,7 @@
local bin = require "bin" local bin = require "bin"
local bit = require "bit" local bit = require "bit"
local datetime = require "datetime"
local ipOps = require "ipOps" local ipOps = require "ipOps"
local math = require "math" local math = require "math"
local nmap = require "nmap" local nmap = require "nmap"
@@ -523,7 +524,7 @@ OptionToString = {
if ( HWTYPE_ETHER == opt.hwtype ) then if ( HWTYPE_ETHER == opt.hwtype ) then
local mac = stdnse.tohex(opt.mac):upper() local mac = stdnse.tohex(opt.mac):upper()
mac = mac:gsub("..", "%1:"):sub(1, -2) mac = mac:gsub("..", "%1:"):sub(1, -2)
local tm = stdnse.format_timestamp(opt.time) local tm = datetime.format_timestamp(opt.time)
return "Client identifier", ("MAC: %s; Time: %s"):format(mac, tm) return "Client identifier", ("MAC: %s; Time: %s"):format(mac, tm)
end end
end, end,

View File

@@ -1,7 +1,7 @@
local bin = require "bin" local bin = require "bin"
local datetime = require "datetime"
local http = require "http" local http = require "http"
local nmap = require "nmap" local nmap = require "nmap"
local os = require "os"
local stdnse = require "stdnse" local stdnse = require "stdnse"
local tab = require "tab" local tab = require "tab"
local table = require "table" local table = require "table"
@@ -410,7 +410,7 @@ Helper = {
results[printer] = results[printer] or {} results[printer] = results[printer] or {}
table.insert(results[printer], { table.insert(results[printer], {
id = id, id = id,
time = stdnse.format_timestamp(tm), time = datetime.format_timestamp(tm),
state = ( IPP.StateName[tonumber(state)] or "Unknown" ), state = ( IPP.StateName[tonumber(state)] or "Unknown" ),
size = size, size = size,
owner = owner, owner = owner,

View File

@@ -19,6 +19,7 @@
-- --
local asn1 = require "asn1" local asn1 = require "asn1"
local datetime = require "datetime"
local io = require "io" local io = require "io"
local nmap = require "nmap" local nmap = require "nmap"
local os = require "os" local os = require "os"
@@ -834,7 +835,7 @@ function convertADTimeStamp(timestamp)
result = ( timestamp // 10000000 ) - 3036 result = ( timestamp // 10000000 ) - 3036
result = result + base_time result = result + base_time
result = stdnse.format_timestamp(result, 0) result = datetime.format_timestamp(result, 0)
else else
result = 'Never' result = 'Never'
end end

View File

@@ -52,6 +52,7 @@
local bin = require "bin" local bin = require "bin"
local bit = require "bit" local bit = require "bit"
local datetime = require "datetime"
local ipOps = require "ipOps" local ipOps = require "ipOps"
local math = require "math" local math = require "math"
local msrpctypes = require "msrpctypes" local msrpctypes = require "msrpctypes"
@@ -1228,7 +1229,6 @@ function epmapper_lookup(smbstate,handle)
netbios = nil, netbios = nil,
ncacn_http = nil ncacn_http = nil
} }
--stdnse.set_tostring(lookup_response,stdnse.format_generator({key_order = {"new_handle,annotation,uuid,exe,tcp_port,udp_port,ip_addr,ncalrpc,ncacn_np,netbios,ncacn_http"}}))
lookup_response.new_handle = string.sub(data,25,44) lookup_response.new_handle = string.sub(data,25,44)
@@ -2629,7 +2629,7 @@ function winreg_enumkey(smbstate, handle, index, name)
-- [in,out,unique] NTTIME *last_changed_time -- [in,out,unique] NTTIME *last_changed_time
pos, result['changed_time'] = msrpctypes.unmarshall_NTTIME_ptr(arguments, pos) pos, result['changed_time'] = msrpctypes.unmarshall_NTTIME_ptr(arguments, pos)
result['changed_date'] = stdnse.format_timestamp(result['changed_time']) result['changed_date'] = datetime.format_timestamp(result['changed_time'])
pos, result['return'] = msrpctypes.unmarshall_int32(arguments, pos) pos, result['return'] = msrpctypes.unmarshall_int32(arguments, pos)
if(result['return'] == nil) then if(result['return'] == nil) then
@@ -2771,7 +2771,7 @@ function winreg_queryinfokey(smbstate, handle)
-- [out,ref] NTTIME *last_changed_time -- [out,ref] NTTIME *last_changed_time
pos, result['last_changed_time'] = msrpctypes.unmarshall_NTTIME(arguments, pos) pos, result['last_changed_time'] = msrpctypes.unmarshall_NTTIME(arguments, pos)
result['last_changed_date'] = stdnse.format_timestamp(result['last_changed_time']) result['last_changed_date'] = datetime.format_timestamp(result['last_changed_time'])
pos, result['return'] = msrpctypes.unmarshall_int32(arguments, pos) pos, result['return'] = msrpctypes.unmarshall_int32(arguments, pos)
if(result['return'] == nil) then if(result['return'] == nil) then
@@ -4421,7 +4421,7 @@ local function get_domain_info(host, domain)
response['groups'] = groups response['groups'] = groups
response['users'] = names response['users'] = names
if(querydomaininfo2_result_8['info']['domain_create_time'] ~= 0) then if(querydomaininfo2_result_8['info']['domain_create_time'] ~= 0) then
response['created'] = stdnse.format_timestamp(querydomaininfo2_result_8['info']['domain_create_time']) response['created'] = datetime.format_timestamp(querydomaininfo2_result_8['info']['domain_create_time'])
else else
response['created'] = "unknown" response['created'] = "unknown"
end end
@@ -4889,11 +4889,11 @@ function get_server_stats(host)
local stats = netservergetstatistics_result['stat'] local stats = netservergetstatistics_result['stat']
-- Convert the date to a string -- Convert the date to a string
stats['start_str'] = stdnse.format_timestamp(stats['start']) stats['start_str'] = datetime.format_timestamp(stats['start'])
-- Get the period and convert it to a proper time offset -- Get the period and convert it to a proper time offset
stats['period'] = os.time() - stats['start'] stats['period'] = os.time() - stats['start']
stats.period_str = stdnse.format_time(stats.period) stats.period_str = datetime.format_time(stats.period)
-- Combine the 64-bit values -- Combine the 64-bit values
stats['bytessent'] = bit.bor(bit.lshift(stats['bytessent_high'], 32), stats['bytessent_low']) stats['bytessent'] = bit.bor(bit.lshift(stats['bytessent_high'], 32), stats['bytessent_low'])

View File

@@ -7,6 +7,7 @@
-- @author Patrik Karlsson <patrik@cqure.net> -- @author Patrik Karlsson <patrik@cqure.net>
-- --
local bin = require "bin" local bin = require "bin"
local datetime = require "datetime"
local ipOps = require "ipOps" local ipOps = require "ipOps"
local nmap = require "nmap" local nmap = require "nmap"
local stdnse = require "stdnse" local stdnse = require "stdnse"
@@ -103,7 +104,7 @@ Response = {
pos, self.time, self.ip = bin.unpack(">II", self.data, pos) pos, self.time, self.ip = bin.unpack(">II", self.data, pos)
self.ip = ipOps.fromdword(self.ip) self.ip = ipOps.fromdword(self.ip)
self.time = stdnse.format_timestamp(self.time) self.time = datetime.format_timestamp(self.time)
return true return true
end, end,

View File

@@ -77,6 +77,7 @@
local bin = require "bin" local bin = require "bin"
local datafiles = require "datafiles" local datafiles = require "datafiles"
local datetime = require "datetime"
local math = require "math" local math = require "math"
local nmap = require "nmap" local nmap = require "nmap"
local stdnse = require "stdnse" local stdnse = require "stdnse"
@@ -3204,7 +3205,7 @@ Util =
-- @param number of seconds since some given start time -- @param number of seconds since some given start time
-- (the "epoch") -- (the "epoch")
-- @return string that represents time. -- @return string that represents time.
TimeToString = stdnse.format_timestamp, TimeToString = datetime.format_timestamp,
--- Converts the size in bytes to a human readable format --- Converts the size in bytes to a human readable format
-- --

View File

@@ -125,6 +125,7 @@ local asn1 = require "asn1"
local bin = require "bin" local bin = require "bin"
local bit = require "bit" local bit = require "bit"
local coroutine = require "coroutine" local coroutine = require "coroutine"
local datetime = require "datetime"
local io = require "io" local io = require "io"
local math = require "math" local math = require "math"
local match = require "match" local match = require "match"
@@ -1049,7 +1050,7 @@ function negotiate_v1(smb, overrides)
-- Convert the time and timezone to more useful values -- Convert the time and timezone to more useful values
smb['time'] = (smb['time'] // 10000000) - 11644473600 smb['time'] = (smb['time'] // 10000000) - 11644473600
smb['date'] = stdnse.format_timestamp(smb['time']) smb['date'] = datetime.format_timestamp(smb['time'])
smb['timezone'] = -(smb['timezone'] / 60) smb['timezone'] = -(smb['timezone'] / 60)
if(smb['timezone'] == 0) then if(smb['timezone'] == 0) then
smb['timezone_str'] = "UTC+0" smb['timezone_str'] = "UTC+0"
@@ -2861,7 +2862,7 @@ function find_files(smbstate, fname, options)
local time = fe.created local time = fe.created
time = (time // 10000000) - 11644473600 time = (time // 10000000) - 11644473600
fe.created = stdnse.format_timestamp(time) fe.created = datetime.format_timestamp(time)
-- TODO: cleanup fe.s_fname -- TODO: cleanup fe.s_fname
pos, fe.fname = bin.unpack("A" .. f_len, response.data, pos) pos, fe.fname = bin.unpack("A" .. f_len, response.data, pos)

View File

@@ -11,6 +11,7 @@
-- @copyright Same as Nmap--See https://nmap.org/book/man-legal.html -- @copyright Same as Nmap--See https://nmap.org/book/man-legal.html
--- ---
local datetime = require "datetime"
local string = require "string" local string = require "string"
local stdnse = require "stdnse" local stdnse = require "stdnse"
local nmap = require "nmap" local nmap = require "nmap"
@@ -388,12 +389,12 @@ function negotiate_v2(smb, overrides)
-- Convert the time and timezone to human readable values (taken from smb.lua) -- Convert the time and timezone to human readable values (taken from smb.lua)
smb['time'] = (smb['time'] // 10000000) - 11644473600 smb['time'] = (smb['time'] // 10000000) - 11644473600
smb['date'] = stdnse.format_timestamp(smb['time']) smb['date'] = datetime.format_timestamp(smb['time'])
-- Samba does not report the boot time -- Samba does not report the boot time
if smb['start_time'] ~= 0 then if smb['start_time'] ~= 0 then
smb['start_time'] = (smb['start_time'] // 10000000) - 11644473600 smb['start_time'] = (smb['start_time'] // 10000000) - 11644473600
smb['start_date'] = stdnse.format_timestamp(smb['start_time']) smb['start_date'] = datetime.format_timestamp(smb['start_time'])
else else
smb['start_date'] = "N/A" smb['start_date'] = "N/A"
end end

View File

@@ -10,7 +10,6 @@ local _G = require "_G"
local coroutine = require "coroutine" local coroutine = require "coroutine"
local math = require "math" local math = require "math"
local nmap = require "nmap" local nmap = require "nmap"
local os = require "os"
local string = require "string" local string = require "string"
local table = require "table" local table = require "table"
local assert = assert; local assert = assert;
@@ -30,8 +29,6 @@ local type = type
local pcall = pcall local pcall = pcall
local ceil = math.ceil local ceil = math.ceil
local floor = math.floor
local fmod = math.fmod
local max = math.max local max = math.max
local random = math.random local random = math.random
@@ -50,10 +47,6 @@ local remove = table.remove;
local pack = table.pack; local pack = table.pack;
local unpack = table.unpack; local unpack = table.unpack;
local difftime = os.difftime;
local time = os.time;
local date = os.date;
local EMPTY = {}; -- Empty constant table local EMPTY = {}; -- Empty constant table
_ENV = require "strict" {}; _ENV = require "strict" {};
@@ -500,194 +493,6 @@ function parse_timespec(timespec)
return t * m return t * m
end end
-- Find the offset in seconds between local time and UTC. That is, if we
-- interpret a UTC date table as a local date table by passing it to os.time,
-- how much must be added to the resulting integer timestamp to make it
-- correct?
local function utc_offset(t)
-- What does the calendar say locally?
local localtime = date("*t", t)
-- What does the calendar say in UTC?
local gmtime = date("!*t", t)
-- Interpret both as local calendar dates and find the difference.
return difftime(time(localtime), time(gmtime))
end
--- Convert a date table into an integer timestamp.
--
-- Unlike os.time, this does not assume that the date table represents a local
-- time. Rather, it takes an optional offset number of seconds representing the
-- time zone, and returns the timestamp that would result using that time zone
-- as local time. If the offset is omitted or 0, the date table is interpreted
-- as a UTC date. For example, 4:00 UTC is the same as 5:00 UTC+1:
-- <code>
-- date_to_timestamp({year=1970,month=1,day=1,hour=4,min=0,sec=0}) --> 14400
-- date_to_timestamp({year=1970,month=1,day=1,hour=4,min=0,sec=0}, 0) --> 14400
-- date_to_timestamp({year=1970,month=1,day=1,hour=5,min=0,sec=0}, 1*60*60) --> 14400
-- </code>
-- And 4:00 UTC+1 is an earlier time:
-- <code>
-- date_to_timestamp({year=1970,month=1,day=1,hour=4,min=0,sec=0}, 1*60*60) --> 10800
-- </code>
function date_to_timestamp(date, offset)
offset = offset or 0
return time(date) + utc_offset(time(date)) - offset
end
local function format_tz(offset)
local sign, hh, mm
if not offset then
return ""
end
if offset < 0 then
sign = "-"
offset = -offset
else
sign = "+"
end
-- Truncate to minutes.
offset = floor(offset / 60)
hh = floor(offset / 60)
mm = floor(fmod(offset, 60))
return format("%s%02d:%02d", sign, hh, mm)
end
--- Format a date and time (and optional time zone) for structured output.
--
-- Formatting is done according to RFC 3339 (a profile of ISO 8601), except
-- that a time zone may be omitted to signify an unspecified local time zone.
-- Time zones are given as an integer number of seconds from UTC. Use
-- <code>0</code> to mark UTC itself. Formatted strings with a time zone look
-- like this:
-- <code>
-- format_timestamp(os.time(), 0) --> "2012-09-07T23:37:42+00:00"
-- format_timestamp(os.time(), 2*60*60) --> "2012-09-07T23:37:42+02:00"
-- </code>
-- Without a time zone they look like this:
-- <code>
-- format_timestamp(os.time()) --> "2012-09-07T23:37:42"
-- </code>
--
-- This function should be used for all dates emitted as part of NSE structured
-- output.
function format_timestamp(t, offset)
if type(t) == "table" then
return format(
"%d-%02d-%02dT%02d:%02d:%02d",
t.year, t.month, t.day, t.hour, t.min, t.sec
)
else
local tz_string = format_tz(offset)
offset = offset or 0
local status, result = pcall(date, "!%Y-%m-%dT%H:%M:%S", floor(t + offset))
if not status then
local tmp = floor(t + offset)
if tmp > 0xffffffff then
-- Maybe too far in the future?
local seconds_in_year = 31556926
local extra_years = (tmp - 0xffffffff) // seconds_in_year + 1
tmp = tmp - extra_years * seconds_in_year
status, result = pcall(date, "!*t", tmp)
if status then
-- seconds_in_year is imprecise, so we truncate to date only
result = format("%d-%02d-%02d", result.year + extra_years, result.month, result.day)
end
end
end
if not status then
return ("Invalid timestamp: %s"):format(t)
end
return result .. tz_string
end
end
--- Format a time interval into a string
--
-- String is in the same format as format_difftime
-- @param interval A time interval
-- @param unit The time unit division as a number. If <code>interval</code> is
-- in milliseconds, this is 1000 for instance. Default: 1 (seconds)
-- @return The time interval in string format
function format_time(interval, unit)
local sign = ""
if interval < 0 then
sign = "-"
interval = math.abs(interval)
end
unit = unit or 1
local precision = floor(math.log(unit, 10))
local sec = (interval % (60 * unit)) / unit
interval = interval // (60 * unit)
local min = interval % 60
interval = interval // 60
local hr = interval % 24
interval = interval // 24
local s = format("%.0fd%02.0fh%02.0fm%02.".. precision .."fs",
interval, hr, min, sec)
-- trim off leading 0 and "empty" units
return sign .. (match(s, "([1-9].*)") or format("%0.".. precision .."fs", 0))
end
--- Format the difference between times <code>t2</code> and <code>t1</code>
-- into a string
--
-- String is in one of the forms (signs may vary):
-- * 0s
-- * -4s
-- * +2m38s
-- * -9h12m34s
-- * +5d17h05m06s
-- * -2y177d10h13m20s
-- The string shows <code>t2</code> relative to <code>t1</code>; i.e., the
-- calculation is <code>t2</code> minus <code>t1</code>.
function format_difftime(t2, t1)
local d, s, sign, yeardiff
d = difftime(time(t2), time(t1))
if d > 0 then
sign = "+"
elseif d < 0 then
sign = "-"
t2, t1 = t1, t2
d = -d
else
sign = ""
end
-- t2 is always later than or equal to t1 here.
-- The year is a tricky case because it's not a fixed number of days
-- the way a day is a fixed number of hours or an hour is a fixed
-- number of minutes. For example, the difference between 2008-02-10
-- and 2009-02-10 is 366 days because 2008 was a leap year, but it
-- should be printed as 1y0d0h0m0s, not 1y1d0h0m0s. We advance t1 to be
-- the latest year such that it is still before t2, which means that its
-- year will be equal to or one less than t2's. The number of years
-- skipped is stored in yeardiff.
if t2.year > t1.year then
local tmpyear = t1.year
-- Put t1 in the same year as t2.
t1.year = t2.year
d = difftime(time(t2), time(t1))
if d < 0 then
-- Too far. Back off one year.
t1.year = t2.year - 1
d = difftime(time(t2), time(t1))
end
yeardiff = t1.year - tmpyear
t1.year = tmpyear
else
yeardiff = 0
end
local s = format_time(d)
if yeardiff == 0 then return sign .. s end
-- Years.
s = format("%dy", yeardiff) .. s
return sign .. s
end
--- Returns the current time in milliseconds since the epoch --- Returns the current time in milliseconds since the epoch
-- @return The current time in milliseconds since the epoch -- @return The current time in milliseconds since the epoch
function clock_ms() function clock_ms()

View File

@@ -1,4 +1,4 @@
local os = require "os" local datetime = require "datetime"
local shortport = require "shortport" local shortport = require "shortport"
local stdnse = require "stdnse" local stdnse = require "stdnse"
local tab = require "tab" local tab = require "tab"
@@ -67,7 +67,7 @@ action = function(host, port)
if ( target.ALLOW_NEW_TARGETS ) then if ( target.ALLOW_NEW_TARGETS ) then
target.add(node.address.host) target.add(node.address.host)
end end
tab.addrow(response, ("%s:%d"):format(node.address.host, node.address.port), stdnse.format_timestamp(node.ts)) tab.addrow(response, ("%s:%d"):format(node.address.host, node.address.port), datetime.format_timestamp(node.ts))
end end
if ( #response > 1 ) then if ( #response > 1 ) then

View File

@@ -63,7 +63,7 @@ action = function(host, port)
datetime.record_skew(host, ver.timestamp, request_time) datetime.record_skew(host, ver.timestamp, request_time)
local result = stdnse.output_table() local result = stdnse.output_table()
result["Timestamp"] = stdnse.format_timestamp(ver.timestamp) result["Timestamp"] = datetime.format_timestamp(ver.timestamp)
result["Network"] = NETWORK[ver.magic] result["Network"] = NETWORK[ver.magic]
result["Version"] = ver.ver result["Version"] = ver.ver
result["Node Id"] = ver.nodeid result["Node Id"] = ver.nodeid

View File

@@ -1,4 +1,5 @@
local coroutine = require "coroutine" local coroutine = require "coroutine"
local datetime = require "datetime"
local formulas = require "formulas" local formulas = require "formulas"
local math = require "math" local math = require "math"
local nmap = require "nmap" local nmap = require "nmap"
@@ -103,9 +104,9 @@ hostaction = function(host)
if mean ~= 0 or stddev ~= 0 or nmap.verbosity() > 1 then if mean ~= 0 or stddev ~= 0 or nmap.verbosity() > 1 then
local out = {mean = mean, stddev = stddev, median = median} local out = {mean = mean, stddev = stddev, median = median}
return out, ("mean: %s, deviation: %s, median: %s"):format( return out, ("mean: %s, deviation: %s, median: %s"):format(
stdnse.format_time(mean), datetime.format_time(mean),
stdnse.format_time(stddev), datetime.format_time(stddev),
stdnse.format_time(median) datetime.format_time(median)
) )
end end
end end
@@ -169,10 +170,10 @@ postaction = function()
for mean, group in pairs(groups) do for mean, group in pairs(groups) do
-- Collapse the biggest group -- Collapse the biggest group
if #groups > 1 and #group > host_count // 2 then if #groups > 1 and #group > host_count // 2 then
out[stdnse.format_time(mean)] = "Majority of systems scanned" out[datetime.format_time(mean)] = "Majority of systems scanned"
elseif #group > 1 then elseif #group > 1 then
-- Only record groups of more than one system together -- Only record groups of more than one system together
out[stdnse.format_time(mean)] = group out[datetime.format_time(mean)] = group
end end
end end

View File

@@ -1,3 +1,4 @@
local datetime = require "datetime"
local math = require "math" local math = require "math"
local match = require "match" local match = require "match"
local nmap = require "nmap" local nmap = require "nmap"
@@ -113,7 +114,7 @@ local function decodeTag(tag, lines)
"version" == tag ) then "version" == tag ) then
return ("%s: %s"):format(long_names[tag], lines[1]) return ("%s: %s"):format(long_names[tag], lines[1])
elseif ( "uptime" == tag ) then elseif ( "uptime" == tag ) then
return ("%s: %s"):format(long_names[tag], stdnse.format_time(lines[1] * 60)) return ("%s: %s"):format(long_names[tag], datetime.format_time(lines[1] * 60))
elseif ( "mem" == tag ) then elseif ( "mem" == tag ) then
local total, used = table.unpack(stdnse.strsplit("%s", lines[1])) local total, used = table.unpack(stdnse.strsplit("%s", lines[1]))
if ( not(total) or not(used) ) then if ( not(total) or not(used) ) then

View File

@@ -1,3 +1,4 @@
local datetime = require "datetime"
local gps = require "gps" local gps = require "gps"
local match = require "match" local match = require "match"
local nmap = require "nmap" local nmap = require "nmap"
@@ -96,7 +97,7 @@ action = function(host, port)
end end
local output = { local output = {
("Time of fix: %s"):format(stdnse.format_timestamp(gps.Util.convertTime(gpsinfo.date, gpsinfo.time))), ("Time of fix: %s"):format(datetime.format_timestamp(gps.Util.convertTime(gpsinfo.date, gpsinfo.time))),
("Coordinates: %.4f,%.4f"):format(tonumber(gpsinfo.latitude), tonumber(gpsinfo.longitude)), ("Coordinates: %.4f,%.4f"):format(tonumber(gpsinfo.latitude), tonumber(gpsinfo.longitude)),
("Speed: %s knots"):format(gpsinfo.speed) ("Speed: %s knots"):format(gpsinfo.speed)
} }

View File

@@ -1,3 +1,4 @@
local datetime = require "datetime"
local http = require "http" local http = require "http"
local os = require "os" local os = require "os"
local shortport = require "shortport" local shortport = require "shortport"
@@ -42,16 +43,16 @@ action = function(host, port)
if not response_date then if not response_date then
return return
end end
local response_time = stdnse.date_to_timestamp(response_date) local response_time = datetime.date_to_timestamp(response_date)
local output_tab = stdnse.output_table() local output_tab = stdnse.output_table()
output_tab.date = stdnse.format_timestamp(response_time, 0) output_tab.date = datetime.format_timestamp(response_time, 0)
output_tab.delta = os.difftime(response_time, request_time) output_tab.delta = os.difftime(response_time, request_time)
datetime.record_skew(host, response_time, request_time) datetime.record_skew(host, response_time, request_time)
local output_str = string.format("%s; %s from local time.", local output_str = string.format("%s; %s from local time.",
response.header["date"], stdnse.format_difftime(os.date("!*t", response_time), os.date("!*t", request_time))) response.header["date"], datetime.format_difftime(os.date("!*t", response_time), os.date("!*t", request_time)))
return output_tab, output_str return output_tab, output_str
end end

View File

@@ -1,5 +1,5 @@
local mobileme = require "mobileme" local mobileme = require "mobileme"
local os = require "os" local datetime = require "datetime"
local stdnse = require "stdnse" local stdnse = require "stdnse"
local tab = require "tab" local tab = require "tab"
@@ -74,7 +74,7 @@ action = function()
end end
local ts local ts
if ( info.timestamp and 1000 < info.timestamp ) then if ( info.timestamp and 1000 < info.timestamp ) then
ts = stdnse.format_timestamp(info.timestamp//1000) ts = datetime.format_timestamp(info.timestamp//1000)
else else
ts = "-" ts = "-"
end end

View File

@@ -1,4 +1,5 @@
local coroutine = require "coroutine" local coroutine = require "coroutine"
local datetime = require "datetime"
local math = require "math" local math = require "math"
local nmap = require "nmap" local nmap = require "nmap"
local os = require "os" local os = require "os"
@@ -334,7 +335,7 @@ action = function(host, port)
end end
stop = os.date("!*t") stop = os.date("!*t")
dos_time = stdnse.format_difftime(stop, start) dos_time = datetime.format_difftime(stop, start)
if DOSed then if DOSed then
if Reason == "slowloris" then if Reason == "slowloris" then
stdnse.debug2("Slowloris Attack stopped, building output") stdnse.debug2("Slowloris Attack stopped, building output")

View File

@@ -57,7 +57,7 @@ local filter = {
["pid"] = { name = "Process ID" }, ["pid"] = { name = "Process ID" },
["uptime"] = { name = "Uptime", func = function(v) return ("%d seconds"):format(v) end }, ["uptime"] = { name = "Uptime", func = function(v) return ("%d seconds"):format(v) end },
["time"] = { name = "Server time", func = stdnse.format_timestamp }, ["time"] = { name = "Server time", func = datetime.format_timestamp },
["pointer_size"] = { name = "Architecture", func = function(v) return v .. " bit" end }, ["pointer_size"] = { name = "Architecture", func = function(v) return v .. " bit" end },
["rusage_user"] = { name = "Used CPU (user)" }, ["rusage_user"] = { name = "Used CPU (user)" },
["rusage_system"] = { name = "Used CPU (system)"}, ["rusage_system"] = { name = "Used CPU (system)"},

View File

@@ -112,7 +112,7 @@ action = function(host, port)
datetime.record_skew(host, tstamp, recvtime) datetime.record_skew(host, tstamp, recvtime)
output["receive time stamp"] = stdnse.format_timestamp(tstamp) output["receive time stamp"] = datetime.format_timestamp(tstamp)
end end
status, bufrlres = comm.exchange(host, port, rlreq, {timeout=TIMEOUT}) status, bufrlres = comm.exchange(host, port, rlreq, {timeout=TIMEOUT})

View File

@@ -1,4 +1,5 @@
local comm = require "comm" local comm = require "comm"
local datetime = require "datetime"
local nmap = require "nmap" local nmap = require "nmap"
local shortport = require "shortport" local shortport = require "shortport"
local stdnse = require "stdnse" local stdnse = require "stdnse"
@@ -174,7 +175,7 @@ local function formattime(data)
if not time then if not time then
return return
end end
return stdnse.format_timestamp(time) return datetime.format_timestamp(time)
end end
local function formatvalue(key, nson) local function formatvalue(key, nson)

View File

@@ -1,3 +1,4 @@
local datetime = require "datetime"
local stdnse = require "stdnse" local stdnse = require "stdnse"
local shortport = require "shortport" local shortport = require "shortport"
local comm = require "comm" local comm = require "comm"
@@ -192,7 +193,7 @@ local function format_dimensions(res)
values[ params[counter] ] = val values[ params[counter] ] = val
end end
res["Date and Time"] = stdnse.format_timestamp(values) res["Date and Time"] = datetime.format_timestamp(values)
end end
if res["Device Type"] then if res["Device Type"] then

View File

@@ -59,6 +59,6 @@ action = function(host, port)
nmap.set_port_version(host, port, "hardmatched") nmap.set_port_version(host, port, "hardmatched")
end end
return stdnse.format_timestamp(stamp) return datetime.format_timestamp(stamp)
end end
end end

View File

@@ -1,3 +1,4 @@
local datetime = require "datetime"
local rpc = require "rpc" local rpc = require "rpc"
local shortport = require "shortport" local shortport = require "shortport"
local stdnse = require "stdnse" local stdnse = require "stdnse"
@@ -108,10 +109,10 @@ local function rusers2_entry(comm, data, pos)
if not pos then return fail(entry.host) end if not pos then return fail(entry.host) end
pos, entry.time = rpc.Util.unmarshall_uint32(data, pos) pos, entry.time = rpc.Util.unmarshall_uint32(data, pos)
entry.time = stdnse.format_timestamp(entry.time) entry.time = datetime.format_timestamp(entry.time)
pos, entry.idle = rpc.Util.unmarshall_uint32(data, pos) pos, entry.idle = rpc.Util.unmarshall_uint32(data, pos)
entry.idle = stdnse.format_time(entry.idle) entry.idle = datetime.format_time(entry.idle)
return pos, entry, data return pos, entry, data
end end

View File

@@ -1,3 +1,4 @@
local datetime = require "datetime"
local msrpc = require "msrpc" local msrpc = require "msrpc"
local smb = require "smb" local smb = require "smb"
local stdnse = require "stdnse" local stdnse = require "stdnse"
@@ -306,14 +307,14 @@ action = function(host)
if(time == 0) then if(time == 0) then
time = "[just logged in, it's probably you]" time = "[just logged in, it's probably you]"
else else
time = stdnse.format_time(time) time = datetime.format_time(time)
end end
local idle_time = sessions[i]['idle_time'] local idle_time = sessions[i]['idle_time']
if(idle_time == 0) then if(idle_time == 0) then
idle_time = "[not idle]" idle_time = "[not idle]"
else else
idle_time = stdnse.format_time(idle_time) idle_time = datetime.format_time(idle_time)
end end
table.insert(sessions_output, string.format("%s is connected from %s for %s, idle for %s", sessions[i]['user'], sessions[i]['client'], time, idle_time)) table.insert(sessions_output, string.format("%s is connected from %s for %s, idle for %s", sessions[i]['user'], sessions[i]['client'], time, idle_time))

View File

@@ -161,7 +161,7 @@ action = function(host)
response.domain = result.domain response.domain = result.domain
response.server = result.server response.server = result.server
if result.time and result.timezone then if result.time and result.timezone then
response.date = stdnse.format_timestamp(result.time, result.timezone * 60 * 60) response.date = datetime.format_timestamp(result.time, result.timezone * 60 * 60)
datetime.record_skew(host, result.time - result.timezone * 60 * 60, request_time) datetime.record_skew(host, result.time - result.timezone * 60 * 60, request_time)
end end
response.fqdn = result.fqdn response.fqdn = result.fqdn

View File

@@ -1,3 +1,4 @@
local datetime = require "datetime"
local msrpc = require "msrpc" local msrpc = require "msrpc"
local os = require "os" local os = require "os"
local smb = require "smb" local smb = require "smb"
@@ -156,7 +157,7 @@ local function get_info_registry(host)
result['status-currentversion'], result['currentversion'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "CurrentVersion") result['status-currentversion'], result['currentversion'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "CurrentVersion")
result['status-installdate'], result['installdate'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "InstallDate") result['status-installdate'], result['installdate'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "InstallDate")
if(result['status-installdate'] ~= false) then if(result['status-installdate'] ~= false) then
result['installdate'] = stdnse.format_timestamp(result['installdate']) result['installdate'] = datetime.format_timestamp(result['installdate'])
end end
result['status-productname'], result['productname'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "Productname") result['status-productname'], result['productname'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "Productname")

View File

@@ -1,3 +1,4 @@
local datetime = require "datetime"
local datafiles = require "datafiles" local datafiles = require "datafiles"
local ipOps = require "ipOps" local ipOps = require "ipOps"
local nmap = require "nmap" local nmap = require "nmap"
@@ -129,7 +130,7 @@ action = function (host, port)
output.engineIDData = stdnse.tohex(engineID:sub(5)) output.engineIDData = stdnse.tohex(engineID:sub(5))
end end
output.snmpEngineBoots = decoded[2] output.snmpEngineBoots = decoded[2]
output.snmpEngineTime = stdnse.format_time(decoded[3]) output.snmpEngineTime = datetime.format_time(decoded[3])
port.version = port.version or {} port.version = port.version or {}
port.version.service = "snmp" port.version.service = "snmp"

View File

@@ -1,3 +1,4 @@
local datetime = require "datetime"
local nmap = require "nmap" local nmap = require "nmap"
local shortport = require "shortport" local shortport = require "shortport"
local snmp = require "snmp" local snmp = require "snmp"
@@ -62,7 +63,7 @@ action = function(host, port)
return return
end end
result = result .. "\n" .. string.format(" System uptime: %s (%s timeticks)", stdnse.format_time(uptime, 100), tostring(uptime)) result = result .. "\n" .. string.format(" System uptime: %s (%s timeticks)", datetime.format_time(uptime, 100), tostring(uptime))
return result return result
end end

View File

@@ -1,3 +1,4 @@
local datetime = require "datetime"
local bin = require "bin" local bin = require "bin"
local nmap = require "nmap" local nmap = require "nmap"
local shortport = require "shortport" local shortport = require "shortport"
@@ -90,7 +91,7 @@ local date_xlate = {
sec = 7 sec = 7
} }
-- translate date parts to positional indices for stdnse.format_timestamp -- translate date parts to positional indices for datetime.format_timestamp
local date_metatab = { local date_metatab = {
__index = function (t, k) __index = function (t, k)
return t[date_xlate[k]] return t[date_xlate[k]]
@@ -123,7 +124,7 @@ local function process_answer( tbl )
local sw_item = { local sw_item = {
["name"] = v.value, ["name"] = v.value,
["install_date"] = stdnse.format_timestamp(install_date_tab) ["install_date"] = datetime.format_timestamp(install_date_tab)
} }
setmetatable(sw_item, sw_metatab) setmetatable(sw_item, sw_metatab)

View File

@@ -1,3 +1,4 @@
local datetime = require "datetime"
local nmap = require "nmap" local nmap = require "nmap"
local shortport = require "shortport" local shortport = require "shortport"
local sslcert = require "sslcert" local sslcert = require "sslcert"
@@ -143,7 +144,7 @@ function date_to_string(date)
if type(date) == "string" then if type(date) == "string" then
return string.format("Can't parse; string is \"%s\"", date) return string.format("Can't parse; string is \"%s\"", date)
else else
return stdnse.format_timestamp(date) return datetime.format_timestamp(date)
end end
end end
@@ -218,7 +219,7 @@ local function output_tab(cert)
if type(v)=="string" then if type(v)=="string" then
o.validity[k] = v o.validity[k] = v
else else
o.validity[k] = stdnse.format_timestamp(v) o.validity[k] = datetime.format_timestamp(v)
end end
end end
o.md5 = stdnse.tohex(cert:digest("md5")) o.md5 = stdnse.tohex(cert:digest("md5"))

View File

@@ -140,7 +140,7 @@ local get_time_sample = function (host, port)
-- extract time from response -- extract time from response
local tstatus, ttm = extract_time(response) local tstatus, ttm = extract_time(response)
if not tstatus then return nil end if not tstatus then return nil end
stdnse.debug(detail_debug, "TLS sample: %s", stdnse.format_timestamp(ttm, 0)) stdnse.debug(detail_debug, "TLS sample: %s", datetime.format_timestamp(ttm, 0))
return {target=ttm, scanner=stm, delta=os.difftime(ttm, stm)} return {target=ttm, scanner=stm, delta=os.difftime(ttm, stm)}
end end
@@ -205,11 +205,11 @@ action = function(host, port)
datetime.record_skew(host, tm.target, tm.scanner) datetime.record_skew(host, tm.target, tm.scanner)
local output = { local output = {
date = stdnse.format_timestamp(tm.target, 0), date = datetime.format_timestamp(tm.target, 0),
delta = tm.delta, delta = tm.delta,
} }
return output, return output,
string.format("%s; %s from scanner time.", output.date, string.format("%s; %s from scanner time.", output.date,
stdnse.format_difftime(os.date("!*t", tm.target), datetime.format_difftime(os.date("!*t", tm.target),
os.date("!*t", tm.scanner))) os.date("!*t", tm.scanner)))
end end