diff options
-rw-r--r-- | epan/epan.c | 14 | ||||
-rw-r--r-- | epan/epan.h | 4 | ||||
-rw-r--r-- | epan/libwireshark.def | 1 | ||||
-rw-r--r-- | epan/proto.c | 35 | ||||
-rw-r--r-- | epan/proto.h | 2 | ||||
-rw-r--r-- | file.c | 85 |
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); @@ -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; |