3 * Testy, Virtual(-izable) Buffer of guint8*'s
5 * "Testy" -- the buffer gets mad when an attempt to access data
6 * beyond the bounds of the buffer. An exception is thrown.
8 * "Virtual" -- the buffer can have its own data, can use a subset of
9 * the data of a backing tvbuff, or can be a composite of
14 * Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
16 * Code to convert IEEE floating point formats to native floating point
17 * derived from code Copyright (c) Ashok Narayanan, 2000
19 * Wireshark - Network traffic analyzer
20 * By Gerald Combs <gerald@wireshark.org>
21 * Copyright 1998 Gerald Combs
23 * This program is free software; you can redistribute it and/or
24 * modify it under the terms of the GNU General Public License
25 * as published by the Free Software Foundation; either version 2
26 * of the License, or (at your option) any later version.
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the Free Software
35 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
52 #include "proto.h" /* XXX - only used for DISSECTOR_ASSERT, probably a new header file? */
55 ensure_contiguous_no_exception(tvbuff_t *tvb, const gint offset, const gint length,
59 ensure_contiguous(tvbuff_t *tvb, const gint offset, const gint length);
61 #if GLIB_CHECK_VERSION(2,10,0)
63 /* We dole out tvbuff's from this memchunk. */
64 static GMemChunk *tvbuff_mem_chunk = NULL;
70 #if GLIB_CHECK_VERSION(2,10,0)
72 if (!tvbuff_mem_chunk)
73 tvbuff_mem_chunk = g_mem_chunk_create(tvbuff_t, 20, G_ALLOC_AND_FREE);
80 #if GLIB_CHECK_VERSION(2,10,0)
83 g_mem_chunk_destroy(tvbuff_mem_chunk);
85 tvbuff_mem_chunk = NULL;
90 tvb_init(tvbuff_t *tvb, const tvbuff_type type)
92 tvb_backing_t *backing;
93 tvb_comp_t *composite;
96 tvb->initialized = FALSE;
99 tvb->reported_length = 0;
101 tvb->real_data = NULL;
102 tvb->raw_offset = -1;
107 case TVBUFF_REAL_DATA:
112 backing = &tvb->tvbuffs.subset;
118 case TVBUFF_COMPOSITE:
119 composite = &tvb->tvbuffs.composite;
120 composite->tvbs = NULL;
121 composite->start_offsets = NULL;
122 composite->end_offsets = NULL;
126 DISSECTOR_ASSERT_NOT_REACHED();
133 tvb_new(const tvbuff_type type)
137 #if GLIB_CHECK_VERSION(2,10,0)
138 tvb = g_slice_new(tvbuff_t);
140 tvb = g_chunk_new(tvbuff_t, tvbuff_mem_chunk);
149 tvb_new_with_subset(const guint subset_tvb_offset, const guint subset_tvb_length)
151 tvbuff_t *tvb = tvb_new(TVBUFF_SUBSET);
152 tvb->tvbuffs.subset.offset = subset_tvb_offset;
153 tvb->tvbuffs.subset.length = subset_tvb_length;
159 tvb_free(tvbuff_t* tvb)
161 tvbuff_t *member_tvb;
162 tvb_comp_t *composite;
167 if (tvb->usage_count == 0) {
169 case TVBUFF_REAL_DATA:
172 * XXX - do this with a union?
174 tvb->free_cb((gpointer)tvb->real_data);
179 /* This will be NULL if tvb_new_subset() fails because
180 * reported_length < -1 */
181 if (tvb->tvbuffs.subset.tvb) {
182 tvb_decrement_usage_count(tvb->tvbuffs.subset.tvb, 1);
186 case TVBUFF_COMPOSITE:
187 composite = &tvb->tvbuffs.composite;
188 for (slist = composite->tvbs; slist != NULL ; slist = slist->next) {
189 member_tvb = slist->data;
190 tvb_decrement_usage_count(member_tvb, 1);
193 g_slist_free(composite->tvbs);
195 g_free(composite->start_offsets);
196 g_free(composite->end_offsets);
197 if (tvb->real_data) {
199 * XXX - do this with a union?
201 g_free((gpointer)tvb->real_data);
208 g_slist_free(tvb->used_in);
211 #if GLIB_CHECK_VERSION(2,10,0)
212 g_slice_free(tvbuff_t, tvb);
214 g_chunk_free(tvb, tvbuff_mem_chunk);
220 tvb_increment_usage_count(tvbuff_t* tvb, const guint count)
222 tvb->usage_count += count;
224 return tvb->usage_count;
228 tvb_decrement_usage_count(tvbuff_t* tvb, const guint count)
230 if (tvb->usage_count <= count) {
231 tvb->usage_count = 1;
236 tvb->usage_count -= count;
237 return tvb->usage_count;
243 tvb_free_chain(tvbuff_t* tvb)
247 /* Recursively call tvb_free_chain() */
248 for (slist = tvb->used_in; slist != NULL ; slist = slist->next) {
249 tvb_free_chain( (tvbuff_t*)slist->data );
252 /* Stop the recursion */
259 tvb_set_free_cb(tvbuff_t* tvb, const tvbuff_free_cb_t func)
261 DISSECTOR_ASSERT(tvb);
262 DISSECTOR_ASSERT(tvb->type == TVBUFF_REAL_DATA);
267 add_to_used_in_list(tvbuff_t *tvb, tvbuff_t *used_in)
269 tvb->used_in = g_slist_prepend(tvb->used_in, used_in);
270 tvb_increment_usage_count(tvb, 1);
274 tvb_set_child_real_data_tvbuff(tvbuff_t* parent, tvbuff_t* child)
276 DISSECTOR_ASSERT(parent && child);
277 DISSECTOR_ASSERT(parent->initialized);
278 DISSECTOR_ASSERT(child->initialized);
279 DISSECTOR_ASSERT(child->type == TVBUFF_REAL_DATA);
280 add_to_used_in_list(parent, child);
284 tvb_set_real_data_no_exceptions(tvbuff_t* tvb, const guint8* data, const guint length, const gint reported_length)
286 tvb->real_data = data;
287 tvb->length = length;
288 tvb->reported_length = reported_length;
289 tvb->initialized = TRUE;
293 tvb_set_real_data(tvbuff_t* tvb, const guint8* data, const guint length, const gint reported_length)
295 DISSECTOR_ASSERT(tvb);
296 DISSECTOR_ASSERT(tvb->type == TVBUFF_REAL_DATA);
297 DISSECTOR_ASSERT(!tvb->initialized);
299 THROW_ON(reported_length < -1, ReportedBoundsError);
301 tvb_set_real_data_no_exceptions(tvb, data, length, reported_length);
305 tvb_new_real_data(const guint8* data, const guint length, const gint reported_length)
309 THROW_ON(reported_length < -1, ReportedBoundsError);
311 tvb = tvb_new(TVBUFF_REAL_DATA);
313 tvb_set_real_data_no_exceptions(tvb, data, length, reported_length);
316 * This is the top-level real tvbuff for this data source,
317 * so its data source tvbuff is itself.
325 tvb_new_child_real_data(tvbuff_t *parent, const guint8* data, const guint length, const gint reported_length)
327 tvbuff_t *tvb = tvb_new_real_data(data, length, reported_length);
329 tvb_set_child_real_data_tvbuff (parent, tvb);
335 /* Computes the absolute offset and length based on a possibly-negative offset
336 * and a length that is possible -1 (which means "to the end of the data").
337 * Returns TRUE/FALSE indicating whether the offset is in bounds or
338 * not. The integer ptrs are modified with the new offset and length.
339 * No exception is thrown.
341 * XXX - we return TRUE, not FALSE, if the offset is positive and right
342 * after the end of the tvbuff (i.e., equal to the length). We do this
343 * so that a dissector constructing a subset tvbuff for the next protocol
344 * will get a zero-length tvbuff, not an exception, if there's no data
345 * left for the next protocol - we want the next protocol to be the one
346 * that gets an exception, so the error is reported as an error in that
347 * protocol rather than the containing protocol. */
349 compute_offset_length(const guint tvb_length_val, const guint tvb_reported_length_val, const gint offset, const gint length_val,
350 guint *offset_ptr, guint *length_ptr, int *exception)
352 DISSECTOR_ASSERT(offset_ptr);
353 DISSECTOR_ASSERT(length_ptr);
355 /* Compute the offset */
357 /* Positive offset - relative to the beginning of the packet. */
358 if ((guint) offset > tvb_reported_length_val) {
360 *exception = ReportedBoundsError;
364 else if ((guint) offset > tvb_length_val) {
366 *exception = BoundsError;
371 *offset_ptr = offset;
375 /* Negative offset - relative to the end of the packet. */
376 if ((guint) -offset > tvb_reported_length_val) {
378 *exception = ReportedBoundsError;
382 else if ((guint) -offset > tvb_length_val) {
384 *exception = BoundsError;
389 *offset_ptr = tvb_length_val + offset;
393 /* Compute the length */
394 if (length_val < -1) {
396 /* XXX - ReportedBoundsError? */
397 *exception = BoundsError;
401 else if (length_val == -1) {
402 *length_ptr = tvb_length_val - *offset_ptr;
405 *length_ptr = length_val;
413 check_offset_length_no_exception(const guint tvb_length_val, const guint tvb_reported_length_val, const gint offset, gint const length_val,
414 guint *offset_ptr, guint *length_ptr, int *exception)
418 if (!compute_offset_length(tvb_length_val, tvb_reported_length_val, offset, length_val, offset_ptr, length_ptr, exception)) {
423 * Compute the offset of the first byte past the length.
425 end_offset = *offset_ptr + *length_ptr;
428 * Check for an overflow, and clamp "end_offset" at the maximum
429 * if we got an overflow - that should force us to indicate that
430 * we're past the end of the tvbuff.
432 if (end_offset < *offset_ptr)
433 end_offset = UINT_MAX;
436 * Check whether that offset goes more than one byte past the
439 * If not, return TRUE; otherwise, return FALSE and, if "exception"
440 * is non-null, return the appropriate exception through it.
442 if (end_offset <= tvb_length_val) {
445 else if (end_offset <= tvb_reported_length_val) {
447 *exception = BoundsError;
452 *exception = ReportedBoundsError;
459 /* Checks (+/-) offset and length and throws an exception if
460 * either is out of bounds. Sets integer ptrs to the new offset
463 check_offset_length(const guint tvb_length_val, const guint tvb_reported_length_val, const gint offset, gint const length_val,
464 guint *offset_ptr, guint *length_ptr)
468 if (!check_offset_length_no_exception(tvb_length_val, tvb_reported_length_val, offset, length_val, offset_ptr, length_ptr, &exception)) {
469 DISSECTOR_ASSERT(exception > 0);
475 tvb_set_subset_no_exceptions(tvbuff_t *tvb, tvbuff_t *backing, const gint reported_length)
477 tvb->tvbuffs.subset.tvb = backing;
478 tvb->length = tvb->tvbuffs.subset.length;
480 if (reported_length == -1) {
481 tvb->reported_length = backing->reported_length - tvb->tvbuffs.subset.offset;
484 tvb->reported_length = reported_length;
486 tvb->initialized = TRUE;
487 add_to_used_in_list(backing, tvb);
489 /* Optimization. If the backing buffer has a pointer to contiguous, real data,
490 * then we can point directly to our starting offset in that buffer */
491 if (backing->real_data != NULL) {
492 tvb->real_data = backing->real_data + tvb->tvbuffs.subset.offset;
497 tvb_set_subset(tvbuff_t *tvb, tvbuff_t *backing,
498 const gint backing_offset, const gint backing_length, const gint reported_length)
500 DISSECTOR_ASSERT(tvb);
501 DISSECTOR_ASSERT(tvb->type == TVBUFF_SUBSET);
502 DISSECTOR_ASSERT(!tvb->initialized);
504 THROW_ON(reported_length < -1, ReportedBoundsError);
506 check_offset_length(backing->length, backing->reported_length, backing_offset, backing_length,
507 &tvb->tvbuffs.subset.offset,
508 &tvb->tvbuffs.subset.length);
510 tvb_set_subset_no_exceptions(tvb, backing, reported_length);
514 tvb_new_subset(tvbuff_t *backing, const gint backing_offset, const gint backing_length, const gint reported_length)
517 guint subset_tvb_offset;
518 guint subset_tvb_length;
520 DISSECTOR_ASSERT(backing && backing->initialized);
522 THROW_ON(reported_length < -1, ReportedBoundsError);
524 check_offset_length(backing->length, backing->reported_length, backing_offset, backing_length,
528 tvb = tvb_new_with_subset(subset_tvb_offset, subset_tvb_length);
530 tvb_set_subset_no_exceptions(tvb, backing, reported_length);
533 * The top-level data source of this tvbuff is the top-level
534 * data source of its parent.
536 tvb->ds_tvb = backing->ds_tvb;
542 tvb_new_subset_remaining(tvbuff_t *backing, const gint backing_offset)
545 guint subset_tvb_offset;
546 guint subset_tvb_length;
548 check_offset_length(backing->length, backing->reported_length, backing_offset, -1 /* backing_length */,
552 tvb = tvb_new_with_subset(subset_tvb_offset, subset_tvb_length);
554 tvb_set_subset_no_exceptions(tvb, backing, -1 /* reported_length */);
557 * The top-level data source of this tvbuff is the top-level
558 * data source of its parent.
560 tvb->ds_tvb = backing->ds_tvb;
566 tvb_composite_append(tvbuff_t* tvb, tvbuff_t* member)
568 tvb_comp_t *composite;
570 DISSECTOR_ASSERT(tvb && !tvb->initialized);
571 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
572 composite = &tvb->tvbuffs.composite;
573 composite->tvbs = g_slist_append( composite->tvbs, member );
574 add_to_used_in_list(tvb, member);
578 tvb_composite_prepend(tvbuff_t* tvb, tvbuff_t* member)
580 tvb_comp_t *composite;
582 DISSECTOR_ASSERT(tvb && !tvb->initialized);
583 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
584 composite = &tvb->tvbuffs.composite;
585 composite->tvbs = g_slist_prepend( composite->tvbs, member );
586 add_to_used_in_list(tvb, member);
590 tvb_new_composite(void)
592 return tvb_new(TVBUFF_COMPOSITE);
596 tvb_composite_finalize(tvbuff_t* tvb)
600 tvbuff_t *member_tvb;
601 tvb_comp_t *composite;
604 DISSECTOR_ASSERT(tvb && !tvb->initialized);
605 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
606 DISSECTOR_ASSERT(tvb->length == 0);
608 composite = &tvb->tvbuffs.composite;
609 num_members = g_slist_length(composite->tvbs);
611 composite->start_offsets = g_new(guint, num_members);
612 composite->end_offsets = g_new(guint, num_members);
614 for (slist = composite->tvbs; slist != NULL; slist = slist->next) {
615 DISSECTOR_ASSERT((guint) i < num_members);
616 member_tvb = slist->data;
617 composite->start_offsets[i] = tvb->length;
618 tvb->length += member_tvb->length;
619 composite->end_offsets[i] = tvb->length - 1;
623 tvb->initialized = TRUE;
629 tvb_length(const tvbuff_t* tvb)
631 DISSECTOR_ASSERT(tvb && tvb->initialized);
637 tvb_length_remaining(const tvbuff_t *tvb, const gint offset)
639 guint abs_offset, abs_length;
641 DISSECTOR_ASSERT(tvb && tvb->initialized);
643 if (compute_offset_length(tvb->length, tvb->reported_length, offset, -1, &abs_offset, &abs_length, NULL)) {
652 tvb_ensure_length_remaining(const tvbuff_t *tvb, const gint offset)
654 guint abs_offset, abs_length;
657 DISSECTOR_ASSERT(tvb && tvb->initialized);
659 if (!compute_offset_length(tvb->length, tvb->reported_length, offset, -1, &abs_offset, &abs_length, &exception)) {
662 if (abs_length == 0) {
664 * This routine ensures there's at least one byte available.
665 * There aren't any bytes available, so throw the appropriate
668 if (abs_offset >= tvb->reported_length)
669 THROW(ReportedBoundsError);
679 /* Validates that 'length' bytes are available starting from
680 * offset (pos/neg). Does not throw an exception. */
682 tvb_bytes_exist(const tvbuff_t *tvb, const gint offset, const gint length)
684 guint abs_offset, abs_length;
686 DISSECTOR_ASSERT(tvb && tvb->initialized);
688 if (!compute_offset_length(tvb->length, tvb->reported_length, offset, length, &abs_offset, &abs_length, NULL))
691 if (abs_offset + abs_length <= tvb->length) {
699 /* Validates that 'length' bytes are available starting from
700 * offset (pos/neg). Throws an exception if they aren't. */
702 tvb_ensure_bytes_exist(const tvbuff_t *tvb, const gint offset, const gint length)
704 guint abs_offset, abs_length;
706 DISSECTOR_ASSERT(tvb && tvb->initialized);
709 * -1 doesn't mean "until end of buffer", as that's pointless
710 * for this routine. We must treat it as a Really Large Positive
711 * Number, so that we throw an exception; we throw
712 * ReportedBoundsError, as if it were past even the end of a
713 * reassembled packet, and past the end of even the data we
716 * We do the same with other negative lengths.
719 THROW(ReportedBoundsError);
721 check_offset_length(tvb->length, tvb->reported_length, offset, length, &abs_offset, &abs_length);
725 tvb_offset_exists(const tvbuff_t *tvb, const gint offset)
727 guint abs_offset, abs_length;
729 DISSECTOR_ASSERT(tvb && tvb->initialized);
730 if (!compute_offset_length(tvb->length, tvb->reported_length, offset, -1, &abs_offset, &abs_length, NULL))
733 if (abs_offset < tvb->length) {
742 tvb_reported_length(const tvbuff_t* tvb)
744 DISSECTOR_ASSERT(tvb && tvb->initialized);
746 return tvb->reported_length;
750 tvb_reported_length_remaining(const tvbuff_t *tvb, const gint offset)
752 guint abs_offset, abs_length;
754 DISSECTOR_ASSERT(tvb && tvb->initialized);
756 if (compute_offset_length(tvb->length, tvb->reported_length, offset, -1, &abs_offset, &abs_length, NULL)) {
757 if (tvb->reported_length >= abs_offset)
758 return tvb->reported_length - abs_offset;
767 /* Set the reported length of a tvbuff to a given value; used for protocols
768 whose headers contain an explicit length and where the calling
769 dissector's payload may include padding as well as the packet for
772 Also adjusts the data length. */
774 tvb_set_reported_length(tvbuff_t* tvb, const guint reported_length)
776 DISSECTOR_ASSERT(tvb && tvb->initialized);
778 if (reported_length > tvb->reported_length)
779 THROW(ReportedBoundsError);
781 tvb->reported_length = reported_length;
782 if (reported_length < tvb->length)
783 tvb->length = reported_length;
789 first_real_data_ptr(tvbuff_t *tvb)
794 case TVBUFF_REAL_DATA:
795 return tvb->real_data;
797 member = tvb->tvbuffs.subset.tvb;
798 return first_real_data_ptr(member);
799 case TVBUFF_COMPOSITE:
800 member = tvb->tvbuffs.composite.tvbs->data;
801 return first_real_data_ptr(member);
804 DISSECTOR_ASSERT_NOT_REACHED();
810 offset_from_real_beginning(const tvbuff_t *tvb, const guint counter)
815 case TVBUFF_REAL_DATA:
818 member = tvb->tvbuffs.subset.tvb;
819 return offset_from_real_beginning(member, counter + tvb->tvbuffs.subset.offset);
820 case TVBUFF_COMPOSITE:
821 member = tvb->tvbuffs.composite.tvbs->data;
822 return offset_from_real_beginning(member, counter);
825 DISSECTOR_ASSERT_NOT_REACHED();
830 tvb_offset_from_real_beginning(const tvbuff_t *tvb)
832 return offset_from_real_beginning(tvb, 0);
836 composite_ensure_contiguous_no_exception(tvbuff_t *tvb, const guint abs_offset,
837 const guint abs_length)
839 guint i, num_members;
840 tvb_comp_t *composite;
841 tvbuff_t *member_tvb = NULL;
842 guint member_offset, member_length;
845 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
847 /* Maybe the range specified by offset/length
848 * is contiguous inside one of the member tvbuffs */
849 composite = &tvb->tvbuffs.composite;
850 num_members = g_slist_length(composite->tvbs);
852 for (i = 0; i < num_members; i++) {
853 if (abs_offset <= composite->end_offsets[i]) {
854 slist = g_slist_nth(composite->tvbs, i);
855 member_tvb = slist->data;
859 DISSECTOR_ASSERT(member_tvb);
861 if (check_offset_length_no_exception(member_tvb->length, member_tvb->reported_length, abs_offset - composite->start_offsets[i],
862 abs_length, &member_offset, &member_length, NULL)) {
865 * The range is, in fact, contiguous within member_tvb.
867 DISSECTOR_ASSERT(!tvb->real_data);
868 return ensure_contiguous_no_exception(member_tvb, member_offset, member_length, NULL);
871 tvb->real_data = tvb_memdup(tvb, 0, -1);
872 return tvb->real_data + abs_offset;
875 DISSECTOR_ASSERT_NOT_REACHED();
880 ensure_contiguous_no_exception(tvbuff_t *tvb, const gint offset, const gint length,
883 guint abs_offset, abs_length;
885 if (!check_offset_length_no_exception(tvb->length, tvb->reported_length, offset, length,
886 &abs_offset, &abs_length, exception)) {
891 * We know that all the data is present in the tvbuff, so
892 * no exceptions should be thrown.
894 if (tvb->real_data) {
895 return tvb->real_data + abs_offset;
899 case TVBUFF_REAL_DATA:
900 DISSECTOR_ASSERT_NOT_REACHED();
902 return ensure_contiguous_no_exception(tvb->tvbuffs.subset.tvb,
903 abs_offset - tvb->tvbuffs.subset.offset,
905 case TVBUFF_COMPOSITE:
906 return composite_ensure_contiguous_no_exception(tvb, abs_offset, abs_length);
910 DISSECTOR_ASSERT_NOT_REACHED();
915 ensure_contiguous(tvbuff_t *tvb, const gint offset, const gint length)
920 p = ensure_contiguous_no_exception(tvb, offset, length, &exception);
922 DISSECTOR_ASSERT(exception > 0);
929 fast_ensure_contiguous(tvbuff_t *tvb, const gint offset, const guint length)
934 DISSECTOR_ASSERT(tvb && tvb->initialized);
935 /* We don't check for overflow in this fast path so we only handle simple types */
936 DISSECTOR_ASSERT(length <= 8);
938 if (offset < 0 || !tvb->real_data) {
939 return ensure_contiguous(tvb, offset, length);
943 end_offset = u_offset + length;
945 if (end_offset <= tvb->length) {
946 return tvb->real_data + u_offset;
949 if (end_offset > tvb->reported_length) {
950 THROW(ReportedBoundsError);
958 guint8_pbrk(const guint8* haystack, size_t haystacklen, const guint8 *needles, guchar *found_needle)
960 gchar tmp[256] = { 0 };
961 const guint8 *haystack_end;
966 haystack_end = haystack + haystacklen;
967 while (haystack < haystack_end) {
968 if (tmp[*haystack]) {
970 *found_needle = *haystack;
981 /************** ACCESSORS **************/
984 composite_memcpy(tvbuff_t *tvb, guint8* target, guint abs_offset, size_t abs_length)
986 guint i, num_members;
987 tvb_comp_t *composite;
988 tvbuff_t *member_tvb = NULL;
989 guint member_offset, member_length;
993 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
995 /* Maybe the range specified by offset/length
996 * is contiguous inside one of the member tvbuffs */
997 composite = &tvb->tvbuffs.composite;
998 num_members = g_slist_length(composite->tvbs);
1000 for (i = 0; i < num_members; i++) {
1001 if (abs_offset <= composite->end_offsets[i]) {
1002 slist = g_slist_nth(composite->tvbs, i);
1003 member_tvb = slist->data;
1007 DISSECTOR_ASSERT(member_tvb);
1009 if (check_offset_length_no_exception(member_tvb->length, member_tvb->reported_length, abs_offset - composite->start_offsets[i],
1010 (gint) abs_length, &member_offset, &member_length, NULL)) {
1012 DISSECTOR_ASSERT(!tvb->real_data);
1013 return tvb_memcpy(member_tvb, target, member_offset, member_length);
1016 /* The requested data is non-contiguous inside
1017 * the member tvb. We have to memcpy() the part that's in the member tvb,
1018 * then iterate across the other member tvb's, copying their portions
1019 * until we have copied all data.
1021 retval = compute_offset_length(member_tvb->length, member_tvb->reported_length, abs_offset - composite->start_offsets[i], -1,
1022 &member_offset, &member_length, NULL);
1023 DISSECTOR_ASSERT(retval);
1025 tvb_memcpy(member_tvb, target, member_offset, member_length);
1026 abs_offset += member_length;
1027 abs_length -= member_length;
1030 if (abs_length > 0) {
1031 composite_memcpy(tvb, target + member_length, abs_offset, abs_length);
1037 DISSECTOR_ASSERT_NOT_REACHED();
1042 tvb_memcpy(tvbuff_t *tvb, void* target, const gint offset, size_t length)
1044 guint abs_offset, abs_length;
1046 DISSECTOR_ASSERT(tvb && tvb->initialized);
1049 * XXX - we should eliminate the "length = -1 means 'to the end
1050 * of the tvbuff'" convention, and use other means to achieve
1051 * that; this would let us eliminate a bunch of checks for
1052 * negative lengths in cases where the protocol has a 32-bit
1055 * Allowing -1 but throwing an assertion on other negative
1056 * lengths is a bit more work with the length being a size_t;
1057 * instead, we check for a length <= 2^31-1.
1059 DISSECTOR_ASSERT(length <= 0x7FFFFFFF);
1060 check_offset_length(tvb->length, tvb->reported_length, offset, (gint) length, &abs_offset, &abs_length);
1062 if (tvb->real_data) {
1063 return memcpy(target, tvb->real_data + abs_offset, abs_length);
1067 case TVBUFF_REAL_DATA:
1068 DISSECTOR_ASSERT_NOT_REACHED();
1071 return tvb_memcpy(tvb->tvbuffs.subset.tvb, target,
1072 abs_offset - tvb->tvbuffs.subset.offset,
1075 case TVBUFF_COMPOSITE:
1076 return composite_memcpy(tvb, target, offset, length);
1079 DISSECTOR_ASSERT_NOT_REACHED();
1085 * XXX - this doesn't treat a length of -1 as an error.
1086 * If it did, this could replace some code that calls
1087 * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies
1090 * "composite_ensure_contiguous_no_exception()" depends on -1 not being
1091 * an error; does anything else depend on this routine treating -1 as
1092 * meaning "to the end of the buffer"?
1095 tvb_memdup(tvbuff_t *tvb, const gint offset, size_t length)
1097 guint abs_offset, abs_length;
1100 DISSECTOR_ASSERT(tvb && tvb->initialized);
1102 check_offset_length(tvb->length, tvb->reported_length, offset, (gint) length, &abs_offset, &abs_length);
1104 duped = g_malloc(abs_length);
1105 return tvb_memcpy(tvb, duped, abs_offset, abs_length);
1109 * XXX - this doesn't treat a length of -1 as an error.
1110 * If it did, this could replace some code that calls
1111 * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies
1114 * "composite_ensure_contiguous_no_exception()" depends on -1 not being
1115 * an error; does anything else depend on this routine treating -1 as
1116 * meaning "to the end of the buffer"?
1118 * This function allocates memory from a buffer with packet lifetime.
1119 * You do not have to free this buffer, it will be automatically freed
1120 * when wireshark starts decoding the next packet.
1121 * Do not use this function if you want the allocated memory to be persistent
1122 * after the current packet has been dissected.
1125 ep_tvb_memdup(tvbuff_t *tvb, const gint offset, size_t length)
1127 guint abs_offset, abs_length;
1130 DISSECTOR_ASSERT(tvb && tvb->initialized);
1132 check_offset_length(tvb->length, tvb->reported_length, offset, (gint) length, &abs_offset, &abs_length);
1134 duped = ep_alloc(abs_length);
1135 return tvb_memcpy(tvb, duped, abs_offset, abs_length);
1141 tvb_get_ptr(tvbuff_t *tvb, const gint offset, const gint length)
1143 return ensure_contiguous(tvb, offset, length);
1146 /* ---------------- */
1148 tvb_get_guint8(tvbuff_t *tvb, const gint offset)
1152 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint8));
1157 tvb_get_ntohs(tvbuff_t *tvb, const gint offset)
1161 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint16));
1166 tvb_get_ntoh24(tvbuff_t *tvb, const gint offset)
1170 ptr = fast_ensure_contiguous(tvb, offset, 3);
1171 return pntoh24(ptr);
1175 tvb_get_ntohl(tvbuff_t *tvb, const gint offset)
1179 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1184 tvb_get_ntoh64(tvbuff_t *tvb, const gint offset)
1188 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint64));
1189 return pntoh64(ptr);
1193 * Stuff for IEEE float handling on platforms that don't have IEEE
1194 * format as the native floating-point format.
1196 * For now, we treat only the VAX as such a platform.
1198 * XXX - other non-IEEE boxes that can run UNIX include some Crays,
1199 * and possibly other machines.
1201 * It appears that the official Linux port to System/390 and
1202 * zArchitecture uses IEEE format floating point (not a
1205 * I don't know whether there are any other machines that
1206 * could run Wireshark and that don't use IEEE format.
1207 * As far as I know, all of the main commercial microprocessor
1208 * families on which OSes that support Wireshark can run
1209 * use IEEE format (x86, 68k, SPARC, MIPS, PA-RISC, Alpha,
1210 * IA-64, and so on).
1220 #define IEEE_SP_NUMBER_WIDTH 32 /* bits in number */
1221 #define IEEE_SP_EXP_WIDTH 8 /* bits in exponent */
1222 #define IEEE_SP_MANTISSA_WIDTH 23 /* IEEE_SP_NUMBER_WIDTH - 1 - IEEE_SP_EXP_WIDTH */
1224 #define IEEE_SP_SIGN_MASK 0x80000000
1225 #define IEEE_SP_EXPONENT_MASK 0x7F800000
1226 #define IEEE_SP_MANTISSA_MASK 0x007FFFFF
1227 #define IEEE_SP_INFINITY IEEE_SP_EXPONENT_MASK
1229 #define IEEE_SP_IMPLIED_BIT (1 << IEEE_SP_MANTISSA_WIDTH)
1230 #define IEEE_SP_INFINITE ((1 << IEEE_SP_EXP_WIDTH) - 1)
1231 #define IEEE_SP_BIAS ((1 << (IEEE_SP_EXP_WIDTH - 1)) - 1)
1234 ieee_float_is_zero(const guint32 w)
1236 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1240 get_ieee_float(const guint32 w)
1246 sign = w & IEEE_SP_SIGN_MASK;
1247 exponent = w & IEEE_SP_EXPONENT_MASK;
1248 mantissa = w & IEEE_SP_MANTISSA_MASK;
1250 if (ieee_float_is_zero(w)) {
1251 /* number is zero, unnormalized, or not-a-number */
1256 * XXX - how to handle this?
1258 if (IEEE_SP_INFINITY == exponent) {
1260 * number is positive or negative infinity, or a special value
1262 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1266 exponent = ((exponent >> IEEE_SP_MANTISSA_WIDTH) - IEEE_SP_BIAS) -
1267 IEEE_SP_MANTISSA_WIDTH;
1268 mantissa |= IEEE_SP_IMPLIED_BIT;
1271 return -mantissa * pow(2, exponent);
1273 return mantissa * pow(2, exponent);
1278 * We assume that if you don't have IEEE floating-point, you have a
1279 * compiler that understands 64-bit integral quantities.
1281 #define IEEE_DP_NUMBER_WIDTH 64 /* bits in number */
1282 #define IEEE_DP_EXP_WIDTH 11 /* bits in exponent */
1283 #define IEEE_DP_MANTISSA_WIDTH 52 /* IEEE_DP_NUMBER_WIDTH - 1 - IEEE_DP_EXP_WIDTH */
1285 #define IEEE_DP_SIGN_MASK 0x8000000000000000LL
1286 #define IEEE_DP_EXPONENT_MASK 0x7FF0000000000000LL
1287 #define IEEE_DP_MANTISSA_MASK 0x000FFFFFFFFFFFFFLL
1288 #define IEEE_DP_INFINITY IEEE_DP_EXPONENT_MASK
1290 #define IEEE_DP_IMPLIED_BIT (1LL << IEEE_DP_MANTISSA_WIDTH)
1291 #define IEEE_DP_INFINITE ((1 << IEEE_DP_EXP_WIDTH) - 1)
1292 #define IEEE_DP_BIAS ((1 << (IEEE_DP_EXP_WIDTH - 1)) - 1)
1295 ieee_double_is_zero(const guint64 w)
1297 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1301 get_ieee_double(const guint64 w)
1307 sign = w & IEEE_DP_SIGN_MASK;
1308 exponent = w & IEEE_DP_EXPONENT_MASK;
1309 mantissa = w & IEEE_DP_MANTISSA_MASK;
1311 if (ieee_double_is_zero(w)) {
1312 /* number is zero, unnormalized, or not-a-number */
1317 * XXX - how to handle this?
1319 if (IEEE_DP_INFINITY == exponent) {
1321 * number is positive or negative infinity, or a special value
1323 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1327 exponent = ((exponent >> IEEE_DP_MANTISSA_WIDTH) - IEEE_DP_BIAS) -
1328 IEEE_DP_MANTISSA_WIDTH;
1329 mantissa |= IEEE_DP_IMPLIED_BIT;
1332 return -mantissa * pow(2, exponent);
1334 return mantissa * pow(2, exponent);
1339 * Fetches an IEEE single-precision floating-point number, in
1340 * big-endian form, and returns a "float".
1342 * XXX - should this be "double", in case there are IEEE single-
1343 * precision numbers that won't fit in some platform's native
1347 tvb_get_ntohieee_float(tvbuff_t *tvb, const int offset)
1350 return get_ieee_float(tvb_get_ntohl(tvb, offset));
1357 ieee_fp_union.w = tvb_get_ntohl(tvb, offset);
1358 return ieee_fp_union.f;
1363 * Fetches an IEEE double-precision floating-point number, in
1364 * big-endian form, and returns a "double".
1367 tvb_get_ntohieee_double(tvbuff_t *tvb, const int offset)
1381 #ifdef WORDS_BIGENDIAN
1382 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset);
1383 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset+4);
1385 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset+4);
1386 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset);
1389 return get_ieee_double(ieee_fp_union.dw);
1391 return ieee_fp_union.d;
1396 tvb_get_letohs(tvbuff_t *tvb, const gint offset)
1400 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint16));
1401 return pletohs(ptr);
1405 tvb_get_letoh24(tvbuff_t *tvb, const gint offset)
1409 ptr = fast_ensure_contiguous(tvb, offset, 3);
1410 return pletoh24(ptr);
1414 tvb_get_letohl(tvbuff_t *tvb, const gint offset)
1418 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1419 return pletohl(ptr);
1423 tvb_get_letoh64(tvbuff_t *tvb, const gint offset)
1427 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint64));
1428 return pletoh64(ptr);
1432 * Fetches an IEEE single-precision floating-point number, in
1433 * little-endian form, and returns a "float".
1435 * XXX - should this be "double", in case there are IEEE single-
1436 * precision numbers that won't fit in some platform's native
1440 tvb_get_letohieee_float(tvbuff_t *tvb, const int offset)
1443 return get_ieee_float(tvb_get_letohl(tvb, offset));
1450 ieee_fp_union.w = tvb_get_letohl(tvb, offset);
1451 return ieee_fp_union.f;
1456 * Fetches an IEEE double-precision floating-point number, in
1457 * little-endian form, and returns a "double".
1460 tvb_get_letohieee_double(tvbuff_t *tvb, const int offset)
1474 #ifdef WORDS_BIGENDIAN
1475 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset+4);
1476 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset);
1478 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset);
1479 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset+4);
1482 return get_ieee_double(ieee_fp_union.dw);
1484 return ieee_fp_union.d;
1488 /* Fetch an IPv4 address, in network byte order.
1489 * We do *not* convert them to host byte order; we leave them in
1490 * network byte order. */
1492 tvb_get_ipv4(tvbuff_t *tvb, const gint offset)
1497 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1498 memcpy(&addr, ptr, sizeof addr);
1502 /* Fetch an IPv6 address. */
1504 tvb_get_ipv6(tvbuff_t *tvb, const gint offset, struct e_in6_addr *addr)
1508 ptr = ensure_contiguous(tvb, offset, sizeof(*addr));
1509 memcpy(addr, ptr, sizeof *addr);
1514 tvb_get_ntohguid(tvbuff_t *tvb, const gint offset, e_guid_t *guid)
1516 ensure_contiguous(tvb, offset, sizeof(*guid));
1517 guid->data1 = tvb_get_ntohl(tvb, offset);
1518 guid->data2 = tvb_get_ntohs(tvb, offset + 4);
1519 guid->data3 = tvb_get_ntohs(tvb, offset + 6);
1520 tvb_memcpy(tvb, guid->data4, offset + 8, sizeof guid->data4);
1524 tvb_get_letohguid(tvbuff_t *tvb, const gint offset, e_guid_t *guid)
1526 ensure_contiguous(tvb, offset, sizeof(*guid));
1527 guid->data1 = tvb_get_letohl(tvb, offset);
1528 guid->data2 = tvb_get_letohs(tvb, offset + 4);
1529 guid->data3 = tvb_get_letohs(tvb, offset + 6);
1530 tvb_memcpy(tvb, guid->data4, offset + 8, sizeof guid->data4);
1534 tvb_get_guid(tvbuff_t *tvb, const gint offset, e_guid_t *guid, const gboolean little_endian)
1536 if (little_endian) {
1537 tvb_get_letohguid(tvb, offset, guid);
1539 tvb_get_ntohguid(tvb, offset, guid);
1543 static const guint8 bit_mask8[] = {
1554 /* Bit offset mask for number of bits = 8 - 16 */
1555 static const guint16 bit_mask16[] = {
1566 /* Get 1 - 8 bits */
1568 tvb_get_bits8(tvbuff_t *tvb, gint bit_offset, const gint no_of_bits)
1575 DISSECTOR_ASSERT_NOT_REACHED();
1577 /* Byte align offset */
1578 offset = bit_offset>>3;
1580 /* Find out which mask to use for the most significant octet
1581 * by convering bit_offset into the offset into the first
1584 bit_offset = bit_offset & 0x7;
1585 tot_no_bits = bit_offset+no_of_bits;
1587 /* Read one octet, mask off bit_offset bits and left shift out the unused bits */
1588 value = tvb_get_guint8(tvb,offset) & bit_mask8[bit_offset];
1589 value = value >> (8-tot_no_bits);
1591 /* Read two octets, mask off bit_offset bits and left shift out the unused bits */
1592 value = tvb_get_ntohs(tvb,offset) & bit_mask16[bit_offset];
1593 value = value >> (16 - tot_no_bits);
1596 return (guint8)value;
1599 /* Get 9 - 16 bits */
1600 /* Bit offset mask for number of bits = 16 - 32 */
1601 static const guint32 bit_mask32[] = {
1613 tvb_get_bits16(tvbuff_t *tvb, gint bit_offset, const gint no_of_bits,const gboolean little_endian)
1617 guint16 tempval = 0;
1620 if ((no_of_bits<=8)||(no_of_bits>16)) {
1621 /* If bits <= 8 use tvb_get_bits8 */
1622 DISSECTOR_ASSERT_NOT_REACHED();
1625 DISSECTOR_ASSERT_NOT_REACHED();
1626 /* This part is not implemented yet */
1629 /* Byte align offset */
1630 offset = bit_offset>>3;
1632 /* Find out which mask to use for the most significant octet
1633 * by convering bit_offset into the offset into the first
1636 bit_offset = bit_offset & 0x7;
1637 tot_no_bits = bit_offset+no_of_bits;
1638 /* Read two octets and mask off bit_offset bits */
1639 value = tvb_get_ntohs(tvb,offset) & bit_mask16[bit_offset];
1640 if(tot_no_bits < 16){
1641 /* Left shift out the unused bits */
1642 value = value >> (16 - tot_no_bits);
1643 }else if(tot_no_bits > 16){
1644 /* Spans three octets, read next octet and shift as needed */
1645 value = value << (tot_no_bits - 16);
1646 tempval = tvb_get_guint8(tvb,offset+2);
1647 tempval = tempval >> (24-tot_no_bits);
1648 value = value | tempval;
1654 /* Bit offset mask for number of bits = 32 - 64 */
1655 static const guint64 bit_mask64[] = {
1656 G_GINT64_CONSTANT(0xffffffffffffffffU),
1657 G_GINT64_CONSTANT(0x7fffffffffffffffU),
1658 G_GINT64_CONSTANT(0x3fffffffffffffffU),
1659 G_GINT64_CONSTANT(0x1fffffffffffffffU),
1660 G_GINT64_CONSTANT(0x0fffffffffffffffU),
1661 G_GINT64_CONSTANT(0x07ffffffffffffffU),
1662 G_GINT64_CONSTANT(0x03ffffffffffffffU),
1663 G_GINT64_CONSTANT(0x01ffffffffffffffU)
1667 tvb_get_bits32(tvbuff_t *tvb, gint bit_offset, const gint no_of_bits, const gboolean little_endian)
1671 guint32 tempval = 0;
1674 if ((no_of_bits<=16)||(no_of_bits>32)) {
1675 /* If bits <= 16 use tvb_get_bits8 or tvb_get_bits16 */
1676 DISSECTOR_ASSERT_NOT_REACHED();
1679 DISSECTOR_ASSERT_NOT_REACHED();
1680 /* This part is not implemented yet */
1683 /* Byte align offset */
1684 offset = bit_offset>>3;
1686 /* Find out which mask to use for the most significant octet
1687 * by convering bit_offset into the offset into the first
1690 bit_offset = bit_offset & 0x7;
1691 tot_no_bits = bit_offset+no_of_bits;
1692 /* Read four octets and mask off bit_offset bits */
1693 value = tvb_get_ntohl(tvb,offset) & bit_mask32[bit_offset];
1694 if(tot_no_bits < 32){
1695 /* Left shift out the unused bits */
1696 value = value >> (32 - tot_no_bits);
1697 }else if(tot_no_bits > 32){
1698 /* Spans five octets, read next octet and shift as needed */
1699 value = value << (tot_no_bits - 32);
1700 tempval = tvb_get_guint8(tvb,offset+4);
1701 tempval = tempval >> (40-tot_no_bits);
1702 value = value | tempval;
1709 tvb_get_bits64(tvbuff_t *tvb, gint bit_offset, const gint no_of_bits, const gboolean little_endian)
1713 guint64 tempval = 0;
1716 if ((no_of_bits<=32)||(no_of_bits>64)) {
1717 /* If bits <= 32 use tvb_get_bits8, tvb_get_bits16 or tvb_get_bits32 */
1718 DISSECTOR_ASSERT_NOT_REACHED();
1721 DISSECTOR_ASSERT_NOT_REACHED();
1722 /* This part is not implemented yet */
1725 /* Byte align offset */
1726 offset = bit_offset>>3;
1728 /* Find out which mask to use for the most significant octet
1729 * by convering bit_offset into the offset into the first
1732 bit_offset = bit_offset & 0x7;
1733 tot_no_bits = bit_offset+no_of_bits;
1734 /* Read eight octets and mask off bit_offset bits */
1735 value = tvb_get_ntoh64(tvb,offset) & bit_mask64[bit_offset];
1736 if (tot_no_bits < 64){
1737 /* Left shift out the unused bits */
1738 value = value >> (64 - tot_no_bits);
1739 }else if (tot_no_bits > 64){
1740 /* Spans nine octets, read next octet and shift as needed */
1741 value = value << (tot_no_bits - 64);
1742 tempval = tvb_get_guint8(tvb,offset+8);
1743 tempval = tempval >> (72-tot_no_bits);
1744 value = value | tempval;
1751 tvb_get_bits(tvbuff_t *tvb, const gint bit_offset, const gint no_of_bits, const gboolean little_endian)
1753 /* This function can handle only up to 32 requested bits */
1754 if (no_of_bits > 32)
1755 DISSECTOR_ASSERT_NOT_REACHED();
1757 if (no_of_bits == 0)
1760 /* Number of requested bits is in range [17, 32] */
1761 if (no_of_bits > 16)
1762 return tvb_get_bits32(tvb, bit_offset, no_of_bits, little_endian);
1764 /* Number of requested bits is in range [9, 16] */
1766 return tvb_get_bits16(tvb, bit_offset, no_of_bits, little_endian);
1768 /* Number of requested bits is in range [1, 8] */
1769 return tvb_get_bits8(tvb, bit_offset, no_of_bits);
1772 /* Find first occurence of needle in tvbuff, starting at offset. Searches
1773 * at most maxlength number of bytes; if maxlength is -1, searches to
1775 * Returns the offset of the found needle, or -1 if not found.
1776 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1777 * in that case, -1 will be returned if the boundary is reached before
1778 * finding needle. */
1780 tvb_find_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength, const guint8 needle)
1782 const guint8 *result;
1783 guint abs_offset, junk_length;
1787 DISSECTOR_ASSERT(tvb && tvb->initialized);
1789 check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
1791 /* Only search to end of tvbuff, w/o throwing exception. */
1792 tvbufflen = tvb_length_remaining(tvb, abs_offset);
1793 if (maxlength == -1) {
1794 /* No maximum length specified; search to end of tvbuff. */
1797 else if (tvbufflen < (guint) maxlength) {
1798 /* Maximum length goes past end of tvbuff; search to end
1803 /* Maximum length doesn't go past end of tvbuff; search
1808 /* If we have real data, perform our search now. */
1809 if (tvb->real_data) {
1810 result = memchr(tvb->real_data + abs_offset, needle, limit);
1811 if (result == NULL) {
1815 return (gint) (result - tvb->real_data);
1820 case TVBUFF_REAL_DATA:
1821 DISSECTOR_ASSERT_NOT_REACHED();
1824 return tvb_find_guint8(tvb->tvbuffs.subset.tvb,
1825 abs_offset - tvb->tvbuffs.subset.offset,
1828 case TVBUFF_COMPOSITE:
1829 DISSECTOR_ASSERT_NOT_REACHED();
1830 /* XXX - return composite_find_guint8(tvb, offset, limit, needle); */
1833 DISSECTOR_ASSERT_NOT_REACHED();
1837 /* Find first occurence of any of the needles in tvbuff, starting at offset.
1838 * Searches at most maxlength number of bytes; if maxlength is -1, searches
1840 * Returns the offset of the found needle, or -1 if not found.
1841 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1842 * in that case, -1 will be returned if the boundary is reached before
1843 * finding needle. */
1845 tvb_pbrk_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength, const guint8 *needles, guchar *found_needle)
1847 const guint8 *result;
1848 guint abs_offset, junk_length;
1852 DISSECTOR_ASSERT(tvb && tvb->initialized);
1854 check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
1856 /* Only search to end of tvbuff, w/o throwing exception. */
1857 tvbufflen = tvb_length_remaining(tvb, abs_offset);
1858 if (maxlength == -1) {
1859 /* No maximum length specified; search to end of tvbuff. */
1862 else if (tvbufflen < (guint) maxlength) {
1863 /* Maximum length goes past end of tvbuff; search to end
1868 /* Maximum length doesn't go past end of tvbuff; search
1873 /* If we have real data, perform our search now. */
1874 if (tvb->real_data) {
1875 result = guint8_pbrk(tvb->real_data + abs_offset, limit, needles, found_needle);
1876 if (result == NULL) {
1880 return (gint) (result - tvb->real_data);
1885 case TVBUFF_REAL_DATA:
1886 DISSECTOR_ASSERT_NOT_REACHED();
1889 return tvb_pbrk_guint8(tvb->tvbuffs.subset.tvb,
1890 abs_offset - tvb->tvbuffs.subset.offset,
1891 limit, needles, found_needle);
1893 case TVBUFF_COMPOSITE:
1894 DISSECTOR_ASSERT_NOT_REACHED();
1895 /* XXX - return composite_pbrk_guint8(tvb, offset, limit, needle); */
1898 DISSECTOR_ASSERT_NOT_REACHED();
1902 /* Find size of stringz (NUL-terminated string) by looking for terminating
1903 * NUL. The size of the string includes the terminating NUL.
1905 * If the NUL isn't found, it throws the appropriate exception.
1908 tvb_strsize(tvbuff_t *tvb, const gint offset)
1910 guint abs_offset, junk_length;
1913 DISSECTOR_ASSERT(tvb && tvb->initialized);
1915 check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
1916 nul_offset = tvb_find_guint8(tvb, abs_offset, -1, 0);
1917 if (nul_offset == -1) {
1919 * OK, we hit the end of the tvbuff, so we should throw
1922 * Did we hit the end of the captured data, or the end
1923 * of the actual data? If there's less captured data
1924 * than actual data, we presumably hit the end of the
1925 * captured data, otherwise we hit the end of the actual
1928 if (tvb_length(tvb) < tvb_reported_length(tvb)) {
1931 THROW(ReportedBoundsError);
1934 return (nul_offset - abs_offset) + 1;
1937 /* Find length of string by looking for end of string ('\0'), up to
1938 * 'maxlength' characters'; if 'maxlength' is -1, searches to end
1940 * Returns -1 if 'maxlength' reached before finding EOS. */
1942 tvb_strnlen(tvbuff_t *tvb, const gint offset, const guint maxlength)
1945 guint abs_offset, junk_length;
1947 DISSECTOR_ASSERT(tvb && tvb->initialized);
1949 check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
1951 result_offset = tvb_find_guint8(tvb, abs_offset, maxlength, 0);
1953 if (result_offset == -1) {
1957 return result_offset - abs_offset;
1962 * Implement strneql etc
1966 * Call strncmp after checking if enough chars left, returning 0 if
1967 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1970 tvb_strneql(tvbuff_t *tvb, const gint offset, const gchar *str, const gint size)
1974 ptr = ensure_contiguous_no_exception(tvb, offset, size, NULL);
1977 int cmp = strncmp((const char *)ptr, str, size);
1980 * Return 0 if equal, -1 otherwise.
1982 return (cmp == 0 ? 0 : -1);
1985 * Not enough characters in the tvbuff to match the
1993 * Call g_ascii_strncasecmp after checking if enough chars left, returning
1994 * 0 if it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1997 tvb_strncaseeql(tvbuff_t *tvb, const gint offset, const gchar *str, const gint size)
2001 ptr = ensure_contiguous_no_exception(tvb, offset, size, NULL);
2004 int cmp = g_ascii_strncasecmp((const char *)ptr, str, size);
2007 * Return 0 if equal, -1 otherwise.
2009 return (cmp == 0 ? 0 : -1);
2012 * Not enough characters in the tvbuff to match the
2020 * Call memcmp after checking if enough chars left, returning 0 if
2021 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
2024 tvb_memeql(tvbuff_t *tvb, const gint offset, const guint8 *str, size_t size)
2028 ptr = ensure_contiguous_no_exception(tvb, offset, (gint) size, NULL);
2031 int cmp = memcmp(ptr, str, size);
2034 * Return 0 if equal, -1 otherwise.
2036 return (cmp == 0 ? 0 : -1);
2039 * Not enough characters in the tvbuff to match the
2046 /* Convert a string from Unicode to ASCII. At the moment we fake it by
2047 * replacing all non-ASCII characters with a '.' )-: The caller must
2048 * free the result returned. The len parameter is the number of guint16's
2049 * to convert from Unicode. */
2051 tvb_fake_unicode(tvbuff_t *tvb, int offset, const int len, const gboolean little_endian)
2057 /* Make sure we have enough data before allocating the buffer,
2058 so we don't blow up if the length is huge. */
2059 tvb_ensure_bytes_exist(tvb, offset, 2*len);
2061 /* We know we won't throw an exception, so we don't have to worry
2062 about leaking this buffer. */
2063 buffer = g_malloc(len + 1);
2065 for (i = 0; i < len; i++) {
2066 character = little_endian ? tvb_get_letohs(tvb, offset)
2067 : tvb_get_ntohs(tvb, offset);
2068 buffer[i] = character < 256 ? character : '.';
2077 /* Convert a string from Unicode to ASCII. At the moment we fake it by
2078 * replacing all non-ASCII characters with a '.' )-: The len parameter is
2079 * the number of guint16's to convert from Unicode.
2081 * This function allocates memory from a buffer with packet lifetime.
2082 * You do not have to free this buffer, it will be automatically freed
2083 * when wireshark starts decoding the next packet.
2086 tvb_get_ephemeral_faked_unicode(tvbuff_t *tvb, int offset, const int len, const gboolean little_endian)
2092 /* Make sure we have enough data before allocating the buffer,
2093 so we don't blow up if the length is huge. */
2094 tvb_ensure_bytes_exist(tvb, offset, 2*len);
2096 /* We know we won't throw an exception, so we don't have to worry
2097 about leaking this buffer. */
2098 buffer = ep_alloc(len + 1);
2100 for (i = 0; i < len; i++) {
2101 character = little_endian ? tvb_get_letohs(tvb, offset)
2102 : tvb_get_ntohs(tvb, offset);
2103 buffer[i] = character < 256 ? character : '.';
2113 * Format the data in the tvb from offset for length ...
2117 tvb_format_text(tvbuff_t *tvb, const gint offset, const gint size)
2122 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2123 len = tvb_length_remaining(tvb, offset);
2124 ptr = ensure_contiguous(tvb, offset, len);
2127 return format_text(ptr, len);
2131 * Format the data in the tvb from offset for length ...
2135 tvb_format_text_wsp(tvbuff_t *tvb, const gint offset, const gint size)
2140 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2142 len = tvb_length_remaining(tvb, offset);
2143 ptr = ensure_contiguous(tvb, offset, len);
2147 return format_text_wsp(ptr, len);
2152 * Like "tvb_format_text()", but for null-padded strings; don't show
2153 * the null padding characters as "\000".
2156 tvb_format_stringzpad(tvbuff_t *tvb, const gint offset, const gint size)
2158 const guint8 *ptr, *p;
2162 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2164 len = tvb_length_remaining(tvb, offset);
2165 ptr = ensure_contiguous(tvb, offset, len);
2169 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2171 return format_text(ptr, stringlen);
2176 * Like "tvb_format_text_wsp()", but for null-padded strings; don't show
2177 * the null padding characters as "\000".
2180 tvb_format_stringzpad_wsp(tvbuff_t *tvb, const gint offset, const gint size)
2182 const guint8 *ptr, *p;
2186 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2188 len = tvb_length_remaining(tvb, offset);
2189 ptr = ensure_contiguous(tvb, offset, len);
2193 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2195 return format_text_wsp(ptr, stringlen);
2200 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2201 * to hold a non-null-terminated string of that length at that offset,
2202 * plus a trailing '\0', copy the string into it, and return a pointer
2205 * Throws an exception if the tvbuff ends before the string does.
2208 tvb_get_string(tvbuff_t *tvb, const gint offset, const gint length)
2211 guint8 *strbuf = NULL;
2213 tvb_ensure_bytes_exist(tvb, offset, length);
2215 ptr = ensure_contiguous(tvb, offset, length);
2216 strbuf = g_malloc(length + 1);
2218 memcpy(strbuf, ptr, length);
2220 strbuf[length] = '\0';
2224 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2225 * to hold a non-null-terminated string of that length at that offset,
2226 * plus a trailing '\0', copy the string into it, and return a pointer
2229 * Throws an exception if the tvbuff ends before the string does.
2231 * This function allocates memory from a buffer with packet lifetime.
2232 * You do not have to free this buffer, it will be automatically freed
2233 * when wireshark starts decoding the next packet.
2234 * Do not use this function if you want the allocated memory to be persistent
2235 * after the current packet has been dissected.
2238 tvb_get_ephemeral_string(tvbuff_t *tvb, const gint offset, const gint length)
2241 guint8 *strbuf = NULL;
2243 tvb_ensure_bytes_exist(tvb, offset, length);
2245 ptr = ensure_contiguous(tvb, offset, length);
2246 strbuf = ep_alloc(length + 1);
2248 memcpy(strbuf, ptr, length);
2250 strbuf[length] = '\0';
2255 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2256 * to hold a non-null-terminated string of that length at that offset,
2257 * plus a trailing '\0', copy the string into it, and return a pointer
2260 * Throws an exception if the tvbuff ends before the string does.
2262 * This function allocates memory from a buffer with capture session lifetime.
2263 * You do not have to free this buffer, it will be automatically freed
2264 * when wireshark starts or opens a new capture.
2267 tvb_get_seasonal_string(tvbuff_t *tvb, const gint offset, const gint length)
2270 guint8 *strbuf = NULL;
2272 tvb_ensure_bytes_exist(tvb, offset, length);
2274 ptr = ensure_contiguous(tvb, offset, length);
2275 strbuf = se_alloc(length + 1);
2277 memcpy(strbuf, ptr, length);
2279 strbuf[length] = '\0';
2284 * Given a tvbuff and an offset, with the offset assumed to refer to
2285 * a null-terminated string, find the length of that string (and throw
2286 * an exception if the tvbuff ends before we find the null), allocate
2287 * a buffer big enough to hold the string, copy the string into it,
2288 * and return a pointer to the string. Also return the length of the
2289 * string (including the terminating null) through a pointer.
2292 tvb_get_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp)
2297 size = tvb_strsize(tvb, offset);
2298 strptr = g_malloc(size);
2299 tvb_memcpy(tvb, strptr, offset, size);
2305 * Given a tvbuff and an offset, with the offset assumed to refer to
2306 * a null-terminated string, find the length of that string (and throw
2307 * an exception if the tvbuff ends before we find the null), allocate
2308 * a buffer big enough to hold the string, copy the string into it,
2309 * and return a pointer to the string. Also return the length of the
2310 * string (including the terminating null) through a pointer.
2312 * This function allocates memory from a buffer with packet lifetime.
2313 * You do not have to free this buffer, it will be automatically freed
2314 * when wireshark starts decoding the next packet.
2315 * Do not use this function if you want the allocated memory to be persistent
2316 * after the current packet has been dissected.
2319 tvb_get_ephemeral_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp)
2324 size = tvb_strsize(tvb, offset);
2325 strptr = ep_alloc(size);
2326 tvb_memcpy(tvb, strptr, offset, size);
2333 * Given a tvbuff and an offset, with the offset assumed to refer to
2334 * a null-terminated string, find the length of that string (and throw
2335 * an exception if the tvbuff ends before we find the null), allocate
2336 * a buffer big enough to hold the string, copy the string into it,
2337 * and return a pointer to the string. Also return the length of the
2338 * string (including the terminating null) through a pointer.
2340 * This function allocates memory from a buffer with capture session lifetime.
2341 * You do not have to free this buffer, it will be automatically freed
2342 * when wireshark starts or opens a new capture.
2345 tvb_get_seasonal_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp)
2350 size = tvb_strsize(tvb, offset);
2351 strptr = se_alloc(size);
2352 tvb_memcpy(tvb, strptr, offset, size);
2358 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
2359 * no more than bufsize number of bytes, including terminating NUL, to buffer.
2360 * Returns length of string (not including terminating NUL), or -1 if the string was
2361 * truncated in the buffer due to not having reached the terminating NUL.
2362 * In this way, it acts like g_snprintf().
2364 * bufsize MUST be greater than 0.
2366 * When processing a packet where the remaining number of bytes is less
2367 * than bufsize, an exception is not thrown if the end of the packet
2368 * is reached before the NUL is found. If no NUL is found before reaching
2369 * the end of the short packet, -1 is still returned, and the string
2370 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
2371 * at the correct spot, terminating the string.
2373 * *bytes_copied will contain the number of bytes actually copied,
2374 * including the terminating-NUL.
2377 _tvb_get_nstringz(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* buffer,
2381 guint abs_offset, junk_length;
2383 gboolean decreased_max = FALSE;
2385 check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
2387 /* There must at least be room for the terminating NUL. */
2388 DISSECTOR_ASSERT(bufsize != 0);
2390 /* If there's no room for anything else, just return the NUL. */
2397 /* Only read to end of tvbuff, w/o throwing exception. */
2398 len = tvb_length_remaining(tvb, abs_offset);
2400 /* check_offset_length() won't throw an exception if we're
2401 * looking at the byte immediately after the end of the tvbuff. */
2403 THROW(ReportedBoundsError);
2406 /* This should not happen because check_offset_length() would
2407 * have already thrown an exception if 'offset' were out-of-bounds.
2409 DISSECTOR_ASSERT(len != -1);
2412 * If we've been passed a negative number, bufsize will
2415 DISSECTOR_ASSERT(bufsize <= G_MAXINT);
2417 if ((guint)len < bufsize) {
2419 decreased_max = TRUE;
2425 stringlen = tvb_strnlen(tvb, abs_offset, limit - 1);
2426 /* If NUL wasn't found, copy the data and return -1 */
2427 if (stringlen == -1) {
2428 tvb_memcpy(tvb, buffer, abs_offset, limit);
2429 if (decreased_max) {
2431 /* Add 1 for the extra NUL that we set at buffer[limit],
2432 * pretending that it was copied as part of the string. */
2433 *bytes_copied = limit + 1;
2436 *bytes_copied = limit;
2441 /* Copy the string to buffer */
2442 tvb_memcpy(tvb, buffer, abs_offset, stringlen + 1);
2443 *bytes_copied = stringlen + 1;
2447 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
2448 * no more than bufsize number of bytes, including terminating NUL, to buffer.
2449 * Returns length of string (not including terminating NUL), or -1 if the string was
2450 * truncated in the buffer due to not having reached the terminating NUL.
2451 * In this way, it acts like g_snprintf().
2453 * When processing a packet where the remaining number of bytes is less
2454 * than bufsize, an exception is not thrown if the end of the packet
2455 * is reached before the NUL is found. If no NUL is found before reaching
2456 * the end of the short packet, -1 is still returned, and the string
2457 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
2458 * at the correct spot, terminating the string.
2461 tvb_get_nstringz(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* buffer)
2465 DISSECTOR_ASSERT(tvb && tvb->initialized);
2467 return _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
2470 /* Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
2471 * have a terminating NUL. If the string was truncated when copied into buffer,
2472 * a NUL is placed at the end of buffer to terminate it.
2475 tvb_get_nstringz0(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* buffer)
2477 gint len, bytes_copied;
2479 DISSECTOR_ASSERT(tvb && tvb->initialized);
2481 len = _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
2484 buffer[bufsize - 1] = 0;
2485 return bytes_copied - 1;
2493 * Given a tvbuff, an offset into the tvbuff, and a length that starts
2494 * at that offset (which may be -1 for "all the way to the end of the
2495 * tvbuff"), find the end of the (putative) line that starts at the
2496 * specified offset in the tvbuff, going no further than the specified
2499 * Return the length of the line (not counting the line terminator at
2500 * the end), or, if we don't find a line terminator:
2502 * if "deseg" is true, return -1;
2504 * if "deseg" is false, return the amount of data remaining in
2507 * Set "*next_offset" to the offset of the character past the line
2508 * terminator, or past the end of the buffer if we don't find a line
2509 * terminator. (It's not set if we return -1.)
2512 tvb_find_line_end(tvbuff_t *tvb, const gint offset, int len, gint *next_offset,
2513 const gboolean desegment)
2518 guchar found_needle = 0;
2521 len = tvb_length_remaining(tvb, offset);
2523 * XXX - what if "len" is still -1, meaning "offset is past the
2524 * end of the tvbuff"?
2526 eob_offset = offset + len;
2529 * Look either for a CR or an LF.
2531 eol_offset = tvb_pbrk_guint8(tvb, offset, len, (const guint8 *)"\r\n", &found_needle);
2532 if (eol_offset == -1) {
2534 * No CR or LF - line is presumably continued in next packet.
2538 * Tell our caller we saw no EOL, so they can
2539 * try to desegment and get the entire line
2545 * Pretend the line runs to the end of the tvbuff.
2547 linelen = eob_offset - offset;
2549 *next_offset = eob_offset;
2553 * Find the number of bytes between the starting offset
2556 linelen = eol_offset - offset;
2561 if (found_needle == '\r') {
2563 * Yes - is it followed by an LF?
2565 if (eol_offset + 1 >= eob_offset) {
2567 * Dunno - the next byte isn't in this
2572 * We'll return -1, although that
2573 * runs the risk that if the line
2574 * really *is* terminated with a CR,
2575 * we won't properly dissect this
2578 * It's probably more likely that
2579 * the line ends with CR-LF than
2580 * that it ends with CR by itself.
2586 * Well, we can at least look at the next
2589 if (tvb_get_guint8(tvb, eol_offset + 1) == '\n') {
2591 * It's an LF; skip over the CR.
2599 * Return the offset of the character after the last
2600 * character in the line, skipping over the last character
2601 * in the line terminator.
2604 *next_offset = eol_offset + 1;
2610 * Given a tvbuff, an offset into the tvbuff, and a length that starts
2611 * at that offset (which may be -1 for "all the way to the end of the
2612 * tvbuff"), find the end of the (putative) line that starts at the
2613 * specified offset in the tvbuff, going no further than the specified
2616 * However, treat quoted strings inside the buffer specially - don't
2617 * treat newlines in quoted strings as line terminators.
2619 * Return the length of the line (not counting the line terminator at
2620 * the end), or the amount of data remaining in the buffer if we don't
2621 * find a line terminator.
2623 * Set "*next_offset" to the offset of the character past the line
2624 * terminator, or past the end of the buffer if we don't find a line
2628 tvb_find_line_end_unquoted(tvbuff_t *tvb, const gint offset, int len,
2631 gint cur_offset, char_offset;
2638 len = tvb_length_remaining(tvb, offset);
2640 * XXX - what if "len" is still -1, meaning "offset is past the
2641 * end of the tvbuff"?
2643 eob_offset = offset + len;
2645 cur_offset = offset;
2649 * Is this part of the string quoted?
2653 * Yes - look only for the terminating quote.
2655 char_offset = tvb_find_guint8(tvb, cur_offset, len,
2659 * Look either for a CR, an LF, or a '"'.
2661 char_offset = tvb_pbrk_guint8(tvb, cur_offset, len,
2662 (const guint8 *)"\r\n\"", &c);
2664 if (char_offset == -1) {
2666 * Not found - line is presumably continued in
2668 * We pretend the line runs to the end of the tvbuff.
2670 linelen = eob_offset - offset;
2672 *next_offset = eob_offset;
2678 * We're processing a quoted string.
2679 * We only looked for ", so we know it's a ";
2680 * as we're processing a quoted string, it's a
2690 * Un-quoted "; it begins a quoted
2696 * It's a CR or LF; we've found a line
2699 * Find the number of bytes between the
2700 * starting offset and the CR or LF.
2702 linelen = char_offset - offset;
2709 * Yes; is it followed by an LF?
2711 if (char_offset + 1 < eob_offset &&
2712 tvb_get_guint8(tvb, char_offset + 1)
2715 * Yes; skip over the CR.
2722 * Return the offset of the character after
2723 * the last character in the line, skipping
2724 * over the last character in the line
2725 * terminator, and quit.
2728 *next_offset = char_offset + 1;
2734 * Step past the character we found.
2736 cur_offset = char_offset + 1;
2737 if (cur_offset >= eob_offset) {
2739 * The character we found was the last character
2740 * in the tvbuff - line is presumably continued in
2742 * We pretend the line runs to the end of the tvbuff.
2744 linelen = eob_offset - offset;
2746 *next_offset = eob_offset;
2754 * Copied from the mgcp dissector. (This function should be moved to /epan )
2755 * tvb_skip_wsp - Returns the position in tvb of the first non-whitespace
2756 * character following offset or offset + maxlength -1 whichever
2760 * tvb - The tvbuff in which we are skipping whitespace.
2761 * offset - The offset in tvb from which we begin trying to skip whitespace.
2762 * maxlength - The maximum distance from offset that we may try to skip
2765 * Returns: The position in tvb of the first non-whitespace
2766 * character following offset or offset + maxlength -1 whichever
2769 gint tvb_skip_wsp(tvbuff_t* tvb, const gint offset, const gint maxlength)
2771 gint counter = offset;
2772 gint end = offset + maxlength,tvb_len;
2775 /* Get the length remaining */
2776 tvb_len = tvb_length(tvb);
2777 end = offset + maxlength;
2783 /* Skip past spaces, tabs, CRs and LFs until run out or meet something else */
2784 for (counter = offset;
2786 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
2787 tempchar == '\t' || tempchar == '\r' || tempchar == '\n');
2793 gint tvb_skip_wsp_return(tvbuff_t* tvb, const gint offset){
2794 gint counter = offset;
2799 for(counter = offset; counter > end &&
2800 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
2801 tempchar == '\t' || tempchar == '\n' || tempchar == '\r'); counter--);
2808 * Format a bunch of data from a tvbuff as bytes, returning a pointer
2809 * to the string with the formatted data, with "punct" as a byte
2813 tvb_bytes_to_str_punct(tvbuff_t *tvb, const gint offset, const gint len, const gchar punct)
2815 return bytes_to_str_punct(tvb_get_ptr(tvb, offset, len), len, punct);
2819 * Format a bunch of data from a tvbuff as bytes, returning a pointer
2820 * to the string with the formatted data.
2823 tvb_bytes_to_str(tvbuff_t *tvb, const gint offset, const gint len)
2825 return bytes_to_str(tvb_get_ptr(tvb, offset, len), len);
2828 /* Find a needle tvbuff within a haystack tvbuff. */
2830 tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb, const gint haystack_offset)
2832 guint haystack_abs_offset, haystack_abs_length;
2833 const guint8 *haystack_data;
2834 const guint8 *needle_data;
2835 const guint needle_len = needle_tvb->length;
2836 const guint8 *location;
2838 DISSECTOR_ASSERT(haystack_tvb && haystack_tvb->initialized);
2840 if (haystack_tvb->length < 1 || needle_tvb->length < 1) {
2844 /* Get pointers to the tvbuffs' data. */
2845 haystack_data = tvb_get_ptr(haystack_tvb, 0, -1);
2846 needle_data = tvb_get_ptr(needle_tvb, 0, -1);
2848 check_offset_length(haystack_tvb->length, haystack_tvb->reported_length, haystack_offset, -1,
2849 &haystack_abs_offset, &haystack_abs_length);
2851 location = epan_memmem(haystack_data + haystack_abs_offset, haystack_abs_length,
2852 needle_data, needle_len);
2855 return (gint) (location - haystack_data);
2863 * Uncompresses a zlib compressed packet inside a message of tvb at offset with
2864 * length comprlen. Returns an uncompressed tvbuffer if uncompression
2865 * succeeded or NULL if uncompression failed.
2867 #define TVB_Z_MIN_BUFSIZ 32768
2868 #define TVB_Z_MAX_BUFSIZ 1048576 * 10
2869 /* #define TVB_Z_DEBUG 1 */
2873 tvb_uncompress(tvbuff_t *tvb, const int offset, int comprlen)
2876 guint bytes_out = 0;
2877 guint8 *compr = NULL;
2878 guint8 *uncompr = NULL;
2879 tvbuff_t *uncompr_tvb = NULL;
2880 z_streamp strm = NULL;
2881 Bytef *strmbuf = NULL;
2882 guint inits_done = 0;
2883 gint wbits = MAX_WBITS;
2884 guint8 *next = NULL;
2885 guint bufsiz = TVB_Z_MIN_BUFSIZ;
2887 guint inflate_passes = 0;
2888 guint bytes_in = tvb_length_remaining(tvb, offset);
2895 compr = tvb_memdup(tvb, offset, comprlen);
2901 * Assume that the uncompressed data is at least twice as big as
2902 * the compressed size.
2904 bufsiz = tvb_length_remaining(tvb, offset) * 2;
2905 bufsiz = CLAMP(bufsiz, TVB_Z_MIN_BUFSIZ, TVB_Z_MAX_BUFSIZ);
2908 printf("bufsiz: %u bytes\n", bufsiz);
2913 strm = g_new0(z_stream, 1);
2914 strm->next_in = next;
2915 strm->avail_in = comprlen;
2917 strmbuf = g_malloc0(bufsiz);
2918 strm->next_out = strmbuf;
2919 strm->avail_out = bufsiz;
2921 err = inflateInit2(strm, wbits);
2932 memset(strmbuf, '\0', bufsiz);
2933 strm->next_out = strmbuf;
2934 strm->avail_out = bufsiz;
2936 err = inflate(strm, Z_SYNC_FLUSH);
2938 if (err == Z_OK || err == Z_STREAM_END) {
2939 guint bytes_pass = bufsiz - strm->avail_out;
2945 if (uncompr == NULL) {
2946 uncompr = g_memdup(strmbuf, bytes_pass);
2948 guint8 *new_data = g_malloc0(bytes_out + bytes_pass);
2950 g_memmove(new_data, uncompr, bytes_out);
2951 g_memmove((new_data + bytes_out), strmbuf,
2958 bytes_out += bytes_pass;
2960 if ( err == Z_STREAM_END) {
2966 } else if (err == Z_BUF_ERROR) {
2968 * It's possible that not enough frames were captured
2969 * to decompress this fully, so return what we've done
2976 if (uncompr != NULL) {
2983 } else if (err == Z_DATA_ERROR && inits_done == 1
2984 && uncompr == NULL && (*compr == 0x1f) &&
2985 (*(compr + 1) == 0x8b)) {
2987 * inflate() is supposed to handle both gzip and deflate
2988 * streams automatically, but in reality it doesn't
2989 * seem to handle either (at least not within the
2990 * context of an HTTP response.) We have to try
2991 * several tweaks, depending on the type of data and
2992 * version of the library installed.
2996 * Gzip file format. Skip past the header, since the
2997 * fix to make it work (setting windowBits to 31)
2998 * doesn't work with all versions of the library.
3000 Bytef *c = compr + 2;
3003 if (*c == Z_DEFLATED) {
3015 /* Skip past the MTIME, XFL, and OS fields. */
3018 if (flags & (1 << 2)) {
3019 /* An Extra field is present. */
3020 gint xsize = (gint)(*c |
3026 if (flags & (1 << 3)) {
3027 /* A null terminated filename */
3029 while ((c - compr) < comprlen && *c != '\0') {
3036 if (flags & (1 << 4)) {
3037 /* A null terminated comment */
3039 while ((c - compr) < comprlen && *c != '\0') {
3049 strm->next_in = next;
3050 if (c - compr > comprlen) {
3057 comprlen -= (int) (c - compr);
3060 err = inflateInit2(strm, wbits);
3062 } else if (err == Z_DATA_ERROR && uncompr == NULL &&
3066 * Re-init the stream with a negative
3067 * MAX_WBITS. This is necessary due to
3068 * some servers (Apache) not sending
3069 * the deflate header with the
3070 * content-encoded response.
3076 strm->next_in = next;
3077 strm->avail_in = comprlen;
3080 memset(strmbuf, '\0', bufsiz);
3081 strm->next_out = strmbuf;
3082 strm->avail_out = bufsiz;
3084 err = inflateInit2(strm, wbits);
3102 if (uncompr == NULL) {
3111 printf("inflate() total passes: %u\n", inflate_passes);
3112 printf("bytes in: %u\nbytes out: %u\n\n", bytes_in, bytes_out);
3115 if (uncompr != NULL) {
3116 uncompr_tvb = tvb_new_real_data((guint8*) uncompr, bytes_out,
3118 tvb_set_free_cb(uncompr_tvb, g_free);
3125 tvb_uncompress(tvbuff_t *tvb _U_, const int offset _U_, int comprlen _U_)
3131 tvbuff_t* tvb_child_uncompress(tvbuff_t *parent, tvbuff_t *tvb, const int offset, int comprlen)
3133 tvbuff_t *new_tvb = tvb_uncompress(tvb, offset, comprlen);
3135 tvb_set_child_real_data_tvbuff (parent, new_tvb);