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 * NOTE: to support code written when proto_tree_add_item() took a
1535 * gboolean as its last argument, with FALSE meaning "big-endian"
1536 * and TRUE meaning "little-endian", we treat any non-zero value of
1537 * "representation" as meaning "little-endian".
1540 tvb_get_guid(tvbuff_t *tvb, const gint offset, e_guid_t *guid, const guint representation)
1542 if (representation) {
1543 tvb_get_letohguid(tvb, offset, guid);
1545 tvb_get_ntohguid(tvb, offset, guid);
1549 static const guint8 bit_mask8[] = {
1560 /* Bit offset mask for number of bits = 8 - 16 */
1561 static const guint16 bit_mask16[] = {
1572 /* Get 1 - 8 bits */
1574 tvb_get_bits8(tvbuff_t *tvb, gint bit_offset, const gint no_of_bits)
1581 DISSECTOR_ASSERT_NOT_REACHED();
1583 /* Byte align offset */
1584 offset = bit_offset>>3;
1586 /* Find out which mask to use for the most significant octet
1587 * by convering bit_offset into the offset into the first
1590 bit_offset = bit_offset & 0x7;
1591 tot_no_bits = bit_offset+no_of_bits;
1593 /* Read one octet, mask off bit_offset bits and left shift out the unused bits */
1594 value = tvb_get_guint8(tvb,offset) & bit_mask8[bit_offset];
1595 value = value >> (8-tot_no_bits);
1597 /* Read two octets, mask off bit_offset bits and left shift out the unused bits */
1598 value = tvb_get_ntohs(tvb,offset) & bit_mask16[bit_offset];
1599 value = value >> (16 - tot_no_bits);
1602 return (guint8)value;
1605 /* Get 9 - 16 bits */
1606 /* Bit offset mask for number of bits = 16 - 32 */
1607 static const guint32 bit_mask32[] = {
1619 tvb_get_bits16(tvbuff_t *tvb, gint bit_offset, const gint no_of_bits,const gboolean little_endian)
1623 guint16 tempval = 0;
1626 if ((no_of_bits<=8)||(no_of_bits>16)) {
1627 /* If bits <= 8 use tvb_get_bits8 */
1628 DISSECTOR_ASSERT_NOT_REACHED();
1631 DISSECTOR_ASSERT_NOT_REACHED();
1632 /* This part is not implemented yet */
1635 /* Byte align offset */
1636 offset = bit_offset>>3;
1638 /* Find out which mask to use for the most significant octet
1639 * by convering bit_offset into the offset into the first
1642 bit_offset = bit_offset & 0x7;
1643 tot_no_bits = bit_offset+no_of_bits;
1644 /* Read two octets and mask off bit_offset bits */
1645 value = tvb_get_ntohs(tvb,offset) & bit_mask16[bit_offset];
1646 if(tot_no_bits < 16){
1647 /* Left shift out the unused bits */
1648 value = value >> (16 - tot_no_bits);
1649 }else if(tot_no_bits > 16){
1650 /* Spans three octets, read next octet and shift as needed */
1651 value = value << (tot_no_bits - 16);
1652 tempval = tvb_get_guint8(tvb,offset+2);
1653 tempval = tempval >> (24-tot_no_bits);
1654 value = value | tempval;
1660 /* Bit offset mask for number of bits = 32 - 64 */
1661 static const guint64 bit_mask64[] = {
1662 G_GINT64_CONSTANT(0xffffffffffffffffU),
1663 G_GINT64_CONSTANT(0x7fffffffffffffffU),
1664 G_GINT64_CONSTANT(0x3fffffffffffffffU),
1665 G_GINT64_CONSTANT(0x1fffffffffffffffU),
1666 G_GINT64_CONSTANT(0x0fffffffffffffffU),
1667 G_GINT64_CONSTANT(0x07ffffffffffffffU),
1668 G_GINT64_CONSTANT(0x03ffffffffffffffU),
1669 G_GINT64_CONSTANT(0x01ffffffffffffffU)
1673 tvb_get_bits32(tvbuff_t *tvb, gint bit_offset, const gint no_of_bits, const gboolean little_endian)
1677 guint32 tempval = 0;
1679 guint8 tot_no_octets = 0;
1683 if ((no_of_bits<=16)||(no_of_bits>32)) {
1684 /* If bits <= 16 use tvb_get_bits8 or tvb_get_bits16 */
1685 DISSECTOR_ASSERT_NOT_REACHED();
1688 DISSECTOR_ASSERT_NOT_REACHED();
1689 /* This part is not implemented yet */
1692 /* Byte align offset */
1693 offset = bit_offset>>3;
1695 bit_offset = bit_offset & 0x7;
1696 tot_no_bits = bit_offset+no_of_bits;
1697 tot_no_octets = tot_no_bits / 8;
1698 if (tot_no_bits % 8)
1700 shift = no_of_bits - (8 - bit_offset);
1702 value = tvb_get_guint8(tvb, offset) & bit_mask8[bit_offset];
1703 value = value << shift;
1705 for (i = 1; i < tot_no_octets; i++)
1708 tempval = tvb_get_guint8(tvb, offset+i);
1711 tempval = tempval << shift;
1715 tempval = tempval >> (- shift);
1717 value = value | tempval;
1724 tvb_get_bits64(tvbuff_t *tvb, gint bit_offset, const gint no_of_bits, const gboolean little_endian)
1728 guint64 tempval = 0;
1731 if ((no_of_bits<=32)||(no_of_bits>64)) {
1732 /* If bits <= 32 use tvb_get_bits8, tvb_get_bits16 or tvb_get_bits32 */
1733 DISSECTOR_ASSERT_NOT_REACHED();
1736 DISSECTOR_ASSERT_NOT_REACHED();
1737 /* This part is not implemented yet */
1740 /* Byte align offset */
1741 offset = bit_offset>>3;
1743 /* Find out which mask to use for the most significant octet
1744 * by convering bit_offset into the offset into the first
1747 bit_offset = bit_offset & 0x7;
1748 tot_no_bits = bit_offset+no_of_bits;
1749 /* Read eight octets and mask off bit_offset bits */
1750 value = tvb_get_ntoh64(tvb,offset) & bit_mask64[bit_offset];
1751 if (tot_no_bits < 64){
1752 /* Left shift out the unused bits */
1753 value = value >> (64 - tot_no_bits);
1754 }else if (tot_no_bits > 64){
1755 /* Spans nine octets, read next octet and shift as needed */
1756 value = value << (tot_no_bits - 64);
1757 tempval = tvb_get_guint8(tvb,offset+8);
1758 tempval = tempval >> (72-tot_no_bits);
1759 value = value | tempval;
1766 tvb_get_bits(tvbuff_t *tvb, const gint bit_offset, const gint no_of_bits, const gboolean little_endian)
1768 /* This function can handle only up to 32 requested bits */
1769 if (no_of_bits > 32)
1770 DISSECTOR_ASSERT_NOT_REACHED();
1772 if (no_of_bits == 0)
1775 /* Number of requested bits is in range [17, 32] */
1776 if (no_of_bits > 16)
1777 return tvb_get_bits32(tvb, bit_offset, no_of_bits, little_endian);
1779 /* Number of requested bits is in range [9, 16] */
1781 return tvb_get_bits16(tvb, bit_offset, no_of_bits, little_endian);
1783 /* Number of requested bits is in range [1, 8] */
1784 return tvb_get_bits8(tvb, bit_offset, no_of_bits);
1787 /* Find first occurence of needle in tvbuff, starting at offset. Searches
1788 * at most maxlength number of bytes; if maxlength is -1, searches to
1790 * Returns the offset of the found needle, or -1 if not found.
1791 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1792 * in that case, -1 will be returned if the boundary is reached before
1793 * finding needle. */
1795 tvb_find_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength, const guint8 needle)
1797 const guint8 *result;
1798 guint abs_offset, junk_length;
1802 DISSECTOR_ASSERT(tvb && tvb->initialized);
1804 check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
1806 /* Only search to end of tvbuff, w/o throwing exception. */
1807 tvbufflen = tvb_length_remaining(tvb, abs_offset);
1808 if (maxlength == -1) {
1809 /* No maximum length specified; search to end of tvbuff. */
1812 else if (tvbufflen < (guint) maxlength) {
1813 /* Maximum length goes past end of tvbuff; search to end
1818 /* Maximum length doesn't go past end of tvbuff; search
1823 /* If we have real data, perform our search now. */
1824 if (tvb->real_data) {
1825 result = memchr(tvb->real_data + abs_offset, needle, limit);
1826 if (result == NULL) {
1830 return (gint) (result - tvb->real_data);
1835 case TVBUFF_REAL_DATA:
1836 DISSECTOR_ASSERT_NOT_REACHED();
1839 return tvb_find_guint8(tvb->tvbuffs.subset.tvb,
1840 abs_offset - tvb->tvbuffs.subset.offset,
1843 case TVBUFF_COMPOSITE:
1844 DISSECTOR_ASSERT_NOT_REACHED();
1845 /* XXX - return composite_find_guint8(tvb, offset, limit, needle); */
1848 DISSECTOR_ASSERT_NOT_REACHED();
1852 /* Find first occurence of any of the needles in tvbuff, starting at offset.
1853 * Searches at most maxlength number of bytes; if maxlength is -1, searches
1855 * Returns the offset of the found needle, or -1 if not found.
1856 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1857 * in that case, -1 will be returned if the boundary is reached before
1858 * finding needle. */
1860 tvb_pbrk_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength, const guint8 *needles, guchar *found_needle)
1862 const guint8 *result;
1863 guint abs_offset, junk_length;
1867 DISSECTOR_ASSERT(tvb && tvb->initialized);
1869 check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
1871 /* Only search to end of tvbuff, w/o throwing exception. */
1872 tvbufflen = tvb_length_remaining(tvb, abs_offset);
1873 if (maxlength == -1) {
1874 /* No maximum length specified; search to end of tvbuff. */
1877 else if (tvbufflen < (guint) maxlength) {
1878 /* Maximum length goes past end of tvbuff; search to end
1883 /* Maximum length doesn't go past end of tvbuff; search
1888 /* If we have real data, perform our search now. */
1889 if (tvb->real_data) {
1890 result = guint8_pbrk(tvb->real_data + abs_offset, limit, needles, found_needle);
1891 if (result == NULL) {
1895 return (gint) (result - tvb->real_data);
1900 case TVBUFF_REAL_DATA:
1901 DISSECTOR_ASSERT_NOT_REACHED();
1904 return tvb_pbrk_guint8(tvb->tvbuffs.subset.tvb,
1905 abs_offset - tvb->tvbuffs.subset.offset,
1906 limit, needles, found_needle);
1908 case TVBUFF_COMPOSITE:
1909 DISSECTOR_ASSERT_NOT_REACHED();
1910 /* XXX - return composite_pbrk_guint8(tvb, offset, limit, needle); */
1913 DISSECTOR_ASSERT_NOT_REACHED();
1917 /* Find size of stringz (NUL-terminated string) by looking for terminating
1918 * NUL. The size of the string includes the terminating NUL.
1920 * If the NUL isn't found, it throws the appropriate exception.
1923 tvb_strsize(tvbuff_t *tvb, const gint offset)
1925 guint abs_offset, junk_length;
1928 DISSECTOR_ASSERT(tvb && tvb->initialized);
1930 check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
1931 nul_offset = tvb_find_guint8(tvb, abs_offset, -1, 0);
1932 if (nul_offset == -1) {
1934 * OK, we hit the end of the tvbuff, so we should throw
1937 * Did we hit the end of the captured data, or the end
1938 * of the actual data? If there's less captured data
1939 * than actual data, we presumably hit the end of the
1940 * captured data, otherwise we hit the end of the actual
1943 if (tvb_length(tvb) < tvb_reported_length(tvb)) {
1946 THROW(ReportedBoundsError);
1949 return (nul_offset - abs_offset) + 1;
1952 /* Unicode (UTF-16) version of tvb_strsize */
1953 /* Returns number of *UTF-16 characters* (not bytes) excluding the null terminator */
1955 tvb_unicode_strsize(tvbuff_t *tvb, const gint offset)
1960 DISSECTOR_ASSERT(tvb && tvb->initialized);
1963 /* Endianness doesn't matter when looking for null */
1964 uchar = tvb_get_ntohs(tvb, offset + i);
1966 } while(uchar != 0);
1968 return i; /* Number of *UTF-16* characters */
1971 /* Find length of string by looking for end of string ('\0'), up to
1972 * 'maxlength' characters'; if 'maxlength' is -1, searches to end
1974 * Returns -1 if 'maxlength' reached before finding EOS. */
1976 tvb_strnlen(tvbuff_t *tvb, const gint offset, const guint maxlength)
1979 guint abs_offset, junk_length;
1981 DISSECTOR_ASSERT(tvb && tvb->initialized);
1983 check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
1985 result_offset = tvb_find_guint8(tvb, abs_offset, maxlength, 0);
1987 if (result_offset == -1) {
1991 return result_offset - abs_offset;
1996 * Implement strneql etc
2000 * Call strncmp after checking if enough chars left, returning 0 if
2001 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
2004 tvb_strneql(tvbuff_t *tvb, const gint offset, const gchar *str, const size_t size)
2008 ptr = ensure_contiguous_no_exception(tvb, offset, (gint)size, NULL);
2011 int cmp = strncmp((const char *)ptr, str, size);
2014 * Return 0 if equal, -1 otherwise.
2016 return (cmp == 0 ? 0 : -1);
2019 * Not enough characters in the tvbuff to match the
2027 * Call g_ascii_strncasecmp after checking if enough chars left, returning
2028 * 0 if it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
2031 tvb_strncaseeql(tvbuff_t *tvb, const gint offset, const gchar *str, const size_t size)
2035 ptr = ensure_contiguous_no_exception(tvb, offset, (gint)size, NULL);
2038 int cmp = g_ascii_strncasecmp((const char *)ptr, str, size);
2041 * Return 0 if equal, -1 otherwise.
2043 return (cmp == 0 ? 0 : -1);
2046 * Not enough characters in the tvbuff to match the
2054 * Call memcmp after checking if enough chars left, returning 0 if
2055 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
2058 tvb_memeql(tvbuff_t *tvb, const gint offset, const guint8 *str, size_t size)
2062 ptr = ensure_contiguous_no_exception(tvb, offset, (gint) size, NULL);
2065 int cmp = memcmp(ptr, str, size);
2068 * Return 0 if equal, -1 otherwise.
2070 return (cmp == 0 ? 0 : -1);
2073 * Not enough characters in the tvbuff to match the
2080 /* Convert a string from Unicode to ASCII. At the moment we fake it by
2081 * replacing all non-ASCII characters with a '.' )-: The caller must
2082 * free the result returned. The len parameter is the number of guint16's
2083 * to convert from Unicode. */
2085 tvb_fake_unicode(tvbuff_t *tvb, int offset, const int len, const gboolean little_endian)
2091 /* Make sure we have enough data before allocating the buffer,
2092 so we don't blow up if the length is huge. */
2093 tvb_ensure_bytes_exist(tvb, offset, 2*len);
2095 /* We know we won't throw an exception, so we don't have to worry
2096 about leaking this buffer. */
2097 buffer = g_malloc(len + 1);
2099 for (i = 0; i < len; i++) {
2100 character = little_endian ? tvb_get_letohs(tvb, offset)
2101 : tvb_get_ntohs(tvb, offset);
2102 buffer[i] = character < 256 ? character : '.';
2111 /* Convert a string from Unicode to ASCII. At the moment we fake it by
2112 * replacing all non-ASCII characters with a '.' )-: The len parameter is
2113 * the number of guint16's to convert from Unicode.
2115 * This function allocates memory from a buffer with packet lifetime.
2116 * You do not have to free this buffer, it will be automatically freed
2117 * when wireshark starts decoding the next packet.
2120 tvb_get_ephemeral_faked_unicode(tvbuff_t *tvb, int offset, const int len, const gboolean little_endian)
2126 /* Make sure we have enough data before allocating the buffer,
2127 so we don't blow up if the length is huge. */
2128 tvb_ensure_bytes_exist(tvb, offset, 2*len);
2130 /* We know we won't throw an exception, so we don't have to worry
2131 about leaking this buffer. */
2132 buffer = ep_alloc(len + 1);
2134 for (i = 0; i < len; i++) {
2135 character = little_endian ? tvb_get_letohs(tvb, offset)
2136 : tvb_get_ntohs(tvb, offset);
2137 buffer[i] = character < 256 ? character : '.';
2147 * Format the data in the tvb from offset for length ...
2151 tvb_format_text(tvbuff_t *tvb, const gint offset, const gint size)
2156 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2157 len = tvb_length_remaining(tvb, offset);
2158 ptr = ensure_contiguous(tvb, offset, len);
2161 return format_text(ptr, len);
2165 * Format the data in the tvb from offset for length ...
2169 tvb_format_text_wsp(tvbuff_t *tvb, const gint offset, const gint size)
2174 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2176 len = tvb_length_remaining(tvb, offset);
2177 ptr = ensure_contiguous(tvb, offset, len);
2181 return format_text_wsp(ptr, len);
2186 * Like "tvb_format_text()", but for null-padded strings; don't show
2187 * the null padding characters as "\000".
2190 tvb_format_stringzpad(tvbuff_t *tvb, const gint offset, const gint size)
2192 const guint8 *ptr, *p;
2196 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2198 len = tvb_length_remaining(tvb, offset);
2199 ptr = ensure_contiguous(tvb, offset, len);
2203 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2205 return format_text(ptr, stringlen);
2210 * Like "tvb_format_text_wsp()", but for null-padded strings; don't show
2211 * the null padding characters as "\000".
2214 tvb_format_stringzpad_wsp(tvbuff_t *tvb, const gint offset, const gint size)
2216 const guint8 *ptr, *p;
2220 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2222 len = tvb_length_remaining(tvb, offset);
2223 ptr = ensure_contiguous(tvb, offset, len);
2227 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2229 return format_text_wsp(ptr, stringlen);
2234 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2235 * to hold a non-null-terminated string of that length at that offset,
2236 * plus a trailing '\0', copy the string into it, and return a pointer
2239 * Throws an exception if the tvbuff ends before the string does.
2242 tvb_get_string(tvbuff_t *tvb, const gint offset, const gint length)
2245 guint8 *strbuf = NULL;
2247 tvb_ensure_bytes_exist(tvb, offset, length);
2249 ptr = ensure_contiguous(tvb, offset, length);
2250 strbuf = g_malloc(length + 1);
2252 memcpy(strbuf, ptr, length);
2254 strbuf[length] = '\0';
2259 * Unicode (UTF-16) version of tvb_get_string()
2261 * Encoding paramter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN
2263 * Specify length in bytes
2265 * Returns an UTF-8 string that must be freed by the caller
2268 tvb_get_unicode_string(tvbuff_t *tvb, const gint offset, gint length, const guint encoding)
2270 gchar *tmpbuf = NULL;
2272 gint i; /* Byte counter for tvbuff */
2274 GString *strbuf = NULL;
2276 strbuf = g_string_new(NULL);
2278 for(i = 0; i < length; i += 2) {
2280 if(encoding == ENC_BIG_ENDIAN)
2281 uchar = tvb_get_ntohs(tvb, offset + i);
2283 uchar = tvb_get_letohs(tvb, offset + i);
2285 /* Calculate how much space is needed to store UTF-16 character
2287 tmpbuf_len = g_unichar_to_utf8(uchar, NULL);
2289 tmpbuf = g_malloc(tmpbuf_len + 1); /* + 1 to make room for null
2292 g_unichar_to_utf8(uchar, tmpbuf);
2294 /* NULL terminate the tmpbuf so g_string_append knows where
2296 tmpbuf[tmpbuf_len] = '\0';
2298 g_string_append(strbuf, tmpbuf);
2303 return g_string_free(strbuf, FALSE);
2307 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2308 * to hold a non-null-terminated string of that length at that offset,
2309 * plus a trailing '\0', copy the string into it, and return a pointer
2312 * Throws an exception if the tvbuff ends before the string does.
2314 * This function allocates memory from a buffer with packet lifetime.
2315 * You do not have to free this buffer, it will be automatically freed
2316 * when wireshark starts decoding the next packet.
2317 * Do not use this function if you want the allocated memory to be persistent
2318 * after the current packet has been dissected.
2321 tvb_get_ephemeral_string(tvbuff_t *tvb, const gint offset, const gint length)
2324 guint8 *strbuf = NULL;
2326 tvb_ensure_bytes_exist(tvb, offset, length);
2328 ptr = ensure_contiguous(tvb, offset, length);
2329 strbuf = ep_alloc(length + 1);
2331 memcpy(strbuf, ptr, length);
2333 strbuf[length] = '\0';
2338 * Unicode (UTF-16) version of tvb_get_ephemeral_string()
2340 * Encoding paramter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN
2342 * Specify length in bytes
2344 * Returns an ep_ allocated UTF-8 string
2347 tvb_get_ephemeral_unicode_string(tvbuff_t *tvb, const gint offset, gint length, const guint encoding)
2349 gchar *tmpbuf = NULL;
2351 gint i; /* Byte counter for tvbuff */
2353 emem_strbuf_t *strbuf = NULL;
2355 strbuf = ep_strbuf_new(NULL);
2357 for(i = 0; i < length; i += 2) {
2359 if(encoding == ENC_BIG_ENDIAN)
2360 uchar = tvb_get_ntohs(tvb, offset + i);
2362 uchar = tvb_get_letohs(tvb, offset + i);
2364 /* Calculate how much space is needed to store UTF-16 character
2366 tmpbuf_len = g_unichar_to_utf8(uchar, NULL);
2368 tmpbuf = g_malloc(tmpbuf_len + 1); /* + 1 to make room for null
2371 g_unichar_to_utf8(uchar, tmpbuf);
2373 /* NULL terminate the tmpbuf so ep_strbuf_append knows where
2375 tmpbuf[tmpbuf_len] = '\0';
2377 ep_strbuf_append(strbuf, tmpbuf);
2386 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2387 * to hold a non-null-terminated string of that length at that offset,
2388 * plus a trailing '\0', copy the string into it, and return a pointer
2391 * Throws an exception if the tvbuff ends before the string does.
2393 * This function allocates memory from a buffer with capture session lifetime.
2394 * You do not have to free this buffer, it will be automatically freed
2395 * when wireshark starts or opens a new capture.
2398 tvb_get_seasonal_string(tvbuff_t *tvb, const gint offset, const gint length)
2401 guint8 *strbuf = NULL;
2403 tvb_ensure_bytes_exist(tvb, offset, length);
2405 ptr = ensure_contiguous(tvb, offset, length);
2406 strbuf = se_alloc(length + 1);
2408 memcpy(strbuf, ptr, length);
2410 strbuf[length] = '\0';
2415 * Given a tvbuff and an offset, with the offset assumed to refer to
2416 * a null-terminated string, find the length of that string (and throw
2417 * an exception if the tvbuff ends before we find the null), allocate
2418 * a buffer big enough to hold the string, copy the string into it,
2419 * and return a pointer to the string. Also return the length of the
2420 * string (including the terminating null) through a pointer.
2423 tvb_get_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp)
2428 size = tvb_strsize(tvb, offset);
2429 strptr = g_malloc(size);
2430 tvb_memcpy(tvb, strptr, offset, size);
2436 * Given a tvbuff and an offset, with the offset assumed to refer to
2437 * a null-terminated string, find the length of that string (and throw
2438 * an exception if the tvbuff ends before we find the null), allocate
2439 * a buffer big enough to hold the string, copy the string into it,
2440 * and return a pointer to the string. Also return the length of the
2441 * string (including the terminating null) through a pointer.
2443 * This function allocates memory from a buffer with packet lifetime.
2444 * You do not have to free this buffer, it will be automatically freed
2445 * when wireshark starts decoding the next packet.
2446 * Do not use this function if you want the allocated memory to be persistent
2447 * after the current packet has been dissected.
2450 tvb_get_ephemeral_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp)
2455 size = tvb_strsize(tvb, offset);
2456 strptr = ep_alloc(size);
2457 tvb_memcpy(tvb, strptr, offset, size);
2464 * Unicode (UTF-16) version of tvb_get_ephemeral_stringz()
2466 * Encoding paramter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN
2468 * Returns an ep_ allocated UTF-8 string and updates lengthp pointer with length of string (in bytes)
2471 tvb_get_ephemeral_unicode_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding)
2473 gchar *tmpbuf = NULL;
2475 gint size; /* Number of UTF-16 characters */
2476 gint i; /* Byte counter for tvbuff */
2478 emem_strbuf_t *strbuf = NULL;
2480 strbuf = ep_strbuf_new(NULL);
2482 size = tvb_unicode_strsize(tvb, offset);
2484 for(i = 0; i < size; i += 2) {
2486 if(encoding == ENC_BIG_ENDIAN)
2487 uchar = tvb_get_ntohs(tvb, offset + i);
2489 uchar = tvb_get_letohs(tvb, offset + i);
2491 /* Calculate how much space is needed to store UTF-16 character
2493 tmpbuf_len = g_unichar_to_utf8(uchar, NULL);
2495 tmpbuf = g_malloc(tmpbuf_len + 1); /* + 1 to make room for null
2498 g_unichar_to_utf8(uchar, tmpbuf);
2500 /* NULL terminate the tmpbuf so ep_strbuf_append knows where
2502 tmpbuf[tmpbuf_len] = '\0';
2504 ep_strbuf_append(strbuf, tmpbuf);
2510 *lengthp = i; /* Number of *bytes* processed */
2516 * Given a tvbuff and an offset, with the offset assumed to refer to
2517 * a null-terminated string, find the length of that string (and throw
2518 * an exception if the tvbuff ends before we find the null), allocate
2519 * a buffer big enough to hold the string, copy the string into it,
2520 * and return a pointer to the string. Also return the length of the
2521 * string (including the terminating null) through a pointer.
2523 * This function allocates memory from a buffer with capture session lifetime.
2524 * You do not have to free this buffer, it will be automatically freed
2525 * when wireshark starts or opens a new capture.
2528 tvb_get_seasonal_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp)
2533 size = tvb_strsize(tvb, offset);
2534 strptr = se_alloc(size);
2535 tvb_memcpy(tvb, strptr, offset, size);
2541 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
2542 * no more than bufsize number of bytes, including terminating NUL, to buffer.
2543 * Returns length of string (not including terminating NUL), or -1 if the string was
2544 * truncated in the buffer due to not having reached the terminating NUL.
2545 * In this way, it acts like g_snprintf().
2547 * bufsize MUST be greater than 0.
2549 * When processing a packet where the remaining number of bytes is less
2550 * than bufsize, an exception is not thrown if the end of the packet
2551 * is reached before the NUL is found. If no NUL is found before reaching
2552 * the end of the short packet, -1 is still returned, and the string
2553 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
2554 * at the correct spot, terminating the string.
2556 * *bytes_copied will contain the number of bytes actually copied,
2557 * including the terminating-NUL.
2560 _tvb_get_nstringz(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* buffer,
2564 guint abs_offset, junk_length;
2566 gboolean decreased_max = FALSE;
2568 check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
2570 /* There must at least be room for the terminating NUL. */
2571 DISSECTOR_ASSERT(bufsize != 0);
2573 /* If there's no room for anything else, just return the NUL. */
2580 /* Only read to end of tvbuff, w/o throwing exception. */
2581 len = tvb_length_remaining(tvb, abs_offset);
2583 /* check_offset_length() won't throw an exception if we're
2584 * looking at the byte immediately after the end of the tvbuff. */
2586 THROW(ReportedBoundsError);
2589 /* This should not happen because check_offset_length() would
2590 * have already thrown an exception if 'offset' were out-of-bounds.
2592 DISSECTOR_ASSERT(len != -1);
2595 * If we've been passed a negative number, bufsize will
2598 DISSECTOR_ASSERT(bufsize <= G_MAXINT);
2600 if ((guint)len < bufsize) {
2602 decreased_max = TRUE;
2608 stringlen = tvb_strnlen(tvb, abs_offset, limit - 1);
2609 /* If NUL wasn't found, copy the data and return -1 */
2610 if (stringlen == -1) {
2611 tvb_memcpy(tvb, buffer, abs_offset, limit);
2612 if (decreased_max) {
2614 /* Add 1 for the extra NUL that we set at buffer[limit],
2615 * pretending that it was copied as part of the string. */
2616 *bytes_copied = limit + 1;
2619 *bytes_copied = limit;
2624 /* Copy the string to buffer */
2625 tvb_memcpy(tvb, buffer, abs_offset, stringlen + 1);
2626 *bytes_copied = stringlen + 1;
2630 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
2631 * no more than bufsize number of bytes, including terminating NUL, to buffer.
2632 * Returns length of string (not including terminating NUL), or -1 if the string was
2633 * truncated in the buffer due to not having reached the terminating NUL.
2634 * In this way, it acts like g_snprintf().
2636 * When processing a packet where the remaining number of bytes is less
2637 * than bufsize, an exception is not thrown if the end of the packet
2638 * is reached before the NUL is found. If no NUL is found before reaching
2639 * the end of the short packet, -1 is still returned, and the string
2640 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
2641 * at the correct spot, terminating the string.
2644 tvb_get_nstringz(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* buffer)
2648 DISSECTOR_ASSERT(tvb && tvb->initialized);
2650 return _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
2653 /* Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
2654 * have a terminating NUL. If the string was truncated when copied into buffer,
2655 * a NUL is placed at the end of buffer to terminate it.
2658 tvb_get_nstringz0(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* buffer)
2660 gint len, bytes_copied;
2662 DISSECTOR_ASSERT(tvb && tvb->initialized);
2664 len = _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
2667 buffer[bufsize - 1] = 0;
2668 return bytes_copied - 1;
2676 * Given a tvbuff, an offset into the tvbuff, and a length that starts
2677 * at that offset (which may be -1 for "all the way to the end of the
2678 * tvbuff"), find the end of the (putative) line that starts at the
2679 * specified offset in the tvbuff, going no further than the specified
2682 * Return the length of the line (not counting the line terminator at
2683 * the end), or, if we don't find a line terminator:
2685 * if "deseg" is true, return -1;
2687 * if "deseg" is false, return the amount of data remaining in
2690 * Set "*next_offset" to the offset of the character past the line
2691 * terminator, or past the end of the buffer if we don't find a line
2692 * terminator. (It's not set if we return -1.)
2695 tvb_find_line_end(tvbuff_t *tvb, const gint offset, int len, gint *next_offset,
2696 const gboolean desegment)
2701 guchar found_needle = 0;
2704 len = tvb_length_remaining(tvb, offset);
2706 * XXX - what if "len" is still -1, meaning "offset is past the
2707 * end of the tvbuff"?
2709 eob_offset = offset + len;
2712 * Look either for a CR or an LF.
2714 eol_offset = tvb_pbrk_guint8(tvb, offset, len, (const guint8 *)"\r\n", &found_needle);
2715 if (eol_offset == -1) {
2717 * No CR or LF - line is presumably continued in next packet.
2721 * Tell our caller we saw no EOL, so they can
2722 * try to desegment and get the entire line
2728 * Pretend the line runs to the end of the tvbuff.
2730 linelen = eob_offset - offset;
2732 *next_offset = eob_offset;
2736 * Find the number of bytes between the starting offset
2739 linelen = eol_offset - offset;
2744 if (found_needle == '\r') {
2746 * Yes - is it followed by an LF?
2748 if (eol_offset + 1 >= eob_offset) {
2750 * Dunno - the next byte isn't in this
2755 * We'll return -1, although that
2756 * runs the risk that if the line
2757 * really *is* terminated with a CR,
2758 * we won't properly dissect this
2761 * It's probably more likely that
2762 * the line ends with CR-LF than
2763 * that it ends with CR by itself.
2769 * Well, we can at least look at the next
2772 if (tvb_get_guint8(tvb, eol_offset + 1) == '\n') {
2774 * It's an LF; skip over the CR.
2782 * Return the offset of the character after the last
2783 * character in the line, skipping over the last character
2784 * in the line terminator.
2787 *next_offset = eol_offset + 1;
2793 * Given a tvbuff, an offset into the tvbuff, and a length that starts
2794 * at that offset (which may be -1 for "all the way to the end of the
2795 * tvbuff"), find the end of the (putative) line that starts at the
2796 * specified offset in the tvbuff, going no further than the specified
2799 * However, treat quoted strings inside the buffer specially - don't
2800 * treat newlines in quoted strings as line terminators.
2802 * Return the length of the line (not counting the line terminator at
2803 * the end), or the amount of data remaining in the buffer if we don't
2804 * find a line terminator.
2806 * Set "*next_offset" to the offset of the character past the line
2807 * terminator, or past the end of the buffer if we don't find a line
2811 tvb_find_line_end_unquoted(tvbuff_t *tvb, const gint offset, int len,
2814 gint cur_offset, char_offset;
2821 len = tvb_length_remaining(tvb, offset);
2823 * XXX - what if "len" is still -1, meaning "offset is past the
2824 * end of the tvbuff"?
2826 eob_offset = offset + len;
2828 cur_offset = offset;
2832 * Is this part of the string quoted?
2836 * Yes - look only for the terminating quote.
2838 char_offset = tvb_find_guint8(tvb, cur_offset, len,
2842 * Look either for a CR, an LF, or a '"'.
2844 char_offset = tvb_pbrk_guint8(tvb, cur_offset, len,
2845 (const guint8 *)"\r\n\"", &c);
2847 if (char_offset == -1) {
2849 * Not found - line is presumably continued in
2851 * We pretend the line runs to the end of the tvbuff.
2853 linelen = eob_offset - offset;
2855 *next_offset = eob_offset;
2861 * We're processing a quoted string.
2862 * We only looked for ", so we know it's a ";
2863 * as we're processing a quoted string, it's a
2873 * Un-quoted "; it begins a quoted
2879 * It's a CR or LF; we've found a line
2882 * Find the number of bytes between the
2883 * starting offset and the CR or LF.
2885 linelen = char_offset - offset;
2892 * Yes; is it followed by an LF?
2894 if (char_offset + 1 < eob_offset &&
2895 tvb_get_guint8(tvb, char_offset + 1)
2898 * Yes; skip over the CR.
2905 * Return the offset of the character after
2906 * the last character in the line, skipping
2907 * over the last character in the line
2908 * terminator, and quit.
2911 *next_offset = char_offset + 1;
2917 * Step past the character we found.
2919 cur_offset = char_offset + 1;
2920 if (cur_offset >= eob_offset) {
2922 * The character we found was the last character
2923 * in the tvbuff - line is presumably continued in
2925 * We pretend the line runs to the end of the tvbuff.
2927 linelen = eob_offset - offset;
2929 *next_offset = eob_offset;
2937 * Copied from the mgcp dissector. (This function should be moved to /epan )
2938 * tvb_skip_wsp - Returns the position in tvb of the first non-whitespace
2939 * character following offset or offset + maxlength -1 whichever
2943 * tvb - The tvbuff in which we are skipping whitespace.
2944 * offset - The offset in tvb from which we begin trying to skip whitespace.
2945 * maxlength - The maximum distance from offset that we may try to skip
2948 * Returns: The position in tvb of the first non-whitespace
2949 * character following offset or offset + maxlength -1 whichever
2952 gint tvb_skip_wsp(tvbuff_t* tvb, const gint offset, const gint maxlength)
2954 gint counter = offset;
2955 gint end = offset + maxlength,tvb_len;
2958 /* Get the length remaining */
2959 tvb_len = tvb_length(tvb);
2960 end = offset + maxlength;
2966 /* Skip past spaces, tabs, CRs and LFs until run out or meet something else */
2967 for (counter = offset;
2969 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
2970 tempchar == '\t' || tempchar == '\r' || tempchar == '\n');
2976 gint tvb_skip_wsp_return(tvbuff_t* tvb, const gint offset){
2977 gint counter = offset;
2982 for(counter = offset; counter > end &&
2983 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
2984 tempchar == '\t' || tempchar == '\n' || tempchar == '\r'); counter--);
2991 * Format a bunch of data from a tvbuff as bytes, returning a pointer
2992 * to the string with the formatted data, with "punct" as a byte
2996 tvb_bytes_to_str_punct(tvbuff_t *tvb, const gint offset, const gint len, const gchar punct)
2998 return bytes_to_str_punct(tvb_get_ptr(tvb, offset, len), len, punct);
3003 * Given a tvbuff, an offset into the tvbuff, and a length that starts
3004 * at that offset (which may be -1 for "all the way to the end of the
3005 * tvbuff"), fetch BCD encoded digits from a tvbuff starting from either
3006 * the low or high half byte, formating the digits according to an input digit set,
3007 * if NUll a default digit set of 0-9 returning "?" for overdecadic digits will be used.
3008 * A pointer to the EP allocated string will be returned.
3009 * Note a tvbuff content of 0xf is considered a 'filler' and will end the conversion.
3011 static dgt_set_t Dgt1_9_bcd = {
3013 /* 0 1 2 3 4 5 6 7 8 9 a b c d e */
3014 '0','1','2','3','4','5','6','7','8','9','?','?','?','?','?'
3018 tvb_bcd_dig_to_ep_str(tvbuff_t *tvb, const gint offset, const gint len, dgt_set_t *dgt, gboolean skip_first)
3024 gint t_offset = offset;
3030 length = tvb_length(tvb);
3031 if (length < offset){
3035 length = offset + len;
3037 digit_str = ep_alloc((length - offset)*2+1);
3039 while ( t_offset < length ){
3041 octet = tvb_get_guint8(tvb,t_offset);
3043 digit_str[i] = dgt->out[octet & 0x0f];
3049 * unpack second value in byte
3053 if (octet == 0x0f) /* odd number bytes - hit filler */
3056 digit_str[i] = dgt->out[octet & 0x0f];
3067 * Format a bunch of data from a tvbuff as bytes, returning a pointer
3068 * to the string with the formatted data.
3071 tvb_bytes_to_str(tvbuff_t *tvb, const gint offset, const gint len)
3073 return bytes_to_str(tvb_get_ptr(tvb, offset, len), len);
3076 /* Find a needle tvbuff within a haystack tvbuff. */
3078 tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb, const gint haystack_offset)
3080 guint haystack_abs_offset, haystack_abs_length;
3081 const guint8 *haystack_data;
3082 const guint8 *needle_data;
3083 const guint needle_len = needle_tvb->length;
3084 const guint8 *location;
3086 DISSECTOR_ASSERT(haystack_tvb && haystack_tvb->initialized);
3088 if (haystack_tvb->length < 1 || needle_tvb->length < 1) {
3092 /* Get pointers to the tvbuffs' data. */
3093 haystack_data = tvb_get_ptr(haystack_tvb, 0, -1);
3094 needle_data = tvb_get_ptr(needle_tvb, 0, -1);
3096 check_offset_length(haystack_tvb->length, haystack_tvb->reported_length, haystack_offset, -1,
3097 &haystack_abs_offset, &haystack_abs_length);
3099 location = epan_memmem(haystack_data + haystack_abs_offset, haystack_abs_length,
3100 needle_data, needle_len);
3103 return (gint) (location - haystack_data);
3111 * Uncompresses a zlib compressed packet inside a message of tvb at offset with
3112 * length comprlen. Returns an uncompressed tvbuffer if uncompression
3113 * succeeded or NULL if uncompression failed.
3115 #define TVB_Z_MIN_BUFSIZ 32768
3116 #define TVB_Z_MAX_BUFSIZ 1048576 * 10
3117 /* #define TVB_Z_DEBUG 1 */
3121 tvb_uncompress(tvbuff_t *tvb, const int offset, int comprlen)
3124 guint bytes_out = 0;
3125 guint8 *compr = NULL;
3126 guint8 *uncompr = NULL;
3127 tvbuff_t *uncompr_tvb = NULL;
3128 z_streamp strm = NULL;
3129 Bytef *strmbuf = NULL;
3130 guint inits_done = 0;
3131 gint wbits = MAX_WBITS;
3132 guint8 *next = NULL;
3133 guint bufsiz = TVB_Z_MIN_BUFSIZ;
3135 guint inflate_passes = 0;
3136 guint bytes_in = tvb_length_remaining(tvb, offset);
3143 compr = tvb_memdup(tvb, offset, comprlen);
3149 * Assume that the uncompressed data is at least twice as big as
3150 * the compressed size.
3152 bufsiz = tvb_length_remaining(tvb, offset) * 2;
3153 bufsiz = CLAMP(bufsiz, TVB_Z_MIN_BUFSIZ, TVB_Z_MAX_BUFSIZ);
3156 printf("bufsiz: %u bytes\n", bufsiz);
3161 strm = g_new0(z_stream, 1);
3162 strm->next_in = next;
3163 strm->avail_in = comprlen;
3165 strmbuf = g_malloc0(bufsiz);
3166 strm->next_out = strmbuf;
3167 strm->avail_out = bufsiz;
3169 err = inflateInit2(strm, wbits);
3180 memset(strmbuf, '\0', bufsiz);
3181 strm->next_out = strmbuf;
3182 strm->avail_out = bufsiz;
3184 err = inflate(strm, Z_SYNC_FLUSH);
3186 if (err == Z_OK || err == Z_STREAM_END) {
3187 guint bytes_pass = bufsiz - strm->avail_out;
3193 if (uncompr == NULL) {
3194 uncompr = g_memdup(strmbuf, bytes_pass);
3196 guint8 *new_data = g_malloc0(bytes_out + bytes_pass);
3198 g_memmove(new_data, uncompr, bytes_out);
3199 g_memmove((new_data + bytes_out), strmbuf,
3206 bytes_out += bytes_pass;
3208 if ( err == Z_STREAM_END) {
3214 } else if (err == Z_BUF_ERROR) {
3216 * It's possible that not enough frames were captured
3217 * to decompress this fully, so return what we've done
3224 if (uncompr != NULL) {
3231 } else if (err == Z_DATA_ERROR && inits_done == 1
3232 && uncompr == NULL && (*compr == 0x1f) &&
3233 (*(compr + 1) == 0x8b)) {
3235 * inflate() is supposed to handle both gzip and deflate
3236 * streams automatically, but in reality it doesn't
3237 * seem to handle either (at least not within the
3238 * context of an HTTP response.) We have to try
3239 * several tweaks, depending on the type of data and
3240 * version of the library installed.
3244 * Gzip file format. Skip past the header, since the
3245 * fix to make it work (setting windowBits to 31)
3246 * doesn't work with all versions of the library.
3248 Bytef *c = compr + 2;
3251 if (*c == Z_DEFLATED) {
3263 /* Skip past the MTIME, XFL, and OS fields. */
3266 if (flags & (1 << 2)) {
3267 /* An Extra field is present. */
3268 gint xsize = (gint)(*c |
3274 if (flags & (1 << 3)) {
3275 /* A null terminated filename */
3277 while ((c - compr) < comprlen && *c != '\0') {
3284 if (flags & (1 << 4)) {
3285 /* A null terminated comment */
3287 while ((c - compr) < comprlen && *c != '\0') {
3297 strm->next_in = next;
3298 if (c - compr > comprlen) {
3305 comprlen -= (int) (c - compr);
3308 err = inflateInit2(strm, wbits);
3310 } else if (err == Z_DATA_ERROR && uncompr == NULL &&
3314 * Re-init the stream with a negative
3315 * MAX_WBITS. This is necessary due to
3316 * some servers (Apache) not sending
3317 * the deflate header with the
3318 * content-encoded response.
3324 strm->next_in = next;
3325 strm->avail_in = comprlen;
3328 memset(strmbuf, '\0', bufsiz);
3329 strm->next_out = strmbuf;
3330 strm->avail_out = bufsiz;
3332 err = inflateInit2(strm, wbits);
3350 if (uncompr == NULL) {
3359 printf("inflate() total passes: %u\n", inflate_passes);
3360 printf("bytes in: %u\nbytes out: %u\n\n", bytes_in, bytes_out);
3363 if (uncompr != NULL) {
3364 uncompr_tvb = tvb_new_real_data((guint8*) uncompr, bytes_out,
3366 tvb_set_free_cb(uncompr_tvb, g_free);
3373 tvb_uncompress(tvbuff_t *tvb _U_, const int offset _U_, int comprlen _U_)
3379 tvbuff_t* tvb_child_uncompress(tvbuff_t *parent, tvbuff_t *tvb, const int offset, int comprlen)
3381 tvbuff_t *new_tvb = tvb_uncompress(tvb, offset, comprlen);
3383 tvb_set_child_real_data_tvbuff (parent, new_tvb);