aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-tftp.c
diff options
context:
space:
mode:
authorMoshe Kaplan <me@moshekaplan.com>2016-11-24 09:37:01 -0500
committerMichael Mann <mmann78@netscape.net>2016-12-02 16:07:35 +0000
commit20c57cb298e4f3b7ac66a22fb7477e4cf424a11b (patch)
tree3929a45a2f0df5182af007af697edfa9a55a4634 /epan/dissectors/packet-tftp.c
parent9ca313cfbe4993a0a36520d216a3e4282b0b7b99 (diff)
Enable exporting objects with tshark
A new "--export-object <protocol>,<destdir>" option is added to tshark. This required refactoring Export Object behavior in all GUIs to give the export object handling to the dissector, rather than the ui layer. Included in the refactoring was fixing some serious memory leaks in Qt Export Object dialog, crash due to memory scope issues in GTK Export Object dialog, and addition sorting column feature in Qt dialog (set up by creating a widget to manage the items that were previously leaking memory) Bug: 9319 Ping-Bug: 13174 Change-Id: I515d7662fa1f150f672b1476716f347ec27deb9b Reviewed-on: https://code.wireshark.org/review/18927 Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Peter Wu <peter@lekensteyn.nl> Tested-by: Michael Mann <mmann78@netscape.net> Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan/dissectors/packet-tftp.c')
-rw-r--r--epan/dissectors/packet-tftp.c91
1 files changed, 90 insertions, 1 deletions
diff --git a/epan/dissectors/packet-tftp.c b/epan/dissectors/packet-tftp.c
index b60c716222..ca108b0f57 100644
--- a/epan/dissectors/packet-tftp.c
+++ b/epan/dissectors/packet-tftp.c
@@ -46,6 +46,7 @@
#include <epan/expert.h>
#include <epan/prefs.h>
#include <epan/tap.h>
+#include <epan/export_object.h>
#include "packet-tftp.h"
@@ -140,6 +141,94 @@ static const value_string tftp_error_code_vals[] = {
static int tftp_eo_tap = -1;
+/* A list of block list entries to delete from cleanup callback when window is closed. */
+typedef struct eo_info_dynamic_t {
+ gchar *filename;
+ GSList *block_list;
+} eo_info_dynamic_t;
+static GSList *s_dynamic_info_list = NULL;
+
+/* Tap function */
+static gboolean
+tftp_eo_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, const void *data)
+{
+ export_object_list_t *object_list = (export_object_list_t *)tapdata;
+ const tftp_eo_t *eo_info = (const tftp_eo_t *)data;
+ export_object_entry_t *entry;
+
+ GSList *block_iterator;
+ guint payload_data_offset = 0;
+ eo_info_dynamic_t *dynamic_info;
+
+ /* These values will be freed when the Export Object window is closed. */
+ entry = g_new(export_object_entry_t, 1);
+
+ /* Remember which frame had the last block of the file */
+ entry->pkt_num = pinfo->num;
+
+ /* Copy filename */
+ entry->filename = g_path_get_basename(eo_info->filename);
+
+ /* Iterate over list of blocks and concatenate into contiguous memory */
+ entry->payload_len = eo_info->payload_len;
+ entry->payload_data = (guint8 *)g_try_malloc((gsize)entry->payload_len);
+ for (block_iterator = eo_info->block_list; block_iterator; block_iterator = block_iterator->next) {
+ file_block_t *block = (file_block_t*)block_iterator->data;
+ memcpy(entry->payload_data + payload_data_offset,
+ block->data,
+ block->length);
+ payload_data_offset += block->length;
+ }
+
+ /* These 2 fields not used */
+ entry->hostname = NULL;
+ entry->content_type = NULL;
+
+ /* Add to list of entries to be cleaned up. eo_info is only packet scope, so
+ need to make list only of block list now */
+ dynamic_info = g_new(eo_info_dynamic_t, 1);
+ dynamic_info->filename = eo_info->filename;
+ dynamic_info->block_list = eo_info->block_list;
+ s_dynamic_info_list = g_slist_append(s_dynamic_info_list, (eo_info_dynamic_t*)dynamic_info);
+
+ /* Pass out entry to the GUI */
+ object_list->add_entry(object_list->gui_data, entry);
+
+ return TRUE; /* State changed - window should be redrawn */
+}
+
+/* Clean up the stored parts of a single tapped entry */
+static void cleanup_tftp_eo(eo_info_dynamic_t *dynamic_info)
+{
+ GSList *block_iterator;
+ /* Free the filename */
+ g_free(dynamic_info->filename);
+
+ /* Walk list of block items */
+ for (block_iterator = dynamic_info->block_list; block_iterator; block_iterator = block_iterator->next) {
+ file_block_t *block = (file_block_t*)(block_iterator->data);
+ /* Free block data */
+ wmem_free(NULL, block->data);
+
+ /* Free block itself */
+ g_free(block);
+ }
+}
+
+/* Callback for freeing up data supplied with taps. The taps themselves only have
+ packet scope, so only store/free dynamic memory pointers */
+void tftp_eo_cleanup(void)
+{
+ /* Cleanup each entry in the global list */
+ GSList *dynamic_iterator;
+ for (dynamic_iterator = s_dynamic_info_list; dynamic_iterator; dynamic_iterator = dynamic_iterator->next) {
+ eo_info_dynamic_t *dynamic_info = (eo_info_dynamic_t*)dynamic_iterator->data;
+ cleanup_tftp_eo(dynamic_info);
+ }
+ /* List is empty again */
+ s_dynamic_info_list = NULL;
+}
+
static void
tftp_dissect_options(tvbuff_t *tvb, packet_info *pinfo, int offset,
proto_tree *tree, guint16 opcode, tftp_conv_info_t *tftp_info)
@@ -684,7 +773,7 @@ proto_register_tftp(void)
prefs_register_protocol(proto_tftp, apply_tftp_prefs);
/* Register the tap for the "Export Object" function */
- tftp_eo_tap = register_tap("tftp_eo"); /* TFTP Export Object tap */
+ tftp_eo_tap = register_export_object(proto_tftp, tftp_eo_packet, tftp_eo_cleanup);
}
void