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

Lua 64 bit integer to double conversion works in Mac, not in Windows

0

I have some code in my dissector similar to this:

value = UInt64(0x3f91df0b2b89dd1e)
unEncoded = Struct.pack("E", value)
finalValue = Struct.unpack("d", unEncoded)
print("Value is " .. finalValue)

Running Wireshark in Mac I got: Value is 0.017452406437284. Using tshark in Mac got the same value. This is the correct value I expected.

However, in Windows, things start to go haywire. Running Wireshark, I got Value as 3.6089288239837e-315; tshark in Windows I got Value as 2.1219957904712e-314.

Crazy!

I do need my dissectors to work in Windows. What should I do?

asked 19 Mar '14, 08:48

YXI's gravatar image

YXI
21182023
accept rate: 0%

edited 19 Mar '14, 11:32

Hadriel's gravatar image

Hadriel
2.7k2939

Which Wireshark version, and which Windows operating system version?

Also, FYI: you shouldn't make a call to UInt64() with a number that big - it's a Lua number before it gets to UInt64(), and a Lua number that big loses precision (Lua numbers are doubles, so only ~53 bits of precision). Your number luckily happens to be a precise one as a Lua number, but it's bad practice. That's why UInt64() now has an optional second argument, to let you give the low-32 and high-32 bits as separate Lua numbers, so that you don't lose the precision. :)

(19 Mar '14, 11:37) Hadriel

Thanks for pointing that out. In my real code, I actually pass a string, not a number, like this:

obj_64 = UInt64.new()

value = obj_64.fromhex(tostring(allBytes))

allBytes is an 8-byte ByteArray. This won't have the loss of precision problem, right?

I'm using Windows 7 (32-bit) on a nightly built from a few weeks ago: wireshark-1.11.3-rc1-1851-gb2689ab-dirty from master

Any ideas?

(19 Mar '14, 12:04) YXI

Right, that way shouldn't lose precision. You can easily test it by doing:

local obj_64 = UInt64.new()
value = obj_64.fromhex(tostring(allBytes))
print(value)

That should print out the full number.

(19 Mar '14, 12:25) Hadriel

Yes, but why did windows gave the wrong numbers after conversion to double as stated in my original question?

(19 Mar '14, 12:27) YXI

A quick tshark run of this command got me the correct converted double! Great. Now I will change my real code (a lot more complex) and run in Wireshark and see how it goes.

(19 Mar '14, 12:59) YXI

@Hadriel, can you post an answer so the OP can accept it?

(19 Mar '14, 14:13) grahamb ♦
showing 5 of 6 show 1 more comments

2 Answers:

0

Have you tried just doing the Struct.unpack("d", unEncoded) part without the UInt64 portions, by creating a Lua string of the binary bytes? Like so:

-- binary string representing 0x3f91df0b2b89dd1e
-- in little-endian format
print(Struct.unpack("d", "\30\221\137\43\11\223\145\63"))

BTW, as an aside, a nice thing about Lua 5.2 is it takes hex control characters in Lua strings (finally!), so you could do this instead:

print(Struct.unpack("d", "\x1E\xDD\x89\x2B\x0B\xDF\x91\x3F"))

Though I haven't tried it myself. You're using Lua 5.2 if you downloaded Wireshark 1.11.3 as a pre-built install package, I think.

answered 19 Mar '14, 16:18

Hadriel's gravatar image

Hadriel
2.7k2939
accept rate: 18%

FYI, print(Struct.unpack("d", "\x1E\xDD\x89\x2B\x0B\xDF\x91\x3F")) did not produce the correct number even in Mac. It returned 1.1410133289434e-36. It should return 0.017452406437284.

(20 Mar '14, 08:05) YXI

But you said earlier: "Running Wireshark in Mac I got: Value is 0.017452406437284. Using tshark in Mac got the same value. This is the correct value I expected." So unless UInt64.fromhex() produces the wrong value, and Struct.unpack() also produces an incorrect answer but in the right way as to undo UInt64's error, I don't see how this could be.

On your Mac, can you select the "About Wireshark" menu item and paste the output here?

(20 Mar '14, 08:19) Hadriel

I ran tshark on Mac of a script that has only one line of code: print(Struct.unpack("d", "\x1E\xDD\x89\x2B\x0B\xDF\x91\x3F")). It returned the wrong number.
But doing the decimal version, also a one-line script file: print(Struct.unpack("d", "\30\221\137\43\11\223\145\63")) produced the right number. So it seems the hex form of unpack is not working even in Lua 5.2.

(20 Mar '14, 08:43) YXI

On your Mac, can you select the "About Wireshark" menu item and paste the output here?

(20 Mar '14, 08:52) Hadriel

Version 1.11.3-1864-geef0fa6 (wireshark-1.11.3-rc1-1864-geef0fa6-dirty from unknown)

Copyright 1998-2014 Gerald Combs [email protected] and contributors. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Compiled (64-bit) with Qt 5.2.1 with GLib 2.36.0, with libpcap, with libz 1.2.3, without POSIX capabilities, with SMI 0.4.8, without c-ares, without ADNS, with Lua 5.1, without Python, with GnuTLS 2.12.19, with Gcrypt 1.5.0, with MIT Kerberos, with GeoIP, without PortAudio, with AirPcap.

Running on Mac OS X 10.9.2, build 13C64 (Darwin 13.1.0), without locale, with libpcap version 1.3.0 - Apple version 41, with libz 1.2.5, GnuTLS 2.12.19, Gcrypt 1.5.0, without AirPcap. Intel(R) Core(TM) i7-3615QM CPU @ 2.30GHz

Built using llvm-gcc 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.9.00).

(20 Mar '14, 08:59) YXI

Sorry, I'm still using Lua 5.1. Would the newest nightly build have 5.2?

(20 Mar '14, 09:03) YXI

Right, so apparently 1.11.3 ships with Lua 5.1 not 5.2. (that's a bug, since 1.10.6 ships with Lua 5.2)

See the with Lua 5.1 in that output.

But that's why it wasn't working for you. :)

(20 Mar '14, 09:24) Hadriel

Huh, my mistake, 1.10.x ships with Lua 5.1 too. So it's not a bug, but an enhancement. (to have Wireshark 1.11.x and beyond use Lua 5.2)

(20 Mar '14, 09:42) Hadriel

Windows trouble is still here! I changed my code. Now I feed Struct.unpack() the string sequence of bytes in decimal. Mac side worked like a charm. tshark in windows is working correctly also. However, Wireshark still gave me 3.6089288239837e-315, just like before.
Help!

(20 Mar '14, 16:23) YXI

Hold on, I'll fire up a Windows VM and try it.

(20 Mar '14, 17:54) Hadriel
showing 5 of 10 show 5 more comments

0

It worked for me, on Windows XP.

See this: alt text

answered 20 Mar '14, 18:08

Hadriel's gravatar image

Hadriel
2.7k2939
accept rate: 18%

The hex string "1EDD892B00000000" gives me 3.6089288239837e-315. In other words, doing this:

print(Struct.unpack("d", Struct.fromhex("1EDD892B00000000")))

gives me 3.6089288239837e-315.

(20 Mar '14, 18:25) Hadriel

Which, of course, happen to correspond to the last 4 bytes of your original hex string, in little-endian order.

(20 Mar '14, 18:26) Hadriel

Why don't you try printing out the sequence of bytes you're going to give Struct.unpack()? Struct has a tohex()/fromhex() which just converts a string back/forth without packing/unpacking. So use it like so:

print(Struct.tohex(my_binary_string))
(20 Mar '14, 18:29) Hadriel

Please move that to a new question thread. The way this site works is each thread has one question and one or more answers to it. (and they're pretty strict about keeping to that :)

Also, that way I can edit your question's formatting to show code separately from text, whereas I can't edit comments.

(21 Mar '14, 08:42) Hadriel