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

Lua: Comparing a boolean value

0

I've been trying to get a comparison going on my code, but can't seem to manage the way to do it:

I have this field:

f.bitmap1_b1_10000000 = ProtoField.bool("f.bitmap1_b1_10000000","condition present?",8,{"Present","Not Present"},0x80)

I then eventually set it's value:

local bitmap1_b1_10000000 = data(offset,1)
subtree:add(f.bitmap1_b1_10000000,bitmap1_b1_10000000)

And the value shows up correctly on the dissector window (I've checked, and it works for every one of the 128 fields.. >_<)

Now, onto parsing the rest of the data, I'm trying to conditionally execute my code based upon the boolean fields, but cannot seem to:

These DO work on the GUI, but DO NOT work on the code(devel 1.7.0):

if f.bitmap1_b1_10000000 == 1 then
    offset = offset + 8
end

if f.bitmap1_b1_10000000 == "Present" then offset = offset + 8 end

This too does not work (for some reason beyond my comprehension):

if (data(correct_offset,1):uint() and 0x80) then
offset = offset + 8
end

Neither does this:

if (data(correct_offset,1):uint() % (2*0x80) >= 0x80) then
offset = offset + 8
end

(the offsets are correct on the code, I’m just simplifing them here)

So, is there a way to actually do it? What am I doing wrong?

asked 24 Feb ‘12, 23:14

gutoandreollo's gravatar image

gutoandreollo
6114
accept rate: 0%

edited 25 Feb ‘12, 17:02

helloworld's gravatar image

helloworld
3.1k42041

By (data(correct_offset,1):uint() and 0x80) do you mean to perform a bitwise-and? If so, this may be part of your problem. I don’t know if this has changed since I last implemented a Lua-based dissector, but Wireshark’s Lua interpreter does not have an extension for bitwise operators. See this article on the lua-users wiki.

(25 Feb ‘12, 08:50) multipleinte…


One Answer:

1

Display Filters != Lua

By "work on the GUI", are you referring to the Display Filter Textbox? As in: you enter "f.bitmap1_b1_10000000 == 1" into the textbox, which filters your packet list accordingly, but when you try that same predicate in Lua, it does not evaluate to true. Correct? If so, then you're incorrectly assuming the syntax is the same.

In your Lua, this line:

if f.bitmap1_b1_10000000 == 1 then

is comparing whether the ProtoField defined by f.bitmap1_b1_10000000 is equal to 1, which is nonsense because of a type mismatch. That should be a syntax error.

Maybe you meant to use the variable (with a similar name) you had declared earlier:

if bitmap1_b1_10000000 == 1 then

but that would be comparing a TvbRange with a number, which is the same syntax error as before.


I'm not sure why this filter:

f.bitmap1_b1_10000000 == "Present"

does anything for you. That's comparing a boolean field (which presumably only accepts 0, 1, false, and true) to a string. I guess it could be comparing only the first byte of the string (empty string is false, else true).

Use bit.band

The and keyword is logical AND; not bitwise AND. You're looking for bit.band (which Wireshark Lua supports natively):

if (bit.band( data(correct_offset,1):uint(), 0x80 ) == 0x80) then


Your original line always evaluates to true:

if (data(correct_offset,1):uint() and 0x80) then

In Lua, when non-nil objects are logically AND-ed, the result is always the last object. For example, (1 and 0) is true and results in 0; and (1 and nil) is false and results in nil.

So, assuming uint() is never nil, the above line is equivalent to:

if 0x80 then

which is also:

if true then

answered 25 Feb '12, 16:02

helloworld's gravatar image

helloworld
3.1k42041
accept rate: 28%

edited 26 Feb '12, 10:56

THANK YOU for your answer.

On each of the points: On TvbRange: I've found that both of them work, as long as there's a direct relationship between the variable and the TvbRange.. I really cannot see why it should work, but empirically (as of devel 1.7.0), it does.. o.O

On the display filter, I do realize it's different from Lua, but I had a glimmer of hope that it could maybe work, or at least accept the same syntax. "Present" (and it's opposite, "Not Present") are the binary value table for the variable (as defined on the ProtoField.Bool

(26 Feb '12, 06:38) gutoandreollo

On bit.band, THANK YOU once again for your answer! It works flawlessly! I'd tried bit32.band (as per the lua-users wiki), but its not implemented.. bit.band(), on the other hand, works just fine.

Now, the next step is: Is there a way to obtain the logical value (true/false) for a ProtoField.Bool? I'm getting to the point where I'm writing the post_dissector, and the variables aren't quite local anymore.. :(

(26 Feb '12, 06:38) gutoandreollo

I've found that both of them work, as long as there's a direct relationship between the variable and the TvbRange.. I really cannot see why it should work, but empirically (as of devel 1.7.0), it does..

You're talking about the Use TvbRange section. Ah, you're right. When I saw your subtree:add line without a TvbRange, I assumed that the variable used was something other than a TvbRange (such as a number), which is something I see done often. It turns out that variable was indeed a TvbRange, so that particular advice wasn't that helpful (oops, I'll proofread next time).

(26 Feb '12, 10:57) helloworld

To get the value of that ProtoField, you need to use a Field. Your mileage may vary as it's been reported to not extract fields defined from Lua. If that's the case, you'll have to re-parse your data in your post-dissector.

(26 Feb '12, 11:12) helloworld