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 if (composite->start_offsets)
172 g_free(composite->start_offsets);
173 if (composite->end_offsets)
174 g_free(composite->end_offsets);
175 if (tvb->real_data) {
177 * XXX - do this with a union?
179 g_free((gpointer)tvb->real_data);
186 g_slist_free(tvb->used_in);
189 g_chunk_free(tvb, tvbuff_mem_chunk);
194 tvb_increment_usage_count(tvbuff_t* tvb, guint count)
196 tvb->usage_count += count;
198 return tvb->usage_count;
202 tvb_decrement_usage_count(tvbuff_t* tvb, guint count)
204 if (tvb->usage_count <= count) {
205 tvb->usage_count = 1;
210 tvb->usage_count -= count;
211 return tvb->usage_count;
217 tvb_free_chain(tvbuff_t* tvb)
221 /* Recursively call tvb_free_chain() */
222 for (slist = tvb->used_in; slist != NULL ; slist = slist->next) {
223 tvb_free_chain( (tvbuff_t*)slist->data );
226 /* Stop the recursion */
233 tvb_set_free_cb(tvbuff_t* tvb, tvbuff_free_cb_t func)
235 DISSECTOR_ASSERT(tvb);
236 DISSECTOR_ASSERT(tvb->type == TVBUFF_REAL_DATA);
241 add_to_used_in_list(tvbuff_t *tvb, tvbuff_t *used_in)
243 tvb->used_in = g_slist_prepend(tvb->used_in, used_in);
244 tvb_increment_usage_count(tvb, 1);
248 tvb_set_child_real_data_tvbuff(tvbuff_t* parent, tvbuff_t* child)
250 DISSECTOR_ASSERT(parent && child);
251 DISSECTOR_ASSERT(parent->initialized);
252 DISSECTOR_ASSERT(child->initialized);
253 DISSECTOR_ASSERT(child->type == TVBUFF_REAL_DATA);
254 add_to_used_in_list(parent, child);
258 tvb_set_real_data(tvbuff_t* tvb, const guint8* data, guint length, gint reported_length)
260 DISSECTOR_ASSERT(tvb);
261 DISSECTOR_ASSERT(tvb->type == TVBUFF_REAL_DATA);
262 DISSECTOR_ASSERT(!tvb->initialized);
264 if (reported_length < -1) {
265 THROW(ReportedBoundsError);
268 tvb->real_data = data;
269 tvb->length = length;
270 tvb->reported_length = reported_length;
271 tvb->initialized = TRUE;
275 tvb_new_real_data(const guint8* data, guint length, gint reported_length)
277 static tvbuff_t *last_tvb=NULL;
280 tvb = tvb_new(TVBUFF_REAL_DATA);
285 /* remember this tvb in case we throw an exception and
286 * lose the pointer to it.
290 tvb_set_real_data(tvb, data, length, reported_length);
293 * This is the top-level real tvbuff for this data source,
294 * so its data source tvbuff is itself.
298 /* ok no exception so we dont need to remember it any longer */
304 /* Computes the absolute offset and length based on a possibly-negative offset
305 * and a length that is possible -1 (which means "to the end of the data").
306 * Returns TRUE/FALSE indicating whether the offset is in bounds or
307 * not. The integer ptrs are modified with the new offset and length.
308 * No exception is thrown.
310 * XXX - we return TRUE, not FALSE, if the offset is positive and right
311 * after the end of the tvbuff (i.e., equal to the length). We do this
312 * so that a dissector constructing a subset tvbuff for the next protocol
313 * will get a zero-length tvbuff, not an exception, if there's no data
314 * left for the next protocol - we want the next protocol to be the one
315 * that gets an exception, so the error is reported as an error in that
316 * protocol rather than the containing protocol. */
318 compute_offset_length(tvbuff_t *tvb, gint offset, gint length,
319 guint *offset_ptr, guint *length_ptr, int *exception)
321 DISSECTOR_ASSERT(offset_ptr);
322 DISSECTOR_ASSERT(length_ptr);
324 /* Compute the offset */
326 /* Positive offset - relative to the beginning of the packet. */
327 if ((guint) offset > tvb->reported_length) {
329 *exception = ReportedBoundsError;
333 else if ((guint) offset > tvb->length) {
335 *exception = BoundsError;
340 *offset_ptr = offset;
344 /* Negative offset - relative to the end of the packet. */
345 if ((guint) -offset > tvb->reported_length) {
347 *exception = ReportedBoundsError;
351 else if ((guint) -offset > tvb->length) {
353 *exception = BoundsError;
358 *offset_ptr = tvb->length + offset;
362 /* Compute the length */
365 /* XXX - ReportedBoundsError? */
366 *exception = BoundsError;
370 else if (length == -1) {
371 *length_ptr = tvb->length - *offset_ptr;
374 *length_ptr = length;
382 check_offset_length_no_exception(tvbuff_t *tvb, gint offset, gint length,
383 guint *offset_ptr, guint *length_ptr, int *exception)
387 DISSECTOR_ASSERT(tvb && tvb->initialized);
389 if (!compute_offset_length(tvb, offset, length, offset_ptr, length_ptr, exception)) {
394 * Compute the offset of the first byte past the length.
396 end_offset = *offset_ptr + *length_ptr;
399 * Check for an overflow, and clamp "end_offset" at the maximum
400 * if we got an overflow - that should force us to indicate that
401 * we're past the end of the tvbuff.
403 if (end_offset < *offset_ptr)
404 end_offset = UINT_MAX;
407 * Check whether that offset goes more than one byte past the
410 * If not, return TRUE; otherwise, return FALSE and, if "exception"
411 * is non-null, return the appropriate exception through it.
413 if (end_offset <= tvb->length) {
416 else if (end_offset <= tvb->reported_length) {
418 *exception = BoundsError;
424 *exception = ReportedBoundsError;
429 DISSECTOR_ASSERT_NOT_REACHED();
432 /* Checks (+/-) offset and length and throws an exception if
433 * either is out of bounds. Sets integer ptrs to the new offset
436 check_offset_length(tvbuff_t *tvb, gint offset, gint length,
437 guint *offset_ptr, guint *length_ptr)
441 if (!check_offset_length_no_exception(tvb, offset, length, offset_ptr, length_ptr, &exception)) {
442 DISSECTOR_ASSERT(exception > 0);
450 tvb_set_subset(tvbuff_t *tvb, tvbuff_t *backing,
451 gint backing_offset, gint backing_length, gint reported_length)
453 DISSECTOR_ASSERT(tvb);
454 DISSECTOR_ASSERT(tvb->type == TVBUFF_SUBSET);
455 DISSECTOR_ASSERT(!tvb->initialized);
457 if (reported_length < -1) {
458 THROW(ReportedBoundsError);
461 check_offset_length(backing, backing_offset, backing_length,
462 &tvb->tvbuffs.subset.offset,
463 &tvb->tvbuffs.subset.length);
465 tvb->tvbuffs.subset.tvb = backing;
466 tvb->length = tvb->tvbuffs.subset.length;
468 if (reported_length == -1) {
469 tvb->reported_length = backing->reported_length - tvb->tvbuffs.subset.offset;
472 tvb->reported_length = reported_length;
474 tvb->initialized = TRUE;
475 add_to_used_in_list(backing, tvb);
477 /* Optimization. If the backing buffer has a pointer to contiguous, real data,
478 * then we can point directly to our starting offset in that buffer */
479 if (backing->real_data != NULL) {
480 tvb->real_data = backing->real_data + tvb->tvbuffs.subset.offset;
486 tvb_new_subset(tvbuff_t *backing, gint backing_offset, gint backing_length, gint reported_length)
488 static tvbuff_t *last_tvb=NULL;
491 tvb = tvb_new(TVBUFF_SUBSET);
496 /* remember this tvb in case we throw an exception and
497 * lose the pointer to it.
501 tvb_set_subset(tvb, backing, backing_offset, backing_length, reported_length);
504 * The top-level data source of this tvbuff is the top-level
505 * data source of its parent.
507 tvb->ds_tvb = backing->ds_tvb;
509 /* ok no exception so we dont need to remember it any longer */
516 tvb_composite_append(tvbuff_t* tvb, tvbuff_t* member)
518 tvb_comp_t *composite;
520 DISSECTOR_ASSERT(tvb && !tvb->initialized);
521 composite = &tvb->tvbuffs.composite;
522 composite->tvbs = g_slist_append( composite->tvbs, member );
523 add_to_used_in_list(member, tvb);
527 tvb_composite_prepend(tvbuff_t* tvb, tvbuff_t* member)
529 tvb_comp_t *composite;
531 DISSECTOR_ASSERT(tvb && !tvb->initialized);
532 composite = &tvb->tvbuffs.composite;
533 composite->tvbs = g_slist_prepend( composite->tvbs, member );
534 add_to_used_in_list(member, tvb);
538 tvb_new_composite(void)
540 return tvb_new(TVBUFF_COMPOSITE);
544 tvb_composite_finalize(tvbuff_t* tvb)
548 tvbuff_t *member_tvb;
549 tvb_comp_t *composite;
552 DISSECTOR_ASSERT(tvb && !tvb->initialized);
553 DISSECTOR_ASSERT(tvb->length == 0);
555 composite = &tvb->tvbuffs.composite;
556 num_members = g_slist_length(composite->tvbs);
558 composite->start_offsets = g_new(guint, num_members);
559 composite->end_offsets = g_new(guint, num_members);
561 for (slist = composite->tvbs; slist != NULL; slist = slist->next) {
562 DISSECTOR_ASSERT((guint) i < num_members);
563 member_tvb = slist->data;
564 composite->start_offsets[i] = tvb->length;
565 tvb->length += member_tvb->length;
566 composite->end_offsets[i] = tvb->length - 1;
570 tvb->initialized = TRUE;
576 tvb_length(tvbuff_t* tvb)
578 DISSECTOR_ASSERT(tvb && tvb->initialized);
584 tvb_length_remaining(tvbuff_t *tvb, gint offset)
586 guint abs_offset, abs_length;
588 DISSECTOR_ASSERT(tvb && tvb->initialized);
590 if (compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL)) {
599 tvb_ensure_length_remaining(tvbuff_t *tvb, gint offset)
601 guint abs_offset, abs_length;
604 DISSECTOR_ASSERT(tvb && tvb->initialized);
606 if (!compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, &exception)) {
609 if (abs_length == 0) {
611 * This routine ensures there's at least one byte available.
612 * There aren't any bytes available, so throw the appropriate
615 if (abs_offset >= tvb->reported_length)
616 THROW(ReportedBoundsError);
626 /* Validates that 'length' bytes are available starting from
627 * offset (pos/neg). Does not throw an exception. */
629 tvb_bytes_exist(tvbuff_t *tvb, gint offset, gint length)
631 guint abs_offset, abs_length;
633 DISSECTOR_ASSERT(tvb && tvb->initialized);
635 if (!compute_offset_length(tvb, offset, length, &abs_offset, &abs_length, NULL))
638 if (abs_offset + abs_length <= tvb->length) {
646 /* Validates that 'length' bytes are available starting from
647 * offset (pos/neg). Throws an exception if they aren't. */
649 tvb_ensure_bytes_exist(tvbuff_t *tvb, gint offset, gint length)
651 guint abs_offset, abs_length;
653 DISSECTOR_ASSERT(tvb && tvb->initialized);
656 * -1 doesn't mean "until end of buffer", as that's pointless
657 * for this routine. We must treat it as a Really Large Positive
658 * Number, so that we throw an exception; we throw
659 * ReportedBoundsError, as if it were past even the end of a
660 * reassembled packet, and past the end of even the data we
663 * We do the same with other negative lengths.
666 THROW(ReportedBoundsError);
668 check_offset_length(tvb, offset, length, &abs_offset, &abs_length);
672 tvb_offset_exists(tvbuff_t *tvb, gint offset)
674 guint abs_offset, abs_length;
676 DISSECTOR_ASSERT(tvb && tvb->initialized);
677 if (!compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL))
680 if (abs_offset < tvb->length) {
689 tvb_reported_length(tvbuff_t* tvb)
691 DISSECTOR_ASSERT(tvb && tvb->initialized);
693 return tvb->reported_length;
697 tvb_reported_length_remaining(tvbuff_t *tvb, gint offset)
699 guint abs_offset, abs_length;
701 DISSECTOR_ASSERT(tvb && tvb->initialized);
703 if (compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL)) {
704 if (tvb->reported_length >= abs_offset)
705 return tvb->reported_length - abs_offset;
714 /* Set the reported length of a tvbuff to a given value; used for protocols
715 whose headers contain an explicit length and where the calling
716 dissector's payload may include padding as well as the packet for
719 Also adjusts the data length. */
721 tvb_set_reported_length(tvbuff_t* tvb, guint reported_length)
723 DISSECTOR_ASSERT(tvb && tvb->initialized);
725 if (reported_length > tvb->reported_length)
726 THROW(ReportedBoundsError);
728 tvb->reported_length = reported_length;
729 if (reported_length < tvb->length)
730 tvb->length = reported_length;
735 first_real_data_ptr(tvbuff_t *tvb)
740 case TVBUFF_REAL_DATA:
741 return tvb->real_data;
743 member = tvb->tvbuffs.subset.tvb;
744 return first_real_data_ptr(member);
745 case TVBUFF_COMPOSITE:
746 member = tvb->tvbuffs.composite.tvbs->data;
747 return first_real_data_ptr(member);
750 DISSECTOR_ASSERT_NOT_REACHED();
755 offset_from_real_beginning(tvbuff_t *tvb, int counter)
760 case TVBUFF_REAL_DATA:
763 member = tvb->tvbuffs.subset.tvb;
764 return offset_from_real_beginning(member, counter + tvb->tvbuffs.subset.offset);
765 case TVBUFF_COMPOSITE:
766 member = tvb->tvbuffs.composite.tvbs->data;
767 return offset_from_real_beginning(member, counter);
770 DISSECTOR_ASSERT_NOT_REACHED();
775 composite_ensure_contiguous_no_exception(tvbuff_t *tvb, guint abs_offset,
778 guint i, num_members;
779 tvb_comp_t *composite;
780 tvbuff_t *member_tvb = NULL;
781 guint member_offset, member_length;
784 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
786 /* Maybe the range specified by offset/length
787 * is contiguous inside one of the member tvbuffs */
788 composite = &tvb->tvbuffs.composite;
789 num_members = g_slist_length(composite->tvbs);
791 for (i = 0; i < num_members; i++) {
792 if (abs_offset <= composite->end_offsets[i]) {
793 slist = g_slist_nth(composite->tvbs, i);
794 member_tvb = slist->data;
798 DISSECTOR_ASSERT(member_tvb);
800 if (check_offset_length_no_exception(member_tvb, abs_offset - composite->start_offsets[i],
801 abs_length, &member_offset, &member_length, NULL)) {
804 * The range is, in fact, contiguous within member_tvb.
806 DISSECTOR_ASSERT(!tvb->real_data);
807 return ensure_contiguous_no_exception(member_tvb, member_offset, member_length, NULL);
810 tvb->real_data = tvb_memdup(tvb, 0, -1);
811 return tvb->real_data + abs_offset;
814 DISSECTOR_ASSERT_NOT_REACHED();
819 ensure_contiguous_no_exception(tvbuff_t *tvb, gint offset, gint length,
822 guint abs_offset, abs_length;
824 if (!check_offset_length_no_exception(tvb, offset, length,
825 &abs_offset, &abs_length, exception)) {
830 * We know that all the data is present in the tvbuff, so
831 * no exceptions should be thrown.
833 if (tvb->real_data) {
834 return tvb->real_data + abs_offset;
838 case TVBUFF_REAL_DATA:
839 DISSECTOR_ASSERT_NOT_REACHED();
841 return ensure_contiguous_no_exception(tvb->tvbuffs.subset.tvb,
842 abs_offset - tvb->tvbuffs.subset.offset,
844 case TVBUFF_COMPOSITE:
845 return composite_ensure_contiguous_no_exception(tvb, abs_offset, abs_length);
849 DISSECTOR_ASSERT_NOT_REACHED();
854 ensure_contiguous(tvbuff_t *tvb, gint offset, gint length)
859 p = ensure_contiguous_no_exception(tvb, offset, length, &exception);
861 DISSECTOR_ASSERT(exception > 0);
868 guint8_find(const guint8* haystack, size_t haystacklen, guint8 needle)
873 for (b = haystack, i = 0; (guint) i < haystacklen; i++, b++) {
883 guint8_pbrk(const guint8* haystack, size_t haystacklen, guint8 *needles)
887 guint8 item, *needlep, needle;
889 for (b = haystack, i = 0; (guint) i < haystacklen; i++, b++) {
892 while ((needle = *needlep) != '\0') {
904 /************** ACCESSORS **************/
907 composite_memcpy(tvbuff_t *tvb, guint8* target, guint abs_offset, guint abs_length)
909 guint i, num_members;
910 tvb_comp_t *composite;
911 tvbuff_t *member_tvb = NULL;
912 guint member_offset, member_length;
916 DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE);
918 /* Maybe the range specified by offset/length
919 * is contiguous inside one of the member tvbuffs */
920 composite = &tvb->tvbuffs.composite;
921 num_members = g_slist_length(composite->tvbs);
923 for (i = 0; i < num_members; i++) {
924 if (abs_offset <= composite->end_offsets[i]) {
925 slist = g_slist_nth(composite->tvbs, i);
926 member_tvb = slist->data;
930 DISSECTOR_ASSERT(member_tvb);
932 if (check_offset_length_no_exception(member_tvb, abs_offset - composite->start_offsets[i],
933 abs_length, &member_offset, &member_length, NULL)) {
935 DISSECTOR_ASSERT(!tvb->real_data);
936 return tvb_memcpy(member_tvb, target, member_offset, member_length);
939 /* The requested data is non-contiguous inside
940 * the member tvb. We have to memcpy() the part that's in the member tvb,
941 * then iterate across the other member tvb's, copying their portions
942 * until we have copied all data.
944 retval = compute_offset_length(member_tvb, abs_offset - composite->start_offsets[i], -1,
945 &member_offset, &member_length, NULL);
946 DISSECTOR_ASSERT(retval);
948 tvb_memcpy(member_tvb, target, member_offset, member_length);
949 abs_offset += member_length;
950 abs_length -= member_length;
953 if (abs_length > 0) {
954 composite_memcpy(tvb, target + member_length, abs_offset, abs_length);
960 DISSECTOR_ASSERT_NOT_REACHED();
965 tvb_memcpy(tvbuff_t *tvb, guint8* target, gint offset, gint length)
967 guint abs_offset, abs_length;
969 DISSECTOR_ASSERT(length >= -1);
970 check_offset_length(tvb, offset, length, &abs_offset, &abs_length);
972 if (tvb->real_data) {
973 return (guint8*) memcpy(target, tvb->real_data + abs_offset, abs_length);
977 case TVBUFF_REAL_DATA:
978 DISSECTOR_ASSERT_NOT_REACHED();
981 return tvb_memcpy(tvb->tvbuffs.subset.tvb, target,
982 abs_offset - tvb->tvbuffs.subset.offset,
985 case TVBUFF_COMPOSITE:
986 return composite_memcpy(tvb, target, offset, length);
989 DISSECTOR_ASSERT_NOT_REACHED();
995 * XXX - this doesn't treat a length of -1 as an error.
996 * If it did, this could replace some code that calls
997 * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies
1000 * "composite_ensure_contiguous_no_exception()" depends on -1 not being
1001 * an error; does anything else depend on this routine treating -1 as
1002 * meaning "to the end of the buffer"?
1005 tvb_memdup(tvbuff_t *tvb, gint offset, gint length)
1007 guint abs_offset, abs_length;
1010 check_offset_length(tvb, offset, length, &abs_offset, &abs_length);
1012 duped = g_malloc(abs_length);
1013 return tvb_memcpy(tvb, duped, abs_offset, abs_length);
1017 * XXX - this doesn't treat a length of -1 as an error.
1018 * If it did, this could replace some code that calls
1019 * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies
1022 * "composite_ensure_contiguous_no_exception()" depends on -1 not being
1023 * an error; does anything else depend on this routine treating -1 as
1024 * meaning "to the end of the buffer"?
1026 * This function allocates memory from a buffer with packet lifetime.
1027 * You do not have to free this buffer, it will be automatically freed
1028 * when wireshark starts decoding the next packet.
1029 * Do not use this function if you want the allocated memory to be persistent
1030 * after the current packet has been dissected.
1033 ep_tvb_memdup(tvbuff_t *tvb, gint offset, gint length)
1035 guint abs_offset, abs_length;
1038 check_offset_length(tvb, offset, length, &abs_offset, &abs_length);
1040 duped = ep_alloc(abs_length);
1041 return tvb_memcpy(tvb, duped, abs_offset, abs_length);
1047 tvb_get_ptr(tvbuff_t *tvb, gint offset, gint length)
1049 return ensure_contiguous(tvb, offset, length);
1053 tvb_get_guint8(tvbuff_t *tvb, gint offset)
1057 ptr = ensure_contiguous(tvb, offset, sizeof(guint8));
1062 tvb_get_ntohs(tvbuff_t *tvb, gint offset)
1066 ptr = ensure_contiguous(tvb, offset, sizeof(guint16));
1071 tvb_get_ntoh24(tvbuff_t *tvb, gint offset)
1075 ptr = ensure_contiguous(tvb, offset, 3);
1076 return pntoh24(ptr);
1080 tvb_get_ntohl(tvbuff_t *tvb, gint offset)
1084 ptr = ensure_contiguous(tvb, offset, sizeof(guint32));
1089 tvb_get_ntoh64(tvbuff_t *tvb, gint offset)
1093 ptr = ensure_contiguous(tvb, offset, sizeof(guint64));
1094 return pntoh64(ptr);
1098 * Stuff for IEEE float handling on platforms that don't have IEEE
1099 * format as the native floating-point format.
1101 * For now, we treat only the VAX as such a platform.
1103 * XXX - other non-IEEE boxes that can run UNIX include some Crays,
1104 * and possibly other machines.
1106 * It appears that the official Linux port to System/390 and
1107 * zArchitecture uses IEEE format floating point (not a
1110 * I don't know whether there are any other machines that
1111 * could run Wireshark and that don't use IEEE format.
1112 * As far as I know, all of the main commercial microprocessor
1113 * families on which OSes that support Wireshark can run
1114 * use IEEE format (x86, 68k, SPARC, MIPS, PA-RISC, Alpha,
1115 * IA-64, and so on).
1125 #define IEEE_SP_NUMBER_WIDTH 32 /* bits in number */
1126 #define IEEE_SP_EXP_WIDTH 8 /* bits in exponent */
1127 #define IEEE_SP_MANTISSA_WIDTH 23 /* IEEE_SP_NUMBER_WIDTH - 1 - IEEE_SP_EXP_WIDTH */
1129 #define IEEE_SP_SIGN_MASK 0x80000000
1130 #define IEEE_SP_EXPONENT_MASK 0x7F800000
1131 #define IEEE_SP_MANTISSA_MASK 0x007FFFFF
1132 #define IEEE_SP_INFINITY IEEE_SP_EXPONENT_MASK
1134 #define IEEE_SP_IMPLIED_BIT (1 << IEEE_SP_MANTISSA_WIDTH)
1135 #define IEEE_SP_INFINITE ((1 << IEEE_SP_EXP_WIDTH) - 1)
1136 #define IEEE_SP_BIAS ((1 << (IEEE_SP_EXP_WIDTH - 1)) - 1)
1139 ieee_float_is_zero(guint32 w)
1141 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1145 get_ieee_float(guint32 w)
1151 sign = w & IEEE_SP_SIGN_MASK;
1152 exponent = w & IEEE_SP_EXPONENT_MASK;
1153 mantissa = w & IEEE_SP_MANTISSA_MASK;
1155 if (ieee_float_is_zero(w)) {
1156 /* number is zero, unnormalized, or not-a-number */
1161 * XXX - how to handle this?
1163 if (IEEE_SP_INFINITY == exponent) {
1165 * number is positive or negative infinity, or a special value
1167 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1171 exponent = ((exponent >> IEEE_SP_MANTISSA_WIDTH) - IEEE_SP_BIAS) -
1172 IEEE_SP_MANTISSA_WIDTH;
1173 mantissa |= IEEE_SP_IMPLIED_BIT;
1176 return -mantissa * pow(2, exponent);
1178 return mantissa * pow(2, exponent);
1183 * We assume that if you don't have IEEE floating-point, you have a
1184 * compiler that understands 64-bit integral quantities.
1186 #define IEEE_DP_NUMBER_WIDTH 64 /* bits in number */
1187 #define IEEE_DP_EXP_WIDTH 11 /* bits in exponent */
1188 #define IEEE_DP_MANTISSA_WIDTH 52 /* IEEE_DP_NUMBER_WIDTH - 1 - IEEE_DP_EXP_WIDTH */
1190 #define IEEE_DP_SIGN_MASK 0x8000000000000000LL
1191 #define IEEE_DP_EXPONENT_MASK 0x7FF0000000000000LL
1192 #define IEEE_DP_MANTISSA_MASK 0x000FFFFFFFFFFFFFLL
1193 #define IEEE_DP_INFINITY IEEE_DP_EXPONENT_MASK
1195 #define IEEE_DP_IMPLIED_BIT (1LL << IEEE_DP_MANTISSA_WIDTH)
1196 #define IEEE_DP_INFINITE ((1 << IEEE_DP_EXP_WIDTH) - 1)
1197 #define IEEE_DP_BIAS ((1 << (IEEE_DP_EXP_WIDTH - 1)) - 1)
1200 ieee_double_is_zero(guint64 w)
1202 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1206 get_ieee_double(guint64 w)
1212 sign = w & IEEE_DP_SIGN_MASK;
1213 exponent = w & IEEE_DP_EXPONENT_MASK;
1214 mantissa = w & IEEE_DP_MANTISSA_MASK;
1216 if (ieee_double_is_zero(w)) {
1217 /* number is zero, unnormalized, or not-a-number */
1222 * XXX - how to handle this?
1224 if (IEEE_DP_INFINITY == exponent) {
1226 * number is positive or negative infinity, or a special value
1228 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1232 exponent = ((exponent >> IEEE_DP_MANTISSA_WIDTH) - IEEE_DP_BIAS) -
1233 IEEE_DP_MANTISSA_WIDTH;
1234 mantissa |= IEEE_DP_IMPLIED_BIT;
1237 return -mantissa * pow(2, exponent);
1239 return mantissa * pow(2, exponent);
1244 * Fetches an IEEE single-precision floating-point number, in
1245 * big-endian form, and returns a "float".
1247 * XXX - should this be "double", in case there are IEEE single-
1248 * precision numbers that won't fit in some platform's native
1252 tvb_get_ntohieee_float(tvbuff_t *tvb, int offset)
1255 return get_ieee_float(tvb_get_ntohl(tvb, offset));
1262 ieee_fp_union.w = tvb_get_ntohl(tvb, offset);
1263 return ieee_fp_union.f;
1268 * Fetches an IEEE double-precision floating-point number, in
1269 * big-endian form, and returns a "double".
1272 tvb_get_ntohieee_double(tvbuff_t *tvb, int offset)
1286 #ifdef WORDS_BIGENDIAN
1287 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset);
1288 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset+4);
1290 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset+4);
1291 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset);
1294 return get_ieee_double(ieee_fp_union.dw);
1296 return ieee_fp_union.d;
1301 tvb_get_letohs(tvbuff_t *tvb, gint offset)
1305 ptr = ensure_contiguous(tvb, offset, sizeof(guint16));
1306 return pletohs(ptr);
1310 tvb_get_letoh24(tvbuff_t *tvb, gint offset)
1314 ptr = ensure_contiguous(tvb, offset, 3);
1315 return pletoh24(ptr);
1319 tvb_get_letohl(tvbuff_t *tvb, gint offset)
1323 ptr = ensure_contiguous(tvb, offset, sizeof(guint32));
1324 return pletohl(ptr);
1328 tvb_get_letoh64(tvbuff_t *tvb, gint offset)
1332 ptr = ensure_contiguous(tvb, offset, sizeof(guint64));
1333 return pletoh64(ptr);
1337 * Fetches an IEEE single-precision floating-point number, in
1338 * little-endian form, and returns a "float".
1340 * XXX - should this be "double", in case there are IEEE single-
1341 * precision numbers that won't fit in some platform's native
1345 tvb_get_letohieee_float(tvbuff_t *tvb, int offset)
1348 return get_ieee_float(tvb_get_letohl(tvb, offset));
1355 ieee_fp_union.w = tvb_get_letohl(tvb, offset);
1356 return ieee_fp_union.f;
1361 * Fetches an IEEE double-precision floating-point number, in
1362 * little-endian form, and returns a "double".
1365 tvb_get_letohieee_double(tvbuff_t *tvb, int offset)
1379 #ifdef WORDS_BIGENDIAN
1380 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset+4);
1381 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset);
1383 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset);
1384 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset+4);
1387 return get_ieee_double(ieee_fp_union.dw);
1389 return ieee_fp_union.d;
1393 /* Fetch an IPv4 address, in network byte order.
1394 * We do *not* convert them to host byte order; we leave them in
1395 * network byte order. */
1397 tvb_get_ipv4(tvbuff_t *tvb, gint offset)
1402 ptr = ensure_contiguous(tvb, offset, sizeof(guint32));
1403 memcpy(&addr, ptr, sizeof addr);
1407 /* Fetch an IPv6 address. */
1409 tvb_get_ipv6(tvbuff_t *tvb, gint offset, struct e_in6_addr *addr)
1413 ptr = ensure_contiguous(tvb, offset, sizeof(*addr));
1414 memcpy(addr, ptr, sizeof *addr);
1419 tvb_get_ntohguid(tvbuff_t *tvb, gint offset, e_guid_t *guid)
1421 ensure_contiguous(tvb, offset, sizeof(*guid));
1422 guid->data1 = tvb_get_ntohl(tvb, offset);
1423 guid->data2 = tvb_get_ntohs(tvb, offset + 4);
1424 guid->data3 = tvb_get_ntohs(tvb, offset + 6);
1425 tvb_memcpy(tvb, guid->data4, offset + 8, sizeof guid->data4);
1429 tvb_get_letohguid(tvbuff_t *tvb, gint offset, e_guid_t *guid)
1431 ensure_contiguous(tvb, offset, sizeof(*guid));
1432 guid->data1 = tvb_get_letohl(tvb, offset);
1433 guid->data2 = tvb_get_letohs(tvb, offset + 4);
1434 guid->data3 = tvb_get_letohs(tvb, offset + 6);
1435 tvb_memcpy(tvb, guid->data4, offset + 8, sizeof guid->data4);
1439 tvb_get_guid(tvbuff_t *tvb, gint offset, e_guid_t *guid, gboolean little_endian)
1441 if (little_endian) {
1442 tvb_get_letohguid(tvb, offset, guid);
1444 tvb_get_ntohguid(tvb, offset, guid);
1448 /* Find first occurence of needle in tvbuff, starting at offset. Searches
1449 * at most maxlength number of bytes; if maxlength is -1, searches to
1451 * Returns the offset of the found needle, or -1 if not found.
1452 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1453 * in that case, -1 will be returned if the boundary is reached before
1454 * finding needle. */
1456 tvb_find_guint8(tvbuff_t *tvb, gint offset, gint maxlength, guint8 needle)
1458 const guint8 *result;
1459 guint abs_offset, junk_length;
1463 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1465 /* Only search to end of tvbuff, w/o throwing exception. */
1466 tvbufflen = tvb_length_remaining(tvb, abs_offset);
1467 if (maxlength == -1) {
1468 /* No maximum length specified; search to end of tvbuff. */
1471 else if (tvbufflen < (guint) maxlength) {
1472 /* Maximum length goes past end of tvbuff; search to end
1477 /* Maximum length doesn't go past end of tvbuff; search
1482 /* If we have real data, perform our search now. */
1483 if (tvb->real_data) {
1484 result = guint8_find(tvb->real_data + abs_offset, limit, needle);
1485 if (result == NULL) {
1489 return result - tvb->real_data;
1494 case TVBUFF_REAL_DATA:
1495 DISSECTOR_ASSERT_NOT_REACHED();
1498 return tvb_find_guint8(tvb->tvbuffs.subset.tvb,
1499 abs_offset - tvb->tvbuffs.subset.offset,
1502 case TVBUFF_COMPOSITE:
1503 DISSECTOR_ASSERT_NOT_REACHED();
1504 /* XXX - return composite_find_guint8(tvb, offset, limit, needle); */
1507 DISSECTOR_ASSERT_NOT_REACHED();
1511 /* Find first occurence of any of the needles in tvbuff, starting at offset.
1512 * Searches at most maxlength number of bytes; if maxlength is -1, searches
1514 * Returns the offset of the found needle, or -1 if not found.
1515 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1516 * in that case, -1 will be returned if the boundary is reached before
1517 * finding needle. */
1519 tvb_pbrk_guint8(tvbuff_t *tvb, gint offset, gint maxlength, const guint8 *needles)
1521 const guint8 *result;
1522 guint abs_offset, junk_length;
1526 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1528 /* Only search to end of tvbuff, w/o throwing exception. */
1529 tvbufflen = tvb_length_remaining(tvb, abs_offset);
1530 if (maxlength == -1) {
1531 /* No maximum length specified; search to end of tvbuff. */
1534 else if (tvbufflen < (guint) maxlength) {
1535 /* Maximum length goes past end of tvbuff; search to end
1540 /* Maximum length doesn't go past end of tvbuff; search
1545 /* If we have real data, perform our search now. */
1546 if (tvb->real_data) {
1547 result = guint8_pbrk(tvb->real_data + abs_offset, limit, needles);
1548 if (result == NULL) {
1552 return result - tvb->real_data;
1557 case TVBUFF_REAL_DATA:
1558 DISSECTOR_ASSERT_NOT_REACHED();
1561 return tvb_pbrk_guint8(tvb->tvbuffs.subset.tvb,
1562 abs_offset - tvb->tvbuffs.subset.offset,
1565 case TVBUFF_COMPOSITE:
1566 DISSECTOR_ASSERT_NOT_REACHED();
1567 /* XXX - return composite_pbrk_guint8(tvb, offset, limit, needle); */
1570 DISSECTOR_ASSERT_NOT_REACHED();
1574 /* Find size of stringz (NUL-terminated string) by looking for terminating
1575 * NUL. The size of the string includes the terminating NUL.
1577 * If the NUL isn't found, it throws the appropriate exception.
1580 tvb_strsize(tvbuff_t *tvb, gint offset)
1582 guint abs_offset, junk_length;
1585 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1586 nul_offset = tvb_find_guint8(tvb, abs_offset, -1, 0);
1587 if (nul_offset == -1) {
1589 * OK, we hit the end of the tvbuff, so we should throw
1592 * Did we hit the end of the captured data, or the end
1593 * of the actual data? If there's less captured data
1594 * than actual data, we presumably hit the end of the
1595 * captured data, otherwise we hit the end of the actual
1598 if (tvb_length(tvb) < tvb_reported_length(tvb)) {
1601 THROW(ReportedBoundsError);
1604 return (nul_offset - abs_offset) + 1;
1607 /* Find length of string by looking for end of string ('\0'), up to
1608 * 'maxlength' characters'; if 'maxlength' is -1, searches to end
1610 * Returns -1 if 'maxlength' reached before finding EOS. */
1612 tvb_strnlen(tvbuff_t *tvb, gint offset, guint maxlength)
1615 guint abs_offset, junk_length;
1617 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1619 result_offset = tvb_find_guint8(tvb, abs_offset, maxlength, 0);
1621 if (result_offset == -1) {
1625 return result_offset - abs_offset;
1630 * Implement strneql etc
1634 * Call strncmp after checking if enough chars left, returning 0 if
1635 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1638 tvb_strneql(tvbuff_t *tvb, gint offset, const gchar *str, gint size)
1642 ptr = ensure_contiguous_no_exception(tvb, offset, size, NULL);
1645 int cmp = strncmp((const char *)ptr, str, size);
1648 * Return 0 if equal, -1 otherwise.
1650 return (cmp == 0 ? 0 : -1);
1653 * Not enough characters in the tvbuff to match the
1661 * Call strncasecmp after checking if enough chars left, returning 0 if
1662 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1665 tvb_strncaseeql(tvbuff_t *tvb, gint offset, const gchar *str, gint size)
1669 ptr = ensure_contiguous_no_exception(tvb, offset, size, NULL);
1672 int cmp = strncasecmp((const char *)ptr, str, size);
1675 * Return 0 if equal, -1 otherwise.
1677 return (cmp == 0 ? 0 : -1);
1680 * Not enough characters in the tvbuff to match the
1688 * Call memcmp after checking if enough chars left, returning 0 if
1689 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1692 tvb_memeql(tvbuff_t *tvb, gint offset, const guint8 *str, gint size)
1696 ptr = ensure_contiguous_no_exception(tvb, offset, size, NULL);
1699 int cmp = memcmp(ptr, str, size);
1702 * Return 0 if equal, -1 otherwise.
1704 return (cmp == 0 ? 0 : -1);
1707 * Not enough characters in the tvbuff to match the
1714 /* Convert a string from Unicode to ASCII. At the moment we fake it by
1715 * replacing all non-ASCII characters with a '.' )-: The caller must
1716 * free the result returned. The len parameter is the number of guint16's
1717 * to convert from Unicode. */
1719 tvb_fake_unicode(tvbuff_t *tvb, int offset, int len, gboolean little_endian)
1725 /* Make sure we have enough data before allocating the buffer,
1726 so we don't blow up if the length is huge. */
1727 tvb_ensure_bytes_exist(tvb, offset, 2*len);
1729 /* We know we won't throw an exception, so we don't have to worry
1730 about leaking this buffer. */
1731 buffer = g_malloc(len + 1);
1733 for (i = 0; i < len; i++) {
1734 character = little_endian ? tvb_get_letohs(tvb, offset)
1735 : tvb_get_ntohs(tvb, offset);
1736 buffer[i] = character < 256 ? character : '.';
1745 /* Convert a string from Unicode to ASCII. At the moment we fake it by
1746 * replacing all non-ASCII characters with a '.' )-: The len parameter is
1747 * the number of guint16's to convert from Unicode.
1749 * This function allocates memory from a buffer with packet lifetime.
1750 * You do not have to free this buffer, it will be automatically freed
1751 * when wireshark starts decoding the next packet.
1754 tvb_get_ephemeral_faked_unicode(tvbuff_t *tvb, int offset, int len, gboolean little_endian)
1760 /* Make sure we have enough data before allocating the buffer,
1761 so we don't blow up if the length is huge. */
1762 tvb_ensure_bytes_exist(tvb, offset, 2*len);
1764 /* We know we won't throw an exception, so we don't have to worry
1765 about leaking this buffer. */
1766 buffer = ep_alloc(len + 1);
1768 for (i = 0; i < len; i++) {
1769 character = little_endian ? tvb_get_letohs(tvb, offset)
1770 : tvb_get_ntohs(tvb, offset);
1771 buffer[i] = character < 256 ? character : '.';
1781 * Format the data in the tvb from offset for length ...
1785 tvb_format_text(tvbuff_t *tvb, gint offset, gint size)
1790 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
1792 len = tvb_length_remaining(tvb, offset);
1793 ptr = ensure_contiguous(tvb, offset, len);
1797 return format_text(ptr, len);
1802 * Format the data in the tvb from offset for length ...
1806 tvb_format_text_wsp(tvbuff_t *tvb, gint offset, gint size)
1811 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
1813 len = tvb_length_remaining(tvb, offset);
1814 ptr = ensure_contiguous(tvb, offset, len);
1818 return format_text_wsp(ptr, len);
1823 * Like "tvb_format_text()", but for null-padded strings; don't show
1824 * the null padding characters as "\000".
1827 tvb_format_stringzpad(tvbuff_t *tvb, gint offset, gint size)
1829 const guint8 *ptr, *p;
1833 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
1835 len = tvb_length_remaining(tvb, offset);
1836 ptr = ensure_contiguous(tvb, offset, len);
1840 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
1842 return format_text(ptr, stringlen);
1847 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
1848 * to hold a non-null-terminated string of that length at that offset,
1849 * plus a trailing '\0', copy the string into it, and return a pointer
1852 * Throws an exception if the tvbuff ends before the string does.
1855 tvb_get_string(tvbuff_t *tvb, gint offset, gint length)
1858 guint8 *strbuf = NULL;
1860 tvb_ensure_bytes_exist(tvb, offset, length);
1862 ptr = ensure_contiguous(tvb, offset, length);
1863 strbuf = g_malloc(length + 1);
1865 memcpy(strbuf, ptr, length);
1867 strbuf[length] = '\0';
1871 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
1872 * to hold a non-null-terminated string of that length at that offset,
1873 * plus a trailing '\0', copy the string into it, and return a pointer
1876 * Throws an exception if the tvbuff ends before the string does.
1878 * This function allocates memory from a buffer with packet lifetime.
1879 * You do not have to free this buffer, it will be automatically freed
1880 * when wireshark starts decoding the next packet.
1881 * Do not use this function if you want the allocated memory to be persistent
1882 * after the current packet has been dissected.
1885 tvb_get_ephemeral_string(tvbuff_t *tvb, gint offset, gint length)
1888 guint8 *strbuf = NULL;
1890 tvb_ensure_bytes_exist(tvb, offset, length);
1892 ptr = ensure_contiguous(tvb, offset, length);
1893 strbuf = ep_alloc(length + 1);
1895 memcpy(strbuf, ptr, length);
1897 strbuf[length] = '\0';
1903 * Given a tvbuff and an offset, with the offset assumed to refer to
1904 * a null-terminated string, find the length of that string (and throw
1905 * an exception if the tvbuff ends before we find the null), allocate
1906 * a buffer big enough to hold the string, copy the string into it,
1907 * and return a pointer to the string. Also return the length of the
1908 * string (including the terminating null) through a pointer.
1911 tvb_get_stringz(tvbuff_t *tvb, gint offset, gint *lengthp)
1916 size = tvb_strsize(tvb, offset);
1917 strptr = g_malloc(size);
1918 tvb_memcpy(tvb, strptr, offset, size);
1923 * Given a tvbuff and an offset, with the offset assumed to refer to
1924 * a null-terminated string, find the length of that string (and throw
1925 * an exception if the tvbuff ends before we find the null), allocate
1926 * a buffer big enough to hold the string, copy the string into it,
1927 * and return a pointer to the string. Also return the length of the
1928 * string (including the terminating null) through a pointer.
1930 * This function allocates memory from a buffer with packet lifetime.
1931 * You do not have to free this buffer, it will be automatically freed
1932 * when wireshark starts decoding the next packet.
1933 * Do not use this function if you want the allocated memory to be persistent
1934 * after the current packet has been dissected.
1937 tvb_get_ephemeral_stringz(tvbuff_t *tvb, gint offset, gint *lengthp)
1942 size = tvb_strsize(tvb, offset);
1943 strptr = ep_alloc(size);
1944 tvb_memcpy(tvb, strptr, offset, size);
1949 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
1950 * no more than bufsize number of bytes, including terminating NUL, to buffer.
1951 * Returns length of string (not including terminating NUL), or -1 if the string was
1952 * truncated in the buffer due to not having reached the terminating NUL.
1953 * In this way, it acts like g_snprintf().
1955 * bufsize MUST be greater than 0.
1957 * When processing a packet where the remaining number of bytes is less
1958 * than bufsize, an exception is not thrown if the end of the packet
1959 * is reached before the NUL is found. If no NUL is found before reaching
1960 * the end of the short packet, -1 is still returned, and the string
1961 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
1962 * at the correct spot, terminating the string.
1964 * *bytes_copied will contain the number of bytes actually copied,
1965 * including the terminating-NUL.
1968 _tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer,
1972 guint abs_offset, junk_length;
1974 gboolean decreased_max = FALSE;
1976 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1978 /* There must at least be room for the terminating NUL. */
1979 DISSECTOR_ASSERT(bufsize != 0);
1981 /* If there's no room for anything else, just return the NUL. */
1988 /* Only read to end of tvbuff, w/o throwing exception. */
1989 len = tvb_length_remaining(tvb, abs_offset);
1991 /* check_offset_length() won't throw an exception if we're
1992 * looking at the byte immediately after the end of the tvbuff. */
1994 THROW(ReportedBoundsError);
1997 /* This should not happen because check_offset_length() would
1998 * have already thrown an exception if 'offset' were out-of-bounds.
2000 DISSECTOR_ASSERT(len != -1);
2003 * If we've been passed a negative number, bufsize will
2006 DISSECTOR_ASSERT(bufsize <= G_MAXINT);
2008 if ((guint)len < bufsize) {
2010 decreased_max = TRUE;
2016 stringlen = tvb_strnlen(tvb, abs_offset, limit - 1);
2017 /* If NUL wasn't found, copy the data and return -1 */
2018 if (stringlen == -1) {
2019 tvb_memcpy(tvb, buffer, abs_offset, limit);
2020 if (decreased_max) {
2022 /* Add 1 for the extra NUL that we set at buffer[limit],
2023 * pretending that it was copied as part of the string. */
2024 *bytes_copied = limit + 1;
2027 *bytes_copied = limit;
2032 /* Copy the string to buffer */
2033 tvb_memcpy(tvb, buffer, abs_offset, stringlen + 1);
2034 *bytes_copied = stringlen + 1;
2038 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
2039 * no more than bufsize number of bytes, including terminating NUL, to buffer.
2040 * Returns length of string (not including terminating NUL), or -1 if the string was
2041 * truncated in the buffer due to not having reached the terminating NUL.
2042 * In this way, it acts like g_snprintf().
2044 * When processing a packet where the remaining number of bytes is less
2045 * than bufsize, an exception is not thrown if the end of the packet
2046 * is reached before the NUL is found. If no NUL is found before reaching
2047 * the end of the short packet, -1 is still returned, and the string
2048 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
2049 * at the correct spot, terminating the string.
2052 tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer)
2056 return _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
2059 /* Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
2060 * have a terminating NUL. If the string was truncated when copied into buffer,
2061 * a NUL is placed at the end of buffer to terminate it.
2064 tvb_get_nstringz0(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer)
2066 gint len, bytes_copied;
2068 len = _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
2071 buffer[bufsize - 1] = 0;
2072 return bytes_copied - 1;
2080 * Given a tvbuff, an offset into the tvbuff, and a length that starts
2081 * at that offset (which may be -1 for "all the way to the end of the
2082 * tvbuff"), find the end of the (putative) line that starts at the
2083 * specified offset in the tvbuff, going no further than the specified
2086 * Return the length of the line (not counting the line terminator at
2087 * the end), or, if we don't find a line terminator:
2089 * if "deseg" is true, return -1;
2091 * if "deseg" is false, return the amount of data remaining in
2094 * Set "*next_offset" to the offset of the character past the line
2095 * terminator, or past the end of the buffer if we don't find a line
2096 * terminator. (It's not set if we return -1.)
2099 tvb_find_line_end(tvbuff_t *tvb, gint offset, int len, gint *next_offset,
2107 len = tvb_length_remaining(tvb, offset);
2109 * XXX - what if "len" is still -1, meaning "offset is past the
2110 * end of the tvbuff"?
2112 eob_offset = offset + len;
2115 * Look either for a CR or an LF.
2117 eol_offset = tvb_pbrk_guint8(tvb, offset, len, (const guint8 *)"\r\n");
2118 if (eol_offset == -1) {
2120 * No CR or LF - line is presumably continued in next packet.
2124 * Tell our caller we saw no EOL, so they can
2125 * try to desegment and get the entire line
2131 * Pretend the line runs to the end of the tvbuff.
2133 linelen = eob_offset - offset;
2134 *next_offset = eob_offset;
2138 * Find the number of bytes between the starting offset
2141 linelen = eol_offset - offset;
2146 if (tvb_get_guint8(tvb, eol_offset) == '\r') {
2148 * Yes - is it followed by an LF?
2150 if (eol_offset + 1 >= eob_offset) {
2152 * Dunno - the next byte isn't in this
2157 * We'll return -1, although that
2158 * runs the risk that if the line
2159 * really *is* terminated with a CR,
2160 * we won't properly dissect this
2163 * It's probably more likely that
2164 * the line ends with CR-LF than
2165 * that it ends with CR by itself.
2171 * Well, we can at least look at the next
2174 if (tvb_get_guint8(tvb, eol_offset + 1) == '\n') {
2176 * It's an LF; skip over the CR.
2184 * Return the offset of the character after the last
2185 * character in the line, skipping over the last character
2186 * in the line terminator.
2188 *next_offset = eol_offset + 1;
2194 * Given a tvbuff, an offset into the tvbuff, and a length that starts
2195 * at that offset (which may be -1 for "all the way to the end of the
2196 * tvbuff"), find the end of the (putative) line that starts at the
2197 * specified offset in the tvbuff, going no further than the specified
2200 * However, treat quoted strings inside the buffer specially - don't
2201 * treat newlines in quoted strings as line terminators.
2203 * Return the length of the line (not counting the line terminator at
2204 * the end), or the amount of data remaining in the buffer if we don't
2205 * find a line terminator.
2207 * Set "*next_offset" to the offset of the character past the line
2208 * terminator, or past the end of the buffer if we don't find a line
2212 tvb_find_line_end_unquoted(tvbuff_t *tvb, gint offset, int len,
2215 gint cur_offset, char_offset;
2222 len = tvb_length_remaining(tvb, offset);
2224 * XXX - what if "len" is still -1, meaning "offset is past the
2225 * end of the tvbuff"?
2227 eob_offset = offset + len;
2229 cur_offset = offset;
2233 * Is this part of the string quoted?
2237 * Yes - look only for the terminating quote.
2239 char_offset = tvb_find_guint8(tvb, cur_offset, len,
2243 * Look either for a CR, an LF, or a '"'.
2245 char_offset = tvb_pbrk_guint8(tvb, cur_offset, len,
2246 (const guint8 *)"\r\n\"");
2248 if (char_offset == -1) {
2250 * Not found - line is presumably continued in
2252 * We pretend the line runs to the end of the tvbuff.
2254 linelen = eob_offset - offset;
2255 *next_offset = eob_offset;
2261 * We're processing a quoted string.
2262 * We only looked for ", so we know it's a ";
2263 * as we're processing a quoted string, it's a
2271 c = tvb_get_guint8(tvb, char_offset);
2274 * Un-quoted "; it begins a quoted
2280 * It's a CR or LF; we've found a line
2283 * Find the number of bytes between the
2284 * starting offset and the CR or LF.
2286 linelen = char_offset - offset;
2293 * Yes; is it followed by an LF?
2295 if (char_offset + 1 < eob_offset &&
2296 tvb_get_guint8(tvb, char_offset + 1)
2299 * Yes; skip over the CR.
2306 * Return the offset of the character after
2307 * the last character in the line, skipping
2308 * over the last character in the line
2309 * terminator, and quit.
2311 *next_offset = char_offset + 1;
2317 * Step past the character we found.
2319 cur_offset = char_offset + 1;
2320 if (cur_offset >= eob_offset) {
2322 * The character we found was the last character
2323 * in the tvbuff - line is presumably continued in
2325 * We pretend the line runs to the end of the tvbuff.
2327 linelen = eob_offset - offset;
2328 *next_offset = eob_offset;
2336 * Format a bunch of data from a tvbuff as bytes, returning a pointer
2337 * to the string with the formatted data, with "punct" as a byte
2341 tvb_bytes_to_str_punct(tvbuff_t *tvb, gint offset, gint len, gchar punct)
2343 return bytes_to_str_punct(tvb_get_ptr(tvb, offset, len), len, punct);
2347 * Format a bunch of data from a tvbuff as bytes, returning a pointer
2348 * to the string with the formatted data.
2351 tvb_bytes_to_str(tvbuff_t *tvb, gint offset, gint len)
2353 return bytes_to_str(tvb_get_ptr(tvb, offset, len), len);
2356 /* Find a needle tvbuff within a haystack tvbuff. */
2358 tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb, gint haystack_offset)
2360 guint haystack_abs_offset, haystack_abs_length;
2361 const guint8 *haystack_data;
2362 const guint8 *needle_data;
2363 const guint needle_len = needle_tvb->length;
2364 const guint8 *location;
2366 if (haystack_tvb->length < 1 || needle_tvb->length < 1) {
2370 /* Get pointers to the tvbuffs' data. */
2371 haystack_data = tvb_get_ptr(haystack_tvb, 0, -1);
2372 needle_data = tvb_get_ptr(needle_tvb, 0, -1);
2374 check_offset_length(haystack_tvb, haystack_offset, -1,
2375 &haystack_abs_offset, &haystack_abs_length);
2377 location = epan_memmem(haystack_data + haystack_abs_offset, haystack_abs_length,
2378 needle_data, needle_len);
2381 return location - haystack_data;
2392 * Uncompresses a zlib compressed packet inside a message of tvb at offset with
2393 * length comprlen. Returns an uncompressed tvbuffer if uncompression
2394 * succeeded or NULL if uncompression failed.
2396 #define TVB_Z_MIN_BUFSIZ 32768
2397 #define TVB_Z_MAX_BUFSIZ 1048576 * 10
2398 /* #define TVB_Z_DEBUG 1 */
2402 tvb_uncompress(tvbuff_t *tvb, int offset, int comprlen)
2407 guint bytes_out = 0;
2408 guint8 *compr = NULL;
2409 guint8 *uncompr = NULL;
2410 tvbuff_t *uncompr_tvb = NULL;
2411 z_streamp strm = NULL;
2412 Bytef *strmbuf = NULL;
2413 guint inits_done = 0;
2414 gint wbits = MAX_WBITS;
2415 guint8 *next = NULL;
2416 guint bufsiz = TVB_Z_MIN_BUFSIZ;
2418 guint inflate_passes = 0;
2419 guint bytes_in = tvb_length_remaining(tvb, offset);
2426 strm = g_malloc0(sizeof(z_stream));
2432 compr = tvb_memdup(tvb, offset, comprlen);
2440 * Assume that the uncompressed data is at least twice as big as
2441 * the compressed size.
2443 bufsiz = tvb_length_remaining(tvb, offset) * 2;
2445 if (bufsiz < TVB_Z_MIN_BUFSIZ) {
2446 bufsiz = TVB_Z_MIN_BUFSIZ;
2447 } else if (bufsiz > TVB_Z_MAX_BUFSIZ) {
2448 bufsiz = TVB_Z_MIN_BUFSIZ;
2452 printf("bufsiz: %u bytes\n", bufsiz);
2457 strm->next_in = next;
2458 strm->avail_in = comprlen;
2461 strmbuf = g_malloc0(bufsiz);
2463 if(strmbuf == NULL) {
2469 strm->next_out = strmbuf;
2470 strm->avail_out = bufsiz;
2472 err = inflateInit2(strm, wbits);
2483 memset(strmbuf, '\0', bufsiz);
2484 strm->next_out = strmbuf;
2485 strm->avail_out = bufsiz;
2487 err = inflate(strm, Z_SYNC_FLUSH);
2489 if (err == Z_OK || err == Z_STREAM_END) {
2490 guint bytes_pass = bufsiz - strm->avail_out;
2496 if (uncompr == NULL) {
2497 uncompr = g_memdup(strmbuf, bytes_pass);
2499 guint8 *new_data = g_malloc0(bytes_out +
2502 if (new_data == NULL) {
2508 if (uncompr != NULL) {
2515 g_memmove(new_data, uncompr, bytes_out);
2516 g_memmove((new_data + bytes_out), strmbuf,
2523 bytes_out += bytes_pass;
2525 if ( err == Z_STREAM_END) {
2531 } else if (err == Z_BUF_ERROR) {
2533 * It's possible that not enough frames were captured
2534 * to decompress this fully, so return what we've done
2541 if (uncompr != NULL) {
2548 } else if (err == Z_DATA_ERROR && inits_done == 1
2549 && uncompr == NULL && (*compr == 0x1f) &&
2550 (*(compr + 1) == 0x8b)) {
2552 * inflate() is supposed to handle both gzip and deflate
2553 * streams automatically, but in reality it doesn't
2554 * seem to handle either (at least not within the
2555 * context of an HTTP response.) We have to try
2556 * several tweaks, depending on the type of data and
2557 * version of the library installed.
2561 * Gzip file format. Skip past the header, since the
2562 * fix to make it work (setting windowBits to 31)
2563 * doesn't work with all versions of the library.
2565 Bytef *c = compr + 2;
2568 if (*c == Z_DEFLATED) {
2580 /* Skip past the MTIME, XFL, and OS fields. */
2583 if (flags & (1 << 2)) {
2584 /* An Extra field is present. */
2585 gint xsize = (gint)(*c |
2591 if (flags & (1 << 3)) {
2592 /* A null terminated filename */
2594 while (*c != '\0') {
2601 if (flags & (1 << 4)) {
2602 /* A null terminated comment */
2604 while (*c != '\0') {
2614 strm->next_in = next;
2615 if (c - compr > comprlen) {
2622 comprlen -= (c - compr);
2625 err = inflateInit2(strm, wbits);
2627 } else if (err == Z_DATA_ERROR && uncompr == NULL &&
2631 * Re-init the stream with a negative
2632 * MAX_WBITS. This is necessary due to
2633 * some servers (Apache) not sending
2634 * the deflate header with the
2635 * content-encoded response.
2641 strm->next_in = next;
2642 strm->avail_in = comprlen;
2644 memset(strmbuf, '\0', bufsiz);
2645 strm->next_out = strmbuf;
2646 strm->avail_out = bufsiz;
2648 err = inflateInit2(strm, wbits);
2666 if (uncompr == NULL) {
2675 printf("inflate() total passes: %u\n", inflate_passes);
2676 printf("bytes in: %u\nbytes out: %u\n\n", bytes_in, bytes_out);
2679 if (uncompr != NULL) {
2680 uncompr_tvb = tvb_new_real_data((guint8*) uncompr, bytes_out,
2682 tvb_set_free_cb(uncompr_tvb, g_free);
2689 tvb_uncompress(tvbuff_t *tvb _U_, int offset _U_, int comprlen _U_)