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 : '.';
1686 /* Convert a string from Unicode to ASCII. At the moment we fake it by
1687 * replacing all non-ASCII characters with a '.' )-: The len parameter is
1688 * the number of guint16's to convert from Unicode.
1690 * This function allocates memory from a buffer with packet lifetime.
1691 * You do not have to free this buffer, it will be automatically freed
1692 * when ethereal starts decoding the next packet.
1695 tvb_get_ephemeral_faked_unicode(tvbuff_t *tvb, int offset, int len, gboolean little_endian)
1701 /* Make sure we have enough data before allocating the buffer,
1702 so we don't blow up if the length is huge. */
1703 tvb_ensure_bytes_exist(tvb, offset, 2*len);
1705 /* We know we won't throw an exception, so we don't have to worry
1706 about leaking this buffer. */
1707 buffer = ep_alloc(len + 1);
1709 for (i = 0; i < len; i++) {
1710 character = little_endian ? tvb_get_letohs(tvb, offset)
1711 : tvb_get_ntohs(tvb, offset);
1712 buffer[i] = character < 256 ? character : '.';
1722 * Format the data in the tvb from offset for length ...
1726 tvb_format_text(tvbuff_t *tvb, gint offset, gint size)
1731 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
1733 len = tvb_length_remaining(tvb, offset);
1734 ptr = ensure_contiguous(tvb, offset, len);
1738 return format_text(ptr, len);
1743 * Like "tvb_format_text()", but for null-padded strings; don't show
1744 * the null padding characters as "\000".
1747 tvb_format_stringzpad(tvbuff_t *tvb, gint offset, gint size)
1749 const guint8 *ptr, *p;
1753 if ((ptr = ensure_contiguous(tvb, offset, size)) == NULL) {
1755 len = tvb_length_remaining(tvb, offset);
1756 ptr = ensure_contiguous(tvb, offset, len);
1760 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
1762 return format_text(ptr, stringlen);
1767 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
1768 * to hold a non-null-terminated string of that length at that offset,
1769 * plus a trailing '\0', copy the string into it, and return a pointer
1772 * Throws an exception if the tvbuff ends before the string does.
1775 tvb_get_string(tvbuff_t *tvb, gint offset, gint length)
1778 guint8 *strbuf = NULL;
1780 tvb_ensure_bytes_exist(tvb, offset, length);
1782 ptr = ensure_contiguous(tvb, offset, length);
1783 strbuf = g_malloc(length + 1);
1785 memcpy(strbuf, ptr, length);
1787 strbuf[length] = '\0';
1791 * Given a tvbuff, an offset, and a length, allocate a buffer big enough
1792 * to hold a non-null-terminated string of that length at that offset,
1793 * plus a trailing '\0', copy the string into it, and return a pointer
1796 * Throws an exception if the tvbuff ends before the string does.
1798 * This function allocates memory from a buffer with packet lifetime.
1799 * You do not have to free this buffer, it will be automatically freed
1800 * when ethereal starts decoding the next packet.
1801 * Do not use this function if you want the allocated memory to be persistent
1802 * after the current packet has been dissected.
1805 tvb_get_ephemeral_string(tvbuff_t *tvb, gint offset, gint length)
1808 guint8 *strbuf = NULL;
1810 tvb_ensure_bytes_exist(tvb, offset, length);
1812 ptr = ensure_contiguous(tvb, offset, length);
1813 strbuf = ep_alloc(length + 1);
1815 memcpy(strbuf, ptr, length);
1817 strbuf[length] = '\0';
1823 * Given a tvbuff and an offset, with the offset assumed to refer to
1824 * a null-terminated string, find the length of that string (and throw
1825 * an exception if the tvbuff ends before we find the null), allocate
1826 * a buffer big enough to hold the string, copy the string into it,
1827 * and return a pointer to the string. Also return the length of the
1828 * string (including the terminating null) through a pointer.
1831 tvb_get_stringz(tvbuff_t *tvb, gint offset, gint *lengthp)
1836 size = tvb_strsize(tvb, offset);
1837 strptr = g_malloc(size);
1838 tvb_memcpy(tvb, strptr, offset, size);
1843 * Given a tvbuff and an offset, with the offset assumed to refer to
1844 * a null-terminated string, find the length of that string (and throw
1845 * an exception if the tvbuff ends before we find the null), allocate
1846 * a buffer big enough to hold the string, copy the string into it,
1847 * and return a pointer to the string. Also return the length of the
1848 * string (including the terminating null) through a pointer.
1850 * This function allocates memory from a buffer with packet lifetime.
1851 * You do not have to free this buffer, it will be automatically freed
1852 * when ethereal starts decoding the next packet.
1853 * Do not use this function if you want the allocated memory to be persistent
1854 * after the current packet has been dissected.
1857 tvb_get_ephemeral_stringz(tvbuff_t *tvb, gint offset, gint *lengthp)
1862 size = tvb_strsize(tvb, offset);
1863 strptr = ep_alloc(size);
1864 tvb_memcpy(tvb, strptr, offset, size);
1869 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
1870 * no more than bufsize number of bytes, including terminating NUL, to buffer.
1871 * Returns length of string (not including terminating NUL), or -1 if the string was
1872 * truncated in the buffer due to not having reached the terminating NUL.
1873 * In this way, it acts like g_snprintf().
1875 * bufsize MUST be greater than 0.
1877 * When processing a packet where the remaining number of bytes is less
1878 * than bufsize, an exception is not thrown if the end of the packet
1879 * is reached before the NUL is found. If no NUL is found before reaching
1880 * the end of the short packet, -1 is still returned, and the string
1881 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
1882 * at the correct spot, terminating the string.
1884 * *bytes_copied will contain the number of bytes actually copied,
1885 * including the terminating-NUL.
1888 _tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer,
1892 guint abs_offset, junk_length;
1894 gboolean decreased_max = FALSE;
1896 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1898 /* There must at least be room for the terminating NUL. */
1899 g_assert(bufsize != 0);
1901 /* If there's no room for anything else, just return the NUL. */
1908 /* Only read to end of tvbuff, w/o throwing exception. */
1909 len = tvb_length_remaining(tvb, abs_offset);
1911 /* check_offset_length() won't throw an exception if we're
1912 * looking at the byte immediately after the end of the tvbuff. */
1914 THROW(ReportedBoundsError);
1917 /* This should not happen because check_offset_length() would
1918 * have already thrown an exception if 'offset' were out-of-bounds.
1920 g_assert(len != -1);
1923 * If we've been passed a negative number, bufsize will
1926 g_assert(bufsize <= G_MAXINT);
1928 if ((guint)len < bufsize) {
1930 decreased_max = TRUE;
1936 stringlen = tvb_strnlen(tvb, abs_offset, limit - 1);
1937 /* If NUL wasn't found, copy the data and return -1 */
1938 if (stringlen == -1) {
1939 tvb_memcpy(tvb, buffer, abs_offset, limit);
1940 if (decreased_max) {
1942 /* Add 1 for the extra NUL that we set at buffer[limit],
1943 * pretending that it was copied as part of the string. */
1944 *bytes_copied = limit + 1;
1947 *bytes_copied = limit;
1952 /* Copy the string to buffer */
1953 tvb_memcpy(tvb, buffer, abs_offset, stringlen + 1);
1954 *bytes_copied = stringlen + 1;
1958 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
1959 * no more than bufsize number of bytes, including terminating NUL, to buffer.
1960 * Returns length of string (not including terminating NUL), or -1 if the string was
1961 * truncated in the buffer due to not having reached the terminating NUL.
1962 * In this way, it acts like g_snprintf().
1964 * When processing a packet where the remaining number of bytes is less
1965 * than bufsize, an exception is not thrown if the end of the packet
1966 * is reached before the NUL is found. If no NUL is found before reaching
1967 * the end of the short packet, -1 is still returned, and the string
1968 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
1969 * at the correct spot, terminating the string.
1972 tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer)
1976 return _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
1979 /* Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
1980 * have a terminating NUL. If the string was truncated when copied into buffer,
1981 * a NUL is placed at the end of buffer to terminate it.
1984 tvb_get_nstringz0(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer)
1986 gint len, bytes_copied;
1988 len = _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
1991 buffer[bufsize - 1] = 0;
1992 return bytes_copied - 1;
2000 * Given a tvbuff, an offset into the tvbuff, and a length that starts
2001 * at that offset (which may be -1 for "all the way to the end of the
2002 * tvbuff"), find the end of the (putative) line that starts at the
2003 * specified offset in the tvbuff, going no further than the specified
2006 * Return the length of the line (not counting the line terminator at
2007 * the end), or, if we don't find a line terminator:
2009 * if "deseg" is true, return -1;
2011 * if "deseg" is false, return the amount of data remaining in
2014 * Set "*next_offset" to the offset of the character past the line
2015 * terminator, or past the end of the buffer if we don't find a line
2016 * terminator. (It's not set if we return -1.)
2019 tvb_find_line_end(tvbuff_t *tvb, gint offset, int len, gint *next_offset,
2027 len = tvb_length_remaining(tvb, offset);
2029 * XXX - what if "len" is still -1, meaning "offset is past the
2030 * end of the tvbuff"?
2032 eob_offset = offset + len;
2035 * Look either for a CR or an LF.
2037 eol_offset = tvb_pbrk_guint8(tvb, offset, len, (guint8 *)"\r\n");
2038 if (eol_offset == -1) {
2040 * No CR or LF - line is presumably continued in next packet.
2044 * Tell our caller we saw no EOL, so they can
2045 * try to desegment and get the entire line
2051 * Pretend the line runs to the end of the tvbuff.
2053 linelen = eob_offset - offset;
2054 *next_offset = eob_offset;
2058 * Find the number of bytes between the starting offset
2061 linelen = eol_offset - offset;
2066 if (tvb_get_guint8(tvb, eol_offset) == '\r') {
2068 * Yes - is it followed by an LF?
2070 if (eol_offset + 1 >= eob_offset) {
2072 * Dunno - the next byte isn't in this
2077 * We'll return -1, although that
2078 * runs the risk that if the line
2079 * really *is* terminated with a CR,
2080 * we won't properly dissect this
2083 * It's probably more likely that
2084 * the line ends with CR-LF than
2085 * that it ends with CR by itself.
2091 * Well, we can at least look at the next
2094 if (tvb_get_guint8(tvb, eol_offset + 1) == '\n') {
2096 * It's an LF; skip over the CR.
2104 * Return the offset of the character after the last
2105 * character in the line, skipping over the last character
2106 * in the line terminator.
2108 *next_offset = eol_offset + 1;
2114 * Given a tvbuff, an offset into the tvbuff, and a length that starts
2115 * at that offset (which may be -1 for "all the way to the end of the
2116 * tvbuff"), find the end of the (putative) line that starts at the
2117 * specified offset in the tvbuff, going no further than the specified
2120 * However, treat quoted strings inside the buffer specially - don't
2121 * treat newlines in quoted strings as line terminators.
2123 * Return the length of the line (not counting the line terminator at
2124 * the end), or the amount of data remaining in the buffer if we don't
2125 * find a line terminator.
2127 * Set "*next_offset" to the offset of the character past the line
2128 * terminator, or past the end of the buffer if we don't find a line
2132 tvb_find_line_end_unquoted(tvbuff_t *tvb, gint offset, int len,
2135 gint cur_offset, char_offset;
2142 len = tvb_length_remaining(tvb, offset);
2144 * XXX - what if "len" is still -1, meaning "offset is past the
2145 * end of the tvbuff"?
2147 eob_offset = offset + len;
2149 cur_offset = offset;
2153 * Is this part of the string quoted?
2157 * Yes - look only for the terminating quote.
2159 char_offset = tvb_find_guint8(tvb, cur_offset, len,
2163 * Look either for a CR, an LF, or a '"'.
2165 char_offset = tvb_pbrk_guint8(tvb, cur_offset, len,
2166 (guint8 *)"\r\n\"");
2168 if (char_offset == -1) {
2170 * Not found - line is presumably continued in
2172 * We pretend the line runs to the end of the tvbuff.
2174 linelen = eob_offset - offset;
2175 *next_offset = eob_offset;
2181 * We're processing a quoted string.
2182 * We only looked for ", so we know it's a ";
2183 * as we're processing a quoted string, it's a
2191 c = tvb_get_guint8(tvb, char_offset);
2194 * Un-quoted "; it begins a quoted
2200 * It's a CR or LF; we've found a line
2203 * Find the number of bytes between the
2204 * starting offset and the CR or LF.
2206 linelen = char_offset - offset;
2213 * Yes; is it followed by an LF?
2215 if (char_offset + 1 < eob_offset &&
2216 tvb_get_guint8(tvb, char_offset + 1)
2219 * Yes; skip over the CR.
2226 * Return the offset of the character after
2227 * the last character in the line, skipping
2228 * over the last character in the line
2229 * terminator, and quit.
2231 *next_offset = char_offset + 1;
2237 * Step past the character we found.
2239 cur_offset = char_offset + 1;
2240 if (cur_offset >= eob_offset) {
2242 * The character we found was the last character
2243 * in the tvbuff - line is presumably continued in
2245 * We pretend the line runs to the end of the tvbuff.
2247 linelen = eob_offset - offset;
2248 *next_offset = eob_offset;
2256 * Format a bunch of data from a tvbuff as bytes, returning a pointer
2257 * to the string with the formatted data, with "punct" as a byte
2261 tvb_bytes_to_str_punct(tvbuff_t *tvb, gint offset, gint len, gchar punct)
2263 return bytes_to_str_punct(tvb_get_ptr(tvb, offset, len), len, punct);
2267 * Format a bunch of data from a tvbuff as bytes, returning a pointer
2268 * to the string with the formatted data.
2271 tvb_bytes_to_str(tvbuff_t *tvb, gint offset, gint len)
2273 return bytes_to_str(tvb_get_ptr(tvb, offset, len), len);
2276 /* Find a needle tvbuff within a haystack tvbuff. */
2278 tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb, gint haystack_offset)
2280 guint haystack_abs_offset, haystack_abs_length;
2281 const guint8 *haystack_data;
2282 const guint8 *needle_data;
2283 const guint needle_len = needle_tvb->length;
2284 const guint8 *location;
2286 if (haystack_tvb->length < 1 || needle_tvb->length < 1) {
2290 /* Get pointers to the tvbuffs' data. */
2291 haystack_data = tvb_get_ptr(haystack_tvb, 0, -1);
2292 needle_data = tvb_get_ptr(needle_tvb, 0, -1);
2294 check_offset_length(haystack_tvb, haystack_offset, -1,
2295 &haystack_abs_offset, &haystack_abs_length);
2297 location = epan_memmem(haystack_data + haystack_abs_offset, haystack_abs_length,
2298 needle_data, needle_len);
2301 return location - haystack_data;
2312 * Uncompresses a zlib compressed packet inside a message of tvb at offset with
2313 * length comprlen. Returns an uncompressed tvbuffer if uncompression
2314 * succeeded or NULL if uncompression failed.
2316 #define TVB_Z_MIN_BUFSIZ 32768
2317 #define TVB_Z_MAX_BUFSIZ 1048576 * 10
2318 /* #define TVB_Z_DEBUG 1 */
2322 tvb_uncompress(tvbuff_t *tvb, int offset, int comprlen)
2327 guint bytes_out = 0;
2328 guint8 *compr = NULL;
2329 guint8 *uncompr = NULL;
2330 tvbuff_t *uncompr_tvb = NULL;
2331 z_streamp strm = NULL;
2332 Bytef *strmbuf = NULL;
2333 guint inits_done = 0;
2334 gint wbits = MAX_WBITS;
2335 guint8 *next = NULL;
2336 guint bufsiz = TVB_Z_MIN_BUFSIZ;
2338 guint inflate_passes = 0;
2339 guint bytes_in = tvb_length_remaining(tvb, offset);
2346 strm = g_malloc0(sizeof(z_stream));
2352 compr = tvb_memdup(tvb, offset, comprlen);
2360 * Assume that the uncompressed data is at least twice as big as
2361 * the compressed size.
2363 bufsiz = tvb_length_remaining(tvb, offset) * 2;
2365 if (bufsiz < TVB_Z_MIN_BUFSIZ) {
2366 bufsiz = TVB_Z_MIN_BUFSIZ;
2367 } else if (bufsiz > TVB_Z_MAX_BUFSIZ) {
2368 bufsiz = TVB_Z_MIN_BUFSIZ;
2372 printf("bufsiz: %u bytes\n", bufsiz);
2377 strm->next_in = next;
2378 strm->avail_in = comprlen;
2381 strmbuf = g_malloc0(bufsiz);
2383 if(strmbuf == NULL) {
2389 strm->next_out = strmbuf;
2390 strm->avail_out = bufsiz;
2392 err = inflateInit2(strm, wbits);
2402 memset(strmbuf, '\0', bufsiz);
2403 strm->next_out = strmbuf;
2404 strm->avail_out = bufsiz;
2406 err = inflate(strm, Z_SYNC_FLUSH);
2408 if (err == Z_OK || err == Z_STREAM_END) {
2409 guint bytes_pass = bufsiz - strm->avail_out;
2415 if (uncompr == NULL) {
2416 uncompr = g_memdup(strmbuf, bytes_pass);
2418 guint8 *new_data = g_malloc0(bytes_out +
2421 if (new_data == NULL) {
2426 if (uncompr != NULL) {
2433 g_memmove(new_data, uncompr, bytes_out);
2434 g_memmove((new_data + bytes_out), strmbuf,
2441 bytes_out += bytes_pass;
2443 if ( err == Z_STREAM_END) {
2449 } else if (err == Z_BUF_ERROR) {
2451 * It's possible that not enough frames were captured
2452 * to decompress this fully, so return what we've done
2459 if (uncompr != NULL) {
2466 } else if (err == Z_DATA_ERROR && inits_done == 1
2467 && uncompr == NULL && (*compr == 0x1f) &&
2468 (*(compr + 1) == 0x8b)) {
2470 * inflate() is supposed to handle both gzip and deflate
2471 * streams automatically, but in reality it doesn't
2472 * seem to handle either (at least not within the
2473 * context of an HTTP response.) We have to try
2474 * several tweaks, depending on the type of data and
2475 * version of the library installed.
2479 * Gzip file format. Skip past the header, since the
2480 * fix to make it work (setting windowBits to 31)
2481 * doesn't work with all versions of the library.
2483 Bytef *c = compr + 2;
2486 if (*c == Z_DEFLATED) {
2497 /* Skip past the MTIME, XFL, and OS fields. */
2500 if (flags & (1 << 2)) {
2501 /* An Extra field is present. */
2502 gint xsize = (gint)(*c |
2508 if (flags & (1 << 3)) {
2509 /* A null terminated filename */
2511 while (*c != '\0') {
2518 if (flags & (1 << 4)) {
2519 /* A null terminated comment */
2521 while (*c != '\0') {
2531 strm->next_in = next;
2532 if (c - compr > comprlen) {
2538 comprlen -= (c - compr);
2540 err = inflateInit2(strm, wbits);
2542 } else if (err == Z_DATA_ERROR && uncompr == NULL &&
2546 * Re-init the stream with a negative
2547 * MAX_WBITS. This is necessary due to
2548 * some servers (Apache) not sending
2549 * the deflate header with the
2550 * content-encoded response.
2556 strm->next_in = next;
2557 strm->avail_in = comprlen;
2559 memset(strmbuf, '\0', bufsiz);
2560 strm->next_out = strmbuf;
2561 strm->avail_out = bufsiz;
2563 err = inflateInit2(strm, wbits);
2580 if (uncompr == NULL) {
2589 printf("inflate() total passes: %u\n", inflate_passes);
2590 printf("bytes in: %u\nbytes out: %u\n\n", bytes_in, bytes_out);
2593 if (uncompr != NULL) {
2594 uncompr_tvb = tvb_new_real_data((guint8*) uncompr, bytes_out,
2596 tvb_set_free_cb(uncompr_tvb, g_free);
2603 tvb_uncompress(tvbuff_t *tvb _U_, int offset _U_, int comprlen _U_)