You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Wireshark Lua解析器中仅解析Zigbee Cluster Library帧的单个属性

问题:为Wireshark编写Lua解析器修改Zigbee属性显示

这是我第一次提问,我是Lua新手,若有错误请指正。

通用需求

想要为Wireshark编写一个Lua解析器,仅解析Zigbee Cluster Library帧中的指定属性(如将Attribute: 0x0400显示为Attribute: Temperature (0x0400)),同时让官方解析器处理其余内容。

遇到的问题

问题1:解析器的正确挂载方式

测试时将解析器添加到wpan.panid解析器表,指定PANID为0x9dbd时能生效,但仅适用于该特定PANID,且挂载层级过低,只想针对zbee_zcl.attr.id这个属性做修改。

  • 疑问:如何让解析器不受PANID限制被调用?如何仅锚定到zbee_zcl.attr.id属性?

问题2:调用官方解析器无效果

尝试先调用官方的zbee_nwk、zbee_aps、zbee_zcl解析器,再修改目标属性,但调用后解析树无变化。
测试代码:

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)
  • 疑问:为什么调用官方解析器后解析树没变化?是不是调用方式错误?会不会是载荷加密(已在Wireshark中添加密钥)导致的?

TLDR

有经验的开发者会如何实现:让官方解析器处理大部分内容,仅修改指定Zigbee属性的显示?


解决方案

针对你的需求,最适合的方式是使用后解析器(Post-dissector),它能在官方解析器完成解析后,对已生成的解析树进行修改或补充,完美匹配你“只改指定属性,其余交给官方”的需求。

优化后的实现代码

-- 定义后解析器
local zbee_postDissector = Proto("zbee_post", "Zigbee Attribute Display Enhancement")

-- 定义要替换显示的属性映射(可根据需求扩展)
local attr_map = {
    [0x0400] = "Temperature",
    -- 可添加更多属性,比如 [0x0401] = "Humidity"
}

-- 注册后解析器
register_postdissector(zbee_postDissector)

-- 后解析器逻辑
function zbee_postDissector.dissector(tvbuf, pinfo, tree)
    -- 遍历所有已解析的zbee_zcl.attr.id节点
    local attr_ids = {attr_id()}
    for _, attr in ipairs(attr_ids) do
        if attr and attr.value then
            -- 获取属性ID对应的名称
            local attr_name = attr_map[attr.value]
            if attr_name then
                -- 修改原节点的显示文本
                attr:set_text(string.format("%s (0x%04X)", attr_name, attr.value))
            end
        end
    end
    return true
end

关键说明

  1. 后解析器的优势:无需挂载到特定解析器表,会自动在所有官方解析器执行后运行,不受PANID限制,直接针对已解析的zbee_zcl.attr.id节点操作。
  2. 原代码问题分析:
    • 你之前挂载到wpan.panid的方式属于替换式解析器,会覆盖官方解析逻辑,且仅针对特定PANID生效。
    • 直接调用官方解析器无效果,是因为wpan.panid对应的缓冲区是整个WPAN帧,而zbee_nwk需要的是NWK层的子缓冲区,直接传入整个帧缓冲区会导致解析失败。
  3. 加密问题排查:如果已在Wireshark中添加正确的解密密钥,官方解析器能正常解析出zbee_zcl.attr.id,后解析器就能正常工作;如果解析树中看不到该属性,先确认解密是否成功。

内容的提问来源于stack exchange,提问作者Ducksenz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 22:40:24