Protobuf dissector with nested structures
We have our own protocol for communication between devices. It is based on protobuf structures over websocket.
PacketMessage.proto :
syntax = "proto3"; package pb_pm;
enum BodyType { BodyType_UNSPECIFIED = 0; RESPONSE = 1; HANDSHAKE = 2; V2X = 3; RTK = 4; SYSTEM = 5; }
enum BodyCompressType { BodyCompressType_UNSPECIFIED = 0; NONE = 1; LZMA = 2; }
message PacketMessage {
optional uint32 messageId = 1; /** [0 - 2^32] */
reserved 2;
BodyCompressType bodyCompressType = 3;
BodyType bodyType = 4;
bytes body = 5;
}
handshake.proto :
syntax = "proto3";
package pb_hs;
message Handshake { fixed32 protocolVersion = 1; string hostname = 2; string mac = 3; }
v2x.proto:
syntax = "proto3";
package pb_v2x;
import "V2X/Facility/Facility.proto";
import "V2X/Fluent/Fluent.proto";
message V2X { reserved 1 to 2, 5; oneof v2x { fac.Facility facility = 3; fl.Fluent fluent = 4; } }
I wrote some lua dissectors, and it works fine for one type of body field:
do local protobuf_dissector = Dissector.get("protobuf") local proto = Proto("tedix", "TEDIX Protocol") proto.dissector = function(tvb, pinfo, tree) local subtree = tree:add(proto, tvb()) if "pb_pm.PacketMessage" ~= nil then pinfo.private["pb_msg_type"] = "message," .. "pb_pm.PacketMessage" end pcall(Dissector.call, protobuf_dissector, tvb, pinfo, subtree) end local ws_dissector_table = DissectorTable.get("ws.port") ws_dissector_table:add(7246, proto) end
do local protobuf_field_table = DissectorTable.get("protobuf_field") local message_type_dissector = Dissector.get("protobuf") proto_messge_type_V2X = Proto("message_type_dissector", "V2X") proto_messge_type_V2X.dissector = function(tvb, pinfo, subtree) pinfo.cols.protocol = proto_messge_type_V2X.name local subsubtree = subtree:add(proto_messge_type_V2X, tvb()) if "pb_v2x.V2X" ~= nil then pinfo.private["pb_msg_type"] = "message," .. "pb_v2x.V2X" end pcall(Dissector.call, message_type_dissector, tvb, pinfo, subsubtree) end protobuf_field_table:add("pb_pm.PacketMessage.body", proto_messge_type_V2X) end
The protocol consists of several nested proto structures. Moreover, it is implied that, depending on the BodyType field, there will be different filling of the body field. for example, there may be a message like V2X or Handshake.
How can I write a dissector for such a protocol?
How to get the value of the BodyType field inside the Lua dissector to call different dissectors of the body field?
Do you have a sample pcap (and .proto file) you could share?
Hello, @Chuckc. Yes. Here. In archive there are pcap file with packages with bodyType = HANDSHAKE , and bodyType=V2X . Proto structures, screenshots, and some Lua dissectors.
What version of Wireshark are you using? The sample capture included in the archive opens as websocket?
Wireshark Version 4.0.5 (v4.0.5-0-ge556162d8da3).
I tried to open it, and I see that wireshark recognized the packets only as tcp. Although when I saved these packages, they looked like a websocket.
I noticed this problem earlier. In order for wireshark to recognize packets as websocket, it is necessary that it be launched in real time , before the client starts communicating with the server. It transmits http Switching Protocols packet with Upgrade connection. And then wireshark recognise packets as websocket packets.
Wireshark cannot correctly process this packet in the saved pcap file.
Sorry for the delay - I missed your update.
It does not open in 4.0.6 but tested today with a dev build (Version 4.1.0rc0-3005-g44a3271adb89) and dissection works.