This is a static archive of our old Q&A Site. Please post any new questions and answers at ask.wireshark.org.

How to convert le_nstime() to string in Lua

0

How do I convert TvbRange.le_nstime() to a string? I tried the following Lua:

local field_time = ProtoField.absolute_time("TIME","TIME",base.LOCAL);
...
function SCP_proto.dissector (buf, pkt, root){
 local value={
    [0] =0,
    [1] =0,
    [2] =0
  }
  ...
  for i=0,2,1 do
     ...
     local example_subtree = subtree:add(field_time,buf(offset,8):le_nstime());
     value[i] = tostring(buf(offset,8):le_nstime());
     ...
  end
}

...but value[i] = tostring(buf(offset,8):le\_nstime()) does not work the way I expected. The time format of value[i] is in seconds ("1336188353.000000150") instead of "Month|Day|Year|Time" format ("May 5, 2012 07:25:53.000000150"). However, in the Packet Details Pane, I see "May 5, 2012 07:25:53.000000150" as expected.

How can I get a formatted time-string from le_nstime() like the one I see in the protocol tree?

Wireshark 1.7, Win 7, Lua 5.1

This question is marked "community wiki".

asked 05 Jun '12, 03:24

PavelMSTU's gravatar image

PavelMSTU
26236
accept rate: 50%

edited 05 Jun '12, 16:15

helloworld's gravatar image

helloworld
3.1k42041


One Answer:

1

You're looking for format_date (or format_time), as in:

  -- First, convert the NSTime to a string (which yields a decimal number).
  -- Then, convert that string into a Lua number, required by format_date().
  local seconds = tostring(buf(offset,8):le_nstime())
  seconds = tonumber(seconds)
  value[i] = format_date(seconds)

But I should point out some other things about your sample code above:

  1. There is no base.LOCAL (despite the documentation in the Wireshark user manual...this is a bug). Since it doesn't exist, base.LOCAL is equivalent to nil.

  2. You don't need to initialize a table with zeroes. You can simply declare the table with empty brackets, and Lua is smart enough to know what to do when you index into the table with: value[i]. (Or maybe there's omitted code that actually checks these indices for zero...weird.)

    local value = {}

  3. You don't need to convert the TvbRange into an NSTime when adding it to the tree because field_time is a ProtoField.absolute_time, which is inherently an NSTime. The endianness of the buffer is implied by TreeItem.add() and TreeItem.add_le() (you want add_le() in this case).

    local example_subtree = subtree:add_le(field_time, buf(offset,8));

answered 05 Jun '12, 17:08

helloworld's gravatar image

helloworld
3.1k42041
accept rate: 28%

edited 05 Jun '12, 18:40

Helloworld, very thenks to you!

But code:


local seconds = tostring(buf(offset,8):le_nstime())

seconds = tonumber(seconds)

value[i] = format_date(seconds)


don't work. Because tonumber function return nil.

I think this mistake arises, because 8 byte double can't converted in Lua. This code works correctly:


local seconds = tostring( buf(offset,4):le_nstime());

seconds = string.sub(seconds,0,10); --[[ Return 10 numbers of seconds, from January 1, 1970 ]]--

seconds = tonumber(seconds);

value[i] = format_date(seconds);


(06 Jun '12, 00:52) PavelMSTU

Actually, an NSTime can be either 4 or 8 bytes. You lose precision with 4 bytes. tonumber() only returns nil for non-convertible strings. The tostring() conversion could've returned a non-convertible string (perhaps nil), which would indicate a problem with the buffer contents.

You don't need to parse out the seconds from the string since tonumber() handles floating-point numbers.

(06 Jun '12, 07:39) helloworld