From a8a54197fa14aa65846edd4ffc186d811dd7f583 Mon Sep 17 00:00:00 2001 From: Maarten de Vries Date: Mon, 24 Jan 2022 13:21:29 +0100 Subject: [PATCH] Add wireshark dissector for TCP and UDP transports. --- CHANGELOG | 1 + wireshark/README.md | 10 +++++ wireshark/fizyr-rpc.lua | 94 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 wireshark/README.md create mode 100644 wireshark/fizyr-rpc.lua diff --git a/CHANGELOG b/CHANGELOG index a777ec2..450d611 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,7 @@ - [fix][minor] Remove the `Sized` restriction for the `EncodeBody` trait. - [impl][patch] Use `poll_write_vectored` in the TCP transport to write the header and body with a single syscall. - [rename][major] Rename `crate::util::format` module to `crate::format`. +- [add][patch] Add Wireshark dissector for TCP and UDP transports for easier debugging. # Version 0.5.0-alpha7 - 2022-01-10 - [add][minor] Add a specific `Format` trait for generated interaces to avoid writing overly long trait bounds. diff --git a/wireshark/README.md b/wireshark/README.md new file mode 100644 index 0000000..f2d85dd --- /dev/null +++ b/wireshark/README.md @@ -0,0 +1,10 @@ +# Wireshark dissector + +This folder contains a Wireshark dissector for the Fizyr RPC protocol. +Copy the `fizyr-rpc.lua` file to your Wireshark plugin directory to install it. +See [the Wireshark manual][wireshark-plugin-folder] for more information on the plugin folder. + +Afterwards, either restart Wireshark or select the "Reload LUA plugins" option from the "Analyze" menu. +You should now be able to activate the dissector from "Decode As ..." dialog from the "Analyze" menu. + +[wireshark-plugin-folder]: https://www.wireshark.org/docs/wsug_html_chunked/ChPluginFolders.html diff --git a/wireshark/fizyr-rpc.lua b/wireshark/fizyr-rpc.lua new file mode 100644 index 0000000..d1d101b --- /dev/null +++ b/wireshark/fizyr-rpc.lua @@ -0,0 +1,94 @@ +do + local fizyr_rpc_tcp_proto = Proto("fizyr_rpc_tcp", "Fizyr RPC over TCP"); + local fizyr_rpc_udp_proto = Proto("fizyr_rpc_udp", "Fizyr RPC over UDP"); + + local udp_length = Field.new("udp.length"); + + local field_length = ProtoField.uint32( + "fizyr_rpc.message_length", + "Message length", + base.DEC, + nil, + nil, + "The length of the message, excluding the message length itself." + ) + + local field_kind = ProtoField.uint32( + "fizyr_rpc.message_type", + "Message type", + base.DEC, + { + [0] = "Request", + [1] = "Response", + [2] = "RequestUpdate", + [3] = "ResponseUpdate", + [4] = "Stream", + }, + nil, + "The type of the RPC message: Request, Response, RequestUpdate, ResponseUpdate or Stream." + ) + + local field_request_id = ProtoField.uint32( + "fizyr_rpc.request_id", + "Request ID", + base.DEC, + nil, + nil, + "The request ID of the message. Not used for stream messages." + ) + + local field_service_id = ProtoField.int32( + "fizyr_rpc.service_id", + "Service ID", + base.DEC, + nil, + nil, + "The service ID of the message." + ) + + local field_body = ProtoField.bytes( + "fizyr_rpc.body", + "Message body", + base.SPACE, + "The message body/payload." + ) + + fizyr_rpc_tcp_proto.fields = { + field_length, + field_kind, + field_request_id, + field_service_id, + field_body, + } + + function fizyr_rpc_tcp_proto.dissector(buffer, pinfo, tree) + dissect_tcp_pdus(buffer, tree, 4, fizyr_rpc_tcp_get_length, fizyr_rpc_tcp_dissect_reassembled) + end + + function fizyr_rpc_tcp_get_length(buffer, pinfo, offset) + return 4 + buffer(0, 4):le_uint() + end + + function fizyr_rpc_tcp_dissect_reassembled(buffer, pinfo, tree) + local subtree = tree:add(fizyr_rpc_tcp_proto, buffer) + subtree:add_le(field_length, buffer(0, 4)) + subtree:add_le(field_kind, buffer(4, 4)) + subtree:add_le(field_request_id, buffer(8, 4)) + subtree:add_le(field_service_id, buffer(12, 4)) + subtree:add_le(field_body, buffer(16)) + end + + function fizyr_rpc_udp_proto.dissector(buffer, pinfo, tree) + subtree:add_le(field_length, udp_length()) + subtree:add_le(field_kind, buffer(0, 4)) + subtree:add_le(field_request_id, buffer(4, 4)) + subtree:add_le(field_service_id, buffer(8, 4)) + subtree:add_le(field_body, buffer(12)) + end + + local tcp_table = DissectorTable.get("tcp.port") + tcp_table:add("1-65535", fizyr_rpc_tcp_proto) + + local udp_table = DissectorTable.get("udp.port") + udp_table:add("1-65535", fizyr_rpc_udp_proto) +end