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 * 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.
54 ensure_contiguous_no_exception(tvbuff_t *tvb, gint offset, gint length,
58 ensure_contiguous(tvbuff_t *tvb, gint offset, gint length);
60 /* We dole out tvbuff's from this memchunk. */
61 GMemChunk *tvbuff_mem_chunk = NULL;
66 if (!tvbuff_mem_chunk)
67 tvbuff_mem_chunk = g_mem_chunk_create(tvbuff_t, 20, G_ALLOC_AND_FREE);
74 g_mem_chunk_destroy(tvbuff_mem_chunk);
76 tvbuff_mem_chunk = NULL;
83 tvb_init(tvbuff_t *tvb, tvbuff_type type)
85 tvb_backing_t *backing;
86 tvb_comp_t *composite;
89 tvb->initialized = FALSE;
92 tvb->reported_length = 0;
94 tvb->real_data = NULL;
100 case TVBUFF_REAL_DATA:
105 backing = &tvb->tvbuffs.subset;
111 case TVBUFF_COMPOSITE:
112 composite = &tvb->tvbuffs.composite;
113 composite->tvbs = NULL;
114 composite->start_offsets = NULL;
115 composite->end_offsets = NULL;
122 tvb_new(tvbuff_type type)
126 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 g_assert(tvb->type == TVBUFF_REAL_DATA);
240 add_to_used_in_list(tvbuff_t *tvb, tvbuff_t *used_in)
242 tvb->used_in = g_slist_prepend(tvb->used_in, used_in);
243 tvb_increment_usage_count(tvb, 1);
247 tvb_set_child_real_data_tvbuff(tvbuff_t* parent, tvbuff_t* child)
249 g_assert(parent->initialized);
250 g_assert(child->initialized);
251 g_assert(child->type == TVBUFF_REAL_DATA);
252 add_to_used_in_list(parent, child);
256 tvb_set_real_data(tvbuff_t* tvb, const guint8* data, guint length, gint reported_length)
258 g_assert(tvb->type == TVBUFF_REAL_DATA);
259 g_assert(!tvb->initialized);
261 if (reported_length < -1) {
262 THROW(ReportedBoundsError);
265 tvb->real_data = data;
266 tvb->length = length;
267 tvb->reported_length = reported_length;
268 tvb->initialized = TRUE;
272 tvb_new_real_data(const guint8* data, guint length, gint reported_length)
274 static tvbuff_t *last_tvb=NULL;
277 tvb = tvb_new(TVBUFF_REAL_DATA);
282 /* remember this tvb in case we throw an exception and
283 * lose the pointer to it.
287 tvb_set_real_data(tvb, data, length, reported_length);
290 * This is the top-level real tvbuff for this data source,
291 * so its data source tvbuff is itself.
295 /* ok no exception so we dont need to remember it any longer */
301 /* Computes the absolute offset and length based on a possibly-negative offset
302 * and a length that is possible -1 (which means "to the end of the data").
303 * Returns TRUE/FALSE indicating whether the offset is in bounds or
304 * not. The integer ptrs are modified with the new offset and length.
305 * No exception is thrown.
307 * XXX - we return TRUE, not FALSE, if the offset is positive and right
308 * after the end of the tvbuff (i.e., equal to the length). We do this
309 * so that a dissector constructing a subset tvbuff for the next protocol
310 * will get a zero-length tvbuff, not an exception, if there's no data
311 * left for the next protocol - we want the next protocol to be the one
312 * that gets an exception, so the error is reported as an error in that
313 * protocol rather than the containing protocol. */
315 compute_offset_length(tvbuff_t *tvb, gint offset, gint length,
316 guint *offset_ptr, guint *length_ptr, int *exception)
318 g_assert(offset_ptr);
319 g_assert(length_ptr);
321 /* Compute the offset */
323 /* Positive offset - relative to the beginning of the packet. */
324 if ((guint) offset > tvb->reported_length) {
326 *exception = ReportedBoundsError;
330 else if ((guint) offset > tvb->length) {
332 *exception = BoundsError;
337 *offset_ptr = offset;
341 /* Negative offset - relative to the end of the packet. */
342 if ((guint) -offset > tvb->reported_length) {
344 *exception = ReportedBoundsError;
348 else if ((guint) -offset > tvb->length) {
350 *exception = BoundsError;
355 *offset_ptr = tvb->length + offset;
359 /* Compute the length */
362 /* XXX - ReportedBoundsError? */
363 *exception = BoundsError;
367 else if (length == -1) {
368 *length_ptr = tvb->length - *offset_ptr;
371 *length_ptr = length;
379 check_offset_length_no_exception(tvbuff_t *tvb, gint offset, gint length,
380 guint *offset_ptr, guint *length_ptr, int *exception)
384 g_assert(tvb->initialized);
386 if (!compute_offset_length(tvb, offset, length, offset_ptr, length_ptr, exception)) {
391 * Compute the offset of the first byte past the length.
393 end_offset = *offset_ptr + *length_ptr;
396 * Check for an overflow, and clamp "end_offset" at the maximum
397 * if we got an overflow - that should force us to indicate that
398 * we're past the end of the tvbuff.
400 if (end_offset < *offset_ptr)
401 end_offset = UINT_MAX;
404 * Check whether that offset goes more than one byte past the
407 * If not, return TRUE; otherwise, return FALSE and, if "exception"
408 * is non-null, return the appropriate exception through it.
410 if (end_offset <= tvb->length) {
413 else if (end_offset <= tvb->reported_length) {
415 *exception = BoundsError;
421 *exception = ReportedBoundsError;
426 g_assert_not_reached();
429 /* Checks (+/-) offset and length and throws an exception if
430 * either is out of bounds. Sets integer ptrs to the new offset
433 check_offset_length(tvbuff_t *tvb, gint offset, gint length,
434 guint *offset_ptr, guint *length_ptr)
438 if (!check_offset_length_no_exception(tvb, offset, length, offset_ptr, length_ptr, &exception)) {
439 g_assert(exception > 0);
447 tvb_set_subset(tvbuff_t *tvb, tvbuff_t *backing,
448 gint backing_offset, gint backing_length, gint reported_length)
450 g_assert(tvb->type == TVBUFF_SUBSET);
451 g_assert(!tvb->initialized);
453 if (reported_length < -1) {
454 THROW(ReportedBoundsError);
457 check_offset_length(backing, backing_offset, backing_length,
458 &tvb->tvbuffs.subset.offset,
459 &tvb->tvbuffs.subset.length);
461 tvb->tvbuffs.subset.tvb = backing;
462 tvb->length = tvb->tvbuffs.subset.length;
464 if (reported_length == -1) {
465 tvb->reported_length = backing->reported_length - tvb->tvbuffs.subset.offset;
468 tvb->reported_length = reported_length;
470 tvb->initialized = TRUE;
471 add_to_used_in_list(backing, tvb);
473 /* Optimization. If the backing buffer has a pointer to contiguous, real data,
474 * then we can point directly to our starting offset in that buffer */
475 if (backing->real_data != NULL) {
476 tvb->real_data = backing->real_data + tvb->tvbuffs.subset.offset;
482 tvb_new_subset(tvbuff_t *backing, gint backing_offset, gint backing_length, gint reported_length)
484 static tvbuff_t *last_tvb=NULL;
487 tvb = tvb_new(TVBUFF_SUBSET);
492 /* remember this tvb in case we throw an exception and
493 * lose the pointer to it.
497 tvb_set_subset(tvb, backing, backing_offset, backing_length, reported_length);
500 * The top-level data source of this tvbuff is the top-level
501 * data source of its parent.
503 tvb->ds_tvb = backing->ds_tvb;
505 /* ok no exception so we dont need to remember it any longer */
512 tvb_composite_append(tvbuff_t* tvb, tvbuff_t* member)
514 tvb_comp_t *composite;
516 g_assert(!tvb->initialized);
517 composite = &tvb->tvbuffs.composite;
518 composite->tvbs = g_slist_append( composite->tvbs, member );
519 add_to_used_in_list(member, tvb);
523 tvb_composite_prepend(tvbuff_t* tvb, tvbuff_t* member)
525 tvb_comp_t *composite;
527 g_assert(!tvb->initialized);
528 composite = &tvb->tvbuffs.composite;
529 composite->tvbs = g_slist_prepend( composite->tvbs, member );
530 add_to_used_in_list(member, tvb);
534 tvb_new_composite(void)
536 return tvb_new(TVBUFF_COMPOSITE);
540 tvb_composite_finalize(tvbuff_t* tvb)
544 tvbuff_t *member_tvb;
545 tvb_comp_t *composite;
548 g_assert(!tvb->initialized);
549 g_assert(tvb->length == 0);
551 composite = &tvb->tvbuffs.composite;
552 num_members = g_slist_length(composite->tvbs);
554 composite->start_offsets = g_new(guint, num_members);
555 composite->end_offsets = g_new(guint, num_members);
557 for (slist = composite->tvbs; slist != NULL; slist = slist->next) {
558 g_assert((guint) i < num_members);
559 member_tvb = slist->data;
560 composite->start_offsets[i] = tvb->length;
561 tvb->length += member_tvb->length;
562 composite->end_offsets[i] = tvb->length - 1;
566 tvb->initialized = TRUE;
572 tvb_length(tvbuff_t* tvb)
574 g_assert(tvb->initialized);
580 tvb_length_remaining(tvbuff_t *tvb, gint offset)
582 guint abs_offset, abs_length;
584 g_assert(tvb->initialized);
586 if (compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL)) {
595 tvb_ensure_length_remaining(tvbuff_t *tvb, gint offset)
597 guint abs_offset, abs_length;
600 g_assert(tvb->initialized);
602 if (!compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, &exception)) {
605 if (abs_length == 0) {
607 * This routine ensures there's at least one byte available.
608 * There aren't any bytes available, so throw the appropriate
611 if (abs_offset >= tvb->reported_length)
612 THROW(ReportedBoundsError);
622 /* Validates that 'length' bytes are available starting from
623 * offset (pos/neg). Does not throw an exception. */
625 tvb_bytes_exist(tvbuff_t *tvb, gint offset, gint length)
627 guint abs_offset, abs_length;
629 g_assert(tvb->initialized);
631 if (!compute_offset_length(tvb, offset, length, &abs_offset, &abs_length, NULL))
634 if (abs_offset + abs_length <= tvb->length) {
642 /* Validates that 'length' bytes are available starting from
643 * offset (pos/neg). Throws an exception if they aren't. */
645 tvb_ensure_bytes_exist(tvbuff_t *tvb, gint offset, gint length)
647 guint abs_offset, abs_length;
649 g_assert(tvb->initialized);
652 * -1 doesn't mean "until end of buffer", as that's pointless
653 * for this routine. We must treat it as a Really Large Positive
654 * Number, so that we throw an exception; we throw
655 * ReportedBoundsError, as if it were past even the end of a
656 * reassembled packet, and past the end of even the data we
659 * We do the same with other negative lengths.
662 THROW(ReportedBoundsError);
664 check_offset_length(tvb, offset, length, &abs_offset, &abs_length);
668 tvb_offset_exists(tvbuff_t *tvb, gint offset)
670 guint abs_offset, abs_length;
672 g_assert(tvb->initialized);
673 if (!compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL))
676 if (abs_offset < tvb->length) {
685 tvb_reported_length(tvbuff_t* tvb)
687 g_assert(tvb->initialized);
689 return tvb->reported_length;
693 tvb_reported_length_remaining(tvbuff_t *tvb, gint offset)
695 guint abs_offset, abs_length;
697 g_assert(tvb->initialized);
699 if (compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL)) {
700 if (tvb->reported_length >= abs_offset)
701 return tvb->reported_length - abs_offset;
710 /* Set the reported length of a tvbuff to a given value; used for protocols
711 whose headers contain an explicit length and where the calling
712 dissector's payload may include padding as well as the packet for
715 Also adjusts the data length. */
717 tvb_set_reported_length(tvbuff_t* tvb, guint reported_length)
719 g_assert(tvb->initialized);
721 if (reported_length > tvb->reported_length)
722 THROW(ReportedBoundsError);
724 tvb->reported_length = reported_length;
725 if (reported_length < tvb->length)
726 tvb->length = reported_length;
731 first_real_data_ptr(tvbuff_t *tvb)
736 case TVBUFF_REAL_DATA:
737 return tvb->real_data;
739 member = tvb->tvbuffs.subset.tvb;
740 return first_real_data_ptr(member);
741 case TVBUFF_COMPOSITE:
742 member = tvb->tvbuffs.composite.tvbs->data;
743 return first_real_data_ptr(member);
746 g_assert_not_reached();
751 offset_from_real_beginning(tvbuff_t *tvb, int counter)
756 case TVBUFF_REAL_DATA:
759 member = tvb->tvbuffs.subset.tvb;
760 return offset_from_real_beginning(member, counter + tvb->tvbuffs.subset.offset);
761 case TVBUFF_COMPOSITE:
762 member = tvb->tvbuffs.composite.tvbs->data;
763 return offset_from_real_beginning(member, counter);
766 g_assert_not_reached();
771 composite_ensure_contiguous_no_exception(tvbuff_t *tvb, guint abs_offset,
774 guint i, num_members;
775 tvb_comp_t *composite;
776 tvbuff_t *member_tvb = NULL;
777 guint member_offset, member_length;
780 g_assert(tvb->type == TVBUFF_COMPOSITE);
782 /* Maybe the range specified by offset/length
783 * is contiguous inside one of the member tvbuffs */
784 composite = &tvb->tvbuffs.composite;
785 num_members = g_slist_length(composite->tvbs);
787 for (i = 0; i < num_members; i++) {
788 if (abs_offset <= composite->end_offsets[i]) {
789 slist = g_slist_nth(composite->tvbs, i);
790 member_tvb = slist->data;
794 g_assert(member_tvb);
796 if (check_offset_length_no_exception(member_tvb, abs_offset - composite->start_offsets[i],
797 abs_length, &member_offset, &member_length, NULL)) {
800 * The range is, in fact, contiguous within member_tvb.
802 g_assert(!tvb->real_data);
803 return ensure_contiguous_no_exception(member_tvb, member_offset, member_length, NULL);
806 tvb->real_data = tvb_memdup(tvb, 0, -1);
807 return tvb->real_data + abs_offset;
810 g_assert_not_reached();
815 ensure_contiguous_no_exception(tvbuff_t *tvb, gint offset, gint length,
818 guint abs_offset, abs_length;
820 if (!check_offset_length_no_exception(tvb, offset, length,
821 &abs_offset, &abs_length, exception)) {
826 * We know that all the data is present in the tvbuff, so
827 * no exceptions should be thrown.
829 if (tvb->real_data) {
830 return tvb->real_data + abs_offset;
834 case TVBUFF_REAL_DATA:
835 g_assert_not_reached();
837 return ensure_contiguous_no_exception(tvb->tvbuffs.subset.tvb,
838 abs_offset - tvb->tvbuffs.subset.offset,
840 case TVBUFF_COMPOSITE:
841 return composite_ensure_contiguous_no_exception(tvb, abs_offset, abs_length);
845 g_assert_not_reached();
850 ensure_contiguous(tvbuff_t *tvb, gint offset, gint length)
855 p = ensure_contiguous_no_exception(tvb, offset, length, &exception);
857 g_assert(exception > 0);
864 guint8_find(const guint8* haystack, size_t haystacklen, guint8 needle)
869 for (b = haystack, i = 0; (guint) i < haystacklen; i++, b++) {
879 guint8_pbrk(const guint8* haystack, size_t haystacklen, guint8 *needles)
883 guint8 item, *needlep, needle;
885 for (b = haystack, i = 0; (guint) i < haystacklen; i++, b++) {
888 while ((needle = *needlep) != '\0') {
900 /************** ACCESSORS **************/
903 composite_memcpy(tvbuff_t *tvb, guint8* target, guint abs_offset, guint abs_length)
905 guint i, num_members;
906 tvb_comp_t *composite;
907 tvbuff_t *member_tvb = NULL;
908 guint member_offset, member_length;
912 g_assert(tvb->type == TVBUFF_COMPOSITE);
914 /* Maybe the range specified by offset/length
915 * is contiguous inside one of the member tvbuffs */
916 composite = &tvb->tvbuffs.composite;
917 num_members = g_slist_length(composite->tvbs);
919 for (i = 0; i < num_members; i++) {
920 if (abs_offset <= composite->end_offsets[i]) {
921 slist = g_slist_nth(composite->tvbs, i);
922 member_tvb = slist->data;
926 g_assert(member_tvb);
928 if (check_offset_length_no_exception(member_tvb, abs_offset - composite->start_offsets[i],
929 abs_length, &member_offset, &member_length, NULL)) {
931 g_assert(!tvb->real_data);
932 return tvb_memcpy(member_tvb, target, member_offset, member_length);
935 /* The requested data is non-contiguous inside
936 * the member tvb. We have to memcpy() the part that's in the member tvb,
937 * then iterate across the other member tvb's, copying their portions
938 * until we have copied all data.
940 retval = compute_offset_length(member_tvb, abs_offset - composite->start_offsets[i], -1,
941 &member_offset, &member_length, NULL);
944 tvb_memcpy(member_tvb, target, member_offset, member_length);
945 abs_offset += member_length;
946 abs_length -= member_length;
949 if (abs_length > 0) {
950 composite_memcpy(tvb, target + member_length, abs_offset, abs_length);
956 g_assert_not_reached();
961 tvb_memcpy(tvbuff_t *tvb, guint8* target, gint offset, gint length)
963 guint abs_offset, abs_length;
965 g_assert(length >= -1);
966 check_offset_length(tvb, offset, length, &abs_offset, &abs_length);
968 if (tvb->real_data) {
969 return (guint8*) memcpy(target, tvb->real_data + abs_offset, abs_length);
973 case TVBUFF_REAL_DATA:
974 g_assert_not_reached();
977 return tvb_memcpy(tvb->tvbuffs.subset.tvb, target,
978 abs_offset - tvb->tvbuffs.subset.offset,
981 case TVBUFF_COMPOSITE:
982 return composite_memcpy(tvb, target, offset, length);
985 g_assert_not_reached();
991 * XXX - this doesn't treat a length of -1 as an error.
992 * If it did, this could replace some code that calls
993 * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies
996 * "composite_ensure_contiguous_no_exception()" depends on -1 not being
997 * an error; does anything else depend on this routine treating -1 as
998 * meaning "to the end of the buffer"?
1001 tvb_memdup(tvbuff_t *tvb, gint offset, gint length)
1003 guint abs_offset, abs_length;
1006 check_offset_length(tvb, offset, length, &abs_offset, &abs_length);
1008 duped = g_malloc(abs_length);
1009 return tvb_memcpy(tvb, duped, abs_offset, abs_length);
1013 * XXX - this doesn't treat a length of -1 as an error.
1014 * If it did, this could replace some code that calls
1015 * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies
1018 * "composite_ensure_contiguous_no_exception()" depends on -1 not being
1019 * an error; does anything else depend on this routine treating -1 as
1020 * meaning "to the end of the buffer"?
1022 * This function allocates memory from a buffer with packet lifetime.
1023 * You do not have to free this buffer, it will be automatically freed
1024 * when ethereal starts decoding the next packet.
1025 * Do not use this function if you want the allocated memory to be persistent
1026 * after the current packet has been dissected.
1029 ep_tvb_memdup(tvbuff_t *tvb, gint offset, gint length)
1031 guint abs_offset, abs_length;
1034 check_offset_length(tvb, offset, length, &abs_offset, &abs_length);
1036 duped = ep_alloc(abs_length);
1037 return tvb_memcpy(tvb, duped, abs_offset, abs_length);
1043 tvb_get_ptr(tvbuff_t *tvb, gint offset, gint length)
1045 return ensure_contiguous(tvb, offset, length);
1049 tvb_get_guint8(tvbuff_t *tvb, gint offset)
1053 ptr = ensure_contiguous(tvb, offset, sizeof(guint8));
1058 tvb_get_ntohs(tvbuff_t *tvb, gint offset)
1062 ptr = ensure_contiguous(tvb, offset, sizeof(guint16));
1067 tvb_get_ntoh24(tvbuff_t *tvb, gint offset)
1071 ptr = ensure_contiguous(tvb, offset, 3);
1072 return pntoh24(ptr);
1076 tvb_get_ntohl(tvbuff_t *tvb, gint offset)
1080 ptr = ensure_contiguous(tvb, offset, sizeof(guint32));
1085 tvb_get_ntoh64(tvbuff_t *tvb, gint offset)
1089 ptr = ensure_contiguous(tvb, offset, sizeof(guint64));
1090 return pntoh64(ptr);
1094 * Stuff for IEEE float handling on platforms that don't have IEEE
1095 * format as the native floating-point format.
1097 * For now, we treat only the VAX as such a platform.
1099 * XXX - other non-IEEE boxes that can run UNIX include some Crays,
1100 * and possibly other machines.
1102 * It appears that the official Linux port to System/390 and
1103 * zArchitecture uses IEEE format floating point (not a
1106 * I don't know whether there are any other machines that
1107 * could run Ethereal and that don't use IEEE format.
1108 * As far as I know, all of the main commercial microprocessor
1109 * families on which OSes that support Ethereal can run
1110 * use IEEE format (x86, 68k, SPARC, MIPS, PA-RISC, Alpha,
1111 * IA-64, and so on).
1121 #define IEEE_SP_NUMBER_WIDTH 32 /* bits in number */
1122 #define IEEE_SP_EXP_WIDTH 8 /* bits in exponent */
1123 #define IEEE_SP_MANTISSA_WIDTH 23 /* IEEE_SP_NUMBER_WIDTH - 1 - IEEE_SP_EXP_WIDTH */
1125 #define IEEE_SP_SIGN_MASK 0x80000000
1126 #define IEEE_SP_EXPONENT_MASK 0x7F800000
1127 #define IEEE_SP_MANTISSA_MASK 0x007FFFFF
1128 #define IEEE_SP_INFINITY IEEE_SP_EXPONENT_MASK
1130 #define IEEE_SP_IMPLIED_BIT (1 << IEEE_SP_MANTISSA_WIDTH)
1131 #define IEEE_SP_INFINITE ((1 << IEEE_SP_EXP_WIDTH) - 1)
1132 #define IEEE_SP_BIAS ((1 << (IEEE_SP_EXP_WIDTH - 1)) - 1)
1135 ieee_float_is_zero(guint32 w)
1137 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1141 get_ieee_float(guint32 w)
1147 sign = w & IEEE_SP_SIGN_MASK;
1148 exponent = w & IEEE_SP_EXPONENT_MASK;
1149 mantissa = w & IEEE_SP_MANTISSA_MASK;
1151 if (ieee_float_is_zero(w)) {
1152 /* number is zero, unnormalized, or not-a-number */
1157 * XXX - how to handle this?
1159 if (IEEE_SP_INFINITY == exponent) {
1161 * number is positive or negative infinity, or a special value
1163 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1167 exponent = ((exponent >> IEEE_SP_MANTISSA_WIDTH) - IEEE_SP_BIAS) -
1168 IEEE_SP_MANTISSA_WIDTH;
1169 mantissa |= IEEE_SP_IMPLIED_BIT;
1172 return -mantissa * pow(2, exponent);
1174 return mantissa * pow(2, exponent);
1179 * We assume that if you don't have IEEE floating-point, you have a
1180 * compiler that understands 64-bit integral quantities.
1182 #define IEEE_DP_NUMBER_WIDTH 64 /* bits in number */
1183 #define IEEE_DP_EXP_WIDTH 11 /* bits in exponent */
1184 #define IEEE_DP_MANTISSA_WIDTH 52 /* IEEE_DP_NUMBER_WIDTH - 1 - IEEE_DP_EXP_WIDTH */
1186 #define IEEE_DP_SIGN_MASK 0x8000000000000000LL
1187 #define IEEE_DP_EXPONENT_MASK 0x7FF0000000000000LL
1188 #define IEEE_DP_MANTISSA_MASK 0x000FFFFFFFFFFFFFLL
1189 #define IEEE_DP_INFINITY IEEE_DP_EXPONENT_MASK
1191 #define IEEE_DP_IMPLIED_BIT (1LL << IEEE_DP_MANTISSA_WIDTH)
1192 #define IEEE_DP_INFINITE ((1 << IEEE_DP_EXP_WIDTH) - 1)
1193 #define IEEE_DP_BIAS ((1 << (IEEE_DP_EXP_WIDTH - 1)) - 1)
1196 ieee_double_is_zero(guint64 w)
1198 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1202 get_ieee_double(guint64 w)
1208 sign = w & IEEE_DP_SIGN_MASK;
1209 exponent = w & IEEE_DP_EXPONENT_MASK;
1210 mantissa = w & IEEE_DP_MANTISSA_MASK;
1212 if (ieee_double_is_zero(w)) {
1213 /* number is zero, unnormalized, or not-a-number */
1218 * XXX - how to handle this?
1220 if (IEEE_DP_INFINITY == exponent) {
1222 * number is positive or negative infinity, or a special value
1224 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1228 exponent = ((exponent >> IEEE_DP_MANTISSA_WIDTH) - IEEE_DP_BIAS) -
1229 IEEE_DP_MANTISSA_WIDTH;
1230 mantissa |= IEEE_DP_IMPLIED_BIT;
1233 return -mantissa * pow(2, exponent);
1235 return mantissa * pow(2, exponent);
1240 * Fetches an IEEE single-precision floating-point number, in
1241 * big-endian form, and returns a "float".
1243 * XXX - should this be "double", in case there are IEEE single-
1244 * precision numbers that won't fit in some platform's native
1248 tvb_get_ntohieee_float(tvbuff_t *tvb, int offset)
1251 return get_ieee_float(tvb_get_ntohl(tvb, offset));
1258 ieee_fp_union.w = tvb_get_ntohl(tvb, offset);
1259 return ieee_fp_union.f;
1264 * Fetches an IEEE double-precision floating-point number, in
1265 * big-endian form, and returns a "double".
1268 tvb_get_ntohieee_double(tvbuff_t *tvb, int offset)
1282 #ifdef WORDS_BIGENDIAN
1283 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset);
1284 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset+4);
1286 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset+4);
1287 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset);
1290 return get_ieee_double(ieee_fp_union.dw);
1292 return ieee_fp_union.d;
1297 tvb_get_letohs(tvbuff_t *tvb, gint offset)
1301 ptr = ensure_contiguous(tvb, offset, sizeof(guint16));
1302 return pletohs(ptr);
1306 tvb_get_letoh24(tvbuff_t *tvb, gint offset)
1310 ptr = ensure_contiguous(tvb, offset, 3);
1311 return pletoh24(ptr);
1315 tvb_get_letohl(tvbuff_t *tvb, gint offset)
1319 ptr = ensure_contiguous(tvb, offset, sizeof(guint32));
1320 return pletohl(ptr);
1324 tvb_get_letoh64(tvbuff_t *tvb, gint offset)
1328 ptr = ensure_contiguous(tvb, offset, sizeof(guint64));
1329 return pletoh64(ptr);
1333 * Fetches an IEEE single-precision floating-point number, in
1334 * little-endian form, and returns a "float".
1336 * XXX - should this be "double", in case there are IEEE single-
1337 * precision numbers that won't fit in some platform's native
1341 tvb_get_letohieee_float(tvbuff_t *tvb, int offset)
1344 return get_ieee_float(tvb_get_letohl(tvb, offset));
1351 ieee_fp_union.w = tvb_get_letohl(tvb, offset);
1352 return ieee_fp_union.f;
1357 * Fetches an IEEE double-precision floating-point number, in
1358 * little-endian form, and returns a "double".
1361 tvb_get_letohieee_double(tvbuff_t *tvb, int offset)
1375 #ifdef WORDS_BIGENDIAN
1376 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset+4);
1377 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset);
1379 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset);
1380 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset+4);
1383 return get_ieee_double(ieee_fp_union.dw);
1385 return ieee_fp_union.d;
1389 /* Find first occurence of needle in tvbuff, starting at offset. Searches
1390 * at most maxlength number of bytes; if maxlength is -1, searches to
1392 * Returns the offset of the found needle, or -1 if not found.
1393 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1394 * in that case, -1 will be returned if the boundary is reached before
1395 * finding needle. */
1397 tvb_find_guint8(tvbuff_t *tvb, gint offset, gint maxlength, guint8 needle)
1399 const guint8 *result;
1400 guint abs_offset, junk_length;
1404 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1406 /* Only search to end of tvbuff, w/o throwing exception. */
1407 tvbufflen = tvb_length_remaining(tvb, abs_offset);
1408 if (maxlength == -1) {
1409 /* No maximum length specified; search to end of tvbuff. */
1412 else if (tvbufflen < (guint) maxlength) {
1413 /* Maximum length goes past end of tvbuff; search to end
1418 /* Maximum length doesn't go past end of tvbuff; search
1423 /* If we have real data, perform our search now. */
1424 if (tvb->real_data) {
1425 result = guint8_find(tvb->real_data + abs_offset, limit, needle);
1426 if (result == NULL) {
1430 return result - tvb->real_data;
1435 case TVBUFF_REAL_DATA:
1436 g_assert_not_reached();
1439 return tvb_find_guint8(tvb->tvbuffs.subset.tvb,
1440 abs_offset - tvb->tvbuffs.subset.offset,
1443 case TVBUFF_COMPOSITE:
1444 g_assert_not_reached();
1445 /* XXX - return composite_find_guint8(tvb, offset, limit, needle); */
1448 g_assert_not_reached();
1452 /* Find first occurence of any of the needles in tvbuff, starting at offset.
1453 * Searches at most maxlength number of bytes; if maxlength is -1, searches
1455 * Returns the offset of the found needle, or -1 if not found.
1456 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1457 * in that case, -1 will be returned if the boundary is reached before
1458 * finding needle. */
1460 tvb_pbrk_guint8(tvbuff_t *tvb, gint offset, gint maxlength, guint8 *needles)
1462 const guint8 *result;
1463 guint abs_offset, junk_length;
1467 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1469 /* Only search to end of tvbuff, w/o throwing exception. */
1470 tvbufflen = tvb_length_remaining(tvb, abs_offset);
1471 if (maxlength == -1) {
1472 /* No maximum length specified; search to end of tvbuff. */
1475 else if (tvbufflen < (guint) maxlength) {
1476 /* Maximum length goes past end of tvbuff; search to end
1481 /* Maximum length doesn't go past end of tvbuff; search
1486 /* If we have real data, perform our search now. */
1487 if (tvb->real_data) {
1488 result = guint8_pbrk(tvb->real_data + abs_offset, limit, needles);
1489 if (result == NULL) {
1493 return result - tvb->real_data;
1498 case TVBUFF_REAL_DATA:
1499 g_assert_not_reached();
1502 return tvb_pbrk_guint8(tvb->tvbuffs.subset.tvb,
1503 abs_offset - tvb->tvbuffs.subset.offset,
1506 case TVBUFF_COMPOSITE:
1507 g_assert_not_reached();
1508 /* XXX - return composite_pbrk_guint8(tvb, offset, limit, needle); */
1511 g_assert_not_reached();
1515 /* Find size of stringz (NUL-terminated string) by looking for terminating
1516 * NUL. The size of the string includes the terminating NUL.
1518 * If the NUL isn't found, it throws the appropriate exception.
1521 tvb_strsize(tvbuff_t *tvb, gint offset)
1523 guint abs_offset, junk_length;
1526 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1527 nul_offset = tvb_find_guint8(tvb, abs_offset, -1, 0);
1528 if (nul_offset == -1) {
1530 * OK, we hit the end of the tvbuff, so we should throw
1533 * Did we hit the end of the captured data, or the end
1534 * of the actual data? If there's less captured data
1535 * than actual data, we presumably hit the end of the
1536 * captured data, otherwise we hit the end of the actual
1539 if (tvb_length(tvb) < tvb_reported_length(tvb)) {
1542 THROW(ReportedBoundsError);
1545 return (nul_offset - abs_offset) + 1;
1548 /* Find length of string by looking for end of string ('\0'), up to
1549 * 'maxlength' characters'; if 'maxlength' is -1, searches to end
1551 * Returns -1 if 'maxlength' reached before finding EOS. */
1553 tvb_strnlen(tvbuff_t *tvb, gint offset, guint maxlength)
1556 guint abs_offset, junk_length;
1558 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1560 result_offset = tvb_find_guint8(tvb, abs_offset, maxlength, 0);
1562 if (result_offset == -1) {
1566 return result_offset - abs_offset;
1571 * Implement strneql etc
1575 * Call strncmp after checking if enough chars left, returning 0 if
1576 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1579 tvb_strneql(tvbuff_t *tvb, gint offset, const gchar *str, gint size)
1583 ptr = ensure_contiguous_no_exception(tvb, offset, size, NULL);
1586 int cmp = strncmp((const char *)ptr, str, size);
1589 * Return 0 if equal, -1 otherwise.
1591 return (cmp == 0 ? 0 : -1);
1594 * Not enough characters in the tvbuff to match the
1602 * Call strncasecmp after checking if enough chars left, returning 0 if
1603 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1606 tvb_strncaseeql(tvbuff_t *tvb, gint offset, const gchar *str, gint size)
1610 ptr = ensure_contiguous_no_exception(tvb, offset, size, NULL);
1613 int cmp = strncasecmp((const char *)ptr, str, size);
1616 * Return 0 if equal, -1 otherwise.
1618 return (cmp == 0 ? 0 : -1);
1621 * Not enough characters in the tvbuff to match the
1629 * Call memcmp after checking if enough chars left, returning 0 if
1630 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1633 tvb_memeql(tvbuff_t *tvb, gint offset, const guint8 *str, gint size)
1637 ptr = ensure_contiguous_no_exception(tvb, offset, size, NULL);
1640 int cmp = memcmp(ptr, str, size);
1643 * Return 0 if equal, -1 otherwise.
1645 return (cmp == 0 ? 0 : -1);
1648 * Not enough characters in the tvbuff to match the
1655 /* Convert a string from Unicode to ASCII. At the moment we fake it by
1656 * replacing all non-ASCII characters with a '.' )-: The caller must
1657 * free the result returned. The len parameter is the number of guint16's
1658 * to convert from Unicode. */
1660 tvb_fake_unicode(tvbuff_t *tvb, int offset, int len, gboolean little_endian)
1666 /* Make sure we have enough data before allocating the buffer,
1667 so we don't blow up if the length is huge. */
1668 tvb_ensure_bytes_exist(tvb, offset, 2*len);
1670 /* We know we won't throw an exception, so we don't have to worry
1671 about leaking this buffer. */
1672 buffer = g_malloc(len + 1);
1674 for (i = 0; i < len; i++) {
1675 character = little_endian ? tvb_get_letohs(tvb, offset)
1676 : tvb_get_ntohs(tvb, offset);
1677 buffer[i] = character < 256 ? character : '.';
1687 * Format the data in the tvb from offset for length ...
1691 tvb_format_text(tvbuff_t *tvb, gint offset, gint size)
1696 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
1698 len = tvb_length_remaining(tvb, offset);
1699 ptr = ensure_contiguous(tvb, offset, len);
1703 return format_text(ptr, len);
1708 * Like "tvb_format_text()", but for null-padded strings; don't show
1709 * the null padding characters as "\000".
1712 tvb_format_stringzpad(tvbuff_t *tvb, gint offset, gint size)
1714 const guint8 *ptr, *p;
1718 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
1720 len = tvb_length_remaining(tvb, offset);
1721 ptr = ensure_contiguous(tvb, offset, len);
1725 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
1727 return format_text(ptr, stringlen);
1732 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
1733 * to hold a non-null-terminated string of that length at that offset,
1734 * plus a trailing '\0', copy the string into it, and return a pointer
1737 * Throws an exception if the tvbuff ends before the string does.
1740 tvb_get_string(tvbuff_t *tvb, gint offset, gint length)
1743 guint8 *strbuf = NULL;
1745 tvb_ensure_bytes_exist(tvb, offset, length);
1747 ptr = ensure_contiguous(tvb, offset, length);
1748 strbuf = g_malloc(length + 1);
1750 memcpy(strbuf, ptr, length);
1752 strbuf[length] = '\0';
1756 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
1757 * to hold a non-null-terminated string of that length at that offset,
1758 * plus a trailing '\0', copy the string into it, and return a pointer
1761 * Throws an exception if the tvbuff ends before the string does.
1763 * This function allocates memory from a buffer with packet lifetime.
1764 * You do not have to free this buffer, it will be automatically freed
1765 * when ethereal starts decoding the next packet.
1766 * Do not use this function if you want the allocated memory to be persistent
1767 * after the current packet has been dissected.
1770 ep_tvb_get_string(tvbuff_t *tvb, gint offset, gint length)
1773 guint8 *strbuf = NULL;
1775 tvb_ensure_bytes_exist(tvb, offset, length);
1777 ptr = ensure_contiguous(tvb, offset, length);
1778 strbuf = ep_alloc(length + 1);
1780 memcpy(strbuf, ptr, length);
1782 strbuf[length] = '\0';
1788 * Given a tvbuff and an offset, with the offset assumed to refer to
1789 * a null-terminated string, find the length of that string (and throw
1790 * an exception if the tvbuff ends before we find the null), allocate
1791 * a buffer big enough to hold the string, copy the string into it,
1792 * and return a pointer to the string. Also return the length of the
1793 * string (including the terminating null) through a pointer.
1796 tvb_get_stringz(tvbuff_t *tvb, gint offset, gint *lengthp)
1801 size = tvb_strsize(tvb, offset);
1802 strptr = g_malloc(size);
1803 tvb_memcpy(tvb, strptr, offset, size);
1808 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
1809 * no more than bufsize number of bytes, including terminating NUL, to buffer.
1810 * Returns length of string (not including terminating NUL), or -1 if the string was
1811 * truncated in the buffer due to not having reached the terminating NUL.
1812 * In this way, it acts like snprintf().
1814 * bufsize MUST be greater than 0.
1816 * When processing a packet where the remaining number of bytes is less
1817 * than bufsize, an exception is not thrown if the end of the packet
1818 * is reached before the NUL is found. If no NUL is found before reaching
1819 * the end of the short packet, -1 is still returned, and the string
1820 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
1821 * at the correct spot, terminating the string.
1823 * *bytes_copied will contain the number of bytes actually copied,
1824 * including the terminating-NUL.
1827 _tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer,
1831 guint abs_offset, junk_length;
1833 gboolean decreased_max = FALSE;
1835 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1837 /* There must at least be room for the terminating NUL. */
1838 g_assert(bufsize != 0);
1840 /* If there's no room for anything else, just return the NUL. */
1847 /* Only read to end of tvbuff, w/o throwing exception. */
1848 len = tvb_length_remaining(tvb, abs_offset);
1850 /* check_offset_length() won't throw an exception if we're
1851 * looking at the byte immediately after the end of the tvbuff. */
1853 THROW(ReportedBoundsError);
1856 /* This should not happen because check_offset_length() would
1857 * have already thrown an exception if 'offset' were out-of-bounds.
1859 g_assert(len != -1);
1862 * If we've been passed a negative number, bufsize will
1865 g_assert(bufsize <= G_MAXINT);
1867 if ((guint)len < bufsize) {
1869 decreased_max = TRUE;
1875 stringlen = tvb_strnlen(tvb, abs_offset, limit - 1);
1876 /* If NUL wasn't found, copy the data and return -1 */
1877 if (stringlen == -1) {
1878 tvb_memcpy(tvb, buffer, abs_offset, limit);
1879 if (decreased_max) {
1881 /* Add 1 for the extra NUL that we set at buffer[limit],
1882 * pretending that it was copied as part of the string. */
1883 *bytes_copied = limit + 1;
1886 *bytes_copied = limit;
1891 /* Copy the string to buffer */
1892 tvb_memcpy(tvb, buffer, abs_offset, stringlen + 1);
1893 *bytes_copied = stringlen + 1;
1897 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
1898 * no more than bufsize number of bytes, including terminating NUL, to buffer.
1899 * Returns length of string (not including terminating NUL), or -1 if the string was
1900 * truncated in the buffer due to not having reached the terminating NUL.
1901 * In this way, it acts like snprintf().
1903 * When processing a packet where the remaining number of bytes is less
1904 * than bufsize, an exception is not thrown if the end of the packet
1905 * is reached before the NUL is found. If no NUL is found before reaching
1906 * the end of the short packet, -1 is still returned, and the string
1907 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
1908 * at the correct spot, terminating the string.
1911 tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer)
1915 return _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
1918 /* Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
1919 * have a terminating NUL. If the string was truncated when copied into buffer,
1920 * a NUL is placed at the end of buffer to terminate it.
1923 tvb_get_nstringz0(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer)
1925 gint len, bytes_copied;
1927 len = _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
1930 buffer[bufsize - 1] = 0;
1931 return bytes_copied - 1;
1939 * Given a tvbuff, an offset into the tvbuff, and a length that starts
1940 * at that offset (which may be -1 for "all the way to the end of the
1941 * tvbuff"), find the end of the (putative) line that starts at the
1942 * specified offset in the tvbuff, going no further than the specified
1945 * Return the length of the line (not counting the line terminator at
1946 * the end), or, if we don't find a line terminator:
1948 * if "deseg" is true, return -1;
1950 * if "deseg" is false, return the amount of data remaining in
1953 * Set "*next_offset" to the offset of the character past the line
1954 * terminator, or past the end of the buffer if we don't find a line
1955 * terminator. (It's not set if we return -1.)
1958 tvb_find_line_end(tvbuff_t *tvb, gint offset, int len, gint *next_offset,
1966 len = tvb_length_remaining(tvb, offset);
1968 * XXX - what if "len" is still -1, meaning "offset is past the
1969 * end of the tvbuff"?
1971 eob_offset = offset + len;
1974 * Look either for a CR or an LF.
1976 eol_offset = tvb_pbrk_guint8(tvb, offset, len, (guint8 *)"\r\n");
1977 if (eol_offset == -1) {
1979 * No CR or LF - line is presumably continued in next packet.
1983 * Tell our caller we saw no EOL, so they can
1984 * try to desegment and get the entire line
1990 * Pretend the line runs to the end of the tvbuff.
1992 linelen = eob_offset - offset;
1993 *next_offset = eob_offset;
1997 * Find the number of bytes between the starting offset
2000 linelen = eol_offset - offset;
2005 if (tvb_get_guint8(tvb, eol_offset) == '\r') {
2007 * Yes - is it followed by an LF?
2009 if (eol_offset + 1 >= eob_offset) {
2011 * Dunno - the next byte isn't in this
2016 * We'll return -1, although that
2017 * runs the risk that if the line
2018 * really *is* terminated with a CR,
2019 * we won't properly dissect this
2022 * It's probably more likely that
2023 * the line ends with CR-LF than
2024 * that it ends with CR by itself.
2030 * Well, we can at least look at the next
2033 if (tvb_get_guint8(tvb, eol_offset + 1) == '\n') {
2035 * It's an LF; skip over the CR.
2043 * Return the offset of the character after the last
2044 * character in the line, skipping over the last character
2045 * in the line terminator.
2047 *next_offset = eol_offset + 1;
2053 * Given a tvbuff, an offset into the tvbuff, and a length that starts
2054 * at that offset (which may be -1 for "all the way to the end of the
2055 * tvbuff"), find the end of the (putative) line that starts at the
2056 * specified offset in the tvbuff, going no further than the specified
2059 * However, treat quoted strings inside the buffer specially - don't
2060 * treat newlines in quoted strings as line terminators.
2062 * Return the length of the line (not counting the line terminator at
2063 * the end), or the amount of data remaining in the buffer if we don't
2064 * find a line terminator.
2066 * Set "*next_offset" to the offset of the character past the line
2067 * terminator, or past the end of the buffer if we don't find a line
2071 tvb_find_line_end_unquoted(tvbuff_t *tvb, gint offset, int len,
2074 gint cur_offset, char_offset;
2081 len = tvb_length_remaining(tvb, offset);
2083 * XXX - what if "len" is still -1, meaning "offset is past the
2084 * end of the tvbuff"?
2086 eob_offset = offset + len;
2088 cur_offset = offset;
2092 * Is this part of the string quoted?
2096 * Yes - look only for the terminating quote.
2098 char_offset = tvb_find_guint8(tvb, cur_offset, len,
2102 * Look either for a CR, an LF, or a '"'.
2104 char_offset = tvb_pbrk_guint8(tvb, cur_offset, len,
2105 (guint8 *)"\r\n\"");
2107 if (char_offset == -1) {
2109 * Not found - line is presumably continued in
2111 * We pretend the line runs to the end of the tvbuff.
2113 linelen = eob_offset - offset;
2114 *next_offset = eob_offset;
2120 * We're processing a quoted string.
2121 * We only looked for ", so we know it's a ";
2122 * as we're processing a quoted string, it's a
2130 c = tvb_get_guint8(tvb, char_offset);
2133 * Un-quoted "; it begins a quoted
2139 * It's a CR or LF; we've found a line
2142 * Find the number of bytes between the
2143 * starting offset and the CR or LF.
2145 linelen = char_offset - offset;
2152 * Yes; is it followed by an LF?
2154 if (char_offset + 1 < eob_offset &&
2155 tvb_get_guint8(tvb, char_offset + 1)
2158 * Yes; skip over the CR.
2165 * Return the offset of the character after
2166 * the last character in the line, skipping
2167 * over the last character in the line
2168 * terminator, and quit.
2170 *next_offset = char_offset + 1;
2176 * Step past the character we found.
2178 cur_offset = char_offset + 1;
2179 if (cur_offset >= eob_offset) {
2181 * The character we found was the last character
2182 * in the tvbuff - line is presumably continued in
2184 * We pretend the line runs to the end of the tvbuff.
2186 linelen = eob_offset - offset;
2187 *next_offset = eob_offset;
2195 * Format a bunch of data from a tvbuff as bytes, returning a pointer
2196 * to the string with the formatted data, with "punct" as a byte
2200 tvb_bytes_to_str_punct(tvbuff_t *tvb, gint offset, gint len, gchar punct)
2202 return bytes_to_str_punct(tvb_get_ptr(tvb, offset, len), len, punct);
2206 * Format a bunch of data from a tvbuff as bytes, returning a pointer
2207 * to the string with the formatted data.
2210 tvb_bytes_to_str(tvbuff_t *tvb, gint offset, gint len)
2212 return bytes_to_str(tvb_get_ptr(tvb, offset, len), len);
2215 /* Find a needle tvbuff within a haystack tvbuff. */
2217 tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb, gint haystack_offset)
2219 guint haystack_abs_offset, haystack_abs_length;
2220 const guint8 *haystack_data;
2221 const guint8 *needle_data;
2222 const guint needle_len = needle_tvb->length;
2223 const guint8 *location;
2225 if (haystack_tvb->length < 1 || needle_tvb->length < 1) {
2229 /* Get pointers to the tvbuffs' data. */
2230 haystack_data = tvb_get_ptr(haystack_tvb, 0, -1);
2231 needle_data = tvb_get_ptr(needle_tvb, 0, -1);
2233 check_offset_length(haystack_tvb, haystack_offset, -1,
2234 &haystack_abs_offset, &haystack_abs_length);
2236 location = epan_memmem(haystack_data + haystack_abs_offset, haystack_abs_length,
2237 needle_data, needle_len);
2240 return location - haystack_data;
2251 * Uncompresses a zlib compressed packet inside a message of tvb at offset with
2252 * length comprlen. Returns an uncompressed tvbuffer if uncompression
2253 * succeeded or NULL if uncompression failed.
2255 #define TVB_Z_MIN_BUFSIZ 32768
2256 #define TVB_Z_MAX_BUFSIZ 1048576 * 10
2257 /* #define TVB_Z_DEBUG 1 */
2261 tvb_uncompress(tvbuff_t *tvb, int offset, int comprlen)
2266 guint bytes_out = 0;
2267 guint8 *compr = NULL;
2268 guint8 *uncompr = NULL;
2269 tvbuff_t *uncompr_tvb = NULL;
2270 z_streamp strm = NULL;
2271 Bytef *strmbuf = NULL;
2272 guint inits_done = 0;
2273 gint wbits = MAX_WBITS;
2274 guint8 *next = NULL;
2275 guint bufsiz = TVB_Z_MIN_BUFSIZ;
2277 guint inflate_passes = 0;
2278 guint bytes_in = tvb_length_remaining(tvb, offset);
2285 strm = g_malloc0(sizeof(z_stream));
2291 compr = tvb_memdup(tvb, offset, comprlen);
2299 * Assume that the uncompressed data is at least twice as big as
2300 * the compressed size.
2302 bufsiz = tvb_length_remaining(tvb, offset) * 2;
2304 if (bufsiz < TVB_Z_MIN_BUFSIZ) {
2305 bufsiz = TVB_Z_MIN_BUFSIZ;
2306 } else if (bufsiz > TVB_Z_MAX_BUFSIZ) {
2307 bufsiz = TVB_Z_MIN_BUFSIZ;
2311 printf("bufsiz: %u bytes\n", bufsiz);
2316 strm->next_in = next;
2317 strm->avail_in = comprlen;
2320 strmbuf = g_malloc0(bufsiz);
2322 if(strmbuf == NULL) {
2328 strm->next_out = strmbuf;
2329 strm->avail_out = bufsiz;
2331 err = inflateInit2(strm, wbits);
2341 memset(strmbuf, '\0', bufsiz);
2342 strm->next_out = strmbuf;
2343 strm->avail_out = bufsiz;
2345 err = inflate(strm, Z_SYNC_FLUSH);
2347 if (err == Z_OK || err == Z_STREAM_END) {
2348 guint bytes_pass = bufsiz - strm->avail_out;
2354 if (uncompr == NULL) {
2355 uncompr = g_memdup(strmbuf, bytes_pass);
2357 guint8 *new_data = g_malloc0(bytes_out +
2360 if (new_data == NULL) {
2365 if (uncompr != NULL) {
2372 g_memmove(new_data, uncompr, bytes_out);
2373 g_memmove((new_data + bytes_out), strmbuf,
2380 bytes_out += bytes_pass;
2382 if ( err == Z_STREAM_END) {
2388 } else if (err == Z_BUF_ERROR) {
2390 * It's possible that not enough frames were captured
2391 * to decompress this fully, so return what we've done
2398 if (uncompr != NULL) {
2405 } else if (err == Z_DATA_ERROR && inits_done == 1
2406 && uncompr == NULL && (*compr == 0x1f) &&
2407 (*(compr + 1) == 0x8b)) {
2409 * inflate() is supposed to handle both gzip and deflate
2410 * streams automatically, but in reality it doesn't
2411 * seem to handle either (at least not within the
2412 * context of an HTTP response.) We have to try
2413 * several tweaks, depending on the type of data and
2414 * version of the library installed.
2418 * Gzip file format. Skip past the header, since the
2419 * fix to make it work (setting windowBits to 31)
2420 * doesn't work with all versions of the library.
2422 Bytef *c = compr + 2;
2425 if (*c == Z_DEFLATED) {
2436 /* Skip past the MTIME, XFL, and OS fields. */
2439 if (flags & (1 << 2)) {
2440 /* An Extra field is present. */
2441 gint xsize = (gint)(*c |
2447 if (flags & (1 << 3)) {
2448 /* A null terminated filename */
2450 while (*c != '\0') {
2457 if (flags & (1 << 4)) {
2458 /* A null terminated comment */
2460 while (*c != '\0') {
2470 strm->next_in = next;
2471 if (c - compr > comprlen) {
2477 comprlen -= (c - compr);
2479 err = inflateInit2(strm, wbits);
2481 } else if (err == Z_DATA_ERROR && uncompr == NULL &&
2485 * Re-init the stream with a negative
2486 * MAX_WBITS. This is necessary due to
2487 * some servers (Apache) not sending
2488 * the deflate header with the
2489 * content-encoded response.
2495 strm->next_in = next;
2496 strm->avail_in = comprlen;
2498 memset(strmbuf, '\0', bufsiz);
2499 strm->next_out = strmbuf;
2500 strm->avail_out = bufsiz;
2502 err = inflateInit2(strm, wbits);
2519 if (uncompr == NULL) {
2528 printf("inflate() total passes: %u\n", inflate_passes);
2529 printf("bytes in: %u\nbytes out: %u\n\n", bytes_in, bytes_out);
2532 if (uncompr != NULL) {
2533 uncompr_tvb = tvb_new_real_data((guint8*) uncompr, bytes_out,
2535 tvb_set_free_cb(uncompr_tvb, g_free);
2542 tvb_uncompress(tvbuff_t *tvb _U_, int offset _U_, int comprlen _U_)