Huge thanks to our Platinum Members Endace and LiveAction,
and our Silver Member Veeam, for supporting the Wireshark Foundation and project.

Wireshark-dev: Re: [Wireshark-dev] Can't get nsecs info form lua srcript ?

From: John Sullivan <jsethdev@xxxxxxxxxxxxxxxxxxxx>
Date: Thu, 20 Nov 2014 22:43:47 +0000
On Thursday, November 20, 2014, 4:07:33 PM, ?? wrote:
>  Is it possible to get  accurate nanosecond info for lua script ?   For the
> same packet , I got pinfo.abs_ts == 1416493696.7953 in lua script  , but in
> main window the time show as "1416493696.795345000",    is it possible to
> got  the accurate nanosecond in lua ?

The answer to your question consists of two parts: firstly, your
immediate problem.

A double-precision IEEE 754 number[1] contains 1 sign bit, 11 exponent
bits, and 53 mantissa bits, to give a total of 64 bits. (The first
mantissa bit is assumed to be 1 and so not stored, so it does add up!)

53 bits gets you a little under 16 decimal digits of significance
(53 / (log(10)/log(2)) = 15.955). (That means any number containing 15
significant digits should be representable, after rounding. Not every
number containing 16 significant digits will be.)

Using an online calculator[2][3], we can see how the more precise
number above would be stored, and what the nearest representable
neighbour numbers are to it:

                    1416493696.7953450 => 41D51B7EA032E6EF
41D51B7EA032E6EE => 1416493696.7953448
41D51B7EA032E6F0 => 1416493696.7953453

So you can see that from your original number, it is impossible to
represent any other number closer than +300ns / -200ns from it. This
gives you your maximum timestamp resolution achievable if the
timestamp is represented as a double-precision number of seconds since
the UNIX epoch.

Note that the precision available to the right of the decimal point
depends on the number of bits required to represent the integer part
to the left of the decimal point. When that changes, so to does your
maximum precision. The last time that changed was at
time_t==0x40000000 (Sat 10 Jan 13:37:04 UTC 2004), when the precision
dropped from 100-200ns to the current value. The next time it will
happen, assuming we're all using unsigned or 64-bit time_t by then
will be time_t==0x80000000 (Tue 19 Jan 03:14:08 UTC 2038) when it will
drop again to 500ns.

Another way of looking at that is that we have 53 bits to represent
the timestamp, the seconds part requires 31 bits leaving us 22 bits to
represent parts of a second. 22 bits can represent a little over 4
million unique values, there are 1 million microseconds in a second so
each can be uniquely identified, but there are 1 billion nanoseconds
so not all nanosecond values can be.

lua, of course, appears to give you even less than that. But that's an
illusion:

$ lua
Lua 5.2.2  Copyright (C) 1994-2013 Lua.org, PUC-Rio
> a = 1416493696.795345000
> b = 1416493696.7953
> print(a)
1416493696.7953
> print(b)
1416493696.7953
> print(a-b)
4.5061111450195e-05
> print(string.format("%f",a))
1416493696.795345
> print(string.format("%f",b))
1416493696.795300

So lua is internally representing the full precision of the original
number, but its default display format for numbers is:

lua-5.1.4/src/luaconf.h.template.in:#define LUA_NUMBER  double
lua-5.1.4/src/luaconf.h.template.in:#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
lua-5.1.4/src/luaconf.h.template.in:#define LUA_NUMBER_FMT              "%.14g"

So lua is by default deliberately only formatting 14 significant
digits, 1 fewer than the accuracy limit and 2 fewer than the
representable limit. If you want those extra digits to display, you
have to call string.format() with your own format string, but beware:
not all the digits that result from that have any meaning whatsoever!

[1] http://en.wikipedia.org/wiki/Floating_point#IEEE_754:_floating_point_in_modern_computers
[2] http://babbage.cs.qc.cuny.edu/IEEE-754.old/Decimal.html
[3] http://babbage.cs.qc.cuny.edu/IEEE-754.old/64bit.html


The second part of the answer involves the meaning of a nanosecond
precision packet timestamp.

On a 1Gbps link a maximum size (but not jumbo) ethernet frame takes
12us to transmit.

On a 10Gbps link it takes 1.2us.

If that is a fibre 10Gbps link the packet can travel 360 metres in
that time. 540m over copper. That'll get you round a building. If
you're transiting a city that'll be 20us or so (one-way), across a
continent about 5ms. And that's just signal propagation delay,
switching/routing/buffering delays will swamp those figures, and be
much less predictable.

So it unlikely that measuring packet arrival time down to nanosecond
precision actually gives you any more accuracy than measuring to
microsecond or even tens of microsecond precision.

John
-- 
Dead stars still burn