Wireshark Lua插件如何基于前置字段值动态设置ProtoField的valuestring
Wireshark Lua 插件动态ProtoField valuestring 实现方案
核心逻辑:不要为子字段绑定静态全局valuestring,该属性是协议全局共享的,动态修改会导致不同报文解析结果互相污染。正确做法是在dissector解析阶段,先获取前置父字段的实际值,动态生成对应子字段的映射表,再控制子字段的显示格式即可,两种稳定实现方式如下:
方式1:动态传入valuestring(推荐)
Wireshark的TreeItem:add()方法支持传入自定义valuestring覆盖ProtoField定义的静态值,会自动按照官方规范格式字段名: 映射值 (原始值)渲染,不需要手动处理文本拼接:
-- 协议定义阶段,子字段不绑定静态valuestring local myProto = Proto("myProto", "My Custom Protocol") local parent_type = ProtoField.uint8("myProto.myParentField", "Parent", base.HEX, {[0x10] = "1", [0x20] = "2"}, 0xf0, "") -- 第五个参数valuestring留空,后续动态传入 local child_type = ProtoField.uint8("myProto.myChildField", "Child", base.HEX, nil, 0x0f, "") myProto.fields = {parent_type, child_type} function myProto.dissector(buffer, pinfo, tree) local subtree = tree:add(myProto, buffer(), "My Protocol Data") -- 1. 先解析父字段,拿到实际取值 local parent_val = buffer(0,1):uint() & 0xf0 subtree:add(parent_type, buffer(0,1)) -- 2. 根据父字段值生成对应子字段的动态valuestring local child_valstr if parent_val == 0x10 then -- 父字段值为1的场景 child_valstr = { [0x01] = "3", [0x02] = "4" } else -- 父字段值为2的场景 child_valstr = { [0x01] = "5", [0x02] = "6" } end -- 3. 添加子字段时替换显示内容,自动适配前缀格式 local child_raw = buffer(0,1):uint() & 0x0f local child_item = subtree:add(child_type, buffer(0,1)) child_item:set_text(child_item:get_text():gsub("%(0x%x+)$", string.format("%s (0x%02x)", child_valstr[child_raw], child_raw))) end
方式2:通用文本替换方案(适合复杂自定义格式)
如果需要更灵活的显示逻辑,可以先获取字段默认生成的完整文本(包含位掩码前缀、字段名),做字符串替换后再设置回去,避免手动拼接位掩码前缀出错:
-- 接上面dissector中的逻辑 local child_item = subtree:add(child_type, buffer(0,1)) local child_raw = buffer(0,1):uint() & 0x0f local child_show_val = child_valstr[child_raw] -- 提取默认文本,替换值部分为自定义格式 local default_text = child_item:get_text() local new_text = default_text:gsub("Child: %((0x%x+)%)", string.format("Child: %s (%s)", child_show_val, "%1")) child_item:set_text(new_text)
问题原因说明
之前用append_text出现顺序颠倒,是因为Wireshark默认渲染无valuestring的字段时,会先输出Child: (0x01),后续append的内容会追加在末尾,所以出现(0x01) 3的颠倒格式。直接调用set_text只传值的话会覆盖掉默认生成的位掩码前缀和字段名,因此需要保留原有前缀再替换值的部分。
内容的提问来源于stack exchange,提问作者Anirudh Chari
相关产品推荐
相关产品推荐

