tvbuff_t * tvb_new_subset_length(tvbuff_t *backing, const gint backing_offset, const gint backing_length) { gint captured_length; tvbuff_t *tvb; guint subset_tvb_offset; guint subset_tvb_length; DISSECTOR_ASSERT(backing && backing->initialized); THROW_ON(backing_length < 0, ReportedBoundsError); /* * Give the next dissector only captured_length bytes. */ captured_length = tvb_length_remaining(backing, backing_offset); THROW_ON(captured_length < 0, BoundsError); if (captured_length > backing_length) captured_length = backing_length; tvb_check_offset_length(backing, backing_offset, captured_length, &subset_tvb_offset, &subset_tvb_length); tvb = tvb_new_with_subset(backing, backing_length, subset_tvb_offset, subset_tvb_length); tvb_add_to_chain(backing, tvb); return tvb; }
static void dissect_mime_encap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item* item; guint len; /* XXX, COL_INFO */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "MIME_FILE"); item = proto_tree_add_item(tree, proto_mime_encap, tvb, 0, -1, ENC_NA); /* frames with nsec >= 1000000000 means errors :) */ if (pinfo->fd->abs_ts.nsecs >= 1000000000) { proto_item_append_text(item, " (Error)"); /* return; */ /* dissect what we have */ } len = tvb_length(tvb); if (!pinfo->fd->flags.visited) { if (len) { tvbuff_t *cloned_tvb = tvb_clone(tvb); if (!file_tvbs) { file_tvbs = cloned_tvb; whole_tvb = tvb_new_composite(); } else tvb_add_to_chain(file_tvbs, cloned_tvb); tvb_composite_append(whole_tvb, cloned_tvb); } else tvb_composite_finalize(whole_tvb); } /* End of file? */ if (!len && whole_tvb) { /* * Here we're doing some trick. * * We don't want to call dissectors with composite tvb, cause dissectors can create subsets or real data child * on it, which would append to whole_tvb chain and would be freed only in mime_encap_init. * * So we create some tvb which pass all calls to whole_tvb, but chain with tvb (which is freed in dissection cleanup) */ tvbuff_t *tmp_tvb = tvb_new_chain(tvb, whole_tvb); proto_item_append_text(item, " (Final)"); add_new_data_source(pinfo, tmp_tvb, "Whole file"); if (!dissector_try_heuristic(heur_subdissector_list, tmp_tvb, pinfo, tree, NULL)) { proto_item_append_text(item, " (Unhandled)"); call_dissector(data_handle, tmp_tvb, pinfo, tree); } } }
tvbuff_t * tvb_new_subset_remaining(tvbuff_t *backing, const gint backing_offset) { tvbuff_t *tvb; guint subset_tvb_offset; guint subset_tvb_length; tvb_check_offset_length(backing, backing_offset, -1 /* backing_length */, &subset_tvb_offset, &subset_tvb_length); tvb = tvb_new_with_subset(backing, -1 /* reported_length */, subset_tvb_offset, subset_tvb_length); tvb_add_to_chain(backing, tvb); return tvb; }
tvbuff_t * tvb_new_subset(tvbuff_t *backing, const gint backing_offset, const gint backing_length, const gint reported_length) { tvbuff_t *tvb; guint subset_tvb_offset; guint subset_tvb_length; DISSECTOR_ASSERT(backing && backing->initialized); THROW_ON(reported_length < -1, ReportedBoundsError); tvb_check_offset_length(backing, backing_offset, backing_length, &subset_tvb_offset, &subset_tvb_length); tvb = tvb_new_with_subset(backing, reported_length, subset_tvb_offset, subset_tvb_length); tvb_add_to_chain(backing, tvb); return tvb; }