From 9d519b5659aa8c0c4aa984bc6169909eb31be7d6 Mon Sep 17 00:00:00 2001 From: Jakub Zawadzki Date: Wed, 31 Jul 2013 19:58:13 +0000 Subject: [PATCH] Move composite tvbuff to seperate file (with some subtle changes). svn path=/trunk/; revision=51071 --- epan/CMakeLists.txt | 1 + epan/Makefile.common | 1 + epan/tvbuff.c | 257 ------------------------------------- epan/tvbuff_composite.c | 275 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 277 insertions(+), 257 deletions(-) create mode 100644 epan/tvbuff_composite.c diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt index e5d662c070..4c5eba8e93 100644 --- a/epan/CMakeLists.txt +++ b/epan/CMakeLists.txt @@ -1499,6 +1499,7 @@ set(LIBWIRESHARK_FILES to_str.c tvbparse.c tvbuff.c + tvbuff_composite.c tvbuff_real.c tvbuff_subset.c uat.c diff --git a/epan/Makefile.common b/epan/Makefile.common index 92561541a4..b587dc57ec 100644 --- a/epan/Makefile.common +++ b/epan/Makefile.common @@ -97,6 +97,7 @@ LIBWIRESHARK_SRC = \ tfs.c \ to_str.c \ tvbparse.c \ + tvbuff_composite.c \ tvbuff_real.c \ tvbuff_subset.c \ tvbuff.c \ diff --git a/epan/tvbuff.c b/epan/tvbuff.c index c95c2d6199..0e029fdc73 100644 --- a/epan/tvbuff.c +++ b/epan/tvbuff.c @@ -51,8 +51,6 @@ #include "charsets.h" #include "proto.h" /* XXX - only used for DISSECTOR_ASSERT, probably a new header file? */ -static inline const struct tvb_ops *get_tvb_composite_ops(void); - static const guint8* ensure_contiguous_no_exception(tvbuff_t *tvb, const gint offset, const gint length, int *pexception); @@ -84,24 +82,6 @@ tvb_new(const struct tvb_ops *ops) return tvb; } -static void -composite_free(tvbuff_t *tvb) -{ - struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb; - tvb_comp_t *composite = &composite_tvb->composite; - - g_slist_free(composite->tvbs); - - g_free(composite->start_offsets); - g_free(composite->end_offsets); - if (tvb->real_data) { - /* - * XXX - do this with a union? - */ - g_free((gpointer)tvb->real_data); - } -} - static void tvb_free_internal(tvbuff_t *tvb) { @@ -397,105 +377,6 @@ tvb_new_octet_aligned(tvbuff_t *tvb, guint32 bit_offset, gint32 no_of_bits) return sub_tvb; } -/* - * Composite tvb - * - * 1. A composite tvb is automatically chained to its first member when the - * tvb is finalized. - * This means that composite tvb members must all be in the same chain. - * ToDo: enforce this: By searching the chain? - */ -tvbuff_t * -tvb_new_composite(void) -{ - tvbuff_t *tvb = tvb_new(get_tvb_composite_ops()); - struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb; - tvb_comp_t *composite = &composite_tvb->composite; - - composite->tvbs = NULL; - composite->start_offsets = NULL; - composite->end_offsets = NULL; - - return tvb; -} - -void -tvb_composite_append(tvbuff_t *tvb, tvbuff_t *member) -{ - struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb; - tvb_comp_t *composite; - - DISSECTOR_ASSERT(tvb && !tvb->initialized); - DISSECTOR_ASSERT(tvb->ops == get_tvb_composite_ops()); - - /* Don't allow zero-length TVBs: composite_memcpy() can't handle them - * and anyway it makes no sense. - */ - DISSECTOR_ASSERT(member->length); - - composite = &composite_tvb->composite; - composite->tvbs = g_slist_append(composite->tvbs, member); -} - -void -tvb_composite_prepend(tvbuff_t *tvb, tvbuff_t *member) -{ - struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb; - tvb_comp_t *composite; - - DISSECTOR_ASSERT(tvb && !tvb->initialized); - DISSECTOR_ASSERT(tvb->ops == get_tvb_composite_ops()); - - /* Don't allow zero-length TVBs: composite_memcpy() can't handle them - * and anyway it makes no sense. - */ - DISSECTOR_ASSERT(member->length); - - composite = &composite_tvb->composite; - composite->tvbs = g_slist_prepend(composite->tvbs, member); -} - - -void -tvb_composite_finalize(tvbuff_t *tvb) -{ - struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb; - GSList *slist; - guint num_members; - tvbuff_t *member_tvb; - tvb_comp_t *composite; - int i = 0; - - DISSECTOR_ASSERT(tvb && !tvb->initialized); - DISSECTOR_ASSERT(tvb->ops == get_tvb_composite_ops()); - DISSECTOR_ASSERT(tvb->length == 0); - DISSECTOR_ASSERT(tvb->reported_length == 0); - - composite = &composite_tvb->composite; - num_members = g_slist_length(composite->tvbs); - - /* Dissectors should not create composite TVBs if they're not going to - * put at least one TVB in them. - * (Without this check--or something similar--we'll seg-fault below.) - */ - DISSECTOR_ASSERT(num_members); - - composite->start_offsets = g_new(guint, num_members); - composite->end_offsets = g_new(guint, num_members); - - for (slist = composite->tvbs; slist != NULL; slist = slist->next) { - DISSECTOR_ASSERT((guint) i < num_members); - member_tvb = (tvbuff_t *)slist->data; - composite->start_offsets[i] = tvb->length; - tvb->length += member_tvb->length; - tvb->reported_length += member_tvb->reported_length; - composite->end_offsets[i] = tvb->length - 1; - i++; - } - tvb_add_to_chain((tvbuff_t *)composite->tvbs->data, tvb); /* chain composite tvb to first member */ - tvb->initialized = TRUE; -} - static tvbuff_t * tvb_generic_clone_offset_len(tvbuff_t *tvb, guint offset, guint len) { @@ -726,67 +607,12 @@ tvb_offset_from_real_beginning_counter(const tvbuff_t *tvb, const guint counter) return 0; } -static guint -composite_offset(const tvbuff_t *tvb, const guint counter) -{ - const struct tvb_composite *composite_tvb = (const struct tvb_composite *) tvb; - const tvbuff_t *member = (const tvbuff_t *)composite_tvb->composite.tvbs->data; - - return tvb_offset_from_real_beginning_counter(member, counter); -} - guint tvb_offset_from_real_beginning(const tvbuff_t *tvb) { return tvb_offset_from_real_beginning_counter(tvb, 0); } -static const guint8* -composite_get_ptr(tvbuff_t *tvb, guint abs_offset, guint abs_length) -{ - struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb; - guint i, num_members; - tvb_comp_t *composite; - tvbuff_t *member_tvb = NULL; - guint member_offset, member_length; - GSList *slist; - int exception; - - DISSECTOR_ASSERT(tvb->ops == get_tvb_composite_ops()); - - /* Maybe the range specified by offset/length - * is contiguous inside one of the member tvbuffs */ - composite = &composite_tvb->composite; - num_members = g_slist_length(composite->tvbs); - - for (i = 0; i < num_members; i++) { - if (abs_offset <= composite->end_offsets[i]) { - slist = g_slist_nth(composite->tvbs, i); - member_tvb = (tvbuff_t *)slist->data; - break; - } - } - DISSECTOR_ASSERT(member_tvb); - - exception = check_offset_length_no_exception(member_tvb, - abs_offset - composite->start_offsets[i], - abs_length, &member_offset, &member_length); - - if (!exception) { - /* - * The range is, in fact, contiguous within member_tvb. - */ - DISSECTOR_ASSERT(!tvb->real_data); - return ensure_contiguous_no_exception(member_tvb, member_offset, member_length, NULL); - } - else { - tvb->real_data = (guint8 *)tvb_memdup(tvb, 0, -1); - return tvb->real_data + abs_offset; - } - - DISSECTOR_ASSERT_NOT_REACHED(); -} - static const guint8* ensure_contiguous_no_exception(tvbuff_t *tvb, const gint offset, const gint length, int *pexception) { @@ -889,70 +715,6 @@ guint8_pbrk(const guint8* haystack, size_t haystacklen, const guint8 *needles, g /************** ACCESSORS **************/ -static void * -composite_memcpy(tvbuff_t *tvb, void* _target, guint abs_offset, size_t abs_length) -{ - struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb; - guint8 *target = (guint8 *) _target; - - guint i, num_members; - tvb_comp_t *composite; - tvbuff_t *member_tvb = NULL; - guint member_offset, member_length; - int exception; - GSList *slist; - - DISSECTOR_ASSERT(tvb->ops == get_tvb_composite_ops()); - - /* Maybe the range specified by offset/length - * is contiguous inside one of the member tvbuffs */ - composite = &composite_tvb->composite; - num_members = g_slist_length(composite->tvbs); - - for (i = 0; i < num_members; i++) { - if (abs_offset <= composite->end_offsets[i]) { - slist = g_slist_nth(composite->tvbs, i); - member_tvb = (tvbuff_t *)slist->data; - break; - } - } - DISSECTOR_ASSERT(member_tvb); - - exception = check_offset_length_no_exception(member_tvb, abs_offset - composite->start_offsets[i], - (gint) abs_length, &member_offset, &member_length); - - if (!exception) { - DISSECTOR_ASSERT(!tvb->real_data); - return tvb_memcpy(member_tvb, target, member_offset, member_length); - } - else { - /* The requested data is non-contiguous inside - * the member tvb. We have to memcpy() the part that's in the member tvb, - * then iterate across the other member tvb's, copying their portions - * until we have copied all data. - */ - exception = compute_offset_and_remaining(member_tvb, abs_offset - composite->start_offsets[i], - &member_offset, &member_length); - DISSECTOR_ASSERT(!exception); - - /* composite_memcpy() can't handle a member_length of zero. */ - DISSECTOR_ASSERT(member_length); - - tvb_memcpy(member_tvb, target, member_offset, member_length); - abs_offset += member_length; - abs_length -= member_length; - - /* Recurse */ - if (abs_length > 0) { - composite_memcpy(tvb, target + member_length, abs_offset, abs_length); - } - - return target; - } - - DISSECTOR_ASSERT_NOT_REACHED(); -} - void * tvb_memcpy(tvbuff_t *tvb, void *target, const gint offset, size_t length) { @@ -978,11 +740,6 @@ tvb_memcpy(tvbuff_t *tvb, void *target, const gint offset, size_t length) return memcpy(target, tvb->real_data + abs_offset, abs_length); } - if (tvb->ops == get_tvb_composite_ops()) { - /* special case for composite, bug?! */ - return composite_memcpy(tvb, target, offset, length); - } - if (tvb->ops->tvb_memcpy) return tvb->ops->tvb_memcpy(tvb, target, abs_offset, abs_length); @@ -3486,17 +3243,3 @@ tvb_get_ds_tvb(tvbuff_t *tvb) return(tvb->ds_tvb); } -static gsize composite_sizeof(void) { return sizeof(struct tvb_composite); } - -static const struct tvb_ops tvb_composite_ops = { - composite_sizeof, /* size */ - composite_free, /* free */ - composite_offset, /* offset */ - composite_get_ptr, /* get_ptr */ - NULL, /* composite_memcpy */ /* memcpy */ - NULL, /* find_guint8 XXX */ - NULL, /* pbrk_guint8 XXX */ - NULL, /* clone */ -}; - -static inline const struct tvb_ops *get_tvb_composite_ops(void) { return &tvb_composite_ops; } diff --git a/epan/tvbuff_composite.c b/epan/tvbuff_composite.c new file mode 100644 index 0000000000..8ec3cc12dc --- /dev/null +++ b/epan/tvbuff_composite.c @@ -0,0 +1,275 @@ +/* tvbuff_composite.c + * + * $Id$ + * + * Copyright (c) 2000 by Gilbert Ramirez + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include "tvbuff.h" +#include "tvbuff-int.h" +#include "proto.h" /* XXX - only used for DISSECTOR_ASSERT, probably a new header file? */ + +static gsize +composite_sizeof(void) +{ + return sizeof(struct tvb_composite); +} + +static void +composite_free(tvbuff_t *tvb) +{ + struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb; + tvb_comp_t *composite = &composite_tvb->composite; + + g_slist_free(composite->tvbs); + + g_free(composite->start_offsets); + g_free(composite->end_offsets); + if (tvb->real_data) { + /* + * XXX - do this with a union? + */ + g_free((gpointer)tvb->real_data); + } +} + +static guint +composite_offset(const tvbuff_t *tvb, const guint counter) +{ + const struct tvb_composite *composite_tvb = (const struct tvb_composite *) tvb; + const tvbuff_t *member = (const tvbuff_t *)composite_tvb->composite.tvbs->data; + + return tvb_offset_from_real_beginning_counter(member, counter); +} + +static const guint8* +composite_get_ptr(tvbuff_t *tvb, guint abs_offset, guint abs_length) +{ + struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb; + guint i, num_members; + tvb_comp_t *composite; + tvbuff_t *member_tvb = NULL; + guint member_offset; + GSList *slist; + + /* DISSECTOR_ASSERT(tvb->ops == &tvb_composite_ops); */ + + /* Maybe the range specified by offset/length + * is contiguous inside one of the member tvbuffs */ + composite = &composite_tvb->composite; + num_members = g_slist_length(composite->tvbs); + + for (i = 0; i < num_members; i++) { + if (abs_offset <= composite->end_offsets[i]) { + slist = g_slist_nth(composite->tvbs, i); + member_tvb = (tvbuff_t *)slist->data; + break; + } + } + DISSECTOR_ASSERT(member_tvb); + + member_offset = abs_offset - composite->start_offsets[i]; + + if (tvb_bytes_exist(member_tvb, member_offset, abs_length)) { + /* + * The range is, in fact, contiguous within member_tvb. + */ + DISSECTOR_ASSERT(!tvb->real_data); + return tvb_get_ptr(member_tvb, member_offset, abs_length); + } + else { + tvb->real_data = (guint8 *)tvb_memdup(tvb, 0, -1); + return tvb->real_data + abs_offset; + } + + DISSECTOR_ASSERT_NOT_REACHED(); +} + +static void * +composite_memcpy(tvbuff_t *tvb, void* _target, guint abs_offset, guint abs_length) +{ + struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb; + guint8 *target = (guint8 *) _target; + + guint i, num_members; + tvb_comp_t *composite; + tvbuff_t *member_tvb = NULL; + guint member_offset, member_length; + GSList *slist; + + /* DISSECTOR_ASSERT(tvb->ops == &tvb_composite_ops); */ + + /* Maybe the range specified by offset/length + * is contiguous inside one of the member tvbuffs */ + composite = &composite_tvb->composite; + num_members = g_slist_length(composite->tvbs); + + for (i = 0; i < num_members; i++) { + if (abs_offset <= composite->end_offsets[i]) { + slist = g_slist_nth(composite->tvbs, i); + member_tvb = (tvbuff_t *)slist->data; + break; + } + } + DISSECTOR_ASSERT(member_tvb); + + member_offset = abs_offset - composite->start_offsets[i]; + + if (tvb_bytes_exist(member_tvb, member_offset, abs_length)) { + DISSECTOR_ASSERT(!tvb->real_data); + return tvb_memcpy(member_tvb, target, member_offset, abs_length); + } + else { + /* The requested data is non-contiguous inside + * the member tvb. We have to memcpy() the part that's in the member tvb, + * then iterate across the other member tvb's, copying their portions + * until we have copied all data. + */ + member_length = tvb_length_remaining(member_tvb, member_offset); + + /* composite_memcpy() can't handle a member_length of zero. */ + DISSECTOR_ASSERT(member_length > 0); + + tvb_memcpy(member_tvb, target, member_offset, member_length); + abs_offset += member_length; + abs_length -= member_length; + + /* Recurse */ + if (abs_length > 0) { + composite_memcpy(tvb, target + member_length, abs_offset, abs_length); + } + + return target; + } + + DISSECTOR_ASSERT_NOT_REACHED(); +} + +static const struct tvb_ops tvb_composite_ops = { + composite_sizeof, /* size */ + composite_free, /* free */ + composite_offset, /* offset */ + composite_get_ptr, /* get_ptr */ + composite_memcpy, /* memcpy */ + NULL, /* find_guint8 XXX */ + NULL, /* pbrk_guint8 XXX */ + NULL, /* clone */ +}; + +/* + * Composite tvb + * + * 1. A composite tvb is automatically chained to its first member when the + * tvb is finalized. + * This means that composite tvb members must all be in the same chain. + * ToDo: enforce this: By searching the chain? + */ +tvbuff_t * +tvb_new_composite(void) +{ + tvbuff_t *tvb = tvb_new(&tvb_composite_ops); + struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb; + tvb_comp_t *composite = &composite_tvb->composite; + + composite->tvbs = NULL; + composite->start_offsets = NULL; + composite->end_offsets = NULL; + + return tvb; +} + +void +tvb_composite_append(tvbuff_t *tvb, tvbuff_t *member) +{ + struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb; + tvb_comp_t *composite; + + DISSECTOR_ASSERT(tvb && !tvb->initialized); + DISSECTOR_ASSERT(tvb->ops == &tvb_composite_ops); + + /* Don't allow zero-length TVBs: composite_memcpy() can't handle them + * and anyway it makes no sense. + */ + DISSECTOR_ASSERT(member->length); + + composite = &composite_tvb->composite; + composite->tvbs = g_slist_append(composite->tvbs, member); +} + +void +tvb_composite_prepend(tvbuff_t *tvb, tvbuff_t *member) +{ + struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb; + tvb_comp_t *composite; + + DISSECTOR_ASSERT(tvb && !tvb->initialized); + DISSECTOR_ASSERT(tvb->ops == &tvb_composite_ops); + + /* Don't allow zero-length TVBs: composite_memcpy() can't handle them + * and anyway it makes no sense. + */ + DISSECTOR_ASSERT(member->length); + + composite = &composite_tvb->composite; + composite->tvbs = g_slist_prepend(composite->tvbs, member); +} + +void +tvb_composite_finalize(tvbuff_t *tvb) +{ + struct tvb_composite *composite_tvb = (struct tvb_composite *) tvb; + GSList *slist; + guint num_members; + tvbuff_t *member_tvb; + tvb_comp_t *composite; + int i = 0; + + DISSECTOR_ASSERT(tvb && !tvb->initialized); + DISSECTOR_ASSERT(tvb->ops == &tvb_composite_ops); + DISSECTOR_ASSERT(tvb->length == 0); + DISSECTOR_ASSERT(tvb->reported_length == 0); + + composite = &composite_tvb->composite; + num_members = g_slist_length(composite->tvbs); + + /* Dissectors should not create composite TVBs if they're not going to + * put at least one TVB in them. + * (Without this check--or something similar--we'll seg-fault below.) + */ + DISSECTOR_ASSERT(num_members); + + composite->start_offsets = g_new(guint, num_members); + composite->end_offsets = g_new(guint, num_members); + + for (slist = composite->tvbs; slist != NULL; slist = slist->next) { + DISSECTOR_ASSERT((guint) i < num_members); + member_tvb = (tvbuff_t *)slist->data; + composite->start_offsets[i] = tvb->length; + tvb->length += member_tvb->length; + tvb->reported_length += member_tvb->reported_length; + composite->end_offsets[i] = tvb->length - 1; + i++; + } + tvb_add_to_chain((tvbuff_t *)composite->tvbs->data, tvb); /* chain composite tvb to first member */ + tvb->initialized = TRUE; +}