2 local protobuf_dissector
= Dissector
.get("protobuf")
4 -- Create protobuf dissector based on UDP or TCP.
5 -- The UDP dissector will take the whole tvb as a message.
6 -- The TCP dissector will parse tvb as format:
7 -- [4bytes length][a message][4bytes length][a message]...
8 -- @param name The name of the new dissector.
9 -- @param desc The description of the new dissector.
10 -- @param for_udp Register the new dissector to UDP table.(Enable 'Decode as')
11 -- @param for_tcp Register the new dissector to TCP table.(Enable 'Decode as')
12 -- @param msgtype Message type. This must be the root message defined in your .proto file.
13 local function create_protobuf_dissector(name
, desc
, for_udp
, for_tcp
, msgtype
)
14 local proto
= Proto(name
, desc
)
15 local f_length
= ProtoField
.uint32(name
.. ".length", "Length", base
.DEC
)
16 proto
.fields
= { f_length
}
18 proto
.dissector
= function(tvb
, pinfo
, tree
)
19 local subtree
= tree
:add(proto
, tvb())
20 if for_udp
and pinfo
.port_type
== 3 then -- UDP
21 if msgtype
~= nil then
22 pinfo
.private
["pb_msg_type"] = "message," .. msgtype
24 pcall(Dissector
.call, protobuf_dissector
, tvb
, pinfo
, subtree
)
25 elseif for_tcp
and pinfo
.port_type
== 2 then -- TCP
27 local remaining_len
= tvb
:len()
28 while remaining_len
> 0 do
29 if remaining_len
< 4 then -- head not enough
30 pinfo
.desegment_offset
= offset
31 pinfo
.desegment_len
= DESEGMENT_ONE_MORE_SEGMENT
35 local data_len
= tvb(offset
, 4):uint()
37 if remaining_len
- 4 < data_len
then -- data not enough
38 pinfo
.desegment_offset
= offset
39 pinfo
.desegment_len
= data_len
- (remaining_len
- 4)
42 subtree
:add(f_length
, tvb(offset
, 4))
44 if msgtype
~= nil then
45 pinfo
.private
["pb_msg_type"] = "message," .. msgtype
47 pcall(Dissector
.call, protobuf_dissector
,
48 tvb(offset
+ 4, data_len
):tvb(), pinfo
, subtree
)
50 offset
= offset
+ 4 + data_len
51 remaining_len
= remaining_len
- 4 - data_len
54 pinfo
.columns
.protocol
:set(name
)
57 if for_udp
then DissectorTable
.get("udp.port"):add(0, proto
) end
58 if for_tcp
then DissectorTable
.get("tcp.port"):add(0, proto
) end
62 -- default pure protobuf udp and tcp dissector without message type
63 create_protobuf_dissector("protobuf_udp", "Protobuf UDP")
64 create_protobuf_dissector("protobuf_tcp", "Protobuf TCP")
65 -- add more protobuf dissectors with message types
66 create_protobuf_dissector("AddrBook", "Tutorial AddressBook",
67 true, true, "tutorial.AddressBook")