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 /* We dole out tvbuff's from this memchunk. */
62 GMemChunk *tvbuff_mem_chunk = NULL;
67 if (!tvbuff_mem_chunk)
68 tvbuff_mem_chunk = g_mem_chunk_create(tvbuff_t, 20, G_ALLOC_AND_FREE);
75 g_mem_chunk_destroy(tvbuff_mem_chunk);
77 tvbuff_mem_chunk = NULL;
84 tvb_init(tvbuff_t *tvb, tvbuff_type type)
86 tvb_backing_t *backing;
87 tvb_comp_t *composite;
90 tvb->initialized = FALSE;
93 tvb->reported_length = 0;
95 tvb->real_data = NULL;
101 case TVBUFF_REAL_DATA:
106 backing = &tvb->tvbuffs.subset;
112 case TVBUFF_COMPOSITE:
113 composite = &tvb->tvbuffs.composite;
114 composite->tvbs = NULL;
115 composite->start_offsets = NULL;
116 composite->end_offsets = NULL;
123 tvb_new(tvbuff_type type)
127 tvb = g_chunk_new(tvbuff_t, tvbuff_mem_chunk);
135 tvb_free(tvbuff_t* tvb)
137 tvbuff_t *member_tvb;
138 tvb_comp_t *composite;
143 if (tvb->usage_count == 0) {
145 case TVBUFF_REAL_DATA:
148 * XXX - do this with a union?
150 tvb->free_cb((gpointer)tvb->real_data);
155 /* This will be NULL if tvb_new_subset() fails because
156 * reported_length < -1 */
157 if (tvb->tvbuffs.subset.tvb) {
158 tvb_decrement_usage_count(tvb->tvbuffs.subset.tvb, 1);
162 case TVBUFF_COMPOSITE:
163 composite = &tvb->tvbuffs.composite;
164 for (slist = composite->tvbs; slist != NULL ; slist = slist->next) {
165 member_tvb = slist->data;
166 tvb_decrement_usage_count(member_tvb, 1);
169 g_slist_free(composite->tvbs);
171 g_free(composite->start_offsets);
172 g_free(composite->end_offsets);
173 if (tvb->real_data) {
175 * XXX - do this with a union?
177 g_free((gpointer)tvb->real_data);
184 g_slist_free(tvb->used_in);
187 g_chunk_free(tvb, tvbuff_mem_chunk);
192 tvb_increment_usage_count(tvbuff_t* tvb, guint count)
194 tvb->usage_count += count;
196 return tvb->usage_count;
200 tvb_decrement_usage_count(tvbuff_t* tvb, guint count)
202 if (tvb->usage_count <= count) {
203 tvb->usage_count = 1;
208 tvb->usage_count -= count;
209 return tvb->usage_count;
215 tvb_free_chain(tvbuff_t* tvb)
219 /* Recursively call tvb_free_chain() */
220 for (slist = tvb->used_in; slist != NULL ; slist = slist->next) {
221 tvb_free_chain( (tvbuff_t*)slist->data );
224 /* Stop the recursion */
231 tvb_set_free_cb(tvbuff_t* tvb, tvbuff_free_cb_t func)
233 DISSECTOR_ASSERT(tvb);
234 DISSECTOR_ASSERT(tvb->type == TVBUFF_REAL_DATA);
239 add_to_used_in_list(tvbuff_t *tvb, tvbuff_t *used_in)
241 tvb->used_in = g_slist_prepend(tvb->used_in, used_in);
242 tvb_increment_usage_count(tvb, 1);
246 tvb_set_child_real_data_tvbuff(tvbuff_t* parent, tvbuff_t* child)
248 DISSECTOR_ASSERT(parent && child);
249 DISSECTOR_ASSERT(parent->initialized);
250 DISSECTOR_ASSERT(child->initialized);
251 DISSECTOR_ASSERT(child->type == TVBUFF_REAL_DATA);
252 add_to_used_in_list(parent, child);
256 tvb_set_real_data(tvbuff_t* tvb, const guint8* data, guint length, gint reported_length)
258 DISSECTOR_ASSERT(tvb);
259 DISSECTOR_ASSERT(tvb->type == TVBUFF_REAL_DATA);
260 DISSECTOR_ASSERT(!tvb->initialized);
262 if (reported_length < -1) {
263 THROW(ReportedBoundsError);
266 tvb->real_data = data;
267 tvb->length = length;
268 tvb->reported_length = reported_length;
269 tvb->initialized = TRUE;
273 tvb_new_real_data(const guint8* data, guint length, gint reported_length)
275 static tvbuff_t *last_tvb=NULL;
278 tvb = tvb_new(TVBUFF_REAL_DATA);
283 /* remember this tvb in case we throw an exception and
284 * lose the pointer to it.
288 tvb_set_real_data(tvb, data, length, reported_length);
291 * This is the top-level real tvbuff for this data source,
292 * so its data source tvbuff is itself.
296 /* ok no exception so we dont need to remember it any longer */
303 tvb_new_child_real_data(tvbuff_t *parent, const guint8* data, guint length, gint reported_length)
305 tvbuff_t *tvb = tvb_new_real_data(data, length, reported_length);
307 tvb_set_child_real_data_tvbuff (parent, tvb);
313 /* Computes the absolute offset and length based on a possibly-negative offset
314 * and a length that is possible -1 (which means "to the end of the data").
315 * Returns TRUE/FALSE indicating whether the offset is in bounds or
316 * not. The integer ptrs are modified with the new offset and length.
317 * No exception is thrown.
319 * XXX - we return TRUE, not FALSE, if the offset is positive and right
320 * after the end of the tvbuff (i.e., equal to the length). We do this
321 * so that a dissector constructing a subset tvbuff for the next protocol
322 * will get a zero-length tvbuff, not an exception, if there's no data
323 * left for the next protocol - we want the next protocol to be the one
324 * that gets an exception, so the error is reported as an error in that
325 * protocol rather than the containing protocol. */
327 compute_offset_length(tvbuff_t *tvb, gint offset, gint length,
328 guint *offset_ptr, guint *length_ptr, int *exception)
330 DISSECTOR_ASSERT(offset_ptr);
331 DISSECTOR_ASSERT(length_ptr);
333 /* Compute the offset */
335 /* Positive offset - relative to the beginning of the packet. */
336 if ((guint) offset > tvb->reported_length) {
338 *exception = ReportedBoundsError;
342 else if ((guint) offset > tvb->length) {
344 *exception = BoundsError;
349 *offset_ptr = offset;
353 /* Negative offset - relative to the end of the packet. */
354 if ((guint) -offset > tvb->reported_length) {
356 *exception = ReportedBoundsError;
360 else if ((guint) -offset > tvb->length) {
362 *exception = BoundsError;
367 *offset_ptr = tvb->length + offset;
371 /* Compute the length */
374 /* XXX - ReportedBoundsError? */
375 *exception = BoundsError;
379 else if (length == -1) {
380 *length_ptr = tvb->length - *offset_ptr;
383 *length_ptr = length;
391 check_offset_length_no_exception(tvbuff_t *tvb, gint offset, gint length,
392 guint *offset_ptr, guint *length_ptr, int *exception)
396 DISSECTOR_ASSERT(tvb && tvb->initialized);
398 if (!compute_offset_length(tvb, offset, length, offset_ptr, length_ptr, exception)) {
403 * Compute the offset of the first byte past the length.
405 end_offset = *offset_ptr + *length_ptr;
408 * Check for an overflow, and clamp "end_offset" at the maximum
409 * if we got an overflow - that should force us to indicate that
410 * we're past the end of the tvbuff.
412 if (end_offset < *offset_ptr)
413 end_offset = UINT_MAX;
416 * Check whether that offset goes more than one byte past the
419 * If not, return TRUE; otherwise, return FALSE and, if "exception"
420 * is non-null, return the appropriate exception through it.
422 if (end_offset <= tvb->length) {
425 else if (end_offset <= tvb->reported_length) {
427 *exception = BoundsError;
432 *exception = ReportedBoundsError;
439 /* Checks (+/-) offset and length and throws an exception if
440 * either is out of bounds. Sets integer ptrs to the new offset
443 check_offset_length(tvbuff_t *tvb, gint offset, gint length,
444 guint *offset_ptr, guint *length_ptr)
448 if (!check_offset_length_no_exception(tvb, offset, length, offset_ptr, length_ptr, &exception)) {
449 DISSECTOR_ASSERT(exception > 0);
457 tvb_set_subset(tvbuff_t *tvb, tvbuff_t *backing,
458 gint backing_offset, gint backing_length, gint reported_length)
460 DISSECTOR_ASSERT(tvb);
461 DISSECTOR_ASSERT(tvb->type == TVBUFF_SUBSET);
462 DISSECTOR_ASSERT(!tvb->initialized);
464 if (reported_length < -1) {
465 THROW(ReportedBoundsError);
468 check_offset_length(backing, backing_offset, backing_length,
469 &tvb->tvbuffs.subset.offset,
470 &tvb->tvbuffs.subset.length);
472 tvb->tvbuffs.subset.tvb = backing;
473 tvb->length = tvb->tvbuffs.subset.length;
475 if (reported_length == -1) {
476 tvb->reported_length = backing->reported_length - tvb->tvbuffs.subset.offset;
479 tvb->reported_length = reported_length;
481 tvb->initialized = TRUE;
482 add_to_used_in_list(backing, tvb);
484 /* Optimization. If the backing buffer has a pointer to contiguous, real data,
485 * then we can point directly to our starting offset in that buffer */
486 if (backing->real_data != NULL) {
487 tvb->real_data = backing->real_data + tvb->tvbuffs.subset.offset;
493 tvb_new_subset(tvbuff_t *backing, gint backing_offset, gint backing_length, gint reported_length)
495 static tvbuff_t *last_tvb=NULL;
498 tvb = tvb_new(TVBUFF_SUBSET);
503 /* remember this tvb in case we throw an exception and
504 * lose the pointer to it.
508 tvb_set_subset(tvb, backing, backing_offset, backing_length, reported_length);
511 * The top-level data source of this tvbuff is the top-level
512 * data source of its parent.
514 tvb->ds_tvb = backing->ds_tvb;
516 /* ok no exception so we dont need to remember it any longer */
523 tvb_composite_append(tvbuff_t* tvb, tvbuff_t* member)
525 tvb_comp_t *composite;
527 DISSECTOR_ASSERT(tvb && !tvb->initialized);
528 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
529 composite = &tvb->tvbuffs.composite;
530 composite->tvbs = g_slist_append( composite->tvbs, member );
531 add_to_used_in_list(tvb, member);
535 tvb_composite_prepend(tvbuff_t* tvb, tvbuff_t* member)
537 tvb_comp_t *composite;
539 DISSECTOR_ASSERT(tvb && !tvb->initialized);
540 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
541 composite = &tvb->tvbuffs.composite;
542 composite->tvbs = g_slist_prepend( composite->tvbs, member );
543 add_to_used_in_list(tvb, member);
547 tvb_new_composite(void)
549 return tvb_new(TVBUFF_COMPOSITE);
553 tvb_composite_finalize(tvbuff_t* tvb)
557 tvbuff_t *member_tvb;
558 tvb_comp_t *composite;
561 DISSECTOR_ASSERT(tvb && !tvb->initialized);
562 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
563 DISSECTOR_ASSERT(tvb->length == 0);
565 composite = &tvb->tvbuffs.composite;
566 num_members = g_slist_length(composite->tvbs);
568 composite->start_offsets = g_new(guint, num_members);
569 composite->end_offsets = g_new(guint, num_members);
571 for (slist = composite->tvbs; slist != NULL; slist = slist->next) {
572 DISSECTOR_ASSERT((guint) i < num_members);
573 member_tvb = slist->data;
574 composite->start_offsets[i] = tvb->length;
575 tvb->length += member_tvb->length;
576 composite->end_offsets[i] = tvb->length - 1;
580 tvb->initialized = TRUE;
586 tvb_length(tvbuff_t* tvb)
588 DISSECTOR_ASSERT(tvb && tvb->initialized);
594 tvb_length_remaining(tvbuff_t *tvb, gint offset)
596 guint abs_offset, abs_length;
598 DISSECTOR_ASSERT(tvb && tvb->initialized);
600 if (compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL)) {
609 tvb_ensure_length_remaining(tvbuff_t *tvb, gint offset)
611 guint abs_offset, abs_length;
614 DISSECTOR_ASSERT(tvb && tvb->initialized);
616 if (!compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, &exception)) {
619 if (abs_length == 0) {
621 * This routine ensures there's at least one byte available.
622 * There aren't any bytes available, so throw the appropriate
625 if (abs_offset >= tvb->reported_length)
626 THROW(ReportedBoundsError);
636 /* Validates that 'length' bytes are available starting from
637 * offset (pos/neg). Does not throw an exception. */
639 tvb_bytes_exist(tvbuff_t *tvb, gint offset, gint length)
641 guint abs_offset, abs_length;
643 DISSECTOR_ASSERT(tvb && tvb->initialized);
645 if (!compute_offset_length(tvb, offset, length, &abs_offset, &abs_length, NULL))
648 if (abs_offset + abs_length <= tvb->length) {
656 /* Validates that 'length' bytes are available starting from
657 * offset (pos/neg). Throws an exception if they aren't. */
659 tvb_ensure_bytes_exist(tvbuff_t *tvb, gint offset, gint length)
661 guint abs_offset, abs_length;
663 DISSECTOR_ASSERT(tvb && tvb->initialized);
666 * -1 doesn't mean "until end of buffer", as that's pointless
667 * for this routine. We must treat it as a Really Large Positive
668 * Number, so that we throw an exception; we throw
669 * ReportedBoundsError, as if it were past even the end of a
670 * reassembled packet, and past the end of even the data we
673 * We do the same with other negative lengths.
676 THROW(ReportedBoundsError);
678 check_offset_length(tvb, offset, length, &abs_offset, &abs_length);
682 tvb_offset_exists(tvbuff_t *tvb, gint offset)
684 guint abs_offset, abs_length;
686 DISSECTOR_ASSERT(tvb && tvb->initialized);
687 if (!compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL))
690 if (abs_offset < tvb->length) {
699 tvb_reported_length(tvbuff_t* tvb)
701 DISSECTOR_ASSERT(tvb && tvb->initialized);
703 return tvb->reported_length;
707 tvb_reported_length_remaining(tvbuff_t *tvb, gint offset)
709 guint abs_offset, abs_length;
711 DISSECTOR_ASSERT(tvb && tvb->initialized);
713 if (compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL)) {
714 if (tvb->reported_length >= abs_offset)
715 return tvb->reported_length - abs_offset;
724 /* Set the reported length of a tvbuff to a given value; used for protocols
725 whose headers contain an explicit length and where the calling
726 dissector's payload may include padding as well as the packet for
729 Also adjusts the data length. */
731 tvb_set_reported_length(tvbuff_t* tvb, guint reported_length)
733 DISSECTOR_ASSERT(tvb && tvb->initialized);
735 if (reported_length > tvb->reported_length)
736 THROW(ReportedBoundsError);
738 tvb->reported_length = reported_length;
739 if (reported_length < tvb->length)
740 tvb->length = reported_length;
746 first_real_data_ptr(tvbuff_t *tvb)
751 case TVBUFF_REAL_DATA:
752 return tvb->real_data;
754 member = tvb->tvbuffs.subset.tvb;
755 return first_real_data_ptr(member);
756 case TVBUFF_COMPOSITE:
757 member = tvb->tvbuffs.composite.tvbs->data;
758 return first_real_data_ptr(member);
761 DISSECTOR_ASSERT_NOT_REACHED();
767 offset_from_real_beginning(tvbuff_t *tvb, int counter)
772 case TVBUFF_REAL_DATA:
775 member = tvb->tvbuffs.subset.tvb;
776 return offset_from_real_beginning(member, counter + tvb->tvbuffs.subset.offset);
777 case TVBUFF_COMPOSITE:
778 member = tvb->tvbuffs.composite.tvbs->data;
779 return offset_from_real_beginning(member, counter);
782 DISSECTOR_ASSERT_NOT_REACHED();
787 composite_ensure_contiguous_no_exception(tvbuff_t *tvb, guint abs_offset,
790 guint i, num_members;
791 tvb_comp_t *composite;
792 tvbuff_t *member_tvb = NULL;
793 guint member_offset, member_length;
796 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
798 /* Maybe the range specified by offset/length
799 * is contiguous inside one of the member tvbuffs */
800 composite = &tvb->tvbuffs.composite;
801 num_members = g_slist_length(composite->tvbs);
803 for (i = 0; i < num_members; i++) {
804 if (abs_offset <= composite->end_offsets[i]) {
805 slist = g_slist_nth(composite->tvbs, i);
806 member_tvb = slist->data;
810 DISSECTOR_ASSERT(member_tvb);
812 if (check_offset_length_no_exception(member_tvb, abs_offset - composite->start_offsets[i],
813 abs_length, &member_offset, &member_length, NULL)) {
816 * The range is, in fact, contiguous within member_tvb.
818 DISSECTOR_ASSERT(!tvb->real_data);
819 return ensure_contiguous_no_exception(member_tvb, member_offset, member_length, NULL);
822 tvb->real_data = tvb_memdup(tvb, 0, -1);
823 return tvb->real_data + abs_offset;
826 DISSECTOR_ASSERT_NOT_REACHED();
831 ensure_contiguous_no_exception(tvbuff_t *tvb, gint offset, gint length,
834 guint abs_offset, abs_length;
836 if (!check_offset_length_no_exception(tvb, offset, length,
837 &abs_offset, &abs_length, exception)) {
842 * We know that all the data is present in the tvbuff, so
843 * no exceptions should be thrown.
845 if (tvb->real_data) {
846 return tvb->real_data + abs_offset;
850 case TVBUFF_REAL_DATA:
851 DISSECTOR_ASSERT_NOT_REACHED();
853 return ensure_contiguous_no_exception(tvb->tvbuffs.subset.tvb,
854 abs_offset - tvb->tvbuffs.subset.offset,
856 case TVBUFF_COMPOSITE:
857 return composite_ensure_contiguous_no_exception(tvb, abs_offset, abs_length);
861 DISSECTOR_ASSERT_NOT_REACHED();
865 /* ----------------------------- */
867 fast_ensure_contiguous(tvbuff_t *tvb, gint offset, guint length)
872 DISSECTOR_ASSERT(tvb && tvb->initialized);
873 if (offset < 0 || !tvb->real_data) {
874 return ensure_contiguous(tvb, offset, length);
878 end_offset = u_offset + length;
880 /* don't need to check for overflow because length <= 8 */
882 if (end_offset <= tvb->length) {
883 return tvb->real_data + u_offset;
886 if (end_offset > tvb->reported_length) {
887 THROW(ReportedBoundsError);
896 ensure_contiguous(tvbuff_t *tvb, gint offset, gint length)
901 p = ensure_contiguous_no_exception(tvb, offset, length, &exception);
903 DISSECTOR_ASSERT(exception > 0);
910 guint8_find(const guint8* haystack, size_t haystacklen, guint8 needle)
915 for (b = haystack, i = 0; (guint) i < haystacklen; i++, b++) {
925 guint8_pbrk(const guint8* haystack, size_t haystacklen, const guint8 *needles)
930 const guint8 *needlep;
932 for (b = haystack, i = 0; (guint) i < haystacklen; i++, b++) {
935 while ((needle = *needlep) != '\0') {
947 /************** ACCESSORS **************/
950 composite_memcpy(tvbuff_t *tvb, guint8* target, guint abs_offset, size_t abs_length)
952 guint i, num_members;
953 tvb_comp_t *composite;
954 tvbuff_t *member_tvb = NULL;
955 guint member_offset, member_length;
959 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
961 /* Maybe the range specified by offset/length
962 * is contiguous inside one of the member tvbuffs */
963 composite = &tvb->tvbuffs.composite;
964 num_members = g_slist_length(composite->tvbs);
966 for (i = 0; i < num_members; i++) {
967 if (abs_offset <= composite->end_offsets[i]) {
968 slist = g_slist_nth(composite->tvbs, i);
969 member_tvb = slist->data;
973 DISSECTOR_ASSERT(member_tvb);
975 if (check_offset_length_no_exception(member_tvb, abs_offset - composite->start_offsets[i],
976 (gint) abs_length, &member_offset, &member_length, NULL)) {
978 DISSECTOR_ASSERT(!tvb->real_data);
979 return tvb_memcpy(member_tvb, target, member_offset, member_length);
982 /* The requested data is non-contiguous inside
983 * the member tvb. We have to memcpy() the part that's in the member tvb,
984 * then iterate across the other member tvb's, copying their portions
985 * until we have copied all data.
987 retval = compute_offset_length(member_tvb, abs_offset - composite->start_offsets[i], -1,
988 &member_offset, &member_length, NULL);
989 DISSECTOR_ASSERT(retval);
991 tvb_memcpy(member_tvb, target, member_offset, member_length);
992 abs_offset += member_length;
993 abs_length -= member_length;
996 if (abs_length > 0) {
997 composite_memcpy(tvb, target + member_length, abs_offset, abs_length);
1003 DISSECTOR_ASSERT_NOT_REACHED();
1008 tvb_memcpy(tvbuff_t *tvb, void* target, gint offset, size_t length)
1010 guint abs_offset, abs_length;
1013 * XXX - we should eliminate the "length = -1 means 'to the end
1014 * of the tvbuff'" convention, and use other means to achieve
1015 * that; this would let us eliminate a bunch of checks for
1016 * negative lengths in cases where the protocol has a 32-bit
1019 * Allowing -1 but throwing an assertion on other negative
1020 * lengths is a bit more work with the length being a size_t;
1021 * instead, we check for a length <= 2^31-1.
1023 DISSECTOR_ASSERT(length <= 0x7FFFFFFF);
1024 check_offset_length(tvb, offset, (gint) length, &abs_offset, &abs_length);
1026 if (tvb->real_data) {
1027 return memcpy(target, tvb->real_data + abs_offset, abs_length);
1031 case TVBUFF_REAL_DATA:
1032 DISSECTOR_ASSERT_NOT_REACHED();
1035 return tvb_memcpy(tvb->tvbuffs.subset.tvb, target,
1036 abs_offset - tvb->tvbuffs.subset.offset,
1039 case TVBUFF_COMPOSITE:
1040 return composite_memcpy(tvb, target, offset, length);
1043 DISSECTOR_ASSERT_NOT_REACHED();
1049 * XXX - this doesn't treat a length of -1 as an error.
1050 * If it did, this could replace some code that calls
1051 * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies
1054 * "composite_ensure_contiguous_no_exception()" depends on -1 not being
1055 * an error; does anything else depend on this routine treating -1 as
1056 * meaning "to the end of the buffer"?
1059 tvb_memdup(tvbuff_t *tvb, gint offset, size_t length)
1061 guint abs_offset, abs_length;
1064 check_offset_length(tvb, offset, (gint) length, &abs_offset, &abs_length);
1066 duped = g_malloc(abs_length);
1067 return tvb_memcpy(tvb, duped, abs_offset, abs_length);
1071 * XXX - this doesn't treat a length of -1 as an error.
1072 * If it did, this could replace some code that calls
1073 * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies
1076 * "composite_ensure_contiguous_no_exception()" depends on -1 not being
1077 * an error; does anything else depend on this routine treating -1 as
1078 * meaning "to the end of the buffer"?
1080 * This function allocates memory from a buffer with packet lifetime.
1081 * You do not have to free this buffer, it will be automatically freed
1082 * when wireshark starts decoding the next packet.
1083 * Do not use this function if you want the allocated memory to be persistent
1084 * after the current packet has been dissected.
1087 ep_tvb_memdup(tvbuff_t *tvb, gint offset, size_t length)
1089 guint abs_offset, abs_length;
1092 check_offset_length(tvb, offset, (gint) length, &abs_offset, &abs_length);
1094 duped = ep_alloc(abs_length);
1095 return tvb_memcpy(tvb, duped, abs_offset, abs_length);
1101 tvb_get_ptr(tvbuff_t *tvb, gint offset, gint length)
1103 return ensure_contiguous(tvb, offset, length);
1106 /* ---------------- */
1108 tvb_get_guint8(tvbuff_t *tvb, gint offset)
1112 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint8));
1117 tvb_get_ntohs(tvbuff_t *tvb, gint offset)
1121 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint16));
1126 tvb_get_ntoh24(tvbuff_t *tvb, gint offset)
1130 ptr = fast_ensure_contiguous(tvb, offset, 3);
1131 return pntoh24(ptr);
1135 tvb_get_ntohl(tvbuff_t *tvb, gint offset)
1139 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1144 tvb_get_ntoh64(tvbuff_t *tvb, gint offset)
1148 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint64));
1149 return pntoh64(ptr);
1153 * Stuff for IEEE float handling on platforms that don't have IEEE
1154 * format as the native floating-point format.
1156 * For now, we treat only the VAX as such a platform.
1158 * XXX - other non-IEEE boxes that can run UNIX include some Crays,
1159 * and possibly other machines.
1161 * It appears that the official Linux port to System/390 and
1162 * zArchitecture uses IEEE format floating point (not a
1165 * I don't know whether there are any other machines that
1166 * could run Wireshark and that don't use IEEE format.
1167 * As far as I know, all of the main commercial microprocessor
1168 * families on which OSes that support Wireshark can run
1169 * use IEEE format (x86, 68k, SPARC, MIPS, PA-RISC, Alpha,
1170 * IA-64, and so on).
1180 #define IEEE_SP_NUMBER_WIDTH 32 /* bits in number */
1181 #define IEEE_SP_EXP_WIDTH 8 /* bits in exponent */
1182 #define IEEE_SP_MANTISSA_WIDTH 23 /* IEEE_SP_NUMBER_WIDTH - 1 - IEEE_SP_EXP_WIDTH */
1184 #define IEEE_SP_SIGN_MASK 0x80000000
1185 #define IEEE_SP_EXPONENT_MASK 0x7F800000
1186 #define IEEE_SP_MANTISSA_MASK 0x007FFFFF
1187 #define IEEE_SP_INFINITY IEEE_SP_EXPONENT_MASK
1189 #define IEEE_SP_IMPLIED_BIT (1 << IEEE_SP_MANTISSA_WIDTH)
1190 #define IEEE_SP_INFINITE ((1 << IEEE_SP_EXP_WIDTH) - 1)
1191 #define IEEE_SP_BIAS ((1 << (IEEE_SP_EXP_WIDTH - 1)) - 1)
1194 ieee_float_is_zero(guint32 w)
1196 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1200 get_ieee_float(guint32 w)
1206 sign = w & IEEE_SP_SIGN_MASK;
1207 exponent = w & IEEE_SP_EXPONENT_MASK;
1208 mantissa = w & IEEE_SP_MANTISSA_MASK;
1210 if (ieee_float_is_zero(w)) {
1211 /* number is zero, unnormalized, or not-a-number */
1216 * XXX - how to handle this?
1218 if (IEEE_SP_INFINITY == exponent) {
1220 * number is positive or negative infinity, or a special value
1222 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1226 exponent = ((exponent >> IEEE_SP_MANTISSA_WIDTH) - IEEE_SP_BIAS) -
1227 IEEE_SP_MANTISSA_WIDTH;
1228 mantissa |= IEEE_SP_IMPLIED_BIT;
1231 return -mantissa * pow(2, exponent);
1233 return mantissa * pow(2, exponent);
1238 * We assume that if you don't have IEEE floating-point, you have a
1239 * compiler that understands 64-bit integral quantities.
1241 #define IEEE_DP_NUMBER_WIDTH 64 /* bits in number */
1242 #define IEEE_DP_EXP_WIDTH 11 /* bits in exponent */
1243 #define IEEE_DP_MANTISSA_WIDTH 52 /* IEEE_DP_NUMBER_WIDTH - 1 - IEEE_DP_EXP_WIDTH */
1245 #define IEEE_DP_SIGN_MASK 0x8000000000000000LL
1246 #define IEEE_DP_EXPONENT_MASK 0x7FF0000000000000LL
1247 #define IEEE_DP_MANTISSA_MASK 0x000FFFFFFFFFFFFFLL
1248 #define IEEE_DP_INFINITY IEEE_DP_EXPONENT_MASK
1250 #define IEEE_DP_IMPLIED_BIT (1LL << IEEE_DP_MANTISSA_WIDTH)
1251 #define IEEE_DP_INFINITE ((1 << IEEE_DP_EXP_WIDTH) - 1)
1252 #define IEEE_DP_BIAS ((1 << (IEEE_DP_EXP_WIDTH - 1)) - 1)
1255 ieee_double_is_zero(guint64 w)
1257 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1261 get_ieee_double(guint64 w)
1267 sign = w & IEEE_DP_SIGN_MASK;
1268 exponent = w & IEEE_DP_EXPONENT_MASK;
1269 mantissa = w & IEEE_DP_MANTISSA_MASK;
1271 if (ieee_double_is_zero(w)) {
1272 /* number is zero, unnormalized, or not-a-number */
1277 * XXX - how to handle this?
1279 if (IEEE_DP_INFINITY == exponent) {
1281 * number is positive or negative infinity, or a special value
1283 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1287 exponent = ((exponent >> IEEE_DP_MANTISSA_WIDTH) - IEEE_DP_BIAS) -
1288 IEEE_DP_MANTISSA_WIDTH;
1289 mantissa |= IEEE_DP_IMPLIED_BIT;
1292 return -mantissa * pow(2, exponent);
1294 return mantissa * pow(2, exponent);
1299 * Fetches an IEEE single-precision floating-point number, in
1300 * big-endian form, and returns a "float".
1302 * XXX - should this be "double", in case there are IEEE single-
1303 * precision numbers that won't fit in some platform's native
1307 tvb_get_ntohieee_float(tvbuff_t *tvb, int offset)
1310 return get_ieee_float(tvb_get_ntohl(tvb, offset));
1317 ieee_fp_union.w = tvb_get_ntohl(tvb, offset);
1318 return ieee_fp_union.f;
1323 * Fetches an IEEE double-precision floating-point number, in
1324 * big-endian form, and returns a "double".
1327 tvb_get_ntohieee_double(tvbuff_t *tvb, int offset)
1341 #ifdef WORDS_BIGENDIAN
1342 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset);
1343 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset+4);
1345 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset+4);
1346 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset);
1349 return get_ieee_double(ieee_fp_union.dw);
1351 return ieee_fp_union.d;
1356 tvb_get_letohs(tvbuff_t *tvb, gint offset)
1360 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint16));
1361 return pletohs(ptr);
1365 tvb_get_letoh24(tvbuff_t *tvb, gint offset)
1369 ptr = fast_ensure_contiguous(tvb, offset, 3);
1370 return pletoh24(ptr);
1374 tvb_get_letohl(tvbuff_t *tvb, gint offset)
1378 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1379 return pletohl(ptr);
1383 tvb_get_letoh64(tvbuff_t *tvb, gint offset)
1387 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint64));
1388 return pletoh64(ptr);
1392 * Fetches an IEEE single-precision floating-point number, in
1393 * little-endian form, and returns a "float".
1395 * XXX - should this be "double", in case there are IEEE single-
1396 * precision numbers that won't fit in some platform's native
1400 tvb_get_letohieee_float(tvbuff_t *tvb, int offset)
1403 return get_ieee_float(tvb_get_letohl(tvb, offset));
1410 ieee_fp_union.w = tvb_get_letohl(tvb, offset);
1411 return ieee_fp_union.f;
1416 * Fetches an IEEE double-precision floating-point number, in
1417 * little-endian form, and returns a "double".
1420 tvb_get_letohieee_double(tvbuff_t *tvb, int offset)
1434 #ifdef WORDS_BIGENDIAN
1435 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset+4);
1436 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset);
1438 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset);
1439 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset+4);
1442 return get_ieee_double(ieee_fp_union.dw);
1444 return ieee_fp_union.d;
1448 /* Fetch an IPv4 address, in network byte order.
1449 * We do *not* convert them to host byte order; we leave them in
1450 * network byte order. */
1452 tvb_get_ipv4(tvbuff_t *tvb, gint offset)
1457 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1458 memcpy(&addr, ptr, sizeof addr);
1462 /* Fetch an IPv6 address. */
1464 tvb_get_ipv6(tvbuff_t *tvb, gint offset, struct e_in6_addr *addr)
1468 ptr = ensure_contiguous(tvb, offset, sizeof(*addr));
1469 memcpy(addr, ptr, sizeof *addr);
1474 tvb_get_ntohguid(tvbuff_t *tvb, gint offset, e_guid_t *guid)
1476 ensure_contiguous(tvb, offset, sizeof(*guid));
1477 guid->data1 = tvb_get_ntohl(tvb, offset);
1478 guid->data2 = tvb_get_ntohs(tvb, offset + 4);
1479 guid->data3 = tvb_get_ntohs(tvb, offset + 6);
1480 tvb_memcpy(tvb, guid->data4, offset + 8, sizeof guid->data4);
1484 tvb_get_letohguid(tvbuff_t *tvb, gint offset, e_guid_t *guid)
1486 ensure_contiguous(tvb, offset, sizeof(*guid));
1487 guid->data1 = tvb_get_letohl(tvb, offset);
1488 guid->data2 = tvb_get_letohs(tvb, offset + 4);
1489 guid->data3 = tvb_get_letohs(tvb, offset + 6);
1490 tvb_memcpy(tvb, guid->data4, offset + 8, sizeof guid->data4);
1494 tvb_get_guid(tvbuff_t *tvb, gint offset, e_guid_t *guid, gboolean little_endian)
1496 if (little_endian) {
1497 tvb_get_letohguid(tvb, offset, guid);
1499 tvb_get_ntohguid(tvb, offset, guid);
1503 static const guint8 bit_mask8[] = {
1514 /* Bit offset mask for number of bits = 8 - 16 */
1515 static const guint16 bit_mask16[] = {
1526 /* Get 1 - 8 bits */
1528 tvb_get_bits8(tvbuff_t *tvb, gint bit_offset, gint no_of_bits)
1535 DISSECTOR_ASSERT_NOT_REACHED();
1537 /* Byte align offset */
1538 offset = bit_offset>>3;
1540 /* Find out which mask to use for the most significant octet
1541 * by convering bit_offset into the offset into the first
1544 bit_offset = bit_offset & 0x7;
1545 tot_no_bits = bit_offset+no_of_bits;
1547 /* Read one octet, mask off bit_offset bits and left shift out the unused bits */
1548 value = tvb_get_guint8(tvb,offset) & bit_mask8[bit_offset];
1549 value = value >> (8-tot_no_bits);
1551 /* Read two octets, mask off bit_offset bits and left shift out the unused bits */
1552 value = tvb_get_ntohs(tvb,offset) & bit_mask16[bit_offset];
1553 value = value >> (16 - tot_no_bits);
1556 return (guint8)value;
1559 /* Get 9 - 16 bits */
1560 /* Bit offset mask for number of bits = 16 - 32 */
1561 static const guint32 bit_mask32[] = {
1573 tvb_get_bits16(tvbuff_t *tvb, gint bit_offset, gint no_of_bits,gboolean little_endian)
1577 guint16 tempval = 0;
1580 if ((no_of_bits<=8)||(no_of_bits>16)) {
1581 /* If bits <= 8 use tvb_get_bits8 */
1582 DISSECTOR_ASSERT_NOT_REACHED();
1585 DISSECTOR_ASSERT_NOT_REACHED();
1586 /* This part is not implemented yet */
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;
1598 /* Read two octets and mask off bit_offset bits */
1599 value = tvb_get_ntohs(tvb,offset) & bit_mask16[bit_offset];
1600 if(tot_no_bits < 16){
1601 /* Left shift out the unused bits */
1602 value = value >> (16 - tot_no_bits);
1603 }else if(tot_no_bits > 16){
1604 /* Spans three octets, read next octet and shift as needed */
1605 value = value << (tot_no_bits - 16);
1606 tempval = tvb_get_guint8(tvb,offset+2);
1607 tempval = tempval >> (24-tot_no_bits);
1608 value = value | tempval;
1614 /* Bit offset mask for number of bits = 32 - 64 */
1615 static const guint64 bit_mask64[] = {
1616 G_GINT64_CONSTANT(0xffffffffffffffffU),
1617 G_GINT64_CONSTANT(0x7fffffffffffffffU),
1618 G_GINT64_CONSTANT(0x3fffffffffffffffU),
1619 G_GINT64_CONSTANT(0x1fffffffffffffffU),
1620 G_GINT64_CONSTANT(0x0fffffffffffffffU),
1621 G_GINT64_CONSTANT(0x07ffffffffffffffU),
1622 G_GINT64_CONSTANT(0x03ffffffffffffffU),
1623 G_GINT64_CONSTANT(0x01ffffffffffffffU)
1627 tvb_get_bits32(tvbuff_t *tvb, gint bit_offset, gint no_of_bits, gboolean little_endian)
1631 guint32 tempval = 0;
1634 if ((no_of_bits<=16)||(no_of_bits>32)) {
1635 /* If bits <= 16 use tvb_get_bits8 or tvb_get_bits16 */
1636 DISSECTOR_ASSERT_NOT_REACHED();
1639 DISSECTOR_ASSERT_NOT_REACHED();
1640 /* This part is not implemented yet */
1643 /* Byte align offset */
1644 offset = bit_offset>>3;
1646 /* Find out which mask to use for the most significant octet
1647 * by convering bit_offset into the offset into the first
1650 bit_offset = bit_offset & 0x7;
1651 tot_no_bits = bit_offset+no_of_bits;
1652 /* Read four octets and mask off bit_offset bits */
1653 value = tvb_get_ntohl(tvb,offset) & bit_mask32[bit_offset];
1654 if(tot_no_bits < 32){
1655 /* Left shift out the unused bits */
1656 value = value >> (32 - tot_no_bits);
1657 }else if(tot_no_bits > 32){
1658 /* Spans five octets, read next octet and shift as needed */
1659 value = value << (tot_no_bits - 32);
1660 tempval = tvb_get_guint8(tvb,offset+4);
1661 tempval = tempval >> (40-tot_no_bits);
1662 value = value | tempval;
1669 tvb_get_bits64(tvbuff_t *tvb, gint bit_offset, gint no_of_bits, gboolean little_endian)
1673 guint64 tempval = 0;
1676 if ((no_of_bits<=32)||(no_of_bits>64)) {
1677 /* If bits <= 32 use tvb_get_bits8, tvb_get_bits16 or tvb_get_bits32 */
1678 DISSECTOR_ASSERT_NOT_REACHED();
1681 DISSECTOR_ASSERT_NOT_REACHED();
1682 /* This part is not implemented yet */
1685 /* Byte align offset */
1686 offset = bit_offset>>3;
1688 /* Find out which mask to use for the most significant octet
1689 * by convering bit_offset into the offset into the first
1692 bit_offset = bit_offset & 0x7;
1693 tot_no_bits = bit_offset+no_of_bits;
1694 /* Read eight octets and mask off bit_offset bits */
1695 value = tvb_get_ntoh64(tvb,offset) & bit_mask64[bit_offset];
1696 if (tot_no_bits < 64){
1697 /* Left shift out the unused bits */
1698 value = value >> (64 - tot_no_bits);
1699 }else if (tot_no_bits > 64){
1700 /* Spans nine octets, read next octet and shift as needed */
1701 value = value << (tot_no_bits - 64);
1702 tempval = tvb_get_guint8(tvb,offset+8);
1703 tempval = tempval >> (72-tot_no_bits);
1704 value = value | tempval;
1710 /* Find first occurence of needle in tvbuff, starting at offset. Searches
1711 * at most maxlength number of bytes; if maxlength is -1, searches to
1713 * Returns the offset of the found needle, or -1 if not found.
1714 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1715 * in that case, -1 will be returned if the boundary is reached before
1716 * finding needle. */
1718 tvb_find_guint8(tvbuff_t *tvb, gint offset, gint maxlength, guint8 needle)
1720 const guint8 *result;
1721 guint abs_offset, junk_length;
1725 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1727 /* Only search to end of tvbuff, w/o throwing exception. */
1728 tvbufflen = tvb_length_remaining(tvb, abs_offset);
1729 if (maxlength == -1) {
1730 /* No maximum length specified; search to end of tvbuff. */
1733 else if (tvbufflen < (guint) maxlength) {
1734 /* Maximum length goes past end of tvbuff; search to end
1739 /* Maximum length doesn't go past end of tvbuff; search
1744 /* If we have real data, perform our search now. */
1745 if (tvb->real_data) {
1746 result = guint8_find(tvb->real_data + abs_offset, limit, needle);
1747 if (result == NULL) {
1751 return (gint) (result - tvb->real_data);
1756 case TVBUFF_REAL_DATA:
1757 DISSECTOR_ASSERT_NOT_REACHED();
1760 return tvb_find_guint8(tvb->tvbuffs.subset.tvb,
1761 abs_offset - tvb->tvbuffs.subset.offset,
1764 case TVBUFF_COMPOSITE:
1765 DISSECTOR_ASSERT_NOT_REACHED();
1766 /* XXX - return composite_find_guint8(tvb, offset, limit, needle); */
1769 DISSECTOR_ASSERT_NOT_REACHED();
1773 /* Find first occurence of any of the needles in tvbuff, starting at offset.
1774 * Searches at most maxlength number of bytes; if maxlength is -1, searches
1776 * Returns the offset of the found needle, or -1 if not found.
1777 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1778 * in that case, -1 will be returned if the boundary is reached before
1779 * finding needle. */
1781 tvb_pbrk_guint8(tvbuff_t *tvb, gint offset, gint maxlength, const guint8 *needles)
1783 const guint8 *result;
1784 guint abs_offset, junk_length;
1788 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1790 /* Only search to end of tvbuff, w/o throwing exception. */
1791 tvbufflen = tvb_length_remaining(tvb, abs_offset);
1792 if (maxlength == -1) {
1793 /* No maximum length specified; search to end of tvbuff. */
1796 else if (tvbufflen < (guint) maxlength) {
1797 /* Maximum length goes past end of tvbuff; search to end
1802 /* Maximum length doesn't go past end of tvbuff; search
1807 /* If we have real data, perform our search now. */
1808 if (tvb->real_data) {
1809 result = guint8_pbrk(tvb->real_data + abs_offset, limit, needles);
1810 if (result == NULL) {
1814 return (gint) (result - tvb->real_data);
1819 case TVBUFF_REAL_DATA:
1820 DISSECTOR_ASSERT_NOT_REACHED();
1823 return tvb_pbrk_guint8(tvb->tvbuffs.subset.tvb,
1824 abs_offset - tvb->tvbuffs.subset.offset,
1827 case TVBUFF_COMPOSITE:
1828 DISSECTOR_ASSERT_NOT_REACHED();
1829 /* XXX - return composite_pbrk_guint8(tvb, offset, limit, needle); */
1832 DISSECTOR_ASSERT_NOT_REACHED();
1836 /* Find size of stringz (NUL-terminated string) by looking for terminating
1837 * NUL. The size of the string includes the terminating NUL.
1839 * If the NUL isn't found, it throws the appropriate exception.
1842 tvb_strsize(tvbuff_t *tvb, gint offset)
1844 guint abs_offset, junk_length;
1847 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1848 nul_offset = tvb_find_guint8(tvb, abs_offset, -1, 0);
1849 if (nul_offset == -1) {
1851 * OK, we hit the end of the tvbuff, so we should throw
1854 * Did we hit the end of the captured data, or the end
1855 * of the actual data? If there's less captured data
1856 * than actual data, we presumably hit the end of the
1857 * captured data, otherwise we hit the end of the actual
1860 if (tvb_length(tvb) < tvb_reported_length(tvb)) {
1863 THROW(ReportedBoundsError);
1866 return (nul_offset - abs_offset) + 1;
1869 /* Find length of string by looking for end of string ('\0'), up to
1870 * 'maxlength' characters'; if 'maxlength' is -1, searches to end
1872 * Returns -1 if 'maxlength' reached before finding EOS. */
1874 tvb_strnlen(tvbuff_t *tvb, gint offset, guint maxlength)
1877 guint abs_offset, junk_length;
1879 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1881 result_offset = tvb_find_guint8(tvb, abs_offset, maxlength, 0);
1883 if (result_offset == -1) {
1887 return result_offset - abs_offset;
1892 * Implement strneql etc
1896 * Call strncmp after checking if enough chars left, returning 0 if
1897 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1900 tvb_strneql(tvbuff_t *tvb, gint offset, const gchar *str, gint size)
1904 ptr = ensure_contiguous_no_exception(tvb, offset, size, NULL);
1907 int cmp = strncmp((const char *)ptr, str, size);
1910 * Return 0 if equal, -1 otherwise.
1912 return (cmp == 0 ? 0 : -1);
1915 * Not enough characters in the tvbuff to match the
1923 * Call g_ascii_strncasecmp after checking if enough chars left, returning
1924 * 0 if it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1927 tvb_strncaseeql(tvbuff_t *tvb, gint offset, const gchar *str, gint size)
1931 ptr = ensure_contiguous_no_exception(tvb, offset, size, NULL);
1934 int cmp = g_ascii_strncasecmp((const char *)ptr, str, size);
1937 * Return 0 if equal, -1 otherwise.
1939 return (cmp == 0 ? 0 : -1);
1942 * Not enough characters in the tvbuff to match the
1950 * Call memcmp after checking if enough chars left, returning 0 if
1951 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1954 tvb_memeql(tvbuff_t *tvb, gint offset, const guint8 *str, size_t size)
1958 ptr = ensure_contiguous_no_exception(tvb, offset, (gint) size, NULL);
1961 int cmp = memcmp(ptr, str, size);
1964 * Return 0 if equal, -1 otherwise.
1966 return (cmp == 0 ? 0 : -1);
1969 * Not enough characters in the tvbuff to match the
1976 /* Convert a string from Unicode to ASCII. At the moment we fake it by
1977 * replacing all non-ASCII characters with a '.' )-: The caller must
1978 * free the result returned. The len parameter is the number of guint16's
1979 * to convert from Unicode. */
1981 tvb_fake_unicode(tvbuff_t *tvb, int offset, int len, gboolean little_endian)
1987 /* Make sure we have enough data before allocating the buffer,
1988 so we don't blow up if the length is huge. */
1989 tvb_ensure_bytes_exist(tvb, offset, 2*len);
1991 /* We know we won't throw an exception, so we don't have to worry
1992 about leaking this buffer. */
1993 buffer = g_malloc(len + 1);
1995 for (i = 0; i < len; i++) {
1996 character = little_endian ? tvb_get_letohs(tvb, offset)
1997 : tvb_get_ntohs(tvb, offset);
1998 buffer[i] = character < 256 ? character : '.';
2007 /* Convert a string from Unicode to ASCII. At the moment we fake it by
2008 * replacing all non-ASCII characters with a '.' )-: The len parameter is
2009 * the number of guint16's to convert from Unicode.
2011 * This function allocates memory from a buffer with packet lifetime.
2012 * You do not have to free this buffer, it will be automatically freed
2013 * when wireshark starts decoding the next packet.
2016 tvb_get_ephemeral_faked_unicode(tvbuff_t *tvb, int offset, int len, gboolean little_endian)
2022 /* Make sure we have enough data before allocating the buffer,
2023 so we don't blow up if the length is huge. */
2024 tvb_ensure_bytes_exist(tvb, offset, 2*len);
2026 /* We know we won't throw an exception, so we don't have to worry
2027 about leaking this buffer. */
2028 buffer = ep_alloc(len + 1);
2030 for (i = 0; i < len; i++) {
2031 character = little_endian ? tvb_get_letohs(tvb, offset)
2032 : tvb_get_ntohs(tvb, offset);
2033 buffer[i] = character < 256 ? character : '.';
2043 * Format the data in the tvb from offset for length ...
2047 tvb_format_text(tvbuff_t *tvb, gint offset, gint size)
2052 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2054 len = tvb_length_remaining(tvb, offset);
2055 ptr = ensure_contiguous(tvb, offset, len);
2059 return format_text(ptr, len);
2064 * Format the data in the tvb from offset for length ...
2068 tvb_format_text_wsp(tvbuff_t *tvb, gint offset, gint size)
2073 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2075 len = tvb_length_remaining(tvb, offset);
2076 ptr = ensure_contiguous(tvb, offset, len);
2080 return format_text_wsp(ptr, len);
2085 * Like "tvb_format_text()", but for null-padded strings; don't show
2086 * the null padding characters as "\000".
2089 tvb_format_stringzpad(tvbuff_t *tvb, gint offset, gint size)
2091 const guint8 *ptr, *p;
2095 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2097 len = tvb_length_remaining(tvb, offset);
2098 ptr = ensure_contiguous(tvb, offset, len);
2102 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2104 return format_text(ptr, stringlen);
2109 * Like "tvb_format_text_wsp()", but for null-padded strings; don't show
2110 * the null padding characters as "\000".
2113 tvb_format_stringzpad_wsp(tvbuff_t *tvb, gint offset, gint size)
2115 const guint8 *ptr, *p;
2119 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2121 len = tvb_length_remaining(tvb, offset);
2122 ptr = ensure_contiguous(tvb, offset, len);
2126 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2128 return format_text_wsp(ptr, stringlen);
2133 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2134 * to hold a non-null-terminated string of that length at that offset,
2135 * plus a trailing '\0', copy the string into it, and return a pointer
2138 * Throws an exception if the tvbuff ends before the string does.
2141 tvb_get_string(tvbuff_t *tvb, gint offset, gint length)
2144 guint8 *strbuf = NULL;
2146 tvb_ensure_bytes_exist(tvb, offset, length);
2148 ptr = ensure_contiguous(tvb, offset, length);
2149 strbuf = g_malloc(length + 1);
2151 memcpy(strbuf, ptr, length);
2153 strbuf[length] = '\0';
2157 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2158 * to hold a non-null-terminated string of that length at that offset,
2159 * plus a trailing '\0', copy the string into it, and return a pointer
2162 * Throws an exception if the tvbuff ends before the string does.
2164 * This function allocates memory from a buffer with packet lifetime.
2165 * You do not have to free this buffer, it will be automatically freed
2166 * when wireshark starts decoding the next packet.
2167 * Do not use this function if you want the allocated memory to be persistent
2168 * after the current packet has been dissected.
2171 tvb_get_ephemeral_string(tvbuff_t *tvb, gint offset, gint length)
2174 guint8 *strbuf = NULL;
2176 tvb_ensure_bytes_exist(tvb, offset, length);
2178 ptr = ensure_contiguous(tvb, offset, length);
2179 strbuf = ep_alloc(length + 1);
2181 memcpy(strbuf, ptr, length);
2183 strbuf[length] = '\0';
2188 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2189 * to hold a non-null-terminated string of that length at that offset,
2190 * plus a trailing '\0', copy the string into it, and return a pointer
2193 * Throws an exception if the tvbuff ends before the string does.
2195 * This function allocates memory from a buffer with capture session lifetime.
2196 * You do not have to free this buffer, it will be automatically freed
2197 * when wireshark starts or opens a new capture.
2200 tvb_get_seasonal_string(tvbuff_t *tvb, gint offset, gint length)
2203 guint8 *strbuf = NULL;
2205 tvb_ensure_bytes_exist(tvb, offset, length);
2207 ptr = ensure_contiguous(tvb, offset, length);
2208 strbuf = se_alloc(length + 1);
2210 memcpy(strbuf, ptr, length);
2212 strbuf[length] = '\0';
2217 * Given a tvbuff and an offset, with the offset assumed to refer to
2218 * a null-terminated string, find the length of that string (and throw
2219 * an exception if the tvbuff ends before we find the null), allocate
2220 * a buffer big enough to hold the string, copy the string into it,
2221 * and return a pointer to the string. Also return the length of the
2222 * string (including the terminating null) through a pointer.
2225 tvb_get_stringz(tvbuff_t *tvb, gint offset, gint *lengthp)
2230 size = tvb_strsize(tvb, offset);
2231 strptr = g_malloc(size);
2232 tvb_memcpy(tvb, strptr, offset, size);
2237 * Given a tvbuff and an offset, with the offset assumed to refer to
2238 * a null-terminated string, find the length of that string (and throw
2239 * an exception if the tvbuff ends before we find the null), allocate
2240 * a buffer big enough to hold the string, copy the string into it,
2241 * and return a pointer to the string. Also return the length of the
2242 * string (including the terminating null) through a pointer.
2244 * This function allocates memory from a buffer with packet lifetime.
2245 * You do not have to free this buffer, it will be automatically freed
2246 * when wireshark starts decoding the next packet.
2247 * Do not use this function if you want the allocated memory to be persistent
2248 * after the current packet has been dissected.
2251 tvb_get_ephemeral_stringz(tvbuff_t *tvb, gint offset, gint *lengthp)
2256 size = tvb_strsize(tvb, offset);
2257 strptr = ep_alloc(size);
2258 tvb_memcpy(tvb, strptr, offset, size);
2264 * Given a tvbuff and an offset, with the offset assumed to refer to
2265 * a null-terminated string, find the length of that string (and throw
2266 * an exception if the tvbuff ends before we find the null), allocate
2267 * a buffer big enough to hold the string, copy the string into it,
2268 * and return a pointer to the string. Also return the length of the
2269 * string (including the terminating null) through a pointer.
2271 * This function allocates memory from a buffer with capture session lifetime.
2272 * You do not have to free this buffer, it will be automatically freed
2273 * when wireshark starts or opens a new capture.
2276 tvb_get_seasonal_stringz(tvbuff_t *tvb, gint offset, gint *lengthp)
2281 size = tvb_strsize(tvb, offset);
2282 strptr = se_alloc(size);
2283 tvb_memcpy(tvb, strptr, offset, size);
2288 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
2289 * no more than bufsize number of bytes, including terminating NUL, to buffer.
2290 * Returns length of string (not including terminating NUL), or -1 if the string was
2291 * truncated in the buffer due to not having reached the terminating NUL.
2292 * In this way, it acts like g_snprintf().
2294 * bufsize MUST be greater than 0.
2296 * When processing a packet where the remaining number of bytes is less
2297 * than bufsize, an exception is not thrown if the end of the packet
2298 * is reached before the NUL is found. If no NUL is found before reaching
2299 * the end of the short packet, -1 is still returned, and the string
2300 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
2301 * at the correct spot, terminating the string.
2303 * *bytes_copied will contain the number of bytes actually copied,
2304 * including the terminating-NUL.
2307 _tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer,
2311 guint abs_offset, junk_length;
2313 gboolean decreased_max = FALSE;
2315 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
2317 /* There must at least be room for the terminating NUL. */
2318 DISSECTOR_ASSERT(bufsize != 0);
2320 /* If there's no room for anything else, just return the NUL. */
2327 /* Only read to end of tvbuff, w/o throwing exception. */
2328 len = tvb_length_remaining(tvb, abs_offset);
2330 /* check_offset_length() won't throw an exception if we're
2331 * looking at the byte immediately after the end of the tvbuff. */
2333 THROW(ReportedBoundsError);
2336 /* This should not happen because check_offset_length() would
2337 * have already thrown an exception if 'offset' were out-of-bounds.
2339 DISSECTOR_ASSERT(len != -1);
2342 * If we've been passed a negative number, bufsize will
2345 DISSECTOR_ASSERT(bufsize <= G_MAXINT);
2347 if ((guint)len < bufsize) {
2349 decreased_max = TRUE;
2355 stringlen = tvb_strnlen(tvb, abs_offset, limit - 1);
2356 /* If NUL wasn't found, copy the data and return -1 */
2357 if (stringlen == -1) {
2358 tvb_memcpy(tvb, buffer, abs_offset, limit);
2359 if (decreased_max) {
2361 /* Add 1 for the extra NUL that we set at buffer[limit],
2362 * pretending that it was copied as part of the string. */
2363 *bytes_copied = limit + 1;
2366 *bytes_copied = limit;
2371 /* Copy the string to buffer */
2372 tvb_memcpy(tvb, buffer, abs_offset, stringlen + 1);
2373 *bytes_copied = stringlen + 1;
2377 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
2378 * no more than bufsize number of bytes, including terminating NUL, to buffer.
2379 * Returns length of string (not including terminating NUL), or -1 if the string was
2380 * truncated in the buffer due to not having reached the terminating NUL.
2381 * In this way, it acts like g_snprintf().
2383 * When processing a packet where the remaining number of bytes is less
2384 * than bufsize, an exception is not thrown if the end of the packet
2385 * is reached before the NUL is found. If no NUL is found before reaching
2386 * the end of the short packet, -1 is still returned, and the string
2387 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
2388 * at the correct spot, terminating the string.
2391 tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer)
2395 return _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
2398 /* Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
2399 * have a terminating NUL. If the string was truncated when copied into buffer,
2400 * a NUL is placed at the end of buffer to terminate it.
2403 tvb_get_nstringz0(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer)
2405 gint len, bytes_copied;
2407 len = _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
2410 buffer[bufsize - 1] = 0;
2411 return bytes_copied - 1;
2419 * Given a tvbuff, an offset into the tvbuff, and a length that starts
2420 * at that offset (which may be -1 for "all the way to the end of the
2421 * tvbuff"), find the end of the (putative) line that starts at the
2422 * specified offset in the tvbuff, going no further than the specified
2425 * Return the length of the line (not counting the line terminator at
2426 * the end), or, if we don't find a line terminator:
2428 * if "deseg" is true, return -1;
2430 * if "deseg" is false, return the amount of data remaining in
2433 * Set "*next_offset" to the offset of the character past the line
2434 * terminator, or past the end of the buffer if we don't find a line
2435 * terminator. (It's not set if we return -1.)
2438 tvb_find_line_end(tvbuff_t *tvb, gint offset, int len, gint *next_offset,
2446 len = tvb_length_remaining(tvb, offset);
2448 * XXX - what if "len" is still -1, meaning "offset is past the
2449 * end of the tvbuff"?
2451 eob_offset = offset + len;
2454 * Look either for a CR or an LF.
2456 eol_offset = tvb_pbrk_guint8(tvb, offset, len, (const guint8 *)"\r\n");
2457 if (eol_offset == -1) {
2459 * No CR or LF - line is presumably continued in next packet.
2463 * Tell our caller we saw no EOL, so they can
2464 * try to desegment and get the entire line
2470 * Pretend the line runs to the end of the tvbuff.
2472 linelen = eob_offset - offset;
2473 *next_offset = eob_offset;
2477 * Find the number of bytes between the starting offset
2480 linelen = eol_offset - offset;
2485 if (tvb_get_guint8(tvb, eol_offset) == '\r') {
2487 * Yes - is it followed by an LF?
2489 if (eol_offset + 1 >= eob_offset) {
2491 * Dunno - the next byte isn't in this
2496 * We'll return -1, although that
2497 * runs the risk that if the line
2498 * really *is* terminated with a CR,
2499 * we won't properly dissect this
2502 * It's probably more likely that
2503 * the line ends with CR-LF than
2504 * that it ends with CR by itself.
2510 * Well, we can at least look at the next
2513 if (tvb_get_guint8(tvb, eol_offset + 1) == '\n') {
2515 * It's an LF; skip over the CR.
2523 * Return the offset of the character after the last
2524 * character in the line, skipping over the last character
2525 * in the line terminator.
2527 *next_offset = eol_offset + 1;
2533 * Given a tvbuff, an offset into the tvbuff, and a length that starts
2534 * at that offset (which may be -1 for "all the way to the end of the
2535 * tvbuff"), find the end of the (putative) line that starts at the
2536 * specified offset in the tvbuff, going no further than the specified
2539 * However, treat quoted strings inside the buffer specially - don't
2540 * treat newlines in quoted strings as line terminators.
2542 * Return the length of the line (not counting the line terminator at
2543 * the end), or the amount of data remaining in the buffer if we don't
2544 * find a line terminator.
2546 * Set "*next_offset" to the offset of the character past the line
2547 * terminator, or past the end of the buffer if we don't find a line
2551 tvb_find_line_end_unquoted(tvbuff_t *tvb, gint offset, int len,
2554 gint cur_offset, char_offset;
2561 len = tvb_length_remaining(tvb, offset);
2563 * XXX - what if "len" is still -1, meaning "offset is past the
2564 * end of the tvbuff"?
2566 eob_offset = offset + len;
2568 cur_offset = offset;
2572 * Is this part of the string quoted?
2576 * Yes - look only for the terminating quote.
2578 char_offset = tvb_find_guint8(tvb, cur_offset, len,
2582 * Look either for a CR, an LF, or a '"'.
2584 char_offset = tvb_pbrk_guint8(tvb, cur_offset, len,
2585 (const guint8 *)"\r\n\"");
2587 if (char_offset == -1) {
2589 * Not found - line is presumably continued in
2591 * We pretend the line runs to the end of the tvbuff.
2593 linelen = eob_offset - offset;
2594 *next_offset = eob_offset;
2600 * We're processing a quoted string.
2601 * We only looked for ", so we know it's a ";
2602 * as we're processing a quoted string, it's a
2610 c = tvb_get_guint8(tvb, char_offset);
2613 * Un-quoted "; it begins a quoted
2619 * It's a CR or LF; we've found a line
2622 * Find the number of bytes between the
2623 * starting offset and the CR or LF.
2625 linelen = char_offset - offset;
2632 * Yes; is it followed by an LF?
2634 if (char_offset + 1 < eob_offset &&
2635 tvb_get_guint8(tvb, char_offset + 1)
2638 * Yes; skip over the CR.
2645 * Return the offset of the character after
2646 * the last character in the line, skipping
2647 * over the last character in the line
2648 * terminator, and quit.
2650 *next_offset = char_offset + 1;
2656 * Step past the character we found.
2658 cur_offset = char_offset + 1;
2659 if (cur_offset >= eob_offset) {
2661 * The character we found was the last character
2662 * in the tvbuff - line is presumably continued in
2664 * We pretend the line runs to the end of the tvbuff.
2666 linelen = eob_offset - offset;
2667 *next_offset = eob_offset;
2675 * Copied from the mgcp dissector. (This function should be moved to /epan )
2676 * tvb_skip_wsp - Returns the position in tvb of the first non-whitespace
2677 * character following offset or offset + maxlength -1 whichever
2681 * tvb - The tvbuff in which we are skipping whitespace.
2682 * offset - The offset in tvb from which we begin trying to skip whitespace.
2683 * maxlength - The maximum distance from offset that we may try to skip
2686 * Returns: The position in tvb of the first non-whitespace
2687 * character following offset or offset + maxlength -1 whichever
2690 gint tvb_skip_wsp(tvbuff_t* tvb, gint offset, gint maxlength)
2692 gint counter = offset;
2693 gint end = offset + maxlength,tvb_len;
2696 /* Get the length remaining */
2697 tvb_len = tvb_length(tvb);
2698 end = offset + maxlength;
2704 /* Skip past spaces, tabs, CRs and LFs until run out or meet something else */
2705 for (counter = offset;
2707 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
2708 tempchar == '\t' || tempchar == '\r' || tempchar == '\n');
2714 gint tvb_skip_wsp_return(tvbuff_t* tvb, gint offset){
2715 gint counter = offset;
2720 for(counter = offset; counter > end &&
2721 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
2722 tempchar == '\t' || tempchar == '\n' || tempchar == '\r'); counter--);
2729 * Format a bunch of data from a tvbuff as bytes, returning a pointer
2730 * to the string with the formatted data, with "punct" as a byte
2734 tvb_bytes_to_str_punct(tvbuff_t *tvb, gint offset, gint len, gchar punct)
2736 return bytes_to_str_punct(tvb_get_ptr(tvb, offset, len), len, punct);
2740 * Format a bunch of data from a tvbuff as bytes, returning a pointer
2741 * to the string with the formatted data.
2744 tvb_bytes_to_str(tvbuff_t *tvb, gint offset, gint len)
2746 return bytes_to_str(tvb_get_ptr(tvb, offset, len), len);
2749 /* Find a needle tvbuff within a haystack tvbuff. */
2751 tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb, gint haystack_offset)
2753 guint haystack_abs_offset, haystack_abs_length;
2754 const guint8 *haystack_data;
2755 const guint8 *needle_data;
2756 const guint needle_len = needle_tvb->length;
2757 const guint8 *location;
2759 if (haystack_tvb->length < 1 || needle_tvb->length < 1) {
2763 /* Get pointers to the tvbuffs' data. */
2764 haystack_data = tvb_get_ptr(haystack_tvb, 0, -1);
2765 needle_data = tvb_get_ptr(needle_tvb, 0, -1);
2767 check_offset_length(haystack_tvb, haystack_offset, -1,
2768 &haystack_abs_offset, &haystack_abs_length);
2770 location = epan_memmem(haystack_data + haystack_abs_offset, haystack_abs_length,
2771 needle_data, needle_len);
2774 return (gint) (location - haystack_data);
2782 * Uncompresses a zlib compressed packet inside a message of tvb at offset with
2783 * length comprlen. Returns an uncompressed tvbuffer if uncompression
2784 * succeeded or NULL if uncompression failed.
2786 #define TVB_Z_MIN_BUFSIZ 32768
2787 #define TVB_Z_MAX_BUFSIZ 1048576 * 10
2788 /* #define TVB_Z_DEBUG 1 */
2792 tvb_uncompress(tvbuff_t *tvb, int offset, int comprlen)
2797 guint bytes_out = 0;
2798 guint8 *compr = NULL;
2799 guint8 *uncompr = NULL;
2800 tvbuff_t *uncompr_tvb = NULL;
2801 z_streamp strm = NULL;
2802 Bytef *strmbuf = NULL;
2803 guint inits_done = 0;
2804 gint wbits = MAX_WBITS;
2805 guint8 *next = NULL;
2806 guint bufsiz = TVB_Z_MIN_BUFSIZ;
2808 guint inflate_passes = 0;
2809 guint bytes_in = tvb_length_remaining(tvb, offset);
2816 strm = g_malloc0(sizeof(z_stream));
2822 compr = tvb_memdup(tvb, offset, comprlen);
2830 * Assume that the uncompressed data is at least twice as big as
2831 * the compressed size.
2833 bufsiz = tvb_length_remaining(tvb, offset) * 2;
2835 if (bufsiz < TVB_Z_MIN_BUFSIZ) {
2836 bufsiz = TVB_Z_MIN_BUFSIZ;
2837 } else if (bufsiz > TVB_Z_MAX_BUFSIZ) {
2838 bufsiz = TVB_Z_MIN_BUFSIZ;
2842 printf("bufsiz: %u bytes\n", bufsiz);
2847 strm->next_in = next;
2848 strm->avail_in = comprlen;
2851 strmbuf = g_malloc0(bufsiz);
2853 if(strmbuf == NULL) {
2859 strm->next_out = strmbuf;
2860 strm->avail_out = bufsiz;
2862 err = inflateInit2(strm, wbits);
2873 memset(strmbuf, '\0', bufsiz);
2874 strm->next_out = strmbuf;
2875 strm->avail_out = bufsiz;
2877 err = inflate(strm, Z_SYNC_FLUSH);
2879 if (err == Z_OK || err == Z_STREAM_END) {
2880 guint bytes_pass = bufsiz - strm->avail_out;
2886 if (uncompr == NULL) {
2887 uncompr = g_memdup(strmbuf, bytes_pass);
2889 guint8 *new_data = g_malloc0(bytes_out +
2892 if (new_data == NULL) {
2898 if (uncompr != NULL) {
2905 g_memmove(new_data, uncompr, bytes_out);
2906 g_memmove((new_data + bytes_out), strmbuf,
2913 bytes_out += bytes_pass;
2915 if ( err == Z_STREAM_END) {
2921 } else if (err == Z_BUF_ERROR) {
2923 * It's possible that not enough frames were captured
2924 * to decompress this fully, so return what we've done
2931 if (uncompr != NULL) {
2938 } else if (err == Z_DATA_ERROR && inits_done == 1
2939 && uncompr == NULL && (*compr == 0x1f) &&
2940 (*(compr + 1) == 0x8b)) {
2942 * inflate() is supposed to handle both gzip and deflate
2943 * streams automatically, but in reality it doesn't
2944 * seem to handle either (at least not within the
2945 * context of an HTTP response.) We have to try
2946 * several tweaks, depending on the type of data and
2947 * version of the library installed.
2951 * Gzip file format. Skip past the header, since the
2952 * fix to make it work (setting windowBits to 31)
2953 * doesn't work with all versions of the library.
2955 Bytef *c = compr + 2;
2958 if (*c == Z_DEFLATED) {
2970 /* Skip past the MTIME, XFL, and OS fields. */
2973 if (flags & (1 << 2)) {
2974 /* An Extra field is present. */
2975 gint xsize = (gint)(*c |
2981 if (flags & (1 << 3)) {
2982 /* A null terminated filename */
2984 while ((c - compr) < comprlen && *c != '\0') {
2991 if (flags & (1 << 4)) {
2992 /* A null terminated comment */
2994 while ((c - compr) < comprlen && *c != '\0') {
3004 strm->next_in = next;
3005 if (c - compr > comprlen) {
3012 comprlen -= (int) (c - compr);
3015 err = inflateInit2(strm, wbits);
3017 } else if (err == Z_DATA_ERROR && uncompr == NULL &&
3021 * Re-init the stream with a negative
3022 * MAX_WBITS. This is necessary due to
3023 * some servers (Apache) not sending
3024 * the deflate header with the
3025 * content-encoded response.
3031 strm->next_in = next;
3032 strm->avail_in = comprlen;
3035 memset(strmbuf, '\0', bufsiz);
3036 strm->next_out = strmbuf;
3037 strm->avail_out = bufsiz;
3039 err = inflateInit2(strm, wbits);
3057 if (uncompr == NULL) {
3066 printf("inflate() total passes: %u\n", inflate_passes);
3067 printf("bytes in: %u\nbytes out: %u\n\n", bytes_in, bytes_out);
3070 if (uncompr != NULL) {
3071 uncompr_tvb = tvb_new_real_data((guint8*) uncompr, bytes_out,
3073 tvb_set_free_cb(uncompr_tvb, g_free);
3080 tvb_uncompress(tvbuff_t *tvb _U_, int offset _U_, int comprlen _U_)
3086 tvbuff_t* tvb_child_uncompress(tvbuff_t *parent _U_, tvbuff_t *tvb, int offset, int comprlen)
3088 tvbuff_t *new_tvb = tvb_uncompress(tvb, offset, comprlen);
3090 tvb_set_child_real_data_tvbuff (parent, new_tvb);