forked from osmocom/wireshark
epan: Allow nested dependent packets
Save all dependent frames when there are multiple levels of reassembly. This is a retry of !6329, combined with the fix in !6509 which were reverted in !6545. epan: fix a segfault, introduced in !6329
This commit is contained in:
parent
693dc40936
commit
f870c6085d
|
@ -1879,7 +1879,7 @@ static void dissect_host_anchor_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree
|
|||
proto_item_set_generated(pi);
|
||||
/* XXX: Need to do this each time because pinfo is discarded. Filtering does not reset visited as it does not do a full redissect.
|
||||
We also might not catch all frames in the first pass (e.g. comment after record). */
|
||||
mark_frame_as_depended_upon(pinfo, anchored_info->frame_num);
|
||||
mark_frame_as_depended_upon(pinfo->fd, anchored_info->frame_num);
|
||||
}
|
||||
frame = wmem_list_frame_next(frame);
|
||||
}
|
||||
|
@ -1925,12 +1925,12 @@ dissect_host_id_source_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
|
|||
pi = proto_tree_add_uint(hostid_tree, hf_erf_source_next, tvb, 0, 0, fnum_next);
|
||||
proto_item_set_generated(pi);
|
||||
/* XXX: Save the surrounding nearest periodic records when we do a filtered save so we keep native ERF metadata */
|
||||
mark_frame_as_depended_upon(pinfo, fnum_next);
|
||||
mark_frame_as_depended_upon(pinfo->fd, fnum_next);
|
||||
}
|
||||
if (fnum != G_MAXUINT32) {
|
||||
pi = proto_tree_add_uint(hostid_tree, hf_erf_source_prev, tvb, 0, 0, fnum);
|
||||
proto_item_set_generated(pi);
|
||||
mark_frame_as_depended_upon(pinfo, fnum);
|
||||
mark_frame_as_depended_upon(pinfo->fd, fnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2919,7 +2919,7 @@ fragment_reassembly(tvbuff_t *tvb, sctp_fragment *fragment,
|
|||
frag_i->frame_num, offset, offset + frag_i->len - 1, frag_i->len);
|
||||
offset += frag_i->len;
|
||||
|
||||
mark_frame_as_depended_upon(pinfo, frag_i->frame_num);
|
||||
mark_frame_as_depended_upon(pinfo->fd, frag_i->frame_num);
|
||||
}
|
||||
|
||||
for (frag_i = msg->fragments;
|
||||
|
@ -2931,7 +2931,7 @@ fragment_reassembly(tvbuff_t *tvb, sctp_fragment *fragment,
|
|||
frag_i->frame_num, offset, offset + frag_i->len - 1, frag_i->len);
|
||||
offset += frag_i->len;
|
||||
|
||||
mark_frame_as_depended_upon(pinfo, frag_i->frame_num);
|
||||
mark_frame_as_depended_upon(pinfo->fd, frag_i->frame_num);
|
||||
}
|
||||
} else {
|
||||
for (frag_i = find_fragment(message->begin, stream_id, stream_seq_num, u_bit);
|
||||
|
@ -2943,7 +2943,7 @@ fragment_reassembly(tvbuff_t *tvb, sctp_fragment *fragment,
|
|||
frag_i->frame_num, offset, offset + frag_i->len - 1, frag_i->len);
|
||||
offset += frag_i->len;
|
||||
|
||||
mark_frame_as_depended_upon(pinfo, frag_i->frame_num);
|
||||
mark_frame_as_depended_upon(pinfo->fd, frag_i->frame_num);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3158,7 +3158,7 @@ fragment_reassembly(tvbuff_t *tvb, sctp_fragment *fragment,
|
|||
frag_i->frame_num, offset, offset + frag_i->len - 1, frag_i->len);
|
||||
offset += frag_i->len;
|
||||
|
||||
mark_frame_as_depended_upon(pinfo, frag_i->frame_num);
|
||||
mark_frame_as_depended_upon(pinfo->fd, frag_i->frame_num);
|
||||
}
|
||||
|
||||
for (frag_i = msg->fragments;
|
||||
|
@ -3170,7 +3170,7 @@ fragment_reassembly(tvbuff_t *tvb, sctp_fragment *fragment,
|
|||
frag_i->frame_num, offset, offset + frag_i->len - 1, frag_i->len);
|
||||
offset += frag_i->len;
|
||||
|
||||
mark_frame_as_depended_upon(pinfo, frag_i->frame_num);
|
||||
mark_frame_as_depended_upon(pinfo->fd, frag_i->frame_num);
|
||||
}
|
||||
} else {
|
||||
for (frag_i = find_fragment(message->begin, stream_id, stream_seq_num, u_bit);
|
||||
|
@ -3182,7 +3182,7 @@ fragment_reassembly(tvbuff_t *tvb, sctp_fragment *fragment,
|
|||
frag_i->frame_num, offset, offset + frag_i->len - 1, frag_i->len);
|
||||
offset += frag_i->len;
|
||||
|
||||
mark_frame_as_depended_upon(pinfo, frag_i->frame_num);
|
||||
mark_frame_as_depended_upon(pinfo->fd, frag_i->frame_num);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -611,7 +611,7 @@ tree_add_fragment_list(struct rlc_sdu *sdu, tvbuff_t *tvb,packet_info *pinfo, pr
|
|||
sdufrag->frame_num, sdufrag->seq);
|
||||
}
|
||||
|
||||
mark_frame_as_depended_upon(pinfo, sdufrag->frame_num);
|
||||
mark_frame_as_depended_upon(pinfo->fd, sdufrag->frame_num);
|
||||
|
||||
offset += sdufrag->len;
|
||||
sdufrag = sdufrag->next;
|
||||
|
|
|
@ -573,7 +573,6 @@ epan_dissect_reset(epan_dissect_t *edt)
|
|||
wtap_block_unref(edt->pi.rec->block);
|
||||
|
||||
g_slist_free(edt->pi.proto_data);
|
||||
g_slist_free(edt->pi.dependent_frames);
|
||||
|
||||
/* Free the data sources list. */
|
||||
free_data_sources(&edt->pi);
|
||||
|
@ -684,7 +683,6 @@ epan_dissect_cleanup(epan_dissect_t* edt)
|
|||
g_slist_foreach(epan_plugins, epan_plugin_dissect_cleanup, edt);
|
||||
|
||||
g_slist_free(edt->pi.proto_data);
|
||||
g_slist_free(edt->pi.dependent_frames);
|
||||
|
||||
/* Free the data sources list. */
|
||||
free_data_sources(&edt->pi);
|
||||
|
|
|
@ -161,6 +161,7 @@ frame_data_init(frame_data *fdata, guint32 num, const wtap_rec *rec,
|
|||
fdata->subnum = 0;
|
||||
fdata->passed_dfilter = 0;
|
||||
fdata->dependent_of_displayed = 0;
|
||||
fdata->dependent_frames = NULL;
|
||||
fdata->encoding = PACKET_CHAR_ENC_CHAR_ASCII;
|
||||
fdata->visited = 0;
|
||||
fdata->marked = 0;
|
||||
|
@ -306,6 +307,11 @@ frame_data_destroy(frame_data *fdata)
|
|||
g_slist_free(fdata->pfd);
|
||||
fdata->pfd = NULL;
|
||||
}
|
||||
|
||||
if (fdata->dependent_frames) {
|
||||
g_slist_free(fdata->dependent_frames);
|
||||
fdata->dependent_frames = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -77,6 +77,7 @@ typedef struct _frame_data {
|
|||
are 32 bits. */
|
||||
unsigned int passed_dfilter : 1; /**< 1 = display, 0 = no display */
|
||||
unsigned int dependent_of_displayed : 1; /**< 1 if a displayed frame depends on this frame */
|
||||
GSList *dependent_frames; /**< A list of frames which this one depends on */
|
||||
/* Do NOT use packet_char_enc enum here: MSVC compiler does not handle an enum in a bit field properly */
|
||||
unsigned int encoding : 1; /**< Character encoding (ASCII, EBCDIC...) */
|
||||
unsigned int visited : 1; /**< Has this packet been visited yet? 1=Yes,0=No*/
|
||||
|
|
|
@ -321,6 +321,7 @@ find_and_mark_frame_depended_upon(gpointer data, gpointer user_data)
|
|||
if (dependent_frame && frames) {
|
||||
dependent_fd = frame_data_sequence_find(frames, dependent_frame);
|
||||
dependent_fd->dependent_of_displayed = 1;
|
||||
g_slist_foreach(dependent_fd->dependent_frames, find_and_mark_frame_depended_upon, frames);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -445,11 +445,11 @@ free_data_sources(packet_info *pinfo)
|
|||
}
|
||||
|
||||
void
|
||||
mark_frame_as_depended_upon(packet_info *pinfo, guint32 frame_num)
|
||||
mark_frame_as_depended_upon(frame_data *fd, guint32 frame_num)
|
||||
{
|
||||
/* Don't mark a frame as dependent on itself */
|
||||
if (frame_num != pinfo->num) {
|
||||
pinfo->dependent_frames = g_slist_prepend(pinfo->dependent_frames, GUINT_TO_POINTER(frame_num));
|
||||
if (frame_num != fd->num) {
|
||||
fd->dependent_frames = g_slist_prepend(fd->dependent_frames, GUINT_TO_POINTER(frame_num));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -772,7 +772,7 @@ extern void free_data_sources(packet_info *pinfo);
|
|||
* if the user does a File->Save-As of only the Displayed packets and the
|
||||
* current frame passed the display filter.
|
||||
*/
|
||||
WS_DLL_PUBLIC void mark_frame_as_depended_upon(packet_info *pinfo, guint32 frame_num);
|
||||
WS_DLL_PUBLIC void mark_frame_as_depended_upon(frame_data *fd, guint32 frame_num);
|
||||
|
||||
/* Structure passed to the frame dissector */
|
||||
typedef struct frame_data_s
|
||||
|
|
|
@ -149,8 +149,6 @@ typedef struct _packet_info {
|
|||
|
||||
GSList* proto_data; /**< Per packet proto data */
|
||||
|
||||
GSList* dependent_frames; /**< A list of frames which this one depends on */
|
||||
|
||||
GSList* frame_end_routines;
|
||||
|
||||
wmem_allocator_t *pool; /**< Memory pool scoped to the pinfo struct */
|
||||
|
|
|
@ -2964,7 +2964,7 @@ show_fragment(fragment_item *fd, const int offset, const fragment_items *fit,
|
|||
plurality(fd->len, "", "s"));
|
||||
}
|
||||
proto_item_set_generated(fei);
|
||||
mark_frame_as_depended_upon(pinfo, fd->frame);
|
||||
mark_frame_as_depended_upon(pinfo->fd, fd->frame);
|
||||
if (fd->flags & (FD_OVERLAP|FD_OVERLAPCONFLICT
|
||||
|FD_MULTIPLETAILS|FD_TOOLONGFRAGMENT) ) {
|
||||
/* this fragment has some flags set, create a subtree
|
||||
|
|
2
file.c
2
file.c
|
@ -1199,7 +1199,7 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
|
|||
* (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->provider.frames);
|
||||
g_slist_foreach(edt->pi.fd->dependent_frames, find_and_mark_frame_depended_upon, cf->provider.frames);
|
||||
}
|
||||
} else
|
||||
fdata->passed_dfilter = 1;
|
||||
|
|
4
sharkd.c
4
sharkd.c
|
@ -309,14 +309,14 @@ process_packet(capture_file *cf, epan_dissect_t *edt,
|
|||
cf->provider.prev_cap = cf->provider.prev_dis = frame_data_sequence_add(cf->provider.frames, &fdlocal);
|
||||
|
||||
/* If we're not doing dissection then there won't be any dependent frames.
|
||||
* More importantly, edt.pi.dependent_frames won't be initialized because
|
||||
* More importantly, edt.pi.fd.dependent_frames won't be initialized because
|
||||
* epan hasn't been initialized.
|
||||
* if we *are* doing dissection, then mark the dependent frames, but only
|
||||
* if a display filter was given and it matches this packet.
|
||||
*/
|
||||
if (edt && cf->dfcode) {
|
||||
if (dfilter_apply_edt(cf->dfcode, edt)) {
|
||||
g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->provider.frames);
|
||||
g_slist_foreach(edt->pi.fd->dependent_frames, find_and_mark_frame_depended_upon, cf->provider.frames);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1068,11 +1068,11 @@ process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
|
|||
cf->provider.prev_cap = cf->provider.prev_dis = frame_data_sequence_add(cf->provider.frames, &fdlocal);
|
||||
|
||||
/* If we're not doing dissection then there won't be any dependent frames.
|
||||
* More importantly, edt.pi.dependent_frames won't be initialized because
|
||||
* More importantly, edt.pi.fd.dependent_frames won't be initialized because
|
||||
* epan hasn't been initialized.
|
||||
*/
|
||||
if (edt) {
|
||||
g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->provider.frames);
|
||||
g_slist_foreach(edt->pi.fd->dependent_frames, find_and_mark_frame_depended_upon, cf->provider.frames);
|
||||
}
|
||||
|
||||
cf->count++;
|
||||
|
|
4
tshark.c
4
tshark.c
|
@ -3050,14 +3050,14 @@ process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
|
|||
cf->provider.prev_cap = cf->provider.prev_dis = frame_data_sequence_add(cf->provider.frames, &fdlocal);
|
||||
|
||||
/* If we're not doing dissection then there won't be any dependent frames.
|
||||
* More importantly, edt.pi.dependent_frames won't be initialized because
|
||||
* More importantly, edt.pi.fd.dependent_frames won't be initialized because
|
||||
* epan hasn't been initialized.
|
||||
* if we *are* doing dissection, then mark the dependent frames, but only
|
||||
* if a display filter was given and it matches this packet.
|
||||
*/
|
||||
if (edt && cf->dfcode) {
|
||||
if (dfilter_apply_edt(cf->dfcode, edt)) {
|
||||
g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->provider.frames);
|
||||
g_slist_foreach(edt->pi.fd->dependent_frames, find_and_mark_frame_depended_upon, cf->provider.frames);
|
||||
}
|
||||
|
||||
if (selected_frame_number != 0 && selected_frame_number == cf->count + 1) {
|
||||
|
|
Loading…
Reference in New Issue