Bug Summary

File:builds/wireshark/wireshark/epan/proto.c
Warning:line 13464, column 39
The result of left shift is undefined because the right operand '64' 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 proto.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/proto.c -o /builds/wireshark/wireshark/sbout/2025-06-27-100304-3847-1 -Xclang -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2025-06-27-100304-3847-1 -x c /builds/wireshark/wireshark/epan/proto.c
1/* proto.c
2 * Routines for protocol tree
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include "config.h"
12#define WS_LOG_DOMAIN"Epan" LOG_DOMAIN_EPAN"Epan"
13#include "wireshark.h"
14
15#include <float.h>
16#include <errno(*__errno_location ()).h>
17
18#include <epan/tfs.h>
19#include <epan/unit_strings.h>
20
21#include <wsutil/array.h>
22#include <wsutil/bits_ctz.h>
23#include <wsutil/bits_count_ones.h>
24#include <wsutil/sign_ext.h>
25#include <wsutil/utf8_entities.h>
26#include <wsutil/json_dumper.h>
27#include <wsutil/pint.h>
28#include <wsutil/unicode-utils.h>
29#include <wsutil/dtoa.h>
30
31#include <ftypes/ftypes.h>
32
33#include "packet.h"
34#include "exceptions.h"
35#include "ptvcursor.h"
36#include "strutil.h"
37#include "addr_resolv.h"
38#include "address_types.h"
39#include "oids.h"
40#include "proto.h"
41#include "epan_dissect.h"
42#include "dfilter/dfilter.h"
43#include "tvbuff.h"
44#include "charsets.h"
45#include "column-info.h"
46#include "to_str.h"
47#include "osi-utils.h"
48#include "expert.h"
49#include "show_exception.h"
50#include "in_cksum.h"
51#include "register-int.h"
52
53#include <wsutil/crash_info.h>
54#include <wsutil/epochs.h>
55
56/* Ptvcursor limits */
57#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
58#define SUBTREE_MAX_LEVELS256 256
59
60typedef struct __subtree_lvl {
61 int cursor_offset;
62 proto_item *it;
63 proto_tree *tree;
64} subtree_lvl;
65
66struct ptvcursor {
67 wmem_allocator_t *scope;
68 subtree_lvl *pushed_tree;
69 uint8_t pushed_tree_index;
70 uint8_t pushed_tree_max;
71 proto_tree *tree;
72 tvbuff_t *tvb;
73 int offset;
74};
75
76#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
77
78/** See inlined comments.
79 @param tree the tree to append this item to
80 @param free_block a code block to call to free resources if this returns
81 @return NULL if 'tree' is null */
82#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
83 if (!tree) { \
84 free_block; \
85 return NULL((void*)0); \
86 }
87
88/** See inlined comments.
89 @param tree the tree to append this item to
90 @return NULL if 'tree' is null */
91#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
92 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
93
94/** See inlined comments.
95 @param length the length of this item
96 @param cleanup_block a code block to call to free resources if this returns
97 @return NULL if 'length' is lower -1 or equal 0 */
98#define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return (
(void*)0); }
\
99 if (length < -1 || length == 0 ) { \
100 cleanup_block; \
101 return NULL((void*)0); \
102 }
103
104/** See inlined comments.
105 @param length the length of this item
106 @return NULL if 'length' is lower -1 or equal 0 */
107#define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
\
108 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
109
110/** See inlined comments.
111 @param tree the tree to append this item to
112 @param hfindex field index
113 @param hfinfo header_field
114 @param free_block a code block to call to free resources if this returns
115 @return the header field matching 'hfinfo' */
116#define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 116
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 116, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 116, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 116, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { free_block; return proto_tree_add_fake_node(tree, hfinfo
); } } }
\
117 /* If the tree is not visible and this item is not referenced \
118 we don't have to do much work at all but we should still \
119 return a node so that referenced field items below this node \
120 (think proto_item_add_subtree()) will still have somewhere \
121 to attach to or else filtering will not work (they would be \
122 ignored since tree would be NULL). \
123 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
124 because that means we can change its length or repr, and we \
125 don't want to do so with calls intended for this faked new \
126 item, so this item needs a new (hidden) child node. \
127 We fake FT_PROTOCOL unless some clients have requested us \
128 not to do so. \
129 */ \
130 PTREE_DATA(tree)((tree)->tree_data)->count++; \
131 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 131, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 131, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 131, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
132 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
133 free_block; \
134 if (wireshark_abort_on_too_many_items) \
135 ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 136
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
136 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 136
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
137 /* Let the exception handler add items to the tree */ \
138 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
139 THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
140 wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
141 "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
142 hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
; \
143 } \
144 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
145 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
146 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
147 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
148 && (hfinfo->type != FT_PROTOCOL || \
149 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
150 free_block; \
151 /* return fake node with no field info */\
152 return proto_tree_add_fake_node(tree, hfinfo); \
153 } \
154 } \
155 }
156
157/** See inlined comments.
158 @param tree the tree to append this item to
159 @param hfindex field index
160 @param hfinfo header_field
161 @return the header field matching 'hfinfo' */
162#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 162
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 162, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 162, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 162, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
\
163 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 163
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 163, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 163, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 163, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
164
165
166/** See inlined comments.
167 @param pi the created protocol item we're about to return */
168#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 168, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
169 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 169, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
170 if (!PITEM_FINFO(pi)((pi)->finfo)) \
171 return pi; \
172 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
173 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
174 /* If the tree (GUI) or item isn't visible it's pointless for \
175 * us to generate the protocol item's string representation */ \
176 return pi; \
177 }
178/* Same as above but returning void */
179#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
180 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
181 return; \
182 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
183 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
184 /* If the tree (GUI) or item isn't visible it's pointless for \
185 * us to generate the protocol item's string representation */ \
186 return; \
187 }
188/* Similar to above, but allows a NULL tree */
189#define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
\
190 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
191 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
192 /* If the tree (GUI) or item isn't visible it's pointless for \
193 * us to generate the protocol item's string representation */ \
194 return pi; \
195 }
196
197#ifdef ENABLE_CHECK_FILTER
198#define CHECK_HF_VALUE(type, spec, start_values) \
199{ \
200 const type *current; \
201 int n, m; \
202 current = start_values; \
203 for (n=0; current; n++, current++) { \
204 /* Drop out if we reached the end. */ \
205 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
206 break; \
207 } \
208 /* Check value against all previous */ \
209 for (m=0; m < n; m++) { \
210 /* There are lots of duplicates with the same string, \
211 so only report if different... */ \
212 if ((start_values[m].value == current->value) && \
213 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
214 ws_warning("Field '%s' (%s) has a conflicting entry in its" \do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 217, __func__, "Field '%s' (%s) has a conflicting entry in its"
" value_string: %" spec " is at indices %u (%s) and %u (%s)"
, hfinfo->name, hfinfo->abbrev, current->value, m, start_values
[m].strptr, n, current->strptr); } } while (0)
215 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 217, __func__, "Field '%s' (%s) has a conflicting entry in its"
" value_string: %" spec " is at indices %u (%s) and %u (%s)"
, hfinfo->name, hfinfo->abbrev, current->value, m, start_values
[m].strptr, n, current->strptr); } } while (0)
216 hfinfo->name, hfinfo->abbrev, \do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 217, __func__, "Field '%s' (%s) has a conflicting entry in its"
" value_string: %" spec " is at indices %u (%s) and %u (%s)"
, hfinfo->name, hfinfo->abbrev, current->value, m, start_values
[m].strptr, n, current->strptr); } } while (0)
217 current->value, m, start_values[m].strptr, n, current->strptr)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 217, __func__, "Field '%s' (%s) has a conflicting entry in its"
" value_string: %" spec " is at indices %u (%s) and %u (%s)"
, hfinfo->name, hfinfo->abbrev, current->value, m, start_values
[m].strptr, n, current->strptr); } } while (0)
; \
218 } \
219 } \
220 } \
221}
222#endif
223
224/* The longest NUMBER-like field label we have is for BASE_OUI, which
225 * can have up to 64 bytes for the manufacturer name if resolved plus
226 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
227 */
228#define NUMBER_LABEL_LENGTH80 80
229
230static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
231static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
232static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
233static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
234static int hfinfo_bitoffset(const header_field_info *hfinfo);
235static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
236static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
237
238#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
239 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
240
241static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
242static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
243#define LABEL_MARK_TRUNCATED_START(label_str, value_pos)label_mark_truncated(label_str, 0, value_pos) label_mark_truncated(label_str, 0, value_pos)
244
245static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
246static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
247static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
248static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
249static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
250static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252
253static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
254static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
255static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
256static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
257
258static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
259static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
260static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
261static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
264static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
265static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
266static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
267static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
268
269static void proto_cleanup_base(void);
270
271static proto_item *
272proto_tree_add_node(proto_tree *tree, field_info *fi);
273
274static proto_item *
275proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
276
277static void
278get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
279 int *item_length, const unsigned encoding);
280
281static int
282get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
283 int length, unsigned item_length, const int encoding);
284
285static field_info *
286new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
287 const int start, const int item_length);
288
289static proto_item *
290proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
291 int start, int *length);
292
293static void
294proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
295static void
296proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
297
298static void
299proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
300static void
301proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
302static void
303proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
304static void
305proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
306static void
307proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
308static void
309proto_tree_set_string(field_info *fi, const char* value);
310static void
311proto_tree_set_ax25(field_info *fi, const uint8_t* value);
312static void
313proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
314static void
315proto_tree_set_vines(field_info *fi, const uint8_t* value);
316static void
317proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
318static void
319proto_tree_set_ether(field_info *fi, const uint8_t* value);
320static void
321proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
322static void
323proto_tree_set_ipxnet(field_info *fi, uint32_t value);
324static void
325proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
326static void
327proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
328static void
329proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
330static void
331proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
332static void
333proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
334static void
335proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
336static void
337proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
338static void
339proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
340static void
341proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
342static void
343proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
344static void
345proto_tree_set_boolean(field_info *fi, uint64_t value);
346static void
347proto_tree_set_float(field_info *fi, float value);
348static void
349proto_tree_set_double(field_info *fi, double value);
350static void
351proto_tree_set_uint(field_info *fi, uint32_t value);
352static void
353proto_tree_set_int(field_info *fi, int32_t value);
354static void
355proto_tree_set_uint64(field_info *fi, uint64_t value);
356static void
357proto_tree_set_int64(field_info *fi, int64_t value);
358static void
359proto_tree_set_eui64(field_info *fi, const uint64_t value);
360static void
361proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
362
363/* Handle type length mismatch (now filterable) expert info */
364static int proto_type_length_mismatch;
365static expert_field ei_type_length_mismatch_error;
366static expert_field ei_type_length_mismatch_warn;
367static void register_type_length_mismatch(void);
368
369/* Handle byte array string decoding errors with expert info */
370static int proto_byte_array_string_decoding_error;
371static expert_field ei_byte_array_string_decoding_failed_error;
372static void register_byte_array_string_decodinws_error(void);
373
374/* Handle date and time string decoding errors with expert info */
375static int proto_date_time_string_decoding_error;
376static expert_field ei_date_time_string_decoding_failed_error;
377static void register_date_time_string_decodinws_error(void);
378
379/* Handle string errors expert info */
380static int proto_string_errors;
381static expert_field ei_string_trailing_characters;
382static void register_string_errors(void);
383
384static int proto_register_field_init(header_field_info *hfinfo, const int parent);
385
386/* special-case header field used within proto.c */
387static header_field_info hfi_text_only =
388 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
389int hf_text_only;
390
391/* Structure for information about a protocol */
392struct _protocol {
393 const char *name; /* long description */
394 const char *short_name; /* short description */
395 const char *filter_name; /* name of this protocol in filters */
396 GPtrArray *fields; /* fields for this protocol */
397 int proto_id; /* field ID for this protocol */
398 bool_Bool is_enabled; /* true if protocol is enabled */
399 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
400 bool_Bool can_toggle; /* true if is_enabled can be changed */
401 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
402 For dissectors that need a protocol name so they
403 can be added to a dissector table, but use the
404 parent_proto_id for things like enable/disable */
405 GList *heur_list; /* Heuristic dissectors associated with this protocol */
406};
407
408/* List of all protocols */
409static GList *protocols;
410
411/* Structure stored for deregistered g_slice */
412struct g_slice_data {
413 size_t block_size;
414 void *mem_block;
415};
416
417/* Deregistered fields */
418static GPtrArray *deregistered_fields;
419static GPtrArray *deregistered_data;
420static GPtrArray *deregistered_slice;
421
422/* indexed by prefix, contains initializers */
423static GHashTable* prefixes;
424
425/* Contains information about a field when a dissector calls
426 * proto_tree_add_item. */
427#define FIELD_INFO_NEW(pool, fi)fi = ((field_info*)wmem_alloc((pool), sizeof(field_info))) fi = wmem_new(pool, field_info)((field_info*)wmem_alloc((pool), sizeof(field_info)))
428#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
429
430/* Contains the space for proto_nodes. */
431#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
432 node->first_child = NULL((void*)0); \
433 node->last_child = NULL((void*)0); \
434 node->next = NULL((void*)0);
435
436#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
437 wmem_free(pool, node)
438
439/* String space for protocol and field items for the GUI */
440#define ITEM_LABEL_NEW(pool, il)il = ((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))
); il->value_pos = 0; il->value_len = 0;
\
441 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
442 il->value_pos = 0; \
443 il->value_len = 0;
444#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
445 wmem_free(pool, il);
446
447#define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 447, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 447, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 447, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
448 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
449 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 449
, __func__, "Unregistered hf! index=%d", hfindex)
; \
450 DISSECTOR_ASSERT_HINT(hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len, "Unregistered hf!")((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 450, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
451 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!")((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 451, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
452 hfinfo = gpa_hfinfo.hfi[hfindex];
453
454/* List which stores protocols and fields that have been registered */
455typedef struct _gpa_hfinfo_t {
456 uint32_t len;
457 uint32_t allocated_len;
458 header_field_info **hfi;
459} gpa_hfinfo_t;
460
461static gpa_hfinfo_t gpa_hfinfo;
462
463/* Hash table of abbreviations and IDs */
464static GHashTable *gpa_name_map;
465static header_field_info *same_name_hfinfo;
466
467/* Hash table protocol aliases. const char * -> const char * */
468static GHashTable *gpa_protocol_aliases;
469
470/*
471 * We're called repeatedly with the same field name when sorting a column.
472 * Cache our last gpa_name_map hit for faster lookups.
473 */
474static char *last_field_name;
475static header_field_info *last_hfinfo;
476
477static void save_same_name_hfinfo(void *data)
478{
479 same_name_hfinfo = (header_field_info*)data;
480}
481
482/* Points to the first element of an array of bits, indexed by
483 a subtree item type; that array element is true if subtrees of
484 an item of that type are to be expanded. */
485static uint32_t *tree_is_expanded;
486
487/* Number of elements in that array. The entry with index 0 is not used. */
488int num_tree_types = 1;
489
490/* Name hashtables for fast detection of duplicate names */
491static GHashTable* proto_names;
492static GHashTable* proto_short_names;
493static GHashTable* proto_filter_names;
494
495static const char *reserved_filter_names[] = {
496 /* Display filter keywords. */
497 "eq",
498 "ne",
499 "all_eq",
500 "any_eq",
501 "all_ne",
502 "any_ne",
503 "gt",
504 "ge",
505 "lt",
506 "le",
507 "bitand",
508 "bitwise_and",
509 "contains",
510 "matches",
511 "not",
512 "and",
513 "or",
514 "xor",
515 "in",
516 "any",
517 "all",
518 "true",
519 "false",
520 "nan",
521 "inf",
522 "infinity",
523 NULL((void*)0)
524};
525
526static GHashTable *proto_reserved_filter_names;
527
528static int
529proto_compare_name(const void *p1_arg, const void *p2_arg)
530{
531 const protocol_t *p1 = (const protocol_t *)p1_arg;
532 const protocol_t *p2 = (const protocol_t *)p2_arg;
533
534 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
535}
536
537static GSList *dissector_plugins;
538
539#ifdef HAVE_PLUGINS1
540void
541proto_register_plugin(const proto_plugin *plug)
542{
543 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
544}
545#else /* HAVE_PLUGINS */
546void
547proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
548{
549 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 549, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
550}
551#endif /* HAVE_PLUGINS */
552
553static void
554call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
555{
556 proto_plugin *plug = (proto_plugin *)data;
557
558 if (plug->register_protoinfo) {
559 plug->register_protoinfo();
560 }
561}
562
563static void
564call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
565{
566 proto_plugin *plug = (proto_plugin *)data;
567
568 if (plug->register_handoff) {
569 plug->register_handoff();
570 }
571}
572
573/* initialize data structures and register protocols and fields */
574void
575proto_init(GSList *register_all_plugin_protocols_list,
576 GSList *register_all_plugin_handoffs_list,
577 register_cb cb,
578 void *client_data)
579{
580 proto_cleanup_base();
581
582 proto_names = g_hash_table_new(g_str_hash, g_str_equal);
583 proto_short_names = g_hash_table_new(g_str_hash, g_str_equal);
584 proto_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
585
586 proto_reserved_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
587 for (const char **ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
588 /* GHashTable has no key destructor so the cast is safe. */
589 g_hash_table_add(proto_reserved_filter_names, *(char **)ptr);
590 }
591
592 gpa_hfinfo.len = 0;
593 gpa_hfinfo.allocated_len = 0;
594 gpa_hfinfo.hfi = NULL((void*)0);
595 gpa_name_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL((void*)0), save_same_name_hfinfo);
596 gpa_protocol_aliases = g_hash_table_new(g_str_hash, g_str_equal);
597 deregistered_fields = g_ptr_array_new();
598 deregistered_data = g_ptr_array_new();
599 deregistered_slice = g_ptr_array_new();
600
601 /* Initialize the ftype subsystem */
602 ftypes_initialize();
603
604 /* Initialize the address type subsystem */
605 address_types_initialize();
606
607 /* Register one special-case FT_TEXT_ONLY field for use when
608 converting wireshark to new-style proto_tree. These fields
609 are merely strings on the GUI tree; they are not filterable */
610 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
611
612 /* Register the pseudo-protocols used for exceptions. */
613 register_show_exception();
614 register_type_length_mismatch();
615 register_byte_array_string_decodinws_error();
616 register_date_time_string_decodinws_error();
617 register_string_errors();
618 ftypes_register_pseudofields();
619 col_register_protocol();
620
621 /* Have each built-in dissector register its protocols, fields,
622 dissector tables, and dissectors to be called through a
623 handle, and do whatever one-time initialization it needs to
624 do. */
625 register_all_protocols(cb, client_data);
626
627 /* Now call the registration routines for all epan plugins. */
628 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
629 ((void (*)(register_cb, void *))l->data)(cb, client_data);
630 }
631
632 /* Now call the registration routines for all dissector plugins. */
633 if (cb)
634 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
635 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
636
637 /* Now call the "handoff registration" routines of all built-in
638 dissectors; those routines register the dissector in other
639 dissectors' handoff tables, and fetch any dissector handles
640 they need. */
641 register_all_protocol_handoffs(cb, client_data);
642
643 /* Now do the same with epan plugins. */
644 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
645 ((void (*)(register_cb, void *))l->data)(cb, client_data);
646 }
647
648 /* Now do the same with dissector plugins. */
649 if (cb)
650 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
651 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
652
653 /* sort the protocols by protocol name */
654 protocols = g_list_sort(protocols, proto_compare_name);
655
656 /* sort the dissector handles in dissector tables (for -G reports
657 * and -d error messages. The GUI sorts the handles itself.) */
658 packet_all_tables_sort_handles();
659
660 /* We've assigned all the subtree type values; allocate the array
661 for them, and zero it out. */
662 tree_is_expanded = g_new0(uint32_t, (num_tree_types/32)+1)((uint32_t *) g_malloc0_n (((num_tree_types/32)+1), sizeof (uint32_t
)))
;
663}
664
665static void
666proto_cleanup_base(void)
667{
668 protocol_t *protocol;
669 header_field_info *hfinfo;
670
671 /* Free the abbrev/ID hash table */
672 if (gpa_name_map) {
673 g_hash_table_destroy(gpa_name_map);
674 gpa_name_map = NULL((void*)0);
675 }
676 if (gpa_protocol_aliases) {
677 g_hash_table_destroy(gpa_protocol_aliases);
678 gpa_protocol_aliases = NULL((void*)0);
679 }
680 g_free(last_field_name);
681 last_field_name = NULL((void*)0);
682
683 while (protocols) {
684 protocol = (protocol_t *)protocols->data;
685 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo)if((protocol->proto_id == 0 || (unsigned)protocol->proto_id
> gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 685
, __func__, "Unregistered hf! index=%d", protocol->proto_id
); ((void) ((protocol->proto_id > 0 && (unsigned
)protocol->proto_id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 685, "protocol->proto_id > 0 && (unsigned)protocol->proto_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[protocol->
proto_id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 685, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
686 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id)((void) ((protocol->proto_id == hfinfo->id) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 686, "protocol->proto_id == hfinfo->id"
))))
;
687
688 g_slice_free(header_field_info, hfinfo)do { if (1) g_slice_free1 (sizeof (header_field_info), (hfinfo
)); else (void) ((header_field_info*) 0 == (hfinfo)); } while
(0)
;
689 if (protocol->parent_proto_id != -1) {
690 // pino protocol
691 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 691, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
692 DISSECTOR_ASSERT(protocol->heur_list == NULL)((void) ((protocol->heur_list == ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 692, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
693 } else {
694 if (protocol->fields) {
695 g_ptr_array_free(protocol->fields, true1);
696 }
697 g_list_free(protocol->heur_list);
698 }
699 protocols = g_list_remove(protocols, protocol);
700 g_free(protocol);
701 }
702
703 if (proto_names) {
704 g_hash_table_destroy(proto_names);
705 proto_names = NULL((void*)0);
706 }
707
708 if (proto_short_names) {
709 g_hash_table_destroy(proto_short_names);
710 proto_short_names = NULL((void*)0);
711 }
712
713 if (proto_filter_names) {
714 g_hash_table_destroy(proto_filter_names);
715 proto_filter_names = NULL((void*)0);
716 }
717
718 if (proto_reserved_filter_names) {
719 g_hash_table_destroy(proto_reserved_filter_names);
720 proto_reserved_filter_names = NULL((void*)0);
721 }
722
723 if (gpa_hfinfo.allocated_len) {
724 gpa_hfinfo.len = 0;
725 gpa_hfinfo.allocated_len = 0;
726 g_free(gpa_hfinfo.hfi);
727 gpa_hfinfo.hfi = NULL((void*)0);
728 }
729
730 if (deregistered_fields) {
731 g_ptr_array_free(deregistered_fields, true1);
732 deregistered_fields = NULL((void*)0);
733 }
734
735 if (deregistered_data) {
736 g_ptr_array_free(deregistered_data, true1);
737 deregistered_data = NULL((void*)0);
738 }
739
740 if (deregistered_slice) {
741 g_ptr_array_free(deregistered_slice, true1);
742 deregistered_slice = NULL((void*)0);
743 }
744
745 g_free(tree_is_expanded);
746 tree_is_expanded = NULL((void*)0);
747
748 if (prefixes)
749 g_hash_table_destroy(prefixes);
750}
751
752void
753proto_cleanup(void)
754{
755 proto_free_deregistered_fields();
756 proto_cleanup_base();
757
758 g_slist_free(dissector_plugins);
759 dissector_plugins = NULL((void*)0);
760}
761
762static bool_Bool
763// NOLINTNEXTLINE(misc-no-recursion)
764proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
765 void *data)
766{
767 proto_node *pnode = tree;
768 proto_node *child;
769 proto_node *current;
770
771 if (func(pnode, data))
772 return true1;
773
774 child = pnode->first_child;
775 while (child != NULL((void*)0)) {
776 /*
777 * The routine we call might modify the child, e.g. by
778 * freeing it, so we get the child's successor before
779 * calling that routine.
780 */
781 current = child;
782 child = current->next;
783 // We recurse here, but we're limited by prefs.gui_max_tree_depth
784 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
785 return true1;
786 }
787
788 return false0;
789}
790
791void
792proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
793 void *data)
794{
795 proto_node *node = tree;
796 proto_node *current;
797
798 if (!node)
799 return;
800
801 node = node->first_child;
802 while (node != NULL((void*)0)) {
803 current = node;
804 node = current->next;
805 func((proto_tree *)current, data);
806 }
807}
808
809static void
810free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
811{
812 GPtrArray *ptrs = (GPtrArray *)value;
813 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
814 header_field_info *hfinfo;
815
816 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo)if((hfid == 0 || (unsigned)hfid > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 816, __func__, "Unregistered hf! index=%d",
hfid); ((void) ((hfid > 0 && (unsigned)hfid < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 816, "hfid > 0 && (unsigned)hfid < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfid] != (
(void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 816, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
817 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
818 /* when a field is referenced by a filter this also
819 affects the refcount for the parent protocol so we need
820 to adjust the refcount for the parent as well
821 */
822 if (hfinfo->parent != -1) {
823 header_field_info *parent_hfinfo;
824 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo)if((hfinfo->parent == 0 || (unsigned)hfinfo->parent >
gpa_hfinfo.len) && wireshark_abort_on_dissector_bug)
ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 824
, __func__, "Unregistered hf! index=%d", hfinfo->parent); (
(void) ((hfinfo->parent > 0 && (unsigned)hfinfo
->parent < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 824, "hfinfo->parent > 0 && (unsigned)hfinfo->parent < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
parent] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 824, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
825 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
826 }
827 hfinfo->ref_type = HF_REF_TYPE_NONE;
828 }
829
830 g_ptr_array_free(ptrs, true1);
831}
832
833static void
834proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
835{
836 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
837
838 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
839
840 if (finfo) {
841 fvalue_free(finfo->value);
842 finfo->value = NULL((void*)0);
843 }
844}
845
846void
847proto_tree_reset(proto_tree *tree)
848{
849 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
850
851 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
852
853 /* free tree data */
854 if (tree_data->interesting_hfids) {
855 /* Free all the GPtrArray's in the interesting_hfids hash. */
856 g_hash_table_foreach(tree_data->interesting_hfids,
857 free_GPtrArray_value, NULL((void*)0));
858
859 /* And then remove all values. */
860 g_hash_table_remove_all(tree_data->interesting_hfids);
861 }
862
863 /* Reset track of the number of children */
864 tree_data->count = 0;
865
866 /* Reset our loop checks */
867 tree_data->idle_count_ds_tvb = NULL((void*)0);
868 tree_data->max_start = 0;
869 tree_data->start_idle_count = 0;
870
871 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
872}
873
874/* frees the resources that the dissection a proto_tree uses */
875void
876proto_tree_free(proto_tree *tree)
877{
878 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
879
880 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
881
882 /* free tree data */
883 if (tree_data->interesting_hfids) {
884 /* Free all the GPtrArray's in the interesting_hfids hash. */
885 g_hash_table_foreach(tree_data->interesting_hfids,
886 free_GPtrArray_value, NULL((void*)0));
887
888 /* And then destroy the hash. */
889 g_hash_table_destroy(tree_data->interesting_hfids);
890 }
891
892 g_slice_free(tree_data_t, tree_data)do { if (1) g_slice_free1 (sizeof (tree_data_t), (tree_data))
; else (void) ((tree_data_t*) 0 == (tree_data)); } while (0)
;
893
894 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
895}
896
897/* Is the parsing being done for a visible proto_tree or an invisible one?
898 * By setting this correctly, the proto_tree creation is sped up by not
899 * having to call vsnprintf and copy strings around.
900 */
901bool_Bool
902proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
903{
904 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
905
906 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
907
908 return old_visible;
909}
910
911void
912proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
913{
914 if (tree)
915 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
916}
917
918/* Assume dissector set only its protocol fields.
919 This function is called by dissectors and allows the speeding up of filtering
920 in wireshark; if this function returns false it is safe to reset tree to NULL
921 and thus skip calling most of the expensive proto_tree_add_...()
922 functions.
923 If the tree is visible we implicitly assume the field is referenced.
924*/
925bool_Bool
926proto_field_is_referenced(proto_tree *tree, int proto_id)
927{
928 register header_field_info *hfinfo;
929
930
931 if (!tree)
932 return false0;
933
934 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
935 return true1;
936
937 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo)if((proto_id == 0 || (unsigned)proto_id > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 937, __func__, "Unregistered hf! index=%d",
proto_id); ((void) ((proto_id > 0 && (unsigned)proto_id
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 937, "proto_id > 0 && (unsigned)proto_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[proto_id]
!= ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 937, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
938 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
939 return true1;
940
941 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
942 return true1;
943
944 return false0;
945}
946
947
948/* Finds a record in the hfinfo array by id. */
949header_field_info *
950proto_registrar_get_nth(unsigned hfindex)
951{
952 register header_field_info *hfinfo;
953
954 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 954, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 954, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 954, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
955 return hfinfo;
956}
957
958
959/* Prefix initialization
960 * this allows for a dissector to register a display filter name prefix
961 * so that it can delay the initialization of the hf array as long as
962 * possible.
963 */
964
965/* compute a hash for the part before the dot of a display filter */
966static unsigned
967prefix_hash (const void *key) {
968 /* end the string at the dot and compute its hash */
969 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
970 char* c = copy;
971 unsigned tmp;
972
973 for (; *c; c++) {
974 if (*c == '.') {
975 *c = 0;
976 break;
977 }
978 }
979
980 tmp = g_str_hash(copy);
981 g_free(copy);
982 return tmp;
983}
984
985/* are both strings equal up to the end or the dot? */
986static gboolean
987prefix_equal (const void *ap, const void *bp) {
988 const char* a = (const char *)ap;
989 const char* b = (const char *)bp;
990
991 do {
992 char ac = *a++;
993 char bc = *b++;
994
995 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
996
997 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
998 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
999
1000 if (ac != bc) return FALSE(0);
1001 } while (1);
1002
1003 return FALSE(0);
1004}
1005
1006/* Register a new prefix for "delayed" initialization of field arrays */
1007void
1008proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1009 if (! prefixes ) {
1010 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1011 }
1012
1013 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1014}
1015
1016/* helper to call all prefix initializers */
1017static gboolean
1018initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1019 ((prefix_initializer_t)v)((const char *)k);
1020 return TRUE(!(0));
1021}
1022
1023/** Initialize every remaining uninitialized prefix. */
1024void
1025proto_initialize_all_prefixes(void) {
1026 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1027}
1028
1029/* Finds a record in the hfinfo array by name.
1030 * If it fails to find it in the already registered fields,
1031 * it tries to find and call an initializer in the prefixes
1032 * table and if so it looks again.
1033 */
1034
1035header_field_info *
1036proto_registrar_get_byname(const char *field_name)
1037{
1038 header_field_info *hfinfo;
1039 prefix_initializer_t pi;
1040
1041 if (!field_name)
1042 return NULL((void*)0);
1043
1044 if (g_strcmp0(field_name, last_field_name) == 0) {
1045 return last_hfinfo;
1046 }
1047
1048 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
1049
1050 if (hfinfo) {
1051 g_free(last_field_name);
1052 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1053 last_hfinfo = hfinfo;
1054 return hfinfo;
1055 }
1056
1057 if (!prefixes)
1058 return NULL((void*)0);
1059
1060 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1061 pi(field_name);
1062 g_hash_table_remove(prefixes, field_name);
1063 } else {
1064 return NULL((void*)0);
1065 }
1066
1067 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
1068
1069 if (hfinfo) {
1070 g_free(last_field_name);
1071 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1072 last_hfinfo = hfinfo;
1073 }
1074 return hfinfo;
1075}
1076
1077header_field_info*
1078proto_registrar_get_byalias(const char *alias_name)
1079{
1080 if (!alias_name) {
1081 return NULL((void*)0);
1082 }
1083
1084 /* Find our aliased protocol. */
1085 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1086 char *dot = strchr(an_copy, '.');
1087 if (dot) {
1088 *dot = '\0';
1089 }
1090 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1091 if (!proto_pfx) {
1092 g_free(an_copy);
1093 return NULL((void*)0);
1094 }
1095
1096 /* Construct our aliased field and look it up. */
1097 GString *filter_name = g_string_new(proto_pfx);
1098 if (dot) {
1099 g_string_append_printf(filter_name, ".%s", dot+1);
1100 }
1101 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1102 g_free(an_copy);
1103 g_string_free(filter_name, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) (
(filter_name), ((!(0)))) : g_string_free_and_steal (filter_name
)) : (g_string_free) ((filter_name), ((!(0)))))
;
1104
1105 return hfinfo;
1106}
1107
1108int
1109proto_registrar_get_id_byname(const char *field_name)
1110{
1111 header_field_info *hfinfo;
1112
1113 hfinfo = proto_registrar_get_byname(field_name);
1114
1115 if (!hfinfo)
1116 return -1;
1117
1118 return hfinfo->id;
1119}
1120
1121static int
1122label_strcat_flags(const header_field_info *hfinfo)
1123{
1124 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1125 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1126
1127 return 0;
1128}
1129
1130static char *
1131format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1132 const uint8_t *bytes, unsigned length, size_t max_str_len)
1133{
1134 char *str = NULL((void*)0);
1135 const uint8_t *p;
1136 bool_Bool is_printable;
1137
1138 if (bytes) {
1139 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1140 /*
1141 * If all bytes are valid and printable UTF-8, show the
1142 * bytes as a string - in quotes to indicate that it's
1143 * a string.
1144 */
1145 if (isprint_utf8_string(bytes, length)) {
1146 str = wmem_strdup_printf(scope, "\"%.*s\"",
1147 (int)length, bytes);
1148 return str;
1149 }
1150 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1151 /*
1152 * Check whether all bytes are printable.
1153 */
1154 is_printable = true1;
1155 for (p = bytes; p < bytes+length; p++) {
1156 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1157 /* Not printable. */
1158 is_printable = false0;
1159 break;
1160 }
1161 }
1162
1163 /*
1164 * If all bytes are printable ASCII, show the bytes
1165 * as a string - in quotes to indicate that it's
1166 * a string.
1167 */
1168 if (is_printable) {
1169 str = wmem_strdup_printf(scope, "\"%.*s\"",
1170 (int)length, bytes);
1171 return str;
1172 }
1173 }
1174
1175 /*
1176 * Either it's not printable ASCII, or we don't care whether
1177 * it's printable ASCII; show it as hex bytes.
1178 */
1179 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1180 case SEP_DOT:
1181 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1182 break;
1183 case SEP_DASH:
1184 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1185 break;
1186 case SEP_COLON:
1187 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1188 break;
1189 case SEP_SPACE:
1190 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1191 break;
1192 case BASE_NONE:
1193 default:
1194 if (prefs.display_byte_fields_with_spaces) {
1195 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1196 } else {
1197 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1198 }
1199 break;
1200 }
1201 }
1202 else {
1203 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1204 str = wmem_strdup(scope, "<none>");
1205 } else {
1206 str = wmem_strdup(scope, "<MISSING>");
1207 }
1208 }
1209 return str;
1210}
1211
1212static char *
1213format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1214 const uint8_t *bytes, unsigned length)
1215{
1216 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1217}
1218
1219static void
1220ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1221{
1222 subtree_lvl *pushed_tree;
1223
1224 DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER)((void) ((ptvc->pushed_tree_max <= 256 -8) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 1224, "ptvc->pushed_tree_max <= 256-8"))))
;
1225 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1226
1227 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1228 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1228, "pushed_tree != ((void*)0)"
))))
;
1229 ptvc->pushed_tree = pushed_tree;
1230}
1231
1232static void
1233ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1234{
1235 ptvc->pushed_tree = NULL((void*)0);
1236 ptvc->pushed_tree_max = 0;
1237 DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0)((void) ((ptvc->pushed_tree_index == 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1237, "ptvc->pushed_tree_index == 0"
))))
;
1238 ptvc->pushed_tree_index = 0;
1239}
1240
1241/* Allocates an initializes a ptvcursor_t with 3 variables:
1242 * proto_tree, tvbuff, and offset. */
1243ptvcursor_t *
1244ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, int offset)
1245{
1246 ptvcursor_t *ptvc;
1247
1248 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1249 ptvc->scope = scope;
1250 ptvc->tree = tree;
1251 ptvc->tvb = tvb;
1252 ptvc->offset = offset;
1253 ptvc->pushed_tree = NULL((void*)0);
1254 ptvc->pushed_tree_max = 0;
1255 ptvc->pushed_tree_index = 0;
1256 return ptvc;
1257}
1258
1259
1260/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1261void
1262ptvcursor_free(ptvcursor_t *ptvc)
1263{
1264 ptvcursor_free_subtree_levels(ptvc);
1265 /*g_free(ptvc);*/
1266}
1267
1268/* Returns tvbuff. */
1269tvbuff_t *
1270ptvcursor_tvbuff(ptvcursor_t *ptvc)
1271{
1272 return ptvc->tvb;
1273}
1274
1275/* Returns current offset. */
1276int
1277ptvcursor_current_offset(ptvcursor_t *ptvc)
1278{
1279 return ptvc->offset;
1280}
1281
1282proto_tree *
1283ptvcursor_tree(ptvcursor_t *ptvc)
1284{
1285 if (!ptvc)
1286 return NULL((void*)0);
1287
1288 return ptvc->tree;
1289}
1290
1291void
1292ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1293{
1294 ptvc->tree = tree;
1295}
1296
1297/* creates a subtree, sets it as the working tree and pushes the old working tree */
1298proto_tree *
1299ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1300{
1301 subtree_lvl *subtree;
1302 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1303 ptvcursor_new_subtree_levels(ptvc);
1304
1305 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1306 subtree->tree = ptvc->tree;
1307 subtree->it= NULL((void*)0);
1308 ptvc->pushed_tree_index++;
1309 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1310}
1311
1312/* pops a subtree */
1313void
1314ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1315{
1316 subtree_lvl *subtree;
1317
1318 if (ptvc->pushed_tree_index <= 0)
1319 return;
1320
1321 ptvc->pushed_tree_index--;
1322 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1323 if (subtree->it != NULL((void*)0))
1324 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1325
1326 ptvc->tree = subtree->tree;
1327}
1328
1329/* saves the current tvb offset and the item in the current subtree level */
1330static void
1331ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1332{
1333 subtree_lvl *subtree;
1334
1335 DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0)((void) ((ptvc->pushed_tree_index > 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1335, "ptvc->pushed_tree_index > 0"
))))
;
1336
1337 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1338 subtree->it = it;
1339 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1340}
1341
1342/* Creates a subtree and adds it to the cursor as the working tree but does not
1343 * save the old working tree */
1344proto_tree *
1345ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1346{
1347 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1348 return ptvc->tree;
1349}
1350
1351static proto_tree *
1352ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1353{
1354 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1355 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1356 ptvcursor_subtree_set_item(ptvc, it);
1357 return ptvcursor_tree(ptvc);
1358}
1359
1360/* Add an item to the tree and create a subtree
1361 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1362 * In this case, when the subtree will be closed, the parent item length will
1363 * be equal to the advancement of the cursor since the creation of the subtree.
1364 */
1365proto_tree *
1366ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1367 const unsigned encoding, int ett_subtree)
1368{
1369 proto_item *it;
1370
1371 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1372 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1373}
1374
1375static proto_item *
1376proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1377
1378/* Add a text node to the tree and create a subtree
1379 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1380 * In this case, when the subtree will be closed, the item length will be equal
1381 * to the advancement of the cursor since the creation of the subtree.
1382 */
1383proto_tree *
1384ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1385 int ett_subtree, const char *format, ...)
1386{
1387 proto_item *pi;
1388 va_list ap;
1389 header_field_info *hfinfo;
1390 proto_tree *tree;
1391
1392 tree = ptvcursor_tree(ptvc);
1393
1394 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1395
1396 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1396
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1396, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1396, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1396, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1397
1398 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1399 ptvcursor_current_offset(ptvc), length);
1400
1401 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1401, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1402
1403 va_start(ap, format)__builtin_va_start(ap, format);
1404 proto_tree_set_representation(pi, format, ap);
1405 va_end(ap)__builtin_va_end(ap);
1406
1407 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1408}
1409
1410/* Add a text-only node, leaving it to our caller to fill the text in */
1411static proto_item *
1412proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1413{
1414 proto_item *pi;
1415
1416 if (tree == NULL((void*)0))
1417 return NULL((void*)0);
1418
1419 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1420
1421 return pi;
1422}
1423
1424/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1425proto_item *
1426proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1427 const char *format, ...)
1428{
1429 proto_item *pi;
1430 va_list ap;
1431 header_field_info *hfinfo;
1432
1433 if (length == -1) {
1434 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1435 } else {
1436 tvb_ensure_bytes_exist(tvb, start, length);
1437 }
1438
1439 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1440
1441 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1441
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1441, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1441, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1441, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1442
1443 pi = proto_tree_add_text_node(tree, tvb, start, length);
1444
1445 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1445, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1446
1447 va_start(ap, format)__builtin_va_start(ap, format);
1448 proto_tree_set_representation(pi, format, ap);
1449 va_end(ap)__builtin_va_end(ap);
1450
1451 return pi;
1452}
1453
1454/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1455proto_item *
1456proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1457 int length, const char *format, va_list ap)
1458{
1459 proto_item *pi;
1460 header_field_info *hfinfo;
1461
1462 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1463 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1464 * the length to be what's in the tvbuff if length is -1, and the
1465 * minimum of length and what's in the tvbuff if not.
1466 */
1467
1468 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1469
1470 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1470
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1470, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1470, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1470, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1471
1472 pi = proto_tree_add_text_node(tree, tvb, start, length);
1473
1474 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1474, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1475
1476 proto_tree_set_representation(pi, format, ap);
1477
1478 return pi;
1479}
1480
1481/* Add a text-only node that creates a subtree underneath.
1482 */
1483proto_tree *
1484proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1485{
1486 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1487}
1488
1489/* Add a text-only node that creates a subtree underneath.
1490 */
1491proto_tree *
1492proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1493{
1494 proto_tree *pt;
1495 proto_item *pi;
1496 va_list ap;
1497
1498 va_start(ap, format)__builtin_va_start(ap, format);
1499 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1500 va_end(ap)__builtin_va_end(ap);
1501
1502 if (tree_item != NULL((void*)0))
1503 *tree_item = pi;
1504
1505 pt = proto_item_add_subtree(pi, idx);
1506
1507 return pt;
1508}
1509
1510/* Add a text-only node for debugging purposes. The caller doesn't need
1511 * to worry about tvbuff, start, or length. Debug message gets sent to
1512 * STDOUT, too */
1513proto_item *
1514proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1515{
1516 proto_item *pi;
1517 va_list ap;
1518
1519 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1520
1521 if (pi) {
1522 va_start(ap, format)__builtin_va_start(ap, format);
1523 proto_tree_set_representation(pi, format, ap);
1524 va_end(ap)__builtin_va_end(ap);
1525 }
1526 va_start(ap, format)__builtin_va_start(ap, format);
1527 vprintf(format, ap);
1528 va_end(ap)__builtin_va_end(ap);
1529 printf("\n");
1530
1531 return pi;
1532}
1533
1534proto_item *
1535proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1536{
1537 proto_item *pi;
1538 header_field_info *hfinfo;
1539
1540 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1541
1542 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1542
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1542, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1542, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1542, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1543
1544 pi = proto_tree_add_text_node(tree, tvb, start, length);
1545
1546 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1546, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1547
1548 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1549
1550 return pi;
1551}
1552
1553proto_item *
1554proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1555{
1556 proto_item *pi;
1557 header_field_info *hfinfo;
1558 char *str;
1559
1560 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1561
1562 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1562
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1562, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1562, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1562, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1563
1564 pi = proto_tree_add_text_node(tree, tvb, start, length);
1565
1566 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1566, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1567
1568 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1569 proto_item_set_text(pi, "%s", str);
1570 wmem_free(NULL((void*)0), str);
1571
1572 return pi;
1573}
1574
1575void proto_report_dissector_bug(const char *format, ...)
1576{
1577 va_list args;
1578
1579 if (wireshark_abort_on_dissector_bug) {
1580 /*
1581 * Try to have the error message show up in the crash
1582 * information.
1583 */
1584 va_start(args, format)__builtin_va_start(args, format);
1585 ws_vadd_crash_info(format, args);
1586 va_end(args)__builtin_va_end(args);
1587
1588 /*
1589 * Print the error message.
1590 */
1591 va_start(args, format)__builtin_va_start(args, format);
1592 vfprintf(stderrstderr, format, args);
1593 va_end(args)__builtin_va_end(args);
1594 putc('\n', stderrstderr);
1595
1596 /*
1597 * And crash.
1598 */
1599 abort();
1600 } else {
1601 va_start(args, format)__builtin_va_start(args, format);
1602 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1603 va_end(args)__builtin_va_end(args);
1604 }
1605}
1606
1607/* We could probably get away with changing is_error to a minimum length value. */
1608static void
1609report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1610{
1611 if (is_error) {
1612 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1613 } else {
1614 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1615 }
1616
1617 if (is_error) {
1618 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1619 }
1620}
1621
1622static uint32_t
1623get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1624{
1625 uint32_t value;
1626 bool_Bool length_error;
1627
1628 switch (length) {
1629
1630 case 1:
1631 value = tvb_get_uint8(tvb, offset);
1632 if (encoding & ENC_ZIGBEE0x40000000) {
1633 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1634 value = 0;
1635 }
1636 }
1637 break;
1638
1639 case 2:
1640 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1641 : tvb_get_ntohs(tvb, offset);
1642 if (encoding & ENC_ZIGBEE0x40000000) {
1643 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1644 value = 0;
1645 }
1646 }
1647 break;
1648
1649 case 3:
1650 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1651 : tvb_get_ntoh24(tvb, offset);
1652 break;
1653
1654 case 4:
1655 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1656 : tvb_get_ntohl(tvb, offset);
1657 break;
1658
1659 default:
1660 if (length < 1) {
1661 length_error = true1;
1662 value = 0;
1663 } else {
1664 length_error = false0;
1665 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1666 : tvb_get_ntohl(tvb, offset);
1667 }
1668 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1669 break;
1670 }
1671 return value;
1672}
1673
1674static inline uint64_t
1675get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1676{
1677 uint64_t value;
1678
1679 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1680
1681 if (length < 1 || length > 8) {
1682 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1683 }
1684
1685 return value;
1686}
1687
1688static int32_t
1689get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1690{
1691 int32_t value;
1692 bool_Bool length_error;
1693
1694 switch (length) {
1695
1696 case 1:
1697 value = tvb_get_int8(tvb, offset);
1698 break;
1699
1700 case 2:
1701 value = encoding ? tvb_get_letohis(tvb, offset)
1702 : tvb_get_ntohis(tvb, offset);
1703 break;
1704
1705 case 3:
1706 value = encoding ? tvb_get_letohi24(tvb, offset)
1707 : tvb_get_ntohi24(tvb, offset);
1708 break;
1709
1710 case 4:
1711 value = encoding ? tvb_get_letohil(tvb, offset)
1712 : tvb_get_ntohil(tvb, offset);
1713 break;
1714
1715 default:
1716 if (length < 1) {
1717 length_error = true1;
1718 value = 0;
1719 } else {
1720 length_error = false0;
1721 value = encoding ? tvb_get_letohil(tvb, offset)
1722 : tvb_get_ntohil(tvb, offset);
1723 }
1724 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1725 break;
1726 }
1727 return value;
1728}
1729
1730/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1731 * be cast-able as a int64_t. This is weird, but what the code has always done.
1732 */
1733static inline uint64_t
1734get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1735{
1736 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1737
1738 switch (length) {
1739 case 7:
1740 value = ws_sign_ext64(value, 56);
1741 break;
1742 case 6:
1743 value = ws_sign_ext64(value, 48);
1744 break;
1745 case 5:
1746 value = ws_sign_ext64(value, 40);
1747 break;
1748 case 4:
1749 value = ws_sign_ext64(value, 32);
1750 break;
1751 case 3:
1752 value = ws_sign_ext64(value, 24);
1753 break;
1754 case 2:
1755 value = ws_sign_ext64(value, 16);
1756 break;
1757 case 1:
1758 value = ws_sign_ext64(value, 8);
1759 break;
1760 }
1761
1762 return value;
1763}
1764
1765/* For FT_STRING */
1766static inline const uint8_t *
1767get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1768 int length, int *ret_length, const unsigned encoding)
1769{
1770 if (length == -1) {
1771 length = tvb_ensure_captured_length_remaining(tvb, start);
1772 }
1773 *ret_length = length;
1774 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1775}
1776
1777/* For FT_STRINGZ */
1778static inline const uint8_t *
1779get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1780 int start, int length, int *ret_length, const unsigned encoding)
1781{
1782 const uint8_t *value;
1783
1784 if (length < -1) {
1785 report_type_length_mismatch(tree, "a string", length, true1);
1786 }
1787 if (length == -1) {
1788 /* This can throw an exception */
1789 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1790 } else {
1791 /* In this case, length signifies the length of the string.
1792 *
1793 * This could either be a null-padded string, which doesn't
1794 * necessarily have a '\0' at the end, or a null-terminated
1795 * string, with a trailing '\0'. (Yes, there are cases
1796 * where you have a string that's both counted and null-
1797 * terminated.)
1798 *
1799 * In the first case, we must allocate a buffer of length
1800 * "length+1", to make room for a trailing '\0'.
1801 *
1802 * In the second case, we don't assume that there is a
1803 * trailing '\0' there, as the packet might be malformed.
1804 * (XXX - should we throw an exception if there's no
1805 * trailing '\0'?) Therefore, we allocate a buffer of
1806 * length "length+1", and put in a trailing '\0', just to
1807 * be safe.
1808 *
1809 * (XXX - this would change if we made string values counted
1810 * rather than null-terminated.)
1811 */
1812 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1813 }
1814 *ret_length = length;
1815 return value;
1816}
1817
1818/* For FT_UINT_STRING */
1819static inline const uint8_t *
1820get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1821 tvbuff_t *tvb, int start, int length, int *ret_length,
1822 const unsigned encoding)
1823{
1824 uint32_t n;
1825 const uint8_t *value;
1826
1827 /* I believe it's ok if this is called with a NULL tree */
1828 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1829 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1830 length += n;
1831 *ret_length = length;
1832 return value;
1833}
1834
1835/* For FT_STRINGZPAD */
1836static inline const uint8_t *
1837get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1838 int length, int *ret_length, const unsigned encoding)
1839{
1840 /*
1841 * XXX - currently, string values are null-
1842 * terminated, so a "zero-padded" string
1843 * isn't special. If we represent string
1844 * values as something that includes a counted
1845 * array of bytes, we'll need to strip the
1846 * trailing NULs.
1847 */
1848 if (length == -1) {
1849 length = tvb_ensure_captured_length_remaining(tvb, start);
1850 }
1851 *ret_length = length;
1852 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1853}
1854
1855/* For FT_STRINGZTRUNC */
1856static inline const uint8_t *
1857get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1858 int length, int *ret_length, const unsigned encoding)
1859{
1860 /*
1861 * XXX - currently, string values are null-
1862 * terminated, so a "zero-truncated" string
1863 * isn't special. If we represent string
1864 * values as something that includes a counted
1865 * array of bytes, we'll need to strip everything
1866 * starting with the terminating NUL.
1867 */
1868 if (length == -1) {
1869 length = tvb_ensure_captured_length_remaining(tvb, start);
1870 }
1871 *ret_length = length;
1872 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1873}
1874
1875/*
1876 * Deltas between the epochs for various non-UN*X time stamp formats and
1877 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1878 * stamp format.
1879 */
1880
1881/*
1882 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1883 * XXX - if it's OK if this is unsigned, can we just use
1884 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1885 */
1886#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1887
1888/*
1889 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1890 */
1891#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1892
1893/* this can be called when there is no tree, so tree may be null */
1894static void
1895get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1896 const int length, const unsigned encoding, nstime_t *time_stamp,
1897 const bool_Bool is_relative)
1898{
1899 uint32_t tmpsecs;
1900 uint64_t tmp64secs;
1901 uint64_t todusecs;
1902
1903 switch (encoding) {
1904
1905 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1906 /*
1907 * If the length is 16, 8-byte seconds, followed
1908 * by 8-byte fractional time in nanoseconds,
1909 * both big-endian.
1910 *
1911 * If the length is 12, 8-byte seconds, followed
1912 * by 4-byte fractional time in nanoseconds,
1913 * both big-endian.
1914 *
1915 * If the length is 8, 4-byte seconds, followed
1916 * by 4-byte fractional time in nanoseconds,
1917 * both big-endian.
1918 *
1919 * For absolute times, the seconds are seconds
1920 * since the UN*X epoch.
1921 */
1922 if (length == 16) {
1923 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1924 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1925 } else if (length == 12) {
1926 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1927 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1928 } else if (length == 8) {
1929 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1930 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1931 } else if (length == 4) {
1932 /*
1933 * Backwards compatibility.
1934 * ENC_TIME_SECS_NSECS is 0; using
1935 * ENC_BIG_ENDIAN by itself with a 4-byte
1936 * time-in-seconds value was done in the
1937 * past.
1938 */
1939 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1940 time_stamp->nsecs = 0;
1941 } else {
1942 time_stamp->secs = 0;
1943 time_stamp->nsecs = 0;
1944 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1945 }
1946 break;
1947
1948 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
1949 /*
1950 * If the length is 16, 8-byte seconds, followed
1951 * by 8-byte fractional time in nanoseconds,
1952 * both little-endian.
1953 *
1954 * If the length is 12, 8-byte seconds, followed
1955 * by 4-byte fractional time in nanoseconds,
1956 * both little-endian.
1957 *
1958 * If the length is 8, 4-byte seconds, followed
1959 * by 4-byte fractional time in nanoseconds,
1960 * both little-endian.
1961 *
1962 * For absolute times, the seconds are seconds
1963 * since the UN*X epoch.
1964 */
1965 if (length == 16) {
1966 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
1967 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
1968 } else if (length == 12) {
1969 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
1970 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
1971 } else if (length == 8) {
1972 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1973 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1974 } else if (length == 4) {
1975 /*
1976 * Backwards compatibility.
1977 * ENC_TIME_SECS_NSECS is 0; using
1978 * ENC_LITTLE_ENDIAN by itself with a 4-byte
1979 * time-in-seconds value was done in the
1980 * past.
1981 */
1982 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1983 time_stamp->nsecs = 0;
1984 } else {
1985 time_stamp->secs = 0;
1986 time_stamp->nsecs = 0;
1987 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1988 }
1989 break;
1990
1991 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
1992 /*
1993 * NTP time stamp, big-endian.
1994 * Only supported for absolute times.
1995 */
1996 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1996, "!is_relative"
))))
;
1997
1998 /* We need a temporary variable here so the unsigned math
1999 * works correctly (for years > 2036 according to RFC 2030
2000 * chapter 3).
2001 *
2002 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2003 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2004 * If bit 0 is not set, the time is in the range 2036-2104 and
2005 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2006 */
2007 tmpsecs = tvb_get_ntohl(tvb, start);
2008 if ((tmpsecs & 0x80000000) != 0)
2009 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2010 else
2011 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2012
2013 if (length == 8) {
2014 tmp64secs = tvb_get_ntoh64(tvb, start);
2015 if (tmp64secs == 0) {
2016 //This is "NULL" time
2017 time_stamp->secs = 0;
2018 time_stamp->nsecs = 0;
2019 } else {
2020 /*
2021 * Convert 1/2^32s of a second to
2022 * nanoseconds.
2023 */
2024 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2025 }
2026 } else if (length == 4) {
2027 /*
2028 * Backwards compatibility.
2029 */
2030 if (tmpsecs == 0) {
2031 //This is "NULL" time
2032 time_stamp->secs = 0;
2033 }
2034 time_stamp->nsecs = 0;
2035 } else {
2036 time_stamp->secs = 0;
2037 time_stamp->nsecs = 0;
2038 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2039 }
2040 break;
2041
2042 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2043 /*
2044 * NTP time stamp, little-endian.
2045 * Only supported for absolute times.
2046 *
2047 * NTP doesn't use this, because it's an Internet format
2048 * and hence big-endian. Any implementation must decide
2049 * whether the NTP timestamp is a 64-bit unsigned fixed
2050 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2051 * with a 32-bit unsigned seconds field followed by a
2052 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2053 * the previous two).
2054 *
2055 * XXX: We do the latter, but no dissector uses this format.
2056 * OTOH, ERF timestamps do the former, so perhaps we
2057 * should switch the interpretation so that packet-erf.c
2058 * could use this directly?
2059 */
2060 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2060, "!is_relative"
))))
;
2061
2062 /* We need a temporary variable here so the unsigned math
2063 * works correctly (for years > 2036 according to RFC 2030
2064 * chapter 3).
2065 *
2066 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2067 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2068 * If bit 0 is not set, the time is in the range 2036-2104 and
2069 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2070 */
2071 tmpsecs = tvb_get_letohl(tvb, start);
2072 if ((tmpsecs & 0x80000000) != 0)
2073 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2074 else
2075 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2076
2077 if (length == 8) {
2078 tmp64secs = tvb_get_letoh64(tvb, start);
2079 if (tmp64secs == 0) {
2080 //This is "NULL" time
2081 time_stamp->secs = 0;
2082 time_stamp->nsecs = 0;
2083 } else {
2084 /*
2085 * Convert 1/2^32s of a second to
2086 * nanoseconds.
2087 */
2088 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2089 }
2090 } else if (length == 4) {
2091 /*
2092 * Backwards compatibility.
2093 */
2094 if (tmpsecs == 0) {
2095 //This is "NULL" time
2096 time_stamp->secs = 0;
2097 }
2098 time_stamp->nsecs = 0;
2099 } else {
2100 time_stamp->secs = 0;
2101 time_stamp->nsecs = 0;
2102 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2103 }
2104 break;
2105
2106 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2107 /*
2108 * S/3x0 and z/Architecture TOD clock time stamp,
2109 * big-endian. The epoch is January 1, 1900,
2110 * 00:00:00 (proleptic?) UTC.
2111 *
2112 * Only supported for absolute times.
2113 */
2114 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2114, "!is_relative"
))))
;
2115 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2115, "length == 8"
))))
;
2116
2117 if (length == 8) {
2118 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2119 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2120 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2121 } else {
2122 time_stamp->secs = 0;
2123 time_stamp->nsecs = 0;
2124 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2125 }
2126 break;
2127
2128 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2129 /*
2130 * S/3x0 and z/Architecture TOD clock time stamp,
2131 * little-endian. The epoch is January 1, 1900,
2132 * 00:00:00 (proleptic?) UTC.
2133 *
2134 * Only supported for absolute times.
2135 */
2136 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2136, "!is_relative"
))))
;
2137
2138 if (length == 8) {
2139 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2140 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2141 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2142 } else {
2143 time_stamp->secs = 0;
2144 time_stamp->nsecs = 0;
2145 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2146 }
2147 break;
2148
2149 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2150 /*
2151 * Time stamp using the same seconds/fraction format
2152 * as NTP, but with the origin of the time stamp being
2153 * the UNIX epoch rather than the NTP epoch; big-
2154 * endian.
2155 *
2156 * Only supported for absolute times.
2157 */
2158 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2158, "!is_relative"
))))
;
2159
2160 if (length == 8) {
2161 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2162 /*
2163 * Convert 1/2^32s of a second to nanoseconds.
2164 */
2165 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2166 } else {
2167 time_stamp->secs = 0;
2168 time_stamp->nsecs = 0;
2169 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2170 }
2171 break;
2172
2173 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2174 /*
2175 * Time stamp using the same seconds/fraction format
2176 * as NTP, but with the origin of the time stamp being
2177 * the UNIX epoch rather than the NTP epoch; little-
2178 * endian.
2179 *
2180 * Only supported for absolute times.
2181 *
2182 * The RTPS specification explicitly supports Little
2183 * Endian encoding. In one place, it states that its
2184 * Time_t representation "is the one defined by ...
2185 * RFC 1305", but in another explicitly defines it as
2186 * a struct consisting of an 32 bit unsigned seconds
2187 * field and a 32 bit unsigned fraction field, not a 64
2188 * bit fixed point, so we do that here.
2189 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2190 */
2191 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2191, "!is_relative"
))))
;
2192
2193 if (length == 8) {
2194 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2195 /*
2196 * Convert 1/2^32s of a second to nanoseconds.
2197 */
2198 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2199 } else {
2200 time_stamp->secs = 0;
2201 time_stamp->nsecs = 0;
2202 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2203 }
2204 break;
2205
2206 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2207 /*
2208 * MIP6 time stamp, big-endian.
2209 * A 64-bit unsigned integer field containing a timestamp. The
2210 * value indicates the number of seconds since January 1, 1970,
2211 * 00:00 UTC, by using a fixed point format. In this format, the
2212 * integer number of seconds is contained in the first 48 bits of
2213 * the field, and the remaining 16 bits indicate the number of
2214 * 1/65536 fractions of a second.
2215
2216 * Only supported for absolute times.
2217 */
2218 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2218, "!is_relative"
))))
;
2219
2220 if (length == 8) {
2221 /* We need a temporary variable here so the casting and fractions
2222 * of a second work correctly.
2223 */
2224 tmp64secs = tvb_get_ntoh48(tvb, start);
2225 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2226 tmpsecs <<= 16;
2227
2228 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2229 //This is "NULL" time
2230 time_stamp->secs = 0;
2231 time_stamp->nsecs = 0;
2232 } else {
2233 time_stamp->secs = (time_t)tmp64secs;
2234 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2235 }
2236 } else {
2237 time_stamp->secs = 0;
2238 time_stamp->nsecs = 0;
2239 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2240 }
2241 break;
2242
2243 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2244 /*
2245 * If the length is 16, 8-byte seconds, followed
2246 * by 8-byte fractional time in microseconds,
2247 * both big-endian.
2248 *
2249 * If the length is 12, 8-byte seconds, followed
2250 * by 4-byte fractional time in microseconds,
2251 * both big-endian.
2252 *
2253 * If the length is 8, 4-byte seconds, followed
2254 * by 4-byte fractional time in microseconds,
2255 * both big-endian.
2256 *
2257 * For absolute times, the seconds are seconds
2258 * since the UN*X epoch.
2259 */
2260 if (length == 16) {
2261 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2262 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2263 } else if (length == 12) {
2264 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2265 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2266 } else if (length == 8) {
2267 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2268 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2269 } else {
2270 time_stamp->secs = 0;
2271 time_stamp->nsecs = 0;
2272 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2273 }
2274 break;
2275
2276 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2277 /*
2278 * If the length is 16, 8-byte seconds, followed
2279 * by 8-byte fractional time in microseconds,
2280 * both little-endian.
2281 *
2282 * If the length is 12, 8-byte seconds, followed
2283 * by 4-byte fractional time in microseconds,
2284 * both little-endian.
2285 *
2286 * If the length is 8, 4-byte seconds, followed
2287 * by 4-byte fractional time in microseconds,
2288 * both little-endian.
2289 *
2290 * For absolute times, the seconds are seconds
2291 * since the UN*X epoch.
2292 */
2293 if (length == 16) {
2294 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2295 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2296 } else if (length == 12) {
2297 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2298 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2299 } else if (length == 8) {
2300 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2301 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2302 } else {
2303 time_stamp->secs = 0;
2304 time_stamp->nsecs = 0;
2305 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2306 }
2307 break;
2308
2309 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2310 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2311 /*
2312 * Seconds, 1 to 8 bytes.
2313 * For absolute times, it's seconds since the
2314 * UN*X epoch.
2315 */
2316 if (length >= 1 && length <= 8) {
2317 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2318 time_stamp->nsecs = 0;
2319 } else {
2320 time_stamp->secs = 0;
2321 time_stamp->nsecs = 0;
2322 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2323 }
2324 break;
2325
2326 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2327 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2328 /*
2329 * Milliseconds, 1 to 8 bytes.
2330 * For absolute times, it's milliseconds since the
2331 * UN*X epoch.
2332 */
2333 if (length >= 1 && length <= 8) {
2334 uint64_t msecs;
2335
2336 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2337 time_stamp->secs = (time_t)(msecs / 1000);
2338 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2339 } else {
2340 time_stamp->secs = 0;
2341 time_stamp->nsecs = 0;
2342 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2343 }
2344 break;
2345
2346 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2347 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2348 /*
2349 * Microseconds, 1 to 8 bytes.
2350 * For absolute times, it's microseconds since the
2351 * UN*X epoch.
2352 */
2353 if (length >= 1 && length <= 8) {
2354 uint64_t usecs;
2355
2356 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2357 time_stamp->secs = (time_t)(usecs / 1000000);
2358 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2359 } else {
2360 time_stamp->secs = 0;
2361 time_stamp->nsecs = 0;
2362 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2363 }
2364 break;
2365
2366 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2367 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2368 /*
2369 * nanoseconds, 1 to 8 bytes.
2370 * For absolute times, it's nanoseconds since the
2371 * UN*X epoch.
2372 */
2373
2374 if (length >= 1 && length <= 8) {
2375 uint64_t nsecs;
2376
2377 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2378 time_stamp->secs = (time_t)(nsecs / 1000000000);
2379 time_stamp->nsecs = (int)(nsecs % 1000000000);
2380 } else {
2381 time_stamp->secs = 0;
2382 time_stamp->nsecs = 0;
2383 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2384 }
2385 break;
2386
2387 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2388 /*
2389 * 1/64ths of a second since the UN*X epoch,
2390 * big-endian.
2391 *
2392 * Only supported for absolute times.
2393 */
2394 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2394, "!is_relative"
))))
;
2395
2396 if (length == 8) {
2397 /*
2398 * The upper 48 bits are seconds since the
2399 * UN*X epoch.
2400 */
2401 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2402 /*
2403 * The lower 16 bits are 1/2^16s of a second;
2404 * convert them to nanoseconds.
2405 *
2406 * XXX - this may give the impression of higher
2407 * precision than you actually get.
2408 */
2409 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2410 } else {
2411 time_stamp->secs = 0;
2412 time_stamp->nsecs = 0;
2413 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2414 }
2415 break;
2416
2417 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2418 /*
2419 * 1/64ths of a second since the UN*X epoch,
2420 * little-endian.
2421 *
2422 * Only supported for absolute times.
2423 */
2424 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2424, "!is_relative"
))))
;
2425
2426 if (length == 8) {
2427 /*
2428 * XXX - this is assuming that, if anybody
2429 * were ever to use this format - RFC 3971
2430 * doesn't, because that's an Internet
2431 * protocol, and those use network byte
2432 * order, i.e. big-endian - they'd treat it
2433 * as a 64-bit count of 1/2^16s of a second,
2434 * putting the upper 48 bits at the end.
2435 *
2436 * The lower 48 bits are seconds since the
2437 * UN*X epoch.
2438 */
2439 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2440 /*
2441 * The upper 16 bits are 1/2^16s of a second;
2442 * convert them to nanoseconds.
2443 *
2444 * XXX - this may give the impression of higher
2445 * precision than you actually get.
2446 */
2447 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2448 } else {
2449 time_stamp->secs = 0;
2450 time_stamp->nsecs = 0;
2451 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2452 }
2453 break;
2454
2455 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2456 /*
2457 * NTP time stamp, with 1-second resolution (i.e.,
2458 * seconds since the NTP epoch), big-endian.
2459 * Only supported for absolute times.
2460 */
2461 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2461, "!is_relative"
))))
;
2462
2463 if (length == 4) {
2464 /*
2465 * We need a temporary variable here so the unsigned math
2466 * works correctly (for years > 2036 according to RFC 2030
2467 * chapter 3).
2468 *
2469 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2470 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2471 * If bit 0 is not set, the time is in the range 2036-2104 and
2472 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2473 */
2474 tmpsecs = tvb_get_ntohl(tvb, start);
2475 if ((tmpsecs & 0x80000000) != 0)
2476 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2477 else
2478 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2479 time_stamp->nsecs = 0;
2480 } else {
2481 time_stamp->secs = 0;
2482 time_stamp->nsecs = 0;
2483 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2484 }
2485 break;
2486
2487 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2488 /*
2489 * NTP time stamp, with 1-second resolution (i.e.,
2490 * seconds since the NTP epoch), little-endian.
2491 * Only supported for absolute times.
2492 */
2493 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2493, "!is_relative"
))))
;
2494
2495 /*
2496 * We need a temporary variable here so the unsigned math
2497 * works correctly (for years > 2036 according to RFC 2030
2498 * chapter 3).
2499 *
2500 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2501 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2502 * If bit 0 is not set, the time is in the range 2036-2104 and
2503 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2504 */
2505 if (length == 4) {
2506 tmpsecs = tvb_get_letohl(tvb, start);
2507 if ((tmpsecs & 0x80000000) != 0)
2508 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2509 else
2510 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2511 time_stamp->nsecs = 0;
2512 } else {
2513 time_stamp->secs = 0;
2514 time_stamp->nsecs = 0;
2515 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2516 }
2517 break;
2518
2519 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2520 /*
2521 * Milliseconds, 6 to 8 bytes.
2522 * For absolute times, it's milliseconds since the
2523 * NTP epoch.
2524 *
2525 * ETSI TS 129.274 8.119 defines this as:
2526 * "a 48 bit unsigned integer in network order format
2527 * ...encoded as the number of milliseconds since
2528 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2529 * rounded value of 1000 x the value of the 64-bit
2530 * timestamp (Seconds + (Fraction / (1<<32))) defined
2531 * in clause 6 of IETF RFC 5905."
2532 *
2533 * Taken literally, the part after "i.e." would
2534 * mean that the value rolls over before reaching
2535 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2536 * when the 64 bit timestamp rolls over, and we have
2537 * to pick an NTP Era equivalence class to support
2538 * (such as 1968-01-20 to 2104-02-06).
2539 *
2540 * OTOH, the extra room might be used to store Era
2541 * information instead, in which case times until
2542 * 10819-08-03 can be represented with 6 bytes without
2543 * ambiguity. We handle both implementations, and assume
2544 * that times before 1968-01-20 are not represented.
2545 *
2546 * Only 6 bytes or more makes sense as an absolute
2547 * time. 5 bytes or fewer could express a span of
2548 * less than 35 years, either 1900-1934 or 2036-2070.
2549 */
2550 if (length >= 6 && length <= 8) {
2551 uint64_t msecs;
2552
2553 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2554 tmp64secs = (msecs / 1000);
2555 /*
2556 * Assume that times in the first half of NTP
2557 * Era 0 really represent times in the NTP
2558 * Era 1.
2559 */
2560 if (tmp64secs >= 0x80000000)
2561 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2562 else
2563 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2564 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2565 }
2566 else {
2567 time_stamp->secs = 0;
2568 time_stamp->nsecs = 0;
2569 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2570 }
2571 break;
2572
2573 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2574 /*
2575 * MP4 file time stamps, big-endian.
2576 * Only supported for absolute times.
2577 */
2578 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2578, "!is_relative"
))))
;
2579
2580 if (length == 8) {
2581 tmp64secs = tvb_get_ntoh64(tvb, start);
2582 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2583 time_stamp->nsecs = 0;
2584 } else if (length == 4) {
2585 tmpsecs = tvb_get_ntohl(tvb, start);
2586 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2587 time_stamp->nsecs = 0;
2588 } else {
2589 time_stamp->secs = 0;
2590 time_stamp->nsecs = 0;
2591 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2592 }
2593 break;
2594
2595 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2596 /*
2597 * Zigbee ZCL time stamps, big-endian.
2598 * Only supported for absolute times.
2599 */
2600 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2600, "!is_relative"
))))
;
2601
2602 if (length == 8) {
2603 tmp64secs = tvb_get_ntoh64(tvb, start);
2604 time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2605 time_stamp->nsecs = 0;
2606 } else if (length == 4) {
2607 tmpsecs = tvb_get_ntohl(tvb, start);
2608 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2609 time_stamp->nsecs = 0;
2610 } else {
2611 time_stamp->secs = 0;
2612 time_stamp->nsecs = 0;
2613 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2614 }
2615 break;
2616
2617 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2618 /*
2619 * Zigbee ZCL time stamps, little-endian.
2620 * Only supported for absolute times.
2621 */
2622 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2622, "!is_relative"
))))
;
2623
2624 if (length == 8) {
2625 tmp64secs = tvb_get_letoh64(tvb, start);
2626 time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2627 time_stamp->nsecs = 0;
2628 } else if (length == 4) {
2629 tmpsecs = tvb_get_letohl(tvb, start);
2630 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2631 time_stamp->nsecs = 0;
2632 } else {
2633 time_stamp->secs = 0;
2634 time_stamp->nsecs = 0;
2635 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2636 }
2637 break;
2638
2639 default:
2640 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2640))
;
2641 break;
2642 }
2643}
2644
2645static void
2646tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2647{
2648 const header_field_info *hfinfo = fi->hfinfo;
2649
2650 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2651 GPtrArray *ptrs = NULL((void*)0);
2652
2653 if (tree_data->interesting_hfids == NULL((void*)0)) {
2654 /* Initialize the hash because we now know that it is needed */
2655 tree_data->interesting_hfids =
2656 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2657 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2658 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2659 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2660 }
2661
2662 if (!ptrs) {
2663 /* First element triggers the creation of pointer array */
2664 ptrs = g_ptr_array_new();
2665 g_hash_table_insert(tree_data->interesting_hfids,
2666 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2667 }
2668
2669 g_ptr_array_add(ptrs, fi);
2670 }
2671}
2672
2673
2674/*
2675 * Validates that field length bytes are available starting from
2676 * start (pos/neg). Throws an exception if they aren't.
2677 */
2678static void
2679test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2680 int start, int length, const unsigned encoding)
2681{
2682 int size = length;
2683
2684 if (!tvb)
2685 return;
2686
2687 if ((hfinfo->type == FT_STRINGZ) ||
2688 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2689 (FT_IS_UINT(hfinfo->type)(((hfinfo->type) == FT_CHAR || (hfinfo->type) == FT_UINT8
|| (hfinfo->type) == FT_UINT16 || (hfinfo->type) == FT_UINT24
|| (hfinfo->type) == FT_UINT32 || (hfinfo->type) == FT_FRAMENUM
) || ((hfinfo->type) == FT_UINT40 || (hfinfo->type) == FT_UINT48
|| (hfinfo->type) == FT_UINT56 || (hfinfo->type) == FT_UINT64
))
|| FT_IS_INT(hfinfo->type)(((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
) || ((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
))
))) {
2690 /* If we're fetching until the end of the TVB, only validate
2691 * that the offset is within range.
2692 */
2693 if (length == -1)
2694 size = 0;
2695 }
2696
2697 tvb_ensure_bytes_exist(tvb, start, size);
2698}
2699
2700static void
2701detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2702{
2703 bool_Bool found_stray_character = false0;
2704
2705 if (!string)
2706 return;
2707
2708 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2709 case ENC_ASCII0x00000000:
2710 case ENC_UTF_80x00000002:
2711 for (int i = (int)strlen(string); i < length; i++) {
2712 if (string[i] != '\0') {
2713 found_stray_character = true1;
2714 break;
2715 }
2716 }
2717 break;
2718
2719 default:
2720 break;
2721 }
2722
2723 if (found_stray_character) {
2724 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2725 }
2726}
2727
2728static void
2729free_fvalue_cb(void *data)
2730{
2731 fvalue_t *fv = (fvalue_t*)data;
2732 fvalue_free(fv);
2733}
2734
2735/* Add an item to a proto_tree, using the text label registered to that item;
2736 the item is extracted from the tvbuff handed to it. */
2737static proto_item *
2738proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2739 tvbuff_t *tvb, int start, int length,
2740 unsigned encoding)
2741{
2742 proto_item *pi;
2743 uint32_t value, n;
2744 uint64_t value64;
2745 ws_in4_addr ipv4_value;
2746 float floatval;
2747 double doubleval;
2748 const char *stringval = NULL((void*)0);
2749 nstime_t time_stamp;
2750 bool_Bool length_error;
2751
2752 /* Ensure that the newly created fvalue_t is freed if we throw an
2753 * exception before adding it to the tree. (gcc creates clobbering
2754 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2755 * XXX: Move the new_field_info() call inside here?
2756 */
2757 CLEANUP_PUSH(free_fvalue_cb, new_fi->value){ struct except_stacknode except_sn; struct except_cleanup except_cl
; except_setup_clean(&except_sn, &except_cl, (free_fvalue_cb
), (new_fi->value))
;
2758
2759 switch (new_fi->hfinfo->type) {
2760 case FT_NONE:
2761 /* no value to set for FT_NONE */
2762 break;
2763
2764 case FT_PROTOCOL:
2765 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2766 break;
2767
2768 case FT_BYTES:
2769 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2770 break;
2771
2772 case FT_UINT_BYTES:
2773 n = get_uint_value(tree, tvb, start, length, encoding);
2774 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2775
2776 /* Instead of calling proto_item_set_len(), since we don't yet
2777 * have a proto_item, we set the field_info's length ourselves. */
2778 new_fi->length = n + length;
2779 break;
2780
2781 case FT_BOOLEAN:
2782 /*
2783 * Map all non-zero values to little-endian for
2784 * backwards compatibility.
2785 */
2786 if (encoding)
2787 encoding = ENC_LITTLE_ENDIAN0x80000000;
2788 proto_tree_set_boolean(new_fi,
2789 get_uint64_value(tree, tvb, start, length, encoding));
2790 break;
2791
2792 case FT_CHAR:
2793 /* XXX - make these just FT_UINT? */
2794 case FT_UINT8:
2795 case FT_UINT16:
2796 case FT_UINT24:
2797 case FT_UINT32:
2798 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2799 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2800 value = (uint32_t)value64;
2801 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2802 new_fi->flags |= FI_VARINT0x00040000;
2803 }
2804 }
2805 else {
2806 /*
2807 * Map all non-zero values to little-endian for
2808 * backwards compatibility.
2809 */
2810 if (encoding)
2811 encoding = ENC_LITTLE_ENDIAN0x80000000;
2812
2813 value = get_uint_value(tree, tvb, start, length, encoding);
2814 }
2815 proto_tree_set_uint(new_fi, value);
2816 break;
2817
2818 case FT_UINT40:
2819 case FT_UINT48:
2820 case FT_UINT56:
2821 case FT_UINT64:
2822 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2823 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2824 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2825 new_fi->flags |= FI_VARINT0x00040000;
2826 }
2827 }
2828 else {
2829 /*
2830 * Map all other non-zero values to little-endian for
2831 * backwards compatibility.
2832 */
2833 if (encoding)
2834 encoding = ENC_LITTLE_ENDIAN0x80000000;
2835
2836 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2837 }
2838 proto_tree_set_uint64(new_fi, value64);
2839 break;
2840
2841 /* XXX - make these just FT_INT? */
2842 case FT_INT8:
2843 case FT_INT16:
2844 case FT_INT24:
2845 case FT_INT32:
2846 /*
2847 * Map all non-zero values to little-endian for
2848 * backwards compatibility.
2849 */
2850 if (encoding)
2851 encoding = ENC_LITTLE_ENDIAN0x80000000;
2852 proto_tree_set_int(new_fi,
2853 get_int_value(tree, tvb, start, length, encoding));
2854 break;
2855
2856 case FT_INT40:
2857 case FT_INT48:
2858 case FT_INT56:
2859 case FT_INT64:
2860 /*
2861 * Map all non-zero values to little-endian for
2862 * backwards compatibility.
2863 */
2864 if (encoding)
2865 encoding = ENC_LITTLE_ENDIAN0x80000000;
2866 proto_tree_set_int64(new_fi,
2867 get_int64_value(tree, tvb, start, length, encoding));
2868 break;
2869
2870 case FT_IPv4:
2871 /*
2872 * Map all non-zero values to little-endian for
2873 * backwards compatibility.
2874 */
2875 if (encoding)
2876 encoding = ENC_LITTLE_ENDIAN0x80000000;
2877 if (length != FT_IPv4_LEN4) {
2878 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2879 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2880 }
2881 ipv4_value = tvb_get_ipv4(tvb, start);
2882 /*
2883 * NOTE: to support code written when
2884 * proto_tree_add_item() took a bool as its
2885 * last argument, with false meaning "big-endian"
2886 * and true meaning "little-endian", we treat any
2887 * non-zero value of "encoding" as meaning
2888 * "little-endian".
2889 */
2890 proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(ipv4_value)(((guint32) ( (((guint32) (ipv4_value) & (guint32) 0x000000ffU
) << 24) | (((guint32) (ipv4_value) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (ipv4_value) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (ipv4_value) & (guint32) 0xff000000U
) >> 24))))
: ipv4_value);
2891 break;
2892
2893 case FT_IPXNET:
2894 if (length != FT_IPXNET_LEN4) {
2895 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2896 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2897 }
2898 proto_tree_set_ipxnet(new_fi,
2899 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2900 break;
2901
2902 case FT_IPv6:
2903 if (length != FT_IPv6_LEN16) {
2904 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2905 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2906 }
2907 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2908 break;
2909
2910 case FT_FCWWN:
2911 if (length != FT_FCWWN_LEN8) {
2912 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2913 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2914 }
2915 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2916 break;
2917
2918 case FT_AX25:
2919 if (length != 7) {
2920 length_error = length < 7 ? true1 : false0;
2921 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2922 }
2923 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2924 break;
2925
2926 case FT_VINES:
2927 if (length != VINES_ADDR_LEN6) {
2928 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
2929 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2930 }
2931 proto_tree_set_vines_tvb(new_fi, tvb, start);
2932 break;
2933
2934 case FT_ETHER:
2935 if (length != FT_ETHER_LEN6) {
2936 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
2937 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2938 }
2939 proto_tree_set_ether_tvb(new_fi, tvb, start);
2940 break;
2941
2942 case FT_EUI64:
2943 /*
2944 * Map all non-zero values to little-endian for
2945 * backwards compatibility.
2946 */
2947 if (encoding)
2948 encoding = ENC_LITTLE_ENDIAN0x80000000;
2949 if (length != FT_EUI64_LEN8) {
2950 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
2951 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2952 }
2953 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2954 break;
2955 case FT_GUID:
2956 /*
2957 * Map all non-zero values to little-endian for
2958 * backwards compatibility.
2959 */
2960 if (encoding)
2961 encoding = ENC_LITTLE_ENDIAN0x80000000;
2962 if (length != FT_GUID_LEN16) {
2963 length_error = length < FT_GUID_LEN16 ? true1 : false0;
2964 report_type_length_mismatch(tree, "a GUID", length, length_error);
2965 }
2966 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2967 break;
2968
2969 case FT_OID:
2970 case FT_REL_OID:
2971 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2972 break;
2973
2974 case FT_SYSTEM_ID:
2975 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2976 break;
2977
2978 case FT_FLOAT:
2979 /*
2980 * NOTE: to support code written when
2981 * proto_tree_add_item() took a bool as its
2982 * last argument, with false meaning "big-endian"
2983 * and true meaning "little-endian", we treat any
2984 * non-zero value of "encoding" as meaning
2985 * "little-endian".
2986 *
2987 * At some point in the future, we might
2988 * support non-IEEE-binary floating-point
2989 * formats in the encoding as well
2990 * (IEEE decimal, System/3x0, VAX).
2991 */
2992 if (encoding)
2993 encoding = ENC_LITTLE_ENDIAN0x80000000;
2994 if (length != 4) {
2995 length_error = length < 4 ? true1 : false0;
2996 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
2997 }
2998 if (encoding)
2999 floatval = tvb_get_letohieee_float(tvb, start);
3000 else
3001 floatval = tvb_get_ntohieee_float(tvb, start);
3002 proto_tree_set_float(new_fi, floatval);
3003 break;
3004
3005 case FT_DOUBLE:
3006 /*
3007 * NOTE: to support code written when
3008 * proto_tree_add_item() took a bool as its
3009 * last argument, with false meaning "big-endian"
3010 * and true meaning "little-endian", we treat any
3011 * non-zero value of "encoding" as meaning
3012 * "little-endian".
3013 *
3014 * At some point in the future, we might
3015 * support non-IEEE-binary floating-point
3016 * formats in the encoding as well
3017 * (IEEE decimal, System/3x0, VAX).
3018 */
3019 if (encoding == true1)
3020 encoding = ENC_LITTLE_ENDIAN0x80000000;
3021 if (length != 8) {
3022 length_error = length < 8 ? true1 : false0;
3023 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3024 }
3025 if (encoding)
3026 doubleval = tvb_get_letohieee_double(tvb, start);
3027 else
3028 doubleval = tvb_get_ntohieee_double(tvb, start);
3029 proto_tree_set_double(new_fi, doubleval);
3030 break;
3031
3032 case FT_STRING:
3033 stringval = get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3034 tvb, start, length, &length, encoding);
3035 proto_tree_set_string(new_fi, stringval);
3036
3037 /* Instead of calling proto_item_set_len(), since we
3038 * don't yet have a proto_item, we set the
3039 * field_info's length ourselves.
3040 *
3041 * XXX - our caller can't use that length to
3042 * advance an offset unless they arrange that
3043 * there always be a protocol tree into which
3044 * we're putting this item.
3045 */
3046 new_fi->length = length;
3047 break;
3048
3049 case FT_STRINGZ:
3050 stringval = get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3051 tree, tvb, start, length, &length, encoding);
3052 proto_tree_set_string(new_fi, stringval);
3053
3054 /* Instead of calling proto_item_set_len(),
3055 * since we don't yet have a proto_item, we
3056 * set the field_info's length ourselves.
3057 *
3058 * XXX - our caller can't use that length to
3059 * advance an offset unless they arrange that
3060 * there always be a protocol tree into which
3061 * we're putting this item.
3062 */
3063 new_fi->length = length;
3064 break;
3065
3066 case FT_UINT_STRING:
3067 /*
3068 * NOTE: to support code written when
3069 * proto_tree_add_item() took a bool as its
3070 * last argument, with false meaning "big-endian"
3071 * and true meaning "little-endian", if the
3072 * encoding value is true, treat that as
3073 * ASCII with a little-endian length.
3074 *
3075 * This won't work for code that passes
3076 * arbitrary non-zero values; that code
3077 * will need to be fixed.
3078 */
3079 if (encoding == true1)
3080 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3081 stringval = get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3082 tree, tvb, start, length, &length, encoding);
3083 proto_tree_set_string(new_fi, stringval);
3084
3085 /* Instead of calling proto_item_set_len(), since we
3086 * don't yet have a proto_item, we set the
3087 * field_info's length ourselves.
3088 *
3089 * XXX - our caller can't use that length to
3090 * advance an offset unless they arrange that
3091 * there always be a protocol tree into which
3092 * we're putting this item.
3093 */
3094 new_fi->length = length;
3095 break;
3096
3097 case FT_STRINGZPAD:
3098 stringval = get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3099 tvb, start, length, &length, encoding);
3100 proto_tree_set_string(new_fi, stringval);
3101
3102 /* Instead of calling proto_item_set_len(), since we
3103 * don't yet have a proto_item, we set the
3104 * field_info's length ourselves.
3105 *
3106 * XXX - our caller can't use that length to
3107 * advance an offset unless they arrange that
3108 * there always be a protocol tree into which
3109 * we're putting this item.
3110 */
3111 new_fi->length = length;
3112 break;
3113
3114 case FT_STRINGZTRUNC:
3115 stringval = get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3116 tvb, start, length, &length, encoding);
3117 proto_tree_set_string(new_fi, stringval);
3118
3119 /* Instead of calling proto_item_set_len(), since we
3120 * don't yet have a proto_item, we set the
3121 * field_info's length ourselves.
3122 *
3123 * XXX - our caller can't use that length to
3124 * advance an offset unless they arrange that
3125 * there always be a protocol tree into which
3126 * we're putting this item.
3127 */
3128 new_fi->length = length;
3129 break;
3130
3131 case FT_ABSOLUTE_TIME:
3132 /*
3133 * Absolute times can be in any of a number of
3134 * formats, and they can be big-endian or
3135 * little-endian.
3136 *
3137 * Historically FT_TIMEs were only timespecs;
3138 * the only question was whether they were stored
3139 * in big- or little-endian format.
3140 *
3141 * For backwards compatibility, we interpret an
3142 * encoding of 1 as meaning "little-endian timespec",
3143 * so that passing true is interpreted as that.
3144 */
3145 if (encoding == true1)
3146 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3147
3148 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3149
3150 proto_tree_set_time(new_fi, &time_stamp);
3151 break;
3152
3153 case FT_RELATIVE_TIME:
3154 /*
3155 * Relative times can be in any of a number of
3156 * formats, and they can be big-endian or
3157 * little-endian.
3158 *
3159 * Historically FT_TIMEs were only timespecs;
3160 * the only question was whether they were stored
3161 * in big- or little-endian format.
3162 *
3163 * For backwards compatibility, we interpret an
3164 * encoding of 1 as meaning "little-endian timespec",
3165 * so that passing true is interpreted as that.
3166 */
3167 if (encoding == true1)
3168 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3169
3170 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3171
3172 proto_tree_set_time(new_fi, &time_stamp);
3173 break;
3174 case FT_IEEE_11073_SFLOAT:
3175 if (encoding)
3176 encoding = ENC_LITTLE_ENDIAN0x80000000;
3177 if (length != 2) {
3178 length_error = length < 2 ? true1 : false0;
3179 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3180 }
3181
3182 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3183
3184 break;
3185 case FT_IEEE_11073_FLOAT:
3186 if (encoding)
3187 encoding = ENC_LITTLE_ENDIAN0x80000000;
3188 if (length != 4) {
3189 length_error = length < 4 ? true1 : false0;
3190 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3191 }
3192 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3193
3194 break;
3195 default:
3196 REPORT_DISSECTOR_BUG("field %s is of unknown type %d (%s)",proto_report_dissector_bug("field %s is of unknown type %d (%s)"
, new_fi->hfinfo->abbrev, new_fi->hfinfo->type, ftype_name
(new_fi->hfinfo->type))
3197 new_fi->hfinfo->abbrev,proto_report_dissector_bug("field %s is of unknown type %d (%s)"
, new_fi->hfinfo->abbrev, new_fi->hfinfo->type, ftype_name
(new_fi->hfinfo->type))
3198 new_fi->hfinfo->type,proto_report_dissector_bug("field %s is of unknown type %d (%s)"
, new_fi->hfinfo->abbrev, new_fi->hfinfo->type, ftype_name
(new_fi->hfinfo->type))
3199 ftype_name(new_fi->hfinfo->type))proto_report_dissector_bug("field %s is of unknown type %d (%s)"
, new_fi->hfinfo->abbrev, new_fi->hfinfo->type, ftype_name
(new_fi->hfinfo->type))
;
3200 break;
3201 }
3202 FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN)do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
;
3203
3204 /* Don't add new node to proto_tree until now so that any exceptions
3205 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3206 /* XXX. wouldn't be better to add this item to tree, with some special
3207 * flag (FI_EXCEPTION?) to know which item caused exception? For
3208 * strings and bytes, we would have to set new_fi->value to something
3209 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3210 * could handle NULL values. */
3211 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3212 pi = proto_tree_add_node(tree, new_fi);
3213
3214 switch (new_fi->hfinfo->type) {
3215
3216 case FT_STRING:
3217 /* XXX: trailing stray character detection should be done
3218 * _before_ conversion to UTF-8, because conversion can change
3219 * the length, or else get_string_length should return a value
3220 * for the "length in bytes of the string after conversion
3221 * including internal nulls." (Noting that we do, for other
3222 * reasons, still need the "length in bytes in the field",
3223 * especially for FT_STRINGZ.)
3224 *
3225 * This is true even for ASCII and UTF-8, because
3226 * substituting REPLACEMENT CHARACTERS for illegal characters
3227 * can also do so (and for UTF-8 possibly even make the
3228 * string _shorter_).
3229 */
3230 detect_trailing_stray_characters(encoding, stringval, length, pi);
3231 break;
3232
3233 default:
3234 break;
3235 }
3236
3237 return pi;
3238}
3239
3240proto_item *
3241proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3242 const int start, int length,
3243 const unsigned encoding, int32_t *retval)
3244{
3245 header_field_info *hfinfo;
3246 field_info *new_fi;
3247 int32_t value;
3248
3249 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3249, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3249,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3249, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3250
3251 switch (hfinfo->type) {
3252 case FT_INT8:
3253 case FT_INT16:
3254 case FT_INT24:
3255 case FT_INT32:
3256 break;
3257 case FT_INT64:
3258 REPORT_DISSECTOR_BUG("64-bit signed integer field %s used with proto_tree_add_item_ret_int()",proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
3259 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3260 default:
3261 REPORT_DISSECTOR_BUG("Non-signed-integer field %s used with proto_tree_add_item_ret_int()",proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
3262 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3263 }
3264
3265 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3266 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3267 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3268 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3269 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3270 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3271 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3272
3273 if (encoding & ENC_STRING0x03000000) {
3274 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3275 }
3276 /* I believe it's ok if this is called with a NULL tree */
3277 value = get_int_value(tree, tvb, start, length, encoding);
3278
3279 if (retval) {
3280 int no_of_bits;
3281 *retval = value;
3282 if (hfinfo->bitmask) {
3283 /* Mask out irrelevant portions */
3284 *retval &= (uint32_t)(hfinfo->bitmask);
3285 /* Shift bits */
3286 *retval >>= hfinfo_bitshift(hfinfo);
3287 }
3288 no_of_bits = ws_count_ones(hfinfo->bitmask);
3289 *retval = ws_sign_ext32(*retval, no_of_bits);
3290 }
3291
3292 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3293
3294 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3294
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3294, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3294, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3294, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3295
3296 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3297
3298 proto_tree_set_int(new_fi, value);
3299
3300 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3301
3302 return proto_tree_add_node(tree, new_fi);
3303}
3304
3305proto_item *
3306proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3307 const int start, int length,
3308 const unsigned encoding, uint32_t *retval)
3309{
3310 header_field_info *hfinfo;
3311 field_info *new_fi;
3312 uint32_t value;
3313
3314 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3314, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3314,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3314, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3315
3316 switch (hfinfo->type) {
3317 case FT_CHAR:
3318 case FT_UINT8:
3319 case FT_UINT16:
3320 case FT_UINT24:
3321 case FT_UINT32:
3322 break;
3323 default:
3324 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",proto_report_dissector_bug("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
3325 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
3326 }
3327
3328 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3329 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3330 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3331 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3332 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3333 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3334 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3335
3336 if (encoding & ENC_STRING0x03000000) {
3337 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3338 }
3339 /* I believe it's ok if this is called with a NULL tree */
3340 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3341 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3342 uint64_t temp64;
3343 tvb_get_varint(tvb, start, length, &temp64, encoding);
3344 value = (uint32_t)temp64;
3345 } else {
3346 value = get_uint_value(tree, tvb, start, length, encoding);
3347 }
3348
3349 if (retval) {
3350 *retval = value;
3351 if (hfinfo->bitmask) {
3352 /* Mask out irrelevant portions */
3353 *retval &= (uint32_t)(hfinfo->bitmask);
3354 /* Shift bits */
3355 *retval >>= hfinfo_bitshift(hfinfo);
3356 }
3357 }
3358
3359 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3360
3361 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3361
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3361, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3361, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3361, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3362
3363 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3364
3365 proto_tree_set_uint(new_fi, value);
3366
3367 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3368 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3369 new_fi->flags |= FI_VARINT0x00040000;
3370 }
3371 return proto_tree_add_node(tree, new_fi);
3372}
3373
3374/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3375 * and returns proto_item* and uint value retreived*/
3376proto_item *
3377ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3378 const unsigned encoding, uint32_t *retval)
3379{
3380 field_info *new_fi;
3381 header_field_info *hfinfo;
3382 int item_length;
3383 int offset;
3384 uint32_t value;
3385
3386 offset = ptvc->offset;
3387 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3387, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3387,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3387, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3388
3389 switch (hfinfo->type) {
3390 case FT_CHAR:
3391 case FT_UINT8:
3392 case FT_UINT16:
3393 case FT_UINT24:
3394 case FT_UINT32:
3395 break;
3396 default:
3397 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",proto_report_dissector_bug("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
3398 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
3399 }
3400
3401 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3402 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3403
3404 /* I believe it's ok if this is called with a NULL tree */
3405 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3406 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3407
3408 if (retval) {
3409 *retval = value;
3410 if (hfinfo->bitmask) {
3411 /* Mask out irrelevant portions */
3412 *retval &= (uint32_t)(hfinfo->bitmask);
3413 /* Shift bits */
3414 *retval >>= hfinfo_bitshift(hfinfo);
3415 }
3416 }
3417
3418 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3419 item_length, encoding);
3420
3421 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3422
3423 /* Coast clear. Try and fake it */
3424 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo)((ptvc->tree)->tree_data)->count++; if((hfindex == 0
|| (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3424
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3424, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3424, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((ptvc->tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3424, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree
)->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc
->tree)->tree_data)->visible)) { if (proto_item_is_hidden
((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT
) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) &&
(hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data
)->fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(ptvc->tree, hfinfo); } } }
;
3425
3426 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3427
3428 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3429 offset, length, encoding);
3430}
3431
3432/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3433 * and returns proto_item* and int value retreived*/
3434proto_item *
3435ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3436 const unsigned encoding, int32_t *retval)
3437{
3438 field_info *new_fi;
3439 header_field_info *hfinfo;
3440 int item_length;
3441 int offset;
3442 uint32_t value;
3443
3444 offset = ptvc->offset;
3445 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3445, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3445,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3445, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3446
3447 switch (hfinfo->type) {
3448 case FT_INT8:
3449 case FT_INT16:
3450 case FT_INT24:
3451 case FT_INT32:
3452 break;
3453 default:
3454 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
3455 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3456 }
3457
3458 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3459 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3460
3461 /* I believe it's ok if this is called with a NULL tree */
3462 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3463 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3464
3465 if (retval) {
3466 int no_of_bits;
3467 *retval = value;
3468 if (hfinfo->bitmask) {
3469 /* Mask out irrelevant portions */
3470 *retval &= (uint32_t)(hfinfo->bitmask);
3471 /* Shift bits */
3472 *retval >>= hfinfo_bitshift(hfinfo);
3473 }
3474 no_of_bits = ws_count_ones(hfinfo->bitmask);
3475 *retval = ws_sign_ext32(*retval, no_of_bits);
3476 }
3477
3478 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3479 item_length, encoding);
3480
3481 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3482
3483 /* Coast clear. Try and fake it */
3484 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo)((ptvc->tree)->tree_data)->count++; if((hfindex == 0
|| (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3484
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3484, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3484, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((ptvc->tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3484, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree
)->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc
->tree)->tree_data)->visible)) { if (proto_item_is_hidden
((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT
) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) &&
(hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data
)->fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(ptvc->tree, hfinfo); } } }
;
3485
3486 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3487
3488 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3489 offset, length, encoding);
3490}
3491
3492/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3493 * and returns proto_item* and string value retreived */
3494proto_item*
3495ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3496{
3497 header_field_info *hfinfo;
3498 field_info *new_fi;
3499 const uint8_t *value;
3500 int item_length;
3501 int offset;
3502
3503 offset = ptvc->offset;
3504
3505 PROTO_REGISTRAR_GET_NTH(hf, hfinfo)if((hf == 0 || (unsigned)hf > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3505
, __func__, "Unregistered hf! index=%d", hf); ((void) ((hf >
0 && (unsigned)hf < gpa_hfinfo.len) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3505, "hf > 0 && (unsigned)hf < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf] != ((
void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3505, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3506
3507 switch (hfinfo->type) {
3508 case FT_STRING:
3509 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3510 break;
3511 case FT_STRINGZ:
3512 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3513 break;
3514 case FT_UINT_STRING:
3515 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3516 break;
3517 case FT_STRINGZPAD:
3518 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3519 break;
3520 case FT_STRINGZTRUNC:
3521 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3522 break;
3523 default:
3524 REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC",proto_report_dissector_bug("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC"
, hfinfo->abbrev)
3525 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC"
, hfinfo->abbrev)
;
3526 }
3527
3528 if (retval)
3529 *retval = value;
3530
3531 ptvc->offset += item_length;
3532
3533 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3534
3535 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo)((ptvc->tree)->tree_data)->count++; if((hfinfo->id
== 0 || (unsigned)hfinfo->id > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3535, __func__, "Unregistered hf! index=%d"
, hfinfo->id); ((void) ((hfinfo->id > 0 && (
unsigned)hfinfo->id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3535,
"hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3535, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((ptvc->tree)->tree_data)->count > prefs
.gui_max_tree_items) { ((void)0); if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3535
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree
)->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc
->tree)->tree_data)->visible)) { if (proto_item_is_hidden
((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT
) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) &&
(hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data
)->fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(ptvc->tree, hfinfo); } } }
;
3536
3537 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3538
3539 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3540 offset, length, encoding);
3541}
3542
3543/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3544 * and returns proto_item* and boolean value retreived */
3545proto_item*
3546ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3547{
3548 header_field_info *hfinfo;
3549 field_info *new_fi;
3550 int item_length;
3551 int offset;
3552 uint64_t value, bitval;
3553
3554 offset = ptvc->offset;
3555 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3555, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3555,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3555, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3556
3557 if (hfinfo->type != FT_BOOLEAN) {
3558 REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
3559 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3560 }
3561
3562 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3563 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3564 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3565 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3566 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3567 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3568 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3569
3570 if (encoding & ENC_STRING0x03000000) {
3571 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3572 }
3573
3574 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3575 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3576
3577 /* I believe it's ok if this is called with a NULL tree */
3578 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3579
3580 if (retval) {
3581 bitval = value;
3582 if (hfinfo->bitmask) {
3583 /* Mask out irrelevant portions */
3584 bitval &= hfinfo->bitmask;
3585 }
3586 *retval = (bitval != 0);
3587 }
3588
3589 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3590 item_length, encoding);
3591
3592 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3593
3594 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo)((ptvc->tree)->tree_data)->count++; if((hfinfo->id
== 0 || (unsigned)hfinfo->id > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3594, __func__, "Unregistered hf! index=%d"
, hfinfo->id); ((void) ((hfinfo->id > 0 && (
unsigned)hfinfo->id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3594,
"hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3594, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((ptvc->tree)->tree_data)->count > prefs
.gui_max_tree_items) { ((void)0); if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3594
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree
)->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc
->tree)->tree_data)->visible)) { if (proto_item_is_hidden
((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT
) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) &&
(hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data
)->fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(ptvc->tree, hfinfo); } } }
;
3595
3596 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3597
3598 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3599 offset, length, encoding);
3600}
3601
3602proto_item *
3603proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3604 const int start, int length, const unsigned encoding, uint64_t *retval)
3605{
3606 header_field_info *hfinfo;
3607 field_info *new_fi;
3608 uint64_t value;
3609
3610 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3610, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3610,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3610, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3611
3612 switch (hfinfo->type) {
3613 case FT_UINT40:
3614 case FT_UINT48:
3615 case FT_UINT56:
3616 case FT_UINT64:
3617 break;
3618 default:
3619 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64",proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
3620 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3621 }
3622
3623 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3624 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3625 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3626 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3627 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3628 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3629 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3630
3631 if (encoding & ENC_STRING0x03000000) {
3632 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3633 }
3634 /* I believe it's ok if this is called with a NULL tree */
3635 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3636 tvb_get_varint(tvb, start, length, &value, encoding);
3637 } else {
3638 value = get_uint64_value(tree, tvb, start, length, encoding);
3639 }
3640
3641 if (retval) {
3642 *retval = value;
3643 if (hfinfo->bitmask) {
3644 /* Mask out irrelevant portions */
3645 *retval &= hfinfo->bitmask;
3646 /* Shift bits */
3647 *retval >>= hfinfo_bitshift(hfinfo);
3648 }
3649 }
3650
3651 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3652
3653 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3653
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3653, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3653, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3653, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3654
3655 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3656
3657 proto_tree_set_uint64(new_fi, value);
3658
3659 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3660 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3661 new_fi->flags |= FI_VARINT0x00040000;
3662 }
3663
3664 return proto_tree_add_node(tree, new_fi);
3665}
3666
3667proto_item *
3668proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3669 const int start, int length, const unsigned encoding, int64_t *retval)
3670{
3671 header_field_info *hfinfo;
3672 field_info *new_fi;
3673 int64_t value;
3674
3675 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3675, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3675,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3675, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3676
3677 switch (hfinfo->type) {
3678 case FT_INT40:
3679 case FT_INT48:
3680 case FT_INT56:
3681 case FT_INT64:
3682 break;
3683 default:
3684 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
3685 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3686 }
3687
3688 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3689 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3690 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3691 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3692 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3693 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3694 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3695
3696 if (encoding & ENC_STRING0x03000000) {
3697 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3698 }
3699 /* I believe it's ok if this is called with a NULL tree */
3700 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3701 tvb_get_varint(tvb, start, length, &value, encoding);
3702 }
3703 else {
3704 value = get_int64_value(tree, tvb, start, length, encoding);
3705 }
3706
3707 if (retval) {
3708 *retval = value;
3709 }
3710
3711 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3712
3713 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3713
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3713, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3713, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3713, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3714
3715 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3716
3717 proto_tree_set_int64(new_fi, value);
3718
3719 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3720 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3721 new_fi->flags |= FI_VARINT0x00040000;
3722 }
3723
3724 return proto_tree_add_node(tree, new_fi);
3725}
3726
3727proto_item *
3728proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3729 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3730{
3731 header_field_info *hfinfo;
3732 field_info *new_fi;
3733 uint64_t value;
3734
3735 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3735, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3735,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3735, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3736
3737 if ((!FT_IS_INT(hfinfo->type)(((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
) || ((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
))
) && (!FT_IS_UINT(hfinfo->type)(((hfinfo->type) == FT_CHAR || (hfinfo->type) == FT_UINT8
|| (hfinfo->type) == FT_UINT16 || (hfinfo->type) == FT_UINT24
|| (hfinfo->type) == FT_UINT32 || (hfinfo->type) == FT_FRAMENUM
) || ((hfinfo->type) == FT_UINT40 || (hfinfo->type) == FT_UINT48
|| (hfinfo->type) == FT_UINT56 || (hfinfo->type) == FT_UINT64
))
)) {
3738 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT or FT_INT",proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
3739 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3740 }
3741
3742 /* length validation for native number encoding caught by get_uint64_value() */
3743 /* length has to be -1 or > 0 regardless of encoding */
3744 if (length == 0)
3745 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_varint",proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
3746 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3747
3748 if (encoding & ENC_STRING0x03000000) {
3749 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3750 }
3751
3752 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3753
3754 if (retval) {
3755 *retval = value;
3756 if (hfinfo->bitmask) {
3757 /* Mask out irrelevant portions */
3758 *retval &= hfinfo->bitmask;
3759 /* Shift bits */
3760 *retval >>= hfinfo_bitshift(hfinfo);
3761 }
3762 }
3763
3764 if (lenretval) {
3765 *lenretval = length;
3766 }
3767
3768 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3769
3770 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3770
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3770, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3770, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3770, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3771
3772 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3773
3774 proto_tree_set_uint64(new_fi, value);
3775
3776 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3777 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3778 new_fi->flags |= FI_VARINT0x00040000;
3779 }
3780
3781 return proto_tree_add_node(tree, new_fi);
3782
3783}
3784
3785proto_item *
3786proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3787 const int start, int length,
3788 const unsigned encoding, bool_Bool *retval)
3789{
3790 header_field_info *hfinfo;
3791 field_info *new_fi;
3792 uint64_t value, bitval;
3793
3794 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3794, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3794,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3794, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3795
3796 if (hfinfo->type != FT_BOOLEAN) {
3797 REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
3798 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3799 }
3800
3801 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3802 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3803 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3804 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3805 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3806 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3807 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3808
3809 if (encoding & ENC_STRING0x03000000) {
3810 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3811 }
3812 /* I believe it's ok if this is called with a NULL tree */
3813 value = get_uint64_value(tree, tvb, start, length, encoding);
3814
3815 if (retval) {
3816 bitval = value;
3817 if (hfinfo->bitmask) {
3818 /* Mask out irrelevant portions */
3819 bitval &= hfinfo->bitmask;
3820 }
3821 *retval = (bitval != 0);
3822 }
3823
3824 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3825
3826 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3826
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3826, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3826, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3826, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3827
3828 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3829
3830 proto_tree_set_boolean(new_fi, value);
3831
3832 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3833
3834 return proto_tree_add_node(tree, new_fi);
3835}
3836
3837proto_item *
3838proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3839 const int start, int length,
3840 const unsigned encoding, float *retval)
3841{
3842 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3843 field_info *new_fi;
3844 float value;
3845
3846 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3846,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3847
3848 if (hfinfo->type != FT_FLOAT) {
3849 REPORT_DISSECTOR_BUG("field %s is not of type FT_FLOAT", hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_FLOAT"
, hfinfo->abbrev)
;
3850 }
3851
3852 if (length != 4) {
3853 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3854 }
3855
3856 /* treat any nonzero encoding as little endian for backwards compatibility */
3857 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3858 if (retval) {
3859 *retval = value;
3860 }
3861
3862 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3863
3864 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3864
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3864, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3864, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3864, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3865
3866 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3867 if (encoding) {
3868 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3869 }
3870
3871 proto_tree_set_float(new_fi, value);
3872
3873 return proto_tree_add_node(tree, new_fi);
3874}
3875
3876proto_item *
3877proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3878 const int start, int length,
3879 const unsigned encoding, double *retval)
3880{
3881 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3882 field_info *new_fi;
3883 double value;
3884
3885 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3885,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3886
3887 if (hfinfo->type != FT_DOUBLE) {
3888 REPORT_DISSECTOR_BUG("field %s is not of type FT_DOUBLE", hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_DOUBLE"
, hfinfo->abbrev)
;
3889 }
3890
3891 if (length != 8) {
3892 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3893 }
3894
3895 /* treat any nonzero encoding as little endian for backwards compatibility */
3896 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3897 if (retval) {
3898 *retval = value;
3899 }
3900
3901 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3902
3903 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3903
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3903, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3903, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3903, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3904
3905 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3906 if (encoding) {
3907 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3908 }
3909
3910 proto_tree_set_double(new_fi, value);
3911
3912 return proto_tree_add_node(tree, new_fi);
3913}
3914
3915proto_item *
3916proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3917 const int start, int length,
3918 const unsigned encoding, ws_in4_addr *retval)
3919{
3920 header_field_info *hfinfo;
3921 field_info *new_fi;
3922 ws_in4_addr value;
3923
3924 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3924, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3924,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3924, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3925
3926 switch (hfinfo->type) {
3927 case FT_IPv4:
3928 break;
3929 default:
3930 REPORT_DISSECTOR_BUG("field %s is not of type FT_IPv4",proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
3931 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
3932 }
3933
3934 if (length != FT_IPv4_LEN4)
3935 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_ipv4",proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
3936 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
3937
3938 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3939 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3940 }
3941
3942 /*
3943 * NOTE: to support code written when proto_tree_add_item() took
3944 * a bool as its last argument, with false meaning "big-endian"
3945 * and true meaning "little-endian", we treat any non-zero value
3946 * of "encoding" as meaning "little-endian".
3947 */
3948 value = tvb_get_ipv4(tvb, start);
3949 if (encoding)
3950 value = GUINT32_SWAP_LE_BE(value)(((guint32) ( (((guint32) (value) & (guint32) 0x000000ffU
) << 24) | (((guint32) (value) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (value) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (value) & (guint32) 0xff000000U
) >> 24))))
;
3951
3952 if (retval) {
3953 *retval = value;
3954 }
3955
3956 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3957
3958 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3958
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3958, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3958, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3958, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3959
3960 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3961
3962 proto_tree_set_ipv4(new_fi, value);
3963
3964 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3965 return proto_tree_add_node(tree, new_fi);
3966}
3967
3968proto_item *
3969proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3970 const int start, int length,
3971 const unsigned encoding, ws_in6_addr *addr)
3972{
3973 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3974 field_info *new_fi;
3975
3976 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3976,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3977
3978 switch (hfinfo->type) {
3979 case FT_IPv6:
3980 break;
3981 default:
3982 REPORT_DISSECTOR_BUG("field %s is not of type FT_IPv6",proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
3983 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
3984 }
3985
3986 if (length != FT_IPv6_LEN16)
3987 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_ipv6",proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
3988 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
3989
3990 if (encoding) {
3991 REPORT_DISSECTOR_BUG("Encodings not yet implemented for proto_tree_add_item_ret_ipv6")proto_report_dissector_bug("Encodings not yet implemented for proto_tree_add_item_ret_ipv6"
)
;
3992 }
3993
3994 tvb_get_ipv6(tvb, start, addr);
3995
3996 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3997
3998 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3998
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3998, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3998, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3998, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3999
4000 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4001
4002 proto_tree_set_ipv6(new_fi, addr);
4003
4004 return proto_tree_add_node(tree, new_fi);
4005}
4006
4007proto_item *
4008proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4009 const int start, int length, const unsigned encoding, uint8_t *retval) {
4010
4011 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4012 field_info *new_fi;
4013
4014 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4014,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4015
4016 switch (hfinfo->type) {
4017 case FT_ETHER:
4018 break;
4019 default:
4020 REPORT_DISSECTOR_BUG("field %s is not of type FT_ETHER",proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
4021 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4022 }
4023
4024 if (length != FT_ETHER_LEN6)
4025 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_ether",proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
4026 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4027
4028 if (encoding) {
4029 REPORT_DISSECTOR_BUG("Encodings not yet implemented for proto_tree_add_item_ret_ether")proto_report_dissector_bug("Encodings not yet implemented for proto_tree_add_item_ret_ether"
)
;
4030 }
4031
4032 tvb_memcpy(tvb, retval, start, length);
4033
4034 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4035
4036 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4036
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4036, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4036, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4036, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4037
4038 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4039
4040 proto_tree_set_ether(new_fi, retval);
4041
4042 return proto_tree_add_node(tree, new_fi);
4043}
4044
4045
4046proto_item *
4047proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4048 tvbuff_t *tvb,
4049 const int start, int length,
4050 const unsigned encoding,
4051 wmem_allocator_t *scope,
4052 const uint8_t **retval,
4053 int *lenretval)
4054{
4055 proto_item *pi;
4056 header_field_info *hfinfo;
4057 field_info *new_fi;
4058 const uint8_t *value;
4059
4060 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4060, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4060,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4060, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4061
4062 switch (hfinfo->type) {
4063 case FT_STRING:
4064 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4065 break;
4066 case FT_STRINGZ:
4067 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4068 break;
4069 case FT_UINT_STRING:
4070 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4071 break;
4072 case FT_STRINGZPAD:
4073 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4074 break;
4075 case FT_STRINGZTRUNC:
4076 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4077 break;
4078 default:
4079 REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC",proto_report_dissector_bug("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC"
, hfinfo->abbrev)
4080 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC"
, hfinfo->abbrev)
;
4081 }
4082
4083 if (retval)
4084 *retval = value;
4085
4086 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4087
4088 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4088
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4088, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4088, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4088, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4089
4090 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4091
4092 proto_tree_set_string(new_fi, value);
4093
4094 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4095
4096 pi = proto_tree_add_node(tree, new_fi);
4097
4098 switch (hfinfo->type) {
4099
4100 case FT_STRINGZ:
4101 case FT_STRINGZPAD:
4102 case FT_STRINGZTRUNC:
4103 case FT_UINT_STRING:
4104 break;
4105
4106 case FT_STRING:
4107 detect_trailing_stray_characters(encoding, value, length, pi);
4108 break;
4109
4110 default:
4111 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4111
, __func__, "assertion \"not reached\" failed")
;
4112 }
4113
4114 return pi;
4115}
4116
4117proto_item *
4118proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4119 const int start, int length,
4120 const unsigned encoding, wmem_allocator_t *scope,
4121 const uint8_t **retval)
4122{
4123 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4124 tvb, start, length, encoding, scope, retval, &length);
4125}
4126
4127proto_item *
4128proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4129 tvbuff_t *tvb,
4130 const int start, int length,
4131 const unsigned encoding,
4132 wmem_allocator_t *scope,
4133 char **retval,
4134 int *lenretval)
4135{
4136 proto_item *pi;
4137 header_field_info *hfinfo;
4138 field_info *new_fi;
4139 const uint8_t *value;
4140 uint32_t n = 0;
4141
4142 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4142, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4142,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4142, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4143
4144 switch (hfinfo->type) {
4145 case FT_STRING:
4146 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4147 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4148 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4149 break;
4150 case FT_STRINGZ:
4151 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4152 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4153 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4154 break;
4155 case FT_UINT_STRING:
4156 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4157 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4158 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4159 break;
4160 case FT_STRINGZPAD:
4161 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4162 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4163 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4164 break;
4165 case FT_STRINGZTRUNC:
4166 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4167 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4168 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4169 break;
4170 case FT_BYTES:
4171 tvb_ensure_bytes_exist(tvb, start, length);
4172 value = tvb_get_ptr(tvb, start, length);
4173 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4174 *lenretval = length;
4175 break;
4176 case FT_UINT_BYTES:
4177 n = get_uint_value(tree, tvb, start, length, encoding);
4178 tvb_ensure_bytes_exist(tvb, start + length, n);
4179 value = tvb_get_ptr(tvb, start + length, n);
4180 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4181 *lenretval = length + n;
4182 break;
4183 default:
4184 REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, FT_STRINGZTRUNC, FT_BYTES, or FT_UINT_BYTES",proto_report_dissector_bug("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, FT_STRINGZTRUNC, FT_BYTES, or FT_UINT_BYTES"
, hfinfo->abbrev)
4185 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, FT_STRINGZTRUNC, FT_BYTES, or FT_UINT_BYTES"
, hfinfo->abbrev)
;
4186 }
4187
4188 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4189
4190 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4190
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4190, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4190, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4190, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4191
4192 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4193
4194 switch (hfinfo->type) {
4195
4196 case FT_STRING:
4197 case FT_STRINGZ:
4198 case FT_UINT_STRING:
4199 case FT_STRINGZPAD:
4200 case FT_STRINGZTRUNC:
4201 proto_tree_set_string(new_fi, value);
4202 break;
4203
4204 case FT_BYTES:
4205 proto_tree_set_bytes(new_fi, value, length);
4206 break;
4207
4208 case FT_UINT_BYTES:
4209 proto_tree_set_bytes(new_fi, value, n);
4210 break;
4211
4212 default:
4213 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4213
, __func__, "assertion \"not reached\" failed")
;
4214 }
4215
4216 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4217
4218 pi = proto_tree_add_node(tree, new_fi);
4219
4220 switch (hfinfo->type) {
4221
4222 case FT_STRINGZ:
4223 case FT_STRINGZPAD:
4224 case FT_STRINGZTRUNC:
4225 case FT_UINT_STRING:
4226 break;
4227
4228 case FT_STRING:
4229 detect_trailing_stray_characters(encoding, value, length, pi);
4230 break;
4231
4232 case FT_BYTES:
4233 case FT_UINT_BYTES:
4234 break;
4235
4236 default:
4237 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4237
, __func__, "assertion \"not reached\" failed")
;
4238 }
4239
4240 return pi;
4241}
4242
4243proto_item *
4244proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4245 tvbuff_t *tvb,
4246 const int start, int length,
4247 const unsigned encoding,
4248 wmem_allocator_t *scope,
4249 char **retval)
4250{
4251 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4252 tvb, start, length, encoding, scope, retval, &length);
4253}
4254
4255proto_item *
4256proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4257 tvbuff_t *tvb,
4258 const int start, int length, const unsigned encoding,
4259 wmem_allocator_t *scope, char **retval)
4260{
4261 header_field_info *hfinfo;
4262 field_info *new_fi;
4263 nstime_t time_stamp;
4264 int flags;
4265
4266 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4266, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4266,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4266, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4267
4268 switch (hfinfo->type) {
4269 case FT_ABSOLUTE_TIME:
4270 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4271 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4272 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4273 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4274 }
4275 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4276 break;
4277 case FT_RELATIVE_TIME:
4278 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4279 *retval = rel_time_to_secs_str(scope, &time_stamp);
4280 break;
4281 default:
4282 REPORT_DISSECTOR_BUG("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME",proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
4283 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4284 }
4285
4286 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4287
4288 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4288
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4288, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4288, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4288, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4289
4290 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4291
4292 switch (hfinfo->type) {
4293
4294 case FT_ABSOLUTE_TIME:
4295 case FT_RELATIVE_TIME:
4296 proto_tree_set_time(new_fi, &time_stamp);
4297 break;
4298 default:
4299 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4299
, __func__, "assertion \"not reached\" failed")
;
4300 }
4301
4302 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4303
4304 return proto_tree_add_node(tree, new_fi);
4305}
4306
4307/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4308 and returns proto_item* */
4309proto_item *
4310ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4311 const unsigned encoding)
4312{
4313 field_info *new_fi;
4314 header_field_info *hfinfo;
4315 int item_length;
4316 int offset;
4317
4318 offset = ptvc->offset;
4319 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4319, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4319,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4319, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4320 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4321 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4322
4323 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
4324 item_length, encoding);
4325
4326 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4327
4328 /* Coast clear. Try and fake it */
4329 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo)((ptvc->tree)->tree_data)->count++; if((hfindex == 0
|| (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4329
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4329, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4329, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((ptvc->tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4329, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree
)->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc
->tree)->tree_data)->visible)) { if (proto_item_is_hidden
((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT
) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) &&
(hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data
)->fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(ptvc->tree, hfinfo); } } }
;
4330
4331 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4332
4333 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4334 offset, length, encoding);
4335}
4336
4337/* Add an item to a proto_tree, using the text label registered to that item;
4338 the item is extracted from the tvbuff handed to it. */
4339proto_item *
4340proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4341 const int start, int length, const unsigned encoding)
4342{
4343 field_info *new_fi;
4344 int item_length;
4345
4346 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4346,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4347
4348 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4349 test_length(hfinfo, tvb, start, item_length, encoding);
4350
4351 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4352
4353 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4353
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4353, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4353, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4353, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4354
4355 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4356
4357 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4358}
4359
4360proto_item *
4361proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4362 const int start, int length, const unsigned encoding)
4363{
4364 register header_field_info *hfinfo;
4365
4366 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4366, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4366,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4366, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4367 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4368}
4369
4370/* Add an item to a proto_tree, using the text label registered to that item;
4371 the item is extracted from the tvbuff handed to it.
4372
4373 Return the length of the item through the pointer. */
4374proto_item *
4375proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4376 tvbuff_t *tvb, const int start,
4377 int length, const unsigned encoding,
4378 int *lenretval)
4379{
4380 field_info *new_fi;
4381 int item_length;
4382 proto_item *item;
4383
4384 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4384,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4385
4386 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4387 test_length(hfinfo, tvb, start, item_length, encoding);
4388
4389 if (!tree) {
4390 /*
4391 * We need to get the correct item length here.
4392 * That's normally done by proto_tree_new_item(),
4393 * but we won't be calling it.
4394 */
4395 *lenretval = get_full_length(hfinfo, tvb, start, length,
4396 item_length, encoding);
4397 return NULL((void*)0);
4398 }
4399
4400 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo, {((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4407
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4407, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4407, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4407
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4401 /*((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4407
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4407, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4407, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4407
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4402 * Even if the tree item is not referenced (and thus faked),((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4407
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4407, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4407, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4407
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4403 * the caller must still be informed of the actual length.((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4407
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4407, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4407, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4407
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4404 */((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4407
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4407, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4407, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4407
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4405 *lenretval = get_full_length(hfinfo, tvb, start, length,((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4407
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4407, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4407, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4407
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4406 item_length, encoding);((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4407
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4407, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4407, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4407
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4407 })((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4407
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4407, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4407, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4407
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
;
4408
4409 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4410
4411 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4412 *lenretval = new_fi->length;
4413 return item;
4414}
4415
4416proto_item *
4417proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4418 const int start, int length,
4419 const unsigned encoding, int *lenretval)
4420{
4421 register header_field_info *hfinfo;
4422
4423 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4423, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4423,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4423, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4424 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4425}
4426
4427/* which FT_ types can use proto_tree_add_bytes_item() */
4428static inline bool_Bool
4429validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4430{
4431 return (type == FT_BYTES ||
4432 type == FT_UINT_BYTES ||
4433 type == FT_OID ||
4434 type == FT_REL_OID ||
4435 type == FT_SYSTEM_ID );
4436}
4437
4438/* Note: this does no validation that the byte array of an FT_OID or
4439 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4440 so I think it's ok to continue not validating it?
4441 */
4442proto_item *
4443proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4444 const int start, int length, const unsigned encoding,
4445 GByteArray *retval, int *endoff, int *err)
4446{
4447 field_info *new_fi;
4448 GByteArray *bytes = retval;
4449 GByteArray *created_bytes = NULL((void*)0);
4450 bool_Bool failed = false0;
4451 uint32_t n = 0;
4452 header_field_info *hfinfo;
4453 bool_Bool generate = (bytes || tree) ? true1 : false0;
4454
4455 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4455, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4455,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4455, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4456
4457 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4457,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4458
4459 DISSECTOR_ASSERT_HINT(validate_proto_tree_add_bytes_ftype(hfinfo->type),((void) ((validate_proto_tree_add_bytes_ftype(hfinfo->type
)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4460, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4460 "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type")((void) ((validate_proto_tree_add_bytes_ftype(hfinfo->type
)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4460, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4461
4462 CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
;
4463
4464 if (encoding & ENC_STR_NUM0x01000000) {
4465 REPORT_DISSECTOR_BUG("Decoding number strings for byte arrays is not supported")proto_report_dissector_bug("Decoding number strings for byte arrays is not supported"
)
;
4466 }
4467
4468 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4469 if (hfinfo->type == FT_UINT_BYTES) {
4470 /* can't decode FT_UINT_BYTES from strings */
4471 REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called for "proto_report_dissector_bug("proto_tree_add_bytes_item called for "
"FT_UINT_BYTES type, but as ENC_STR_HEX")
4472 "FT_UINT_BYTES type, but as ENC_STR_HEX")proto_report_dissector_bug("proto_tree_add_bytes_item called for "
"FT_UINT_BYTES type, but as ENC_STR_HEX")
;
4473 }
4474
4475 unsigned hex_encoding = encoding;
4476 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4477 /* If none of the separator values are used,
4478 * assume no separator (the common case). */
4479 hex_encoding |= ENC_SEP_NONE0x00010000;
4480#if 0
4481 REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called "proto_report_dissector_bug("proto_tree_add_bytes_item called "
"with ENC_STR_HEX but no ENC_SEP_XXX value")
4482 "with ENC_STR_HEX but no ENC_SEP_XXX value")proto_report_dissector_bug("proto_tree_add_bytes_item called "
"with ENC_STR_HEX but no ENC_SEP_XXX value")
;
4483#endif
4484 }
4485
4486 if (!bytes) {
4487 /* caller doesn't care about return value, but we need it to
4488 call tvb_get_string_bytes() and set the tree later */
4489 bytes = created_bytes = g_byte_array_new();
4490 }
4491
4492 /*
4493 * bytes might be NULL after this, but can't add expert
4494 * error until later; if it's NULL, just note that
4495 * it failed.
4496 */
4497 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4498 if (bytes == NULL((void*)0))
4499 failed = true1;
4500 }
4501 else if (generate) {
4502 tvb_ensure_bytes_exist(tvb, start, length);
4503
4504 if (hfinfo->type == FT_UINT_BYTES) {
4505 n = length; /* n is now the "header" length */
4506 length = get_uint_value(tree, tvb, start, n, encoding);
4507 /* length is now the value's length; only store the value in the array */
4508 tvb_ensure_bytes_exist(tvb, start + n, length);
4509 if (!bytes) {
4510 /* caller doesn't care about return value, but
4511 * we may need it to set the tree later */
4512 bytes = created_bytes = g_byte_array_new();
4513 }
4514 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4515 }
4516 else if (length > 0) {
4517 if (!bytes) {
4518 /* caller doesn't care about return value, but
4519 * we may need it to set the tree later */
4520 bytes = created_bytes = g_byte_array_new();
4521 }
4522 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4523 }
4524
4525 if (endoff)
4526 *endoff = start + n + length;
4527 }
4528
4529 if (err)
4530 *err = failed ? EINVAL22 : 0;
4531
4532 CHECK_FOR_NULL_TREE_AND_FREE(tree,if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4533 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4534 if (created_bytes)if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4535 g_byte_array_free(created_bytes, true);if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4536 created_bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4537 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4538 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4539
4540 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo,((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4546
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4546, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4546, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { if (created_bytes) g_byte_array_free(created_bytes, 1);
created_bytes = ((void*)0); bytes = ((void*)0); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4546
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4541 {((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4546
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4546, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4546, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { if (created_bytes) g_byte_array_free(created_bytes, 1);
created_bytes = ((void*)0); bytes = ((void*)0); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4546
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4542 if (created_bytes)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4546
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4546, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4546, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { if (created_bytes) g_byte_array_free(created_bytes, 1);
created_bytes = ((void*)0); bytes = ((void*)0); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4546
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4543 g_byte_array_free(created_bytes, true);((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4546
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4546, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4546, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { if (created_bytes) g_byte_array_free(created_bytes, 1);
created_bytes = ((void*)0); bytes = ((void*)0); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4546
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4544 created_bytes = NULL;((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4546
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4546, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4546, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { if (created_bytes) g_byte_array_free(created_bytes, 1);
created_bytes = ((void*)0); bytes = ((void*)0); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4546
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4545 bytes = NULL;((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4546
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4546, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4546, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { if (created_bytes) g_byte_array_free(created_bytes, 1);
created_bytes = ((void*)0); bytes = ((void*)0); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4546
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4546 } )((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4546
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4546, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4546, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { if (created_bytes) g_byte_array_free(created_bytes, 1);
created_bytes = ((void*)0); bytes = ((void*)0); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4546
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
;
4547
4548 /* n will be zero except when it's a FT_UINT_BYTES */
4549 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4550
4551 if (encoding & ENC_STRING0x03000000) {
4552 if (failed)
4553 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4554
4555 if (bytes)
4556 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4557 else
4558 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4559
4560 if (created_bytes)
4561 g_byte_array_free(created_bytes, true1);
4562 }
4563 else {
4564 /* n will be zero except when it's a FT_UINT_BYTES */
4565 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4566
4567 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4568 * use the byte array created above in this case.
4569 */
4570 if (created_bytes)
4571 g_byte_array_free(created_bytes, true1);
4572
4573 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4574 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN)do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
;
4575 }
4576
4577 return proto_tree_add_node(tree, new_fi);
4578}
4579
4580
4581proto_item *
4582proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4583 const int start, int length, const unsigned encoding,
4584 nstime_t *retval, int *endoff, int *err)
4585{
4586 field_info *new_fi;
4587 nstime_t time_stamp;
4588 int saved_err = 0;
4589 header_field_info *hfinfo;
4590
4591 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4591, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4591,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4591, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4592
4593 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4593,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4594
4595 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4596 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4597 if(retval)if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4598 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4599 nstime_set_zero(retval);if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4600 }if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4601 } )if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
;
4602
4603 nstime_set_zero(&time_stamp);
4604
4605 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4606 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ABSOLUTE_TIME)((void) (((hfinfo)->type == FT_ABSOLUTE_TIME) ? (void)0 : (
proto_report_dissector_bug("%s:%u: field %s is not of type ""FT_ABSOLUTE_TIME"
, "epan/proto.c", 4606, ((hfinfo))->abbrev))))
;
4607 /* The only string format that could be a relative time is
4608 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4609 * relative to "now" currently.
4610 */
4611 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4612 saved_err = EINVAL22;
4613 }
4614 else {
4615 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo)((void) (((hfinfo)->type == FT_ABSOLUTE_TIME || (hfinfo)->
type == FT_RELATIVE_TIME) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, "epan/proto.c", 4615, ((hfinfo))->abbrev))))
;
4616 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4617
4618 tvb_ensure_bytes_exist(tvb, start, length);
4619 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4620 if (endoff) *endoff = start + length;
4621 }
4622
4623 if (err) *err = saved_err;
4624
4625 if (retval) {
4626 retval->secs = time_stamp.secs;
4627 retval->nsecs = time_stamp.nsecs;
4628 }
4629
4630 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4631
4632 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4632
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4632, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4632, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4632, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4633
4634 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4635
4636 proto_tree_set_time(new_fi, &time_stamp);
4637
4638 if (encoding & ENC_STRING0x03000000) {
4639 if (saved_err)
4640 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4641 }
4642 else {
4643 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4644 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN)do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
;
4645 }
4646
4647 return proto_tree_add_node(tree, new_fi);
4648}
4649
4650/* Add a FT_NONE to a proto_tree */
4651proto_item *
4652proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4653 const int start, int length, const char *format,
4654 ...)
4655{
4656 proto_item *pi;
4657 va_list ap;
4658 header_field_info *hfinfo;
4659
4660 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4661
4662 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4662
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4662, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4662, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4662, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4663
4664 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_NONE)((void) (((hfinfo)->type == FT_NONE) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_NONE", "epan/proto.c", 4664
, ((hfinfo))->abbrev))))
;
4665
4666 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4667
4668 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4668, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4669
4670 va_start(ap, format)__builtin_va_start(ap, format);
4671 proto_tree_set_representation(pi, format, ap);
4672 va_end(ap)__builtin_va_end(ap);
4673
4674 /* no value to set for FT_NONE */
4675 return pi;
4676}
4677
4678/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4679 * offset, and returns proto_item* */
4680proto_item *
4681ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4682 const unsigned encoding)
4683{
4684 proto_item *item;
4685
4686 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4687 length, encoding);
4688
4689 return item;
4690}
4691
4692/* Advance the ptvcursor's offset within its tvbuff without
4693 * adding anything to the proto_tree. */
4694void
4695ptvcursor_advance(ptvcursor_t* ptvc, int length)
4696{
4697 ptvc->offset += length;
4698}
4699
4700
4701static void
4702proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4703{
4704 fvalue_set_protocol(fi->value, tvb, field_data, length);
4705}
4706
4707/* Add a FT_PROTOCOL to a proto_tree */
4708proto_item *
4709proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4710 int start, int length, const char *format, ...)
4711{
4712 proto_item *pi;
4713 tvbuff_t *protocol_tvb;
4714 va_list ap;
4715 header_field_info *hfinfo;
4716 char* protocol_rep;
4717
4718 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4719
4720 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4720
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4720, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4720, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4720, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4721
4722 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL)((void) (((hfinfo)->type == FT_PROTOCOL) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_PROTOCOL", "epan/proto.c"
, 4722, ((hfinfo))->abbrev))))
;
4723
4724 /*
4725 * This can throw an exception, so do it before we allocate anything.
4726 */
4727 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4728
4729 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4730
4731 va_start(ap, format)__builtin_va_start(ap, format);
4732 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4733 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4734 g_free(protocol_rep);
4735 va_end(ap)__builtin_va_end(ap);
4736
4737 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4737, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4738
4739 va_start(ap, format)__builtin_va_start(ap, format);
4740 proto_tree_set_representation(pi, format, ap);
4741 va_end(ap)__builtin_va_end(ap);
4742
4743 return pi;
4744}
4745
4746/* Add a FT_BYTES to a proto_tree */
4747proto_item *
4748proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4749 int length, const uint8_t *start_ptr)
4750{
4751 proto_item *pi;
4752 header_field_info *hfinfo;
4753 int item_length;
4754
4755 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4755, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4755,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4755, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4756 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4757 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4758
4759 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4760
4761 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4761
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4761, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4761, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4761, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4762
4763 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES)((void) (((hfinfo)->type == FT_BYTES) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_BYTES", "epan/proto.c",
4763, ((hfinfo))->abbrev))))
;
4764
4765 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4766 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4767
4768 return pi;
4769}
4770
4771/* Add a FT_BYTES to a proto_tree */
4772proto_item *
4773proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4774 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4775{
4776 proto_item *pi;
4777 header_field_info *hfinfo;
4778 int item_length;
4779
4780 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4780, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4780,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4780, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4781 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4782 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4783
4784 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4785
4786 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4786
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4786, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4786, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4786, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4787
4788 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES)((void) (((hfinfo)->type == FT_BYTES) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_BYTES", "epan/proto.c",
4788, ((hfinfo))->abbrev))))
;
4789
4790 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4791 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4792
4793 return pi;
4794}
4795
4796proto_item *
4797proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4798 int start, int length,
4799 const uint8_t *start_ptr,
4800 const char *format, ...)
4801{
4802 proto_item *pi;
4803 va_list ap;
4804
4805 if (start_ptr == NULL((void*)0))
4806 start_ptr = tvb_get_ptr(tvb, start, length);
4807
4808 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4809
4810 TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
;
4811
4812 va_start(ap, format)__builtin_va_start(ap, format);
4813 proto_tree_set_representation_value(pi, format, ap);
4814 va_end(ap)__builtin_va_end(ap);
4815
4816 return pi;
4817}
4818
4819proto_item *
4820proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4821 int start, int length, const uint8_t *start_ptr,
4822 const char *format, ...)
4823{
4824 proto_item *pi;
4825 va_list ap;
4826
4827 if (start_ptr == NULL((void*)0))
4828 start_ptr = tvb_get_ptr(tvb, start, length);
4829
4830 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4831
4832 TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
;
4833
4834 va_start(ap, format)__builtin_va_start(ap, format);
4835 proto_tree_set_representation(pi, format, ap);
4836 va_end(ap)__builtin_va_end(ap);
4837
4838 return pi;
4839}
4840
4841static void
4842proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4843{
4844 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4844, "length >= 0"
))))
;
4845 DISSECTOR_ASSERT(start_ptr != NULL || length == 0)((void) ((start_ptr != ((void*)0) || length == 0) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 4845, "start_ptr != ((void*)0) || length == 0"
))))
;
4846
4847 fvalue_set_bytes_data(fi->value, start_ptr, length);
4848}
4849
4850
4851static void
4852proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4853{
4854 tvb_ensure_bytes_exist(tvb, offset, length);
4855 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4856}
4857
4858static void
4859proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4860{
4861 GByteArray *bytes;
4862
4863 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4863, "value != ((void*)0)"
))))
;
4864
4865 bytes = byte_array_dup(value);
4866
4867 fvalue_set_byte_array(fi->value, bytes);
4868}
4869
4870/* Add a FT_*TIME to a proto_tree */
4871proto_item *
4872proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4873 int length, const nstime_t *value_ptr)
4874{
4875 proto_item *pi;
4876 header_field_info *hfinfo;
4877
4878 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4879
4880 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4880
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4880, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4880, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4880, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4881
4882 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo)((void) (((hfinfo)->type == FT_ABSOLUTE_TIME || (hfinfo)->
type == FT_RELATIVE_TIME) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, "epan/proto.c", 4882, ((hfinfo))->abbrev))))
;
4883
4884 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4885 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4886
4887 return pi;
4888}
4889
4890proto_item *
4891proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4892 int start, int length, nstime_t *value_ptr,
4893 const char *format, ...)
4894{
4895 proto_item *pi;
4896 va_list ap;
4897
4898 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4899 if (pi != tree) {
4900 va_start(ap, format)__builtin_va_start(ap, format);
4901 proto_tree_set_representation_value(pi, format, ap);
4902 va_end(ap)__builtin_va_end(ap);
4903 }
4904
4905 return pi;
4906}
4907
4908proto_item *
4909proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4910 int start, int length, nstime_t *value_ptr,
4911 const char *format, ...)
4912{
4913 proto_item *pi;
4914 va_list ap;
4915
4916 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4917 if (pi != tree) {
4918 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4918, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4919
4920 va_start(ap, format)__builtin_va_start(ap, format);
4921 proto_tree_set_representation(pi, format, ap);
4922 va_end(ap)__builtin_va_end(ap);
4923 }
4924
4925 return pi;
4926}
4927
4928/* Set the FT_*TIME value */
4929static void
4930proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4931{
4932 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4932, "value_ptr != ((void*)0)"
))))
;
4933
4934 fvalue_set_time(fi->value, value_ptr);
4935}
4936
4937/* Add a FT_IPXNET to a proto_tree */
4938proto_item *
4939proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4940 int length, uint32_t value)
4941{
4942 proto_item *pi;
4943 header_field_info *hfinfo;
4944
4945 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4946
4947 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4947
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4947, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4947, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4947, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4948
4949 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPXNET)((void) (((hfinfo)->type == FT_IPXNET) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_IPXNET", "epan/proto.c"
, 4949, ((hfinfo))->abbrev))))
;
4950
4951 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4952 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
4953
4954 return pi;
4955}
4956
4957proto_item *
4958proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4959 int start, int length, uint32_t value,
4960 const char *format, ...)
4961{
4962 proto_item *pi;
4963 va_list ap;
4964
4965 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4966 if (pi != tree) {
4967 va_start(ap, format)__builtin_va_start(ap, format);
4968 proto_tree_set_representation_value(pi, format, ap);
4969 va_end(ap)__builtin_va_end(ap);
4970 }
4971
4972 return pi;
4973}
4974
4975proto_item *
4976proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4977 int start, int length, uint32_t value,
4978 const char *format, ...)
4979{
4980 proto_item *pi;
4981 va_list ap;
4982
4983 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4984 if (pi != tree) {
4985 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4985, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4986
4987 va_start(ap, format)__builtin_va_start(ap, format);
4988 proto_tree_set_representation(pi, format, ap);
4989 va_end(ap)__builtin_va_end(ap);
4990 }
4991
4992 return pi;
4993}
4994
4995/* Set the FT_IPXNET value */
4996static void
4997proto_tree_set_ipxnet(field_info *fi, uint32_t value)
4998{
4999 fvalue_set_uinteger(fi->value, value);
5000}
5001
5002/* Add a FT_IPv4 to a proto_tree */
5003proto_item *
5004proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5005 int length, ws_in4_addr value)
5006{
5007 proto_item *pi;
5008 header_field_info *hfinfo;
5009
5010 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5011
5012 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5012
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5012, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5012, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5012, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5013
5014 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv4)((void) (((hfinfo)->type == FT_IPv4) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_IPv4", "epan/proto.c", 5014
, ((hfinfo))->abbrev))))
;
5015
5016 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5017 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5018
5019 return pi;
5020}
5021
5022proto_item *
5023proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5024 int start, int length, ws_in4_addr value,
5025 const char *format, ...)
5026{
5027 proto_item *pi;
5028 va_list ap;
5029
5030 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5031 if (pi != tree) {
5032 va_start(ap, format)__builtin_va_start(ap, format);
5033 proto_tree_set_representation_value(pi, format, ap);
5034 va_end(ap)__builtin_va_end(ap);
5035 }
5036
5037 return pi;
5038}
5039
5040proto_item *
5041proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5042 int start, int length, ws_in4_addr value,
5043 const char *format, ...)
5044{
5045 proto_item *pi;
5046 va_list ap;
5047
5048 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5049 if (pi != tree) {
5050 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5050, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5051
5052 va_start(ap, format)__builtin_va_start(ap, format);
5053 proto_tree_set_representation(pi, format, ap);
5054 va_end(ap)__builtin_va_end(ap);
5055 }
5056
5057 return pi;
5058}
5059
5060/* Set the FT_IPv4 value */
5061static void
5062proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5063{
5064 ipv4_addr_and_mask ipv4;
5065 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5066 fvalue_set_ipv4(fi->value, &ipv4);
5067}
5068
5069/* Add a FT_IPv6 to a proto_tree */
5070proto_item *
5071proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5072 int length, const ws_in6_addr *value)
5073{
5074 proto_item *pi;
5075 header_field_info *hfinfo;
5076
5077 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5078
5079 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5079
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5079, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5079, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5079, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5080
5081 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv6)((void) (((hfinfo)->type == FT_IPv6) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_IPv6", "epan/proto.c", 5081
, ((hfinfo))->abbrev))))
;
5082
5083 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5084 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5085
5086 return pi;
5087}
5088
5089proto_item *
5090proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5091 int start, int length,
5092 const ws_in6_addr *value_ptr,
5093 const char *format, ...)
5094{
5095 proto_item *pi;
5096 va_list ap;
5097
5098 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5099 if (pi != tree) {
5100 va_start(ap, format)__builtin_va_start(ap, format);
5101 proto_tree_set_representation_value(pi, format, ap);
5102 va_end(ap)__builtin_va_end(ap);
5103 }
5104
5105 return pi;
5106}
5107
5108proto_item *
5109proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5110 int start, int length,
5111 const ws_in6_addr *value_ptr,
5112 const char *format, ...)
5113{
5114 proto_item *pi;
5115 va_list ap;
5116
5117 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5118 if (pi != tree) {
5119 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5119, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5120
5121 va_start(ap, format)__builtin_va_start(ap, format);
5122 proto_tree_set_representation(pi, format, ap);
5123 va_end(ap)__builtin_va_end(ap);
5124 }
5125
5126 return pi;
5127}
5128
5129/* Set the FT_IPv6 value */
5130static void
5131proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5132{
5133 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5133, "value != ((void*)0)"
))))
;
5134 ipv6_addr_and_prefix ipv6;
5135 ipv6.addr = *value;
5136 ipv6.prefix = 128;
5137 fvalue_set_ipv6(fi->value, &ipv6);
5138}
5139
5140static void
5141proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5142{
5143 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5144}
5145
5146/* Set the FT_FCWWN value */
5147static void
5148proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5149{
5150 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5150, "value_ptr != ((void*)0)"
))))
;
5151 fvalue_set_fcwwn(fi->value, value_ptr);
5152}
5153
5154static void
5155proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5156{
5157 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5158}
5159
5160/* Add a FT_GUID to a proto_tree */
5161proto_item *
5162proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5163 int length, const e_guid_t *value_ptr)
5164{
5165 proto_item *pi;
5166 header_field_info *hfinfo;
5167
5168 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5169
5170 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5170
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5170, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5170, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5170, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5171
5172 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_GUID)((void) (((hfinfo)->type == FT_GUID) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_GUID", "epan/proto.c", 5172
, ((hfinfo))->abbrev))))
;
5173
5174 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5175 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5176
5177 return pi;
5178}
5179
5180proto_item *
5181proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5182 int start, int length,
5183 const e_guid_t *value_ptr,
5184 const char *format, ...)
5185{
5186 proto_item *pi;
5187 va_list ap;
5188
5189 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5190 if (pi != tree) {
5191 va_start(ap, format)__builtin_va_start(ap, format);
5192 proto_tree_set_representation_value(pi, format, ap);
5193 va_end(ap)__builtin_va_end(ap);
5194 }
5195
5196 return pi;
5197}
5198
5199proto_item *
5200proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5201 int start, int length, const e_guid_t *value_ptr,
5202 const char *format, ...)
5203{
5204 proto_item *pi;
5205 va_list ap;
5206
5207 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5208 if (pi != tree) {
5209 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5209, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5210
5211 va_start(ap, format)__builtin_va_start(ap, format);
5212 proto_tree_set_representation(pi, format, ap);
5213 va_end(ap)__builtin_va_end(ap);
5214 }
5215
5216 return pi;
5217}
5218
5219/* Set the FT_GUID value */
5220static void
5221proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5222{
5223 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5223, "value_ptr != ((void*)0)"
))))
;
5224 fvalue_set_guid(fi->value, value_ptr);
5225}
5226
5227static void
5228proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5229 const unsigned encoding)
5230{
5231 e_guid_t guid;
5232
5233 tvb_get_guid(tvb, start, &guid, encoding);
5234 proto_tree_set_guid(fi, &guid);
5235}
5236
5237/* Add a FT_OID to a proto_tree */
5238proto_item *
5239proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5240 int length, const uint8_t* value_ptr)
5241{
5242 proto_item *pi;
5243 header_field_info *hfinfo;
5244
5245 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5246
5247 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5247
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5247, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5247, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5247, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5248
5249 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_OID)((void) (((hfinfo)->type == FT_OID) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_OID", "epan/proto.c", 5249
, ((hfinfo))->abbrev))))
;
5250
5251 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5252 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5253
5254 return pi;
5255}
5256
5257proto_item *
5258proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5259 int start, int length,
5260 const uint8_t* value_ptr,
5261 const char *format, ...)
5262{
5263 proto_item *pi;
5264 va_list ap;
5265
5266 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5267 if (pi != tree) {
5268 va_start(ap, format)__builtin_va_start(ap, format);
5269 proto_tree_set_representation_value(pi, format, ap);
5270 va_end(ap)__builtin_va_end(ap);
5271 }
5272
5273 return pi;
5274}
5275
5276proto_item *
5277proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5278 int start, int length, const uint8_t* value_ptr,
5279 const char *format, ...)
5280{
5281 proto_item *pi;
5282 va_list ap;
5283
5284 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5285 if (pi != tree) {
5286 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5286, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5287
5288 va_start(ap, format)__builtin_va_start(ap, format);
5289 proto_tree_set_representation(pi, format, ap);
5290 va_end(ap)__builtin_va_end(ap);
5291 }
5292
5293 return pi;
5294}
5295
5296/* Set the FT_OID value */
5297static void
5298proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5299{
5300 GByteArray *bytes;
5301
5302 DISSECTOR_ASSERT(value_ptr != NULL || length == 0)((void) ((value_ptr != ((void*)0) || length == 0) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 5302, "value_ptr != ((void*)0) || length == 0"
))))
;
5303
5304 bytes = g_byte_array_new();
5305 if (length > 0) {
5306 g_byte_array_append(bytes, value_ptr, length);
5307 }
5308 fvalue_set_byte_array(fi->value, bytes);
5309}
5310
5311static void
5312proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5313{
5314 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5315}
5316
5317/* Set the FT_SYSTEM_ID value */
5318static void
5319proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5320{
5321 GByteArray *bytes;
5322
5323 DISSECTOR_ASSERT(value_ptr != NULL || length == 0)((void) ((value_ptr != ((void*)0) || length == 0) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 5323, "value_ptr != ((void*)0) || length == 0"
))))
;
5324
5325 bytes = g_byte_array_new();
5326 if (length > 0) {
5327 g_byte_array_append(bytes, value_ptr, length);
5328 }
5329 fvalue_set_byte_array(fi->value, bytes);
5330}
5331
5332static void
5333proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5334{
5335 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5336}
5337
5338/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5339 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5340 * is destroyed. */
5341proto_item *
5342proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5343 int length, const char* value)
5344{
5345 proto_item *pi;
5346 header_field_info *hfinfo;
5347 int item_length;
5348
5349 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5349, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5349,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5349, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5350 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5351 /*
5352 * Special case - if the length is 0, skip the test, so that
5353 * we can have an empty string right after the end of the
5354 * packet. (This handles URL-encoded forms where the last field
5355 * has no value so the form ends right after the =.)
5356 */
5357 if (item_length != 0)
5358 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5359
5360 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5361
5362 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5362
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5362, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5362, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5362, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5363
5364 DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo)((void) ((((hfinfo)->type) == FT_STRING || ((hfinfo)->type
) == FT_STRINGZ || ((hfinfo)->type) == FT_STRINGZPAD || ((
hfinfo)->type) == FT_STRINGZTRUNC || ((hfinfo)->type) ==
FT_UINT_STRING || ((hfinfo)->type) == FT_AX25) ? (void)0 :
(proto_report_dissector_bug("%s:%u: field %s is not of type FT_STRING, FT_STRINGZ, FT_STRINGZPAD, FT_STRINGZTRUNC, or FT_UINT_STRING"
, "epan/proto.c", 5364, ((hfinfo))->abbrev))))
;
5365
5366 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5367 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5367, "length >= 0"
))))
;
5368
5369 WS_UTF_8_CHECK(value, -1)do { const char *__uni_endptr; if (1 && (value) != ((
void*)0) && !g_utf8_validate(value, -1, &__uni_endptr
)) { do { if (1) { ws_log_utf8_full("UTF-8", LOG_LEVEL_DEBUG,
"epan/proto.c", 5369, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5370 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5371
5372 return pi;
5373}
5374
5375proto_item *
5376proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5377 int start, int length, const char* value,
5378 const char *format,
5379 ...)
5380{
5381 proto_item *pi;
5382 va_list ap;
5383
5384 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5385 if (pi != tree) {
5386 va_start(ap, format)__builtin_va_start(ap, format);
5387 proto_tree_set_representation_value(pi, format, ap);
5388 va_end(ap)__builtin_va_end(ap);
5389 }
5390
5391 return pi;
5392}
5393
5394proto_item *
5395proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5396 int start, int length, const char* value,
5397 const char *format, ...)
5398{
5399 proto_item *pi;
5400 va_list ap;
5401
5402 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5403 if (pi != tree) {
5404 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5404, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5405
5406 va_start(ap, format)__builtin_va_start(ap, format);
5407 proto_tree_set_representation(pi, format, ap);
5408 va_end(ap)__builtin_va_end(ap);
5409 }
5410
5411 return pi;
5412}
5413
5414/* Set the FT_STRING value */
5415static void
5416proto_tree_set_string(field_info *fi, const char* value)
5417{
5418 if (value) {
5419 fvalue_set_string(fi->value, value);
5420 } else {
5421 /*
5422 * XXX - why is a null value for a string field
5423 * considered valid?
5424 */
5425 fvalue_set_string(fi->value, "[ Null ]");
5426 }
5427}
5428
5429/* Set the FT_AX25 value */
5430static void
5431proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5432{
5433 fvalue_set_ax25(fi->value, value);
5434}
5435
5436static void
5437proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5438{
5439 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5440}
5441
5442/* Set the FT_VINES value */
5443static void
5444proto_tree_set_vines(field_info *fi, const uint8_t* value)
5445{
5446 fvalue_set_vines(fi->value, value);
5447}
5448
5449static void
5450proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5451{
5452 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5453}
5454
5455/* Add a FT_ETHER to a proto_tree */
5456proto_item *
5457proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5458 int length, const uint8_t* value)
5459{
5460 proto_item *pi;
5461 header_field_info *hfinfo;
5462
5463 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5464
5465 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5465
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5465, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5465, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5465, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5466
5467 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ETHER)((void) (((hfinfo)->type == FT_ETHER) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_ETHER", "epan/proto.c",
5467, ((hfinfo))->abbrev))))
;
5468
5469 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5470 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5471
5472 return pi;
5473}
5474
5475proto_item *
5476proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5477 int start, int length, const uint8_t* value,
5478 const char *format, ...)
5479{
5480 proto_item *pi;
5481 va_list ap;
5482
5483 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5484 if (pi != tree) {
5485 va_start(ap, format)__builtin_va_start(ap, format);
5486 proto_tree_set_representation_value(pi, format, ap);
5487 va_end(ap)__builtin_va_end(ap);
5488 }
5489
5490 return pi;
5491}
5492
5493proto_item *
5494proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5495 int start, int length, const uint8_t* value,
5496 const char *format, ...)
5497{
5498 proto_item *pi;
5499 va_list ap;
5500
5501 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5502 if (pi != tree) {
5503 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5503, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5504
5505 va_start(ap, format)__builtin_va_start(ap, format);
5506 proto_tree_set_representation(pi, format, ap);
5507 va_end(ap)__builtin_va_end(ap);
5508 }
5509
5510 return pi;
5511}
5512
5513/* Set the FT_ETHER value */
5514static void
5515proto_tree_set_ether(field_info *fi, const uint8_t* value)
5516{
5517 fvalue_set_ether(fi->value, value);
5518}
5519
5520static void
5521proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5522{
5523 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5524}
5525
5526/* Add a FT_BOOLEAN to a proto_tree */
5527proto_item *
5528proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5529 int length, uint64_t value)
5530{
5531 proto_item *pi;
5532 header_field_info *hfinfo;
5533
5534 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5535
5536 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5536
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5536, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5536, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5536, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5537
5538 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN)((void) (((hfinfo)->type == FT_BOOLEAN) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_BOOLEAN", "epan/proto.c"
, 5538, ((hfinfo))->abbrev))))
;
5539
5540 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5541 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5542
5543 return pi;
5544}
5545
5546proto_item *
5547proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5548 tvbuff_t *tvb, int start, int length,
5549 uint64_t value, const char *format, ...)
5550{
5551 proto_item *pi;
5552 va_list ap;
5553
5554 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5555 if (pi != tree) {
5556 va_start(ap, format)__builtin_va_start(ap, format);
5557 proto_tree_set_representation_value(pi, format, ap);
5558 va_end(ap)__builtin_va_end(ap);
5559 }
5560
5561 return pi;
5562}
5563
5564proto_item *
5565proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5566 int start, int length, uint64_t value,
5567 const char *format, ...)
5568{
5569 proto_item *pi;
5570 va_list ap;
5571
5572 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5573 if (pi != tree) {
5574 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5574, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5575
5576 va_start(ap, format)__builtin_va_start(ap, format);
5577 proto_tree_set_representation(pi, format, ap);
5578 va_end(ap)__builtin_va_end(ap);
5579 }
5580
5581 return pi;
5582}
5583
5584/* Set the FT_BOOLEAN value */
5585static void
5586proto_tree_set_boolean(field_info *fi, uint64_t value)
5587{
5588 proto_tree_set_uint64(fi, value);
5589}
5590
5591/* Generate, into "buf", a string showing the bits of a bitfield.
5592 Return a pointer to the character after that string. */
5593static char *
5594other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5595{
5596 int i = 0;
5597 uint64_t bit;
5598 char *p;
5599
5600 p = buf;
5601
5602 /* This is a devel error. It is safer to stop here. */
5603 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5603, "width >= 1"
))))
;
5604
5605 bit = UINT64_C(1)1UL << (width - 1);
5606 for (;;) {
5607 if (mask & bit) {
5608 /* This bit is part of the field. Show its value. */
5609 if (val & bit)
5610 *p++ = '1';
5611 else
5612 *p++ = '0';
5613 } else {
5614 /* This bit is not part of the field. */
5615 *p++ = '.';
5616 }
5617 bit >>= 1;
5618 i++;
5619 if (i >= width)
5620 break;
5621 if (i % 4 == 0)
5622 *p++ = ' ';
5623 }
5624 *p = '\0';
5625 return p;
5626}
5627
5628static char *
5629decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5630{
5631 char *p;
5632
5633 p = other_decode_bitfield_value(buf, val, mask, width);
5634 p = g_stpcpy(p, " = ");
5635
5636 return p;
5637}
5638
5639static char *
5640other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5641{
5642 int i = 0;
5643 uint64_t bit;
5644 char *p;
5645
5646 p = buf;
5647
5648 /* This is a devel error. It is safer to stop here. */
5649 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5649, "width >= 1"
))))
;
5650
5651 bit = UINT64_C(1)1UL << (width - 1);
5652 for (;;) {
5653 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5654 (mask & bit)) {
5655 /* This bit is part of the field. Show its value. */
5656 if (val & bit)
5657 *p++ = '1';
5658 else
5659 *p++ = '0';
5660 } else {
5661 /* This bit is not part of the field. */
5662 *p++ = '.';
5663 }
5664 bit >>= 1;
5665 i++;
5666 if (i >= width)
5667 break;
5668 if (i % 4 == 0)
5669 *p++ = ' ';
5670 }
5671
5672 *p = '\0';
5673 return p;
5674}
5675
5676static char *
5677decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5678{
5679 char *p;
5680
5681 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5682 p = g_stpcpy(p, " = ");
5683
5684 return p;
5685}
5686
5687/* Add a FT_FLOAT to a proto_tree */
5688proto_item *
5689proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5690 int length, float value)
5691{
5692 proto_item *pi;
5693 header_field_info *hfinfo;
5694
5695 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5696
5697 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5697
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5697, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5697, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5697, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5698
5699 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_FLOAT)((void) (((hfinfo)->type == FT_FLOAT) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_FLOAT", "epan/proto.c",
5699, ((hfinfo))->abbrev))))
;
5700
5701 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5702 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5703
5704 return pi;
5705}
5706
5707proto_item *
5708proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5709 int start, int length, float value,
5710 const char *format, ...)
5711{
5712 proto_item *pi;
5713 va_list ap;
5714
5715 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5716 if (pi != tree) {
5717 va_start(ap, format)__builtin_va_start(ap, format);
5718 proto_tree_set_representation_value(pi, format, ap);
5719 va_end(ap)__builtin_va_end(ap);
5720 }
5721
5722 return pi;
5723}
5724
5725proto_item *
5726proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5727 int start, int length, float value,
5728 const char *format, ...)
5729{
5730 proto_item *pi;
5731 va_list ap;
5732
5733 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5734 if (pi != tree) {
5735 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5735, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5736
5737 va_start(ap, format)__builtin_va_start(ap, format);
5738 proto_tree_set_representation(pi, format, ap);
5739 va_end(ap)__builtin_va_end(ap);
5740 }
5741
5742 return pi;
5743}
5744
5745/* Set the FT_FLOAT value */
5746static void
5747proto_tree_set_float(field_info *fi, float value)
5748{
5749 fvalue_set_floating(fi->value, value);
5750}
5751
5752/* Add a FT_DOUBLE to a proto_tree */
5753proto_item *
5754proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5755 int length, double value)
5756{
5757 proto_item *pi;
5758 header_field_info *hfinfo;
5759
5760 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5761
5762 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5762
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5762, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5762, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5762, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5763
5764 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_DOUBLE)((void) (((hfinfo)->type == FT_DOUBLE) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_DOUBLE", "epan/proto.c"
, 5764, ((hfinfo))->abbrev))))
;
5765
5766 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5767 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5768
5769 return pi;
5770}
5771
5772proto_item *
5773proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5774 int start, int length, double value,
5775 const char *format, ...)
5776{
5777 proto_item *pi;
5778 va_list ap;
5779
5780 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5781 if (pi != tree) {
5782 va_start(ap, format)__builtin_va_start(ap, format);
5783 proto_tree_set_representation_value(pi, format, ap);
5784 va_end(ap)__builtin_va_end(ap);
5785 }
5786
5787 return pi;
5788}
5789
5790proto_item *
5791proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5792 int start, int length, double value,
5793 const char *format, ...)
5794{
5795 proto_item *pi;
5796 va_list ap;
5797
5798 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5799 if (pi != tree) {
5800 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5800, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5801
5802 va_start(ap, format)__builtin_va_start(ap, format);
5803 proto_tree_set_representation(pi, format, ap);
5804 va_end(ap)__builtin_va_end(ap);
5805 }
5806
5807 return pi;
5808}
5809
5810/* Set the FT_DOUBLE value */
5811static void
5812proto_tree_set_double(field_info *fi, double value)
5813{
5814 fvalue_set_floating(fi->value, value);
5815}
5816
5817/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5818proto_item *
5819proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5820 int length, uint32_t value)
5821{
5822 proto_item *pi = NULL((void*)0);
5823 header_field_info *hfinfo;
5824
5825 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5826
5827 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5827
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5827, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5827, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5827, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5828
5829 switch (hfinfo->type) {
5830 case FT_CHAR:
5831 case FT_UINT8:
5832 case FT_UINT16:
5833 case FT_UINT24:
5834 case FT_UINT32:
5835 case FT_FRAMENUM:
5836 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5837 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5838 break;
5839
5840 default:
5841 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, or FT_FRAMENUM",proto_report_dissector_bug("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, or FT_FRAMENUM"
, hfinfo->abbrev)
5842 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, or FT_FRAMENUM"
, hfinfo->abbrev)
;
5843 }
5844
5845 return pi;
5846}
5847
5848proto_item *
5849proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5850 int start, int length, uint32_t value,
5851 const char *format, ...)
5852{
5853 proto_item *pi;
5854 va_list ap;
5855
5856 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5857 if (pi != tree) {
5858 va_start(ap, format)__builtin_va_start(ap, format);
5859 proto_tree_set_representation_value(pi, format, ap);
5860 va_end(ap)__builtin_va_end(ap);
5861 }
5862
5863 return pi;
5864}
5865
5866proto_item *
5867proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5868 int start, int length, uint32_t value,
5869 const char *format, ...)
5870{
5871 proto_item *pi;
5872 va_list ap;
5873
5874 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5875 if (pi != tree) {
5876 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5876, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5877
5878 va_start(ap, format)__builtin_va_start(ap, format);
5879 proto_tree_set_representation(pi, format, ap);
5880 va_end(ap)__builtin_va_end(ap);
5881 }
5882
5883 return pi;
5884}
5885
5886/* Set the FT_UINT{8,16,24,32} value */
5887static void
5888proto_tree_set_uint(field_info *fi, uint32_t value)
5889{
5890 const header_field_info *hfinfo;
5891 uint32_t integer;
5892
5893 hfinfo = fi->hfinfo;
5894 integer = value;
5895
5896 if (hfinfo->bitmask) {
5897 /* Mask out irrelevant portions */
5898 integer &= (uint32_t)(hfinfo->bitmask);
5899
5900 /* Shift bits */
5901 integer >>= hfinfo_bitshift(hfinfo);
5902
5903 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5904 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth
(hfinfo)) & 63) << 12)); } while(0)
;
5905 }
5906
5907 fvalue_set_uinteger(fi->value, integer);
5908}
5909
5910/* Add FT_UINT{40,48,56,64} to a proto_tree */
5911proto_item *
5912proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5913 int length, uint64_t value)
5914{
5915 proto_item *pi = NULL((void*)0);
5916 header_field_info *hfinfo;
5917
5918 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5919
5920 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5920
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5920, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5920, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5920, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5921
5922 switch (hfinfo->type) {
5923 case FT_UINT40:
5924 case FT_UINT48:
5925 case FT_UINT56:
5926 case FT_UINT64:
5927 case FT_FRAMENUM:
5928 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5929 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
5930 break;
5931
5932 default:
5933 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, FT_UINT64, or FT_FRAMENUM",proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, FT_UINT64, or FT_FRAMENUM"
, hfinfo->abbrev)
5934 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, FT_UINT64, or FT_FRAMENUM"
, hfinfo->abbrev)
;
5935 }
5936
5937 return pi;
5938}
5939
5940proto_item *
5941proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5942 int start, int length, uint64_t value,
5943 const char *format, ...)
5944{
5945 proto_item *pi;
5946 va_list ap;
5947
5948 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5949 if (pi != tree) {
5950 va_start(ap, format)__builtin_va_start(ap, format);
5951 proto_tree_set_representation_value(pi, format, ap);
5952 va_end(ap)__builtin_va_end(ap);
5953 }
5954
5955 return pi;
5956}
5957
5958proto_item *
5959proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5960 int start, int length, uint64_t value,
5961 const char *format, ...)
5962{
5963 proto_item *pi;
5964 va_list ap;
5965
5966 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5967 if (pi != tree) {
5968 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5968, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5969
5970 va_start(ap, format)__builtin_va_start(ap, format);
5971 proto_tree_set_representation(pi, format, ap);
5972 va_end(ap)__builtin_va_end(ap);
5973 }
5974
5975 return pi;
5976}
5977
5978/* Set the FT_UINT{40,48,56,64} value */
5979static void
5980proto_tree_set_uint64(field_info *fi, uint64_t value)
5981{
5982 const header_field_info *hfinfo;
5983 uint64_t integer;
5984
5985 hfinfo = fi->hfinfo;
5986 integer = value;
5987
5988 if (hfinfo->bitmask) {
5989 /* Mask out irrelevant portions */
5990 integer &= hfinfo->bitmask;
5991
5992 /* Shift bits */
5993 integer >>= hfinfo_bitshift(hfinfo);
5994
5995 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5996 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth
(hfinfo)) & 63) << 12)); } while(0)
;
5997 }
5998
5999 fvalue_set_uinteger64(fi->value, integer);
6000}
6001
6002/* Add FT_INT{8,16,24,32} to a proto_tree */
6003proto_item *
6004proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6005 int length, int32_t value)
6006{
6007 proto_item *pi = NULL((void*)0);
6008 header_field_info *hfinfo;
6009
6010 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6011
6012 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6012
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6012, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6012, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6012, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
6013
6014 switch (hfinfo->type) {
6015 case FT_INT8:
6016 case FT_INT16:
6017 case FT_INT24:
6018 case FT_INT32:
6019 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6020 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6021 break;
6022
6023 default:
6024 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
6025 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6026 }
6027
6028 return pi;
6029}
6030
6031proto_item *
6032proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6033 int start, int length, int32_t value,
6034 const char *format, ...)
6035{
6036 proto_item *pi;
6037 va_list ap;
6038
6039 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6040 if (pi != tree) {
6041 va_start(ap, format)__builtin_va_start(ap, format);
6042 proto_tree_set_representation_value(pi, format, ap);
6043 va_end(ap)__builtin_va_end(ap);
6044 }
6045
6046 return pi;
6047}
6048
6049proto_item *
6050proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6051 int start, int length, int32_t value,
6052 const char *format, ...)
6053{
6054 proto_item *pi;
6055 va_list ap;
6056
6057 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6058 if (pi != tree) {
6059 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6059, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6060
6061 va_start(ap, format)__builtin_va_start(ap, format);
6062 proto_tree_set_representation(pi, format, ap);
6063 va_end(ap)__builtin_va_end(ap);
6064 }
6065
6066 return pi;
6067}
6068
6069/* Set the FT_INT{8,16,24,32} value */
6070static void
6071proto_tree_set_int(field_info *fi, int32_t value)
6072{
6073 const header_field_info *hfinfo;
6074 uint32_t integer;
6075 int no_of_bits;
6076
6077 hfinfo = fi->hfinfo;
6078 integer = (uint32_t) value;
6079
6080 if (hfinfo->bitmask) {
6081 /* Mask out irrelevant portions */
6082 integer &= (uint32_t)(hfinfo->bitmask);
6083
6084 /* Shift bits */
6085 integer >>= hfinfo_bitshift(hfinfo);
6086
6087 no_of_bits = ws_count_ones(hfinfo->bitmask);
6088 integer = ws_sign_ext32(integer, no_of_bits);
6089
6090 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6091 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth
(hfinfo)) & 63) << 12)); } while(0)
;
6092 }
6093
6094 fvalue_set_sinteger(fi->value, integer);
6095}
6096
6097/* Add FT_INT{40,48,56,64} to a proto_tree */
6098proto_item *
6099proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6100 int length, int64_t value)
6101{
6102 proto_item *pi = NULL((void*)0);
6103 header_field_info *hfinfo;
6104
6105 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6106
6107 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6107
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6107, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6107, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6107, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
6108
6109 switch (hfinfo->type) {
6110 case FT_INT40:
6111 case FT_INT48:
6112 case FT_INT56:
6113 case FT_INT64:
6114 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6115 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6116 break;
6117
6118 default:
6119 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
6120 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6121 }
6122
6123 return pi;
6124}
6125
6126proto_item *
6127proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6128 int start, int length, int64_t value,
6129 const char *format, ...)
6130{
6131 proto_item *pi;
6132 va_list ap;
6133
6134 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6135 if (pi != tree) {
6136 va_start(ap, format)__builtin_va_start(ap, format);
6137 proto_tree_set_representation_value(pi, format, ap);
6138 va_end(ap)__builtin_va_end(ap);
6139 }
6140
6141 return pi;
6142}
6143
6144/* Set the FT_INT{40,48,56,64} value */
6145static void
6146proto_tree_set_int64(field_info *fi, int64_t value)
6147{
6148 const header_field_info *hfinfo;
6149 uint64_t integer;
6150 int no_of_bits;
6151
6152 hfinfo = fi->hfinfo;
6153 integer = value;
6154
6155 if (hfinfo->bitmask) {
6156 /* Mask out irrelevant portions */
6157 integer &= hfinfo->bitmask;
6158
6159 /* Shift bits */
6160 integer >>= hfinfo_bitshift(hfinfo);
6161
6162 no_of_bits = ws_count_ones(hfinfo->bitmask);
6163 integer = ws_sign_ext64(integer, no_of_bits);
6164
6165 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6166 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth
(hfinfo)) & 63) << 12)); } while(0)
;
6167 }
6168
6169 fvalue_set_sinteger64(fi->value, integer);
6170}
6171
6172proto_item *
6173proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6174 int start, int length, int64_t value,
6175 const char *format, ...)
6176{
6177 proto_item *pi;
6178 va_list ap;
6179
6180 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6181 if (pi != tree) {
6182 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6182, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6183
6184 va_start(ap, format)__builtin_va_start(ap, format);
6185 proto_tree_set_representation(pi, format, ap);
6186 va_end(ap)__builtin_va_end(ap);
6187 }
6188
6189 return pi;
6190}
6191
6192/* Add a FT_EUI64 to a proto_tree */
6193proto_item *
6194proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6195 int length, const uint64_t value)
6196{
6197 proto_item *pi;
6198 header_field_info *hfinfo;
6199
6200 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6201
6202 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6202
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6202, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6202, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6202, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
6203
6204 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_EUI64)((void) (((hfinfo)->type == FT_EUI64) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_EUI64", "epan/proto.c",
6204, ((hfinfo))->abbrev))))
;
6205
6206 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6207 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6208
6209 return pi;
6210}
6211
6212proto_item *
6213proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6214 int start, int length, const uint64_t value,
6215 const char *format, ...)
6216{
6217 proto_item *pi;
6218 va_list ap;
6219
6220 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6221 if (pi != tree) {
6222 va_start(ap, format)__builtin_va_start(ap, format);
6223 proto_tree_set_representation_value(pi, format, ap);
6224 va_end(ap)__builtin_va_end(ap);
6225 }
6226
6227 return pi;
6228}
6229
6230proto_item *
6231proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6232 int start, int length, const uint64_t value,
6233 const char *format, ...)
6234{
6235 proto_item *pi;
6236 va_list ap;
6237
6238 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6239 if (pi != tree) {
6240 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6240, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6241
6242 va_start(ap, format)__builtin_va_start(ap, format);
6243 proto_tree_set_representation(pi, format, ap);
6244 va_end(ap)__builtin_va_end(ap);
6245 }
6246
6247 return pi;
6248}
6249
6250/* Set the FT_EUI64 value */
6251static void
6252proto_tree_set_eui64(field_info *fi, const uint64_t value)
6253{
6254 uint8_t v[FT_EUI64_LEN8];
6255 phton64(v, value);
6256 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6257}
6258
6259static void
6260proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6261{
6262 if (encoding)
6263 {
6264 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6265 } else {
6266 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6267 }
6268}
6269
6270proto_item *
6271proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6272 const mac_hf_list_t *list_generic,
6273 int idx, tvbuff_t *tvb,
6274 proto_tree *tree, int offset)
6275{
6276 const uint8_t addr[6];
6277 const char *addr_name = NULL((void*)0);
6278 const char *oui_name = NULL((void*)0);
6279 proto_item *addr_item = NULL((void*)0);
6280 proto_tree *addr_tree = NULL((void*)0);
6281 proto_item *ret_val = NULL((void*)0);
6282
6283 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6284 return NULL((void*)0);
6285 }
6286
6287 /* Resolve what we can of the address */
6288 tvb_memcpy(tvb, (void *)addr, offset, 6);
6289 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6290 addr_name = get_ether_name(addr);
6291 }
6292 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6293 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6294 }
6295
6296 /* Add the item for the specific address type */
6297 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6298 if (idx >= 0) {
6299 addr_tree = proto_item_add_subtree(ret_val, idx);
6300 }
6301 else {
6302 addr_tree = tree;
6303 }
6304
6305 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6306 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6307 tvb, offset, 6, addr_name);
6308 proto_item_set_generated(addr_item);
6309 proto_item_set_hidden(addr_item);
6310 }
6311
6312 if (list_specific->hf_oui != NULL((void*)0)) {
6313 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6314 proto_item_set_generated(addr_item);
6315 proto_item_set_hidden(addr_item);
6316
6317 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6318 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6319 proto_item_set_generated(addr_item);
6320 proto_item_set_hidden(addr_item);
6321 }
6322 }
6323
6324 if (list_specific->hf_lg != NULL((void*)0)) {
6325 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6326 }
6327 if (list_specific->hf_ig != NULL((void*)0)) {
6328 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6329 }
6330
6331 /* Were we given a list for generic address fields? If not, stop here */
6332 if (list_generic == NULL((void*)0)) {
6333 return ret_val;
6334 }
6335
6336 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6337 proto_item_set_hidden(addr_item);
6338
6339 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6340 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6341 tvb, offset, 6, addr_name);
6342 proto_item_set_generated(addr_item);
6343 proto_item_set_hidden(addr_item);
6344 }
6345
6346 if (list_generic->hf_oui != NULL((void*)0)) {
6347 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6348 proto_item_set_generated(addr_item);
6349 proto_item_set_hidden(addr_item);
6350
6351 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6352 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6353 proto_item_set_generated(addr_item);
6354 proto_item_set_hidden(addr_item);
6355 }
6356 }
6357
6358 if (list_generic->hf_lg != NULL((void*)0)) {
6359 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6360 proto_item_set_hidden(addr_item);
6361 }
6362 if (list_generic->hf_ig != NULL((void*)0)) {
6363 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6364 proto_item_set_hidden(addr_item);
6365 }
6366 return ret_val;
6367}
6368
6369static proto_item *
6370proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6371{
6372 proto_node *pnode, *tnode, *sibling;
6373 field_info *tfi;
6374 unsigned depth = 1;
6375
6376 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6376, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6377
6378 /*
6379 * Restrict our depth. proto_tree_traverse_pre_order and
6380 * proto_tree_traverse_post_order (and possibly others) are recursive
6381 * so we need to be mindful of our stack size.
6382 */
6383 if (tree->first_child == NULL((void*)0)) {
6384 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6385 depth++;
6386 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6387 THROW_MESSAGE(DissectorError, wmem_strdup_printf(PNODE_POOL(tree),except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)"
, prefs.gui_max_tree_depth, hfinfo->name, hfinfo->abbrev
, ((const char*) (__func__)), 6390)))
6388 "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)",except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)"
, prefs.gui_max_tree_depth, hfinfo->name, hfinfo->abbrev
, ((const char*) (__func__)), 6390)))
6389 prefs.gui_max_tree_depth,except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)"
, prefs.gui_max_tree_depth, hfinfo->name, hfinfo->abbrev
, ((const char*) (__func__)), 6390)))
6390 hfinfo->name, hfinfo->abbrev, G_STRFUNC, __LINE__))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)"
, prefs.gui_max_tree_depth, hfinfo->name, hfinfo->abbrev
, ((const char*) (__func__)), 6390)))
;
6391 }
6392 }
6393 }
6394
6395 /*
6396 * Make sure "tree" is ready to have subtrees under it, by
6397 * checking whether it's been given an ett_ value.
6398 *
6399 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6400 * node of the protocol tree. That node is not displayed,
6401 * so it doesn't need an ett_ value to remember whether it
6402 * was expanded.
6403 */
6404 tnode = tree;
6405 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6406 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6407 REPORT_DISSECTOR_BUG("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)",proto_report_dissector_bug("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)"
, hfinfo->name, hfinfo->abbrev, tfi->tree_type, "epan/proto.c"
, 6408)
6408 hfinfo->name, hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__)proto_report_dissector_bug("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)"
, hfinfo->name, hfinfo->abbrev, tfi->tree_type, "epan/proto.c"
, 6408)
;
6409 /* XXX - is it safe to continue here? */
6410 }
6411
6412 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6413 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6414 pnode->parent = tnode;
6415 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6416 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6417 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6418
6419 if (tnode->last_child != NULL((void*)0)) {
6420 sibling = tnode->last_child;
6421 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6421, "sibling->next == ((void*)0)"
))))
;
6422 sibling->next = pnode;
6423 } else
6424 tnode->first_child = pnode;
6425 tnode->last_child = pnode;
6426
6427 /* We should not be adding a fake node for an interesting field */
6428 ws_assert(hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT)do { if ((1) && !(hfinfo->ref_type != HF_REF_TYPE_DIRECT
&& hfinfo->ref_type != HF_REF_TYPE_PRINT)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6428, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6429
6430 /* XXX - Should the proto_item have a header_field_info member, at least
6431 * for faked items, to know what hfi was faked? (Some dissectors look at
6432 * the tree items directly.)
6433 */
6434 return (proto_item *)pnode;
6435}
6436
6437/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6438static proto_item *
6439proto_tree_add_node(proto_tree *tree, field_info *fi)
6440{
6441 proto_node *pnode, *tnode, *sibling;
6442 field_info *tfi;
6443 unsigned depth = 1;
6444
6445 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6445, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6446
6447 /*
6448 * Restrict our depth. proto_tree_traverse_pre_order and
6449 * proto_tree_traverse_post_order (and possibly others) are recursive
6450 * so we need to be mindful of our stack size.
6451 */
6452 if (tree->first_child == NULL((void*)0)) {
6453 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6454 depth++;
6455 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6456 fvalue_free(fi->value);
6457 fi->value = NULL((void*)0);
6458 THROW_MESSAGE(DissectorError, wmem_strdup_printf(PNODE_POOL(tree),except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)"
, prefs.gui_max_tree_depth, fi->hfinfo->name, fi->hfinfo
->abbrev, ((const char*) (__func__)), 6461)))
6459 "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)",except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)"
, prefs.gui_max_tree_depth, fi->hfinfo->name, fi->hfinfo
->abbrev, ((const char*) (__func__)), 6461)))
6460 prefs.gui_max_tree_depth,except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)"
, prefs.gui_max_tree_depth, fi->hfinfo->name, fi->hfinfo
->abbrev, ((const char*) (__func__)), 6461)))
6461 fi->hfinfo->name, fi->hfinfo->abbrev, G_STRFUNC, __LINE__))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)"
, prefs.gui_max_tree_depth, fi->hfinfo->name, fi->hfinfo
->abbrev, ((const char*) (__func__)), 6461)))
;
6462 }
6463 }
6464 }
6465
6466 /*
6467 * Make sure "tree" is ready to have subtrees under it, by
6468 * checking whether it's been given an ett_ value.
6469 *
6470 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6471 * node of the protocol tree. That node is not displayed,
6472 * so it doesn't need an ett_ value to remember whether it
6473 * was expanded.
6474 */
6475 tnode = tree;
6476 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6477 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6478 /* Since we are not adding fi to a node, its fvalue won't get
6479 * freed by proto_tree_free_node(), so free it now.
6480 */
6481 fvalue_free(fi->value);
6482 fi->value = NULL((void*)0);
6483 REPORT_DISSECTOR_BUG("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)",proto_report_dissector_bug("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)"
, fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type
, "epan/proto.c", 6484)
6484 fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__)proto_report_dissector_bug("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)"
, fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type
, "epan/proto.c", 6484)
;
6485 /* XXX - is it safe to continue here? */
6486 }
6487
6488 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6489 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6490 pnode->parent = tnode;
6491 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6492 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6493 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6494
6495 if (tnode->last_child != NULL((void*)0)) {
6496 sibling = tnode->last_child;
6497 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6497, "sibling->next == ((void*)0)"
))))
;
6498 sibling->next = pnode;
6499 } else
6500 tnode->first_child = pnode;
6501 tnode->last_child = pnode;
6502
6503 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6504
6505 return (proto_item *)pnode;
6506}
6507
6508
6509/* Generic way to allocate field_info and add to proto_tree.
6510 * Sets *pfi to address of newly-allocated field_info struct */
6511static proto_item *
6512proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6513 int *length)
6514{
6515 proto_item *pi;
6516 field_info *fi;
6517 int item_length;
6518
6519 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6520 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6521 pi = proto_tree_add_node(tree, fi);
6522
6523 return pi;
6524}
6525
6526
6527static void
6528get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6529 int *item_length, const unsigned encoding)
6530{
6531 int length_remaining;
6532
6533 /*
6534 * We only allow a null tvbuff if the item has a zero length,
6535 * i.e. if there's no data backing it.
6536 */
6537 DISSECTOR_ASSERT(tvb != NULL || *length == 0)((void) ((tvb != ((void*)0) || *length == 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6537, "tvb != ((void*)0) || *length == 0"
))))
;
6538
6539 /*
6540 * XXX - in some protocols, there are 32-bit unsigned length
6541 * fields, so lengths in protocol tree and tvbuff routines
6542 * should really be unsigned. We should have, for those
6543 * field types for which "to the end of the tvbuff" makes sense,
6544 * additional routines that take no length argument and
6545 * add fields that run to the end of the tvbuff.
6546 */
6547 if (*length == -1) {
6548 /*
6549 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6550 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6551 * of -1 means "set the length to what remains in the
6552 * tvbuff".
6553 *
6554 * The assumption is either that
6555 *
6556 * 1) the length of the item can only be determined
6557 * by dissection (typically true of items with
6558 * subitems, which are probably FT_NONE or
6559 * FT_PROTOCOL)
6560 *
6561 * or
6562 *
6563 * 2) if the tvbuff is "short" (either due to a short
6564 * snapshot length or due to lack of reassembly of
6565 * fragments/segments/whatever), we want to display
6566 * what's available in the field (probably FT_BYTES
6567 * or FT_STRING) and then throw an exception later
6568 *
6569 * or
6570 *
6571 * 3) the field is defined to be "what's left in the
6572 * packet"
6573 *
6574 * so we set the length to what remains in the tvbuff so
6575 * that, if we throw an exception while dissecting, it
6576 * has what is probably the right value.
6577 *
6578 * For FT_STRINGZ, it means "the string is null-terminated,
6579 * not null-padded; set the length to the actual length
6580 * of the string", and if the tvbuff if short, we just
6581 * throw an exception.
6582 *
6583 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6584 * it means "find the end of the string",
6585 * and if the tvbuff if short, we just throw an exception.
6586 *
6587 * It's not valid for any other type of field. For those
6588 * fields, we treat -1 the same way we treat other
6589 * negative values - we assume the length is a Really
6590 * Big Positive Number, and throw a ReportedBoundsError
6591 * exception, under the assumption that the Really Big
6592 * Length would run past the end of the packet.
6593 */
6594 if ((FT_IS_INT(hfinfo->type)(((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
) || ((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
))
) || (FT_IS_UINT(hfinfo->type)(((hfinfo->type) == FT_CHAR || (hfinfo->type) == FT_UINT8
|| (hfinfo->type) == FT_UINT16 || (hfinfo->type) == FT_UINT24
|| (hfinfo->type) == FT_UINT32 || (hfinfo->type) == FT_FRAMENUM
) || ((hfinfo->type) == FT_UINT40 || (hfinfo->type) == FT_UINT48
|| (hfinfo->type) == FT_UINT56 || (hfinfo->type) == FT_UINT64
))
)) {
6595 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6596 /*
6597 * Leave the length as -1, so our caller knows
6598 * it was -1.
6599 */
6600 *item_length = *length;
6601 return;
6602 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6603 switch (tvb_get_uint8(tvb, start) >> 6)
6604 {
6605 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6606 *item_length = 1;
6607 break;
6608 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6609 *item_length = 2;
6610 break;
6611 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6612 *item_length = 4;
6613 break;
6614 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6615 *item_length = 8;
6616 break;
6617 }
6618 }
6619 }
6620
6621 switch (hfinfo->type) {
6622
6623 case FT_PROTOCOL:
6624 case FT_NONE:
6625 case FT_BYTES:
6626 case FT_STRING:
6627 case FT_STRINGZPAD:
6628 case FT_STRINGZTRUNC:
6629 /*
6630 * We allow FT_PROTOCOLs to be zero-length -
6631 * for example, an ONC RPC NULL procedure has
6632 * neither arguments nor reply, so the
6633 * payload for that protocol is empty.
6634 *
6635 * We also allow the others to be zero-length -
6636 * because that's the way the code has been for a
6637 * long, long time.
6638 *
6639 * However, we want to ensure that the start
6640 * offset is not *past* the byte past the end
6641 * of the tvbuff: we throw an exception in that
6642 * case.
6643 */
6644 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6645 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6645, "*length >= 0"
))))
;
6646 break;
6647
6648 case FT_STRINGZ:
6649 /*
6650 * Leave the length as -1, so our caller knows
6651 * it was -1.
6652 */
6653 break;
6654
6655 default:
6656 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6657 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6657))
;
6658 }
6659 *item_length = *length;
6660 } else {
6661 *item_length = *length;
6662 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6663 /*
6664 * These types are for interior nodes of the
6665 * tree, and don't have data associated with
6666 * them; if the length is negative (XXX - see
6667 * above) or goes past the end of the tvbuff,
6668 * cut it short at the end of the tvbuff.
6669 * That way, if this field is selected in
6670 * Wireshark, we don't highlight stuff past
6671 * the end of the data.
6672 */
6673 /* XXX - what to do, if we don't have a tvb? */
6674 if (tvb) {
6675 length_remaining = tvb_captured_length_remaining(tvb, start);
6676 if (*item_length < 0 ||
6677 (*item_length > 0 &&
6678 (length_remaining < *item_length)))
6679 *item_length = length_remaining;
6680 }
6681 }
6682 if (*item_length < 0) {
6683 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6684 }
6685 }
6686}
6687
6688static int
6689get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6690 int length, unsigned item_length, const int encoding)
6691{
6692 uint32_t n;
6693
6694 /*
6695 * We need to get the correct item length here.
6696 * That's normally done by proto_tree_new_item(),
6697 * but we won't be calling it.
6698 */
6699 switch (hfinfo->type) {
6700
6701 case FT_NONE:
6702 case FT_PROTOCOL:
6703 case FT_BYTES:
6704 /*
6705 * The length is the specified length.
6706 */
6707 break;
6708
6709 case FT_UINT_BYTES:
6710 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6711 item_length += n;
6712 if ((int)item_length < length) {
6713 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6714 }
6715 break;
6716
6717 /* XXX - make these just FT_UINT? */
6718 case FT_UINT8:
6719 case FT_UINT16:
6720 case FT_UINT24:
6721 case FT_UINT32:
6722 case FT_UINT40:
6723 case FT_UINT48:
6724 case FT_UINT56:
6725 case FT_UINT64:
6726 /* XXX - make these just FT_INT? */
6727 case FT_INT8:
6728 case FT_INT16:
6729 case FT_INT24:
6730 case FT_INT32:
6731 case FT_INT40:
6732 case FT_INT48:
6733 case FT_INT56:
6734 case FT_INT64:
6735 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6736 if (length < -1) {
6737 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6738 }
6739 if (length == -1) {
6740 uint64_t dummy;
6741 /* This can throw an exception */
6742 /* XXX - do this without fetching the varint? */
6743 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6744 if (length == 0) {
6745 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6746 }
6747 }
6748 item_length = length;
6749 break;
6750 }
6751
6752 /*
6753 * The length is the specified length.
6754 */
6755 break;
6756
6757 case FT_BOOLEAN:
6758 case FT_CHAR:
6759 case FT_IPv4:
6760 case FT_IPXNET:
6761 case FT_IPv6:
6762 case FT_FCWWN:
6763 case FT_AX25:
6764 case FT_VINES:
6765 case FT_ETHER:
6766 case FT_EUI64:
6767 case FT_GUID:
6768 case FT_OID:
6769 case FT_REL_OID:
6770 case FT_SYSTEM_ID:
6771 case FT_FLOAT:
6772 case FT_DOUBLE:
6773 case FT_STRING:
6774 /*
6775 * The length is the specified length.
6776 */
6777 break;
6778
6779 case FT_STRINGZ:
6780 if (length < -1) {
6781 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6782 }
6783 if (length == -1) {
6784 /* This can throw an exception */
6785 /* XXX - do this without fetching the string? */
6786 wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, &length, encoding));
6787 }
6788 item_length = length;
6789 break;
6790
6791 case FT_UINT_STRING:
6792 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6793 item_length += n;
6794 if ((int)item_length < length) {
6795 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6796 }
6797 break;
6798
6799 case FT_STRINGZPAD:
6800 case FT_STRINGZTRUNC:
6801 case FT_ABSOLUTE_TIME:
6802 case FT_RELATIVE_TIME:
6803 case FT_IEEE_11073_SFLOAT:
6804 case FT_IEEE_11073_FLOAT:
6805 /*
6806 * The length is the specified length.
6807 */
6808 break;
6809
6810 default:
6811 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in gset_full_length()",proto_report_dissector_bug("field %s has type %d (%s) not handled in gset_full_length()"
, hfinfo->abbrev, hfinfo->type, ftype_name(hfinfo->type
))
6812 hfinfo->abbrev,proto_report_dissector_bug("field %s has type %d (%s) not handled in gset_full_length()"
, hfinfo->abbrev, hfinfo->type, ftype_name(hfinfo->type
))
6813 hfinfo->type,proto_report_dissector_bug("field %s has type %d (%s) not handled in gset_full_length()"
, hfinfo->abbrev, hfinfo->type, ftype_name(hfinfo->type
))
6814 ftype_name(hfinfo->type))proto_report_dissector_bug("field %s has type %d (%s) not handled in gset_full_length()"
, hfinfo->abbrev, hfinfo->type, ftype_name(hfinfo->type
))
;
6815 break;
6816 }
6817 return item_length;
6818}
6819
6820// This was arbitrarily chosen, but if you're adding 50K items to the tree
6821// without advancing the offset you should probably take a long, hard look
6822// at what you're doing.
6823// We *could* make this a configurable option, but I (Gerald) would like to
6824// avoid adding yet another nerd knob.
6825# define PROTO_TREE_MAX_IDLE50000 50000
6826static field_info *
6827new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6828 const int start, const int item_length)
6829{
6830 field_info *fi;
6831
6832 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6833
6834 fi->hfinfo = hfinfo;
6835 fi->start = start;
6836 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6837 /* add the data source tvbuff */
6838 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6839
6840 // If our start offset hasn't advanced after adding many items it probably
6841 // means we're in a large or infinite loop.
6842 if (fi->start > 0) {
6843 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6844 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6845 DISSECTOR_ASSERT_HINT(PTREE_DATA(tree)->start_idle_count < PROTO_TREE_MAX_IDLE, fi->hfinfo->abbrev)((void) ((((tree)->tree_data)->start_idle_count < 50000
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6845, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6846 } else {
6847 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6848 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6849 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6850 }
6851 }
6852 fi->length = item_length;
6853 fi->tree_type = -1;
6854 fi->flags = 0;
6855 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6856 /* If the tree is not visible, set the item hidden, unless we
6857 * need the representation or length and can't fake them.
6858 */
6859 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6860 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6861 }
6862 }
6863 fi->value = fvalue_new(fi->hfinfo->type);
6864 fi->rep = NULL((void*)0);
6865
6866 fi->appendix_start = 0;
6867 fi->appendix_length = 0;
6868
6869 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6870 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6871
6872 return fi;
6873}
6874
6875static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6876{
6877 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6878 return 0;
6879 }
6880
6881 /* Search for field name */
6882 char *ptr = strstr(representation, hfinfo->name);
6883 if (!ptr) {
6884 return 0;
6885 }
6886
6887 /* Check if field name ends with the ": " delimiter */
6888 ptr += strlen(hfinfo->name);
6889 if (strncmp(ptr, ": ", 2) == 0) {
6890 ptr += 2;
6891 }
6892
6893 /* Return offset to after field name */
6894 return ptr - representation;
6895}
6896
6897/* If the protocol tree is to be visible, set the representation of a
6898 proto_tree entry with the name of the field for the item and with
6899 the value formatted with the supplied printf-style format and
6900 argument list. */
6901static void
6902proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6903{
6904 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6904, __func__, "assertion failed: %s", "pi"
); } while (0)
;
6905
6906 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6907 * items string representation */
6908 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
6909 size_t name_pos, ret = 0;
6910 char *str;
6911 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6912 const header_field_info *hf;
6913
6914 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6914, "fi"))))
;
6915
6916 hf = fi->hfinfo;
6917
6918 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep)fi->rep = ((item_label_t*)wmem_alloc((((pi)->tree_data->
pinfo->pool)), sizeof(item_label_t))); fi->rep->value_pos
= 0; fi->rep->value_len = 0;
;
6919 if (hf->bitmask && (hf->type == FT_BOOLEAN || FT_IS_UINT(hf->type)(((hf->type) == FT_CHAR || (hf->type) == FT_UINT8 || (hf
->type) == FT_UINT16 || (hf->type) == FT_UINT24 || (hf->
type) == FT_UINT32 || (hf->type) == FT_FRAMENUM) || ((hf->
type) == FT_UINT40 || (hf->type) == FT_UINT48 || (hf->type
) == FT_UINT56 || (hf->type) == FT_UINT64))
)) {
6920 uint64_t val;
6921 char *p;
6922
6923 if (FT_IS_UINT32(hf->type)((hf->type) == FT_CHAR || (hf->type) == FT_UINT8 || (hf
->type) == FT_UINT16 || (hf->type) == FT_UINT24 || (hf->
type) == FT_UINT32 || (hf->type) == FT_FRAMENUM)
)
6924 val = fvalue_get_uinteger(fi->value);
6925 else
6926 val = fvalue_get_uinteger64(fi->value);
6927
6928 val <<= hfinfo_bitshift(hf);
6929
6930 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
6931 ret = (p - fi->rep->representation);
6932 }
6933
6934 /* put in the hf name */
6935 name_pos = ret = label_concat(fi->rep->representation, ret, hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, hf->
name, 0)
;
6936
6937 ret = label_concat(fi->rep->representation, ret, ": ")ws_label_strcpy(fi->rep->representation, 240, ret, ": "
, 0)
;
6938 /* If possible, Put in the value of the string */
6939 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
6940 WS_UTF_8_CHECK(str, -1)do { const char *__uni_endptr; if (1 && (str) != ((void
*)0) && !g_utf8_validate(str, -1, &__uni_endptr))
{ do { if (1) { ws_log_utf8_full("UTF-8", LOG_LEVEL_DEBUG, "epan/proto.c"
, 6940, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
6941 fi->rep->value_pos = ret;
6942 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, str, 0);
6943 if (ret >= ITEM_LABEL_LENGTH240) {
6944 /* Uh oh, we don't have enough room. Tell the user
6945 * that the field is truncated.
6946 */
6947 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
6948 }
6949 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
6950 }
6951}
6952
6953/* If the protocol tree is to be visible, set the representation of a
6954 proto_tree entry with the representation formatted with the supplied
6955 printf-style format and argument list. */
6956static void
6957proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
6958{
6959 size_t ret; /*tmp return value */
6960 char *str;
6961 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6962
6963 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6963, "fi"))))
;
6964
6965 if (!proto_item_is_hidden(pi)) {
6966 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep)fi->rep = ((item_label_t*)wmem_alloc((((pi)->tree_data->
pinfo->pool)), sizeof(item_label_t))); fi->rep->value_pos
= 0; fi->rep->value_len = 0;
;
6967
6968 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
6969 WS_UTF_8_CHECK(str, -1)do { const char *__uni_endptr; if (1 && (str) != ((void
*)0) && !g_utf8_validate(str, -1, &__uni_endptr))
{ do { if (1) { ws_log_utf8_full("UTF-8", LOG_LEVEL_DEBUG, "epan/proto.c"
, 6969, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
6970 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
6971 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
6972 if (ret >= ITEM_LABEL_LENGTH240) {
6973 /* Uh oh, we don't have enough room. Tell the user
6974 * that the field is truncated.
6975 */
6976 LABEL_MARK_TRUNCATED_START(fi->rep->representation, &fi->rep->value_pos)label_mark_truncated(fi->rep->representation, 0, &fi
->rep->value_pos)
;
6977 }
6978 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
6979 }
6980}
6981
6982static int
6983proto_strlcpy(char *dest, const char *src, size_t dest_size)
6984{
6985 if (dest_size == 0) return 0;
6986
6987 size_t res = g_strlcpy(dest, src, dest_size);
6988
6989 /* At most dest_size - 1 characters will be copied
6990 * (unless dest_size is 0). */
6991 if (res >= dest_size)
6992 res = dest_size - 1;
6993 return (int) res;
6994}
6995
6996static header_field_info *
6997hfinfo_same_name_get_prev(const header_field_info *hfinfo)
6998{
6999 header_field_info *dup_hfinfo;
7000
7001 if (hfinfo->same_name_prev_id == -1)
7002 return NULL((void*)0);
7003 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, dup_hfinfo)if((hfinfo->same_name_prev_id == 0 || (unsigned)hfinfo->
same_name_prev_id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7003
, __func__, "Unregistered hf! index=%d", hfinfo->same_name_prev_id
); ((void) ((hfinfo->same_name_prev_id > 0 && (
unsigned)hfinfo->same_name_prev_id < gpa_hfinfo.len) ? (
void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 7003, "hfinfo->same_name_prev_id > 0 && (unsigned)hfinfo->same_name_prev_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
same_name_prev_id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 7003,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7004 return dup_hfinfo;
7005}
7006
7007static void
7008hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7009{
7010 g_free(last_field_name);
7011 last_field_name = NULL((void*)0);
7012
7013 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7014 /* No hfinfo with the same name */
7015 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
7016 return;
7017 }
7018
7019 if (hfinfo->same_name_next) {
7020 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7021 }
7022
7023 if (hfinfo->same_name_prev_id != -1) {
7024 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7025 same_name_prev->same_name_next = hfinfo->same_name_next;
7026 if (!hfinfo->same_name_next) {
7027 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7028 g_hash_table_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7029 }
7030 }
7031}
7032
7033int
7034proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7035{
7036 const header_field_info *hfinfo = finfo->hfinfo;
7037 int label_len = 0;
7038 char *tmp_str;
7039 const char *str;
7040 const uint8_t *bytes;
7041 uint32_t number;
7042 uint64_t number64;
7043 const char *hf_str_val;
7044 char number_buf[NUMBER_LABEL_LENGTH80];
7045 const char *number_out;
7046 address addr;
7047 const ipv4_addr_and_mask *ipv4;
7048 const ipv6_addr_and_prefix *ipv6;
7049
7050 switch (hfinfo->type) {
7051
7052 case FT_NONE:
7053 case FT_PROTOCOL:
7054 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7055
7056 case FT_UINT_BYTES:
7057 case FT_BYTES:
7058 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7059 hfinfo,
7060 fvalue_get_bytes_data(finfo->value),
7061 (unsigned)fvalue_length2(finfo->value),
7062 label_str_size);
7063 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7064 wmem_free(NULL((void*)0), tmp_str);
7065 break;
7066
7067 case FT_ABSOLUTE_TIME:
7068 {
7069 const nstime_t *value = fvalue_get_time(finfo->value);
7070 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7071 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7072 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7073 }
7074 if (hfinfo->strings) {
7075 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7076 if (time_string != NULL((void*)0)) {
7077 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7078 break;
7079 }
7080 }
7081 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7082 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7083 wmem_free(NULL((void*)0), tmp_str);
7084 break;
7085 }
7086
7087 case FT_RELATIVE_TIME:
7088 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7089 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7090 wmem_free(NULL((void*)0), tmp_str);
7091 break;
7092
7093 case FT_BOOLEAN:
7094 number64 = fvalue_get_uinteger64(finfo->value);
7095 label_len = proto_strlcpy(display_label_str,
7096 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7097 break;
7098
7099 case FT_CHAR:
7100 number = fvalue_get_uinteger(finfo->value);
7101
7102 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7103 char tmp[ITEM_LABEL_LENGTH240];
7104 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7105
7106 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7106, "fmtfunc"))))
;
7107 fmtfunc(tmp, number);
7108
7109 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7110
7111 } else if (hfinfo->strings) {
7112 number_out = hf_try_val_to_str(number, hfinfo);
7113
7114 if (!number_out) {
7115 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7116 }
7117
7118 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7119
7120 } else {
7121 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7122
7123 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7124 }
7125
7126 break;
7127
7128 /* XXX - make these just FT_NUMBER? */
7129 case FT_INT8:
7130 case FT_INT16:
7131 case FT_INT24:
7132 case FT_INT32:
7133 case FT_UINT8:
7134 case FT_UINT16:
7135 case FT_UINT24:
7136 case FT_UINT32:
7137 case FT_FRAMENUM:
7138 hf_str_val = NULL((void*)0);
7139 number = FT_IS_INT(hfinfo->type)(((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
) || ((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
))
?
7140 (uint32_t) fvalue_get_sinteger(finfo->value) :
7141 fvalue_get_uinteger(finfo->value);
7142
7143 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7144 char tmp[ITEM_LABEL_LENGTH240];
7145 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7146
7147 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7147, "fmtfunc"))))
;
7148 fmtfunc(tmp, number);
7149
7150 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7151
7152 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7153 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7154 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7155 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7156 hf_str_val = hf_try_val_to_str(number, hfinfo);
7157 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7158 } else {
7159 number_out = hf_try_val_to_str(number, hfinfo);
7160
7161 if (!number_out) {
7162 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7163 }
7164
7165 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7166 }
7167 } else {
7168 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7169
7170 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7171 }
7172
7173 break;
7174
7175 case FT_INT40:
7176 case FT_INT48:
7177 case FT_INT56:
7178 case FT_INT64:
7179 case FT_UINT40:
7180 case FT_UINT48:
7181 case FT_UINT56:
7182 case FT_UINT64:
7183 hf_str_val = NULL((void*)0);
7184 number64 = FT_IS_INT(hfinfo->type)(((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
) || ((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
))
?
7185 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7186 fvalue_get_uinteger64(finfo->value);
7187
7188 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7189 char tmp[ITEM_LABEL_LENGTH240];
7190 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7191
7192 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7192, "fmtfunc64"
))))
;
7193 fmtfunc64(tmp, number64);
7194
7195 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7196 } else if (hfinfo->strings) {
7197 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7198 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7199 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7200 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7201 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7202 } else {
7203 number_out = hf_try_val64_to_str(number64, hfinfo);
7204
7205 if (!number_out)
7206 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7207
7208 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7209 }
7210 } else {
7211 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7212
7213 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7214 }
7215
7216 break;
7217
7218 case FT_EUI64:
7219 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7220 tmp_str = address_to_display(NULL((void*)0), &addr);
7221 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7222 wmem_free(NULL((void*)0), tmp_str);
7223 break;
7224
7225 case FT_IPv4:
7226 ipv4 = fvalue_get_ipv4(finfo->value);
7227 //XXX: Should we ignore the mask?
7228 set_address_ipv4(&addr, ipv4);
7229 tmp_str = address_to_display(NULL((void*)0), &addr);
7230 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7231 wmem_free(NULL((void*)0), tmp_str);
7232 free_address(&addr);
7233 break;
7234
7235 case FT_IPv6:
7236 ipv6 = fvalue_get_ipv6(finfo->value);
7237 set_address_ipv6(&addr, ipv6);
7238 tmp_str = address_to_display(NULL((void*)0), &addr);
7239 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7240 wmem_free(NULL((void*)0), tmp_str);
7241 free_address(&addr);
7242 break;
7243
7244 case FT_FCWWN:
7245 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7246 tmp_str = address_to_display(NULL((void*)0), &addr);
7247 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7248 wmem_free(NULL((void*)0), tmp_str);
7249 break;
7250
7251 case FT_ETHER:
7252 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7253 tmp_str = address_to_display(NULL((void*)0), &addr);
7254 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7255 wmem_free(NULL((void*)0), tmp_str);
7256 break;
7257
7258 case FT_GUID:
7259 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7260 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7261 wmem_free(NULL((void*)0), tmp_str);
7262 break;
7263
7264 case FT_REL_OID:
7265 bytes = fvalue_get_bytes_data(finfo->value);
7266 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7267 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7268 wmem_free(NULL((void*)0), tmp_str);
7269 break;
7270
7271 case FT_OID:
7272 bytes = fvalue_get_bytes_data(finfo->value);
7273 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7274 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7275 wmem_free(NULL((void*)0), tmp_str);
7276 break;
7277
7278 case FT_SYSTEM_ID:
7279 bytes = fvalue_get_bytes_data(finfo->value);
7280 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7281 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7282 wmem_free(NULL((void*)0), tmp_str);
7283 break;
7284
7285 case FT_FLOAT:
7286 case FT_DOUBLE:
7287 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7288 break;
7289
7290 case FT_IEEE_11073_SFLOAT:
7291 case FT_IEEE_11073_FLOAT:
7292 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7293 break;
7294
7295 case FT_STRING:
7296 case FT_STRINGZ:
7297 case FT_UINT_STRING:
7298 case FT_STRINGZPAD:
7299 case FT_STRINGZTRUNC:
7300 str = fvalue_get_string(finfo->value);
7301 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, str, label_strcat_flags(hfinfo));
7302 if (label_len >= label_str_size) {
7303 /* Truncation occurred. Get the real length
7304 * copied (not including '\0') */
7305 label_len = label_str_size ? label_str_size - 1 : 0;
7306 }
7307 break;
7308
7309 default:
7310 /* First try ftype string representation */
7311 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7312 if (!tmp_str) {
7313 /* Default to show as bytes */
7314 bytes = fvalue_get_bytes_data(finfo->value);
7315 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7316 }
7317 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7318 wmem_free(NULL((void*)0), tmp_str);
7319 break;
7320 }
7321 return label_len;
7322}
7323
7324const char *
7325proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7326 char *result, char *expr, const int size)
7327{
7328 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7329 GPtrArray *finfos;
7330 field_info *finfo = NULL((void*)0);
7331 header_field_info* hfinfo;
7332 const char *abbrev = NULL((void*)0);
7333
7334 char *str;
7335 col_custom_t *field_idx;
7336 int field_id;
7337 int ii = 0;
7338
7339 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7339, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7340 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7341 field_id = field_idx->field_id;
7342 if (field_id == 0) {
7343 GPtrArray *fvals = NULL((void*)0);
7344 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7345 if (fvals != NULL((void*)0)) {
7346
7347 // XXX - Handling occurrences is unusual when more
7348 // than one field is involved, e.g. there's four
7349 // results for tcp.port + tcp.port. We may really
7350 // want to apply it to the operands, not the output.
7351 // Note that occurrences are not quite the same as
7352 // the layer operator (should the grammar support
7353 // both?)
7354 /* Calculate single index or set outer boundaries */
7355 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7356 if (occurrence < 0) {
7357 i = occurrence + len;
7358 last = i;
7359 } else if (occurrence > 0) {
7360 i = occurrence - 1;
7361 last = i;
7362 } else {
7363 i = 0;
7364 last = len - 1;
7365 }
7366 if (i < 0 || i >= len) {
7367 g_ptr_array_unref(fvals);
7368 continue;
7369 }
7370 for (; i <= last; i++) {
7371 /* XXX - We could have a "resolved" result
7372 * for types where the value depends only
7373 * on the type, e.g. FT_IPv4, and not on
7374 * hfinfo->strings. Supporting the latter
7375 * requires knowing which hfinfo matched
7376 * if there are multiple with the same
7377 * abbreviation. In any case, we need to
7378 * know the expected return type of the
7379 * field expression.
7380 */
7381 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7382 if (offset_r && (offset_r < (size - 1)))
7383 result[offset_r++] = ',';
7384 if (offset_e && (offset_e < (size - 1)))
7385 expr[offset_e++] = ',';
7386 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7387 // col_{add,append,set}_* calls ws_label_strcpy
7388 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7389
7390 g_free(str);
7391 }
7392 g_ptr_array_unref(fvals);
7393 } else if (passed) {
7394 // XXX - Occurrence doesn't make sense for a test
7395 // output, it should be applied to the operands.
7396 if (offset_r && (offset_r < (size - 1)))
7397 result[offset_r++] = ',';
7398 if (offset_e && (offset_e < (size - 1)))
7399 expr[offset_e++] = ',';
7400 /* Prevent multiple check marks */
7401 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7402 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7403 } else {
7404 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7405 }
7406 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7407 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7408 } else {
7409 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7410 }
7411 }
7412 continue;
7413 }
7414 PROTO_REGISTRAR_GET_NTH((unsigned)field_id, hfinfo)if(((unsigned)field_id == 0 || (unsigned)(unsigned)field_id >
gpa_hfinfo.len) && wireshark_abort_on_dissector_bug)
ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7414
, __func__, "Unregistered hf! index=%d", (unsigned)field_id);
((void) (((unsigned)field_id > 0 && (unsigned)(unsigned
)field_id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 7414,
"(unsigned)field_id > 0 && (unsigned)(unsigned)field_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[(unsigned
)field_id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 7414,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7415
7416 /* do we need to rewind ? */
7417 if (!hfinfo)
7418 return "";
7419
7420 if (occurrence < 0) {
7421 /* Search other direction */
7422 while (hfinfo->same_name_prev_id != -1) {
7423 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, hfinfo)if((hfinfo->same_name_prev_id == 0 || (unsigned)hfinfo->
same_name_prev_id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7423
, __func__, "Unregistered hf! index=%d", hfinfo->same_name_prev_id
); ((void) ((hfinfo->same_name_prev_id > 0 && (
unsigned)hfinfo->same_name_prev_id < gpa_hfinfo.len) ? (
void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 7423, "hfinfo->same_name_prev_id > 0 && (unsigned)hfinfo->same_name_prev_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
same_name_prev_id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 7423,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7424 }
7425 }
7426
7427 prev_len = 0; /* Reset handled occurrences */
7428
7429 while (hfinfo) {
7430 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7431
7432 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7433 if (occurrence < 0) {
7434 hfinfo = hfinfo->same_name_next;
7435 } else {
7436 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7437 }
7438 continue;
7439 }
7440
7441 /* Are there enough occurrences of the field? */
7442 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7443 if (occurrence < 0) {
7444 hfinfo = hfinfo->same_name_next;
7445 } else {
7446 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7447 }
7448 prev_len += len;
7449 continue;
7450 }
7451
7452 /* Calculate single index or set outer boundaries */
7453 if (occurrence < 0) {
7454 i = occurrence + len + prev_len;
7455 last = i;
7456 } else if (occurrence > 0) {
7457 i = occurrence - 1 - prev_len;
7458 last = i;
7459 } else {
7460 i = 0;
7461 last = len - 1;
7462 }
7463
7464 prev_len += len; /* Count handled occurrences */
7465
7466 while (i <= last) {
7467 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7468
7469 if (offset_r && (offset_r < (size - 1)))
7470 result[offset_r++] = ',';
7471
7472 if (display_details) {
7473 char representation[ITEM_LABEL_LENGTH240];
7474 size_t offset = 0;
7475
7476 if (finfo->rep && finfo->rep->value_len) {
7477 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7478 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7479 } else {
7480 proto_item_fill_label(finfo, representation, &offset);
7481 }
7482 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7483 } else {
7484 switch (hfinfo->type) {
7485
7486 case FT_NONE:
7487 case FT_PROTOCOL:
7488 /* Prevent multiple check marks */
7489 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7490 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7491 } else {
7492 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7493 }
7494 break;
7495
7496 default:
7497 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7498 break;
7499 }
7500 }
7501
7502 if (offset_e && (offset_e < (size - 1)))
7503 expr[offset_e++] = ',';
7504
7505 if (hfinfo->strings && hfinfo->type != FT_FRAMENUM && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE && (FT_IS_INT(hfinfo->type)(((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
) || ((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
))
|| FT_IS_UINT(hfinfo->type)(((hfinfo->type) == FT_CHAR || (hfinfo->type) == FT_UINT8
|| (hfinfo->type) == FT_UINT16 || (hfinfo->type) == FT_UINT24
|| (hfinfo->type) == FT_UINT32 || (hfinfo->type) == FT_FRAMENUM
) || ((hfinfo->type) == FT_UINT40 || (hfinfo->type) == FT_UINT48
|| (hfinfo->type) == FT_UINT56 || (hfinfo->type) == FT_UINT64
))
)) {
7506 const char *hf_str_val;
7507 /* Integer types with BASE_NONE never get the numeric value. */
7508 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7509 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7510 } else if (FT_IS_UINT32(hfinfo->type)((hfinfo->type) == FT_CHAR || (hfinfo->type) == FT_UINT8
|| (hfinfo->type) == FT_UINT16 || (hfinfo->type) == FT_UINT24
|| (hfinfo->type) == FT_UINT32 || (hfinfo->type) == FT_FRAMENUM
)
) {
7511 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7512 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7513 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7514 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7515 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7516 }
7517 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7518 offset_e = (int)strlen(expr);
7519 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7520 /* Prevent multiple check marks */
7521 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7522 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7523 } else {
7524 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7525 }
7526 } else {
7527 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7528 // col_{add,append,set}_* calls ws_label_strcpy
7529 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7530 wmem_free(NULL((void*)0), str);
7531 }
7532 i++;
7533 }
7534
7535 /* XXX: Why is only the first abbreviation returned for a multifield
7536 * custom column? */
7537 if (!abbrev) {
7538 /* Store abbrev for return value */
7539 abbrev = hfinfo->abbrev;
7540 }
7541
7542 if (occurrence == 0) {
7543 /* Fetch next hfinfo with same name (abbrev) */
7544 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7545 } else {
7546 hfinfo = NULL((void*)0);
7547 }
7548 }
7549 }
7550
7551 if (offset_r >= (size - 1)) {
7552 mark_truncated(result, 0, size, NULL((void*)0));
7553 }
7554 if (offset_e >= (size - 1)) {
7555 mark_truncated(expr, 0, size, NULL((void*)0));
7556 }
7557 return abbrev ? abbrev : "";
7558}
7559
7560char *
7561proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7562{
7563 int len, prev_len, last, i;
7564 GPtrArray *finfos;
7565 field_info *finfo = NULL((void*)0);
7566 header_field_info* hfinfo;
7567
7568 char *filter = NULL((void*)0);
7569 GPtrArray *filter_array;
7570
7571 col_custom_t *col_custom;
7572 int field_id;
7573
7574 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7574, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7575 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7576 for (GSList *iter = field_ids; iter; iter = iter->next) {
7577 col_custom = (col_custom_t*)iter->data;
7578 field_id = col_custom->field_id;
7579 if (field_id == 0) {
7580 GPtrArray *fvals = NULL((void*)0);
7581 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7582 if (fvals != NULL((void*)0)) {
7583 // XXX - Handling occurrences is unusual when more
7584 // than one field is involved, e.g. there's four
7585 // results for tcp.port + tcp.port. We really
7586 // want to apply it to the operands, not the output.
7587 /* Calculate single index or set outer boundaries */
7588 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7589 if (occurrence < 0) {
7590 i = occurrence + len;
7591 last = i;
7592 } else if (occurrence > 0) {
7593 i = occurrence - 1;
7594 last = i;
7595 } else {
7596 i = 0;
7597 last = len - 1;
7598 }
7599 if (i < 0 || i >= len) {
7600 g_ptr_array_unref(fvals);
7601 continue;
7602 }
7603 for (; i <= last; i++) {
7604 /* XXX - Should multiple values for one
7605 * field use set membership to reduce
7606 * verbosity, here and below? */
7607 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7608 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7609 wmem_free(NULL((void*)0), str);
7610 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7611 g_ptr_array_add(filter_array, filter);
7612 }
7613 }
7614 g_ptr_array_unref(fvals);
7615 } else if (passed) {
7616 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7617 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7618 g_ptr_array_add(filter_array, filter);
7619 }
7620 } else {
7621 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7622 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7623 g_ptr_array_add(filter_array, filter);
7624 }
7625 }
7626 continue;
7627 }
7628
7629 PROTO_REGISTRAR_GET_NTH((unsigned)field_id, hfinfo)if(((unsigned)field_id == 0 || (unsigned)(unsigned)field_id >
gpa_hfinfo.len) && wireshark_abort_on_dissector_bug)
ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7629
, __func__, "Unregistered hf! index=%d", (unsigned)field_id);
((void) (((unsigned)field_id > 0 && (unsigned)(unsigned
)field_id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 7629,
"(unsigned)field_id > 0 && (unsigned)(unsigned)field_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[(unsigned
)field_id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 7629,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7630
7631 /* do we need to rewind ? */
7632 if (!hfinfo)
7633 return NULL((void*)0);
7634
7635 if (occurrence < 0) {
7636 /* Search other direction */
7637 while (hfinfo->same_name_prev_id != -1) {
7638 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, hfinfo)if((hfinfo->same_name_prev_id == 0 || (unsigned)hfinfo->
same_name_prev_id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7638
, __func__, "Unregistered hf! index=%d", hfinfo->same_name_prev_id
); ((void) ((hfinfo->same_name_prev_id > 0 && (
unsigned)hfinfo->same_name_prev_id < gpa_hfinfo.len) ? (
void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 7638, "hfinfo->same_name_prev_id > 0 && (unsigned)hfinfo->same_name_prev_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
same_name_prev_id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 7638,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7639 }
7640 }
7641
7642 prev_len = 0; /* Reset handled occurrences */
7643
7644 while (hfinfo) {
7645 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7646
7647 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7648 if (occurrence < 0) {
7649 hfinfo = hfinfo->same_name_next;
7650 } else {
7651 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7652 }
7653 continue;
7654 }
7655
7656 /* Are there enough occurrences of the field? */
7657 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7658 if (occurrence < 0) {
7659 hfinfo = hfinfo->same_name_next;
7660 } else {
7661 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7662 }
7663 prev_len += len;
7664 continue;
7665 }
7666
7667 /* Calculate single index or set outer boundaries */
7668 if (occurrence < 0) {
7669 i = occurrence + len + prev_len;
7670 last = i;
7671 } else if (occurrence > 0) {
7672 i = occurrence - 1 - prev_len;
7673 last = i;
7674 } else {
7675 i = 0;
7676 last = len - 1;
7677 }
7678
7679 prev_len += len; /* Count handled occurrences */
7680
7681 while (i <= last) {
7682 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7683
7684 filter = proto_construct_match_selected_string(finfo, edt);
7685 if (filter) {
7686 /* Only add the same expression once (especially for FT_PROTOCOL).
7687 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7688 */
7689 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7690 g_ptr_array_add(filter_array, filter);
7691 }
7692 }
7693 i++;
7694 }
7695
7696 if (occurrence == 0) {
7697 /* Fetch next hfinfo with same name (abbrev) */
7698 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7699 } else {
7700 hfinfo = NULL((void*)0);
7701 }
7702 }
7703 }
7704
7705 g_ptr_array_add(filter_array, NULL((void*)0));
7706
7707 /* XXX: Should this be || or && ? */
7708 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7709
7710 g_ptr_array_free(filter_array, true1);
7711
7712 return output;
7713}
7714
7715/* Set text of proto_item after having already been created. */
7716void
7717proto_item_set_text(proto_item *pi, const char *format, ...)
7718{
7719 field_info *fi = NULL((void*)0);
7720 va_list ap;
7721
7722 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7723
7724 fi = PITEM_FINFO(pi)((pi)->finfo);
7725 if (fi == NULL((void*)0))
7726 return;
7727
7728 if (fi->rep) {
7729 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7730 fi->rep = NULL((void*)0);
7731 }
7732
7733 va_start(ap, format)__builtin_va_start(ap, format);
7734 proto_tree_set_representation(pi, format, ap);
7735 va_end(ap)__builtin_va_end(ap);
7736}
7737
7738/* Append to text of proto_item after having already been created. */
7739void
7740proto_item_append_text(proto_item *pi, const char *format, ...)
7741{
7742 field_info *fi = NULL((void*)0);
7743 size_t curlen;
7744 char *str;
7745 va_list ap;
7746
7747 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7748
7749 fi = PITEM_FINFO(pi)((pi)->finfo);
7750 if (fi == NULL((void*)0)) {
7751 return;
7752 }
7753
7754 if (!proto_item_is_hidden(pi)) {
7755 /*
7756 * If we don't already have a representation,
7757 * generate the default representation.
7758 */
7759 if (fi->rep == NULL((void*)0)) {
7760 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep)fi->rep = ((item_label_t*)wmem_alloc((((pi)->tree_data->
pinfo->pool)), sizeof(item_label_t))); fi->rep->value_pos
= 0; fi->rep->value_len = 0;
;
7761 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7762 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7763 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7764 (strncmp(format, ": ", 2) == 0)) {
7765 fi->rep->value_pos += 2;
7766 }
7767 }
7768 if (fi->rep) {
7769 curlen = strlen(fi->rep->representation);
7770 /* curlen doesn't include the \0 byte.
7771 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7772 * the representation has already been truncated (of an up
7773 * to 4 byte UTF-8 character) or is just at the maximum length
7774 * unless we search for " [truncated]" (which may not be
7775 * at the start.)
7776 * It's safer to do nothing.
7777 */
7778 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7779 va_start(ap, format)__builtin_va_start(ap, format);
7780 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7781 va_end(ap)__builtin_va_end(ap);
7782 WS_UTF_8_CHECK(str, -1)do { const char *__uni_endptr; if (1 && (str) != ((void
*)0) && !g_utf8_validate(str, -1, &__uni_endptr))
{ do { if (1) { ws_log_utf8_full("UTF-8", LOG_LEVEL_DEBUG, "epan/proto.c"
, 7782, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7783 /* Keep fi->rep->value_pos */
7784 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, str, 0);
7785 if (curlen >= ITEM_LABEL_LENGTH240) {
7786 /* Uh oh, we don't have enough room. Tell the user
7787 * that the field is truncated.
7788 */
7789 LABEL_MARK_TRUNCATED_START(fi->rep->representation, &fi->rep->value_pos)label_mark_truncated(fi->rep->representation, 0, &fi
->rep->value_pos)
;
7790 }
7791 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7792 }
7793 }
7794 }
7795}
7796
7797/* Prepend to text of proto_item after having already been created. */
7798void
7799proto_item_prepend_text(proto_item *pi, const char *format, ...)
7800{
7801 field_info *fi = NULL((void*)0);
7802 size_t pos;
7803 char representation[ITEM_LABEL_LENGTH240];
7804 char *str;
7805 va_list ap;
7806
7807 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7808
7809 fi = PITEM_FINFO(pi)((pi)->finfo);
7810 if (fi == NULL((void*)0)) {
7811 return;
7812 }
7813
7814 if (!proto_item_is_hidden(pi)) {
7815 /*
7816 * If we don't already have a representation,
7817 * generate the default representation.
7818 */
7819 if (fi->rep == NULL((void*)0)) {
7820 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep)fi->rep = ((item_label_t*)wmem_alloc((((pi)->tree_data->
pinfo->pool)), sizeof(item_label_t))); fi->rep->value_pos
= 0; fi->rep->value_len = 0;
;
7821 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7822 } else
7823 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7824
7825 va_start(ap, format)__builtin_va_start(ap, format);
7826 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7827 va_end(ap)__builtin_va_end(ap);
7828 WS_UTF_8_CHECK(str, -1)do { const char *__uni_endptr; if (1 && (str) != ((void
*)0) && !g_utf8_validate(str, -1, &__uni_endptr))
{ do { if (1) { ws_log_utf8_full("UTF-8", LOG_LEVEL_DEBUG, "epan/proto.c"
, 7828, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7829 fi->rep->value_pos += strlen(str);
7830 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7831 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, representation, 0);
7832 /* XXX: As above, if the old representation is close to the label
7833 * length, it might already be marked as truncated. */
7834 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7835 /* Uh oh, we don't have enough room. Tell the user
7836 * that the field is truncated.
7837 */
7838 LABEL_MARK_TRUNCATED_START(fi->rep->representation, &fi->rep->value_pos)label_mark_truncated(fi->rep->representation, 0, &fi
->rep->value_pos)
;
7839 }
7840 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7841 }
7842}
7843
7844static void
7845finfo_set_len(field_info *fi, const int length)
7846{
7847 int length_remaining;
7848
7849 DISSECTOR_ASSERT_HINT(length >= 0, fi->hfinfo->abbrev)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 7849,
"length >= 0", fi->hfinfo->abbrev))))
;
7850 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7851 if (length > length_remaining)
7852 fi->length = length_remaining;
7853 else
7854 fi->length = length;
7855
7856 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7857 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7858 fvalue_set_protocol_length(fi->value, fi->length);
7859 }
7860
7861 /*
7862 * You cannot just make the "len" field of a GByteArray
7863 * larger, if there's no data to back that length;
7864 * you can only make it smaller.
7865 */
7866 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7867 GBytes *bytes = fvalue_get_bytes(fi->value);
7868 size_t size;
7869 const void *data = g_bytes_get_data(bytes, &size);
7870 if ((size_t)fi->length <= size) {
7871 fvalue_set_bytes_data(fi->value, data, fi->length);
7872 }
7873 g_bytes_unref(bytes);
7874 }
7875}
7876
7877void
7878proto_item_set_len(proto_item *pi, const int length)
7879{
7880 field_info *fi;
7881
7882 if (pi == NULL((void*)0))
7883 return;
7884
7885 fi = PITEM_FINFO(pi)((pi)->finfo);
7886 if (fi == NULL((void*)0))
7887 return;
7888
7889 finfo_set_len(fi, length);
7890}
7891
7892/*
7893 * Sets the length of the item based on its start and on the specified
7894 * offset, which is the offset past the end of the item; as the start
7895 * in the item is relative to the beginning of the data source tvbuff,
7896 * we need to pass in a tvbuff - the end offset is relative to the beginning
7897 * of that tvbuff.
7898 */
7899void
7900proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7901{
7902 field_info *fi;
7903 int length;
7904
7905 if (pi == NULL((void*)0))
7906 return;
7907
7908 fi = PITEM_FINFO(pi)((pi)->finfo);
7909 if (fi == NULL((void*)0))
7910 return;
7911
7912 end += tvb_raw_offset(tvb);
7913 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7913, "end >= fi->start"
))))
;
7914 length = end - fi->start;
7915
7916 finfo_set_len(fi, length);
7917}
7918
7919int
7920proto_item_get_len(const proto_item *pi)
7921{
7922 field_info *fi;
7923
7924 if (!pi)
7925 return -1;
7926 fi = PITEM_FINFO(pi)((pi)->finfo);
7927 return fi ? fi->length : -1;
7928}
7929
7930void
7931proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
7932 if (!ti) {
7933 return;
7934 }
7935 FI_SET_FLAG(PNODE_FINFO(ti), FI_BITS_OFFSET(bits_offset))do { if (((ti)->finfo)) (((ti)->finfo))->flags = (((
ti)->finfo))->flags | ((((bits_offset) & 63) <<
5)); } while(0)
;
7936 FI_SET_FLAG(PNODE_FINFO(ti), FI_BITS_SIZE(bits_len))do { if (((ti)->finfo)) (((ti)->finfo))->flags = (((
ti)->finfo))->flags | ((((bits_len) & 63) << 12
)); } while(0)
;
7937}
7938
7939char *
7940proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
7941{
7942 field_info *fi;
7943
7944 if (!pi)
7945 return wmem_strdup(scope, "");
7946 fi = PITEM_FINFO(pi)((pi)->finfo);
7947 if (!fi)
7948 return wmem_strdup(scope, "");
7949 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7949, "fi->hfinfo != ((void*)0)"
))))
;
7950 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
7951}
7952
7953proto_tree *
7954proto_tree_create_root(packet_info *pinfo)
7955{
7956 proto_node *pnode;
7957
7958 /* Initialize the proto_node */
7959 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
7960 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
7961 pnode->parent = NULL((void*)0);
7962 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
7963 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
7964
7965 /* Make sure we can access pinfo everywhere */
7966 pnode->tree_data->pinfo = pinfo;
7967
7968 /* Don't initialize the tree_data_t. Wait until we know we need it */
7969 pnode->tree_data->interesting_hfids = NULL((void*)0);
7970
7971 /* Set the default to false so it's easier to
7972 * find errors; if we expect to see the protocol tree
7973 * but for some reason the default 'visible' is not
7974 * changed, then we'll find out very quickly. */
7975 pnode->tree_data->visible = false0;
7976
7977 /* Make sure that we fake protocols (if possible) */
7978 pnode->tree_data->fake_protocols = true1;
7979
7980 /* Keep track of the number of children */
7981 pnode->tree_data->count = 0;
7982
7983 /* Initialize our loop checks */
7984 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
7985 pnode->tree_data->max_start = 0;
7986 pnode->tree_data->start_idle_count = 0;
7987
7988 return (proto_tree *)pnode;
7989}
7990
7991
7992/* "prime" a proto_tree with a single hfid that a dfilter
7993 * is interested in. */
7994void
7995proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
7996{
7997 header_field_info *hfinfo;
7998
7999 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo)if((hfid == 0 || (unsigned)hfid > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 7999, __func__, "Unregistered hf! index=%d"
, hfid); ((void) ((hfid > 0 && (unsigned)hfid <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 7999, "hfid > 0 && (unsigned)hfid < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfid] != (
(void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 7999, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8000 /* this field is referenced by a filter so increase the refcount.
8001 also increase the refcount for the parent, i.e the protocol.
8002 Don't increase the refcount if we're already printing the
8003 type, as that is a superset of direct reference.
8004 */
8005 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8006 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8007 }
8008 /* only increase the refcount if there is a parent.
8009 if this is a protocol and not a field then parent will be -1
8010 and there is no parent to add any refcounting for.
8011 */
8012 if (hfinfo->parent != -1) {
8013 header_field_info *parent_hfinfo;
8014 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo)if((hfinfo->parent == 0 || (unsigned)hfinfo->parent >
gpa_hfinfo.len) && wireshark_abort_on_dissector_bug)
ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 8014
, __func__, "Unregistered hf! index=%d", hfinfo->parent); (
(void) ((hfinfo->parent > 0 && (unsigned)hfinfo
->parent < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 8014,
"hfinfo->parent > 0 && (unsigned)hfinfo->parent < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
parent] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 8014,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8015
8016 /* Mark parent as indirectly referenced unless it is already directly
8017 * referenced, i.e. the user has specified the parent in a filter.
8018 */
8019 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8020 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8021 }
8022}
8023
8024/* "prime" a proto_tree with a single hfid that a dfilter
8025 * is interested in. */
8026void
8027proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8028{
8029 header_field_info *hfinfo;
8030
8031 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo)if((hfid == 0 || (unsigned)hfid > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 8031, __func__, "Unregistered hf! index=%d"
, hfid); ((void) ((hfid > 0 && (unsigned)hfid <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8031, "hfid > 0 && (unsigned)hfid < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfid] != (
(void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8031, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8032 /* this field is referenced by an (output) filter so increase the refcount.
8033 also increase the refcount for the parent, i.e the protocol.
8034 */
8035 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8036 /* only increase the refcount if there is a parent.
8037 if this is a protocol and not a field then parent will be -1
8038 and there is no parent to add any refcounting for.
8039 */
8040 if (hfinfo->parent != -1) {
8041 header_field_info *parent_hfinfo;
8042 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo)if((hfinfo->parent == 0 || (unsigned)hfinfo->parent >
gpa_hfinfo.len) && wireshark_abort_on_dissector_bug)
ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 8042
, __func__, "Unregistered hf! index=%d", hfinfo->parent); (
(void) ((hfinfo->parent > 0 && (unsigned)hfinfo
->parent < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 8042,
"hfinfo->parent > 0 && (unsigned)hfinfo->parent < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
parent] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 8042,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8043
8044 /* Mark parent as indirectly referenced unless it is already directly
8045 * referenced, i.e. the user has specified the parent in a filter.
8046 */
8047 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8048 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8049 }
8050}
8051
8052proto_tree *
8053proto_item_add_subtree(proto_item *pi, const int idx) {
8054 field_info *fi;
8055
8056 if (!pi)
8057 return NULL((void*)0);
8058
8059 DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types)((void) ((idx >= 0 && idx < num_tree_types) ? (
void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 8059, "idx >= 0 && idx < num_tree_types"
))))
;
8060
8061 fi = PITEM_FINFO(pi)((pi)->finfo);
8062 if (!fi)
8063 return (proto_tree *)pi;
8064
8065 fi->tree_type = idx;
8066
8067 return (proto_tree *)pi;
8068}
8069
8070proto_tree *
8071proto_item_get_subtree(proto_item *pi) {
8072 field_info *fi;
8073
8074 if (!pi)
8075 return NULL((void*)0);
8076 fi = PITEM_FINFO(pi)((pi)->finfo);
8077 if ( (fi) && (fi->tree_type == -1) )
8078 return NULL((void*)0);
8079 return (proto_tree *)pi;
8080}
8081
8082proto_item *
8083proto_item_get_parent(const proto_item *ti) {
8084 if (!ti)
8085 return NULL((void*)0);
8086 return ti->parent;
8087}
8088
8089proto_item *
8090proto_item_get_parent_nth(proto_item *ti, int gen) {
8091 if (!ti)
8092 return NULL((void*)0);
8093 while (gen--) {
8094 ti = ti->parent;
8095 if (!ti)
8096 return NULL((void*)0);
8097 }
8098 return ti;
8099}
8100
8101
8102proto_item *
8103proto_tree_get_parent(proto_tree *tree) {
8104 if (!tree)
8105 return NULL((void*)0);
8106 return (proto_item *)tree;
8107}
8108
8109proto_tree *
8110proto_tree_get_parent_tree(proto_tree *tree) {
8111 if (!tree)
8112 return NULL((void*)0);
8113
8114 /* we're the root tree, there's no parent
8115 return ourselves so the caller has at least a tree to attach to */
8116 if (!tree->parent)
8117 return tree;
8118
8119 return (proto_tree *)tree->parent;
8120}
8121
8122proto_tree *
8123proto_tree_get_root(proto_tree *tree) {
8124 if (!tree)
8125 return NULL((void*)0);
8126 while (tree->parent) {
8127 tree = tree->parent;
8128 }
8129 return tree;
8130}
8131
8132void
8133proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8134 proto_item *item_to_move)
8135{
8136 /* This function doesn't generate any values. It only reorganizes the prococol tree
8137 * so we can bail out immediately if it isn't visible. */
8138 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8139 return;
8140
8141 DISSECTOR_ASSERT(item_to_move->parent == tree)((void) ((item_to_move->parent == tree) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8141, "item_to_move->parent == tree"
))))
;
8142 DISSECTOR_ASSERT(fixed_item->parent == tree)((void) ((fixed_item->parent == tree) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8142, "fixed_item->parent == tree"
))))
;
8143
8144 /*** cut item_to_move out ***/
8145
8146 /* is item_to_move the first? */
8147 if (tree->first_child == item_to_move) {
8148 /* simply change first child to next */
8149 tree->first_child = item_to_move->next;
8150
8151 DISSECTOR_ASSERT(tree->last_child != item_to_move)((void) ((tree->last_child != item_to_move) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8151, "tree->last_child != item_to_move"
))))
;
8152 } else {
8153 proto_item *curr_item;
8154 /* find previous and change it's next */
8155 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8156 if (curr_item->next == item_to_move) {
8157 break;
8158 }
8159 }
8160
8161 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8161, "curr_item"
))))
;
8162
8163 curr_item->next = item_to_move->next;
8164
8165 /* fix last_child if required */
8166 if (tree->last_child == item_to_move) {
8167 tree->last_child = curr_item;
8168 }
8169 }
8170
8171 /*** insert to_move after fixed ***/
8172 item_to_move->next = fixed_item->next;
8173 fixed_item->next = item_to_move;
8174 if (tree->last_child == fixed_item) {
8175 tree->last_child = item_to_move;
8176 }
8177}
8178
8179void
8180proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8181 const int length)
8182{
8183 field_info *fi;
8184
8185 if (tree == NULL((void*)0))
8186 return;
8187
8188 fi = PTREE_FINFO(tree)((tree)->finfo);
8189 if (fi == NULL((void*)0))
8190 return;
8191
8192 start += tvb_raw_offset(tvb);
8193 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8193, "start >= 0"
))))
;
8194 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8194, "length >= 0"
))))
;
8195
8196 fi->appendix_start = start;
8197 fi->appendix_length = length;
8198}
8199
8200static void
8201check_protocol_filter_name_or_fail(const char *filter_name)
8202{
8203 /* Require at least two characters. */
8204 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8205 REPORT_DISSECTOR_BUG("Protocol filter name \"%s\" cannot have length less than two.", filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" cannot have length less than two."
, filter_name)
;
8206 }
8207
8208 if (proto_check_field_name(filter_name) != '\0') {
8209 REPORT_DISSECTOR_BUG("Protocol filter name \"%s\" has one or more invalid characters."proto_report_dissector_bug("Protocol filter name \"%s\" has one or more invalid characters."
" Allowed are letters, digits, '-', '_' and non-repeating '.'."
" This might be caused by an inappropriate plugin or a development error."
, filter_name)
8210 " Allowed are letters, digits, '-', '_' and non-repeating '.'."proto_report_dissector_bug("Protocol filter name \"%s\" has one or more invalid characters."
" Allowed are letters, digits, '-', '_' and non-repeating '.'."
" This might be caused by an inappropriate plugin or a development error."
, filter_name)
8211 " This might be caused by an inappropriate plugin or a development error.", filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" has one or more invalid characters."
" Allowed are letters, digits, '-', '_' and non-repeating '.'."
" This might be caused by an inappropriate plugin or a development error."
, filter_name)
;
8212 }
8213
8214 /* Check that it doesn't match some very common numeric forms. */
8215 if (filter_name[0] == '0' &&
8216 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8217 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8218 REPORT_DISSECTOR_BUG("Protocol filter name \"%s\" cannot start with \"%c%c\".",proto_report_dissector_bug("Protocol filter name \"%s\" cannot start with \"%c%c\"."
, filter_name, filter_name[0], filter_name[1])
8219 filter_name, filter_name[0], filter_name[1])proto_report_dissector_bug("Protocol filter name \"%s\" cannot start with \"%c%c\"."
, filter_name, filter_name[0], filter_name[1])
;
8220 }
8221
8222 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8223
8224 /* Check that it contains at least one letter. */
8225 bool_Bool have_letter = false0;
8226 for (const char *s = filter_name; *s != '\0'; s++) {
8227 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8228 have_letter = true1;
8229 break;
8230 }
8231 }
8232 if (!have_letter) {
8233 REPORT_DISSECTOR_BUG("Protocol filter name \"%s\" must contain at least one letter a-z.",proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
8234 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8235 }
8236
8237 /* Check for reserved keywords. */
8238 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8239 REPORT_DISSECTOR_BUG("Protocol filter name \"%s\" is invalid because it is a reserved keyword."proto_report_dissector_bug("Protocol filter name \"%s\" is invalid because it is a reserved keyword."
" This might be caused by an inappropriate plugin or a development error."
, filter_name)
8240 " This might be caused by an inappropriate plugin or a development error.", filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" is invalid because it is a reserved keyword."
" This might be caused by an inappropriate plugin or a development error."
, filter_name)
;
8241 }
8242}
8243
8244int
8245proto_register_protocol(const char *name, const char *short_name,
8246 const char *filter_name)
8247{
8248 protocol_t *protocol;
8249 header_field_info *hfinfo;
8250
8251 /*
8252 * Make sure there's not already a protocol with any of those
8253 * names. Crash if there is, as that's an error in the code
8254 * or an inappropriate plugin.
8255 * This situation has to be fixed to not register more than one
8256 * protocol with the same name.
8257 */
8258
8259 if (g_hash_table_lookup(proto_names, name)) {
8260 /* ws_error will terminate the program */
8261 REPORT_DISSECTOR_BUG("Duplicate protocol name \"%s\"!"proto_report_dissector_bug("Duplicate protocol name \"%s\"!" " This might be caused by an inappropriate plugin or a development error."
, name)
8262 " This might be caused by an inappropriate plugin or a development error.", name)proto_report_dissector_bug("Duplicate protocol name \"%s\"!" " This might be caused by an inappropriate plugin or a development error."
, name)
;
8263 }
8264
8265 if (g_hash_table_lookup(proto_short_names, short_name)) {
8266 REPORT_DISSECTOR_BUG("Duplicate protocol short_name \"%s\"!"proto_report_dissector_bug("Duplicate protocol short_name \"%s\"!"
" This might be caused by an inappropriate plugin or a development error."
, short_name)
8267 " This might be caused by an inappropriate plugin or a development error.", short_name)proto_report_dissector_bug("Duplicate protocol short_name \"%s\"!"
" This might be caused by an inappropriate plugin or a development error."
, short_name)
;
8268 }
8269
8270 check_protocol_filter_name_or_fail(filter_name);
8271
8272 if (g_hash_table_lookup(proto_filter_names, filter_name)) {
8273 REPORT_DISSECTOR_BUG("Duplicate protocol filter_name \"%s\"!"proto_report_dissector_bug("Duplicate protocol filter_name \"%s\"!"
" This might be caused by an inappropriate plugin or a development error."
, filter_name)
8274 " This might be caused by an inappropriate plugin or a development error.", filter_name)proto_report_dissector_bug("Duplicate protocol filter_name \"%s\"!"
" This might be caused by an inappropriate plugin or a development error."
, filter_name)
;
8275 }
8276
8277 /*
8278 * Add this protocol to the list of known protocols;
8279 * the list is sorted by protocol short name.
8280 */
8281 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8282 protocol->name = name;
8283 protocol->short_name = short_name;
8284 protocol->filter_name = filter_name;
8285 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8286 protocol->is_enabled = true1; /* protocol is enabled by default */
8287 protocol->enabled_by_default = true1; /* see previous comment */
8288 protocol->can_toggle = true1;
8289 protocol->parent_proto_id = -1;
8290 protocol->heur_list = NULL((void*)0);
8291
8292 /* List will be sorted later by name, when all protocols completed registering */
8293 protocols = g_list_prepend(protocols, protocol);
8294 g_hash_table_insert(proto_names, (void *)name, protocol);
8295 g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol);
8296 g_hash_table_insert(proto_short_names, (void *)short_name, protocol);
8297
8298 /* Here we allocate a new header_field_info struct */
8299 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8300 hfinfo->name = name;
8301 hfinfo->abbrev = filter_name;
8302 hfinfo->type = FT_PROTOCOL;
8303 hfinfo->display = BASE_NONE;
8304 hfinfo->strings = protocol;
8305 hfinfo->bitmask = 0;
8306 hfinfo->ref_type = HF_REF_TYPE_NONE;
8307 hfinfo->blurb = NULL((void*)0);
8308 hfinfo->parent = -1; /* This field differentiates protos and fields */
8309
8310 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8311 return protocol->proto_id;
8312}
8313
8314int
8315proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8316{
8317 protocol_t *protocol;
8318 header_field_info *hfinfo;
8319
8320 /*
8321 * Helper protocols don't need the strict rules as a "regular" protocol
8322 * Just register it in a list and make a hf_ field from it
8323 */
8324 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8325 REPORT_DISSECTOR_BUG("Pino \"%s\" must be of type FT_PROTOCOL or FT_BYTES.", name)proto_report_dissector_bug("Pino \"%s\" must be of type FT_PROTOCOL or FT_BYTES."
, name)
;
8326 }
8327
8328 if (parent_proto <= 0) {
8329 REPORT_DISSECTOR_BUG("Must have a valid parent protocol for helper protocol \"%s\"!"proto_report_dissector_bug("Must have a valid parent protocol for helper protocol \"%s\"!"
" This might be caused by an inappropriate plugin or a development error."
, name)
8330 " This might be caused by an inappropriate plugin or a development error.", name)proto_report_dissector_bug("Must have a valid parent protocol for helper protocol \"%s\"!"
" This might be caused by an inappropriate plugin or a development error."
, name)
;
8331 }
8332
8333 check_protocol_filter_name_or_fail(filter_name);
8334
8335 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8336 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8337 protocol->name = name;
8338 protocol->short_name = short_name;
8339 protocol->filter_name = filter_name;
8340 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8341
8342 /* Enabling and toggling is really determined by parent protocol,
8343 but provide default values here */
8344 protocol->is_enabled = true1;
8345 protocol->enabled_by_default = true1;
8346 protocol->can_toggle = true1;
8347
8348 protocol->parent_proto_id = parent_proto;
8349 protocol->heur_list = NULL((void*)0);
8350
8351 /* List will be sorted later by name, when all protocols completed registering */
8352 protocols = g_list_prepend(protocols, protocol);
8353
8354 /* Here we allocate a new header_field_info struct */
8355 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8356 hfinfo->name = name;
8357 hfinfo->abbrev = filter_name;
8358 hfinfo->type = field_type;
8359 hfinfo->display = BASE_NONE;
8360 if (field_type == FT_BYTES) {
8361 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8362 }
8363 hfinfo->strings = protocol;
8364 hfinfo->bitmask = 0;
8365 hfinfo->ref_type = HF_REF_TYPE_NONE;
8366 hfinfo->blurb = NULL((void*)0);
8367 hfinfo->parent = -1; /* This field differentiates protos and fields */
8368
8369 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8370 return protocol->proto_id;
8371}
8372
8373bool_Bool
8374proto_deregister_protocol(const char *short_name)
8375{
8376 protocol_t *protocol;
8377 header_field_info *hfinfo;
8378 int proto_id;
8379 unsigned i;
8380
8381 proto_id = proto_get_id_by_short_name(short_name);
8382 protocol = find_protocol_by_id(proto_id);
8383 if (protocol == NULL((void*)0))
8384 return false0;
8385
8386 g_hash_table_remove(proto_names, protocol->name);
8387 g_hash_table_remove(proto_short_names, (void *)short_name);
8388 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8389
8390 if (protocol->fields) {
8391 for (i = 0; i < protocol->fields->len; i++) {
8392 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8393 hfinfo_remove_from_gpa_name_map(hfinfo);
8394 expert_deregister_expertinfo(hfinfo->abbrev);
8395 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8396 }
8397 g_ptr_array_free(protocol->fields, true1);
8398 protocol->fields = NULL((void*)0);
8399 }
8400
8401 g_list_free(protocol->heur_list);
8402
8403 /* Remove this protocol from the list of known protocols */
8404 protocols = g_list_remove(protocols, protocol);
8405
8406 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8407 g_hash_table_steal(gpa_name_map, protocol->filter_name);
8408
8409 g_free(last_field_name);
8410 last_field_name = NULL((void*)0);
8411
8412 return true1;
8413}
8414
8415void
8416proto_register_alias(const int proto_id, const char *alias_name)
8417{
8418 protocol_t *protocol;
8419
8420 protocol = find_protocol_by_id(proto_id);
8421 if (alias_name && protocol) {
8422 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8423 }
8424}
8425
8426/*
8427 * Routines to use to iterate over the protocols.
8428 * The argument passed to the iterator routines is an opaque cookie to
8429 * their callers; it's the GList pointer for the current element in
8430 * the list.
8431 * The ID of the protocol is returned, or -1 if there is no protocol.
8432 */
8433int
8434proto_get_first_protocol(void **cookie)
8435{
8436 protocol_t *protocol;
8437
8438 if (protocols == NULL((void*)0))
8439 return -1;
8440 *cookie = protocols;
8441 protocol = (protocol_t *)protocols->data;
8442 return protocol->proto_id;
8443}
8444
8445int
8446proto_get_data_protocol(void *cookie)
8447{
8448 GList *list_item = (GList *)cookie;
8449
8450 protocol_t *protocol = (protocol_t *)list_item->data;
8451 return protocol->proto_id;
8452}
8453
8454int
8455proto_get_next_protocol(void **cookie)
8456{
8457 GList *list_item = (GList *)*cookie;
8458 protocol_t *protocol;
8459
8460 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8461 if (list_item == NULL((void*)0))
8462 return -1;
8463 *cookie = list_item;
8464 protocol = (protocol_t *)list_item->data;
8465 return protocol->proto_id;
8466}
8467
8468header_field_info *
8469proto_get_first_protocol_field(const int proto_id, void **cookie)
8470{
8471 protocol_t *protocol = find_protocol_by_id(proto_id);
8472
8473 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8474 return NULL((void*)0);
8475
8476 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8477 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8478}
8479
8480header_field_info *
8481proto_get_next_protocol_field(const int proto_id, void **cookie)
8482{
8483 protocol_t *protocol = find_protocol_by_id(proto_id);
8484 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8485
8486 i++;
8487
8488 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8489 return NULL((void*)0);
8490
8491 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8492 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8493}
8494
8495protocol_t *
8496find_protocol_by_id(const int proto_id)
8497{
8498 header_field_info *hfinfo;
8499
8500 if (proto_id <= 0)
8501 return NULL((void*)0);
8502
8503 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo)if((proto_id == 0 || (unsigned)proto_id > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 8503, __func__, "Unregistered hf! index=%d"
, proto_id); ((void) ((proto_id > 0 && (unsigned)proto_id
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 8503,
"proto_id > 0 && (unsigned)proto_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[proto_id]
!= ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8503, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8504 if (hfinfo->type != FT_PROTOCOL) {
8505 DISSECTOR_ASSERT(hfinfo->display & BASE_PROTOCOL_INFO)((void) ((hfinfo->display & 0x00004000) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8505, "hfinfo->display & 0x00004000"
))))
;
8506 }
8507 return (protocol_t *)hfinfo->strings;
8508}
8509
8510int
8511proto_get_id(const protocol_t *protocol)
8512{
8513 return protocol->proto_id;
8514}
8515
8516bool_Bool
8517proto_name_already_registered(const char *name)
8518{
8519 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8519, "name", "No name present"))))
;
8520
8521 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8522 return true1;
8523 return false0;
8524}
8525
8526int
8527proto_get_id_by_filter_name(const char *filter_name)
8528{
8529 const protocol_t *protocol = NULL((void*)0);
8530
8531 DISSECTOR_ASSERT_HINT(filter_name, "No filter name present")((void) ((filter_name) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 8531,
"filter_name", "No filter name present"))))
;
8532
8533 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8534
8535 if (protocol == NULL((void*)0))
8536 return -1;
8537 return protocol->proto_id;
8538}
8539
8540int
8541proto_get_id_by_short_name(const char *short_name)
8542{
8543 const protocol_t *protocol = NULL((void*)0);
8544
8545 DISSECTOR_ASSERT_HINT(short_name, "No short name present")((void) ((short_name) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 8545,
"short_name", "No short name present"))))
;
8546
8547 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8548
8549 if (protocol == NULL((void*)0))
8550 return -1;
8551 return protocol->proto_id;
8552}
8553
8554const char *
8555proto_get_protocol_name(const int proto_id)
8556{
8557 protocol_t *protocol;
8558
8559 protocol = find_protocol_by_id(proto_id);
8560
8561 if (protocol == NULL((void*)0))
8562 return NULL((void*)0);
8563 return protocol->name;
8564}
8565
8566const char *
8567proto_get_protocol_short_name(const protocol_t *protocol)
8568{
8569 if (protocol == NULL((void*)0))
8570 return "(none)";
8571 return protocol->short_name;
8572}
8573
8574const char *
8575proto_get_protocol_long_name(const protocol_t *protocol)
8576{
8577 if (protocol == NULL((void*)0))
8578 return "(none)";
8579 return protocol->name;
8580}
8581
8582const char *
8583proto_get_protocol_filter_name(const int proto_id)
8584{
8585 protocol_t *protocol;
8586
8587 protocol = find_protocol_by_id(proto_id);
8588 if (protocol == NULL((void*)0))
8589 return "(none)";
8590 return protocol->filter_name;
8591}
8592
8593void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8594{
8595 heur_dtbl_entry_t* heuristic_dissector;
8596
8597 if (protocol == NULL((void*)0))
8598 return;
8599
8600 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8601 if (heuristic_dissector != NULL((void*)0))
8602 {
8603 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8604 }
8605}
8606
8607void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8608{
8609 if (protocol == NULL((void*)0))
8610 return;
8611
8612 g_list_foreach(protocol->heur_list, func, user_data);
8613}
8614
8615void
8616proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8617 bool_Bool *is_tcp, bool_Bool *is_udp,
8618 bool_Bool *is_sctp, bool_Bool *is_tls,
8619 bool_Bool *is_rtp,
8620 bool_Bool *is_lte_rlc)
8621{
8622 wmem_list_frame_t *protos = wmem_list_head(layers);
8623 int proto_id;
8624 const char *proto_name;
8625
8626 /* Walk the list of a available protocols in the packet and
8627 attempt to find "major" ones. */
8628 /* It might make more sense to assemble and return a bitfield. */
8629 while (protos != NULL((void*)0))
8630 {
8631 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8632 proto_name = proto_get_protocol_filter_name(proto_id);
8633
8634 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8635 (!strcmp(proto_name, "ipv6")))) {
8636 *is_ip = true1;
8637 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8638 *is_tcp = true1;
8639 } else if (is_udp && !strcmp(proto_name, "udp")) {
8640 *is_udp = true1;
8641 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8642 *is_sctp = true1;
8643 } else if (is_tls && !strcmp(proto_name, "tls")) {
8644 *is_tls = true1;
8645 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8646 *is_rtp = true1;
8647 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8648 *is_lte_rlc = true1;
8649 }
8650
8651 protos = wmem_list_frame_next(protos);
8652 }
8653}
8654
8655bool_Bool
8656proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8657{
8658 wmem_list_frame_t *protos = wmem_list_head(layers);
8659 int proto_id;
8660 const char *name;
8661
8662 /* Walk the list of a available protocols in the packet and
8663 attempt to find the specified protocol. */
8664 while (protos != NULL((void*)0))
8665 {
8666 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8667 name = proto_get_protocol_filter_name(proto_id);
8668
8669 if (!strcmp(name, proto_name))
8670 {
8671 return true1;
8672 }
8673
8674 protos = wmem_list_frame_next(protos);
8675 }
8676
8677 return false0;
8678}
8679
8680char *
8681proto_list_layers(const packet_info *pinfo)
8682{
8683 wmem_strbuf_t *buf;
8684 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8685
8686 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8687
8688 /* Walk the list of layers in the packet and
8689 return a string of all entries. */
8690 while (layers != NULL((void*)0))
8691 {
8692 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8693
8694 layers = wmem_list_frame_next(layers);
8695 if (layers != NULL((void*)0)) {
8696 wmem_strbuf_append_c(buf, ':');
8697 }
8698 }
8699
8700 return wmem_strbuf_finalize(buf);
8701}
8702
8703uint8_t
8704proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8705{
8706 int *proto_layer_num_ptr;
8707
8708 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8709 if (proto_layer_num_ptr == NULL((void*)0)) {
8710 return 0;
8711 }
8712
8713 return (uint8_t)*proto_layer_num_ptr;
8714}
8715
8716bool_Bool
8717proto_is_pino(const protocol_t *protocol)
8718{
8719 return (protocol->parent_proto_id != -1);
8720}
8721
8722bool_Bool
8723// NOLINTNEXTLINE(misc-no-recursion)
8724proto_is_protocol_enabled(const protocol_t *protocol)
8725{
8726 if (protocol == NULL((void*)0))
8727 return false0;
8728
8729 //parent protocol determines enable/disable for helper dissectors
8730 if (proto_is_pino(protocol))
8731 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8732
8733 return protocol->is_enabled;
8734}
8735
8736bool_Bool
8737// NOLINTNEXTLINE(misc-no-recursion)
8738proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8739{
8740 //parent protocol determines enable/disable for helper dissectors
8741 if (proto_is_pino(protocol))
8742 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8743
8744 return protocol->enabled_by_default;
8745}
8746
8747bool_Bool
8748// NOLINTNEXTLINE(misc-no-recursion)
8749proto_can_toggle_protocol(const int proto_id)
8750{
8751 protocol_t *protocol;
8752
8753 protocol = find_protocol_by_id(proto_id);
8754 //parent protocol determines toggling for helper dissectors
8755 if (proto_is_pino(protocol))
8756 return proto_can_toggle_protocol(protocol->parent_proto_id);
8757
8758 return protocol->can_toggle;
8759}
8760
8761void
8762proto_disable_by_default(const int proto_id)
8763{
8764 protocol_t *protocol;
8765
8766 protocol = find_protocol_by_id(proto_id);
8767 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8767, "protocol->can_toggle"
))))
;
8768 DISSECTOR_ASSERT(proto_is_pino(protocol) == false)((void) ((proto_is_pino(protocol) == 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8768, "proto_is_pino(protocol) == 0"
))))
;
8769 protocol->is_enabled = false0;
8770 protocol->enabled_by_default = false0;
8771}
8772
8773void
8774proto_set_decoding(const int proto_id, const bool_Bool enabled)
8775{
8776 protocol_t *protocol;
8777
8778 protocol = find_protocol_by_id(proto_id);
8779 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8779, "protocol->can_toggle"
))))
;
8780 DISSECTOR_ASSERT(proto_is_pino(protocol) == false)((void) ((proto_is_pino(protocol) == 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8780, "proto_is_pino(protocol) == 0"
))))
;
8781 protocol->is_enabled = enabled;
8782}
8783
8784void
8785proto_disable_all(void)
8786{
8787 /* This doesn't explicitly disable heuristic protocols,
8788 * but the heuristic doesn't get called if the parent
8789 * protocol isn't enabled.
8790 */
8791 protocol_t *protocol;
8792 GList *list_item = protocols;
8793
8794 if (protocols == NULL((void*)0))
8795 return;
8796
8797 while (list_item) {
8798 protocol = (protocol_t *)list_item->data;
8799 if (protocol->can_toggle) {
8800 protocol->is_enabled = false0;
8801 }
8802 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8803 }
8804}
8805
8806static void
8807heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8808{
8809 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8810
8811 heur->enabled = heur->enabled_by_default;
8812}
8813
8814void
8815proto_reenable_all(void)
8816{
8817 protocol_t *protocol;
8818 GList *list_item = protocols;
8819
8820 if (protocols == NULL((void*)0))
8821 return;
8822
8823 while (list_item) {
8824 protocol = (protocol_t *)list_item->data;
8825 if (protocol->can_toggle)
8826 protocol->is_enabled = protocol->enabled_by_default;
8827 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8828 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8829 }
8830}
8831
8832void
8833proto_set_cant_toggle(const int proto_id)
8834{
8835 protocol_t *protocol;
8836
8837 protocol = find_protocol_by_id(proto_id);
8838 protocol->can_toggle = false0;
8839}
8840
8841static int
8842proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8843{
8844 if (proto != NULL((void*)0)) {
8845 g_ptr_array_add(proto->fields, hfi);
8846 }
8847
8848 return proto_register_field_init(hfi, parent);
8849}
8850
8851/* for use with static arrays only, since we don't allocate our own copies
8852of the header_field_info struct contained within the hf_register_info struct */
8853void
8854proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8855{
8856 hf_register_info *ptr = hf;
8857 protocol_t *proto;
8858 int i;
8859
8860 proto = find_protocol_by_id(parent);
8861
8862 if (proto->fields == NULL((void*)0)) {
8863 proto->fields = g_ptr_array_sized_new(num_records);
8864 }
8865
8866 for (i = 0; i < num_records; i++, ptr++) {
8867 /*
8868 * Make sure we haven't registered this yet.
8869 * Most fields have variables associated with them
8870 * that are initialized to -1; some have array elements,
8871 * or possibly uninitialized variables, so we also allow
8872 * 0 (which is unlikely to be the field ID we get back
8873 * from "proto_register_field_init()").
8874 */
8875 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8876 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8877 "Duplicate field detected in call to proto_register_field_array: %s is already registered",proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8878 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8879 return;
8880 }
8881
8882 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8883 }
8884}
8885
8886/* deregister already registered fields */
8887void
8888proto_deregister_field (const int parent, int hf_id)
8889{
8890 header_field_info *hfi;
8891 protocol_t *proto;
8892 unsigned i;
8893
8894 g_free(last_field_name);
8895 last_field_name = NULL((void*)0);
8896
8897 if (hf_id == -1 || hf_id == 0)
8898 return;
8899
8900 proto = find_protocol_by_id (parent);
8901 if (!proto || proto->fields == NULL((void*)0)) {
8902 return;
8903 }
8904
8905 for (i = 0; i < proto->fields->len; i++) {
8906 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8907 if (hfi->id == hf_id) {
8908 /* Found the hf_id in this protocol */
8909 g_hash_table_steal(gpa_name_map, hfi->abbrev);
8910 g_ptr_array_remove_index_fast(proto->fields, i);
8911 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8912 return;
8913 }
8914 }
8915}
8916
8917/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
8918void
8919proto_deregister_all_fields_with_prefix(const int parent, const gchar *prefix)
8920{
8921 header_field_info *hfinfo;
8922 protocol_t *proto;
8923
8924 g_free(last_field_name);
8925 last_field_name = NULL((void*)0);
8926
8927 proto = find_protocol_by_id(parent);
8928 if (proto && proto->fields && proto->fields->len > 0) {
8929 guint i = proto->fields->len;
8930 do {
8931 i--;
8932
8933 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8934 if (g_str_has_prefix(hfinfo->abbrev, prefix)(__builtin_constant_p (prefix)? __extension__ ({ const char *
const __str = (hfinfo->abbrev); const char * const __prefix
= (prefix); gboolean __result = (0); if (__str == ((void*)0)
|| __prefix == ((void*)0)) __result = (g_str_has_prefix) (__str
, __prefix); else { const size_t __str_len = strlen (((__str)
+ !(__str))); const size_t __prefix_len = strlen (((__prefix
) + !(__prefix))); if (__str_len >= __prefix_len) __result
= memcmp (((__str) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len
) == 0; } __result; }) : (g_str_has_prefix) (hfinfo->abbrev
, prefix) )
) {
8935 hfinfo_remove_from_gpa_name_map(hfinfo);
8936 expert_deregister_expertinfo(hfinfo->abbrev);
8937 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8938 g_ptr_array_remove_index_fast(proto->fields, i);
8939 }
8940 } while (i > 0);
8941 }
8942}
8943
8944void
8945proto_add_deregistered_data (void *data)
8946{
8947 g_ptr_array_add(deregistered_data, data);
8948}
8949
8950void
8951proto_add_deregistered_slice (size_t block_size, void *mem_block)
8952{
8953 struct g_slice_data *slice_data = g_slice_new(struct g_slice_data)((struct g_slice_data*) g_slice_alloc (sizeof (struct g_slice_data
)))
;
8954
8955 slice_data->block_size = block_size;
8956 slice_data->mem_block = mem_block;
8957
8958 g_ptr_array_add(deregistered_slice, slice_data);
8959}
8960
8961void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
8962{
8963 if (field_strings == NULL((void*)0)) {
8964 return;
8965 }
8966
8967 switch (field_type) {
8968 case FT_FRAMENUM:
8969 /* This is just an integer represented as a pointer */
8970 break;
8971 case FT_PROTOCOL: {
8972 protocol_t *protocol = (protocol_t *)field_strings;
8973 g_free((char *)protocol->short_name);
8974 break;
8975 }
8976 case FT_BOOLEAN: {
8977 true_false_string *tf = (true_false_string *)field_strings;
8978 g_free((char *)tf->true_string);
8979 g_free((char *)tf->false_string);
8980 break;
8981 }
8982 case FT_UINT40:
8983 case FT_INT40:
8984 case FT_UINT48:
8985 case FT_INT48:
8986 case FT_UINT56:
8987 case FT_INT56:
8988 case FT_UINT64:
8989 case FT_INT64: {
8990 if (field_display & BASE_UNIT_STRING0x00001000) {
8991 unit_name_string *unit = (unit_name_string *)field_strings;
8992 g_free((char *)unit->singular);
8993 g_free((char *)unit->plural);
8994 } else if (field_display & BASE_RANGE_STRING0x00000100) {
8995 range_string *rs = (range_string *)field_strings;
8996 while (rs->strptr) {
8997 g_free((char *)rs->strptr);
8998 rs++;
8999 }
9000 } else if (field_display & BASE_EXT_STRING0x00000200) {
9001 val64_string_ext *vse = (val64_string_ext *)field_strings;
9002 val64_string *vs = (val64_string *)vse->_vs_p;
9003 while (vs->strptr) {
9004 g_free((char *)vs->strptr);
9005 vs++;
9006 }
9007 val64_string_ext_free(vse);
9008 field_strings = NULL((void*)0);
9009 } else if (field_display == BASE_CUSTOM) {
9010 /* this will be a pointer to a function, don't free that */
9011 field_strings = NULL((void*)0);
9012 } else {
9013 val64_string *vs64 = (val64_string *)field_strings;
9014 while (vs64->strptr) {
9015 g_free((char *)vs64->strptr);
9016 vs64++;
9017 }
9018 }
9019 break;
9020 }
9021 case FT_CHAR:
9022 case FT_UINT8:
9023 case FT_INT8:
9024 case FT_UINT16:
9025 case FT_INT16:
9026 case FT_UINT24:
9027 case FT_INT24:
9028 case FT_UINT32:
9029 case FT_INT32:
9030 case FT_FLOAT:
9031 case FT_DOUBLE: {
9032 if (field_display & BASE_UNIT_STRING0x00001000) {
9033 unit_name_string *unit = (unit_name_string *)field_strings;
9034 g_free((char *)unit->singular);
9035 g_free((char *)unit->plural);
9036 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9037 range_string *rs = (range_string *)field_strings;
9038 while (rs->strptr) {
9039 g_free((char *)rs->strptr);
9040 rs++;
9041 }
9042 } else if (field_display & BASE_EXT_STRING0x00000200) {
9043 value_string_ext *vse = (value_string_ext *)field_strings;
9044 value_string *vs = (value_string *)vse->_vs_p;
9045 while (vs->strptr) {
9046 g_free((char *)vs->strptr);
9047 vs++;
9048 }
9049 value_string_ext_free(vse);
9050 field_strings = NULL((void*)0);
9051 } else if (field_display == BASE_CUSTOM) {
9052 /* this will be a pointer to a function, don't free that */
9053 field_strings = NULL((void*)0);
9054 } else {
9055 value_string *vs = (value_string *)field_strings;
9056 while (vs->strptr) {
9057 g_free((char *)vs->strptr);
9058 vs++;
9059 }
9060 }
9061 break;
9062 default:
9063 break;
9064 }
9065 }
9066
9067 if (field_type != FT_FRAMENUM) {
9068 g_free((void *)field_strings);
9069 }
9070}
9071
9072static void
9073free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9074{
9075 header_field_info *hfi = (header_field_info *) data;
9076 int hf_id = hfi->id;
9077
9078 g_free((char *)hfi->name);
9079 g_free((char *)hfi->abbrev);
9080 g_free((char *)hfi->blurb);
9081
9082 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9083
9084 if (hfi->parent == -1)
9085 g_slice_free(header_field_info, hfi)do { if (1) g_slice_free1 (sizeof (header_field_info), (hfi))
; else (void) ((header_field_info*) 0 == (hfi)); } while (0)
;
9086
9087 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9088}
9089
9090static void
9091free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9092{
9093 g_free (data);
9094}
9095
9096static void
9097free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9098{
9099 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9100
9101 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9102 g_slice_free(struct g_slice_data, slice_data)do { if (1) g_slice_free1 (sizeof (struct g_slice_data), (slice_data
)); else (void) ((struct g_slice_data*) 0 == (slice_data)); }
while (0)
;
9103}
9104
9105/* free deregistered fields and data */
9106void
9107proto_free_deregistered_fields (void)
9108{
9109 expert_free_deregistered_expertinfos();
9110
9111 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9112 g_ptr_array_free(deregistered_fields, true1);
9113 deregistered_fields = g_ptr_array_new();
9114
9115 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9116 g_ptr_array_free(deregistered_data, true1);
9117 deregistered_data = g_ptr_array_new();
9118
9119 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9120 g_ptr_array_free(deregistered_slice, true1);
9121 deregistered_slice = g_ptr_array_new();
9122}
9123
9124static const value_string hf_display[] = {
9125 { BASE_NONE, "BASE_NONE" },
9126 { BASE_DEC, "BASE_DEC" },
9127 { BASE_HEX, "BASE_HEX" },
9128 { BASE_OCT, "BASE_OCT" },
9129 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9130 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9131 { BASE_CUSTOM, "BASE_CUSTOM" },
9132 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9133 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9134 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9135 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9136 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9137 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9138 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9139 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9140 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9141 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9142 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9143 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9144 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9145 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9146 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9147 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9148 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9149 { BASE_PT_UDP, "BASE_PT_UDP" },
9150 { BASE_PT_TCP, "BASE_PT_TCP" },
9151 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9152 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9153 { BASE_OUI, "BASE_OUI" },
9154 { 0, NULL((void*)0) } };
9155
9156const char* proto_field_display_to_string(int field_display)
9157{
9158 return val_to_str_const(field_display, hf_display, "Unknown");
9159}
9160
9161static inline port_type
9162display_to_port_type(field_display_e e)
9163{
9164 switch (e) {
9165 case BASE_PT_UDP:
9166 return PT_UDP;
9167 case BASE_PT_TCP:
9168 return PT_TCP;
9169 case BASE_PT_DCCP:
9170 return PT_DCCP;
9171 case BASE_PT_SCTP:
9172 return PT_SCTP;
9173 default:
9174 break;
9175 }
9176 return PT_NONE;
9177}
9178
9179/* temporary function containing assert part for easier profiling */
9180static void
9181tmp_fld_check_assert(header_field_info *hfinfo)
9182{
9183 char* tmp_str;
9184
9185 /* The field must have a name (with length > 0) */
9186 if (!hfinfo->name || !hfinfo->name[0]) {
9187 if (hfinfo->abbrev)
9188 /* Try to identify the field */
9189 REPORT_DISSECTOR_BUG("Field (abbrev='%s') does not have a name",proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
9190 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9191 else
9192 /* Hum, no luck */
9193 REPORT_DISSECTOR_BUG("Field does not have a name (nor an abbreviation)")proto_report_dissector_bug("Field does not have a name (nor an abbreviation)"
)
;
9194 }
9195
9196 /* fields with an empty string for an abbreviation aren't filterable */
9197 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9198 REPORT_DISSECTOR_BUG("Field '%s' does not have an abbreviation", hfinfo->name)proto_report_dissector_bug("Field '%s' does not have an abbreviation"
, hfinfo->name)
;
9199
9200 /* These types of fields are allowed to have value_strings,
9201 * true_false_strings or a protocol_t struct
9202 */
9203 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9204 switch (hfinfo->type) {
9205
9206 /*
9207 * These types are allowed to support display value_strings,
9208 * value64_strings, the extended versions of the previous
9209 * two, range strings, or unit strings.
9210 */
9211 case FT_CHAR:
9212 case FT_UINT8:
9213 case FT_UINT16:
9214 case FT_UINT24:
9215 case FT_UINT32:
9216 case FT_UINT40:
9217 case FT_UINT48:
9218 case FT_UINT56:
9219 case FT_UINT64:
9220 case FT_INT8:
9221 case FT_INT16:
9222 case FT_INT24:
9223 case FT_INT32:
9224 case FT_INT40:
9225 case FT_INT48:
9226 case FT_INT56:
9227 case FT_INT64:
9228 case FT_BOOLEAN:
9229 case FT_PROTOCOL:
9230 break;
9231
9232 /*
9233 * This is allowed to have a value of type
9234 * enum ft_framenum_type to indicate what relationship
9235 * the frame in question has to the frame in which
9236 * the field is put.
9237 */
9238 case FT_FRAMENUM:
9239 break;
9240
9241 /*
9242 * These types are allowed to support only unit strings.
9243 */
9244 case FT_FLOAT:
9245 case FT_DOUBLE:
9246 case FT_IEEE_11073_SFLOAT:
9247 case FT_IEEE_11073_FLOAT:
9248 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9249 REPORT_DISSECTOR_BUG("Field '%s' (%s) has a non-unit-strings 'strings' value but is of type %s"proto_report_dissector_bug("Field '%s' (%s) has a non-unit-strings 'strings' value but is of type %s"
" (which is only allowed to have unit strings)", hfinfo->
name, hfinfo->abbrev, ftype_name(hfinfo->type))
9250 " (which is only allowed to have unit strings)",proto_report_dissector_bug("Field '%s' (%s) has a non-unit-strings 'strings' value but is of type %s"
" (which is only allowed to have unit strings)", hfinfo->
name, hfinfo->abbrev, ftype_name(hfinfo->type))
9251 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) has a non-unit-strings 'strings' value but is of type %s"
" (which is only allowed to have unit strings)", hfinfo->
name, hfinfo->abbrev, ftype_name(hfinfo->type))
;
9252 }
9253 break;
9254
9255 /*
9256 * These types are allowed to support display
9257 * time_value_strings.
9258 */
9259 case FT_ABSOLUTE_TIME:
9260 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9261 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9262 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9263 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9264 REPORT_DISSECTOR_BUG("Field '%s' (%s) has a non-time-value-strings 'strings' value but is of type %s"proto_report_dissector_bug("Field '%s' (%s) has a non-time-value-strings 'strings' value but is of type %s"
" (which is only allowed to have time-value strings)", hfinfo
->name, hfinfo->abbrev, ftype_name(hfinfo->type))
9265 " (which is only allowed to have time-value strings)",proto_report_dissector_bug("Field '%s' (%s) has a non-time-value-strings 'strings' value but is of type %s"
" (which is only allowed to have time-value strings)", hfinfo
->name, hfinfo->abbrev, ftype_name(hfinfo->type))
9266 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) has a non-time-value-strings 'strings' value but is of type %s"
" (which is only allowed to have time-value strings)", hfinfo
->name, hfinfo->abbrev, ftype_name(hfinfo->type))
;
9267 }
9268 break;
9269
9270 /*
9271 * This type is only allowed to support a string if it's
9272 * a protocol (for pinos).
9273 */
9274 case FT_BYTES:
9275 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9276 REPORT_DISSECTOR_BUG("Field '%s' (%s) has a non-protocol-info 'strings' value but is of type %s"proto_report_dissector_bug("Field '%s' (%s) has a non-protocol-info 'strings' value but is of type %s"
" (which is only allowed to have protocol-info strings)", hfinfo
->name, hfinfo->abbrev, ftype_name(hfinfo->type))
9277 " (which is only allowed to have protocol-info strings)",proto_report_dissector_bug("Field '%s' (%s) has a non-protocol-info 'strings' value but is of type %s"
" (which is only allowed to have protocol-info strings)", hfinfo
->name, hfinfo->abbrev, ftype_name(hfinfo->type))
9278 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) has a non-protocol-info 'strings' value but is of type %s"
" (which is only allowed to have protocol-info strings)", hfinfo
->name, hfinfo->abbrev, ftype_name(hfinfo->type))
;
9279 }
9280 break;
9281
9282 default:
9283 REPORT_DISSECTOR_BUG("Field '%s' (%s) has a 'strings' value but is of type %s"proto_report_dissector_bug("Field '%s' (%s) has a 'strings' value but is of type %s"
" (which is not allowed to have strings)", hfinfo->name, hfinfo
->abbrev, ftype_name(hfinfo->type))
9284 " (which is not allowed to have strings)",proto_report_dissector_bug("Field '%s' (%s) has a 'strings' value but is of type %s"
" (which is not allowed to have strings)", hfinfo->name, hfinfo
->abbrev, ftype_name(hfinfo->type))
9285 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) has a 'strings' value but is of type %s"
" (which is not allowed to have strings)", hfinfo->name, hfinfo
->abbrev, ftype_name(hfinfo->type))
;
9286 }
9287 }
9288
9289 /* TODO: This check may slow down startup, and output quite a few warnings.
9290 It would be good to be able to enable this (and possibly other checks?)
9291 in non-release builds. */
9292#ifdef ENABLE_CHECK_FILTER
9293 /* Check for duplicate value_string values.
9294 There are lots that have the same value *and* string, so for now only
9295 report those that have same value but different string. */
9296 if ((hfinfo->strings != NULL((void*)0)) &&
9297 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9298 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9299 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9300 (
9301 (hfinfo->type == FT_CHAR) ||
9302 (hfinfo->type == FT_UINT8) ||
9303 (hfinfo->type == FT_UINT16) ||
9304 (hfinfo->type == FT_UINT24) ||
9305 (hfinfo->type == FT_UINT32) ||
9306 (hfinfo->type == FT_INT8) ||
9307 (hfinfo->type == FT_INT16) ||
9308 (hfinfo->type == FT_INT24) ||
9309 (hfinfo->type == FT_INT32) )) {
9310
9311 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9312 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9313 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9314 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9315 } else {
9316 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9317 CHECK_HF_VALUE(value_string, "u", start_values);
9318 }
9319 } else {
9320 const value_string *start_values = (const value_string*)hfinfo->strings;
9321 CHECK_HF_VALUE(value_string, "u", start_values);
9322 }
9323 }
9324
9325 if (hfinfo->type == FT_BOOLEAN) {
9326 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9327 if (tfs) {
9328 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9329 ws_warning("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9331, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9330 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9331, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9331 tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9331, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
;
9332 }
9333 }
9334 }
9335
9336 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9337 const range_string *rs = (const range_string*)(hfinfo->strings);
9338 if (rs) {
9339 const range_string *this_it = rs;
9340
9341 do {
9342 if (this_it->value_max < this_it->value_min) {
9343 ws_warning("value_range_string error: %s (%s) entry for \"%s\" - max(%"PRIu64" 0x%"PRIx64") is less than min(%"PRIu64" 0x%"PRIx64")",do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9347, __func__, "value_range_string error: %s (%s) entry for \"%s\" - max(%"
"l" "u"" 0x%""l" "x"") is less than min(%""l" "u"" 0x%""l" "x"
")", hfinfo->name, hfinfo->abbrev, this_it->strptr, this_it
->value_max, this_it->value_max, this_it->value_min,
this_it->value_min); } } while (0)
9344 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9347, __func__, "value_range_string error: %s (%s) entry for \"%s\" - max(%"
"l" "u"" 0x%""l" "x"") is less than min(%""l" "u"" 0x%""l" "x"
")", hfinfo->name, hfinfo->abbrev, this_it->strptr, this_it
->value_max, this_it->value_max, this_it->value_min,
this_it->value_min); } } while (0)
9345 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9347, __func__, "value_range_string error: %s (%s) entry for \"%s\" - max(%"
"l" "u"" 0x%""l" "x"") is less than min(%""l" "u"" 0x%""l" "x"
")", hfinfo->name, hfinfo->abbrev, this_it->strptr, this_it
->value_max, this_it->value_max, this_it->value_min,
this_it->value_min); } } while (0)
9346 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9347, __func__, "value_range_string error: %s (%s) entry for \"%s\" - max(%"
"l" "u"" 0x%""l" "x"") is less than min(%""l" "u"" 0x%""l" "x"
")", hfinfo->name, hfinfo->abbrev, this_it->strptr, this_it
->value_max, this_it->value_max, this_it->value_min,
this_it->value_min); } } while (0)
9347 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9347, __func__, "value_range_string error: %s (%s) entry for \"%s\" - max(%"
"l" "u"" 0x%""l" "x"") is less than min(%""l" "u"" 0x%""l" "x"
")", hfinfo->name, hfinfo->abbrev, this_it->strptr, this_it
->value_max, this_it->value_max, this_it->value_min,
this_it->value_min); } } while (0)
;
9348 ++this_it;
9349 continue;
9350 }
9351
9352 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9353 /* Not OK if this one is completely hidden by an earlier one! */
9354 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9355 ws_warning("value_range_string error: %s (%s) hidden by earlier entry "do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9361, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9356 "(prev=\"%s\": %"PRIu64" 0x%"PRIx64" -> %"PRIu64" 0x%"PRIx64") (this=\"%s\": %"PRIu64" 0x%"PRIx64" -> %"PRIu64" 0x%"PRIx64")",do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9361, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9357 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9361, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9358 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9361, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9359 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9361, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9360 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9361, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9361 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9361, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
;
9362 }
9363 }
9364 ++this_it;
9365 } while (this_it->strptr);
9366 }
9367 }
9368#endif
9369
9370 switch (hfinfo->type) {
9371
9372 case FT_CHAR:
9373 /* Require the char type to have BASE_HEX, BASE_OCT,
9374 * BASE_CUSTOM, or BASE_NONE as its base.
9375 *
9376 * If the display value is BASE_NONE and there is a
9377 * strings conversion then the dissector writer is
9378 * telling us that the field's numerical value is
9379 * meaningless; we'll avoid showing the value to the
9380 * user.
9381 */
9382 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9383 case BASE_HEX:
9384 case BASE_OCT:
9385 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9386 break;
9387 case BASE_NONE:
9388 if (hfinfo->strings == NULL((void*)0))
9389 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an integral value (%s)"proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9390 " but is being displayed as BASE_NONE but"proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9391 " without a strings conversion",proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9392 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9393 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9394 break;
9395 default:
9396 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9397 REPORT_DISSECTOR_BUG("Field '%s' (%s) is a character value (%s)"proto_report_dissector_bug("Field '%s' (%s) is a character value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
9398 " but is being displayed as %s",proto_report_dissector_bug("Field '%s' (%s) is a character value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
9399 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is a character value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
9400 ftype_name(hfinfo->type), tmp_str)proto_report_dissector_bug("Field '%s' (%s) is a character value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
;
9401 //wmem_free(NULL, tmp_str);
9402 }
9403 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9404 REPORT_DISSECTOR_BUG("Field '%s' (%s) is a character value (%s) but has a unit string",proto_report_dissector_bug("Field '%s' (%s) is a character value (%s) but has a unit string"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9405 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is a character value (%s) but has a unit string"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9406 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is a character value (%s) but has a unit string"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9407 }
9408 break;
9409 case FT_INT8:
9410 case FT_INT16:
9411 case FT_INT24:
9412 case FT_INT32:
9413 case FT_INT40:
9414 case FT_INT48:
9415 case FT_INT56:
9416 case FT_INT64:
9417 /* Hexadecimal and octal are, in printf() and everywhere
9418 * else, unsigned so don't allow dissectors to register a
9419 * signed field to be displayed unsigned. (Else how would
9420 * we display negative values?)
9421 */
9422 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9423 case BASE_HEX:
9424 case BASE_OCT:
9425 case BASE_DEC_HEX:
9426 case BASE_HEX_DEC:
9427 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9428 REPORT_DISSECTOR_BUG("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)",proto_report_dissector_bug("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9429 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9430 ftype_name(hfinfo->type), tmp_str)proto_report_dissector_bug("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
;
9431 //wmem_free(NULL, tmp_str);
9432 }
9433 /* FALL THROUGH */
9434 case FT_UINT8:
9435 case FT_UINT16:
9436 case FT_UINT24:
9437 case FT_UINT32:
9438 case FT_UINT40:
9439 case FT_UINT48:
9440 case FT_UINT56:
9441 case FT_UINT64:
9442 if (IS_BASE_PORT(hfinfo->display)(((hfinfo->display)==BASE_PT_UDP||(hfinfo->display)==BASE_PT_TCP
||(hfinfo->display)==BASE_PT_DCCP||(hfinfo->display)==BASE_PT_SCTP
))
) {
9443 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9444 if (hfinfo->type != FT_UINT16) {
9445 REPORT_DISSECTOR_BUG("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s",proto_report_dissector_bug("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s"
, hfinfo->name, hfinfo->abbrev, tmp_str, ftype_name(hfinfo
->type))
9446 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s"
, hfinfo->name, hfinfo->abbrev, tmp_str, ftype_name(hfinfo
->type))
9447 tmp_str, ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s"
, hfinfo->name, hfinfo->abbrev, tmp_str, ftype_name(hfinfo
->type))
;
9448 }
9449 if (hfinfo->strings != NULL((void*)0)) {
9450 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s (%s) but has a strings value",proto_report_dissector_bug("Field '%s' (%s) is an %s (%s) but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9451 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s (%s) but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9452 ftype_name(hfinfo->type), tmp_str)proto_report_dissector_bug("Field '%s' (%s) is an %s (%s) but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
;
9453 }
9454 if (hfinfo->bitmask != 0) {
9455 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s (%s) but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s (%s) but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9456 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s (%s) but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9457 ftype_name(hfinfo->type), tmp_str)proto_report_dissector_bug("Field '%s' (%s) is an %s (%s) but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
;
9458 }
9459 wmem_free(NULL((void*)0), tmp_str);
9460 break;
9461 }
9462
9463 if (hfinfo->display == BASE_OUI) {
9464 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9465 if (hfinfo->type != FT_UINT24) {
9466 REPORT_DISSECTOR_BUG("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT24, not %s",proto_report_dissector_bug("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT24, not %s"
, hfinfo->name, hfinfo->abbrev, tmp_str, ftype_name(hfinfo
->type))
9467 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT24, not %s"
, hfinfo->name, hfinfo->abbrev, tmp_str, ftype_name(hfinfo
->type))
9468 tmp_str, ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT24, not %s"
, hfinfo->name, hfinfo->abbrev, tmp_str, ftype_name(hfinfo
->type))
;
9469 }
9470 if (hfinfo->strings != NULL((void*)0)) {
9471 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s (%s) but has a strings value",proto_report_dissector_bug("Field '%s' (%s) is an %s (%s) but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9472 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s (%s) but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9473 ftype_name(hfinfo->type), tmp_str)proto_report_dissector_bug("Field '%s' (%s) is an %s (%s) but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
;
9474 }
9475 if (hfinfo->bitmask != 0) {
9476 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s (%s) but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s (%s) but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9477 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s (%s) but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9478 ftype_name(hfinfo->type), tmp_str)proto_report_dissector_bug("Field '%s' (%s) is an %s (%s) but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
;
9479 }
9480 wmem_free(NULL((void*)0), tmp_str);
9481 break;
9482 }
9483
9484 /* Require integral types (other than frame number,
9485 * which is always displayed in decimal) to have a
9486 * number base.
9487 *
9488 * If the display value is BASE_NONE and there is a
9489 * strings conversion then the dissector writer is
9490 * telling us that the field's numerical value is
9491 * meaningless; we'll avoid showing the value to the
9492 * user.
9493 */
9494 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9495 case BASE_DEC:
9496 case BASE_HEX:
9497 case BASE_OCT:
9498 case BASE_DEC_HEX:
9499 case BASE_HEX_DEC:
9500 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9501 break;
9502 case BASE_NONE:
9503 if (hfinfo->strings == NULL((void*)0)) {
9504 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an integral value (%s)"proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9505 " but is being displayed as BASE_NONE but"proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9506 " without a strings conversion",proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9507 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9508 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9509 }
9510 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9511 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an integral value (%s)"proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" that is being displayed as BASE_NONE but" " with BASE_SPECIAL_VALS"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9512 " that is being displayed as BASE_NONE but"proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" that is being displayed as BASE_NONE but" " with BASE_SPECIAL_VALS"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9513 " with BASE_SPECIAL_VALS",proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" that is being displayed as BASE_NONE but" " with BASE_SPECIAL_VALS"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9514 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" that is being displayed as BASE_NONE but" " with BASE_SPECIAL_VALS"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9515 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" that is being displayed as BASE_NONE but" " with BASE_SPECIAL_VALS"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9516 }
9517 break;
9518
9519 default:
9520 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9521 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an integral value (%s)"proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
9522 " but is being displayed as %s",proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
9523 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
9524 ftype_name(hfinfo->type), tmp_str)proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
;
9525 //wmem_free(NULL, tmp_str);
9526 }
9527 break;
9528 case FT_BYTES:
9529 case FT_UINT_BYTES:
9530 /* Require bytes to have a "display type" that could
9531 * add a character between displayed bytes.
9532 */
9533 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9534 case BASE_NONE:
9535 case SEP_DOT:
9536 case SEP_DASH:
9537 case SEP_COLON:
9538 case SEP_SPACE:
9539 break;
9540 default:
9541 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9542 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an byte array but is being displayed as %s instead of BASE_NONE, SEP_DOT, SEP_DASH, SEP_COLON, or SEP_SPACE",proto_report_dissector_bug("Field '%s' (%s) is an byte array but is being displayed as %s instead of BASE_NONE, SEP_DOT, SEP_DASH, SEP_COLON, or SEP_SPACE"
, hfinfo->name, hfinfo->abbrev, tmp_str)
9543 hfinfo->name, hfinfo->abbrev, tmp_str)proto_report_dissector_bug("Field '%s' (%s) is an byte array but is being displayed as %s instead of BASE_NONE, SEP_DOT, SEP_DASH, SEP_COLON, or SEP_SPACE"
, hfinfo->name, hfinfo->abbrev, tmp_str)
;
9544 //wmem_free(NULL, tmp_str);
9545 }
9546 if (hfinfo->bitmask != 0)
9547 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9548 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9549 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9550 //allowed to support string if its a protocol (for pinos)
9551 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9552 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9553 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9554 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9555 break;
9556
9557 case FT_PROTOCOL:
9558 case FT_FRAMENUM:
9559 if (hfinfo->display != BASE_NONE) {
9560 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9561 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE",proto_report_dissector_bug("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9562 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9563 ftype_name(hfinfo->type), tmp_str)proto_report_dissector_bug("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
;
9564 //wmem_free(NULL, tmp_str);
9565 }
9566 if (hfinfo->bitmask != 0)
9567 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9568 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9569 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9570 break;
9571
9572 case FT_BOOLEAN:
9573 break;
9574
9575 case FT_ABSOLUTE_TIME:
9576 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9577 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9578 REPORT_DISSECTOR_BUG("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time",proto_report_dissector_bug("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9579 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type), tmp_str)proto_report_dissector_bug("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
;
9580 //wmem_free(NULL, tmp_str);
9581 }
9582 if (hfinfo->bitmask != 0)
9583 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9584 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9585 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9586 break;
9587
9588 case FT_STRING:
9589 case FT_STRINGZ:
9590 case FT_UINT_STRING:
9591 case FT_STRINGZPAD:
9592 case FT_STRINGZTRUNC:
9593 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9594 case BASE_NONE:
9595 case BASE_STR_WSP:
9596 break;
9597
9598 default:
9599 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9600 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an string value (%s)"proto_report_dissector_bug("Field '%s' (%s) is an string value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
9601 " but is being displayed as %s",proto_report_dissector_bug("Field '%s' (%s) is an string value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
9602 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an string value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
9603 ftype_name(hfinfo->type), tmp_str)proto_report_dissector_bug("Field '%s' (%s) is an string value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
;
9604 //wmem_free(NULL, tmp_str);
9605 }
9606
9607 if (hfinfo->bitmask != 0)
9608 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9609 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9610 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9611 if (hfinfo->strings != NULL((void*)0))
9612 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9613 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9614 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9615 break;
9616
9617 case FT_IPv4:
9618 switch (hfinfo->display) {
9619 case BASE_NONE:
9620 case BASE_NETMASK:
9621 break;
9622
9623 default:
9624 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9625 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an IPv4 value (%s)"proto_report_dissector_bug("Field '%s' (%s) is an IPv4 value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
9626 " but is being displayed as %s",proto_report_dissector_bug("Field '%s' (%s) is an IPv4 value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
9627 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an IPv4 value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
9628 ftype_name(hfinfo->type), tmp_str)proto_report_dissector_bug("Field '%s' (%s) is an IPv4 value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
;
9629 //wmem_free(NULL, tmp_str);
9630 break;
9631 }
9632 break;
9633 case FT_FLOAT:
9634 case FT_DOUBLE:
9635 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9636 case BASE_NONE:
9637 case BASE_DEC:
9638 case BASE_HEX:
9639 case BASE_EXP:
9640 case BASE_CUSTOM:
9641 break;
9642 default:
9643 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9644 REPORT_DISSECTOR_BUG("Field '%s' (%s) is a float value (%s)"proto_report_dissector_bug("Field '%s' (%s) is a float value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
9645 " but is being displayed as %s",proto_report_dissector_bug("Field '%s' (%s) is a float value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
9646 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is a float value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
9647 ftype_name(hfinfo->type), tmp_str)proto_report_dissector_bug("Field '%s' (%s) is a float value (%s)"
" but is being displayed as %s", hfinfo->name, hfinfo->
abbrev, ftype_name(hfinfo->type), tmp_str)
;
9648 //wmem_free(NULL, tmp_str);
9649 }
9650 if (hfinfo->bitmask != 0)
9651 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9652 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9653 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9654 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9655 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9656 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9657 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9658 break;
9659 case FT_IEEE_11073_SFLOAT:
9660 case FT_IEEE_11073_FLOAT:
9661 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9662 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9663 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE",proto_report_dissector_bug("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9664 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9665 ftype_name(hfinfo->type),proto_report_dissector_bug("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9666 tmp_str)proto_report_dissector_bug("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
;
9667 //wmem_free(NULL, tmp_str);
9668 }
9669 if (hfinfo->bitmask != 0)
9670 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9671 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9672 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9673 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9674 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9675 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9676 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9677 break;
9678 default:
9679 if (hfinfo->display != BASE_NONE) {
9680 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9681 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE",proto_report_dissector_bug("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9682 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9683 ftype_name(hfinfo->type),proto_report_dissector_bug("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9684 tmp_str)proto_report_dissector_bug("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
;
9685 //wmem_free(NULL, tmp_str);
9686 }
9687 if (hfinfo->bitmask != 0)
9688 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9689 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9690 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9691 if (hfinfo->strings != NULL((void*)0))
9692 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9693 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9694 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9695 break;
9696 }
9697}
9698
9699static void
9700register_type_length_mismatch(void)
9701{
9702 static ei_register_info ei[] = {
9703 { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Trying to fetch X with length Y", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
9704 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", PI_MALFORMED0x07000000, PI_WARN0x00600000, "Trying to fetch X with length Y", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
9705 };
9706
9707 expert_module_t* expert_type_length_mismatch;
9708
9709 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9710
9711 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9712 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9713
9714 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9715 disabling them makes no sense. */
9716 proto_set_cant_toggle(proto_type_length_mismatch);
9717}
9718
9719static void
9720register_byte_array_string_decodinws_error(void)
9721{
9722 static ei_register_info ei[] = {
9723 { &ei_byte_array_string_decoding_failed_error,
9724 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9725 "Failed to decode byte array from string", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
9726 }
9727 },
9728 };
9729
9730 expert_module_t* expert_byte_array_string_decoding_error;
9731
9732 proto_byte_array_string_decoding_error =
9733 proto_register_protocol("Byte Array-String Decoding Error",
9734 "Byte Array-string decoding error",
9735 "_ws.byte_array_string.decoding_error");
9736
9737 expert_byte_array_string_decoding_error =
9738 expert_register_protocol(proto_byte_array_string_decoding_error);
9739 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9740
9741 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9742 disabling them makes no sense. */
9743 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9744}
9745
9746static void
9747register_date_time_string_decodinws_error(void)
9748{
9749 static ei_register_info ei[] = {
9750 { &ei_date_time_string_decoding_failed_error,
9751 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9752 "Failed to decode date and time from string", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
9753 }
9754 },
9755 };
9756
9757 expert_module_t* expert_date_time_string_decoding_error;
9758
9759 proto_date_time_string_decoding_error =
9760 proto_register_protocol("Date and Time-String Decoding Error",
9761 "Date and Time-string decoding error",
9762 "_ws.date_time_string.decoding_error");
9763
9764 expert_date_time_string_decoding_error =
9765 expert_register_protocol(proto_date_time_string_decoding_error);
9766 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9767
9768 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9769 disabling them makes no sense. */
9770 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9771}
9772
9773static void
9774register_string_errors(void)
9775{
9776 static ei_register_info ei[] = {
9777 { &ei_string_trailing_characters,
9778 { "_ws.string.trailing_stray_characters", PI_UNDECODED0x05000000, PI_WARN0x00600000, "Trailing stray characters", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}
9779 },
9780 };
9781
9782 expert_module_t* expert_string_errors;
9783
9784 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9785
9786 expert_string_errors = expert_register_protocol(proto_string_errors);
9787 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9788
9789 /* "String Errors" isn't really a protocol, it's an error indication;
9790 disabling them makes no sense. */
9791 proto_set_cant_toggle(proto_string_errors);
9792}
9793
9794#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
9795static int
9796proto_register_field_init(header_field_info *hfinfo, const int parent)
9797{
9798
9799 tmp_fld_check_assert(hfinfo);
9800
9801 hfinfo->parent = parent;
9802 hfinfo->same_name_next = NULL((void*)0);
9803 hfinfo->same_name_prev_id = -1;
9804
9805 /* if we always add and never delete, then id == len - 1 is correct */
9806 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9807 if (!gpa_hfinfo.hfi) {
9808 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9809 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9810 /* The entry with index 0 is not used. */
9811 gpa_hfinfo.hfi[0] = NULL((void*)0);
9812 gpa_hfinfo.len = 1;
9813 } else {
9814 gpa_hfinfo.allocated_len += 1000;
9815 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9816 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9817 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9818 }
9819 }
9820 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9821 gpa_hfinfo.len++;
9822 hfinfo->id = gpa_hfinfo.len - 1;
9823
9824 /* if we have real names, enter this field in the name tree */
9825 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
9826
9827 header_field_info *same_name_next_hfinfo;
9828 unsigned char c;
9829
9830 /* Check that the filter name (abbreviation) is legal;
9831 * it must contain only alphanumerics, '-', "_", and ".". */
9832 c = proto_check_field_name(hfinfo->abbrev);
9833 if (c) {
9834 if (c == '.') {
9835 REPORT_DISSECTOR_BUG("Invalid leading, duplicated or trailing '.' found in filter name '%s'", hfinfo->abbrev)proto_report_dissector_bug("Invalid leading, duplicated or trailing '.' found in filter name '%s'"
, hfinfo->abbrev)
;
9836 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9837 REPORT_DISSECTOR_BUG("Invalid character '%c' in filter name '%s'", c, hfinfo->abbrev)proto_report_dissector_bug("Invalid character '%c' in filter name '%s'"
, c, hfinfo->abbrev)
;
9838 } else {
9839 REPORT_DISSECTOR_BUG("Invalid byte \\%03o in filter name '%s'", c, hfinfo->abbrev)proto_report_dissector_bug("Invalid byte \\%03o in filter name '%s'"
, c, hfinfo->abbrev)
;
9840 }
9841 }
9842
9843 /* We allow multiple hfinfo's to be registered under the same
9844 * abbreviation. This was done for X.25, as, depending
9845 * on whether it's modulo-8 or modulo-128 operation,
9846 * some bitfield fields may be in different bits of
9847 * a byte, and we want to be able to refer to that field
9848 * with one name regardless of whether the packets
9849 * are modulo-8 or modulo-128 packets. */
9850
9851 same_name_hfinfo = NULL((void*)0);
9852
9853 g_hash_table_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9854 /* GLIB 2.x - if it is already present
9855 * the previous hfinfo with the same name is saved
9856 * to same_name_hfinfo by value destroy callback */
9857 if (same_name_hfinfo) {
9858 /* There's already a field with this name.
9859 * Put the current field *before* that field
9860 * in the list of fields with this name, Thus,
9861 * we end up with an effectively
9862 * doubly-linked-list of same-named hfinfo's,
9863 * with the head of the list (stored in the
9864 * hash) being the last seen hfinfo.
9865 */
9866 same_name_next_hfinfo =
9867 same_name_hfinfo->same_name_next;
9868
9869 hfinfo->same_name_next = same_name_next_hfinfo;
9870 if (same_name_next_hfinfo)
9871 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9872
9873 same_name_hfinfo->same_name_next = hfinfo;
9874 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9875#ifdef ENABLE_CHECK_FILTER
9876 while (same_name_hfinfo) {
9877 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9878 ws_warning("'%s' exists multiple times with incompatible types: %s and %s", hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(same_name_hfinfo->type))do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9878, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type)); } } while (0)
;
9879 same_name_hfinfo = same_name_hfinfo->same_name_next;
9880 }
9881#endif
9882 }
9883 }
9884
9885 return hfinfo->id;
9886}
9887
9888void
9889proto_register_subtree_array(int * const *indices, const int num_indices)
9890{
9891 int i;
9892 int *const *ptr = indices;
9893
9894 /*
9895 * If we've already allocated the array of tree types, expand
9896 * it; this lets plugins such as mate add tree types after
9897 * the initial startup. (If we haven't already allocated it,
9898 * we don't allocate it; on the first pass, we just assign
9899 * ett values and keep track of how many we've assigned, and
9900 * when we're finished registering all dissectors we allocate
9901 * the array, so that we do only one allocation rather than
9902 * wasting CPU time and memory by growing the array for each
9903 * dissector that registers ett values.)
9904 */
9905 if (tree_is_expanded != NULL((void*)0)) {
9906 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9907
9908 /* set new items to 0 */
9909 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9910 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9911 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9912 }
9913
9914 /*
9915 * Assign "num_indices" subtree numbers starting at "num_tree_types",
9916 * returning the indices through the pointers in the array whose
9917 * first element is pointed to by "indices", and update
9918 * "num_tree_types" appropriately.
9919 */
9920 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9921 if (**ptr != -1 && **ptr != 0) {
9922 REPORT_DISSECTOR_BUG("register_subtree_array: subtree item type (ett_...) not -1 or 0 !"proto_report_dissector_bug("register_subtree_array: subtree item type (ett_...) not -1 or 0 !"
" This is a development error:" " Either the subtree item type has already been assigned or"
" was not initialized to -1 or 0.")
9923 " This is a development error:"proto_report_dissector_bug("register_subtree_array: subtree item type (ett_...) not -1 or 0 !"
" This is a development error:" " Either the subtree item type has already been assigned or"
" was not initialized to -1 or 0.")
9924 " Either the subtree item type has already been assigned or"proto_report_dissector_bug("register_subtree_array: subtree item type (ett_...) not -1 or 0 !"
" This is a development error:" " Either the subtree item type has already been assigned or"
" was not initialized to -1 or 0.")
9925 " was not initialized to -1 or 0.")proto_report_dissector_bug("register_subtree_array: subtree item type (ett_...) not -1 or 0 !"
" This is a development error:" " Either the subtree item type has already been assigned or"
" was not initialized to -1 or 0.")
;
9926 }
9927 **ptr = num_tree_types;
9928 }
9929}
9930
9931static void
9932mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
9933{
9934 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "]";
9935 const size_t trunc_len = sizeof(trunc_str)-1;
9936 char *last_char;
9937
9938 /* ..... field_name: dataaaaaaaaaaaaa
9939 * |
9940 * ^^^^^ name_pos
9941 *
9942 * ..... field_name […]: dataaaaaaaaaaaaa
9943 *
9944 * name_pos==0 means that we have only data or only a field_name
9945 */
9946
9947 if (name_pos < size - trunc_len) {
9948 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
9949 memcpy(label_str + name_pos, trunc_str, trunc_len);
9950
9951 /* in general, label_str is UTF-8
9952 we can truncate it only at the beginning of a new character
9953 we go backwards from the byte right after our buffer and
9954 find the next starting byte of a UTF-8 character, this is
9955 where we cut
9956 there's no need to use g_utf8_find_prev_char(), the search
9957 will always succeed since we copied trunc_str into the
9958 buffer */
9959 /* g_utf8_prev_char does not deference the memory address
9960 * passed in (until after decrementing it, so it is perfectly
9961 * legal to pass in a pointer one past the last element.
9962 */
9963 last_char = g_utf8_prev_char(label_str + size);
9964 *last_char = '\0';
9965
9966 if (value_pos && *value_pos > 0) {
9967 if (name_pos == 0) {
9968 *value_pos += trunc_len;
9969 } else {
9970 /* Move one back to include trunc_str in the value. */
9971 *value_pos -= 1;
9972 }
9973 }
9974 } else if (name_pos < size)
9975 (void) g_strlcpy(label_str + name_pos, trunc_str, size - name_pos);
9976}
9977
9978static void
9979label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
9980{
9981 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
9982}
9983
9984static size_t
9985label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
9986{
9987 size_t name_pos;
9988
9989 /* "%s: %s", hfinfo->name, text */
9990 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
9991 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
9992 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
9993 if (value_pos) {
9994 *value_pos = pos;
9995 }
9996 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, text ? text : "(null)", label_strcat_flags(hfinfo));
9997 }
9998
9999 if (pos >= ITEM_LABEL_LENGTH240) {
10000 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10001 label_mark_truncated(label_str, name_pos, value_pos);
10002 }
10003
10004 return pos;
10005}
10006
10007static size_t
10008label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10009{
10010 size_t name_pos;
10011
10012 /* "%s: %s (%s)", hfinfo->name, text, descr */
10013 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10014 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10015 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10016 if (value_pos) {
10017 *value_pos = pos;
10018 }
10019 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10020 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10021 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10022 } else {
10023 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10024 pos = label_concat(label_str, pos, " (")ws_label_strcpy(label_str, 240, pos, " (", 0);
10025 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10026 pos = label_concat(label_str, pos, ")")ws_label_strcpy(label_str, 240, pos, ")", 0);
10027 }
10028 }
10029
10030 if (pos >= ITEM_LABEL_LENGTH240) {
10031 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10032 label_mark_truncated(label_str, name_pos, value_pos);
10033 }
10034
10035 return pos;
10036}
10037
10038void
10039proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10040{
10041 const header_field_info *hfinfo;
10042 const char *str;
10043 const uint8_t *bytes;
10044 uint32_t integer;
10045 const ipv4_addr_and_mask *ipv4;
10046 const ipv6_addr_and_prefix *ipv6;
10047 const e_guid_t *guid;
10048 char *name;
10049 address addr;
10050 char *addr_str;
10051 char *tmp;
10052
10053 if (!label_str) {
10054 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10054, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10055 return;
10056 }
10057
10058 label_str[0]= '\0';
10059
10060 if (!fi) {
10061 return;
10062 }
10063
10064 hfinfo = fi->hfinfo;
10065
10066 switch (hfinfo->type) {
10067 case FT_NONE:
10068 case FT_PROTOCOL:
10069 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10070 if (value_pos) {
10071 *value_pos = strlen(hfinfo->name);
10072 }
10073 break;
10074
10075 case FT_BOOLEAN:
10076 fill_label_boolean(fi, label_str, value_pos);
10077 break;
10078
10079 case FT_BYTES:
10080 case FT_UINT_BYTES:
10081 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10082 fvalue_get_bytes_data(fi->value),
10083 (unsigned)fvalue_length2(fi->value));
10084 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10085 wmem_free(NULL((void*)0), tmp);
10086 break;
10087
10088 case FT_CHAR:
10089 if (hfinfo->bitmask) {
10090 fill_label_bitfield_char(fi, label_str, value_pos);
10091 } else {
10092 fill_label_char(fi, label_str, value_pos);
10093 }
10094 break;
10095
10096 /* Four types of integers to take care of:
10097 * Bitfield, with val_string
10098 * Bitfield, w/o val_string
10099 * Non-bitfield, with val_string
10100 * Non-bitfield, w/o val_string
10101 */
10102 case FT_UINT8:
10103 case FT_UINT16:
10104 case FT_UINT24:
10105 case FT_UINT32:
10106 if (hfinfo->bitmask) {
10107 fill_label_bitfield(fi, label_str, value_pos, false0);
10108 } else {
10109 fill_label_number(fi, label_str, value_pos, false0);
10110 }
10111 break;
10112
10113 case FT_FRAMENUM:
10114 fill_label_number(fi, label_str, value_pos, false0);
10115 break;
10116
10117 case FT_UINT40:
10118 case FT_UINT48:
10119 case FT_UINT56:
10120 case FT_UINT64:
10121 if (hfinfo->bitmask) {
10122 fill_label_bitfield64(fi, label_str, value_pos, false0);
10123 } else {
10124 fill_label_number64(fi, label_str, value_pos, false0);
10125 }
10126 break;
10127
10128 case FT_INT8:
10129 case FT_INT16:
10130 case FT_INT24:
10131 case FT_INT32:
10132 if (hfinfo->bitmask) {
10133 fill_label_bitfield(fi, label_str, value_pos, true1);
10134 } else {
10135 fill_label_number(fi, label_str, value_pos, true1);
10136 }
10137 break;
10138
10139 case FT_INT40:
10140 case FT_INT48:
10141 case FT_INT56:
10142 case FT_INT64:
10143 if (hfinfo->bitmask) {
10144 fill_label_bitfield64(fi, label_str, value_pos, true1);
10145 } else {
10146 fill_label_number64(fi, label_str, value_pos, true1);
10147 }
10148 break;
10149
10150 case FT_FLOAT:
10151 case FT_DOUBLE:
10152 fill_label_float(fi, label_str, value_pos);
10153 break;
10154
10155 case FT_ABSOLUTE_TIME:
10156 {
10157 const nstime_t *value = fvalue_get_time(fi->value);
10158 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10159 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10160 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10161 }
10162 if (hfinfo->strings) {
10163 /*
10164 * Table of time valus to be displayed
10165 * specially.
10166 */
10167 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10168 if (time_string != NULL((void*)0)) {
10169 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10170 break;
10171 }
10172 }
10173 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10174 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10175 wmem_free(NULL((void*)0), tmp);
10176 break;
10177 }
10178 case FT_RELATIVE_TIME:
10179 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10180 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10181 wmem_free(NULL((void*)0), tmp);
10182 break;
10183
10184 case FT_IPXNET:
10185 integer = fvalue_get_uinteger(fi->value);
10186 tmp = get_ipxnet_name(NULL((void*)0), integer);
10187 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10188 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10189 wmem_free(NULL((void*)0), tmp);
10190 wmem_free(NULL((void*)0), addr_str);
10191 break;
10192
10193 case FT_VINES:
10194 addr.type = AT_VINES;
10195 addr.len = VINES_ADDR_LEN6;
10196 addr.data = fvalue_get_bytes_data(fi->value);
10197
10198 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10199 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10200 wmem_free(NULL((void*)0), addr_str);
10201 break;
10202
10203 case FT_ETHER:
10204 bytes = fvalue_get_bytes_data(fi->value);
10205
10206 addr.type = AT_ETHER;
10207 addr.len = 6;
10208 addr.data = bytes;
10209
10210 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10211 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10212 wmem_free(NULL((void*)0), addr_str);
10213 break;
10214
10215 case FT_IPv4:
10216 ipv4 = fvalue_get_ipv4(fi->value);
10217 set_address_ipv4(&addr, ipv4);
10218
10219 if (hfinfo->display == BASE_NETMASK) {
10220 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10221 } else {
10222 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10223 }
10224 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10225 wmem_free(NULL((void*)0), addr_str);
10226 free_address(&addr);
10227 break;
10228
10229 case FT_IPv6:
10230 ipv6 = fvalue_get_ipv6(fi->value);
10231 set_address_ipv6(&addr, ipv6);
10232
10233 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10234 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10235 wmem_free(NULL((void*)0), addr_str);
10236 free_address(&addr);
10237 break;
10238
10239 case FT_FCWWN:
10240 bytes = fvalue_get_bytes_data(fi->value);
10241 addr.type = AT_FCWWN;
10242 addr.len = FCWWN_ADDR_LEN8;
10243 addr.data = bytes;
10244
10245 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10246 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10247 wmem_free(NULL((void*)0), addr_str);
10248 break;
10249
10250 case FT_GUID:
10251 guid = fvalue_get_guid(fi->value);
10252 tmp = guid_to_str(NULL((void*)0), guid);
10253 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10254 wmem_free(NULL((void*)0), tmp);
10255 break;
10256
10257 case FT_OID:
10258 bytes = fvalue_get_bytes_data(fi->value);
10259 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10260 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10261 if (name) {
10262 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10263 wmem_free(NULL((void*)0), name);
10264 } else {
10265 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10266 }
10267 wmem_free(NULL((void*)0), tmp);
10268 break;
10269
10270 case FT_REL_OID:
10271 bytes = fvalue_get_bytes_data(fi->value);
10272 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10273 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10274 if (name) {
10275 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10276 wmem_free(NULL((void*)0), name);
10277 } else {
10278 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10279 }
10280 wmem_free(NULL((void*)0), tmp);
10281 break;
10282
10283 case FT_SYSTEM_ID:
10284 bytes = fvalue_get_bytes_data(fi->value);
10285 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10286 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10287 wmem_free(NULL((void*)0), tmp);
10288 break;
10289
10290 case FT_EUI64:
10291 bytes = fvalue_get_bytes_data(fi->value);
10292 addr.type = AT_EUI64;
10293 addr.len = EUI64_ADDR_LEN8;
10294 addr.data = bytes;
10295
10296 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10297 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10298 wmem_free(NULL((void*)0), addr_str);
10299 break;
10300 case FT_STRING:
10301 case FT_STRINGZ:
10302 case FT_UINT_STRING:
10303 case FT_STRINGZPAD:
10304 case FT_STRINGZTRUNC:
10305 case FT_AX25:
10306 str = fvalue_get_string(fi->value);
10307 label_fill(label_str, 0, hfinfo, str, value_pos);
10308 break;
10309
10310 case FT_IEEE_11073_SFLOAT:
10311 case FT_IEEE_11073_FLOAT:
10312 fill_label_ieee_11073_float(fi, label_str, value_pos);
10313 break;
10314
10315 default:
10316 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_fill_label()",proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_item_fill_label()"
, hfinfo->abbrev, hfinfo->type, ftype_name(hfinfo->type
))
10317 hfinfo->abbrev,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_item_fill_label()"
, hfinfo->abbrev, hfinfo->type, ftype_name(hfinfo->type
))
10318 hfinfo->type,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_item_fill_label()"
, hfinfo->abbrev, hfinfo->type, ftype_name(hfinfo->type
))
10319 ftype_name(hfinfo->type))proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_item_fill_label()"
, hfinfo->abbrev, hfinfo->type, ftype_name(hfinfo->type
))
;
10320 break;
10321 }
10322}
10323
10324static void
10325fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10326{
10327 char *p;
10328 int bitfield_byte_length = 0, bitwidth;
10329 uint64_t unshifted_value;
10330 uint64_t value;
10331
10332 const header_field_info *hfinfo = fi->hfinfo;
10333
10334 value = fvalue_get_uinteger64(fi->value);
10335 if (hfinfo->bitmask) {
10336 /* Figure out the bit width */
10337 bitwidth = hfinfo_container_bitwidth(hfinfo);
10338
10339 /* Un-shift bits */
10340 unshifted_value = value;
10341 unshifted_value <<= hfinfo_bitshift(hfinfo);
10342
10343 /* Create the bitfield first */
10344 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10345 bitfield_byte_length = (int) (p - label_str);
10346 }
10347
10348 /* Fill in the textual info */
10349 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10350}
10351
10352static const char *
10353hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10354{
10355 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10356 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10357
10358 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10359 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10360 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10361 else
10362 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10363 }
10364
10365 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10366 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10367
10368 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10369 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10370
10371 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10372}
10373
10374static const char *
10375hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10376{
10377 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10378 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10379 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10380 else
10381 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10382 }
10383
10384 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10385 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10386
10387 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10388 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10389
10390 /* If this is reached somebody registered a 64-bit field with a 32-bit
10391 * value-string, which isn't right. */
10392 REPORT_DISSECTOR_BUG("field %s is a 64-bit field with a 32-bit value_string",proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
10393 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10394
10395 /* This is necessary to squelch MSVC errors; is there
10396 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10397 never returns? */
10398 return NULL((void*)0);
10399}
10400
10401static const char *
10402hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10403{
10404 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10405 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10406
10407 REPORT_DISSECTOR_BUG("field %s (FT_DOUBLE) has no base_unit_string", hfinfo->abbrev)proto_report_dissector_bug("field %s (FT_DOUBLE) has no base_unit_string"
, hfinfo->abbrev)
;
10408
10409 /* This is necessary to squelch MSVC errors; is there
10410 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10411 never returns? */
10412 return NULL((void*)0);
10413}
10414
10415static const char *
10416hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10417{
10418 const char *str = hf_try_val_to_str(value, hfinfo);
10419
10420 return (str) ? str : unknown_str;
10421}
10422
10423static const char *
10424hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10425{
10426 const char *str = hf_try_val64_to_str(value, hfinfo);
10427
10428 return (str) ? str : unknown_str;
10429}
10430
10431/* Fills data for bitfield chars with val_strings */
10432static void
10433fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10434{
10435 char *p;
10436 int bitfield_byte_length, bitwidth;
10437 uint32_t unshifted_value;
10438 uint32_t value;
10439
10440 char buf[32];
10441 const char *out;
10442
10443 const header_field_info *hfinfo = fi->hfinfo;
10444
10445 /* Figure out the bit width */
10446 bitwidth = hfinfo_container_bitwidth(hfinfo);
10447
10448 /* Un-shift bits */
10449 value = fvalue_get_uinteger(fi->value);
10450
10451 unshifted_value = value;
10452 if (hfinfo->bitmask) {
10453 unshifted_value <<= hfinfo_bitshift(hfinfo);
10454 }
10455
10456 /* Create the bitfield first */
10457 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10458 bitfield_byte_length = (int) (p - label_str);
10459
10460 /* Fill in the textual info using stored (shifted) value */
10461 if (hfinfo->display == BASE_CUSTOM) {
10462 char tmp[ITEM_LABEL_LENGTH240];
10463 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10464
10465 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10465, "fmtfunc"))))
;
10466 fmtfunc(tmp, value);
10467 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10468 }
10469 else if (hfinfo->strings) {
10470 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10471
10472 out = hfinfo_char_vals_format(hfinfo, buf, value);
10473 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10474 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10475 else
10476 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10477 }
10478 else {
10479 out = hfinfo_char_value_format(hfinfo, buf, value);
10480
10481 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10482 }
10483}
10484
10485/* Fills data for bitfield ints with val_strings */
10486static void
10487fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10488{
10489 char *p;
10490 int bitfield_byte_length, bitwidth;
10491 uint32_t value, unshifted_value;
10492 char buf[NUMBER_LABEL_LENGTH80];
10493 const char *out;
10494
10495 const header_field_info *hfinfo = fi->hfinfo;
10496
10497 /* Figure out the bit width */
10498 if (fi->flags & FI_VARINT0x00040000)
10499 bitwidth = fi->length*8;
10500 else
10501 bitwidth = hfinfo_container_bitwidth(hfinfo);
10502
10503 /* Un-shift bits */
10504 if (is_signed)
10505 value = fvalue_get_sinteger(fi->value);
10506 else
10507 value = fvalue_get_uinteger(fi->value);
10508
10509 unshifted_value = value;
10510 if (hfinfo->bitmask) {
10511 unshifted_value <<= hfinfo_bitshift(hfinfo);
10512 }
10513
10514 /* Create the bitfield first */
10515 if (fi->flags & FI_VARINT0x00040000)
10516 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10517 else
10518 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10519 bitfield_byte_length = (int) (p - label_str);
10520
10521 /* Fill in the textual info using stored (shifted) value */
10522 if (hfinfo->display == BASE_CUSTOM) {
10523 char tmp[ITEM_LABEL_LENGTH240];
10524 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10525
10526 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10526, "fmtfunc"))))
;
10527 fmtfunc(tmp, value);
10528 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10529 }
10530 else if (hfinfo->strings) {
10531 const char *val_str = hf_try_val_to_str(value, hfinfo);
10532
10533 out = hfinfo_number_vals_format(hfinfo, buf, value);
10534 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10535 /*
10536 * Unique values only display value_string string
10537 * if there is a match. Otherwise it's just a number
10538 */
10539 if (val_str) {
10540 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10541 } else {
10542 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10543 }
10544 } else {
10545 if (val_str == NULL((void*)0))
10546 val_str = "Unknown";
10547
10548 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10549 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10550 else
10551 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10552 }
10553 }
10554 else {
10555 out = hfinfo_number_value_format(hfinfo, buf, value);
10556
10557 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10558 }
10559}
10560
10561static void
10562fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10563{
10564 char *p;
10565 int bitfield_byte_length, bitwidth;
10566 uint64_t value, unshifted_value;
10567 char buf[NUMBER_LABEL_LENGTH80];
10568 const char *out;
10569
10570 const header_field_info *hfinfo = fi->hfinfo;
10571
10572 /* Figure out the bit width */
10573 if (fi->flags & FI_VARINT0x00040000)
10574 bitwidth = fi->length*8;
10575 else
10576 bitwidth = hfinfo_container_bitwidth(hfinfo);
10577
10578 /* Un-shift bits */
10579 if (is_signed)
10580 value = fvalue_get_sinteger64(fi->value);
10581 else
10582 value = fvalue_get_uinteger64(fi->value);
10583
10584 unshifted_value = value;
10585 if (hfinfo->bitmask) {
10586 unshifted_value <<= hfinfo_bitshift(hfinfo);
10587 }
10588
10589 /* Create the bitfield first */
10590 if (fi->flags & FI_VARINT0x00040000)
10591 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10592 else
10593 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10594 bitfield_byte_length = (int) (p - label_str);
10595
10596 /* Fill in the textual info using stored (shifted) value */
10597 if (hfinfo->display == BASE_CUSTOM) {
10598 char tmp[ITEM_LABEL_LENGTH240];
10599 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10600
10601 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10601, "fmtfunc64"
))))
;
10602 fmtfunc64(tmp, value);
10603 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10604 }
10605 else if (hfinfo->strings) {
10606 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10607
10608 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10609 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10610 /*
10611 * Unique values only display value_string string
10612 * if there is a match. Otherwise it's just a number
10613 */
10614 if (val_str) {
10615 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10616 } else {
10617 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10618 }
10619 } else {
10620 if (val_str == NULL((void*)0))
10621 val_str = "Unknown";
10622
10623 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10624 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10625 else
10626 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10627 }
10628 }
10629 else {
10630 out = hfinfo_number_value_format64(hfinfo, buf, value);
10631
10632 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10633 }
10634}
10635
10636static void
10637fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10638{
10639 const header_field_info *hfinfo = fi->hfinfo;
10640 uint32_t value;
10641
10642 char buf[32];
10643 const char *out;
10644
10645 value = fvalue_get_uinteger(fi->value);
10646
10647 /* Fill in the textual info */
10648 if (hfinfo->display == BASE_CUSTOM) {
10649 char tmp[ITEM_LABEL_LENGTH240];
10650 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10651
10652 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10652, "fmtfunc"))))
;
10653 fmtfunc(tmp, value);
10654 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10655 }
10656 else if (hfinfo->strings) {
10657 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10658
10659 out = hfinfo_char_vals_format(hfinfo, buf, value);
10660 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10661 }
10662 else {
10663 out = hfinfo_char_value_format(hfinfo, buf, value);
10664
10665 label_fill(label_str, 0, hfinfo, out, value_pos);
10666 }
10667}
10668
10669static void
10670fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10671{
10672 const header_field_info *hfinfo = fi->hfinfo;
10673 uint32_t value;
10674
10675 char buf[NUMBER_LABEL_LENGTH80];
10676 const char *out;
10677
10678 if (is_signed)
10679 value = fvalue_get_sinteger(fi->value);
10680 else
10681 value = fvalue_get_uinteger(fi->value);
10682
10683 /* Fill in the textual info */
10684 if (hfinfo->display == BASE_CUSTOM) {
10685 char tmp[ITEM_LABEL_LENGTH240];
10686 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10687
10688 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10688, "fmtfunc"))))
;
10689 fmtfunc(tmp, value);
10690 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10691 }
10692 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10693 /*
10694 * It makes no sense to have a value-string table for a
10695 * frame-number field - they're just integers giving
10696 * the ordinal frame number.
10697 */
10698 const char *val_str = hf_try_val_to_str(value, hfinfo);
10699
10700 out = hfinfo_number_vals_format(hfinfo, buf, value);
10701 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10702 /*
10703 * Unique values only display value_string string
10704 * if there is a match. Otherwise it's just a number
10705 */
10706 if (val_str) {
10707 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10708 } else {
10709 label_fill(label_str, 0, hfinfo, out, value_pos);
10710 }
10711 } else {
10712 if (val_str == NULL((void*)0))
10713 val_str = "Unknown";
10714
10715 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10716 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10717 else
10718 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10719 }
10720 }
10721 else if (IS_BASE_PORT(hfinfo->display)(((hfinfo->display)==BASE_PT_UDP||(hfinfo->display)==BASE_PT_TCP
||(hfinfo->display)==BASE_PT_DCCP||(hfinfo->display)==BASE_PT_SCTP
))
) {
10722 char tmp[ITEM_LABEL_LENGTH240];
10723
10724 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10725 display_to_port_type((field_display_e)hfinfo->display), value);
10726 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10727 }
10728 else {
10729 out = hfinfo_number_value_format(hfinfo, buf, value);
10730
10731 label_fill(label_str, 0, hfinfo, out, value_pos);
10732 }
10733}
10734
10735static void
10736fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10737{
10738 const header_field_info *hfinfo = fi->hfinfo;
10739 uint64_t value;
10740
10741 char buf[NUMBER_LABEL_LENGTH80];
10742 const char *out;
10743
10744 if (is_signed)
10745 value = fvalue_get_sinteger64(fi->value);
10746 else
10747 value = fvalue_get_uinteger64(fi->value);
10748
10749 /* Fill in the textual info */
10750 if (hfinfo->display == BASE_CUSTOM) {
10751 char tmp[ITEM_LABEL_LENGTH240];
10752 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10753
10754 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10754, "fmtfunc64"
))))
;
10755 fmtfunc64(tmp, value);
10756 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10757 }
10758 else if (hfinfo->strings) {
10759 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10760
10761 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10762 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10763 /*
10764 * Unique values only display value_string string
10765 * if there is a match. Otherwise it's just a number
10766 */
10767 if (val_str) {
10768 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10769 } else {
10770 label_fill(label_str, 0, hfinfo, out, value_pos);
10771 }
10772 } else {
10773 if (val_str == NULL((void*)0))
10774 val_str = "Unknown";
10775
10776 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10777 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10778 else
10779 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10780 }
10781 }
10782 else {
10783 out = hfinfo_number_value_format64(hfinfo, buf, value);
10784
10785 label_fill(label_str, 0, hfinfo, out, value_pos);
10786 }
10787}
10788
10789static size_t
10790fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10791{
10792 int display;
10793 int n;
10794 double value;
10795
10796 if (label_str_size < 12) {
10797 /* Not enough room to write an entire floating point value. */
10798 return 0;
10799 }
10800
10801 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10802 value = fvalue_get_floating(fi->value);
10803
10804 if (display == BASE_CUSTOM) {
10805 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10806 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10806, "fmtfunc"))))
;
10807 fmtfunc(label_str, value);
10808 return strlen(label_str);
10809 }
10810
10811 switch (display) {
10812 case BASE_NONE:
10813 if (fi->hfinfo->type == FT_FLOAT) {
10814 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10815 } else {
10816 n = (int)strlen(dtoa_g_fmt(label_str, value));
10817 }
10818 break;
10819 case BASE_DEC:
10820 n = snprintf(label_str, label_str_size, "%f", value);
10821 break;
10822 case BASE_HEX:
10823 n = snprintf(label_str, label_str_size, "%a", value);
10824 break;
10825 case BASE_EXP:
10826 n = snprintf(label_str, label_str_size, "%e", value);
10827 break;
10828 default:
10829 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10829
, __func__, "assertion \"not reached\" failed")
;
10830 }
10831 if (n < 0) {
10832 return 0; /* error */
10833 }
10834 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10835 const char *hf_str_val;
10836 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10837 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10838 }
10839 if (n > label_str_size) {
10840 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10840, __func__, "label length too small"); } } while (0)
;
10841 return strlen(label_str);
10842 }
10843
10844 return n;
10845}
10846
10847void
10848fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10849{
10850 char tmp[ITEM_LABEL_LENGTH240];
10851
10852 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10853 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10854}
10855
10856static size_t
10857fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10858{
10859 int display;
10860 size_t pos = 0;
10861 double value;
10862 char* tmp_str;
10863
10864 if (label_str_size < 12) {
10865 /* Not enough room to write an entire floating point value. */
10866 return 0;
10867 }
10868
10869 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10870 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10871 pos = label_concat(label_str, pos, tmp_str)ws_label_strcpy(label_str, 240, pos, tmp_str, 0);
10872 wmem_free(NULL((void*)0), tmp_str);
10873
10874 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10875 const char *hf_str_val;
10876 fvalue_to_double(fi->value, &value);
10877 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10878 pos = label_concat(label_str, pos, hf_str_val)ws_label_strcpy(label_str, 240, pos, hf_str_val, 0);
10879 }
10880 if ((int)pos > label_str_size) {
10881 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10881, __func__, "label length too small"); } } while (0)
;
10882 return strlen(label_str);
10883 }
10884
10885 return pos;
10886}
10887
10888void
10889fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
10890{
10891 char tmp[ITEM_LABEL_LENGTH240];
10892
10893 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
10894 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10895}
10896
10897int
10898hfinfo_bitshift(const header_field_info *hfinfo)
10899{
10900 return ws_ctz(hfinfo->bitmask);
10901}
10902
10903
10904static int
10905hfinfo_bitoffset(const header_field_info *hfinfo)
10906{
10907 if (!hfinfo->bitmask) {
10908 return 0;
10909 }
10910
10911 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
10912 * as the first bit */
10913 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
10914}
10915
10916static int
10917hfinfo_mask_bitwidth(const header_field_info *hfinfo)
10918{
10919 if (!hfinfo->bitmask) {
10920 return 0;
10921 }
10922
10923 /* ilog2 = first set bit, ctz = last set bit */
10924 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
10925}
10926
10927static int
10928hfinfo_type_bitwidth(enum ftenum type)
10929{
10930 int bitwidth = 0;
10931
10932 switch (type) {
10933 case FT_CHAR:
10934 case FT_UINT8:
10935 case FT_INT8:
10936 bitwidth = 8;
10937 break;
10938 case FT_UINT16:
10939 case FT_INT16:
10940 bitwidth = 16;
10941 break;
10942 case FT_UINT24:
10943 case FT_INT24:
10944 bitwidth = 24;
10945 break;
10946 case FT_UINT32:
10947 case FT_INT32:
10948 bitwidth = 32;
10949 break;
10950 case FT_UINT40:
10951 case FT_INT40:
10952 bitwidth = 40;
10953 break;
10954 case FT_UINT48:
10955 case FT_INT48:
10956 bitwidth = 48;
10957 break;
10958 case FT_UINT56:
10959 case FT_INT56:
10960 bitwidth = 56;
10961 break;
10962 case FT_UINT64:
10963 case FT_INT64:
10964 bitwidth = 64;
10965 break;
10966 default:
10967 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 10967))
;
10968 ;
10969 }
10970 return bitwidth;
10971}
10972
10973
10974static int
10975hfinfo_container_bitwidth(const header_field_info *hfinfo)
10976{
10977 if (!hfinfo->bitmask) {
10978 return 0;
10979 }
10980
10981 if (hfinfo->type == FT_BOOLEAN) {
10982 return hfinfo->display; /* hacky? :) */
10983 }
10984
10985 return hfinfo_type_bitwidth(hfinfo->type);
10986}
10987
10988static int
10989hfinfo_hex_digits(const header_field_info *hfinfo)
10990{
10991 int bitwidth;
10992
10993 /* If we have a bitmask, hfinfo->type is the width of the container, so not
10994 * appropriate to determine the number of hex digits for the field.
10995 * So instead, we compute it from the bitmask.
10996 */
10997 if (hfinfo->bitmask != 0) {
10998 bitwidth = hfinfo_mask_bitwidth(hfinfo);
10999 } else {
11000 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11001 }
11002
11003 /* Divide by 4, rounding up, to get number of hex digits. */
11004 return (bitwidth + 3) / 4;
11005}
11006
11007const char *
11008hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11009{
11010 char *ptr = &buf[6];
11011 static const char hex_digits[16] =
11012 { '0', '1', '2', '3', '4', '5', '6', '7',
11013 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11014
11015 *ptr = '\0';
11016 *(--ptr) = '\'';
11017 /* Properly format value */
11018 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11019 /*
11020 * Printable, so just show the character, and, if it needs
11021 * to be escaped, escape it.
11022 */
11023 *(--ptr) = value;
11024 if (value == '\\' || value == '\'')
11025 *(--ptr) = '\\';
11026 } else {
11027 /*
11028 * Non-printable; show it as an escape sequence.
11029 */
11030 switch (value) {
11031
11032 case '\0':
11033 /*
11034 * Show a NUL with only one digit.
11035 */
11036 *(--ptr) = '0';
11037 break;
11038
11039 case '\a':
11040 case '\b':
11041 case '\f':
11042 case '\n':
11043 case '\r':
11044 case '\t':
11045 case '\v':
11046 *(--ptr) = value - '\a' + 'a';
11047 break;
11048
11049 default:
11050 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11051
11052 case BASE_OCT:
11053 *(--ptr) = (value & 0x7) + '0';
11054 value >>= 3;
11055 *(--ptr) = (value & 0x7) + '0';
11056 value >>= 3;
11057 *(--ptr) = (value & 0x7) + '0';
11058 break;
11059
11060 case BASE_HEX:
11061 *(--ptr) = hex_digits[value & 0x0F];
11062 value >>= 4;
11063 *(--ptr) = hex_digits[value & 0x0F];
11064 *(--ptr) = 'x';
11065 break;
11066
11067 default:
11068 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11069 }
11070 }
11071 *(--ptr) = '\\';
11072 }
11073 *(--ptr) = '\'';
11074 return ptr;
11075}
11076
11077static const char *
11078hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11079{
11080 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11081 bool_Bool isint = FT_IS_INT(hfinfo->type)(((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
) || ((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
))
;
11082
11083 *ptr = '\0';
11084 /* Properly format value */
11085 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11086 case BASE_DEC:
11087 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11088
11089 case BASE_DEC_HEX:
11090 *(--ptr) = ')';
11091 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11092 *(--ptr) = '(';
11093 *(--ptr) = ' ';
11094 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11095 return ptr;
11096
11097 case BASE_OCT:
11098 return oct_to_str_back(ptr, value);
11099
11100 case BASE_HEX:
11101 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11102
11103 case BASE_HEX_DEC:
11104 *(--ptr) = ')';
11105 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11106 *(--ptr) = '(';
11107 *(--ptr) = ' ';
11108 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11109 return ptr;
11110
11111 case BASE_PT_UDP:
11112 case BASE_PT_TCP:
11113 case BASE_PT_DCCP:
11114 case BASE_PT_SCTP:
11115 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11116 display_to_port_type((field_display_e)display), value);
11117 return buf;
11118 case BASE_OUI:
11119 {
11120 uint8_t p_oui[3];
11121 const char *manuf_name;
11122
11123 p_oui[0] = value >> 16 & 0xFF;
11124 p_oui[1] = value >> 8 & 0xFF;
11125 p_oui[2] = value & 0xFF;
11126
11127 /* Attempt an OUI lookup. */
11128 manuf_name = uint_get_manuf_name_if_known(value);
11129 if (manuf_name == NULL((void*)0)) {
11130 /* Could not find an OUI. */
11131 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11132 }
11133 else {
11134 /* Found an address string. */
11135 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11136 }
11137 return buf;
11138 }
11139
11140 default:
11141 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11142 }
11143 return ptr;
11144}
11145
11146static const char *
11147hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11148{
11149 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11150 bool_Bool isint = FT_IS_INT(hfinfo->type)(((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
) || ((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
))
;
11151
11152 *ptr = '\0';
11153 /* Properly format value */
11154 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11155 case BASE_DEC:
11156 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11157
11158 case BASE_DEC_HEX:
11159 *(--ptr) = ')';
11160 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11161 *(--ptr) = '(';
11162 *(--ptr) = ' ';
11163 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11164 return ptr;
11165
11166 case BASE_OCT:
11167 return oct64_to_str_back(ptr, value);
11168
11169 case BASE_HEX:
11170 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11171
11172 case BASE_HEX_DEC:
11173 *(--ptr) = ')';
11174 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11175 *(--ptr) = '(';
11176 *(--ptr) = ' ';
11177 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11178 return ptr;
11179
11180 default:
11181 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11182 }
11183
11184 return ptr;
11185}
11186
11187static const char *
11188hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11189{
11190 int display = hfinfo->display;
11191
11192 if (hfinfo->type == FT_FRAMENUM) {
11193 /*
11194 * Frame numbers are always displayed in decimal.
11195 */
11196 display = BASE_DEC;
11197 }
11198
11199 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11200}
11201
11202static const char *
11203hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11204{
11205 int display = hfinfo->display;
11206
11207 if (hfinfo->type == FT_FRAMENUM) {
11208 /*
11209 * Frame numbers are always displayed in decimal.
11210 */
11211 display = BASE_DEC;
11212 }
11213
11214 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11215}
11216
11217static const char *
11218hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11219{
11220 /* Get the underlying BASE_ value */
11221 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11222
11223 return hfinfo_char_value_format_display(display, buf, value);
11224}
11225
11226static const char *
11227hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11228{
11229 /* Get the underlying BASE_ value */
11230 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11231
11232 if (hfinfo->type == FT_FRAMENUM) {
11233 /*
11234 * Frame numbers are always displayed in decimal.
11235 */
11236 display = BASE_DEC;
11237 }
11238
11239 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11240 display = BASE_DEC;
11241 } else if (display == BASE_OUI) {
11242 display = BASE_HEX;
11243 }
11244
11245 switch (display) {
11246 case BASE_NONE:
11247 /* case BASE_DEC: */
11248 case BASE_DEC_HEX:
11249 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11250 case BASE_CUSTOM:
11251 display = BASE_DEC;
11252 break;
11253
11254 /* case BASE_HEX: */
11255 case BASE_HEX_DEC:
11256 display = BASE_HEX;
11257 break;
11258 }
11259
11260 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11261}
11262
11263static const char *
11264hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11265{
11266 /* Get the underlying BASE_ value */
11267 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11268
11269 if (hfinfo->type == FT_FRAMENUM) {
11270 /*
11271 * Frame numbers are always displayed in decimal.
11272 */
11273 display = BASE_DEC;
11274 }
11275
11276 switch (display) {
11277 case BASE_NONE:
11278 /* case BASE_DEC: */
11279 case BASE_DEC_HEX:
11280 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11281 case BASE_CUSTOM:
11282 display = BASE_DEC;
11283 break;
11284
11285 /* case BASE_HEX: */
11286 case BASE_HEX_DEC:
11287 display = BASE_HEX;
11288 break;
11289 }
11290
11291 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11292}
11293
11294static const char *
11295hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11296{
11297 /* Get the underlying BASE_ value */
11298 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11299
11300 return hfinfo_char_value_format_display(display, buf, value);
11301}
11302
11303static const char *
11304hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11305{
11306 /* Get the underlying BASE_ value */
11307 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11308
11309 if (display == BASE_NONE)
11310 return NULL((void*)0);
11311
11312 if (display == BASE_DEC_HEX)
11313 display = BASE_DEC;
11314 if (display == BASE_HEX_DEC)
11315 display = BASE_HEX;
11316
11317 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11318}
11319
11320static const char *
11321hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11322{
11323 /* Get the underlying BASE_ value */
11324 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11325
11326 if (display == BASE_NONE)
11327 return NULL((void*)0);
11328
11329 if (display == BASE_DEC_HEX)
11330 display = BASE_DEC;
11331 if (display == BASE_HEX_DEC)
11332 display = BASE_HEX;
11333
11334 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11335}
11336
11337const char *
11338proto_registrar_get_name(const int n)
11339{
11340 header_field_info *hfinfo;
11341
11342 PROTO_REGISTRAR_GET_NTH(n, hfinfo)if((n == 0 || (unsigned)n > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11342
, __func__, "Unregistered hf! index=%d", n); ((void) ((n >
0 && (unsigned)n < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11342
, "n > 0 && (unsigned)n < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[n] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11342, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11343 return hfinfo->name;
11344}
11345
11346const char *
11347proto_registrar_get_abbrev(const int n)
11348{
11349 header_field_info *hfinfo;
11350
11351 PROTO_REGISTRAR_GET_NTH(n, hfinfo)if((n == 0 || (unsigned)n > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11351
, __func__, "Unregistered hf! index=%d", n); ((void) ((n >
0 && (unsigned)n < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11351
, "n > 0 && (unsigned)n < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[n] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11351, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11352 return hfinfo->abbrev;
11353}
11354
11355enum ftenum
11356proto_registrar_get_ftype(const int n)
11357{
11358 header_field_info *hfinfo;
11359
11360 PROTO_REGISTRAR_GET_NTH(n, hfinfo)if((n == 0 || (unsigned)n > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11360
, __func__, "Unregistered hf! index=%d", n); ((void) ((n >
0 && (unsigned)n < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11360
, "n > 0 && (unsigned)n < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[n] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11360, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11361 return hfinfo->type;
11362}
11363
11364int
11365proto_registrar_get_parent(const int n)
11366{
11367 header_field_info *hfinfo;
11368
11369 PROTO_REGISTRAR_GET_NTH(n, hfinfo)if((n == 0 || (unsigned)n > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11369
, __func__, "Unregistered hf! index=%d", n); ((void) ((n >
0 && (unsigned)n < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11369
, "n > 0 && (unsigned)n < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[n] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11369, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11370 return hfinfo->parent;
11371}
11372
11373bool_Bool
11374proto_registrar_is_protocol(const int n)
11375{
11376 header_field_info *hfinfo;
11377
11378 PROTO_REGISTRAR_GET_NTH(n, hfinfo)if((n == 0 || (unsigned)n > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11378
, __func__, "Unregistered hf! index=%d", n); ((void) ((n >
0 && (unsigned)n < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11378
, "n > 0 && (unsigned)n < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[n] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11378, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11379 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11380}
11381
11382/* Returns length of field in packet (not necessarily the length
11383 * in our internal representation, as in the case of IPv4).
11384 * 0 means undeterminable at time of registration
11385 * -1 means the field is not registered. */
11386int
11387proto_registrar_get_length(const int n)
11388{
11389 header_field_info *hfinfo;
11390
11391 PROTO_REGISTRAR_GET_NTH(n, hfinfo)if((n == 0 || (unsigned)n > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11391
, __func__, "Unregistered hf! index=%d", n); ((void) ((n >
0 && (unsigned)n < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11391
, "n > 0 && (unsigned)n < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[n] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11391, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11392 return ftype_wire_size(hfinfo->type);
11393}
11394
11395/* Looks for a protocol or a field in a proto_tree. Returns true if
11396 * it exists anywhere, or false if it exists nowhere. */
11397bool_Bool
11398proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11399{
11400 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11401
11402 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11403 return true1;
11404 }
11405 else {
11406 return false0;
11407 }
11408}
11409
11410/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11411 * This only works if the hfindex was "primed" before the dissection
11412 * took place, as we just pass back the already-created GPtrArray*.
11413 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11414 * handles that. */
11415GPtrArray *
11416proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11417{
11418 if (!tree)
11419 return NULL((void*)0);
11420
11421 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11422 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11423 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11424 else
11425 return NULL((void*)0);
11426}
11427
11428bool_Bool
11429proto_tracking_interesting_fields(const proto_tree *tree)
11430{
11431 GHashTable *interesting_hfids;
11432
11433 if (!tree)
11434 return false0;
11435
11436 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11437
11438 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11439}
11440
11441/* Helper struct for proto_find_info() and proto_all_finfos() */
11442typedef struct {
11443 GPtrArray *array;
11444 int id;
11445} ffdata_t;
11446
11447/* Helper function for proto_find_info() */
11448static bool_Bool
11449find_finfo(proto_node *node, void * data)
11450{
11451 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11452 if (fi && fi->hfinfo) {
11453 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11454 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11455 }
11456 }
11457
11458 /* Don't stop traversing. */
11459 return false0;
11460}
11461
11462/* Helper function for proto_find_first_info() */
11463static bool_Bool
11464find_first_finfo(proto_node *node, void *data)
11465{
11466 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11467 if (fi && fi->hfinfo) {
11468 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11469 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11470
11471 /* Stop traversing. */
11472 return true1;
11473 }
11474 }
11475
11476 /* Continue traversing. */
11477 return false0;
11478}
11479
11480/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11481* This works on any proto_tree, primed or unprimed, but actually searches
11482* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11483* The caller does need to free the returned GPtrArray with
11484* g_ptr_array_free(<array>, true).
11485*/
11486GPtrArray *
11487proto_find_finfo(proto_tree *tree, const int id)
11488{
11489 ffdata_t ffdata;
11490
11491 ffdata.array = g_ptr_array_new();
11492 ffdata.id = id;
11493
11494 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11495
11496 return ffdata.array;
11497}
11498
11499/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11500* This works on any proto_tree, primed or unprimed, but actually searches
11501* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11502* The caller does need to free the returned GPtrArray with
11503* g_ptr_array_free(<array>, true).
11504*/
11505GPtrArray *
11506proto_find_first_finfo(proto_tree *tree, const int id)
11507{
11508 ffdata_t ffdata;
11509
11510 ffdata.array = g_ptr_array_new();
11511 ffdata.id = id;
11512
11513 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11514
11515 return ffdata.array;
11516}
11517
11518/* Helper function for proto_all_finfos() */
11519static bool_Bool
11520every_finfo(proto_node *node, void * data)
11521{
11522 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11523 if (fi && fi->hfinfo) {
11524 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11525 }
11526
11527 /* Don't stop traversing. */
11528 return false0;
11529}
11530
11531/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11532 * The caller does need to free the returned GPtrArray with
11533 * g_ptr_array_free(<array>, true).
11534 */
11535GPtrArray *
11536proto_all_finfos(proto_tree *tree)
11537{
11538 ffdata_t ffdata;
11539
11540 /* Pre allocate enough space to hold all fields in most cases */
11541 ffdata.array = g_ptr_array_sized_new(512);
11542 ffdata.id = 0;
11543
11544 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11545
11546 return ffdata.array;
11547}
11548
11549
11550typedef struct {
11551 unsigned offset;
11552 field_info *finfo;
11553 tvbuff_t *tvb;
11554} offset_search_t;
11555
11556static bool_Bool
11557check_for_offset(proto_node *node, void * data)
11558{
11559 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11560 offset_search_t *offsearch = (offset_search_t *)data;
11561
11562 /* !fi == the top most container node which holds nothing */
11563 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11564 if (offsearch->offset >= (unsigned) fi->start &&
11565 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11566
11567 offsearch->finfo = fi;
11568 return false0; /* keep traversing */
11569 }
11570 }
11571 return false0; /* keep traversing */
11572}
11573
11574/* Search a proto_tree backwards (from leaves to root) looking for the field
11575 * whose start/length occupies 'offset' */
11576/* XXX - I couldn't find an easy way to search backwards, so I search
11577 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11578 * the one I want to return to the user. This algorithm is inefficient
11579 * and could be re-done, but I'd have to handle all the children and
11580 * siblings of each node myself. When I have more time I'll do that.
11581 * (yeah right) */
11582field_info *
11583proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11584{
11585 offset_search_t offsearch;
11586
11587 offsearch.offset = offset;
11588 offsearch.finfo = NULL((void*)0);
11589 offsearch.tvb = tvb;
11590
11591 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11592
11593 return offsearch.finfo;
11594}
11595
11596typedef struct {
11597 int length;
11598 char *buf;
11599} decoded_data_t;
11600
11601static bool_Bool
11602check_for_undecoded(proto_node *node, void * data)
11603{
11604 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11605 decoded_data_t* decoded = (decoded_data_t*)data;
11606 int i;
11607 unsigned byte;
11608 unsigned bit;
11609
11610 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11611 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11612 byte = i / 8;
11613 bit = i % 8;
11614 decoded->buf[byte] |= (1 << bit);
11615 }
11616 }
11617
11618 return false0;
11619}
11620
11621char*
11622proto_find_undecoded_data(proto_tree *tree, unsigned length)
11623{
11624 decoded_data_t decoded;
11625 decoded.length = length;
11626 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11627
11628 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11629 return decoded.buf;
11630}
11631
11632/* Dumps the protocols in the registration database to stdout. An independent
11633 * program can take this output and format it into nice tables or HTML or
11634 * whatever.
11635 *
11636 * There is one record per line. The fields are tab-delimited.
11637 *
11638 * Field 1 = protocol name
11639 * Field 2 = protocol short name
11640 * Field 3 = protocol filter name
11641 * Field 4 = protocol enabled
11642 * Field 5 = protocol enabled by default
11643 * Field 6 = protocol can toggle
11644 */
11645void
11646proto_registrar_dump_protocols(void)
11647{
11648 protocol_t *protocol;
11649 int i;
11650 void *cookie = NULL((void*)0);
11651
11652
11653 i = proto_get_first_protocol(&cookie);
11654 while (i != -1) {
11655 protocol = find_protocol_by_id(i);
11656 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11657 protocol->name,
11658 protocol->short_name,
11659 protocol->filter_name,
11660 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11661 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11662 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11663 i = proto_get_next_protocol(&cookie);
11664 }
11665}
11666
11667/* Dumps the value_strings, extended value string headers, range_strings
11668 * or true/false strings for fields that have them.
11669 * There is one record per line. Fields are tab-delimited.
11670 * There are four types of records: Value String, Extended Value String Header,
11671 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11672 * the type of record.
11673 *
11674 * Note that a record will be generated only if the value_string,... is referenced
11675 * in a registered hfinfo entry.
11676 *
11677 *
11678 * Value Strings
11679 * -------------
11680 * Field 1 = 'V'
11681 * Field 2 = Field abbreviation to which this value string corresponds
11682 * Field 3 = Integer value
11683 * Field 4 = String
11684 *
11685 * Extended Value String Headers
11686 * -----------------------------
11687 * Field 1 = 'E'
11688 * Field 2 = Field abbreviation to which this extended value string header corresponds
11689 * Field 3 = Extended Value String "Name"
11690 * Field 4 = Number of entries in the associated value_string array
11691 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11692 *
11693 * Range Strings
11694 * -------------
11695 * Field 1 = 'R'
11696 * Field 2 = Field abbreviation to which this range string corresponds
11697 * Field 3 = Integer value: lower bound
11698 * Field 4 = Integer value: upper bound
11699 * Field 5 = String
11700 *
11701 * True/False Strings
11702 * ------------------
11703 * Field 1 = 'T'
11704 * Field 2 = Field abbreviation to which this true/false string corresponds
11705 * Field 3 = True String
11706 * Field 4 = False String
11707 */
11708void
11709proto_registrar_dump_values(void)
11710{
11711 header_field_info *hfinfo;
11712 int i, len, vi;
11713 const value_string *vals;
11714 const val64_string *vals64;
11715 const range_string *range;
11716 const true_false_string *tfs;
11717 const unit_name_string *units;
11718
11719 len = gpa_hfinfo.len;
11720 for (i = 0; i < len ; i++) {
11721 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11722 continue; /* This is a deregistered protocol or field */
11723
11724 PROTO_REGISTRAR_GET_NTH(i, hfinfo)if((i == 0 || (unsigned)i > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11724
, __func__, "Unregistered hf! index=%d", i); ((void) ((i >
0 && (unsigned)i < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11724
, "i > 0 && (unsigned)i < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[i] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11724, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11725
11726 if (hfinfo->id == hf_text_only) {
11727 continue;
11728 }
11729
11730 /* ignore protocols */
11731 if (proto_registrar_is_protocol(i)) {
11732 continue;
11733 }
11734 /* process header fields */
11735#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11736 /*
11737 * If this field isn't at the head of the list of
11738 * fields with this name, skip this field - all
11739 * fields with the same name are really just versions
11740 * of the same field stored in different bits, and
11741 * should have the same type/radix/value list, and
11742 * just differ in their bit masks. (If a field isn't
11743 * a bitfield, but can be, say, 1 or 2 bytes long,
11744 * it can just be made FT_UINT16, meaning the
11745 * *maximum* length is 2 bytes, and be used
11746 * for all lengths.)
11747 */
11748 if (hfinfo->same_name_prev_id != -1)
11749 continue;
11750#endif
11751 vals = NULL((void*)0);
11752 vals64 = NULL((void*)0);
11753 range = NULL((void*)0);
11754 tfs = NULL((void*)0);
11755 units = NULL((void*)0);
11756
11757 if (hfinfo->strings != NULL((void*)0)) {
11758 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11759 (hfinfo->type == FT_CHAR ||
11760 hfinfo->type == FT_UINT8 ||
11761 hfinfo->type == FT_UINT16 ||
11762 hfinfo->type == FT_UINT24 ||
11763 hfinfo->type == FT_UINT32 ||
11764 hfinfo->type == FT_UINT40 ||
11765 hfinfo->type == FT_UINT48 ||
11766 hfinfo->type == FT_UINT56 ||
11767 hfinfo->type == FT_UINT64 ||
11768 hfinfo->type == FT_INT8 ||
11769 hfinfo->type == FT_INT16 ||
11770 hfinfo->type == FT_INT24 ||
11771 hfinfo->type == FT_INT32 ||
11772 hfinfo->type == FT_INT40 ||
11773 hfinfo->type == FT_INT48 ||
11774 hfinfo->type == FT_INT56 ||
11775 hfinfo->type == FT_INT64 ||
11776 hfinfo->type == FT_FLOAT ||
11777 hfinfo->type == FT_DOUBLE)) {
11778
11779 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11780 range = (const range_string *)hfinfo->strings;
11781 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11782 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11783 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11784 } else {
11785 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11786 }
11787 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11788 vals64 = (const val64_string *)hfinfo->strings;
11789 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11790 units = (const unit_name_string *)hfinfo->strings;
11791 } else {
11792 vals = (const value_string *)hfinfo->strings;
11793 }
11794 }
11795 else if (hfinfo->type == FT_BOOLEAN) {
11796 tfs = (const struct true_false_string *)hfinfo->strings;
11797 }
11798 }
11799
11800 /* Print value strings? */
11801 if (vals) {
11802 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11803 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11804 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11805 if (!val64_string_ext_validate(vse_p)) {
11806 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11806, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11807 continue;
11808 }
11809 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11810 printf("E\t%s\t%u\t%s\t%s\n",
11811 hfinfo->abbrev,
11812 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11813 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11814 val64_string_ext_match_type_str(vse_p));
11815 } else {
11816 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11817 if (!value_string_ext_validate(vse_p)) {
11818 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11818, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11819 continue;
11820 }
11821 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11822 printf("E\t%s\t%u\t%s\t%s\n",
11823 hfinfo->abbrev,
11824 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11825 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11826 value_string_ext_match_type_str(vse_p));
11827 }
11828 }
11829 vi = 0;
11830 while (vals[vi].strptr) {
11831 /* Print in the proper base */
11832 if (hfinfo->type == FT_CHAR) {
11833 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11834 printf("V\t%s\t'%c'\t%s\n",
11835 hfinfo->abbrev,
11836 vals[vi].value,
11837 vals[vi].strptr);
11838 } else {
11839 if (hfinfo->display == BASE_HEX) {
11840 printf("V\t%s\t'\\x%02x'\t%s\n",
11841 hfinfo->abbrev,
11842 vals[vi].value,
11843 vals[vi].strptr);
11844 }
11845 else {
11846 printf("V\t%s\t'\\%03o'\t%s\n",
11847 hfinfo->abbrev,
11848 vals[vi].value,
11849 vals[vi].strptr);
11850 }
11851 }
11852 } else {
11853 if (hfinfo->display == BASE_HEX) {
11854 printf("V\t%s\t0x%x\t%s\n",
11855 hfinfo->abbrev,
11856 vals[vi].value,
11857 vals[vi].strptr);
11858 }
11859 else {
11860 printf("V\t%s\t%u\t%s\n",
11861 hfinfo->abbrev,
11862 vals[vi].value,
11863 vals[vi].strptr);
11864 }
11865 }
11866 vi++;
11867 }
11868 }
11869 else if (vals64) {
11870 vi = 0;
11871 while (vals64[vi].strptr) {
11872 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11873 hfinfo->abbrev,
11874 vals64[vi].value,
11875 vals64[vi].strptr);
11876 vi++;
11877 }
11878 }
11879
11880 /* print range strings? */
11881 else if (range) {
11882 vi = 0;
11883 while (range[vi].strptr) {
11884 /* Print in the proper base */
11885 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
11886 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
11887 hfinfo->abbrev,
11888 range[vi].value_min,
11889 range[vi].value_max,
11890 range[vi].strptr);
11891 }
11892 else {
11893 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
11894 hfinfo->abbrev,
11895 range[vi].value_min,
11896 range[vi].value_max,
11897 range[vi].strptr);
11898 }
11899 vi++;
11900 }
11901 }
11902
11903 /* Print true/false strings? */
11904 else if (tfs) {
11905 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
11906 tfs->true_string, tfs->false_string);
11907 }
11908 /* Print unit strings? */
11909 else if (units) {
11910 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
11911 units->singular, units->plural ? units->plural : "(no plural)");
11912 }
11913 }
11914}
11915
11916/* Prints the number of registered fields.
11917 * Useful for determining an appropriate value for
11918 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
11919 *
11920 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
11921 * the number of fields, true otherwise.
11922 */
11923bool_Bool
11924proto_registrar_dump_fieldcount(void)
11925{
11926 uint32_t i;
11927 header_field_info *hfinfo;
11928 uint32_t deregistered_count = 0;
11929 uint32_t same_name_count = 0;
11930 uint32_t protocol_count = 0;
11931
11932 for (i = 0; i < gpa_hfinfo.len; i++) {
11933 if (gpa_hfinfo.hfi[i] == NULL((void*)0)) {
11934 deregistered_count++;
11935 continue; /* This is a deregistered protocol or header field */
11936 }
11937
11938 PROTO_REGISTRAR_GET_NTH(i, hfinfo)if((i == 0 || (unsigned)i > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11938
, __func__, "Unregistered hf! index=%d", i); ((void) ((i >
0 && (unsigned)i < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11938
, "i > 0 && (unsigned)i < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[i] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11938, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11939
11940 if (proto_registrar_is_protocol(i))
11941 protocol_count++;
11942
11943 if (hfinfo->same_name_prev_id != -1)
11944 same_name_count++;
11945 }
11946
11947 printf("There are %u header fields registered, of which:\n"
11948 "\t%u are deregistered\n"
11949 "\t%u are protocols\n"
11950 "\t%u have the same name as another field\n\n",
11951 gpa_hfinfo.len, deregistered_count, protocol_count,
11952 same_name_count);
11953
11954 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
11955 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
11956 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
11957 "\n");
11958
11959 printf("The header field table consumes %u KiB of memory.\n",
11960 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
11961 printf("The fields themselves consume %u KiB of memory.\n",
11962 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
11963
11964 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
11965}
11966
11967static void
11968elastic_add_base_mapping(json_dumper *dumper)
11969{
11970 json_dumper_set_member_name(dumper, "index_patterns");
11971 json_dumper_begin_array(dumper);
11972 // The index names from write_json_index() in print.c
11973 json_dumper_value_string(dumper, "packets-*");
11974 json_dumper_end_array(dumper);
11975
11976 json_dumper_set_member_name(dumper, "settings");
11977 json_dumper_begin_object(dumper);
11978 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
11979 json_dumper_value_anyf(dumper, "%d", 1000000);
11980 json_dumper_end_object(dumper);
11981}
11982
11983static char*
11984ws_type_to_elastic(unsigned type)
11985{
11986 switch(type) {
11987 case FT_INT8:
11988 return "byte";
11989 case FT_UINT8:
11990 case FT_INT16:
11991 return "short";
11992 case FT_UINT16:
11993 case FT_INT32:
11994 case FT_UINT24:
11995 case FT_INT24:
11996 return "integer";
11997 case FT_FRAMENUM:
11998 case FT_UINT32:
11999 case FT_UINT40:
12000 case FT_UINT48:
12001 case FT_UINT56:
12002 case FT_INT40:
12003 case FT_INT48:
12004 case FT_INT56:
12005 case FT_INT64:
12006 return "long";
12007 case FT_UINT64:
12008 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12009 case FT_FLOAT:
12010 return "float";
12011 case FT_DOUBLE:
12012 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12013 return "double";
12014 case FT_IPv6:
12015 case FT_IPv4:
12016 return "ip";
12017 case FT_ABSOLUTE_TIME:
12018 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12019 case FT_BOOLEAN:
12020 return "boolean";
12021 default:
12022 return NULL((void*)0);
12023 }
12024}
12025
12026static char*
12027dot_to_underscore(char* str)
12028{
12029 unsigned i;
12030 for (i = 0; i < strlen(str); i++) {
12031 if (str[i] == '.')
12032 str[i] = '_';
12033 }
12034 return str;
12035}
12036
12037/* Dumps a mapping file for ElasticSearch
12038 * This is the v1 (legacy) _template API.
12039 * At some point it may need to be updated with the composable templates
12040 * introduced in Elasticsearch 7.8 (_index_template)
12041 */
12042void
12043proto_registrar_dump_elastic(const char* filter)
12044{
12045 header_field_info *hfinfo;
12046 header_field_info *parent_hfinfo;
12047 unsigned i;
12048 bool_Bool open_object = true1;
12049 const char* prev_proto = NULL((void*)0);
12050 char* str;
12051 char** protos = NULL((void*)0);
12052 char* proto;
12053 bool_Bool found;
12054 unsigned j;
12055 char* type;
12056 char* prev_item = NULL((void*)0);
12057
12058 /* We have filtering protocols. Extract them. */
12059 if (filter) {
12060 protos = g_strsplit(filter, ",", -1);
12061 }
12062
12063 /*
12064 * To help tracking down the json tree, objects have been appended with a comment:
12065 * n.label -> where n is the indentation level and label the name of the object
12066 */
12067
12068 json_dumper dumper = {
12069 .output_file = stdoutstdout,
12070 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12071 };
12072 json_dumper_begin_object(&dumper); // 1.root
12073 elastic_add_base_mapping(&dumper);
12074
12075 json_dumper_set_member_name(&dumper, "mappings");
12076 json_dumper_begin_object(&dumper); // 2.mappings
12077
12078 json_dumper_set_member_name(&dumper, "properties");
12079 json_dumper_begin_object(&dumper); // 3.properties
12080 json_dumper_set_member_name(&dumper, "timestamp");
12081 json_dumper_begin_object(&dumper); // 4.timestamp
12082 json_dumper_set_member_name(&dumper, "type");
12083 json_dumper_value_string(&dumper, "date");
12084 json_dumper_end_object(&dumper); // 4.timestamp
12085
12086 json_dumper_set_member_name(&dumper, "layers");
12087 json_dumper_begin_object(&dumper); // 4.layers
12088 json_dumper_set_member_name(&dumper, "properties");
12089 json_dumper_begin_object(&dumper); // 5.properties
12090
12091 for (i = 0; i < gpa_hfinfo.len; i++) {
12092 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12093 continue; /* This is a deregistered protocol or header field */
12094
12095 PROTO_REGISTRAR_GET_NTH(i, hfinfo)if((i == 0 || (unsigned)i > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 12095
, __func__, "Unregistered hf! index=%d", i); ((void) ((i >
0 && (unsigned)i < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 12095
, "i > 0 && (unsigned)i < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[i] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 12095, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12096
12097 /*
12098 * Skip the pseudo-field for "proto_tree_add_text()" since
12099 * we don't want it in the list of filterable protocols.
12100 */
12101 if (hfinfo->id == hf_text_only)
12102 continue;
12103
12104 if (!proto_registrar_is_protocol(i)) {
12105 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo)if((hfinfo->parent == 0 || (unsigned)hfinfo->parent >
gpa_hfinfo.len) && wireshark_abort_on_dissector_bug)
ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 12105
, __func__, "Unregistered hf! index=%d", hfinfo->parent); (
(void) ((hfinfo->parent > 0 && (unsigned)hfinfo
->parent < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 12105
, "hfinfo->parent > 0 && (unsigned)hfinfo->parent < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
parent] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 12105
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12106
12107 /*
12108 * Skip the field if filter protocols have been set and this one's
12109 * parent is not listed.
12110 */
12111 if (protos) {
12112 found = false0;
12113 j = 0;
12114 proto = protos[0];
12115 while(proto) {
12116 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12117 found = true1;
12118 break;
12119 }
12120 j++;
12121 proto = protos[j];
12122 }
12123 if (!found)
12124 continue;
12125 }
12126
12127 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12128 json_dumper_end_object(&dumper); // 7.properties
12129 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12130 open_object = true1;
12131 }
12132
12133 prev_proto = parent_hfinfo->abbrev;
12134
12135 if (open_object) {
12136 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12137 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12138 json_dumper_set_member_name(&dumper, "properties");
12139 json_dumper_begin_object(&dumper); // 7.properties
12140 open_object = false0;
12141 }
12142 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12143 type = ws_type_to_elastic(hfinfo->type);
12144 /* when type is NULL, we have the default mapping: string */
12145 if (type) {
12146 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12147 dot_to_underscore(str);
12148 if (g_strcmp0(prev_item, str)) {
12149 json_dumper_set_member_name(&dumper, str);
12150 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12151 json_dumper_set_member_name(&dumper, "type");
12152 json_dumper_value_string(&dumper, type);
12153 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12154 }
12155 g_free(prev_item);
12156 prev_item = str;
12157 }
12158 }
12159 }
12160 g_free(prev_item);
12161
12162 if (prev_proto) {
12163 json_dumper_end_object(&dumper); // 7.properties
12164 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12165 }
12166
12167 json_dumper_end_object(&dumper); // 5.properties
12168 json_dumper_end_object(&dumper); // 4.layers
12169 json_dumper_end_object(&dumper); // 3.properties
12170 json_dumper_end_object(&dumper); // 2.mappings
12171 json_dumper_end_object(&dumper); // 1.root
12172 bool_Bool ret = json_dumper_finish(&dumper);
12173 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12173, "ret"))))
;
12174
12175 g_strfreev(protos);
12176}
12177
12178/* Dumps the contents of the registration database to stdout. An independent
12179 * program can take this output and format it into nice tables or HTML or
12180 * whatever.
12181 *
12182 * There is one record per line. Each record is either a protocol or a header
12183 * field, differentiated by the first field. The fields are tab-delimited.
12184 *
12185 * Protocols
12186 * ---------
12187 * Field 1 = 'P'
12188 * Field 2 = descriptive protocol name
12189 * Field 3 = protocol abbreviation
12190 *
12191 * Header Fields
12192 * -------------
12193 * Field 1 = 'F'
12194 * Field 2 = descriptive field name
12195 * Field 3 = field abbreviation
12196 * Field 4 = type ( textual representation of the ftenum type )
12197 * Field 5 = parent protocol abbreviation
12198 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12199 * Field 7 = bitmask: format: hex: 0x....
12200 * Field 8 = blurb describing field
12201 */
12202void
12203proto_registrar_dump_fields(void)
12204{
12205 header_field_info *hfinfo, *parent_hfinfo;
12206 int i, len;
12207 const char *enum_name;
12208 const char *base_name;
12209 const char *blurb;
12210 char width[5];
12211
12212 len = gpa_hfinfo.len;
12213 for (i = 0; i < len ; i++) {
12214 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12215 continue; /* This is a deregistered protocol or header field */
12216
12217 PROTO_REGISTRAR_GET_NTH(i, hfinfo)if((i == 0 || (unsigned)i > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 12217
, __func__, "Unregistered hf! index=%d", i); ((void) ((i >
0 && (unsigned)i < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 12217
, "i > 0 && (unsigned)i < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[i] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 12217, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12218
12219 /*
12220 * Skip the pseudo-field for "proto_tree_add_text()" since
12221 * we don't want it in the list of filterable fields.
12222 */
12223 if (hfinfo->id == hf_text_only)
12224 continue;
12225
12226 /* format for protocols */
12227 if (proto_registrar_is_protocol(i)) {
12228 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12229 }
12230 /* format for header fields */
12231 else {
12232 /*
12233 * If this field isn't at the head of the list of
12234 * fields with this name, skip this field - all
12235 * fields with the same name are really just versions
12236 * of the same field stored in different bits, and
12237 * should have the same type/radix/value list, and
12238 * just differ in their bit masks. (If a field isn't
12239 * a bitfield, but can be, say, 1 or 2 bytes long,
12240 * it can just be made FT_UINT16, meaning the
12241 * *maximum* length is 2 bytes, and be used
12242 * for all lengths.)
12243 */
12244 if (hfinfo->same_name_prev_id != -1)
12245 continue;
12246
12247 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo)if((hfinfo->parent == 0 || (unsigned)hfinfo->parent >
gpa_hfinfo.len) && wireshark_abort_on_dissector_bug)
ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 12247
, __func__, "Unregistered hf! index=%d", hfinfo->parent); (
(void) ((hfinfo->parent > 0 && (unsigned)hfinfo
->parent < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 12247
, "hfinfo->parent > 0 && (unsigned)hfinfo->parent < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
parent] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 12247
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12248
12249 enum_name = ftype_name(hfinfo->type);
12250 base_name = "";
12251
12252 if (hfinfo->type == FT_CHAR ||
12253 hfinfo->type == FT_UINT8 ||
12254 hfinfo->type == FT_UINT16 ||
12255 hfinfo->type == FT_UINT24 ||
12256 hfinfo->type == FT_UINT32 ||
12257 hfinfo->type == FT_UINT40 ||
12258 hfinfo->type == FT_UINT48 ||
12259 hfinfo->type == FT_UINT56 ||
12260 hfinfo->type == FT_UINT64 ||
12261 hfinfo->type == FT_INT8 ||
12262 hfinfo->type == FT_INT16 ||
12263 hfinfo->type == FT_INT24 ||
12264 hfinfo->type == FT_INT32 ||
12265 hfinfo->type == FT_INT40 ||
12266 hfinfo->type == FT_INT48 ||
12267 hfinfo->type == FT_INT56 ||
12268 hfinfo->type == FT_INT64) {
12269
12270 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12271 case BASE_NONE:
12272 case BASE_DEC:
12273 case BASE_HEX:
12274 case BASE_OCT:
12275 case BASE_DEC_HEX:
12276 case BASE_HEX_DEC:
12277 case BASE_CUSTOM:
12278 case BASE_PT_UDP:
12279 case BASE_PT_TCP:
12280 case BASE_PT_DCCP:
12281 case BASE_PT_SCTP:
12282 case BASE_OUI:
12283 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12284 break;
12285 default:
12286 base_name = "????";
12287 break;
12288 }
12289 } else if (hfinfo->type == FT_BOOLEAN) {
12290 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12291 snprintf(width, sizeof(width), "%d", hfinfo->display);
12292 base_name = width;
12293 }
12294
12295 blurb = hfinfo->blurb;
12296 if (blurb == NULL((void*)0))
12297 blurb = "";
12298 else if (strlen(blurb) == 0)
12299 blurb = "\"\"";
12300
12301 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12302 hfinfo->name, hfinfo->abbrev, enum_name,
12303 parent_hfinfo->abbrev, base_name,
12304 hfinfo->bitmask, blurb);
12305 }
12306 }
12307}
12308
12309/* Dumps all abbreviated field and protocol completions of the given string to
12310 * stdout. An independent program may use this for command-line tab completion
12311 * of fields.
12312 */
12313bool_Bool
12314proto_registrar_dump_field_completions(const char *prefix)
12315{
12316 header_field_info *hfinfo;
12317 int i, len;
12318 size_t prefix_len;
12319 bool_Bool matched = false0;
12320
12321 prefix_len = strlen(prefix);
12322 len = gpa_hfinfo.len;
12323 for (i = 0; i < len ; i++) {
12324 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12325 continue; /* This is a deregistered protocol or header field */
12326
12327 PROTO_REGISTRAR_GET_NTH(i, hfinfo)if((i == 0 || (unsigned)i > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 12327
, __func__, "Unregistered hf! index=%d", i); ((void) ((i >
0 && (unsigned)i < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 12327
, "i > 0 && (unsigned)i < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[i] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 12327, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12328
12329 /*
12330 * Skip the pseudo-field for "proto_tree_add_text()" since
12331 * we don't want it in the list of filterable fields.
12332 */
12333 if (hfinfo->id == hf_text_only)
12334 continue;
12335
12336 /* format for protocols */
12337 if (proto_registrar_is_protocol(i)) {
12338 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12339 matched = true1;
12340 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12341 }
12342 }
12343 /* format for header fields */
12344 else {
12345 /*
12346 * If this field isn't at the head of the list of
12347 * fields with this name, skip this field - all
12348 * fields with the same name are really just versions
12349 * of the same field stored in different bits, and
12350 * should have the same type/radix/value list, and
12351 * just differ in their bit masks. (If a field isn't
12352 * a bitfield, but can be, say, 1 or 2 bytes long,
12353 * it can just be made FT_UINT16, meaning the
12354 * *maximum* length is 2 bytes, and be used
12355 * for all lengths.)
12356 */
12357 if (hfinfo->same_name_prev_id != -1)
12358 continue;
12359
12360 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12361 matched = true1;
12362 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12363 }
12364 }
12365 }
12366 return matched;
12367}
12368
12369/* Dumps field types and descriptive names to stdout. An independent
12370 * program can take this output and format it into nice tables or HTML or
12371 * whatever.
12372 *
12373 * There is one record per line. The fields are tab-delimited.
12374 *
12375 * Field 1 = field type name, e.g. FT_UINT8
12376 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12377 */
12378void
12379proto_registrar_dump_ftypes(void)
12380{
12381 int fte;
12382
12383 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12384 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12385 }
12386}
12387
12388/* This function indicates whether it's possible to construct a
12389 * "match selected" display filter string for the specified field,
12390 * returns an indication of whether it's possible, and, if it's
12391 * possible and "filter" is non-null, constructs the filter and
12392 * sets "*filter" to point to it.
12393 * You do not need to [g_]free() this string since it will be automatically
12394 * freed once the next packet is dissected.
12395 */
12396static bool_Bool
12397construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12398 char **filter)
12399{
12400 const header_field_info *hfinfo;
12401 char *ptr;
12402 int buf_len;
12403 int i;
12404 int start, length, length_remaining;
12405 uint8_t c;
12406
12407 if (!finfo)
12408 return false0;
12409
12410 hfinfo = finfo->hfinfo;
12411 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12411, "hfinfo"))))
;
12412
12413 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12414 * then "the numeric value ... is not used when preparing
12415 * filters for the field in question." If it's any other
12416 * base, we'll generate the filter normally (which will
12417 * be numeric, even though the human-readable string does
12418 * work for filtering.)
12419 *
12420 * XXX - It might be nice to use fvalue_to_string_repr() in
12421 * "proto_item_fill_label()" as well, although, there, you'd
12422 * have to deal with the base *and* with resolved values for
12423 * addresses.
12424 *
12425 * Perhaps in addition to taking the repr type (DISPLAY
12426 * or DFILTER) and the display (base), fvalue_to_string_repr()
12427 * should have the the "strings" values in the header_field_info
12428 * structure for the field as a parameter, so it can have
12429 * if the field is Boolean or an enumerated integer type,
12430 * the tables used to generate human-readable values.
12431 */
12432 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12433 const char *str = NULL((void*)0);
12434
12435 switch (hfinfo->type) {
12436
12437 case FT_INT8:
12438 case FT_INT16:
12439 case FT_INT24:
12440 case FT_INT32:
12441 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12442 break;
12443
12444 case FT_CHAR:
12445 case FT_UINT8:
12446 case FT_UINT16:
12447 case FT_UINT24:
12448 case FT_UINT32:
12449 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12450 break;
12451
12452 default:
12453 break;
12454 }
12455
12456 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12457 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12458 return true1;
12459 }
12460 }
12461
12462 switch (hfinfo->type) {
12463
12464 case FT_PROTOCOL:
12465 if (filter != NULL((void*)0))
12466 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12467 break;
12468
12469 case FT_NONE:
12470 /*
12471 * If the length is 0, just match the name of the
12472 * field.
12473 *
12474 * (Also check for negative values, just in case,
12475 * as we'll cast it to an unsigned value later.)
12476 */
12477 length = finfo->length;
12478 if (length == 0) {
12479 if (filter != NULL((void*)0))
12480 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12481 break;
12482 }
12483 if (length < 0)
12484 return false0;
12485
12486 /*
12487 * This doesn't have a value, so we'd match
12488 * on the raw bytes at this address.
12489 *
12490 * Should we be allowed to access to the raw bytes?
12491 * If "edt" is NULL, the answer is "no".
12492 */
12493 if (edt == NULL((void*)0))
12494 return false0;
12495
12496 /*
12497 * Is this field part of the raw frame tvbuff?
12498 * If not, we can't use "frame[N:M]" to match
12499 * it.
12500 *
12501 * XXX - should this be frame-relative, or
12502 * protocol-relative?
12503 *
12504 * XXX - does this fallback for non-registered
12505 * fields even make sense?
12506 */
12507 if (finfo->ds_tvb != edt->tvb)
12508 return false0; /* you lose */
12509
12510 /*
12511 * Don't go past the end of that tvbuff.
12512 */
12513 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12514 if (length > length_remaining)
12515 length = length_remaining;
12516 if (length <= 0)
12517 return false0;
12518
12519 if (filter != NULL((void*)0)) {
12520 start = finfo->start;
12521 buf_len = 32 + length * 3;
12522 *filter = (char *)wmem_alloc0(NULL((void*)0), buf_len);
12523 ptr = *filter;
12524
12525 ptr += snprintf(ptr, buf_len-(ptr-*filter),
12526 "frame[%d:%d] == ", finfo->start, length);
12527 for (i=0; i<length; i++) {
12528 c = tvb_get_uint8(finfo->ds_tvb, start);
12529 start++;
12530 if (i == 0 ) {
12531 ptr += snprintf(ptr, buf_len-(ptr-*filter), "%02x", c);
12532 }
12533 else {
12534 ptr += snprintf(ptr, buf_len-(ptr-*filter), ":%02x", c);
12535 }
12536 }
12537 }
12538 break;
12539
12540 /* By default, use the fvalue's "to_string_repr" method. */
12541 default:
12542 if (filter != NULL((void*)0)) {
12543 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12544 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12545 wmem_free(NULL((void*)0), str);
12546 }
12547 break;
12548 }
12549
12550 return true1;
12551}
12552
12553/*
12554 * Returns true if we can do a "match selected" on the field, false
12555 * otherwise.
12556 */
12557bool_Bool
12558proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12559{
12560 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12561}
12562
12563/* This function attempts to construct a "match selected" display filter
12564 * string for the specified field; if it can do so, it returns a pointer
12565 * to the string, otherwise it returns NULL.
12566 *
12567 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12568 */
12569char *
12570proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12571{
12572 char *filter = NULL((void*)0);
12573
12574 if (!construct_match_selected_string(finfo, edt, &filter))
12575 {
12576 wmem_free(NULL((void*)0), filter);
12577 return NULL((void*)0);
12578 }
12579 return filter;
12580}
12581
12582/* This function is common code for all proto_tree_add_bitmask... functions.
12583 */
12584
12585static bool_Bool
12586proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12587 const int len, const int ett, int * const *fields,
12588 const int flags, bool_Bool first,
12589 bool_Bool use_parent_tree,
12590 proto_tree* tree, uint64_t value)
12591{
12592 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12593 uint64_t bitmask = 0;
12594 uint64_t tmpval;
12595 header_field_info *hf;
12596 uint32_t integer32;
12597 int bit_offset;
12598 int no_of_bits;
12599
12600 if (!*fields)
12601 REPORT_DISSECTOR_BUG("Illegal call of proto_item_add_bitmask_tree without fields")proto_report_dissector_bug("Illegal call of proto_item_add_bitmask_tree without fields"
)
;
12602
12603 if (len < 0 || len > 8)
12604 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12605 /**
12606 * packet-frame.c uses len=0 since the value is taken from the packet
12607 * metadata, not the packet bytes. In that case, assume that all bits
12608 * in the provided value are valid.
12609 */
12610 if (len > 0) {
12611 available_bits >>= (8 - (unsigned)len)*8;
12612 }
12613
12614 if (use_parent_tree == false0)
12615 tree = proto_item_add_subtree(item, ett);
12616
12617 while (*fields) {
12618 uint64_t present_bits;
12619 PROTO_REGISTRAR_GET_NTH(**fields,hf)if((**fields == 0 || (unsigned)**fields > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 12619, __func__, "Unregistered hf! index=%d"
, **fields); ((void) ((**fields > 0 && (unsigned)*
*fields < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 12619
, "**fields > 0 && (unsigned)**fields < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[**fields]
!= ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 12619, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12620 DISSECTOR_ASSERT_HINT(hf->bitmask != 0, hf->abbrev)((void) ((hf->bitmask != 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 12620
, "hf->bitmask != 0", hf->abbrev))))
;
12621
12622 bitmask |= hf->bitmask;
12623
12624 /* Skip fields that aren't fully present */
12625 present_bits = available_bits & hf->bitmask;
12626 if (present_bits != hf->bitmask) {
12627 fields++;
12628 continue;
12629 }
12630
12631 switch (hf->type) {
12632 case FT_CHAR:
12633 case FT_UINT8:
12634 case FT_UINT16:
12635 case FT_UINT24:
12636 case FT_UINT32:
12637 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12638 break;
12639
12640 case FT_INT8:
12641 case FT_INT16:
12642 case FT_INT24:
12643 case FT_INT32:
12644 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12645 break;
12646
12647 case FT_UINT40:
12648 case FT_UINT48:
12649 case FT_UINT56:
12650 case FT_UINT64:
12651 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12652 break;
12653
12654 case FT_INT40:
12655 case FT_INT48:
12656 case FT_INT56:
12657 case FT_INT64:
12658 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12659 break;
12660
12661 case FT_BOOLEAN:
12662 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12663 break;
12664
12665 default:
12666 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()",proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()"
, hf->abbrev, hf->type, ftype_name(hf->type))
12667 hf->abbrev,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()"
, hf->abbrev, hf->type, ftype_name(hf->type))
12668 hf->type,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()"
, hf->abbrev, hf->type, ftype_name(hf->type))
12669 ftype_name(hf->type))proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()"
, hf->abbrev, hf->type, ftype_name(hf->type))
;
12670 break;
12671 }
12672 if (flags & BMT_NO_APPEND0x01) {
12673 fields++;
12674 continue;
12675 }
12676 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12677
12678 /* XXX: README.developer and the comments have always defined
12679 * BMT_NO_INT as "only boolean flags are added to the title /
12680 * don't add non-boolean (integral) fields", but the
12681 * implementation has always added BASE_CUSTOM and fields with
12682 * value_strings, though not fields with unit_strings.
12683 * Possibly this is because some dissectors use a FT_UINT8
12684 * with a value_string for fields that should be a FT_BOOLEAN.
12685 */
12686 switch (hf->type) {
12687 case FT_CHAR:
12688 if (hf->display == BASE_CUSTOM) {
12689 char lbl[ITEM_LABEL_LENGTH240];
12690 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12691
12692 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12692, "fmtfunc"))))
;
12693 fmtfunc(lbl, (uint32_t) tmpval);
12694 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12695 hf->name, lbl);
12696 first = false0;
12697 }
12698 else if (hf->strings) {
12699 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12700 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12701 first = false0;
12702 }
12703 else if (!(flags & BMT_NO_INT0x02)) {
12704 char buf[32];
12705 const char *out;
12706
12707 if (!first) {
12708 proto_item_append_text(item, ", ");
12709 }
12710
12711 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12712 proto_item_append_text(item, "%s: %s", hf->name, out);
12713 first = false0;
12714 }
12715
12716 break;
12717
12718 case FT_UINT8:
12719 case FT_UINT16:
12720 case FT_UINT24:
12721 case FT_UINT32:
12722 if (hf->display == BASE_CUSTOM) {
12723 char lbl[ITEM_LABEL_LENGTH240];
12724 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12725
12726 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12726, "fmtfunc"))))
;
12727 fmtfunc(lbl, (uint32_t) tmpval);
12728 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12729 hf->name, lbl);
12730 first = false0;
12731 }
12732 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12733 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12734 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12735 first = false0;
12736 }
12737 else if (!(flags & BMT_NO_INT0x02)) {
12738 char buf[NUMBER_LABEL_LENGTH80];
12739 const char *out = NULL((void*)0);
12740
12741 if (!first) {
12742 proto_item_append_text(item, ", ");
12743 }
12744
12745 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12746 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12747 }
12748 if (out == NULL((void*)0)) {
12749 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12750 }
12751 proto_item_append_text(item, "%s: %s", hf->name, out);
12752 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12753 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12754 }
12755 first = false0;
12756 }
12757
12758 break;
12759
12760 case FT_INT8:
12761 case FT_INT16:
12762 case FT_INT24:
12763 case FT_INT32:
12764 integer32 = (uint32_t) tmpval;
12765 if (hf->bitmask) {
12766 no_of_bits = ws_count_ones(hf->bitmask);
12767 integer32 = ws_sign_ext32(integer32, no_of_bits);
12768 }
12769 if (hf->display == BASE_CUSTOM) {
12770 char lbl[ITEM_LABEL_LENGTH240];
12771 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12772
12773 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12773, "fmtfunc"))))
;
12774 fmtfunc(lbl, (int32_t) integer32);
12775 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12776 hf->name, lbl);
12777 first = false0;
12778 }
12779 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12780 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12781 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12782 first = false0;
12783 }
12784 else if (!(flags & BMT_NO_INT0x02)) {
12785 char buf[NUMBER_LABEL_LENGTH80];
12786 const char *out = NULL((void*)0);
12787
12788 if (!first) {
12789 proto_item_append_text(item, ", ");
12790 }
12791
12792 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12793 out = hf_try_val_to_str((int32_t) integer32, hf);
12794 }
12795 if (out == NULL((void*)0)) {
12796 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12797 }
12798 proto_item_append_text(item, "%s: %s", hf->name, out);
12799 if (hf->display & BASE_UNIT_STRING0x00001000) {
12800 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12801 }
12802 first = false0;
12803 }
12804
12805 break;
12806
12807 case FT_UINT40:
12808 case FT_UINT48:
12809 case FT_UINT56:
12810 case FT_UINT64:
12811 if (hf->display == BASE_CUSTOM) {
12812 char lbl[ITEM_LABEL_LENGTH240];
12813 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12814
12815 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12815, "fmtfunc"))))
;
12816 fmtfunc(lbl, tmpval);
12817 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12818 hf->name, lbl);
12819 first = false0;
12820 }
12821 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12822 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12823 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12824 first = false0;
12825 }
12826 else if (!(flags & BMT_NO_INT0x02)) {
12827 char buf[NUMBER_LABEL_LENGTH80];
12828 const char *out = NULL((void*)0);
12829
12830 if (!first) {
12831 proto_item_append_text(item, ", ");
12832 }
12833
12834 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12835 out = hf_try_val64_to_str(tmpval, hf);
12836 }
12837 if (out == NULL((void*)0)) {
12838 out = hfinfo_number_value_format64(hf, buf, tmpval);
12839 }
12840 proto_item_append_text(item, "%s: %s", hf->name, out);
12841 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12842 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12843 }
12844 first = false0;
12845 }
12846
12847 break;
12848
12849 case FT_INT40:
12850 case FT_INT48:
12851 case FT_INT56:
12852 case FT_INT64:
12853 if (hf->bitmask) {
12854 no_of_bits = ws_count_ones(hf->bitmask);
12855 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12856 }
12857 if (hf->display == BASE_CUSTOM) {
12858 char lbl[ITEM_LABEL_LENGTH240];
12859 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12860
12861 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12861, "fmtfunc"))))
;
12862 fmtfunc(lbl, (int64_t) tmpval);
12863 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12864 hf->name, lbl);
12865 first = false0;
12866 }
12867 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12868 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12869 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12870 first = false0;
12871 }
12872 else if (!(flags & BMT_NO_INT0x02)) {
12873 char buf[NUMBER_LABEL_LENGTH80];
12874 const char *out = NULL((void*)0);
12875
12876 if (!first) {
12877 proto_item_append_text(item, ", ");
12878 }
12879
12880 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12881 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12882 }
12883 if (out == NULL((void*)0)) {
12884 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12885 }
12886 proto_item_append_text(item, "%s: %s", hf->name, out);
12887 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12888 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12889 }
12890 first = false0;
12891 }
12892
12893 break;
12894
12895 case FT_BOOLEAN:
12896 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12897 /* If we have true/false strings, emit full - otherwise messages
12898 might look weird */
12899 const struct true_false_string *tfs =
12900 (const struct true_false_string *)hf->strings;
12901
12902 if (tmpval) {
12903 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12904 hf->name, tfs->true_string);
12905 first = false0;
12906 } else if (!(flags & BMT_NO_FALSE0x04)) {
12907 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12908 hf->name, tfs->false_string);
12909 first = false0;
12910 }
12911 } else if (hf->bitmask & value) {
12912 /* If the flag is set, show the name */
12913 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
12914 first = false0;
12915 }
12916 break;
12917 default:
12918 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()",proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()"
, hf->abbrev, hf->type, ftype_name(hf->type))
12919 hf->abbrev,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()"
, hf->abbrev, hf->type, ftype_name(hf->type))
12920 hf->type,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()"
, hf->abbrev, hf->type, ftype_name(hf->type))
12921 ftype_name(hf->type))proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()"
, hf->abbrev, hf->type, ftype_name(hf->type))
;
12922 break;
12923 }
12924
12925 fields++;
12926 }
12927
12928 /* XXX: We don't pass the hfi into this function. Perhaps we should,
12929 * but then again most dissectors don't set the bitmask field for
12930 * the higher level bitmask hfi, so calculate the bitmask from the
12931 * fields present. */
12932 if (item) {
12933 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
12934 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
12935 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset))do { if (((item)->finfo)) (((item)->finfo))->flags =
(((item)->finfo))->flags | ((((bit_offset) & 63) <<
5)); } while(0)
;
12936 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits))do { if (((item)->finfo)) (((item)->finfo))->flags =
(((item)->finfo))->flags | ((((no_of_bits) & 63) <<
12)); } while(0)
;
12937 }
12938 return first;
12939}
12940
12941/* This function will dissect a sequence of bytes that describe a
12942 * bitmask and supply the value of that sequence through a pointer.
12943 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12944 * to be dissected.
12945 * This field will form an expansion under which the individual fields of the
12946 * bitmask is dissected and displayed.
12947 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12948 *
12949 * fields is an array of pointers to int that lists all the fields of the
12950 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12951 * or another integer of the same type/size as hf_hdr with a mask specified.
12952 * This array is terminated by a NULL entry.
12953 *
12954 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
12955 * FT_integer fields that have a value_string attached will have the
12956 * matched string displayed on the expansion line.
12957 */
12958proto_item *
12959proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
12960 const unsigned offset, const int hf_hdr,
12961 const int ett, int * const *fields,
12962 const unsigned encoding, uint64_t *retval)
12963{
12964 return proto_tree_add_bitmask_with_flags_ret_uint64(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08, retval);
12965}
12966
12967/* This function will dissect a sequence of bytes that describe a
12968 * bitmask.
12969 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12970 * to be dissected.
12971 * This field will form an expansion under which the individual fields of the
12972 * bitmask is dissected and displayed.
12973 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12974 *
12975 * fields is an array of pointers to int that lists all the fields of the
12976 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12977 * or another integer of the same type/size as hf_hdr with a mask specified.
12978 * This array is terminated by a NULL entry.
12979 *
12980 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
12981 * FT_integer fields that have a value_string attached will have the
12982 * matched string displayed on the expansion line.
12983 */
12984proto_item *
12985proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
12986 const unsigned offset, const int hf_hdr,
12987 const int ett, int * const *fields,
12988 const unsigned encoding)
12989{
12990 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
12991}
12992
12993/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
12994 * what data is appended to the header.
12995 */
12996proto_item *
12997proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
12998 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
12999 uint64_t *retval)
13000{
13001 proto_item *item = NULL((void*)0);
13002 header_field_info *hf;
13003 int len;
13004 uint64_t value;
13005
13006 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf)if((hf_hdr == 0 || (unsigned)hf_hdr > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 13006, __func__, "Unregistered hf! index=%d"
, hf_hdr); ((void) ((hf_hdr > 0 && (unsigned)hf_hdr
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13006
, "hf_hdr > 0 && (unsigned)hf_hdr < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_hdr] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13006, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13007 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf)((void) (((((((hf)->type) == FT_INT8 || ((hf)->type) ==
FT_INT16 || ((hf)->type) == FT_INT24 || ((hf)->type) ==
FT_INT32) || (((hf)->type) == FT_INT40 || ((hf)->type)
== FT_INT48 || ((hf)->type) == FT_INT56 || ((hf)->type
) == FT_INT64)) || ((((hf)->type) == FT_CHAR || ((hf)->
type) == FT_UINT8 || ((hf)->type) == FT_UINT16 || ((hf)->
type) == FT_UINT24 || ((hf)->type) == FT_UINT32 || ((hf)->
type) == FT_FRAMENUM) || (((hf)->type) == FT_UINT40 || ((hf
)->type) == FT_UINT48 || ((hf)->type) == FT_UINT56 || (
(hf)->type) == FT_UINT64)))) ? (void)0 : proto_report_dissector_bug
("%s:%u: field %s is not of type FT_CHAR or an FT_{U}INTn type"
, "epan/proto.c", 13007, (hf)->abbrev)))
;
13008 len = ftype_wire_size(hf->type);
13009 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13010
13011 if (parent_tree) {
13012 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13013 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13014 flags, false0, false0, NULL((void*)0), value);
13015 }
13016
13017 *retval = value;
13018 if (hf->bitmask) {
13019 /* Mask out irrelevant portions */
13020 *retval &= hf->bitmask;
13021 /* Shift bits */
13022 *retval >>= hfinfo_bitshift(hf);
13023 }
13024
13025 return item;
13026}
13027
13028/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13029 * what data is appended to the header.
13030 */
13031proto_item *
13032proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13033 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13034{
13035 proto_item *item = NULL((void*)0);
13036 header_field_info *hf;
13037 int len;
13038 uint64_t value;
13039
13040 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf)if((hf_hdr == 0 || (unsigned)hf_hdr > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 13040, __func__, "Unregistered hf! index=%d"
, hf_hdr); ((void) ((hf_hdr > 0 && (unsigned)hf_hdr
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13040
, "hf_hdr > 0 && (unsigned)hf_hdr < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_hdr] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13040, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13041 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf)((void) (((((((hf)->type) == FT_INT8 || ((hf)->type) ==
FT_INT16 || ((hf)->type) == FT_INT24 || ((hf)->type) ==
FT_INT32) || (((hf)->type) == FT_INT40 || ((hf)->type)
== FT_INT48 || ((hf)->type) == FT_INT56 || ((hf)->type
) == FT_INT64)) || ((((hf)->type) == FT_CHAR || ((hf)->
type) == FT_UINT8 || ((hf)->type) == FT_UINT16 || ((hf)->
type) == FT_UINT24 || ((hf)->type) == FT_UINT32 || ((hf)->
type) == FT_FRAMENUM) || (((hf)->type) == FT_UINT40 || ((hf
)->type) == FT_UINT48 || ((hf)->type) == FT_UINT56 || (
(hf)->type) == FT_UINT64)))) ? (void)0 : proto_report_dissector_bug
("%s:%u: field %s is not of type FT_CHAR or an FT_{U}INTn type"
, "epan/proto.c", 13041, (hf)->abbrev)))
;
13042
13043 if (parent_tree) {
13044 len = ftype_wire_size(hf->type);
13045 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13046 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13047 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13048 flags, false0, false0, NULL((void*)0), value);
13049 }
13050
13051 return item;
13052}
13053
13054/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13055 can't be retrieved directly from tvb) */
13056proto_item *
13057proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13058 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13059{
13060 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13061 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13062}
13063
13064/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13065WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13066proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13067 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13068{
13069 proto_item *item = NULL((void*)0);
13070 header_field_info *hf;
13071 int len;
13072
13073 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf)if((hf_hdr == 0 || (unsigned)hf_hdr > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 13073, __func__, "Unregistered hf! index=%d"
, hf_hdr); ((void) ((hf_hdr > 0 && (unsigned)hf_hdr
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13073
, "hf_hdr > 0 && (unsigned)hf_hdr < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_hdr] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13073, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13074 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf)((void) (((((((hf)->type) == FT_INT8 || ((hf)->type) ==
FT_INT16 || ((hf)->type) == FT_INT24 || ((hf)->type) ==
FT_INT32) || (((hf)->type) == FT_INT40 || ((hf)->type)
== FT_INT48 || ((hf)->type) == FT_INT56 || ((hf)->type
) == FT_INT64)) || ((((hf)->type) == FT_CHAR || ((hf)->
type) == FT_UINT8 || ((hf)->type) == FT_UINT16 || ((hf)->
type) == FT_UINT24 || ((hf)->type) == FT_UINT32 || ((hf)->
type) == FT_FRAMENUM) || (((hf)->type) == FT_UINT40 || ((hf
)->type) == FT_UINT48 || ((hf)->type) == FT_UINT56 || (
(hf)->type) == FT_UINT64)))) ? (void)0 : proto_report_dissector_bug
("%s:%u: field %s is not of type FT_CHAR or an FT_{U}INTn type"
, "epan/proto.c", 13074, (hf)->abbrev)))
;
13075 /* the proto_tree_add_uint/_uint64() calls below
13076 will fail if tvb==NULL and len!=0 */
13077 len = tvb ? ftype_wire_size(hf->type) : 0;
13078
13079 if (parent_tree) {
13080 if (len <= 4)
13081 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13082 else
13083 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13084
13085 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13086 flags, false0, false0, NULL((void*)0), value);
13087 }
13088
13089 return item;
13090}
13091
13092/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13093void
13094proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13095 const int len, int * const *fields, const unsigned encoding)
13096{
13097 uint64_t value;
13098
13099 if (tree) {
13100 value = get_uint64_value(tree, tvb, offset, len, encoding);
13101 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13102 BMT_NO_APPEND0x01, false0, true1, tree, value);
13103 }
13104}
13105
13106WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13107proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13108 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13109{
13110 uint64_t value;
13111
13112 value = get_uint64_value(tree, tvb, offset, len, encoding);
13113 if (tree) {
13114 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13115 BMT_NO_APPEND0x01, false0, true1, tree, value);
13116 }
13117 if (retval) {
13118 *retval = value;
13119 }
13120}
13121
13122WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13123proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13124 const int len, int * const *fields, const uint64_t value)
13125{
13126 if (tree) {
13127 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13128 BMT_NO_APPEND0x01, false0, true1, tree, value);
13129 }
13130}
13131
13132
13133/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13134 * This is intended to support bitmask fields whose lengths can vary, perhaps
13135 * as the underlying standard evolves over time.
13136 * With this API there is the possibility of being called to display more or
13137 * less data than the dissector was coded to support.
13138 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13139 * Thus when presented with "too much" or "too little" data, MSbits will be
13140 * ignored or MSfields sacrificed.
13141 *
13142 * Only fields for which all defined bits are available are displayed.
13143 */
13144proto_item *
13145proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13146 const unsigned offset, const unsigned len, const int hf_hdr,
13147 const int ett, int * const *fields, struct expert_field* exp,
13148 const unsigned encoding)
13149{
13150 proto_item *item = NULL((void*)0);
13151 header_field_info *hf;
13152 unsigned decodable_len;
13153 unsigned decodable_offset;
13154 uint32_t decodable_value;
13155 uint64_t value;
13156
13157 PROTO_REGISTRAR_GET_NTH(hf_hdr, hf)if((hf_hdr == 0 || (unsigned)hf_hdr > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 13157, __func__, "Unregistered hf! index=%d"
, hf_hdr); ((void) ((hf_hdr > 0 && (unsigned)hf_hdr
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13157
, "hf_hdr > 0 && (unsigned)hf_hdr < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_hdr] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13157, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13158 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf)((void) (((((((hf)->type) == FT_INT8 || ((hf)->type) ==
FT_INT16 || ((hf)->type) == FT_INT24 || ((hf)->type) ==
FT_INT32) || (((hf)->type) == FT_INT40 || ((hf)->type)
== FT_INT48 || ((hf)->type) == FT_INT56 || ((hf)->type
) == FT_INT64)) || ((((hf)->type) == FT_CHAR || ((hf)->
type) == FT_UINT8 || ((hf)->type) == FT_UINT16 || ((hf)->
type) == FT_UINT24 || ((hf)->type) == FT_UINT32 || ((hf)->
type) == FT_FRAMENUM) || (((hf)->type) == FT_UINT40 || ((hf
)->type) == FT_UINT48 || ((hf)->type) == FT_UINT56 || (
(hf)->type) == FT_UINT64)))) ? (void)0 : proto_report_dissector_bug
("%s:%u: field %s is not of type FT_CHAR or an FT_{U}INTn type"
, "epan/proto.c", 13158, (hf)->abbrev)))
;
13159
13160 decodable_offset = offset;
13161 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13162
13163 /* If we are ftype_wire_size-limited,
13164 * make sure we decode as many LSBs as possible.
13165 */
13166 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13167 decodable_offset += (len - decodable_len);
13168 }
13169
13170 if (parent_tree) {
13171 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13172 decodable_len, encoding);
13173
13174 /* The root item covers all the bytes even if we can't decode them all */
13175 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13176 decodable_value);
13177 }
13178
13179 if (decodable_len < len) {
13180 /* Dissector likely requires updating for new protocol revision */
13181 expert_add_info_format(NULL((void*)0), item, exp,
13182 "Only least-significant %d of %d bytes decoded",
13183 decodable_len, len);
13184 }
13185
13186 if (item) {
13187 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13188 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13189 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13190 }
13191
13192 return item;
13193}
13194
13195/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13196proto_item *
13197proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13198 const unsigned offset, const unsigned len,
13199 const char *name, const char *fallback,
13200 const int ett, int * const *fields,
13201 const unsigned encoding, const int flags)
13202{
13203 proto_item *item = NULL((void*)0);
13204 uint64_t value;
13205
13206 if (parent_tree) {
13207 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13208 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13209 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13210 flags, true1, false0, NULL((void*)0), value) && fallback) {
13211 /* Still at first item - append 'fallback' text if any */
13212 proto_item_append_text(item, "%s", fallback);
13213 }
13214 }
13215
13216 return item;
13217}
13218
13219proto_item *
13220proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13221 const unsigned bit_offset, const int no_of_bits,
13222 const unsigned encoding)
13223{
13224 header_field_info *hfinfo;
13225 int octet_length;
13226 int octet_offset;
13227
13228 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 13228, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13228
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13228, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13229
13230 if (no_of_bits < 0) {
13231 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13232 }
13233 octet_length = (no_of_bits + 7) >> 3;
13234 octet_offset = bit_offset >> 3;
13235 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13236
13237 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13238 * but only after doing a bunch more work (which we can, in the common
13239 * case, shortcut here).
13240 */
13241 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13242 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13242
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13242, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13242, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13242, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
13243
13244 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13245}
13246
13247/*
13248 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13249 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13250 * Offset should be given in bits from the start of the tvb.
13251 */
13252
13253static proto_item *
13254_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13255 const unsigned bit_offset, const int no_of_bits,
13256 uint64_t *return_value, const unsigned encoding)
13257{
13258 int offset;
13259 unsigned length;
13260 uint8_t tot_no_bits;
13261 char *bf_str;
13262 char lbl_str[ITEM_LABEL_LENGTH240];
13263 uint64_t value = 0;
13264 uint8_t *bytes = NULL((void*)0);
13265 size_t bytes_length = 0;
13266
13267 proto_item *pi;
13268 header_field_info *hf_field;
13269
13270 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13271 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 13271, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13271
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13271, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13272
13273 if (hf_field->bitmask != 0) {
13274 REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_bits_ret_val"proto_report_dissector_bug("Incompatible use of proto_tree_add_bits_ret_val"
" with field '%s' (%s) with bitmask != 0", hf_field->abbrev
, hf_field->name)
13275 " with field '%s' (%s) with bitmask != 0",proto_report_dissector_bug("Incompatible use of proto_tree_add_bits_ret_val"
" with field '%s' (%s) with bitmask != 0", hf_field->abbrev
, hf_field->name)
13276 hf_field->abbrev, hf_field->name)proto_report_dissector_bug("Incompatible use of proto_tree_add_bits_ret_val"
" with field '%s' (%s) with bitmask != 0", hf_field->abbrev
, hf_field->name)
;
13277 }
13278
13279 if (no_of_bits < 0) {
13280 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13281 } else if (no_of_bits == 0) {
13282 REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_ret_val() has a bit width of 0",proto_report_dissector_bug("field %s passed to proto_tree_add_bits_ret_val() has a bit width of 0"
, hf_field->abbrev)
13283 hf_field->abbrev)proto_report_dissector_bug("field %s passed to proto_tree_add_bits_ret_val() has a bit width of 0"
, hf_field->abbrev)
;
13284 }
13285
13286 /* Byte align offset */
13287 offset = bit_offset>>3;
13288
13289 /*
13290 * Calculate the number of octets used to hold the bits
13291 */
13292 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13293 length = (tot_no_bits + 7) >> 3;
13294
13295 if (no_of_bits < 65) {
13296 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13297 } else if (hf_field->type != FT_BYTES) {
13298 REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_ret_val() has a bit width of %u > 64",proto_report_dissector_bug("field %s passed to proto_tree_add_bits_ret_val() has a bit width of %u > 64"
, hf_field->abbrev, no_of_bits)
13299 hf_field->abbrev, no_of_bits)proto_report_dissector_bug("field %s passed to proto_tree_add_bits_ret_val() has a bit width of %u > 64"
, hf_field->abbrev, no_of_bits)
;
13300 return NULL((void*)0);
13301 }
13302
13303 /* Sign extend for signed types */
13304 switch (hf_field->type) {
13305 case FT_INT8:
13306 case FT_INT16:
13307 case FT_INT24:
13308 case FT_INT32:
13309 case FT_INT40:
13310 case FT_INT48:
13311 case FT_INT56:
13312 case FT_INT64:
13313 value = ws_sign_ext64(value, no_of_bits);
13314 break;
13315
13316 default:
13317 break;
13318 }
13319
13320 if (return_value) {
13321 *return_value = value;
13322 }
13323
13324 /* Coast clear. Try and fake it */
13325 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13326 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13326
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13326, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13326, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13326, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13327
13328 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13329
13330 switch (hf_field->type) {
13331 case FT_BOOLEAN:
13332 /* Boolean field */
13333 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13334 "%s = %s: %s",
13335 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13336 break;
13337
13338 case FT_CHAR:
13339 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13340 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13341 break;
13342
13343 case FT_UINT8:
13344 case FT_UINT16:
13345 case FT_UINT24:
13346 case FT_UINT32:
13347 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13348 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13349 break;
13350
13351 case FT_INT8:
13352 case FT_INT16:
13353 case FT_INT24:
13354 case FT_INT32:
13355 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13356 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13357 break;
13358
13359 case FT_UINT40:
13360 case FT_UINT48:
13361 case FT_UINT56:
13362 case FT_UINT64:
13363 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13364 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13365 break;
13366
13367 case FT_INT40:
13368 case FT_INT48:
13369 case FT_INT56:
13370 case FT_INT64:
13371 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13372 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13373 break;
13374
13375 case FT_BYTES:
13376 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13377 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13378 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13379 proto_item_set_text(pi, "%s", lbl_str);
13380 return pi;
13381
13382 /* TODO: should handle FT_UINT_BYTES ? */
13383
13384 default:
13385 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_bits_ret_val()",proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_bits_ret_val()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
13386 hf_field->abbrev,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_bits_ret_val()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
13387 hf_field->type,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_bits_ret_val()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
13388 ftype_name(hf_field->type))proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_bits_ret_val()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
;
13389 return NULL((void*)0);
13390 }
13391
13392 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13393 return pi;
13394}
13395
13396proto_item *
13397proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13398 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13399 uint64_t *return_value)
13400{
13401 proto_item *pi;
13402 int no_of_bits;
13403 int octet_offset;
13404 unsigned mask_initial_bit_offset;
13405 unsigned mask_greatest_bit_offset;
13406 unsigned octet_length;
13407 uint8_t i;
13408 char bf_str[256];
13409 char lbl_str[ITEM_LABEL_LENGTH240];
13410 uint64_t value;
13411 uint64_t composite_bitmask;
13412 uint64_t composite_bitmap;
13413
13414 header_field_info *hf_field;
13415
13416 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13417 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 13417, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13417
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13417, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
1
Assuming 'hfindex' is not equal to 0
2
Assuming 'hfindex' is <= field 'len'
3
Assuming 'hfindex' is > 0
4
Assuming 'hfindex' is < field 'len'
5
'?' condition is true
6
Assuming the condition is true
7
'?' condition is true
13418
13419 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13420 REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_split_bits_item_ret_val"proto_report_dissector_bug("Incompatible use of proto_tree_add_split_bits_item_ret_val"
" with field '%s' (%s) with bitmask != 0", hf_field->abbrev
, hf_field->name)
13421 " with field '%s' (%s) with bitmask != 0",proto_report_dissector_bug("Incompatible use of proto_tree_add_split_bits_item_ret_val"
" with field '%s' (%s) with bitmask != 0", hf_field->abbrev
, hf_field->name)
13422 hf_field->abbrev, hf_field->name)proto_report_dissector_bug("Incompatible use of proto_tree_add_split_bits_item_ret_val"
" with field '%s' (%s) with bitmask != 0", hf_field->abbrev
, hf_field->name)
;
13423 }
13424
13425 mask_initial_bit_offset = bit_offset % 8;
13426
13427 no_of_bits = 0;
13428 value = 0;
13429 i = 0;
13430 mask_greatest_bit_offset = 0;
13431 composite_bitmask = 0;
13432 composite_bitmap = 0;
13433
13434 while (crumb_spec[i].crumb_bit_length != 0) {
10
Assuming field 'crumb_bit_length' is not equal to 0
11
Loop condition is true. Entering loop body
13435 uint64_t crumb_mask, crumb_value;
13436 uint8_t crumb_end_bit_offset;
13437
13438 crumb_value = tvb_get_bits64(tvb,
13439 bit_offset + crumb_spec[i].crumb_bit_offset,
13440 crumb_spec[i].crumb_bit_length,
13441 ENC_BIG_ENDIAN0x00000000);
13442 value += crumb_value;
13443 no_of_bits += crumb_spec[i].crumb_bit_length;
13444 DISSECTOR_ASSERT_HINT(no_of_bits <= 64, "a value larger than 64 bits cannot be represented")((void) ((no_of_bits <= 64) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13444
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13445
13446 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13447 octet containing the initial offset.
13448 If the mask is beyond 32 bits, then give up on bit map display.
13449 This could be improved in future, probably showing a table
13450 of 32 or 64 bits per row */
13451 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13452 crumb_end_bit_offset = mask_initial_bit_offset
13453 + crumb_spec[i].crumb_bit_offset
13454 + crumb_spec[i].crumb_bit_length;
13455 crumb_mask = (UINT64_C(1)1UL << crumb_spec[i].crumb_bit_length) - 1;
15
Assuming right operand of bit shift is less than 64
16
Value assigned to 'crumb_mask'
13456
13457 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13458 mask_greatest_bit_offset = crumb_end_bit_offset;
13459 }
13460 /* Currently the bitmap of the crumbs are only shown if
13461 * smaller than 32 bits. Do not bother calculating the
13462 * mask if it is larger than that. */
13463 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13464 composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
20
The result of left shift is undefined because the right operand '64' is not smaller than 64, the capacity of 'uint64_t'
13465 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13466 }
13467 }
13468 /* Shift left for the next segment */
13469 value <<= crumb_spec[++i].crumb_bit_length;
13470 }
13471
13472 /* Sign extend for signed types */
13473 switch (hf_field->type) {
13474 case FT_INT8:
13475 case FT_INT16:
13476 case FT_INT24:
13477 case FT_INT32:
13478 case FT_INT40:
13479 case FT_INT48:
13480 case FT_INT56:
13481 case FT_INT64:
13482 value = ws_sign_ext64(value, no_of_bits);
13483 break;
13484 default:
13485 break;
13486 }
13487
13488 if (return_value) {
13489 *return_value = value;
13490 }
13491
13492 /* Coast clear. Try and fake it */
13493 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13494 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13494
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13494, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13494, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13494, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13495
13496 /* initialise the format string */
13497 bf_str[0] = '\0';
13498
13499 octet_offset = bit_offset >> 3;
13500
13501 /* Round up mask length to nearest octet */
13502 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13503 mask_greatest_bit_offset = octet_length << 3;
13504
13505 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13506 It would be a useful enhancement to eliminate this restriction. */
13507 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13508 other_decode_bitfield_value(bf_str,
13509 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13510 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13511 mask_greatest_bit_offset);
13512 } else {
13513 /* If the bitmask is too large, try to describe its contents. */
13514 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13515 }
13516
13517 switch (hf_field->type) {
13518 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13519 /* Boolean field */
13520 return proto_tree_add_boolean_format(tree, hfindex,
13521 tvb, octet_offset, octet_length, value,
13522 "%s = %s: %s",
13523 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13524 break;
13525
13526 case FT_CHAR:
13527 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13528 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13529 break;
13530
13531 case FT_UINT8:
13532 case FT_UINT16:
13533 case FT_UINT24:
13534 case FT_UINT32:
13535 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13536 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13537 break;
13538
13539 case FT_INT8:
13540 case FT_INT16:
13541 case FT_INT24:
13542 case FT_INT32:
13543 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13544 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13545 break;
13546
13547 case FT_UINT40:
13548 case FT_UINT48:
13549 case FT_UINT56:
13550 case FT_UINT64:
13551 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13552 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13553 break;
13554
13555 case FT_INT40:
13556 case FT_INT48:
13557 case FT_INT56:
13558 case FT_INT64:
13559 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13560 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13561 break;
13562
13563 default:
13564 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_split_bits_item_ret_val()",proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_split_bits_item_ret_val()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
13565 hf_field->abbrev,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_split_bits_item_ret_val()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
13566 hf_field->type,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_split_bits_item_ret_val()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
13567 ftype_name(hf_field->type))proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_split_bits_item_ret_val()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
;
13568 return NULL((void*)0);
13569 }
13570 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13571 return pi;
13572}
13573
13574void
13575proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13576 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13577{
13578 header_field_info *hfinfo;
13579 int start = bit_offset >> 3;
13580 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13581
13582 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13583 * so that we can use the tree's memory scope in calculating the string */
13584 if (length == -1) {
13585 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13586 } else {
13587 tvb_ensure_bytes_exist(tvb, start, length);
13588 }
13589 if (!tree) return;
13590
13591 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 13591, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13591
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13591, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13592 proto_tree_add_text_internal(tree, tvb, start, length,
13593 "%s crumb %d of %s (decoded above)",
13594 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13595 tvb_get_bits32(tvb,
13596 bit_offset,
13597 crumb_spec[crumb_index].crumb_bit_length,
13598 ENC_BIG_ENDIAN0x00000000),
13599 ENC_BIG_ENDIAN0x00000000),
13600 crumb_index,
13601 hfinfo->name);
13602}
13603
13604proto_item *
13605proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13606 const unsigned bit_offset, const int no_of_bits,
13607 uint64_t *return_value, const unsigned encoding)
13608{
13609 proto_item *item;
13610
13611 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13612 bit_offset, no_of_bits,
13613 return_value, encoding))) {
13614 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset))do { if (((item)->finfo)) (((item)->finfo))->flags =
(((item)->finfo))->flags | ((((bit_offset) & 63) <<
5)); } while(0)
;
13615 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits))do { if (((item)->finfo)) (((item)->finfo))->flags =
(((item)->finfo))->flags | ((((no_of_bits) & 63) <<
12)); } while(0)
;
13616 }
13617 return item;
13618}
13619
13620static proto_item *
13621_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13622 tvbuff_t *tvb, const unsigned bit_offset,
13623 const int no_of_bits, void *value_ptr,
13624 const unsigned encoding, char *value_str)
13625{
13626 int offset;
13627 unsigned length;
13628 uint8_t tot_no_bits;
13629 char *str;
13630 uint64_t value = 0;
13631 header_field_info *hf_field;
13632
13633 /* We do not have to return a value, try to fake it as soon as possible */
13634 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13635 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13635
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13635, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13635, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13635, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13636
13637 if (hf_field->bitmask != 0) {
13638 REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_bits_format_value"proto_report_dissector_bug("Incompatible use of proto_tree_add_bits_format_value"
" with field '%s' (%s) with bitmask != 0", hf_field->abbrev
, hf_field->name)
13639 " with field '%s' (%s) with bitmask != 0",proto_report_dissector_bug("Incompatible use of proto_tree_add_bits_format_value"
" with field '%s' (%s) with bitmask != 0", hf_field->abbrev
, hf_field->name)
13640 hf_field->abbrev, hf_field->name)proto_report_dissector_bug("Incompatible use of proto_tree_add_bits_format_value"
" with field '%s' (%s) with bitmask != 0", hf_field->abbrev
, hf_field->name)
;
13641 }
13642
13643 if (no_of_bits < 0) {
13644 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13645 } else if (no_of_bits == 0) {
13646 REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_format_value() has a bit width of 0",proto_report_dissector_bug("field %s passed to proto_tree_add_bits_format_value() has a bit width of 0"
, hf_field->abbrev)
13647 hf_field->abbrev)proto_report_dissector_bug("field %s passed to proto_tree_add_bits_format_value() has a bit width of 0"
, hf_field->abbrev)
;
13648 }
13649
13650 /* Byte align offset */
13651 offset = bit_offset>>3;
13652
13653 /*
13654 * Calculate the number of octets used to hold the bits
13655 */
13656 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13657 length = tot_no_bits>>3;
13658 /* If we are using part of the next octet, increase length by 1 */
13659 if (tot_no_bits & 0x07)
13660 length++;
13661
13662 if (no_of_bits < 65) {
13663 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13664 } else {
13665 REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_format_value() has a bit width of %u > 65",proto_report_dissector_bug("field %s passed to proto_tree_add_bits_format_value() has a bit width of %u > 65"
, hf_field->abbrev, no_of_bits)
13666 hf_field->abbrev, no_of_bits)proto_report_dissector_bug("field %s passed to proto_tree_add_bits_format_value() has a bit width of %u > 65"
, hf_field->abbrev, no_of_bits)
;
13667 return NULL((void*)0);
13668 }
13669
13670 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13671
13672 (void) g_strlcat(str, " = ", 256+64);
13673 (void) g_strlcat(str, hf_field->name, 256+64);
13674
13675 /*
13676 * This function does not receive an actual value but a dimensionless pointer to that value.
13677 * For this reason, the type of the header field is examined in order to determine
13678 * what kind of value we should read from this address.
13679 * The caller of this function must make sure that for the specific header field type the address of
13680 * a compatible value is provided.
13681 */
13682 switch (hf_field->type) {
13683 case FT_BOOLEAN:
13684 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13685 "%s: %s", str, value_str);
13686 break;
13687
13688 case FT_CHAR:
13689 case FT_UINT8:
13690 case FT_UINT16:
13691 case FT_UINT24:
13692 case FT_UINT32:
13693 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13694 "%s: %s", str, value_str);
13695 break;
13696
13697 case FT_UINT40:
13698 case FT_UINT48:
13699 case FT_UINT56:
13700 case FT_UINT64:
13701 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13702 "%s: %s", str, value_str);
13703 break;
13704
13705 case FT_INT8:
13706 case FT_INT16:
13707 case FT_INT24:
13708 case FT_INT32:
13709 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13710 "%s: %s", str, value_str);
13711 break;
13712
13713 case FT_INT40:
13714 case FT_INT48:
13715 case FT_INT56:
13716 case FT_INT64:
13717 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13718 "%s: %s", str, value_str);
13719 break;
13720
13721 case FT_FLOAT:
13722 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13723 "%s: %s", str, value_str);
13724 break;
13725
13726 default:
13727 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_bits_format_value()",proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_bits_format_value()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
13728 hf_field->abbrev,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_bits_format_value()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
13729 hf_field->type,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_bits_format_value()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
13730 ftype_name(hf_field->type))proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_bits_format_value()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
;
13731 return NULL((void*)0);
13732 }
13733}
13734
13735static proto_item *
13736proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13737 tvbuff_t *tvb, const unsigned bit_offset,
13738 const int no_of_bits, void *value_ptr,
13739 const unsigned encoding, char *value_str)
13740{
13741 proto_item *item;
13742
13743 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13744 tvb, bit_offset, no_of_bits,
13745 value_ptr, encoding, value_str))) {
13746 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset))do { if (((item)->finfo)) (((item)->finfo))->flags =
(((item)->finfo))->flags | ((((bit_offset) & 63) <<
5)); } while(0)
;
13747 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits))do { if (((item)->finfo)) (((item)->finfo))->flags =
(((item)->finfo))->flags | ((((no_of_bits) & 63) <<
12)); } while(0)
;
13748 }
13749 return item;
13750}
13751
13752#define CREATE_VALUE_STRING(tree,dst,format,ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
\
13753 va_start(ap, format)__builtin_va_start(ap, format); \
13754 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13755 va_end(ap)__builtin_va_end(ap);
13756
13757proto_item *
13758proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13759 tvbuff_t *tvb, const unsigned bit_offset,
13760 const int no_of_bits, uint32_t value,
13761 const unsigned encoding,
13762 const char *format, ...)
13763{
13764 va_list ap;
13765 char *dst;
13766 header_field_info *hf_field;
13767
13768 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13769
13770 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13770
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13770, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13770, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13770, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13771
13772 switch (hf_field->type) {
13773 case FT_UINT8:
13774 case FT_UINT16:
13775 case FT_UINT24:
13776 case FT_UINT32:
13777 break;
13778
13779 default:
13780 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hf_field->abbrev)
13781 hf_field->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hf_field->abbrev)
;
13782 return NULL((void*)0);
13783 }
13784
13785 CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
;
13786
13787 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13788}
13789
13790proto_item *
13791proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13792 tvbuff_t *tvb, const unsigned bit_offset,
13793 const int no_of_bits, uint64_t value,
13794 const unsigned encoding,
13795 const char *format, ...)
13796{
13797 va_list ap;
13798 char *dst;
13799 header_field_info *hf_field;
13800
13801 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13802
13803 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13803
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13803, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13803, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13803, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13804
13805 switch (hf_field->type) {
13806 case FT_UINT40:
13807 case FT_UINT48:
13808 case FT_UINT56:
13809 case FT_UINT64:
13810 break;
13811
13812 default:
13813 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64",proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hf_field->abbrev)
13814 hf_field->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hf_field->abbrev)
;
13815 return NULL((void*)0);
13816 }
13817
13818 CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
;
13819
13820 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13821}
13822
13823proto_item *
13824proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13825 tvbuff_t *tvb, const unsigned bit_offset,
13826 const int no_of_bits, float value,
13827 const unsigned encoding,
13828 const char *format, ...)
13829{
13830 va_list ap;
13831 char *dst;
13832 header_field_info *hf_field;
13833
13834 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13835
13836 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13836
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13836, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13836, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13836, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13837
13838 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_FLOAT)((void) (((hf_field)->type == FT_FLOAT) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_FLOAT", "epan/proto.c",
13838, ((hf_field))->abbrev))))
;
13839
13840 CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
;
13841
13842 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13843}
13844
13845proto_item *
13846proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13847 tvbuff_t *tvb, const unsigned bit_offset,
13848 const int no_of_bits, int32_t value,
13849 const unsigned encoding,
13850 const char *format, ...)
13851{
13852 va_list ap;
13853 char *dst;
13854 header_field_info *hf_field;
13855
13856 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13857
13858 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13858
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13858, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13858, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13858, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13859
13860 switch (hf_field->type) {
13861 case FT_INT8:
13862 case FT_INT16:
13863 case FT_INT24:
13864 case FT_INT32:
13865 break;
13866
13867 default:
13868 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hf_field->abbrev)
13869 hf_field->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hf_field->abbrev)
;
13870 return NULL((void*)0);
13871 }
13872
13873 CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
;
13874
13875 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13876}
13877
13878proto_item *
13879proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13880 tvbuff_t *tvb, const unsigned bit_offset,
13881 const int no_of_bits, int64_t value,
13882 const unsigned encoding,
13883 const char *format, ...)
13884{
13885 va_list ap;
13886 char *dst;
13887 header_field_info *hf_field;
13888
13889 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13890
13891 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13891
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13891, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13891, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13891, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13892
13893 switch (hf_field->type) {
13894 case FT_INT40:
13895 case FT_INT48:
13896 case FT_INT56:
13897 case FT_INT64:
13898 break;
13899
13900 default:
13901 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hf_field->abbrev)
13902 hf_field->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hf_field->abbrev)
;
13903 return NULL((void*)0);
13904 }
13905
13906 CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
;
13907
13908 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13909}
13910
13911proto_item *
13912proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
13913 tvbuff_t *tvb, const unsigned bit_offset,
13914 const int no_of_bits, uint64_t value,
13915 const unsigned encoding,
13916 const char *format, ...)
13917{
13918 va_list ap;
13919 char *dst;
13920 header_field_info *hf_field;
13921
13922 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13923
13924 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13924
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13924, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13924, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13924, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13925
13926 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN)((void) (((hf_field)->type == FT_BOOLEAN) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_BOOLEAN", "epan/proto.c"
, 13926, ((hf_field))->abbrev))))
;
13927
13928 CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
;
13929
13930 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13931}
13932
13933proto_item *
13934proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13935 const unsigned bit_offset, const int no_of_chars)
13936{
13937 proto_item *pi;
13938 header_field_info *hfinfo;
13939 int byte_length;
13940 int byte_offset;
13941 char *string;
13942
13943 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13944
13945 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13945
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13945, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13945, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13945, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
13946
13947 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING)((void) (((hfinfo)->type == FT_STRING) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_STRING", "epan/proto.c"
, 13947, ((hfinfo))->abbrev))))
;
13948
13949 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13950 byte_offset = bit_offset >> 3;
13951
13952 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
13953
13954 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
13955 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 13955, "byte_length >= 0"
))))
;
13956 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
13957
13958 return pi;
13959}
13960
13961proto_item *
13962proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13963 const unsigned bit_offset, const int no_of_chars)
13964{
13965 proto_item *pi;
13966 header_field_info *hfinfo;
13967 int byte_length;
13968 int byte_offset;
13969 char *string;
13970
13971 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13972
13973 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13973
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13973, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13973, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13973, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
13974
13975 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING)((void) (((hfinfo)->type == FT_STRING) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_STRING", "epan/proto.c"
, 13975, ((hfinfo))->abbrev))))
;
13976
13977 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13978 byte_offset = bit_offset >> 3;
13979
13980 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
13981
13982 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
13983 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 13983, "byte_length >= 0"
))))
;
13984 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
13985
13986 return pi;
13987}
13988
13989const value_string proto_checksum_vals[] = {
13990 { PROTO_CHECKSUM_E_BAD, "Bad" },
13991 { PROTO_CHECKSUM_E_GOOD, "Good" },
13992 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
13993 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
13994 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
13995
13996 { 0, NULL((void*)0) }
13997};
13998
13999proto_item *
14000proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14001 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14002 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14003{
14004 header_field_info *hfinfo;
14005 uint32_t checksum;
14006 uint32_t len;
14007 proto_item* ti = NULL((void*)0);
14008 proto_item* ti2;
14009 bool_Bool incorrect_checksum = true1;
14010
14011 PROTO_REGISTRAR_GET_NTH(hf_checksum, hfinfo)if((hf_checksum == 0 || (unsigned)hf_checksum > gpa_hfinfo
.len) && wireshark_abort_on_dissector_bug) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 14011, __func__, "Unregistered hf! index=%d"
, hf_checksum); ((void) ((hf_checksum > 0 && (unsigned
)hf_checksum < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 14011
, "hf_checksum > 0 && (unsigned)hf_checksum < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_checksum
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14011, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14012
14013 switch (hfinfo->type) {
14014 case FT_UINT8:
14015 len = 1;
14016 break;
14017 case FT_UINT16:
14018 len = 2;
14019 break;
14020 case FT_UINT24:
14021 len = 3;
14022 break;
14023 case FT_UINT32:
14024 len = 4;
14025 break;
14026 default:
14027 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
14028 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14029 }
14030
14031 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14032 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14033 proto_item_set_generated(ti);
14034 if (hf_checksum_status != -1) {
14035 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14036 proto_item_set_generated(ti2);
14037 }
14038 return ti;
14039 }
14040
14041 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14042 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14043 proto_item_set_generated(ti);
14044 } else {
14045 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14046 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14047 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14048 if (computed_checksum == 0) {
14049 proto_item_append_text(ti, " [correct]");
14050 if (hf_checksum_status != -1) {
14051 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14052 proto_item_set_generated(ti2);
14053 }
14054 incorrect_checksum = false0;
14055 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14056 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14057 /* XXX - This can't distinguish between "shouldbe"
14058 * 0x0000 and 0xFFFF unless we know whether there
14059 * were any nonzero bits (other than the checksum).
14060 * Protocols should not use this path if they might
14061 * have an all zero packet.
14062 * Some implementations put the wrong zero; maybe
14063 * we should have a special expert info for that?
14064 */
14065 }
14066 } else {
14067 if (checksum == computed_checksum) {
14068 proto_item_append_text(ti, " [correct]");
14069 if (hf_checksum_status != -1) {
14070 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14071 proto_item_set_generated(ti2);
14072 }
14073 incorrect_checksum = false0;
14074 }
14075 }
14076
14077 if (incorrect_checksum) {
14078 if (hf_checksum_status != -1) {
14079 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14080 proto_item_set_generated(ti2);
14081 }
14082 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14083 proto_item_append_text(ti, " [incorrect]");
14084 if (bad_checksum_expert != NULL((void*)0))
14085 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14086 } else {
14087 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14088 if (bad_checksum_expert != NULL((void*)0))
14089 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%0*x]", expert_get_summary(bad_checksum_expert), len * 2, computed_checksum);
14090 }
14091 }
14092 } else {
14093 if (hf_checksum_status != -1) {
14094 proto_item_append_text(ti, " [unverified]");
14095 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14096 proto_item_set_generated(ti2);
14097 }
14098 }
14099 }
14100
14101 return ti;
14102}
14103
14104proto_item *
14105proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14106 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14107 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14108{
14109 header_field_info *hfinfo;
14110 uint8_t *checksum = NULL((void*)0);
14111 proto_item* ti = NULL((void*)0);
14112 proto_item* ti2;
14113 bool_Bool incorrect_checksum = true1;
14114
14115 PROTO_REGISTRAR_GET_NTH(hf_checksum, hfinfo)if((hf_checksum == 0 || (unsigned)hf_checksum > gpa_hfinfo
.len) && wireshark_abort_on_dissector_bug) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 14115, __func__, "Unregistered hf! index=%d"
, hf_checksum); ((void) ((hf_checksum > 0 && (unsigned
)hf_checksum < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 14115
, "hf_checksum > 0 && (unsigned)hf_checksum < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_checksum
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14115, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14116
14117 if (hfinfo->type != FT_BYTES) {
14118 REPORT_DISSECTOR_BUG("field %s is not of type FT_BYTES",proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
14119 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
14120 }
14121
14122 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14123 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14124 proto_item_set_generated(ti);
14125 if (hf_checksum_status != -1) {
14126 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14127 proto_item_set_generated(ti2);
14128 }
14129 return ti;
14130 }
14131
14132 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14133 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14134 proto_item_set_generated(ti);
14135 } else {
14136 checksum = (uint8_t*)wmem_alloc0_array(pinfo->pool, uint8_t, checksum_len)((uint8_t*)wmem_alloc0((pinfo->pool), (((((checksum_len)) <=
0) || ((size_t)sizeof(uint8_t) > (9223372036854775807L / (
size_t)((checksum_len))))) ? 0 : (sizeof(uint8_t) * ((checksum_len
))))))
;
14137 tvb_memcpy(tvb, checksum, offset, checksum_len);
14138 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14139 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14140 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14141 if (computed_checksum == 0) {
14142 proto_item_append_text(ti, " [correct]");
14143 if (hf_checksum_status != -1) {
14144 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14145 proto_item_set_generated(ti2);
14146 }
14147 incorrect_checksum = false0;
14148 }
14149 } else {
14150 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14151 proto_item_append_text(ti, " [correct]");
14152 if (hf_checksum_status != -1) {
14153 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14154 proto_item_set_generated(ti2);
14155 }
14156 incorrect_checksum = false0;
14157 }
14158 }
14159
14160 if (incorrect_checksum) {
14161 if (hf_checksum_status != -1) {
14162 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14163 proto_item_set_generated(ti2);
14164 }
14165 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14166 proto_item_append_text(ti, " [incorrect]");
14167 if (bad_checksum_expert != NULL((void*)0))
14168 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14169 } else {
14170 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14171 char *computed_checksum_str = (char*)wmem_alloc0_array(pinfo->pool, char, computed_checksum_str_len)((char*)wmem_alloc0((pinfo->pool), (((((computed_checksum_str_len
)) <= 0) || ((size_t)sizeof(char) > (9223372036854775807L
/ (size_t)((computed_checksum_str_len))))) ? 0 : (sizeof(char
) * ((computed_checksum_str_len))))))
;
14172 for (size_t counter = 0; counter < checksum_len; ++counter) {
14173 snprintf(
14174 /* On ecah iteration inserts two characters */
14175 (char*)&computed_checksum_str[counter << 1],
14176 computed_checksum_str_len - (counter << 1),
14177 "%02x",
14178 computed_checksum[counter]);
14179 }
14180 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14181 if (bad_checksum_expert != NULL((void*)0))
14182 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14183 }
14184 }
14185 } else {
14186 if (hf_checksum_status != -1) {
14187 proto_item_append_text(ti, " [unverified]");
14188 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14189 proto_item_set_generated(ti2);
14190 }
14191 }
14192 }
14193
14194 return ti;
14195}
14196
14197unsigned char
14198proto_check_field_name(const char *field_name)
14199{
14200 return module_check_valid_name(field_name, false0);
14201}
14202
14203unsigned char
14204proto_check_field_name_lower(const char *field_name)
14205{
14206 return module_check_valid_name(field_name, true1);
14207}
14208
14209bool_Bool
14210tree_expanded(int tree_type)
14211{
14212 if (tree_type <= 0) {
14213 return false0;
14214 }
14215 ws_assert(tree_type >= 0 && tree_type < num_tree_types)do { if ((1) && !(tree_type >= 0 && tree_type
< num_tree_types)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 14215, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14216 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14217}
14218
14219void
14220tree_expanded_set(int tree_type, bool_Bool value)
14221{
14222 ws_assert(tree_type >= 0 && tree_type < num_tree_types)do { if ((1) && !(tree_type >= 0 && tree_type
< num_tree_types)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 14222, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14223
14224 if (value)
14225 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14226 else
14227 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14228}
14229
14230/*
14231 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14232 *
14233 * Local variables:
14234 * c-basic-offset: 8
14235 * tab-width: 8
14236 * indent-tabs-mode: t
14237 * End:
14238 *
14239 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14240 * :indentSize=8:tabSize=8:noTabs=false:
14241 */