mqtt: Add option to uncompress message when decoding
authorStig Bjørlykke <stig@bjorlykke.org>
Sat, 7 Apr 2018 20:35:35 +0000 (22:35 +0200)
committerStig Bjørlykke <stig@bjorlykke.org>
Sun, 8 Apr 2018 19:37:18 +0000 (19:37 +0000)
Add support for uncompressing message data before dissecting
based on topic.

Bug: 14591
Change-Id: Ibaead205a4df791d8e903935dfd29b9b8c13ddc5
Reviewed-on: https://code.wireshark.org/review/26794
Petri-Dish: Stig Bjørlykke <stig@bjorlykke.org>
Reviewed-by: Christopher Maynard <Christopher.Maynard@gtech.com>
Tested-by: Petri Dish Buildbot
epan/dissectors/packet-mqtt.c

index 5b19677533bf1e28ef672ebdd057e2476a9f7657..137cdb322b284ffedf84369e05e8e834b136b6a7 100644 (file)
@@ -176,6 +176,7 @@ typedef struct _mqtt_message_decode_t {
   guint   match_criteria;
   char   *topic_pattern;
   GRegex *topic_regex;
+  guint   msg_decoding;
   char   *payload_proto_name;
   dissector_handle_t payload_proto;
 } mqtt_message_decode_t;
@@ -195,6 +196,15 @@ static const value_string match_criteria[] = {
   { 0, NULL }
 };
 
+#define MSG_DECODING_NONE        0
+#define MSG_DECODING_COMPRESSED  1
+
+static const value_string msg_decoding[] = {
+  { MSG_DECODING_NONE,       "none" },
+  { MSG_DECODING_COMPRESSED, "compressed" },
+  { 0, NULL }
+};
+
 #define PROP_PAYLOAD_FORMAT_INDICATOR          0x01
 #define PROP_PUBLICATION_EXPIRY_INTERVAL       0x02
 #define PROP_CONTENT_TYPE                      0x03
@@ -589,7 +599,9 @@ static void *mqtt_message_decode_copy_cb(void *dest, const void *orig, size_t le
 
   d->match_criteria = o->match_criteria;
   d->topic_pattern = g_strdup(o->topic_pattern);
+  d->msg_decoding = o->msg_decoding;
   d->payload_proto_name = g_strdup(o->payload_proto_name);
+  d->payload_proto = o->payload_proto;
 
   return d;
 }
@@ -631,6 +643,7 @@ static void mqtt_message_decode_free_cb(void *record)
 
 UAT_VS_DEF(message_decode, match_criteria, mqtt_message_decode_t, guint, MATCH_CRITERIA_EQUAL, "Equal to")
 UAT_CSTRING_CB_DEF(message_decode, topic_pattern, mqtt_message_decode_t)
+UAT_VS_DEF(message_decode, msg_decoding, mqtt_message_decode_t, guint, MSG_DECODING_NONE, "none")
 UAT_PROTO_DEF(message_decode, payload_proto, payload_proto, payload_proto_name, mqtt_message_decode_t)
 
 static void mqtt_user_decode_message(proto_tree *tree, proto_tree *mqtt_tree, packet_info *pinfo, const guint8 *topic_str, tvbuff_t *msg_tvb)
@@ -684,11 +697,23 @@ static void mqtt_user_decode_message(proto_tree *tree, proto_tree *mqtt_tree, pa
 
   if (match_found)
   {
-    proto_item *ti = proto_tree_add_string(mqtt_tree, hf_mqtt_pubmsg_decoded, msg_tvb, 0, -1,
-                                           message_decode_entry->payload_proto_name);
-    PROTO_ITEM_SET_GENERATED(ti);
+    if (message_decode_entry->msg_decoding == MSG_DECODING_COMPRESSED)
+    {
+      msg_tvb = tvb_child_uncompress(msg_tvb, msg_tvb, 0, tvb_reported_length(msg_tvb));
+      if (msg_tvb)
+      {
+        add_new_data_source(pinfo, msg_tvb, "Uncompressed Message");
+      }
+    }
 
-    call_dissector(message_decode_entry->payload_proto, msg_tvb, pinfo, tree);
+    if (msg_tvb)
+    {
+      proto_item *ti = proto_tree_add_string(mqtt_tree, hf_mqtt_pubmsg_decoded, msg_tvb, 0, -1,
+                                             message_decode_entry->payload_proto_name);
+      PROTO_ITEM_SET_GENERATED(ti);
+
+      call_dissector(message_decode_entry->payload_proto, msg_tvb, pinfo, tree);
+    }
   }
 }
 
@@ -1565,6 +1590,7 @@ void proto_register_mqtt(void)
   static uat_field_t mqtt_message_decode_flds[] = {
     UAT_FLD_VS(message_decode, match_criteria, "Match criteria", match_criteria, "Match criteria"),
     UAT_FLD_CSTRING(message_decode, topic_pattern, "Topic pattern", "Pattern to match for the topic"),
+    UAT_FLD_VS(message_decode, msg_decoding, "Decoding", msg_decoding, "Decode message before dissecting as protocol"),
     UAT_FLD_PROTO(message_decode, payload_proto, "Payload protocol",
                   "Protocol to be used for the message part of the matching topic"),
     UAT_END_FIELDS