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 * SPDX-License-Identifier: GPL-2.0-or-later
30 #include "wsutil/pint.h"
31 #include "wsutil/sign_ext.h"
32 #include "wsutil/unicode-utils.h"
33 #include "wsutil/nstime.h"
34 #include "wsutil/time_util.h"
36 #include "tvbuff-int.h"
40 #include "proto.h" /* XXX - only used for DISSECTOR_ASSERT, probably a new header file? */
41 #include "exceptions.h"
44 * Just make sure we include the prototype for strptime as well
45 * (needed for glibc 2.2) but make sure we do this only if not
49 /*#ifndef HAVE_STRPTIME*/
51 #include "wsutil/strptime.h"
56 _tvb_get_bits64(tvbuff_t *tvb, guint bit_offset, const gint total_no_of_bits);
59 _tvb_captured_length_remaining(const tvbuff_t *tvb, const gint offset);
61 static inline const guint8*
62 ensure_contiguous(tvbuff_t *tvb, const gint offset, const gint length);
64 static inline guint8 *
65 tvb_get_raw_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, const gint length);
68 tvb_new(const struct tvb_ops *ops)
71 gsize size = ops->tvb_size;
73 g_assert(size >= sizeof(*tvb));
75 tvb = (tvbuff_t *) g_slice_alloc(size);
79 tvb->initialized = FALSE;
82 tvb->reported_length = 0;
83 tvb->contained_length = 0;
84 tvb->real_data = NULL;
92 tvb_free_internal(tvbuff_t *tvb)
96 DISSECTOR_ASSERT(tvb);
98 if (tvb->ops->tvb_free)
99 tvb->ops->tvb_free(tvb);
101 size = tvb->ops->tvb_size;
103 g_slice_free1(size, tvb);
106 /* XXX: just call tvb_free_chain();
107 * Not removed so that existing dissectors using tvb_free() need not be changed.
108 * I'd argue that existing calls to tvb_free() should have actually beeen
109 * calls to tvb_free_chain() although the calls were OK as long as no
110 * subsets, etc had been created on the tvb. */
112 tvb_free(tvbuff_t *tvb)
118 tvb_free_chain(tvbuff_t *tvb)
121 DISSECTOR_ASSERT(tvb);
123 next_tvb = tvb->next;
124 tvb_free_internal(tvb);
130 tvb_new_chain(tvbuff_t *parent, tvbuff_t *backing)
132 tvbuff_t *tvb = tvb_new_proxy(backing);
134 tvb_add_to_chain(parent, tvb);
139 tvb_add_to_chain(tvbuff_t *parent, tvbuff_t *child)
141 tvbuff_t *tmp = child;
143 DISSECTOR_ASSERT(parent);
144 DISSECTOR_ASSERT(child);
150 tmp->next = parent->next;
156 * Check whether that offset goes more than one byte past the
159 * If not, return 0; otherwise, return exception
162 validate_offset(const tvbuff_t *tvb, const guint abs_offset)
164 if (G_LIKELY(abs_offset <= tvb->length)) {
170 * It's not OK, but why? Which boundaries is it
173 if (abs_offset <= tvb->contained_length) {
175 * It's past the captured length, but not past
176 * the reported end of any parent tvbuffs from
177 * which this is constructed, or the reported
178 * end of this tvbuff, so it's out of bounds
179 * solely because we're past the end of the
186 * There's some actual packet boundary, not just the
187 * artificial boundary imposed by packet slicing, that
190 if (abs_offset <= tvb->reported_length) {
192 * We're within the bounds of what this tvbuff
193 * purportedly contains, based on some length
194 * value, but we're not within the bounds of
195 * something from which this tvbuff was
196 * extracted, so that length value ran past
197 * the end of some parent tvbuff.
199 return ContainedBoundsError;
203 * OK, we're past the bounds of what this tvbuff
204 * purportedly contains.
206 if (tvb->flags & TVBUFF_FRAGMENT) {
208 * This tvbuff is the first fragment of a larger
209 * packet that hasn't been reassembled, so we
210 * assume that's the source of the prblem - if
211 * we'd reassembled the packet, we wouldn't
212 * have gone past the end.
214 * That might not be true, but for at least
215 * some forms of reassembly, such as IP
216 * reassembly, you don't know how big the
217 * reassembled packet is unless you reassemble
218 * it, so, in those cases, we can't determine
219 * whether we would have gone past the end
220 * had we reassembled the packet.
222 return FragmentBoundsError;
226 * OK, it looks as if we ran past the claimed length
229 return ReportedBoundsError;
233 compute_offset(const tvbuff_t *tvb, const gint offset, guint *offset_ptr)
236 /* Positive offset - relative to the beginning of the packet. */
237 if (G_LIKELY((guint) offset <= tvb->length)) {
238 *offset_ptr = offset;
239 } else if ((guint) offset <= tvb->contained_length) {
241 } else if ((guint) offset <= tvb->reported_length) {
242 return ContainedBoundsError;
243 } else if (tvb->flags & TVBUFF_FRAGMENT) {
244 return FragmentBoundsError;
246 return ReportedBoundsError;
250 /* Negative offset - relative to the end of the packet. */
251 if (G_LIKELY((guint) -offset <= tvb->length)) {
252 *offset_ptr = tvb->length + offset;
253 } else if ((guint) -offset <= tvb->contained_length) {
255 } else if ((guint) -offset <= tvb->reported_length) {
256 return ContainedBoundsError;
257 } else if (tvb->flags & TVBUFF_FRAGMENT) {
258 return FragmentBoundsError;
260 return ReportedBoundsError;
268 compute_offset_and_remaining(const tvbuff_t *tvb, const gint offset, guint *offset_ptr, guint *rem_len)
272 exception = compute_offset(tvb, offset, offset_ptr);
274 *rem_len = tvb->length - *offset_ptr;
279 /* Computes the absolute offset and length based on a possibly-negative offset
280 * and a length that is possible -1 (which means "to the end of the data").
281 * Returns integer indicating whether the offset is in bounds (0) or
282 * not (exception number). The integer ptrs are modified with the new offset,
283 * captured (available) length, and contained length (amount that's present
284 * in the parent tvbuff based on its reported length).
285 * No exception is thrown; on success, we return 0, otherwise we return an
286 * exception for the caller to throw if appropriate.
288 * XXX - we return success (0), if the offset is positive and right
289 * after the end of the tvbuff (i.e., equal to the length). We do this
290 * so that a dissector constructing a subset tvbuff for the next protocol
291 * will get a zero-length tvbuff, not an exception, if there's no data
292 * left for the next protocol - we want the next protocol to be the one
293 * that gets an exception, so the error is reported as an error in that
294 * protocol rather than the containing protocol. */
296 check_offset_length_no_exception(const tvbuff_t *tvb,
297 const gint offset, gint const length_val,
298 guint *offset_ptr, guint *length_ptr)
303 DISSECTOR_ASSERT(offset_ptr);
304 DISSECTOR_ASSERT(length_ptr);
306 /* Compute the offset */
307 exception = compute_offset(tvb, offset, offset_ptr);
311 if (length_val < -1) {
312 /* XXX - ReportedBoundsError? */
316 /* Compute the length */
317 if (length_val == -1)
318 *length_ptr = tvb->length - *offset_ptr;
320 *length_ptr = length_val;
323 * Compute the offset of the first byte past the length.
325 end_offset = *offset_ptr + *length_ptr;
328 * Check for an overflow
330 if (end_offset < *offset_ptr)
333 return validate_offset(tvb, end_offset);
336 /* Checks (+/-) offset and length and throws an exception if
337 * either is out of bounds. Sets integer ptrs to the new offset
340 check_offset_length(const tvbuff_t *tvb,
341 const gint offset, gint const length_val,
342 guint *offset_ptr, guint *length_ptr)
346 exception = check_offset_length_no_exception(tvb, offset, length_val, offset_ptr, length_ptr);
352 tvb_check_offset_length(const tvbuff_t *tvb,
353 const gint offset, gint const length_val,
354 guint *offset_ptr, guint *length_ptr)
356 check_offset_length(tvb, offset, length_val, offset_ptr, length_ptr);
359 static const unsigned char left_aligned_bitmask[] = {
371 tvb_new_octet_aligned(tvbuff_t *tvb, guint32 bit_offset, gint32 no_of_bits)
373 tvbuff_t *sub_tvb = NULL;
376 guint8 left, right, remaining_bits, *buf;
379 DISSECTOR_ASSERT(tvb && tvb->initialized);
381 byte_offset = bit_offset >> 3;
382 left = bit_offset % 8; /* for left-shifting */
383 right = 8 - left; /* for right-shifting */
385 if (no_of_bits == -1) {
386 datalen = _tvb_captured_length_remaining(tvb, byte_offset);
389 datalen = no_of_bits >> 3;
390 remaining_bits = no_of_bits % 8;
391 if (remaining_bits) {
396 /* already aligned -> shortcut */
397 if ((left == 0) && (remaining_bits == 0)) {
398 return tvb_new_subset_length_caplen(tvb, byte_offset, datalen, datalen);
401 DISSECTOR_ASSERT(datalen>0);
403 /* if at least one trailing byte is available, we must use the content
404 * of that byte for the last shift (i.e. tvb_get_ptr() must use datalen + 1
405 * if non extra byte is available, the last shifted byte requires
408 if (_tvb_captured_length_remaining(tvb, byte_offset) > datalen) {
409 data = ensure_contiguous(tvb, byte_offset, datalen + 1); /* tvb_get_ptr */
411 /* Do this allocation AFTER tvb_get_ptr() (which could throw an exception) */
412 buf = (guint8 *)g_malloc(datalen);
414 /* shift tvb data bit_offset bits to the left */
415 for (i = 0; i < datalen; i++)
416 buf[i] = (data[i] << left) | (data[i+1] >> right);
418 data = ensure_contiguous(tvb, byte_offset, datalen); /* tvb_get_ptr() */
420 /* Do this allocation AFTER tvb_get_ptr() (which could throw an exception) */
421 buf = (guint8 *)g_malloc(datalen);
423 /* shift tvb data bit_offset bits to the left */
424 for (i = 0; i < (datalen-1); i++)
425 buf[i] = (data[i] << left) | (data[i+1] >> right);
426 buf[datalen-1] = data[datalen-1] << left; /* set last octet */
428 buf[datalen-1] &= left_aligned_bitmask[remaining_bits];
430 sub_tvb = tvb_new_child_real_data(tvb, buf, datalen, datalen);
431 tvb_set_free_cb(sub_tvb, g_free);
437 tvb_generic_clone_offset_len(tvbuff_t *tvb, guint offset, guint len)
439 tvbuff_t *cloned_tvb;
442 DISSECTOR_ASSERT(tvb_bytes_exist(tvb, offset, len));
444 data = (guint8 *) g_malloc(len);
446 tvb_memcpy(tvb, data, offset, len);
448 cloned_tvb = tvb_new_real_data(data, len, len);
449 tvb_set_free_cb(cloned_tvb, g_free);
455 tvb_clone_offset_len(tvbuff_t *tvb, guint offset, guint len)
457 if (tvb->ops->tvb_clone) {
458 tvbuff_t *cloned_tvb;
460 cloned_tvb = tvb->ops->tvb_clone(tvb, offset, len);
465 return tvb_generic_clone_offset_len(tvb, offset, len);
469 tvb_clone(tvbuff_t *tvb)
471 return tvb_clone_offset_len(tvb, 0, tvb->length);
475 tvb_captured_length(const tvbuff_t *tvb)
477 DISSECTOR_ASSERT(tvb && tvb->initialized);
482 /* For tvbuff internal use */
484 _tvb_captured_length_remaining(const tvbuff_t *tvb, const gint offset)
486 guint abs_offset = 0, rem_length;
489 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &rem_length);
497 tvb_captured_length_remaining(const tvbuff_t *tvb, const gint offset)
499 guint abs_offset = 0, rem_length;
502 DISSECTOR_ASSERT(tvb && tvb->initialized);
504 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &rem_length);
512 tvb_ensure_captured_length_remaining(const tvbuff_t *tvb, const gint offset)
514 guint abs_offset = 0, rem_length = 0;
517 DISSECTOR_ASSERT(tvb && tvb->initialized);
519 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &rem_length);
523 if (rem_length == 0) {
525 * This routine ensures there's at least one byte available.
526 * There aren't any bytes available, so throw the appropriate
529 if (abs_offset < tvb->contained_length) {
531 } else if (abs_offset < tvb->reported_length) {
532 THROW(ContainedBoundsError);
533 } else if (tvb->flags & TVBUFF_FRAGMENT) {
534 THROW(FragmentBoundsError);
536 THROW(ReportedBoundsError);
545 /* Validates that 'length' bytes are available starting from
546 * offset (pos/neg). Does not throw an exception. */
548 tvb_bytes_exist(const tvbuff_t *tvb, const gint offset, const gint length)
550 guint abs_offset = 0, abs_length;
553 DISSECTOR_ASSERT(tvb && tvb->initialized);
556 * Negative lengths are not possible and indicate a bug (e.g. arithmetic
557 * error or an overly large value from packet data).
562 exception = check_offset_length_no_exception(tvb, offset, length, &abs_offset, &abs_length);
569 /* Validates that 'length' bytes, where 'length' is a 64-bit unsigned
570 * integer, are available starting from offset (pos/neg). Throws an
571 * exception if they aren't. */
573 tvb_ensure_bytes_exist64(const tvbuff_t *tvb, const gint offset, const guint64 length)
576 * Make sure the value fits in a signed integer; if not, assume
577 * that means that it's too big.
579 if (length > G_MAXINT) {
580 THROW(ReportedBoundsError);
583 /* OK, now cast it and try it with tvb_ensure_bytes_exist(). */
584 tvb_ensure_bytes_exist(tvb, offset, (gint)length);
587 /* Validates that 'length' bytes are available starting from
588 * offset (pos/neg). Throws an exception if they aren't. */
590 tvb_ensure_bytes_exist(const tvbuff_t *tvb, const gint offset, const gint length)
592 guint real_offset, end_offset;
594 DISSECTOR_ASSERT(tvb && tvb->initialized);
597 * -1 doesn't mean "until end of buffer", as that's pointless
598 * for this routine. We must treat it as a Really Large Positive
599 * Number, so that we throw an exception; we throw
600 * ReportedBoundsError, as if it were past even the end of a
601 * reassembled packet, and past the end of even the data we
604 * We do the same with other negative lengths.
607 THROW(ReportedBoundsError);
610 /* XXX: Below this point could be replaced with a call to
611 * check_offset_length with no functional change, however this is a
612 * *very* hot path and check_offset_length is not well-optimized for
613 * this case, so we eat some code duplication for a lot of speedup. */
616 /* Positive offset - relative to the beginning of the packet. */
617 if (G_LIKELY((guint) offset <= tvb->length)) {
618 real_offset = offset;
619 } else if ((guint) offset <= tvb->contained_length) {
621 } else if ((guint) offset <= tvb->reported_length) {
622 THROW(ContainedBoundsError);
623 } else if (tvb->flags & TVBUFF_FRAGMENT) {
624 THROW(FragmentBoundsError);
626 THROW(ReportedBoundsError);
630 /* Negative offset - relative to the end of the packet. */
631 if (G_LIKELY((guint) -offset <= tvb->length)) {
632 real_offset = tvb->length + offset;
633 } else if ((guint) -offset <= tvb->contained_length) {
635 } else if ((guint) -offset <= tvb->reported_length) {
636 THROW(ContainedBoundsError);
637 } else if (tvb->flags & TVBUFF_FRAGMENT) {
638 THROW(FragmentBoundsError);
640 THROW(ReportedBoundsError);
645 * Compute the offset of the first byte past the length.
647 end_offset = real_offset + length;
650 * Check for an overflow
652 if (end_offset < real_offset)
655 if (G_LIKELY(end_offset <= tvb->length))
657 else if (end_offset <= tvb->contained_length)
659 else if (end_offset <= tvb->reported_length)
660 THROW(ContainedBoundsError);
661 else if (tvb->flags & TVBUFF_FRAGMENT)
662 THROW(FragmentBoundsError);
664 THROW(ReportedBoundsError);
668 tvb_offset_exists(const tvbuff_t *tvb, const gint offset)
670 guint abs_offset = 0;
673 DISSECTOR_ASSERT(tvb && tvb->initialized);
675 exception = compute_offset(tvb, offset, &abs_offset);
679 /* compute_offset only throws an exception on >, not >= because of the
680 * comment above check_offset_length_no_exception, but here we want the
681 * opposite behaviour so we check ourselves... */
682 if (abs_offset < tvb->length) {
691 tvb_reported_length(const tvbuff_t *tvb)
693 DISSECTOR_ASSERT(tvb && tvb->initialized);
695 return tvb->reported_length;
699 tvb_reported_length_remaining(const tvbuff_t *tvb, const gint offset)
701 guint abs_offset = 0;
704 DISSECTOR_ASSERT(tvb && tvb->initialized);
706 exception = compute_offset(tvb, offset, &abs_offset);
710 if (tvb->reported_length >= abs_offset)
711 return tvb->reported_length - abs_offset;
716 /* Set the reported length of a tvbuff to a given value; used for protocols
717 * whose headers contain an explicit length and where the calling
718 * dissector's payload may include padding as well as the packet for
720 * Also adjusts the available and contained length. */
722 tvb_set_reported_length(tvbuff_t *tvb, const guint reported_length)
724 DISSECTOR_ASSERT(tvb && tvb->initialized);
726 if (reported_length > tvb->reported_length)
727 THROW(ReportedBoundsError);
729 tvb->reported_length = reported_length;
730 if (reported_length < tvb->length)
731 tvb->length = reported_length;
732 if (reported_length < tvb->contained_length)
733 tvb->contained_length = reported_length;
737 tvb_offset_from_real_beginning_counter(const tvbuff_t *tvb, const guint counter)
739 if (tvb->ops->tvb_offset)
740 return tvb->ops->tvb_offset(tvb, counter);
742 DISSECTOR_ASSERT_NOT_REACHED();
747 tvb_offset_from_real_beginning(const tvbuff_t *tvb)
749 return tvb_offset_from_real_beginning_counter(tvb, 0);
752 static inline const guint8*
753 ensure_contiguous_no_exception(tvbuff_t *tvb, const gint offset, const gint length, int *pexception)
755 guint abs_offset = 0, abs_length = 0;
758 exception = check_offset_length_no_exception(tvb, offset, length, &abs_offset, &abs_length);
761 *pexception = exception;
766 * Special case: if the caller (e.g. tvb_get_ptr) requested no data,
767 * then it is acceptable to have an empty tvb (!tvb->real_data).
774 * We know that all the data is present in the tvbuff, so
775 * no exceptions should be thrown.
778 return tvb->real_data + abs_offset;
780 if (tvb->ops->tvb_get_ptr)
781 return tvb->ops->tvb_get_ptr(tvb, abs_offset, abs_length);
783 DISSECTOR_ASSERT_NOT_REACHED();
787 static inline const guint8*
788 ensure_contiguous(tvbuff_t *tvb, const gint offset, const gint length)
793 p = ensure_contiguous_no_exception(tvb, offset, length, &exception);
794 if (p == NULL && length != 0) {
795 DISSECTOR_ASSERT(exception > 0);
801 static inline const guint8*
802 fast_ensure_contiguous(tvbuff_t *tvb, const gint offset, const guint length)
807 DISSECTOR_ASSERT(tvb && tvb->initialized);
808 /* We don't check for overflow in this fast path so we only handle simple types */
809 DISSECTOR_ASSERT(length <= 8);
811 if (offset < 0 || !tvb->real_data) {
812 return ensure_contiguous(tvb, offset, length);
816 end_offset = u_offset + length;
818 if (G_LIKELY(end_offset <= tvb->length)) {
819 return tvb->real_data + u_offset;
820 } else if (end_offset <= tvb->contained_length) {
822 } else if (end_offset <= tvb->reported_length) {
823 THROW(ContainedBoundsError);
824 } else if (tvb->flags & TVBUFF_FRAGMENT) {
825 THROW(FragmentBoundsError);
827 THROW(ReportedBoundsError);
835 /************** ACCESSORS **************/
838 tvb_memcpy(tvbuff_t *tvb, void *target, const gint offset, size_t length)
840 guint abs_offset = 0, abs_length = 0;
842 DISSECTOR_ASSERT(tvb && tvb->initialized);
845 * XXX - we should eliminate the "length = -1 means 'to the end
846 * of the tvbuff'" convention, and use other means to achieve
847 * that; this would let us eliminate a bunch of checks for
848 * negative lengths in cases where the protocol has a 32-bit
851 * Allowing -1 but throwing an assertion on other negative
852 * lengths is a bit more work with the length being a size_t;
853 * instead, we check for a length <= 2^31-1.
855 DISSECTOR_ASSERT(length <= 0x7FFFFFFF);
856 check_offset_length(tvb, offset, (gint) length, &abs_offset, &abs_length);
858 if (tvb->real_data) {
859 return memcpy(target, tvb->real_data + abs_offset, abs_length);
862 if (tvb->ops->tvb_memcpy)
863 return tvb->ops->tvb_memcpy(tvb, target, abs_offset, abs_length);
866 * If the length is 0, there's nothing to do.
867 * (tvb->real_data could be null if it's allocated with
872 * XXX, fallback to slower method
874 DISSECTOR_ASSERT_NOT_REACHED();
881 * XXX - this doesn't treat a length of -1 as an error.
882 * If it did, this could replace some code that calls
883 * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies
886 * "composite_get_ptr()" depends on -1 not being
887 * an error; does anything else depend on this routine treating -1 as
888 * meaning "to the end of the buffer"?
890 * If scope is NULL, memory is allocated with g_malloc() and user must
891 * explicitly free it with g_free().
892 * If scope is not NULL, memory is allocated with the corresponding pool
896 tvb_memdup(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, size_t length)
898 guint abs_offset = 0, abs_length = 0;
901 DISSECTOR_ASSERT(tvb && tvb->initialized);
903 check_offset_length(tvb, offset, (gint) length, &abs_offset, &abs_length);
905 duped = wmem_alloc(scope, abs_length);
906 return tvb_memcpy(tvb, duped, abs_offset, abs_length);
912 tvb_get_ptr(tvbuff_t *tvb, const gint offset, const gint length)
914 return ensure_contiguous(tvb, offset, length);
917 /* ---------------- */
919 tvb_get_guint8(tvbuff_t *tvb, const gint offset)
923 ptr = fast_ensure_contiguous(tvb, offset, 1);
928 tvb_get_gint8(tvbuff_t *tvb, const gint offset)
932 ptr = fast_ensure_contiguous(tvb, offset, 1);
937 tvb_get_ntohs(tvbuff_t *tvb, const gint offset)
941 ptr = fast_ensure_contiguous(tvb, offset, 2);
946 tvb_get_ntohis(tvbuff_t *tvb, const gint offset)
950 ptr = fast_ensure_contiguous(tvb, offset, 2);
955 tvb_get_ntoh24(tvbuff_t *tvb, const gint offset)
959 ptr = fast_ensure_contiguous(tvb, offset, 3);
964 tvb_get_ntohi24(tvbuff_t *tvb, const gint offset)
968 ret = ws_sign_ext32(tvb_get_ntoh24(tvb, offset), 24);
974 tvb_get_ntohl(tvbuff_t *tvb, const gint offset)
978 ptr = fast_ensure_contiguous(tvb, offset, 4);
983 tvb_get_ntohil(tvbuff_t *tvb, const gint offset)
987 ptr = fast_ensure_contiguous(tvb, offset, 4);
992 tvb_get_ntoh40(tvbuff_t *tvb, const gint offset)
996 ptr = fast_ensure_contiguous(tvb, offset, 5);
1001 tvb_get_ntohi40(tvbuff_t *tvb, const gint offset)
1005 ret = ws_sign_ext64(tvb_get_ntoh40(tvb, offset), 40);
1011 tvb_get_ntoh48(tvbuff_t *tvb, const gint offset)
1015 ptr = fast_ensure_contiguous(tvb, offset, 6);
1016 return pntoh48(ptr);
1020 tvb_get_ntohi48(tvbuff_t *tvb, const gint offset)
1024 ret = ws_sign_ext64(tvb_get_ntoh48(tvb, offset), 48);
1030 tvb_get_ntoh56(tvbuff_t *tvb, const gint offset)
1034 ptr = fast_ensure_contiguous(tvb, offset, 7);
1035 return pntoh56(ptr);
1039 tvb_get_ntohi56(tvbuff_t *tvb, const gint offset)
1043 ret = ws_sign_ext64(tvb_get_ntoh56(tvb, offset), 56);
1049 tvb_get_ntoh64(tvbuff_t *tvb, const gint offset)
1053 ptr = fast_ensure_contiguous(tvb, offset, 8);
1054 return pntoh64(ptr);
1058 tvb_get_ntohi64(tvbuff_t *tvb, const gint offset)
1062 ptr = fast_ensure_contiguous(tvb, offset, 8);
1063 return pntoh64(ptr);
1067 tvb_get_guint16(tvbuff_t *tvb, const gint offset, const guint encoding) {
1068 if (encoding & ENC_LITTLE_ENDIAN) {
1069 return tvb_get_letohs(tvb, offset);
1071 return tvb_get_ntohs(tvb, offset);
1076 tvb_get_gint16(tvbuff_t *tvb, const gint offset, const guint encoding) {
1077 if (encoding & ENC_LITTLE_ENDIAN) {
1078 return tvb_get_letohis(tvb, offset);
1080 return tvb_get_ntohis(tvb, offset);
1085 tvb_get_guint24(tvbuff_t *tvb, const gint offset, const guint encoding) {
1086 if (encoding & ENC_LITTLE_ENDIAN) {
1087 return tvb_get_letoh24(tvb, offset);
1089 return tvb_get_ntoh24(tvb, offset);
1094 tvb_get_gint24(tvbuff_t *tvb, const gint offset, const guint encoding) {
1095 if (encoding & ENC_LITTLE_ENDIAN) {
1096 return tvb_get_letohi24(tvb, offset);
1098 return tvb_get_ntohi24(tvb, offset);
1103 tvb_get_guint32(tvbuff_t *tvb, const gint offset, const guint encoding) {
1104 if (encoding & ENC_LITTLE_ENDIAN) {
1105 return tvb_get_letohl(tvb, offset);
1107 return tvb_get_ntohl(tvb, offset);
1112 tvb_get_gint32(tvbuff_t *tvb, const gint offset, const guint encoding) {
1113 if (encoding & ENC_LITTLE_ENDIAN) {
1114 return tvb_get_letohil(tvb, offset);
1116 return tvb_get_ntohil(tvb, offset);
1121 tvb_get_guint40(tvbuff_t *tvb, const gint offset, const guint encoding) {
1122 if (encoding & ENC_LITTLE_ENDIAN) {
1123 return tvb_get_letoh40(tvb, offset);
1125 return tvb_get_ntoh40(tvb, offset);
1130 tvb_get_gint40(tvbuff_t *tvb, const gint offset, const guint encoding) {
1131 if (encoding & ENC_LITTLE_ENDIAN) {
1132 return tvb_get_letohi40(tvb, offset);
1134 return tvb_get_ntohi40(tvb, offset);
1139 tvb_get_guint48(tvbuff_t *tvb, const gint offset, const guint encoding) {
1140 if (encoding & ENC_LITTLE_ENDIAN) {
1141 return tvb_get_letoh48(tvb, offset);
1143 return tvb_get_ntoh48(tvb, offset);
1148 tvb_get_gint48(tvbuff_t *tvb, const gint offset, const guint encoding) {
1149 if (encoding & ENC_LITTLE_ENDIAN) {
1150 return tvb_get_letohi48(tvb, offset);
1152 return tvb_get_ntohi48(tvb, offset);
1157 tvb_get_guint56(tvbuff_t *tvb, const gint offset, const guint encoding) {
1158 if (encoding & ENC_LITTLE_ENDIAN) {
1159 return tvb_get_letoh56(tvb, offset);
1161 return tvb_get_ntoh56(tvb, offset);
1166 tvb_get_gint56(tvbuff_t *tvb, const gint offset, const guint encoding) {
1167 if (encoding & ENC_LITTLE_ENDIAN) {
1168 return tvb_get_letohi56(tvb, offset);
1170 return tvb_get_ntohi56(tvb, offset);
1175 tvb_get_guint64(tvbuff_t *tvb, const gint offset, const guint encoding) {
1176 if (encoding & ENC_LITTLE_ENDIAN) {
1177 return tvb_get_letoh64(tvb, offset);
1179 return tvb_get_ntoh64(tvb, offset);
1184 tvb_get_gint64(tvbuff_t *tvb, const gint offset, const guint encoding) {
1185 if (encoding & ENC_LITTLE_ENDIAN) {
1186 return tvb_get_letohi64(tvb, offset);
1188 return tvb_get_ntohi64(tvb, offset);
1193 tvb_get_ieee_float(tvbuff_t *tvb, const gint offset, const guint encoding) {
1194 if (encoding & ENC_LITTLE_ENDIAN) {
1195 return tvb_get_letohieee_float(tvb, offset);
1197 return tvb_get_ntohieee_float(tvb, offset);
1202 tvb_get_ieee_double(tvbuff_t *tvb, const gint offset, const guint encoding) {
1203 if (encoding & ENC_LITTLE_ENDIAN) {
1204 return tvb_get_letohieee_double(tvb, offset);
1206 return tvb_get_ntohieee_double(tvb, offset);
1211 * Stuff for IEEE float handling on platforms that don't have IEEE
1212 * format as the native floating-point format.
1214 * For now, we treat only the VAX as such a platform.
1216 * XXX - other non-IEEE boxes that can run UN*X include some Crays,
1217 * and possibly other machines. However, I don't know whether there
1218 * are any other machines that could run Wireshark and that don't use
1219 * IEEE format. As far as I know, all of the main current and past
1220 * commercial microprocessor families on which OSes that support
1221 * Wireshark can run use IEEE format (x86, ARM, 68k, SPARC, MIPS,
1222 * PA-RISC, Alpha, IA-64, and so on), and it appears that the official
1223 * Linux port to System/390 and zArchitecture uses IEEE format floating-
1224 * point rather than IBM hex floating-point (not a huge surprise), so
1225 * I'm not sure that leaves any 32-bit or larger UN*X or Windows boxes,
1226 * other than VAXes, that don't use IEEE format. If you're not running
1227 * UN*X or Windows, the floating-point format is probably going to be
1228 * the least of your problems in a port.
1238 #define IEEE_SP_NUMBER_WIDTH 32 /* bits in number */
1239 #define IEEE_SP_EXP_WIDTH 8 /* bits in exponent */
1240 #define IEEE_SP_MANTISSA_WIDTH 23 /* IEEE_SP_NUMBER_WIDTH - 1 - IEEE_SP_EXP_WIDTH */
1242 #define IEEE_SP_SIGN_MASK 0x80000000
1243 #define IEEE_SP_EXPONENT_MASK 0x7F800000
1244 #define IEEE_SP_MANTISSA_MASK 0x007FFFFF
1245 #define IEEE_SP_INFINITY IEEE_SP_EXPONENT_MASK
1247 #define IEEE_SP_IMPLIED_BIT (1 << IEEE_SP_MANTISSA_WIDTH)
1248 #define IEEE_SP_INFINITE ((1 << IEEE_SP_EXP_WIDTH) - 1)
1249 #define IEEE_SP_BIAS ((1 << (IEEE_SP_EXP_WIDTH - 1)) - 1)
1252 ieee_float_is_zero(const guint32 w)
1254 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1258 get_ieee_float(const guint32 w)
1264 sign = w & IEEE_SP_SIGN_MASK;
1265 exponent = w & IEEE_SP_EXPONENT_MASK;
1266 mantissa = w & IEEE_SP_MANTISSA_MASK;
1268 if (ieee_float_is_zero(w)) {
1269 /* number is zero, unnormalized, or not-a-number */
1274 * XXX - how to handle this?
1276 if (IEEE_SP_INFINITY == exponent) {
1278 * number is positive or negative infinity, or a special value
1280 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1284 exponent = ((exponent >> IEEE_SP_MANTISSA_WIDTH) - IEEE_SP_BIAS) -
1285 IEEE_SP_MANTISSA_WIDTH;
1286 mantissa |= IEEE_SP_IMPLIED_BIT;
1289 return -mantissa * pow(2, exponent);
1291 return mantissa * pow(2, exponent);
1296 * We assume that if you don't have IEEE floating-point, you have a
1297 * compiler that understands 64-bit integral quantities.
1299 #define IEEE_DP_NUMBER_WIDTH 64 /* bits in number */
1300 #define IEEE_DP_EXP_WIDTH 11 /* bits in exponent */
1301 #define IEEE_DP_MANTISSA_WIDTH 52 /* IEEE_DP_NUMBER_WIDTH - 1 - IEEE_DP_EXP_WIDTH */
1303 #define IEEE_DP_SIGN_MASK G_GINT64_CONSTANT(0x8000000000000000)
1304 #define IEEE_DP_EXPONENT_MASK G_GINT64_CONSTANT(0x7FF0000000000000)
1305 #define IEEE_DP_MANTISSA_MASK G_GINT64_CONSTANT(0x000FFFFFFFFFFFFF)
1306 #define IEEE_DP_INFINITY IEEE_DP_EXPONENT_MASK
1308 #define IEEE_DP_IMPLIED_BIT (G_GINT64_CONSTANT(1) << IEEE_DP_MANTISSA_WIDTH)
1309 #define IEEE_DP_INFINITE ((1 << IEEE_DP_EXP_WIDTH) - 1)
1310 #define IEEE_DP_BIAS ((1 << (IEEE_DP_EXP_WIDTH - 1)) - 1)
1313 ieee_double_is_zero(const guint64 w)
1315 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1319 get_ieee_double(const guint64 w)
1325 sign = w & IEEE_DP_SIGN_MASK;
1326 exponent = w & IEEE_DP_EXPONENT_MASK;
1327 mantissa = w & IEEE_DP_MANTISSA_MASK;
1329 if (ieee_double_is_zero(w)) {
1330 /* number is zero, unnormalized, or not-a-number */
1335 * XXX - how to handle this?
1337 if (IEEE_DP_INFINITY == exponent) {
1339 * number is positive or negative infinity, or a special value
1341 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1345 exponent = ((exponent >> IEEE_DP_MANTISSA_WIDTH) - IEEE_DP_BIAS) -
1346 IEEE_DP_MANTISSA_WIDTH;
1347 mantissa |= IEEE_DP_IMPLIED_BIT;
1350 return -mantissa * pow(2, exponent);
1352 return mantissa * pow(2, exponent);
1357 * Fetches an IEEE single-precision floating-point number, in
1358 * big-endian form, and returns a "float".
1360 * XXX - should this be "double", in case there are IEEE single-
1361 * precision numbers that won't fit in some platform's native
1365 tvb_get_ntohieee_float(tvbuff_t *tvb, const int offset)
1368 return get_ieee_float(tvb_get_ntohl(tvb, offset));
1375 ieee_fp_union.w = tvb_get_ntohl(tvb, offset);
1376 return ieee_fp_union.f;
1381 * Fetches an IEEE double-precision floating-point number, in
1382 * big-endian form, and returns a "double".
1385 tvb_get_ntohieee_double(tvbuff_t *tvb, const int offset)
1399 #if G_BYTE_ORDER == G_BIG_ENDIAN
1400 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset);
1401 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset+4);
1403 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset+4);
1404 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset);
1407 return get_ieee_double(ieee_fp_union.dw);
1409 return ieee_fp_union.d;
1414 tvb_get_letohs(tvbuff_t *tvb, const gint offset)
1418 ptr = fast_ensure_contiguous(tvb, offset, 2);
1419 return pletoh16(ptr);
1423 tvb_get_letohis(tvbuff_t *tvb, const gint offset)
1427 ptr = fast_ensure_contiguous(tvb, offset, 2);
1428 return pletoh16(ptr);
1432 tvb_get_letoh24(tvbuff_t *tvb, const gint offset)
1436 ptr = fast_ensure_contiguous(tvb, offset, 3);
1437 return pletoh24(ptr);
1441 tvb_get_letohi24(tvbuff_t *tvb, const gint offset)
1445 ret = ws_sign_ext32(tvb_get_letoh24(tvb, offset), 24);
1451 tvb_get_letohl(tvbuff_t *tvb, const gint offset)
1455 ptr = fast_ensure_contiguous(tvb, offset, 4);
1456 return pletoh32(ptr);
1460 tvb_get_letohil(tvbuff_t *tvb, const gint offset)
1464 ptr = fast_ensure_contiguous(tvb, offset, 4);
1465 return pletoh32(ptr);
1469 tvb_get_letoh40(tvbuff_t *tvb, const gint offset)
1473 ptr = fast_ensure_contiguous(tvb, offset, 5);
1474 return pletoh40(ptr);
1478 tvb_get_letohi40(tvbuff_t *tvb, const gint offset)
1482 ret = ws_sign_ext64(tvb_get_letoh40(tvb, offset), 40);
1488 tvb_get_letoh48(tvbuff_t *tvb, const gint offset)
1492 ptr = fast_ensure_contiguous(tvb, offset, 6);
1493 return pletoh48(ptr);
1497 tvb_get_letohi48(tvbuff_t *tvb, const gint offset)
1501 ret = ws_sign_ext64(tvb_get_letoh48(tvb, offset), 48);
1507 tvb_get_letoh56(tvbuff_t *tvb, const gint offset)
1511 ptr = fast_ensure_contiguous(tvb, offset, 7);
1512 return pletoh56(ptr);
1516 tvb_get_letohi56(tvbuff_t *tvb, const gint offset)
1520 ret = ws_sign_ext64(tvb_get_letoh56(tvb, offset), 56);
1526 tvb_get_letoh64(tvbuff_t *tvb, const gint offset)
1530 ptr = fast_ensure_contiguous(tvb, offset, 8);
1531 return pletoh64(ptr);
1535 tvb_get_letohi64(tvbuff_t *tvb, const gint offset)
1539 ptr = fast_ensure_contiguous(tvb, offset, 8);
1540 return pletoh64(ptr);
1544 * Fetches an IEEE single-precision floating-point number, in
1545 * little-endian form, and returns a "float".
1547 * XXX - should this be "double", in case there are IEEE single-
1548 * precision numbers that won't fit in some platform's native
1552 tvb_get_letohieee_float(tvbuff_t *tvb, const int offset)
1555 return get_ieee_float(tvb_get_letohl(tvb, offset));
1562 ieee_fp_union.w = tvb_get_letohl(tvb, offset);
1563 return ieee_fp_union.f;
1568 * Fetches an IEEE double-precision floating-point number, in
1569 * little-endian form, and returns a "double".
1572 tvb_get_letohieee_double(tvbuff_t *tvb, const int offset)
1586 #if G_BYTE_ORDER == G_BIG_ENDIAN
1587 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset+4);
1588 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset);
1590 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset);
1591 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset+4);
1594 return get_ieee_double(ieee_fp_union.dw);
1596 return ieee_fp_union.d;
1601 validate_single_byte_ascii_encoding(const guint encoding)
1603 const guint enc = encoding & ~ENC_STR_MASK;
1609 case ENC_3GPP_TS_23_038_7BITS:
1611 REPORT_DISSECTOR_BUG("Invalid string encoding type passed to tvb_get_string_XXX");
1616 /* make sure something valid was set */
1618 REPORT_DISSECTOR_BUG("No string encoding type passed to tvb_get_string_XXX");
1622 tvb_get_string_bytes(tvbuff_t *tvb, const gint offset, const gint length,
1623 const guint encoding, GByteArray *bytes, gint *endoff)
1625 const gchar *ptr = (gchar*) tvb_get_raw_string(wmem_packet_scope(), tvb, offset, length);
1626 const gchar *begin = ptr;
1627 const gchar *end = NULL;
1628 GByteArray *retval = NULL;
1632 validate_single_byte_ascii_encoding(encoding);
1634 if (endoff) *endoff = 0;
1636 while (*begin == ' ') begin++;
1638 if (*begin && bytes) {
1639 if (hex_str_to_bytes_encoding(begin, bytes, &end, encoding, FALSE)) {
1640 if (bytes->len > 0) {
1641 if (endoff) *endoff = offset + (gint)(end - ptr);
1651 /* support hex-encoded time values? */
1653 tvb_get_string_time(tvbuff_t *tvb, const gint offset, const gint length,
1654 const guint encoding, nstime_t *ns, gint *endoff)
1656 const gchar *begin = (gchar*) tvb_get_raw_string(wmem_packet_scope(), tvb, offset, length);
1657 const gchar *ptr = begin;
1658 const gchar *end = NULL;
1660 nstime_t* retval = NULL;
1665 gboolean matched = FALSE;
1669 validate_single_byte_ascii_encoding(encoding);
1671 DISSECTOR_ASSERT(ns);
1673 memset(&tm, 0, sizeof(tm));
1678 while (*ptr == ' ') ptr++;
1681 /* note: sscanf is known to be inconsistent across platforms with respect
1682 to whether a %n is counted as a return value or not, so we have to use
1684 if ((encoding & ENC_ISO_8601_DATE_TIME) == ENC_ISO_8601_DATE_TIME) {
1685 /* TODO: using sscanf this many times is probably slow; might want
1686 to parse it by hand in the future */
1687 /* 2014-04-07T05:41:56+00:00 */
1688 if (sscanf(ptr, "%d-%d-%d%*c%d:%d:%d%c%d:%d%n",
1702 /* no seconds is ok */
1703 else if (sscanf(ptr, "%d-%d-%d%*c%d:%d%c%d:%d%n",
1716 /* 2007-04-05T14:30:56Z */
1717 else if (sscanf(ptr, "%d-%d-%d%*c%d:%d:%dZ%n",
1730 /* 2007-04-05T14:30Z no seconds is ok */
1731 else if (sscanf(ptr, "%d-%d-%d%*c%d:%dZ%n",
1746 end = ptr + num_chars;
1748 if (tm.tm_year > 1900) tm.tm_year -= 1900;
1749 if (sign == '-') off_hr = -off_hr;
1752 else if (encoding & ENC_ISO_8601_DATE) {
1754 if (sscanf(ptr, "%d-%d-%d%n",
1761 end = ptr + num_chars;
1763 if (tm.tm_year > 1900) tm.tm_year -= 1900;
1766 else if (encoding & ENC_ISO_8601_TIME) {
1768 if (sscanf(ptr, "%d:%d:%d%n",
1774 /* what should we do about day/month/year? */
1775 /* setting it to "now" for now */
1776 time_t time_now = time(NULL);
1777 struct tm *tm_now = gmtime(&time_now);
1778 if (tm_now != NULL) {
1779 tm.tm_year = tm_now->tm_year;
1780 tm.tm_mon = tm_now->tm_mon;
1781 tm.tm_mday = tm_now->tm_mday;
1783 /* The second before the Epoch */
1788 end = ptr + num_chars;
1793 else if (encoding & ENC_RFC_822 || encoding & ENC_RFC_1123) {
1794 if (encoding & ENC_RFC_822) {
1795 /* this will unfortunately match ENC_RFC_1123 style
1796 strings too, partially - probably need to do this the long way */
1797 end = strptime(ptr, "%a, %d %b %y %H:%M:%S", &tm);
1798 if (!end) end = strptime(ptr, "%a, %d %b %y %H:%M", &tm);
1799 if (!end) end = strptime(ptr, "%d %b %y %H:%M:%S", &tm);
1800 if (!end) end = strptime(ptr, "%d %b %y %H:%M", &tm);
1802 else if (encoding & ENC_RFC_1123) {
1803 end = strptime(ptr, "%a, %d %b %Y %H:%M:%S", &tm);
1804 if (!end) end = strptime(ptr, "%a, %d %b %Y %H:%M", &tm);
1805 if (!end) end = strptime(ptr, "%d %b %Y %H:%M:%S", &tm);
1806 if (!end) end = strptime(ptr, "%d %b %Y %H:%M", &tm);
1810 if (*end == ' ') end++;
1811 if (g_ascii_strncasecmp(end, "UT", 2) == 0)
1815 else if (g_ascii_strncasecmp(end, "GMT", 3) == 0)
1819 else if (sscanf(end, "%c%2d%2d%n",
1827 if (sign == '-') off_hr = -off_hr;
1833 ns->secs = mktime_utc (&tm);
1835 ns->secs += (off_hr * 3600) + (off_min * 60);
1836 else if (off_hr < 0)
1837 ns->secs -= ((-off_hr) * 3600) + (off_min * 60);
1840 *endoff = (gint)(offset + (end - begin));
1846 /* Fetch an IPv4 address, in network byte order.
1847 * We do *not* convert them to host byte order; we leave them in
1848 * network byte order. */
1850 tvb_get_ipv4(tvbuff_t *tvb, const gint offset)
1855 ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1856 memcpy(&addr, ptr, sizeof addr);
1860 /* Fetch an IPv6 address. */
1862 tvb_get_ipv6(tvbuff_t *tvb, const gint offset, ws_in6_addr *addr)
1866 ptr = ensure_contiguous(tvb, offset, sizeof(*addr));
1867 memcpy(addr, ptr, sizeof *addr);
1872 tvb_get_ntohguid(tvbuff_t *tvb, const gint offset, e_guid_t *guid)
1874 const guint8 *ptr = ensure_contiguous(tvb, offset, GUID_LEN);
1876 guid->data1 = pntoh32(ptr + 0);
1877 guid->data2 = pntoh16(ptr + 4);
1878 guid->data3 = pntoh16(ptr + 6);
1879 memcpy(guid->data4, ptr + 8, sizeof guid->data4);
1883 tvb_get_letohguid(tvbuff_t *tvb, const gint offset, e_guid_t *guid)
1885 const guint8 *ptr = ensure_contiguous(tvb, offset, GUID_LEN);
1887 guid->data1 = pletoh32(ptr + 0);
1888 guid->data2 = pletoh16(ptr + 4);
1889 guid->data3 = pletoh16(ptr + 6);
1890 memcpy(guid->data4, ptr + 8, sizeof guid->data4);
1894 * NOTE: to support code written when proto_tree_add_item() took a
1895 * gboolean as its last argument, with FALSE meaning "big-endian"
1896 * and TRUE meaning "little-endian", we treat any non-zero value of
1897 * "encoding" as meaning "little-endian".
1900 tvb_get_guid(tvbuff_t *tvb, const gint offset, e_guid_t *guid, const guint encoding)
1903 tvb_get_letohguid(tvb, offset, guid);
1905 tvb_get_ntohguid(tvb, offset, guid);
1909 static const guint8 bit_mask8[] = {
1921 /* Get 1 - 8 bits */
1923 tvb_get_bits8(tvbuff_t *tvb, guint bit_offset, const gint no_of_bits)
1925 return (guint8)_tvb_get_bits64(tvb, bit_offset, no_of_bits);
1928 /* Get 9 - 16 bits */
1930 tvb_get_bits16(tvbuff_t *tvb, guint bit_offset, const gint no_of_bits,const guint encoding _U_)
1932 /* note that encoding has no meaning here, as the tvb is considered to contain an octet array */
1933 return (guint16)_tvb_get_bits64(tvb, bit_offset, no_of_bits);
1936 /* Get 1 - 32 bits */
1938 tvb_get_bits32(tvbuff_t *tvb, guint bit_offset, const gint no_of_bits, const guint encoding _U_)
1940 /* note that encoding has no meaning here, as the tvb is considered to contain an octet array */
1941 return (guint32)_tvb_get_bits64(tvb, bit_offset, no_of_bits);
1944 /* Get 1 - 64 bits */
1946 tvb_get_bits64(tvbuff_t *tvb, guint bit_offset, const gint no_of_bits, const guint encoding _U_)
1948 /* note that encoding has no meaning here, as the tvb is considered to contain an octet array */
1949 return _tvb_get_bits64(tvb, bit_offset, no_of_bits);
1952 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
1953 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
1954 * Offset should be given in bits from the start of the tvb.
1955 * The function tolerates requests for more than 64 bits, but will only return the least significant 64 bits.
1958 _tvb_get_bits64(tvbuff_t *tvb, guint bit_offset, const gint total_no_of_bits)
1961 guint octet_offset = bit_offset >> 3;
1962 guint8 required_bits_in_first_octet = 8 - (bit_offset % 8);
1964 if(required_bits_in_first_octet > total_no_of_bits)
1966 /* the required bits don't extend to the end of the first octet */
1967 guint8 right_shift = required_bits_in_first_octet - total_no_of_bits;
1968 value = (tvb_get_guint8(tvb, octet_offset) >> right_shift) & bit_mask8[total_no_of_bits % 8];
1972 guint8 remaining_bit_length = total_no_of_bits;
1974 /* get the bits up to the first octet boundary */
1976 required_bits_in_first_octet %= 8;
1977 if(required_bits_in_first_octet != 0)
1979 value = tvb_get_guint8(tvb, octet_offset) & bit_mask8[required_bits_in_first_octet];
1980 remaining_bit_length -= required_bits_in_first_octet;
1983 /* take the biggest words, shorts or octets that we can */
1984 while (remaining_bit_length > 7)
1986 switch (remaining_bit_length >> 4)
1989 /* 8 - 15 bits. (note that 0 - 7 would have dropped out of the while() loop) */
1991 value += tvb_get_guint8(tvb, octet_offset);
1992 remaining_bit_length -= 8;
1999 value += tvb_get_ntohs(tvb, octet_offset);
2000 remaining_bit_length -= 16;
2008 value += tvb_get_ntohl(tvb, octet_offset);
2009 remaining_bit_length -= 32;
2014 /* 64 bits (or more???) */
2015 value = tvb_get_ntoh64(tvb, octet_offset);
2016 remaining_bit_length -= 64;
2021 /* get bits from any partial octet at the tail */
2022 if(remaining_bit_length)
2024 value <<= remaining_bit_length;
2025 value += (tvb_get_guint8(tvb, octet_offset) >> (8 - remaining_bit_length));
2030 /* Get 1 - 32 bits (should be deprecated as same as tvb_get_bits32??) */
2032 tvb_get_bits(tvbuff_t *tvb, const guint bit_offset, const gint no_of_bits, const guint encoding _U_)
2034 /* note that encoding has no meaning here, as the tvb is considered to contain an octet array */
2035 return (guint32)_tvb_get_bits64(tvb, bit_offset, no_of_bits);
2039 tvb_find_guint8_generic(tvbuff_t *tvb, guint abs_offset, guint limit, guint8 needle)
2042 const guint8 *result;
2044 ptr = ensure_contiguous(tvb, abs_offset, limit); /* tvb_get_ptr() */
2046 result = (const guint8 *) memchr(ptr, needle, limit);
2050 return (gint) ((result - ptr) + abs_offset);
2053 /* Find first occurrence of needle in tvbuff, starting at offset. Searches
2054 * at most maxlength number of bytes; if maxlength is -1, searches to
2056 * Returns the offset of the found needle, or -1 if not found.
2057 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
2058 * in that case, -1 will be returned if the boundary is reached before
2059 * finding needle. */
2061 tvb_find_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength, const guint8 needle)
2063 const guint8 *result;
2064 guint abs_offset = 0;
2068 DISSECTOR_ASSERT(tvb && tvb->initialized);
2070 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &limit);
2074 /* Only search to end of tvbuff, w/o throwing exception. */
2075 if (maxlength >= 0 && limit > (guint) maxlength) {
2076 /* Maximum length doesn't go past end of tvbuff; search
2078 limit = (guint) maxlength;
2081 /* If we have real data, perform our search now. */
2082 if (tvb->real_data) {
2083 result = (const guint8 *)memchr(tvb->real_data + abs_offset, needle, limit);
2084 if (result == NULL) {
2088 return (gint) (result - tvb->real_data);
2092 if (tvb->ops->tvb_find_guint8)
2093 return tvb->ops->tvb_find_guint8(tvb, abs_offset, limit, needle);
2095 return tvb_find_guint8_generic(tvb, offset, limit, needle);
2098 /* Same as tvb_find_guint8() with 16bit needle. */
2100 tvb_find_guint16(tvbuff_t *tvb, const gint offset, const gint maxlength,
2101 const guint16 needle)
2103 const guint8 needle1 = ((needle & 0xFF00) >> 8);
2104 const guint8 needle2 = ((needle & 0x00FF) >> 0);
2105 gint searched_bytes = 0;
2110 tvb_find_guint8(tvb, pos, maxlength - searched_bytes, needle1);
2113 if (offset1 == -1) {
2117 searched_bytes = offset - pos + 1;
2119 if ((maxlength != -1) && (searched_bytes >= maxlength)) {
2123 offset2 = tvb_find_guint8(tvb, offset1 + 1, 1, needle2);
2125 searched_bytes += 1;
2127 if (offset2 != -1) {
2128 if ((maxlength != -1) && (searched_bytes > maxlength)) {
2135 } while (searched_bytes < maxlength);
2141 tvb_ws_mempbrk_guint8_generic(tvbuff_t *tvb, guint abs_offset, guint limit, const ws_mempbrk_pattern* pattern, guchar *found_needle)
2144 const guint8 *result;
2146 ptr = ensure_contiguous(tvb, abs_offset, limit); /* tvb_get_ptr */
2148 result = ws_mempbrk_exec(ptr, limit, pattern, found_needle);
2152 return (gint) ((result - ptr) + abs_offset);
2156 /* Find first occurrence of any of the pattern chars in tvbuff, starting at offset.
2157 * Searches at most maxlength number of bytes; if maxlength is -1, searches
2159 * Returns the offset of the found needle, or -1 if not found.
2160 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
2161 * in that case, -1 will be returned if the boundary is reached before
2162 * finding needle. */
2164 tvb_ws_mempbrk_pattern_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength,
2165 const ws_mempbrk_pattern* pattern, guchar *found_needle)
2167 const guint8 *result;
2168 guint abs_offset = 0;
2172 DISSECTOR_ASSERT(tvb && tvb->initialized);
2174 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &limit);
2178 /* Only search to end of tvbuff, w/o throwing exception. */
2179 if (limit > (guint) maxlength) {
2180 /* Maximum length doesn't go past end of tvbuff; search
2185 /* If we have real data, perform our search now. */
2186 if (tvb->real_data) {
2187 result = ws_mempbrk_exec(tvb->real_data + abs_offset, limit, pattern, found_needle);
2188 if (result == NULL) {
2192 return (gint) (result - tvb->real_data);
2196 if (tvb->ops->tvb_ws_mempbrk_pattern_guint8)
2197 return tvb->ops->tvb_ws_mempbrk_pattern_guint8(tvb, abs_offset, limit, pattern, found_needle);
2199 return tvb_ws_mempbrk_guint8_generic(tvb, abs_offset, limit, pattern, found_needle);
2202 /* Find size of stringz (NUL-terminated string) by looking for terminating
2203 * NUL. The size of the string includes the terminating NUL.
2205 * If the NUL isn't found, it throws the appropriate exception.
2208 tvb_strsize(tvbuff_t *tvb, const gint offset)
2210 guint abs_offset = 0, junk_length;
2213 DISSECTOR_ASSERT(tvb && tvb->initialized);
2215 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
2216 nul_offset = tvb_find_guint8(tvb, abs_offset, -1, 0);
2217 if (nul_offset == -1) {
2219 * OK, we hit the end of the tvbuff, so we should throw
2222 if (tvb->length < tvb->contained_length) {
2224 } else if (tvb->length < tvb->reported_length) {
2225 THROW(ContainedBoundsError);
2226 } else if (tvb->flags & TVBUFF_FRAGMENT) {
2227 THROW(FragmentBoundsError);
2229 THROW(ReportedBoundsError);
2232 return (nul_offset - abs_offset) + 1;
2235 /* UTF-16/UCS-2 version of tvb_strsize */
2236 /* Returns number of bytes including the (two-bytes) null terminator */
2238 tvb_unicode_strsize(tvbuff_t *tvb, const gint offset)
2243 DISSECTOR_ASSERT(tvb && tvb->initialized);
2246 /* Endianness doesn't matter when looking for null */
2247 uchar = tvb_get_ntohs(tvb, offset + i);
2249 } while(uchar != 0);
2254 /* Find length of string by looking for end of string ('\0'), up to
2255 * 'maxlength' characters'; if 'maxlength' is -1, searches to end
2257 * Returns -1 if 'maxlength' reached before finding EOS. */
2259 tvb_strnlen(tvbuff_t *tvb, const gint offset, const guint maxlength)
2262 guint abs_offset = 0, junk_length;
2264 DISSECTOR_ASSERT(tvb && tvb->initialized);
2266 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
2268 result_offset = tvb_find_guint8(tvb, abs_offset, maxlength, 0);
2270 if (result_offset == -1) {
2274 return result_offset - abs_offset;
2279 * Implement strneql etc
2283 * Call strncmp after checking if enough chars left, returning 0 if
2284 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
2287 tvb_strneql(tvbuff_t *tvb, const gint offset, const gchar *str, const size_t size)
2291 ptr = ensure_contiguous_no_exception(tvb, offset, (gint)size, NULL);
2294 int cmp = strncmp((const char *)ptr, str, size);
2297 * Return 0 if equal, -1 otherwise.
2299 return (cmp == 0 ? 0 : -1);
2302 * Not enough characters in the tvbuff to match the
2310 * Call g_ascii_strncasecmp after checking if enough chars left, returning
2311 * 0 if it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
2314 tvb_strncaseeql(tvbuff_t *tvb, const gint offset, const gchar *str, const size_t size)
2318 ptr = ensure_contiguous_no_exception(tvb, offset, (gint)size, NULL);
2321 int cmp = g_ascii_strncasecmp((const char *)ptr, str, size);
2324 * Return 0 if equal, -1 otherwise.
2326 return (cmp == 0 ? 0 : -1);
2329 * Not enough characters in the tvbuff to match the
2337 * Check that the tvbuff contains at least size bytes, starting at
2338 * offset, and that those bytes are equal to str. Return 0 for success
2339 * and -1 for error. This function does not throw an exception.
2342 tvb_memeql(tvbuff_t *tvb, const gint offset, const guint8 *str, size_t size)
2346 ptr = ensure_contiguous_no_exception(tvb, offset, (gint) size, NULL);
2349 int cmp = memcmp(ptr, str, size);
2352 * Return 0 if equal, -1 otherwise.
2354 return (cmp == 0 ? 0 : -1);
2357 * Not enough characters in the tvbuff to match the
2365 * Format the data in the tvb from offset for size. Returned string is
2366 * wmem packet_scoped so call must be in that scope.
2369 tvb_format_text(tvbuff_t *tvb, const gint offset, const gint size)
2374 len = (size > 0) ? size : 0;
2376 ptr = ensure_contiguous(tvb, offset, size);
2377 return format_text(wmem_packet_scope(), ptr, len);
2381 * Format the data in the tvb from offset for length ...
2384 tvb_format_text_wsp(wmem_allocator_t* allocator, tvbuff_t *tvb, const gint offset, const gint size)
2389 len = (size > 0) ? size : 0;
2391 ptr = ensure_contiguous(tvb, offset, size);
2392 return format_text_wsp(allocator, ptr, len);
2396 * Like "tvb_format_text()", but for null-padded strings; don't show
2397 * the null padding characters as "\000". Returned string is wmem packet_scoped
2398 * so call must be in that scope.
2401 tvb_format_stringzpad(tvbuff_t *tvb, const gint offset, const gint size)
2403 const guint8 *ptr, *p;
2407 len = (size > 0) ? size : 0;
2409 ptr = ensure_contiguous(tvb, offset, size);
2410 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2412 return format_text(wmem_packet_scope(), ptr, stringlen);
2416 * Like "tvb_format_text_wsp()", but for null-padded strings; don't show
2417 * the null padding characters as "\000".
2420 tvb_format_stringzpad_wsp(wmem_allocator_t* allocator, tvbuff_t *tvb, const gint offset, const gint size)
2422 const guint8 *ptr, *p;
2426 len = (size > 0) ? size : 0;
2428 ptr = ensure_contiguous(tvb, offset, size);
2429 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2431 return format_text_wsp(allocator, ptr, stringlen);
2434 /* Unicode REPLACEMENT CHARACTER */
2435 #define UNREPL 0x00FFFD
2438 * All string functions below take a scope as an argument.
2441 * If scope is NULL, memory is allocated with g_malloc() and user must
2442 * explicitly free it with g_free().
2443 * If scope is not NULL, memory is allocated with the corresponding pool
2446 * All functions throw an exception if the tvbuff ends before the string
2451 * Given a wmem scope, tvbuff, an offset, and a length, treat the string
2452 * of bytes referred to by the tvbuff, offset, and length as an ASCII string,
2453 * with all bytes with the high-order bit set being invalid, and return a
2454 * pointer to a UTF-8 string, allocated using the wmem scope.
2456 * Octets with the highest bit set will be converted to the Unicode
2457 * REPLACEMENT CHARACTER.
2460 tvb_get_ascii_string(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint length)
2464 ptr = ensure_contiguous(tvb, offset, length);
2465 return get_ascii_string(scope, ptr, length);
2469 * Given a wmem scope, a tvbuff, an offset, and a length, treat the string
2470 * of bytes referred to by the tvbuff, the offset. and the length as a UTF-8
2471 * string, and return a pointer to that string, allocated using the wmem scope.
2473 * XXX - should map invalid UTF-8 sequences to UNREPL.
2476 tvb_get_utf_8_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, const gint length)
2480 tvb_ensure_bytes_exist(tvb, offset, length); /* make sure length = -1 fails */
2481 strbuf = (guint8 *)wmem_alloc(scope, length + 1);
2482 tvb_memcpy(tvb, strbuf, offset, length);
2483 strbuf[length] = '\0';
2488 * Given a wmem scope, tvbuff, an offset, and a length, treat the string
2489 * of bytes referred to by the tvbuff, the offset, and the length as a
2490 * raw string, and return a pointer to that string, allocated using the
2491 * wmem scope. This means a null is appended at the end, but no replacement
2492 * checking is done otherwise. Currently tvb_get_utf_8_string() does not
2493 * replace either, but it might in the future.
2495 * Also, this one allows a length of -1 to mean get all, but does not
2496 * allow a negative offset.
2498 static inline guint8 *
2499 tvb_get_raw_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, const gint length)
2502 gint abs_length = length;
2504 DISSECTOR_ASSERT(offset >= 0);
2505 DISSECTOR_ASSERT(abs_length >= -1);
2508 abs_length = tvb->length - offset;
2510 tvb_ensure_bytes_exist(tvb, offset, abs_length);
2511 strbuf = (guint8 *)wmem_alloc(scope, abs_length + 1);
2512 tvb_memcpy(tvb, strbuf, offset, abs_length);
2513 strbuf[abs_length] = '\0';
2518 * Given a wmem scope, a tvbuff, an offset, and a length, treat the string
2519 * of bytes referred to by the tvbuff, the offset, and the length as an
2520 * ISO 8859/1 string, and return a pointer to a UTF-8 string, allocated
2521 * using the wmem scope.
2524 tvb_get_string_8859_1(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint length)
2528 ptr = ensure_contiguous(tvb, offset, length);
2529 return get_8859_1_string(scope, ptr, length);
2533 * Given a wmem scope, a tvbuff, an offset, a length, and a translation
2534 * table, treat the string of bytes referred to by the tvbuff, the offset,
2535 * and the length as a string encoded using one octet per character, with
2536 * octets with the high-order bit clear being ASCII and octets with the
2537 * high-order bit set being mapped by the translation table to 2-byte
2538 * Unicode Basic Multilingual Plane characters (including REPLACEMENT
2539 * CHARACTER), and return a pointer to a UTF-8 string, allocated with the
2543 tvb_get_string_unichar2(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint length, const gunichar2 table[0x80])
2547 ptr = ensure_contiguous(tvb, offset, length);
2548 return get_unichar2_string(scope, ptr, length, table);
2552 * Given a wmem scope, a tvbuff, an offset, a length, and an encoding
2553 * giving the byte order, treat the string of bytes referred to by the
2554 * tvbuff, the offset, and the length as a UCS-2 encoded string in
2555 * the byte order in question, containing characters from the Basic
2556 * Multilingual Plane (plane 0) of Unicode, and return a pointer to a
2557 * UTF-8 string, allocated with the wmem scope.
2559 * Encoding parameter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN.
2561 * Specify length in bytes.
2563 * XXX - should map lead and trail surrogate values to REPLACEMENT
2564 * CHARACTERs (0xFFFD)?
2565 * XXX - if there are an odd number of bytes, should put a
2566 * REPLACEMENT CHARACTER at the end.
2569 tvb_get_ucs_2_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint length, const guint encoding)
2573 ptr = ensure_contiguous(tvb, offset, length);
2574 return get_ucs_2_string(scope, ptr, length, encoding);
2578 * Given a wmem scope, a tvbuff, an offset, a length, and an encoding
2579 * giving the byte order, treat the string of bytes referred to by the
2580 * tvbuff, the offset, and the length as a UTF-16 encoded string in
2581 * the byte order in question, and return a pointer to a UTF-8 string,
2582 * allocated with the wmem scope.
2584 * Encoding parameter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN.
2586 * Specify length in bytes.
2588 * XXX - should map surrogate errors to REPLACEMENT CHARACTERs (0xFFFD).
2589 * XXX - should map code points > 10FFFF to REPLACEMENT CHARACTERs.
2590 * XXX - if there are an odd number of bytes, should put a
2591 * REPLACEMENT CHARACTER at the end.
2594 tvb_get_utf_16_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint length, const guint encoding)
2598 ptr = ensure_contiguous(tvb, offset, length);
2599 return get_utf_16_string(scope, ptr, length, encoding);
2603 * Given a wmem scope, a tvbuff, an offset, a length, and an encoding
2604 * giving the byte order, treat the string of bytes referred to by the
2605 * tvbuff, the offset, and the length as a UCS-4 encoded string in
2606 * the byte order in question, and return a pointer to a UTF-8 string,
2607 * allocated with the wmem scope.
2609 * Encoding parameter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN
2611 * Specify length in bytes
2613 * XXX - should map lead and trail surrogate values to a "substitute"
2615 * XXX - should map code points > 10FFFF to REPLACEMENT CHARACTERs.
2616 * XXX - if the number of bytes isn't a multiple of 4, should put a
2617 * REPLACEMENT CHARACTER at the end.
2620 tvb_get_ucs_4_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint length, const guint encoding)
2624 ptr = ensure_contiguous(tvb, offset, length);
2625 return get_ucs_4_string(scope, ptr, length, encoding);
2629 tvb_get_ts_23_038_7bits_string(wmem_allocator_t *scope, tvbuff_t *tvb,
2630 const gint bit_offset, gint no_of_chars)
2632 gint in_offset = bit_offset >> 3; /* Current pointer to the input buffer */
2633 gint length = ((no_of_chars + 1) * 7 + (bit_offset & 0x07)) >> 3;
2636 DISSECTOR_ASSERT(tvb && tvb->initialized);
2638 ptr = ensure_contiguous(tvb, in_offset, length);
2639 return get_ts_23_038_7bits_string(scope, ptr, bit_offset, no_of_chars);
2643 tvb_get_ascii_7bits_string(wmem_allocator_t *scope, tvbuff_t *tvb,
2644 const gint bit_offset, gint no_of_chars)
2646 gint in_offset = bit_offset >> 3; /* Current pointer to the input buffer */
2647 gint length = ((no_of_chars + 1) * 7 + (bit_offset & 0x07)) >> 3;
2650 DISSECTOR_ASSERT(tvb && tvb->initialized);
2652 ptr = ensure_contiguous(tvb, in_offset, length);
2653 return get_ascii_7bits_string(scope, ptr, bit_offset, no_of_chars);
2657 * Given a wmem scope, a tvbuff, an offset, a length, and a translation
2658 * table, treat the string of bytes referred to by the tvbuff, the offset,
2659 * and the length as a string encoded using one octet per character, with
2660 * octets being mapped by the translation table to 2-byte Unicode Basic
2661 * Multilingual Plane characters (including REPLACEMENT CHARACTER), and
2662 * return a pointer to a UTF-8 string, allocated with the wmem scope.
2665 tvb_get_nonascii_unichar2_string(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint length, const gunichar2 table[256])
2669 ptr = ensure_contiguous(tvb, offset, length);
2670 return get_nonascii_unichar2_string(scope, ptr, length, table);
2674 tvb_get_t61_string(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint length)
2678 ptr = ensure_contiguous(tvb, offset, length);
2679 return get_t61_string(scope, ptr, length);
2683 * Given a tvbuff, an offset, a length, and an encoding, allocate a
2684 * buffer big enough to hold a non-null-terminated string of that length
2685 * at that offset, plus a trailing '\0', copy into the buffer the
2686 * string as converted from the appropriate encoding to UTF-8, and
2687 * return a pointer to the string.
2690 tvb_get_string_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset,
2691 const gint length, const guint encoding)
2695 DISSECTOR_ASSERT(tvb && tvb->initialized);
2697 /* make sure length = -1 fails */
2699 THROW(ReportedBoundsError);
2702 switch (encoding & ENC_CHARENCODING_MASK) {
2707 * For now, we treat bogus values as meaning
2708 * "ASCII" rather than reporting an error,
2709 * for the benefit of old dissectors written
2710 * when the last argument to proto_tree_add_item()
2711 * was a gboolean for the byte order, not an
2712 * encoding value, and passed non-zero values
2713 * other than TRUE to mean "little-endian".
2715 strptr = tvb_get_ascii_string(scope, tvb, offset, length);
2720 * XXX - should map lead and trail surrogate value code
2721 * points to a "substitute" UTF-8 character?
2722 * XXX - should map code points > 10FFFF to REPLACEMENT
2725 strptr = tvb_get_utf_8_string(scope, tvb, offset, length);
2729 strptr = tvb_get_utf_16_string(scope, tvb, offset, length,
2730 encoding & ENC_LITTLE_ENDIAN);
2734 strptr = tvb_get_ucs_2_string(scope, tvb, offset, length,
2735 encoding & ENC_LITTLE_ENDIAN);
2739 strptr = tvb_get_ucs_4_string(scope, tvb, offset, length,
2740 encoding & ENC_LITTLE_ENDIAN);
2743 case ENC_ISO_8859_1:
2745 * ISO 8859-1 printable code point values are equal
2746 * to the equivalent Unicode code point value, so
2747 * no translation table is needed.
2749 strptr = tvb_get_string_8859_1(scope, tvb, offset, length);
2752 case ENC_ISO_8859_2:
2753 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_2);
2756 case ENC_ISO_8859_3:
2757 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_3);
2760 case ENC_ISO_8859_4:
2761 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_4);
2764 case ENC_ISO_8859_5:
2765 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_5);
2768 case ENC_ISO_8859_6:
2769 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_6);
2772 case ENC_ISO_8859_7:
2773 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_7);
2776 case ENC_ISO_8859_8:
2777 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_8);
2780 case ENC_ISO_8859_9:
2781 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_9);
2784 case ENC_ISO_8859_10:
2785 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_10);
2788 case ENC_ISO_8859_11:
2789 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_11);
2792 case ENC_ISO_8859_13:
2793 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_13);
2796 case ENC_ISO_8859_14:
2797 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_14);
2800 case ENC_ISO_8859_15:
2801 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_15);
2804 case ENC_ISO_8859_16:
2805 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_16);
2808 case ENC_WINDOWS_1250:
2809 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_cp1250);
2813 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_mac_roman);
2817 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_cp437);
2820 case ENC_3GPP_TS_23_038_7BITS:
2822 gint bit_offset = offset << 3;
2823 gint no_of_chars = (length << 3) / 7;
2824 strptr = tvb_get_ts_23_038_7bits_string(scope, tvb, bit_offset, no_of_chars);
2828 case ENC_ASCII_7BITS:
2830 gint bit_offset = offset << 3;
2831 gint no_of_chars = (length << 3) / 7;
2832 strptr = tvb_get_ascii_7bits_string(scope, tvb, bit_offset, no_of_chars);
2838 * "Common" EBCDIC, covering all characters with the
2839 * same code point in all Roman-alphabet EBCDIC code
2842 strptr = tvb_get_nonascii_unichar2_string(scope, tvb, offset, length, charset_table_ebcdic);
2845 case ENC_EBCDIC_CP037:
2847 * EBCDIC code page 037.
2849 strptr = tvb_get_nonascii_unichar2_string(scope, tvb, offset, length, charset_table_ebcdic_cp037);
2853 strptr = tvb_get_t61_string(scope, tvb, offset, length);
2860 * This is like tvb_get_string_enc(), except that it handles null-padded
2863 * Currently, string values are stored as UTF-8 null-terminated strings,
2864 * so nothing needs to be done differently for null-padded strings; we
2865 * could save a little memory by not storing the null padding.
2867 * If we ever store string values differently, in a fashion that doesn't
2868 * involve null termination, that might change.
2871 tvb_get_stringzpad(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset,
2872 const gint length, const guint encoding)
2874 return tvb_get_string_enc(scope, tvb, offset, length, encoding);
2878 * These routines are like the above routines, except that they handle
2879 * null-terminated strings. They find the length of that string (and
2880 * throw an exception if the tvbuff ends before we find the null), and
2881 * also return through a pointer the length of the string, in bytes,
2882 * including the terminating null (the terminating null being 2 bytes
2883 * for UCS-2 and UTF-16, 4 bytes for UCS-4, and 1 byte for other
2887 tvb_get_ascii_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint *lengthp)
2892 size = tvb_strsize(tvb, offset);
2893 ptr = ensure_contiguous(tvb, offset, size);
2894 /* XXX, conversion between signed/unsigned integer */
2897 return get_ascii_string(scope, ptr, size);
2901 tvb_get_utf_8_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint *lengthp)
2906 size = tvb_strsize(tvb, offset);
2907 strptr = (guint8 *)wmem_alloc(scope, size);
2908 tvb_memcpy(tvb, strptr, offset, size);
2915 tvb_get_stringz_8859_1(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint *lengthp)
2920 size = tvb_strsize(tvb, offset);
2921 ptr = ensure_contiguous(tvb, offset, size);
2922 /* XXX, conversion between signed/unsigned integer */
2925 return get_8859_1_string(scope, ptr, size);
2929 tvb_get_stringz_unichar2(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint *lengthp, const gunichar2 table[0x80])
2934 size = tvb_strsize(tvb, offset);
2935 ptr = ensure_contiguous(tvb, offset, size);
2936 /* XXX, conversion between signed/unsigned integer */
2939 return get_unichar2_string(scope, ptr, size, table);
2943 * Given a tvbuff and an offset, with the offset assumed to refer to
2944 * a null-terminated string, find the length of that string (and throw
2945 * an exception if the tvbuff ends before we find the null), ensure that
2946 * the TVB is flat, and return a pointer to the string (in the TVB).
2947 * Also return the length of the string (including the terminating null)
2948 * through a pointer.
2950 * As long as we aren't using composite TVBs, this saves the cycles used
2951 * (often unnecessariliy) in allocating a buffer and copying the string into
2952 * it. (If we do start using composite TVBs, we may want to replace this
2953 * function with the _ephemeral version.)
2956 tvb_get_const_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp)
2959 const guint8 *strptr;
2961 size = tvb_strsize(tvb, offset);
2962 strptr = ensure_contiguous(tvb, offset, size);
2969 tvb_get_ucs_2_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding)
2971 gint size; /* Number of bytes in string */
2974 size = tvb_unicode_strsize(tvb, offset);
2975 ptr = ensure_contiguous(tvb, offset, size);
2976 /* XXX, conversion between signed/unsigned integer */
2979 return get_ucs_2_string(scope, ptr, size, encoding);
2983 tvb_get_utf_16_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding)
2988 size = tvb_unicode_strsize(tvb, offset);
2989 ptr = ensure_contiguous(tvb, offset, size);
2990 /* XXX, conversion between signed/unsigned integer */
2993 return get_utf_16_string(scope, ptr, size, encoding);
2997 tvb_get_ucs_4_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding)
3005 /* Endianness doesn't matter when looking for null */
3006 uchar = tvb_get_ntohl(tvb, offset + size);
3008 } while(uchar != 0);
3010 ptr = ensure_contiguous(tvb, offset, size);
3011 /* XXX, conversion between signed/unsigned integer */
3014 return get_ucs_4_string(scope, ptr, size, encoding);
3018 tvb_get_nonascii_unichar2_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint *lengthp, const gunichar2 table[256])
3023 size = tvb_strsize(tvb, offset);
3024 ptr = ensure_contiguous(tvb, offset, size);
3025 /* XXX, conversion between signed/unsigned integer */
3028 return get_nonascii_unichar2_string(scope, ptr, size, table);
3032 tvb_get_t61_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint *lengthp)
3037 size = tvb_strsize(tvb, offset);
3038 ptr = ensure_contiguous(tvb, offset, size);
3039 /* XXX, conversion between signed/unsigned integer */
3042 return get_t61_string(scope, ptr, size);
3046 tvb_get_stringz_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding)
3050 DISSECTOR_ASSERT(tvb && tvb->initialized);
3052 switch (encoding & ENC_CHARENCODING_MASK) {
3057 * For now, we treat bogus values as meaning
3058 * "ASCII" rather than reporting an error,
3059 * for the benefit of old dissectors written
3060 * when the last argument to proto_tree_add_item()
3061 * was a gboolean for the byte order, not an
3062 * encoding value, and passed non-zero values
3063 * other than TRUE to mean "little-endian".
3065 strptr = tvb_get_ascii_stringz(scope, tvb, offset, lengthp);
3070 * XXX - should map all invalid UTF-8 sequences
3071 * to a "substitute" UTF-8 character.
3072 * XXX - should map code points > 10FFFF to REPLACEMENT
3075 strptr = tvb_get_utf_8_stringz(scope, tvb, offset, lengthp);
3079 strptr = tvb_get_utf_16_stringz(scope, tvb, offset, lengthp,
3080 encoding & ENC_LITTLE_ENDIAN);
3084 strptr = tvb_get_ucs_2_stringz(scope, tvb, offset, lengthp,
3085 encoding & ENC_LITTLE_ENDIAN);
3089 strptr = tvb_get_ucs_4_stringz(scope, tvb, offset, lengthp,
3090 encoding & ENC_LITTLE_ENDIAN);
3093 case ENC_ISO_8859_1:
3095 * ISO 8859-1 printable code point values are equal
3096 * to the equivalent Unicode code point value, so
3097 * no translation table is needed.
3099 strptr = tvb_get_stringz_8859_1(scope, tvb, offset, lengthp);
3102 case ENC_ISO_8859_2:
3103 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_2);
3106 case ENC_ISO_8859_3:
3107 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_3);
3110 case ENC_ISO_8859_4:
3111 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_4);
3114 case ENC_ISO_8859_5:
3115 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_5);
3118 case ENC_ISO_8859_6:
3119 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_6);
3122 case ENC_ISO_8859_7:
3123 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_7);
3126 case ENC_ISO_8859_8:
3127 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_8);
3130 case ENC_ISO_8859_9:
3131 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_9);
3134 case ENC_ISO_8859_10:
3135 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_10);
3138 case ENC_ISO_8859_11:
3139 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_11);
3142 case ENC_ISO_8859_13:
3143 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_13);
3146 case ENC_ISO_8859_14:
3147 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_14);
3150 case ENC_ISO_8859_15:
3151 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_15);
3154 case ENC_ISO_8859_16:
3155 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_16);
3158 case ENC_WINDOWS_1250:
3159 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_cp1250);
3163 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_mac_roman);
3167 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_cp437);
3170 case ENC_3GPP_TS_23_038_7BITS:
3171 REPORT_DISSECTOR_BUG("TS 23.038 7bits has no null character and doesn't support null-terminated strings");
3174 case ENC_ASCII_7BITS:
3175 REPORT_DISSECTOR_BUG("tvb_get_stringz_enc function with ENC_ASCII_7BITS not implemented yet");
3180 * "Common" EBCDIC, covering all characters with the
3181 * same code point in all Roman-alphabet EBCDIC code
3184 strptr = tvb_get_nonascii_unichar2_stringz(scope, tvb, offset, lengthp, charset_table_ebcdic);
3187 case ENC_EBCDIC_CP037:
3189 * EBCDIC code page 037.
3191 strptr = tvb_get_nonascii_unichar2_stringz(scope, tvb, offset, lengthp, charset_table_ebcdic_cp037);
3195 strptr = tvb_get_t61_stringz(scope, tvb, offset, lengthp);
3202 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
3203 * no more than bufsize number of bytes, including terminating NUL, to buffer.
3204 * Returns length of string (not including terminating NUL), or -1 if the string was
3205 * truncated in the buffer due to not having reached the terminating NUL.
3206 * In this way, it acts like g_snprintf().
3208 * bufsize MUST be greater than 0.
3210 * When processing a packet where the remaining number of bytes is less
3211 * than bufsize, an exception is not thrown if the end of the packet
3212 * is reached before the NUL is found. If no NUL is found before reaching
3213 * the end of the short packet, -1 is still returned, and the string
3214 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
3215 * at the correct spot, terminating the string.
3217 * *bytes_copied will contain the number of bytes actually copied,
3218 * including the terminating-NUL.
3221 _tvb_get_nstringz(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* buffer, gint *bytes_copied)
3224 guint abs_offset = 0;
3225 gint limit, len = 0;
3226 gboolean decreased_max = FALSE;
3228 /* Only read to end of tvbuff, w/o throwing exception. */
3229 check_offset_length(tvb, offset, -1, &abs_offset, &len);
3231 /* There must at least be room for the terminating NUL. */
3232 DISSECTOR_ASSERT(bufsize != 0);
3234 /* If there's no room for anything else, just return the NUL. */
3241 /* check_offset_length() won't throw an exception if we're
3242 * looking at the byte immediately after the end of the tvbuff. */
3244 THROW(ReportedBoundsError);
3247 /* This should not happen because check_offset_length() would
3248 * have already thrown an exception if 'offset' were out-of-bounds.
3250 DISSECTOR_ASSERT(len != -1);
3253 * If we've been passed a negative number, bufsize will
3256 DISSECTOR_ASSERT(bufsize <= G_MAXINT);
3258 if ((guint)len < bufsize) {
3260 decreased_max = TRUE;
3266 stringlen = tvb_strnlen(tvb, abs_offset, limit - 1);
3267 /* If NUL wasn't found, copy the data and return -1 */
3268 if (stringlen == -1) {
3269 tvb_memcpy(tvb, buffer, abs_offset, limit);
3270 if (decreased_max) {
3272 /* Add 1 for the extra NUL that we set at buffer[limit],
3273 * pretending that it was copied as part of the string. */
3274 *bytes_copied = limit + 1;
3277 *bytes_copied = limit;
3282 /* Copy the string to buffer */
3283 tvb_memcpy(tvb, buffer, abs_offset, stringlen + 1);
3284 *bytes_copied = stringlen + 1;
3288 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
3289 * no more than bufsize number of bytes, including terminating NUL, to buffer.
3290 * Returns length of string (not including terminating NUL), or -1 if the string was
3291 * truncated in the buffer due to not having reached the terminating NUL.
3292 * In this way, it acts like g_snprintf().
3294 * When processing a packet where the remaining number of bytes is less
3295 * than bufsize, an exception is not thrown if the end of the packet
3296 * is reached before the NUL is found. If no NUL is found before reaching
3297 * the end of the short packet, -1 is still returned, and the string
3298 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
3299 * at the correct spot, terminating the string.
3302 tvb_get_nstringz(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8 *buffer)
3306 DISSECTOR_ASSERT(tvb && tvb->initialized);
3308 return _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
3311 /* Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
3312 * have a terminating NUL. If the string was truncated when copied into buffer,
3313 * a NUL is placed at the end of buffer to terminate it.
3316 tvb_get_nstringz0(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* buffer)
3318 gint len, bytes_copied;
3320 DISSECTOR_ASSERT(tvb && tvb->initialized);
3322 len = _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
3325 buffer[bufsize - 1] = 0;
3326 return bytes_copied - 1;
3334 static ws_mempbrk_pattern pbrk_crlf;
3336 * Given a tvbuff, an offset into the tvbuff, and a length that starts
3337 * at that offset (which may be -1 for "all the way to the end of the
3338 * tvbuff"), find the end of the (putative) line that starts at the
3339 * specified offset in the tvbuff, going no further than the specified
3342 * Return the length of the line (not counting the line terminator at
3343 * the end), or, if we don't find a line terminator:
3345 * if "desegment" is true, return -1;
3347 * if "desegment" is false, return the amount of data remaining in
3350 * Set "*next_offset" to the offset of the character past the line
3351 * terminator, or past the end of the buffer if we don't find a line
3352 * terminator. (It's not set if we return -1.)
3355 tvb_find_line_end(tvbuff_t *tvb, const gint offset, int len, gint *next_offset, const gboolean desegment)
3360 guchar found_needle = 0;
3361 static gboolean compiled = FALSE;
3363 DISSECTOR_ASSERT(tvb && tvb->initialized);
3366 len = _tvb_captured_length_remaining(tvb, offset);
3367 /* if offset is past the end of the tvbuff, len is now 0 */
3370 eob_offset = offset + len;
3373 ws_mempbrk_compile(&pbrk_crlf, "\r\n");
3378 * Look either for a CR or an LF.
3380 eol_offset = tvb_ws_mempbrk_pattern_guint8(tvb, offset, len, &pbrk_crlf, &found_needle);
3381 if (eol_offset == -1) {
3383 * No CR or LF - line is presumably continued in next packet.
3387 * Tell our caller we saw no EOL, so they can
3388 * try to desegment and get the entire line
3394 * Pretend the line runs to the end of the tvbuff.
3396 linelen = eob_offset - offset;
3398 *next_offset = eob_offset;
3402 * Find the number of bytes between the starting offset
3405 linelen = eol_offset - offset;
3410 if (found_needle == '\r') {
3412 * Yes - is it followed by an LF?
3414 if (eol_offset + 1 >= eob_offset) {
3416 * Dunno - the next byte isn't in this
3421 * We'll return -1, although that
3422 * runs the risk that if the line
3423 * really *is* terminated with a CR,
3424 * we won't properly dissect this
3427 * It's probably more likely that
3428 * the line ends with CR-LF than
3429 * that it ends with CR by itself.
3435 * Well, we can at least look at the next
3438 if (tvb_get_guint8(tvb, eol_offset + 1) == '\n') {
3440 * It's an LF; skip over the CR.
3448 * Return the offset of the character after the last
3449 * character in the line, skipping over the last character
3450 * in the line terminator.
3453 *next_offset = eol_offset + 1;
3458 static ws_mempbrk_pattern pbrk_crlf_dquote;
3460 * Given a tvbuff, an offset into the tvbuff, and a length that starts
3461 * at that offset (which may be -1 for "all the way to the end of the
3462 * tvbuff"), find the end of the (putative) line that starts at the
3463 * specified offset in the tvbuff, going no further than the specified
3466 * However, treat quoted strings inside the buffer specially - don't
3467 * treat newlines in quoted strings as line terminators.
3469 * Return the length of the line (not counting the line terminator at
3470 * the end), or the amount of data remaining in the buffer if we don't
3471 * find a line terminator.
3473 * Set "*next_offset" to the offset of the character past the line
3474 * terminator, or past the end of the buffer if we don't find a line
3478 tvb_find_line_end_unquoted(tvbuff_t *tvb, const gint offset, int len, gint *next_offset)
3480 gint cur_offset, char_offset;
3485 static gboolean compiled = FALSE;
3487 DISSECTOR_ASSERT(tvb && tvb->initialized);
3490 len = _tvb_captured_length_remaining(tvb, offset);
3493 ws_mempbrk_compile(&pbrk_crlf_dquote, "\r\n\"");
3498 * XXX - what if "len" is still -1, meaning "offset is past the
3499 * end of the tvbuff"?
3501 eob_offset = offset + len;
3503 cur_offset = offset;
3507 * Is this part of the string quoted?
3511 * Yes - look only for the terminating quote.
3513 char_offset = tvb_find_guint8(tvb, cur_offset, len,
3517 * Look either for a CR, an LF, or a '"'.
3519 char_offset = tvb_ws_mempbrk_pattern_guint8(tvb, cur_offset, len, &pbrk_crlf_dquote, &c);
3521 if (char_offset == -1) {
3523 * Not found - line is presumably continued in
3525 * We pretend the line runs to the end of the tvbuff.
3527 linelen = eob_offset - offset;
3529 *next_offset = eob_offset;
3535 * We're processing a quoted string.
3536 * We only looked for ", so we know it's a ";
3537 * as we're processing a quoted string, it's a
3547 * Un-quoted "; it begins a quoted
3553 * It's a CR or LF; we've found a line
3556 * Find the number of bytes between the
3557 * starting offset and the CR or LF.
3559 linelen = char_offset - offset;
3566 * Yes; is it followed by an LF?
3568 if (char_offset + 1 < eob_offset &&
3569 tvb_get_guint8(tvb, char_offset + 1)
3572 * Yes; skip over the CR.
3579 * Return the offset of the character after
3580 * the last character in the line, skipping
3581 * over the last character in the line
3582 * terminator, and quit.
3585 *next_offset = char_offset + 1;
3591 * Step past the character we found.
3593 cur_offset = char_offset + 1;
3594 if (cur_offset >= eob_offset) {
3596 * The character we found was the last character
3597 * in the tvbuff - line is presumably continued in
3599 * We pretend the line runs to the end of the tvbuff.
3601 linelen = eob_offset - offset;
3603 *next_offset = eob_offset;
3611 * Copied from the mgcp dissector. (This function should be moved to /epan )
3612 * tvb_skip_wsp - Returns the position in tvb of the first non-whitespace
3613 * character following offset or offset + maxlength -1 whichever
3617 * tvb - The tvbuff in which we are skipping whitespace.
3618 * offset - The offset in tvb from which we begin trying to skip whitespace.
3619 * maxlength - The maximum distance from offset that we may try to skip
3622 * Returns: The position in tvb of the first non-whitespace
3623 * character following offset or offset + maxlength -1 whichever
3627 tvb_skip_wsp(tvbuff_t *tvb, const gint offset, const gint maxlength)
3629 gint counter = offset;
3633 DISSECTOR_ASSERT(tvb && tvb->initialized);
3635 /* Get the length remaining */
3636 /*tvb_len = tvb_captured_length(tvb);*/
3637 tvb_len = tvb->length;
3639 end = offset + maxlength;
3645 /* Skip past spaces, tabs, CRs and LFs until run out or meet something else */
3646 for (counter = offset;
3648 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
3649 tempchar == '\t' || tempchar == '\r' || tempchar == '\n');
3656 tvb_skip_wsp_return(tvbuff_t *tvb, const gint offset)
3658 gint counter = offset;
3661 DISSECTOR_ASSERT(tvb && tvb->initialized);
3663 for (counter = offset; counter > 0 &&
3664 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
3665 tempchar == '\t' || tempchar == '\n' || tempchar == '\r'); counter--);
3672 tvb_skip_guint8(tvbuff_t *tvb, int offset, const int maxlength, const guint8 ch)
3676 DISSECTOR_ASSERT(tvb && tvb->initialized);
3678 /* Get the length remaining */
3679 /*tvb_len = tvb_captured_length(tvb);*/
3680 tvb_len = tvb->length;
3682 end = offset + maxlength;
3686 while (offset < end) {
3687 guint8 tempch = tvb_get_guint8(tvb, offset);
3698 * Format a bunch of data from a tvbuff as bytes, returning a pointer
3699 * to the string with the formatted data, with "punct" as a byte
3703 tvb_bytes_to_str_punct(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, const gint len, const gchar punct)
3705 return bytestring_to_str(scope, ensure_contiguous(tvb, offset, len), len, punct);
3710 * Given a tvbuff, an offset into the tvbuff, and a length that starts
3711 * at that offset (which may be -1 for "all the way to the end of the
3712 * tvbuff"), fetch BCD encoded digits from a tvbuff starting from either
3713 * the low or high half byte, formating the digits according to an input digit set,
3714 * if NUll a default digit set of 0-9 returning "?" for overdecadic digits will be used.
3715 * A pointer to the packet scope allocated string will be returned.
3716 * Note a tvbuff content of 0xf is considered a 'filler' and will end the conversion.
3718 static const dgt_set_t Dgt1_9_bcd = {
3720 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f*/
3721 '0','1','2','3','4','5','6','7','8','9','?','?','?','?','?','?'
3725 tvb_bcd_dig_to_wmem_packet_str(tvbuff_t *tvb, const gint offset, const gint len, const dgt_set_t *dgt, gboolean skip_first)
3731 gint t_offset = offset;
3733 DISSECTOR_ASSERT(tvb && tvb->initialized);
3739 /*length = tvb_captured_length(tvb);*/
3740 length = tvb->length;
3741 if (length < offset) {
3745 length = offset + len;
3747 digit_str = (char *)wmem_alloc(wmem_packet_scope(), (length - offset)*2+1);
3749 while (t_offset < length) {
3751 octet = tvb_get_guint8(tvb,t_offset);
3753 digit_str[i] = dgt->out[octet & 0x0f];
3759 * unpack second value in byte
3763 if (t_offset == length - 1 && octet == 0x0f) {
3765 * This is the last octet, and the low-order
3766 * nibble is 0xf, so we have an odd number of
3767 * digits, and this is a filler digit. Ignore
3773 digit_str[i] = dgt->out[octet & 0x0f];
3784 * Format a bunch of data from a tvbuff as bytes, returning a pointer
3785 * to the string with the formatted data.
3787 gchar *tvb_bytes_to_str(wmem_allocator_t *allocator, tvbuff_t *tvb,
3788 const gint offset, const gint len)
3790 return bytes_to_str(allocator, ensure_contiguous(tvb, offset, len), len);
3793 /* Find a needle tvbuff within a haystack tvbuff. */
3795 tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb, const gint haystack_offset)
3797 guint haystack_abs_offset = 0, haystack_abs_length = 0;
3798 const guint8 *haystack_data;
3799 const guint8 *needle_data;
3800 const guint needle_len = needle_tvb->length;
3801 const guint8 *location;
3803 DISSECTOR_ASSERT(haystack_tvb && haystack_tvb->initialized);
3805 if (haystack_tvb->length < 1 || needle_tvb->length < 1) {
3809 /* Get pointers to the tvbuffs' data. */
3810 haystack_data = ensure_contiguous(haystack_tvb, 0, -1);
3811 needle_data = ensure_contiguous(needle_tvb, 0, -1);
3813 check_offset_length(haystack_tvb, haystack_offset, -1,
3814 &haystack_abs_offset, &haystack_abs_length);
3816 location = epan_memmem(haystack_data + haystack_abs_offset, haystack_abs_length,
3817 needle_data, needle_len);
3820 return (gint) (location - haystack_data);
3827 tvb_raw_offset(tvbuff_t *tvb)
3829 return ((tvb->raw_offset==-1) ? (tvb->raw_offset = tvb_offset_from_real_beginning(tvb)) : tvb->raw_offset);
3833 tvb_set_fragment(tvbuff_t *tvb)
3835 tvb->flags |= TVBUFF_FRAGMENT;
3839 tvb_get_ds_tvb(tvbuff_t *tvb)
3841 return(tvb->ds_tvb);
3845 tvb_get_varint(tvbuff_t *tvb, guint offset, guint maxlen, guint64 *value, const guint encoding)
3849 if (encoding & ENC_VARINT_PROTOBUF) {
3851 guint64 b; /* current byte */
3853 for (i = 0; ((i < FT_VARINT_MAX_LEN) && (i < maxlen)); ++i) {
3854 b = tvb_get_guint8(tvb, offset++);
3855 *value |= ((b & 0x7F) << (i * 7)); /* add lower 7 bits to val */
3858 /* end successfully becauseof last byte's msb(most significant bit) is zero */
3862 } else if (encoding & ENC_VARINT_QUIC) {
3864 /* calculate variable length */
3865 *value = tvb_get_guint8(tvb, offset);
3866 switch((*value) >> 6) {
3867 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
3870 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
3871 *value = tvb_get_ntohs(tvb, offset) & 0x3FFF;
3873 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
3874 *value = tvb_get_ntohl(tvb, offset) & 0x3FFFFFFF;
3876 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
3877 *value = tvb_get_ntoh64(tvb, offset) & G_GUINT64_CONSTANT(0x3FFFFFFFFFFFFFFF);
3879 default: /* No Possible */
3880 g_assert_not_reached();
3886 return 0; /* 10 bytes scanned, but no bytes' msb is zero */
3890 * Editor modelines - http://www.wireshark.org/tools/modelines.html
3895 * indent-tabs-mode: t
3898 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3899 * :indentSize=8:tabSize=8:noTabs=false: