在lua wireshark解剖仪中重新组装PDU

在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中记录所有消息(组装成消息的区块)。这能做到吗?如何

在一个系统中,我有一个自定义协议,我想实现一个Wireshark解析器,这样我就可以使用Wireshark分析通信

  • 对象通过协议发送,我们称之为“消息”。每条消息可以很大,可能高达100MB,也可以很小,例如50字节

  • 每条消息被分成大约1KB的块,并用序列号和guid消息id进行标记,这些可以在另一端用于重新组装消息

到目前为止,我已经成功地制作了一个剖析器,它可以将所有区块单独记录到Wireshark,但我想进一步,并在Wireshark中记录所有消息(组装成消息的区块)。这能做到吗?如何做到?是否有可能在我下面开发的解析器之上实现一个解析器

若有可能在下面的解析器之上实现一个解析器,我如何确保它只分析myproto PDU?下面的解析器在特定的tcp端口上触发,但这对于第二阶段解析器不起作用

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。