aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/epan.c14
-rw-r--r--epan/epan.h4
-rw-r--r--epan/libwireshark.def1
-rw-r--r--epan/proto.c35
-rw-r--r--epan/proto.h2
-rw-r--r--file.c85
6 files changed, 104 insertions, 37 deletions
diff --git a/epan/epan.c b/epan/epan.c
index 8a11d6c47a..5d1292e5f3 100644
--- a/epan/epan.c
+++ b/epan/epan.c
@@ -199,6 +199,20 @@ epan_dissect_run(epan_dissect_t *edt, struct wtap_pkthdr *phdr,
}
void
+epan_dissect_reset(epan_dissect_t *edt)
+{
+ /* epan_dissect_cleanup(edt) without freeing tree */
+ g_slist_free(edt->pi.dependent_frames);
+ free_data_sources(&edt->pi);
+ tvb_free_chain(edt->tvb);
+
+ /* epan_dissect_init(edt, create_proto, visible_proto) */
+ edt->pi.dependent_frames = NULL;
+ if (edt->tree)
+ proto_tree_reset(edt->tree);
+}
+
+void
epan_dissect_cleanup(epan_dissect_t* edt)
{
g_assert(edt);
diff --git a/epan/epan.h b/epan/epan.h
index c668fa0423..e618b33a64 100644
--- a/epan/epan.h
+++ b/epan/epan.h
@@ -170,6 +170,10 @@ epan_dissect_cleanup(epan_dissect_t* edt);
void
epan_dissect_free(epan_dissect_t* edt);
+/** reset edt for next packet dissection */
+void
+epan_dissect_reset(epan_dissect_t *edt);
+
/** Sets custom column */
const gchar *
epan_custom_set(epan_dissect_t *edt, int id, gint occurrence,
diff --git a/epan/libwireshark.def b/epan/libwireshark.def
index 3b82f647de..7f5e918cc8 100644
--- a/epan/libwireshark.def
+++ b/epan/libwireshark.def
@@ -411,6 +411,7 @@ epan_dissect_init
epan_dissect_new
epan_dissect_prime_dfilter
epan_dissect_run
+epan_dissect_reset
epan_get_compiled_version_info
epan_get_runtime_version_info
epan_get_version
diff --git a/epan/proto.c b/epan/proto.c
index 4a76ed416b..3d47074ab7 100644
--- a/epan/proto.c
+++ b/epan/proto.c
@@ -532,9 +532,8 @@ proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
}
static void
-free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
+unref_GPtrArray_value(gpointer key, gpointer value _U_, gpointer user_data _U_)
{
- GPtrArray *ptrs = value;
gint hfid = (gint)(long)key;
header_field_info *hfinfo;
@@ -551,6 +550,12 @@ free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
}
hfinfo->ref_type = HF_REF_TYPE_NONE;
}
+}
+
+static void
+free_GPtrArray_value(gpointer value)
+{
+ GPtrArray *ptrs = value;
g_ptr_array_free(ptrs, TRUE);
}
@@ -561,7 +566,7 @@ free_node_tree_data(tree_data_t *tree_data)
if (tree_data->interesting_hfids) {
/* Free all the GPtrArray's in the interesting_hfids hash. */
g_hash_table_foreach(tree_data->interesting_hfids,
- free_GPtrArray_value, NULL);
+ unref_GPtrArray_value, NULL);
/* And then destroy the hash. */
g_hash_table_destroy(tree_data->interesting_hfids);
@@ -609,6 +614,28 @@ proto_tree_free(proto_tree *tree)
free_node_tree_data(tree_data);
}
+void
+proto_tree_reset(proto_tree *tree)
+{
+ tree_data_t *tree_data = PTREE_DATA(tree);
+
+ proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
+
+ /* reset tree */
+ tree->parent = NULL;
+ tree->first_child = NULL;
+ tree->last_child = NULL;
+ tree->next = NULL;
+ PNODE_FINFO(tree) = NULL;
+
+ /* reset tree_data */
+ if (tree_data->interesting_hfids) {
+ g_hash_table_destroy(tree_data->interesting_hfids);
+ tree_data->interesting_hfids = NULL;
+ }
+ tree_data->count = 0;
+}
+
/* Is the parsing being done for a visible proto_tree or an invisible one?
* By setting this correctly, the proto_tree creation is sped up by not
* having to call g_vsnprintf and copy strings around.
@@ -1172,7 +1199,7 @@ proto_lookup_or_create_interesting_hfids(proto_tree *tree,
if (PTREE_DATA(tree)->interesting_hfids == NULL) {
/* Initialize the hash because we now know that it is needed */
PTREE_DATA(tree)->interesting_hfids =
- g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
+ g_hash_table_new_full(g_direct_hash, NULL /* g_direct_equal */, NULL, free_GPtrArray_value);
}
ptrs = g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
diff --git a/epan/proto.h b/epan/proto.h
index f4ab54965b..eed80182b2 100644
--- a/epan/proto.h
+++ b/epan/proto.h
@@ -701,6 +701,8 @@ extern gboolean proto_item_set_expert_flags(proto_item *ti, const int group, con
@return the new tree root */
extern proto_tree* proto_tree_create_root(struct _packet_info *pinfo);
+extern void proto_tree_reset(proto_tree *tree);
+
/** Clear memory for entry proto_tree. Clears proto_tree struct also.
@param tree the tree to free */
extern void proto_tree_free(proto_tree *tree);
diff --git a/file.c b/file.c
index 1869f6a444..554fa5f85f 100644
--- a/file.c
+++ b/file.c
@@ -89,7 +89,7 @@ static gulong computed_elapsed;
static void cf_reset_state(capture_file *cf);
static int read_packet(capture_file *cf, dfilter_t *dfcode,
- gboolean create_proto_tree, column_info *cinfo, gint64 offset);
+ epan_dissect_t *edt, column_info *cinfo, gint64 offset);
static void rescan_packets(capture_file *cf, const char *action, const char *action_item, gboolean redissect);
@@ -495,6 +495,13 @@ calc_progbar_val(capture_file *cf, gint64 size, gint64 file_pos, gchar *status_s
return progbar_val;
}
+static void
+epan_dissect_finish(epan_dissect_t *edt)
+{
+ if (edt->tree)
+ proto_tree_free(edt->tree);
+}
+
cf_read_status_t
cf_read(capture_file *cf, gboolean reloading)
{
@@ -513,7 +520,8 @@ cf_read(capture_file *cf, gboolean reloading)
volatile gint64 progbar_quantum;
dfilter_t *dfcode;
column_info *cinfo;
- volatile gboolean create_proto_tree;
+ epan_dissect_t edt;
+ gboolean create_proto_tree;
guint tap_flags;
volatile int count = 0;
#ifdef HAVE_LIBPCAP
@@ -533,6 +541,9 @@ cf_read(capture_file *cf, gboolean reloading)
cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
create_proto_tree =
(dfcode != NULL || have_filtering_tap_listeners() || (tap_flags & TL_REQUIRES_PROTO_TREE));
+ epan_dissect_init(&edt, create_proto_tree, FALSE);
+ if (dfcode != NULL)
+ epan_dissect_prime_dfilter(&edt, dfcode);
reset_tap_listeners();
@@ -620,7 +631,7 @@ cf_read(capture_file *cf, gboolean reloading)
break;
}
TRY {
- read_packet(cf, dfcode, create_proto_tree, cinfo, data_offset);
+ read_packet(cf, dfcode, &edt, cinfo, data_offset);
}
CATCH(OutOfMemoryError) {
simple_message_box(ESD_TYPE_ERROR, NULL,
@@ -637,6 +648,7 @@ cf_read(capture_file *cf, gboolean reloading)
}
ENDTRY;
}
+ epan_dissect_finish(&edt);
/* Free the display name */
g_free(name_ptr);
@@ -764,14 +776,15 @@ cf_start_tail(capture_file *cf, const char *fname, gboolean is_tempfile, int *er
cf_read_status_t
cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
{
- gint64 data_offset = 0;
- gchar *err_info;
- volatile int newly_displayed_packets = 0;
- dfilter_t *dfcode;
- column_info *cinfo;
- volatile gboolean create_proto_tree;
- guint tap_flags;
- gboolean compiled;
+ gint64 data_offset = 0;
+ gchar *err_info;
+ volatile int newly_displayed_packets = 0;
+ dfilter_t *dfcode;
+ column_info *cinfo;
+ epan_dissect_t edt;
+ gboolean create_proto_tree;
+ guint tap_flags;
+ gboolean compiled;
/* Compile the current display filter.
* We assume this will not fail since cf->dfilter is only set in
@@ -785,6 +798,9 @@ cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
create_proto_tree =
(dfcode != NULL || have_filtering_tap_listeners() || (tap_flags & TL_REQUIRES_PROTO_TREE));
+ epan_dissect_init(&edt, create_proto_tree, FALSE);
+ if (dfcode != NULL)
+ epan_dissect_prime_dfilter(&edt, dfcode);
*err = 0;
@@ -806,7 +822,7 @@ cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
break;
}
TRY{
- if (read_packet(cf, dfcode, create_proto_tree, cinfo,
+ if (read_packet(cf, dfcode, &edt, cinfo,
data_offset) != -1) {
newly_displayed_packets++;
}
@@ -827,6 +843,7 @@ cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
ENDTRY;
to_read--;
}
+ epan_dissect_finish(&edt);
/* Update the file encapsulation; it might have changed based on the
packets we've read. */
@@ -885,6 +902,7 @@ cf_finish_tail(capture_file *cf, int *err)
dfilter_t *dfcode;
column_info *cinfo;
gboolean create_proto_tree;
+ epan_dissect_t edt;
guint tap_flags;
gboolean compiled;
@@ -900,6 +918,9 @@ cf_finish_tail(capture_file *cf, int *err)
cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
create_proto_tree =
(dfcode != NULL || have_filtering_tap_listeners() || (tap_flags & TL_REQUIRES_PROTO_TREE));
+ epan_dissect_init(&edt, create_proto_tree, FALSE);
+ if (dfcode != NULL)
+ epan_dissect_prime_dfilter(&edt, dfcode);
if (cf->wth == NULL) {
cf_close(cf);
@@ -917,8 +938,9 @@ cf_finish_tail(capture_file *cf, int *err)
aren't any packets left to read) exit. */
break;
}
- read_packet(cf, dfcode, create_proto_tree, cinfo, data_offset);
+ read_packet(cf, dfcode, &edt, cinfo, data_offset);
}
+ epan_dissect_finish(&edt);
/* Cleanup and release all dfilter resources */
if (dfcode != NULL) {
@@ -1089,38 +1111,30 @@ find_and_mark_frame_depended_upon(gpointer data, gpointer user_data)
static int
add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
- dfilter_t *dfcode, gboolean create_proto_tree, column_info *cinfo,
+ dfilter_t *dfcode, epan_dissect_t *edt, column_info *cinfo,
struct wtap_pkthdr *phdr, const guchar *buf,
gboolean add_to_packet_list)
{
- epan_dissect_t edt;
- gint row = -1;
+ gint row = -1;
frame_data_set_before_dissect(fdata, &cf->elapsed_time,
&first_ts, prev_dis, prev_cap);
prev_cap = fdata;
- /* Dissect the frame. */
- epan_dissect_init(&edt, create_proto_tree, FALSE);
-
- if (dfcode != NULL) {
- epan_dissect_prime_dfilter(&edt, dfcode);
- }
-
- tap_queue_init(&edt);
- epan_dissect_run(&edt, phdr, buf, fdata, cinfo);
- tap_push_tapped_queue(&edt);
+ tap_queue_init(edt);
+ epan_dissect_run(edt, phdr, buf, fdata, cinfo);
+ tap_push_tapped_queue(edt);
/* If we don't have a display filter, set "passed_dfilter" to 1. */
if (dfcode != NULL) {
- fdata->flags.passed_dfilter = dfilter_apply_edt(dfcode, &edt) ? 1 : 0;
+ fdata->flags.passed_dfilter = dfilter_apply_edt(dfcode, edt) ? 1 : 0;
if (fdata->flags.passed_dfilter) {
/* This frame passed the display filter but it may depend on other
* (potentially not displayed) frames. Find those frames and mark them
* as depended upon.
*/
- g_slist_foreach(edt.pi.dependent_frames, find_and_mark_frame_depended_upon, cf);
+ g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf);
}
} else
fdata->flags.passed_dfilter = 1;
@@ -1130,7 +1144,7 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
if (add_to_packet_list) {
/* We fill the needed columns from new_packet_list */
- row = packet_list_append(cinfo, fdata, &edt.pi);
+ row = packet_list_append(cinfo, fdata, &edt->pi);
}
if (fdata->flags.passed_dfilter || fdata->flags.ref_time)
@@ -1158,7 +1172,7 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
cf->last_displayed = fdata->num;
}
- epan_dissect_cleanup(&edt);
+ epan_dissect_reset(edt);
return row;
}
@@ -1166,7 +1180,7 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
/* returns the row of the new packet in the packet list or -1 if not displayed */
static int
read_packet(capture_file *cf, dfilter_t *dfcode,
- gboolean create_proto_tree, column_info *cinfo, gint64 offset)
+ epan_dissect_t *edt, column_info *cinfo, gint64 offset)
{
struct wtap_pkthdr *phdr = wtap_phdr(cf->wth);
const guchar *buf = wtap_buf_ptr(cf->wth);
@@ -1211,7 +1225,7 @@ read_packet(capture_file *cf, dfilter_t *dfcode,
if (!cf->redissecting) {
row = add_packet_to_packet_list(fdata, cf, dfcode,
- create_proto_tree, cinfo,
+ edt, cinfo,
phdr, buf, TRUE);
}
}
@@ -1752,6 +1766,7 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item, gb
int progbar_quantum;
dfilter_t *dfcode;
column_info *cinfo;
+ epan_dissect_t edt;
gboolean create_proto_tree;
guint tap_flags;
gboolean add_to_packet_list = FALSE;
@@ -1770,6 +1785,9 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item, gb
cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
create_proto_tree =
(dfcode != NULL || have_filtering_tap_listeners() || (tap_flags & TL_REQUIRES_PROTO_TREE));
+ epan_dissect_init(&edt, create_proto_tree, FALSE);
+ if (dfcode != NULL)
+ epan_dissect_prime_dfilter(&edt, dfcode);
reset_tap_listeners();
/* Which frame, if any, is the currently selected frame?
@@ -1921,7 +1939,7 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item, gb
preceding_frame_num = prev_frame_num;
preceding_frame = prev_frame;
}
- add_packet_to_packet_list(fdata, cf, dfcode, create_proto_tree,
+ add_packet_to_packet_list(fdata, cf, dfcode, &edt,
cinfo, &cf->phdr, cf->pd,
add_to_packet_list);
@@ -1944,6 +1962,7 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item, gb
prev_frame_num = fdata->num;
prev_frame = fdata;
}
+ epan_dissect_finish(&edt);
/* We are done redissecting the packet list. */
cf->redissecting = FALSE;