wireshark如何写一个lua脚本解析自定义报文字段?(Proto、DissectorTable.get、function .dissector、dissector_table:add)

步骤

  • 定义私有protocol:local myprotocol = Proto("my proto", "My proto"),需要Proto的类来定义
  • 获取DissectorTable:local dissector_table = DissectorTable.get("udp.port") 获取解析表,并且用udp.port去获取
  • 定义解析函数 function myprotocol.dissector(buffer, pinfo, tree), 这里的myprotocol是定义的协议的类实体,然后实现它的成员函数dissector,以便解析。 这里还包括定义myprotocol的fields字段,方便function中将fields加入到tree中
  • 最后将udp的端口和私有proto加入到dissector_table中。dissector_table:add(udpport, myprotocol)

实操效果


```c
local p_multi = Proto("multi", "MultiProto");

local vs_protos = {
        [2] = "mtp2",
        [3] = "mtp3",
        [4] = "alcap",
        [5] = "h248",
        [6] = "ranap",
        [7] = "rnsap",
        [8] = "nbap"
}

local f_proto = ProtoField.uint8("multi.protocol", "Protocol", base.DEC, vs_protos)
local f_dir = ProtoField.uint8("multi.direction", "Direction", base.DEC, { [1] = "incoming", [0] = "outgoing"})
local f_text = ProtoField.string("multi.text", "Text")

p_multi.fields = { f_proto, f_dir, f_text }

local data_dis = Dissector.get("data")

local protos = {
        [2] = Dissector.get("mtp2"),
        [3] = Dissector.get("mtp3"),
        [4] = Dissector.get("alcap"),
        [5] = Dissector.get("h248"),
        [6] = Dissector.get("ranap"),
        [7] = Dissector.get("rnsap"),
        [8] = Dissector.get("nbap"),
        [9] = Dissector.get("rrc"),
        [10] = DissectorTable.get("sctp.ppi"):get_dissector(3), -- m3ua
        [11] = DissectorTable.get("ip.proto"):get_dissector(132), -- sctp
}

function p_multi.dissector(buf, pkt, tree)

        local subtree = tree:add(p_multi, buf(0,2))
        subtree:add(f_proto, buf(0,1))
        subtree:add(f_dir, buf(1,1))

        local proto_id = buf(0,1):uint()

        local dissector = protos[proto_id]

        if dissector ~= nil then
                -- Dissector was found, invoke subdissector with a new Tvb,
                -- created from the current buffer (skipping first two bytes).
                dissector:call(buf(2):tvb(), pkt, tree)
        elseif proto_id < 2 then
                subtree:add(f_text, buf(2))
                -- pkt.cols.info:set(buf(2, buf:len() - 3):string())
        else
                -- fallback dissector that just shows the raw data.
                data_dis:call(buf(2):tvb(), pkt, tree)
        end

end

local wtap_encap_table = DissectorTable.get("wtap_encap")
local udp_encap_table = DissectorTable.get("udp.port")

wtap_encap_table:add(wtap.USER15, p_multi)
wtap_encap_table:add(wtap.USER12, p_multi)
udp_encap_table:add(7555, p_multi)```

其他

  • 需要3种主体:
    • Proto定义私有协议(类似IP),然后定义Proto的field和dissector解析函数(入参固定)
    • DissectorTable类,能够从解析树中获取某个tree的node,然后使用这个node的add,将协议添加到table中
    • tree,作为dissector入参传入,后面add会作为subtree添加到tree上
  • 关键3点:1. Proto定义协议;2. 定义Proto的dissector函数; 3. DissectorTable 4. 将Proto挂到DissectorTable是哪个
  • 最核心:定义Protocol,然后dissector解析函数,函数挂到tree中,父tree从DisectorTable上

参考:
https://www.wireshark.org/docs/wsdg_html_chunked/wslua_dissector_example.html

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值