Bug Summary

File:builds/wireshark/wireshark/epan/tvbuff.c
Warning:line 2332, column 58
The result of left shift is undefined because the right operand is not smaller than 64, the capacity of 'uint64_t'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name tvbuff.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-18/lib/clang/18 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan -isystem /builds/wireshark/wireshark/build/epan -isystem /usr/include/libxml2 -isystem /usr/include/lua5.4 -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D epan_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-truncation -Wno-format-nonliteral -Wno-pointer-sign -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -dwarf-debug-flags /usr/lib/llvm-18/bin/clang -### --analyze -x c -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D epan_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan -isystem /builds/wireshark/wireshark/build/epan -isystem /usr/include/libxml2 -isystem /usr/include/lua5.4 -fvisibility=hidden -fexcess-precision=fast -fstrict-flex-arrays=3 -fstack-clash-protection -fcf-protection=full -D _GLIBCXX_ASSERTIONS -fstack-protector-strong -fno-delete-null-pointer-checks -fno-strict-overflow -fno-strict-aliasing -fexceptions -Wno-format-truncation -Wno-format-nonliteral -fdiagnostics-color=always -Wno-pointer-sign -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -std=gnu11 -fPIC /builds/wireshark/wireshark/epan/tvbuff.c -o /builds/wireshark/wireshark/sbout/2024-10-21-100301-3898-1 -Xclang -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2024-10-21-100301-3898-1 -x c /builds/wireshark/wireshark/epan/tvbuff.c
1/* tvbuff.c
2 *
3 * Testy, Virtual(-izable) Buffer of uint8_t*'s
4 *
5 * "Testy" -- the buffer gets mad when an attempt to access data
6 * beyond the bounds of the buffer. An exception is thrown.
7 *
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
10 * other tvbuffs.
11 *
12 * Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
13 *
14 * Code to convert IEEE floating point formats to native floating point
15 * derived from code Copyright (c) Ashok Narayanan, 2000
16 *
17 * Wireshark - Network traffic analyzer
18 * By Gerald Combs <gerald@wireshark.org>
19 * Copyright 1998 Gerald Combs
20 *
21 * SPDX-License-Identifier: GPL-2.0-or-later
22 */
23
24#include "config.h"
25
26#include <string.h>
27#include <stdio.h>
28#include <errno(*__errno_location ()).h>
29
30#include <glib.h>
31
32#include "wsutil/pint.h"
33#include "wsutil/sign_ext.h"
34#include "wsutil/strtoi.h"
35#include "wsutil/unicode-utils.h"
36#include "wsutil/nstime.h"
37#include "wsutil/time_util.h"
38#include <wsutil/ws_assert.h>
39#include "tvbuff.h"
40#include "tvbuff-int.h"
41#include "strutil.h"
42#include "to_str.h"
43#include "charsets.h"
44#include "proto.h" /* XXX - only used for DISSECTOR_ASSERT, probably a new header file? */
45#include "exceptions.h"
46
47#include <time.h>
48
49static uint64_t
50_tvb_get_bits64(tvbuff_t *tvb, unsigned bit_offset, const int total_no_of_bits);
51
52static uint64_t
53_tvb_get_bits64_le(tvbuff_t *tvb, unsigned bit_offset, const int total_no_of_bits);
54
55static inline int
56_tvb_captured_length_remaining(const tvbuff_t *tvb, const int offset);
57
58static inline const uint8_t*
59ensure_contiguous(tvbuff_t *tvb, const int offset, const int length);
60
61static inline uint8_t *
62tvb_get_raw_string(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, const int length);
63
64tvbuff_t *
65tvb_new(const struct tvb_ops *ops)
66{
67 tvbuff_t *tvb;
68 size_t size = ops->tvb_size;
69
70 ws_assert(size >= sizeof(*tvb))do { if ((1) && !(size >= sizeof(*tvb))) ws_log_fatal_full
("", LOG_LEVEL_ERROR, "epan/tvbuff.c", 70, __func__, "assertion failed: %s"
, "size >= sizeof(*tvb)"); } while (0)
;
71
72 tvb = (tvbuff_t *) g_slice_alloc(size);
73
74 tvb->next = NULL((void*)0);
75 tvb->ops = ops;
76 tvb->initialized = false0;
77 tvb->flags = 0;
78 tvb->length = 0;
79 tvb->reported_length = 0;
80 tvb->contained_length = 0;
81 tvb->real_data = NULL((void*)0);
82 tvb->raw_offset = -1;
83 tvb->ds_tvb = NULL((void*)0);
84
85 return tvb;
86}
87
88static void
89tvb_free_internal(tvbuff_t *tvb)
90{
91 size_t size;
92
93 DISSECTOR_ASSERT(tvb)((void) ((tvb) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/tvbuff.c", 93, "tvb"))))
;
94
95 if (tvb->ops->tvb_free)
96 tvb->ops->tvb_free(tvb);
97
98 size = tvb->ops->tvb_size;
99
100 g_slice_free1(size, tvb);
101}
102
103/* XXX: just call tvb_free_chain();
104 * Not removed so that existing dissectors using tvb_free() need not be changed.
105 * I'd argue that existing calls to tvb_free() should have actually beeen
106 * calls to tvb_free_chain() although the calls were OK as long as no
107 * subsets, etc had been created on the tvb. */
108void
109tvb_free(tvbuff_t *tvb)
110{
111 tvb_free_chain(tvb);
112}
113
114void
115tvb_free_chain(tvbuff_t *tvb)
116{
117 tvbuff_t *next_tvb;
118 DISSECTOR_ASSERT(tvb)((void) ((tvb) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/tvbuff.c", 118, "tvb"))))
;
119 while (tvb) {
120 next_tvb = tvb->next;
121 tvb_free_internal(tvb);
122 tvb = next_tvb;
123 }
124}
125
126tvbuff_t *
127tvb_new_chain(tvbuff_t *parent, tvbuff_t *backing)
128{
129 tvbuff_t *tvb = tvb_new_proxy(backing);
130
131 tvb_add_to_chain(parent, tvb);
132 return tvb;
133}
134
135void
136tvb_add_to_chain(tvbuff_t *parent, tvbuff_t *child)
137{
138 tvbuff_t *tmp;
139
140 DISSECTOR_ASSERT(parent)((void) ((parent) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/tvbuff.c", 140, "parent"))))
;
141 DISSECTOR_ASSERT(child)((void) ((child) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/tvbuff.c", 141, "child"))))
;
142
143 while (child) {
144 tmp = child;
145 child = child->next;
146
147 tmp->next = parent->next;
148 parent->next = tmp;
149 }
150}
151
152/*
153 * Check whether that offset goes more than one byte past the
154 * end of the buffer.
155 *
156 * If not, return 0; otherwise, return exception
157 */
158static inline int
159validate_offset(const tvbuff_t *tvb, const unsigned abs_offset)
160{
161 if (G_LIKELY(abs_offset <= tvb->length)(abs_offset <= tvb->length)) {
162 /* It's OK. */
163 return 0;
164 }
165
166 /*
167 * It's not OK, but why? Which boundaries is it
168 * past?
169 */
170 if (abs_offset <= tvb->contained_length) {
171 /*
172 * It's past the captured length, but not past
173 * the reported end of any parent tvbuffs from
174 * which this is constructed, or the reported
175 * end of this tvbuff, so it's out of bounds
176 * solely because we're past the end of the
177 * captured data.
178 */
179 return BoundsError1;
180 }
181
182 /*
183 * There's some actual packet boundary, not just the
184 * artificial boundary imposed by packet slicing, that
185 * we're past.
186 */
187
188 if (tvb->flags & TVBUFF_FRAGMENT0x00000001) {
189 /*
190 * This tvbuff is the first fragment of a larger
191 * packet that hasn't been reassembled, so we
192 * assume that's the source of the problem - if
193 * we'd reassembled the packet, we wouldn't have
194 * gone past the end.
195 *
196 * That might not be true, but for at least
197 * some forms of reassembly, such as IP
198 * reassembly, you don't know how big the
199 * reassembled packet is unless you reassemble
200 * it, so, in those cases, we can't determine
201 * whether we would have gone past the end
202 * had we reassembled the packet.
203 */
204 return FragmentBoundsError4;
205 }
206
207 /* OK, we're not an unreassembled fragment (that we know of). */
208 if (abs_offset <= tvb->reported_length) {
209 /*
210 * We're within the bounds of what this tvbuff
211 * purportedly contains, based on some length
212 * value, but we're not within the bounds of
213 * something from which this tvbuff was
214 * extracted, so that length value ran past
215 * the end of some parent tvbuff.
216 */
217 return ContainedBoundsError2;
218 }
219
220 /*
221 * OK, it looks as if we ran past the claimed length
222 * of data.
223 */
224 return ReportedBoundsError3;
225}
226
227static inline int
228compute_offset(const tvbuff_t *tvb, const int offset, unsigned *offset_ptr)
229{
230 if (offset >= 0) {
231 /* Positive offset - relative to the beginning of the packet. */
232 if (G_LIKELY((unsigned) offset <= tvb->length)((unsigned) offset <= tvb->length)) {
233 *offset_ptr = offset;
234 } else if ((unsigned) offset <= tvb->contained_length) {
235 return BoundsError1;
236 } else if (tvb->flags & TVBUFF_FRAGMENT0x00000001) {
237 return FragmentBoundsError4;
238 } else if ((unsigned) offset <= tvb->reported_length) {
239 return ContainedBoundsError2;
240 } else {
241 return ReportedBoundsError3;
242 }
243 }
244 else {
245 /* Negative offset - relative to the end of the packet. */
246 if (G_LIKELY((unsigned) -offset <= tvb->length)((unsigned) -offset <= tvb->length)) {
247 *offset_ptr = tvb->length + offset;
248 } else if ((unsigned) -offset <= tvb->contained_length) {
249 return BoundsError1;
250 } else if (tvb->flags & TVBUFF_FRAGMENT0x00000001) {
251 return FragmentBoundsError4;
252 } else if ((unsigned) -offset <= tvb->reported_length) {
253 return ContainedBoundsError2;
254 } else {
255 return ReportedBoundsError3;
256 }
257 }
258
259 return 0;
260}
261
262static inline int
263compute_offset_and_remaining(const tvbuff_t *tvb, const int offset, unsigned *offset_ptr, unsigned *rem_len)
264{
265 int exception;
266
267 exception = compute_offset(tvb, offset, offset_ptr);
268 if (!exception)
269 *rem_len = tvb->length - *offset_ptr;
270
271 return exception;
272}
273
274/* Computes the absolute offset and length based on a possibly-negative offset
275 * and a length that is possible -1 (which means "to the end of the data").
276 * Returns integer indicating whether the offset is in bounds (0) or
277 * not (exception number). The integer ptrs are modified with the new offset,
278 * captured (available) length, and contained length (amount that's present
279 * in the parent tvbuff based on its reported length).
280 * No exception is thrown; on success, we return 0, otherwise we return an
281 * exception for the caller to throw if appropriate.
282 *
283 * XXX - we return success (0), if the offset is positive and right
284 * after the end of the tvbuff (i.e., equal to the length). We do this
285 * so that a dissector constructing a subset tvbuff for the next protocol
286 * will get a zero-length tvbuff, not an exception, if there's no data
287 * left for the next protocol - we want the next protocol to be the one
288 * that gets an exception, so the error is reported as an error in that
289 * protocol rather than the containing protocol. */
290static inline int
291check_offset_length_no_exception(const tvbuff_t *tvb,
292 const int offset, int const length_val,
293 unsigned *offset_ptr, unsigned *length_ptr)
294{
295 unsigned end_offset;
296 int exception;
297
298 DISSECTOR_ASSERT(offset_ptr)((void) ((offset_ptr) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 298, "offset_ptr"
))))
;
299 DISSECTOR_ASSERT(length_ptr)((void) ((length_ptr) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 299, "length_ptr"
))))
;
300
301 /* Compute the offset */
302 exception = compute_offset(tvb, offset, offset_ptr);
303 if (exception)
304 return exception;
305
306 if (length_val < -1) {
307 /* XXX - ReportedBoundsError? */
308 return BoundsError1;
309 }
310
311 /* Compute the length */
312 if (length_val == -1)
313 *length_ptr = tvb->length - *offset_ptr;
314 else
315 *length_ptr = length_val;
316
317 /*
318 * Compute the offset of the first byte past the length.
319 */
320 end_offset = *offset_ptr + *length_ptr;
321
322 /*
323 * Check for an overflow
324 */
325 if (end_offset < *offset_ptr)
326 return BoundsError1;
327
328 return validate_offset(tvb, end_offset);
329}
330
331/* Checks (+/-) offset and length and throws an exception if
332 * either is out of bounds. Sets integer ptrs to the new offset
333 * and length. */
334static inline void
335check_offset_length(const tvbuff_t *tvb,
336 const int offset, int const length_val,
337 unsigned *offset_ptr, unsigned *length_ptr)
338{
339 int exception;
340
341 exception = check_offset_length_no_exception(tvb, offset, length_val, offset_ptr, length_ptr);
342 if (exception)
343 THROW(exception)except_throw(1, (exception), ((void*)0));
344}
345
346void
347tvb_check_offset_length(const tvbuff_t *tvb,
348 const int offset, int const length_val,
349 unsigned *offset_ptr, unsigned *length_ptr)
350{
351 check_offset_length(tvb, offset, length_val, offset_ptr, length_ptr);
352}
353
354static const unsigned char left_aligned_bitmask[] = {
355 0xff,
356 0x80,
357 0xc0,
358 0xe0,
359 0xf0,
360 0xf8,
361 0xfc,
362 0xfe
363};
364
365tvbuff_t *
366tvb_new_octet_aligned(tvbuff_t *tvb, uint32_t bit_offset, int32_t no_of_bits)
367{
368 tvbuff_t *sub_tvb = NULL((void*)0);
369 uint32_t byte_offset;
370 int32_t datalen, i;
371 uint8_t left, right, remaining_bits, *buf;
372 const uint8_t *data;
373
374 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 374, "tvb && tvb->initialized"
))))
;
375
376 byte_offset = bit_offset >> 3;
377 left = bit_offset % 8; /* for left-shifting */
378 right = 8 - left; /* for right-shifting */
379
380 if (no_of_bits == -1) {
381 datalen = _tvb_captured_length_remaining(tvb, byte_offset);
382 remaining_bits = 0;
383 } else {
384 datalen = no_of_bits >> 3;
385 remaining_bits = no_of_bits % 8;
386 if (remaining_bits) {
387 datalen++;
388 }
389 }
390
391 /* already aligned -> shortcut */
392 if ((left == 0) && (remaining_bits == 0)) {
393 return tvb_new_subset_length_caplen(tvb, byte_offset, datalen, datalen);
394 }
395
396 DISSECTOR_ASSERT(datalen>0)((void) ((datalen>0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 396, "datalen>0"
))))
;
397
398 /* if at least one trailing byte is available, we must use the content
399 * of that byte for the last shift (i.e. tvb_get_ptr() must use datalen + 1
400 * if non extra byte is available, the last shifted byte requires
401 * special treatment
402 */
403 if (_tvb_captured_length_remaining(tvb, byte_offset) > datalen) {
404 data = ensure_contiguous(tvb, byte_offset, datalen + 1); /* tvb_get_ptr */
405
406 /* Do this allocation AFTER tvb_get_ptr() (which could throw an exception) */
407 buf = (uint8_t *)g_malloc(datalen);
408
409 /* shift tvb data bit_offset bits to the left */
410 for (i = 0; i < datalen; i++)
411 buf[i] = (data[i] << left) | (data[i+1] >> right);
412 } else {
413 data = ensure_contiguous(tvb, byte_offset, datalen); /* tvb_get_ptr() */
414
415 /* Do this allocation AFTER tvb_get_ptr() (which could throw an exception) */
416 buf = (uint8_t *)g_malloc(datalen);
417
418 /* shift tvb data bit_offset bits to the left */
419 for (i = 0; i < (datalen-1); i++)
420 buf[i] = (data[i] << left) | (data[i+1] >> right);
421 buf[datalen-1] = data[datalen-1] << left; /* set last octet */
422 }
423 buf[datalen-1] &= left_aligned_bitmask[remaining_bits];
424
425 sub_tvb = tvb_new_child_real_data(tvb, buf, datalen, datalen);
426 tvb_set_free_cb(sub_tvb, g_free);
427
428 return sub_tvb;
429}
430
431tvbuff_t *
432tvb_new_octet_right_aligned(tvbuff_t *tvb, uint32_t bit_offset, int32_t no_of_bits)
433{
434 tvbuff_t *sub_tvb = NULL((void*)0);
435 uint32_t byte_offset;
436 int src_len, dst_len, i;
437 uint8_t left, right, remaining_bits, *buf;
438 const uint8_t *data;
439
440 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 440, "tvb && tvb->initialized"
))))
;
441
442 byte_offset = bit_offset / 8;
443 /* right shift to put bits in place and discard least significant bits */
444 right = bit_offset % 8;
445 /* left shift to get most significant bits from next octet */
446 left = 8 - right;
447
448 if (no_of_bits == -1) {
449 dst_len = _tvb_captured_length_remaining(tvb, byte_offset);
450 remaining_bits = 0;
451 } else {
452 dst_len = no_of_bits / 8;
453 remaining_bits = no_of_bits % 8;
454 if (remaining_bits) {
455 dst_len++;
456 }
457 }
458
459 /* already aligned -> shortcut */
460 if ((right == 0) && (remaining_bits == 0)) {
461 return tvb_new_subset_length_caplen(tvb, byte_offset, dst_len, dst_len);
462 }
463
464 DISSECTOR_ASSERT(dst_len>0)((void) ((dst_len>0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 464, "dst_len>0"
))))
;
465
466 if (_tvb_captured_length_remaining(tvb, byte_offset) > dst_len) {
467 /* last octet will get data from trailing octet */
468 src_len = dst_len + 1;
469 } else {
470 /* last octet will be zero padded */
471 src_len = dst_len;
472 }
473
474 data = ensure_contiguous(tvb, byte_offset, src_len); /* tvb_get_ptr */
475
476 /* Do this allocation AFTER tvb_get_ptr() (which could throw an exception) */
477 buf = (uint8_t *)g_malloc(dst_len);
478
479 for (i = 0; i < (dst_len - 1); i++)
480 buf[i] = (data[i] >> right) | (data[i+1] << left);
481
482 /* Special handling for last octet */
483 buf[i] = (data[i] >> right);
484 /* Shift most significant bits from trailing octet if available */
485 if (src_len > dst_len)
486 buf[i] |= (data[i+1] << left);
487 /* Preserve only remaining bits in last octet if not multiple of 8 */
488 if (remaining_bits)
489 buf[i] &= ((1 << remaining_bits) - 1);
490
491 sub_tvb = tvb_new_child_real_data(tvb, buf, dst_len, dst_len);
492 tvb_set_free_cb(sub_tvb, g_free);
493
494 return sub_tvb;
495}
496
497static tvbuff_t *
498tvb_generic_clone_offset_len(tvbuff_t *tvb, unsigned offset, unsigned len)
499{
500 tvbuff_t *cloned_tvb;
501 uint8_t *data;
502
503 DISSECTOR_ASSERT(tvb_bytes_exist(tvb, offset, len))((void) ((tvb_bytes_exist(tvb, offset, len)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 503, "tvb_bytes_exist(tvb, offset, len)"
))))
;
504
505 data = (uint8_t *) g_malloc(len);
506
507 tvb_memcpy(tvb, data, offset, len);
508
509 cloned_tvb = tvb_new_real_data(data, len, len);
510 tvb_set_free_cb(cloned_tvb, g_free);
511
512 return cloned_tvb;
513}
514
515tvbuff_t *
516tvb_clone_offset_len(tvbuff_t *tvb, unsigned offset, unsigned len)
517{
518 if (tvb->ops->tvb_clone) {
519 tvbuff_t *cloned_tvb;
520
521 cloned_tvb = tvb->ops->tvb_clone(tvb, offset, len);
522 if (cloned_tvb)
523 return cloned_tvb;
524 }
525
526 return tvb_generic_clone_offset_len(tvb, offset, len);
527}
528
529tvbuff_t *
530tvb_clone(tvbuff_t *tvb)
531{
532 return tvb_clone_offset_len(tvb, 0, tvb->length);
533}
534
535unsigned
536tvb_captured_length(const tvbuff_t *tvb)
537{
538 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 538, "tvb && tvb->initialized"
))))
;
539
540 return tvb->length;
541}
542
543/* For tvbuff internal use */
544static inline int
545_tvb_captured_length_remaining(const tvbuff_t *tvb, const int offset)
546{
547 unsigned abs_offset = 0, rem_length;
548 int exception;
549
550 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &rem_length);
551 if (exception)
552 return 0;
553
554 return rem_length;
555}
556
557int
558tvb_captured_length_remaining(const tvbuff_t *tvb, const int offset)
559{
560 unsigned abs_offset = 0, rem_length;
561 int exception;
562
563 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 563, "tvb && tvb->initialized"
))))
;
564
565 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &rem_length);
566 if (exception)
567 return 0;
568
569 return rem_length;
570}
571
572unsigned
573tvb_ensure_captured_length_remaining(const tvbuff_t *tvb, const int offset)
574{
575 unsigned abs_offset = 0, rem_length = 0;
576 int exception;
577
578 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 578, "tvb && tvb->initialized"
))))
;
579
580 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &rem_length);
581 if (exception)
582 THROW(exception)except_throw(1, (exception), ((void*)0));
583
584 if (rem_length == 0) {
585 /*
586 * This routine ensures there's at least one byte available.
587 * There aren't any bytes available, so throw the appropriate
588 * exception.
589 */
590 if (abs_offset < tvb->contained_length) {
591 THROW(BoundsError)except_throw(1, (1), ((void*)0));
592 } else if (tvb->flags & TVBUFF_FRAGMENT0x00000001) {
593 THROW(FragmentBoundsError)except_throw(1, (4), ((void*)0));
594 } else if (abs_offset < tvb->reported_length) {
595 THROW(ContainedBoundsError)except_throw(1, (2), ((void*)0));
596 } else {
597 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
598 }
599 }
600 return rem_length;
601}
602
603/* Validates that 'length' bytes are available starting from
604 * offset (pos/neg). Does not throw an exception. */
605bool_Bool
606tvb_bytes_exist(const tvbuff_t *tvb, const int offset, const int length)
607{
608 unsigned abs_offset = 0, abs_length;
609 int exception;
610
611 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 611, "tvb && tvb->initialized"
))))
;
612
613 /*
614 * Negative lengths are not possible and indicate a bug (e.g. arithmetic
615 * error or an overly large value from packet data).
616 */
617 if (length < 0)
618 return false0;
619
620 exception = check_offset_length_no_exception(tvb, offset, length, &abs_offset, &abs_length);
621 if (exception)
622 return false0;
623
624 return true1;
625}
626
627/* Validates that 'length' bytes, where 'length' is a 64-bit unsigned
628 * integer, are available starting from offset (pos/neg). Throws an
629 * exception if they aren't. */
630void
631tvb_ensure_bytes_exist64(const tvbuff_t *tvb, const int offset, const uint64_t length)
632{
633 /*
634 * Make sure the value fits in a signed integer; if not, assume
635 * that means that it's too big.
636 */
637 if (length > INT_MAX2147483647) {
638 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
639 }
640
641 /* OK, now cast it and try it with tvb_ensure_bytes_exist(). */
642 tvb_ensure_bytes_exist(tvb, offset, (int)length);
643}
644
645/* Validates that 'length' bytes are available starting from
646 * offset (pos/neg). Throws an exception if they aren't. */
647void
648tvb_ensure_bytes_exist(const tvbuff_t *tvb, const int offset, const int length)
649{
650 unsigned real_offset, end_offset;
651
652 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 652, "tvb && tvb->initialized"
))))
;
653
654 /*
655 * -1 doesn't mean "until end of buffer", as that's pointless
656 * for this routine. We must treat it as a Really Large Positive
657 * Number, so that we throw an exception; we throw
658 * ReportedBoundsError, as if it were past even the end of a
659 * reassembled packet, and past the end of even the data we
660 * didn't capture.
661 *
662 * We do the same with other negative lengths.
663 */
664 if (length < 0) {
665 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
666 }
667
668 /* XXX: Below this point could be replaced with a call to
669 * check_offset_length with no functional change, however this is a
670 * *very* hot path and check_offset_length is not well-optimized for
671 * this case, so we eat some code duplication for a lot of speedup. */
672
673 if (offset >= 0) {
674 /* Positive offset - relative to the beginning of the packet. */
675 if (G_LIKELY((unsigned) offset <= tvb->length)((unsigned) offset <= tvb->length)) {
676 real_offset = offset;
677 } else if ((unsigned) offset <= tvb->contained_length) {
678 THROW(BoundsError)except_throw(1, (1), ((void*)0));
679 } else if (tvb->flags & TVBUFF_FRAGMENT0x00000001) {
680 THROW(FragmentBoundsError)except_throw(1, (4), ((void*)0));
681 } else if ((unsigned) offset <= tvb->reported_length) {
682 THROW(ContainedBoundsError)except_throw(1, (2), ((void*)0));
683 } else {
684 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
685 }
686 }
687 else {
688 /* Negative offset - relative to the end of the packet. */
689 if (G_LIKELY((unsigned) -offset <= tvb->length)((unsigned) -offset <= tvb->length)) {
690 real_offset = tvb->length + offset;
691 } else if ((unsigned) -offset <= tvb->contained_length) {
692 THROW(BoundsError)except_throw(1, (1), ((void*)0));
693 } else if (tvb->flags & TVBUFF_FRAGMENT0x00000001) {
694 THROW(FragmentBoundsError)except_throw(1, (4), ((void*)0));
695 } else if ((unsigned) -offset <= tvb->reported_length) {
696 THROW(ContainedBoundsError)except_throw(1, (2), ((void*)0));
697 } else {
698 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
699 }
700 }
701
702 /*
703 * Compute the offset of the first byte past the length.
704 */
705 end_offset = real_offset + length;
706
707 /*
708 * Check for an overflow
709 */
710 if (end_offset < real_offset)
711 THROW(BoundsError)except_throw(1, (1), ((void*)0));
712
713 if (G_LIKELY(end_offset <= tvb->length)(end_offset <= tvb->length))
714 return;
715 else if (end_offset <= tvb->contained_length)
716 THROW(BoundsError)except_throw(1, (1), ((void*)0));
717 else if (tvb->flags & TVBUFF_FRAGMENT0x00000001)
718 THROW(FragmentBoundsError)except_throw(1, (4), ((void*)0));
719 else if (end_offset <= tvb->reported_length)
720 THROW(ContainedBoundsError)except_throw(1, (2), ((void*)0));
721 else
722 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
723}
724
725bool_Bool
726tvb_offset_exists(const tvbuff_t *tvb, const int offset)
727{
728 unsigned abs_offset = 0;
729 int exception;
730
731 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 731, "tvb && tvb->initialized"
))))
;
732
733 exception = compute_offset(tvb, offset, &abs_offset);
734 if (exception)
735 return false0;
736
737 /* compute_offset only throws an exception on >, not >= because of the
738 * comment above check_offset_length_no_exception, but here we want the
739 * opposite behaviour so we check ourselves... */
740 return abs_offset < tvb->length;
741}
742
743unsigned
744tvb_reported_length(const tvbuff_t *tvb)
745{
746 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 746, "tvb && tvb->initialized"
))))
;
747
748 return tvb->reported_length;
749}
750
751int
752tvb_reported_length_remaining(const tvbuff_t *tvb, const int offset)
753{
754 unsigned abs_offset = 0;
755 int exception;
756
757 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 757, "tvb && tvb->initialized"
))))
;
758
759 exception = compute_offset(tvb, offset, &abs_offset);
760 if (exception)
761 return 0;
762
763 if (tvb->reported_length >= abs_offset)
764 return tvb->reported_length - abs_offset;
765 else
766 return 0;
767}
768
769unsigned
770tvb_ensure_reported_length_remaining(const tvbuff_t *tvb, const int offset)
771{
772 unsigned abs_offset = 0;
773 int exception;
774
775 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 775, "tvb && tvb->initialized"
))))
;
776
777 exception = compute_offset(tvb, offset, &abs_offset);
778 if (exception)
779 THROW(exception)except_throw(1, (exception), ((void*)0));
780
781 if (tvb->reported_length >= abs_offset)
782 return tvb->reported_length - abs_offset;
783 else
784 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
785}
786
787/* Set the reported length of a tvbuff to a given value; used for protocols
788 * whose headers contain an explicit length and where the calling
789 * dissector's payload may include padding as well as the packet for
790 * this protocol.
791 * Also adjusts the available and contained length. */
792void
793tvb_set_reported_length(tvbuff_t *tvb, const unsigned reported_length)
794{
795 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 795, "tvb && tvb->initialized"
))))
;
796
797 if (reported_length > tvb->reported_length)
798 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
799
800 tvb->reported_length = reported_length;
801 if (reported_length < tvb->length)
802 tvb->length = reported_length;
803 if (reported_length < tvb->contained_length)
804 tvb->contained_length = reported_length;
805}
806
807/* Repair a tvbuff where the captured length is greater than the
808 * reported length; such a tvbuff makes no sense, as it's impossible
809 * to capture more data than is in the packet.
810 */
811void
812tvb_fix_reported_length(tvbuff_t *tvb)
813{
814 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 814, "tvb && tvb->initialized"
))))
;
815 DISSECTOR_ASSERT(tvb->reported_length < tvb->length)((void) ((tvb->reported_length < tvb->length) ? (void
)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/tvbuff.c", 815, "tvb->reported_length < tvb->length"
))))
;
816
817 tvb->reported_length = tvb->length;
818 if (tvb->contained_length < tvb->length)
819 tvb->contained_length = tvb->length;
820}
821
822unsigned
823tvb_offset_from_real_beginning_counter(const tvbuff_t *tvb, const unsigned counter)
824{
825 if (tvb->ops->tvb_offset)
826 return tvb->ops->tvb_offset(tvb, counter);
827
828 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/tvbuff.c", 828))
;
829 return 0;
830}
831
832unsigned
833tvb_offset_from_real_beginning(const tvbuff_t *tvb)
834{
835 return tvb_offset_from_real_beginning_counter(tvb, 0);
836}
837
838static inline const uint8_t*
839ensure_contiguous_no_exception(tvbuff_t *tvb, const int offset, const int length, int *pexception)
840{
841 unsigned abs_offset = 0, abs_length = 0;
842 int exception;
843
844 exception = check_offset_length_no_exception(tvb, offset, length, &abs_offset, &abs_length);
845 if (exception) {
846 if (pexception)
847 *pexception = exception;
848 return NULL((void*)0);
849 }
850
851 /*
852 * Special case: if the caller (e.g. tvb_get_ptr) requested no data,
853 * then it is acceptable to have an empty tvb (!tvb->real_data).
854 */
855 if (length == 0) {
856 return NULL((void*)0);
857 }
858
859 /*
860 * We know that all the data is present in the tvbuff, so
861 * no exceptions should be thrown.
862 */
863 if (tvb->real_data)
864 return tvb->real_data + abs_offset;
865
866 if (tvb->ops->tvb_get_ptr)
867 return tvb->ops->tvb_get_ptr(tvb, abs_offset, abs_length);
868
869 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/tvbuff.c", 869))
;
870 return NULL((void*)0);
871}
872
873static inline const uint8_t*
874ensure_contiguous(tvbuff_t *tvb, const int offset, const int length)
875{
876 int exception = 0;
877 const uint8_t *p;
878
879 p = ensure_contiguous_no_exception(tvb, offset, length, &exception);
880 if (p == NULL((void*)0) && length != 0) {
881 DISSECTOR_ASSERT(exception > 0)((void) ((exception > 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 881, "exception > 0"
))))
;
882 THROW(exception)except_throw(1, (exception), ((void*)0));
883 }
884 return p;
885}
886
887static inline const uint8_t*
888fast_ensure_contiguous(tvbuff_t *tvb, const int offset, const unsigned length)
889{
890 unsigned end_offset;
891 unsigned u_offset;
892
893 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 893, "tvb && tvb->initialized"
))))
;
894 /* We don't check for overflow in this fast path so we only handle simple types */
895 DISSECTOR_ASSERT(length <= 8)((void) ((length <= 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 895, "length <= 8"
))))
;
896
897 if (offset < 0 || !tvb->real_data) {
898 return ensure_contiguous(tvb, offset, length);
899 }
900
901 u_offset = offset;
902 end_offset = u_offset + length;
903
904 if (G_LIKELY(end_offset <= tvb->length)(end_offset <= tvb->length)) {
905 return tvb->real_data + u_offset;
906 } else if (end_offset <= tvb->contained_length) {
907 THROW(BoundsError)except_throw(1, (1), ((void*)0));
908 } else if (tvb->flags & TVBUFF_FRAGMENT0x00000001) {
909 THROW(FragmentBoundsError)except_throw(1, (4), ((void*)0));
910 } else if (end_offset <= tvb->reported_length) {
911 THROW(ContainedBoundsError)except_throw(1, (2), ((void*)0));
912 } else {
913 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
914 }
915 /* not reached */
916 return NULL((void*)0);
917}
918
919
920
921/************** ACCESSORS **************/
922
923void *
924tvb_memcpy(tvbuff_t *tvb, void *target, const int offset, size_t length)
925{
926 unsigned abs_offset = 0, abs_length = 0;
927
928 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 928, "tvb && tvb->initialized"
))))
;
929
930 /*
931 * XXX - we should eliminate the "length = -1 means 'to the end
932 * of the tvbuff'" convention, and use other means to achieve
933 * that; this would let us eliminate a bunch of checks for
934 * negative lengths in cases where the protocol has a 32-bit
935 * length field.
936 *
937 * Allowing -1 but throwing an assertion on other negative
938 * lengths is a bit more work with the length being a size_t;
939 * instead, we check for a length <= 2^31-1.
940 */
941 DISSECTOR_ASSERT(length <= 0x7FFFFFFF)((void) ((length <= 0x7FFFFFFF) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 941, "length <= 0x7FFFFFFF"
))))
;
942 check_offset_length(tvb, offset, (int) length, &abs_offset, &abs_length);
943
944 if (target && tvb->real_data) {
945 return memcpy(target, tvb->real_data + abs_offset, abs_length);
946 }
947
948 if (target && tvb->ops->tvb_memcpy)
949 return tvb->ops->tvb_memcpy(tvb, target, abs_offset, abs_length);
950
951 /*
952 * If the length is 0, there's nothing to do.
953 * (tvb->real_data could be null if it's allocated with
954 * a size of length.)
955 */
956 if (length != 0) {
957 /*
958 * XXX, fallback to slower method
959 */
960 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/tvbuff.c", 960))
;
961 }
962 return NULL((void*)0);
963}
964
965
966/*
967 * XXX - this doesn't treat a length of -1 as an error.
968 * If it did, this could replace some code that calls
969 * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies
970 * data to it.
971 *
972 * "composite_get_ptr()" depends on -1 not being
973 * an error; does anything else depend on this routine treating -1 as
974 * meaning "to the end of the buffer"?
975 *
976 * If scope is NULL, memory is allocated with g_malloc() and user must
977 * explicitly free it with g_free().
978 * If scope is not NULL, memory is allocated with the corresponding pool
979 * lifetime.
980 */
981void *
982tvb_memdup(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, size_t length)
983{
984 unsigned abs_offset = 0, abs_length = 0;
985 void *duped;
986
987 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 987, "tvb && tvb->initialized"
))))
;
988
989 check_offset_length(tvb, offset, (int) length, &abs_offset, &abs_length);
990
991 if (abs_length == 0)
992 return NULL((void*)0);
993
994 duped = wmem_alloc(scope, abs_length);
995 return tvb_memcpy(tvb, duped, abs_offset, abs_length);
996}
997
998
999
1000const uint8_t*
1001tvb_get_ptr(tvbuff_t *tvb, const int offset, const int length)
1002{
1003 return ensure_contiguous(tvb, offset, length);
1004}
1005
1006/* ---------------- */
1007uint8_t
1008tvb_get_uint8(tvbuff_t *tvb, const int offset)
1009{
1010 const uint8_t *ptr;
1011
1012 ptr = fast_ensure_contiguous(tvb, offset, 1);
1013 return *ptr;
1014}
1015
1016int8_t
1017tvb_get_int8(tvbuff_t *tvb, const int offset)
1018{
1019 const uint8_t *ptr;
1020
1021 ptr = fast_ensure_contiguous(tvb, offset, 1);
1022 return *ptr;
1023}
1024
1025uint16_t
1026tvb_get_ntohs(tvbuff_t *tvb, const int offset)
1027{
1028 const uint8_t *ptr;
1029
1030 ptr = fast_ensure_contiguous(tvb, offset, 2);
1031 return pntoh16(ptr);
1032}
1033
1034int16_t
1035tvb_get_ntohis(tvbuff_t *tvb, const int offset)
1036{
1037 const uint8_t *ptr;
1038
1039 ptr = fast_ensure_contiguous(tvb, offset, 2);
1040 return pntoh16(ptr);
1041}
1042
1043uint32_t
1044tvb_get_ntoh24(tvbuff_t *tvb, const int offset)
1045{
1046 const uint8_t *ptr;
1047
1048 ptr = fast_ensure_contiguous(tvb, offset, 3);
1049 return pntoh24(ptr);
1050}
1051
1052int32_t
1053tvb_get_ntohi24(tvbuff_t *tvb, const int offset)
1054{
1055 uint32_t ret;
1056
1057 ret = ws_sign_ext32(tvb_get_ntoh24(tvb, offset), 24);
1058
1059 return (int32_t)ret;
1060}
1061
1062uint32_t
1063tvb_get_ntohl(tvbuff_t *tvb, const int offset)
1064{
1065 const uint8_t *ptr;
1066
1067 ptr = fast_ensure_contiguous(tvb, offset, 4);
1068 return pntoh32(ptr);
1069}
1070
1071int32_t
1072tvb_get_ntohil(tvbuff_t *tvb, const int offset)
1073{
1074 const uint8_t *ptr;
1075
1076 ptr = fast_ensure_contiguous(tvb, offset, 4);
1077 return pntoh32(ptr);
1078}
1079
1080uint64_t
1081tvb_get_ntoh40(tvbuff_t *tvb, const int offset)
1082{
1083 const uint8_t *ptr;
1084
1085 ptr = fast_ensure_contiguous(tvb, offset, 5);
1086 return pntoh40(ptr);
1087}
1088
1089int64_t
1090tvb_get_ntohi40(tvbuff_t *tvb, const int offset)
1091{
1092 uint64_t ret;
1093
1094 ret = ws_sign_ext64(tvb_get_ntoh40(tvb, offset), 40);
1095
1096 return (int64_t)ret;
1097}
1098
1099uint64_t
1100tvb_get_ntoh48(tvbuff_t *tvb, const int offset)
1101{
1102 const uint8_t *ptr;
1103
1104 ptr = fast_ensure_contiguous(tvb, offset, 6);
1105 return pntoh48(ptr);
1106}
1107
1108int64_t
1109tvb_get_ntohi48(tvbuff_t *tvb, const int offset)
1110{
1111 uint64_t ret;
1112
1113 ret = ws_sign_ext64(tvb_get_ntoh48(tvb, offset), 48);
1114
1115 return (int64_t)ret;
1116}
1117
1118uint64_t
1119tvb_get_ntoh56(tvbuff_t *tvb, const int offset)
1120{
1121 const uint8_t *ptr;
1122
1123 ptr = fast_ensure_contiguous(tvb, offset, 7);
1124 return pntoh56(ptr);
1125}
1126
1127int64_t
1128tvb_get_ntohi56(tvbuff_t *tvb, const int offset)
1129{
1130 uint64_t ret;
1131
1132 ret = ws_sign_ext64(tvb_get_ntoh56(tvb, offset), 56);
1133
1134 return (int64_t)ret;
1135}
1136
1137uint64_t
1138tvb_get_ntoh64(tvbuff_t *tvb, const int offset)
1139{
1140 const uint8_t *ptr;
1141
1142 ptr = fast_ensure_contiguous(tvb, offset, 8);
1143 return pntoh64(ptr);
1144}
1145
1146int64_t
1147tvb_get_ntohi64(tvbuff_t *tvb, const int offset)
1148{
1149 const uint8_t *ptr;
1150
1151 ptr = fast_ensure_contiguous(tvb, offset, 8);
1152 return pntoh64(ptr);
1153}
1154
1155uint16_t
1156tvb_get_uint16(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1157 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1158 return tvb_get_letohs(tvb, offset);
1159 } else {
1160 return tvb_get_ntohs(tvb, offset);
1161 }
1162}
1163
1164int16_t
1165tvb_get_int16(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1166 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1167 return tvb_get_letohis(tvb, offset);
1168 } else {
1169 return tvb_get_ntohis(tvb, offset);
1170 }
1171}
1172
1173uint32_t
1174tvb_get_uint24(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1175 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1176 return tvb_get_letoh24(tvb, offset);
1177 } else {
1178 return tvb_get_ntoh24(tvb, offset);
1179 }
1180}
1181
1182int32_t
1183tvb_get_int24(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1184 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1185 return tvb_get_letohi24(tvb, offset);
1186 } else {
1187 return tvb_get_ntohi24(tvb, offset);
1188 }
1189}
1190
1191uint32_t
1192tvb_get_uint32(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1193 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1194 return tvb_get_letohl(tvb, offset);
1195 } else {
1196 return tvb_get_ntohl(tvb, offset);
1197 }
1198}
1199
1200int32_t
1201tvb_get_int32(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1202 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1203 return tvb_get_letohil(tvb, offset);
1204 } else {
1205 return tvb_get_ntohil(tvb, offset);
1206 }
1207}
1208
1209uint64_t
1210tvb_get_uint40(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1211 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1212 return tvb_get_letoh40(tvb, offset);
1213 } else {
1214 return tvb_get_ntoh40(tvb, offset);
1215 }
1216}
1217
1218int64_t
1219tvb_get_int40(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1220 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1221 return tvb_get_letohi40(tvb, offset);
1222 } else {
1223 return tvb_get_ntohi40(tvb, offset);
1224 }
1225}
1226
1227uint64_t
1228tvb_get_uint48(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1229 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1230 return tvb_get_letoh48(tvb, offset);
1231 } else {
1232 return tvb_get_ntoh48(tvb, offset);
1233 }
1234}
1235
1236int64_t
1237tvb_get_int48(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1238 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1239 return tvb_get_letohi48(tvb, offset);
1240 } else {
1241 return tvb_get_ntohi48(tvb, offset);
1242 }
1243}
1244
1245uint64_t
1246tvb_get_uint56(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1247 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1248 return tvb_get_letoh56(tvb, offset);
1249 } else {
1250 return tvb_get_ntoh56(tvb, offset);
1251 }
1252}
1253
1254int64_t
1255tvb_get_int56(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1256 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1257 return tvb_get_letohi56(tvb, offset);
1258 } else {
1259 return tvb_get_ntohi56(tvb, offset);
1260 }
1261}
1262
1263uint64_t
1264tvb_get_uint64(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1265 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1266 return tvb_get_letoh64(tvb, offset);
1267 } else {
1268 return tvb_get_ntoh64(tvb, offset);
1269 }
1270}
1271
1272int64_t
1273tvb_get_int64(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1274 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1275 return tvb_get_letohi64(tvb, offset);
1276 } else {
1277 return tvb_get_ntohi64(tvb, offset);
1278 }
1279}
1280
1281float
1282tvb_get_ieee_float(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1283 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1284 return tvb_get_letohieee_float(tvb, offset);
1285 } else {
1286 return tvb_get_ntohieee_float(tvb, offset);
1287 }
1288}
1289
1290double
1291tvb_get_ieee_double(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1292 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1293 return tvb_get_letohieee_double(tvb, offset);
1294 } else {
1295 return tvb_get_ntohieee_double(tvb, offset);
1296 }
1297}
1298
1299/*
1300 * Stuff for IEEE float handling on platforms that don't have IEEE
1301 * format as the native floating-point format.
1302 *
1303 * For now, we treat only the VAX as such a platform.
1304 *
1305 * XXX - other non-IEEE boxes that can run UN*X include some Crays,
1306 * and possibly other machines. However, I don't know whether there
1307 * are any other machines that could run Wireshark and that don't use
1308 * IEEE format. As far as I know, all of the main current and past
1309 * commercial microprocessor families on which OSes that support
1310 * Wireshark can run use IEEE format (x86, ARM, 68k, SPARC, MIPS,
1311 * PA-RISC, Alpha, IA-64, and so on), and it appears that the official
1312 * Linux port to System/390 and zArchitecture uses IEEE format floating-
1313 * point rather than IBM hex floating-point (not a huge surprise), so
1314 * I'm not sure that leaves any 32-bit or larger UN*X or Windows boxes,
1315 * other than VAXes, that don't use IEEE format. If you're not running
1316 * UN*X or Windows, the floating-point format is probably going to be
1317 * the least of your problems in a port.
1318 */
1319
1320#if defined(vax)
1321
1322#include <math.h>
1323
1324/*
1325 * Single-precision.
1326 */
1327#define IEEE_SP_NUMBER_WIDTH 32 /* bits in number */
1328#define IEEE_SP_EXP_WIDTH 8 /* bits in exponent */
1329#define IEEE_SP_MANTISSA_WIDTH 23 /* IEEE_SP_NUMBER_WIDTH - 1 - IEEE_SP_EXP_WIDTH */
1330
1331#define IEEE_SP_SIGN_MASK 0x80000000
1332#define IEEE_SP_EXPONENT_MASK 0x7F800000
1333#define IEEE_SP_MANTISSA_MASK 0x007FFFFF
1334#define IEEE_SP_INFINITY IEEE_SP_EXPONENT_MASK
1335
1336#define IEEE_SP_IMPLIED_BIT (1 << IEEE_SP_MANTISSA_WIDTH)
1337#define IEEE_SP_INFINITE ((1 << IEEE_SP_EXP_WIDTH) - 1)
1338#define IEEE_SP_BIAS ((1 << (IEEE_SP_EXP_WIDTH - 1)) - 1)
1339
1340static int
1341ieee_float_is_zero(const uint32_t w)
1342{
1343 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1344}
1345
1346static float
1347get_ieee_float(const uint32_t w)
1348{
1349 long sign;
1350 long exponent;
1351 long mantissa;
1352
1353 sign = w & IEEE_SP_SIGN_MASK;
1354 exponent = w & IEEE_SP_EXPONENT_MASK;
1355 mantissa = w & IEEE_SP_MANTISSA_MASK;
1356
1357 if (ieee_float_is_zero(w)) {
1358 /* number is zero, unnormalized, or not-a-number */
1359 return 0.0;
1360 }
1361#if 0
1362 /*
1363 * XXX - how to handle this?
1364 */
1365 if (IEEE_SP_INFINITY == exponent) {
1366 /*
1367 * number is positive or negative infinity, or a special value
1368 */
1369 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1370 }
1371#endif
1372
1373 exponent = ((exponent >> IEEE_SP_MANTISSA_WIDTH) - IEEE_SP_BIAS) -
1374 IEEE_SP_MANTISSA_WIDTH;
1375 mantissa |= IEEE_SP_IMPLIED_BIT;
1376
1377 if (sign)
1378 return -mantissa * pow(2, exponent);
1379 else
1380 return mantissa * pow(2, exponent);
1381}
1382
1383/*
1384 * Double-precision.
1385 * We assume that if you don't have IEEE floating-point, you have a
1386 * compiler that understands 64-bit integral quantities.
1387 */
1388#define IEEE_DP_NUMBER_WIDTH 64 /* bits in number */
1389#define IEEE_DP_EXP_WIDTH 11 /* bits in exponent */
1390#define IEEE_DP_MANTISSA_WIDTH 52 /* IEEE_DP_NUMBER_WIDTH - 1 - IEEE_DP_EXP_WIDTH */
1391
1392#define IEEE_DP_SIGN_MASK INT64_C(0x8000000000000000)0x8000000000000000L
1393#define IEEE_DP_EXPONENT_MASK INT64_C(0x7FF0000000000000)0x7FF0000000000000L
1394#define IEEE_DP_MANTISSA_MASK INT64_C(0x000FFFFFFFFFFFFF)0x000FFFFFFFFFFFFFL
1395#define IEEE_DP_INFINITY IEEE_DP_EXPONENT_MASK
1396
1397#define IEEE_DP_IMPLIED_BIT (INT64_C(1)1L << IEEE_DP_MANTISSA_WIDTH)
1398#define IEEE_DP_INFINITE ((1 << IEEE_DP_EXP_WIDTH) - 1)
1399#define IEEE_DP_BIAS ((1 << (IEEE_DP_EXP_WIDTH - 1)) - 1)
1400
1401static int
1402ieee_double_is_zero(const uint64_t w)
1403{
1404 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1405}
1406
1407static double
1408get_ieee_double(const uint64_t w)
1409{
1410 int64_t sign;
1411 int64_t exponent;
1412 int64_t mantissa;
1413
1414 sign = w & IEEE_DP_SIGN_MASK;
1415 exponent = w & IEEE_DP_EXPONENT_MASK;
1416 mantissa = w & IEEE_DP_MANTISSA_MASK;
1417
1418 if (ieee_double_is_zero(w)) {
1419 /* number is zero, unnormalized, or not-a-number */
1420 return 0.0;
1421 }
1422#if 0
1423 /*
1424 * XXX - how to handle this?
1425 */
1426 if (IEEE_DP_INFINITY == exponent) {
1427 /*
1428 * number is positive or negative infinity, or a special value
1429 */
1430 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1431 }
1432#endif
1433
1434 exponent = ((exponent >> IEEE_DP_MANTISSA_WIDTH) - IEEE_DP_BIAS) -
1435 IEEE_DP_MANTISSA_WIDTH;
1436 mantissa |= IEEE_DP_IMPLIED_BIT;
1437
1438 if (sign)
1439 return -mantissa * pow(2, exponent);
1440 else
1441 return mantissa * pow(2, exponent);
1442}
1443#endif
1444
1445/*
1446 * Fetches an IEEE single-precision floating-point number, in
1447 * big-endian form, and returns a "float".
1448 *
1449 * XXX - should this be "double", in case there are IEEE single-
1450 * precision numbers that won't fit in some platform's native
1451 * "float" format?
1452 */
1453float
1454tvb_get_ntohieee_float(tvbuff_t *tvb, const int offset)
1455{
1456#if defined(vax)
1457 return get_ieee_float(tvb_get_ntohl(tvb, offset));
1458#else
1459 union {
1460 float f;
1461 uint32_t w;
1462 } ieee_fp_union;
1463
1464 ieee_fp_union.w = tvb_get_ntohl(tvb, offset);
1465 return ieee_fp_union.f;
1466#endif
1467}
1468
1469/*
1470 * Fetches an IEEE double-precision floating-point number, in
1471 * big-endian form, and returns a "double".
1472 */
1473double
1474tvb_get_ntohieee_double(tvbuff_t *tvb, const int offset)
1475{
1476#if defined(vax)
1477 union {
1478 uint32_t w[2];
1479 uint64_t dw;
1480 } ieee_fp_union;
1481#else
1482 union {
1483 double d;
1484 uint32_t w[2];
1485 } ieee_fp_union;
1486#endif
1487
1488#if G_BYTE_ORDER1234 == G_BIG_ENDIAN4321
1489 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset);
1490 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset+4);
1491#else
1492 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset+4);
1493 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset);
1494#endif
1495#if defined(vax)
1496 return get_ieee_double(ieee_fp_union.dw);
1497#else
1498 return ieee_fp_union.d;
1499#endif
1500}
1501
1502uint16_t
1503tvb_get_letohs(tvbuff_t *tvb, const int offset)
1504{
1505 const uint8_t *ptr;
1506
1507 ptr = fast_ensure_contiguous(tvb, offset, 2);
1508 return pletoh16(ptr);
1509}
1510
1511int16_t
1512tvb_get_letohis(tvbuff_t *tvb, const int offset)
1513{
1514 const uint8_t *ptr;
1515
1516 ptr = fast_ensure_contiguous(tvb, offset, 2);
1517 return pletoh16(ptr);
1518}
1519
1520uint32_t
1521tvb_get_letoh24(tvbuff_t *tvb, const int offset)
1522{
1523 const uint8_t *ptr;
1524
1525 ptr = fast_ensure_contiguous(tvb, offset, 3);
1526 return pletoh24(ptr);
1527}
1528
1529int32_t
1530tvb_get_letohi24(tvbuff_t *tvb, const int offset)
1531{
1532 uint32_t ret;
1533
1534 ret = ws_sign_ext32(tvb_get_letoh24(tvb, offset), 24);
1535
1536 return (int32_t)ret;
1537}
1538
1539uint32_t
1540tvb_get_letohl(tvbuff_t *tvb, const int offset)
1541{
1542 const uint8_t *ptr;
1543
1544 ptr = fast_ensure_contiguous(tvb, offset, 4);
1545 return pletoh32(ptr);
1546}
1547
1548int32_t
1549tvb_get_letohil(tvbuff_t *tvb, const int offset)
1550{
1551 const uint8_t *ptr;
1552
1553 ptr = fast_ensure_contiguous(tvb, offset, 4);
1554 return pletoh32(ptr);
1555}
1556
1557uint64_t
1558tvb_get_letoh40(tvbuff_t *tvb, const int offset)
1559{
1560 const uint8_t *ptr;
1561
1562 ptr = fast_ensure_contiguous(tvb, offset, 5);
1563 return pletoh40(ptr);
1564}
1565
1566int64_t
1567tvb_get_letohi40(tvbuff_t *tvb, const int offset)
1568{
1569 uint64_t ret;
1570
1571 ret = ws_sign_ext64(tvb_get_letoh40(tvb, offset), 40);
1572
1573 return (int64_t)ret;
1574}
1575
1576uint64_t
1577tvb_get_letoh48(tvbuff_t *tvb, const int offset)
1578{
1579 const uint8_t *ptr;
1580
1581 ptr = fast_ensure_contiguous(tvb, offset, 6);
1582 return pletoh48(ptr);
1583}
1584
1585int64_t
1586tvb_get_letohi48(tvbuff_t *tvb, const int offset)
1587{
1588 uint64_t ret;
1589
1590 ret = ws_sign_ext64(tvb_get_letoh48(tvb, offset), 48);
1591
1592 return (int64_t)ret;
1593}
1594
1595uint64_t
1596tvb_get_letoh56(tvbuff_t *tvb, const int offset)
1597{
1598 const uint8_t *ptr;
1599
1600 ptr = fast_ensure_contiguous(tvb, offset, 7);
1601 return pletoh56(ptr);
1602}
1603
1604int64_t
1605tvb_get_letohi56(tvbuff_t *tvb, const int offset)
1606{
1607 uint64_t ret;
1608
1609 ret = ws_sign_ext64(tvb_get_letoh56(tvb, offset), 56);
1610
1611 return (int64_t)ret;
1612}
1613
1614uint64_t
1615tvb_get_letoh64(tvbuff_t *tvb, const int offset)
1616{
1617 const uint8_t *ptr;
1618
1619 ptr = fast_ensure_contiguous(tvb, offset, 8);
1620 return pletoh64(ptr);
1621}
1622
1623int64_t
1624tvb_get_letohi64(tvbuff_t *tvb, const int offset)
1625{
1626 const uint8_t *ptr;
1627
1628 ptr = fast_ensure_contiguous(tvb, offset, 8);
1629 return pletoh64(ptr);
1630}
1631
1632/*
1633 * Fetches an IEEE single-precision floating-point number, in
1634 * little-endian form, and returns a "float".
1635 *
1636 * XXX - should this be "double", in case there are IEEE single-
1637 * precision numbers that won't fit in some platform's native
1638 * "float" format?
1639 */
1640float
1641tvb_get_letohieee_float(tvbuff_t *tvb, const int offset)
1642{
1643#if defined(vax)
1644 return get_ieee_float(tvb_get_letohl(tvb, offset));
1645#else
1646 union {
1647 float f;
1648 uint32_t w;
1649 } ieee_fp_union;
1650
1651 ieee_fp_union.w = tvb_get_letohl(tvb, offset);
1652 return ieee_fp_union.f;
1653#endif
1654}
1655
1656/*
1657 * Fetches an IEEE double-precision floating-point number, in
1658 * little-endian form, and returns a "double".
1659 */
1660double
1661tvb_get_letohieee_double(tvbuff_t *tvb, const int offset)
1662{
1663#if defined(vax)
1664 union {
1665 uint32_t w[2];
1666 uint64_t dw;
1667 } ieee_fp_union;
1668#else
1669 union {
1670 double d;
1671 uint32_t w[2];
1672 } ieee_fp_union;
1673#endif
1674
1675#if G_BYTE_ORDER1234 == G_BIG_ENDIAN4321
1676 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset+4);
1677 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset);
1678#else
1679 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset);
1680 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset+4);
1681#endif
1682#if defined(vax)
1683 return get_ieee_double(ieee_fp_union.dw);
1684#else
1685 return ieee_fp_union.d;
1686#endif
1687}
1688
1689/* This function is a slight misnomer. It accepts all encodings that are
1690 * ASCII "enough", which means encodings that are the same as US-ASCII
1691 * for textual representations of dates and hex bytes; i.e., the same
1692 * for the hex digits and Z (in practice, all alphanumerics), and the
1693 * four separators ':' '-' '.' and ' '
1694 * That means that any encoding that keeps the ISO/IEC 646 invariant
1695 * characters the same (including the T.61 8 bit encoding and multibyte
1696 * encodings like EUC-KR and GB18030) are OK, even if they replace characters
1697 * like '$' '#' and '\' with national variants, but not encodings like UTF-16
1698 * that include extra null bytes.
1699 * For our current purposes, the unpacked GSM 7-bit default alphabet (but not
1700 * all National Language Shift Tables) also satisfies this requirement, but
1701 * note that it does *not* keep all ISO/IEC 646 invariant characters the same.
1702 * If this internal function gets used for additional purposes than currently,
1703 * the set of encodings that it accepts could change.
1704 * */
1705static inline void
1706validate_single_byte_ascii_encoding(const unsigned encoding)
1707{
1708 const unsigned enc = encoding & ~ENC_CHARENCODING_MASK0x0000FFFE;
1709
1710 switch (enc) {
1711 case ENC_UTF_160x00000004:
1712 case ENC_UCS_20x00000006:
1713 case ENC_UCS_40x00000008:
1714 case ENC_3GPP_TS_23_038_7BITS_PACKED0x0000002C:
1715 case ENC_ASCII_7BITS0x00000034:
1716 case ENC_EBCDIC0x0000002E:
1717 case ENC_EBCDIC_CP0370x00000038:
1718 case ENC_EBCDIC_CP5000x00000060:
1719 case ENC_BCD_DIGITS_0_90x00000044:
1720 case ENC_KEYPAD_ABC_TBCD0x00000046:
1721 case ENC_KEYPAD_BC_TBCD0x00000048:
1722 case ENC_ETSI_TS_102_221_ANNEX_A0x0000004E:
1723 case ENC_APN_STR0x00000054:
1724 case ENC_DECT_STANDARD_4BITS_TBCD0x00000058:
1725 REPORT_DISSECTOR_BUG("Invalid string encoding type passed to tvb_get_string_XXX")proto_report_dissector_bug("Invalid string encoding type passed to tvb_get_string_XXX"
)
;
1726 break;
1727 default:
1728 break;
1729 }
1730 /* make sure something valid was set */
1731 if (enc == 0)
1732 REPORT_DISSECTOR_BUG("No string encoding type passed to tvb_get_string_XXX")proto_report_dissector_bug("No string encoding type passed to tvb_get_string_XXX"
)
;
1733}
1734
1735GByteArray*
1736tvb_get_string_bytes(tvbuff_t *tvb, const int offset, const int length,
1737 const unsigned encoding, GByteArray *bytes, int *endoff)
1738{
1739 char *ptr;
1740 const char *begin;
1741 const char *end = NULL((void*)0);
1742 GByteArray *retval = NULL((void*)0);
1743
1744 validate_single_byte_ascii_encoding(encoding);
1745
1746 ptr = (char*) tvb_get_raw_string(NULL((void*)0), tvb, offset, length);
1747 begin = ptr;
1748
1749 if (endoff) *endoff = offset;
1750
1751 while (*begin == ' ') begin++;
1752
1753 if (*begin && bytes) {
1754 if (hex_str_to_bytes_encoding(begin, bytes, &end, encoding, false0)) {
1755 if (bytes->len > 0) {
1756 if (endoff) *endoff = offset + (int)(end - ptr);
1757 retval = bytes;
1758 }
1759 }
1760 }
1761
1762 wmem_free(NULL((void*)0), ptr);
1763
1764 return retval;
1765}
1766
1767static bool_Bool
1768parse_month_name(const char *name, int *tm_mon)
1769{
1770 static const char months[][4] = { "Jan", "Feb", "Mar", "Apr", "May",
1771 "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
1772 for (int i = 0; i < 12; i++) {
1773 if (memcmp(months[i], name, 4) == 0) {
1774 *tm_mon = i;
1775 return true1;
1776 }
1777 }
1778 return false0;
1779}
1780
1781/*
1782 * Is the character a WSP character, as per RFC 5234? (space or tab).
1783 */
1784#define IS_WSP(c)((c) == ' ' || (c) == '\t') ((c) == ' ' || (c) == '\t')
1785
1786/* support hex-encoded time values? */
1787nstime_t*
1788tvb_get_string_time(tvbuff_t *tvb, const int offset, const int length,
1789 const unsigned encoding, nstime_t *ns, int *endoff)
1790{
1791 char *begin;
1792 const char *ptr;
1793 const char *end = NULL((void*)0);
1794 int num_chars = 0;
1795 int utc_offset = 0;
1796
1797 validate_single_byte_ascii_encoding(encoding);
1798
1799 DISSECTOR_ASSERT(ns)((void) ((ns) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/tvbuff.c", 1799, "ns"))))
;
1800
1801 begin = (char*) tvb_get_raw_string(NULL((void*)0), tvb, offset, length);
1802 ptr = begin;
1803
1804 while (IS_WSP(*ptr)((*ptr) == ' ' || (*ptr) == '\t'))
1805 ptr++;
1806
1807 if (*ptr) {
1808 if ((encoding & ENC_ISO_8601_DATE_TIME0x00030000) == ENC_ISO_8601_DATE_TIME0x00030000) {
1809 if (!(end = iso8601_to_nstime(ns, ptr, ISO8601_DATETIME))) {
1810
1811
1812 goto fail;
1813 }
1814 } else if ((encoding & ENC_ISO_8601_DATE_TIME_BASIC0x00100000) == ENC_ISO_8601_DATE_TIME_BASIC0x00100000) {
1815 if (!(end = iso8601_to_nstime(ns, ptr, ISO8601_DATETIME_BASIC))) {
1816
1817
1818 goto fail;
1819 }
1820 } else {
1821 struct tm tm;
1822
1823 memset(&tm, 0, sizeof(tm));
1824 tm.tm_isdst = -1;
1825 ns->secs = 0;
1826 ns->nsecs = 0;
1827
1828 /* note: sscanf is known to be inconsistent across platforms with respect
1829 to whether a %n is counted as a return value or not, so we have to use
1830 '>=' a lot */
1831 if (encoding & ENC_ISO_8601_DATE0x00010000) {
1832 /* 2014-04-07 */
1833 if (sscanf(ptr, "%d-%d-%d%n",
1834 &tm.tm_year,
1835 &tm.tm_mon,
1836 &tm.tm_mday,
1837 &num_chars) >= 3)
1838 {
1839 end = ptr + num_chars;
1840 tm.tm_mon--;
1841 if (tm.tm_year > 1900) tm.tm_year -= 1900;
1842 } else {
1843 goto fail;
1844 }
1845 }
1846 else if (encoding & ENC_ISO_8601_TIME0x00020000) {
1847 /* 2014-04-07 */
1848 if (sscanf(ptr, "%d:%d:%d%n",
1849 &tm.tm_hour,
1850 &tm.tm_min,
1851 &tm.tm_sec,
1852 &num_chars) >= 2)
1853 {
1854 /* what should we do about day/month/year? */
1855 /* setting it to "now" for now */
1856 time_t time_now = time(NULL((void*)0));
1857 struct tm *tm_now = gmtime(&time_now);
1858 if (tm_now != NULL((void*)0)) {
1859 tm.tm_year = tm_now->tm_year;
1860 tm.tm_mon = tm_now->tm_mon;
1861 tm.tm_mday = tm_now->tm_mday;
1862 } else {
1863 /* The second before the Epoch */
1864 tm.tm_year = 69;
1865 tm.tm_mon = 12;
1866 tm.tm_mday = 31;
1867 }
1868 end = ptr + num_chars;
1869 } else {
1870 goto fail;
1871 }
1872 }
1873 else if (encoding & ENC_IMF_DATE_TIME0x00040000) {
1874 /*
1875 * Match [dow,] day month year hh:mm[:ss] with
1876 * two-digit years (RFC 822) or four-digit
1877 * years (RFCs 1123, 2822, 5822). Skip
1878 * the day of week since it is locale
1879 * dependent and does not affect the resulting
1880 * date anyway.
1881 */
1882 if (g_ascii_isalpha(ptr[0])((g_ascii_table[(guchar) (ptr[0])] & G_ASCII_ALPHA) != 0) && g_ascii_isalpha(ptr[1])((g_ascii_table[(guchar) (ptr[1])] & G_ASCII_ALPHA) != 0) && g_ascii_isalpha(ptr[2])((g_ascii_table[(guchar) (ptr[2])] & G_ASCII_ALPHA) != 0) && ptr[3] == ',')
1883 ptr += 4; /* Skip day of week. */
1884
1885 /*
1886 * Parse the day-of-month and month
1887 * name.
1888 */
1889 char month_name[4] = { 0 };
1890
1891 if (sscanf(ptr, "%d %3s%n",
1892 &tm.tm_mday,
1893 month_name,
1894 &num_chars) < 2)
1895 {
1896 /* Not matched. */
1897 goto fail;
1898 }
1899 if (!parse_month_name(month_name, &tm.tm_mon)) {
1900 goto fail;
1901 }
1902 ptr += num_chars;
1903 while (IS_WSP(*ptr)((*ptr) == ' ' || (*ptr) == '\t'))
1904 ptr++;
1905
1906 /*
1907 * Scan the year. Treat 2-digit years
1908 * differently from 4-digit years.
1909 */
1910 uint32_t year;
1911 const char *yearendp;
1912
1913 if (!ws_strtou32(ptr, &yearendp, &year)) {
1914 goto fail;
1915 }
1916 if (!IS_WSP(*yearendp)((*yearendp) == ' ' || (*yearendp) == '\t')) {
1917 /* Not followed by WSP. */
1918 goto fail;
1919 }
1920 if (yearendp - ptr < 2) {
1921 /* 1-digit year. Error. */
1922 goto fail;
1923 }
1924 if (yearendp - ptr == 2) {
1925 /*
1926 * 2-digit year.
1927 *
1928 * Match RFC 2822/RFC 5322 behavior;
1929 * add 2000 to years from 0 to
1930 * 49 and 1900 to uears from 50
1931 * to 99.
1932 */
1933 if (year <= 49) {
1934 year += 2000;
1935 } else {
1936 year += 1900;
1937 }
1938 } else if (yearendp - ptr == 3) {
1939 /*
1940 * 3-digit year.
1941 *
1942 * Match RFC 2822/RFC 5322 behavior;
1943 * add 1900 to the year.
1944 */
1945 year += 1900;
1946 }
1947 tm.tm_year = year - 1900;
1948 ptr = yearendp;
1949 while (IS_WSP(*ptr)((*ptr) == ' ' || (*ptr) == '\t'))
1950 ptr++;
1951
1952 /* Parse the time. */
1953 if (sscanf(ptr, "%d:%d%n:%d%n",
1954 &tm.tm_hour,
1955 &tm.tm_min,
1956 &num_chars,
1957 &tm.tm_sec,
1958 &num_chars) < 2)
1959 {
1960 goto fail;
1961 }
1962 ptr += num_chars;
1963 while (IS_WSP(*ptr)((*ptr) == ' ' || (*ptr) == '\t'))
1964 ptr++;
1965
1966 /*
1967 * Parse the time zone.
1968 * Check for obs-zone values first.
1969 */
1970 if (g_ascii_strncasecmp(ptr, "UT", 2) == 0)
1971 {
1972 ptr += 2;
1973 }
1974 else if (g_ascii_strncasecmp(ptr, "GMT", 3) == 0)
1975 {
1976 ptr += 3;
1977 }
1978 else
1979 {
1980 char sign;
1981 int off_hr;
1982 int off_min;
1983
1984 if (sscanf(ptr, "%c%2d%2d%n",
1985 &sign,
1986 &off_hr,
1987 &off_min,
1988 &num_chars) < 3)
1989 {
1990 goto fail;
1991 }
1992
1993 /*
1994 * If sign is '+', there's a positive
1995 * UTC offset.
1996 *
1997 * If sign is '-', there's a negative
1998 * UTC offset.
1999 *
2000 * Otherwise, that's an invalid UTC
2001 * offset string.
2002 */
2003 if (sign == '+')
2004 utc_offset += (off_hr * 3600) + (off_min * 60);
2005 else if (sign == '-')
2006 utc_offset -= (off_hr * 3600) + (off_min * 60);
2007 else {
2008 /* Sign must be + or - */
2009 goto fail;
2010 }
2011 ptr += num_chars;
2012 }
2013 end = ptr;
2014 }
2015 ns->secs = mktime_utc(&tm);
2016 if (ns->secs == (time_t)-1 && errno(*__errno_location ()) != 0) {
2017 goto fail;
2018 }
2019 ns->secs += utc_offset;
2020 }
2021 } else {
2022 /* Empty string */
2023 goto fail;
2024 }
2025
2026 if (endoff)
2027 *endoff = (int)(offset + (end - begin));
2028 wmem_free(NULL((void*)0), begin);
2029 return ns;
2030
2031fail:
2032 wmem_free(NULL((void*)0), begin);
2033 return NULL((void*)0);
2034}
2035
2036/* Fetch an IPv4 address, in network byte order.
2037 * We do *not* convert them to host byte order; we leave them in
2038 * network byte order. */
2039uint32_t
2040tvb_get_ipv4(tvbuff_t *tvb, const int offset)
2041{
2042 const uint8_t *ptr;
2043 uint32_t addr;
2044
2045 ptr = fast_ensure_contiguous(tvb, offset, sizeof(uint32_t));
2046 memcpy(&addr, ptr, sizeof addr);
2047 return addr;
2048}
2049
2050/* Fetch an IPv6 address. */
2051void
2052tvb_get_ipv6(tvbuff_t *tvb, const int offset, ws_in6_addr *addr)
2053{
2054 const uint8_t *ptr;
2055
2056 ptr = ensure_contiguous(tvb, offset, sizeof(*addr));
2057 memcpy(addr, ptr, sizeof *addr);
2058}
2059
2060/*
2061 * These routines return the length of the address in bytes on success
2062 * and -1 if the prefix length is too long.
2063 */
2064int
2065tvb_get_ipv4_addr_with_prefix_len(tvbuff_t *tvb, int offset, ws_in4_addr *addr,
2066 uint32_t prefix_len)
2067{
2068 uint8_t addr_len;
2069
2070 if (prefix_len > 32)
2071 return -1;
2072
2073 addr_len = (prefix_len + 7) / 8;
2074 *addr = 0;
2075 tvb_memcpy(tvb, addr, offset, addr_len);
2076 if (prefix_len % 8)
2077 ((uint8_t*)addr)[addr_len - 1] &= ((0xff00 >> (prefix_len % 8)) & 0xff);
2078 return addr_len;
2079}
2080
2081/*
2082 * These routines return the length of the address in bytes on success
2083 * and -1 if the prefix length is too long.
2084 */
2085int
2086tvb_get_ipv6_addr_with_prefix_len(tvbuff_t *tvb, int offset, ws_in6_addr *addr,
2087 uint32_t prefix_len)
2088{
2089 uint32_t addr_len;
2090
2091 if (prefix_len > 128)
2092 return -1;
2093
2094 addr_len = (prefix_len + 7) / 8;
2095 memset(addr->bytes, 0, 16);
2096 tvb_memcpy(tvb, addr->bytes, offset, addr_len);
2097 if (prefix_len % 8) {
2098 addr->bytes[addr_len - 1] &=
2099 ((0xff00 >> (prefix_len % 8)) & 0xff);
2100 }
2101
2102 return addr_len;
2103}
2104
2105/* Fetch a GUID. */
2106void
2107tvb_get_ntohguid(tvbuff_t *tvb, const int offset, e_guid_t *guid)
2108{
2109 const uint8_t *ptr = ensure_contiguous(tvb, offset, GUID_LEN16);
2110
2111 guid->data1 = pntoh32(ptr + 0);
2112 guid->data2 = pntoh16(ptr + 4);
2113 guid->data3 = pntoh16(ptr + 6);
2114 memcpy(guid->data4, ptr + 8, sizeof guid->data4);
2115}
2116
2117void
2118tvb_get_letohguid(tvbuff_t *tvb, const int offset, e_guid_t *guid)
2119{
2120 const uint8_t *ptr = ensure_contiguous(tvb, offset, GUID_LEN16);
2121
2122 guid->data1 = pletoh32(ptr + 0);
2123 guid->data2 = pletoh16(ptr + 4);
2124 guid->data3 = pletoh16(ptr + 6);
2125 memcpy(guid->data4, ptr + 8, sizeof guid->data4);
2126}
2127
2128/*
2129 * NOTE: to support code written when proto_tree_add_item() took a
2130 * bool as its last argument, with false meaning "big-endian"
2131 * and true meaning "little-endian", we treat any non-zero value of
2132 * "encoding" as meaning "little-endian".
2133 */
2134void
2135tvb_get_guid(tvbuff_t *tvb, const int offset, e_guid_t *guid, const unsigned encoding)
2136{
2137 if (encoding) {
2138 tvb_get_letohguid(tvb, offset, guid);
2139 } else {
2140 tvb_get_ntohguid(tvb, offset, guid);
2141 }
2142}
2143
2144static const uint8_t bit_mask8[] = {
2145 0x00,
2146 0x01,
2147 0x03,
2148 0x07,
2149 0x0f,
2150 0x1f,
2151 0x3f,
2152 0x7f,
2153 0xff
2154};
2155
2156
2157/* Get a variable amount of bits
2158 *
2159 * Return a byte array with bit limited data.
2160 * When encoding is ENC_BIG_ENDIAN, the data is aligned to the left.
2161 * When encoding is ENC_LITTLE_ENDIAN, the data is aligned to the right.
2162 */
2163uint8_t *
2164tvb_get_bits_array(wmem_allocator_t *scope, tvbuff_t *tvb, const int bit_offset,
2165 size_t no_of_bits, size_t *data_length, const unsigned encoding)
2166{
2167 tvbuff_t *sub_tvb;
2168 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
2169 sub_tvb = tvb_new_octet_right_aligned(tvb, bit_offset, (int32_t) no_of_bits);
2170 } else {
2171 sub_tvb = tvb_new_octet_aligned(tvb, bit_offset, (int32_t) no_of_bits);
2172 }
2173 *data_length = tvb_reported_length(sub_tvb);
2174 return (uint8_t*)tvb_memdup(scope, sub_tvb, 0, *data_length);
2175}
2176
2177/* Get 1 - 8 bits */
2178uint8_t
2179tvb_get_bits8(tvbuff_t *tvb, unsigned bit_offset, const int no_of_bits)
2180{
2181 return (uint8_t)_tvb_get_bits64(tvb, bit_offset, no_of_bits);
2182}
2183
2184/* Get 1 - 16 bits */
2185uint16_t
2186tvb_get_bits16(tvbuff_t *tvb, unsigned bit_offset, const int no_of_bits, const unsigned encoding)
2187{
2188 return (uint16_t)tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
2189}
2190
2191/* Get 1 - 32 bits */
2192uint32_t
2193tvb_get_bits32(tvbuff_t *tvb, unsigned bit_offset, const int no_of_bits, const unsigned encoding)
2194{
2195 return (uint32_t)tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
2196}
2197
2198/* Get 1 - 64 bits */
2199uint64_t
2200tvb_get_bits64(tvbuff_t *tvb, unsigned bit_offset, const int no_of_bits, const unsigned encoding)
2201{
2202 /* encoding determines bit numbering within octet array */
2203 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
2
Assuming the condition is true
3
Taking true branch
2204 return _tvb_get_bits64_le(tvb, bit_offset, no_of_bits);
4
Calling '_tvb_get_bits64_le'
2205 } else {
2206 return _tvb_get_bits64(tvb, bit_offset, no_of_bits);
2207 }
2208}
2209
2210/*
2211 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
2212 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
2213 * Offset should be given in bits from the start of the tvb.
2214 * Bits within octet are numbered from MSB (0) to LSB (7). Bit at bit_offset is return value most significant bit.
2215 * The function tolerates requests for more than 64 bits, but will only return the least significant 64 bits.
2216 */
2217static uint64_t
2218_tvb_get_bits64(tvbuff_t *tvb, unsigned bit_offset, const int total_no_of_bits)
2219{
2220 uint64_t value;
2221 unsigned octet_offset = bit_offset >> 3;
2222 uint8_t required_bits_in_first_octet = 8 - (bit_offset % 8);
2223
2224 if(required_bits_in_first_octet > total_no_of_bits)
2225 {
2226 /* the required bits don't extend to the end of the first octet */
2227 uint8_t right_shift = required_bits_in_first_octet - total_no_of_bits;
2228 value = (tvb_get_uint8(tvb, octet_offset) >> right_shift) & bit_mask8[total_no_of_bits % 8];
2229 }
2230 else
2231 {
2232 uint8_t remaining_bit_length = total_no_of_bits;
2233
2234 /* get the bits up to the first octet boundary */
2235 value = 0;
2236 required_bits_in_first_octet %= 8;
2237 if(required_bits_in_first_octet != 0)
2238 {
2239 value = tvb_get_uint8(tvb, octet_offset) & bit_mask8[required_bits_in_first_octet];
2240 remaining_bit_length -= required_bits_in_first_octet;
2241 octet_offset ++;
2242 }
2243 /* take the biggest words, shorts or octets that we can */
2244 while (remaining_bit_length > 7)
2245 {
2246 switch (remaining_bit_length >> 4)
2247 {
2248 case 0:
2249 /* 8 - 15 bits. (note that 0 - 7 would have dropped out of the while() loop) */
2250 value <<= 8;
2251 value += tvb_get_uint8(tvb, octet_offset);
2252 remaining_bit_length -= 8;
2253 octet_offset ++;
2254 break;
2255
2256 case 1:
2257 /* 16 - 31 bits */
2258 value <<= 16;
2259 value += tvb_get_ntohs(tvb, octet_offset);
2260 remaining_bit_length -= 16;
2261 octet_offset += 2;
2262 break;
2263
2264 case 2:
2265 case 3:
2266 /* 32 - 63 bits */
2267 value <<= 32;
2268 value += tvb_get_ntohl(tvb, octet_offset);
2269 remaining_bit_length -= 32;
2270 octet_offset += 4;
2271 break;
2272
2273 default:
2274 /* 64 bits (or more???) */
2275 value = tvb_get_ntoh64(tvb, octet_offset);
2276 remaining_bit_length -= 64;
2277 octet_offset += 8;
2278 break;
2279 }
2280 }
2281 /* get bits from any partial octet at the tail */
2282 if(remaining_bit_length)
2283 {
2284 value <<= remaining_bit_length;
2285 value += (tvb_get_uint8(tvb, octet_offset) >> (8 - remaining_bit_length));
2286 }
2287 }
2288 return value;
2289}
2290
2291/*
2292 * Offset should be given in bits from the start of the tvb.
2293 * Bits within octet are numbered from LSB (0) to MSB (7). Bit at bit_offset is return value least significant bit.
2294 * The function tolerates requests for more than 64 bits, but will only return the least significant 64 bits.
2295 */
2296static uint64_t
2297_tvb_get_bits64_le(tvbuff_t *tvb, unsigned bit_offset, const int total_no_of_bits)
2298{
2299 uint64_t value = 0;
2300 unsigned octet_offset = bit_offset / 8;
2301 int remaining_bits = total_no_of_bits;
2302 int shift = 0;
2303
2304 if (remaining_bits > 64)
5
Assuming 'remaining_bits' is <= 64
6
Taking false branch
2305 {
2306 remaining_bits = 64;
2307 }
2308
2309 if (bit_offset % 8)
7
Assuming the condition is true
8
Taking true branch
2310 {
2311 /* not aligned, extract bits from first octet */
2312 shift = 8 - (bit_offset % 8);
2313 value = tvb_get_uint8(tvb, octet_offset) >> (bit_offset % 8);
2314 if (shift > remaining_bits)
9
Assuming 'shift' is <= 'remaining_bits'
10
Taking false branch
2315 {
2316 /* keep only the requested bits */
2317 value &= (UINT64_C(1)1UL << remaining_bits) - 1;
2318 remaining_bits = 0;
2319 }
2320 else
2321 {
2322 remaining_bits -= shift;
2323 }
2324 octet_offset++;
2325 }
2326
2327 while (remaining_bits > 0)
11
Assuming 'remaining_bits' is > 0
12
Loop condition is true. Entering loop body
16
Assuming 'remaining_bits' is > 0
17
Loop condition is true. Entering loop body
22
Assuming 'remaining_bits' is > 0
23
Loop condition is true. Entering loop body
2328 {
2329 /* take the biggest words, shorts or octets that we can */
2330 if (remaining_bits >= 32)
13
Assuming 'remaining_bits' is >= 32
14
Taking true branch
18
Assuming 'remaining_bits' is >= 32
19
Taking true branch
24
Assuming 'remaining_bits' is >= 32
25
Taking true branch
2331 {
2332 value |= ((uint64_t)tvb_get_letohl(tvb, octet_offset) << shift);
15
Assuming right operand of bit shift is less than 64
20
Assuming right operand of bit shift is less than 64
26
The result of left shift is undefined because the right operand is not smaller than 64, the capacity of 'uint64_t'
2333 shift += 32;
21
Value assigned to 'shift'
2334 remaining_bits -= 32;
2335 octet_offset += 4;
2336 }
2337 else if (remaining_bits >= 16)
2338 {
2339 value |= ((uint64_t)tvb_get_letohs(tvb, octet_offset) << shift);
2340 shift += 16;
2341 remaining_bits -= 16;
2342 octet_offset += 2;
2343 }
2344 else if (remaining_bits >= 8)
2345 {
2346 value |= ((uint64_t)tvb_get_uint8(tvb, octet_offset) << shift);
2347 shift += 8;
2348 remaining_bits -= 8;
2349 octet_offset += 1;
2350 }
2351 else
2352 {
2353 unsigned mask = (1 << remaining_bits) - 1;
2354 value |= (((uint64_t)tvb_get_uint8(tvb, octet_offset) & mask) << shift);
2355 shift += remaining_bits;
2356 remaining_bits = 0;
2357 octet_offset += 1;
2358 }
2359 }
2360 return value;
2361}
2362
2363/* Get 1 - 32 bits (should be deprecated as same as tvb_get_bits32??) */
2364uint32_t
2365tvb_get_bits(tvbuff_t *tvb, const unsigned bit_offset, const int no_of_bits, const unsigned encoding)
2366{
2367 return (uint32_t)tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
1
Calling 'tvb_get_bits64'
2368}
2369
2370static int
2371tvb_find_uint8_generic(tvbuff_t *tvb, unsigned abs_offset, unsigned limit, uint8_t needle)
2372{
2373 const uint8_t *ptr;
2374 const uint8_t *result;
2375
2376 ptr = ensure_contiguous(tvb, abs_offset, limit); /* tvb_get_ptr() */
2377 if (!ptr)
2378 return -1;
2379
2380 result = (const uint8_t *) memchr(ptr, needle, limit);
2381 if (!result)
2382 return -1;
2383
2384 return (int) ((result - ptr) + abs_offset);
2385}
2386
2387/* Find first occurrence of needle in tvbuff, starting at offset. Searches
2388 * at most maxlength number of bytes; if maxlength is -1, searches to
2389 * end of tvbuff.
2390 * Returns the offset of the found needle, or -1 if not found.
2391 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
2392 * in that case, -1 will be returned if the boundary is reached before
2393 * finding needle. */
2394int
2395tvb_find_uint8(tvbuff_t *tvb, const int offset, const int maxlength, const uint8_t needle)
2396{
2397 const uint8_t *result;
2398 unsigned abs_offset = 0;
2399 unsigned limit = 0;
2400 int exception;
2401
2402 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 2402, "tvb && tvb->initialized"
))))
;
2403
2404 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &limit);
2405 if (exception)
2406 THROW(exception)except_throw(1, (exception), ((void*)0));
2407
2408 /* Only search to end of tvbuff, w/o throwing exception. */
2409 if (maxlength >= 0 && limit > (unsigned) maxlength) {
2410 /* Maximum length doesn't go past end of tvbuff; search
2411 to that value. */
2412 limit = (unsigned) maxlength;
2413 }
2414
2415 /* If we have real data, perform our search now. */
2416 if (tvb->real_data) {
2417 result = (const uint8_t *)memchr(tvb->real_data + abs_offset, needle, limit);
2418 if (result == NULL((void*)0)) {
2419 return -1;
2420 }
2421 else {
2422 return (int) (result - tvb->real_data);
2423 }
2424 }
2425
2426 if (tvb->ops->tvb_find_uint8)
2427 return tvb->ops->tvb_find_uint8(tvb, abs_offset, limit, needle);
2428
2429 return tvb_find_uint8_generic(tvb, offset, limit, needle);
2430}
2431
2432/* Same as tvb_find_uint8() with 16bit needle. */
2433int
2434tvb_find_uint16(tvbuff_t *tvb, const int offset, const int maxlength,
2435 const uint16_t needle)
2436{
2437 unsigned abs_offset = 0;
2438 unsigned limit = 0;
2439 int exception;
2440
2441 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &limit);
2442 if (exception)
2443 THROW(exception)except_throw(1, (exception), ((void*)0));
2444
2445 /* Only search to end of tvbuff, w/o throwing exception. */
2446 if (maxlength >= 0 && limit > (unsigned) maxlength) {
2447 /* Maximum length doesn't go past end of tvbuff; search
2448 to that value. */
2449 limit = (unsigned) maxlength;
2450 }
2451
2452 const uint8_t needle1 = ((needle & 0xFF00) >> 8);
2453 const uint8_t needle2 = ((needle & 0x00FF) >> 0);
2454 unsigned searched_bytes = 0;
2455 unsigned pos = abs_offset;
2456
2457 do {
2458 int offset1 =
2459 tvb_find_uint8(tvb, pos, limit - searched_bytes, needle1);
2460 int offset2 = -1;
2461
2462 if (offset1 == -1) {
2463 return -1;
2464 }
2465
2466 searched_bytes = (unsigned)offset1 - abs_offset + 1;
2467
2468 if (searched_bytes >= limit) {
2469 return -1;
2470 }
2471
2472 offset2 = tvb_find_uint8(tvb, offset1 + 1, 1, needle2);
2473
2474 searched_bytes += 1;
2475
2476 if (offset2 != -1) {
2477 if (searched_bytes > limit) {
2478 return -1;
2479 }
2480 return offset1;
2481 }
2482
2483 pos = offset1 + 1;
2484 } while (searched_bytes < limit);
2485
2486 return -1;
2487}
2488
2489static inline int
2490tvb_ws_mempbrk_uint8_generic(tvbuff_t *tvb, unsigned abs_offset, unsigned limit, const ws_mempbrk_pattern* pattern, unsigned char *found_needle)
2491{
2492 const uint8_t *ptr;
2493 const uint8_t *result;
2494
2495 ptr = ensure_contiguous(tvb, abs_offset, limit); /* tvb_get_ptr */
2496 if (!ptr)
2497 return -1;
2498
2499 result = ws_mempbrk_exec(ptr, limit, pattern, found_needle);
2500 if (!result)
2501 return -1;
2502
2503 return (int) ((result - ptr) + abs_offset);
2504}
2505
2506
2507/* Find first occurrence of any of the pattern chars in tvbuff, starting at offset.
2508 * Searches at most maxlength number of bytes; if maxlength is -1, searches
2509 * to end of tvbuff.
2510 * Returns the offset of the found needle, or -1 if not found.
2511 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
2512 * in that case, -1 will be returned if the boundary is reached before
2513 * finding needle. */
2514int
2515tvb_ws_mempbrk_pattern_uint8(tvbuff_t *tvb, const int offset, const int maxlength,
2516 const ws_mempbrk_pattern* pattern, unsigned char *found_needle)
2517{
2518 const uint8_t *result;
2519 unsigned abs_offset = 0;
2520 unsigned limit = 0;
2521 int exception;
2522
2523 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 2523, "tvb && tvb->initialized"
))))
;
2524
2525 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &limit);
2526 if (exception)
2527 THROW(exception)except_throw(1, (exception), ((void*)0));
2528
2529 /* Only search to end of tvbuff, w/o throwing exception. */
2530 if (limit > (unsigned) maxlength) {
2531 /* Maximum length doesn't go past end of tvbuff; search
2532 to that value. */
2533 limit = maxlength;
2534 }
2535
2536 /* If we have real data, perform our search now. */
2537 if (tvb->real_data) {
2538 result = ws_mempbrk_exec(tvb->real_data + abs_offset, limit, pattern, found_needle);
2539 if (result == NULL((void*)0)) {
2540 return -1;
2541 }
2542 else {
2543 return (int) (result - tvb->real_data);
2544 }
2545 }
2546
2547 if (tvb->ops->tvb_ws_mempbrk_pattern_uint8)
2548 return tvb->ops->tvb_ws_mempbrk_pattern_uint8(tvb, abs_offset, limit, pattern, found_needle);
2549
2550 return tvb_ws_mempbrk_uint8_generic(tvb, abs_offset, limit, pattern, found_needle);
2551}
2552
2553/* Find size of stringz (NUL-terminated string) by looking for terminating
2554 * NUL. The size of the string includes the terminating NUL.
2555 *
2556 * If the NUL isn't found, it throws the appropriate exception.
2557 */
2558unsigned
2559tvb_strsize(tvbuff_t *tvb, const int offset)
2560{
2561 unsigned abs_offset = 0, junk_length;
2562 int nul_offset;
2563
2564 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 2564, "tvb && tvb->initialized"
))))
;
2565
2566 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
2567 nul_offset = tvb_find_uint8(tvb, abs_offset, -1, 0);
2568 if (nul_offset == -1) {
2569 /*
2570 * OK, we hit the end of the tvbuff, so we should throw
2571 * an exception.
2572 */
2573 if (tvb->length < tvb->contained_length) {
2574 THROW(BoundsError)except_throw(1, (1), ((void*)0));
2575 } else if (tvb->flags & TVBUFF_FRAGMENT0x00000001) {
2576 THROW(FragmentBoundsError)except_throw(1, (4), ((void*)0));
2577 } else if (tvb->length < tvb->reported_length) {
2578 THROW(ContainedBoundsError)except_throw(1, (2), ((void*)0));
2579 } else {
2580 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
2581 }
2582 }
2583 return (nul_offset - abs_offset) + 1;
2584}
2585
2586/* UTF-16/UCS-2 version of tvb_strsize */
2587/* Returns number of bytes including the (two-bytes) null terminator */
2588unsigned
2589tvb_unicode_strsize(tvbuff_t *tvb, const int offset)
2590{
2591 unsigned i = 0;
2592 gunichar2 uchar;
2593
2594 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 2594, "tvb && tvb->initialized"
))))
;
2595
2596 do {
2597 /* Endianness doesn't matter when looking for null */
2598 uchar = tvb_get_ntohs(tvb, offset + i);
2599 i += 2;
2600 } while(uchar != 0);
2601
2602 return i;
2603}
2604
2605/* Find length of string by looking for end of string ('\0'), up to
2606 * 'maxlength' characters'; if 'maxlength' is -1, searches to end
2607 * of tvbuff.
2608 * Returns -1 if 'maxlength' reached before finding EOS. */
2609int
2610tvb_strnlen(tvbuff_t *tvb, const int offset, const unsigned maxlength)
2611{
2612 int result_offset;
2613 unsigned abs_offset = 0, junk_length;
2614
2615 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 2615, "tvb && tvb->initialized"
))))
;
2616
2617 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
2618
2619 result_offset = tvb_find_uint8(tvb, abs_offset, maxlength, 0);
2620
2621 if (result_offset == -1) {
2622 return -1;
2623 }
2624 else {
2625 return result_offset - abs_offset;
2626 }
2627}
2628
2629/*
2630 * Implement strneql etc
2631 */
2632
2633/*
2634 * Call strncmp after checking if enough chars left, returning 0 if
2635 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
2636 */
2637int
2638tvb_strneql(tvbuff_t *tvb, const int offset, const char *str, const size_t size)
2639{
2640 const uint8_t *ptr;
2641
2642 ptr = ensure_contiguous_no_exception(tvb, offset, (int)size, NULL((void*)0));
2643
2644 if (ptr) {
2645 int cmp = strncmp((const char *)ptr, str, size);
2646
2647 /*
2648 * Return 0 if equal, -1 otherwise.
2649 */
2650 return (cmp == 0 ? 0 : -1);
2651 } else {
2652 /*
2653 * Not enough characters in the tvbuff to match the
2654 * string.
2655 */
2656 return -1;
2657 }
2658}
2659
2660/*
2661 * Call g_ascii_strncasecmp after checking if enough chars left, returning
2662 * 0 if it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
2663 */
2664int
2665tvb_strncaseeql(tvbuff_t *tvb, const int offset, const char *str, const size_t size)
2666{
2667 const uint8_t *ptr;
2668
2669 ptr = ensure_contiguous_no_exception(tvb, offset, (int)size, NULL((void*)0));
2670
2671 if (ptr) {
2672 int cmp = g_ascii_strncasecmp((const char *)ptr, str, size);
2673
2674 /*
2675 * Return 0 if equal, -1 otherwise.
2676 */
2677 return (cmp == 0 ? 0 : -1);
2678 } else {
2679 /*
2680 * Not enough characters in the tvbuff to match the
2681 * string.
2682 */
2683 return -1;
2684 }
2685}
2686
2687/*
2688 * Check that the tvbuff contains at least size bytes, starting at
2689 * offset, and that those bytes are equal to str. Return 0 for success
2690 * and -1 for error. This function does not throw an exception.
2691 */
2692int
2693tvb_memeql(tvbuff_t *tvb, const int offset, const uint8_t *str, size_t size)
2694{
2695 const uint8_t *ptr;
2696
2697 ptr = ensure_contiguous_no_exception(tvb, offset, (int) size, NULL((void*)0));
2698
2699 if (ptr) {
2700 int cmp = memcmp(ptr, str, size);
2701
2702 /*
2703 * Return 0 if equal, -1 otherwise.
2704 */
2705 return (cmp == 0 ? 0 : -1);
2706 } else {
2707 /*
2708 * Not enough characters in the tvbuff to match the
2709 * string.
2710 */
2711 return -1;
2712 }
2713}
2714
2715/**
2716 * Format the data in the tvb from offset for size.
2717 */
2718char *
2719tvb_format_text(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, const int size)
2720{
2721 const uint8_t *ptr;
2722 int len;
2723
2724 len = (size > 0) ? size : 0;
2725
2726 ptr = ensure_contiguous(tvb, offset, size);
2727 return format_text(scope, ptr, len);
2728}
2729
2730/*
2731 * Format the data in the tvb from offset for length ...
2732 */
2733char *
2734tvb_format_text_wsp(wmem_allocator_t* allocator, tvbuff_t *tvb, const int offset, const int size)
2735{
2736 const uint8_t *ptr;
2737 int len;
2738
2739 len = (size > 0) ? size : 0;
2740
2741 ptr = ensure_contiguous(tvb, offset, size);
2742 return format_text_wsp(allocator, ptr, len);
2743}
2744
2745/**
2746 * Like "tvb_format_text()", but for null-padded strings; don't show
2747 * the null padding characters as "\000".
2748 */
2749char *
2750tvb_format_stringzpad(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, const int size)
2751{
2752 const uint8_t *ptr, *p;
2753 int len;
2754 int stringlen;
2755
2756 len = (size > 0) ? size : 0;
2757
2758 ptr = ensure_contiguous(tvb, offset, size);
2759 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2760 ;
2761 return format_text(scope, ptr, stringlen);
2762}
2763
2764/*
2765 * Like "tvb_format_text_wsp()", but for null-padded strings; don't show
2766 * the null padding characters as "\000".
2767 */
2768char *
2769tvb_format_stringzpad_wsp(wmem_allocator_t* allocator, tvbuff_t *tvb, const int offset, const int size)
2770{
2771 const uint8_t *ptr, *p;
2772 int len;
2773 int stringlen;
2774
2775 len = (size > 0) ? size : 0;
2776
2777 ptr = ensure_contiguous(tvb, offset, size);
2778 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2779 ;
2780 return format_text_wsp(allocator, ptr, stringlen);
2781}
2782
2783/*
2784 * All string functions below take a scope as an argument.
2785 *
2786 *
2787 * If scope is NULL, memory is allocated with g_malloc() and user must
2788 * explicitly free it with g_free().
2789 * If scope is not NULL, memory is allocated with the corresponding pool
2790 * lifetime.
2791 *
2792 * All functions throw an exception if the tvbuff ends before the string
2793 * does.
2794 */
2795
2796/*
2797 * Given a wmem scope, a tvbuff, an offset, and a length, treat the string
2798 * of bytes referred to by the tvbuff, offset, and length as an ASCII string,
2799 * with all bytes with the high-order bit set being invalid, and return a
2800 * pointer to a UTF-8 string, allocated using the wmem scope.
2801 *
2802 * Octets with the highest bit set will be converted to the Unicode
2803 * REPLACEMENT CHARACTER.
2804 */
2805static uint8_t *
2806tvb_get_ascii_string(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int length)
2807{
2808 const uint8_t *ptr;
2809
2810 ptr = ensure_contiguous(tvb, offset, length);
2811 return get_ascii_string(scope, ptr, length);
2812}
2813
2814/*
2815 * Given a wmem scope, a tvbuff, an offset, a length, and a translation table,
2816 * treat the string of bytes referred to by the tvbuff, offset, and length
2817 * as a string encoded using one octet per character, with octets with the
2818 * high-order bit clear being mapped by the translation table to 2-byte
2819 * Unicode Basic Multilingual Plane characters (including REPLACEMENT
2820 * CHARACTER) and octets with the high-order bit set being mapped to
2821 * REPLACEMENT CHARACTER, and return a pointer to a UTF-8 string,
2822 * allocated using the wmem scope.
2823 *
2824 * Octets with the highest bit set will be converted to the Unicode
2825 * REPLACEMENT CHARACTER.
2826 */
2827static uint8_t *
2828tvb_get_iso_646_string(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int length, const gunichar2 table[0x80])
2829{
2830 const uint8_t *ptr;
2831
2832 ptr = ensure_contiguous(tvb, offset, length);
2833 return get_iso_646_string(scope, ptr, length, table);
2834}
2835
2836/*
2837 * Given a wmem scope, a tvbuff, an offset, and a length, treat the string
2838 * of bytes referred to by the tvbuff, the offset. and the length as a UTF-8
2839 * string, and return a pointer to a UTF-8 string, allocated using the wmem
2840 * scope, with all ill-formed sequences replaced with the Unicode REPLACEMENT
2841 * CHARACTER according to the recommended "best practices" given in the Unicode
2842 * Standard and specified by W3C/WHATWG.
2843 *
2844 * Note that in conformance with the Unicode Standard, this treats three
2845 * byte sequences corresponding to UTF-16 surrogate halves (paired or unpaired)
2846 * and two byte overlong encodings of 7-bit ASCII characters as invalid and
2847 * substitutes REPLACEMENT CHARACTER for them. Explicit support for nonstandard
2848 * derivative encoding formats (e.g. CESU-8, Java Modified UTF-8, WTF-8) could
2849 * be added later.
2850 */
2851static uint8_t *
2852tvb_get_utf_8_string(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, const int length)
2853{
2854 const uint8_t *ptr;
2855
2856 ptr = ensure_contiguous(tvb, offset, length);
2857 return get_utf_8_string(scope, ptr, length);
2858}
2859
2860/*
2861 * Given a wmem scope, a tvbuff, an offset, and a length, treat the string
2862 * of bytes referred to by the tvbuff, the offset, and the length as a
2863 * raw string, and return a pointer to that string, allocated using the
2864 * wmem scope. This means a null is appended at the end, but no replacement
2865 * checking is done otherwise, unlike tvb_get_utf_8_string().
2866 *
2867 * Also, this one allows a length of -1 to mean get all, but does not
2868 * allow a negative offset.
2869 */
2870static inline uint8_t *
2871tvb_get_raw_string(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, const int length)
2872{
2873 uint8_t *strbuf;
2874 int abs_length = length;
2875
2876 DISSECTOR_ASSERT(offset >= 0)((void) ((offset >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 2876, "offset >= 0"
))))
;
2877 DISSECTOR_ASSERT(abs_length >= -1)((void) ((abs_length >= -1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 2877, "abs_length >= -1"
))))
;
2878
2879 if (abs_length < 0)
2880 abs_length = tvb->length - offset;
2881
2882 tvb_ensure_bytes_exist(tvb, offset, abs_length);
2883 strbuf = (uint8_t *)wmem_alloc(scope, abs_length + 1);
2884 tvb_memcpy(tvb, strbuf, offset, abs_length);
2885 strbuf[abs_length] = '\0';
2886 return strbuf;
2887}
2888
2889/*
2890 * Given a wmem scope, a tvbuff, an offset, and a length, treat the string
2891 * of bytes referred to by the tvbuff, the offset, and the length as an
2892 * ISO 8859/1 string, and return a pointer to a UTF-8 string, allocated
2893 * using the wmem scope.
2894 */
2895static uint8_t *
2896tvb_get_string_8859_1(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int length)
2897{
2898 const uint8_t *ptr;
2899
2900 ptr = ensure_contiguous(tvb, offset, length);
2901 return get_8859_1_string(scope, ptr, length);
2902}
2903
2904/*
2905 * Given a wmem scope, a tvbuff, an offset, a length, and a translation
2906 * table, treat the string of bytes referred to by the tvbuff, the offset,
2907 * and the length as a string encoded using one octet per character, with
2908 * octets with the high-order bit clear being ASCII and octets with the
2909 * high-order bit set being mapped by the translation table to 2-byte
2910 * Unicode Basic Multilingual Plane characters (including REPLACEMENT
2911 * CHARACTER), and return a pointer to a UTF-8 string, allocated with the
2912 * wmem scope.
2913 */
2914static uint8_t *
2915tvb_get_string_unichar2(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int length, const gunichar2 table[0x80])
2916{
2917 const uint8_t *ptr;
2918
2919 ptr = ensure_contiguous(tvb, offset, length);
2920 return get_unichar2_string(scope, ptr, length, table);
2921}
2922
2923/*
2924 * Given a wmem scope, a tvbuff, an offset, a length, and an encoding
2925 * giving the byte order, treat the string of bytes referred to by the
2926 * tvbuff, the offset, and the length as a UCS-2 encoded string in
2927 * the byte order in question, containing characters from the Basic
2928 * Multilingual Plane (plane 0) of Unicode, and return a pointer to a
2929 * UTF-8 string, allocated with the wmem scope.
2930 *
2931 * Encoding parameter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN.
2932 *
2933 * Specify length in bytes.
2934 *
2935 * XXX - should map lead and trail surrogate values to REPLACEMENT
2936 * CHARACTERs (0xFFFD)?
2937 * XXX - if there are an odd number of bytes, should put a
2938 * REPLACEMENT CHARACTER at the end.
2939 */
2940static uint8_t *
2941tvb_get_ucs_2_string(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, int length, const unsigned encoding)
2942{
2943 const uint8_t *ptr;
2944
2945 ptr = ensure_contiguous(tvb, offset, length);
2946 return get_ucs_2_string(scope, ptr, length, encoding);
2947}
2948
2949/*
2950 * Given a wmem scope, a tvbuff, an offset, a length, and an encoding
2951 * giving the byte order, treat the string of bytes referred to by the
2952 * tvbuff, the offset, and the length as a UTF-16 encoded string in
2953 * the byte order in question, and return a pointer to a UTF-8 string,
2954 * allocated with the wmem scope.
2955 *
2956 * Encoding parameter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN.
2957 *
2958 * Specify length in bytes.
2959 *
2960 * XXX - should map surrogate errors to REPLACEMENT CHARACTERs (0xFFFD).
2961 * XXX - should map code points > 10FFFF to REPLACEMENT CHARACTERs.
2962 * XXX - if there are an odd number of bytes, should put a
2963 * REPLACEMENT CHARACTER at the end.
2964 */
2965static uint8_t *
2966tvb_get_utf_16_string(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, int length, const unsigned encoding)
2967{
2968 const uint8_t *ptr;
2969
2970 ptr = ensure_contiguous(tvb, offset, length);
2971 return get_utf_16_string(scope, ptr, length, encoding);
2972}
2973
2974/*
2975 * Given a wmem scope, a tvbuff, an offset, a length, and an encoding
2976 * giving the byte order, treat the string of bytes referred to by the
2977 * tvbuff, the offset, and the length as a UCS-4 encoded string in
2978 * the byte order in question, and return a pointer to a UTF-8 string,
2979 * allocated with the wmem scope.
2980 *
2981 * Encoding parameter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN
2982 *
2983 * Specify length in bytes
2984 *
2985 * XXX - should map lead and trail surrogate values to a "substitute"
2986 * UTF-8 character?
2987 * XXX - should map code points > 10FFFF to REPLACEMENT CHARACTERs.
2988 * XXX - if the number of bytes isn't a multiple of 4, should put a
2989 * REPLACEMENT CHARACTER at the end.
2990 */
2991static char *
2992tvb_get_ucs_4_string(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, int length, const unsigned encoding)
2993{
2994 const uint8_t *ptr;
2995
2996 ptr = ensure_contiguous(tvb, offset, length);
2997 return get_ucs_4_string(scope, ptr, length, encoding);
2998}
2999
3000char *
3001tvb_get_ts_23_038_7bits_string_packed(wmem_allocator_t *scope, tvbuff_t *tvb,
3002 const int bit_offset, int no_of_chars)
3003{
3004 int in_offset = bit_offset >> 3; /* Current pointer to the input buffer */
3005 int length = ((no_of_chars + 1) * 7 + (bit_offset & 0x07)) >> 3;
3006 const uint8_t *ptr;
3007
3008 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 3008, "tvb && tvb->initialized"
))))
;
3009
3010 ptr = ensure_contiguous(tvb, in_offset, length);
3011 return get_ts_23_038_7bits_string_packed(scope, ptr, bit_offset, no_of_chars);
3012}
3013
3014char *
3015tvb_get_ts_23_038_7bits_string_unpacked(wmem_allocator_t *scope, tvbuff_t *tvb,
3016 const int offset, int length)
3017{
3018 const uint8_t *ptr;
3019
3020 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 3020, "tvb && tvb->initialized"
))))
;
3021
3022 ptr = ensure_contiguous(tvb, offset, length);
3023 return get_ts_23_038_7bits_string_unpacked(scope, ptr, length);
3024}
3025
3026char *
3027tvb_get_etsi_ts_102_221_annex_a_string(wmem_allocator_t *scope, tvbuff_t *tvb,
3028 const int offset, int length)
3029{
3030 const uint8_t *ptr;
3031
3032 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 3032, "tvb && tvb->initialized"
))))
;
3033
3034 ptr = ensure_contiguous(tvb, offset, length);
3035 return get_etsi_ts_102_221_annex_a_string(scope, ptr, length);
3036}
3037
3038char *
3039tvb_get_ascii_7bits_string(wmem_allocator_t *scope, tvbuff_t *tvb,
3040 const int bit_offset, int no_of_chars)
3041{
3042 int in_offset = bit_offset >> 3; /* Current pointer to the input buffer */
3043 int length = ((no_of_chars + 1) * 7 + (bit_offset & 0x07)) >> 3;
3044 const uint8_t *ptr;
3045
3046 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 3046, "tvb && tvb->initialized"
))))
;
3047
3048 ptr = ensure_contiguous(tvb, in_offset, length);
3049 return get_ascii_7bits_string(scope, ptr, bit_offset, no_of_chars);
3050}
3051
3052/*
3053 * Given a wmem scope, a tvbuff, an offset, a length, and a translation
3054 * table, treat the string of bytes referred to by the tvbuff, the offset,
3055 * and the length as a string encoded using one octet per character, with
3056 * octets being mapped by the translation table to 2-byte Unicode Basic
3057 * Multilingual Plane characters (including REPLACEMENT CHARACTER), and
3058 * return a pointer to a UTF-8 string, allocated with the wmem scope.
3059 */
3060static uint8_t *
3061tvb_get_nonascii_unichar2_string(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int length, const gunichar2 table[256])
3062{
3063 const uint8_t *ptr;
3064
3065 ptr = ensure_contiguous(tvb, offset, length);
3066 return get_nonascii_unichar2_string(scope, ptr, length, table);
3067}
3068
3069/*
3070 * Given a wmem scope, a tvbuff, an offset, and a length, treat the bytes
3071 * referred to by the tvbuff, offset, and length as a GB18030 encoded string,
3072 * and return a pointer to a UTF-8 string, allocated with the wmem scope,
3073 * converted having substituted REPLACEMENT CHARACTER according to the
3074 * Unicode Standard 5.22 U+FFFD Substitution for Conversion.
3075 * ( https://www.unicode.org/versions/Unicode13.0.0/ch05.pdf )
3076 *
3077 * As expected, this will also decode GBK and GB2312 strings.
3078 */
3079static uint8_t *
3080tvb_get_gb18030_string(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int length)
3081{
3082 const uint8_t *ptr;
3083
3084 ptr = ensure_contiguous(tvb, offset, length);
3085 return get_gb18030_string(scope, ptr, length);
3086}
3087
3088/*
3089 * Given a wmem scope, a tvbuff, an offset, and a length, treat the bytes
3090 * referred to by the tvbuff, offset, and length as a EUC-KR encoded string,
3091 * and return a pointer to a UTF-8 string, allocated with the wmem scope,
3092 * converted having substituted REPLACEMENT CHARACTER according to the
3093 * Unicode Standard 5.22 U+FFFD Substitution for Conversion.
3094 * ( https://www.unicode.org/versions/Unicode13.0.0/ch05.pdf )
3095 */
3096static uint8_t *
3097tvb_get_euc_kr_string(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int length)
3098{
3099 const uint8_t *ptr;
3100
3101 ptr = ensure_contiguous(tvb, offset, length);
3102 return get_euc_kr_string(scope, ptr, length);
3103}
3104
3105static uint8_t *
3106tvb_get_t61_string(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int length)
3107{
3108 const uint8_t *ptr;
3109
3110 ptr = ensure_contiguous(tvb, offset, length);
3111 return get_t61_string(scope, ptr, length);
3112}
3113
3114/*
3115 * Encoding tables for BCD strings.
3116 */
3117static const dgt_set_t Dgt0_9_bcd = {
3118 {
3119 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
3120 '0','1','2','3','4','5','6','7','8','9','?','?','?','?','?','?'
3121 }
3122};
3123
3124static const dgt_set_t Dgt_keypad_abc_tbcd = {
3125 {
3126 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
3127 '0','1','2','3','4','5','6','7','8','9','*','#','a','b','c','?'
3128 }
3129};
3130
3131static const dgt_set_t Dgt_ansi_tbcd = {
3132 {
3133 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
3134 '0','1','2','3','4','5','6','7','8','9','?','B','C','*','#','?'
3135 }
3136};
3137
3138static const dgt_set_t Dgt_dect_standard_4bits_tbcd = {
3139 {
3140 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
3141 '0','1','2','3','4','5','6','7','8','9','?',' ','?','?','?','?'
3142 }
3143};
3144
3145static uint8_t *
3146tvb_get_apn_string(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset,
3147 int length)
3148{
3149 wmem_strbuf_t *str;
3150
3151 /*
3152 * This is a domain name.
3153 *
3154 * 3GPP TS 23.003, section 19.4.2 "Fully Qualified Domain Names
3155 * (FQDNs)", subsection 19.4.2.1 "General", says:
3156 *
3157 * The encoding of any identifier used as part of a Fully
3158 * Qualifed Domain Name (FQDN) shall follow the Name Syntax
3159 * defined in IETF RFC 2181 [18], IETF RFC 1035 [19] and
3160 * IETF RFC 1123 [20]. An FQDN consists of one or more
3161 * labels. Each label is coded as a one octet length field
3162 * followed by that number of octets coded as 8 bit ASCII
3163 * characters.
3164 *
3165 * so this does not appear to use full-blown DNS compression -
3166 * the upper 2 bits of the length don't indicate that it's a
3167 * pointer or an extended label (RFC 2673).
3168 */
3169 str = wmem_strbuf_new_sized(scope, length + 1);
3170 if (length > 0) {
3171 const uint8_t *ptr;
3172
3173 ptr = ensure_contiguous(tvb, offset, length);
3174
3175 for (;;) {
3176 unsigned label_len;
3177
3178 /*
3179 * Process this label.
3180 */
3181 label_len = *ptr;
3182 ptr++;
3183 length--;
3184
3185 while (label_len != 0) {
3186 uint8_t ch;
3187
3188 if (length == 0)
3189 goto end;
3190
3191 ch = *ptr;
3192 if (ch < 0x80)
3193 wmem_strbuf_append_c(str, ch);
3194 else
3195 wmem_strbuf_append_unichar_repl(str)wmem_strbuf_append_unichar(str, 0x00FFFD);
3196 ptr++;
3197 label_len--;
3198 length--;
3199 }
3200
3201 if (length == 0)
3202 goto end;
3203
3204 wmem_strbuf_append_c(str, '.');
3205 }
3206 }
3207
3208end:
3209 return (uint8_t *) wmem_strbuf_finalize(str);
3210}
3211
3212static uint8_t *
3213tvb_get_dect_standard_8bits_string(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int length)
3214{
3215 const uint8_t *ptr;
3216
3217 ptr = ensure_contiguous(tvb, offset, length);
3218 return get_dect_standard_8bits_string(scope, ptr, length);
3219}
3220
3221/*
3222 * Given a tvbuff, an offset, a length, and an encoding, allocate a
3223 * buffer big enough to hold a non-null-terminated string of that length
3224 * at that offset, plus a trailing '\0', copy into the buffer the
3225 * string as converted from the appropriate encoding to UTF-8, and
3226 * return a pointer to the string.
3227 */
3228uint8_t *
3229tvb_get_string_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset,
3230 const int length, const unsigned encoding)
3231{
3232 uint8_t *strptr;
3233 bool_Bool odd, skip_first;
3234
3235 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 3235, "tvb && tvb->initialized"
))))
;
3236
3237 /* make sure length = -1 fails */
3238 if (length < 0) {
3239 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
3240 }
3241
3242 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
3243
3244 case ENC_ASCII0x00000000:
3245 default:
3246 /*
3247 * For now, we treat bogus values as meaning
3248 * "ASCII" rather than reporting an error,
3249 * for the benefit of old dissectors written
3250 * when the last argument to proto_tree_add_item()
3251 * was a bool for the byte order, not an
3252 * encoding value, and passed non-zero values
3253 * other than true to mean "little-endian".
3254 */
3255 strptr = tvb_get_ascii_string(scope, tvb, offset, length);
3256 break;
3257
3258 case ENC_UTF_80x00000002:
3259 strptr = tvb_get_utf_8_string(scope, tvb, offset, length);
3260 break;
3261
3262 case ENC_UTF_160x00000004:
3263 strptr = tvb_get_utf_16_string(scope, tvb, offset, length,
3264 encoding & (ENC_LITTLE_ENDIAN0x80000000|ENC_BOM0x20000000));
3265 break;
3266
3267 case ENC_UCS_20x00000006:
3268 strptr = tvb_get_ucs_2_string(scope, tvb, offset, length,
3269 encoding & (ENC_LITTLE_ENDIAN0x80000000|ENC_BOM0x20000000));
3270 break;
3271
3272 case ENC_UCS_40x00000008:
3273 strptr = tvb_get_ucs_4_string(scope, tvb, offset, length,
3274 encoding & (ENC_LITTLE_ENDIAN0x80000000|ENC_BOM0x20000000));
3275 break;
3276
3277 case ENC_ISO_8859_10x0000000A:
3278 /*
3279 * ISO 8859-1 printable code point values are equal
3280 * to the equivalent Unicode code point value, so
3281 * no translation table is needed.
3282 */
3283 strptr = tvb_get_string_8859_1(scope, tvb, offset, length);
3284 break;
3285
3286 case ENC_ISO_8859_20x0000000C:
3287 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_2);
3288 break;
3289
3290 case ENC_ISO_8859_30x0000000E:
3291 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_3);
3292 break;
3293
3294 case ENC_ISO_8859_40x00000010:
3295 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_4);
3296 break;
3297
3298 case ENC_ISO_8859_50x00000012:
3299 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_5);
3300 break;
3301
3302 case ENC_ISO_8859_60x00000014:
3303 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_6);
3304 break;
3305
3306 case ENC_ISO_8859_70x00000016:
3307 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_7);
3308 break;
3309
3310 case ENC_ISO_8859_80x00000018:
3311 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_8);
3312 break;
3313
3314 case ENC_ISO_8859_90x0000001A:
3315 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_9);
3316 break;
3317
3318 case ENC_ISO_8859_100x0000001C:
3319 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_10);
3320 break;
3321
3322 case ENC_ISO_8859_110x0000001E:
3323 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_11);
3324 break;
3325
3326 case ENC_ISO_8859_130x00000022:
3327 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_13);
3328 break;
3329
3330 case ENC_ISO_8859_140x00000024:
3331 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_14);
3332 break;
3333
3334 case ENC_ISO_8859_150x00000026:
3335 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_15);
3336 break;
3337
3338 case ENC_ISO_8859_160x00000028:
3339 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_16);
3340 break;
3341
3342 case ENC_WINDOWS_12500x0000002A:
3343 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_cp1250);
3344 break;
3345
3346 case ENC_WINDOWS_12510x0000003C:
3347 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_cp1251);
3348 break;
3349
3350 case ENC_WINDOWS_12520x0000003A:
3351 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_cp1252);
3352 break;
3353
3354 case ENC_MAC_ROMAN0x00000030:
3355 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_mac_roman);
3356 break;
3357
3358 case ENC_CP4370x00000032:
3359 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_cp437);
3360 break;
3361
3362 case ENC_CP8550x0000003E:
3363 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_cp855);
3364 break;
3365
3366 case ENC_CP8660x00000040:
3367 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_cp866);
3368 break;
3369
3370 case ENC_ISO_646_BASIC0x00000042:
3371 strptr = tvb_get_iso_646_string(scope, tvb, offset, length, charset_table_iso_646_basic);
3372 break;
3373
3374 case ENC_3GPP_TS_23_038_7BITS_PACKED0x0000002C:
3375 {
3376 int bit_offset = offset << 3;
3377 int no_of_chars = (length << 3) / 7;
3378 strptr = tvb_get_ts_23_038_7bits_string_packed(scope, tvb, bit_offset, no_of_chars);
3379 }
3380 break;
3381
3382 case ENC_ASCII_7BITS0x00000034:
3383 {
3384 int bit_offset = offset << 3;
3385 int no_of_chars = (length << 3) / 7;
3386 strptr = tvb_get_ascii_7bits_string(scope, tvb, bit_offset, no_of_chars);
3387 }
3388 break;
3389
3390 case ENC_EBCDIC0x0000002E:
3391 /*
3392 * "Common" EBCDIC, covering all characters with the
3393 * same code point in all Roman-alphabet EBCDIC code
3394 * pages.
3395 */
3396 strptr = tvb_get_nonascii_unichar2_string(scope, tvb, offset, length, charset_table_ebcdic);
3397 break;
3398
3399 case ENC_EBCDIC_CP0370x00000038:
3400 /*
3401 * EBCDIC code page 037.
3402 */
3403 strptr = tvb_get_nonascii_unichar2_string(scope, tvb, offset, length, charset_table_ebcdic_cp037);
3404 break;
3405
3406 case ENC_EBCDIC_CP5000x00000060:
3407 /*
3408 * EBCDIC code page 500.
3409 */
3410 strptr = tvb_get_nonascii_unichar2_string(scope, tvb, offset, length, charset_table_ebcdic_cp500);
3411 break;
3412
3413 case ENC_T610x00000036:
3414 strptr = tvb_get_t61_string(scope, tvb, offset, length);
3415 break;
3416
3417 case ENC_BCD_DIGITS_0_90x00000044:
3418 /*
3419 * Packed BCD, with digits 0-9.
3420 */
3421 odd = (encoding & ENC_BCD_ODD_NUM_DIG0x00010000) >> 16;
3422 skip_first = (encoding & ENC_BCD_SKIP_FIRST0x00020000) >> 17;
3423 strptr = tvb_get_bcd_string(scope, tvb, offset, length, &Dgt0_9_bcd, skip_first, odd, !(encoding & ENC_LITTLE_ENDIAN0x80000000));
3424 break;
3425
3426 case ENC_KEYPAD_ABC_TBCD0x00000046:
3427 /*
3428 * Keypad-with-a/b/c "telephony BCD" - packed BCD, with
3429 * digits 0-9 and symbols *, #, a, b, and c.
3430 */
3431 odd = (encoding & ENC_BCD_ODD_NUM_DIG0x00010000) >> 16;
3432 skip_first = (encoding & ENC_BCD_SKIP_FIRST0x00020000) >> 17;
3433 strptr = tvb_get_bcd_string(scope, tvb, offset, length, &Dgt_keypad_abc_tbcd, skip_first, odd, !(encoding & ENC_LITTLE_ENDIAN0x80000000));
3434 break;
3435
3436 case ENC_KEYPAD_BC_TBCD0x00000048:
3437 /*
3438 * Keypad-with-B/C "telephony BCD" - packed BCD, with
3439 * digits 0-9 and symbols B, C, *, and #.
3440 */
3441 odd = (encoding & ENC_BCD_ODD_NUM_DIG0x00010000) >> 16;
3442 skip_first = (encoding & ENC_BCD_SKIP_FIRST0x00020000) >> 17;
3443 strptr = tvb_get_bcd_string(scope, tvb, offset, length, &Dgt_ansi_tbcd, skip_first, odd, !(encoding & ENC_LITTLE_ENDIAN0x80000000));
3444 break;
3445
3446 case ENC_3GPP_TS_23_038_7BITS_UNPACKED0x0000004C:
3447 strptr = tvb_get_ts_23_038_7bits_string_unpacked(scope, tvb, offset, length);
3448 break;
3449
3450 case ENC_ETSI_TS_102_221_ANNEX_A0x0000004E:
3451 strptr = tvb_get_etsi_ts_102_221_annex_a_string(scope, tvb, offset, length);
3452 break;
3453
3454 case ENC_GB180300x00000050:
3455 strptr = tvb_get_gb18030_string(scope, tvb, offset, length);
3456 break;
3457
3458 case ENC_EUC_KR0x00000052:
3459 strptr = tvb_get_euc_kr_string(scope, tvb, offset, length);
3460 break;
3461
3462 case ENC_APN_STR0x00000054:
3463 strptr = tvb_get_apn_string(scope, tvb, offset, length);
3464 break;
3465
3466 case ENC_DECT_STANDARD_8BITS0x00000056:
3467 strptr = tvb_get_dect_standard_8bits_string(scope, tvb, offset, length);
3468 break;
3469
3470 case ENC_DECT_STANDARD_4BITS_TBCD0x00000058:
3471 /*
3472 * DECT standard 4bits "telephony BCD" - packed BCD, with
3473 * digits 0-9 and symbol SPACE for 0xb.
3474 */
3475 odd = (encoding & ENC_BCD_ODD_NUM_DIG0x00010000) >> 16;
3476 skip_first = (encoding & ENC_BCD_SKIP_FIRST0x00020000) >> 17;
3477 strptr = tvb_get_bcd_string(scope, tvb, offset, length, &Dgt_dect_standard_4bits_tbcd, skip_first, odd, false0);
3478 break;
3479 }
3480 return strptr;
3481}
3482
3483/*
3484 * This is like tvb_get_string_enc(), except that it handles null-padded
3485 * strings.
3486 *
3487 * Currently, string values are stored as UTF-8 null-terminated strings,
3488 * so nothing needs to be done differently for null-padded strings; we
3489 * could save a little memory by not storing the null padding.
3490 *
3491 * If we ever store string values differently, in a fashion that doesn't
3492 * involve null termination, that might change.
3493 */
3494uint8_t *
3495tvb_get_stringzpad(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset,
3496 const int length, const unsigned encoding)
3497{
3498 return tvb_get_string_enc(scope, tvb, offset, length, encoding);
3499}
3500
3501/*
3502 * These routines are like the above routines, except that they handle
3503 * null-terminated strings. They find the length of that string (and
3504 * throw an exception if the tvbuff ends before we find the null), and
3505 * also return through a pointer the length of the string, in bytes,
3506 * including the terminating null (the terminating null being 2 bytes
3507 * for UCS-2 and UTF-16, 4 bytes for UCS-4, and 1 byte for other
3508 * encodings).
3509 */
3510static uint8_t *
3511tvb_get_ascii_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int *lengthp)
3512{
3513 unsigned size;
3514 const uint8_t *ptr;
3515
3516 size = tvb_strsize(tvb, offset);
3517 ptr = ensure_contiguous(tvb, offset, size);
3518 /* XXX, conversion between signed/unsigned integer */
3519 if (lengthp)
3520 *lengthp = size;
3521 return get_ascii_string(scope, ptr, size);
3522}
3523
3524static uint8_t *
3525tvb_get_iso_646_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int *lengthp, const gunichar2 table[0x80])
3526{
3527 unsigned size;
3528 const uint8_t *ptr;
3529
3530 size = tvb_strsize(tvb, offset);
3531 ptr = ensure_contiguous(tvb, offset, size);
3532 /* XXX, conversion between signed/unsigned integer */
3533 if (lengthp)
3534 *lengthp = size;
3535 return get_iso_646_string(scope, ptr, size, table);
3536}
3537
3538static uint8_t *
3539tvb_get_utf_8_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, int *lengthp)
3540{
3541 unsigned size;
3542 const uint8_t *ptr;
3543
3544 size = tvb_strsize(tvb, offset);
3545 ptr = ensure_contiguous(tvb, offset, size);
3546 /* XXX, conversion between signed/unsigned integer */
3547 if (lengthp)
3548 *lengthp = size;
3549 return get_utf_8_string(scope, ptr, size);
3550}
3551
3552static uint8_t *
3553tvb_get_stringz_8859_1(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int *lengthp)
3554{
3555 unsigned size;
3556 const uint8_t *ptr;
3557
3558 size = tvb_strsize(tvb, offset);
3559 ptr = ensure_contiguous(tvb, offset, size);
3560 /* XXX, conversion between signed/unsigned integer */
3561 if (lengthp)
3562 *lengthp = size;
3563 return get_8859_1_string(scope, ptr, size);
3564}
3565
3566static uint8_t *
3567tvb_get_stringz_unichar2(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int *lengthp, const gunichar2 table[0x80])
3568{
3569 unsigned size;
3570 const uint8_t *ptr;
3571
3572 size = tvb_strsize(tvb, offset);
3573 ptr = ensure_contiguous(tvb, offset, size);
3574 /* XXX, conversion between signed/unsigned integer */
3575 if (lengthp)
3576 *lengthp = size;
3577 return get_unichar2_string(scope, ptr, size, table);
3578}
3579
3580/*
3581 * Given a tvbuff and an offset, with the offset assumed to refer to
3582 * a null-terminated string, find the length of that string (and throw
3583 * an exception if the tvbuff ends before we find the null), ensure that
3584 * the TVB is flat, and return a pointer to the string (in the TVB).
3585 * Also return the length of the string (including the terminating null)
3586 * through a pointer.
3587 *
3588 * As long as we aren't using composite TVBs, this saves the cycles used
3589 * (often unnecessariliy) in allocating a buffer and copying the string into
3590 * it. (If we do start using composite TVBs, we may want to replace this
3591 * function with the _ephemeral version.)
3592 */
3593const uint8_t *
3594tvb_get_const_stringz(tvbuff_t *tvb, const int offset, int *lengthp)
3595{
3596 unsigned size;
3597 const uint8_t *strptr;
3598
3599 size = tvb_strsize(tvb, offset);
3600 strptr = ensure_contiguous(tvb, offset, size);
3601 if (lengthp)
3602 *lengthp = size;
3603 return strptr;
3604}
3605
3606static char *
3607tvb_get_ucs_2_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, int *lengthp, const unsigned encoding)
3608{
3609 int size; /* Number of bytes in string */
3610 const uint8_t *ptr;
3611
3612 size = tvb_unicode_strsize(tvb, offset);
3613 ptr = ensure_contiguous(tvb, offset, size);
3614 /* XXX, conversion between signed/unsigned integer */
3615 if (lengthp)
3616 *lengthp = size;
3617 return get_ucs_2_string(scope, ptr, size, encoding);
3618}
3619
3620static char *
3621tvb_get_utf_16_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, int *lengthp, const unsigned encoding)
3622{
3623 int size;
3624 const uint8_t *ptr;
3625
3626 size = tvb_unicode_strsize(tvb, offset);
3627 ptr = ensure_contiguous(tvb, offset, size);
3628 /* XXX, conversion between signed/unsigned integer */
3629 if (lengthp)
3630 *lengthp = size;
3631 return get_utf_16_string(scope, ptr, size, encoding);
3632}
3633
3634static char *
3635tvb_get_ucs_4_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, int *lengthp, const unsigned encoding)
3636{
3637 int size;
3638 gunichar uchar;
3639 const uint8_t *ptr;
3640
3641 size = 0;
3642 do {
3643 /* Endianness doesn't matter when looking for null */
3644 uchar = tvb_get_ntohl(tvb, offset + size);
3645 size += 4;
3646 } while(uchar != 0);
3647
3648 ptr = ensure_contiguous(tvb, offset, size);
3649 /* XXX, conversion between signed/unsigned integer */
3650 if (lengthp)
3651 *lengthp = size;
3652 return get_ucs_4_string(scope, ptr, size, encoding);
3653}
3654
3655static uint8_t *
3656tvb_get_nonascii_unichar2_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int *lengthp, const gunichar2 table[256])
3657{
3658 unsigned size;
3659 const uint8_t *ptr;
3660
3661 size = tvb_strsize(tvb, offset);
3662 ptr = ensure_contiguous(tvb, offset, size);
3663 /* XXX, conversion between signed/unsigned integer */
3664 if (lengthp)
3665 *lengthp = size;
3666 return get_nonascii_unichar2_string(scope, ptr, size, table);
3667}
3668
3669static uint8_t *
3670tvb_get_t61_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int *lengthp)
3671{
3672 unsigned size;
3673 const uint8_t *ptr;
3674
3675 size = tvb_strsize(tvb, offset);
3676 ptr = ensure_contiguous(tvb, offset, size);
3677 /* XXX, conversion between signed/unsigned integer */
3678 if (lengthp)
3679 *lengthp = size;
3680 return get_t61_string(scope, ptr, size);
3681}
3682
3683static uint8_t *
3684tvb_get_gb18030_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int *lengthp)
3685{
3686 unsigned size;
3687 const uint8_t *ptr;
3688
3689 size = tvb_strsize(tvb, offset);
3690 ptr = ensure_contiguous(tvb, offset, size);
3691 /* XXX, conversion between signed/unsigned integer */
3692 if (lengthp)
3693 *lengthp = size;
3694 return get_gb18030_string(scope, ptr, size);
3695}
3696
3697static uint8_t *
3698tvb_get_euc_kr_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int *lengthp)
3699{
3700 unsigned size;
3701 const uint8_t *ptr;
3702
3703 size = tvb_strsize(tvb, offset);
3704 ptr = ensure_contiguous(tvb, offset, size);
3705 /* XXX, conversion between signed/unsigned integer */
3706 if (lengthp)
3707 *lengthp = size;
3708 return get_euc_kr_string(scope, ptr, size);
3709}
3710
3711static uint8_t *
3712tvb_get_dect_standard_8bits_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int *lengthp)
3713{
3714 unsigned size;
3715 const uint8_t *ptr;
3716
3717 size = tvb_strsize(tvb, offset);
3718 ptr = ensure_contiguous(tvb, offset, size);
3719 /* XXX, conversion between signed/unsigned integer */
3720 if (lengthp)
3721 *lengthp = size;
3722 return get_t61_string(scope, ptr, size);
3723}
3724
3725uint8_t *
3726tvb_get_stringz_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, int *lengthp, const unsigned encoding)
3727{
3728 uint8_t *strptr;
3729
3730 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 3730, "tvb && tvb->initialized"
))))
;
3731
3732 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
3733
3734 case ENC_ASCII0x00000000:
3735 default:
3736 /*
3737 * For now, we treat bogus values as meaning
3738 * "ASCII" rather than reporting an error,
3739 * for the benefit of old dissectors written
3740 * when the last argument to proto_tree_add_item()
3741 * was a bool for the byte order, not an
3742 * encoding value, and passed non-zero values
3743 * other than true to mean "little-endian".
3744 */
3745 strptr = tvb_get_ascii_stringz(scope, tvb, offset, lengthp);
3746 break;
3747
3748 case ENC_UTF_80x00000002:
3749 /*
3750 * XXX - should map all invalid UTF-8 sequences
3751 * to a "substitute" UTF-8 character.
3752 * XXX - should map code points > 10FFFF to REPLACEMENT
3753 * CHARACTERs.
3754 */
3755 strptr = tvb_get_utf_8_stringz(scope, tvb, offset, lengthp);
3756 break;
3757
3758 case ENC_UTF_160x00000004:
3759 strptr = tvb_get_utf_16_stringz(scope, tvb, offset, lengthp,
3760 encoding & (ENC_LITTLE_ENDIAN0x80000000|ENC_BOM0x20000000));
3761 break;
3762
3763 case ENC_UCS_20x00000006:
3764 strptr = tvb_get_ucs_2_stringz(scope, tvb, offset, lengthp,
3765 encoding & (ENC_LITTLE_ENDIAN0x80000000|ENC_BOM0x20000000));
3766 break;
3767
3768 case ENC_UCS_40x00000008:
3769 strptr = tvb_get_ucs_4_stringz(scope, tvb, offset, lengthp,
3770 encoding & (ENC_LITTLE_ENDIAN0x80000000|ENC_BOM0x20000000));
3771 break;
3772
3773 case ENC_ISO_8859_10x0000000A:
3774 /*
3775 * ISO 8859-1 printable code point values are equal
3776 * to the equivalent Unicode code point value, so
3777 * no translation table is needed.
3778 */
3779 strptr = tvb_get_stringz_8859_1(scope, tvb, offset, lengthp);
3780 break;
3781
3782 case ENC_ISO_8859_20x0000000C:
3783 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_2);
3784 break;
3785
3786 case ENC_ISO_8859_30x0000000E:
3787 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_3);
3788 break;
3789
3790 case ENC_ISO_8859_40x00000010:
3791 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_4);
3792 break;
3793
3794 case ENC_ISO_8859_50x00000012:
3795 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_5);
3796 break;
3797
3798 case ENC_ISO_8859_60x00000014:
3799 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_6);
3800 break;
3801
3802 case ENC_ISO_8859_70x00000016:
3803 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_7);
3804 break;
3805
3806 case ENC_ISO_8859_80x00000018:
3807 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_8);
3808 break;
3809
3810 case ENC_ISO_8859_90x0000001A:
3811 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_9);
3812 break;
3813
3814 case ENC_ISO_8859_100x0000001C:
3815 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_10);
3816 break;
3817
3818 case ENC_ISO_8859_110x0000001E:
3819 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_11);
3820 break;
3821
3822 case ENC_ISO_8859_130x00000022:
3823 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_13);
3824 break;
3825
3826 case ENC_ISO_8859_140x00000024:
3827 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_14);
3828 break;
3829
3830 case ENC_ISO_8859_150x00000026:
3831 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_15);
3832 break;
3833
3834 case ENC_ISO_8859_160x00000028:
3835 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_16);
3836 break;
3837
3838 case ENC_WINDOWS_12500x0000002A:
3839 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_cp1250);
3840 break;
3841
3842 case ENC_WINDOWS_12510x0000003C:
3843 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_cp1251);
3844 break;
3845
3846 case ENC_WINDOWS_12520x0000003A:
3847 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_cp1252);
3848 break;
3849
3850 case ENC_MAC_ROMAN0x00000030:
3851 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_mac_roman);
3852 break;
3853
3854 case ENC_CP4370x00000032:
3855 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_cp437);
3856 break;
3857
3858 case ENC_CP8550x0000003E:
3859 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_cp855);
3860 break;
3861
3862 case ENC_CP8660x00000040:
3863 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_cp866);
3864 break;
3865
3866 case ENC_ISO_646_BASIC0x00000042:
3867 strptr = tvb_get_iso_646_stringz(scope, tvb, offset, lengthp, charset_table_iso_646_basic);
3868 break;
3869
3870 case ENC_3GPP_TS_23_038_7BITS_PACKED0x0000002C:
3871 case ENC_3GPP_TS_23_038_7BITS_UNPACKED0x0000004C:
3872 case ENC_ETSI_TS_102_221_ANNEX_A0x0000004E:
3873 REPORT_DISSECTOR_BUG("TS 23.038 7bits has no null character and doesn't support null-terminated strings")proto_report_dissector_bug("TS 23.038 7bits has no null character and doesn't support null-terminated strings"
)
;
3874 break;
3875
3876 case ENC_ASCII_7BITS0x00000034:
3877 REPORT_DISSECTOR_BUG("tvb_get_stringz_enc function with ENC_ASCII_7BITS not implemented yet")proto_report_dissector_bug("tvb_get_stringz_enc function with ENC_ASCII_7BITS not implemented yet"
)
;
3878 break;
3879
3880 case ENC_EBCDIC0x0000002E:
3881 /*
3882 * "Common" EBCDIC, covering all characters with the
3883 * same code point in all Roman-alphabet EBCDIC code
3884 * pages.
3885 */
3886 strptr = tvb_get_nonascii_unichar2_stringz(scope, tvb, offset, lengthp, charset_table_ebcdic);
3887 break;
3888
3889 case ENC_EBCDIC_CP0370x00000038:
3890 /*
3891 * EBCDIC code page 037.
3892 */
3893 strptr = tvb_get_nonascii_unichar2_stringz(scope, tvb, offset, lengthp, charset_table_ebcdic_cp037);
3894 break;
3895
3896 case ENC_EBCDIC_CP5000x00000060:
3897 /*
3898 * EBCDIC code page 500.
3899 */
3900 strptr = tvb_get_nonascii_unichar2_stringz(scope, tvb, offset, lengthp, charset_table_ebcdic_cp500);
3901 break;
3902
3903 case ENC_T610x00000036:
3904 strptr = tvb_get_t61_stringz(scope, tvb, offset, lengthp);
3905 break;
3906
3907 case ENC_GB180300x00000050:
3908 strptr = tvb_get_gb18030_stringz(scope, tvb, offset, lengthp);
3909 break;
3910
3911 case ENC_EUC_KR0x00000052:
3912 strptr = tvb_get_euc_kr_stringz(scope, tvb, offset, lengthp);
3913 break;
3914
3915 case ENC_DECT_STANDARD_8BITS0x00000056:
3916 strptr = tvb_get_dect_standard_8bits_stringz(scope, tvb, offset, lengthp);
3917 break;
3918 }
3919
3920 return strptr;
3921}
3922
3923/* Looks for a stringz (NUL-terminated string) in tvbuff and copies
3924 * no more than bufsize number of bytes, including terminating NUL, to buffer.
3925 * Returns length of string (not including terminating NUL), or -1 if the string was
3926 * truncated in the buffer due to not having reached the terminating NUL.
3927 * In this way, it acts like snprintf().
3928 *
3929 * bufsize MUST be greater than 0.
3930 *
3931 * When processing a packet where the remaining number of bytes is less
3932 * than bufsize, an exception is not thrown if the end of the packet
3933 * is reached before the NUL is found. If no NUL is found before reaching
3934 * the end of the short packet, -1 is still returned, and the string
3935 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
3936 * at the correct spot, terminating the string.
3937 *
3938 * *bytes_copied will contain the number of bytes actually copied,
3939 * including the terminating-NUL.
3940 */
3941static int
3942_tvb_get_raw_bytes_as_stringz(tvbuff_t *tvb, const int offset, const unsigned bufsize, uint8_t* buffer, int *bytes_copied)
3943{
3944 int stringlen;
3945 unsigned abs_offset = 0;
3946 int limit, len = 0;
3947 bool_Bool decreased_max = false0;
3948
3949 /* Only read to end of tvbuff, w/o throwing exception. */
3950 check_offset_length(tvb, offset, -1, &abs_offset, &len);
3951
3952 /* There must at least be room for the terminating NUL. */
3953 DISSECTOR_ASSERT(bufsize != 0)((void) ((bufsize != 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 3953, "bufsize != 0"
))))
;
3954
3955 /* If there's no room for anything else, just return the NUL. */
3956 if (bufsize == 1) {
3957 buffer[0] = 0;
3958 *bytes_copied = 1;
3959 return 0;
3960 }
3961
3962 /* check_offset_length() won't throw an exception if we're
3963 * looking at the byte immediately after the end of the tvbuff. */
3964 if (len == 0) {
3965 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
3966 }
3967
3968 /* This should not happen because check_offset_length() would
3969 * have already thrown an exception if 'offset' were out-of-bounds.
3970 */
3971 DISSECTOR_ASSERT(len != -1)((void) ((len != -1) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 3971, "len != -1"
))))
;
3972
3973 /*
3974 * If we've been passed a negative number, bufsize will
3975 * be huge.
3976 */
3977 DISSECTOR_ASSERT(bufsize <= INT_MAX)((void) ((bufsize <= 2147483647) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 3977, "bufsize <= 2147483647"
))))
;
3978
3979 if ((unsigned)len < bufsize) {
3980 limit = len;
3981 decreased_max = true1;
3982 }
3983 else {
3984 limit = bufsize;
3985 }
3986
3987 stringlen = tvb_strnlen(tvb, abs_offset, limit - 1);
3988 /* If NUL wasn't found, copy the data and return -1 */
3989 if (stringlen == -1) {
3990 tvb_memcpy(tvb, buffer, abs_offset, limit);
3991 if (decreased_max) {
3992 buffer[limit] = 0;
3993 /* Add 1 for the extra NUL that we set at buffer[limit],
3994 * pretending that it was copied as part of the string. */
3995 *bytes_copied = limit + 1;
3996 }
3997 else {
3998 *bytes_copied = limit;
3999 }
4000 return -1;
4001 }
4002
4003 /* Copy the string to buffer */
4004 tvb_memcpy(tvb, buffer, abs_offset, stringlen + 1);
4005 *bytes_copied = stringlen + 1;
4006 return stringlen;
4007}
4008
4009int
4010tvb_get_raw_bytes_as_stringz(tvbuff_t *tvb, const int offset, const unsigned bufsize, uint8_t* buffer)
4011{
4012 int len, bytes_copied;
4013
4014 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4014, "tvb && tvb->initialized"
))))
;
4015
4016 len = _tvb_get_raw_bytes_as_stringz(tvb, offset, bufsize, buffer, &bytes_copied);
4017
4018 if (len == -1) {
4019 buffer[bufsize - 1] = 0;
4020 return bytes_copied - 1;
4021 }
4022 else {
4023 return len;
4024 }
4025}
4026
4027/*
4028 * Given a tvbuff, an offset into the tvbuff, a buffer, and a buffer size,
4029 * extract as many raw bytes from the tvbuff, starting at the offset,
4030 * as 1) are available in the tvbuff and 2) will fit in the buffer, leaving
4031 * room for a terminating NUL.
4032 */
4033int
4034tvb_get_raw_bytes_as_string(tvbuff_t *tvb, const int offset, char *buffer, size_t bufsize)
4035{
4036 int len = 0;
4037
4038 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4038, "tvb && tvb->initialized"
))))
;
4039
4040 /* There must be room for the string and the terminating NUL. */
4041 DISSECTOR_ASSERT(bufsize > 0)((void) ((bufsize > 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4041, "bufsize > 0"
))))
;
4042
4043 DISSECTOR_ASSERT(bufsize - 1 < INT_MAX)((void) ((bufsize - 1 < 2147483647) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4043, "bufsize - 1 < 2147483647"
))))
;
4044
4045 len = tvb_captured_length_remaining(tvb, offset);
4046 if (len <= 0) {
4047 buffer[0] = '\0';
4048 return 0;
4049 }
4050 if (len > (int)(bufsize - 1))
4051 len = (int)(bufsize - 1);
4052
4053 /* Copy the string to buffer */
4054 tvb_memcpy(tvb, buffer, offset, len);
4055 buffer[len] = '\0';
4056 return len;
4057}
4058
4059bool_Bool
4060tvb_ascii_isprint(tvbuff_t *tvb, const int offset, const int length)
4061{
4062 const uint8_t* buf = tvb_get_ptr(tvb, offset, length);
4063 unsigned abs_offset, abs_length = length;
4064
4065 if (length == -1) {
4066 /* tvb_get_ptr has already checked for exceptions. */
4067 compute_offset_and_remaining(tvb, offset, &abs_offset, &abs_length);
4068 }
4069 for (unsigned i = 0; i < abs_length; i++, buf++)
4070 if (!g_ascii_isprint(*buf)((g_ascii_table[(guchar) (*buf)] & G_ASCII_PRINT) != 0))
4071 return false0;
4072
4073 return true1;
4074}
4075
4076bool_Bool
4077tvb_utf_8_isprint(tvbuff_t *tvb, const int offset, const int length)
4078{
4079 const uint8_t* buf = tvb_get_ptr(tvb, offset, length);
4080 unsigned abs_offset, abs_length = length;
4081
4082 if (length == -1) {
4083 /* tvb_get_ptr has already checked for exceptions. */
4084 compute_offset_and_remaining(tvb, offset, &abs_offset, &abs_length);
4085 }
4086
4087 return isprint_utf8_string(buf, abs_length);
4088}
4089
4090bool_Bool
4091tvb_ascii_isdigit(tvbuff_t *tvb, const int offset, const int length)
4092{
4093 const uint8_t* buf = tvb_get_ptr(tvb, offset, length);
4094 unsigned abs_offset, abs_length = length;
4095
4096 if (length == -1) {
4097 /* tvb_get_ptr has already checked for exceptions. */
4098 compute_offset_and_remaining(tvb, offset, &abs_offset, &abs_length);
4099 }
4100 for (unsigned i = 0; i < abs_length; i++, buf++)
4101 if (!g_ascii_isdigit(*buf)((g_ascii_table[(guchar) (*buf)] & G_ASCII_DIGIT) != 0))
4102 return false0;
4103
4104 return true1;
4105}
4106
4107static ws_mempbrk_pattern pbrk_crlf;
4108/*
4109 * Given a tvbuff, an offset into the tvbuff, and a length that starts
4110 * at that offset (which may be -1 for "all the way to the end of the
4111 * tvbuff"), find the end of the (putative) line that starts at the
4112 * specified offset in the tvbuff, going no further than the specified
4113 * length.
4114 *
4115 * Return the length of the line (not counting the line terminator at
4116 * the end), or, if we don't find a line terminator:
4117 *
4118 * if "desegment" is true, return -1;
4119 *
4120 * if "desegment" is false, return the amount of data remaining in
4121 * the buffer.
4122 *
4123 * If "next_offset" is not NULL, set "*next_offset" to the offset of the
4124 * character past the line terminator, or past the end of the buffer if
4125 * we don't find a line terminator. (It's not set if we return -1.)
4126 */
4127int
4128tvb_find_line_end(tvbuff_t *tvb, const int offset, int len, int *next_offset, const bool_Bool desegment)
4129{
4130 int eob_offset;
4131 int eol_offset;
4132 int linelen;
4133 unsigned char found_needle = 0;
4134 static bool_Bool compiled = false0;
4135
4136 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4136, "tvb && tvb->initialized"
))))
;
4137
4138 if (len == -1) {
4139 len = _tvb_captured_length_remaining(tvb, offset);
4140 /* if offset is past the end of the tvbuff, len is now 0 */
4141 }
4142
4143 eob_offset = offset + len;
4144
4145 if (!compiled) {
4146 ws_mempbrk_compile(&pbrk_crlf, "\r\n");
4147 compiled = true1;
4148 }
4149
4150 /*
4151 * Look either for a CR or an LF.
4152 */
4153 eol_offset = tvb_ws_mempbrk_pattern_uint8(tvb, offset, len, &pbrk_crlf, &found_needle);
4154 if (eol_offset == -1) {
4155 /*
4156 * No CR or LF - line is presumably continued in next packet.
4157 */
4158 if (desegment) {
4159 /*
4160 * Tell our caller we saw no EOL, so they can
4161 * try to desegment and get the entire line
4162 * into one tvbuff.
4163 */
4164 return -1;
4165 } else {
4166 /*
4167 * Pretend the line runs to the end of the tvbuff.
4168 */
4169 linelen = eob_offset - offset;
4170 if (next_offset)
4171 *next_offset = eob_offset;
4172 }
4173 } else {
4174 /*
4175 * Find the number of bytes between the starting offset
4176 * and the CR or LF.
4177 */
4178 linelen = eol_offset - offset;
4179
4180 /*
4181 * Is it a CR?
4182 */
4183 if (found_needle == '\r') {
4184 /*
4185 * Yes - is it followed by an LF?
4186 */
4187 if (eol_offset + 1 >= eob_offset) {
4188 /*
4189 * Dunno - the next byte isn't in this
4190 * tvbuff.
4191 */
4192 if (desegment) {
4193 /*
4194 * We'll return -1, although that
4195 * runs the risk that if the line
4196 * really *is* terminated with a CR,
4197 * we won't properly dissect this
4198 * tvbuff.
4199 *
4200 * It's probably more likely that
4201 * the line ends with CR-LF than
4202 * that it ends with CR by itself.
4203 */
4204 return -1;
4205 }
4206 } else {
4207 /*
4208 * Well, we can at least look at the next
4209 * byte.
4210 */
4211 if (tvb_get_uint8(tvb, eol_offset + 1) == '\n') {
4212 /*
4213 * It's an LF; skip over the CR.
4214 */
4215 eol_offset++;
4216 }
4217 }
4218 }
4219
4220 /*
4221 * Return the offset of the character after the last
4222 * character in the line, skipping over the last character
4223 * in the line terminator.
4224 */
4225 if (next_offset)
4226 *next_offset = eol_offset + 1;
4227 }
4228 return linelen;
4229}
4230
4231static ws_mempbrk_pattern pbrk_crlf_dquote;
4232/*
4233 * Given a tvbuff, an offset into the tvbuff, and a length that starts
4234 * at that offset (which may be -1 for "all the way to the end of the
4235 * tvbuff"), find the end of the (putative) line that starts at the
4236 * specified offset in the tvbuff, going no further than the specified
4237 * length.
4238 *
4239 * However, treat quoted strings inside the buffer specially - don't
4240 * treat newlines in quoted strings as line terminators.
4241 *
4242 * Return the length of the line (not counting the line terminator at
4243 * the end), or the amount of data remaining in the buffer if we don't
4244 * find a line terminator.
4245 *
4246 * If "next_offset" is not NULL, set "*next_offset" to the offset of the
4247 * character past the line terminator, or past the end of the buffer if
4248 * we don't find a line terminator.
4249 */
4250int
4251tvb_find_line_end_unquoted(tvbuff_t *tvb, const int offset, int len, int *next_offset)
4252{
4253 int cur_offset, char_offset;
4254 bool_Bool is_quoted;
4255 unsigned char c = 0;
4256 int eob_offset;
4257 int linelen;
4258 static bool_Bool compiled = false0;
4259
4260 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4260, "tvb && tvb->initialized"
))))
;
4261
4262 if (len == -1)
4263 len = _tvb_captured_length_remaining(tvb, offset);
4264
4265 if (!compiled) {
4266 ws_mempbrk_compile(&pbrk_crlf_dquote, "\r\n\"");
4267 compiled = true1;
4268 }
4269
4270 /*
4271 * XXX - what if "len" is still -1, meaning "offset is past the
4272 * end of the tvbuff"?
4273 */
4274 eob_offset = offset + len;
4275
4276 cur_offset = offset;
4277 is_quoted = false0;
4278 for (;;) {
4279 /*
4280 * Is this part of the string quoted?
4281 */
4282 if (is_quoted) {
4283 /*
4284 * Yes - look only for the terminating quote.
4285 */
4286 char_offset = tvb_find_uint8(tvb, cur_offset, len,
4287 '"');
4288 } else {
4289 /*
4290 * Look either for a CR, an LF, or a '"'.
4291 */
4292 char_offset = tvb_ws_mempbrk_pattern_uint8(tvb, cur_offset, len, &pbrk_crlf_dquote, &c);
4293 }
4294 if (char_offset == -1) {
4295 /*
4296 * Not found - line is presumably continued in
4297 * next packet.
4298 * We pretend the line runs to the end of the tvbuff.
4299 */
4300 linelen = eob_offset - offset;
4301 if (next_offset)
4302 *next_offset = eob_offset;
4303 break;
4304 }
4305
4306 if (is_quoted) {
4307 /*
4308 * We're processing a quoted string.
4309 * We only looked for ", so we know it's a ";
4310 * as we're processing a quoted string, it's a
4311 * closing quote.
4312 */
4313 is_quoted = false0;
4314 } else {
4315 /*
4316 * OK, what is it?
4317 */
4318 if (c == '"') {
4319 /*
4320 * Un-quoted "; it begins a quoted
4321 * string.
4322 */
4323 is_quoted = true1;
4324 } else {
4325 /*
4326 * It's a CR or LF; we've found a line
4327 * terminator.
4328 *
4329 * Find the number of bytes between the
4330 * starting offset and the CR or LF.
4331 */
4332 linelen = char_offset - offset;
4333
4334 /*
4335 * Is it a CR?
4336 */
4337 if (c == '\r') {
4338 /*
4339 * Yes; is it followed by an LF?
4340 */
4341 if (char_offset + 1 < eob_offset &&
4342 tvb_get_uint8(tvb, char_offset + 1)
4343 == '\n') {
4344 /*
4345 * Yes; skip over the CR.
4346 */
4347 char_offset++;
4348 }
4349 }
4350
4351 /*
4352 * Return the offset of the character after
4353 * the last character in the line, skipping
4354 * over the last character in the line
4355 * terminator, and quit.
4356 */
4357 if (next_offset)
4358 *next_offset = char_offset + 1;
4359 break;
4360 }
4361 }
4362
4363 /*
4364 * Step past the character we found.
4365 */
4366 cur_offset = char_offset + 1;
4367 if (cur_offset >= eob_offset) {
4368 /*
4369 * The character we found was the last character
4370 * in the tvbuff - line is presumably continued in
4371 * next packet.
4372 * We pretend the line runs to the end of the tvbuff.
4373 */
4374 linelen = eob_offset - offset;
4375 if (next_offset)
4376 *next_offset = eob_offset;
4377 break;
4378 }
4379 }
4380 return linelen;
4381}
4382
4383/*
4384 * Copied from the mgcp dissector. (This function should be moved to /epan )
4385 * tvb_skip_wsp - Returns the position in tvb of the first non-whitespace
4386 * character following offset or offset + maxlength -1 whichever
4387 * is smaller.
4388 *
4389 * Parameters:
4390 * tvb - The tvbuff in which we are skipping whitespace.
4391 * offset - The offset in tvb from which we begin trying to skip whitespace.
4392 * maxlength - The maximum distance from offset that we may try to skip
4393 * whitespace.
4394 *
4395 * Returns: The position in tvb of the first non-whitespace
4396 * character following offset or offset + maxlength -1 whichever
4397 * is smaller.
4398 */
4399int
4400tvb_skip_wsp(tvbuff_t *tvb, const int offset, const int maxlength)
4401{
4402 int counter;
4403 int end, tvb_len;
4404 uint8_t tempchar;
4405
4406 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4406, "tvb && tvb->initialized"
))))
;
4407
4408 /* Get the length remaining */
4409 /*tvb_len = tvb_captured_length(tvb);*/
4410 tvb_len = tvb->length;
4411
4412 end = offset + maxlength;
4413 if (end >= tvb_len)
4414 {
4415 end = tvb_len;
4416 }
4417
4418 /* Skip past spaces, tabs, CRs and LFs until run out or meet something else */
4419 for (counter = offset;
4420 counter < end &&
4421 ((tempchar = tvb_get_uint8(tvb,counter)) == ' ' ||
4422 tempchar == '\t' || tempchar == '\r' || tempchar == '\n');
4423 counter++);
4424
4425 return (counter);
4426}
4427
4428int
4429tvb_skip_wsp_return(tvbuff_t *tvb, const int offset)
4430{
4431 int counter;
4432 uint8_t tempchar;
4433
4434 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4434, "tvb && tvb->initialized"
))))
;
4435
4436 for (counter = offset; counter > 0 &&
4437 ((tempchar = tvb_get_uint8(tvb,counter)) == ' ' ||
4438 tempchar == '\t' || tempchar == '\n' || tempchar == '\r'); counter--);
4439 counter++;
4440
4441 return (counter);
4442}
4443
4444int
4445tvb_skip_uint8(tvbuff_t *tvb, int offset, const int maxlength, const uint8_t ch)
4446{
4447 int end, tvb_len;
4448
4449 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4449, "tvb && tvb->initialized"
))))
;
4450
4451 /* Get the length remaining */
4452 /*tvb_len = tvb_captured_length(tvb);*/
4453 tvb_len = tvb->length;
4454
4455 end = offset + maxlength;
4456 if (end >= tvb_len)
4457 end = tvb_len;
4458
4459 while (offset < end) {
4460 uint8_t tempch = tvb_get_uint8(tvb, offset);
4461
4462 if (tempch != ch)
4463 break;
4464 offset++;
4465 }
4466
4467 return offset;
4468}
4469
4470static ws_mempbrk_pattern pbrk_whitespace;
4471
4472int tvb_get_token_len(tvbuff_t *tvb, const int offset, int len, int *next_offset, const bool_Bool desegment)
4473{
4474 int eob_offset;
4475 int eot_offset;
4476 int tokenlen;
4477 unsigned char found_needle = 0;
4478 static bool_Bool compiled = false0;
4479
4480 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4480, "tvb && tvb->initialized"
))))
;
4481
4482 if (len == -1) {
4483 len = _tvb_captured_length_remaining(tvb, offset);
4484 /* if offset is past the end of the tvbuff, len is now 0 */
4485 }
4486
4487 eob_offset = offset + len;
4488
4489 if (!compiled) {
4490 ws_mempbrk_compile(&pbrk_whitespace, " \r\n");
4491 compiled = true1;
4492 }
4493
4494 /*
4495 * Look either for a space, CR, or LF.
4496 */
4497 eot_offset = tvb_ws_mempbrk_pattern_uint8(tvb, offset, len, &pbrk_whitespace, &found_needle);
4498 if (eot_offset == -1) {
4499 /*
4500 * No space, CR or LF - token is presumably continued in next packet.
4501 */
4502 if (desegment) {
4503 /*
4504 * Tell our caller we saw no whitespace, so they can
4505 * try to desegment and get the entire line
4506 * into one tvbuff.
4507 */
4508 return -1;
4509 }
4510 else {
4511 /*
4512 * Pretend the token runs to the end of the tvbuff.
4513 */
4514 tokenlen = eob_offset - offset;
4515 if (next_offset)
4516 *next_offset = eob_offset;
4517 }
4518 }
4519 else {
4520 /*
4521 * Find the number of bytes between the starting offset
4522 * and the space, CR or LF.
4523 */
4524 tokenlen = eot_offset - offset;
4525
4526 /*
4527 * Return the offset of the character after the last
4528 * character in the line, skipping over the last character
4529 * in the line terminator.
4530 */
4531 if (next_offset)
4532 *next_offset = eot_offset + 1;
4533 }
4534 return tokenlen;
4535}
4536
4537/*
4538 * Format a bunch of data from a tvbuff as bytes, returning a pointer
4539 * to the string with the formatted data, with "punct" as a byte
4540 * separator.
4541 */
4542char *
4543tvb_bytes_to_str_punct(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, const int len, const char punct)
4544{
4545 DISSECTOR_ASSERT(len > 0)((void) ((len > 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4545, "len > 0"
))))
;
4546 return bytes_to_str_punct(scope, ensure_contiguous(tvb, offset, len), len, punct)bytes_to_str_punct_maxlen(scope, ensure_contiguous(tvb, offset
, len), len, punct, 24)
;
4547}
4548
4549/*
4550 * Given a wmem scope, a tvbuff, an offset, a length, an input digit
4551 * set, and a boolean indicator, fetch BCD-encoded digits from a
4552 * tvbuff starting from either the low or high half byte of the
4553 * first byte depending on the boolean indicator (true means "start
4554 * with the high half byte, ignoring the low half byte", and false
4555 * means "start with the low half byte and proceed to the high half
4556 * byte), formating the digits into characters according to the
4557 * input digit set, and return a pointer to a UTF-8 string, allocated
4558 * using the wmem scope. A nibble of 0xf is considered a 'filler'
4559 * and will end the conversion. Similarly if odd is set the last
4560 * high nibble will be omitted. (Note that if both skip_first and
4561 * odd are true, then both the first and last semi-octet are skipped,
4562 * i.e. an even number of nibbles are considered.)
4563 */
4564char *
4565tvb_get_bcd_string(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, int len, const dgt_set_t *dgt, bool_Bool skip_first, bool_Bool odd, bool_Bool bigendian)
4566{
4567 const uint8_t *ptr;
4568 int i = 0;
4569 char *digit_str;
4570 uint8_t octet, nibble;
4571
4572 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4572, "tvb && tvb->initialized"
))))
;
4573
4574 if (len == -1) {
4575 /*
4576 * Run to the end of the captured data.
4577 *
4578 * XXX - captured, or total?
4579 */
4580 /*length = tvb_captured_length(tvb);*/
4581 len = tvb->length;
4582 if (len < offset) {
4583 return (char *)"";
4584 }
4585 len -= offset;
4586 }
4587
4588 ptr = ensure_contiguous(tvb, offset, len);
4589
4590 /*
4591 * XXX - map illegal digits (digits that map to 0) to REPLACEMENT
4592 * CHARACTER, and have all the tables in epan/tvbuff.c use 0 rather
4593 * than '?'?
4594 */
4595 digit_str = (char *)wmem_alloc(scope, len*2 + 1);
4596
4597 while (len > 0) {
4598 octet = *ptr;
4599 if (!skip_first) {
4600 if (bigendian) {
4601 nibble = (octet >> 4) & 0x0f;
4602 } else {
4603 nibble = octet & 0x0f;
4604 }
4605 if (nibble == 0x0f) {
4606 /*
4607 * Stop digit.
4608 */
4609 break;
4610 }
4611 digit_str[i] = dgt->out[nibble];
4612 i++;
4613 }
4614 skip_first = false0;
4615
4616 /*
4617 * unpack second value in byte
4618 */
4619 if (bigendian) {
4620 nibble = octet & 0x0f;
4621 } else {
4622 nibble = octet >> 4;
4623 }
4624
4625 if (nibble == 0x0f) {
4626 /*
4627 * This is the stop digit or a filler digit. Ignore
4628 * it.
4629 */
4630 break;
4631 }
4632 if ((len == 1) && (odd == true1 )){
4633 /* Last octet, skip last high nibble in case of odd number of digits */
4634 break;
4635 }
4636 digit_str[i] = dgt->out[nibble];
4637 i++;
4638
4639 ptr++;
4640 len--;
4641 }
4642 digit_str[i] = '\0';
4643 return digit_str;
4644}
4645
4646/* XXXX Fix me - needs odd indicator added */
4647const char *
4648tvb_bcd_dig_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, const int len, const dgt_set_t *dgt, bool_Bool skip_first)
4649{
4650 if (!dgt)
4651 dgt = &Dgt0_9_bcd;
4652
4653 return tvb_get_bcd_string(scope, tvb, offset, len, dgt, skip_first, false0, false0);
4654}
4655
4656const char *
4657tvb_bcd_dig_to_str_be(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, const int len, const dgt_set_t *dgt, bool_Bool skip_first)
4658{
4659 if (!dgt)
4660 dgt = &Dgt0_9_bcd;
4661
4662 return tvb_get_bcd_string(scope, tvb, offset, len, dgt, skip_first, false0, true1);
4663}
4664
4665/*
4666 * Format a bunch of data from a tvbuff as bytes, returning a pointer
4667 * to the string with the formatted data.
4668 */
4669char *tvb_bytes_to_str(wmem_allocator_t *allocator, tvbuff_t *tvb,
4670 const int offset, const int len)
4671{
4672 DISSECTOR_ASSERT(len > 0)((void) ((len > 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4672, "len > 0"
))))
;
4673 return bytes_to_str(allocator, ensure_contiguous(tvb, offset, len), len)bytes_to_str_maxlen(allocator, ensure_contiguous(tvb, offset,
len), len, 36)
;
4674}
4675
4676/* Find a needle tvbuff within a haystack tvbuff. */
4677int
4678tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb, const int haystack_offset)
4679{
4680 unsigned haystack_abs_offset = 0, haystack_abs_length = 0;
4681 const uint8_t *haystack_data;
4682 const uint8_t *needle_data;
4683 const unsigned needle_len = needle_tvb->length;
4684 const uint8_t *location;
4685
4686 DISSECTOR_ASSERT(haystack_tvb && haystack_tvb->initialized)((void) ((haystack_tvb && haystack_tvb->initialized
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/tvbuff.c", 4686, "haystack_tvb && haystack_tvb->initialized"
))))
;
4687
4688 if (haystack_tvb->length < 1 || needle_tvb->length < 1) {
4689 return -1;
4690 }
4691
4692 /* Get pointers to the tvbuffs' data. */
4693 haystack_data = ensure_contiguous(haystack_tvb, 0, -1);
4694 needle_data = ensure_contiguous(needle_tvb, 0, -1);
4695
4696 check_offset_length(haystack_tvb, haystack_offset, -1,
4697 &haystack_abs_offset, &haystack_abs_length);
4698
4699 location = ws_memmem(haystack_data + haystack_abs_offset, haystack_abs_length,
4700 needle_data, needle_len);
4701
4702 if (location) {
4703 return (int) (location - haystack_data);
4704 }
4705
4706 return -1;
4707}
4708
4709int
4710tvb_raw_offset(tvbuff_t *tvb)
4711{
4712 return ((tvb->raw_offset==-1) ? (tvb->raw_offset = tvb_offset_from_real_beginning(tvb)) : tvb->raw_offset);
4713}
4714
4715void
4716tvb_set_fragment(tvbuff_t *tvb)
4717{
4718 tvb->flags |= TVBUFF_FRAGMENT0x00000001;
4719}
4720
4721struct tvbuff *
4722tvb_get_ds_tvb(tvbuff_t *tvb)
4723{
4724 return(tvb->ds_tvb);
4725}
4726
4727unsigned
4728tvb_get_varint(tvbuff_t *tvb, unsigned offset, unsigned maxlen, uint64_t *value, const unsigned encoding)
4729{
4730 *value = 0;
4731
4732 switch (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
4733 case ENC_VARINT_PROTOBUF0x00000002:
4734 {
4735 unsigned i;
4736 uint64_t b; /* current byte */
4737
4738 for (i = 0; ((i < FT_VARINT_MAX_LEN10) && (i < maxlen)); ++i) {
4739 b = tvb_get_uint8(tvb, offset++);
4740 *value |= ((b & 0x7F) << (i * 7)); /* add lower 7 bits to val */
4741
4742 if (b < 0x80) {
4743 /* end successfully becauseof last byte's msb(most significant bit) is zero */
4744 return i + 1;
4745 }
4746 }
4747 break;
4748 }
4749
4750 case ENC_VARINT_ZIGZAG0x00000008:
4751 {
4752 unsigned i;
4753 uint64_t b; /* current byte */
4754
4755 for (i = 0; ((i < FT_VARINT_MAX_LEN10) && (i < maxlen)); ++i) {
4756 b = tvb_get_uint8(tvb, offset++);
4757 *value |= ((b & 0x7F) << (i * 7)); /* add lower 7 bits to val */
4758
4759 if (b < 0x80) {
4760 /* end successfully becauseof last byte's msb(most significant bit) is zero */
4761 *value = (*value >> 1) ^ ((*value & 1) ? -1 : 0);
4762 return i + 1;
4763 }
4764 }
4765 break;
4766 }
4767
4768 case ENC_VARINT_SDNV0x00000010:
4769 {
4770 /* Decodes similar to protobuf but in MSByte order */
4771 unsigned i;
4772 uint64_t b; /* current byte */
4773
4774 for (i = 0; ((i < FT_VARINT_MAX_LEN10) && (i < maxlen)); ++i) {
4775 b = tvb_get_uint8(tvb, offset++);
4776 if ((i == 9) && (*value >= UINT64_C(1)1UL<<(64-7))) {
4777 // guaranteed overflow, not valid SDNV
4778 return 0;
4779 }
4780 *value <<= 7;
4781 *value |= (b & 0x7F); /* add lower 7 bits to val */
4782
4783 if (b < 0x80) {
4784 /* end successfully because of last byte's msb(most significant bit) is zero */
4785 return i + 1;
4786 }
4787 }
4788 break;
4789 }
4790
4791 case ENC_VARINT_QUIC0x00000004:
4792 {
4793 /* calculate variable length */
4794 *value = tvb_get_uint8(tvb, offset);
4795 switch((*value) >> 6) {
4796 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
4797 (*value) &= 0x3F;
4798 return 1;
4799 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
4800 *value = tvb_get_ntohs(tvb, offset) & 0x3FFF;
4801 return 2;
4802 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
4803 *value = tvb_get_ntohl(tvb, offset) & 0x3FFFFFFF;
4804 return 4;
4805 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
4806 *value = tvb_get_ntoh64(tvb, offset) & UINT64_C(0x3FFFFFFFFFFFFFFF)0x3FFFFFFFFFFFFFFFUL;
4807 return 8;
4808 default: /* No Possible */
4809 ws_assert_not_reached()ws_log_fatal_full("", LOG_LEVEL_ERROR, "epan/tvbuff.c", 4809,
__func__, "assertion \"not reached\" failed")
;
4810 break;
4811 }
4812 break;
4813 }
4814
4815 default:
4816 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/tvbuff.c", 4816))
;
4817 }
4818
4819 return 0; /* 10 bytes scanned, but no bytes' msb is zero */
4820}
4821
4822/*
4823 * Editor modelines - https://www.wireshark.org/tools/modelines.html
4824 *
4825 * Local variables:
4826 * c-basic-offset: 8
4827 * tab-width: 8
4828 * indent-tabs-mode: t
4829 * End:
4830 *
4831 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
4832 * :indentSize=8:tabSize=8:noTabs=false:
4833 */