在lua wireshark解剖仪中重新组装PDU
在一个系统中,我有一个自定义协议,我想实现一个Wireshark解析器,这样我就可以使用Wireshark分析通信在lua wireshark解剖仪中重新组装PDU,lua,network-programming,network-protocols,wireshark-dissector,Lua,Network Programming,Network Protocols,Wireshark Dissector,在一个系统中,我有一个自定义协议,我想实现一个Wireshark解析器,这样我就可以使用Wireshark分析通信 对象通过协议发送,我们称之为“消息”。每条消息可以很大,可能高达100MB,也可以很小,例如50字节 每条消息被分成大约1KB的块,并用序列号和guid消息id进行标记,这些可以在另一端用于重新组装消息 到目前为止,我已经成功地制作了一个剖析器,它可以将所有区块单独记录到Wireshark,但我想进一步,并在Wireshark中记录所有消息(组装成消息的区块)。这能做到吗?如何
- 对象通过协议发送,我们称之为“消息”。每条消息可以很大,可能高达100MB,也可以很小,例如50字节
- 每条消息被分成大约1KB的块,并用序列号和guid消息id进行标记,这些可以在另一端用于重新组装消息
myproto_proto = Proto("myproto", "My Protocol")
function myproto_proto.dissector(buffer, pinfo, tree)
pinfo.cols.protocol = "myproto"
local message_length = buffer(0, 4):le_uint()+4
if message_length>pinfo.len then
pinfo.desegment_len = message_length
pinfo.desegment_offset = 0
return;
end
local subtree = tree:add(myproto_proto, buffer(), "My Protocol Data")
local packet = subtree:add(buffer(0, message_length), "Chunk")
packet:add(buffer(0, 4), "Packet length: " .. buffer(0, 4):le_uint())
packet:add(buffer(32, 16), "Message ID")
packet:add(buffer(48, 4), "Block ID: " .. buffer(48, 4):le_uint())
packet:add(buffer(52, 4), "Max Block ID: " .. buffer(52, 4):le_uint())
packet:add(buffer(68, message_length-68-20), "Data")
pinfo.desegment_len = 0
pinfo.desegment_offset = message_length
return
end
tcp_table = DissectorTable.get("tcp.port")
tcp_table:add(1234, myproto_proto)
假设您已经创建了第二个解析器
msgproto
。因为在块和消息之间似乎没有任何多路复用,所以不需要设置解析器表。相反,在myproto_proto.dissector的末尾,您需要执行一个
msgproto.dissector:call(buffer(68, message_length-68-20):tvb, pinfo, tree)
这将把所有区块数据传递给msgproto
。在消息协议解析器中,您可以使用区块协议的字段,当然还有tvb,它只包含一个区块的数据。你现在需要把这些碎片拼凑成一个巨大无比的tvb。使msgproto
具有以下状态:
local stateMap = {}
function msgproto.init()
stateMap = {}
end
将tvb中的数组转换为ByteArray,并将其他调用中的数组存储到stateMap
。当您将所有数据组合到一个数组中时,我们将其称为oarr
,用它制作一个tvb:
local otvb = ByteArray.tvb(oarr, "message data")
-- starting from 0, need to pass a tvb range, not a tvb.
stree:add(msgproto.fields.payload, otvb(0))
假设您有payload
字段类型Protofield.bytes
。此代码将在Wireshark窗口底部的常规“框架”窗格旁边显示一个名为“消息数据”的新数据窗格
我不确定Wireshark是否会喜欢你的超大缓冲区。除此之外,我非常相信上述方法会奏效。我没有按照这种确切的顺序使用所描述的技术,但我使用了所有所描述的技术,例如,制作一个新的字节窗格,其中填充了纯Lua压缩的数据。假设您已经创建了第二个解析器
msgproto
。因为在块和消息之间似乎没有任何多路复用,所以不需要设置解析器表。相反,在myproto_proto.dissector的末尾,您需要执行一个
msgproto.dissector:call(buffer(68, message_length-68-20):tvb, pinfo, tree)
这将把所有区块数据传递给msgproto
。在消息协议解析器中,您可以使用区块协议的字段,当然还有tvb,它只包含一个区块的数据。你现在需要把这些碎片拼凑成一个巨大无比的tvb。使msgproto
具有以下状态:
local stateMap = {}
function msgproto.init()
stateMap = {}
end
将tvb中的数组转换为ByteArray,并将其他调用中的数组存储到stateMap
。当您将所有数据组合到一个数组中时,我们将其称为oarr
,用它制作一个tvb:
local otvb = ByteArray.tvb(oarr, "message data")
-- starting from 0, need to pass a tvb range, not a tvb.
stree:add(msgproto.fields.payload, otvb(0))
假设您有payload
字段类型Protofield.bytes
。此代码将在Wireshark窗口底部的常规“框架”窗格旁边显示一个名为“消息数据”的新数据窗格
我不确定Wireshark是否会喜欢你的超大缓冲区。除此之外,我非常相信上述方法会奏效。我没有按照这种确切的顺序使用所描述的技术,但我使用了所有所描述的技术,例如,制作一个新的字节窗格,其中填充了纯Lua中压缩的数据。不幸的是,上次我检查时(几年前),无法在Lua中制作“链式剖析器”。您可以使用C API来实现这一点,因为C API非常难使用,但确实提供了这样的额外功能。请注意,如果可以使用C API来实现这一点,则可以从Lua脚本连接到该功能中,尽管这将不是一个纯粹的链接,而是一个“剖析器扩展”?@JohnZwinck有趣,在谷歌搜索链式解剖器后,我发现了以下内容:。你认为这能帮我解决问题吗?@www.jensolsson.se:我不能肯定,但我也看到了那个页面,无法让我的用例工作。我所能说的就是好运,如果你真的必须这么做,考虑使用C。不幸的是,我最后一次检查(几年前),在Lua做“链式扇区”是不可能的。您可以使用C API来实现这一点,因为C API非常难使用,但确实提供了这样的额外功能。请注意,如果可以使用C API来实现这一点,则可以从Lua脚本连接到该功能中,尽管这将不是一个纯粹的链接,而是一个“剖析器扩展”?@JohnZwinck有趣,在谷歌搜索链式解剖器后,我发现了以下内容:。你认为这能帮我解决问题吗?@www.jensolsson.se:我不能肯定,但我也看到了那个页面,无法让我的用例工作。我所能说的就是好运,如果你真的必须这么做,考虑使用C。