两个具有共享字段的 Wireshark Dissectors
Two Wireshark Dissectors with shared fields
我正在为自定义协议编写 wireshark 解析器。该协议有两个变体,在查看转储时通常无法区分它们。所以通常用户会简单地select解码正确的变体。
这两个变体共享相当多的 ProtoField
s 和很多结构,这就是为什么我希望只编写一次大部分的解剖代码,然后让两个顶级解剖器调用它们组件。
大致思路是:
local custom_var1 = Proto("custom_var1", "My custom protocol Variant 1")
local custom_var2 = Proto("custom_var2", "My custom protocol Variant 2")
-- my actual header and data blocks are a lot more complex than single integers of course
local header = ProtoField.uint8("custom.head", "Header")
local data1 = ProtoField.uint64("custom.data1", "Data 1")
local data2 = ProtoField.uint32("custom.data2", "Data 2")
local data3 = ProtoField.uint8("custom.data3", "Data 3")
custom_var1.fields = {header, data1, data2}
custom_var2.fields = {header, data1, data2, data3}
local function dissect_header(tvb, tree)
tree:add(header, tvb(0, 1))
end
local function dissect_data1(tvb, tree)
tree:add(data1, tvb(0, 8))
end
local function dissect_data2(tvb, tree)
tree:add(data2, tvb(0, 4))
end
local function dissect_data3(tvb, tree)
tree:add(data3, tvb(0, 1))
end
function custom_var1.dissector(tvb, pinfo, root)
pinfo.cols.protocol:set(custom_var1.name)
local tree = root:add(custom_var1, tvb(0, 13))
dissect_header(tvb(0), tree)
dissect_data1(tvb(1), tree)
dissect_data2(tvb(9), tree)
end
function custom_var2.dissector(tvb, pinfo, root)
pinfo.cols.protocol:set(custom_var2.name)
local tree = root:add(custom_var2, tvb(0, 14))
dissect_header(tvb(0), tree)
dissect_data2(tvb(1), tree)
dissect_data1(tvb(5), tree)
dissect_data3(tvb(13), tree)
end
tcp_port = DissectorTable.get("tcp.port")
tcp_port:add(31337, custom_var1)
tcp_port:add(31337, custom_var2)
我的问题:当我将 lua 文件放入我的插件目录并启动 wireshark 时,我看到 Wireshark Debug Console
(黑色背景而不是白色,带有 lua console) 消息 18:08:56.505 Err LUA PANIC: fields can be registered only once
后跟 Press any key to exit
,然后我才能做任何其他事情。按下一个键后,wireshark 立即存在。
如何编写两个具有共享字段的解析器,而不需要太多代码重复?
为什么不只写一个解析器并添加一个 preference 供用户选择要应用的变体?例如:
-- Protocol
local p_custom = Proto("custom", "My custom protocol")
local data_dis = Dissector.get("data")
-- Preferences
local default_settings = {
variant = 1
}
local variant_pref_enum = {
{ 1, "1", 1 },
{ 2, "2", 2 }
}
p_custom.prefs.variant = Pref.enum("Variant", default_settings.variant,
"The variant", variant_pref_enum)
-- Fields
local pf = {
header = ProtoField.bytes("custom.head", "Header"),
data1 = ProtoField.uint64("custom.data1", "Data 1"),
data2 = ProtoField.uint32("custom.data2", "Data 2"),
data3 = ProtoField.uint8("custom.data3", "Data 3")
}
p_custom.fields = pf
-- Dissection
function p_custom.dissector(tvbuf, pinfo, tree)
local custom_tree = tree:add(p_custom, tvbuf(0, -1))
custom_tree:add(pf.header, tvbuf(0, 1))
if p_custom.prefs.variant == 1 then
-- Dissect Variant 1
pinfo.cols.protocol:set("CUSTOM 1")
custom_tree:append_text(": Variant 1")
custom_tree:add(pf.data1, tvbuf(1, 8))
custom_tree:add(pf.data2, tvbuf(9, 4))
elseif p_custom.prefs.variant == 2 then
-- Dissect Variant 2
pinfo.cols.protocol:set("CUSTOM 2")
custom_tree:append_text(": Variant 2")
custom_tree:add(pf.data2, tvbuf(1, 4))
custom_tree:add(pf.data1, tvbuf(5, 8))
custom_tree:add(pf.data3, tvbuf(13, 1))
else
-- Unknown Variant
pinfo.cols.protocol:set("CUSTOM ?")
custom_tree:append_text(": Unknown Variant")
data_dis:call(tvbuf:range(1, tvbuf:len() - 1):tvb(), pinfo, tree)
end
end
-- Registration
local tcp_port = DissectorTable.get("tcp.port")
tcp_port:add(31337, p_custom)
当然,如果公共 header 中有可用信息可以帮助确定自动应用哪个变体,则根本不需要首选项。
我正在为自定义协议编写 wireshark 解析器。该协议有两个变体,在查看转储时通常无法区分它们。所以通常用户会简单地select解码正确的变体。
这两个变体共享相当多的 ProtoField
s 和很多结构,这就是为什么我希望只编写一次大部分的解剖代码,然后让两个顶级解剖器调用它们组件。
大致思路是:
local custom_var1 = Proto("custom_var1", "My custom protocol Variant 1")
local custom_var2 = Proto("custom_var2", "My custom protocol Variant 2")
-- my actual header and data blocks are a lot more complex than single integers of course
local header = ProtoField.uint8("custom.head", "Header")
local data1 = ProtoField.uint64("custom.data1", "Data 1")
local data2 = ProtoField.uint32("custom.data2", "Data 2")
local data3 = ProtoField.uint8("custom.data3", "Data 3")
custom_var1.fields = {header, data1, data2}
custom_var2.fields = {header, data1, data2, data3}
local function dissect_header(tvb, tree)
tree:add(header, tvb(0, 1))
end
local function dissect_data1(tvb, tree)
tree:add(data1, tvb(0, 8))
end
local function dissect_data2(tvb, tree)
tree:add(data2, tvb(0, 4))
end
local function dissect_data3(tvb, tree)
tree:add(data3, tvb(0, 1))
end
function custom_var1.dissector(tvb, pinfo, root)
pinfo.cols.protocol:set(custom_var1.name)
local tree = root:add(custom_var1, tvb(0, 13))
dissect_header(tvb(0), tree)
dissect_data1(tvb(1), tree)
dissect_data2(tvb(9), tree)
end
function custom_var2.dissector(tvb, pinfo, root)
pinfo.cols.protocol:set(custom_var2.name)
local tree = root:add(custom_var2, tvb(0, 14))
dissect_header(tvb(0), tree)
dissect_data2(tvb(1), tree)
dissect_data1(tvb(5), tree)
dissect_data3(tvb(13), tree)
end
tcp_port = DissectorTable.get("tcp.port")
tcp_port:add(31337, custom_var1)
tcp_port:add(31337, custom_var2)
我的问题:当我将 lua 文件放入我的插件目录并启动 wireshark 时,我看到 Wireshark Debug Console
(黑色背景而不是白色,带有 lua console) 消息 18:08:56.505 Err LUA PANIC: fields can be registered only once
后跟 Press any key to exit
,然后我才能做任何其他事情。按下一个键后,wireshark 立即存在。
如何编写两个具有共享字段的解析器,而不需要太多代码重复?
为什么不只写一个解析器并添加一个 preference 供用户选择要应用的变体?例如:
-- Protocol
local p_custom = Proto("custom", "My custom protocol")
local data_dis = Dissector.get("data")
-- Preferences
local default_settings = {
variant = 1
}
local variant_pref_enum = {
{ 1, "1", 1 },
{ 2, "2", 2 }
}
p_custom.prefs.variant = Pref.enum("Variant", default_settings.variant,
"The variant", variant_pref_enum)
-- Fields
local pf = {
header = ProtoField.bytes("custom.head", "Header"),
data1 = ProtoField.uint64("custom.data1", "Data 1"),
data2 = ProtoField.uint32("custom.data2", "Data 2"),
data3 = ProtoField.uint8("custom.data3", "Data 3")
}
p_custom.fields = pf
-- Dissection
function p_custom.dissector(tvbuf, pinfo, tree)
local custom_tree = tree:add(p_custom, tvbuf(0, -1))
custom_tree:add(pf.header, tvbuf(0, 1))
if p_custom.prefs.variant == 1 then
-- Dissect Variant 1
pinfo.cols.protocol:set("CUSTOM 1")
custom_tree:append_text(": Variant 1")
custom_tree:add(pf.data1, tvbuf(1, 8))
custom_tree:add(pf.data2, tvbuf(9, 4))
elseif p_custom.prefs.variant == 2 then
-- Dissect Variant 2
pinfo.cols.protocol:set("CUSTOM 2")
custom_tree:append_text(": Variant 2")
custom_tree:add(pf.data2, tvbuf(1, 4))
custom_tree:add(pf.data1, tvbuf(5, 8))
custom_tree:add(pf.data3, tvbuf(13, 1))
else
-- Unknown Variant
pinfo.cols.protocol:set("CUSTOM ?")
custom_tree:append_text(": Unknown Variant")
data_dis:call(tvbuf:range(1, tvbuf:len() - 1):tvb(), pinfo, tree)
end
end
-- Registration
local tcp_port = DissectorTable.get("tcp.port")
tcp_port:add(31337, p_custom)
当然,如果公共 header 中有可用信息可以帮助确定自动应用哪个变体,则根本不需要首选项。