步骤
- 定义私有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