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, size_t length, size_t 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 = (guint) length;
268 tvb->reported_length = (guint) reported_length;
269 tvb->initialized = TRUE;
273 tvb_new_real_data(const guint8* data, size_t length, size_t 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, size_t length, size_t 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, size_t 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 = (guint) length;
391 check_offset_length_no_exception(tvbuff_t *tvb, gint offset, size_t 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;
433 *exception = ReportedBoundsError;
438 DISSECTOR_ASSERT_NOT_REACHED();
441 /* Checks (+/-) offset and length and throws an exception if
442 * either is out of bounds. Sets integer ptrs to the new offset
445 check_offset_length(tvbuff_t *tvb, gint offset, size_t length,
446 guint *offset_ptr, guint *length_ptr)
450 if (!check_offset_length_no_exception(tvb, offset, length, offset_ptr, length_ptr, &exception)) {
451 DISSECTOR_ASSERT(exception > 0);
459 tvb_set_subset(tvbuff_t *tvb, tvbuff_t *backing,
460 gint backing_offset, size_t backing_length, size_t reported_length)
462 DISSECTOR_ASSERT(tvb);
463 DISSECTOR_ASSERT(tvb->type == TVBUFF_SUBSET);
464 DISSECTOR_ASSERT(!tvb->initialized);
466 if (reported_length < -1) {
467 THROW(ReportedBoundsError);
470 check_offset_length(backing, backing_offset, backing_length,
471 &tvb->tvbuffs.subset.offset,
472 &tvb->tvbuffs.subset.length);
474 tvb->tvbuffs.subset.tvb = backing;
475 tvb->length = tvb->tvbuffs.subset.length;
477 if (reported_length == -1) {
478 tvb->reported_length = backing->reported_length - tvb->tvbuffs.subset.offset;
481 tvb->reported_length = (guint) reported_length;
483 tvb->initialized = TRUE;
484 add_to_used_in_list(backing, tvb);
486 /* Optimization. If the backing buffer has a pointer to contiguous, real data,
487 * then we can point directly to our starting offset in that buffer */
488 if (backing->real_data != NULL) {
489 tvb->real_data = backing->real_data + tvb->tvbuffs.subset.offset;
495 tvb_new_subset(tvbuff_t *backing, gint backing_offset, size_t backing_length, size_t reported_length)
497 static tvbuff_t *last_tvb=NULL;
500 tvb = tvb_new(TVBUFF_SUBSET);
505 /* remember this tvb in case we throw an exception and
506 * lose the pointer to it.
510 tvb_set_subset(tvb, backing, backing_offset, backing_length, reported_length);
513 * The top-level data source of this tvbuff is the top-level
514 * data source of its parent.
516 tvb->ds_tvb = backing->ds_tvb;
518 /* ok no exception so we dont need to remember it any longer */
525 tvb_composite_append(tvbuff_t* tvb, tvbuff_t* member)
527 tvb_comp_t *composite;
529 DISSECTOR_ASSERT(tvb && !tvb->initialized);
530 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
531 composite = &tvb->tvbuffs.composite;
532 composite->tvbs = g_slist_append( composite->tvbs, member );
533 add_to_used_in_list(tvb, member);
537 tvb_composite_prepend(tvbuff_t* tvb, tvbuff_t* member)
539 tvb_comp_t *composite;
541 DISSECTOR_ASSERT(tvb && !tvb->initialized);
542 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
543 composite = &tvb->tvbuffs.composite;
544 composite->tvbs = g_slist_prepend( composite->tvbs, member );
545 add_to_used_in_list(tvb, member);
549 tvb_new_composite(void)
551 return tvb_new(TVBUFF_COMPOSITE);
555 tvb_composite_finalize(tvbuff_t* tvb)
559 tvbuff_t *member_tvb;
560 tvb_comp_t *composite;
563 DISSECTOR_ASSERT(tvb && !tvb->initialized);
564 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
565 DISSECTOR_ASSERT(tvb->length == 0);
567 composite = &tvb->tvbuffs.composite;
568 num_members = g_slist_length(composite->tvbs);
570 composite->start_offsets = g_new(guint, num_members);
571 composite->end_offsets = g_new(guint, num_members);
573 for (slist = composite->tvbs; slist != NULL; slist = slist->next) {
574 DISSECTOR_ASSERT((guint) i < num_members);
575 member_tvb = slist->data;
576 composite->start_offsets[i] = tvb->length;
577 tvb->length += member_tvb->length;
578 composite->end_offsets[i] = tvb->length - 1;
582 tvb->initialized = TRUE;
588 tvb_length(tvbuff_t* tvb)
590 DISSECTOR_ASSERT(tvb && tvb->initialized);
596 tvb_length_remaining(tvbuff_t *tvb, gint offset)
598 guint abs_offset, abs_length;
600 DISSECTOR_ASSERT(tvb && tvb->initialized);
602 if (compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL)) {
611 tvb_ensure_length_remaining(tvbuff_t *tvb, gint offset)
613 guint abs_offset, abs_length;
616 DISSECTOR_ASSERT(tvb && tvb->initialized);
618 if (!compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, &exception)) {
621 if (abs_length == 0) {
623 * This routine ensures there's at least one byte available.
624 * There aren't any bytes available, so throw the appropriate
627 if (abs_offset >= tvb->reported_length)
628 THROW(ReportedBoundsError);
638 /* Validates that 'length' bytes are available starting from
639 * offset (pos/neg). Does not throw an exception. */
641 tvb_bytes_exist(tvbuff_t *tvb, gint offset, size_t length)
643 guint abs_offset, abs_length;
645 DISSECTOR_ASSERT(tvb && tvb->initialized);
647 if (!compute_offset_length(tvb, offset, length, &abs_offset, &abs_length, NULL))
650 if (abs_offset + abs_length <= tvb->length) {
658 /* Validates that 'length' bytes are available starting from
659 * offset (pos/neg). Throws an exception if they aren't. */
661 tvb_ensure_bytes_exist(tvbuff_t *tvb, gint offset, size_t length)
663 guint abs_offset, abs_length;
665 DISSECTOR_ASSERT(tvb && tvb->initialized);
668 * -1 doesn't mean "until end of buffer", as that's pointless
669 * for this routine. We must treat it as a Really Large Positive
670 * Number, so that we throw an exception; we throw
671 * ReportedBoundsError, as if it were past even the end of a
672 * reassembled packet, and past the end of even the data we
675 * We do the same with other negative lengths.
678 THROW(ReportedBoundsError);
680 check_offset_length(tvb, offset, length, &abs_offset, &abs_length);
684 tvb_offset_exists(tvbuff_t *tvb, gint offset)
686 guint abs_offset, abs_length;
688 DISSECTOR_ASSERT(tvb && tvb->initialized);
689 if (!compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL))
692 if (abs_offset < tvb->length) {
701 tvb_reported_length(tvbuff_t* tvb)
703 DISSECTOR_ASSERT(tvb && tvb->initialized);
705 return tvb->reported_length;
709 tvb_reported_length_remaining(tvbuff_t *tvb, gint offset)
711 guint abs_offset, abs_length;
713 DISSECTOR_ASSERT(tvb && tvb->initialized);
715 if (compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL)) {
716 if (tvb->reported_length >= abs_offset)
717 return tvb->reported_length - abs_offset;
726 /* Set the reported length of a tvbuff to a given value; used for protocols
727 whose headers contain an explicit length and where the calling
728 dissector's payload may include padding as well as the packet for
731 Also adjusts the data length. */
733 tvb_set_reported_length(tvbuff_t* tvb, guint reported_length)
735 DISSECTOR_ASSERT(tvb && tvb->initialized);
737 if (reported_length > tvb->reported_length)
738 THROW(ReportedBoundsError);
740 tvb->reported_length = reported_length;
741 if (reported_length < tvb->length)
742 tvb->length = reported_length;
748 first_real_data_ptr(tvbuff_t *tvb)
753 case TVBUFF_REAL_DATA:
754 return tvb->real_data;
756 member = tvb->tvbuffs.subset.tvb;
757 return first_real_data_ptr(member);
758 case TVBUFF_COMPOSITE:
759 member = tvb->tvbuffs.composite.tvbs->data;
760 return first_real_data_ptr(member);
763 DISSECTOR_ASSERT_NOT_REACHED();
769 offset_from_real_beginning(tvbuff_t *tvb, int counter)
774 case TVBUFF_REAL_DATA:
777 member = tvb->tvbuffs.subset.tvb;
778 return offset_from_real_beginning(member, counter + tvb->tvbuffs.subset.offset);
779 case TVBUFF_COMPOSITE:
780 member = tvb->tvbuffs.composite.tvbs->data;
781 return offset_from_real_beginning(member, counter);
784 DISSECTOR_ASSERT_NOT_REACHED();
789 composite_ensure_contiguous_no_exception(tvbuff_t *tvb, guint abs_offset,
792 guint i, num_members;
793 tvb_comp_t *composite;
794 tvbuff_t *member_tvb = NULL;
795 guint member_offset, member_length;
798 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
800 /* Maybe the range specified by offset/length
801 * is contiguous inside one of the member tvbuffs */
802 composite = &tvb->tvbuffs.composite;
803 num_members = g_slist_length(composite->tvbs);
805 for (i = 0; i < num_members; i++) {
806 if (abs_offset <= composite->end_offsets[i]) {
807 slist = g_slist_nth(composite->tvbs, i);
808 member_tvb = slist->data;
812 DISSECTOR_ASSERT(member_tvb);
814 if (check_offset_length_no_exception(member_tvb, abs_offset - composite->start_offsets[i],
815 abs_length, &member_offset, &member_length, NULL)) {
818 * The range is, in fact, contiguous within member_tvb.
820 DISSECTOR_ASSERT(!tvb->real_data);
821 return ensure_contiguous_no_exception(member_tvb, member_offset, member_length, NULL);
824 tvb->real_data = tvb_memdup(tvb, 0, -1);
825 return tvb->real_data + abs_offset;
828 DISSECTOR_ASSERT_NOT_REACHED();
833 ensure_contiguous_no_exception(tvbuff_t *tvb, gint offset, gint length,
836 guint abs_offset, abs_length;
838 if (!check_offset_length_no_exception(tvb, offset, length,
839 &abs_offset, &abs_length, exception)) {
844 * We know that all the data is present in the tvbuff, so
845 * no exceptions should be thrown.
847 if (tvb->real_data) {
848 return tvb->real_data + abs_offset;
852 case TVBUFF_REAL_DATA:
853 DISSECTOR_ASSERT_NOT_REACHED();
855 return ensure_contiguous_no_exception(tvb->tvbuffs.subset.tvb,
856 abs_offset - tvb->tvbuffs.subset.offset,
858 case TVBUFF_COMPOSITE:
859 return composite_ensure_contiguous_no_exception(tvb, abs_offset, abs_length);
863 DISSECTOR_ASSERT_NOT_REACHED();
867 /* ----------------------------- */
869 fast_ensure_contiguous(tvbuff_t *tvb, gint offset, guint length)
874 DISSECTOR_ASSERT(tvb && tvb->initialized);
875 if (offset < 0 || !tvb->real_data) {
876 return ensure_contiguous(tvb, offset, length);
880 end_offset = u_offset + length;
882 /* don't need to check for overflow because length <= 8 */
884 if (end_offset <= tvb->length) {
885 return tvb->real_data + u_offset;
888 if (end_offset > tvb->reported_length) {
889 THROW(ReportedBoundsError);
898 ensure_contiguous(tvbuff_t *tvb, gint offset, gint length)
903 p = ensure_contiguous_no_exception(tvb, offset, length, &exception);
905 DISSECTOR_ASSERT(exception > 0);
912 guint8_find(const guint8* haystack, size_t haystacklen, guint8 needle)
917 for (b = haystack, i = 0; (guint) i < haystacklen; i++, b++) {
927 guint8_pbrk(const guint8* haystack, size_t haystacklen, const guint8 *needles)
932 const guint8 *needlep;
934 for (b = haystack, i = 0; (guint) i < haystacklen; i++, b++) {
937 while ((needle = *needlep) != '\0') {
949 /************** ACCESSORS **************/
952 composite_memcpy(tvbuff_t *tvb, guint8* target, guint abs_offset, size_t abs_length)
954 guint i, num_members;
955 tvb_comp_t *composite;
956 tvbuff_t *member_tvb = NULL;
957 guint member_offset, member_length;
961 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
963 /* Maybe the range specified by offset/length
964 * is contiguous inside one of the member tvbuffs */
965 composite = &tvb->tvbuffs.composite;
966 num_members = g_slist_length(composite->tvbs);
968 for (i = 0; i < num_members; i++) {
969 if (abs_offset <= composite->end_offsets[i]) {
970 slist = g_slist_nth(composite->tvbs, i);
971 member_tvb = slist->data;
975 DISSECTOR_ASSERT(member_tvb);
977 if (check_offset_length_no_exception(member_tvb, abs_offset - composite->start_offsets[i],
978 (gint) abs_length, &member_offset, &member_length, NULL)) {
980 DISSECTOR_ASSERT(!tvb->real_data);
981 return tvb_memcpy(member_tvb, target, member_offset, member_length);
984 /* The requested data is non-contiguous inside
985 * the member tvb. We have to memcpy() the part that's in the member tvb,
986 * then iterate across the other member tvb's, copying their portions
987 * until we have copied all data.
989 retval = compute_offset_length(member_tvb, abs_offset - composite->start_offsets[i], -1,
990 &member_offset, &member_length, NULL);
991 DISSECTOR_ASSERT(retval);
993 tvb_memcpy(member_tvb, target, member_offset, member_length);
994 abs_offset += member_length;
995 abs_length -= member_length;
998 if (abs_length > 0) {
999 composite_memcpy(tvb, target + member_length, abs_offset, abs_length);
1005 DISSECTOR_ASSERT_NOT_REACHED();
1010 tvb_memcpy(tvbuff_t *tvb, void* target, gint offset, size_t length)
1012 guint abs_offset, abs_length;
1015 * XXX - we should eliminate the "length = -1 means 'to the end
1016 * of the tvbuff'" convention, and use other means to achieve
1017 * that; this would let us eliminate a bunch of checks for
1018 * negative lengths in cases where the protocol has a 32-bit
1021 * Allowing -1 but throwing an assertion on other negative
1022 * lengths is a bit more work with the length being a size_t;
1023 * instead, we check for a length <= 2^31-1.
1025 DISSECTOR_ASSERT(length <= 0x7FFFFFFF);
1026 check_offset_length(tvb, offset, (gint) length, &abs_offset, &abs_length);
1028 if (tvb->real_data) {
1029 return memcpy(target, tvb->real_data + abs_offset, abs_length);
1033 case TVBUFF_REAL_DATA:
1034 DISSECTOR_ASSERT_NOT_REACHED();
1037 return tvb_memcpy(tvb->tvbuffs.subset.tvb, target,
1038 abs_offset - tvb->tvbuffs.subset.offset,
1041 case TVBUFF_COMPOSITE:
1042 return composite_memcpy(tvb, target, offset, length);
1045 DISSECTOR_ASSERT_NOT_REACHED();
1051 * XXX - this doesn't treat a length of -1 as an error.
1052 * If it did, this could replace some code that calls
1053 * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies
1056 * "composite_ensure_contiguous_no_exception()" depends on -1 not being
1057 * an error; does anything else depend on this routine treating -1 as
1058 * meaning "to the end of the buffer"?
1061 tvb_memdup(tvbuff_t *tvb, gint offset, size_t length)
1063 guint abs_offset, abs_length;
1066 check_offset_length(tvb, offset, (gint) length, &abs_offset, &abs_length);
1068 duped = g_malloc(abs_length);
1069 return tvb_memcpy(tvb, duped, abs_offset, abs_length);
1073 * XXX - this doesn't treat a length of -1 as an error.
1074 * If it did, this could replace some code that calls
1075 * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies
1078 * "composite_ensure_contiguous_no_exception()" depends on -1 not being
1079 * an error; does anything else depend on this routine treating -1 as
1080 * meaning "to the end of the buffer"?
1082 * This function allocates memory from a buffer with packet lifetime.
1083 * You do not have to free this buffer, it will be automatically freed
1084 * when wireshark starts decoding the next packet.
1085 * Do not use this function if you want the allocated memory to be persistent
1086 * after the current packet has been dissected.
1089 ep_tvb_memdup(tvbuff_t *tvb, gint offset, size_t length)
1091 guint abs_offset, abs_length;
1094 check_offset_length(tvb, offset, (gint) length, &abs_offset, &abs_length);
1096 duped = ep_alloc(abs_length);
1097 return tvb_memcpy(tvb, duped, abs_offset, abs_length);
1103 tvb_get_ptr(tvbuff_t *tvb, gint offset, gint length)
1105 return ensure_contiguous(tvb, offset, length);
1108 /* ---------------- */
1110 tvb_get_guint8(tvbuff_t *tvb, gint offset)
1114 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint8));
1119 tvb_get_ntohs(tvbuff_t *tvb, gint offset)
1123 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint16));
1128 tvb_get_ntoh24(tvbuff_t *tvb, gint offset)
1132 ptr = fast_ensure_contiguous(tvb, offset, 3);
1133 return pntoh24(ptr);
1137 tvb_get_ntohl(tvbuff_t *tvb, gint offset)
1141 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1146 tvb_get_ntoh64(tvbuff_t *tvb, gint offset)
1150 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint64));
1151 return pntoh64(ptr);
1155 * Stuff for IEEE float handling on platforms that don't have IEEE
1156 * format as the native floating-point format.
1158 * For now, we treat only the VAX as such a platform.
1160 * XXX - other non-IEEE boxes that can run UNIX include some Crays,
1161 * and possibly other machines.
1163 * It appears that the official Linux port to System/390 and
1164 * zArchitecture uses IEEE format floating point (not a
1167 * I don't know whether there are any other machines that
1168 * could run Wireshark and that don't use IEEE format.
1169 * As far as I know, all of the main commercial microprocessor
1170 * families on which OSes that support Wireshark can run
1171 * use IEEE format (x86, 68k, SPARC, MIPS, PA-RISC, Alpha,
1172 * IA-64, and so on).
1182 #define IEEE_SP_NUMBER_WIDTH 32 /* bits in number */
1183 #define IEEE_SP_EXP_WIDTH 8 /* bits in exponent */
1184 #define IEEE_SP_MANTISSA_WIDTH 23 /* IEEE_SP_NUMBER_WIDTH - 1 - IEEE_SP_EXP_WIDTH */
1186 #define IEEE_SP_SIGN_MASK 0x80000000
1187 #define IEEE_SP_EXPONENT_MASK 0x7F800000
1188 #define IEEE_SP_MANTISSA_MASK 0x007FFFFF
1189 #define IEEE_SP_INFINITY IEEE_SP_EXPONENT_MASK
1191 #define IEEE_SP_IMPLIED_BIT (1 << IEEE_SP_MANTISSA_WIDTH)
1192 #define IEEE_SP_INFINITE ((1 << IEEE_SP_EXP_WIDTH) - 1)
1193 #define IEEE_SP_BIAS ((1 << (IEEE_SP_EXP_WIDTH - 1)) - 1)
1196 ieee_float_is_zero(guint32 w)
1198 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1202 get_ieee_float(guint32 w)
1208 sign = w & IEEE_SP_SIGN_MASK;
1209 exponent = w & IEEE_SP_EXPONENT_MASK;
1210 mantissa = w & IEEE_SP_MANTISSA_MASK;
1212 if (ieee_float_is_zero(w)) {
1213 /* number is zero, unnormalized, or not-a-number */
1218 * XXX - how to handle this?
1220 if (IEEE_SP_INFINITY == exponent) {
1222 * number is positive or negative infinity, or a special value
1224 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1228 exponent = ((exponent >> IEEE_SP_MANTISSA_WIDTH) - IEEE_SP_BIAS) -
1229 IEEE_SP_MANTISSA_WIDTH;
1230 mantissa |= IEEE_SP_IMPLIED_BIT;
1233 return -mantissa * pow(2, exponent);
1235 return mantissa * pow(2, exponent);
1240 * We assume that if you don't have IEEE floating-point, you have a
1241 * compiler that understands 64-bit integral quantities.
1243 #define IEEE_DP_NUMBER_WIDTH 64 /* bits in number */
1244 #define IEEE_DP_EXP_WIDTH 11 /* bits in exponent */
1245 #define IEEE_DP_MANTISSA_WIDTH 52 /* IEEE_DP_NUMBER_WIDTH - 1 - IEEE_DP_EXP_WIDTH */
1247 #define IEEE_DP_SIGN_MASK 0x8000000000000000LL
1248 #define IEEE_DP_EXPONENT_MASK 0x7FF0000000000000LL
1249 #define IEEE_DP_MANTISSA_MASK 0x000FFFFFFFFFFFFFLL
1250 #define IEEE_DP_INFINITY IEEE_DP_EXPONENT_MASK
1252 #define IEEE_DP_IMPLIED_BIT (1LL << IEEE_DP_MANTISSA_WIDTH)
1253 #define IEEE_DP_INFINITE ((1 << IEEE_DP_EXP_WIDTH) - 1)
1254 #define IEEE_DP_BIAS ((1 << (IEEE_DP_EXP_WIDTH - 1)) - 1)
1257 ieee_double_is_zero(guint64 w)
1259 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1263 get_ieee_double(guint64 w)
1269 sign = w & IEEE_DP_SIGN_MASK;
1270 exponent = w & IEEE_DP_EXPONENT_MASK;
1271 mantissa = w & IEEE_DP_MANTISSA_MASK;
1273 if (ieee_double_is_zero(w)) {
1274 /* number is zero, unnormalized, or not-a-number */
1279 * XXX - how to handle this?
1281 if (IEEE_DP_INFINITY == exponent) {
1283 * number is positive or negative infinity, or a special value
1285 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1289 exponent = ((exponent >> IEEE_DP_MANTISSA_WIDTH) - IEEE_DP_BIAS) -
1290 IEEE_DP_MANTISSA_WIDTH;
1291 mantissa |= IEEE_DP_IMPLIED_BIT;
1294 return -mantissa * pow(2, exponent);
1296 return mantissa * pow(2, exponent);
1301 * Fetches an IEEE single-precision floating-point number, in
1302 * big-endian form, and returns a "float".
1304 * XXX - should this be "double", in case there are IEEE single-
1305 * precision numbers that won't fit in some platform's native
1309 tvb_get_ntohieee_float(tvbuff_t *tvb, int offset)
1312 return get_ieee_float(tvb_get_ntohl(tvb, offset));
1319 ieee_fp_union.w = tvb_get_ntohl(tvb, offset);
1320 return ieee_fp_union.f;
1325 * Fetches an IEEE double-precision floating-point number, in
1326 * big-endian form, and returns a "double".
1329 tvb_get_ntohieee_double(tvbuff_t *tvb, int offset)
1343 #ifdef WORDS_BIGENDIAN
1344 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset);
1345 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset+4);
1347 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset+4);
1348 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset);
1351 return get_ieee_double(ieee_fp_union.dw);
1353 return ieee_fp_union.d;
1358 tvb_get_letohs(tvbuff_t *tvb, gint offset)
1362 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint16));
1363 return pletohs(ptr);
1367 tvb_get_letoh24(tvbuff_t *tvb, gint offset)
1371 ptr = fast_ensure_contiguous(tvb, offset, 3);
1372 return pletoh24(ptr);
1376 tvb_get_letohl(tvbuff_t *tvb, gint offset)
1380 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1381 return pletohl(ptr);
1385 tvb_get_letoh64(tvbuff_t *tvb, gint offset)
1389 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint64));
1390 return pletoh64(ptr);
1394 * Fetches an IEEE single-precision floating-point number, in
1395 * little-endian form, and returns a "float".
1397 * XXX - should this be "double", in case there are IEEE single-
1398 * precision numbers that won't fit in some platform's native
1402 tvb_get_letohieee_float(tvbuff_t *tvb, int offset)
1405 return get_ieee_float(tvb_get_letohl(tvb, offset));
1412 ieee_fp_union.w = tvb_get_letohl(tvb, offset);
1413 return ieee_fp_union.f;
1418 * Fetches an IEEE double-precision floating-point number, in
1419 * little-endian form, and returns a "double".
1422 tvb_get_letohieee_double(tvbuff_t *tvb, int offset)
1436 #ifdef WORDS_BIGENDIAN
1437 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset+4);
1438 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset);
1440 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset);
1441 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset+4);
1444 return get_ieee_double(ieee_fp_union.dw);
1446 return ieee_fp_union.d;
1450 /* Fetch an IPv4 address, in network byte order.
1451 * We do *not* convert them to host byte order; we leave them in
1452 * network byte order. */
1454 tvb_get_ipv4(tvbuff_t *tvb, gint offset)
1459 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1460 memcpy(&addr, ptr, sizeof addr);
1464 /* Fetch an IPv6 address. */
1466 tvb_get_ipv6(tvbuff_t *tvb, gint offset, struct e_in6_addr *addr)
1470 ptr = ensure_contiguous(tvb, offset, sizeof(*addr));
1471 memcpy(addr, ptr, sizeof *addr);
1476 tvb_get_ntohguid(tvbuff_t *tvb, gint offset, e_guid_t *guid)
1478 ensure_contiguous(tvb, offset, sizeof(*guid));
1479 guid->data1 = tvb_get_ntohl(tvb, offset);
1480 guid->data2 = tvb_get_ntohs(tvb, offset + 4);
1481 guid->data3 = tvb_get_ntohs(tvb, offset + 6);
1482 tvb_memcpy(tvb, guid->data4, offset + 8, sizeof guid->data4);
1486 tvb_get_letohguid(tvbuff_t *tvb, gint offset, e_guid_t *guid)
1488 ensure_contiguous(tvb, offset, sizeof(*guid));
1489 guid->data1 = tvb_get_letohl(tvb, offset);
1490 guid->data2 = tvb_get_letohs(tvb, offset + 4);
1491 guid->data3 = tvb_get_letohs(tvb, offset + 6);
1492 tvb_memcpy(tvb, guid->data4, offset + 8, sizeof guid->data4);
1496 tvb_get_guid(tvbuff_t *tvb, gint offset, e_guid_t *guid, gboolean little_endian)
1498 if (little_endian) {
1499 tvb_get_letohguid(tvb, offset, guid);
1501 tvb_get_ntohguid(tvb, offset, guid);
1505 static const guint8 bit_mask8[] = {
1516 /* Bit offset mask for number of bits = 8 - 16 */
1517 static const guint16 bit_mask16[] = {
1527 /* Get 1 - 8 bits */
1529 tvb_get_bits8(tvbuff_t *tvb, gint bit_offset, gint no_of_bits)
1536 DISSECTOR_ASSERT_NOT_REACHED();
1538 /* Byte align offset */
1539 offset = bit_offset>>3;
1541 /* Find out which mask to use for the most significant octet
1542 * by convering bit_offset into the offset into the first
1545 bit_offset = bit_offset & 0x7;
1546 tot_no_bits = bit_offset+no_of_bits;
1548 /* Read one octet, mask off bit_offset bits and left shift out the unused bits */
1549 value = tvb_get_guint8(tvb,offset) & bit_mask8[bit_offset];
1550 value = value >> (8-tot_no_bits);
1552 /* Read two octets, mask off bit_offset bits and left shift out the unused bits */
1553 value = tvb_get_ntohs(tvb,offset) & bit_mask16[bit_offset];
1554 value = value >> (16 - tot_no_bits);
1557 return (guint8)value;
1563 /* Get 9 - 16 bits */
1564 /* Bit offset mask for number of bits = 9 - 32 */
1565 static const guint32 bit_mask32[] = {
1576 tvb_get_bits16(tvbuff_t *tvb, gint bit_offset, gint no_of_bits,gboolean little_endian)
1580 guint16 tempval = 0;
1583 if ((no_of_bits<8)||(no_of_bits>16)) {
1584 /* If bits < 8 use tvb_get_bits8 */
1585 DISSECTOR_ASSERT_NOT_REACHED();
1588 DISSECTOR_ASSERT_NOT_REACHED();
1589 /* This part is not implemented yet */
1592 /* Byte align offset */
1593 offset = bit_offset>>3;
1595 /* Find out which mask to use for the most significant octet
1596 * by convering bit_offset into the offset into the first
1599 bit_offset = bit_offset & 0x7;
1600 tot_no_bits = bit_offset+no_of_bits;
1601 /* Read two octets and mask off bit_offset bits */
1602 value = tvb_get_ntohs(tvb,offset) & bit_mask16[bit_offset];
1603 if(tot_no_bits < 16){
1604 /* Left shift out the unused bits */
1605 value = value >> (16 - tot_no_bits);
1606 }else if(tot_no_bits > 16){
1607 /* Spans three octets, read next octet and shift as needed */
1608 value = value << (tot_no_bits - 16);
1609 tempval = tvb_get_guint8(tvb,offset+2);
1610 tempval = tempval >> (24-tot_no_bits);
1611 value = value | tempval;
1618 /* Bit offset mask for number of bits = 32 - 64 */
1619 static const guint64 bit_mask64[] = {
1620 G_GINT64_CONSTANT(0xffffffffffffffffU),
1621 G_GINT64_CONSTANT(0x7fffffffffffffffU),
1622 G_GINT64_CONSTANT(0x3fffffffffffffffU),
1623 G_GINT64_CONSTANT(0x1fffffffffffffffU),
1624 G_GINT64_CONSTANT(0x0fffffffffffffffU),
1625 G_GINT64_CONSTANT(0x07ffffffffffffffU),
1626 G_GINT64_CONSTANT(0x03ffffffffffffffU),
1627 G_GINT64_CONSTANT(0x01ffffffffffffffU)
1631 tvb_get_bits32(tvbuff_t *tvb, gint bit_offset, gint no_of_bits, gboolean little_endian)
1635 guint32 tempval = 0;
1638 if ((no_of_bits<17)||(no_of_bits>32)) {
1639 /* If bits < 17 use tvb_get_bits8 or tvb_get_bits_ntohs */
1640 DISSECTOR_ASSERT_NOT_REACHED();
1643 DISSECTOR_ASSERT_NOT_REACHED();
1644 /* This part is not implemented yet */
1647 /* Byte align offset */
1648 offset = bit_offset>>3;
1650 /* Find out which mask to use for the most significant octet
1651 * by convering bit_offset into the offset into the first
1654 bit_offset = bit_offset & 0x7;
1655 tot_no_bits = bit_offset+no_of_bits;
1656 /* Read four octets and mask off bit_offset bits */
1657 value = tvb_get_ntohl(tvb,offset) & bit_mask32[bit_offset];
1658 if(tot_no_bits < 32){
1659 /* Left shift out the unused bits */
1660 value = value >> (32 - tot_no_bits);
1661 }else if(tot_no_bits > 32){
1662 /* Spans five octets, read next octet and shift as needed */
1663 value = value << (tot_no_bits - 32);
1664 tempval = tvb_get_guint8(tvb,offset+4);
1665 tempval = tempval >> (40-tot_no_bits);
1666 value = value | tempval;
1673 tvb_get_bits64(tvbuff_t *tvb, gint bit_offset, gint no_of_bits, gboolean little_endian)
1678 guint64 tempval = 0;
1681 if ((no_of_bits<32)||(no_of_bits>64)) {
1682 /* If bits < 17 use tvb_get_bits8 or tvb_get_bits_ntohs */
1683 DISSECTOR_ASSERT_NOT_REACHED();
1686 DISSECTOR_ASSERT_NOT_REACHED();
1687 /* This part is not implemented yet */
1690 /* Byte align offset */
1691 offset = bit_offset>>3;
1693 /* Find out which mask to use for the most significant octet
1694 * by convering bit_offset into the offset into the first
1697 bit_offset = bit_offset & 0x7;
1698 tot_no_bits = bit_offset+no_of_bits;
1699 /* Read eight octets and mask off bit_offset bits */
1700 value = tvb_get_ntoh64(tvb,offset) & bit_mask64[bit_offset];
1701 if (tot_no_bits < 64){
1702 /* Left shift out the unused bits */
1703 value = value >> (64 - tot_no_bits);
1704 }else if (tot_no_bits > 64){
1705 /* Spans nine octets, read next octet and shift as needed */
1706 value = value << (tot_no_bits - 64);
1707 tempval = tvb_get_guint8(tvb,offset+8);
1708 tempval = tempval >> (72-tot_no_bits);
1709 value = value | tempval;
1716 /* Find first occurence of needle in tvbuff, starting at offset. Searches
1717 * at most maxlength number of bytes; if maxlength is -1, searches to
1719 * Returns the offset of the found needle, or -1 if not found.
1720 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1721 * in that case, -1 will be returned if the boundary is reached before
1722 * finding needle. */
1724 tvb_find_guint8(tvbuff_t *tvb, gint offset, gint maxlength, guint8 needle)
1726 const guint8 *result;
1727 guint abs_offset, junk_length;
1731 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1733 /* Only search to end of tvbuff, w/o throwing exception. */
1734 tvbufflen = tvb_length_remaining(tvb, abs_offset);
1735 if (maxlength == -1) {
1736 /* No maximum length specified; search to end of tvbuff. */
1739 else if (tvbufflen < (guint) maxlength) {
1740 /* Maximum length goes past end of tvbuff; search to end
1745 /* Maximum length doesn't go past end of tvbuff; search
1750 /* If we have real data, perform our search now. */
1751 if (tvb->real_data) {
1752 result = guint8_find(tvb->real_data + abs_offset, limit, needle);
1753 if (result == NULL) {
1757 return (gint) (result - tvb->real_data);
1762 case TVBUFF_REAL_DATA:
1763 DISSECTOR_ASSERT_NOT_REACHED();
1766 return tvb_find_guint8(tvb->tvbuffs.subset.tvb,
1767 abs_offset - tvb->tvbuffs.subset.offset,
1770 case TVBUFF_COMPOSITE:
1771 DISSECTOR_ASSERT_NOT_REACHED();
1772 /* XXX - return composite_find_guint8(tvb, offset, limit, needle); */
1775 DISSECTOR_ASSERT_NOT_REACHED();
1779 /* Find first occurence of any of the needles in tvbuff, starting at offset.
1780 * Searches at most maxlength number of bytes; if maxlength is -1, searches
1782 * Returns the offset of the found needle, or -1 if not found.
1783 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1784 * in that case, -1 will be returned if the boundary is reached before
1785 * finding needle. */
1787 tvb_pbrk_guint8(tvbuff_t *tvb, gint offset, gint maxlength, const guint8 *needles)
1789 const guint8 *result;
1790 guint abs_offset, junk_length;
1794 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1796 /* Only search to end of tvbuff, w/o throwing exception. */
1797 tvbufflen = tvb_length_remaining(tvb, abs_offset);
1798 if (maxlength == -1) {
1799 /* No maximum length specified; search to end of tvbuff. */
1802 else if (tvbufflen < (guint) maxlength) {
1803 /* Maximum length goes past end of tvbuff; search to end
1808 /* Maximum length doesn't go past end of tvbuff; search
1813 /* If we have real data, perform our search now. */
1814 if (tvb->real_data) {
1815 result = guint8_pbrk(tvb->real_data + abs_offset, limit, needles);
1816 if (result == NULL) {
1820 return (gint) (result - tvb->real_data);
1825 case TVBUFF_REAL_DATA:
1826 DISSECTOR_ASSERT_NOT_REACHED();
1829 return tvb_pbrk_guint8(tvb->tvbuffs.subset.tvb,
1830 abs_offset - tvb->tvbuffs.subset.offset,
1833 case TVBUFF_COMPOSITE:
1834 DISSECTOR_ASSERT_NOT_REACHED();
1835 /* XXX - return composite_pbrk_guint8(tvb, offset, limit, needle); */
1838 DISSECTOR_ASSERT_NOT_REACHED();
1842 /* Find size of stringz (NUL-terminated string) by looking for terminating
1843 * NUL. The size of the string includes the terminating NUL.
1845 * If the NUL isn't found, it throws the appropriate exception.
1848 tvb_strsize(tvbuff_t *tvb, gint offset)
1850 guint abs_offset, junk_length;
1853 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1854 nul_offset = tvb_find_guint8(tvb, abs_offset, -1, 0);
1855 if (nul_offset == -1) {
1857 * OK, we hit the end of the tvbuff, so we should throw
1860 * Did we hit the end of the captured data, or the end
1861 * of the actual data? If there's less captured data
1862 * than actual data, we presumably hit the end of the
1863 * captured data, otherwise we hit the end of the actual
1866 if (tvb_length(tvb) < tvb_reported_length(tvb)) {
1869 THROW(ReportedBoundsError);
1872 return (nul_offset - abs_offset) + 1;
1875 /* Find length of string by looking for end of string ('\0'), up to
1876 * 'maxlength' characters'; if 'maxlength' is -1, searches to end
1878 * Returns -1 if 'maxlength' reached before finding EOS. */
1880 tvb_strnlen(tvbuff_t *tvb, gint offset, guint maxlength)
1883 guint abs_offset, junk_length;
1885 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1887 result_offset = tvb_find_guint8(tvb, abs_offset, maxlength, 0);
1889 if (result_offset == -1) {
1893 return result_offset - abs_offset;
1898 * Implement strneql etc
1902 * Call strncmp after checking if enough chars left, returning 0 if
1903 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1906 tvb_strneql(tvbuff_t *tvb, gint offset, const gchar *str, gint size)
1910 ptr = ensure_contiguous_no_exception(tvb, offset, size, NULL);
1913 int cmp = strncmp((const char *)ptr, str, size);
1916 * Return 0 if equal, -1 otherwise.
1918 return (cmp == 0 ? 0 : -1);
1921 * Not enough characters in the tvbuff to match the
1929 * Call g_ascii_strncasecmp after checking if enough chars left, returning
1930 * 0 if it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1933 tvb_strncaseeql(tvbuff_t *tvb, gint offset, const gchar *str, gint size)
1937 ptr = ensure_contiguous_no_exception(tvb, offset, size, NULL);
1940 int cmp = g_ascii_strncasecmp((const char *)ptr, str, size);
1943 * Return 0 if equal, -1 otherwise.
1945 return (cmp == 0 ? 0 : -1);
1948 * Not enough characters in the tvbuff to match the
1956 * Call memcmp after checking if enough chars left, returning 0 if
1957 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1960 tvb_memeql(tvbuff_t *tvb, gint offset, const guint8 *str, size_t size)
1964 ptr = ensure_contiguous_no_exception(tvb, offset, (gint) size, NULL);
1967 int cmp = memcmp(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
1982 /* Convert a string from Unicode to ASCII. At the moment we fake it by
1983 * replacing all non-ASCII characters with a '.' )-: The caller must
1984 * free the result returned. The len parameter is the number of guint16's
1985 * to convert from Unicode. */
1987 tvb_fake_unicode(tvbuff_t *tvb, int offset, int len, gboolean little_endian)
1993 /* Make sure we have enough data before allocating the buffer,
1994 so we don't blow up if the length is huge. */
1995 tvb_ensure_bytes_exist(tvb, offset, 2*len);
1997 /* We know we won't throw an exception, so we don't have to worry
1998 about leaking this buffer. */
1999 buffer = g_malloc(len + 1);
2001 for (i = 0; i < len; i++) {
2002 character = little_endian ? tvb_get_letohs(tvb, offset)
2003 : tvb_get_ntohs(tvb, offset);
2004 buffer[i] = character < 256 ? character : '.';
2013 /* Convert a string from Unicode to ASCII. At the moment we fake it by
2014 * replacing all non-ASCII characters with a '.' )-: The len parameter is
2015 * the number of guint16's to convert from Unicode.
2017 * This function allocates memory from a buffer with packet lifetime.
2018 * You do not have to free this buffer, it will be automatically freed
2019 * when wireshark starts decoding the next packet.
2022 tvb_get_ephemeral_faked_unicode(tvbuff_t *tvb, int offset, int len, gboolean little_endian)
2028 /* Make sure we have enough data before allocating the buffer,
2029 so we don't blow up if the length is huge. */
2030 tvb_ensure_bytes_exist(tvb, offset, 2*len);
2032 /* We know we won't throw an exception, so we don't have to worry
2033 about leaking this buffer. */
2034 buffer = ep_alloc(len + 1);
2036 for (i = 0; i < len; i++) {
2037 character = little_endian ? tvb_get_letohs(tvb, offset)
2038 : tvb_get_ntohs(tvb, offset);
2039 buffer[i] = character < 256 ? character : '.';
2049 * Format the data in the tvb from offset for length ...
2053 tvb_format_text(tvbuff_t *tvb, gint offset, gint size)
2058 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2060 len = tvb_length_remaining(tvb, offset);
2061 ptr = ensure_contiguous(tvb, offset, len);
2065 return format_text(ptr, len);
2070 * Format the data in the tvb from offset for length ...
2074 tvb_format_text_wsp(tvbuff_t *tvb, gint offset, gint size)
2079 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2081 len = tvb_length_remaining(tvb, offset);
2082 ptr = ensure_contiguous(tvb, offset, len);
2086 return format_text_wsp(ptr, len);
2091 * Like "tvb_format_text()", but for null-padded strings; don't show
2092 * the null padding characters as "\000".
2095 tvb_format_stringzpad(tvbuff_t *tvb, gint offset, gint size)
2097 const guint8 *ptr, *p;
2101 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
2103 len = tvb_length_remaining(tvb, offset);
2104 ptr = ensure_contiguous(tvb, offset, len);
2108 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2110 return format_text(ptr, stringlen);
2115 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2116 * to hold a non-null-terminated string of that length at that offset,
2117 * plus a trailing '\0', copy the string into it, and return a pointer
2120 * Throws an exception if the tvbuff ends before the string does.
2123 tvb_get_string(tvbuff_t *tvb, gint offset, size_t length)
2126 guint8 *strbuf = NULL;
2128 tvb_ensure_bytes_exist(tvb, offset, length);
2130 ptr = ensure_contiguous(tvb, offset, (gint) length);
2131 strbuf = g_malloc(length + 1);
2133 memcpy(strbuf, ptr, length);
2135 strbuf[length] = '\0';
2139 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2140 * to hold a non-null-terminated string of that length at that offset,
2141 * plus a trailing '\0', copy the string into it, and return a pointer
2144 * Throws an exception if the tvbuff ends before the string does.
2146 * This function allocates memory from a buffer with packet lifetime.
2147 * You do not have to free this buffer, it will be automatically freed
2148 * when wireshark starts decoding the next packet.
2149 * Do not use this function if you want the allocated memory to be persistent
2150 * after the current packet has been dissected.
2153 tvb_get_ephemeral_string(tvbuff_t *tvb, gint offset, size_t length)
2156 guint8 *strbuf = NULL;
2158 tvb_ensure_bytes_exist(tvb, offset, length);
2160 ptr = ensure_contiguous(tvb, offset, (gint) length);
2161 strbuf = ep_alloc(length + 1);
2163 memcpy(strbuf, ptr, length);
2165 strbuf[length] = '\0';
2170 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
2171 * to hold a non-null-terminated string of that length at that offset,
2172 * plus a trailing '\0', copy the string into it, and return a pointer
2175 * Throws an exception if the tvbuff ends before the string does.
2177 * This function allocates memory from a buffer with capture session lifetime.
2178 * You do not have to free this buffer, it will be automatically freed
2179 * when wireshark starts or opens a new capture.
2182 tvb_get_seasonal_string(tvbuff_t *tvb, gint offset, size_t length)
2185 guint8 *strbuf = NULL;
2187 tvb_ensure_bytes_exist(tvb, offset, length);
2189 ptr = ensure_contiguous(tvb, offset, (gint) length);
2190 strbuf = se_alloc(length + 1);
2192 memcpy(strbuf, ptr, length);
2194 strbuf[length] = '\0';
2199 * Given a tvbuff and an offset, with the offset assumed to refer to
2200 * a null-terminated string, find the length of that string (and throw
2201 * an exception if the tvbuff ends before we find the null), allocate
2202 * a buffer big enough to hold the string, copy the string into it,
2203 * and return a pointer to the string. Also return the length of the
2204 * string (including the terminating null) through a pointer.
2207 tvb_get_stringz(tvbuff_t *tvb, gint offset, gint *lengthp)
2212 size = tvb_strsize(tvb, offset);
2213 strptr = g_malloc(size);
2214 tvb_memcpy(tvb, strptr, offset, size);
2219 * Given a tvbuff and an offset, with the offset assumed to refer to
2220 * a null-terminated string, find the length of that string (and throw
2221 * an exception if the tvbuff ends before we find the null), allocate
2222 * a buffer big enough to hold the string, copy the string into it,
2223 * and return a pointer to the string. Also return the length of the
2224 * string (including the terminating null) through a pointer.
2226 * This function allocates memory from a buffer with packet lifetime.
2227 * You do not have to free this buffer, it will be automatically freed
2228 * when wireshark starts decoding the next packet.
2229 * Do not use this function if you want the allocated memory to be persistent
2230 * after the current packet has been dissected.
2233 tvb_get_ephemeral_stringz(tvbuff_t *tvb, gint offset, gint *lengthp)
2238 size = tvb_strsize(tvb, offset);
2239 strptr = ep_alloc(size);
2240 tvb_memcpy(tvb, strptr, offset, size);
2246 * Given a tvbuff and an offset, with the offset assumed to refer to
2247 * a null-terminated string, find the length of that string (and throw
2248 * an exception if the tvbuff ends before we find the null), allocate
2249 * a buffer big enough to hold the string, copy the string into it,
2250 * and return a pointer to the string. Also return the length of the
2251 * string (including the terminating null) through a pointer.
2253 * This function allocates memory from a buffer with capture session lifetime.
2254 * You do not have to free this buffer, it will be automatically freed
2255 * when wireshark starts or opens a new capture.
2258 tvb_get_seasonal_stringz(tvbuff_t *tvb, gint offset, gint *lengthp)
2263 size = tvb_strsize(tvb, offset);
2264 strptr = se_alloc(size);
2265 tvb_memcpy(tvb, strptr, offset, size);
2270 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
2271 * no more than bufsize number of bytes, including terminating NUL, to buffer.
2272 * Returns length of string (not including terminating NUL), or -1 if the string was
2273 * truncated in the buffer due to not having reached the terminating NUL.
2274 * In this way, it acts like g_snprintf().
2276 * bufsize MUST be greater than 0.
2278 * When processing a packet where the remaining number of bytes is less
2279 * than bufsize, an exception is not thrown if the end of the packet
2280 * is reached before the NUL is found. If no NUL is found before reaching
2281 * the end of the short packet, -1 is still returned, and the string
2282 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
2283 * at the correct spot, terminating the string.
2285 * *bytes_copied will contain the number of bytes actually copied,
2286 * including the terminating-NUL.
2289 _tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer,
2293 guint abs_offset, junk_length;
2295 gboolean decreased_max = FALSE;
2297 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
2299 /* There must at least be room for the terminating NUL. */
2300 DISSECTOR_ASSERT(bufsize != 0);
2302 /* If there's no room for anything else, just return the NUL. */
2309 /* Only read to end of tvbuff, w/o throwing exception. */
2310 len = tvb_length_remaining(tvb, abs_offset);
2312 /* check_offset_length() won't throw an exception if we're
2313 * looking at the byte immediately after the end of the tvbuff. */
2315 THROW(ReportedBoundsError);
2318 /* This should not happen because check_offset_length() would
2319 * have already thrown an exception if 'offset' were out-of-bounds.
2321 DISSECTOR_ASSERT(len != -1);
2324 * If we've been passed a negative number, bufsize will
2327 DISSECTOR_ASSERT(bufsize <= G_MAXINT);
2329 if ((guint)len < bufsize) {
2331 decreased_max = TRUE;
2337 stringlen = tvb_strnlen(tvb, abs_offset, limit - 1);
2338 /* If NUL wasn't found, copy the data and return -1 */
2339 if (stringlen == -1) {
2340 tvb_memcpy(tvb, buffer, abs_offset, limit);
2341 if (decreased_max) {
2343 /* Add 1 for the extra NUL that we set at buffer[limit],
2344 * pretending that it was copied as part of the string. */
2345 *bytes_copied = limit + 1;
2348 *bytes_copied = limit;
2353 /* Copy the string to buffer */
2354 tvb_memcpy(tvb, buffer, abs_offset, stringlen + 1);
2355 *bytes_copied = stringlen + 1;
2359 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
2360 * no more than bufsize number of bytes, including terminating NUL, to buffer.
2361 * Returns length of string (not including terminating NUL), or -1 if the string was
2362 * truncated in the buffer due to not having reached the terminating NUL.
2363 * In this way, it acts like g_snprintf().
2365 * When processing a packet where the remaining number of bytes is less
2366 * than bufsize, an exception is not thrown if the end of the packet
2367 * is reached before the NUL is found. If no NUL is found before reaching
2368 * the end of the short packet, -1 is still returned, and the string
2369 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
2370 * at the correct spot, terminating the string.
2373 tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer)
2377 return _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
2380 /* Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
2381 * have a terminating NUL. If the string was truncated when copied into buffer,
2382 * a NUL is placed at the end of buffer to terminate it.
2385 tvb_get_nstringz0(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer)
2387 gint len, bytes_copied;
2389 len = _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
2392 buffer[bufsize - 1] = 0;
2393 return bytes_copied - 1;
2401 * Given a tvbuff, an offset into the tvbuff, and a length that starts
2402 * at that offset (which may be -1 for "all the way to the end of the
2403 * tvbuff"), find the end of the (putative) line that starts at the
2404 * specified offset in the tvbuff, going no further than the specified
2407 * Return the length of the line (not counting the line terminator at
2408 * the end), or, if we don't find a line terminator:
2410 * if "deseg" is true, return -1;
2412 * if "deseg" is false, return the amount of data remaining in
2415 * Set "*next_offset" to the offset of the character past the line
2416 * terminator, or past the end of the buffer if we don't find a line
2417 * terminator. (It's not set if we return -1.)
2420 tvb_find_line_end(tvbuff_t *tvb, gint offset, int len, gint *next_offset,
2428 len = tvb_length_remaining(tvb, offset);
2430 * XXX - what if "len" is still -1, meaning "offset is past the
2431 * end of the tvbuff"?
2433 eob_offset = offset + len;
2436 * Look either for a CR or an LF.
2438 eol_offset = tvb_pbrk_guint8(tvb, offset, len, (const guint8 *)"\r\n");
2439 if (eol_offset == -1) {
2441 * No CR or LF - line is presumably continued in next packet.
2445 * Tell our caller we saw no EOL, so they can
2446 * try to desegment and get the entire line
2452 * Pretend the line runs to the end of the tvbuff.
2454 linelen = eob_offset - offset;
2455 *next_offset = eob_offset;
2459 * Find the number of bytes between the starting offset
2462 linelen = eol_offset - offset;
2467 if (tvb_get_guint8(tvb, eol_offset) == '\r') {
2469 * Yes - is it followed by an LF?
2471 if (eol_offset + 1 >= eob_offset) {
2473 * Dunno - the next byte isn't in this
2478 * We'll return -1, although that
2479 * runs the risk that if the line
2480 * really *is* terminated with a CR,
2481 * we won't properly dissect this
2484 * It's probably more likely that
2485 * the line ends with CR-LF than
2486 * that it ends with CR by itself.
2492 * Well, we can at least look at the next
2495 if (tvb_get_guint8(tvb, eol_offset + 1) == '\n') {
2497 * It's an LF; skip over the CR.
2505 * Return the offset of the character after the last
2506 * character in the line, skipping over the last character
2507 * in the line terminator.
2509 *next_offset = eol_offset + 1;
2515 * Given a tvbuff, an offset into the tvbuff, and a length that starts
2516 * at that offset (which may be -1 for "all the way to the end of the
2517 * tvbuff"), find the end of the (putative) line that starts at the
2518 * specified offset in the tvbuff, going no further than the specified
2521 * However, treat quoted strings inside the buffer specially - don't
2522 * treat newlines in quoted strings as line terminators.
2524 * Return the length of the line (not counting the line terminator at
2525 * the end), or the amount of data remaining in the buffer if we don't
2526 * find a line terminator.
2528 * Set "*next_offset" to the offset of the character past the line
2529 * terminator, or past the end of the buffer if we don't find a line
2533 tvb_find_line_end_unquoted(tvbuff_t *tvb, gint offset, int len,
2536 gint cur_offset, char_offset;
2543 len = tvb_length_remaining(tvb, offset);
2545 * XXX - what if "len" is still -1, meaning "offset is past the
2546 * end of the tvbuff"?
2548 eob_offset = offset + len;
2550 cur_offset = offset;
2554 * Is this part of the string quoted?
2558 * Yes - look only for the terminating quote.
2560 char_offset = tvb_find_guint8(tvb, cur_offset, len,
2564 * Look either for a CR, an LF, or a '"'.
2566 char_offset = tvb_pbrk_guint8(tvb, cur_offset, len,
2567 (const guint8 *)"\r\n\"");
2569 if (char_offset == -1) {
2571 * Not found - line is presumably continued in
2573 * We pretend the line runs to the end of the tvbuff.
2575 linelen = eob_offset - offset;
2576 *next_offset = eob_offset;
2582 * We're processing a quoted string.
2583 * We only looked for ", so we know it's a ";
2584 * as we're processing a quoted string, it's a
2592 c = tvb_get_guint8(tvb, char_offset);
2595 * Un-quoted "; it begins a quoted
2601 * It's a CR or LF; we've found a line
2604 * Find the number of bytes between the
2605 * starting offset and the CR or LF.
2607 linelen = char_offset - offset;
2614 * Yes; is it followed by an LF?
2616 if (char_offset + 1 < eob_offset &&
2617 tvb_get_guint8(tvb, char_offset + 1)
2620 * Yes; skip over the CR.
2627 * Return the offset of the character after
2628 * the last character in the line, skipping
2629 * over the last character in the line
2630 * terminator, and quit.
2632 *next_offset = char_offset + 1;
2638 * Step past the character we found.
2640 cur_offset = char_offset + 1;
2641 if (cur_offset >= eob_offset) {
2643 * The character we found was the last character
2644 * in the tvbuff - line is presumably continued in
2646 * We pretend the line runs to the end of the tvbuff.
2648 linelen = eob_offset - offset;
2649 *next_offset = eob_offset;
2657 * Copied from the mgcp dissector. (This function should be moved to /epan )
2658 * tvb_skip_wsp - Returns the position in tvb of the first non-whitespace
2659 * character following offset or offset + maxlength -1 whichever
2663 * tvb - The tvbuff in which we are skipping whitespace.
2664 * offset - The offset in tvb from which we begin trying to skip whitespace.
2665 * maxlength - The maximum distance from offset that we may try to skip
2668 * Returns: The position in tvb of the first non-whitespace
2669 * character following offset or offset + maxlength -1 whichever
2672 gint tvb_skip_wsp(tvbuff_t* tvb, gint offset, gint maxlength)
2674 gint counter = offset;
2675 gint end = offset + maxlength,tvb_len;
2678 /* Get the length remaining */
2679 tvb_len = tvb_length(tvb);
2680 end = offset + maxlength;
2686 /* Skip past spaces, tabs, CRs and LFs until run out or meet something else */
2687 for (counter = offset;
2689 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
2690 tempchar == '\t' || tempchar == '\r' || tempchar == '\n');
2696 gint tvb_skip_wsp_return(tvbuff_t* tvb, gint offset){
2697 gint counter = offset;
2702 for(counter = offset; counter > end &&
2703 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
2704 tempchar == '\t' || tempchar == '\n' || tempchar == '\r'); counter--);
2711 * Format a bunch of data from a tvbuff as bytes, returning a pointer
2712 * to the string with the formatted data, with "punct" as a byte
2716 tvb_bytes_to_str_punct(tvbuff_t *tvb, gint offset, gint len, gchar punct)
2718 return bytes_to_str_punct(tvb_get_ptr(tvb, offset, len), len, punct);
2722 * Format a bunch of data from a tvbuff as bytes, returning a pointer
2723 * to the string with the formatted data.
2726 tvb_bytes_to_str(tvbuff_t *tvb, gint offset, gint len)
2728 return bytes_to_str(tvb_get_ptr(tvb, offset, len), len);
2731 /* Find a needle tvbuff within a haystack tvbuff. */
2733 tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb, gint haystack_offset)
2735 guint haystack_abs_offset, haystack_abs_length;
2736 const guint8 *haystack_data;
2737 const guint8 *needle_data;
2738 const guint needle_len = needle_tvb->length;
2739 const guint8 *location;
2741 if (haystack_tvb->length < 1 || needle_tvb->length < 1) {
2745 /* Get pointers to the tvbuffs' data. */
2746 haystack_data = tvb_get_ptr(haystack_tvb, 0, -1);
2747 needle_data = tvb_get_ptr(needle_tvb, 0, -1);
2749 check_offset_length(haystack_tvb, haystack_offset, -1,
2750 &haystack_abs_offset, &haystack_abs_length);
2752 location = epan_memmem(haystack_data + haystack_abs_offset, haystack_abs_length,
2753 needle_data, needle_len);
2756 return (gint) (location - haystack_data);
2767 * Uncompresses a zlib compressed packet inside a message of tvb at offset with
2768 * length comprlen. Returns an uncompressed tvbuffer if uncompression
2769 * succeeded or NULL if uncompression failed.
2771 #define TVB_Z_MIN_BUFSIZ 32768
2772 #define TVB_Z_MAX_BUFSIZ 1048576 * 10
2773 /* #define TVB_Z_DEBUG 1 */
2777 tvb_uncompress(tvbuff_t *tvb, int offset, int comprlen)
2782 guint bytes_out = 0;
2783 guint8 *compr = NULL;
2784 guint8 *uncompr = NULL;
2785 tvbuff_t *uncompr_tvb = NULL;
2786 z_streamp strm = NULL;
2787 Bytef *strmbuf = NULL;
2788 guint inits_done = 0;
2789 gint wbits = MAX_WBITS;
2790 guint8 *next = NULL;
2791 guint bufsiz = TVB_Z_MIN_BUFSIZ;
2793 guint inflate_passes = 0;
2794 guint bytes_in = tvb_length_remaining(tvb, offset);
2801 strm = g_malloc0(sizeof(z_stream));
2807 compr = tvb_memdup(tvb, offset, comprlen);
2815 * Assume that the uncompressed data is at least twice as big as
2816 * the compressed size.
2818 bufsiz = tvb_length_remaining(tvb, offset) * 2;
2820 if (bufsiz < TVB_Z_MIN_BUFSIZ) {
2821 bufsiz = TVB_Z_MIN_BUFSIZ;
2822 } else if (bufsiz > TVB_Z_MAX_BUFSIZ) {
2823 bufsiz = TVB_Z_MIN_BUFSIZ;
2827 printf("bufsiz: %u bytes\n", bufsiz);
2832 strm->next_in = next;
2833 strm->avail_in = comprlen;
2836 strmbuf = g_malloc0(bufsiz);
2838 if(strmbuf == NULL) {
2844 strm->next_out = strmbuf;
2845 strm->avail_out = bufsiz;
2847 err = inflateInit2(strm, wbits);
2858 memset(strmbuf, '\0', bufsiz);
2859 strm->next_out = strmbuf;
2860 strm->avail_out = bufsiz;
2862 err = inflate(strm, Z_SYNC_FLUSH);
2864 if (err == Z_OK || err == Z_STREAM_END) {
2865 guint bytes_pass = bufsiz - strm->avail_out;
2871 if (uncompr == NULL) {
2872 uncompr = g_memdup(strmbuf, bytes_pass);
2874 guint8 *new_data = g_malloc0(bytes_out +
2877 if (new_data == NULL) {
2883 if (uncompr != NULL) {
2890 g_memmove(new_data, uncompr, bytes_out);
2891 g_memmove((new_data + bytes_out), strmbuf,
2898 bytes_out += bytes_pass;
2900 if ( err == Z_STREAM_END) {
2906 } else if (err == Z_BUF_ERROR) {
2908 * It's possible that not enough frames were captured
2909 * to decompress this fully, so return what we've done
2916 if (uncompr != NULL) {
2923 } else if (err == Z_DATA_ERROR && inits_done == 1
2924 && uncompr == NULL && (*compr == 0x1f) &&
2925 (*(compr + 1) == 0x8b)) {
2927 * inflate() is supposed to handle both gzip and deflate
2928 * streams automatically, but in reality it doesn't
2929 * seem to handle either (at least not within the
2930 * context of an HTTP response.) We have to try
2931 * several tweaks, depending on the type of data and
2932 * version of the library installed.
2936 * Gzip file format. Skip past the header, since the
2937 * fix to make it work (setting windowBits to 31)
2938 * doesn't work with all versions of the library.
2940 Bytef *c = compr + 2;
2943 if (*c == Z_DEFLATED) {
2955 /* Skip past the MTIME, XFL, and OS fields. */
2958 if (flags & (1 << 2)) {
2959 /* An Extra field is present. */
2960 gint xsize = (gint)(*c |
2966 if (flags & (1 << 3)) {
2967 /* A null terminated filename */
2969 while ((c - compr) < comprlen && *c != '\0') {
2976 if (flags & (1 << 4)) {
2977 /* A null terminated comment */
2979 while ((c - compr) < comprlen && *c != '\0') {
2989 strm->next_in = next;
2990 if (c - compr > comprlen) {
2997 comprlen -= (int) (c - compr);
3000 err = inflateInit2(strm, wbits);
3002 } else if (err == Z_DATA_ERROR && uncompr == NULL &&
3006 * Re-init the stream with a negative
3007 * MAX_WBITS. This is necessary due to
3008 * some servers (Apache) not sending
3009 * the deflate header with the
3010 * content-encoded response.
3016 strm->next_in = next;
3017 strm->avail_in = comprlen;
3020 memset(strmbuf, '\0', bufsiz);
3021 strm->next_out = strmbuf;
3022 strm->avail_out = bufsiz;
3024 err = inflateInit2(strm, wbits);
3042 if (uncompr == NULL) {
3051 printf("inflate() total passes: %u\n", inflate_passes);
3052 printf("bytes in: %u\nbytes out: %u\n\n", bytes_in, bytes_out);
3055 if (uncompr != NULL) {
3056 uncompr_tvb = tvb_new_real_data((guint8*) uncompr, bytes_out,
3058 tvb_set_free_cb(uncompr_tvb, g_free);
3065 tvb_uncompress(tvbuff_t *tvb _U_, int offset _U_, int comprlen _U_)
3071 tvbuff_t* tvb_child_uncompress(tvbuff_t *parent _U_, tvbuff_t *tvb, int offset, int comprlen)
3073 tvbuff_t *new_tvb = tvb_uncompress(tvb, offset, comprlen);
3075 tvb_set_child_real_data_tvbuff (parent, new_tvb);