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
12 * $Id: tvbuff.c,v 1.64 2004/05/07 18:15:24 obiot Exp $
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 * Ethereal - Network traffic analyzer
20 * By Gerald Combs <gerald@ethereal.com>
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.
53 ensure_contiguous_no_exception(tvbuff_t *tvb, gint offset, gint length,
57 ensure_contiguous(tvbuff_t *tvb, gint offset, gint length);
59 /* We dole out tvbuff's from this memchunk. */
60 GMemChunk *tvbuff_mem_chunk = NULL;
65 if (!tvbuff_mem_chunk)
66 tvbuff_mem_chunk = g_mem_chunk_create(tvbuff_t, 20, G_ALLOC_AND_FREE);
73 g_mem_chunk_destroy(tvbuff_mem_chunk);
75 tvbuff_mem_chunk = NULL;
82 tvb_init(tvbuff_t *tvb, tvbuff_type type)
84 tvb_backing_t *backing;
85 tvb_comp_t *composite;
88 tvb->initialized = FALSE;
91 tvb->reported_length = 0;
93 tvb->real_data = NULL;
99 case TVBUFF_REAL_DATA:
104 backing = &tvb->tvbuffs.subset;
110 case TVBUFF_COMPOSITE:
111 composite = &tvb->tvbuffs.composite;
112 composite->tvbs = NULL;
113 composite->start_offsets = NULL;
114 composite->end_offsets = NULL;
121 tvb_new(tvbuff_type type)
125 tvb = g_chunk_new(tvbuff_t, tvbuff_mem_chunk);
134 tvb_free(tvbuff_t* tvb)
136 tvbuff_t *member_tvb;
137 tvb_comp_t *composite;
142 if (tvb->usage_count == 0) {
144 case TVBUFF_REAL_DATA:
147 * XXX - do this with a union?
149 tvb->free_cb((gpointer)tvb->real_data);
154 /* This will be NULL if tvb_new_subset() fails because
155 * reported_length < -1 */
156 if (tvb->tvbuffs.subset.tvb) {
157 tvb_decrement_usage_count(tvb->tvbuffs.subset.tvb, 1);
161 case TVBUFF_COMPOSITE:
162 composite = &tvb->tvbuffs.composite;
163 for (slist = composite->tvbs; slist != NULL ; slist = slist->next) {
164 member_tvb = slist->data;
165 tvb_decrement_usage_count(member_tvb, 1);
168 g_slist_free(composite->tvbs);
170 if (composite->start_offsets)
171 g_free(composite->start_offsets);
172 if (composite->end_offsets)
173 g_free(composite->end_offsets);
174 if (tvb->real_data) {
176 * XXX - do this with a union?
178 g_free((gpointer)tvb->real_data);
185 g_slist_free(tvb->used_in);
188 g_chunk_free(tvb, tvbuff_mem_chunk);
193 tvb_increment_usage_count(tvbuff_t* tvb, guint count)
195 tvb->usage_count += count;
197 return tvb->usage_count;
201 tvb_decrement_usage_count(tvbuff_t* tvb, guint count)
203 if (tvb->usage_count <= count) {
204 tvb->usage_count = 1;
209 tvb->usage_count -= count;
210 return tvb->usage_count;
216 tvb_free_chain(tvbuff_t* tvb)
220 /* Recursively call tvb_free_chain() */
221 for (slist = tvb->used_in; slist != NULL ; slist = slist->next) {
222 tvb_free_chain( (tvbuff_t*)slist->data );
225 /* Stop the recursion */
232 tvb_set_free_cb(tvbuff_t* tvb, tvbuff_free_cb_t func)
234 g_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 g_assert(parent->initialized);
249 g_assert(child->initialized);
250 g_assert(child->type == TVBUFF_REAL_DATA);
251 add_to_used_in_list(parent, child);
255 tvb_set_real_data(tvbuff_t* tvb, const guint8* data, guint length, gint reported_length)
257 g_assert(tvb->type == TVBUFF_REAL_DATA);
258 g_assert(!tvb->initialized);
260 if (reported_length < -1) {
261 THROW(ReportedBoundsError);
264 tvb->real_data = data;
265 tvb->length = length;
266 tvb->reported_length = reported_length;
267 tvb->initialized = TRUE;
271 tvb_new_real_data(const guint8* data, guint length, gint reported_length)
273 static tvbuff_t *last_tvb=NULL;
276 tvb = tvb_new(TVBUFF_REAL_DATA);
281 /* remember this tvb in case we throw an exception and
282 * lose the pointer to it.
286 tvb_set_real_data(tvb, data, length, reported_length);
289 * This is the top-level real tvbuff for this data source,
290 * so its data source tvbuff is itself.
294 /* ok no exception so we dont need to remember it any longer */
300 /* Computes the absolute offset and length based on a possibly-negative offset
301 * and a length that is possible -1 (which means "to the end of the data").
302 * Returns TRUE/FALSE indicating whether the offset is in bounds or
303 * not. The integer ptrs are modified with the new offset and length.
304 * No exception is thrown.
306 * XXX - we return TRUE, not FALSE, if the offset is positive and right
307 * after the end of the tvbuff (i.e., equal to the length). We do this
308 * so that a dissector constructing a subset tvbuff for the next protocol
309 * will get a zero-length tvbuff, not an exception, if there's no data
310 * left for the next protocol - we want the next protocol to be the one
311 * that gets an exception, so the error is reported as an error in that
312 * protocol rather than the containing protocol. */
314 compute_offset_length(tvbuff_t *tvb, gint offset, gint length,
315 guint *offset_ptr, guint *length_ptr, int *exception)
317 g_assert(offset_ptr);
318 g_assert(length_ptr);
320 /* Compute the offset */
322 /* Positive offset - relative to the beginning of the packet. */
323 if ((guint) offset > tvb->reported_length) {
325 *exception = ReportedBoundsError;
329 else if ((guint) offset > tvb->length) {
331 *exception = BoundsError;
336 *offset_ptr = offset;
340 /* Negative offset - relative to the end of the packet. */
341 if ((guint) -offset > tvb->reported_length) {
343 *exception = ReportedBoundsError;
347 else if ((guint) -offset > tvb->length) {
349 *exception = BoundsError;
354 *offset_ptr = tvb->length + offset;
358 /* Compute the length */
361 /* XXX - ReportedBoundsError? */
362 *exception = BoundsError;
366 else if (length == -1) {
367 *length_ptr = tvb->length - *offset_ptr;
370 *length_ptr = length;
378 check_offset_length_no_exception(tvbuff_t *tvb, gint offset, gint length,
379 guint *offset_ptr, guint *length_ptr, int *exception)
383 g_assert(tvb->initialized);
385 if (!compute_offset_length(tvb, offset, length, offset_ptr, length_ptr, exception)) {
390 * Compute the offset of the first byte past the length.
392 end_offset = *offset_ptr + *length_ptr;
395 * Check for an overflow, and clamp "end_offset" at the maximum
396 * if we got an overflow - that should force us to indicate that
397 * we're past the end of the tvbuff.
399 if (end_offset < *offset_ptr)
400 end_offset = UINT_MAX;
403 * Check whether that offset goes more than one byte past the
406 * If not, return TRUE; otherwise, return FALSE and, if "exception"
407 * is non-null, return the appropriate exception through it.
409 if (end_offset <= tvb->length) {
412 else if (end_offset <= tvb->reported_length) {
414 *exception = BoundsError;
420 *exception = ReportedBoundsError;
425 g_assert_not_reached();
428 /* Checks (+/-) offset and length and throws an exception if
429 * either is out of bounds. Sets integer ptrs to the new offset
432 check_offset_length(tvbuff_t *tvb, gint offset, gint length,
433 guint *offset_ptr, guint *length_ptr)
437 if (!check_offset_length_no_exception(tvb, offset, length, offset_ptr, length_ptr, &exception)) {
438 g_assert(exception > 0);
446 tvb_set_subset(tvbuff_t *tvb, tvbuff_t *backing,
447 gint backing_offset, gint backing_length, gint reported_length)
449 g_assert(tvb->type == TVBUFF_SUBSET);
450 g_assert(!tvb->initialized);
452 if (reported_length < -1) {
453 THROW(ReportedBoundsError);
456 check_offset_length(backing, backing_offset, backing_length,
457 &tvb->tvbuffs.subset.offset,
458 &tvb->tvbuffs.subset.length);
460 tvb->tvbuffs.subset.tvb = backing;
461 tvb->length = tvb->tvbuffs.subset.length;
463 if (reported_length == -1) {
464 tvb->reported_length = backing->reported_length - tvb->tvbuffs.subset.offset;
467 tvb->reported_length = reported_length;
469 tvb->initialized = TRUE;
470 add_to_used_in_list(backing, tvb);
472 /* Optimization. If the backing buffer has a pointer to contiguous, real data,
473 * then we can point directly to our starting offset in that buffer */
474 if (backing->real_data != NULL) {
475 tvb->real_data = backing->real_data + tvb->tvbuffs.subset.offset;
481 tvb_new_subset(tvbuff_t *backing, gint backing_offset, gint backing_length, gint reported_length)
483 static tvbuff_t *last_tvb=NULL;
486 tvb = tvb_new(TVBUFF_SUBSET);
491 /* remember this tvb in case we throw an exception and
492 * lose the pointer to it.
496 tvb_set_subset(tvb, backing, backing_offset, backing_length, reported_length);
499 * The top-level data source of this tvbuff is the top-level
500 * data source of its parent.
502 tvb->ds_tvb = backing->ds_tvb;
504 /* ok no exception so we dont need to remember it any longer */
511 tvb_composite_append(tvbuff_t* tvb, tvbuff_t* member)
513 tvb_comp_t *composite;
515 g_assert(!tvb->initialized);
516 composite = &tvb->tvbuffs.composite;
517 composite->tvbs = g_slist_append( composite->tvbs, member );
518 add_to_used_in_list(member, tvb);
522 tvb_composite_prepend(tvbuff_t* tvb, tvbuff_t* member)
524 tvb_comp_t *composite;
526 g_assert(!tvb->initialized);
527 composite = &tvb->tvbuffs.composite;
528 composite->tvbs = g_slist_prepend( composite->tvbs, member );
529 add_to_used_in_list(member, tvb);
533 tvb_new_composite(void)
535 return tvb_new(TVBUFF_COMPOSITE);
539 tvb_composite_finalize(tvbuff_t* tvb)
543 tvbuff_t *member_tvb;
544 tvb_comp_t *composite;
547 g_assert(!tvb->initialized);
548 g_assert(tvb->length == 0);
550 composite = &tvb->tvbuffs.composite;
551 num_members = g_slist_length(composite->tvbs);
553 composite->start_offsets = g_new(guint, num_members);
554 composite->end_offsets = g_new(guint, num_members);
556 for (slist = composite->tvbs; slist != NULL; slist = slist->next) {
557 g_assert((guint) i < num_members);
558 member_tvb = slist->data;
559 composite->start_offsets[i] = tvb->length;
560 tvb->length += member_tvb->length;
561 composite->end_offsets[i] = tvb->length - 1;
565 tvb->initialized = TRUE;
571 tvb_length(tvbuff_t* tvb)
573 g_assert(tvb->initialized);
579 tvb_length_remaining(tvbuff_t *tvb, gint offset)
581 guint abs_offset, abs_length;
583 g_assert(tvb->initialized);
585 if (compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL)) {
594 tvb_ensure_length_remaining(tvbuff_t *tvb, gint offset)
596 guint abs_offset, abs_length;
599 g_assert(tvb->initialized);
601 if (!compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, &exception)) {
604 if (abs_length == 0) {
606 * This routine ensures there's at least one byte available.
607 * There aren't any bytes available, so throw the appropriate
610 if (abs_offset >= tvb->reported_length)
611 THROW(ReportedBoundsError);
621 /* Validates that 'length' bytes are available starting from
622 * offset (pos/neg). Does not throw an exception. */
624 tvb_bytes_exist(tvbuff_t *tvb, gint offset, gint length)
626 guint abs_offset, abs_length;
628 g_assert(tvb->initialized);
630 if (!compute_offset_length(tvb, offset, length, &abs_offset, &abs_length, NULL))
633 if (abs_offset + abs_length <= tvb->length) {
641 /* Validates that 'length' bytes are available starting from
642 * offset (pos/neg). Throws an exception if they aren't. */
644 tvb_ensure_bytes_exist(tvbuff_t *tvb, gint offset, gint length)
646 guint abs_offset, abs_length;
648 g_assert(tvb->initialized);
651 * -1 doesn't mean "until end of buffer", as that's pointless
652 * for this routine. We must treat it as a Really Large Positive
653 * Number, so that we throw an exception; we throw
654 * ReportedBoundsError, as if it were past even the end of a
655 * reassembled packet, and past the end of even the data we
658 * We do the same with other negative lengths.
661 THROW(ReportedBoundsError);
663 check_offset_length(tvb, offset, length, &abs_offset, &abs_length);
667 tvb_offset_exists(tvbuff_t *tvb, gint offset)
669 guint abs_offset, abs_length;
671 g_assert(tvb->initialized);
672 if (!compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL))
675 if (abs_offset < tvb->length) {
684 tvb_reported_length(tvbuff_t* tvb)
686 g_assert(tvb->initialized);
688 return tvb->reported_length;
692 tvb_reported_length_remaining(tvbuff_t *tvb, gint offset)
694 guint abs_offset, abs_length;
696 g_assert(tvb->initialized);
698 if (compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL)) {
699 if (tvb->reported_length >= abs_offset)
700 return tvb->reported_length - abs_offset;
709 /* Set the reported length of a tvbuff to a given value; used for protocols
710 whose headers contain an explicit length and where the calling
711 dissector's payload may include padding as well as the packet for
714 Also adjusts the data length. */
716 tvb_set_reported_length(tvbuff_t* tvb, guint reported_length)
718 g_assert(tvb->initialized);
720 if (reported_length > tvb->reported_length)
721 THROW(ReportedBoundsError);
723 tvb->reported_length = reported_length;
724 if (reported_length < tvb->length)
725 tvb->length = reported_length;
730 first_real_data_ptr(tvbuff_t *tvb)
735 case TVBUFF_REAL_DATA:
736 return tvb->real_data;
738 member = tvb->tvbuffs.subset.tvb;
739 return first_real_data_ptr(member);
740 case TVBUFF_COMPOSITE:
741 member = tvb->tvbuffs.composite.tvbs->data;
742 return first_real_data_ptr(member);
745 g_assert_not_reached();
750 offset_from_real_beginning(tvbuff_t *tvb, int counter)
755 case TVBUFF_REAL_DATA:
758 member = tvb->tvbuffs.subset.tvb;
759 return offset_from_real_beginning(member, counter + tvb->tvbuffs.subset.offset);
760 case TVBUFF_COMPOSITE:
761 member = tvb->tvbuffs.composite.tvbs->data;
762 return offset_from_real_beginning(member, counter);
765 g_assert_not_reached();
770 composite_ensure_contiguous_no_exception(tvbuff_t *tvb, guint abs_offset,
773 guint i, num_members;
774 tvb_comp_t *composite;
775 tvbuff_t *member_tvb = NULL;
776 guint member_offset, member_length;
779 g_assert(tvb->type == TVBUFF_COMPOSITE);
781 /* Maybe the range specified by offset/length
782 * is contiguous inside one of the member tvbuffs */
783 composite = &tvb->tvbuffs.composite;
784 num_members = g_slist_length(composite->tvbs);
786 for (i = 0; i < num_members; i++) {
787 if (abs_offset <= composite->end_offsets[i]) {
788 slist = g_slist_nth(composite->tvbs, i);
789 member_tvb = slist->data;
793 g_assert(member_tvb);
795 if (check_offset_length_no_exception(member_tvb, abs_offset - composite->start_offsets[i],
796 abs_length, &member_offset, &member_length, NULL)) {
799 * The range is, in fact, contiguous within member_tvb.
801 g_assert(!tvb->real_data);
802 return ensure_contiguous_no_exception(member_tvb, member_offset, member_length, NULL);
805 tvb->real_data = tvb_memdup(tvb, 0, -1);
806 return tvb->real_data + abs_offset;
809 g_assert_not_reached();
814 ensure_contiguous_no_exception(tvbuff_t *tvb, gint offset, gint length,
817 guint abs_offset, abs_length;
819 if (!check_offset_length_no_exception(tvb, offset, length,
820 &abs_offset, &abs_length, exception)) {
825 * We know that all the data is present in the tvbuff, so
826 * no exceptions should be thrown.
828 if (tvb->real_data) {
829 return tvb->real_data + abs_offset;
833 case TVBUFF_REAL_DATA:
834 g_assert_not_reached();
836 return ensure_contiguous_no_exception(tvb->tvbuffs.subset.tvb,
837 abs_offset - tvb->tvbuffs.subset.offset,
839 case TVBUFF_COMPOSITE:
840 return composite_ensure_contiguous_no_exception(tvb, abs_offset, abs_length);
844 g_assert_not_reached();
849 ensure_contiguous(tvbuff_t *tvb, gint offset, gint length)
854 p = ensure_contiguous_no_exception(tvb, offset, length, &exception);
856 g_assert(exception > 0);
863 guint8_find(const guint8* haystack, size_t haystacklen, guint8 needle)
868 for (b = haystack, i = 0; (guint) i < haystacklen; i++, b++) {
878 guint8_pbrk(const guint8* haystack, size_t haystacklen, guint8 *needles)
882 guint8 item, *needlep, needle;
884 for (b = haystack, i = 0; (guint) i < haystacklen; i++, b++) {
887 while ((needle = *needlep) != '\0') {
899 /************** ACCESSORS **************/
902 composite_memcpy(tvbuff_t *tvb, guint8* target, guint abs_offset, guint abs_length)
904 guint i, num_members;
905 tvb_comp_t *composite;
906 tvbuff_t *member_tvb = NULL;
907 guint member_offset, member_length;
911 g_assert(tvb->type == TVBUFF_COMPOSITE);
913 /* Maybe the range specified by offset/length
914 * is contiguous inside one of the member tvbuffs */
915 composite = &tvb->tvbuffs.composite;
916 num_members = g_slist_length(composite->tvbs);
918 for (i = 0; i < num_members; i++) {
919 if (abs_offset <= composite->end_offsets[i]) {
920 slist = g_slist_nth(composite->tvbs, i);
921 member_tvb = slist->data;
925 g_assert(member_tvb);
927 if (check_offset_length_no_exception(member_tvb, abs_offset - composite->start_offsets[i],
928 abs_length, &member_offset, &member_length, NULL)) {
930 g_assert(!tvb->real_data);
931 return tvb_memcpy(member_tvb, target, member_offset, member_length);
934 /* The requested data is non-contiguous inside
935 * the member tvb. We have to memcpy() the part that's in the member tvb,
936 * then iterate across the other member tvb's, copying their portions
937 * until we have copied all data.
939 retval = compute_offset_length(member_tvb, abs_offset - composite->start_offsets[i], -1,
940 &member_offset, &member_length, NULL);
943 tvb_memcpy(member_tvb, target, member_offset, member_length);
944 abs_offset += member_length;
945 abs_length -= member_length;
948 if (abs_length > 0) {
949 composite_memcpy(tvb, target + member_length, abs_offset, abs_length);
955 g_assert_not_reached();
960 tvb_memcpy(tvbuff_t *tvb, guint8* target, gint offset, gint length)
962 guint abs_offset, abs_length;
964 g_assert(length >= -1);
965 check_offset_length(tvb, offset, length, &abs_offset, &abs_length);
967 if (tvb->real_data) {
968 return (guint8*) memcpy(target, tvb->real_data + abs_offset, abs_length);
972 case TVBUFF_REAL_DATA:
973 g_assert_not_reached();
976 return tvb_memcpy(tvb->tvbuffs.subset.tvb, target,
977 abs_offset - tvb->tvbuffs.subset.offset,
980 case TVBUFF_COMPOSITE:
981 return composite_memcpy(tvb, target, offset, length);
984 g_assert_not_reached();
990 * XXX - this doesn't treat a length of -1 as an error.
991 * If it did, this could replace some code that calls
992 * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies
995 * "composite_ensure_contiguous_no_exception()" depends on -1 not being
996 * an error; does anything else depend on this routine treating -1 as
997 * meaning "to the end of the buffer"?
1000 tvb_memdup(tvbuff_t *tvb, gint offset, gint length)
1002 guint abs_offset, abs_length;
1005 check_offset_length(tvb, offset, length, &abs_offset, &abs_length);
1007 duped = g_malloc(abs_length);
1008 return tvb_memcpy(tvb, duped, abs_offset, abs_length);
1014 tvb_get_ptr(tvbuff_t *tvb, gint offset, gint length)
1016 return ensure_contiguous(tvb, offset, length);
1020 tvb_get_guint8(tvbuff_t *tvb, gint offset)
1024 ptr = ensure_contiguous(tvb, offset, sizeof(guint8));
1029 tvb_get_ntohs(tvbuff_t *tvb, gint offset)
1033 ptr = ensure_contiguous(tvb, offset, sizeof(guint16));
1038 tvb_get_ntoh24(tvbuff_t *tvb, gint offset)
1042 ptr = ensure_contiguous(tvb, offset, 3);
1043 return pntoh24(ptr);
1047 tvb_get_ntohl(tvbuff_t *tvb, gint offset)
1051 ptr = ensure_contiguous(tvb, offset, sizeof(guint32));
1056 * Stuff for IEEE float handling on platforms that don't have IEEE
1057 * format as the native floating-point format.
1059 * For now, we treat only the VAX as such a platform.
1061 * XXX - other non-IEEE boxes that can run UNIX include some Crays,
1062 * and possibly other machines.
1064 * It appears that the official Linux port to System/390 and
1065 * zArchitecture uses IEEE format floating point (not a
1068 * I don't know whether there are any other machines that
1069 * could run Ethereal and that don't use IEEE format.
1070 * As far as I know, all of the main commercial microprocessor
1071 * families on which OSes that support Ethereal can run
1072 * use IEEE format (x86, 68k, SPARC, MIPS, PA-RISC, Alpha,
1073 * IA-64, and so on).
1083 #define IEEE_SP_NUMBER_WIDTH 32 /* bits in number */
1084 #define IEEE_SP_EXP_WIDTH 8 /* bits in exponent */
1085 #define IEEE_SP_MANTISSA_WIDTH 23 /* IEEE_SP_NUMBER_WIDTH - 1 - IEEE_SP_EXP_WIDTH */
1087 #define IEEE_SP_SIGN_MASK 0x80000000
1088 #define IEEE_SP_EXPONENT_MASK 0x7F800000
1089 #define IEEE_SP_MANTISSA_MASK 0x007FFFFF
1090 #define IEEE_SP_INFINITY IEEE_SP_EXPONENT_MASK
1092 #define IEEE_SP_IMPLIED_BIT (1 << IEEE_SP_MANTISSA_WIDTH)
1093 #define IEEE_SP_INFINITE ((1 << IEEE_SP_EXP_WIDTH) - 1)
1094 #define IEEE_SP_BIAS ((1 << (IEEE_SP_EXP_WIDTH - 1)) - 1)
1097 ieee_float_is_zero(guint32 w)
1099 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1103 get_ieee_float(guint32 w)
1109 sign = w & IEEE_SP_SIGN_MASK;
1110 exponent = w & IEEE_SP_EXPONENT_MASK;
1111 mantissa = w & IEEE_SP_MANTISSA_MASK;
1113 if (ieee_float_is_zero(w)) {
1114 /* number is zero, unnormalized, or not-a-number */
1119 * XXX - how to handle this?
1121 if (IEEE_SP_INFINITY == exponent) {
1123 * number is positive or negative infinity, or a special value
1125 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1129 exponent = ((exponent >> IEEE_SP_MANTISSA_WIDTH) - IEEE_SP_BIAS) -
1130 IEEE_SP_MANTISSA_WIDTH;
1131 mantissa |= IEEE_SP_IMPLIED_BIT;
1134 return -mantissa * pow(2, exponent);
1136 return mantissa * pow(2, exponent);
1141 * We assume that if you don't have IEEE floating-point, you have a
1142 * compiler that understands 64-bit integral quantities.
1144 #define IEEE_DP_NUMBER_WIDTH 64 /* bits in number */
1145 #define IEEE_DP_EXP_WIDTH 11 /* bits in exponent */
1146 #define IEEE_DP_MANTISSA_WIDTH 52 /* IEEE_DP_NUMBER_WIDTH - 1 - IEEE_DP_EXP_WIDTH */
1148 #define IEEE_DP_SIGN_MASK 0x8000000000000000LL
1149 #define IEEE_DP_EXPONENT_MASK 0x7FF0000000000000LL
1150 #define IEEE_DP_MANTISSA_MASK 0x000FFFFFFFFFFFFFLL
1151 #define IEEE_DP_INFINITY IEEE_DP_EXPONENT_MASK
1153 #define IEEE_DP_IMPLIED_BIT (1LL << IEEE_DP_MANTISSA_WIDTH)
1154 #define IEEE_DP_INFINITE ((1 << IEEE_DP_EXP_WIDTH) - 1)
1155 #define IEEE_DP_BIAS ((1 << (IEEE_DP_EXP_WIDTH - 1)) - 1)
1158 ieee_double_is_zero(guint64 w)
1160 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1164 get_ieee_double(guint64 w)
1170 sign = w & IEEE_DP_SIGN_MASK;
1171 exponent = w & IEEE_DP_EXPONENT_MASK;
1172 mantissa = w & IEEE_DP_MANTISSA_MASK;
1174 if (ieee_double_is_zero(w)) {
1175 /* number is zero, unnormalized, or not-a-number */
1180 * XXX - how to handle this?
1182 if (IEEE_DP_INFINITY == exponent) {
1184 * number is positive or negative infinity, or a special value
1186 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1190 exponent = ((exponent >> IEEE_DP_MANTISSA_WIDTH) - IEEE_DP_BIAS) -
1191 IEEE_DP_MANTISSA_WIDTH;
1192 mantissa |= IEEE_DP_IMPLIED_BIT;
1195 return -mantissa * pow(2, exponent);
1197 return mantissa * pow(2, exponent);
1202 * Fetches an IEEE single-precision floating-point number, in
1203 * big-endian form, and returns a "float".
1205 * XXX - should this be "double", in case there are IEEE single-
1206 * precision numbers that won't fit in some platform's native
1210 tvb_get_ntohieee_float(tvbuff_t *tvb, int offset)
1213 return get_ieee_float(tvb_get_ntohl(tvb, offset));
1220 ieee_fp_union.w = tvb_get_ntohl(tvb, offset);
1221 return ieee_fp_union.f;
1226 * Fetches an IEEE double-precision floating-point number, in
1227 * big-endian form, and returns a "double".
1230 tvb_get_ntohieee_double(tvbuff_t *tvb, int offset)
1244 #ifdef WORDS_BIGENDIAN
1245 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset);
1246 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset+4);
1248 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset+4);
1249 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset);
1252 return get_ieee_double(ieee_fp_union.dw);
1254 return ieee_fp_union.d;
1259 tvb_get_letohs(tvbuff_t *tvb, gint offset)
1263 ptr = ensure_contiguous(tvb, offset, sizeof(guint16));
1264 return pletohs(ptr);
1268 tvb_get_letoh24(tvbuff_t *tvb, gint offset)
1272 ptr = ensure_contiguous(tvb, offset, 3);
1273 return pletoh24(ptr);
1277 tvb_get_letohl(tvbuff_t *tvb, gint offset)
1281 ptr = ensure_contiguous(tvb, offset, sizeof(guint32));
1282 return pletohl(ptr);
1286 * Fetches an IEEE single-precision floating-point number, in
1287 * little-endian form, and returns a "float".
1289 * XXX - should this be "double", in case there are IEEE single-
1290 * precision numbers that won't fit in some platform's native
1294 tvb_get_letohieee_float(tvbuff_t *tvb, int offset)
1297 return get_ieee_float(tvb_get_letohl(tvb, offset));
1304 ieee_fp_union.w = tvb_get_letohl(tvb, offset);
1305 return ieee_fp_union.f;
1310 * Fetches an IEEE double-precision floating-point number, in
1311 * little-endian form, and returns a "double".
1314 tvb_get_letohieee_double(tvbuff_t *tvb, int offset)
1328 #ifdef WORDS_BIGENDIAN
1329 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset+4);
1330 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset);
1332 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset);
1333 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset+4);
1336 return get_ieee_double(ieee_fp_union.dw);
1338 return ieee_fp_union.d;
1342 /* Find first occurence of needle in tvbuff, starting at offset. Searches
1343 * at most maxlength number of bytes; if maxlength is -1, searches to
1345 * Returns the offset of the found needle, or -1 if not found.
1346 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1347 * in that case, -1 will be returned if the boundary is reached before
1348 * finding needle. */
1350 tvb_find_guint8(tvbuff_t *tvb, gint offset, gint maxlength, guint8 needle)
1352 const guint8 *result;
1353 guint abs_offset, junk_length;
1357 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1359 /* Only search to end of tvbuff, w/o throwing exception. */
1360 tvbufflen = tvb_length_remaining(tvb, abs_offset);
1361 if (maxlength == -1) {
1362 /* No maximum length specified; search to end of tvbuff. */
1365 else if (tvbufflen < (guint) maxlength) {
1366 /* Maximum length goes past end of tvbuff; search to end
1371 /* Maximum length doesn't go past end of tvbuff; search
1376 /* If we have real data, perform our search now. */
1377 if (tvb->real_data) {
1378 result = guint8_find(tvb->real_data + abs_offset, limit, needle);
1379 if (result == NULL) {
1383 return result - tvb->real_data;
1388 case TVBUFF_REAL_DATA:
1389 g_assert_not_reached();
1392 return tvb_find_guint8(tvb->tvbuffs.subset.tvb,
1393 abs_offset - tvb->tvbuffs.subset.offset,
1396 case TVBUFF_COMPOSITE:
1397 g_assert_not_reached();
1398 /* XXX - return composite_find_guint8(tvb, offset, limit, needle); */
1401 g_assert_not_reached();
1405 /* Find first occurence of any of the needles in tvbuff, starting at offset.
1406 * Searches at most maxlength number of bytes; if maxlength is -1, searches
1408 * Returns the offset of the found needle, or -1 if not found.
1409 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1410 * in that case, -1 will be returned if the boundary is reached before
1411 * finding needle. */
1413 tvb_pbrk_guint8(tvbuff_t *tvb, gint offset, gint maxlength, guint8 *needles)
1415 const guint8 *result;
1416 guint abs_offset, junk_length;
1420 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1422 /* Only search to end of tvbuff, w/o throwing exception. */
1423 tvbufflen = tvb_length_remaining(tvb, abs_offset);
1424 if (maxlength == -1) {
1425 /* No maximum length specified; search to end of tvbuff. */
1428 else if (tvbufflen < (guint) maxlength) {
1429 /* Maximum length goes past end of tvbuff; search to end
1434 /* Maximum length doesn't go past end of tvbuff; search
1439 /* If we have real data, perform our search now. */
1440 if (tvb->real_data) {
1441 result = guint8_pbrk(tvb->real_data + abs_offset, limit, needles);
1442 if (result == NULL) {
1446 return result - tvb->real_data;
1451 case TVBUFF_REAL_DATA:
1452 g_assert_not_reached();
1455 return tvb_pbrk_guint8(tvb->tvbuffs.subset.tvb,
1456 abs_offset - tvb->tvbuffs.subset.offset,
1459 case TVBUFF_COMPOSITE:
1460 g_assert_not_reached();
1461 /* XXX - return composite_pbrk_guint8(tvb, offset, limit, needle); */
1464 g_assert_not_reached();
1468 /* Find size of stringz (NUL-terminated string) by looking for terminating
1469 * NUL. The size of the string includes the terminating NUL.
1471 * If the NUL isn't found, it throws the appropriate exception.
1474 tvb_strsize(tvbuff_t *tvb, gint offset)
1476 guint abs_offset, junk_length;
1479 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1480 nul_offset = tvb_find_guint8(tvb, abs_offset, -1, 0);
1481 if (nul_offset == -1) {
1483 * OK, we hit the end of the tvbuff, so we should throw
1486 * Did we hit the end of the captured data, or the end
1487 * of the actual data? If there's less captured data
1488 * than actual data, we presumably hit the end of the
1489 * captured data, otherwise we hit the end of the actual
1492 if (tvb_length(tvb) < tvb_reported_length(tvb)) {
1495 THROW(ReportedBoundsError);
1498 return (nul_offset - abs_offset) + 1;
1501 /* Find length of string by looking for end of string ('\0'), up to
1502 * 'maxlength' characters'; if 'maxlength' is -1, searches to end
1504 * Returns -1 if 'maxlength' reached before finding EOS. */
1506 tvb_strnlen(tvbuff_t *tvb, gint offset, guint maxlength)
1509 guint abs_offset, junk_length;
1511 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1513 result_offset = tvb_find_guint8(tvb, abs_offset, maxlength, 0);
1515 if (result_offset == -1) {
1519 return result_offset - abs_offset;
1524 * Implement strneql etc
1528 * Call strncmp after checking if enough chars left, returning 0 if
1529 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1532 tvb_strneql(tvbuff_t *tvb, gint offset, const gchar *str, gint size)
1536 ptr = ensure_contiguous_no_exception(tvb, offset, size, NULL);
1539 int cmp = strncmp((const char *)ptr, str, size);
1542 * Return 0 if equal, -1 otherwise.
1544 return (cmp == 0 ? 0 : -1);
1547 * Not enough characters in the tvbuff to match the
1555 * Call strncasecmp after checking if enough chars left, returning 0 if
1556 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1559 tvb_strncaseeql(tvbuff_t *tvb, gint offset, const gchar *str, gint size)
1563 ptr = ensure_contiguous_no_exception(tvb, offset, size, NULL);
1566 int cmp = strncasecmp((const char *)ptr, str, size);
1569 * Return 0 if equal, -1 otherwise.
1571 return (cmp == 0 ? 0 : -1);
1574 * Not enough characters in the tvbuff to match the
1582 * Call memcmp after checking if enough chars left, returning 0 if
1583 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1586 tvb_memeql(tvbuff_t *tvb, gint offset, const guint8 *str, gint size)
1590 ptr = ensure_contiguous_no_exception(tvb, offset, size, NULL);
1593 int cmp = memcmp(ptr, str, size);
1596 * Return 0 if equal, -1 otherwise.
1598 return (cmp == 0 ? 0 : -1);
1601 * Not enough characters in the tvbuff to match the
1608 /* Convert a string from Unicode to ASCII. At the moment we fake it by
1609 * assuming all characters are ASCII )-: The caller must free the
1610 * result returned. The len parameter is the number of guint16's to
1611 * convert from Unicode. */
1613 tvb_fake_unicode(tvbuff_t *tvb, int offset, int len, gboolean little_endian)
1619 /* Make sure we have enough data before allocating the buffer,
1620 so we don't blow up if the length is huge. */
1621 tvb_ensure_bytes_exist(tvb, offset, 2*len);
1623 /* We know we won't throw an exception, so we don't have to worry
1624 about leaking this buffer. */
1625 buffer = g_malloc(len + 1);
1627 for (i = 0; i < len; i++) {
1628 character = little_endian ? tvb_get_letohs(tvb, offset)
1629 : tvb_get_ntohs(tvb, offset);
1630 buffer[i] = character & 0xff;
1640 * Format the data in the tvb from offset for length ...
1644 tvb_format_text(tvbuff_t *tvb, gint offset, gint size)
1649 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
1651 len = tvb_length_remaining(tvb, offset);
1652 ptr = ensure_contiguous(tvb, offset, len);
1656 return format_text(ptr, len);
1661 * Like "tvb_format_text()", but for null-padded strings; don't show
1662 * the null padding characters as "\000".
1665 tvb_format_stringzpad(tvbuff_t *tvb, gint offset, gint size)
1667 const guint8 *ptr, *p;
1671 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
1673 len = tvb_length_remaining(tvb, offset);
1674 ptr = ensure_contiguous(tvb, offset, len);
1678 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
1680 return format_text(ptr, stringlen);
1685 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
1686 * to hold a non-null-terminated string of that length at that offset,
1687 * plus a trailing '\0', copy the string into it, and return a pointer
1690 * Throws an exception if the tvbuff ends before the string does.
1693 tvb_get_string(tvbuff_t *tvb, gint offset, gint length)
1698 ptr = ensure_contiguous(tvb, offset, length);
1699 strbuf = g_malloc(length + 1);
1701 memcpy(strbuf, ptr, length);
1702 strbuf[length] = '\0';
1707 * Given a tvbuff and an offset, with the offset assumed to refer to
1708 * a null-terminated string, find the length of that string (and throw
1709 * an exception if the tvbuff ends before we find the null), allocate
1710 * a buffer big enough to hold the string, copy the string into it,
1711 * and return a pointer to the string. Also return the length of the
1712 * string (including the terminating null) through a pointer.
1715 tvb_get_stringz(tvbuff_t *tvb, gint offset, gint *lengthp)
1720 size = tvb_strsize(tvb, offset);
1721 strptr = g_malloc(size);
1722 tvb_memcpy(tvb, strptr, offset, size);
1727 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
1728 * no more than bufsize number of bytes, including terminating NUL, to buffer.
1729 * Returns length of string (not including terminating NUL), or -1 if the string was
1730 * truncated in the buffer due to not having reached the terminating NUL.
1731 * In this way, it acts like snprintf().
1733 * bufsize MUST be greater than 0.
1735 * When processing a packet where the remaining number of bytes is less
1736 * than bufsize, an exception is not thrown if the end of the packet
1737 * is reached before the NUL is found. If no NUL is found before reaching
1738 * the end of the short packet, -1 is still returned, and the string
1739 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
1740 * at the correct spot, terminating the string.
1742 * *bytes_copied will contain the number of bytes actually copied,
1743 * including the terminating-NUL.
1746 _tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer,
1750 guint abs_offset, junk_length;
1752 gboolean decreased_max = FALSE;
1754 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1756 /* There must at least be room for the terminating NUL. */
1757 g_assert(bufsize != 0);
1759 /* If there's no room for anything else, just return the NUL. */
1766 /* Only read to end of tvbuff, w/o throwing exception. */
1767 len = tvb_length_remaining(tvb, abs_offset);
1769 /* check_offset_length() won't throw an exception if we're
1770 * looking at the byte immediately after the end of the tvbuff. */
1772 THROW(ReportedBoundsError);
1775 /* This should not happen because check_offset_length() would
1776 * have already thrown an exception if 'offset' were out-of-bounds.
1778 g_assert(len != -1);
1781 * If we've been passed a negative number, bufsize will
1784 g_assert(bufsize <= G_MAXINT);
1786 if ((guint)len < bufsize) {
1788 decreased_max = TRUE;
1794 stringlen = tvb_strnlen(tvb, abs_offset, limit - 1);
1795 /* If NUL wasn't found, copy the data and return -1 */
1796 if (stringlen == -1) {
1797 tvb_memcpy(tvb, buffer, abs_offset, limit);
1798 if (decreased_max) {
1800 /* Add 1 for the extra NUL that we set at buffer[limit],
1801 * pretending that it was copied as part of the string. */
1802 *bytes_copied = limit + 1;
1805 *bytes_copied = limit;
1810 /* Copy the string to buffer */
1811 tvb_memcpy(tvb, buffer, abs_offset, stringlen + 1);
1812 *bytes_copied = stringlen + 1;
1816 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
1817 * no more than bufsize number of bytes, including terminating NUL, to buffer.
1818 * Returns length of string (not including terminating NUL), or -1 if the string was
1819 * truncated in the buffer due to not having reached the terminating NUL.
1820 * In this way, it acts like snprintf().
1822 * When processing a packet where the remaining number of bytes is less
1823 * than bufsize, an exception is not thrown if the end of the packet
1824 * is reached before the NUL is found. If no NUL is found before reaching
1825 * the end of the short packet, -1 is still returned, and the string
1826 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
1827 * at the correct spot, terminating the string.
1830 tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer)
1834 return _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
1837 /* Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
1838 * have a terminating NUL. If the string was truncated when copied into buffer,
1839 * a NUL is placed at the end of buffer to terminate it.
1842 tvb_get_nstringz0(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer)
1844 gint len, bytes_copied;
1846 len = _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
1849 buffer[bufsize - 1] = 0;
1850 return bytes_copied - 1;
1858 * Given a tvbuff, an offset into the tvbuff, and a length that starts
1859 * at that offset (which may be -1 for "all the way to the end of the
1860 * tvbuff"), find the end of the (putative) line that starts at the
1861 * specified offset in the tvbuff, going no further than the specified
1864 * Return the length of the line (not counting the line terminator at
1865 * the end), or, if we don't find a line terminator:
1867 * if "deseg" is true, return -1;
1869 * if "deseg" is false, return the amount of data remaining in
1872 * Set "*next_offset" to the offset of the character past the line
1873 * terminator, or past the end of the buffer if we don't find a line
1874 * terminator. (It's not set if we return -1.)
1877 tvb_find_line_end(tvbuff_t *tvb, gint offset, int len, gint *next_offset,
1885 len = tvb_length_remaining(tvb, offset);
1887 * XXX - what if "len" is still -1, meaning "offset is past the
1888 * end of the tvbuff"?
1890 eob_offset = offset + len;
1893 * Look either for a CR or an LF.
1895 eol_offset = tvb_pbrk_guint8(tvb, offset, len, (guint8 *)"\r\n");
1896 if (eol_offset == -1) {
1898 * No CR or LF - line is presumably continued in next packet.
1902 * Tell our caller we saw no EOL, so they can
1903 * try to desegment and get the entire line
1909 * Pretend the line runs to the end of the tvbuff.
1911 linelen = eob_offset - offset;
1912 *next_offset = eob_offset;
1916 * Find the number of bytes between the starting offset
1919 linelen = eol_offset - offset;
1924 if (tvb_get_guint8(tvb, eol_offset) == '\r') {
1926 * Yes - is it followed by an LF?
1928 if (eol_offset + 1 >= eob_offset) {
1930 * Dunno - the next byte isn't in this
1935 * We'll return -1, although that
1936 * runs the risk that if the line
1937 * really *is* terminated with a CR,
1938 * we won't properly dissect this
1941 * It's probably more likely that
1942 * the line ends with CR-LF than
1943 * that it ends with CR by itself.
1949 * Well, we can at least look at the next
1952 if (tvb_get_guint8(tvb, eol_offset + 1) == '\n') {
1954 * It's an LF; skip over the CR.
1962 * Return the offset of the character after the last
1963 * character in the line, skipping over the last character
1964 * in the line terminator.
1966 *next_offset = eol_offset + 1;
1972 * Given a tvbuff, an offset into the tvbuff, and a length that starts
1973 * at that offset (which may be -1 for "all the way to the end of the
1974 * tvbuff"), find the end of the (putative) line that starts at the
1975 * specified offset in the tvbuff, going no further than the specified
1978 * However, treat quoted strings inside the buffer specially - don't
1979 * treat newlines in quoted strings as line terminators.
1981 * Return the length of the line (not counting the line terminator at
1982 * the end), or the amount of data remaining in the buffer if we don't
1983 * find a line terminator.
1985 * Set "*next_offset" to the offset of the character past the line
1986 * terminator, or past the end of the buffer if we don't find a line
1990 tvb_find_line_end_unquoted(tvbuff_t *tvb, gint offset, int len,
1993 gint cur_offset, char_offset;
2000 len = tvb_length_remaining(tvb, offset);
2002 * XXX - what if "len" is still -1, meaning "offset is past the
2003 * end of the tvbuff"?
2005 eob_offset = offset + len;
2007 cur_offset = offset;
2011 * Is this part of the string quoted?
2015 * Yes - look only for the terminating quote.
2017 char_offset = tvb_find_guint8(tvb, cur_offset, len,
2021 * Look either for a CR, an LF, or a '"'.
2023 char_offset = tvb_pbrk_guint8(tvb, cur_offset, len,
2024 (guint8 *)"\r\n\"");
2026 if (char_offset == -1) {
2028 * Not found - line is presumably continued in
2030 * We pretend the line runs to the end of the tvbuff.
2032 linelen = eob_offset - offset;
2033 *next_offset = eob_offset;
2039 * We're processing a quoted string.
2040 * We only looked for ", so we know it's a ";
2041 * as we're processing a quoted string, it's a
2049 c = tvb_get_guint8(tvb, char_offset);
2052 * Un-quoted "; it begins a quoted
2058 * It's a CR or LF; we've found a line
2061 * Find the number of bytes between the
2062 * starting offset and the CR or LF.
2064 linelen = char_offset - offset;
2071 * Yes; is it followed by an LF?
2073 if (char_offset + 1 < eob_offset &&
2074 tvb_get_guint8(tvb, char_offset + 1)
2077 * Yes; skip over the CR.
2084 * Return the offset of the character after
2085 * the last character in the line, skipping
2086 * over the last character in the line
2087 * terminator, and quit.
2089 *next_offset = char_offset + 1;
2095 * Step past the character we found.
2097 cur_offset = char_offset + 1;
2098 if (cur_offset >= eob_offset) {
2100 * The character we found was the last character
2101 * in the tvbuff - line is presumably continued in
2103 * We pretend the line runs to the end of the tvbuff.
2105 linelen = eob_offset - offset;
2106 *next_offset = eob_offset;
2114 * Format a bunch of data from a tvbuff as bytes, returning a pointer
2115 * to the string with the formatted data.
2118 tvb_bytes_to_str(tvbuff_t *tvb, gint offset, gint len)
2120 return bytes_to_str(tvb_get_ptr(tvb, offset, len), len);
2123 /* Find a needle tvbuff within a haystack tvbuff. */
2125 tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb, gint haystack_offset)
2127 guint haystack_abs_offset, haystack_abs_length;
2128 const guint8 *haystack_data;
2129 const guint8 *needle_data;
2130 const guint needle_len = needle_tvb->length;
2131 const guint8 *location;
2133 if (haystack_tvb->length < 1 || needle_tvb->length < 1) {
2137 /* Get pointers to the tvbuffs' data. */
2138 haystack_data = tvb_get_ptr(haystack_tvb, 0, -1);
2139 needle_data = tvb_get_ptr(needle_tvb, 0, -1);
2141 check_offset_length(haystack_tvb, haystack_offset, -1,
2142 &haystack_abs_offset, &haystack_abs_length);
2144 location = epan_memmem(haystack_data + haystack_abs_offset, haystack_abs_length,
2145 needle_data, needle_len);
2148 return location - haystack_data;
2159 * Uncompresses a zlib compressed packet inside a message of tvb at offset with
2160 * length comprlen. Returns an uncompressed tvbuffer if uncompression
2161 * succeeded or NULL if uncompression failed.
2163 #define TVB_Z_BUFSIZ 4096
2165 tvb_uncompress(tvbuff_t *tvb, int offset, int comprlen)
2171 guint8 *compr = NULL;
2172 guint8 *uncompr = NULL;
2173 tvbuff_t *uncompr_tvb = NULL;
2174 z_streamp strm = NULL;
2175 gchar strmbuf[TVB_Z_BUFSIZ];
2176 gint inits_done = 0;
2177 gint wbits = MAX_WBITS;
2178 guint8 *next = NULL;
2180 strm = g_malloc0(sizeof(z_stream));
2186 compr = tvb_memdup(tvb, offset, comprlen);
2194 strm->next_in = next;
2195 strm->avail_in = comprlen;
2197 memset(&strmbuf, 0, TVB_Z_BUFSIZ);
2198 strm->next_out = (Bytef *)&strmbuf;
2199 strm->avail_out = TVB_Z_BUFSIZ;
2201 err = inflateInit2(strm, wbits);
2210 memset(&strmbuf, 0, TVB_Z_BUFSIZ);
2211 strm->next_out = (Bytef *)&strmbuf;
2212 strm->avail_out = TVB_Z_BUFSIZ;
2214 err = inflate(strm, Z_SYNC_FLUSH);
2216 if (err == Z_OK || err == Z_STREAM_END) {
2217 guint bytes_pass = TVB_Z_BUFSIZ - strm->avail_out;
2219 if (uncompr == NULL) {
2220 uncompr = g_memdup(&strmbuf, bytes_pass);
2222 guint8 *new_data = g_malloc0(bytes_out +
2225 if (new_data == NULL) {
2229 if (uncompr != NULL) {
2236 g_memmove(new_data, uncompr, bytes_out);
2237 g_memmove((new_data + bytes_out), &strmbuf,
2244 bytes_out += bytes_pass;
2246 if ( err == Z_STREAM_END) {
2251 } else if (err == Z_BUF_ERROR) {
2253 * It's possible that not enough frames were captured
2254 * to decompress this fully, so return what we've done
2260 if (uncompr != NULL) {
2267 } else if (err == Z_DATA_ERROR && inits_done == 1
2268 && uncompr == NULL && (*compr == 0x1f) &&
2269 (*(compr + 1) == 0x8b)) {
2271 * inflate() is supposed to handle both gzip and deflate
2272 * streams automatically, but in reality it doesn't
2273 * seem to handle either (at least not within the
2274 * context of an HTTP response.) We have to try
2275 * several tweaks, depending on the type of data and
2276 * version of the library installed.
2280 * Gzip file format. Skip past the header, since the
2281 * fix to make it work (setting windowBits to 31)
2282 * doesn't work with all versions of the library.
2284 Bytef *c = compr + 2;
2287 if (*c == Z_DEFLATED) {
2297 /* Skip past the MTIME, XFL, and OS fields. */
2301 /* An Extra field is present. */
2302 gint xsize = (gint)(*c |
2309 /* A null terminated filename */
2311 while (*c != '\0') {
2319 /* A null terminated comment */
2321 while (*c != '\0') {
2331 strm->next_in = next;
2332 comprlen -= (c - compr);
2334 err = inflateInit2(strm, wbits);
2336 } else if (err == Z_DATA_ERROR && uncompr == NULL &&
2340 * Re-init the stream with a negative
2341 * MAX_WBITS. This is necessary due to
2342 * some servers (Apache) not sending
2343 * the deflate header with the
2344 * content-encoded response.
2350 strm->next_in = next;
2351 strm->avail_in = comprlen;
2353 memset(&strmbuf, 0, TVB_Z_BUFSIZ);
2354 strm->next_out = (Bytef *)&strmbuf;
2355 strm->avail_out = TVB_Z_BUFSIZ;
2357 err = inflateInit2(strm, wbits);
2372 if (uncompr == NULL) {
2380 if (uncompr != NULL) {
2381 uncompr_tvb = tvb_new_real_data((guint8*) uncompr, bytes_out,
2383 tvb_set_free_cb(uncompr_tvb, g_free);
2390 tvb_uncompress(tvbuff_t *tvb _U_, int offset _U_, int comprlen _U_)