aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorAlexis La Goutte <alexis.lagoutte@gmail.com>2013-03-09 08:44:14 +0000
committerAlexis La Goutte <alexis.lagoutte@gmail.com>2013-03-09 08:44:14 +0000
commita4eb0a12ed36795fb75ab427e5bc2d09a8b95ca0 (patch)
treecfc06ac1a525d2b3b124e5dcb2e77207b6fe790f /ui
parente5d5bb67bc4265ab96bff535d0eb8ca8820e062f (diff)
From Jose Pico via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8377 NEW FEATURE IMPLEMENTED: SMB2 SUPPORT FOR EXPORT->OBJECTS->SMB
Added functionality: - SMB2 support for Export->Objects->SMB - support for SMB_COM_CREATE, SMB_COM_OPEN, SMB_COM_READ and SMB_COM_WRITE commands - Ability to choose between File Id and full file name as identifier for file re-building. Implemented as an option under Edit->Preferences->Protocols->SMB and Edit->Preferences->Protocols->SMB2. Other minor changes and fixes: - Full filename in file - Inclusion of IP of SMB server when treeid name (i.e. hostname) is not known - UTF-8 filenames encoding before passing them to Export Object Window - Re-written insert_chunk function of export_object_smb.c to make it easier to debug - Fixed of an error in insert_chunk function of export_object_smb.c (the verification of next free_chunk was always skipped after deleting one free_chunk). - Removed duplicated code by inserting the function feed_eo_smb in packet-smb.c and packet-smb2.c - Changed the label of Export->Objects->SMB menu into Export->Objects->SMB/SMB2 svn path=/trunk/; revision=48210
Diffstat (limited to 'ui')
-rw-r--r--ui/export_object.h4
-rw-r--r--ui/export_object_smb.c652
-rw-r--r--ui/gtk/export_object_dlg.c36
-rw-r--r--ui/gtk/main_menubar.c2
4 files changed, 386 insertions, 308 deletions
diff --git a/ui/export_object.h b/ui/export_object.h
index ba73361224..c42d8524ff 100644
--- a/ui/export_object.h
+++ b/ui/export_object.h
@@ -59,9 +59,9 @@ const char *ct2ext(const char *content_type);
gboolean eo_dicom_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_,
const void *data);
gboolean eo_http_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_,
- const void *data);
+ const void *data);
gboolean eo_smb_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_,
- const void *data);
+ const void *data);
void eo_smb_cleanup(void);
diff --git a/ui/export_object_smb.c b/ui/export_object_smb.c
index 9153b70787..2e15795a47 100644
--- a/ui/export_object_smb.c
+++ b/ui/export_object_smb.c
@@ -34,6 +34,7 @@
#include <epan/packet.h>
#include <epan/dissectors/packet-smb.h>
+#include <epan/dissectors/packet-smb2.h>
#include <epan/tap.h>
#include "export_object.h"
@@ -45,16 +46,33 @@
#define SMB_EO_CONTAINS_READS 0x01
#define SMB_EO_CONTAINS_WRITES 0x02
#define SMB_EO_CONTAINS_READSANDWRITES 0x03
-#define LEGAL_FILENAME_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ1234567890_."
+#define LEGAL_FILENAME_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_.- /\\{}[]=()&%$!,;.+&%$~#@"
static const value_string smb_eo_contains_string[] = {
- {SMB_EO_CONTAINS_NOTHING, "" },
- {SMB_EO_CONTAINS_READS, "R" },
- {SMB_EO_CONTAINS_WRITES, "W" },
- {SMB_EO_CONTAINS_READSANDWRITES, "R&W"},
- {0, NULL}
- };
-
+ {SMB_EO_CONTAINS_NOTHING, "" },
+ {SMB_EO_CONTAINS_READS, "R" },
+ {SMB_EO_CONTAINS_WRITES, "W" },
+ {SMB_EO_CONTAINS_READSANDWRITES, "R&W"},
+ {0, NULL}
+};
+
+/* Strings that describes the SMB object type */
+static const value_string smb_fid_types[] = {
+ {SMB_FID_TYPE_UNKNOWN,"UNKNOWN"},
+ {SMB_FID_TYPE_FILE,"FILE"},
+ {SMB_FID_TYPE_DIR,"DIRECTORY (Not Implemented)"},
+ {SMB_FID_TYPE_PIPE,"PIPE (Not Implemented)"},
+ {0, NULL}
+};
+
+static const value_string smb2_fid_types[] = {
+ {SMB2_FID_TYPE_UNKNOWN,"UNKNOWN"},
+ {SMB2_FID_TYPE_FILE,"FILE"},
+ {SMB2_FID_TYPE_DIR,"DIRECTORY (Not Implemented)"},
+ {SMB2_FID_TYPE_PIPE,"PIPE (Not Implemented)"},
+ {SMB2_FID_TYPE_OTHER,"OTHER (Not Implemented)"},
+ {0, NULL}
+};
/* This struct contains the relationship between
the row# in the export_object window and the file being captured;
@@ -96,318 +114,350 @@ typedef struct _free_chunk {
static void
insert_chunk(active_file *file, export_object_entry_t *entry, const smb_eo_t *eo_info)
{
- guint nfreechunks = g_slist_length(file->free_chunk_list);
- guint i;
- free_chunk *current_free_chunk;
- free_chunk *new_free_chunk;
- guint64 chunk_offset = eo_info->smb_file_offset;
- guint64 chunk_length = eo_info->payload_len;
- guint64 chunk_end_offset = chunk_offset + chunk_length-1;
- /* Size of file in memory */
- guint64 calculated_size = chunk_offset + chunk_length;
- gpointer dest_memory_addr;
-
- /* Let's recalculate the file length and data gathered */
- if ((file->data_gathered == 0) && (nfreechunks == 0)) {
- /* If this is the first entry for this file, we first
- create an initial free chunk */
- new_free_chunk = g_malloc(sizeof(free_chunk));
- new_free_chunk->start_offset = 0;
- new_free_chunk->end_offset = MAX(file->file_length, chunk_end_offset+1) - 1;
- file->free_chunk_list = NULL;
- file->free_chunk_list = g_slist_append(file->free_chunk_list, new_free_chunk);
- nfreechunks += 1;
- } else {
- if (chunk_end_offset > file->file_length-1) {
- new_free_chunk = g_malloc(sizeof(free_chunk));
- new_free_chunk->start_offset = file->file_length;
- new_free_chunk->end_offset = chunk_end_offset;
- file->free_chunk_list = g_slist_append(file->free_chunk_list, new_free_chunk);
- nfreechunks += 1;
- }
- }
- file->file_length = MAX(file->file_length, chunk_end_offset+1);
-
- for (i=0; i<nfreechunks; i++) {
- current_free_chunk = g_slist_nth_data(file->free_chunk_list, i);
- if (chunk_offset <= current_free_chunk->start_offset) {
- if (chunk_end_offset >= current_free_chunk->start_offset) {
- if (chunk_end_offset < current_free_chunk->end_offset) {
- file->data_gathered +=
- (chunk_end_offset-current_free_chunk->start_offset + 1);
- current_free_chunk->start_offset = chunk_end_offset + 1;
- } else {
- file->data_gathered +=
- (current_free_chunk->end_offset-current_free_chunk->start_offset + 1);
- file->free_chunk_list =
- g_slist_remove(file->free_chunk_list, current_free_chunk);
- nfreechunks -= 1;
- if (nfreechunks == 0) { /* The free chunk list is empty */
- g_slist_free(file->free_chunk_list);
- file->free_chunk_list = NULL;
- break;
- }
- }
- } else {
- break;
- }
- } else {
- if (chunk_offset <= current_free_chunk->end_offset) {
- if (chunk_end_offset < current_free_chunk->end_offset) {
- new_free_chunk = g_malloc(sizeof(free_chunk));
- new_free_chunk->start_offset = chunk_end_offset + 1;
- new_free_chunk->end_offset = current_free_chunk->end_offset;
- current_free_chunk->end_offset = chunk_offset-1;
- file->free_chunk_list =
- g_slist_insert(file->free_chunk_list, new_free_chunk, i + 1);
- file->data_gathered += chunk_length;
- } else {
- file->data_gathered += current_free_chunk->end_offset-chunk_offset + 1;
- current_free_chunk->end_offset = chunk_offset-1;
- }
- }
- }
- }
-
- /* Now, let's insert the data chunk into memory
- ...first, we shall be able to allocate the memory */
- if (!entry->payload_data) {
- /* This is a New file */
- if (calculated_size > G_MAXSIZE) {
- /*
- * The argument to g_try_malloc() is
- * a gsize, the maximum value of which is
- * G_MAXSIZE. If the calculated size is
- * bigger than that, we just say the attempt
- * to allocate memory failed.
- */
- entry->payload_data = NULL;
- } else {
- entry->payload_data = g_try_malloc((gsize)calculated_size);
- entry->payload_len = calculated_size;
- }
- if (!entry->payload_data) {
- /* Memory error */
- file->is_out_of_memory = TRUE;
- }
- } else {
- /* This is an existing file in memory */
- if (calculated_size > (guint64) entry->payload_len &&
- !file->is_out_of_memory) {
- /* We need more memory */
- if (calculated_size > G_MAXSIZE) {
- /*
- * As for g_try_malloc(), so for
- * g_try_realloc().
- */
- dest_memory_addr = NULL;
- } else {
- dest_memory_addr = g_try_realloc(
- entry->payload_data,
- (gsize)calculated_size);
- }
- if (!dest_memory_addr) {
- /* Memory error */
- file->is_out_of_memory = TRUE;
- /* We don't have memory for this file.
- Free the current file content from memory */
- g_free(entry->payload_data);
- entry->payload_data = NULL;
- entry->payload_len = 0;
- } else {
- entry->payload_data = dest_memory_addr;
- entry->payload_len = calculated_size;
- }
- }
- }
- /* ...then, put the chunk of the file in the right place */
- if (!file->is_out_of_memory) {
- dest_memory_addr = entry->payload_data + chunk_offset;
- g_memmove(dest_memory_addr, eo_info->payload_data, eo_info->payload_len);
- }
+gint nfreechunks = g_slist_length(file->free_chunk_list);
+gint i;
+free_chunk *current_free_chunk;
+free_chunk *new_free_chunk;
+guint64 chunk_offset = eo_info->smb_file_offset;
+guint64 chunk_length = eo_info->payload_len;
+guint64 chunk_end_offset = chunk_offset + chunk_length-1;
+/* Size of file in memory */
+guint64 calculated_size = chunk_offset + chunk_length;
+gpointer dest_memory_addr;
+
+ /* Let's recalculate the file length and data gathered */
+ if ((file->data_gathered == 0) && (nfreechunks == 0)) {
+ /* If this is the first entry for this file, we first
+ create an initial free chunk */
+ new_free_chunk = g_malloc(sizeof(free_chunk));
+ new_free_chunk->start_offset = 0;
+ new_free_chunk->end_offset = MAX(file->file_length, chunk_end_offset+1) - 1;
+ file->free_chunk_list = NULL;
+ file->free_chunk_list = g_slist_append(file->free_chunk_list, new_free_chunk);
+ nfreechunks += 1;
+ } else {
+ if (chunk_end_offset > file->file_length-1) {
+ new_free_chunk = g_malloc(sizeof(free_chunk));
+ new_free_chunk->start_offset = file->file_length;
+ new_free_chunk->end_offset = chunk_end_offset;
+ file->free_chunk_list = g_slist_append(file->free_chunk_list, new_free_chunk);
+ nfreechunks += 1;
+ }
+ }
+ file->file_length = MAX(file->file_length, chunk_end_offset+1);
+
+ /* Recalculate each free chunk according with the incoming data chunk */
+ for (i=0; i<nfreechunks; i++) {
+ current_free_chunk = g_slist_nth_data(file->free_chunk_list, i);
+ /* 1. data chunk before the free chunk? */
+ /* -> free chunk is not altered and no new data gathered */
+ if (chunk_end_offset<current_free_chunk->start_offset) {
+ continue;
+ }
+ /* 2. data chunk overlaps the first part of free_chunk */
+ /* -> free chunk shrinks from the beggining */
+ if (chunk_offset<=current_free_chunk->start_offset && chunk_end_offset>=current_free_chunk->start_offset && chunk_end_offset<current_free_chunk->end_offset) {
+ file->data_gathered += chunk_end_offset-current_free_chunk->start_offset+1;
+ current_free_chunk->start_offset=chunk_end_offset+1;
+ continue;
+ }
+ /* 3. data chunk overlaps completely the free chunk */
+ /* -> free chunk is removed */
+ if (chunk_offset<=current_free_chunk->start_offset && chunk_end_offset>=current_free_chunk->end_offset) {
+ file->data_gathered += current_free_chunk->end_offset-current_free_chunk->start_offset+1;
+ file->free_chunk_list = g_slist_remove(file->free_chunk_list, current_free_chunk);
+ nfreechunks -= 1;
+ if (nfreechunks == 0) { /* The free chunk list is empty */
+ g_slist_free(file->free_chunk_list);
+ file->free_chunk_list = NULL;
+ break;
+ }
+ i--;
+ continue;
+ }
+ /* 4. data chunk is inside the free chunk */
+ /* -> free chunk is splitted into two */
+ if (chunk_offset>current_free_chunk->start_offset && chunk_end_offset<current_free_chunk->end_offset) {
+ new_free_chunk = g_malloc(sizeof(free_chunk));
+ new_free_chunk->start_offset = chunk_end_offset + 1;
+ new_free_chunk->end_offset = current_free_chunk->end_offset;
+ current_free_chunk->end_offset = chunk_offset-1;
+ file->free_chunk_list = g_slist_insert(file->free_chunk_list, new_free_chunk, i + 1);
+ file->data_gathered += chunk_length;
+ continue;
+ }
+ /* 5.- data chunk overlaps the end part of free chunk */
+ /* -> free chunk shrinks from the end */
+ if (chunk_offset>current_free_chunk->start_offset && chunk_offset<=current_free_chunk->end_offset && chunk_end_offset>=current_free_chunk->end_offset) {
+ file->data_gathered += current_free_chunk->end_offset-chunk_offset+1;
+ current_free_chunk->end_offset = chunk_offset-1;
+ continue;
+ }
+ /* 6.- data chunk is after the free chunk */
+ /* -> free chunk is not altered and no new data gathered */
+ if (chunk_offset>current_free_chunk->end_offset) {
+ continue;
+ }
+ }
+
+ /* Now, let's insert the data chunk into memory
+ ...first, we shall be able to allocate the memory */
+ if (!entry->payload_data) {
+ /* This is a New file */
+ if (calculated_size > G_MAXSIZE) {
+ /*
+ * The argument to g_try_malloc() is
+ * a gsize, the maximum value of which is
+ * G_MAXSIZE. If the calculated size is
+ * bigger than that, we just say the attempt
+ * to allocate memory failed.
+ */
+ entry->payload_data = NULL;
+ } else {
+ entry->payload_data = g_try_malloc((gsize)calculated_size);
+ entry->payload_len = calculated_size;
+ }
+ if (!entry->payload_data) {
+ /* Memory error */
+ file->is_out_of_memory = TRUE;
+ }
+ } else {
+ /* This is an existing file in memory */
+ if (calculated_size > (guint64) entry->payload_len &&
+ !file->is_out_of_memory) {
+ /* We need more memory */
+ if (calculated_size > G_MAXSIZE) {
+ /*
+ * As for g_try_malloc(), so for
+ * g_try_realloc().
+ */
+ dest_memory_addr = NULL;
+ } else {
+ dest_memory_addr = g_try_realloc(
+ entry->payload_data,
+ (gsize)calculated_size);
+ }
+ if (!dest_memory_addr) {
+ /* Memory error */
+ file->is_out_of_memory = TRUE;
+ /* We don't have memory for this file.
+ Free the current file content from memory */
+ g_free(entry->payload_data);
+ entry->payload_data = NULL;
+ entry->payload_len = 0;
+ } else {
+ entry->payload_data = dest_memory_addr;
+ entry->payload_len = calculated_size;
+ }
+ }
+ }
+ /* ...then, put the chunk of the file in the right place */
+ if (!file->is_out_of_memory) {
+ dest_memory_addr = entry->payload_data + chunk_offset;
+ g_memmove(dest_memory_addr, eo_info->payload_data, eo_info->payload_len);
+ }
}
/* We use this function to obtain the index in the GSL of a given file */
static int
find_incoming_file(GSList *GSL_active_files_p, active_file *incoming_file)
{
- int i, row, last;
- active_file *in_list_file;
-
- row = -1;
- last = g_slist_length(GSL_active_files_p) - 1;
-
- /* We lookup in reverse order because it is more likely that the file
- is one of the latest */
- for (i=last; i>=0; i--) {
- in_list_file = g_slist_nth_data(GSL_active_files_p, i);
- /* The best-working criteria of two identical files is that the file
- that is the same of the file that we are analyzing is the last one
- in the list that has the same tid and the same fid */
- /* note that we have excluded in_list_file->uid == incoming_file->uid
- from the comparison, because a file can be opened by different
- SMB users and it is still the same file */
- if (in_list_file->tid == incoming_file->tid &&
- in_list_file->fid == incoming_file->fid) {
- row = i;
- break;
- }
- }
-
- return row;
+ int i, row, last;
+ active_file *in_list_file;
+
+ row = -1;
+ last = g_slist_length(GSL_active_files_p) - 1;
+
+ /* We lookup in reverse order because it is more likely that the file
+ is one of the latest */
+ for (i=last; i>=0; i--) {
+ in_list_file = g_slist_nth_data(GSL_active_files_p, i);
+ /* The best-working criteria of two identical files is that the file
+ that is the same of the file that we are analyzing is the last one
+ in the list that has the same tid and the same fid */
+ /* note that we have excluded in_list_file->uid == incoming_file->uid
+ from the comparison, because a file can be opened by different
+ SMB users and it is still the same file */
+ if (in_list_file->tid == incoming_file->tid &&
+ in_list_file->fid == incoming_file->fid) {
+ row = i;
+ break;
+ }
+ }
+
+ return row;
}
/* This is the function answering to the registered tap listener call */
gboolean
eo_smb_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, const void *data)
{
- export_object_list_t *object_list = tapdata;
- const smb_eo_t *eo_info = data;
-
- export_object_entry_t *entry;
- export_object_entry_t *current_entry;
- active_file incoming_file;
- gint active_row;
- active_file *new_file;
- active_file *current_file;
- guint8 contains;
- gboolean is_supported_filetype;
- gfloat percent;
-
- gchar **aux_string_v;
-
- /* Is this an eo_smb supported file_type? (right now we only support FILE */
- is_supported_filetype = (eo_info->fid_type == SMB_FID_TYPE_FILE);
-
- /* What kind of data this packet contains? */
- switch(eo_info->cmd) {
- case SMB_COM_READ_ANDX:
- contains = SMB_EO_CONTAINS_READS;
- break;
- case SMB_COM_WRITE_ANDX:
- contains = SMB_EO_CONTAINS_WRITES;
- break;
- default:
- contains = SMB_EO_CONTAINS_NOTHING;
- break;
- }
-
- /* Is this data from an already tracked file or not? */
- incoming_file.tid = eo_info->tid;
- incoming_file.uid = eo_info->uid;
- incoming_file.fid = eo_info->fid;
- active_row = find_incoming_file(GSL_active_files, &incoming_file);
-
- if (active_row == -1) { /* This is a new-tracked file */
- /* Construct the entry in the list of active files */
- entry = g_malloc(sizeof(export_object_entry_t));
- entry->payload_data = NULL;
- entry->payload_len = 0;
- new_file = g_malloc(sizeof(active_file));
- new_file->tid = incoming_file.tid;
- new_file->uid = incoming_file.uid;
- new_file->fid = incoming_file.fid;
- new_file->file_length = eo_info->end_of_file;
- new_file->flag_contains = contains;
- new_file->free_chunk_list = NULL;
- new_file->data_gathered = 0;
- new_file->is_out_of_memory = FALSE;
- entry->pkt_num = pinfo->fd->num;
- entry->hostname = g_strdup(eo_info->hostname);
- if (g_str_has_prefix(eo_info->filename, "\\")) {
- aux_string_v = g_strsplit(eo_info->filename, "\\", -1);
- entry->filename = g_strdup(aux_string_v[g_strv_length(aux_string_v)-1]);
- g_strfreev(aux_string_v);
- } else {
- entry->filename = g_strdup(eo_info->filename);
- }
-
- /* Insert the first chunk in the chunk list of this file */
- if (is_supported_filetype) {
- insert_chunk(new_file, entry, eo_info);
- }
-
- if (new_file->is_out_of_memory) {
- entry->content_type =
- g_strdup_printf("%s (%"G_GUINT64_FORMAT"?/%"G_GUINT64_FORMAT") %s [mem!!]",
- match_strval(eo_info->fid_type, smb_fid_types),
- new_file->data_gathered,
- new_file->file_length,
- match_strval(contains, smb_eo_contains_string));
- } else {
- if (new_file->file_length > 0) {
- percent = (gfloat) (100*new_file->data_gathered/new_file->file_length);
- } else {
- percent = 0.0f;
- }
-
- entry->content_type =
- g_strdup_printf("%s (%"G_GUINT64_FORMAT"/%"G_GUINT64_FORMAT") %s [%5.2f%%]",
- match_strval(eo_info->fid_type, smb_fid_types),
- new_file->data_gathered,
- new_file->file_length,
- match_strval(contains, smb_eo_contains_string),
- percent);
- }
-
- object_list_add_entry(object_list, entry);
- GSL_active_files =
- g_slist_append(GSL_active_files, new_file);
- }
- else if (is_supported_filetype) {
- current_file = g_slist_nth_data(GSL_active_files, active_row);
- /* Recalculate the current file flags */
- current_file->flag_contains = current_file->flag_contains|contains;
- current_entry = object_list_get_entry(object_list, active_row);
-
- insert_chunk(current_file, current_entry, eo_info);
-
- /* Modify the current_entry object_type string */
- if (current_file->is_out_of_memory) {
- current_entry->content_type =
- g_strdup_printf("%s (%"G_GUINT64_FORMAT"?/%"G_GUINT64_FORMAT") %s [mem!!]",
- match_strval(eo_info->fid_type, smb_fid_types),
- current_file->data_gathered,
- current_file->file_length,
- match_strval(current_file->flag_contains, smb_eo_contains_string));
- } else {
- percent = (gfloat) (100*current_file->data_gathered/current_file->file_length);
- current_entry->content_type =
- g_strdup_printf("%s (%"G_GUINT64_FORMAT"/%"G_GUINT64_FORMAT") %s [%5.2f%%]",
- match_strval(eo_info->fid_type, smb_fid_types),
- current_file->data_gathered,
- current_file->file_length,
- match_strval(current_file->flag_contains, smb_eo_contains_string),
- percent);
- }
- }
-
- return TRUE; /* State changed - window should be redrawn */
+export_object_list_t *object_list = tapdata;
+const smb_eo_t *eo_info = data;
+
+export_object_entry_t *entry;
+export_object_entry_t *current_entry;
+active_file incoming_file;
+gint active_row;
+active_file *new_file;
+active_file *current_file;
+guint8 contains;
+gboolean is_supported_filetype;
+gfloat percent;
+
+gchar *aux_smb_fid_type_string;
+
+ if (eo_info->smbversion==1) {
+ /* Is this an eo_smb supported file_type? (right now we only support FILE) */
+ is_supported_filetype = (eo_info->fid_type == SMB_FID_TYPE_FILE);
+ aux_smb_fid_type_string=g_strdup(match_strval(eo_info->fid_type, smb_fid_types));
+
+ /* What kind of data this packet contains? */
+ switch(eo_info->cmd) {
+ case SMB_COM_READ_ANDX:
+ case SMB_COM_READ:
+ contains = SMB_EO_CONTAINS_READS;
+ break;
+ case SMB_COM_WRITE_ANDX:
+ case SMB_COM_WRITE:
+ contains = SMB_EO_CONTAINS_WRITES;
+ break;
+ default:
+ contains = SMB_EO_CONTAINS_NOTHING;
+ break;
+ }
+ } else {
+ /* Is this an eo_smb supported file_type? (right now we only support FILE) */
+ is_supported_filetype = (eo_info->fid_type == SMB2_FID_TYPE_FILE );
+ aux_smb_fid_type_string=g_strdup(match_strval(eo_info->fid_type, smb2_fid_types));
+
+ /* What kind of data this packet contains? */
+ switch(eo_info->cmd) {
+ case SMB2_COM_READ:
+ contains = SMB_EO_CONTAINS_READS;
+ break;
+ case SMB2_COM_WRITE:
+ contains = SMB_EO_CONTAINS_WRITES;
+ break;
+ default:
+ contains = SMB_EO_CONTAINS_NOTHING;
+ break;
+ }
+ }
+
+
+ /* Is this data from an already tracked file or not? */
+ incoming_file.tid = eo_info->tid;
+ incoming_file.uid = eo_info->uid;
+ incoming_file.fid = eo_info->fid;
+ active_row = find_incoming_file(GSL_active_files, &incoming_file);
+
+ if (active_row == -1) { /* This is a new-tracked file */
+ /* Construct the entry in the list of active files */
+ entry = g_malloc(sizeof(export_object_entry_t));
+ entry->payload_data = NULL;
+ entry->payload_len = 0;
+ new_file = g_malloc(sizeof(active_file));
+ new_file->tid = incoming_file.tid;
+ new_file->uid = incoming_file.uid;
+ new_file->fid = incoming_file.fid;
+ new_file->file_length = eo_info->end_of_file;
+ new_file->flag_contains = contains;
+ new_file->free_chunk_list = NULL;
+ new_file->data_gathered = 0;
+ new_file->is_out_of_memory = FALSE;
+ entry->pkt_num = pinfo->fd->num;
+
+ entry->hostname=g_filename_display_name(g_strcanon(eo_info->hostname,LEGAL_FILENAME_CHARS,'?'));
+ entry->filename=g_filename_display_name(g_strcanon(eo_info->filename,LEGAL_FILENAME_CHARS,'?'));
+
+ /* Insert the first chunk in the chunk list of this file */
+ if (is_supported_filetype) {
+ insert_chunk(new_file, entry, eo_info);
+ }
+
+ if (new_file->is_out_of_memory) {
+ entry->content_type =
+ g_strdup_printf("%s (%"G_GUINT64_FORMAT"?/%"G_GUINT64_FORMAT") %s [mem!!]",
+ aux_smb_fid_type_string,
+ new_file->data_gathered,
+ new_file->file_length,
+ match_strval(contains, smb_eo_contains_string));
+ } else {
+ if (new_file->file_length > 0) {
+ percent = (gfloat) (100*new_file->data_gathered/new_file->file_length);
+ } else {
+ percent = 0.0f;
+ }
+
+ entry->content_type =
+ g_strdup_printf("%s (%"G_GUINT64_FORMAT"/%"G_GUINT64_FORMAT") %s [%5.2f%%]",
+ aux_smb_fid_type_string,
+ new_file->data_gathered,
+ new_file->file_length,
+ match_strval(contains, smb_eo_contains_string),
+ percent);
+ }
+
+ object_list_add_entry(object_list, entry);
+ GSL_active_files = g_slist_append(GSL_active_files, new_file);
+ }
+ else if (is_supported_filetype) {
+ current_file = g_slist_nth_data(GSL_active_files, active_row);
+ /* Recalculate the current file flags */
+ current_file->flag_contains = current_file->flag_contains|contains;
+ current_entry = object_list_get_entry(object_list, active_row);
+
+ insert_chunk(current_file, current_entry, eo_info);
+
+ /* Modify the current_entry object_type string */
+ if (current_file->is_out_of_memory) {
+ current_entry->content_type =
+ g_strdup_printf("%s (%"G_GUINT64_FORMAT"?/%"G_GUINT64_FORMAT") %s [mem!!]",
+ aux_smb_fid_type_string,
+ current_file->data_gathered,
+ current_file->file_length,
+ match_strval(current_file->flag_contains, smb_eo_contains_string));
+ } else {
+ percent = (gfloat) (100*current_file->data_gathered/current_file->file_length);
+ current_entry->content_type =
+ g_strdup_printf("%s (%"G_GUINT64_FORMAT"/%"G_GUINT64_FORMAT") %s [%5.2f%%]",
+ aux_smb_fid_type_string,
+ current_file->data_gathered,
+ current_file->file_length,
+ match_strval(current_file->flag_contains, smb_eo_contains_string),
+ percent);
+ }
+ }
+
+ return TRUE; /* State changed - window should be redrawn */
}
+
+
/* This is the eo_protocoldata_reset function that is used in the export_object module
to cleanup any previous private data of the export object functionality before perform
the eo_reset function or when the window closes */
void
eo_smb_cleanup(void)
{
- int i, last;
- active_file *in_list_file;
-
- /* Free any previous data structures used in previous invocation to the
- export_object_smb function */
- last = g_slist_length(GSL_active_files);
- if (GSL_active_files) {
- for (i=last-1; i>=0; i--) {
- in_list_file = g_slist_nth_data(GSL_active_files, i);
- if (in_list_file->free_chunk_list) {
- g_slist_free(in_list_file->free_chunk_list);
- in_list_file->free_chunk_list = NULL;
- }
- g_free(in_list_file);
- }
- g_slist_free(GSL_active_files);
- GSL_active_files = NULL;
- }
+int i, last;
+active_file *in_list_file;
+
+ /* Free any previous data structures used in previous invocation to the
+ export_object_smb function */
+ last = g_slist_length(GSL_active_files);
+ if (GSL_active_files) {
+ for (i=last-1; i>=0; i--) {
+ in_list_file = g_slist_nth_data(GSL_active_files, i);
+ if (in_list_file->free_chunk_list) {
+ g_slist_free(in_list_file->free_chunk_list);
+ in_list_file->free_chunk_list = NULL;
+ }
+ g_free(in_list_file);
+ }
+ g_slist_free(GSL_active_files);
+ GSL_active_files = NULL;
+ }
}
/*
diff --git a/ui/gtk/export_object_dlg.c b/ui/gtk/export_object_dlg.c
index 6b49bbb943..27afb762b9 100644
--- a/ui/gtk/export_object_dlg.c
+++ b/ui/gtk/export_object_dlg.c
@@ -132,6 +132,26 @@ eo_win_destroy_cb(GtkWindow *win _U_, gpointer data)
if (eo_protocoldata_reset != NULL) eo_protocoldata_reset();
}
+static gchar *eo_saveable_pathname(gchar *filename) {
+gchar **splitted_pathname;
+gchar *auxstring, *saveable_pathname;
+guint nparts,i;
+
+ saveable_pathname = NULL;
+ splitted_pathname = g_strsplit_set(filename,"\\",-1);
+ nparts = g_strv_length(splitted_pathname);
+ if (nparts>0) {
+ saveable_pathname=g_strdup(splitted_pathname[0]);
+ }
+ for (i=1;i<nparts;i++) {
+ auxstring = g_strconcat(saveable_pathname,"__",splitted_pathname[i],NULL);
+ g_free(saveable_pathname);
+ saveable_pathname = auxstring;
+ }
+
+ return saveable_pathname;
+}
+
static void
eo_save_clicked_cb(GtkWidget *widget _U_, gpointer arg)
{
@@ -139,6 +159,7 @@ eo_save_clicked_cb(GtkWidget *widget _U_, gpointer arg)
export_object_list_t *object_list = arg;
export_object_entry_t *entry;
gchar *filename = NULL;
+ gchar *auxfilename = NULL;
entry = g_slist_nth_data(object_list->entries,
object_list->row_selected);
@@ -154,14 +175,18 @@ eo_save_clicked_cb(GtkWidget *widget _U_, gpointer arg)
gtk_window_set_transient_for(GTK_WINDOW(save_as_w),
GTK_WINDOW(object_list->dlg));
+ auxfilename = eo_saveable_pathname(entry->filename);
+
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(save_as_w),
- entry->filename);
+ auxfilename);
+
if(gtk_dialog_run(GTK_DIALOG(save_as_w)) == GTK_RESPONSE_ACCEPT) {
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(save_as_w));
eo_save_entry(filename, entry, TRUE);
}
+ g_free(auxfilename);
g_free(filename);
window_destroy(save_as_w);
}
@@ -178,6 +203,7 @@ eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg)
gboolean all_saved = TRUE;
gchar *save_in_path;
GString *safe_filename;
+ gchar *auxfilename = NULL;
int count = 0;
save_in_w = file_selection_new("Wireshark: Save All Objects In ...",
@@ -194,10 +220,12 @@ eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg)
if ((strlen(save_in_path) < MAXFILELEN)) {
do {
g_free(save_as_fullpath);
- if (entry->filename)
- safe_filename = eo_massage_str(entry->filename,
+ if (entry->filename) {
+ auxfilename = eo_saveable_pathname(entry->filename);
+ safe_filename = eo_massage_str(auxfilename,
MAXFILELEN - strlen(save_in_path), count);
- else {
+ g_free(auxfilename);
+ } else {
char generic_name[256];
const char *ext;
ext = ct2ext(entry->content_type);
diff --git a/ui/gtk/main_menubar.c b/ui/gtk/main_menubar.c
index 4f53ba667f..37c4c7b3e5 100644
--- a/ui/gtk/main_menubar.c
+++ b/ui/gtk/main_menubar.c
@@ -1448,7 +1448,7 @@ static const GtkActionEntry main_menu_bar_entries[] = {
NULL, NULL, G_CALLBACK(export_pdml_cmd_cb) },
{ "/File/ExportObjects/HTTP", NULL, "_HTTP", NULL, NULL, G_CALLBACK(eo_http_cb) },
{ "/File/ExportObjects/DICOM", NULL, "_DICOM", NULL, NULL, G_CALLBACK(eo_dicom_cb) },
- { "/File/ExportObjects/SMB", NULL, "_SMB", NULL, NULL, G_CALLBACK(eo_smb_cb) },
+ { "/File/ExportObjects/SMB", NULL, "_SMB/SMB2", NULL, NULL, G_CALLBACK(eo_smb_cb) },
{ "/Edit/Copy", NULL, "Copy", NULL, NULL, NULL },