this is my first time asking and I am new to Lua, so please correct me if I am doing something wrong
General Problem:
I want to write a Lua dissector for wireshark that only dissects one attribute of a given Zigbee Cluster Library frame (see screenshot).
Now I have got many problems and solutions for them that don't work.
Problem 1 - Adding the dissector (at the right spot?):
for testing purposes I added my dissector to the DissectorTable with the name "wpan.panid" for my given PANID with the value of "0x9dbd". This works, but only for the given PANID and way too "low level", because I want to only change one attribute in a deeper layer.
Question 1: So how do I get the dissector to always get called, no matter which PANID and how do I "anchor" (for lack of better wording) it only for my attribute "zbee_zcl.attr.id"
Problem 2 - Letting the "official" wireshark dissectors do its work and then just alter their result
My thought was, that I could call the wireshark dissectors "zbee_nwk", "zbee_aps" and "zbee_zcl" for the three layers and just alter the one attribute I want to dissect. But when I get the "zbee_nwk" dissector and call the call method on it with the exact same information that my dissector got, nothing happens and the tree just stays the same (see next screenshot).
alreadyCalled = false
networkDissector = Dissector.get("zbee_nwk")
applicationSupportDissector = Dissector.get("zbee_aps")
clusterLibraryDissector = Dissector.get("zbee_zcl")
local myProtoField = ProtoField.new("zbee_zcl.attr.id", "zzbee_zcl.attr.id", ftypes.UINT16)
function myFunction(treeViewBuffer, packetInfo, tree)
if(alreadyCalled == false) then
print(tostring(treeViewBuffer) .. " / " .. tostring(packetInfo) .. " / " .. tostring(tree))
print("Nr. of changed stuff: " .. networkDissector:call(treeViewBuffer, packetInfo, tree))
print(tostring(treeViewBuffer) .. " / " .. tostring(packetInfo) .. " / " .. tostring(tree))
alreadyCalled = true
end
end
myProtocol = Proto("MYZIGBEE", "myZigbee")
myProtocol.dissector = myFunction
DissectorTable.get("wpan.panid"):add(0x9dbd, myProtocol)
Questions 2:
TLDR: How would someone with knowledge and experience dissect the attribute and only the attribute shown in the first screenshot and let the "official" wireshark dissectors do the rest.
Example for dissection: Attribute: 0x0400 -> Attribute: Temperature (0x0400)
FROM ACCEPTED ANSWER: (By no means perfect. Loop could probably be made much more efficient)
function zbee_postDissector.dissector(tvbuf, pinfo, tree)
local attr_id_ex = {attr_id()}
i = 1
myValue = attr_id_ex[i]
if myValue == nil then
return
end
pinfo.cols.protocol:set("zbee_post")
local attr_id_tvbr = attr_id_ex.range
local zbee_post_tree = tree:add(zbee_postDissector, attr_id_tvbr)
while myValue ~= nil do
zbee_post_tree:add(pf.attr_id, myValue.range, myValue.value)
i = i + 1
myValue = attr_id_ex[i]
end
end
As far as I'm aware, it's not possible to modify an existing tree item. But what you can do is write a Lua postdissector that adds a new treeitem that is a modification of the existing tree item. For example:
local zbee_post = Proto("zbee_post", "zbee_post dissector") -- The table of attribute IDs you care about. local attr_id_vals = { [0x0001] = "Foo", [0x0004] = "Temperature" } local pf = { attr_id = ProtoField.uint16("zbee_post.attr.id", "Attribute", base.HEX, attr_id_vals) } zbee_post.fields = pf local attr_id = Field.new("zbee_zcl.attr.id") function zbee_post.dissector(tvbuf, pinfo, tree) local attr_id_ex = attr_id() if attr_id_ex == nil then return end pinfo.cols.protocol:set("zbee_post") local attr_id_tvbr = attr_id_ex.range local zbee_post_tree = tree:add(zbee_post, attr_id_tvbr) zbee_post_tree:add(pf.attr_id, attr_id_tvbr, attr_id_ex.value) end register_postdissector(zbee_post)