3 * Testy, Virtual(-izable) Buffer of guint8*'s
5 * "Testy" -- the buffer gets mad when an attempt to access data
6 * beyond the bounds of the buffer. An exception is thrown.
8 * "Virtual" -- the buffer can have its own data, can use a subset of
9 * the data of a backing tvbuff, or can be a composite of
12 * Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
14 * Code to convert IEEE floating point formats to native floating point
15 * derived from code Copyright (c) Ashok Narayanan, 2000
17 * Wireshark - Network traffic analyzer
18 * By Gerald Combs <gerald@wireshark.org>
19 * Copyright 1998 Gerald Combs
21 * This program is free software; you can redistribute it and/or
22 * modify it under the terms of the GNU General Public License
23 * as published by the Free Software Foundation; either version 2
24 * of the License, or (at your option) any later version.
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
42 #include "wsutil/pint.h"
43 #include "wsutil/sign_ext.h"
44 #include "wsutil/unicode-utils.h"
45 #include "wsutil/nstime.h"
46 #include "wsutil/time_util.h"
48 #include "tvbuff-int.h"
52 #include "proto.h" /* XXX - only used for DISSECTOR_ASSERT, probably a new header file? */
53 #include "exceptions.h"
56 * Just make sure we include the prototype for strptime as well
57 * (needed for glibc 2.2) but make sure we do this only if not
61 /*#ifndef HAVE_STRPTIME*/
63 #include "wsutil/strptime.h"
68 _tvb_get_bits64(tvbuff_t *tvb, guint bit_offset, const gint total_no_of_bits);
71 _tvb_captured_length_remaining(const tvbuff_t *tvb, const gint offset);
73 static inline const guint8*
74 ensure_contiguous(tvbuff_t *tvb, const gint offset, const gint length);
76 static inline guint8 *
77 tvb_get_raw_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, const gint length);
80 tvb_new(const struct tvb_ops *ops)
83 gsize size = ops->tvb_size;
85 g_assert(size >= sizeof(*tvb));
87 tvb = (tvbuff_t *) g_slice_alloc(size);
91 tvb->initialized = FALSE;
94 tvb->reported_length = 0;
95 tvb->real_data = NULL;
103 tvb_free_internal(tvbuff_t *tvb)
107 DISSECTOR_ASSERT(tvb);
109 if (tvb->ops->tvb_free)
110 tvb->ops->tvb_free(tvb);
112 size = tvb->ops->tvb_size;
114 g_slice_free1(size, tvb);
117 /* XXX: just call tvb_free_chain();
118 * Not removed so that existing dissectors using tvb_free() need not be changed.
119 * I'd argue that existing calls to tvb_free() should have actually beeen
120 * calls to tvb_free_chain() although the calls were OK as long as no
121 * subsets, etc had been created on the tvb. */
123 tvb_free(tvbuff_t *tvb)
129 tvb_free_chain(tvbuff_t *tvb)
132 DISSECTOR_ASSERT(tvb);
134 next_tvb = tvb->next;
135 tvb_free_internal(tvb);
141 tvb_new_chain(tvbuff_t *parent, tvbuff_t *backing)
143 tvbuff_t *tvb = tvb_new_proxy(backing);
145 tvb_add_to_chain(parent, tvb);
150 tvb_add_to_chain(tvbuff_t *parent, tvbuff_t *child)
152 tvbuff_t *tmp = child;
154 DISSECTOR_ASSERT(parent);
155 DISSECTOR_ASSERT(child);
161 tmp->next = parent->next;
167 * Check whether that offset goes more than one byte past the
170 * If not, return 0; otherwise, return exception
173 validate_offset(const tvbuff_t *tvb, const guint abs_offset)
175 if (G_LIKELY(abs_offset <= tvb->length))
177 else if (abs_offset <= tvb->reported_length)
179 else if (tvb->flags & TVBUFF_FRAGMENT)
180 return FragmentBoundsError;
182 return ReportedBoundsError;
186 compute_offset(const tvbuff_t *tvb, const gint offset, guint *offset_ptr)
189 /* Positive offset - relative to the beginning of the packet. */
190 if ((guint) offset <= tvb->length) {
191 *offset_ptr = offset;
192 } else if ((guint) offset <= tvb->reported_length) {
194 } else if (tvb->flags & TVBUFF_FRAGMENT) {
195 return FragmentBoundsError;
197 return ReportedBoundsError;
201 /* Negative offset - relative to the end of the packet. */
202 if ((guint) -offset <= tvb->length) {
203 *offset_ptr = tvb->length + offset;
204 } else if ((guint) -offset <= tvb->reported_length) {
206 } else if (tvb->flags & TVBUFF_FRAGMENT) {
207 return FragmentBoundsError;
209 return ReportedBoundsError;
217 compute_offset_and_remaining(const tvbuff_t *tvb, const gint offset, guint *offset_ptr, guint *rem_len)
221 exception = compute_offset(tvb, offset, offset_ptr);
223 *rem_len = tvb->length - *offset_ptr;
228 /* Computes the absolute offset and length based on a possibly-negative offset
229 * and a length that is possible -1 (which means "to the end of the data").
230 * Returns integer indicating whether the offset is in bounds (0) or
231 * not (exception number). The integer ptrs are modified with the new offset and length.
232 * No exception is thrown.
234 * XXX - we return success (0), if the offset is positive and right
235 * after the end of the tvbuff (i.e., equal to the length). We do this
236 * so that a dissector constructing a subset tvbuff for the next protocol
237 * will get a zero-length tvbuff, not an exception, if there's no data
238 * left for the next protocol - we want the next protocol to be the one
239 * that gets an exception, so the error is reported as an error in that
240 * protocol rather than the containing protocol. */
242 check_offset_length_no_exception(const tvbuff_t *tvb,
243 const gint offset, gint const length_val,
244 guint *offset_ptr, guint *length_ptr)
249 DISSECTOR_ASSERT(offset_ptr);
250 DISSECTOR_ASSERT(length_ptr);
252 /* Compute the offset */
253 exception = compute_offset(tvb, offset, offset_ptr);
257 if (length_val < -1) {
258 /* XXX - ReportedBoundsError? */
262 /* Compute the length */
263 if (length_val == -1)
264 *length_ptr = tvb->length - *offset_ptr;
266 *length_ptr = length_val;
269 * Compute the offset of the first byte past the length.
271 end_offset = *offset_ptr + *length_ptr;
274 * Check for an overflow
276 if (end_offset < *offset_ptr)
279 return validate_offset(tvb, end_offset);
282 /* Checks (+/-) offset and length and throws an exception if
283 * either is out of bounds. Sets integer ptrs to the new offset
286 check_offset_length(const tvbuff_t *tvb,
287 const gint offset, gint const length_val,
288 guint *offset_ptr, guint *length_ptr)
292 exception = check_offset_length_no_exception(tvb, offset, length_val, offset_ptr, length_ptr);
298 tvb_check_offset_length(const tvbuff_t *tvb,
299 const gint offset, gint const length_val,
300 guint *offset_ptr, guint *length_ptr)
302 check_offset_length(tvb, offset, length_val, offset_ptr, length_ptr);
305 static const unsigned char left_aligned_bitmask[] = {
317 tvb_new_octet_aligned(tvbuff_t *tvb, guint32 bit_offset, gint32 no_of_bits)
319 tvbuff_t *sub_tvb = NULL;
322 guint8 left, right, remaining_bits, *buf;
325 DISSECTOR_ASSERT(tvb && tvb->initialized);
327 byte_offset = bit_offset >> 3;
328 left = bit_offset % 8; /* for left-shifting */
329 right = 8 - left; /* for right-shifting */
331 if (no_of_bits == -1) {
332 datalen = _tvb_captured_length_remaining(tvb, byte_offset);
335 datalen = no_of_bits >> 3;
336 remaining_bits = no_of_bits % 8;
337 if (remaining_bits) {
342 /* already aligned -> shortcut */
343 if ((left == 0) && (remaining_bits == 0)) {
344 return tvb_new_subset(tvb, byte_offset, datalen, datalen);
347 DISSECTOR_ASSERT(datalen>0);
349 /* if at least one trailing byte is available, we must use the content
350 * of that byte for the last shift (i.e. tvb_get_ptr() must use datalen + 1
351 * if non extra byte is available, the last shifted byte requires
354 if (_tvb_captured_length_remaining(tvb, byte_offset) > datalen) {
355 data = ensure_contiguous(tvb, byte_offset, datalen + 1); /* tvb_get_ptr */
357 /* Do this allocation AFTER tvb_get_ptr() (which could throw an exception) */
358 buf = (guint8 *)g_malloc(datalen);
360 /* shift tvb data bit_offset bits to the left */
361 for (i = 0; i < datalen; i++)
362 buf[i] = (data[i] << left) | (data[i+1] >> right);
364 data = ensure_contiguous(tvb, byte_offset, datalen); /* tvb_get_ptr() */
366 /* Do this allocation AFTER tvb_get_ptr() (which could throw an exception) */
367 buf = (guint8 *)g_malloc(datalen);
369 /* shift tvb data bit_offset bits to the left */
370 for (i = 0; i < (datalen-1); i++)
371 buf[i] = (data[i] << left) | (data[i+1] >> right);
372 buf[datalen-1] = data[datalen-1] << left; /* set last octet */
374 buf[datalen-1] &= left_aligned_bitmask[remaining_bits];
376 sub_tvb = tvb_new_child_real_data(tvb, buf, datalen, datalen);
377 tvb_set_free_cb(sub_tvb, g_free);
383 tvb_generic_clone_offset_len(tvbuff_t *tvb, guint offset, guint len)
385 tvbuff_t *cloned_tvb;
388 DISSECTOR_ASSERT(tvb_bytes_exist(tvb, offset, len));
390 data = (guint8 *) g_malloc(len);
392 tvb_memcpy(tvb, data, offset, len);
394 cloned_tvb = tvb_new_real_data(data, len, len);
395 tvb_set_free_cb(cloned_tvb, g_free);
401 tvb_clone_offset_len(tvbuff_t *tvb, guint offset, guint len)
403 if (tvb->ops->tvb_clone) {
404 tvbuff_t *cloned_tvb;
406 cloned_tvb = tvb->ops->tvb_clone(tvb, offset, len);
411 return tvb_generic_clone_offset_len(tvb, offset, len);
415 tvb_clone(tvbuff_t *tvb)
417 return tvb_clone_offset_len(tvb, 0, tvb->length);
421 tvb_captured_length(const tvbuff_t *tvb)
423 DISSECTOR_ASSERT(tvb && tvb->initialized);
428 /* For tvbuff internal use */
430 _tvb_captured_length_remaining(const tvbuff_t *tvb, const gint offset)
432 guint abs_offset, rem_length;
435 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &rem_length);
443 tvb_captured_length_remaining(const tvbuff_t *tvb, const gint offset)
445 guint abs_offset, rem_length;
448 DISSECTOR_ASSERT(tvb && tvb->initialized);
450 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &rem_length);
458 tvb_ensure_captured_length_remaining(const tvbuff_t *tvb, const gint offset)
460 guint abs_offset = 0, rem_length = 0;
463 DISSECTOR_ASSERT(tvb && tvb->initialized);
465 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &rem_length);
469 if (rem_length == 0) {
471 * This routine ensures there's at least one byte available.
472 * There aren't any bytes available, so throw the appropriate
475 if (abs_offset >= tvb->reported_length) {
476 if (tvb->flags & TVBUFF_FRAGMENT) {
477 THROW(FragmentBoundsError);
479 THROW(ReportedBoundsError);
490 /* Validates that 'length' bytes are available starting from
491 * offset (pos/neg). Does not throw an exception. */
493 tvb_bytes_exist(const tvbuff_t *tvb, const gint offset, const gint length)
495 guint abs_offset, abs_length;
498 DISSECTOR_ASSERT(tvb && tvb->initialized);
500 exception = check_offset_length_no_exception(tvb, offset, length, &abs_offset, &abs_length);
507 /* Validates that 'length' bytes, where 'length' is a 64-bit unsigned
508 * integer, are available starting from offset (pos/neg). Throws an
509 * exception if they aren't. */
511 tvb_ensure_bytes_exist64(const tvbuff_t *tvb, const gint offset, const guint64 length)
514 * Make sure the value fits in a signed integer; if not, assume
515 * that means that it's too big.
517 if (length > G_MAXINT) {
518 THROW(ReportedBoundsError);
521 /* OK, now cast it and try it with tvb_ensure_bytes_exist(). */
522 tvb_ensure_bytes_exist(tvb, offset, (gint)length);
525 /* Validates that 'length' bytes are available starting from
526 * offset (pos/neg). Throws an exception if they aren't. */
528 tvb_ensure_bytes_exist(const tvbuff_t *tvb, const gint offset, const gint length)
530 guint real_offset, end_offset;
532 DISSECTOR_ASSERT(tvb && tvb->initialized);
535 * -1 doesn't mean "until end of buffer", as that's pointless
536 * for this routine. We must treat it as a Really Large Positive
537 * Number, so that we throw an exception; we throw
538 * ReportedBoundsError, as if it were past even the end of a
539 * reassembled packet, and past the end of even the data we
542 * We do the same with other negative lengths.
545 THROW(ReportedBoundsError);
548 /* XXX: Below this point could be replaced with a call to
549 * check_offset_length with no functional change, however this is a
550 * *very* hot path and check_offset_length is not well-optimized for
551 * this case, so we eat some code duplication for a lot of speedup. */
554 /* Positive offset - relative to the beginning of the packet. */
555 if ((guint) offset <= tvb->length) {
556 real_offset = offset;
557 } else if ((guint) offset <= tvb->reported_length) {
559 } else if (tvb->flags & TVBUFF_FRAGMENT) {
560 THROW(FragmentBoundsError);
562 THROW(ReportedBoundsError);
566 /* Negative offset - relative to the end of the packet. */
567 if ((guint) -offset <= tvb->length) {
568 real_offset = tvb->length + offset;
569 } else if ((guint) -offset <= tvb->reported_length) {
571 } else if (tvb->flags & TVBUFF_FRAGMENT) {
572 THROW(FragmentBoundsError);
574 THROW(ReportedBoundsError);
579 * Compute the offset of the first byte past the length.
581 end_offset = real_offset + length;
584 * Check for an overflow
586 if (end_offset < real_offset)
589 if (G_LIKELY(end_offset <= tvb->length))
591 else if (end_offset <= tvb->reported_length)
593 else if (tvb->flags & TVBUFF_FRAGMENT)
594 THROW(FragmentBoundsError);
596 THROW(ReportedBoundsError);
600 tvb_offset_exists(const tvbuff_t *tvb, const gint offset)
605 DISSECTOR_ASSERT(tvb && tvb->initialized);
607 exception = compute_offset(tvb, offset, &abs_offset);
611 /* compute_offset only throws an exception on >, not >= because of the
612 * comment above check_offset_length_no_exception, but here we want the
613 * opposite behaviour so we check ourselves... */
614 if (abs_offset < tvb->length) {
623 tvb_reported_length(const tvbuff_t *tvb)
625 DISSECTOR_ASSERT(tvb && tvb->initialized);
627 return tvb->reported_length;
631 tvb_reported_length_remaining(const tvbuff_t *tvb, const gint offset)
636 DISSECTOR_ASSERT(tvb && tvb->initialized);
638 exception = compute_offset(tvb, offset, &abs_offset);
642 if (tvb->reported_length >= abs_offset)
643 return tvb->reported_length - abs_offset;
648 /* Set the reported length of a tvbuff to a given value; used for protocols
649 * whose headers contain an explicit length and where the calling
650 * dissector's payload may include padding as well as the packet for
652 * Also adjusts the data length. */
654 tvb_set_reported_length(tvbuff_t *tvb, const guint reported_length)
656 DISSECTOR_ASSERT(tvb && tvb->initialized);
658 if (reported_length > tvb->reported_length)
659 THROW(ReportedBoundsError);
661 tvb->reported_length = reported_length;
662 if (reported_length < tvb->length)
663 tvb->length = reported_length;
667 tvb_offset_from_real_beginning_counter(const tvbuff_t *tvb, const guint counter)
669 if (tvb->ops->tvb_offset)
670 return tvb->ops->tvb_offset(tvb, counter);
672 DISSECTOR_ASSERT_NOT_REACHED();
677 tvb_offset_from_real_beginning(const tvbuff_t *tvb)
679 return tvb_offset_from_real_beginning_counter(tvb, 0);
682 static inline const guint8*
683 ensure_contiguous_no_exception(tvbuff_t *tvb, const gint offset, const gint length, int *pexception)
685 guint abs_offset = 0, abs_length = 0;
688 exception = check_offset_length_no_exception(tvb, offset, length, &abs_offset, &abs_length);
691 *pexception = exception;
696 * We know that all the data is present in the tvbuff, so
697 * no exceptions should be thrown.
700 return tvb->real_data + abs_offset;
702 if (tvb->ops->tvb_get_ptr)
703 return tvb->ops->tvb_get_ptr(tvb, abs_offset, abs_length);
705 DISSECTOR_ASSERT_NOT_REACHED();
709 static inline const guint8*
710 ensure_contiguous(tvbuff_t *tvb, const gint offset, const gint length)
715 p = ensure_contiguous_no_exception(tvb, offset, length, &exception);
717 DISSECTOR_ASSERT(exception > 0);
723 static inline const guint8*
724 fast_ensure_contiguous(tvbuff_t *tvb, const gint offset, const guint length)
729 DISSECTOR_ASSERT(tvb && tvb->initialized);
730 /* We don't check for overflow in this fast path so we only handle simple types */
731 DISSECTOR_ASSERT(length <= 8);
733 if (offset < 0 || !tvb->real_data) {
734 return ensure_contiguous(tvb, offset, length);
738 end_offset = u_offset + length;
740 if (end_offset <= tvb->length) {
741 return tvb->real_data + u_offset;
744 if (end_offset > tvb->reported_length) {
745 if (tvb->flags & TVBUFF_FRAGMENT) {
746 THROW(FragmentBoundsError);
748 THROW(ReportedBoundsError);
759 /************** ACCESSORS **************/
762 tvb_memcpy(tvbuff_t *tvb, void *target, const gint offset, size_t length)
764 guint abs_offset = 0, abs_length = 0;
766 DISSECTOR_ASSERT(tvb && tvb->initialized);
769 * XXX - we should eliminate the "length = -1 means 'to the end
770 * of the tvbuff'" convention, and use other means to achieve
771 * that; this would let us eliminate a bunch of checks for
772 * negative lengths in cases where the protocol has a 32-bit
775 * Allowing -1 but throwing an assertion on other negative
776 * lengths is a bit more work with the length being a size_t;
777 * instead, we check for a length <= 2^31-1.
779 DISSECTOR_ASSERT(length <= 0x7FFFFFFF);
780 check_offset_length(tvb, offset, (gint) length, &abs_offset, &abs_length);
782 if (tvb->real_data) {
783 return memcpy(target, tvb->real_data + abs_offset, abs_length);
786 if (tvb->ops->tvb_memcpy)
787 return tvb->ops->tvb_memcpy(tvb, target, abs_offset, abs_length);
790 * If the length is 0, there's nothing to do.
791 * (tvb->real_data could be null if it's allocated with
796 * XXX, fallback to slower method
798 DISSECTOR_ASSERT_NOT_REACHED();
805 * XXX - this doesn't treat a length of -1 as an error.
806 * If it did, this could replace some code that calls
807 * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies
810 * "composite_get_ptr()" depends on -1 not being
811 * an error; does anything else depend on this routine treating -1 as
812 * meaning "to the end of the buffer"?
814 * If scope is NULL, memory is allocated with g_malloc() and user must
815 * explicitly free it with g_free().
816 * If scope is not NULL, memory is allocated with the corresponding pool
820 tvb_memdup(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, size_t length)
822 guint abs_offset = 0, abs_length = 0;
825 DISSECTOR_ASSERT(tvb && tvb->initialized);
827 check_offset_length(tvb, offset, (gint) length, &abs_offset, &abs_length);
829 duped = wmem_alloc(scope, abs_length);
830 return tvb_memcpy(tvb, duped, abs_offset, abs_length);
836 tvb_get_ptr(tvbuff_t *tvb, const gint offset, const gint length)
838 return ensure_contiguous(tvb, offset, length);
841 /* ---------------- */
843 tvb_get_guint8(tvbuff_t *tvb, const gint offset)
847 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint8));
852 tvb_get_ntohs(tvbuff_t *tvb, const gint offset)
856 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint16));
861 tvb_get_ntoh24(tvbuff_t *tvb, const gint offset)
865 ptr = fast_ensure_contiguous(tvb, offset, 3);
870 tvb_get_ntohl(tvbuff_t *tvb, const gint offset)
874 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
879 tvb_get_ntoh40(tvbuff_t *tvb, const gint offset)
883 ptr = fast_ensure_contiguous(tvb, offset, 5);
888 tvb_get_ntohi40(tvbuff_t *tvb, const gint offset)
892 ret = ws_sign_ext64(tvb_get_ntoh40(tvb, offset), 40);
898 tvb_get_ntoh48(tvbuff_t *tvb, const gint offset)
902 ptr = fast_ensure_contiguous(tvb, offset, 6);
907 tvb_get_ntohi48(tvbuff_t *tvb, const gint offset)
911 ret = ws_sign_ext64(tvb_get_ntoh48(tvb, offset), 48);
917 tvb_get_ntoh56(tvbuff_t *tvb, const gint offset)
921 ptr = fast_ensure_contiguous(tvb, offset, 7);
926 tvb_get_ntohi56(tvbuff_t *tvb, const gint offset)
930 ret = ws_sign_ext64(tvb_get_ntoh56(tvb, offset), 56);
936 tvb_get_ntoh64(tvbuff_t *tvb, const gint offset)
940 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint64));
945 tvb_get_guint16(tvbuff_t *tvb, const gint offset, const guint encoding) {
946 if (encoding & ENC_LITTLE_ENDIAN) {
947 return tvb_get_letohs(tvb, offset);
949 return tvb_get_ntohs(tvb, offset);
954 tvb_get_guint24(tvbuff_t *tvb, const gint offset, const guint encoding) {
955 if (encoding & ENC_LITTLE_ENDIAN) {
956 return tvb_get_letoh24(tvb, offset);
958 return tvb_get_ntoh24(tvb, offset);
963 tvb_get_guint32(tvbuff_t *tvb, const gint offset, const guint encoding) {
964 if (encoding & ENC_LITTLE_ENDIAN) {
965 return tvb_get_letohl(tvb, offset);
967 return tvb_get_ntohl(tvb, offset);
972 tvb_get_guint40(tvbuff_t *tvb, const gint offset, const guint encoding) {
973 if (encoding & ENC_LITTLE_ENDIAN) {
974 return tvb_get_letoh40(tvb, offset);
976 return tvb_get_ntoh40(tvb, offset);
981 tvb_get_gint40(tvbuff_t *tvb, const gint offset, const guint encoding) {
982 if (encoding & ENC_LITTLE_ENDIAN) {
983 return tvb_get_letohi40(tvb, offset);
985 return tvb_get_ntohi40(tvb, offset);
990 tvb_get_guint48(tvbuff_t *tvb, const gint offset, const guint encoding) {
991 if (encoding & ENC_LITTLE_ENDIAN) {
992 return tvb_get_letoh48(tvb, offset);
994 return tvb_get_ntoh48(tvb, offset);
999 tvb_get_gint48(tvbuff_t *tvb, const gint offset, const guint encoding) {
1000 if (encoding & ENC_LITTLE_ENDIAN) {
1001 return tvb_get_letohi48(tvb, offset);
1003 return tvb_get_ntohi48(tvb, offset);
1008 tvb_get_guint56(tvbuff_t *tvb, const gint offset, const guint encoding) {
1009 if (encoding & ENC_LITTLE_ENDIAN) {
1010 return tvb_get_letoh56(tvb, offset);
1012 return tvb_get_ntoh56(tvb, offset);
1017 tvb_get_gint56(tvbuff_t *tvb, const gint offset, const guint encoding) {
1018 if (encoding & ENC_LITTLE_ENDIAN) {
1019 return tvb_get_letohi56(tvb, offset);
1021 return tvb_get_ntohi56(tvb, offset);
1026 tvb_get_guint64(tvbuff_t *tvb, const gint offset, const guint encoding) {
1027 if (encoding & ENC_LITTLE_ENDIAN) {
1028 return tvb_get_letoh64(tvb, offset);
1030 return tvb_get_ntoh64(tvb, offset);
1035 tvb_get_ieee_float(tvbuff_t *tvb, const gint offset, const guint encoding) {
1036 if (encoding & ENC_LITTLE_ENDIAN) {
1037 return tvb_get_letohieee_float(tvb, offset);
1039 return tvb_get_ntohieee_float(tvb, offset);
1044 tvb_get_ieee_double(tvbuff_t *tvb, const gint offset, const guint encoding) {
1045 if (encoding & ENC_LITTLE_ENDIAN) {
1046 return tvb_get_letohieee_double(tvb, offset);
1048 return tvb_get_ntohieee_double(tvb, offset);
1053 * Stuff for IEEE float handling on platforms that don't have IEEE
1054 * format as the native floating-point format.
1056 * For now, we treat only the VAX as such a platform.
1058 * XXX - other non-IEEE boxes that can run UNIX include some Crays,
1059 * and possibly other machines.
1061 * It appears that the official Linux port to System/390 and
1062 * zArchitecture uses IEEE format floating point (not a
1065 * I don't know whether there are any other machines that
1066 * could run Wireshark and that don't use IEEE format.
1067 * As far as I know, all of the main commercial microprocessor
1068 * families on which OSes that support Wireshark can run
1069 * use IEEE format (x86, 68k, SPARC, MIPS, PA-RISC, Alpha,
1070 * IA-64, and so on).
1080 #define IEEE_SP_NUMBER_WIDTH 32 /* bits in number */
1081 #define IEEE_SP_EXP_WIDTH 8 /* bits in exponent */
1082 #define IEEE_SP_MANTISSA_WIDTH 23 /* IEEE_SP_NUMBER_WIDTH - 1 - IEEE_SP_EXP_WIDTH */
1084 #define IEEE_SP_SIGN_MASK 0x80000000
1085 #define IEEE_SP_EXPONENT_MASK 0x7F800000
1086 #define IEEE_SP_MANTISSA_MASK 0x007FFFFF
1087 #define IEEE_SP_INFINITY IEEE_SP_EXPONENT_MASK
1089 #define IEEE_SP_IMPLIED_BIT (1 << IEEE_SP_MANTISSA_WIDTH)
1090 #define IEEE_SP_INFINITE ((1 << IEEE_SP_EXP_WIDTH) - 1)
1091 #define IEEE_SP_BIAS ((1 << (IEEE_SP_EXP_WIDTH - 1)) - 1)
1094 ieee_float_is_zero(const guint32 w)
1096 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1100 get_ieee_float(const guint32 w)
1106 sign = w & IEEE_SP_SIGN_MASK;
1107 exponent = w & IEEE_SP_EXPONENT_MASK;
1108 mantissa = w & IEEE_SP_MANTISSA_MASK;
1110 if (ieee_float_is_zero(w)) {
1111 /* number is zero, unnormalized, or not-a-number */
1116 * XXX - how to handle this?
1118 if (IEEE_SP_INFINITY == exponent) {
1120 * number is positive or negative infinity, or a special value
1122 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1126 exponent = ((exponent >> IEEE_SP_MANTISSA_WIDTH) - IEEE_SP_BIAS) -
1127 IEEE_SP_MANTISSA_WIDTH;
1128 mantissa |= IEEE_SP_IMPLIED_BIT;
1131 return -mantissa * pow(2, exponent);
1133 return mantissa * pow(2, exponent);
1138 * We assume that if you don't have IEEE floating-point, you have a
1139 * compiler that understands 64-bit integral quantities.
1141 #define IEEE_DP_NUMBER_WIDTH 64 /* bits in number */
1142 #define IEEE_DP_EXP_WIDTH 11 /* bits in exponent */
1143 #define IEEE_DP_MANTISSA_WIDTH 52 /* IEEE_DP_NUMBER_WIDTH - 1 - IEEE_DP_EXP_WIDTH */
1145 #define IEEE_DP_SIGN_MASK G_GINT64_CONSTANT(0x8000000000000000)
1146 #define IEEE_DP_EXPONENT_MASK G_GINT64_CONSTANT(0x7FF0000000000000)
1147 #define IEEE_DP_MANTISSA_MASK G_GINT64_CONSTANT(0x000FFFFFFFFFFFFF)
1148 #define IEEE_DP_INFINITY IEEE_DP_EXPONENT_MASK
1150 #define IEEE_DP_IMPLIED_BIT (G_GINT64_CONSTANT(1) << IEEE_DP_MANTISSA_WIDTH)
1151 #define IEEE_DP_INFINITE ((1 << IEEE_DP_EXP_WIDTH) - 1)
1152 #define IEEE_DP_BIAS ((1 << (IEEE_DP_EXP_WIDTH - 1)) - 1)
1155 ieee_double_is_zero(const guint64 w)
1157 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1161 get_ieee_double(const guint64 w)
1167 sign = w & IEEE_DP_SIGN_MASK;
1168 exponent = w & IEEE_DP_EXPONENT_MASK;
1169 mantissa = w & IEEE_DP_MANTISSA_MASK;
1171 if (ieee_double_is_zero(w)) {
1172 /* number is zero, unnormalized, or not-a-number */
1177 * XXX - how to handle this?
1179 if (IEEE_DP_INFINITY == exponent) {
1181 * number is positive or negative infinity, or a special value
1183 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1187 exponent = ((exponent >> IEEE_DP_MANTISSA_WIDTH) - IEEE_DP_BIAS) -
1188 IEEE_DP_MANTISSA_WIDTH;
1189 mantissa |= IEEE_DP_IMPLIED_BIT;
1192 return -mantissa * pow(2, exponent);
1194 return mantissa * pow(2, exponent);
1199 * Fetches an IEEE single-precision floating-point number, in
1200 * big-endian form, and returns a "float".
1202 * XXX - should this be "double", in case there are IEEE single-
1203 * precision numbers that won't fit in some platform's native
1207 tvb_get_ntohieee_float(tvbuff_t *tvb, const int offset)
1210 return get_ieee_float(tvb_get_ntohl(tvb, offset));
1217 ieee_fp_union.w = tvb_get_ntohl(tvb, offset);
1218 return ieee_fp_union.f;
1223 * Fetches an IEEE double-precision floating-point number, in
1224 * big-endian form, and returns a "double".
1227 tvb_get_ntohieee_double(tvbuff_t *tvb, const int offset)
1241 #ifdef WORDS_BIGENDIAN
1242 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset);
1243 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset+4);
1245 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset+4);
1246 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset);
1249 return get_ieee_double(ieee_fp_union.dw);
1251 return ieee_fp_union.d;
1256 tvb_get_letohs(tvbuff_t *tvb, const gint offset)
1260 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint16));
1261 return pletoh16(ptr);
1265 tvb_get_letoh24(tvbuff_t *tvb, const gint offset)
1269 ptr = fast_ensure_contiguous(tvb, offset, 3);
1270 return pletoh24(ptr);
1274 tvb_get_letohl(tvbuff_t *tvb, const gint offset)
1278 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1279 return pletoh32(ptr);
1283 tvb_get_letoh40(tvbuff_t *tvb, const gint offset)
1287 ptr = fast_ensure_contiguous(tvb, offset, 5);
1288 return pletoh40(ptr);
1292 tvb_get_letohi40(tvbuff_t *tvb, const gint offset)
1296 ret = ws_sign_ext64(tvb_get_letoh40(tvb, offset), 40);
1302 tvb_get_letoh48(tvbuff_t *tvb, const gint offset)
1306 ptr = fast_ensure_contiguous(tvb, offset, 6);
1307 return pletoh48(ptr);
1311 tvb_get_letohi48(tvbuff_t *tvb, const gint offset)
1315 ret = ws_sign_ext64(tvb_get_letoh48(tvb, offset), 48);
1321 tvb_get_letoh56(tvbuff_t *tvb, const gint offset)
1325 ptr = fast_ensure_contiguous(tvb, offset, 7);
1326 return pletoh56(ptr);
1330 tvb_get_letohi56(tvbuff_t *tvb, const gint offset)
1334 ret = ws_sign_ext64(tvb_get_letoh56(tvb, offset), 56);
1340 tvb_get_letoh64(tvbuff_t *tvb, const gint offset)
1344 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint64));
1345 return pletoh64(ptr);
1349 * Fetches an IEEE single-precision floating-point number, in
1350 * little-endian form, and returns a "float".
1352 * XXX - should this be "double", in case there are IEEE single-
1353 * precision numbers that won't fit in some platform's native
1357 tvb_get_letohieee_float(tvbuff_t *tvb, const int offset)
1360 return get_ieee_float(tvb_get_letohl(tvb, offset));
1367 ieee_fp_union.w = tvb_get_letohl(tvb, offset);
1368 return ieee_fp_union.f;
1373 * Fetches an IEEE double-precision floating-point number, in
1374 * little-endian form, and returns a "double".
1377 tvb_get_letohieee_double(tvbuff_t *tvb, const int offset)
1391 #ifdef WORDS_BIGENDIAN
1392 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset+4);
1393 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset);
1395 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset);
1396 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset+4);
1399 return get_ieee_double(ieee_fp_union.dw);
1401 return ieee_fp_union.d;
1406 validate_single_byte_ascii_encoding(const guint encoding)
1408 const guint enc = encoding & ~ENC_STR_MASK;
1414 case ENC_3GPP_TS_23_038_7BITS:
1416 REPORT_DISSECTOR_BUG("Invalid string encoding type passed to tvb_get_string_XXX");
1421 /* make sure something valid was set */
1423 REPORT_DISSECTOR_BUG("No string encoding type passed to tvb_get_string_XXX");
1427 tvb_get_string_bytes(tvbuff_t *tvb, const gint offset, const gint length,
1428 const guint encoding, GByteArray *bytes, gint *endoff)
1430 const gchar *ptr = (gchar*) tvb_get_raw_string(wmem_packet_scope(), tvb, offset, length);
1431 const gchar *begin = ptr;
1432 const gchar *end = NULL;
1433 GByteArray *retval = NULL;
1437 validate_single_byte_ascii_encoding(encoding);
1439 if (endoff) *endoff = 0;
1441 while (*begin == ' ') begin++;
1443 if (*begin && bytes) {
1444 if (hex_str_to_bytes_encoding(begin, bytes, &end, encoding, FALSE)) {
1445 if (bytes->len > 0) {
1446 if (endoff) *endoff = offset + (gint)(end - ptr);
1456 /* support hex-encoded time values? */
1458 tvb_get_string_time(tvbuff_t *tvb, const gint offset, const gint length,
1459 const guint encoding, nstime_t *ns, gint *endoff)
1461 const gchar *begin = (gchar*) tvb_get_raw_string(wmem_packet_scope(), tvb, offset, length);
1462 const gchar *ptr = begin;
1463 const gchar *end = NULL;
1465 nstime_t* retval = NULL;
1470 gboolean matched = FALSE;
1474 validate_single_byte_ascii_encoding(encoding);
1476 DISSECTOR_ASSERT(ns);
1478 memset(&tm, 0, sizeof(tm));
1483 while (*ptr == ' ') ptr++;
1486 /* note: sscanf is known to be inconsistent across platforms with respect
1487 to whether a %n is counted as a return value or not, so we have to use
1489 if ((encoding & ENC_ISO_8601_DATE_TIME) == ENC_ISO_8601_DATE_TIME) {
1490 /* TODO: using sscanf this many times is probably slow; might want
1491 to parse it by hand in the future */
1492 /* 2014-04-07T05:41:56+00:00 */
1493 if (sscanf(ptr, "%d-%d-%d%*c%d:%d:%d%c%d:%d%n",
1507 /* no seconds is ok */
1508 else if (sscanf(ptr, "%d-%d-%d%*c%d:%d%c%d:%d%n",
1521 /* 2007-04-05T14:30:56Z */
1522 else if (sscanf(ptr, "%d-%d-%d%*c%d:%d:%dZ%n",
1535 /* 2007-04-05T14:30Z no seconds is ok */
1536 else if (sscanf(ptr, "%d-%d-%d%*c%d:%dZ%n",
1551 end = ptr + num_chars;
1553 if (tm.tm_year > 1900) tm.tm_year -= 1900;
1554 if (sign == '-') off_hr = -off_hr;
1557 else if (encoding & ENC_ISO_8601_DATE) {
1559 if (sscanf(ptr, "%d-%d-%d%n",
1566 end = ptr + num_chars;
1568 if (tm.tm_year > 1900) tm.tm_year -= 1900;
1571 else if (encoding & ENC_ISO_8601_TIME) {
1573 if (sscanf(ptr, "%d:%d:%d%n",
1579 /* what should we do about day/month/year? */
1580 /* setting it to "now" for now */
1581 time_t time_now = time(NULL);
1582 struct tm *tm_now = gmtime(&time_now);
1583 tm.tm_year = tm_now->tm_year;
1584 tm.tm_mon = tm_now->tm_mon;
1585 tm.tm_mday = tm_now->tm_mday;
1586 end = ptr + num_chars;
1591 else if (encoding & ENC_RFC_822 || encoding & ENC_RFC_1123) {
1592 if (encoding & ENC_RFC_822) {
1593 /* this will unfortunately match ENC_RFC_1123 style
1594 strings too, partially - probably need to do this the long way */
1595 end = strptime(ptr, "%a, %d %b %y %H:%M:%S", &tm);
1596 if (!end) end = strptime(ptr, "%a, %d %b %y %H:%M", &tm);
1597 if (!end) end = strptime(ptr, "%d %b %y %H:%M:%S", &tm);
1598 if (!end) end = strptime(ptr, "%d %b %y %H:%M", &tm);
1600 else if (encoding & ENC_RFC_1123) {
1601 end = strptime(ptr, "%a, %d %b %Y %H:%M:%S", &tm);
1602 if (!end) end = strptime(ptr, "%a, %d %b %Y %H:%M", &tm);
1603 if (!end) end = strptime(ptr, "%d %b %Y %H:%M:%S", &tm);
1604 if (!end) end = strptime(ptr, "%d %b %Y %H:%M", &tm);
1608 if (*end == ' ') end++;
1609 if (g_ascii_strncasecmp(end, "UT", 2) == 0)
1613 else if (g_ascii_strncasecmp(end, "GMT", 3) == 0)
1617 else if (sscanf(end, "%c%2d%2d%n",
1625 if (sign == '-') off_hr = -off_hr;
1631 ns->secs = mktime_utc (&tm);
1633 ns->secs += (off_hr * 3600) + (off_min * 60);
1634 else if (off_hr < 0)
1635 ns->secs -= ((-off_hr) * 3600) + (off_min * 60);
1638 *endoff = (gint)(offset + (end - begin));
1644 /* Fetch an IPv4 address, in network byte order.
1645 * We do *not* convert them to host byte order; we leave them in
1646 * network byte order. */
1648 tvb_get_ipv4(tvbuff_t *tvb, const gint offset)
1653 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1654 memcpy(&addr, ptr, sizeof addr);
1658 /* Fetch an IPv6 address. */
1660 tvb_get_ipv6(tvbuff_t *tvb, const gint offset, struct e_in6_addr *addr)
1664 ptr = ensure_contiguous(tvb, offset, sizeof(*addr));
1665 memcpy(addr, ptr, sizeof *addr);
1670 tvb_get_ntohguid(tvbuff_t *tvb, const gint offset, e_guid_t *guid)
1672 const guint8 *ptr = ensure_contiguous(tvb, offset, GUID_LEN);
1674 guid->data1 = pntoh32(ptr + 0);
1675 guid->data2 = pntoh16(ptr + 4);
1676 guid->data3 = pntoh16(ptr + 6);
1677 memcpy(guid->data4, ptr + 8, sizeof guid->data4);
1681 tvb_get_letohguid(tvbuff_t *tvb, const gint offset, e_guid_t *guid)
1683 const guint8 *ptr = ensure_contiguous(tvb, offset, GUID_LEN);
1685 guid->data1 = pletoh32(ptr + 0);
1686 guid->data2 = pletoh16(ptr + 4);
1687 guid->data3 = pletoh16(ptr + 6);
1688 memcpy(guid->data4, ptr + 8, sizeof guid->data4);
1692 * NOTE: to support code written when proto_tree_add_item() took a
1693 * gboolean as its last argument, with FALSE meaning "big-endian"
1694 * and TRUE meaning "little-endian", we treat any non-zero value of
1695 * "encoding" as meaning "little-endian".
1698 tvb_get_guid(tvbuff_t *tvb, const gint offset, e_guid_t *guid, const guint encoding)
1701 tvb_get_letohguid(tvb, offset, guid);
1703 tvb_get_ntohguid(tvb, offset, guid);
1707 static const guint8 bit_mask8[] = {
1719 /* Get 1 - 8 bits */
1721 tvb_get_bits8(tvbuff_t *tvb, guint bit_offset, const gint no_of_bits)
1723 return (guint8)_tvb_get_bits64(tvb, bit_offset, no_of_bits);
1726 /* Get 9 - 16 bits */
1728 tvb_get_bits16(tvbuff_t *tvb, guint bit_offset, const gint no_of_bits,const guint encoding _U_)
1730 /* note that encoding has no meaning here, as the tvb is considered to contain an octet array */
1731 return (guint16)_tvb_get_bits64(tvb, bit_offset, no_of_bits);
1734 /* Get 1 - 32 bits */
1736 tvb_get_bits32(tvbuff_t *tvb, guint bit_offset, const gint no_of_bits, const guint encoding _U_)
1738 /* note that encoding has no meaning here, as the tvb is considered to contain an octet array */
1739 return (guint32)_tvb_get_bits64(tvb, bit_offset, no_of_bits);
1742 /* Get 1 - 64 bits */
1744 tvb_get_bits64(tvbuff_t *tvb, guint bit_offset, const gint no_of_bits, const guint encoding _U_)
1746 /* note that encoding has no meaning here, as the tvb is considered to contain an octet array */
1747 return _tvb_get_bits64(tvb, bit_offset, no_of_bits);
1750 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
1751 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
1752 * Offset should be given in bits from the start of the tvb.
1753 * The function tolerates requests for more than 64 bits, but will only return the least significant 64 bits.
1756 _tvb_get_bits64(tvbuff_t *tvb, guint bit_offset, const gint total_no_of_bits)
1759 guint octet_offset = bit_offset >> 3;
1760 guint8 required_bits_in_first_octet = 8 - (bit_offset % 8);
1762 if(required_bits_in_first_octet > total_no_of_bits)
1764 /* the required bits don't extend to the end of the first octet */
1765 guint8 right_shift = required_bits_in_first_octet - total_no_of_bits;
1766 value = (tvb_get_guint8(tvb, octet_offset) >> right_shift) & bit_mask8[total_no_of_bits % 8];
1770 guint8 remaining_bit_length = total_no_of_bits;
1772 /* get the bits up to the first octet boundary */
1774 required_bits_in_first_octet %= 8;
1775 if(required_bits_in_first_octet != 0)
1777 value = tvb_get_guint8(tvb, octet_offset) & bit_mask8[required_bits_in_first_octet];
1778 remaining_bit_length -= required_bits_in_first_octet;
1781 /* take the biggest words, shorts or octets that we can */
1782 while (remaining_bit_length > 7)
1784 switch (remaining_bit_length >> 4)
1787 /* 8 - 15 bits. (note that 0 - 7 would have dropped out of the while() loop) */
1789 value += tvb_get_guint8(tvb, octet_offset);
1790 remaining_bit_length -= 8;
1797 value += tvb_get_ntohs(tvb, octet_offset);
1798 remaining_bit_length -= 16;
1806 value += tvb_get_ntohl(tvb, octet_offset);
1807 remaining_bit_length -= 32;
1812 /* 64 bits (or more???) */
1813 value = tvb_get_ntoh64(tvb, octet_offset);
1814 remaining_bit_length -= 64;
1819 /* get bits from any partial octet at the tail */
1820 if(remaining_bit_length)
1822 value <<= remaining_bit_length;
1823 value += (tvb_get_guint8(tvb, octet_offset) >> (8 - remaining_bit_length));
1828 /* Get 1 - 32 bits (should be deprecated as same as tvb_get_bits32??) */
1830 tvb_get_bits(tvbuff_t *tvb, const guint bit_offset, const gint no_of_bits, const guint encoding _U_)
1832 /* note that encoding has no meaning here, as the tvb is considered to contain an octet array */
1833 return (guint32)_tvb_get_bits64(tvb, bit_offset, no_of_bits);
1837 tvb_find_guint8_generic(tvbuff_t *tvb, guint abs_offset, guint limit, guint8 needle)
1840 const guint8 *result;
1842 ptr = ensure_contiguous(tvb, abs_offset, limit); /* tvb_get_ptr() */
1844 result = (const guint8 *) memchr(ptr, needle, limit);
1848 return (gint) ((result - ptr) + abs_offset);
1851 /* Find first occurrence of needle in tvbuff, starting at offset. Searches
1852 * at most maxlength number of bytes; if maxlength is -1, searches to
1854 * Returns the offset of the found needle, or -1 if not found.
1855 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1856 * in that case, -1 will be returned if the boundary is reached before
1857 * finding needle. */
1859 tvb_find_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength, const guint8 needle)
1861 const guint8 *result;
1862 guint abs_offset = 0;
1866 DISSECTOR_ASSERT(tvb && tvb->initialized);
1868 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &limit);
1872 /* Only search to end of tvbuff, w/o throwing exception. */
1873 if (maxlength >= 0 && limit > (guint) maxlength) {
1874 /* Maximum length doesn't go past end of tvbuff; search
1876 limit = (guint) maxlength;
1879 /* If we have real data, perform our search now. */
1880 if (tvb->real_data) {
1881 result = (const guint8 *)memchr(tvb->real_data + abs_offset, needle, limit);
1882 if (result == NULL) {
1886 return (gint) (result - tvb->real_data);
1890 if (tvb->ops->tvb_find_guint8)
1891 return tvb->ops->tvb_find_guint8(tvb, abs_offset, limit, needle);
1893 return tvb_find_guint8_generic(tvb, offset, limit, needle);
1897 tvb_ws_mempbrk_guint8_generic(tvbuff_t *tvb, guint abs_offset, guint limit, const ws_mempbrk_pattern* pattern, guchar *found_needle)
1900 const guint8 *result;
1902 ptr = ensure_contiguous(tvb, abs_offset, limit); /* tvb_get_ptr */
1904 result = ws_mempbrk_exec(ptr, limit, pattern, found_needle);
1908 return (gint) ((result - ptr) + abs_offset);
1912 /* Find first occurrence of any of the pattern chars in tvbuff, starting at offset.
1913 * Searches at most maxlength number of bytes; if maxlength is -1, searches
1915 * Returns the offset of the found needle, or -1 if not found.
1916 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1917 * in that case, -1 will be returned if the boundary is reached before
1918 * finding needle. */
1920 tvb_ws_mempbrk_pattern_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength,
1921 const ws_mempbrk_pattern* pattern, guchar *found_needle)
1923 const guint8 *result;
1924 guint abs_offset = 0;
1928 DISSECTOR_ASSERT(tvb && tvb->initialized);
1930 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &limit);
1934 /* Only search to end of tvbuff, w/o throwing exception. */
1935 if (limit > (guint) maxlength) {
1936 /* Maximum length doesn't go past end of tvbuff; search
1941 /* If we have real data, perform our search now. */
1942 if (tvb->real_data) {
1943 result = ws_mempbrk_exec(tvb->real_data + abs_offset, limit, pattern, found_needle);
1944 if (result == NULL) {
1948 return (gint) (result - tvb->real_data);
1952 if (tvb->ops->tvb_ws_mempbrk_pattern_guint8)
1953 return tvb->ops->tvb_ws_mempbrk_pattern_guint8(tvb, abs_offset, limit, pattern, found_needle);
1955 return tvb_ws_mempbrk_guint8_generic(tvb, abs_offset, limit, pattern, found_needle);
1958 /* Find size of stringz (NUL-terminated string) by looking for terminating
1959 * NUL. The size of the string includes the terminating NUL.
1961 * If the NUL isn't found, it throws the appropriate exception.
1964 tvb_strsize(tvbuff_t *tvb, const gint offset)
1966 guint abs_offset = 0, junk_length;
1969 DISSECTOR_ASSERT(tvb && tvb->initialized);
1971 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1972 nul_offset = tvb_find_guint8(tvb, abs_offset, -1, 0);
1973 if (nul_offset == -1) {
1975 * OK, we hit the end of the tvbuff, so we should throw
1978 * Did we hit the end of the captured data, or the end
1979 * of the actual data? If there's less captured data
1980 * than actual data, we presumably hit the end of the
1981 * captured data, otherwise we hit the end of the actual
1984 if (tvb->length < tvb->reported_length) {
1987 if (tvb->flags & TVBUFF_FRAGMENT) {
1988 THROW(FragmentBoundsError);
1990 THROW(ReportedBoundsError);
1994 return (nul_offset - abs_offset) + 1;
1997 /* UTF-16/UCS-2 version of tvb_strsize */
1998 /* Returns number of bytes including the (two-bytes) null terminator */
2000 tvb_unicode_strsize(tvbuff_t *tvb, const gint offset)
2005 DISSECTOR_ASSERT(tvb && tvb->initialized);
2008 /* Endianness doesn't matter when looking for null */
2009 uchar = tvb_get_ntohs(tvb, offset + i);
2011 } while(uchar != 0);
2016 /* Find length of string by looking for end of string ('\0'), up to
2017 * 'maxlength' characters'; if 'maxlength' is -1, searches to end
2019 * Returns -1 if 'maxlength' reached before finding EOS. */
2021 tvb_strnlen(tvbuff_t *tvb, const gint offset, const guint maxlength)
2024 guint abs_offset = 0, junk_length;
2026 DISSECTOR_ASSERT(tvb && tvb->initialized);
2028 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
2030 result_offset = tvb_find_guint8(tvb, abs_offset, maxlength, 0);
2032 if (result_offset == -1) {
2036 return result_offset - abs_offset;
2041 * Implement strneql etc
2045 * Call strncmp after checking if enough chars left, returning 0 if
2046 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
2049 tvb_strneql(tvbuff_t *tvb, const gint offset, const gchar *str, const size_t size)
2053 ptr = ensure_contiguous_no_exception(tvb, offset, (gint)size, NULL);
2056 int cmp = strncmp((const char *)ptr, str, size);
2059 * Return 0 if equal, -1 otherwise.
2061 return (cmp == 0 ? 0 : -1);
2064 * Not enough characters in the tvbuff to match the
2072 * Call g_ascii_strncasecmp after checking if enough chars left, returning
2073 * 0 if it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
2076 tvb_strncaseeql(tvbuff_t *tvb, const gint offset, const gchar *str, const size_t size)
2080 ptr = ensure_contiguous_no_exception(tvb, offset, (gint)size, NULL);
2083 int cmp = g_ascii_strncasecmp((const char *)ptr, str, size);
2086 * Return 0 if equal, -1 otherwise.
2088 return (cmp == 0 ? 0 : -1);
2091 * Not enough characters in the tvbuff to match the
2099 * Call memcmp after checking if enough chars left, returning 0 if
2100 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
2103 tvb_memeql(tvbuff_t *tvb, const gint offset, const guint8 *str, size_t size)
2107 ptr = ensure_contiguous_no_exception(tvb, offset, (gint) size, NULL);
2110 int cmp = memcmp(ptr, str, size);
2113 * Return 0 if equal, -1 otherwise.
2115 return (cmp == 0 ? 0 : -1);
2118 * Not enough characters in the tvbuff to match the
2126 * Format the data in the tvb from offset for length ...
2129 tvb_format_text(tvbuff_t *tvb, const gint offset, const gint size)
2134 len = (size > 0) ? size : 0;
2136 ptr = ensure_contiguous(tvb, offset, size);
2137 return format_text(ptr, len);
2141 * Format the data in the tvb from offset for length ...
2144 tvb_format_text_wsp(tvbuff_t *tvb, const gint offset, const gint size)
2149 len = (size > 0) ? size : 0;
2151 ptr = ensure_contiguous(tvb, offset, size);
2152 return format_text_wsp(ptr, len);
2156 * Like "tvb_format_text()", but for null-padded strings; don't show
2157 * the null padding characters as "\000".
2160 tvb_format_stringzpad(tvbuff_t *tvb, const gint offset, const gint size)
2162 const guint8 *ptr, *p;
2166 len = (size > 0) ? size : 0;
2168 ptr = ensure_contiguous(tvb, offset, size);
2169 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2171 return format_text(ptr, stringlen);
2175 * Like "tvb_format_text_wsp()", but for null-padded strings; don't show
2176 * the null padding characters as "\000".
2179 tvb_format_stringzpad_wsp(tvbuff_t *tvb, const gint offset, const gint size)
2181 const guint8 *ptr, *p;
2185 len = (size > 0) ? size : 0;
2187 ptr = ensure_contiguous(tvb, offset, size);
2188 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2190 return format_text_wsp(ptr, stringlen);
2193 /* Unicode REPLACEMENT CHARACTER */
2194 #define UNREPL 0x00FFFD
2197 * All string functions below take a scope as an argument.
2200 * If scope is NULL, memory is allocated with g_malloc() and user must
2201 * explicitly free it with g_free().
2202 * If scope is not NULL, memory is allocated with the corresponding pool
2205 * All functions throw an exception if the tvbuff ends before the string
2210 * Given a wmem scope, tvbuff, an offset, and a length, treat the string
2211 * of bytes referred to by the tvbuff, offset, and length as an ASCII string,
2212 * with all bytes with the high-order bit set being invalid, and return a
2213 * pointer to a UTF-8 string, allocated using the wmem scope.
2215 * Octets with the highest bit set will be converted to the Unicode
2216 * REPLACEMENT CHARACTER.
2219 tvb_get_ascii_string(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint length)
2223 ptr = ensure_contiguous(tvb, offset, length);
2224 return get_ascii_string(scope, ptr, length);
2228 * Given a wmem scope, a tvbuff, an offset, and a length, treat the string
2229 * of bytes referred to by the tvbuff, the offset. and the length as a UTF-8
2230 * string, and return a pointer to that string, allocated using the wmem scope.
2232 * XXX - should map invalid UTF-8 sequences to UNREPL.
2235 tvb_get_utf_8_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, const gint length)
2239 tvb_ensure_bytes_exist(tvb, offset, length); /* make sure length = -1 fails */
2240 strbuf = (guint8 *)wmem_alloc(scope, length + 1);
2241 tvb_memcpy(tvb, strbuf, offset, length);
2242 strbuf[length] = '\0';
2247 * Given a wmem scope, tvbuff, an offset, and a length, treat the string
2248 * of bytes referred to by the tvbuff, the offset, and the length as a
2249 * raw string, and return a pointer to that string, allocated using the
2250 * wmem scope. This means a null is appended at the end, but no replacement
2251 * checking is done otherwise. Currently tvb_get_utf_8_string() does not
2252 * replace either, but it might in the future.
2254 * Also, this one allows a length of -1 to mean get all, but does not
2255 * allow a negative offset.
2257 static inline guint8 *
2258 tvb_get_raw_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, const gint length)
2261 gint abs_length = length;
2263 DISSECTOR_ASSERT(offset >= 0);
2264 DISSECTOR_ASSERT(abs_length >= -1);
2267 abs_length = tvb->length - offset;
2269 tvb_ensure_bytes_exist(tvb, offset, abs_length);
2270 strbuf = (guint8 *)wmem_alloc(scope, abs_length + 1);
2271 tvb_memcpy(tvb, strbuf, offset, abs_length);
2272 strbuf[abs_length] = '\0';
2277 * Given a wmem scope, a tvbuff, an offset, and a length, treat the string
2278 * of bytes referred to by the tvbuff, the offset, and the length as an
2279 * ISO 8859/1 string, and return a pointer to a UTF-8 string, allocated
2280 * using the wmem scope.
2283 tvb_get_string_8859_1(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint length)
2287 ptr = ensure_contiguous(tvb, offset, length);
2288 return get_8859_1_string(scope, ptr, length);
2292 * Given a wmem scope, a tvbuff, an offset, and a length, and a translation
2293 * table, treat the string of bytes referred to by the tvbuff, the offset,
2294 * and the length as a string encoded using one octet per character, with
2295 * octets with the high-order bit clear being ASCII and octets with the
2296 * high-order bit set being mapped by the translation table to 2-byte
2297 * Unicode Basic Multilingual Plane characters (including REPLACEMENT
2298 * CHARACTER), and return a pointer to a UTF-8 string, allocated with the
2302 tvb_get_string_unichar2(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint length, const gunichar2 table[0x80])
2306 ptr = ensure_contiguous(tvb, offset, length);
2307 return get_unichar2_string(scope, ptr, length, table);
2311 * Given a wmem scope, a tvbuff, an offset, a length, and an encoding
2312 * giving the byte order, treat the string of bytes referred to by the
2313 * tvbuff, the offset, and the length as a UCS-2 encoded string in
2314 * the byte order in question, containing characters from the Basic
2315 * Multilingual Plane (plane 0) of Unicode, and return a pointer to a
2316 * UTF-8 string, allocated with the wmem scope.
2318 * Encoding parameter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN.
2320 * Specify length in bytes.
2322 * XXX - should map lead and trail surrogate values to REPLACEMENT
2323 * CHARACTERs (0xFFFD)?
2324 * XXX - if there are an odd number of bytes, should put a
2325 * REPLACEMENT CHARACTER at the end.
2328 tvb_get_ucs_2_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint length, const guint encoding)
2332 ptr = ensure_contiguous(tvb, offset, length);
2333 return get_ucs_2_string(scope, ptr, length, encoding);
2337 * Given a wmem scope, a tvbuff, an offset, a length, and an encoding
2338 * giving the byte order, treat the string of bytes referred to by the
2339 * tvbuff, the offset, and the length as a UTF-16 encoded string in
2340 * the byte order in question, and return a pointer to a UTF-8 string,
2341 * allocated with the wmem scope.
2343 * Encoding parameter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN.
2345 * Specify length in bytes.
2347 * XXX - should map surrogate errors to REPLACEMENT CHARACTERs (0xFFFD).
2348 * XXX - should map code points > 10FFFF to REPLACEMENT CHARACTERs.
2349 * XXX - if there are an odd number of bytes, should put a
2350 * REPLACEMENT CHARACTER at the end.
2353 tvb_get_utf_16_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint length, const guint encoding)
2357 ptr = ensure_contiguous(tvb, offset, length);
2358 return get_utf_16_string(scope, ptr, length, encoding);
2362 * Given a wmem scope, a tvbuff, an offset, a length, and an encoding
2363 * giving the byte order, treat the string of bytes referred to by the
2364 * tvbuff, the offset, and the length as a UCS-4 encoded string in
2365 * the byte order in question, and return a pointer to a UTF-8 string,
2366 * allocated with the wmem scope.
2368 * Encoding parameter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN
2370 * Specify length in bytes
2372 * XXX - should map lead and trail surrogate values to a "substitute"
2374 * XXX - should map code points > 10FFFF to REPLACEMENT CHARACTERs.
2375 * XXX - if the number of bytes isn't a multiple of 4, should put a
2376 * REPLACEMENT CHARACTER at the end.
2379 tvb_get_ucs_4_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint length, const guint encoding)
2383 ptr = ensure_contiguous(tvb, offset, length);
2384 return get_ucs_4_string(scope, ptr, length, encoding);
2388 tvb_get_ts_23_038_7bits_string(wmem_allocator_t *scope, tvbuff_t *tvb,
2389 const gint bit_offset, gint no_of_chars)
2391 gint in_offset = bit_offset >> 3; /* Current pointer to the input buffer */
2392 gint length = ((no_of_chars + 1) * 7 + (bit_offset & 0x07)) >> 3;
2395 DISSECTOR_ASSERT(tvb && tvb->initialized);
2397 ptr = ensure_contiguous(tvb, in_offset, length);
2398 return get_ts_23_038_7bits_string(scope, ptr, bit_offset, no_of_chars);
2402 tvb_get_ascii_7bits_string(wmem_allocator_t *scope, tvbuff_t *tvb,
2403 const gint bit_offset, gint no_of_chars)
2405 gint in_offset = bit_offset >> 3; /* Current pointer to the input buffer */
2406 gint length = ((no_of_chars + 1) * 7 + (bit_offset & 0x07)) >> 3;
2409 DISSECTOR_ASSERT(tvb && tvb->initialized);
2411 ptr = ensure_contiguous(tvb, in_offset, length);
2412 return get_ascii_7bits_string(scope, ptr, bit_offset, no_of_chars);
2416 * Given a wmem scope, a tvbuff, an offset, and a length, treat the string
2417 * of bytes referred to by the tvbuff, offset, and length as a string encoded
2418 * in EBCDIC using one octet per character, and return a pointer to a
2419 * UTF-8 string, allocated using the wmem scope.
2422 tvb_get_ebcdic_string(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint length)
2426 ptr = ensure_contiguous(tvb, offset, length);
2427 return get_ebcdic_string(scope, ptr, length);
2431 * Given a tvbuff, an offset, a length, and an encoding, allocate a
2432 * buffer big enough to hold a non-null-terminated string of that length
2433 * at that offset, plus a trailing '\0', copy into the buffer the
2434 * string as converted from the appropriate encoding to UTF-8, and
2435 * return a pointer to the string.
2438 tvb_get_string_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset,
2439 const gint length, const guint encoding)
2443 DISSECTOR_ASSERT(tvb && tvb->initialized);
2445 /* make sure length = -1 fails */
2447 THROW(ReportedBoundsError);
2450 switch (encoding & ENC_CHARENCODING_MASK) {
2455 * For now, we treat bogus values as meaning
2456 * "ASCII" rather than reporting an error,
2457 * for the benefit of old dissectors written
2458 * when the last argument to proto_tree_add_item()
2459 * was a gboolean for the byte order, not an
2460 * encoding value, and passed non-zero values
2461 * other than TRUE to mean "little-endian".
2463 strptr = tvb_get_ascii_string(scope, tvb, offset, length);
2468 * XXX - should map lead and trail surrogate value code
2469 * points to a "substitute" UTF-8 character?
2470 * XXX - should map code points > 10FFFF to REPLACEMENT
2473 strptr = tvb_get_utf_8_string(scope, tvb, offset, length);
2477 strptr = tvb_get_utf_16_string(scope, tvb, offset, length,
2478 encoding & ENC_LITTLE_ENDIAN);
2482 strptr = tvb_get_ucs_2_string(scope, tvb, offset, length,
2483 encoding & ENC_LITTLE_ENDIAN);
2487 strptr = tvb_get_ucs_4_string(scope, tvb, offset, length,
2488 encoding & ENC_LITTLE_ENDIAN);
2491 case ENC_ISO_8859_1:
2493 * ISO 8859-1 printable code point values are equal
2494 * to the equivalent Unicode code point value, so
2495 * no translation table is needed.
2497 strptr = tvb_get_string_8859_1(scope, tvb, offset, length);
2500 case ENC_ISO_8859_2:
2501 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_2);
2504 case ENC_ISO_8859_3:
2505 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_3);
2508 case ENC_ISO_8859_4:
2509 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_4);
2512 case ENC_ISO_8859_5:
2513 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_5);
2516 case ENC_ISO_8859_6:
2517 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_6);
2520 case ENC_ISO_8859_7:
2521 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_7);
2524 case ENC_ISO_8859_8:
2525 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_8);
2528 case ENC_ISO_8859_9:
2529 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_9);
2532 case ENC_ISO_8859_10:
2533 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_10);
2536 case ENC_ISO_8859_11:
2537 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_11);
2540 case ENC_ISO_8859_13:
2541 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_13);
2544 case ENC_ISO_8859_14:
2545 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_14);
2548 case ENC_ISO_8859_15:
2549 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_15);
2552 case ENC_ISO_8859_16:
2553 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_16);
2556 case ENC_WINDOWS_1250:
2557 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_cp1250);
2561 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_mac_roman);
2565 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_cp437);
2568 case ENC_3GPP_TS_23_038_7BITS:
2570 gint bit_offset = offset << 3;
2571 gint no_of_chars = (length << 3) / 7;
2572 strptr = tvb_get_ts_23_038_7bits_string(scope, tvb, bit_offset, no_of_chars);
2576 case ENC_ASCII_7BITS:
2578 gint bit_offset = offset << 3;
2579 gint no_of_chars = (length << 3) / 7;
2580 strptr = tvb_get_ascii_7bits_string(scope, tvb, bit_offset, no_of_chars);
2586 * XXX - multiple "dialects" of EBCDIC?
2588 strptr = tvb_get_ebcdic_string(scope, tvb, offset, length);
2595 * This is like tvb_get_string_enc(), except that it handles null-padded
2598 * Currently, string values are stored as UTF-8 null-terminated strings,
2599 * so nothing needs to be done differently for null-padded strings; we
2600 * could save a little memory by not storing the null padding.
2602 * If we ever store string values differently, in a fashion that doesn't
2603 * involve null termination, that might change.
2606 tvb_get_stringzpad(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset,
2607 const gint length, const guint encoding)
2609 return tvb_get_string_enc(scope, tvb, offset, length, encoding);
2613 * These routines are like the above routines, except that they handle
2614 * null-terminated strings. They find the length of that string (and
2615 * throw an exception if the tvbuff ends before we find the null), and
2616 * also return through a pointer the length of the string, in bytes,
2617 * including the terminating null (the terminating null being 2 bytes
2618 * for UCS-2 and UTF-16, 4 bytes for UCS-4, and 1 byte for other
2622 tvb_get_ascii_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint *lengthp)
2627 size = tvb_strsize(tvb, offset);
2628 ptr = ensure_contiguous(tvb, offset, size);
2629 /* XXX, conversion between signed/unsigned integer */
2632 return get_ascii_string(scope, ptr, size);
2636 tvb_get_utf_8_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint *lengthp)
2641 size = tvb_strsize(tvb, offset);
2642 strptr = (guint8 *)wmem_alloc(scope, size);
2643 tvb_memcpy(tvb, strptr, offset, size);
2650 tvb_get_stringz_8859_1(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint *lengthp)
2655 size = tvb_strsize(tvb, offset);
2656 ptr = ensure_contiguous(tvb, offset, size);
2657 /* XXX, conversion between signed/unsigned integer */
2660 return get_8859_1_string(scope, ptr, size);
2664 tvb_get_stringz_unichar2(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint *lengthp, const gunichar2 table[0x80])
2669 size = tvb_strsize(tvb, offset);
2670 ptr = ensure_contiguous(tvb, offset, size);
2671 /* XXX, conversion between signed/unsigned integer */
2674 return get_unichar2_string(scope, ptr, size, table);
2678 * Given a tvbuff and an offset, with the offset assumed to refer to
2679 * a null-terminated string, find the length of that string (and throw
2680 * an exception if the tvbuff ends before we find the null), ensure that
2681 * the TVB is flat, and return a pointer to the string (in the TVB).
2682 * Also return the length of the string (including the terminating null)
2683 * through a pointer.
2685 * As long as we aren't using composite TVBs, this saves the cycles used
2686 * (often unnecessariliy) in allocating a buffer and copying the string into
2687 * it. (If we do start using composite TVBs, we may want to replace this
2688 * function with the _ephemeral version.)
2691 tvb_get_const_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp)
2694 const guint8 *strptr;
2696 size = tvb_strsize(tvb, offset);
2697 strptr = ensure_contiguous(tvb, offset, size);
2704 tvb_get_ucs_2_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding)
2706 gint size; /* Number of bytes in string */
2709 size = tvb_unicode_strsize(tvb, offset);
2710 ptr = ensure_contiguous(tvb, offset, size);
2711 /* XXX, conversion between signed/unsigned integer */
2714 return get_ucs_2_string(scope, ptr, size, encoding);
2718 tvb_get_utf_16_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding)
2723 size = tvb_unicode_strsize(tvb, offset);
2724 ptr = ensure_contiguous(tvb, offset, size);
2725 /* XXX, conversion between signed/unsigned integer */
2728 return get_utf_16_string(scope, ptr, size, encoding);
2732 tvb_get_ucs_4_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding)
2740 /* Endianness doesn't matter when looking for null */
2741 uchar = tvb_get_ntohl(tvb, offset + size);
2743 } while(uchar != 0);
2745 ptr = ensure_contiguous(tvb, offset, size);
2746 /* XXX, conversion between signed/unsigned integer */
2749 return get_ucs_4_string(scope, ptr, size, encoding);
2753 tvb_get_ebcdic_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint *lengthp)
2758 size = tvb_strsize(tvb, offset);
2759 ptr = ensure_contiguous(tvb, offset, size);
2760 /* XXX, conversion between signed/unsigned integer */
2763 return get_ebcdic_string(scope, ptr, size);
2767 tvb_get_stringz_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding)
2771 DISSECTOR_ASSERT(tvb && tvb->initialized);
2773 switch (encoding & ENC_CHARENCODING_MASK) {
2778 * For now, we treat bogus values as meaning
2779 * "ASCII" rather than reporting an error,
2780 * for the benefit of old dissectors written
2781 * when the last argument to proto_tree_add_item()
2782 * was a gboolean for the byte order, not an
2783 * encoding value, and passed non-zero values
2784 * other than TRUE to mean "little-endian".
2786 strptr = tvb_get_ascii_stringz(scope, tvb, offset, lengthp);
2791 * XXX - should map all invalid UTF-8 sequences
2792 * to a "substitute" UTF-8 character.
2793 * XXX - should map code points > 10FFFF to REPLACEMENT
2796 strptr = tvb_get_utf_8_stringz(scope, tvb, offset, lengthp);
2800 strptr = tvb_get_utf_16_stringz(scope, tvb, offset, lengthp,
2801 encoding & ENC_LITTLE_ENDIAN);
2805 strptr = tvb_get_ucs_2_stringz(scope, tvb, offset, lengthp,
2806 encoding & ENC_LITTLE_ENDIAN);
2810 strptr = tvb_get_ucs_4_stringz(scope, tvb, offset, lengthp,
2811 encoding & ENC_LITTLE_ENDIAN);
2814 case ENC_ISO_8859_1:
2816 * ISO 8859-1 printable code point values are equal
2817 * to the equivalent Unicode code point value, so
2818 * no translation table is needed.
2820 strptr = tvb_get_stringz_8859_1(scope, tvb, offset, lengthp);
2823 case ENC_ISO_8859_2:
2824 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_2);
2827 case ENC_ISO_8859_3:
2828 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_3);
2831 case ENC_ISO_8859_4:
2832 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_4);
2835 case ENC_ISO_8859_5:
2836 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_5);
2839 case ENC_ISO_8859_6:
2840 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_6);
2843 case ENC_ISO_8859_7:
2844 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_7);
2847 case ENC_ISO_8859_8:
2848 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_8);
2851 case ENC_ISO_8859_9:
2852 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_9);
2855 case ENC_ISO_8859_10:
2856 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_10);
2859 case ENC_ISO_8859_11:
2860 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_11);
2863 case ENC_ISO_8859_13:
2864 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_13);
2867 case ENC_ISO_8859_14:
2868 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_14);
2871 case ENC_ISO_8859_15:
2872 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_15);
2875 case ENC_ISO_8859_16:
2876 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_16);
2879 case ENC_WINDOWS_1250:
2880 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_cp1250);
2884 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_mac_roman);
2888 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_cp437);
2891 case ENC_3GPP_TS_23_038_7BITS:
2892 REPORT_DISSECTOR_BUG("TS 23.038 7bits has no null character and doesn't support null-terminated strings");
2895 case ENC_ASCII_7BITS:
2896 REPORT_DISSECTOR_BUG("tvb_get_stringz_enc function with ENC_ASCII_7BITS not implemented yet");
2901 * XXX - multiple "dialects" of EBCDIC?
2903 strptr = tvb_get_ebcdic_stringz(scope, tvb, offset, lengthp);
2910 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
2911 * no more than bufsize number of bytes, including terminating NUL, to buffer.
2912 * Returns length of string (not including terminating NUL), or -1 if the string was
2913 * truncated in the buffer due to not having reached the terminating NUL.
2914 * In this way, it acts like g_snprintf().
2916 * bufsize MUST be greater than 0.
2918 * When processing a packet where the remaining number of bytes is less
2919 * than bufsize, an exception is not thrown if the end of the packet
2920 * is reached before the NUL is found. If no NUL is found before reaching
2921 * the end of the short packet, -1 is still returned, and the string
2922 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
2923 * at the correct spot, terminating the string.
2925 * *bytes_copied will contain the number of bytes actually copied,
2926 * including the terminating-NUL.
2929 _tvb_get_nstringz(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* buffer, gint *bytes_copied)
2932 guint abs_offset = 0;
2933 gint limit, len = 0;
2934 gboolean decreased_max = FALSE;
2936 /* Only read to end of tvbuff, w/o throwing exception. */
2937 check_offset_length(tvb, offset, -1, &abs_offset, &len);
2939 /* There must at least be room for the terminating NUL. */
2940 DISSECTOR_ASSERT(bufsize != 0);
2942 /* If there's no room for anything else, just return the NUL. */
2949 /* check_offset_length() won't throw an exception if we're
2950 * looking at the byte immediately after the end of the tvbuff. */
2952 THROW(ReportedBoundsError);
2955 /* This should not happen because check_offset_length() would
2956 * have already thrown an exception if 'offset' were out-of-bounds.
2958 DISSECTOR_ASSERT(len != -1);
2961 * If we've been passed a negative number, bufsize will
2964 DISSECTOR_ASSERT(bufsize <= G_MAXINT);
2966 if ((guint)len < bufsize) {
2968 decreased_max = TRUE;
2974 stringlen = tvb_strnlen(tvb, abs_offset, limit - 1);
2975 /* If NUL wasn't found, copy the data and return -1 */
2976 if (stringlen == -1) {
2977 tvb_memcpy(tvb, buffer, abs_offset, limit);
2978 if (decreased_max) {
2980 /* Add 1 for the extra NUL that we set at buffer[limit],
2981 * pretending that it was copied as part of the string. */
2982 *bytes_copied = limit + 1;
2985 *bytes_copied = limit;
2990 /* Copy the string to buffer */
2991 tvb_memcpy(tvb, buffer, abs_offset, stringlen + 1);
2992 *bytes_copied = stringlen + 1;
2996 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
2997 * no more than bufsize number of bytes, including terminating NUL, to buffer.
2998 * Returns length of string (not including terminating NUL), or -1 if the string was
2999 * truncated in the buffer due to not having reached the terminating NUL.
3000 * In this way, it acts like g_snprintf().
3002 * When processing a packet where the remaining number of bytes is less
3003 * than bufsize, an exception is not thrown if the end of the packet
3004 * is reached before the NUL is found. If no NUL is found before reaching
3005 * the end of the short packet, -1 is still returned, and the string
3006 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
3007 * at the correct spot, terminating the string.
3010 tvb_get_nstringz(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8 *buffer)
3014 DISSECTOR_ASSERT(tvb && tvb->initialized);
3016 return _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
3019 /* Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
3020 * have a terminating NUL. If the string was truncated when copied into buffer,
3021 * a NUL is placed at the end of buffer to terminate it.
3024 tvb_get_nstringz0(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* buffer)
3026 gint len, bytes_copied;
3028 DISSECTOR_ASSERT(tvb && tvb->initialized);
3030 len = _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
3033 buffer[bufsize - 1] = 0;
3034 return bytes_copied - 1;
3042 static ws_mempbrk_pattern pbrk_crlf;
3044 * Given a tvbuff, an offset into the tvbuff, and a length that starts
3045 * at that offset (which may be -1 for "all the way to the end of the
3046 * tvbuff"), find the end of the (putative) line that starts at the
3047 * specified offset in the tvbuff, going no further than the specified
3050 * Return the length of the line (not counting the line terminator at
3051 * the end), or, if we don't find a line terminator:
3053 * if "deseg" is true, return -1;
3055 * if "deseg" is false, return the amount of data remaining in
3058 * Set "*next_offset" to the offset of the character past the line
3059 * terminator, or past the end of the buffer if we don't find a line
3060 * terminator. (It's not set if we return -1.)
3063 tvb_find_line_end(tvbuff_t *tvb, const gint offset, int len, gint *next_offset, const gboolean desegment)
3068 guchar found_needle = 0;
3069 static gboolean compiled = FALSE;
3071 DISSECTOR_ASSERT(tvb && tvb->initialized);
3074 len = _tvb_captured_length_remaining(tvb, offset);
3076 * XXX - what if "len" is still -1, meaning "offset is past the
3077 * end of the tvbuff"?
3079 eob_offset = offset + len;
3082 ws_mempbrk_compile(&pbrk_crlf, "\r\n");
3087 * Look either for a CR or an LF.
3089 eol_offset = tvb_ws_mempbrk_pattern_guint8(tvb, offset, len, &pbrk_crlf, &found_needle);
3090 if (eol_offset == -1) {
3092 * No CR or LF - line is presumably continued in next packet.
3096 * Tell our caller we saw no EOL, so they can
3097 * try to desegment and get the entire line
3103 * Pretend the line runs to the end of the tvbuff.
3105 linelen = eob_offset - offset;
3107 *next_offset = eob_offset;
3111 * Find the number of bytes between the starting offset
3114 linelen = eol_offset - offset;
3119 if (found_needle == '\r') {
3121 * Yes - is it followed by an LF?
3123 if (eol_offset + 1 >= eob_offset) {
3125 * Dunno - the next byte isn't in this
3130 * We'll return -1, although that
3131 * runs the risk that if the line
3132 * really *is* terminated with a CR,
3133 * we won't properly dissect this
3136 * It's probably more likely that
3137 * the line ends with CR-LF than
3138 * that it ends with CR by itself.
3144 * Well, we can at least look at the next
3147 if (tvb_get_guint8(tvb, eol_offset + 1) == '\n') {
3149 * It's an LF; skip over the CR.
3157 * Return the offset of the character after the last
3158 * character in the line, skipping over the last character
3159 * in the line terminator.
3162 *next_offset = eol_offset + 1;
3167 static ws_mempbrk_pattern pbrk_crlf_dquote;
3169 * Given a tvbuff, an offset into the tvbuff, and a length that starts
3170 * at that offset (which may be -1 for "all the way to the end of the
3171 * tvbuff"), find the end of the (putative) line that starts at the
3172 * specified offset in the tvbuff, going no further than the specified
3175 * However, treat quoted strings inside the buffer specially - don't
3176 * treat newlines in quoted strings as line terminators.
3178 * Return the length of the line (not counting the line terminator at
3179 * the end), or the amount of data remaining in the buffer if we don't
3180 * find a line terminator.
3182 * Set "*next_offset" to the offset of the character past the line
3183 * terminator, or past the end of the buffer if we don't find a line
3187 tvb_find_line_end_unquoted(tvbuff_t *tvb, const gint offset, int len, gint *next_offset)
3189 gint cur_offset, char_offset;
3194 static gboolean compiled = FALSE;
3196 DISSECTOR_ASSERT(tvb && tvb->initialized);
3199 len = _tvb_captured_length_remaining(tvb, offset);
3202 ws_mempbrk_compile(&pbrk_crlf_dquote, "\r\n\"");
3207 * XXX - what if "len" is still -1, meaning "offset is past the
3208 * end of the tvbuff"?
3210 eob_offset = offset + len;
3212 cur_offset = offset;
3216 * Is this part of the string quoted?
3220 * Yes - look only for the terminating quote.
3222 char_offset = tvb_find_guint8(tvb, cur_offset, len,
3226 * Look either for a CR, an LF, or a '"'.
3228 char_offset = tvb_ws_mempbrk_pattern_guint8(tvb, cur_offset, len, &pbrk_crlf_dquote, &c);
3230 if (char_offset == -1) {
3232 * Not found - line is presumably continued in
3234 * We pretend the line runs to the end of the tvbuff.
3236 linelen = eob_offset - offset;
3238 *next_offset = eob_offset;
3244 * We're processing a quoted string.
3245 * We only looked for ", so we know it's a ";
3246 * as we're processing a quoted string, it's a
3256 * Un-quoted "; it begins a quoted
3262 * It's a CR or LF; we've found a line
3265 * Find the number of bytes between the
3266 * starting offset and the CR or LF.
3268 linelen = char_offset - offset;
3275 * Yes; is it followed by an LF?
3277 if (char_offset + 1 < eob_offset &&
3278 tvb_get_guint8(tvb, char_offset + 1)
3281 * Yes; skip over the CR.
3288 * Return the offset of the character after
3289 * the last character in the line, skipping
3290 * over the last character in the line
3291 * terminator, and quit.
3294 *next_offset = char_offset + 1;
3300 * Step past the character we found.
3302 cur_offset = char_offset + 1;
3303 if (cur_offset >= eob_offset) {
3305 * The character we found was the last character
3306 * in the tvbuff - line is presumably continued in
3308 * We pretend the line runs to the end of the tvbuff.
3310 linelen = eob_offset - offset;
3312 *next_offset = eob_offset;
3320 * Copied from the mgcp dissector. (This function should be moved to /epan )
3321 * tvb_skip_wsp - Returns the position in tvb of the first non-whitespace
3322 * character following offset or offset + maxlength -1 whichever
3326 * tvb - The tvbuff in which we are skipping whitespace.
3327 * offset - The offset in tvb from which we begin trying to skip whitespace.
3328 * maxlength - The maximum distance from offset that we may try to skip
3331 * Returns: The position in tvb of the first non-whitespace
3332 * character following offset or offset + maxlength -1 whichever
3336 tvb_skip_wsp(tvbuff_t *tvb, const gint offset, const gint maxlength)
3338 gint counter = offset;
3342 DISSECTOR_ASSERT(tvb && tvb->initialized);
3344 /* Get the length remaining */
3345 /*tvb_len = tvb_captured_length(tvb);*/
3346 tvb_len = tvb->length;
3348 end = offset + maxlength;
3354 /* Skip past spaces, tabs, CRs and LFs until run out or meet something else */
3355 for (counter = offset;
3357 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
3358 tempchar == '\t' || tempchar == '\r' || tempchar == '\n');
3365 tvb_skip_wsp_return(tvbuff_t *tvb, const gint offset) {
3366 gint counter = offset;
3369 for(counter = offset; counter > 0 &&
3370 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
3371 tempchar == '\t' || tempchar == '\n' || tempchar == '\r'); counter--);
3377 tvb_skip_guint8(tvbuff_t *tvb, int offset, const int maxlength, const guint8 ch)
3381 DISSECTOR_ASSERT(tvb && tvb->initialized);
3383 /* Get the length remaining */
3384 /*tvb_len = tvb_captured_length(tvb);*/
3385 tvb_len = tvb->length;
3387 end = offset + maxlength;
3391 while (offset < end) {
3392 guint8 tempch = tvb_get_guint8(tvb, offset);
3403 * Format a bunch of data from a tvbuff as bytes, returning a pointer
3404 * to the string with the formatted data, with "punct" as a byte
3408 tvb_bytes_to_str_punct(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, const gint len, const gchar punct)
3410 return bytestring_to_str(scope, ensure_contiguous(tvb, offset, len), len, punct);
3415 * Given a tvbuff, an offset into the tvbuff, and a length that starts
3416 * at that offset (which may be -1 for "all the way to the end of the
3417 * tvbuff"), fetch BCD encoded digits from a tvbuff starting from either
3418 * the low or high half byte, formating the digits according to an input digit set,
3419 * if NUll a default digit set of 0-9 returning "?" for overdecadic digits will be used.
3420 * A pointer to the packet scope allocated string will be returned.
3421 * Note a tvbuff content of 0xf is considered a 'filler' and will end the conversion.
3423 static dgt_set_t Dgt1_9_bcd = {
3425 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f*/
3426 '0','1','2','3','4','5','6','7','8','9','?','?','?','?','?','?'
3430 tvb_bcd_dig_to_wmem_packet_str(tvbuff_t *tvb, const gint offset, const gint len, dgt_set_t *dgt, gboolean skip_first)
3436 gint t_offset = offset;
3438 DISSECTOR_ASSERT(tvb && tvb->initialized);
3444 /*length = tvb_captured_length(tvb);*/
3445 length = tvb->length;
3446 if (length < offset) {
3450 length = offset + len;
3452 digit_str = (char *)wmem_alloc(wmem_packet_scope(), (length - offset)*2+1);
3454 while (t_offset < length) {
3456 octet = tvb_get_guint8(tvb,t_offset);
3458 digit_str[i] = dgt->out[octet & 0x0f];
3464 * unpack second value in byte
3468 if (t_offset == length - 1 && octet == 0x0f) {
3470 * This is the last octet, and the low-order
3471 * nibble is 0xf, so we have an odd number of
3472 * digits, and this is a filler digit. Ignore
3478 digit_str[i] = dgt->out[octet & 0x0f];
3489 * Format a bunch of data from a tvbuff as bytes, returning a pointer
3490 * to the string with the formatted data.
3492 gchar *tvb_bytes_to_str(wmem_allocator_t *allocator, tvbuff_t *tvb,
3493 const gint offset, const gint len)
3495 return bytes_to_str(allocator, ensure_contiguous(tvb, offset, len), len);
3498 /* Find a needle tvbuff within a haystack tvbuff. */
3500 tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb, const gint haystack_offset)
3502 guint haystack_abs_offset = 0, haystack_abs_length = 0;
3503 const guint8 *haystack_data;
3504 const guint8 *needle_data;
3505 const guint needle_len = needle_tvb->length;
3506 const guint8 *location;
3508 DISSECTOR_ASSERT(haystack_tvb && haystack_tvb->initialized);
3510 if (haystack_tvb->length < 1 || needle_tvb->length < 1) {
3514 /* Get pointers to the tvbuffs' data. */
3515 haystack_data = ensure_contiguous(haystack_tvb, 0, -1);
3516 needle_data = ensure_contiguous(needle_tvb, 0, -1);
3518 check_offset_length(haystack_tvb, haystack_offset, -1,
3519 &haystack_abs_offset, &haystack_abs_length);
3521 location = epan_memmem(haystack_data + haystack_abs_offset, haystack_abs_length,
3522 needle_data, needle_len);
3525 return (gint) (location - haystack_data);
3532 tvb_raw_offset(tvbuff_t *tvb)
3534 return ((tvb->raw_offset==-1) ? (tvb->raw_offset = tvb_offset_from_real_beginning(tvb)) : tvb->raw_offset);
3538 tvb_set_fragment(tvbuff_t *tvb)
3540 tvb->flags |= TVBUFF_FRAGMENT;
3544 tvb_get_ds_tvb(tvbuff_t *tvb)
3546 return(tvb->ds_tvb);
3550 * Editor modelines - http://www.wireshark.org/tools/modelines.html
3555 * indent-tabs-mode: t
3558 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3559 * :indentSize=8:tabSize=8:noTabs=false: