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, gint offset, gint length,
59 ensure_contiguous(tvbuff_t *tvb, gint offset, 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, 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(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(guint subset_tvb_offset, 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, guint count)
222 tvb->usage_count += count;
224 return tvb->usage_count;
228 tvb_decrement_usage_count(tvbuff_t* tvb, 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, 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, guint length, 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, guint length, 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, guint length, 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, guint length, 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(guint tvb_length, guint tvb_reported_length, gint offset, gint length,
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) {
360 *exception = ReportedBoundsError;
364 else if ((guint) offset > tvb_length) {
366 *exception = BoundsError;
371 *offset_ptr = offset;
375 /* Negative offset - relative to the end of the packet. */
376 if ((guint) -offset > tvb_reported_length) {
378 *exception = ReportedBoundsError;
382 else if ((guint) -offset > tvb_length) {
384 *exception = BoundsError;
389 *offset_ptr = tvb_length + offset;
393 /* Compute the length */
396 /* XXX - ReportedBoundsError? */
397 *exception = BoundsError;
401 else if (length == -1) {
402 *length_ptr = tvb_length - *offset_ptr;
405 *length_ptr = length;
413 check_offset_length_no_exception(guint tvb_length, guint tvb_reported_length, gint offset, gint length,
414 guint *offset_ptr, guint *length_ptr, int *exception)
418 if (!compute_offset_length(tvb_length, tvb_reported_length, offset, length, 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) {
445 else if (end_offset <= tvb_reported_length) {
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(guint tvb_length, guint tvb_reported_length, gint offset, gint length,
464 guint *offset_ptr, guint *length_ptr)
468 if (!check_offset_length_no_exception(tvb_length, tvb_reported_length, offset, length, offset_ptr, length_ptr, &exception)) {
469 DISSECTOR_ASSERT(exception > 0);
475 tvb_set_subset_no_exceptions(tvbuff_t *tvb, tvbuff_t *backing, 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 gint backing_offset, gint backing_length, 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, gint backing_offset, gint backing_length, gint reported_length)
517 guint subset_tvb_offset;
518 guint subset_tvb_length;
520 THROW_ON(reported_length < -1, ReportedBoundsError);
522 check_offset_length(backing->length, backing->reported_length, backing_offset, backing_length,
526 tvb = tvb_new_with_subset(subset_tvb_offset, subset_tvb_length);
528 tvb_set_subset_no_exceptions(tvb, backing, reported_length);
531 * The top-level data source of this tvbuff is the top-level
532 * data source of its parent.
534 tvb->ds_tvb = backing->ds_tvb;
540 tvb_new_subset_remaining(tvbuff_t *backing, gint backing_offset)
543 guint subset_tvb_offset;
544 guint subset_tvb_length;
546 check_offset_length(backing->length, backing->reported_length, backing_offset, -1 /* backing_length */,
550 tvb = tvb_new_with_subset(subset_tvb_offset, subset_tvb_length);
552 tvb_set_subset_no_exceptions(tvb, backing, -1 /* reported_length */);
555 * The top-level data source of this tvbuff is the top-level
556 * data source of its parent.
558 tvb->ds_tvb = backing->ds_tvb;
564 tvb_composite_append(tvbuff_t* tvb, tvbuff_t* member)
566 tvb_comp_t *composite;
568 DISSECTOR_ASSERT(tvb && !tvb->initialized);
569 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
570 composite = &tvb->tvbuffs.composite;
571 composite->tvbs = g_slist_append( composite->tvbs, member );
572 add_to_used_in_list(tvb, member);
576 tvb_composite_prepend(tvbuff_t* tvb, tvbuff_t* member)
578 tvb_comp_t *composite;
580 DISSECTOR_ASSERT(tvb && !tvb->initialized);
581 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
582 composite = &tvb->tvbuffs.composite;
583 composite->tvbs = g_slist_prepend( composite->tvbs, member );
584 add_to_used_in_list(tvb, member);
588 tvb_new_composite(void)
590 return tvb_new(TVBUFF_COMPOSITE);
594 tvb_composite_finalize(tvbuff_t* tvb)
598 tvbuff_t *member_tvb;
599 tvb_comp_t *composite;
602 DISSECTOR_ASSERT(tvb && !tvb->initialized);
603 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
604 DISSECTOR_ASSERT(tvb->length == 0);
606 composite = &tvb->tvbuffs.composite;
607 num_members = g_slist_length(composite->tvbs);
609 composite->start_offsets = g_new(guint, num_members);
610 composite->end_offsets = g_new(guint, num_members);
612 for (slist = composite->tvbs; slist != NULL; slist = slist->next) {
613 DISSECTOR_ASSERT((guint) i < num_members);
614 member_tvb = slist->data;
615 composite->start_offsets[i] = tvb->length;
616 tvb->length += member_tvb->length;
617 composite->end_offsets[i] = tvb->length - 1;
621 tvb->initialized = TRUE;
627 tvb_length(tvbuff_t* tvb)
629 DISSECTOR_ASSERT(tvb && tvb->initialized);
635 tvb_length_remaining(tvbuff_t *tvb, gint offset)
637 guint abs_offset, abs_length;
639 DISSECTOR_ASSERT(tvb && tvb->initialized);
641 if (compute_offset_length(tvb->length, tvb->reported_length, offset, -1, &abs_offset, &abs_length, NULL)) {
650 tvb_ensure_length_remaining(tvbuff_t *tvb, gint offset)
652 guint abs_offset, abs_length;
655 DISSECTOR_ASSERT(tvb && tvb->initialized);
657 if (!compute_offset_length(tvb->length, tvb->reported_length, offset, -1, &abs_offset, &abs_length, &exception)) {
660 if (abs_length == 0) {
662 * This routine ensures there's at least one byte available.
663 * There aren't any bytes available, so throw the appropriate
666 if (abs_offset >= tvb->reported_length)
667 THROW(ReportedBoundsError);
677 /* Validates that 'length' bytes are available starting from
678 * offset (pos/neg). Does not throw an exception. */
680 tvb_bytes_exist(tvbuff_t *tvb, gint offset, gint length)
682 guint abs_offset, abs_length;
684 DISSECTOR_ASSERT(tvb && tvb->initialized);
686 if (!compute_offset_length(tvb->length, tvb->reported_length, offset, length, &abs_offset, &abs_length, NULL))
689 if (abs_offset + abs_length <= tvb->length) {
697 /* Validates that 'length' bytes are available starting from
698 * offset (pos/neg). Throws an exception if they aren't. */
700 tvb_ensure_bytes_exist(tvbuff_t *tvb, gint offset, gint length)
702 guint abs_offset, abs_length;
704 DISSECTOR_ASSERT(tvb && tvb->initialized);
707 * -1 doesn't mean "until end of buffer", as that's pointless
708 * for this routine. We must treat it as a Really Large Positive
709 * Number, so that we throw an exception; we throw
710 * ReportedBoundsError, as if it were past even the end of a
711 * reassembled packet, and past the end of even the data we
714 * We do the same with other negative lengths.
717 THROW(ReportedBoundsError);
719 check_offset_length(tvb->length, tvb->reported_length, offset, length, &abs_offset, &abs_length);
723 tvb_offset_exists(tvbuff_t *tvb, gint offset)
725 guint abs_offset, abs_length;
727 DISSECTOR_ASSERT(tvb && tvb->initialized);
728 if (!compute_offset_length(tvb->length, tvb->reported_length, offset, -1, &abs_offset, &abs_length, NULL))
731 if (abs_offset < tvb->length) {
740 tvb_reported_length(tvbuff_t* tvb)
742 DISSECTOR_ASSERT(tvb && tvb->initialized);
744 return tvb->reported_length;
748 tvb_reported_length_remaining(tvbuff_t *tvb, gint offset)
750 guint abs_offset, abs_length;
752 DISSECTOR_ASSERT(tvb && tvb->initialized);
754 if (compute_offset_length(tvb->length, tvb->reported_length, offset, -1, &abs_offset, &abs_length, NULL)) {
755 if (tvb->reported_length >= abs_offset)
756 return tvb->reported_length - abs_offset;
765 /* Set the reported length of a tvbuff to a given value; used for protocols
766 whose headers contain an explicit length and where the calling
767 dissector's payload may include padding as well as the packet for
770 Also adjusts the data length. */
772 tvb_set_reported_length(tvbuff_t* tvb, guint reported_length)
774 DISSECTOR_ASSERT(tvb && tvb->initialized);
776 if (reported_length > tvb->reported_length)
777 THROW(ReportedBoundsError);
779 tvb->reported_length = reported_length;
780 if (reported_length < tvb->length)
781 tvb->length = reported_length;
787 first_real_data_ptr(tvbuff_t *tvb)
792 case TVBUFF_REAL_DATA:
793 return tvb->real_data;
795 member = tvb->tvbuffs.subset.tvb;
796 return first_real_data_ptr(member);
797 case TVBUFF_COMPOSITE:
798 member = tvb->tvbuffs.composite.tvbs->data;
799 return first_real_data_ptr(member);
802 DISSECTOR_ASSERT_NOT_REACHED();
808 offset_from_real_beginning(tvbuff_t *tvb, guint counter)
813 case TVBUFF_REAL_DATA:
816 member = tvb->tvbuffs.subset.tvb;
817 return offset_from_real_beginning(member, counter + tvb->tvbuffs.subset.offset);
818 case TVBUFF_COMPOSITE:
819 member = tvb->tvbuffs.composite.tvbs->data;
820 return offset_from_real_beginning(member, counter);
823 DISSECTOR_ASSERT_NOT_REACHED();
828 tvb_offset_from_real_beginning(tvbuff_t *tvb)
830 return offset_from_real_beginning(tvb, 0);
834 composite_ensure_contiguous_no_exception(tvbuff_t *tvb, guint abs_offset,
837 guint i, num_members;
838 tvb_comp_t *composite;
839 tvbuff_t *member_tvb = NULL;
840 guint member_offset, member_length;
843 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
845 /* Maybe the range specified by offset/length
846 * is contiguous inside one of the member tvbuffs */
847 composite = &tvb->tvbuffs.composite;
848 num_members = g_slist_length(composite->tvbs);
850 for (i = 0; i < num_members; i++) {
851 if (abs_offset <= composite->end_offsets[i]) {
852 slist = g_slist_nth(composite->tvbs, i);
853 member_tvb = slist->data;
857 DISSECTOR_ASSERT(member_tvb);
859 if (check_offset_length_no_exception(member_tvb->length, member_tvb->reported_length, abs_offset - composite->start_offsets[i],
860 abs_length, &member_offset, &member_length, NULL)) {
863 * The range is, in fact, contiguous within member_tvb.
865 DISSECTOR_ASSERT(!tvb->real_data);
866 return ensure_contiguous_no_exception(member_tvb, member_offset, member_length, NULL);
869 tvb->real_data = tvb_memdup(tvb, 0, -1);
870 return tvb->real_data + abs_offset;
873 DISSECTOR_ASSERT_NOT_REACHED();
878 ensure_contiguous_no_exception(tvbuff_t *tvb, gint offset, gint length,
881 guint abs_offset, abs_length;
883 if (!check_offset_length_no_exception(tvb->length, tvb->reported_length, offset, length,
884 &abs_offset, &abs_length, exception)) {
889 * We know that all the data is present in the tvbuff, so
890 * no exceptions should be thrown.
892 if (tvb->real_data) {
893 return tvb->real_data + abs_offset;
897 case TVBUFF_REAL_DATA:
898 DISSECTOR_ASSERT_NOT_REACHED();
900 return ensure_contiguous_no_exception(tvb->tvbuffs.subset.tvb,
901 abs_offset - tvb->tvbuffs.subset.offset,
903 case TVBUFF_COMPOSITE:
904 return composite_ensure_contiguous_no_exception(tvb, abs_offset, abs_length);
908 DISSECTOR_ASSERT_NOT_REACHED();
913 ensure_contiguous(tvbuff_t *tvb, gint offset, gint length)
918 p = ensure_contiguous_no_exception(tvb, offset, length, &exception);
920 DISSECTOR_ASSERT(exception > 0);
927 fast_ensure_contiguous(tvbuff_t *tvb, gint offset, guint length)
932 DISSECTOR_ASSERT(tvb && tvb->initialized);
933 /* We don't check for overflow in this fast path so we only handle simple types */
934 DISSECTOR_ASSERT(length <= 8);
936 if (offset < 0 || !tvb->real_data) {
937 return ensure_contiguous(tvb, offset, length);
941 end_offset = u_offset + length;
943 if (end_offset <= tvb->length) {
944 return tvb->real_data + u_offset;
947 if (end_offset > tvb->reported_length) {
948 THROW(ReportedBoundsError);
956 guint8_find(const guint8* haystack, size_t haystacklen, guint8 needle)
961 for (b = haystack, i = 0; (guint) i < haystacklen; i++, b++) {
971 guint8_pbrk(const guint8* haystack, size_t haystacklen, const guint8 *needles)
976 const guint8 *needlep;
978 for (b = haystack, i = 0; (guint) i < haystacklen; i++, b++) {
981 while ((needle = *needlep) != '\0') {
993 /************** ACCESSORS **************/
996 composite_memcpy(tvbuff_t *tvb, guint8* target, guint abs_offset, size_t abs_length)
998 guint i, num_members;
999 tvb_comp_t *composite;
1000 tvbuff_t *member_tvb = NULL;
1001 guint member_offset, member_length;
1005 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
1007 /* Maybe the range specified by offset/length
1008 * is contiguous inside one of the member tvbuffs */
1009 composite = &tvb->tvbuffs.composite;
1010 num_members = g_slist_length(composite->tvbs);
1012 for (i = 0; i < num_members; i++) {
1013 if (abs_offset <= composite->end_offsets[i]) {
1014 slist = g_slist_nth(composite->tvbs, i);
1015 member_tvb = slist->data;
1019 DISSECTOR_ASSERT(member_tvb);
1021 if (check_offset_length_no_exception(member_tvb->length, member_tvb->reported_length, abs_offset - composite->start_offsets[i],
1022 (gint) abs_length, &member_offset, &member_length, NULL)) {
1024 DISSECTOR_ASSERT(!tvb->real_data);
1025 return tvb_memcpy(member_tvb, target, member_offset, member_length);
1028 /* The requested data is non-contiguous inside
1029 * the member tvb. We have to memcpy() the part that's in the member tvb,
1030 * then iterate across the other member tvb's, copying their portions
1031 * until we have copied all data.
1033 retval = compute_offset_length(member_tvb->length, member_tvb->reported_length, abs_offset - composite->start_offsets[i], -1,
1034 &member_offset, &member_length, NULL);
1035 DISSECTOR_ASSERT(retval);
1037 tvb_memcpy(member_tvb, target, member_offset, member_length);
1038 abs_offset += member_length;
1039 abs_length -= member_length;
1042 if (abs_length > 0) {
1043 composite_memcpy(tvb, target + member_length, abs_offset, abs_length);
1049 DISSECTOR_ASSERT_NOT_REACHED();
1054 tvb_memcpy(tvbuff_t *tvb, void* target, gint offset, size_t length)
1056 guint abs_offset, abs_length;
1058 DISSECTOR_ASSERT(tvb && tvb->initialized);
1061 * XXX - we should eliminate the "length = -1 means 'to the end
1062 * of the tvbuff'" convention, and use other means to achieve
1063 * that; this would let us eliminate a bunch of checks for
1064 * negative lengths in cases where the protocol has a 32-bit
1067 * Allowing -1 but throwing an assertion on other negative
1068 * lengths is a bit more work with the length being a size_t;
1069 * instead, we check for a length <= 2^31-1.
1071 DISSECTOR_ASSERT(length <= 0x7FFFFFFF);
1072 check_offset_length(tvb->length, tvb->reported_length, offset, (gint) length, &abs_offset, &abs_length);
1074 if (tvb->real_data) {
1075 return memcpy(target, tvb->real_data + abs_offset, abs_length);
1079 case TVBUFF_REAL_DATA:
1080 DISSECTOR_ASSERT_NOT_REACHED();
1083 return tvb_memcpy(tvb->tvbuffs.subset.tvb, target,
1084 abs_offset - tvb->tvbuffs.subset.offset,
1087 case TVBUFF_COMPOSITE:
1088 return composite_memcpy(tvb, target, offset, length);
1091 DISSECTOR_ASSERT_NOT_REACHED();
1097 * XXX - this doesn't treat a length of -1 as an error.
1098 * If it did, this could replace some code that calls
1099 * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies
1102 * "composite_ensure_contiguous_no_exception()" depends on -1 not being
1103 * an error; does anything else depend on this routine treating -1 as
1104 * meaning "to the end of the buffer"?
1107 tvb_memdup(tvbuff_t *tvb, gint offset, size_t length)
1109 guint abs_offset, abs_length;
1112 DISSECTOR_ASSERT(tvb && tvb->initialized);
1114 check_offset_length(tvb->length, tvb->reported_length, offset, (gint) length, &abs_offset, &abs_length);
1116 duped = g_malloc(abs_length);
1117 return tvb_memcpy(tvb, duped, abs_offset, abs_length);
1121 * XXX - this doesn't treat a length of -1 as an error.
1122 * If it did, this could replace some code that calls
1123 * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies
1126 * "composite_ensure_contiguous_no_exception()" depends on -1 not being
1127 * an error; does anything else depend on this routine treating -1 as
1128 * meaning "to the end of the buffer"?
1130 * This function allocates memory from a buffer with packet lifetime.
1131 * You do not have to free this buffer, it will be automatically freed
1132 * when wireshark starts decoding the next packet.
1133 * Do not use this function if you want the allocated memory to be persistent
1134 * after the current packet has been dissected.
1137 ep_tvb_memdup(tvbuff_t *tvb, gint offset, size_t length)
1139 guint abs_offset, abs_length;
1142 DISSECTOR_ASSERT(tvb && tvb->initialized);
1144 check_offset_length(tvb->length, tvb->reported_length, offset, (gint) length, &abs_offset, &abs_length);
1146 duped = ep_alloc(abs_length);
1147 return tvb_memcpy(tvb, duped, abs_offset, abs_length);
1153 tvb_get_ptr(tvbuff_t *tvb, gint offset, gint length)
1155 return ensure_contiguous(tvb, offset, length);
1158 /* ---------------- */
1160 tvb_get_guint8(tvbuff_t *tvb, gint offset)
1164 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint8));
1169 tvb_get_ntohs(tvbuff_t *tvb, gint offset)
1173 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint16));
1178 tvb_get_ntoh24(tvbuff_t *tvb, gint offset)
1182 ptr = fast_ensure_contiguous(tvb, offset, 3);
1183 return pntoh24(ptr);
1187 tvb_get_ntohl(tvbuff_t *tvb, gint offset)
1191 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1196 tvb_get_ntoh64(tvbuff_t *tvb, gint offset)
1200 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint64));
1201 return pntoh64(ptr);
1205 * Stuff for IEEE float handling on platforms that don't have IEEE
1206 * format as the native floating-point format.
1208 * For now, we treat only the VAX as such a platform.
1210 * XXX - other non-IEEE boxes that can run UNIX include some Crays,
1211 * and possibly other machines.
1213 * It appears that the official Linux port to System/390 and
1214 * zArchitecture uses IEEE format floating point (not a
1217 * I don't know whether there are any other machines that
1218 * could run Wireshark and that don't use IEEE format.
1219 * As far as I know, all of the main commercial microprocessor
1220 * families on which OSes that support Wireshark can run
1221 * use IEEE format (x86, 68k, SPARC, MIPS, PA-RISC, Alpha,
1222 * IA-64, and so on).
1232 #define IEEE_SP_NUMBER_WIDTH 32 /* bits in number */
1233 #define IEEE_SP_EXP_WIDTH 8 /* bits in exponent */
1234 #define IEEE_SP_MANTISSA_WIDTH 23 /* IEEE_SP_NUMBER_WIDTH - 1 - IEEE_SP_EXP_WIDTH */
1236 #define IEEE_SP_SIGN_MASK 0x80000000
1237 #define IEEE_SP_EXPONENT_MASK 0x7F800000
1238 #define IEEE_SP_MANTISSA_MASK 0x007FFFFF
1239 #define IEEE_SP_INFINITY IEEE_SP_EXPONENT_MASK
1241 #define IEEE_SP_IMPLIED_BIT (1 << IEEE_SP_MANTISSA_WIDTH)
1242 #define IEEE_SP_INFINITE ((1 << IEEE_SP_EXP_WIDTH) - 1)
1243 #define IEEE_SP_BIAS ((1 << (IEEE_SP_EXP_WIDTH - 1)) - 1)
1246 ieee_float_is_zero(guint32 w)
1248 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1252 get_ieee_float(guint32 w)
1258 sign = w & IEEE_SP_SIGN_MASK;
1259 exponent = w & IEEE_SP_EXPONENT_MASK;
1260 mantissa = w & IEEE_SP_MANTISSA_MASK;
1262 if (ieee_float_is_zero(w)) {
1263 /* number is zero, unnormalized, or not-a-number */
1268 * XXX - how to handle this?
1270 if (IEEE_SP_INFINITY == exponent) {
1272 * number is positive or negative infinity, or a special value
1274 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1278 exponent = ((exponent >> IEEE_SP_MANTISSA_WIDTH) - IEEE_SP_BIAS) -
1279 IEEE_SP_MANTISSA_WIDTH;
1280 mantissa |= IEEE_SP_IMPLIED_BIT;
1283 return -mantissa * pow(2, exponent);
1285 return mantissa * pow(2, exponent);
1290 * We assume that if you don't have IEEE floating-point, you have a
1291 * compiler that understands 64-bit integral quantities.
1293 #define IEEE_DP_NUMBER_WIDTH 64 /* bits in number */
1294 #define IEEE_DP_EXP_WIDTH 11 /* bits in exponent */
1295 #define IEEE_DP_MANTISSA_WIDTH 52 /* IEEE_DP_NUMBER_WIDTH - 1 - IEEE_DP_EXP_WIDTH */
1297 #define IEEE_DP_SIGN_MASK 0x8000000000000000LL
1298 #define IEEE_DP_EXPONENT_MASK 0x7FF0000000000000LL
1299 #define IEEE_DP_MANTISSA_MASK 0x000FFFFFFFFFFFFFLL
1300 #define IEEE_DP_INFINITY IEEE_DP_EXPONENT_MASK
1302 #define IEEE_DP_IMPLIED_BIT (1LL << IEEE_DP_MANTISSA_WIDTH)
1303 #define IEEE_DP_INFINITE ((1 << IEEE_DP_EXP_WIDTH) - 1)
1304 #define IEEE_DP_BIAS ((1 << (IEEE_DP_EXP_WIDTH - 1)) - 1)
1307 ieee_double_is_zero(guint64 w)
1309 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1313 get_ieee_double(guint64 w)
1319 sign = w & IEEE_DP_SIGN_MASK;
1320 exponent = w & IEEE_DP_EXPONENT_MASK;
1321 mantissa = w & IEEE_DP_MANTISSA_MASK;
1323 if (ieee_double_is_zero(w)) {
1324 /* number is zero, unnormalized, or not-a-number */
1329 * XXX - how to handle this?
1331 if (IEEE_DP_INFINITY == exponent) {
1333 * number is positive or negative infinity, or a special value
1335 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1339 exponent = ((exponent >> IEEE_DP_MANTISSA_WIDTH) - IEEE_DP_BIAS) -
1340 IEEE_DP_MANTISSA_WIDTH;
1341 mantissa |= IEEE_DP_IMPLIED_BIT;
1344 return -mantissa * pow(2, exponent);
1346 return mantissa * pow(2, exponent);
1351 * Fetches an IEEE single-precision floating-point number, in
1352 * big-endian form, and returns a "float".
1354 * XXX - should this be "double", in case there are IEEE single-
1355 * precision numbers that won't fit in some platform's native
1359 tvb_get_ntohieee_float(tvbuff_t *tvb, int offset)
1362 return get_ieee_float(tvb_get_ntohl(tvb, offset));
1369 ieee_fp_union.w = tvb_get_ntohl(tvb, offset);
1370 return ieee_fp_union.f;
1375 * Fetches an IEEE double-precision floating-point number, in
1376 * big-endian form, and returns a "double".
1379 tvb_get_ntohieee_double(tvbuff_t *tvb, int offset)
1393 #ifdef WORDS_BIGENDIAN
1394 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset);
1395 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset+4);
1397 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset+4);
1398 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset);
1401 return get_ieee_double(ieee_fp_union.dw);
1403 return ieee_fp_union.d;
1408 tvb_get_letohs(tvbuff_t *tvb, gint offset)
1412 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint16));
1413 return pletohs(ptr);
1417 tvb_get_letoh24(tvbuff_t *tvb, gint offset)
1421 ptr = fast_ensure_contiguous(tvb, offset, 3);
1422 return pletoh24(ptr);
1426 tvb_get_letohl(tvbuff_t *tvb, gint offset)
1430 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1431 return pletohl(ptr);
1435 tvb_get_letoh64(tvbuff_t *tvb, gint offset)
1439 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint64));
1440 return pletoh64(ptr);
1444 * Fetches an IEEE single-precision floating-point number, in
1445 * little-endian form, and returns a "float".
1447 * XXX - should this be "double", in case there are IEEE single-
1448 * precision numbers that won't fit in some platform's native
1452 tvb_get_letohieee_float(tvbuff_t *tvb, int offset)
1455 return get_ieee_float(tvb_get_letohl(tvb, offset));
1462 ieee_fp_union.w = tvb_get_letohl(tvb, offset);
1463 return ieee_fp_union.f;
1468 * Fetches an IEEE double-precision floating-point number, in
1469 * little-endian form, and returns a "double".
1472 tvb_get_letohieee_double(tvbuff_t *tvb, int offset)
1486 #ifdef WORDS_BIGENDIAN
1487 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset+4);
1488 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset);
1490 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset);
1491 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset+4);
1494 return get_ieee_double(ieee_fp_union.dw);
1496 return ieee_fp_union.d;
1500 /* Fetch an IPv4 address, in network byte order.
1501 * We do *not* convert them to host byte order; we leave them in
1502 * network byte order. */
1504 tvb_get_ipv4(tvbuff_t *tvb, gint offset)
1509 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1510 memcpy(&addr, ptr, sizeof addr);
1514 /* Fetch an IPv6 address. */
1516 tvb_get_ipv6(tvbuff_t *tvb, gint offset, struct e_in6_addr *addr)
1520 ptr = ensure_contiguous(tvb, offset, sizeof(*addr));
1521 memcpy(addr, ptr, sizeof *addr);
1526 tvb_get_ntohguid(tvbuff_t *tvb, gint offset, e_guid_t *guid)
1528 ensure_contiguous(tvb, offset, sizeof(*guid));
1529 guid->data1 = tvb_get_ntohl(tvb, offset);
1530 guid->data2 = tvb_get_ntohs(tvb, offset + 4);
1531 guid->data3 = tvb_get_ntohs(tvb, offset + 6);
1532 tvb_memcpy(tvb, guid->data4, offset + 8, sizeof guid->data4);
1536 tvb_get_letohguid(tvbuff_t *tvb, gint offset, e_guid_t *guid)
1538 ensure_contiguous(tvb, offset, sizeof(*guid));
1539 guid->data1 = tvb_get_letohl(tvb, offset);
1540 guid->data2 = tvb_get_letohs(tvb, offset + 4);
1541 guid->data3 = tvb_get_letohs(tvb, offset + 6);
1542 tvb_memcpy(tvb, guid->data4, offset + 8, sizeof guid->data4);
1546 tvb_get_guid(tvbuff_t *tvb, gint offset, e_guid_t *guid, gboolean little_endian)
1548 if (little_endian) {
1549 tvb_get_letohguid(tvb, offset, guid);
1551 tvb_get_ntohguid(tvb, offset, guid);
1555 static const guint8 bit_mask8[] = {
1566 /* Bit offset mask for number of bits = 8 - 16 */
1567 static const guint16 bit_mask16[] = {
1578 /* Get 1 - 8 bits */
1580 tvb_get_bits8(tvbuff_t *tvb, gint bit_offset, gint no_of_bits)
1587 DISSECTOR_ASSERT_NOT_REACHED();
1589 /* Byte align offset */
1590 offset = bit_offset>>3;
1592 /* Find out which mask to use for the most significant octet
1593 * by convering bit_offset into the offset into the first
1596 bit_offset = bit_offset & 0x7;
1597 tot_no_bits = bit_offset+no_of_bits;
1599 /* Read one octet, mask off bit_offset bits and left shift out the unused bits */
1600 value = tvb_get_guint8(tvb,offset) & bit_mask8[bit_offset];
1601 value = value >> (8-tot_no_bits);
1603 /* Read two octets, mask off bit_offset bits and left shift out the unused bits */
1604 value = tvb_get_ntohs(tvb,offset) & bit_mask16[bit_offset];
1605 value = value >> (16 - tot_no_bits);
1608 return (guint8)value;
1611 /* Get 9 - 16 bits */
1612 /* Bit offset mask for number of bits = 16 - 32 */
1613 static const guint32 bit_mask32[] = {
1625 tvb_get_bits16(tvbuff_t *tvb, gint bit_offset, gint no_of_bits,gboolean little_endian)
1629 guint16 tempval = 0;
1632 if ((no_of_bits<=8)||(no_of_bits>16)) {
1633 /* If bits <= 8 use tvb_get_bits8 */
1634 DISSECTOR_ASSERT_NOT_REACHED();
1637 DISSECTOR_ASSERT_NOT_REACHED();
1638 /* This part is not implemented yet */
1641 /* Byte align offset */
1642 offset = bit_offset>>3;
1644 /* Find out which mask to use for the most significant octet
1645 * by convering bit_offset into the offset into the first
1648 bit_offset = bit_offset & 0x7;
1649 tot_no_bits = bit_offset+no_of_bits;
1650 /* Read two octets and mask off bit_offset bits */
1651 value = tvb_get_ntohs(tvb,offset) & bit_mask16[bit_offset];
1652 if(tot_no_bits < 16){
1653 /* Left shift out the unused bits */
1654 value = value >> (16 - tot_no_bits);
1655 }else if(tot_no_bits > 16){
1656 /* Spans three octets, read next octet and shift as needed */
1657 value = value << (tot_no_bits - 16);
1658 tempval = tvb_get_guint8(tvb,offset+2);
1659 tempval = tempval >> (24-tot_no_bits);
1660 value = value | tempval;
1666 /* Bit offset mask for number of bits = 32 - 64 */
1667 static const guint64 bit_mask64[] = {
1668 G_GINT64_CONSTANT(0xffffffffffffffffU),
1669 G_GINT64_CONSTANT(0x7fffffffffffffffU),
1670 G_GINT64_CONSTANT(0x3fffffffffffffffU),
1671 G_GINT64_CONSTANT(0x1fffffffffffffffU),
1672 G_GINT64_CONSTANT(0x0fffffffffffffffU),
1673 G_GINT64_CONSTANT(0x07ffffffffffffffU),
1674 G_GINT64_CONSTANT(0x03ffffffffffffffU),
1675 G_GINT64_CONSTANT(0x01ffffffffffffffU)
1679 tvb_get_bits32(tvbuff_t *tvb, gint bit_offset, gint no_of_bits, gboolean little_endian)
1683 guint32 tempval = 0;
1686 if ((no_of_bits<=16)||(no_of_bits>32)) {
1687 /* If bits <= 16 use tvb_get_bits8 or tvb_get_bits16 */
1688 DISSECTOR_ASSERT_NOT_REACHED();
1691 DISSECTOR_ASSERT_NOT_REACHED();
1692 /* This part is not implemented yet */
1695 /* Byte align offset */
1696 offset = bit_offset>>3;
1698 /* Find out which mask to use for the most significant octet
1699 * by convering bit_offset into the offset into the first
1702 bit_offset = bit_offset & 0x7;
1703 tot_no_bits = bit_offset+no_of_bits;
1704 /* Read four octets and mask off bit_offset bits */
1705 value = tvb_get_ntohl(tvb,offset) & bit_mask32[bit_offset];
1706 if(tot_no_bits < 32){
1707 /* Left shift out the unused bits */
1708 value = value >> (32 - tot_no_bits);
1709 }else if(tot_no_bits > 32){
1710 /* Spans five octets, read next octet and shift as needed */
1711 value = value << (tot_no_bits - 32);
1712 tempval = tvb_get_guint8(tvb,offset+4);
1713 tempval = tempval >> (40-tot_no_bits);
1714 value = value | tempval;
1721 tvb_get_bits64(tvbuff_t *tvb, gint bit_offset, gint no_of_bits, gboolean little_endian)
1725 guint64 tempval = 0;
1728 if ((no_of_bits<=32)||(no_of_bits>64)) {
1729 /* If bits <= 32 use tvb_get_bits8, tvb_get_bits16 or tvb_get_bits32 */
1730 DISSECTOR_ASSERT_NOT_REACHED();
1733 DISSECTOR_ASSERT_NOT_REACHED();
1734 /* This part is not implemented yet */
1737 /* Byte align offset */
1738 offset = bit_offset>>3;
1740 /* Find out which mask to use for the most significant octet
1741 * by convering bit_offset into the offset into the first
1744 bit_offset = bit_offset & 0x7;
1745 tot_no_bits = bit_offset+no_of_bits;
1746 /* Read eight octets and mask off bit_offset bits */
1747 value = tvb_get_ntoh64(tvb,offset) & bit_mask64[bit_offset];
1748 if (tot_no_bits < 64){
1749 /* Left shift out the unused bits */
1750 value = value >> (64 - tot_no_bits);
1751 }else if (tot_no_bits > 64){
1752 /* Spans nine octets, read next octet and shift as needed */
1753 value = value << (tot_no_bits - 64);
1754 tempval = tvb_get_guint8(tvb,offset+8);
1755 tempval = tempval >> (72-tot_no_bits);
1756 value = value | tempval;
1762 /* Find first occurence of needle in tvbuff, starting at offset. Searches
1763 * at most maxlength number of bytes; if maxlength is -1, searches to
1765 * Returns the offset of the found needle, or -1 if not found.
1766 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1767 * in that case, -1 will be returned if the boundary is reached before
1768 * finding needle. */
1770 tvb_find_guint8(tvbuff_t *tvb, gint offset, gint maxlength, guint8 needle)
1772 const guint8 *result;
1773 guint abs_offset, junk_length;
1777 DISSECTOR_ASSERT(tvb && tvb->initialized);
1779 check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
1781 /* Only search to end of tvbuff, w/o throwing exception. */
1782 tvbufflen = tvb_length_remaining(tvb, abs_offset);
1783 if (maxlength == -1) {
1784 /* No maximum length specified; search to end of tvbuff. */
1787 else if (tvbufflen < (guint) maxlength) {
1788 /* Maximum length goes past end of tvbuff; search to end
1793 /* Maximum length doesn't go past end of tvbuff; search
1798 /* If we have real data, perform our search now. */
1799 if (tvb->real_data) {
1800 result = guint8_find(tvb->real_data + abs_offset, limit, needle);
1801 if (result == NULL) {
1805 return (gint) (result - tvb->real_data);
1810 case TVBUFF_REAL_DATA:
1811 DISSECTOR_ASSERT_NOT_REACHED();
1814 return tvb_find_guint8(tvb->tvbuffs.subset.tvb,
1815 abs_offset - tvb->tvbuffs.subset.offset,
1818 case TVBUFF_COMPOSITE:
1819 DISSECTOR_ASSERT_NOT_REACHED();
1820 /* XXX - return composite_find_guint8(tvb, offset, limit, needle); */
1823 DISSECTOR_ASSERT_NOT_REACHED();
1827 /* Find first occurence of any of the needles in tvbuff, starting at offset.
1828 * Searches at most maxlength number of bytes; if maxlength is -1, searches
1830 * Returns the offset of the found needle, or -1 if not found.
1831 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1832 * in that case, -1 will be returned if the boundary is reached before
1833 * finding needle. */
1835 tvb_pbrk_guint8(tvbuff_t *tvb, gint offset, gint maxlength, const guint8 *needles)
1837 const guint8 *result;
1838 guint abs_offset, junk_length;
1842 DISSECTOR_ASSERT(tvb && tvb->initialized);
1844 check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
1846 /* Only search to end of tvbuff, w/o throwing exception. */
1847 tvbufflen = tvb_length_remaining(tvb, abs_offset);
1848 if (maxlength == -1) {
1849 /* No maximum length specified; search to end of tvbuff. */
1852 else if (tvbufflen < (guint) maxlength) {
1853 /* Maximum length goes past end of tvbuff; search to end
1858 /* Maximum length doesn't go past end of tvbuff; search
1863 /* If we have real data, perform our search now. */
1864 if (tvb->real_data) {
1865 result = guint8_pbrk(tvb->real_data + abs_offset, limit, needles);
1866 if (result == NULL) {
1870 return (gint) (result - tvb->real_data);
1875 case TVBUFF_REAL_DATA:
1876 DISSECTOR_ASSERT_NOT_REACHED();
1879 return tvb_pbrk_guint8(tvb->tvbuffs.subset.tvb,
1880 abs_offset - tvb->tvbuffs.subset.offset,
1883 case TVBUFF_COMPOSITE:
1884 DISSECTOR_ASSERT_NOT_REACHED();
1885 /* XXX - return composite_pbrk_guint8(tvb, offset, limit, needle); */
1888 DISSECTOR_ASSERT_NOT_REACHED();
1892 /* Find size of stringz (NUL-terminated string) by looking for terminating
1893 * NUL. The size of the string includes the terminating NUL.
1895 * If the NUL isn't found, it throws the appropriate exception.
1898 tvb_strsize(tvbuff_t *tvb, gint offset)
1900 guint abs_offset, junk_length;
1903 DISSECTOR_ASSERT(tvb && tvb->initialized);
1905 check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
1906 nul_offset = tvb_find_guint8(tvb, abs_offset, -1, 0);
1907 if (nul_offset == -1) {
1909 * OK, we hit the end of the tvbuff, so we should throw
1912 * Did we hit the end of the captured data, or the end
1913 * of the actual data? If there's less captured data
1914 * than actual data, we presumably hit the end of the
1915 * captured data, otherwise we hit the end of the actual
1918 if (tvb_length(tvb) < tvb_reported_length(tvb)) {
1921 THROW(ReportedBoundsError);
1924 return (nul_offset - abs_offset) + 1;
1927 /* Find length of string by looking for end of string ('\0'), up to
1928 * 'maxlength' characters'; if 'maxlength' is -1, searches to end
1930 * Returns -1 if 'maxlength' reached before finding EOS. */
1932 tvb_strnlen(tvbuff_t *tvb, gint offset, guint maxlength)
1935 guint abs_offset, junk_length;
1937 DISSECTOR_ASSERT(tvb && tvb->initialized);
1939 check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
1941 result_offset = tvb_find_guint8(tvb, abs_offset, maxlength, 0);
1943 if (result_offset == -1) {
1947 return result_offset - abs_offset;
1952 * Implement strneql etc
1956 * Call strncmp after checking if enough chars left, returning 0 if
1957 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1960 tvb_strneql(tvbuff_t *tvb, gint offset, const gchar *str, gint size)
1964 ptr = ensure_contiguous_no_exception(tvb, offset, size, NULL);
1967 int cmp = strncmp((const char *)ptr, str, size);
1970 * Return 0 if equal, -1 otherwise.
1972 return (cmp == 0 ? 0 : -1);
1975 * Not enough characters in the tvbuff to match the
1983 * Call g_ascii_strncasecmp after checking if enough chars left, returning
1984 * 0 if it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1987 tvb_strncaseeql(tvbuff_t *tvb, gint offset, const gchar *str, gint size)
1991 ptr = ensure_contiguous_no_exception(tvb, offset, size, NULL);
1994 int cmp = g_ascii_strncasecmp((const char *)ptr, str, size);
1997 * Return 0 if equal, -1 otherwise.
1999 return (cmp == 0 ? 0 : -1);
2002 * Not enough characters in the tvbuff to match the
2010 * Call memcmp after checking if enough chars left, returning 0 if
2011 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
2014 tvb_memeql(tvbuff_t *tvb, gint offset, const guint8 *str, size_t size)
2018 ptr = ensure_contiguous_no_exception(tvb, offset, (gint) size, NULL);
2021 int cmp = memcmp(ptr, str, size);
2024 * Return 0 if equal, -1 otherwise.
2026 return (cmp == 0 ? 0 : -1);
2029 * Not enough characters in the tvbuff to match the
2036 /* Convert a string from Unicode to ASCII. At the moment we fake it by
2037 * replacing all non-ASCII characters with a '.' )-: The caller must
2038 * free the result returned. The len parameter is the number of guint16's
2039 * to convert from Unicode. */
2041 tvb_fake_unicode(tvbuff_t *tvb, int offset, int len, gboolean little_endian)
2047 /* Make sure we have enough data before allocating the buffer,
2048 so we don't blow up if the length is huge. */
2049 tvb_ensure_bytes_exist(tvb, offset, 2*len);
2051 /* We know we won't throw an exception, so we don't have to worry
2052 about leaking this buffer. */
2053 buffer = g_malloc(len + 1);
2055 for (i = 0; i < len; i++) {
2056 character = little_endian ? tvb_get_letohs(tvb, offset)
2057 : tvb_get_ntohs(tvb, offset);
2058 buffer[i] = character < 256 ? character : '.';
2067 /* Convert a string from Unicode to ASCII. At the moment we fake it by
2068 * replacing all non-ASCII characters with a '.' )-: The len parameter is
2069 * the number of guint16's to convert from Unicode.
2071 * This function allocates memory from a buffer with packet lifetime.
2072 * You do not have to free this buffer, it will be automatically freed
2073 * when wireshark starts decoding the next packet.
2076 tvb_get_ephemeral_faked_unicode(tvbuff_t *tvb, int offset, int len, gboolean little_endian)
2082 /* Make sure we have enough data before allocating the buffer,
2083 so we don't blow up if the length is huge. */
2084 tvb_ensure_bytes_exist(tvb, offset, 2*len);
2086 /* We know we won't throw an exception, so we don't have to worry
2087 about leaking this buffer. */
2088 buffer = ep_alloc(len + 1);
2090 for (i = 0; i < len; i++) {
2091 character = little_endian ? tvb_get_letohs(tvb, offset)
2092 : tvb_get_ntohs(tvb, offset);
2093 buffer[i] = character < 256 ? character : '.';
2103 * Format the data in the tvb from offset for length ...
2107 tvb_format_text(tvbuff_t *tvb, gint offset, gint size)
2112 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2114 len = tvb_length_remaining(tvb, offset);
2115 ptr = ensure_contiguous(tvb, offset, len);
2119 return format_text(ptr, len);
2124 * Format the data in the tvb from offset for length ...
2128 tvb_format_text_wsp(tvbuff_t *tvb, gint offset, gint size)
2133 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2135 len = tvb_length_remaining(tvb, offset);
2136 ptr = ensure_contiguous(tvb, offset, len);
2140 return format_text_wsp(ptr, len);
2145 * Like "tvb_format_text()", but for null-padded strings; don't show
2146 * the null padding characters as "\000".
2149 tvb_format_stringzpad(tvbuff_t *tvb, gint offset, gint size)
2151 const guint8 *ptr, *p;
2155 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2157 len = tvb_length_remaining(tvb, offset);
2158 ptr = ensure_contiguous(tvb, offset, len);
2162 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2164 return format_text(ptr, stringlen);
2169 * Like "tvb_format_text_wsp()", but for null-padded strings; don't show
2170 * the null padding characters as "\000".
2173 tvb_format_stringzpad_wsp(tvbuff_t *tvb, gint offset, gint size)
2175 const guint8 *ptr, *p;
2179 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2181 len = tvb_length_remaining(tvb, offset);
2182 ptr = ensure_contiguous(tvb, offset, len);
2186 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2188 return format_text_wsp(ptr, stringlen);
2193 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2194 * to hold a non-null-terminated string of that length at that offset,
2195 * plus a trailing '\0', copy the string into it, and return a pointer
2198 * Throws an exception if the tvbuff ends before the string does.
2201 tvb_get_string(tvbuff_t *tvb, gint offset, gint length)
2204 guint8 *strbuf = NULL;
2206 tvb_ensure_bytes_exist(tvb, offset, length);
2208 ptr = ensure_contiguous(tvb, offset, length);
2209 strbuf = g_malloc(length + 1);
2211 memcpy(strbuf, ptr, length);
2213 strbuf[length] = '\0';
2217 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2218 * to hold a non-null-terminated string of that length at that offset,
2219 * plus a trailing '\0', copy the string into it, and return a pointer
2222 * Throws an exception if the tvbuff ends before the string does.
2224 * This function allocates memory from a buffer with packet lifetime.
2225 * You do not have to free this buffer, it will be automatically freed
2226 * when wireshark starts decoding the next packet.
2227 * Do not use this function if you want the allocated memory to be persistent
2228 * after the current packet has been dissected.
2231 tvb_get_ephemeral_string(tvbuff_t *tvb, gint offset, gint length)
2234 guint8 *strbuf = NULL;
2236 tvb_ensure_bytes_exist(tvb, offset, length);
2238 ptr = ensure_contiguous(tvb, offset, length);
2239 strbuf = ep_alloc(length + 1);
2241 memcpy(strbuf, ptr, length);
2243 strbuf[length] = '\0';
2248 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2249 * to hold a non-null-terminated string of that length at that offset,
2250 * plus a trailing '\0', copy the string into it, and return a pointer
2253 * Throws an exception if the tvbuff ends before the string does.
2255 * This function allocates memory from a buffer with capture session lifetime.
2256 * You do not have to free this buffer, it will be automatically freed
2257 * when wireshark starts or opens a new capture.
2260 tvb_get_seasonal_string(tvbuff_t *tvb, gint offset, gint length)
2263 guint8 *strbuf = NULL;
2265 tvb_ensure_bytes_exist(tvb, offset, length);
2267 ptr = ensure_contiguous(tvb, offset, length);
2268 strbuf = se_alloc(length + 1);
2270 memcpy(strbuf, ptr, length);
2272 strbuf[length] = '\0';
2277 * Given a tvbuff and an offset, with the offset assumed to refer to
2278 * a null-terminated string, find the length of that string (and throw
2279 * an exception if the tvbuff ends before we find the null), allocate
2280 * a buffer big enough to hold the string, copy the string into it,
2281 * and return a pointer to the string. Also return the length of the
2282 * string (including the terminating null) through a pointer.
2285 tvb_get_stringz(tvbuff_t *tvb, gint offset, gint *lengthp)
2290 size = tvb_strsize(tvb, offset);
2291 strptr = g_malloc(size);
2292 tvb_memcpy(tvb, strptr, offset, size);
2297 * Given a tvbuff and an offset, with the offset assumed to refer to
2298 * a null-terminated string, find the length of that string (and throw
2299 * an exception if the tvbuff ends before we find the null), allocate
2300 * a buffer big enough to hold the string, copy the string into it,
2301 * and return a pointer to the string. Also return the length of the
2302 * string (including the terminating null) through a pointer.
2304 * This function allocates memory from a buffer with packet lifetime.
2305 * You do not have to free this buffer, it will be automatically freed
2306 * when wireshark starts decoding the next packet.
2307 * Do not use this function if you want the allocated memory to be persistent
2308 * after the current packet has been dissected.
2311 tvb_get_ephemeral_stringz(tvbuff_t *tvb, gint offset, gint *lengthp)
2316 size = tvb_strsize(tvb, offset);
2317 strptr = ep_alloc(size);
2318 tvb_memcpy(tvb, strptr, offset, size);
2324 * Given a tvbuff and an offset, with the offset assumed to refer to
2325 * a null-terminated string, find the length of that string (and throw
2326 * an exception if the tvbuff ends before we find the null), allocate
2327 * a buffer big enough to hold the string, copy the string into it,
2328 * and return a pointer to the string. Also return the length of the
2329 * string (including the terminating null) through a pointer.
2331 * This function allocates memory from a buffer with capture session lifetime.
2332 * You do not have to free this buffer, it will be automatically freed
2333 * when wireshark starts or opens a new capture.
2336 tvb_get_seasonal_stringz(tvbuff_t *tvb, gint offset, gint *lengthp)
2341 size = tvb_strsize(tvb, offset);
2342 strptr = se_alloc(size);
2343 tvb_memcpy(tvb, strptr, offset, size);
2348 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
2349 * no more than bufsize number of bytes, including terminating NUL, to buffer.
2350 * Returns length of string (not including terminating NUL), or -1 if the string was
2351 * truncated in the buffer due to not having reached the terminating NUL.
2352 * In this way, it acts like g_snprintf().
2354 * bufsize MUST be greater than 0.
2356 * When processing a packet where the remaining number of bytes is less
2357 * than bufsize, an exception is not thrown if the end of the packet
2358 * is reached before the NUL is found. If no NUL is found before reaching
2359 * the end of the short packet, -1 is still returned, and the string
2360 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
2361 * at the correct spot, terminating the string.
2363 * *bytes_copied will contain the number of bytes actually copied,
2364 * including the terminating-NUL.
2367 _tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer,
2371 guint abs_offset, junk_length;
2373 gboolean decreased_max = FALSE;
2375 check_offset_length(tvb->length, tvb->reported_length, offset, 0, &abs_offset, &junk_length);
2377 /* There must at least be room for the terminating NUL. */
2378 DISSECTOR_ASSERT(bufsize != 0);
2380 /* If there's no room for anything else, just return the NUL. */
2387 /* Only read to end of tvbuff, w/o throwing exception. */
2388 len = tvb_length_remaining(tvb, abs_offset);
2390 /* check_offset_length() won't throw an exception if we're
2391 * looking at the byte immediately after the end of the tvbuff. */
2393 THROW(ReportedBoundsError);
2396 /* This should not happen because check_offset_length() would
2397 * have already thrown an exception if 'offset' were out-of-bounds.
2399 DISSECTOR_ASSERT(len != -1);
2402 * If we've been passed a negative number, bufsize will
2405 DISSECTOR_ASSERT(bufsize <= G_MAXINT);
2407 if ((guint)len < bufsize) {
2409 decreased_max = TRUE;
2415 stringlen = tvb_strnlen(tvb, abs_offset, limit - 1);
2416 /* If NUL wasn't found, copy the data and return -1 */
2417 if (stringlen == -1) {
2418 tvb_memcpy(tvb, buffer, abs_offset, limit);
2419 if (decreased_max) {
2421 /* Add 1 for the extra NUL that we set at buffer[limit],
2422 * pretending that it was copied as part of the string. */
2423 *bytes_copied = limit + 1;
2426 *bytes_copied = limit;
2431 /* Copy the string to buffer */
2432 tvb_memcpy(tvb, buffer, abs_offset, stringlen + 1);
2433 *bytes_copied = stringlen + 1;
2437 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
2438 * no more than bufsize number of bytes, including terminating NUL, to buffer.
2439 * Returns length of string (not including terminating NUL), or -1 if the string was
2440 * truncated in the buffer due to not having reached the terminating NUL.
2441 * In this way, it acts like g_snprintf().
2443 * When processing a packet where the remaining number of bytes is less
2444 * than bufsize, an exception is not thrown if the end of the packet
2445 * is reached before the NUL is found. If no NUL is found before reaching
2446 * the end of the short packet, -1 is still returned, and the string
2447 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
2448 * at the correct spot, terminating the string.
2451 tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer)
2455 DISSECTOR_ASSERT(tvb && tvb->initialized);
2457 return _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
2460 /* Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
2461 * have a terminating NUL. If the string was truncated when copied into buffer,
2462 * a NUL is placed at the end of buffer to terminate it.
2465 tvb_get_nstringz0(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer)
2467 gint len, bytes_copied;
2469 DISSECTOR_ASSERT(tvb && tvb->initialized);
2471 len = _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
2474 buffer[bufsize - 1] = 0;
2475 return bytes_copied - 1;
2483 * Given a tvbuff, an offset into the tvbuff, and a length that starts
2484 * at that offset (which may be -1 for "all the way to the end of the
2485 * tvbuff"), find the end of the (putative) line that starts at the
2486 * specified offset in the tvbuff, going no further than the specified
2489 * Return the length of the line (not counting the line terminator at
2490 * the end), or, if we don't find a line terminator:
2492 * if "deseg" is true, return -1;
2494 * if "deseg" is false, return the amount of data remaining in
2497 * Set "*next_offset" to the offset of the character past the line
2498 * terminator, or past the end of the buffer if we don't find a line
2499 * terminator. (It's not set if we return -1.)
2502 tvb_find_line_end(tvbuff_t *tvb, gint offset, int len, gint *next_offset,
2510 len = tvb_length_remaining(tvb, offset);
2512 * XXX - what if "len" is still -1, meaning "offset is past the
2513 * end of the tvbuff"?
2515 eob_offset = offset + len;
2518 * Look either for a CR or an LF.
2520 eol_offset = tvb_pbrk_guint8(tvb, offset, len, (const guint8 *)"\r\n");
2521 if (eol_offset == -1) {
2523 * No CR or LF - line is presumably continued in next packet.
2527 * Tell our caller we saw no EOL, so they can
2528 * try to desegment and get the entire line
2534 * Pretend the line runs to the end of the tvbuff.
2536 linelen = eob_offset - offset;
2537 *next_offset = eob_offset;
2541 * Find the number of bytes between the starting offset
2544 linelen = eol_offset - offset;
2549 if (tvb_get_guint8(tvb, eol_offset) == '\r') {
2551 * Yes - is it followed by an LF?
2553 if (eol_offset + 1 >= eob_offset) {
2555 * Dunno - the next byte isn't in this
2560 * We'll return -1, although that
2561 * runs the risk that if the line
2562 * really *is* terminated with a CR,
2563 * we won't properly dissect this
2566 * It's probably more likely that
2567 * the line ends with CR-LF than
2568 * that it ends with CR by itself.
2574 * Well, we can at least look at the next
2577 if (tvb_get_guint8(tvb, eol_offset + 1) == '\n') {
2579 * It's an LF; skip over the CR.
2587 * Return the offset of the character after the last
2588 * character in the line, skipping over the last character
2589 * in the line terminator.
2591 *next_offset = eol_offset + 1;
2597 * Given a tvbuff, an offset into the tvbuff, and a length that starts
2598 * at that offset (which may be -1 for "all the way to the end of the
2599 * tvbuff"), find the end of the (putative) line that starts at the
2600 * specified offset in the tvbuff, going no further than the specified
2603 * However, treat quoted strings inside the buffer specially - don't
2604 * treat newlines in quoted strings as line terminators.
2606 * Return the length of the line (not counting the line terminator at
2607 * the end), or the amount of data remaining in the buffer if we don't
2608 * find a line terminator.
2610 * Set "*next_offset" to the offset of the character past the line
2611 * terminator, or past the end of the buffer if we don't find a line
2615 tvb_find_line_end_unquoted(tvbuff_t *tvb, gint offset, int len,
2618 gint cur_offset, char_offset;
2625 len = tvb_length_remaining(tvb, offset);
2627 * XXX - what if "len" is still -1, meaning "offset is past the
2628 * end of the tvbuff"?
2630 eob_offset = offset + len;
2632 cur_offset = offset;
2636 * Is this part of the string quoted?
2640 * Yes - look only for the terminating quote.
2642 char_offset = tvb_find_guint8(tvb, cur_offset, len,
2646 * Look either for a CR, an LF, or a '"'.
2648 char_offset = tvb_pbrk_guint8(tvb, cur_offset, len,
2649 (const guint8 *)"\r\n\"");
2651 if (char_offset == -1) {
2653 * Not found - line is presumably continued in
2655 * We pretend the line runs to the end of the tvbuff.
2657 linelen = eob_offset - offset;
2658 *next_offset = eob_offset;
2664 * We're processing a quoted string.
2665 * We only looked for ", so we know it's a ";
2666 * as we're processing a quoted string, it's a
2674 c = tvb_get_guint8(tvb, char_offset);
2677 * Un-quoted "; it begins a quoted
2683 * It's a CR or LF; we've found a line
2686 * Find the number of bytes between the
2687 * starting offset and the CR or LF.
2689 linelen = char_offset - offset;
2696 * Yes; is it followed by an LF?
2698 if (char_offset + 1 < eob_offset &&
2699 tvb_get_guint8(tvb, char_offset + 1)
2702 * Yes; skip over the CR.
2709 * Return the offset of the character after
2710 * the last character in the line, skipping
2711 * over the last character in the line
2712 * terminator, and quit.
2714 *next_offset = char_offset + 1;
2720 * Step past the character we found.
2722 cur_offset = char_offset + 1;
2723 if (cur_offset >= eob_offset) {
2725 * The character we found was the last character
2726 * in the tvbuff - line is presumably continued in
2728 * We pretend the line runs to the end of the tvbuff.
2730 linelen = eob_offset - offset;
2731 *next_offset = eob_offset;
2739 * Copied from the mgcp dissector. (This function should be moved to /epan )
2740 * tvb_skip_wsp - Returns the position in tvb of the first non-whitespace
2741 * character following offset or offset + maxlength -1 whichever
2745 * tvb - The tvbuff in which we are skipping whitespace.
2746 * offset - The offset in tvb from which we begin trying to skip whitespace.
2747 * maxlength - The maximum distance from offset that we may try to skip
2750 * Returns: The position in tvb of the first non-whitespace
2751 * character following offset or offset + maxlength -1 whichever
2754 gint tvb_skip_wsp(tvbuff_t* tvb, gint offset, gint maxlength)
2756 gint counter = offset;
2757 gint end = offset + maxlength,tvb_len;
2760 /* Get the length remaining */
2761 tvb_len = tvb_length(tvb);
2762 end = offset + maxlength;
2768 /* Skip past spaces, tabs, CRs and LFs until run out or meet something else */
2769 for (counter = offset;
2771 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
2772 tempchar == '\t' || tempchar == '\r' || tempchar == '\n');
2778 gint tvb_skip_wsp_return(tvbuff_t* tvb, gint offset){
2779 gint counter = offset;
2784 for(counter = offset; counter > end &&
2785 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
2786 tempchar == '\t' || tempchar == '\n' || tempchar == '\r'); counter--);
2793 * Format a bunch of data from a tvbuff as bytes, returning a pointer
2794 * to the string with the formatted data, with "punct" as a byte
2798 tvb_bytes_to_str_punct(tvbuff_t *tvb, gint offset, gint len, gchar punct)
2800 return bytes_to_str_punct(tvb_get_ptr(tvb, offset, len), len, punct);
2804 * Format a bunch of data from a tvbuff as bytes, returning a pointer
2805 * to the string with the formatted data.
2808 tvb_bytes_to_str(tvbuff_t *tvb, gint offset, gint len)
2810 return bytes_to_str(tvb_get_ptr(tvb, offset, len), len);
2813 /* Find a needle tvbuff within a haystack tvbuff. */
2815 tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb, gint haystack_offset)
2817 guint haystack_abs_offset, haystack_abs_length;
2818 const guint8 *haystack_data;
2819 const guint8 *needle_data;
2820 const guint needle_len = needle_tvb->length;
2821 const guint8 *location;
2823 DISSECTOR_ASSERT(haystack_tvb && haystack_tvb->initialized);
2825 if (haystack_tvb->length < 1 || needle_tvb->length < 1) {
2829 /* Get pointers to the tvbuffs' data. */
2830 haystack_data = tvb_get_ptr(haystack_tvb, 0, -1);
2831 needle_data = tvb_get_ptr(needle_tvb, 0, -1);
2833 check_offset_length(haystack_tvb->length, haystack_tvb->reported_length, haystack_offset, -1,
2834 &haystack_abs_offset, &haystack_abs_length);
2836 location = epan_memmem(haystack_data + haystack_abs_offset, haystack_abs_length,
2837 needle_data, needle_len);
2840 return (gint) (location - haystack_data);
2848 * Uncompresses a zlib compressed packet inside a message of tvb at offset with
2849 * length comprlen. Returns an uncompressed tvbuffer if uncompression
2850 * succeeded or NULL if uncompression failed.
2852 #define TVB_Z_MIN_BUFSIZ 32768
2853 #define TVB_Z_MAX_BUFSIZ 1048576 * 10
2854 /* #define TVB_Z_DEBUG 1 */
2858 tvb_uncompress(tvbuff_t *tvb, int offset, int comprlen)
2861 guint bytes_out = 0;
2862 guint8 *compr = NULL;
2863 guint8 *uncompr = NULL;
2864 tvbuff_t *uncompr_tvb = NULL;
2865 z_streamp strm = NULL;
2866 Bytef *strmbuf = NULL;
2867 guint inits_done = 0;
2868 gint wbits = MAX_WBITS;
2869 guint8 *next = NULL;
2870 guint bufsiz = TVB_Z_MIN_BUFSIZ;
2872 guint inflate_passes = 0;
2873 guint bytes_in = tvb_length_remaining(tvb, offset);
2880 compr = tvb_memdup(tvb, offset, comprlen);
2886 * Assume that the uncompressed data is at least twice as big as
2887 * the compressed size.
2889 bufsiz = tvb_length_remaining(tvb, offset) * 2;
2890 bufsiz = CLAMP(bufsiz, TVB_Z_MIN_BUFSIZ, TVB_Z_MAX_BUFSIZ);
2893 printf("bufsiz: %u bytes\n", bufsiz);
2898 strm = g_malloc0(sizeof(z_stream));
2899 strm->next_in = next;
2900 strm->avail_in = comprlen;
2902 strmbuf = g_malloc0(bufsiz);
2903 strm->next_out = strmbuf;
2904 strm->avail_out = bufsiz;
2906 err = inflateInit2(strm, wbits);
2917 memset(strmbuf, '\0', bufsiz);
2918 strm->next_out = strmbuf;
2919 strm->avail_out = bufsiz;
2921 err = inflate(strm, Z_SYNC_FLUSH);
2923 if (err == Z_OK || err == Z_STREAM_END) {
2924 guint bytes_pass = bufsiz - strm->avail_out;
2930 if (uncompr == NULL) {
2931 uncompr = g_memdup(strmbuf, bytes_pass);
2933 guint8 *new_data = g_malloc0(bytes_out + bytes_pass);
2935 g_memmove(new_data, uncompr, bytes_out);
2936 g_memmove((new_data + bytes_out), strmbuf,
2943 bytes_out += bytes_pass;
2945 if ( err == Z_STREAM_END) {
2951 } else if (err == Z_BUF_ERROR) {
2953 * It's possible that not enough frames were captured
2954 * to decompress this fully, so return what we've done
2961 if (uncompr != NULL) {
2968 } else if (err == Z_DATA_ERROR && inits_done == 1
2969 && uncompr == NULL && (*compr == 0x1f) &&
2970 (*(compr + 1) == 0x8b)) {
2972 * inflate() is supposed to handle both gzip and deflate
2973 * streams automatically, but in reality it doesn't
2974 * seem to handle either (at least not within the
2975 * context of an HTTP response.) We have to try
2976 * several tweaks, depending on the type of data and
2977 * version of the library installed.
2981 * Gzip file format. Skip past the header, since the
2982 * fix to make it work (setting windowBits to 31)
2983 * doesn't work with all versions of the library.
2985 Bytef *c = compr + 2;
2988 if (*c == Z_DEFLATED) {
3000 /* Skip past the MTIME, XFL, and OS fields. */
3003 if (flags & (1 << 2)) {
3004 /* An Extra field is present. */
3005 gint xsize = (gint)(*c |
3011 if (flags & (1 << 3)) {
3012 /* A null terminated filename */
3014 while ((c - compr) < comprlen && *c != '\0') {
3021 if (flags & (1 << 4)) {
3022 /* A null terminated comment */
3024 while ((c - compr) < comprlen && *c != '\0') {
3034 strm->next_in = next;
3035 if (c - compr > comprlen) {
3042 comprlen -= (int) (c - compr);
3045 err = inflateInit2(strm, wbits);
3047 } else if (err == Z_DATA_ERROR && uncompr == NULL &&
3051 * Re-init the stream with a negative
3052 * MAX_WBITS. This is necessary due to
3053 * some servers (Apache) not sending
3054 * the deflate header with the
3055 * content-encoded response.
3061 strm->next_in = next;
3062 strm->avail_in = comprlen;
3065 memset(strmbuf, '\0', bufsiz);
3066 strm->next_out = strmbuf;
3067 strm->avail_out = bufsiz;
3069 err = inflateInit2(strm, wbits);
3087 if (uncompr == NULL) {
3096 printf("inflate() total passes: %u\n", inflate_passes);
3097 printf("bytes in: %u\nbytes out: %u\n\n", bytes_in, bytes_out);
3100 if (uncompr != NULL) {
3101 uncompr_tvb = tvb_new_real_data((guint8*) uncompr, bytes_out,
3103 tvb_set_free_cb(uncompr_tvb, g_free);
3110 tvb_uncompress(tvbuff_t *tvb _U_, int offset _U_, int comprlen _U_)
3116 tvbuff_t* tvb_child_uncompress(tvbuff_t *parent _U_, tvbuff_t *tvb, int offset, int comprlen)
3118 tvbuff_t *new_tvb = tvb_uncompress(tvb, offset, comprlen);
3120 tvb_set_child_real_data_tvbuff (parent, new_tvb);