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

Lua Dissector - How To Use “tcp.analysis.flags” Field

0

I am trying to access the value of the "tcp.analysis.flags" field in a Lua script. I would like to apply a certain operation on all packets that have ANY of the TCP analysis flags set. However, it seems that tcp.analysis.flags is a label, and it has no real value that can be manipulated in the Lua script. Here is my code:

tcp_analysis_flags_f = Field.new("tcp.analysis.flags") print(tcp_analysis_flags_f.value)

I expect to get a boolean value or something, but instead I get an error. A print(tcp_analysis_flags_f.type) returns "0", which corresponds to ftype: "NONE".

The Wireshark GUI somehow triggers on these packets (for color filters). How can I use this field in a Lua dissector?

asked 01 Aug '16, 12:11

J_Turner's gravatar image

J_Turner
715510
accept rate: 0%

I'd say there is a step missing. Answering your previous question, @cmaynard has pointed you to these two lines of Lua code:

 5 tcp_src_f = Field.new("tcp.srcport")

18 local tcp_src = tcp_src_f()

As the syntax at line 18 shows, the object defined at line 5 is a function.

So try to change your code to

tcp_analysis_flags_f = Field.new("tcp.analysis.flags")
print(tcp_analysis_flags_f().value)

and see what happens.

Also, be aware that the first line must be part of registration of the dissector (i.e. of the main Lua code), while the second must be part of its execution (i.e. of the dissection function).

(01 Aug ‘16, 14:28) sindy

I didn’t specify it well in my question, but that is actually what I did. I have the function defined in the “registration section” and the print statement in the dissector. If I use print(tcp_analysis_flags_f().type), I get a value back: “0”. But if I do a print(tcp_analysis_flags_f().value), I get a nil value back.

(02 Aug ‘16, 05:52) J_Turner

I believe that tcp.analysis.flags is a field, not a label, but it has no value (neither scalar nor structured). So actually, the very existence of the field in a given frame is the condition you look for: if any tcp analysis flag (like e.g. tcp.analysis.retransmission) exists, the field tcp.analysis.flags exists as well.

(02 Aug ‘16, 06:24) sindy

So how do I practically use it? Is there a way to check if the field exists for a certain frame?

(02 Aug ‘16, 06:32) J_Turner

Never needed that myself (but I have written less than 10 Lua dissectors so far), but I would guess that if your tcp_analysis_flags_f() returns anything else than nil, the field exists, otherwise it doesn’t.

(02 Aug ‘16, 06:36) sindy

So you may try simply

if tcp_analysis_flags_f() then …
(02 Aug ‘16, 06:48) sindy

That worked. Thank you!

(02 Aug ‘16, 07:18) J_Turner
showing 5 of 7 show 2 more comments


2 Answers:

1

Similarly to a few "real" fields in various protocols, tcp.analysis.flags is a field (which is easy to verify as you can filter on it - you cannot filter on labels), but it contains no value - it either is present in the frame (or PDU) or not. This approach saves memory and allows to keep filter expressions simple.

Regardless whether a field has a value or not, the extractor function registered using Field.new("proto.field.name") returns a reference to the object representing the target field if the dissectors which processed the frame so far have added that field to the tree, or nil otherwise. And the way Lua works, nil is equal to false in boolean expressions, while any other value (including 0!) equals to true. This is directly equivalent to the way how field names can be used in display filters - an expression field.name evaluates to true if the field is present in the PDU, an expression !field.name evaluates to true if it is not.

In addition to that, tcp.analysis.flags is a meta-field whose existence is a logical "or" of existence of the individual TCP analysis flags (which themselves are also value-less meta-fields).

So the solution of your need to perform (or not) a certain operation if any of the TCP analysis flags exists in the frame is to register an extractor function for this summary field, tcp.analysis.flags, as you did, and then directly use it as a unary boolean expression in an if statement the following way:

if your_extractor_function() then ...

answered 02 Aug '16, 11:07

sindy's gravatar image

sindy
6.0k4851
accept rate: 24%

1

This answer came out of the comments from @sindy. I am putting it here so it gets marked as answered.

The key was to check if the field existed. If it didn't exist (i.e. the frame didn't fit the "tcp.analysis.flags" filter), it will fail an 'if' condition. Here is the code:

--Outside dissector
tcp_analysis_flags_f = Field.new("tcp.analysis.flags")

–Inside dissector if(tcp_analysis_flags_f()) then –The packet is a tcp.analysis.flags packet end

This allows the Lua dissector to make decisions based on this filter/field.

answered 02 Aug ‘16, 07:18

J_Turner's gravatar image

J_Turner
715510
accept rate: 0%

Since @sindy provided the answer you were looking for, it would have been better if you had asked @sindy to change his comments to an answer so that you could have accepted it. What you’ve effectively done is claimed the answer for yourself, earning yourself undeserved reputation points. This is not good form.

(02 Aug ‘16, 08:40) cmaynard ♦♦

Oops. My bad. @sindy, if you elevate your comments to an answer I will mark it is accepted and delete my answer.

(02 Aug ‘16, 08:43) J_Turner

@cmaynard, look at it from the positive side - for some people it is too complex to just click the Accept icon to highlight the Question as usefully answered for others, whereas @J_Turner took the effort to put together a concise Answer from my hints.

So to satisfy house rules, I’m going to write my own summary as an Answer as I originally intended to after getting @J_Turner’s confirmation that my suggestion worked, but I definitely don’t feel robbed :-)

And as for undeserved reputation, it even seems that accepting your own Answer actually doesn’t earn you any karma points.

(02 Aug ‘16, 09:31) sindy