3 * Testy, Virtual(-izable) Buffer of guint8*'s
5 * "Testy" -- the buffer gets mad when an attempt to access data
6 * beyond the bounds of the buffer. An exception is thrown.
8 * "Virtual" -- the buffer can have its own data, can use a subset of
9 * the data of a backing tvbuff, or can be a composite of
14 * Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
16 * Code to convert IEEE floating point formats to native floating point
17 * derived from code Copyright (c) Ashok Narayanan, 2000
19 * Wireshark - Network traffic analyzer
20 * By Gerald Combs <gerald@wireshark.org>
21 * Copyright 1998 Gerald Combs
23 * This program is free software; you can redistribute it and/or
24 * modify it under the terms of the GNU General Public License
25 * as published by the Free Software Foundation; either version 2
26 * of the License, or (at your option) any later version.
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the Free Software
35 * Foundation, Inc., 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"
46 #include "tvbuff-int.h"
50 #include "proto.h" /* XXX - only used for DISSECTOR_ASSERT, probably a new header file? */
51 #include "exceptions.h"
54 _tvb_get_bits64(tvbuff_t *tvb, guint bit_offset, const gint total_no_of_bits);
57 tvb_new(const struct tvb_ops *ops)
60 gsize size = ops->tvb_size;
62 g_assert(size >= sizeof(*tvb));
64 tvb = (tvbuff_t *) g_slice_alloc(size);
68 tvb->initialized = FALSE;
71 tvb->reported_length = 0;
72 tvb->real_data = NULL;
80 tvb_free_internal(tvbuff_t *tvb)
84 DISSECTOR_ASSERT(tvb);
86 if (tvb->ops->tvb_free)
87 tvb->ops->tvb_free(tvb);
89 size = tvb->ops->tvb_size;
91 g_slice_free1(size, tvb);
94 /* XXX: just call tvb_free_chain();
95 * Not removed so that existing dissectors using tvb_free() need not be changed.
96 * I'd argue that existing calls to tvb_free() should have actually beeen
97 * calls to tvb_free_chain() although the calls were OK as long as no
98 * subsets, etc had been created on the tvb. */
100 tvb_free(tvbuff_t *tvb)
106 tvb_free_chain(tvbuff_t *tvb)
109 DISSECTOR_ASSERT(tvb);
111 next_tvb = tvb->next;
112 tvb_free_internal(tvb);
118 tvb_new_chain(tvbuff_t *parent, tvbuff_t *backing)
120 tvbuff_t *tvb = tvb_new_proxy(backing);
122 tvb_add_to_chain(parent, tvb);
127 tvb_add_to_chain(tvbuff_t *parent, tvbuff_t *child)
129 tvbuff_t *tmp = child;
131 DISSECTOR_ASSERT(parent);
132 DISSECTOR_ASSERT(child);
138 tmp->next = parent->next;
144 * Check whether that offset goes more than one byte past the
147 * If not, return 0; otherwise, return exception
150 validate_offset(const tvbuff_t *tvb, const guint abs_offset)
152 if (G_LIKELY(abs_offset <= tvb->length))
154 else if (abs_offset <= tvb->reported_length)
156 else if (tvb->flags & TVBUFF_FRAGMENT)
157 return FragmentBoundsError;
159 return ReportedBoundsError;
163 compute_offset(const tvbuff_t *tvb, const gint offset, guint *offset_ptr)
166 /* Positive offset - relative to the beginning of the packet. */
167 if ((guint) offset <= tvb->length) {
168 *offset_ptr = offset;
169 } else if ((guint) offset <= tvb->reported_length) {
171 } else if (tvb->flags & TVBUFF_FRAGMENT) {
172 return FragmentBoundsError;
174 return ReportedBoundsError;
178 /* Negative offset - relative to the end of the packet. */
179 if ((guint) -offset <= tvb->length) {
180 *offset_ptr = tvb->length + offset;
181 } else if ((guint) -offset <= tvb->reported_length) {
183 } else if (tvb->flags & TVBUFF_FRAGMENT) {
184 return FragmentBoundsError;
186 return ReportedBoundsError;
194 compute_offset_and_remaining(const tvbuff_t *tvb, const gint offset, guint *offset_ptr, guint *rem_len)
198 exception = compute_offset(tvb, offset, offset_ptr);
200 *rem_len = tvb->length - *offset_ptr;
205 /* Computes the absolute offset and length based on a possibly-negative offset
206 * and a length that is possible -1 (which means "to the end of the data").
207 * Returns integer indicating whether the offset is in bounds (0) or
208 * not (exception number). The integer ptrs are modified with the new offset and length.
209 * No exception is thrown.
211 * XXX - we return success (0), if the offset is positive and right
212 * after the end of the tvbuff (i.e., equal to the length). We do this
213 * so that a dissector constructing a subset tvbuff for the next protocol
214 * will get a zero-length tvbuff, not an exception, if there's no data
215 * left for the next protocol - we want the next protocol to be the one
216 * that gets an exception, so the error is reported as an error in that
217 * protocol rather than the containing protocol. */
219 check_offset_length_no_exception(const tvbuff_t *tvb,
220 const gint offset, gint const length_val,
221 guint *offset_ptr, guint *length_ptr)
226 DISSECTOR_ASSERT(offset_ptr);
227 DISSECTOR_ASSERT(length_ptr);
229 /* Compute the offset */
230 exception = compute_offset(tvb, offset, offset_ptr);
234 if (length_val < -1) {
235 /* XXX - ReportedBoundsError? */
239 /* Compute the length */
240 if (length_val == -1)
241 *length_ptr = tvb->length - *offset_ptr;
243 *length_ptr = length_val;
246 * Compute the offset of the first byte past the length.
248 end_offset = *offset_ptr + *length_ptr;
251 * Check for an overflow
253 if (end_offset < *offset_ptr)
256 return validate_offset(tvb, end_offset);
259 /* Checks (+/-) offset and length and throws an exception if
260 * either is out of bounds. Sets integer ptrs to the new offset
263 check_offset_length(const tvbuff_t *tvb,
264 const gint offset, gint const length_val,
265 guint *offset_ptr, guint *length_ptr)
269 exception = check_offset_length_no_exception(tvb, offset, length_val, offset_ptr, length_ptr);
275 tvb_check_offset_length(const tvbuff_t *tvb,
276 const gint offset, gint const length_val,
277 guint *offset_ptr, guint *length_ptr)
279 check_offset_length(tvb, offset, length_val, offset_ptr, length_ptr);
282 static const unsigned char left_aligned_bitmask[] = {
294 tvb_new_octet_aligned(tvbuff_t *tvb, guint32 bit_offset, gint32 no_of_bits)
296 tvbuff_t *sub_tvb = NULL;
299 guint8 left, right, remaining_bits, *buf;
302 byte_offset = bit_offset >> 3;
303 left = bit_offset % 8; /* for left-shifting */
304 right = 8 - left; /* for right-shifting */
306 if (no_of_bits == -1) {
307 datalen = tvb_length_remaining(tvb, byte_offset);
310 datalen = no_of_bits >> 3;
311 remaining_bits = no_of_bits % 8;
312 if (remaining_bits) {
317 /* already aligned -> shortcut */
318 if ((left == 0) && (remaining_bits == 0)) {
319 return tvb_new_subset(tvb, byte_offset, datalen, -1);
322 DISSECTOR_ASSERT(datalen>0);
324 /* if at least one trailing byte is available, we must use the content
325 * of that byte for the last shift (i.e. tvb_get_ptr() must use datalen + 1
326 * if non extra byte is available, the last shifted byte requires
329 if (tvb_length_remaining(tvb, byte_offset) > datalen) {
330 data = tvb_get_ptr(tvb, byte_offset, datalen + 1);
332 /* Do this allocation AFTER tvb_get_ptr() (which could throw an exception) */
333 buf = (guint8 *)g_malloc(datalen);
335 /* shift tvb data bit_offset bits to the left */
336 for (i = 0; i < datalen; i++)
337 buf[i] = (data[i] << left) | (data[i+1] >> right);
339 data = tvb_get_ptr(tvb, byte_offset, datalen);
341 /* Do this allocation AFTER tvb_get_ptr() (which could throw an exception) */
342 buf = (guint8 *)g_malloc(datalen);
344 /* shift tvb data bit_offset bits to the left */
345 for (i = 0; i < (datalen-1); i++)
346 buf[i] = (data[i] << left) | (data[i+1] >> right);
347 buf[datalen-1] = data[datalen-1] << left; /* set last octet */
349 buf[datalen-1] &= left_aligned_bitmask[remaining_bits];
351 sub_tvb = tvb_new_child_real_data(tvb, buf, datalen, datalen);
352 tvb_set_free_cb(sub_tvb, g_free);
358 tvb_generic_clone_offset_len(tvbuff_t *tvb, guint offset, guint len)
360 tvbuff_t *cloned_tvb;
362 guint8 *data = (guint8 *) g_malloc(len);
364 tvb_memcpy(tvb, data, offset, len);
366 cloned_tvb = tvb_new_real_data(data, len, len);
367 tvb_set_free_cb(cloned_tvb, g_free);
373 tvb_clone_offset_len(tvbuff_t *tvb, guint offset, guint len)
375 if (tvb->ops->tvb_clone) {
376 tvbuff_t *cloned_tvb;
378 cloned_tvb = tvb->ops->tvb_clone(tvb, offset, len);
383 return tvb_generic_clone_offset_len(tvb, offset, len);
387 tvb_clone(tvbuff_t *tvb)
389 return tvb_clone_offset_len(tvb, 0, tvb->length);
393 tvb_length(const tvbuff_t *tvb)
395 DISSECTOR_ASSERT(tvb && tvb->initialized);
401 tvb_length_remaining(const tvbuff_t *tvb, const gint offset)
403 guint abs_offset, rem_length;
406 DISSECTOR_ASSERT(tvb && tvb->initialized);
408 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &rem_length);
416 tvb_ensure_length_remaining(const tvbuff_t *tvb, const gint offset)
418 guint abs_offset, rem_length;
421 DISSECTOR_ASSERT(tvb && tvb->initialized);
423 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &rem_length);
427 if (rem_length == 0) {
429 * This routine ensures there's at least one byte available.
430 * There aren't any bytes available, so throw the appropriate
433 if (abs_offset >= tvb->reported_length) {
434 if (tvb->flags & TVBUFF_FRAGMENT) {
435 THROW(FragmentBoundsError);
437 THROW(ReportedBoundsError);
448 /* Validates that 'length' bytes are available starting from
449 * offset (pos/neg). Does not throw an exception. */
451 tvb_bytes_exist(const tvbuff_t *tvb, const gint offset, const gint length)
453 guint abs_offset, abs_length;
456 DISSECTOR_ASSERT(tvb && tvb->initialized);
458 exception = check_offset_length_no_exception(tvb, offset, length, &abs_offset, &abs_length);
465 /* Validates that 'length' bytes are available starting from
466 * offset (pos/neg). Throws an exception if they aren't. */
468 tvb_ensure_bytes_exist(const tvbuff_t *tvb, const gint offset, const gint length)
470 guint real_offset, end_offset;
472 DISSECTOR_ASSERT(tvb && tvb->initialized);
475 * -1 doesn't mean "until end of buffer", as that's pointless
476 * for this routine. We must treat it as a Really Large Positive
477 * Number, so that we throw an exception; we throw
478 * ReportedBoundsError, as if it were past even the end of a
479 * reassembled packet, and past the end of even the data we
482 * We do the same with other negative lengths.
485 THROW(ReportedBoundsError);
488 /* XXX: Below this point could be replaced with a call to
489 * check_offset_length with no functional change, however this is a
490 * *very* hot path and check_offset_length is not well-optimized for
491 * this case, so we eat some code duplication for a lot of speedup. */
494 /* Positive offset - relative to the beginning of the packet. */
495 if ((guint) offset <= tvb->length) {
496 real_offset = offset;
497 } else if ((guint) offset <= tvb->reported_length) {
499 } else if (tvb->flags & TVBUFF_FRAGMENT) {
500 THROW(FragmentBoundsError);
502 THROW(ReportedBoundsError);
506 /* Negative offset - relative to the end of the packet. */
507 if ((guint) -offset <= tvb->length) {
508 real_offset = tvb->length + offset;
509 } else if ((guint) -offset <= tvb->reported_length) {
511 } else if (tvb->flags & TVBUFF_FRAGMENT) {
512 THROW(FragmentBoundsError);
514 THROW(ReportedBoundsError);
519 * Compute the offset of the first byte past the length.
521 end_offset = real_offset + length;
524 * Check for an overflow
526 if (end_offset < real_offset)
529 if (G_LIKELY(end_offset <= tvb->length))
531 else if (end_offset <= tvb->reported_length)
533 else if (tvb->flags & TVBUFF_FRAGMENT)
534 THROW(FragmentBoundsError);
536 THROW(ReportedBoundsError);
540 tvb_offset_exists(const tvbuff_t *tvb, const gint offset)
545 DISSECTOR_ASSERT(tvb && tvb->initialized);
547 exception = compute_offset(tvb, offset, &abs_offset);
551 /* compute_offset only throws an exception on >, not >= because of the
552 * comment above check_offset_length_no_exception, but here we want the
553 * opposite behaviour so we check ourselves... */
554 if (abs_offset < tvb->length) {
563 tvb_reported_length(const tvbuff_t *tvb)
565 DISSECTOR_ASSERT(tvb && tvb->initialized);
567 return tvb->reported_length;
571 tvb_reported_length_remaining(const tvbuff_t *tvb, const gint offset)
576 DISSECTOR_ASSERT(tvb && tvb->initialized);
578 exception = compute_offset(tvb, offset, &abs_offset);
582 if (tvb->reported_length >= abs_offset)
583 return tvb->reported_length - abs_offset;
588 /* Set the reported length of a tvbuff to a given value; used for protocols
589 * whose headers contain an explicit length and where the calling
590 * dissector's payload may include padding as well as the packet for
592 * Also adjusts the data length. */
594 tvb_set_reported_length(tvbuff_t *tvb, const guint reported_length)
596 DISSECTOR_ASSERT(tvb && tvb->initialized);
598 if (reported_length > tvb->reported_length)
599 THROW(ReportedBoundsError);
601 tvb->reported_length = reported_length;
602 if (reported_length < tvb->length)
603 tvb->length = reported_length;
607 tvb_offset_from_real_beginning_counter(const tvbuff_t *tvb, const guint counter)
609 if (tvb->ops->tvb_offset)
610 return tvb->ops->tvb_offset(tvb, counter);
612 DISSECTOR_ASSERT_NOT_REACHED();
617 tvb_offset_from_real_beginning(const tvbuff_t *tvb)
619 return tvb_offset_from_real_beginning_counter(tvb, 0);
623 ensure_contiguous_no_exception(tvbuff_t *tvb, const gint offset, const gint length, int *pexception)
625 guint abs_offset, abs_length;
628 exception = check_offset_length_no_exception(tvb, offset, length, &abs_offset, &abs_length);
631 *pexception = exception;
636 * We know that all the data is present in the tvbuff, so
637 * no exceptions should be thrown.
640 return tvb->real_data + abs_offset;
642 if (tvb->ops->tvb_get_ptr)
643 return tvb->ops->tvb_get_ptr(tvb, abs_offset, abs_length);
645 DISSECTOR_ASSERT_NOT_REACHED();
650 ensure_contiguous(tvbuff_t *tvb, const gint offset, const gint length)
655 p = ensure_contiguous_no_exception(tvb, offset, length, &exception);
657 DISSECTOR_ASSERT(exception > 0);
664 fast_ensure_contiguous(tvbuff_t *tvb, const gint offset, const guint length)
669 DISSECTOR_ASSERT(tvb && tvb->initialized);
670 /* We don't check for overflow in this fast path so we only handle simple types */
671 DISSECTOR_ASSERT(length <= 8);
673 if (offset < 0 || !tvb->real_data) {
674 return ensure_contiguous(tvb, offset, length);
678 end_offset = u_offset + length;
680 if (end_offset <= tvb->length) {
681 return tvb->real_data + u_offset;
684 if (end_offset > tvb->reported_length) {
685 if (tvb->flags & TVBUFF_FRAGMENT) {
686 THROW(FragmentBoundsError);
688 THROW(ReportedBoundsError);
698 guint8_pbrk(const guint8* haystack, size_t haystacklen, const guint8 *needles, guchar *found_needle)
700 gchar tmp[256] = { 0 };
701 const guint8 *haystack_end;
706 haystack_end = haystack + haystacklen;
707 while (haystack < haystack_end) {
708 if (tmp[*haystack]) {
710 *found_needle = *haystack;
721 /************** ACCESSORS **************/
724 tvb_memcpy(tvbuff_t *tvb, void *target, const gint offset, size_t length)
726 guint abs_offset, abs_length;
728 DISSECTOR_ASSERT(tvb && tvb->initialized);
731 * XXX - we should eliminate the "length = -1 means 'to the end
732 * of the tvbuff'" convention, and use other means to achieve
733 * that; this would let us eliminate a bunch of checks for
734 * negative lengths in cases where the protocol has a 32-bit
737 * Allowing -1 but throwing an assertion on other negative
738 * lengths is a bit more work with the length being a size_t;
739 * instead, we check for a length <= 2^31-1.
741 DISSECTOR_ASSERT(length <= 0x7FFFFFFF);
742 check_offset_length(tvb, offset, (gint) length, &abs_offset, &abs_length);
744 if (tvb->real_data) {
745 return memcpy(target, tvb->real_data + abs_offset, abs_length);
748 if (tvb->ops->tvb_memcpy)
749 return tvb->ops->tvb_memcpy(tvb, target, abs_offset, abs_length);
751 /* XXX, fallback to slower method */
753 DISSECTOR_ASSERT_NOT_REACHED();
759 * XXX - this doesn't treat a length of -1 as an error.
760 * If it did, this could replace some code that calls
761 * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies
764 * "composite_get_ptr()" depends on -1 not being
765 * an error; does anything else depend on this routine treating -1 as
766 * meaning "to the end of the buffer"?
768 * If scope is NULL, memory is allocated with g_malloc() and user must
769 * explicitly free it with g_free().
770 * If scope is not NULL, memory is allocated with the corresponding pool
774 tvb_memdup(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, size_t length)
776 guint abs_offset, abs_length;
779 DISSECTOR_ASSERT(tvb && tvb->initialized);
781 check_offset_length(tvb, offset, (gint) length, &abs_offset, &abs_length);
783 duped = wmem_alloc(scope, abs_length);
784 return tvb_memcpy(tvb, duped, abs_offset, abs_length);
790 tvb_get_ptr(tvbuff_t *tvb, const gint offset, const gint length)
792 return ensure_contiguous(tvb, offset, length);
795 /* ---------------- */
797 tvb_get_guint8(tvbuff_t *tvb, const gint offset)
801 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint8));
806 tvb_get_ntohs(tvbuff_t *tvb, const gint offset)
810 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint16));
815 tvb_get_ntoh24(tvbuff_t *tvb, const gint offset)
819 ptr = fast_ensure_contiguous(tvb, offset, 3);
824 tvb_get_ntohl(tvbuff_t *tvb, const gint offset)
828 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
833 tvb_get_ntoh40(tvbuff_t *tvb, const gint offset)
837 ptr = fast_ensure_contiguous(tvb, offset, 5);
842 tvb_get_ntohi40(tvbuff_t *tvb, const gint offset)
846 ret = ws_sign_ext64(tvb_get_ntoh40(tvb, offset), 40);
852 tvb_get_ntoh48(tvbuff_t *tvb, const gint offset)
856 ptr = fast_ensure_contiguous(tvb, offset, 6);
861 tvb_get_ntohi48(tvbuff_t *tvb, const gint offset)
865 ret = ws_sign_ext64(tvb_get_ntoh48(tvb, offset), 48);
871 tvb_get_ntoh56(tvbuff_t *tvb, const gint offset)
875 ptr = fast_ensure_contiguous(tvb, offset, 7);
880 tvb_get_ntohi56(tvbuff_t *tvb, const gint offset)
884 ret = ws_sign_ext64(tvb_get_ntoh56(tvb, offset), 56);
890 tvb_get_ntoh64(tvbuff_t *tvb, const gint offset)
894 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint64));
899 * Stuff for IEEE float handling on platforms that don't have IEEE
900 * format as the native floating-point format.
902 * For now, we treat only the VAX as such a platform.
904 * XXX - other non-IEEE boxes that can run UNIX include some Crays,
905 * and possibly other machines.
907 * It appears that the official Linux port to System/390 and
908 * zArchitecture uses IEEE format floating point (not a
911 * I don't know whether there are any other machines that
912 * could run Wireshark and that don't use IEEE format.
913 * As far as I know, all of the main commercial microprocessor
914 * families on which OSes that support Wireshark can run
915 * use IEEE format (x86, 68k, SPARC, MIPS, PA-RISC, Alpha,
926 #define IEEE_SP_NUMBER_WIDTH 32 /* bits in number */
927 #define IEEE_SP_EXP_WIDTH 8 /* bits in exponent */
928 #define IEEE_SP_MANTISSA_WIDTH 23 /* IEEE_SP_NUMBER_WIDTH - 1 - IEEE_SP_EXP_WIDTH */
930 #define IEEE_SP_SIGN_MASK 0x80000000
931 #define IEEE_SP_EXPONENT_MASK 0x7F800000
932 #define IEEE_SP_MANTISSA_MASK 0x007FFFFF
933 #define IEEE_SP_INFINITY IEEE_SP_EXPONENT_MASK
935 #define IEEE_SP_IMPLIED_BIT (1 << IEEE_SP_MANTISSA_WIDTH)
936 #define IEEE_SP_INFINITE ((1 << IEEE_SP_EXP_WIDTH) - 1)
937 #define IEEE_SP_BIAS ((1 << (IEEE_SP_EXP_WIDTH - 1)) - 1)
940 ieee_float_is_zero(const guint32 w)
942 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
946 get_ieee_float(const guint32 w)
952 sign = w & IEEE_SP_SIGN_MASK;
953 exponent = w & IEEE_SP_EXPONENT_MASK;
954 mantissa = w & IEEE_SP_MANTISSA_MASK;
956 if (ieee_float_is_zero(w)) {
957 /* number is zero, unnormalized, or not-a-number */
962 * XXX - how to handle this?
964 if (IEEE_SP_INFINITY == exponent) {
966 * number is positive or negative infinity, or a special value
968 return (sign? MINUS_INFINITY: PLUS_INFINITY);
972 exponent = ((exponent >> IEEE_SP_MANTISSA_WIDTH) - IEEE_SP_BIAS) -
973 IEEE_SP_MANTISSA_WIDTH;
974 mantissa |= IEEE_SP_IMPLIED_BIT;
977 return -mantissa * pow(2, exponent);
979 return mantissa * pow(2, exponent);
984 * We assume that if you don't have IEEE floating-point, you have a
985 * compiler that understands 64-bit integral quantities.
987 #define IEEE_DP_NUMBER_WIDTH 64 /* bits in number */
988 #define IEEE_DP_EXP_WIDTH 11 /* bits in exponent */
989 #define IEEE_DP_MANTISSA_WIDTH 52 /* IEEE_DP_NUMBER_WIDTH - 1 - IEEE_DP_EXP_WIDTH */
991 #define IEEE_DP_SIGN_MASK G_GINT64_CONSTANT(0x8000000000000000)
992 #define IEEE_DP_EXPONENT_MASK G_GINT64_CONSTANT(0x7FF0000000000000)
993 #define IEEE_DP_MANTISSA_MASK G_GINT64_CONSTANT(0x000FFFFFFFFFFFFF)
994 #define IEEE_DP_INFINITY IEEE_DP_EXPONENT_MASK
996 #define IEEE_DP_IMPLIED_BIT (G_GINT64_CONSTANT(1) << IEEE_DP_MANTISSA_WIDTH)
997 #define IEEE_DP_INFINITE ((1 << IEEE_DP_EXP_WIDTH) - 1)
998 #define IEEE_DP_BIAS ((1 << (IEEE_DP_EXP_WIDTH - 1)) - 1)
1001 ieee_double_is_zero(const guint64 w)
1003 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1007 get_ieee_double(const guint64 w)
1013 sign = w & IEEE_DP_SIGN_MASK;
1014 exponent = w & IEEE_DP_EXPONENT_MASK;
1015 mantissa = w & IEEE_DP_MANTISSA_MASK;
1017 if (ieee_double_is_zero(w)) {
1018 /* number is zero, unnormalized, or not-a-number */
1023 * XXX - how to handle this?
1025 if (IEEE_DP_INFINITY == exponent) {
1027 * number is positive or negative infinity, or a special value
1029 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1033 exponent = ((exponent >> IEEE_DP_MANTISSA_WIDTH) - IEEE_DP_BIAS) -
1034 IEEE_DP_MANTISSA_WIDTH;
1035 mantissa |= IEEE_DP_IMPLIED_BIT;
1038 return -mantissa * pow(2, exponent);
1040 return mantissa * pow(2, exponent);
1045 * Fetches an IEEE single-precision floating-point number, in
1046 * big-endian form, and returns a "float".
1048 * XXX - should this be "double", in case there are IEEE single-
1049 * precision numbers that won't fit in some platform's native
1053 tvb_get_ntohieee_float(tvbuff_t *tvb, const int offset)
1056 return get_ieee_float(tvb_get_ntohl(tvb, offset));
1063 ieee_fp_union.w = tvb_get_ntohl(tvb, offset);
1064 return ieee_fp_union.f;
1069 * Fetches an IEEE double-precision floating-point number, in
1070 * big-endian form, and returns a "double".
1073 tvb_get_ntohieee_double(tvbuff_t *tvb, const int offset)
1087 #ifdef WORDS_BIGENDIAN
1088 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset);
1089 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset+4);
1091 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset+4);
1092 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset);
1095 return get_ieee_double(ieee_fp_union.dw);
1097 return ieee_fp_union.d;
1102 tvb_get_letohs(tvbuff_t *tvb, const gint offset)
1106 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint16));
1107 return pletoh16(ptr);
1111 tvb_get_letoh24(tvbuff_t *tvb, const gint offset)
1115 ptr = fast_ensure_contiguous(tvb, offset, 3);
1116 return pletoh24(ptr);
1120 tvb_get_letohl(tvbuff_t *tvb, const gint offset)
1124 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1125 return pletoh32(ptr);
1129 tvb_get_letoh40(tvbuff_t *tvb, const gint offset)
1133 ptr = fast_ensure_contiguous(tvb, offset, 5);
1134 return pletoh40(ptr);
1138 tvb_get_letohi40(tvbuff_t *tvb, const gint offset)
1142 ret = ws_sign_ext64(tvb_get_letoh40(tvb, offset), 40);
1148 tvb_get_letoh48(tvbuff_t *tvb, const gint offset)
1152 ptr = fast_ensure_contiguous(tvb, offset, 6);
1153 return pletoh48(ptr);
1157 tvb_get_letohi48(tvbuff_t *tvb, const gint offset)
1161 ret = ws_sign_ext64(tvb_get_letoh48(tvb, offset), 48);
1167 tvb_get_letoh56(tvbuff_t *tvb, const gint offset)
1171 ptr = fast_ensure_contiguous(tvb, offset, 7);
1172 return pletoh56(ptr);
1176 tvb_get_letohi56(tvbuff_t *tvb, const gint offset)
1180 ret = ws_sign_ext64(tvb_get_letoh56(tvb, offset), 56);
1186 tvb_get_letoh64(tvbuff_t *tvb, const gint offset)
1190 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint64));
1191 return pletoh64(ptr);
1195 * Fetches an IEEE single-precision floating-point number, in
1196 * little-endian form, and returns a "float".
1198 * XXX - should this be "double", in case there are IEEE single-
1199 * precision numbers that won't fit in some platform's native
1203 tvb_get_letohieee_float(tvbuff_t *tvb, const int offset)
1206 return get_ieee_float(tvb_get_letohl(tvb, offset));
1213 ieee_fp_union.w = tvb_get_letohl(tvb, offset);
1214 return ieee_fp_union.f;
1219 * Fetches an IEEE double-precision floating-point number, in
1220 * little-endian form, and returns a "double".
1223 tvb_get_letohieee_double(tvbuff_t *tvb, const int offset)
1237 #ifdef WORDS_BIGENDIAN
1238 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset+4);
1239 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset);
1241 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset);
1242 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset+4);
1245 return get_ieee_double(ieee_fp_union.dw);
1247 return ieee_fp_union.d;
1251 /* Fetch an IPv4 address, in network byte order.
1252 * We do *not* convert them to host byte order; we leave them in
1253 * network byte order. */
1255 tvb_get_ipv4(tvbuff_t *tvb, const gint offset)
1260 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1261 memcpy(&addr, ptr, sizeof addr);
1265 /* Fetch an IPv6 address. */
1267 tvb_get_ipv6(tvbuff_t *tvb, const gint offset, struct e_in6_addr *addr)
1271 ptr = ensure_contiguous(tvb, offset, sizeof(*addr));
1272 memcpy(addr, ptr, sizeof *addr);
1277 tvb_get_ntohguid(tvbuff_t *tvb, const gint offset, e_guid_t *guid)
1279 const guint8 *ptr = ensure_contiguous(tvb, offset, GUID_LEN);
1281 guid->data1 = pntoh32(ptr + 0);
1282 guid->data2 = pntoh16(ptr + 4);
1283 guid->data3 = pntoh16(ptr + 6);
1284 memcpy(guid->data4, ptr + 8, sizeof guid->data4);
1288 tvb_get_letohguid(tvbuff_t *tvb, const gint offset, e_guid_t *guid)
1290 const guint8 *ptr = ensure_contiguous(tvb, offset, GUID_LEN);
1292 guid->data1 = pletoh32(ptr + 0);
1293 guid->data2 = pletoh16(ptr + 4);
1294 guid->data3 = pletoh16(ptr + 6);
1295 memcpy(guid->data4, ptr + 8, sizeof guid->data4);
1299 * NOTE: to support code written when proto_tree_add_item() took a
1300 * gboolean as its last argument, with FALSE meaning "big-endian"
1301 * and TRUE meaning "little-endian", we treat any non-zero value of
1302 * "representation" as meaning "little-endian".
1305 tvb_get_guid(tvbuff_t *tvb, const gint offset, e_guid_t *guid, const guint representation)
1307 if (representation) {
1308 tvb_get_letohguid(tvb, offset, guid);
1310 tvb_get_ntohguid(tvb, offset, guid);
1314 static const guint8 bit_mask8[] = {
1326 /* Get 1 - 8 bits */
1328 tvb_get_bits8(tvbuff_t *tvb, guint bit_offset, const gint no_of_bits)
1330 return (guint8)_tvb_get_bits64(tvb, bit_offset, no_of_bits);
1333 /* Get 9 - 16 bits */
1335 tvb_get_bits16(tvbuff_t *tvb, guint bit_offset, const gint no_of_bits,const guint encoding _U_)
1337 /* note that encoding has no meaning here, as the tvb is considered to contain an octet array */
1338 return (guint16)_tvb_get_bits64(tvb, bit_offset, no_of_bits);
1341 /* Get 1 - 32 bits */
1343 tvb_get_bits32(tvbuff_t *tvb, guint bit_offset, const gint no_of_bits, const guint encoding _U_)
1345 /* note that encoding has no meaning here, as the tvb is considered to contain an octet array */
1346 return (guint32)_tvb_get_bits64(tvb, bit_offset, no_of_bits);
1349 /* Get 1 - 64 bits */
1351 tvb_get_bits64(tvbuff_t *tvb, guint bit_offset, const gint no_of_bits, const guint encoding _U_)
1353 /* note that encoding has no meaning here, as the tvb is considered to contain an octet array */
1354 return _tvb_get_bits64(tvb, bit_offset, no_of_bits);
1357 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
1358 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
1359 * Offset should be given in bits from the start of the tvb.
1360 * The function tolerates requests for more than 64 bits, but will only return the least significant 64 bits.
1363 _tvb_get_bits64(tvbuff_t *tvb, guint bit_offset, const gint total_no_of_bits)
1366 guint octet_offset = bit_offset >> 3;
1367 guint8 required_bits_in_first_octet = 8 - (bit_offset % 8);
1369 if(required_bits_in_first_octet > total_no_of_bits)
1371 /* the required bits don't extend to the end of the first octet */
1372 guint8 right_shift = required_bits_in_first_octet - total_no_of_bits;
1373 value = (tvb_get_guint8(tvb, octet_offset) >> right_shift) & bit_mask8[total_no_of_bits % 8];
1377 guint8 remaining_bit_length = total_no_of_bits;
1379 /* get the bits up to the first octet boundary */
1381 required_bits_in_first_octet %= 8;
1382 if(required_bits_in_first_octet != 0)
1384 value = tvb_get_guint8(tvb, octet_offset) & bit_mask8[required_bits_in_first_octet];
1385 remaining_bit_length -= required_bits_in_first_octet;
1388 /* take the biggest words, shorts or octets that we can */
1389 while (remaining_bit_length > 7)
1391 switch (remaining_bit_length >> 4)
1394 /* 8 - 15 bits. (note that 0 - 7 would have dropped out of the while() loop) */
1396 value += tvb_get_guint8(tvb, octet_offset);
1397 remaining_bit_length -= 8;
1404 value += tvb_get_ntohs(tvb, octet_offset);
1405 remaining_bit_length -= 16;
1413 value += tvb_get_ntohl(tvb, octet_offset);
1414 remaining_bit_length -= 32;
1419 /* 64 bits (or more???) */
1420 value = tvb_get_ntoh64(tvb, octet_offset);
1421 remaining_bit_length -= 64;
1426 /* get bits from any partial octet at the tail */
1427 if(remaining_bit_length)
1429 value <<= remaining_bit_length;
1430 value += (tvb_get_guint8(tvb, octet_offset) >> (8 - remaining_bit_length));
1435 /* Get 1 - 32 bits (should be deprecated as same as tvb_get_bits32??) */
1437 tvb_get_bits(tvbuff_t *tvb, const guint bit_offset, const gint no_of_bits, const guint encoding _U_)
1439 /* note that encoding has no meaning here, as the tvb is considered to contain an octet array */
1440 return (guint32)_tvb_get_bits64(tvb, bit_offset, no_of_bits);
1444 tvb_find_guint8_generic(tvbuff_t *tvb, guint abs_offset, guint limit, guint8 needle)
1447 const guint8 *result;
1449 ptr = tvb_get_ptr(tvb, abs_offset, limit);
1451 result = (const guint8 *) memchr(ptr, needle, limit);
1455 return (gint) ((result - ptr) + abs_offset);
1458 /* Find first occurrence of needle in tvbuff, starting at offset. Searches
1459 * at most maxlength number of bytes; if maxlength is -1, searches to
1461 * Returns the offset of the found needle, or -1 if not found.
1462 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1463 * in that case, -1 will be returned if the boundary is reached before
1464 * finding needle. */
1466 tvb_find_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength, const guint8 needle)
1468 const guint8 *result;
1473 DISSECTOR_ASSERT(tvb && tvb->initialized);
1475 check_offset_length(tvb, offset, -1, &abs_offset, &tvbufflen);
1477 /* Only search to end of tvbuff, w/o throwing exception. */
1478 if (maxlength == -1) {
1479 /* No maximum length specified; search to end of tvbuff. */
1482 else if (tvbufflen < (guint) maxlength) {
1483 /* Maximum length goes past end of tvbuff; search to end
1488 /* Maximum length doesn't go past end of tvbuff; search
1493 /* If we have real data, perform our search now. */
1494 if (tvb->real_data) {
1495 result = (const guint8 *)memchr(tvb->real_data + abs_offset, needle, limit);
1496 if (result == NULL) {
1500 return (gint) (result - tvb->real_data);
1504 if (tvb->ops->tvb_find_guint8)
1505 return tvb->ops->tvb_find_guint8(tvb, abs_offset, limit, needle);
1507 return tvb_find_guint8_generic(tvb, offset, limit, needle);
1511 tvb_pbrk_guint8_generic(tvbuff_t *tvb, guint abs_offset, guint limit, const guint8 *needles, guchar *found_needle)
1514 const guint8 *result;
1516 ptr = tvb_get_ptr(tvb, abs_offset, limit);
1518 result = guint8_pbrk(ptr, limit, needles, found_needle);
1522 return (gint) ((result - ptr) + abs_offset);
1525 /* Find first occurrence of any of the needles in tvbuff, starting at offset.
1526 * Searches at most maxlength number of bytes; if maxlength is -1, searches
1528 * Returns the offset of the found needle, or -1 if not found.
1529 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
1530 * in that case, -1 will be returned if the boundary is reached before
1531 * finding needle. */
1533 tvb_pbrk_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength, const guint8 *needles, guchar *found_needle)
1535 const guint8 *result;
1540 DISSECTOR_ASSERT(tvb && tvb->initialized);
1542 check_offset_length(tvb, offset, -1, &abs_offset, &tvbufflen);
1544 /* Only search to end of tvbuff, w/o throwing exception. */
1545 if (maxlength == -1) {
1546 /* No maximum length specified; search to end of tvbuff. */
1549 else if (tvbufflen < (guint) maxlength) {
1550 /* Maximum length goes past end of tvbuff; search to end
1555 /* Maximum length doesn't go past end of tvbuff; search
1560 /* If we have real data, perform our search now. */
1561 if (tvb->real_data) {
1562 result = guint8_pbrk(tvb->real_data + abs_offset, limit, needles, found_needle);
1563 if (result == NULL) {
1567 return (gint) (result - tvb->real_data);
1571 if (tvb->ops->tvb_pbrk_guint8)
1572 return tvb->ops->tvb_pbrk_guint8(tvb, abs_offset, limit, needles, found_needle);
1574 return tvb_pbrk_guint8_generic(tvb, abs_offset, limit, needles, found_needle);
1577 /* Find size of stringz (NUL-terminated string) by looking for terminating
1578 * NUL. The size of the string includes the terminating NUL.
1580 * If the NUL isn't found, it throws the appropriate exception.
1583 tvb_strsize(tvbuff_t *tvb, const gint offset)
1585 guint abs_offset, junk_length;
1588 DISSECTOR_ASSERT(tvb && tvb->initialized);
1590 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1591 nul_offset = tvb_find_guint8(tvb, abs_offset, -1, 0);
1592 if (nul_offset == -1) {
1594 * OK, we hit the end of the tvbuff, so we should throw
1597 * Did we hit the end of the captured data, or the end
1598 * of the actual data? If there's less captured data
1599 * than actual data, we presumably hit the end of the
1600 * captured data, otherwise we hit the end of the actual
1603 if (tvb->length < tvb->reported_length) {
1606 if (tvb->flags & TVBUFF_FRAGMENT) {
1607 THROW(FragmentBoundsError);
1609 THROW(ReportedBoundsError);
1613 return (nul_offset - abs_offset) + 1;
1616 /* UTF-16/UCS-2 version of tvb_strsize */
1617 /* Returns number of bytes including the (two-bytes) null terminator */
1619 tvb_unicode_strsize(tvbuff_t *tvb, const gint offset)
1624 DISSECTOR_ASSERT(tvb && tvb->initialized);
1627 /* Endianness doesn't matter when looking for null */
1628 uchar = tvb_get_ntohs(tvb, offset + i);
1630 } while(uchar != 0);
1635 /* Find length of string by looking for end of string ('\0'), up to
1636 * 'maxlength' characters'; if 'maxlength' is -1, searches to end
1638 * Returns -1 if 'maxlength' reached before finding EOS. */
1640 tvb_strnlen(tvbuff_t *tvb, const gint offset, const guint maxlength)
1643 guint abs_offset, junk_length;
1645 DISSECTOR_ASSERT(tvb && tvb->initialized);
1647 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
1649 result_offset = tvb_find_guint8(tvb, abs_offset, maxlength, 0);
1651 if (result_offset == -1) {
1655 return result_offset - abs_offset;
1660 * Implement strneql etc
1664 * Call strncmp after checking if enough chars left, returning 0 if
1665 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1668 tvb_strneql(tvbuff_t *tvb, const gint offset, const gchar *str, const size_t size)
1672 ptr = ensure_contiguous_no_exception(tvb, offset, (gint)size, NULL);
1675 int cmp = strncmp((const char *)ptr, str, size);
1678 * Return 0 if equal, -1 otherwise.
1680 return (cmp == 0 ? 0 : -1);
1683 * Not enough characters in the tvbuff to match the
1691 * Call g_ascii_strncasecmp after checking if enough chars left, returning
1692 * 0 if it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1695 tvb_strncaseeql(tvbuff_t *tvb, const gint offset, const gchar *str, const size_t size)
1699 ptr = ensure_contiguous_no_exception(tvb, offset, (gint)size, NULL);
1702 int cmp = g_ascii_strncasecmp((const char *)ptr, str, size);
1705 * Return 0 if equal, -1 otherwise.
1707 return (cmp == 0 ? 0 : -1);
1710 * Not enough characters in the tvbuff to match the
1718 * Call memcmp after checking if enough chars left, returning 0 if
1719 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
1722 tvb_memeql(tvbuff_t *tvb, const gint offset, const guint8 *str, size_t size)
1726 ptr = ensure_contiguous_no_exception(tvb, offset, (gint) size, NULL);
1729 int cmp = memcmp(ptr, str, size);
1732 * Return 0 if equal, -1 otherwise.
1734 return (cmp == 0 ? 0 : -1);
1737 * Not enough characters in the tvbuff to match the
1745 * Format the data in the tvb from offset for length ...
1748 tvb_format_text(tvbuff_t *tvb, const gint offset, const gint size)
1753 len = (size > 0) ? size : 0;
1755 ptr = ensure_contiguous(tvb, offset, size);
1756 return format_text(ptr, len);
1760 * Format the data in the tvb from offset for length ...
1763 tvb_format_text_wsp(tvbuff_t *tvb, const gint offset, const gint size)
1768 len = (size > 0) ? size : 0;
1770 ptr = ensure_contiguous(tvb, offset, size);
1771 return format_text_wsp(ptr, len);
1775 * Like "tvb_format_text()", but for null-padded strings; don't show
1776 * the null padding characters as "\000".
1779 tvb_format_stringzpad(tvbuff_t *tvb, const gint offset, const gint size)
1781 const guint8 *ptr, *p;
1785 len = (size > 0) ? size : 0;
1787 ptr = ensure_contiguous(tvb, offset, size);
1788 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
1790 return format_text(ptr, stringlen);
1794 * Like "tvb_format_text_wsp()", but for null-padded strings; don't show
1795 * the null padding characters as "\000".
1798 tvb_format_stringzpad_wsp(tvbuff_t *tvb, const gint offset, const gint size)
1800 const guint8 *ptr, *p;
1804 len = (size > 0) ? size : 0;
1806 ptr = ensure_contiguous(tvb, offset, size);
1807 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
1809 return format_text_wsp(ptr, stringlen);
1812 /* Unicode REPLACEMENT CHARACTER */
1813 #define UNREPL 0x00FFFD
1816 * All string functions below take a scope as an argument.
1819 * If scope is NULL, memory is allocated with g_malloc() and user must
1820 * explicitly free it with g_free().
1821 * If scope is not NULL, memory is allocated with the corresponding pool
1824 * All functions throw an exception if the tvbuff ends before the string
1829 * Given a tvbuff, an offset, and a length, treat the string of bytes
1830 * referred to by them as an ASCII string, with all bytes with the
1831 * high-order bit set being invalid, and return a pointer to a
1834 * Octets with the highest bit set will be converted to the Unicode
1835 * REPLACEMENT CHARACTER.
1838 tvb_get_ascii_string(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint length)
1842 tvb_ensure_bytes_exist(tvb, offset, length); /* make sure length = -1 fails */
1844 str = wmem_strbuf_new(scope, "");
1846 while (length > 0) {
1847 guint8 ch = tvb_get_guint8(tvb, offset);
1850 wmem_strbuf_append_c(str, ch);
1852 wmem_strbuf_append_unichar(str, UNREPL);
1856 wmem_strbuf_append_c(str, '\0');
1858 /* XXX, discarding constiness, should we have some function which "take-over" strbuf->str
1859 (like when strbuf is no longer needed) */
1860 return (guint8 *) wmem_strbuf_get_str(str);
1864 * Given a tvbuff, an offset, and a length, treat the string of bytes
1865 * referred to by them as a UTF-8 string, and return a pointer to that
1868 * XXX - should map invalid UTF-8 sequences to UNREPL.
1871 tvb_get_utf_8_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, const gint length)
1875 tvb_ensure_bytes_exist(tvb, offset, length); /* make sure length = -1 fails */
1876 strbuf = (guint8 *)wmem_alloc(scope, length + 1);
1877 tvb_memcpy(tvb, strbuf, offset, length);
1878 strbuf[length] = '\0';
1883 * Given a tvbuff, an offset, and a length, treat the string of bytes
1884 * referred to by them as an ISO 8859/1 string, with all bytes with the
1885 * high-order bit set being invalid, and return a pointer to a UTF-8
1889 tvb_get_string_8859_1(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint length)
1893 str = wmem_strbuf_new(scope, "");
1895 while (length > 0) {
1896 guint8 ch = tvb_get_guint8(tvb, offset);
1899 wmem_strbuf_append_c(str, ch);
1902 * Note: we assume here that the code points
1903 * 0x80-0x9F are used for C1 control characters,
1904 * and thus have the same value as the corresponding
1905 * Unicode code points.
1907 wmem_strbuf_append_unichar(str, ch);
1913 /* XXX, discarding constiness, should we have some function which "take-over" strbuf->str (like when strbuf is no longer needed) */
1914 return (guint8 *) wmem_strbuf_get_str(str);
1918 * Given a tvbuff, an offset, and a length, and a translation table,
1919 * treat the string of bytes referred to by them as a string encoded
1920 * using one octet per character, with octets with the high-order bit
1921 * clear being ASCII and octets with the high-order bit set being
1922 * mapped by the translation table to 2-byte Unicode Basic Multilingual
1923 * Plane characters (including REPLACEMENT CHARACTER), and return a
1924 * pointer to a UTF-8 string.
1927 tvb_get_string_unichar2(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint length, const gunichar2 table[0x80])
1931 str = wmem_strbuf_new(scope, "");
1933 while (length > 0) {
1934 guint8 ch = tvb_get_guint8(tvb, offset);
1937 wmem_strbuf_append_c(str, ch);
1939 wmem_strbuf_append_unichar(str, table[ch-0x80]);
1944 /* XXX, discarding constiness, should we have some function which "take-over" strbuf->str (like when strbuf is no longer needed) */
1945 return (guint8 *) wmem_strbuf_get_str(str);
1949 * Given a tvbuff, and offset, and a length, treat the string of bytes
1950 * referred to by them as a UCS-2 encoded string containing characters
1951 * from the Basic Multilingual Plane (plane 0) of Unicode, return a
1952 * pointer to a UTF-8 string.
1954 * Encoding parameter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN.
1956 * Specify length in bytes.
1958 * XXX - should map lead and trail surrogate values to REPLACEMENT
1959 * CHARACTERs (0xFFFD)?
1960 * XXX - if there are an odd number of bytes, should put a
1961 * REPLACEMENT CHARACTER at the end.
1963 static wmem_strbuf_t *
1964 tvb_extract_ucs_2_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint length, const guint encoding)
1967 gint i; /* Byte counter for tvbuff */
1968 wmem_strbuf_t *strbuf;
1970 strbuf = wmem_strbuf_new(scope, NULL);
1972 for(i = 0; i + 1 < length; i += 2) {
1973 if (encoding == ENC_BIG_ENDIAN)
1974 uchar = tvb_get_ntohs(tvb, offset + i);
1976 uchar = tvb_get_letohs(tvb, offset + i);
1978 wmem_strbuf_append_unichar(strbuf, uchar);
1982 * XXX - if i < length, this means we were handed an odd
1983 * number of bytes, so we're not a valid UCS-2 string.
1989 tvb_get_ucs_2_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint length, const guint encoding)
1991 wmem_strbuf_t *strbuf;
1993 tvb_ensure_bytes_exist(tvb, offset, length);
1994 strbuf = tvb_extract_ucs_2_string(scope, tvb, offset, length, encoding);
1995 /* XXX, discarding constiness, should we have some function which "take-over" strbuf->str (like when strbuf is no longer needed) */
1996 return (gchar*)wmem_strbuf_get_str(strbuf);
2000 * Given a tvbuff, and offset, and a length, treat the string of bytes
2001 * referred to by them as a UTF-16 encoded string, return a pointer to
2004 * Encoding parameter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN.
2006 * Specify length in bytes.
2008 * XXX - should map surrogate errors to REPLACEMENT CHARACTERs (0xFFFD).
2009 * XXX - should map code points > 10FFFF to REPLACEMENT CHARACTERs.
2010 * XXX - if there are an odd number of bytes, should put a
2011 * REPLACEMENT CHARACTER at the end.
2013 static wmem_strbuf_t *
2014 tvb_extract_utf_16_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint size, const guint encoding)
2016 wmem_strbuf_t *strbuf;
2017 gunichar2 uchar2, lead_surrogate;
2019 gint i; /* Byte counter for tvbuff */
2021 strbuf = wmem_strbuf_new(scope, NULL);
2023 for(i = 0; i + 1 < size; i += 2) {
2024 if (encoding == ENC_BIG_ENDIAN)
2025 uchar2 = tvb_get_ntohs(tvb, offset + i);
2027 uchar2 = tvb_get_letohs(tvb, offset + i);
2029 if (IS_LEAD_SURROGATE(uchar2)) {
2031 * Lead surrogate. Must be followed by
2032 * a trail surrogate.
2035 if (i + 1 >= size) {
2037 * Oops, string ends with a lead surrogate.
2038 * Ignore this for now.
2039 * XXX - insert "substitute" character?
2040 * Report the error in some other
2045 lead_surrogate = uchar2;
2046 if (encoding == ENC_BIG_ENDIAN)
2047 uchar2 = tvb_get_ntohs(tvb, offset + i);
2049 uchar2 = tvb_get_letohs(tvb, offset + i);
2050 if (IS_TRAIL_SURROGATE(uchar2)) {
2051 /* Trail surrogate. */
2052 uchar = SURROGATE_VALUE(lead_surrogate, uchar2);
2053 wmem_strbuf_append_unichar(strbuf, uchar);
2056 * Not a trail surrogate.
2057 * Ignore the entire pair.
2058 * XXX - insert "substitute" character?
2059 * Report the error in some other
2065 if (IS_TRAIL_SURROGATE(uchar2)) {
2067 * Trail surrogate without a preceding
2068 * lead surrogate. Ignore it.
2069 * XXX - insert "substitute" character?
2070 * Report the error in some other
2076 * Non-surrogate; just append it.
2078 wmem_strbuf_append_unichar(strbuf, uchar2);
2084 * XXX - if i < length, this means we were handed an odd
2085 * number of bytes, so we're not a valid UTF-16 string.
2091 tvb_get_utf_16_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint length, const guint encoding)
2093 wmem_strbuf_t *strbuf;
2095 tvb_ensure_bytes_exist(tvb, offset, length);
2096 strbuf = tvb_extract_utf_16_string(scope, tvb, offset, length, encoding);
2097 /* XXX, discarding constiness, should we have some function which "take-over" strbuf->str (like when strbuf is no longer needed) */
2098 return (gchar*)wmem_strbuf_get_str(strbuf);
2102 * Given a tvbuff, and offset, and a length, treat the string of bytes
2103 * referred to by them as a UCS-4 encoded string, return a pointer to
2106 * Encoding parameter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN
2108 * Specify length in bytes
2110 * XXX - should map lead and trail surrogate values to a "substitute"
2112 * XXX - should map code points > 10FFFF to REPLACEMENT CHARACTERs.
2113 * XXX - if the number of bytes isn't a multiple of 4, should put a
2114 * REPLACEMENT CHARACTER at the end.
2116 static wmem_strbuf_t *
2117 tvb_extract_ucs_4_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint length, const guint encoding)
2120 gint i; /* Byte counter for tvbuff */
2121 wmem_strbuf_t *strbuf;
2123 strbuf = wmem_strbuf_new(scope, NULL);
2125 for(i = 0; i + 3 < length; i += 4) {
2126 if (encoding == ENC_BIG_ENDIAN)
2127 uchar = tvb_get_ntohl(tvb, offset + i);
2129 uchar = tvb_get_letohl(tvb, offset + i);
2131 wmem_strbuf_append_unichar(strbuf, uchar);
2135 * XXX - if i < length, this means we were handed a number
2136 * of bytes that's not a multiple of 4, so we're not a valid
2143 tvb_get_ucs_4_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint length, const guint encoding)
2145 wmem_strbuf_t *strbuf;
2147 tvb_ensure_bytes_exist(tvb, offset, length);
2148 strbuf = tvb_extract_ucs_4_string(scope, tvb, offset, length, encoding);
2149 /* XXX, discarding constiness, should we have some function which "take-over" strbuf->str (like when strbuf is no longer needed) */
2150 return (gchar*)wmem_strbuf_get_str(strbuf);
2158 #define GN_BYTE_MASK ((1 << bits) - 1)
2160 #define GN_CHAR_ALPHABET_SIZE 128
2162 #define GN_CHAR_ESCAPE 0x1b
2164 static const gunichar gsm_default_alphabet[GN_CHAR_ALPHABET_SIZE] = {
2166 /* ETSI GSM 03.38, version 6.0.1, section 6.2.1; Default alphabet */
2168 '@', 0xa3, '$', 0xa5, 0xe8, 0xe9, 0xf9, 0xec,
2169 0xf2, 0xc7, '\n', 0xd8, 0xf8, '\r', 0xc5, 0xe5,
2170 0x394, '_', 0x3a6, 0x393, 0x39b, 0x3a9, 0x3a0, 0x3a8,
2171 0x3a3, 0x398, 0x39e, 0xa0, 0xc6, 0xe6, 0xdf, 0xc9,
2172 ' ', '!', '\"', '#', 0xa4, '%', '&', '\'',
2173 '(', ')', '*', '+', ',', '-', '.', '/',
2174 '0', '1', '2', '3', '4', '5', '6', '7',
2175 '8', '9', ':', ';', '<', '=', '>', '?',
2176 0xa1, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
2177 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
2178 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
2179 'X', 'Y', 'Z', 0xc4, 0xd6, 0xd1, 0xdc, 0xa7,
2180 0xbf, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
2181 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
2182 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
2183 'x', 'y', 'z', 0xe4, 0xf6, 0xf1, 0xfc, 0xe0
2187 char_is_escape(unsigned char value)
2189 return (value == GN_CHAR_ESCAPE);
2193 char_def_alphabet_ext_decode(unsigned char value)
2197 case 0x0a: return 0x0c; /* form feed */
2198 case 0x14: return '^';
2199 case 0x28: return '{';
2200 case 0x29: return '}';
2201 case 0x2f: return '\\';
2202 case 0x3c: return '[';
2203 case 0x3d: return '~';
2204 case 0x3e: return ']';
2205 case 0x40: return '|';
2206 case 0x65: return 0x20ac; /* euro */
2207 default: return UNREPL; /* invalid character */
2212 char_def_alphabet_decode(unsigned char value)
2214 if (value < GN_CHAR_ALPHABET_SIZE)
2216 return gsm_default_alphabet[value];
2225 handle_ts_23_038_char(wmem_strbuf_t *strbuf, guint8 code_point,
2226 gboolean saw_escape)
2230 if (char_is_escape(code_point)) {
2232 * XXX - if saw_escape is TRUE here, then this is
2233 * the case where we escape to "another extension table",
2234 * but TS 128 038 V11.0 doesn't specify such an extension
2240 * Have we seen an escape?
2244 uchar = char_def_alphabet_ext_decode(code_point);
2246 uchar = char_def_alphabet_decode(code_point);
2248 wmem_strbuf_append_unichar(strbuf, uchar);
2254 tvb_get_ts_23_038_7bits_string(wmem_allocator_t *scope, tvbuff_t *tvb,
2255 const gint bit_offset, gint no_of_chars)
2257 wmem_strbuf_t *strbuf;
2258 gint char_count; /* character counter for tvbuff */
2259 gint in_offset = bit_offset >> 3; /* Current pointer to the input buffer */
2260 guint8 in_byte, out_byte, rest = 0x00;
2261 gboolean saw_escape = FALSE;
2264 bits = bit_offset & 0x07;
2269 tvb_ensure_bytes_exist(tvb, in_offset, ((no_of_chars + 1) * 7 + (bit_offset & 0x07)) >> 3);
2270 strbuf = wmem_strbuf_new(scope, NULL);
2271 for(char_count = 0; char_count < no_of_chars;) {
2272 /* Get the next byte from the string. */
2273 in_byte = tvb_get_guint8(tvb, in_offset);
2277 * Combine the bits we've accumulated with bits from
2278 * that byte to make a 7-bit code point.
2280 out_byte = ((in_byte & GN_BYTE_MASK) << (7 - bits)) | rest;
2283 * Leftover bits used in that code point.
2285 rest = in_byte >> bits;
2288 * If we don't start from 0th bit, we shouldn't go to the
2289 * next char. Under *out_num we have now 0 and under Rest -
2290 * _first_ part of the char.
2292 if (char_count || (bits == 7)) {
2293 saw_escape = handle_ts_23_038_char(strbuf, out_byte,
2299 * After reading 7 octets we have read 7 full characters
2300 * but we have 7 bits as well. This is the next character.
2302 if ((bits == 1) && (char_count < no_of_chars)) {
2303 saw_escape = handle_ts_23_038_char(strbuf, rest,
2314 * Escape not followed by anything.
2316 * XXX - for now, show the escape as a REPLACEMENT
2319 wmem_strbuf_append_unichar(strbuf, UNREPL);
2322 /* XXX, discarding constiness, should we have some function which "take-over" strbuf->str (like when strbuf is no longer needed) */
2323 return (gchar*)wmem_strbuf_get_str(strbuf);
2327 * Given a tvbuff, an offset, a length, and an encoding, allocate a
2328 * buffer big enough to hold a non-null-terminated string of that length
2329 * at that offset, plus a trailing '\0', copy into the buffer the
2330 * string as converted from the appropriate encoding to UTF-8, and
2331 * return a pointer to the string.
2334 tvb_get_string_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset,
2335 const gint length, const guint encoding)
2340 switch (encoding & ENC_CHARENCODING_MASK) {
2345 * For now, we treat bogus values as meaning
2346 * "ASCII" rather than reporting an error,
2347 * for the benefit of old dissectors written
2348 * when the last argument to proto_tree_add_item()
2349 * was a gboolean for the byte order, not an
2350 * encoding value, and passed non-zero values
2351 * other than TRUE to mean "little-endian".
2353 strbuf = tvb_get_ascii_string(scope, tvb, offset, length);
2358 * XXX - should map lead and trail surrogate value code
2359 * points to a "substitute" UTF-8 character?
2360 * XXX - should map code points > 10FFFF to REPLACEMENT
2363 strbuf = tvb_get_utf_8_string(scope, tvb, offset, length);
2367 strbuf = tvb_get_utf_16_string(scope, tvb, offset, length,
2368 encoding & ENC_LITTLE_ENDIAN);
2372 strbuf = tvb_get_ucs_2_string(scope, tvb, offset, length,
2373 encoding & ENC_LITTLE_ENDIAN);
2377 strbuf = tvb_get_ucs_4_string(scope, tvb, offset, length,
2378 encoding & ENC_LITTLE_ENDIAN);
2381 case ENC_ISO_8859_1:
2383 * ISO 8859-1 printable code point values are equal
2384 * to the equivalent Unicode code point value, so
2385 * no translation table is needed.
2387 strbuf = tvb_get_string_8859_1(scope, tvb, offset, length);
2390 case ENC_ISO_8859_2:
2391 strbuf = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_2);
2394 case ENC_ISO_8859_3:
2395 strbuf = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_3);
2398 case ENC_ISO_8859_4:
2399 strbuf = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_4);
2402 case ENC_ISO_8859_5:
2403 strbuf = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_5);
2406 case ENC_ISO_8859_6:
2407 strbuf = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_6);
2410 case ENC_ISO_8859_7:
2411 strbuf = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_7);
2414 case ENC_ISO_8859_8:
2415 strbuf = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_8);
2418 case ENC_ISO_8859_9:
2419 strbuf = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_9);
2422 case ENC_ISO_8859_10:
2423 strbuf = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_10);
2426 case ENC_ISO_8859_11:
2427 strbuf = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_11);
2430 case ENC_ISO_8859_13:
2431 strbuf = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_13);
2434 case ENC_ISO_8859_14:
2435 strbuf = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_14);
2438 case ENC_ISO_8859_15:
2439 strbuf = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_15);
2442 case ENC_ISO_8859_16:
2443 strbuf = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_16);
2446 case ENC_WINDOWS_1250:
2447 strbuf = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_cp1250);
2450 case ENC_3GPP_TS_23_038_7BITS:
2452 gint bit_offset = offset << 3;
2453 gint no_of_chars = (length << 3) / 7;
2454 strbuf = tvb_get_ts_23_038_7bits_string(scope, tvb, bit_offset, no_of_chars);
2460 * XXX - do the copy and conversion in one pass.
2462 * XXX - multiple "dialects" of EBCDIC?
2464 tvb_ensure_bytes_exist(tvb, offset, length); /* make sure length = -1 fails */
2465 strbuf = (guint8 *)wmem_alloc(scope, length + 1);
2467 ptr = ensure_contiguous(tvb, offset, length);
2468 memcpy(strbuf, ptr, length);
2469 EBCDIC_to_ASCII(strbuf, length);
2471 strbuf[length] = '\0';
2478 * Get an ASCII string; this should not be used in new code.
2481 tvb_get_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset,
2484 return tvb_get_ascii_string(scope, tvb, offset, length);
2488 * These routines are like the above routines, except that they handle
2489 * null-terminated strings. They find the length of that string (and
2490 * throw an exception if the tvbuff ends before we find the null), and
2491 * also return through a pointer the length of the string, in bytes,
2492 * including the terminating null (the terminating null being 2 bytes
2493 * for UCS-2 and UTF-16, 4 bytes for UCS-4, and 1 byte for other
2497 tvb_get_ascii_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint *lengthp)
2502 str = wmem_strbuf_new(scope, "");
2504 size = tvb_strsize(tvb, offset);
2505 for (i = 0; i < size; i++) {
2506 guint8 ch = tvb_get_guint8(tvb, offset);
2509 wmem_strbuf_append_c(str, ch);
2511 wmem_strbuf_append_unichar(str, UNREPL);
2514 /* No need to append '\0' - we processed the NUL in the loop above. */
2519 /* XXX, discarding constiness, should we have some function which "take-over" strbuf->str
2520 (like when strbuf is no longer needed) */
2521 return (guint8 *) wmem_strbuf_get_str(str);
2525 tvb_get_utf_8_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint *lengthp)
2530 size = tvb_strsize(tvb, offset);
2531 strptr = (guint8 *)wmem_alloc(scope, size);
2532 tvb_memcpy(tvb, strptr, offset, size);
2539 tvb_get_stringz_8859_1(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint *lengthp)
2543 /* XXX, convertion between signed/unsigned integer */
2544 *lengthp = size = tvb_strsize(tvb, offset);
2546 return tvb_get_string_8859_1(scope, tvb, offset, size);
2550 tvb_get_stringz_unichar2(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint *lengthp, const gunichar2 table[0x80])
2554 /* XXX, convertion between signed/unsigned integer */
2555 *lengthp = size = tvb_strsize(tvb, offset);
2557 return tvb_get_string_unichar2(scope, tvb, offset, size, table);
2561 * Given a tvbuff and an offset, with the offset assumed to refer to
2562 * a null-terminated string, find the length of that string (and throw
2563 * an exception if the tvbuff ends before we find the null), ensure that
2564 * the TVB is flat, and return a pointer to the string (in the TVB).
2565 * Also return the length of the string (including the terminating null)
2566 * through a pointer.
2568 * As long as we aren't using composite TVBs, this saves the cycles used
2569 * (often unnecessariliy) in allocating a buffer and copying the string into
2570 * it. (If we do start using composite TVBs, we may want to replace this
2571 * function with the _ephemeral versoin.)
2574 tvb_get_const_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp)
2577 const guint8 *strptr;
2579 size = tvb_strsize(tvb, offset);
2580 strptr = ensure_contiguous(tvb, offset, size);
2587 tvb_get_ucs_2_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding)
2589 gint size; /* Number of bytes in string */
2590 wmem_strbuf_t *strbuf;
2592 size = tvb_unicode_strsize(tvb, offset);
2594 strbuf = tvb_extract_ucs_2_string(scope, tvb, offset, size, encoding);
2599 /* XXX, discarding constiness, should we have some function which "take-over" strbuf->str (like when strbuf is no longer needed) */
2600 return (gchar*)wmem_strbuf_get_str(strbuf);
2604 tvb_get_utf_16_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding)
2607 wmem_strbuf_t *strbuf;
2609 size = tvb_unicode_strsize(tvb, offset);
2611 strbuf = tvb_extract_utf_16_string(scope, tvb, offset, size, encoding);
2616 /* XXX, discarding constiness, should we have some function which "take-over" strbuf->str (like when strbuf is no longer needed) */
2617 return (gchar*)wmem_strbuf_get_str(strbuf);
2621 tvb_get_ucs_4_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding)
2624 gint size; /* Number of bytes in string */
2625 wmem_strbuf_t *strbuf;
2627 DISSECTOR_ASSERT(tvb && tvb->initialized);
2631 /* Endianness doesn't matter when looking for null */
2632 uchar = tvb_get_ntohl(tvb, offset + size);
2634 } while(uchar != 0);
2636 strbuf = tvb_extract_ucs_4_string(scope, tvb, offset, size, encoding);
2639 *lengthp = size; /* Number of *bytes* processed */
2641 /* XXX, discarding constiness, should we have some function which "take-over" strbuf->str (like when strbuf is no longer needed) */
2642 return (gchar*)wmem_strbuf_get_str(strbuf);
2646 tvb_get_stringz_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding)
2651 switch (encoding & ENC_CHARENCODING_MASK) {
2656 * For now, we treat bogus values as meaning
2657 * "ASCII" rather than reporting an error,
2658 * for the benefit of old dissectors written
2659 * when the last argument to proto_tree_add_item()
2660 * was a gboolean for the byte order, not an
2661 * encoding value, and passed non-zero values
2662 * other than TRUE to mean "little-endian".
2664 strptr = tvb_get_ascii_stringz(scope, tvb, offset, lengthp);
2669 * XXX - should map all invalid UTF-8 sequences
2670 * to a "substitute" UTF-8 character.
2671 * XXX - should map code points > 10FFFF to REPLACEMENT
2674 strptr = tvb_get_utf_8_stringz(scope, tvb, offset, lengthp);
2678 strptr = tvb_get_utf_16_stringz(scope, tvb, offset, lengthp,
2679 encoding & ENC_LITTLE_ENDIAN);
2683 strptr = tvb_get_ucs_2_stringz(scope, tvb, offset, lengthp,
2684 encoding & ENC_LITTLE_ENDIAN);
2688 strptr = tvb_get_ucs_4_stringz(scope, tvb, offset, lengthp,
2689 encoding & ENC_LITTLE_ENDIAN);
2692 case ENC_ISO_8859_1:
2694 * ISO 8859-1 printable code point values are equal
2695 * to the equivalent Unicode code point value, so
2696 * no translation table is needed.
2698 strptr = tvb_get_stringz_8859_1(scope, tvb, offset, lengthp);
2701 case ENC_ISO_8859_2:
2702 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_2);
2705 case ENC_ISO_8859_3:
2706 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_3);
2709 case ENC_ISO_8859_4:
2710 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_4);
2713 case ENC_ISO_8859_5:
2714 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_5);
2717 case ENC_ISO_8859_6:
2718 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_6);
2721 case ENC_ISO_8859_7:
2722 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_7);
2725 case ENC_ISO_8859_8:
2726 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_8);
2729 case ENC_ISO_8859_9:
2730 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_9);
2733 case ENC_ISO_8859_10:
2734 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_10);
2737 case ENC_ISO_8859_11:
2738 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_11);
2741 case ENC_ISO_8859_13:
2742 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_13);
2745 case ENC_ISO_8859_14:
2746 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_14);
2749 case ENC_ISO_8859_15:
2750 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_15);
2753 case ENC_ISO_8859_16:
2754 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_16);
2757 case ENC_WINDOWS_1250:
2758 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_cp1250);
2761 case ENC_3GPP_TS_23_038_7BITS:
2762 REPORT_DISSECTOR_BUG("TS 23.038 7bits has no null character and doesn't support null-terminated strings");
2767 * XXX - do the copy and conversion in one pass.
2769 * XXX - multiple "dialects" of EBCDIC?
2771 size = tvb_strsize(tvb, offset);
2772 strptr = (guint8 *)wmem_alloc(scope, size);
2773 tvb_memcpy(tvb, strptr, offset, size);
2774 EBCDIC_to_ASCII(strptr, size);
2784 * Get an ASCII string; this should not be used in new code.
2787 tvb_get_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset,
2790 return tvb_get_ascii_stringz(scope, tvb, offset, lengthp);
2793 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
2794 * no more than bufsize number of bytes, including terminating NUL, to buffer.
2795 * Returns length of string (not including terminating NUL), or -1 if the string was
2796 * truncated in the buffer due to not having reached the terminating NUL.
2797 * In this way, it acts like g_snprintf().
2799 * bufsize MUST be greater than 0.
2801 * When processing a packet where the remaining number of bytes is less
2802 * than bufsize, an exception is not thrown if the end of the packet
2803 * is reached before the NUL is found. If no NUL is found before reaching
2804 * the end of the short packet, -1 is still returned, and the string
2805 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
2806 * at the correct spot, terminating the string.
2808 * *bytes_copied will contain the number of bytes actually copied,
2809 * including the terminating-NUL.
2812 _tvb_get_nstringz(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* buffer, gint *bytes_copied)
2817 gboolean decreased_max = FALSE;
2819 /* Only read to end of tvbuff, w/o throwing exception. */
2820 check_offset_length(tvb, offset, -1, &abs_offset, &len);
2822 /* There must at least be room for the terminating NUL. */
2823 DISSECTOR_ASSERT(bufsize != 0);
2825 /* If there's no room for anything else, just return the NUL. */
2832 /* check_offset_length() won't throw an exception if we're
2833 * looking at the byte immediately after the end of the tvbuff. */
2835 THROW(ReportedBoundsError);
2838 /* This should not happen because check_offset_length() would
2839 * have already thrown an exception if 'offset' were out-of-bounds.
2841 DISSECTOR_ASSERT(len != -1);
2844 * If we've been passed a negative number, bufsize will
2847 DISSECTOR_ASSERT(bufsize <= G_MAXINT);
2849 if ((guint)len < bufsize) {
2851 decreased_max = TRUE;
2857 stringlen = tvb_strnlen(tvb, abs_offset, limit - 1);
2858 /* If NUL wasn't found, copy the data and return -1 */
2859 if (stringlen == -1) {
2860 tvb_memcpy(tvb, buffer, abs_offset, limit);
2861 if (decreased_max) {
2863 /* Add 1 for the extra NUL that we set at buffer[limit],
2864 * pretending that it was copied as part of the string. */
2865 *bytes_copied = limit + 1;
2868 *bytes_copied = limit;
2873 /* Copy the string to buffer */
2874 tvb_memcpy(tvb, buffer, abs_offset, stringlen + 1);
2875 *bytes_copied = stringlen + 1;
2879 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
2880 * no more than bufsize number of bytes, including terminating NUL, to buffer.
2881 * Returns length of string (not including terminating NUL), or -1 if the string was
2882 * truncated in the buffer due to not having reached the terminating NUL.
2883 * In this way, it acts like g_snprintf().
2885 * When processing a packet where the remaining number of bytes is less
2886 * than bufsize, an exception is not thrown if the end of the packet
2887 * is reached before the NUL is found. If no NUL is found before reaching
2888 * the end of the short packet, -1 is still returned, and the string
2889 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
2890 * at the correct spot, terminating the string.
2893 tvb_get_nstringz(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* buffer)
2897 DISSECTOR_ASSERT(tvb && tvb->initialized);
2899 return _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
2902 /* Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
2903 * have a terminating NUL. If the string was truncated when copied into buffer,
2904 * a NUL is placed at the end of buffer to terminate it.
2907 tvb_get_nstringz0(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* buffer)
2909 gint len, bytes_copied;
2911 DISSECTOR_ASSERT(tvb && tvb->initialized);
2913 len = _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
2916 buffer[bufsize - 1] = 0;
2917 return bytes_copied - 1;
2925 * Given a tvbuff, an offset into the tvbuff, and a length that starts
2926 * at that offset (which may be -1 for "all the way to the end of the
2927 * tvbuff"), find the end of the (putative) line that starts at the
2928 * specified offset in the tvbuff, going no further than the specified
2931 * Return the length of the line (not counting the line terminator at
2932 * the end), or, if we don't find a line terminator:
2934 * if "deseg" is true, return -1;
2936 * if "deseg" is false, return the amount of data remaining in
2939 * Set "*next_offset" to the offset of the character past the line
2940 * terminator, or past the end of the buffer if we don't find a line
2941 * terminator. (It's not set if we return -1.)
2944 tvb_find_line_end(tvbuff_t *tvb, const gint offset, int len, gint *next_offset, const gboolean desegment)
2949 guchar found_needle = 0;
2952 len = tvb_length_remaining(tvb, offset);
2954 * XXX - what if "len" is still -1, meaning "offset is past the
2955 * end of the tvbuff"?
2957 eob_offset = offset + len;
2960 * Look either for a CR or an LF.
2962 eol_offset = tvb_pbrk_guint8(tvb, offset, len, "\r\n", &found_needle);
2963 if (eol_offset == -1) {
2965 * No CR or LF - line is presumably continued in next packet.
2969 * Tell our caller we saw no EOL, so they can
2970 * try to desegment and get the entire line
2976 * Pretend the line runs to the end of the tvbuff.
2978 linelen = eob_offset - offset;
2980 *next_offset = eob_offset;
2984 * Find the number of bytes between the starting offset
2987 linelen = eol_offset - offset;
2992 if (found_needle == '\r') {
2994 * Yes - is it followed by an LF?
2996 if (eol_offset + 1 >= eob_offset) {
2998 * Dunno - the next byte isn't in this
3003 * We'll return -1, although that
3004 * runs the risk that if the line
3005 * really *is* terminated with a CR,
3006 * we won't properly dissect this
3009 * It's probably more likely that
3010 * the line ends with CR-LF than
3011 * that it ends with CR by itself.
3017 * Well, we can at least look at the next
3020 if (tvb_get_guint8(tvb, eol_offset + 1) == '\n') {
3022 * It's an LF; skip over the CR.
3030 * Return the offset of the character after the last
3031 * character in the line, skipping over the last character
3032 * in the line terminator.
3035 *next_offset = eol_offset + 1;
3041 * Given a tvbuff, an offset into the tvbuff, and a length that starts
3042 * at that offset (which may be -1 for "all the way to the end of the
3043 * tvbuff"), find the end of the (putative) line that starts at the
3044 * specified offset in the tvbuff, going no further than the specified
3047 * However, treat quoted strings inside the buffer specially - don't
3048 * treat newlines in quoted strings as line terminators.
3050 * Return the length of the line (not counting the line terminator at
3051 * the end), or the amount of data remaining in the buffer if we don't
3052 * find a line terminator.
3054 * Set "*next_offset" to the offset of the character past the line
3055 * terminator, or past the end of the buffer if we don't find a line
3059 tvb_find_line_end_unquoted(tvbuff_t *tvb, const gint offset, int len, gint *next_offset)
3061 gint cur_offset, char_offset;
3068 len = tvb_length_remaining(tvb, offset);
3070 * XXX - what if "len" is still -1, meaning "offset is past the
3071 * end of the tvbuff"?
3073 eob_offset = offset + len;
3075 cur_offset = offset;
3079 * Is this part of the string quoted?
3083 * Yes - look only for the terminating quote.
3085 char_offset = tvb_find_guint8(tvb, cur_offset, len,
3089 * Look either for a CR, an LF, or a '"'.
3091 char_offset = tvb_pbrk_guint8(tvb, cur_offset, len, "\r\n\"", &c);
3093 if (char_offset == -1) {
3095 * Not found - line is presumably continued in
3097 * We pretend the line runs to the end of the tvbuff.
3099 linelen = eob_offset - offset;
3101 *next_offset = eob_offset;
3107 * We're processing a quoted string.
3108 * We only looked for ", so we know it's a ";
3109 * as we're processing a quoted string, it's a
3119 * Un-quoted "; it begins a quoted
3125 * It's a CR or LF; we've found a line
3128 * Find the number of bytes between the
3129 * starting offset and the CR or LF.
3131 linelen = char_offset - offset;
3138 * Yes; is it followed by an LF?
3140 if (char_offset + 1 < eob_offset &&
3141 tvb_get_guint8(tvb, char_offset + 1)
3144 * Yes; skip over the CR.
3151 * Return the offset of the character after
3152 * the last character in the line, skipping
3153 * over the last character in the line
3154 * terminator, and quit.
3157 *next_offset = char_offset + 1;
3163 * Step past the character we found.
3165 cur_offset = char_offset + 1;
3166 if (cur_offset >= eob_offset) {
3168 * The character we found was the last character
3169 * in the tvbuff - line is presumably continued in
3171 * We pretend the line runs to the end of the tvbuff.
3173 linelen = eob_offset - offset;
3175 *next_offset = eob_offset;
3183 * Copied from the mgcp dissector. (This function should be moved to /epan )
3184 * tvb_skip_wsp - Returns the position in tvb of the first non-whitespace
3185 * character following offset or offset + maxlength -1 whichever
3189 * tvb - The tvbuff in which we are skipping whitespace.
3190 * offset - The offset in tvb from which we begin trying to skip whitespace.
3191 * maxlength - The maximum distance from offset that we may try to skip
3194 * Returns: The position in tvb of the first non-whitespace
3195 * character following offset or offset + maxlength -1 whichever
3199 tvb_skip_wsp(tvbuff_t *tvb, const gint offset, const gint maxlength)
3201 gint counter = offset;
3205 /* Get the length remaining */
3206 tvb_len = tvb_length(tvb);
3207 end = offset + maxlength;
3213 /* Skip past spaces, tabs, CRs and LFs until run out or meet something else */
3214 for (counter = offset;
3216 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
3217 tempchar == '\t' || tempchar == '\r' || tempchar == '\n');
3224 tvb_skip_wsp_return(tvbuff_t *tvb, const gint offset) {
3225 gint counter = offset;
3228 for(counter = offset; counter > 0 &&
3229 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
3230 tempchar == '\t' || tempchar == '\n' || tempchar == '\r'); counter--);
3236 tvb_skip_guint8(tvbuff_t *tvb, int offset, const int maxlength, const guint8 ch)
3240 /* Get the length remaining */
3241 tvb_len = tvb_length(tvb);
3242 end = offset + maxlength;
3246 while (offset < end) {
3247 guint8 tempch = tvb_get_guint8(tvb, offset);
3258 * Format a bunch of data from a tvbuff as bytes, returning a pointer
3259 * to the string with the formatted data, with "punct" as a byte
3263 tvb_bytes_to_ep_str_punct(tvbuff_t *tvb, const gint offset, const gint len, const gchar punct)
3265 return bytes_to_ep_str_punct(ensure_contiguous(tvb, offset, len), len, punct);
3270 * Given a tvbuff, an offset into the tvbuff, and a length that starts
3271 * at that offset (which may be -1 for "all the way to the end of the
3272 * tvbuff"), fetch BCD encoded digits from a tvbuff starting from either
3273 * the low or high half byte, formating the digits according to an input digit set,
3274 * if NUll a default digit set of 0-9 returning "?" for overdecadic digits will be used.
3275 * A pointer to the packet scope allocated string will be returned.
3276 * Note a tvbuff content of 0xf is considered a 'filler' and will end the conversion.
3278 static dgt_set_t Dgt1_9_bcd = {
3280 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f*/
3281 '0','1','2','3','4','5','6','7','8','9','?','?','?','?','?','?'
3285 tvb_bcd_dig_to_wmem_packet_str(tvbuff_t *tvb, const gint offset, const gint len, dgt_set_t *dgt, gboolean skip_first)
3291 gint t_offset = offset;
3297 length = tvb_length(tvb);
3298 if (length < offset) {
3302 length = offset + len;
3304 digit_str = (char *)wmem_alloc(wmem_packet_scope(), (length - offset)*2+1);
3306 while (t_offset < length) {
3308 octet = tvb_get_guint8(tvb,t_offset);
3310 digit_str[i] = dgt->out[octet & 0x0f];
3316 * unpack second value in byte
3320 if (octet == 0x0f) /* odd number bytes - hit filler */
3323 digit_str[i] = dgt->out[octet & 0x0f];
3334 * Format a bunch of data from a tvbuff as bytes, returning a pointer
3335 * to the string with the formatted data.
3338 tvb_bytes_to_ep_str(tvbuff_t *tvb, const gint offset, const gint len)
3340 return bytes_to_ep_str(ensure_contiguous(tvb, offset, len), len);
3343 /* Find a needle tvbuff within a haystack tvbuff. */
3345 tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb, const gint haystack_offset)
3347 guint haystack_abs_offset, haystack_abs_length;
3348 const guint8 *haystack_data;
3349 const guint8 *needle_data;
3350 const guint needle_len = needle_tvb->length;
3351 const guint8 *location;
3353 DISSECTOR_ASSERT(haystack_tvb && haystack_tvb->initialized);
3355 if (haystack_tvb->length < 1 || needle_tvb->length < 1) {
3359 /* Get pointers to the tvbuffs' data. */
3360 haystack_data = ensure_contiguous(haystack_tvb, 0, -1);
3361 needle_data = ensure_contiguous(needle_tvb, 0, -1);
3363 check_offset_length(haystack_tvb, haystack_offset, -1,
3364 &haystack_abs_offset, &haystack_abs_length);
3366 location = epan_memmem(haystack_data + haystack_abs_offset, haystack_abs_length,
3367 needle_data, needle_len);
3370 return (gint) (location - haystack_data);
3377 tvb_raw_offset(tvbuff_t *tvb)
3379 return ((tvb->raw_offset==-1) ? (tvb->raw_offset = tvb_offset_from_real_beginning(tvb)) : tvb->raw_offset);
3383 tvb_set_fragment(tvbuff_t *tvb)
3385 tvb->flags |= TVBUFF_FRAGMENT;
3389 tvb_get_ds_tvb(tvbuff_t *tvb)
3391 return(tvb->ds_tvb);
3395 * Editor modelines - http://www.wireshark.org/tools/modelines.html
3400 * indent-tabs-mode: t
3403 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3404 * :indentSize=8:tabSize=8:noTabs=false: