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

时间:2013-12-11 10:26:43

标签: lua network-programming network-protocols wireshark-dissector

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

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

  • 每个消息被分成大约1 kB的块,并用序列号和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)

1 个答案:

答案 0 :(得分:1)

我们假设您已经创建了第二个解剖器msgproto。由于您似乎没有在块和消息之间进行任何多路复用,因此您不需要设置解剖器表。相反,在myproto_proto.dissector结束时你做了

 msgproto.dissector:call(buffer(68, message_length-68-20):tvb, pinfo, tree)

这会将所有块数据传递给您的msgproto。在消息协议解析器中,您可以使用块协议的字段,当然还有仅包含一个块的数据的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字段。此代码将创建一个名为" message data"的新数据窗格。出现在常规" Frame"旁边Wireshark窗口底部的窗格。

我不确定Wireshark对你的超大缓冲区的喜爱程度。除此之外,我相信上面概述的方法是有效的。我没有按照这个确切的顺序使用所描述的技术,但我已经使用了所有描述的技术,例如,使用纯Lua中的数据填充新的字节窗格。

相关问题