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

A way to highlight disjoint bytes simultaneously through Lua?

0

I've asked this before, but didn't get any answers. This might be impossible to do.

For my dissector, some tree items have the corresponding value stored in two, not continuous parts.

For example, I have this chunk of a buffer: 1a2b3c4d. The first and last byte combined is the value I need, so 1a4d. I can calculate this value and add a tree item to represent it. But I don't know how to get only the bytes 1a and 4d highlighted, and leaving the middle two bytes alone, when clicking on this tree item.

Any ideas?

asked 28 Mar '14, 12:41

YXI's gravatar image

YXI
21182023
accept rate: 0%

edited 28 Mar '14, 16:00

Hadriel's gravatar image

Hadriel
2.7k2939


4 Answers:

0

You should be able to use proto_tree_add_uint for this, since you can already compute your value.
Using your example, you'd make a header field such as this:

{&hf_myfield, {"My Field", "myproto.myfield", FT_UINT32, BASE_HEX, NULL, 0xFF0000FF, "My Field", HFILL}}
Then, in your dissect_myproto...
   //...
   value = compute_myfield_value(tvb, offset); //or however you want to do this
   proto_tree_add_uint(tree, hf_myfield, tvb, offset, 4, value);
   //...

answered 28 Mar '14, 13:53

multipleinterfaces's gravatar image

multipleinte...
1.3k152340
accept rate: 12%

Is this a C function? I have to use Lua. Also, my value is a 64 bit int.

(28 Mar '14, 14:26) YXI

Yes, it is part of the C interface. I don't think this functionality is exposed through the Lua interface right now, but I'm not as familiar with the Lua API.

(28 Mar '14, 15:17) multipleinte...

According to the docs, the mask option (0xFF0000FF in the example) should be available (optional parameter)

http://www.wireshark.org/docs/wsug_html_chunked/lua_module_Proto.html#lua_class_ProtoField

(28 Mar '14, 15:24) Kurt Knochner ♦

Also, my value is a 64 bit int.

64 bit is a second story. (usable) Lua 64 bit support was only added recently. What is your Wireshark version?

(28 Mar '14, 15:26) Kurt Knochner ♦

Using masks for ProtoFields is supported, and is shown in the dissector.lua example script found here. Using a 64-bit mask isn't though, both because Lua itself would lose precision in such a big number, but also because the current code gets it as a 32-bit integer. I'd argue the latter is a bug, but the former requires accepting a UInt64 mask type anyway to actually work right. So I think you should submit a bug.

(28 Mar '14, 16:09) Hadriel

Apparently the internal C-code for fields only supports a 32-bit mask to begin with. I grep'ed the code, and sure enough not a single 64-bit field uses a mask. The one I found that should have, cheated and pretended it was a 32-bit field because only the lower 32-bits were being used. That will make this tricky to support. :(

(28 Mar '14, 16:35) Hadriel
showing 5 of 6 show 1 more comments

0

You could try "cheating": create your current 64-bit ProtoField without a mask, and also create two 32-bit ProtoField for each 32-bit portion of the 64-bit with the appropriate mask for each portion. When you add the 64-bit one to the tree use the TvbRange of the whole 64-bits, and save the child tree returned from the tree:add() call; then add the two 32-bit ones to the child tree, giving each of them the TvbRange half they each represents. That way the user sees the 64-bit one and if they select it the whole 64-bits are highlighted, with a expandable arrow thing to see the two 32-bit ones under it for each 32-bit half, and clicking those will show the appropriately masked portions.

answered 28 Mar '14, 16:44

Hadriel's gravatar image

Hadriel
2.7k2939
accept rate: 18%

"When you add the 64-bit one to the tree use the TvbRange of the whole 64-bits"... I think this opens a new tab in the bytes pane, because it is not a TvbRange that actually exists in the stream. I don't want to have to have so many new tabs open(they don't auto close when you are done looking at them). Also, ideally, the users can see where the disjoint bytes are located in relation to each other with just open click. Oh, am I picky?

(28 Mar '14, 19:28) YXI

I'm not sure we're using the same words. A "tab" usually means a new window pane, and no adding a tree item does not create a new window. It does create a new branch in the tree, and if you add elements under that branch (i.e., under that child node) then the user will see an expansion icon (an arrow in GTK, or a plus in windows I think) next to that tree item, which they can click to expand to view what's under it if they want to. But it doesn't usually show in expanded form automatically so it shouldn't bother them.

These things are already done all over the place and most people don't notice it. For example, if you have a capture with TCP/IPv4 traffic, you'll see the Frame, Ethernet (or wifi), IP, and TCP in the details pane. If you expand the IP one, you'll see a DSCP field, which itself can be expanded, as well as the flags field, etc. Those aren't really one field each - they're multiple fields each: a parent one that you see without expanding it, and then the child ones under it when you expand them.

(28 Mar '14, 19:41) Hadriel

Sorry I have to use "Your answer" instead of comment, as I have two images.

You will see what I mean by "tab" by looking at the images. Toward the very bottom, there are two tabs, one for frame (79 bytes) and another for myTvb (4 bytes). myTvb is created from disjoint bytes in the payload. Wireshark automatically created the myTvb tab to show this new buffer that does not exist in the original payload.

The code that corresponds to this is as follows:

subtree:add(buffer(0,2),"The first value: " .. buffer(0,2):uint())

local allBytes = ByteArray.new()

local nextByte = buffer(3, 1):bytes()

allBytes:append(nextByte)

nextByte = buffer(4, 1):bytes()

allBytes:append(nextByte)

nextByte = buffer(9, 1):bytes()

allBytes:append(nextByte)

nextByte = buffer(10, 1):bytes()

allBytes:append(nextByte)

debug("bytes are " .. tostring(allBytes))

local myTvb = ByteArray.tvb(allBytes, "My Tvb")

local subtreeNext = subtree:add(myTvb(0,0),"The next value:"..myTvb(0,4):uint())

subtreeNext:add(buffer(3,2), "The first part location" )

subtreeNext:add(buffer(9,2), &quot;The second part location&quot; )</code></pre><p><img src="https://osqa-ask.wireshark.org/upfiles/Screen_Shot_2014-03-31_at_5.10.37_PM_1.png" alt="alt text" /></p><p><img src="https://osqa-ask.wireshark.org/upfiles/Screen_Shot_2014-03-31_at_5.11.28_PM_1.png" alt="alt text" /></p></div><div id="comment-31327-info" class="comment-info"><span class="comment-age">(31 Mar '14, 15:25)</span> <span class="comment-user userinfo">YXI</span></div></div><span id="31360"></span><div id="comment-31360" class="comment"><div id="post-31360-score" class="comment-score"></div><div class="comment-text"><p>That's because you're creating a new <code>Tvb</code>, and adding it to the tree. There's no need to do that. The idea was to use the original <code>Tvb</code> that came in the packet, and to display portions of it using the masking strategy.</p></div><div id="comment-31360-info" class="comment-info"><span class="comment-age">(01 Apr '14, 14:58)</span> <span class="comment-user userinfo">Hadriel</span></div></div></div><div id="comment-tools-31272" class="comment-tools"></div><div class="clear"></div><div id="comment-31272-form-container" class="comment-form-container"></div><div class="clear"></div></div></td></tr></tbody></table>

0

I don't think what you want is possible, either in Lua or C. The bytes pane highlight only does continuous ranges and the creation of a new tvb for data from discontinuous bytes creates the new tab as you have seen.

You would need to make some (possibly) extensive changes in the core Wireshark code to allow highlighting of discontinuous ranges. You can try adding an enhancement request on the Wireshark bugzilla, but I don't know if you'll get any one to take it on.

answered 01 Apr '14, 02:42

grahamb's gravatar image

grahamb ♦
19.8k330206
accept rate: 22%

Thanks. That's what I think.

(02 Apr '14, 07:34) YXI

That's because you're creating a new Tvb, and adding it to the tree. There's no need to do that. The idea was to use the original Tvb that came in the packet, and to display portions of it using the masking strategy.

(02 Apr '14, 09:41) Hadriel

That doesn't fix the OP's original issue in that they want discontiguous bytes highlighted in the bytes pane.

(02 Apr '14, 09:49) grahamb ♦

Right, but this was in the context of the "cheating" proposal I made. His response was that would create a new tab, and my point is it only creates a new tab if you create a new Tvb.

(02 Apr '14, 10:53) Hadriel

In your cheating advice you said, "When you add the 64-bit one to the tree use the TvbRange of the whole 64-bits". How do you get the TvbRange? Code please.

(02 Apr '14, 11:31) YXI

0

Do something like this outside of the dissector function:

local f_value = ProtoField.uint32("myproto.value", "The value")
local f_whole = ProtoField.bytes("myproto.value.hex", "The whole range")
local f_part1 = ProtoField.uint16("myproto.value.part1", "The first part", base.HEX)
local f_part2 = ProtoField.uint16("myproto.value.part2", "The second part", base.HEX)
-- register the above fields to your proto
myproto.fields = { f_value, f_whole, f_part1, f_part2 }

Now for the part inside the dissector function... the following assumes "buffer" is the name of the Tvb given to the dissector() function, and that your bytes start at offset 3 for 8 bytes long, since that's what it looks like from your code earlier; and the following assumes "myval" is the true/real/parsed Lua number value of your disparate fields - there are a couple different ways to achieve that without creating a new Tvb, but I assume you already have a way to do that; for example using the Struct class. If not, let me know and I can show that too.

-- add your value to the tree, without highlighting
local subtree:add(f_value, myval)
-- and add the field for the bytes next, saving the returned child tree
local subtreeNext = subtree:add(f_whole, buffer:range(3,8))
-- add the children
subtreeNext:add(f_part1, buffer:range(3,2))
subtreeNext:add(f_part2, buffer:range(9,2))

Alternatively, you could do this instead, depending on what look you like:

-- add your value to the tree, highlighting all the bytes
local subtreeNext = subtree:add(f_value, buffer:range(3,8), myval)
-- add the children
subtreeNext:add(f_part1, buffer:range(3,2))
subtreeNext:add(f_part2, buffer:range(9,2))

answered 02 Apr '14, 13:47

Hadriel's gravatar image

Hadriel
2.7k2939
accept rate: 18%

edited 02 Apr '14, 13:48

Thanks Hadriel.
This helps, but I don't like the fact that when "The whole range" is selected, everything, including bytes that should be omitted are highlighted. Ideally I want the bytes at the two ends of the range which I actually use highlighted but the ones in the middle not highlighted. I guess that is impossible to do. Your code does help me build my tree though. Much appreciated.

(03 Apr '14, 09:07) YXI