Bug Summary

File:epan/proto.c
Warning:line 13481, 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-19/lib/clang/19 -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-19/lib/clang/19/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 -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2025-07-13-100258-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
244static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
245static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
246static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
247static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
248static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
249static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
250static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251
252static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
253static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
254static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
255static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
256
257static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
258static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
259static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
260static const char* hfinfo_char_value_format_display(int display, char buf[7], 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#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
455
456/* List which stores protocols and fields that have been registered */
457typedef struct _gpa_hfinfo_t {
458 uint32_t len;
459 uint32_t allocated_len;
460 header_field_info **hfi;
461} gpa_hfinfo_t;
462
463static gpa_hfinfo_t gpa_hfinfo;
464
465/* Hash table of abbreviations and IDs */
466static wmem_map_t *gpa_name_map;
467static header_field_info *same_name_hfinfo;
468
469/* Hash table protocol aliases. const char * -> const char * */
470static GHashTable *gpa_protocol_aliases;
471
472/*
473 * We're called repeatedly with the same field name when sorting a column.
474 * Cache our last gpa_name_map hit for faster lookups.
475 */
476static char *last_field_name;
477static header_field_info *last_hfinfo;
478
479/* Points to the first element of an array of bits, indexed by
480 a subtree item type; that array element is true if subtrees of
481 an item of that type are to be expanded. */
482static uint32_t *tree_is_expanded;
483
484/* Number of elements in that array. The entry with index 0 is not used. */
485int num_tree_types = 1;
486
487/* Name hashtables for fast detection of duplicate names */
488static GHashTable* proto_names;
489static GHashTable* proto_short_names;
490static GHashTable* proto_filter_names;
491
492static const char *reserved_filter_names[] = {
493 /* Display filter keywords. */
494 "eq",
495 "ne",
496 "all_eq",
497 "any_eq",
498 "all_ne",
499 "any_ne",
500 "gt",
501 "ge",
502 "lt",
503 "le",
504 "bitand",
505 "bitwise_and",
506 "contains",
507 "matches",
508 "not",
509 "and",
510 "or",
511 "xor",
512 "in",
513 "any",
514 "all",
515 "true",
516 "false",
517 "nan",
518 "inf",
519 "infinity",
520 NULL((void*)0)
521};
522
523static GHashTable *proto_reserved_filter_names;
524
525static int
526proto_compare_name(const void *p1_arg, const void *p2_arg)
527{
528 const protocol_t *p1 = (const protocol_t *)p1_arg;
529 const protocol_t *p2 = (const protocol_t *)p2_arg;
530
531 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
532}
533
534static GSList *dissector_plugins;
535
536#ifdef HAVE_PLUGINS1
537void
538proto_register_plugin(const proto_plugin *plug)
539{
540 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
541}
542#else /* HAVE_PLUGINS */
543void
544proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
545{
546 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 546, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
547}
548#endif /* HAVE_PLUGINS */
549
550static void
551call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
552{
553 proto_plugin *plug = (proto_plugin *)data;
554
555 if (plug->register_protoinfo) {
556 plug->register_protoinfo();
557 }
558}
559
560static void
561call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
562{
563 proto_plugin *plug = (proto_plugin *)data;
564
565 if (plug->register_handoff) {
566 plug->register_handoff();
567 }
568}
569
570/* initialize data structures and register protocols and fields */
571void
572proto_init(GSList *register_all_plugin_protocols_list,
573 GSList *register_all_plugin_handoffs_list,
574 register_cb cb,
575 void *client_data)
576{
577 proto_cleanup_base();
578
579 proto_names = g_hash_table_new(g_str_hash, g_str_equal);
580 proto_short_names = g_hash_table_new(g_str_hash, g_str_equal);
581 proto_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
582
583 proto_reserved_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
584 for (const char **ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
585 /* GHashTable has no key destructor so the cast is safe. */
586 g_hash_table_add(proto_reserved_filter_names, *(char **)ptr);
587 }
588
589 gpa_hfinfo.len = 0;
590 gpa_hfinfo.allocated_len = 0;
591 gpa_hfinfo.hfi = NULL((void*)0);
592 gpa_name_map = wmem_map_new(wmem_epan_scope(), g_str_hash, g_str_equal);
593 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
594 gpa_protocol_aliases = g_hash_table_new(g_str_hash, g_str_equal);
595 deregistered_fields = g_ptr_array_new();
596 deregistered_data = g_ptr_array_new();
597 deregistered_slice = g_ptr_array_new();
598
599 /* Initialize the ftype subsystem */
600 ftypes_initialize();
601
602 /* Initialize the address type subsystem */
603 address_types_initialize();
604
605 /* Register one special-case FT_TEXT_ONLY field for use when
606 converting wireshark to new-style proto_tree. These fields
607 are merely strings on the GUI tree; they are not filterable */
608 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
609
610 /* Register the pseudo-protocols used for exceptions. */
611 register_show_exception();
612 register_type_length_mismatch();
613 register_byte_array_string_decodinws_error();
614 register_date_time_string_decodinws_error();
615 register_string_errors();
616 ftypes_register_pseudofields();
617 col_register_protocol();
618
619 /* Have each built-in dissector register its protocols, fields,
620 dissector tables, and dissectors to be called through a
621 handle, and do whatever one-time initialization it needs to
622 do. */
623 register_all_protocols(cb, client_data);
624
625 /* Now call the registration routines for all epan plugins. */
626 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
627 ((void (*)(register_cb, void *))l->data)(cb, client_data);
628 }
629
630 /* Now call the registration routines for all dissector plugins. */
631 if (cb)
632 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
633 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
634
635 /* Now call the "handoff registration" routines of all built-in
636 dissectors; those routines register the dissector in other
637 dissectors' handoff tables, and fetch any dissector handles
638 they need. */
639 register_all_protocol_handoffs(cb, client_data);
640
641 /* Now do the same with epan plugins. */
642 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
643 ((void (*)(register_cb, void *))l->data)(cb, client_data);
644 }
645
646 /* Now do the same with dissector plugins. */
647 if (cb)
648 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
649 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
650
651 /* sort the protocols by protocol name */
652 protocols = g_list_sort(protocols, proto_compare_name);
653
654 /* sort the dissector handles in dissector tables (for -G reports
655 * and -d error messages. The GUI sorts the handles itself.) */
656 packet_all_tables_sort_handles();
657
658 /* We've assigned all the subtree type values; allocate the array
659 for them, and zero it out. */
660 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
)))
;
661}
662
663static void
664proto_cleanup_base(void)
665{
666 protocol_t *protocol;
667 header_field_info *hfinfo;
668
669 /* Free the abbrev/ID hash table */
670 if (gpa_name_map) {
671 // XXX - We don't have a wmem_map_destroy, but
672 // it does get cleaned up when epan scope is
673 // destroyed
674 //g_hash_table_destroy(gpa_name_map);
675 gpa_name_map = NULL((void*)0);
676 }
677 if (gpa_protocol_aliases) {
678 g_hash_table_destroy(gpa_protocol_aliases);
679 gpa_protocol_aliases = NULL((void*)0);
680 }
681 g_free(last_field_name);
682 last_field_name = NULL((void*)0);
683
684 while (protocols) {
685 protocol = (protocol_t *)protocols->data;
686 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", 686
, __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", 686, "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", 686, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
687 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", 687, "protocol->proto_id == hfinfo->id"
))))
;
688
689 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)
;
690 if (protocol->parent_proto_id != -1) {
691 // pino protocol
692 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 692, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
693 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"
, 693, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
694 } else {
695 if (protocol->fields) {
696 g_ptr_array_free(protocol->fields, true1);
697 }
698 g_list_free(protocol->heur_list);
699 }
700 protocols = g_list_remove(protocols, protocol);
701 g_free(protocol);
702 }
703
704 if (proto_names) {
705 g_hash_table_destroy(proto_names);
706 proto_names = NULL((void*)0);
707 }
708
709 if (proto_short_names) {
710 g_hash_table_destroy(proto_short_names);
711 proto_short_names = NULL((void*)0);
712 }
713
714 if (proto_filter_names) {
715 g_hash_table_destroy(proto_filter_names);
716 proto_filter_names = NULL((void*)0);
717 }
718
719 if (proto_reserved_filter_names) {
720 g_hash_table_destroy(proto_reserved_filter_names);
721 proto_reserved_filter_names = NULL((void*)0);
722 }
723
724 if (gpa_hfinfo.allocated_len) {
725 gpa_hfinfo.len = 0;
726 gpa_hfinfo.allocated_len = 0;
727 g_free(gpa_hfinfo.hfi);
728 gpa_hfinfo.hfi = NULL((void*)0);
729 }
730
731 if (deregistered_fields) {
732 g_ptr_array_free(deregistered_fields, true1);
733 deregistered_fields = NULL((void*)0);
734 }
735
736 if (deregistered_data) {
737 g_ptr_array_free(deregistered_data, true1);
738 deregistered_data = NULL((void*)0);
739 }
740
741 if (deregistered_slice) {
742 g_ptr_array_free(deregistered_slice, true1);
743 deregistered_slice = NULL((void*)0);
744 }
745
746 g_free(tree_is_expanded);
747 tree_is_expanded = NULL((void*)0);
748
749 if (prefixes)
750 g_hash_table_destroy(prefixes);
751}
752
753void
754proto_cleanup(void)
755{
756 proto_free_deregistered_fields();
757 proto_cleanup_base();
758
759 g_slist_free(dissector_plugins);
760 dissector_plugins = NULL((void*)0);
761}
762
763static bool_Bool
764// NOLINTNEXTLINE(misc-no-recursion)
765proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
766 void *data)
767{
768 proto_node *pnode = tree;
769 proto_node *child;
770 proto_node *current;
771
772 if (func(pnode, data))
773 return true1;
774
775 child = pnode->first_child;
776 while (child != NULL((void*)0)) {
777 /*
778 * The routine we call might modify the child, e.g. by
779 * freeing it, so we get the child's successor before
780 * calling that routine.
781 */
782 current = child;
783 child = current->next;
784 // We recurse here, but we're limited by prefs.gui_max_tree_depth
785 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
786 return true1;
787 }
788
789 return false0;
790}
791
792void
793proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
794 void *data)
795{
796 proto_node *node = tree;
797 proto_node *current;
798
799 if (!node)
800 return;
801
802 node = node->first_child;
803 while (node != NULL((void*)0)) {
804 current = node;
805 node = current->next;
806 func((proto_tree *)current, data);
807 }
808}
809
810static void
811free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
812{
813 GPtrArray *ptrs = (GPtrArray *)value;
814 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
815 header_field_info *hfinfo;
816
817 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", 817, __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", 817, "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", 817, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
818 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
819 /* when a field is referenced by a filter this also
820 affects the refcount for the parent protocol so we need
821 to adjust the refcount for the parent as well
822 */
823 if (hfinfo->parent != -1) {
824 header_field_info *parent_hfinfo;
825 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", 825
, __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", 825, "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", 825, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
826 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
827 }
828 hfinfo->ref_type = HF_REF_TYPE_NONE;
829 }
830
831 g_ptr_array_free(ptrs, true1);
832}
833
834static void
835proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
836{
837 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
838
839 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
840
841 if (finfo) {
842 fvalue_free(finfo->value);
843 finfo->value = NULL((void*)0);
844 }
845}
846
847void
848proto_tree_reset(proto_tree *tree)
849{
850 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
851
852 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
853
854 /* free tree data */
855 if (tree_data->interesting_hfids) {
856 /* Free all the GPtrArray's in the interesting_hfids hash. */
857 g_hash_table_foreach(tree_data->interesting_hfids,
858 free_GPtrArray_value, NULL((void*)0));
859
860 /* And then remove all values. */
861 g_hash_table_remove_all(tree_data->interesting_hfids);
862 }
863
864 /* Reset track of the number of children */
865 tree_data->count = 0;
866
867 /* Reset our loop checks */
868 tree_data->idle_count_ds_tvb = NULL((void*)0);
869 tree_data->max_start = 0;
870 tree_data->start_idle_count = 0;
871
872 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
873}
874
875/* frees the resources that the dissection a proto_tree uses */
876void
877proto_tree_free(proto_tree *tree)
878{
879 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
880
881 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
882
883 /* free tree data */
884 if (tree_data->interesting_hfids) {
885 /* Free all the GPtrArray's in the interesting_hfids hash. */
886 g_hash_table_foreach(tree_data->interesting_hfids,
887 free_GPtrArray_value, NULL((void*)0));
888
889 /* And then destroy the hash. */
890 g_hash_table_destroy(tree_data->interesting_hfids);
891 }
892
893 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)
;
894
895 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
896}
897
898/* Is the parsing being done for a visible proto_tree or an invisible one?
899 * By setting this correctly, the proto_tree creation is sped up by not
900 * having to call vsnprintf and copy strings around.
901 */
902bool_Bool
903proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
904{
905 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
906
907 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
908
909 return old_visible;
910}
911
912void
913proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
914{
915 if (tree)
916 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
917}
918
919/* Assume dissector set only its protocol fields.
920 This function is called by dissectors and allows the speeding up of filtering
921 in wireshark; if this function returns false it is safe to reset tree to NULL
922 and thus skip calling most of the expensive proto_tree_add_...()
923 functions.
924 If the tree is visible we implicitly assume the field is referenced.
925*/
926bool_Bool
927proto_field_is_referenced(proto_tree *tree, int proto_id)
928{
929 register header_field_info *hfinfo;
930
931
932 if (!tree)
933 return false0;
934
935 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
936 return true1;
937
938 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", 938, __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", 938, "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", 938, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
939 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
940 return true1;
941
942 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
943 return true1;
944
945 return false0;
946}
947
948
949/* Finds a record in the hfinfo array by id. */
950header_field_info *
951proto_registrar_get_nth(unsigned hfindex)
952{
953 register header_field_info *hfinfo;
954
955 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", 955, __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", 955, "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", 955, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
956 return hfinfo;
957}
958
959
960/* Prefix initialization
961 * this allows for a dissector to register a display filter name prefix
962 * so that it can delay the initialization of the hf array as long as
963 * possible.
964 */
965
966/* compute a hash for the part before the dot of a display filter */
967static unsigned
968prefix_hash (const void *key) {
969 /* end the string at the dot and compute its hash */
970 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
971 char* c = copy;
972 unsigned tmp;
973
974 for (; *c; c++) {
975 if (*c == '.') {
976 *c = 0;
977 break;
978 }
979 }
980
981 tmp = g_str_hash(copy);
982 g_free(copy);
983 return tmp;
984}
985
986/* are both strings equal up to the end or the dot? */
987static gboolean
988prefix_equal (const void *ap, const void *bp) {
989 const char* a = (const char *)ap;
990 const char* b = (const char *)bp;
991
992 do {
993 char ac = *a++;
994 char bc = *b++;
995
996 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
997
998 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
999 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1000
1001 if (ac != bc) return FALSE(0);
1002 } while (1);
1003
1004 return FALSE(0);
1005}
1006
1007/* Register a new prefix for "delayed" initialization of field arrays */
1008void
1009proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1010 if (! prefixes ) {
1011 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1012 }
1013
1014 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1015}
1016
1017/* helper to call all prefix initializers */
1018static gboolean
1019initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1020 ((prefix_initializer_t)v)((const char *)k);
1021 return TRUE(!(0));
1022}
1023
1024/** Initialize every remaining uninitialized prefix. */
1025void
1026proto_initialize_all_prefixes(void) {
1027 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1028}
1029
1030/* Finds a record in the hfinfo array by name.
1031 * If it fails to find it in the already registered fields,
1032 * it tries to find and call an initializer in the prefixes
1033 * table and if so it looks again.
1034 */
1035
1036header_field_info *
1037proto_registrar_get_byname(const char *field_name)
1038{
1039 header_field_info *hfinfo;
1040 prefix_initializer_t pi;
1041
1042 if (!field_name)
1043 return NULL((void*)0);
1044
1045 if (g_strcmp0(field_name, last_field_name) == 0) {
1046 return last_hfinfo;
1047 }
1048
1049 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1050
1051 if (hfinfo) {
1052 g_free(last_field_name);
1053 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1054 last_hfinfo = hfinfo;
1055 return hfinfo;
1056 }
1057
1058 if (!prefixes)
1059 return NULL((void*)0);
1060
1061 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1062 pi(field_name);
1063 g_hash_table_remove(prefixes, field_name);
1064 } else {
1065 return NULL((void*)0);
1066 }
1067
1068 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1069
1070 if (hfinfo) {
1071 g_free(last_field_name);
1072 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1073 last_hfinfo = hfinfo;
1074 }
1075 return hfinfo;
1076}
1077
1078header_field_info*
1079proto_registrar_get_byalias(const char *alias_name)
1080{
1081 if (!alias_name) {
1082 return NULL((void*)0);
1083 }
1084
1085 /* Find our aliased protocol. */
1086 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1087 char *dot = strchr(an_copy, '.');
1088 if (dot) {
1089 *dot = '\0';
1090 }
1091 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1092 if (!proto_pfx) {
1093 g_free(an_copy);
1094 return NULL((void*)0);
1095 }
1096
1097 /* Construct our aliased field and look it up. */
1098 GString *filter_name = g_string_new(proto_pfx);
1099 if (dot) {
1100 g_string_append_printf(filter_name, ".%s", dot+1);
1101 }
1102 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1103 g_free(an_copy);
1104 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)))))
;
1105
1106 return hfinfo;
1107}
1108
1109int
1110proto_registrar_get_id_byname(const char *field_name)
1111{
1112 header_field_info *hfinfo;
1113
1114 hfinfo = proto_registrar_get_byname(field_name);
1115
1116 if (!hfinfo)
1117 return -1;
1118
1119 return hfinfo->id;
1120}
1121
1122static int
1123label_strcat_flags(const header_field_info *hfinfo)
1124{
1125 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1126 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1127
1128 return 0;
1129}
1130
1131static char *
1132format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1133 const uint8_t *bytes, unsigned length, size_t max_str_len)
1134{
1135 char *str = NULL((void*)0);
1136 const uint8_t *p;
1137 bool_Bool is_printable;
1138
1139 if (bytes) {
1140 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1141 /*
1142 * If all bytes are valid and printable UTF-8, show the
1143 * bytes as a string - in quotes to indicate that it's
1144 * a string.
1145 */
1146 if (isprint_utf8_string(bytes, length)) {
1147 str = wmem_strdup_printf(scope, "\"%.*s\"",
1148 (int)length, bytes);
1149 return str;
1150 }
1151 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1152 /*
1153 * Check whether all bytes are printable.
1154 */
1155 is_printable = true1;
1156 for (p = bytes; p < bytes+length; p++) {
1157 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1158 /* Not printable. */
1159 is_printable = false0;
1160 break;
1161 }
1162 }
1163
1164 /*
1165 * If all bytes are printable ASCII, show the bytes
1166 * as a string - in quotes to indicate that it's
1167 * a string.
1168 */
1169 if (is_printable) {
1170 str = wmem_strdup_printf(scope, "\"%.*s\"",
1171 (int)length, bytes);
1172 return str;
1173 }
1174 }
1175
1176 /*
1177 * Either it's not printable ASCII, or we don't care whether
1178 * it's printable ASCII; show it as hex bytes.
1179 */
1180 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1181 case SEP_DOT:
1182 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1183 break;
1184 case SEP_DASH:
1185 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1186 break;
1187 case SEP_COLON:
1188 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1189 break;
1190 case SEP_SPACE:
1191 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1192 break;
1193 case BASE_NONE:
1194 default:
1195 if (prefs.display_byte_fields_with_spaces) {
1196 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1197 } else {
1198 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1199 }
1200 break;
1201 }
1202 }
1203 else {
1204 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1205 str = wmem_strdup(scope, "<none>");
1206 } else {
1207 str = wmem_strdup(scope, "<MISSING>");
1208 }
1209 }
1210 return str;
1211}
1212
1213static char *
1214format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1215 const uint8_t *bytes, unsigned length)
1216{
1217 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1218}
1219
1220static void
1221ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1222{
1223 subtree_lvl *pushed_tree;
1224
1225 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"
, 1225, "ptvc->pushed_tree_max <= 256-8"))))
;
1226 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1227
1228 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1229 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1229, "pushed_tree != ((void*)0)"
))))
;
1230 ptvc->pushed_tree = pushed_tree;
1231}
1232
1233static void
1234ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1235{
1236 ptvc->pushed_tree = NULL((void*)0);
1237 ptvc->pushed_tree_max = 0;
1238 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", 1238, "ptvc->pushed_tree_index == 0"
))))
;
1239 ptvc->pushed_tree_index = 0;
1240}
1241
1242/* Allocates an initializes a ptvcursor_t with 3 variables:
1243 * proto_tree, tvbuff, and offset. */
1244ptvcursor_t *
1245ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, int offset)
1246{
1247 ptvcursor_t *ptvc;
1248
1249 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1250 ptvc->scope = scope;
1251 ptvc->tree = tree;
1252 ptvc->tvb = tvb;
1253 ptvc->offset = offset;
1254 ptvc->pushed_tree = NULL((void*)0);
1255 ptvc->pushed_tree_max = 0;
1256 ptvc->pushed_tree_index = 0;
1257 return ptvc;
1258}
1259
1260
1261/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1262void
1263ptvcursor_free(ptvcursor_t *ptvc)
1264{
1265 ptvcursor_free_subtree_levels(ptvc);
1266 /*g_free(ptvc);*/
1267}
1268
1269/* Returns tvbuff. */
1270tvbuff_t *
1271ptvcursor_tvbuff(ptvcursor_t *ptvc)
1272{
1273 return ptvc->tvb;
1274}
1275
1276/* Returns current offset. */
1277int
1278ptvcursor_current_offset(ptvcursor_t *ptvc)
1279{
1280 return ptvc->offset;
1281}
1282
1283proto_tree *
1284ptvcursor_tree(ptvcursor_t *ptvc)
1285{
1286 if (!ptvc)
1287 return NULL((void*)0);
1288
1289 return ptvc->tree;
1290}
1291
1292void
1293ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1294{
1295 ptvc->tree = tree;
1296}
1297
1298/* creates a subtree, sets it as the working tree and pushes the old working tree */
1299proto_tree *
1300ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1301{
1302 subtree_lvl *subtree;
1303 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1304 ptvcursor_new_subtree_levels(ptvc);
1305
1306 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1307 subtree->tree = ptvc->tree;
1308 subtree->it= NULL((void*)0);
1309 ptvc->pushed_tree_index++;
1310 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1311}
1312
1313/* pops a subtree */
1314void
1315ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1316{
1317 subtree_lvl *subtree;
1318
1319 if (ptvc->pushed_tree_index <= 0)
1320 return;
1321
1322 ptvc->pushed_tree_index--;
1323 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1324 if (subtree->it != NULL((void*)0))
1325 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1326
1327 ptvc->tree = subtree->tree;
1328}
1329
1330/* saves the current tvb offset and the item in the current subtree level */
1331static void
1332ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1333{
1334 subtree_lvl *subtree;
1335
1336 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", 1336, "ptvc->pushed_tree_index > 0"
))))
;
1337
1338 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1339 subtree->it = it;
1340 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1341}
1342
1343/* Creates a subtree and adds it to the cursor as the working tree but does not
1344 * save the old working tree */
1345proto_tree *
1346ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1347{
1348 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1349 return ptvc->tree;
1350}
1351
1352static proto_tree *
1353ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1354{
1355 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1356 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1357 ptvcursor_subtree_set_item(ptvc, it);
1358 return ptvcursor_tree(ptvc);
1359}
1360
1361/* Add an item to the tree and create a subtree
1362 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1363 * In this case, when the subtree will be closed, the parent item length will
1364 * be equal to the advancement of the cursor since the creation of the subtree.
1365 */
1366proto_tree *
1367ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1368 const unsigned encoding, int ett_subtree)
1369{
1370 proto_item *it;
1371
1372 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1373 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1374}
1375
1376static proto_item *
1377proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1378
1379/* Add a text node to the tree and create a subtree
1380 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1381 * In this case, when the subtree will be closed, the item length will be equal
1382 * to the advancement of the cursor since the creation of the subtree.
1383 */
1384proto_tree *
1385ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1386 int ett_subtree, const char *format, ...)
1387{
1388 proto_item *pi;
1389 va_list ap;
1390 header_field_info *hfinfo;
1391 proto_tree *tree;
1392
1393 tree = ptvcursor_tree(ptvc);
1394
1395 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1396
1397 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", 1397
, __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", 1397, "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", 1397, "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", 1397, __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)
; } } }
;
1398
1399 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1400 ptvcursor_current_offset(ptvc), length);
1401
1402 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1402, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1403
1404 va_start(ap, format)__builtin_va_start(ap, format);
1405 proto_tree_set_representation(pi, format, ap);
1406 va_end(ap)__builtin_va_end(ap);
1407
1408 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1409}
1410
1411/* Add a text-only node, leaving it to our caller to fill the text in */
1412static proto_item *
1413proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1414{
1415 proto_item *pi;
1416
1417 if (tree == NULL((void*)0))
1418 return NULL((void*)0);
1419
1420 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1421
1422 return pi;
1423}
1424
1425/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1426proto_item *
1427proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1428 const char *format, ...)
1429{
1430 proto_item *pi;
1431 va_list ap;
1432 header_field_info *hfinfo;
1433
1434 if (length == -1) {
1435 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1436 } else {
1437 tvb_ensure_bytes_exist(tvb, start, length);
1438 }
1439
1440 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1441
1442 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", 1442
, __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", 1442, "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", 1442, "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", 1442, __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)
; } } }
;
1443
1444 pi = proto_tree_add_text_node(tree, tvb, start, length);
1445
1446 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1446, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1447
1448 va_start(ap, format)__builtin_va_start(ap, format);
1449 proto_tree_set_representation(pi, format, ap);
1450 va_end(ap)__builtin_va_end(ap);
1451
1452 return pi;
1453}
1454
1455/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1456proto_item *
1457proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1458 int length, const char *format, va_list ap)
1459{
1460 proto_item *pi;
1461 header_field_info *hfinfo;
1462
1463 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1464 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1465 * the length to be what's in the tvbuff if length is -1, and the
1466 * minimum of length and what's in the tvbuff if not.
1467 */
1468
1469 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1470
1471 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", 1471
, __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", 1471, "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", 1471, "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", 1471, __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)
; } } }
;
1472
1473 pi = proto_tree_add_text_node(tree, tvb, start, length);
1474
1475 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1475, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1476
1477 proto_tree_set_representation(pi, format, ap);
1478
1479 return pi;
1480}
1481
1482/* Add a text-only node that creates a subtree underneath.
1483 */
1484proto_tree *
1485proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1486{
1487 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1488}
1489
1490/* Add a text-only node that creates a subtree underneath.
1491 */
1492proto_tree *
1493proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1494{
1495 proto_tree *pt;
1496 proto_item *pi;
1497 va_list ap;
1498
1499 va_start(ap, format)__builtin_va_start(ap, format);
1500 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1501 va_end(ap)__builtin_va_end(ap);
1502
1503 if (tree_item != NULL((void*)0))
1504 *tree_item = pi;
1505
1506 pt = proto_item_add_subtree(pi, idx);
1507
1508 return pt;
1509}
1510
1511/* Add a text-only node for debugging purposes. The caller doesn't need
1512 * to worry about tvbuff, start, or length. Debug message gets sent to
1513 * STDOUT, too */
1514proto_item *
1515proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1516{
1517 proto_item *pi;
1518 va_list ap;
1519
1520 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1521
1522 if (pi) {
1523 va_start(ap, format)__builtin_va_start(ap, format);
1524 proto_tree_set_representation(pi, format, ap);
1525 va_end(ap)__builtin_va_end(ap);
1526 }
1527 va_start(ap, format)__builtin_va_start(ap, format);
1528 vprintf(format, ap);
1529 va_end(ap)__builtin_va_end(ap);
1530 printf("\n");
1531
1532 return pi;
1533}
1534
1535proto_item *
1536proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1537{
1538 proto_item *pi;
1539 header_field_info *hfinfo;
1540
1541 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1542
1543 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", 1543
, __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", 1543, "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", 1543, "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", 1543, __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)
; } } }
;
1544
1545 pi = proto_tree_add_text_node(tree, tvb, start, length);
1546
1547 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1547, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1548
1549 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1550
1551 return pi;
1552}
1553
1554proto_item *
1555proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1556{
1557 proto_item *pi;
1558 header_field_info *hfinfo;
1559 char *str;
1560
1561 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1562
1563 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", 1563
, __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", 1563, "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", 1563, "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", 1563, __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)
; } } }
;
1564
1565 pi = proto_tree_add_text_node(tree, tvb, start, length);
1566
1567 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1567, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1568
1569 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1570 proto_item_set_text(pi, "%s", str);
1571 wmem_free(NULL((void*)0), str);
1572
1573 return pi;
1574}
1575
1576void proto_report_dissector_bug(const char *format, ...)
1577{
1578 va_list args;
1579
1580 if (wireshark_abort_on_dissector_bug) {
1581 /*
1582 * Try to have the error message show up in the crash
1583 * information.
1584 */
1585 va_start(args, format)__builtin_va_start(args, format);
1586 ws_vadd_crash_info(format, args);
1587 va_end(args)__builtin_va_end(args);
1588
1589 /*
1590 * Print the error message.
1591 */
1592 va_start(args, format)__builtin_va_start(args, format);
1593 vfprintf(stderrstderr, format, args);
1594 va_end(args)__builtin_va_end(args);
1595 putc('\n', stderrstderr);
1596
1597 /*
1598 * And crash.
1599 */
1600 abort();
1601 } else {
1602 va_start(args, format)__builtin_va_start(args, format);
1603 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1604 va_end(args)__builtin_va_end(args);
1605 }
1606}
1607
1608/* We could probably get away with changing is_error to a minimum length value. */
1609static void
1610report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1611{
1612 if (is_error) {
1613 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1614 } else {
1615 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1616 }
1617
1618 if (is_error) {
1619 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1620 }
1621}
1622
1623static uint32_t
1624get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1625{
1626 uint32_t value;
1627 bool_Bool length_error;
1628
1629 switch (length) {
1630
1631 case 1:
1632 value = tvb_get_uint8(tvb, offset);
1633 if (encoding & ENC_ZIGBEE0x40000000) {
1634 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1635 value = 0;
1636 }
1637 }
1638 break;
1639
1640 case 2:
1641 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1642 : tvb_get_ntohs(tvb, offset);
1643 if (encoding & ENC_ZIGBEE0x40000000) {
1644 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1645 value = 0;
1646 }
1647 }
1648 break;
1649
1650 case 3:
1651 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1652 : tvb_get_ntoh24(tvb, offset);
1653 break;
1654
1655 case 4:
1656 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1657 : tvb_get_ntohl(tvb, offset);
1658 break;
1659
1660 default:
1661 if (length < 1) {
1662 length_error = true1;
1663 value = 0;
1664 } else {
1665 length_error = false0;
1666 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1667 : tvb_get_ntohl(tvb, offset);
1668 }
1669 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1670 break;
1671 }
1672 return value;
1673}
1674
1675static inline uint64_t
1676get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1677{
1678 uint64_t value;
1679
1680 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1681
1682 if (length < 1 || length > 8) {
1683 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1684 }
1685
1686 return value;
1687}
1688
1689static int32_t
1690get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1691{
1692 int32_t value;
1693 bool_Bool length_error;
1694
1695 switch (length) {
1696
1697 case 1:
1698 value = tvb_get_int8(tvb, offset);
1699 break;
1700
1701 case 2:
1702 value = encoding ? tvb_get_letohis(tvb, offset)
1703 : tvb_get_ntohis(tvb, offset);
1704 break;
1705
1706 case 3:
1707 value = encoding ? tvb_get_letohi24(tvb, offset)
1708 : tvb_get_ntohi24(tvb, offset);
1709 break;
1710
1711 case 4:
1712 value = encoding ? tvb_get_letohil(tvb, offset)
1713 : tvb_get_ntohil(tvb, offset);
1714 break;
1715
1716 default:
1717 if (length < 1) {
1718 length_error = true1;
1719 value = 0;
1720 } else {
1721 length_error = false0;
1722 value = encoding ? tvb_get_letohil(tvb, offset)
1723 : tvb_get_ntohil(tvb, offset);
1724 }
1725 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1726 break;
1727 }
1728 return value;
1729}
1730
1731/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1732 * be cast-able as a int64_t. This is weird, but what the code has always done.
1733 */
1734static inline uint64_t
1735get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1736{
1737 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1738
1739 switch (length) {
1740 case 7:
1741 value = ws_sign_ext64(value, 56);
1742 break;
1743 case 6:
1744 value = ws_sign_ext64(value, 48);
1745 break;
1746 case 5:
1747 value = ws_sign_ext64(value, 40);
1748 break;
1749 case 4:
1750 value = ws_sign_ext64(value, 32);
1751 break;
1752 case 3:
1753 value = ws_sign_ext64(value, 24);
1754 break;
1755 case 2:
1756 value = ws_sign_ext64(value, 16);
1757 break;
1758 case 1:
1759 value = ws_sign_ext64(value, 8);
1760 break;
1761 }
1762
1763 return value;
1764}
1765
1766/* For FT_STRING */
1767static inline const uint8_t *
1768get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1769 int length, int *ret_length, const unsigned encoding)
1770{
1771 if (length == -1) {
1772 length = tvb_ensure_captured_length_remaining(tvb, start);
1773 }
1774 *ret_length = length;
1775 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1776}
1777
1778/* For FT_STRINGZ */
1779static inline const uint8_t *
1780get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1781 int start, int length, int *ret_length, const unsigned encoding)
1782{
1783 const uint8_t *value;
1784
1785 if (length < -1) {
1786 report_type_length_mismatch(tree, "a string", length, true1);
1787 }
1788 if (length == -1) {
1789 /* This can throw an exception */
1790 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1791 } else {
1792 /* In this case, length signifies the length of the string.
1793 *
1794 * This could either be a null-padded string, which doesn't
1795 * necessarily have a '\0' at the end, or a null-terminated
1796 * string, with a trailing '\0'. (Yes, there are cases
1797 * where you have a string that's both counted and null-
1798 * terminated.)
1799 *
1800 * In the first case, we must allocate a buffer of length
1801 * "length+1", to make room for a trailing '\0'.
1802 *
1803 * In the second case, we don't assume that there is a
1804 * trailing '\0' there, as the packet might be malformed.
1805 * (XXX - should we throw an exception if there's no
1806 * trailing '\0'?) Therefore, we allocate a buffer of
1807 * length "length+1", and put in a trailing '\0', just to
1808 * be safe.
1809 *
1810 * (XXX - this would change if we made string values counted
1811 * rather than null-terminated.)
1812 */
1813 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1814 }
1815 *ret_length = length;
1816 return value;
1817}
1818
1819/* For FT_UINT_STRING */
1820static inline const uint8_t *
1821get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1822 tvbuff_t *tvb, int start, int length, int *ret_length,
1823 const unsigned encoding)
1824{
1825 uint32_t n;
1826 const uint8_t *value;
1827
1828 /* I believe it's ok if this is called with a NULL tree */
1829 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1830 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1831 length += n;
1832 *ret_length = length;
1833 return value;
1834}
1835
1836/* For FT_STRINGZPAD */
1837static inline const uint8_t *
1838get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1839 int length, int *ret_length, const unsigned encoding)
1840{
1841 /*
1842 * XXX - currently, string values are null-
1843 * terminated, so a "zero-padded" string
1844 * isn't special. If we represent string
1845 * values as something that includes a counted
1846 * array of bytes, we'll need to strip the
1847 * trailing NULs.
1848 */
1849 if (length == -1) {
1850 length = tvb_ensure_captured_length_remaining(tvb, start);
1851 }
1852 *ret_length = length;
1853 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1854}
1855
1856/* For FT_STRINGZTRUNC */
1857static inline const uint8_t *
1858get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1859 int length, int *ret_length, const unsigned encoding)
1860{
1861 /*
1862 * XXX - currently, string values are null-
1863 * terminated, so a "zero-truncated" string
1864 * isn't special. If we represent string
1865 * values as something that includes a counted
1866 * array of bytes, we'll need to strip everything
1867 * starting with the terminating NUL.
1868 */
1869 if (length == -1) {
1870 length = tvb_ensure_captured_length_remaining(tvb, start);
1871 }
1872 *ret_length = length;
1873 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1874}
1875
1876/*
1877 * Deltas between the epochs for various non-UN*X time stamp formats and
1878 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1879 * stamp format.
1880 */
1881
1882/*
1883 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1884 * XXX - if it's OK if this is unsigned, can we just use
1885 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1886 */
1887#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1888
1889/*
1890 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1891 */
1892#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1893
1894/* this can be called when there is no tree, so tree may be null */
1895static void
1896get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1897 const int length, const unsigned encoding, nstime_t *time_stamp,
1898 const bool_Bool is_relative)
1899{
1900 uint32_t tmpsecs;
1901 uint64_t tmp64secs;
1902 uint64_t todusecs;
1903
1904 switch (encoding) {
1905
1906 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1907 /*
1908 * If the length is 16, 8-byte seconds, followed
1909 * by 8-byte fractional time in nanoseconds,
1910 * both big-endian.
1911 *
1912 * If the length is 12, 8-byte seconds, followed
1913 * by 4-byte fractional time in nanoseconds,
1914 * both big-endian.
1915 *
1916 * If the length is 8, 4-byte seconds, followed
1917 * by 4-byte fractional time in nanoseconds,
1918 * both big-endian.
1919 *
1920 * For absolute times, the seconds are seconds
1921 * since the UN*X epoch.
1922 */
1923 if (length == 16) {
1924 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1925 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1926 } else if (length == 12) {
1927 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1928 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1929 } else if (length == 8) {
1930 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1931 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1932 } else if (length == 4) {
1933 /*
1934 * Backwards compatibility.
1935 * ENC_TIME_SECS_NSECS is 0; using
1936 * ENC_BIG_ENDIAN by itself with a 4-byte
1937 * time-in-seconds value was done in the
1938 * past.
1939 */
1940 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1941 time_stamp->nsecs = 0;
1942 } else {
1943 time_stamp->secs = 0;
1944 time_stamp->nsecs = 0;
1945 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1946 }
1947 break;
1948
1949 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
1950 /*
1951 * If the length is 16, 8-byte seconds, followed
1952 * by 8-byte fractional time in nanoseconds,
1953 * both little-endian.
1954 *
1955 * If the length is 12, 8-byte seconds, followed
1956 * by 4-byte fractional time in nanoseconds,
1957 * both little-endian.
1958 *
1959 * If the length is 8, 4-byte seconds, followed
1960 * by 4-byte fractional time in nanoseconds,
1961 * both little-endian.
1962 *
1963 * For absolute times, the seconds are seconds
1964 * since the UN*X epoch.
1965 */
1966 if (length == 16) {
1967 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
1968 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
1969 } else if (length == 12) {
1970 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
1971 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
1972 } else if (length == 8) {
1973 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1974 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1975 } else if (length == 4) {
1976 /*
1977 * Backwards compatibility.
1978 * ENC_TIME_SECS_NSECS is 0; using
1979 * ENC_LITTLE_ENDIAN by itself with a 4-byte
1980 * time-in-seconds value was done in the
1981 * past.
1982 */
1983 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1984 time_stamp->nsecs = 0;
1985 } else {
1986 time_stamp->secs = 0;
1987 time_stamp->nsecs = 0;
1988 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1989 }
1990 break;
1991
1992 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
1993 /*
1994 * NTP time stamp, big-endian.
1995 * Only supported for absolute times.
1996 */
1997 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1997, "!is_relative"
))))
;
1998
1999 /* We need a temporary variable here so the unsigned math
2000 * works correctly (for years > 2036 according to RFC 2030
2001 * chapter 3).
2002 *
2003 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2004 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2005 * If bit 0 is not set, the time is in the range 2036-2104 and
2006 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2007 */
2008 tmpsecs = tvb_get_ntohl(tvb, start);
2009 if ((tmpsecs & 0x80000000) != 0)
2010 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2011 else
2012 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2013
2014 if (length == 8) {
2015 tmp64secs = tvb_get_ntoh64(tvb, start);
2016 if (tmp64secs == 0) {
2017 //This is "NULL" time
2018 time_stamp->secs = 0;
2019 time_stamp->nsecs = 0;
2020 } else {
2021 /*
2022 * Convert 1/2^32s of a second to
2023 * nanoseconds.
2024 */
2025 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2026 }
2027 } else if (length == 4) {
2028 /*
2029 * Backwards compatibility.
2030 */
2031 if (tmpsecs == 0) {
2032 //This is "NULL" time
2033 time_stamp->secs = 0;
2034 }
2035 time_stamp->nsecs = 0;
2036 } else {
2037 time_stamp->secs = 0;
2038 time_stamp->nsecs = 0;
2039 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2040 }
2041 break;
2042
2043 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2044 /*
2045 * NTP time stamp, little-endian.
2046 * Only supported for absolute times.
2047 *
2048 * NTP doesn't use this, because it's an Internet format
2049 * and hence big-endian. Any implementation must decide
2050 * whether the NTP timestamp is a 64-bit unsigned fixed
2051 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2052 * with a 32-bit unsigned seconds field followed by a
2053 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2054 * the previous two).
2055 *
2056 * XXX: We do the latter, but no dissector uses this format.
2057 * OTOH, ERF timestamps do the former, so perhaps we
2058 * should switch the interpretation so that packet-erf.c
2059 * could use this directly?
2060 */
2061 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2061, "!is_relative"
))))
;
2062
2063 /* We need a temporary variable here so the unsigned math
2064 * works correctly (for years > 2036 according to RFC 2030
2065 * chapter 3).
2066 *
2067 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2068 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2069 * If bit 0 is not set, the time is in the range 2036-2104 and
2070 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2071 */
2072 tmpsecs = tvb_get_letohl(tvb, start);
2073 if ((tmpsecs & 0x80000000) != 0)
2074 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2075 else
2076 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2077
2078 if (length == 8) {
2079 tmp64secs = tvb_get_letoh64(tvb, start);
2080 if (tmp64secs == 0) {
2081 //This is "NULL" time
2082 time_stamp->secs = 0;
2083 time_stamp->nsecs = 0;
2084 } else {
2085 /*
2086 * Convert 1/2^32s of a second to
2087 * nanoseconds.
2088 */
2089 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2090 }
2091 } else if (length == 4) {
2092 /*
2093 * Backwards compatibility.
2094 */
2095 if (tmpsecs == 0) {
2096 //This is "NULL" time
2097 time_stamp->secs = 0;
2098 }
2099 time_stamp->nsecs = 0;
2100 } else {
2101 time_stamp->secs = 0;
2102 time_stamp->nsecs = 0;
2103 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2104 }
2105 break;
2106
2107 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2108 /*
2109 * S/3x0 and z/Architecture TOD clock time stamp,
2110 * big-endian. The epoch is January 1, 1900,
2111 * 00:00:00 (proleptic?) UTC.
2112 *
2113 * Only supported for absolute times.
2114 */
2115 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2115, "!is_relative"
))))
;
2116 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2116, "length == 8"
))))
;
2117
2118 if (length == 8) {
2119 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2120 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2121 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2122 } else {
2123 time_stamp->secs = 0;
2124 time_stamp->nsecs = 0;
2125 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2126 }
2127 break;
2128
2129 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2130 /*
2131 * S/3x0 and z/Architecture TOD clock time stamp,
2132 * little-endian. The epoch is January 1, 1900,
2133 * 00:00:00 (proleptic?) UTC.
2134 *
2135 * Only supported for absolute times.
2136 */
2137 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2137, "!is_relative"
))))
;
2138
2139 if (length == 8) {
2140 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2141 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2142 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2143 } else {
2144 time_stamp->secs = 0;
2145 time_stamp->nsecs = 0;
2146 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2147 }
2148 break;
2149
2150 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2151 /*
2152 * Time stamp using the same seconds/fraction format
2153 * as NTP, but with the origin of the time stamp being
2154 * the UNIX epoch rather than the NTP epoch; big-
2155 * endian.
2156 *
2157 * Only supported for absolute times.
2158 */
2159 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2159, "!is_relative"
))))
;
2160
2161 if (length == 8) {
2162 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2163 /*
2164 * Convert 1/2^32s of a second to nanoseconds.
2165 */
2166 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2167 } else {
2168 time_stamp->secs = 0;
2169 time_stamp->nsecs = 0;
2170 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2171 }
2172 break;
2173
2174 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2175 /*
2176 * Time stamp using the same seconds/fraction format
2177 * as NTP, but with the origin of the time stamp being
2178 * the UNIX epoch rather than the NTP epoch; little-
2179 * endian.
2180 *
2181 * Only supported for absolute times.
2182 *
2183 * The RTPS specification explicitly supports Little
2184 * Endian encoding. In one place, it states that its
2185 * Time_t representation "is the one defined by ...
2186 * RFC 1305", but in another explicitly defines it as
2187 * a struct consisting of an 32 bit unsigned seconds
2188 * field and a 32 bit unsigned fraction field, not a 64
2189 * bit fixed point, so we do that here.
2190 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2191 */
2192 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2192, "!is_relative"
))))
;
2193
2194 if (length == 8) {
2195 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2196 /*
2197 * Convert 1/2^32s of a second to nanoseconds.
2198 */
2199 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2200 } else {
2201 time_stamp->secs = 0;
2202 time_stamp->nsecs = 0;
2203 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2204 }
2205 break;
2206
2207 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2208 /*
2209 * MIP6 time stamp, big-endian.
2210 * A 64-bit unsigned integer field containing a timestamp. The
2211 * value indicates the number of seconds since January 1, 1970,
2212 * 00:00 UTC, by using a fixed point format. In this format, the
2213 * integer number of seconds is contained in the first 48 bits of
2214 * the field, and the remaining 16 bits indicate the number of
2215 * 1/65536 fractions of a second.
2216
2217 * Only supported for absolute times.
2218 */
2219 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2219, "!is_relative"
))))
;
2220
2221 if (length == 8) {
2222 /* We need a temporary variable here so the casting and fractions
2223 * of a second work correctly.
2224 */
2225 tmp64secs = tvb_get_ntoh48(tvb, start);
2226 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2227 tmpsecs <<= 16;
2228
2229 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2230 //This is "NULL" time
2231 time_stamp->secs = 0;
2232 time_stamp->nsecs = 0;
2233 } else {
2234 time_stamp->secs = (time_t)tmp64secs;
2235 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2236 }
2237 } else {
2238 time_stamp->secs = 0;
2239 time_stamp->nsecs = 0;
2240 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2241 }
2242 break;
2243
2244 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2245 /*
2246 * If the length is 16, 8-byte seconds, followed
2247 * by 8-byte fractional time in microseconds,
2248 * both big-endian.
2249 *
2250 * If the length is 12, 8-byte seconds, followed
2251 * by 4-byte fractional time in microseconds,
2252 * both big-endian.
2253 *
2254 * If the length is 8, 4-byte seconds, followed
2255 * by 4-byte fractional time in microseconds,
2256 * both big-endian.
2257 *
2258 * For absolute times, the seconds are seconds
2259 * since the UN*X epoch.
2260 */
2261 if (length == 16) {
2262 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2263 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2264 } else if (length == 12) {
2265 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2266 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2267 } else if (length == 8) {
2268 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2269 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2270 } else {
2271 time_stamp->secs = 0;
2272 time_stamp->nsecs = 0;
2273 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2274 }
2275 break;
2276
2277 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2278 /*
2279 * If the length is 16, 8-byte seconds, followed
2280 * by 8-byte fractional time in microseconds,
2281 * both little-endian.
2282 *
2283 * If the length is 12, 8-byte seconds, followed
2284 * by 4-byte fractional time in microseconds,
2285 * both little-endian.
2286 *
2287 * If the length is 8, 4-byte seconds, followed
2288 * by 4-byte fractional time in microseconds,
2289 * both little-endian.
2290 *
2291 * For absolute times, the seconds are seconds
2292 * since the UN*X epoch.
2293 */
2294 if (length == 16) {
2295 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2296 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2297 } else if (length == 12) {
2298 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2299 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2300 } else if (length == 8) {
2301 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2302 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2303 } else {
2304 time_stamp->secs = 0;
2305 time_stamp->nsecs = 0;
2306 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2307 }
2308 break;
2309
2310 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2311 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2312 /*
2313 * Seconds, 1 to 8 bytes.
2314 * For absolute times, it's seconds since the
2315 * UN*X epoch.
2316 */
2317 if (length >= 1 && length <= 8) {
2318 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2319 time_stamp->nsecs = 0;
2320 } else {
2321 time_stamp->secs = 0;
2322 time_stamp->nsecs = 0;
2323 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2324 }
2325 break;
2326
2327 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2328 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2329 /*
2330 * Milliseconds, 1 to 8 bytes.
2331 * For absolute times, it's milliseconds since the
2332 * UN*X epoch.
2333 */
2334 if (length >= 1 && length <= 8) {
2335 uint64_t msecs;
2336
2337 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2338 time_stamp->secs = (time_t)(msecs / 1000);
2339 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2340 } else {
2341 time_stamp->secs = 0;
2342 time_stamp->nsecs = 0;
2343 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2344 }
2345 break;
2346
2347 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2348 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2349 /*
2350 * Microseconds, 1 to 8 bytes.
2351 * For absolute times, it's microseconds since the
2352 * UN*X epoch.
2353 */
2354 if (length >= 1 && length <= 8) {
2355 uint64_t usecs;
2356
2357 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2358 time_stamp->secs = (time_t)(usecs / 1000000);
2359 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2360 } else {
2361 time_stamp->secs = 0;
2362 time_stamp->nsecs = 0;
2363 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2364 }
2365 break;
2366
2367 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2368 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2369 /*
2370 * nanoseconds, 1 to 8 bytes.
2371 * For absolute times, it's nanoseconds since the
2372 * UN*X epoch.
2373 */
2374
2375 if (length >= 1 && length <= 8) {
2376 uint64_t nsecs;
2377
2378 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2379 time_stamp->secs = (time_t)(nsecs / 1000000000);
2380 time_stamp->nsecs = (int)(nsecs % 1000000000);
2381 } else {
2382 time_stamp->secs = 0;
2383 time_stamp->nsecs = 0;
2384 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2385 }
2386 break;
2387
2388 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2389 /*
2390 * 1/64ths of a second since the UN*X epoch,
2391 * big-endian.
2392 *
2393 * Only supported for absolute times.
2394 */
2395 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2395, "!is_relative"
))))
;
2396
2397 if (length == 8) {
2398 /*
2399 * The upper 48 bits are seconds since the
2400 * UN*X epoch.
2401 */
2402 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2403 /*
2404 * The lower 16 bits are 1/2^16s of a second;
2405 * convert them to nanoseconds.
2406 *
2407 * XXX - this may give the impression of higher
2408 * precision than you actually get.
2409 */
2410 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2411 } else {
2412 time_stamp->secs = 0;
2413 time_stamp->nsecs = 0;
2414 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2415 }
2416 break;
2417
2418 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2419 /*
2420 * 1/64ths of a second since the UN*X epoch,
2421 * little-endian.
2422 *
2423 * Only supported for absolute times.
2424 */
2425 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2425, "!is_relative"
))))
;
2426
2427 if (length == 8) {
2428 /*
2429 * XXX - this is assuming that, if anybody
2430 * were ever to use this format - RFC 3971
2431 * doesn't, because that's an Internet
2432 * protocol, and those use network byte
2433 * order, i.e. big-endian - they'd treat it
2434 * as a 64-bit count of 1/2^16s of a second,
2435 * putting the upper 48 bits at the end.
2436 *
2437 * The lower 48 bits are seconds since the
2438 * UN*X epoch.
2439 */
2440 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2441 /*
2442 * The upper 16 bits are 1/2^16s of a second;
2443 * convert them to nanoseconds.
2444 *
2445 * XXX - this may give the impression of higher
2446 * precision than you actually get.
2447 */
2448 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2449 } else {
2450 time_stamp->secs = 0;
2451 time_stamp->nsecs = 0;
2452 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2453 }
2454 break;
2455
2456 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2457 /*
2458 * NTP time stamp, with 1-second resolution (i.e.,
2459 * seconds since the NTP epoch), big-endian.
2460 * Only supported for absolute times.
2461 */
2462 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2462, "!is_relative"
))))
;
2463
2464 if (length == 4) {
2465 /*
2466 * We need a temporary variable here so the unsigned math
2467 * works correctly (for years > 2036 according to RFC 2030
2468 * chapter 3).
2469 *
2470 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2471 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2472 * If bit 0 is not set, the time is in the range 2036-2104 and
2473 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2474 */
2475 tmpsecs = tvb_get_ntohl(tvb, start);
2476 if ((tmpsecs & 0x80000000) != 0)
2477 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2478 else
2479 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2480 time_stamp->nsecs = 0;
2481 } else {
2482 time_stamp->secs = 0;
2483 time_stamp->nsecs = 0;
2484 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2485 }
2486 break;
2487
2488 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2489 /*
2490 * NTP time stamp, with 1-second resolution (i.e.,
2491 * seconds since the NTP epoch), little-endian.
2492 * Only supported for absolute times.
2493 */
2494 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2494, "!is_relative"
))))
;
2495
2496 /*
2497 * We need a temporary variable here so the unsigned math
2498 * works correctly (for years > 2036 according to RFC 2030
2499 * chapter 3).
2500 *
2501 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2502 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2503 * If bit 0 is not set, the time is in the range 2036-2104 and
2504 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2505 */
2506 if (length == 4) {
2507 tmpsecs = tvb_get_letohl(tvb, start);
2508 if ((tmpsecs & 0x80000000) != 0)
2509 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2510 else
2511 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2512 time_stamp->nsecs = 0;
2513 } else {
2514 time_stamp->secs = 0;
2515 time_stamp->nsecs = 0;
2516 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2517 }
2518 break;
2519
2520 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2521 /*
2522 * Milliseconds, 6 to 8 bytes.
2523 * For absolute times, it's milliseconds since the
2524 * NTP epoch.
2525 *
2526 * ETSI TS 129.274 8.119 defines this as:
2527 * "a 48 bit unsigned integer in network order format
2528 * ...encoded as the number of milliseconds since
2529 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2530 * rounded value of 1000 x the value of the 64-bit
2531 * timestamp (Seconds + (Fraction / (1<<32))) defined
2532 * in clause 6 of IETF RFC 5905."
2533 *
2534 * Taken literally, the part after "i.e." would
2535 * mean that the value rolls over before reaching
2536 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2537 * when the 64 bit timestamp rolls over, and we have
2538 * to pick an NTP Era equivalence class to support
2539 * (such as 1968-01-20 to 2104-02-06).
2540 *
2541 * OTOH, the extra room might be used to store Era
2542 * information instead, in which case times until
2543 * 10819-08-03 can be represented with 6 bytes without
2544 * ambiguity. We handle both implementations, and assume
2545 * that times before 1968-01-20 are not represented.
2546 *
2547 * Only 6 bytes or more makes sense as an absolute
2548 * time. 5 bytes or fewer could express a span of
2549 * less than 35 years, either 1900-1934 or 2036-2070.
2550 */
2551 if (length >= 6 && length <= 8) {
2552 uint64_t msecs;
2553
2554 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2555 tmp64secs = (msecs / 1000);
2556 /*
2557 * Assume that times in the first half of NTP
2558 * Era 0 really represent times in the NTP
2559 * Era 1.
2560 */
2561 if (tmp64secs >= 0x80000000)
2562 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2563 else
2564 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2565 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2566 }
2567 else {
2568 time_stamp->secs = 0;
2569 time_stamp->nsecs = 0;
2570 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2571 }
2572 break;
2573
2574 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2575 /*
2576 * MP4 file time stamps, big-endian.
2577 * Only supported for absolute times.
2578 */
2579 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2579, "!is_relative"
))))
;
2580
2581 if (length == 8) {
2582 tmp64secs = tvb_get_ntoh64(tvb, start);
2583 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2584 time_stamp->nsecs = 0;
2585 } else if (length == 4) {
2586 tmpsecs = tvb_get_ntohl(tvb, start);
2587 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2588 time_stamp->nsecs = 0;
2589 } else {
2590 time_stamp->secs = 0;
2591 time_stamp->nsecs = 0;
2592 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2593 }
2594 break;
2595
2596 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2597 /*
2598 * Zigbee ZCL time stamps, big-endian.
2599 * Only supported for absolute times.
2600 */
2601 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2601, "!is_relative"
))))
;
2602
2603 if (length == 8) {
2604 tmp64secs = tvb_get_ntoh64(tvb, start);
2605 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);
2606 time_stamp->nsecs = 0;
2607 } else if (length == 4) {
2608 tmpsecs = tvb_get_ntohl(tvb, start);
2609 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2610 time_stamp->nsecs = 0;
2611 } else {
2612 time_stamp->secs = 0;
2613 time_stamp->nsecs = 0;
2614 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2615 }
2616 break;
2617
2618 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2619 /*
2620 * Zigbee ZCL time stamps, little-endian.
2621 * Only supported for absolute times.
2622 */
2623 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2623, "!is_relative"
))))
;
2624
2625 if (length == 8) {
2626 tmp64secs = tvb_get_letoh64(tvb, start);
2627 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);
2628 time_stamp->nsecs = 0;
2629 } else if (length == 4) {
2630 tmpsecs = tvb_get_letohl(tvb, start);
2631 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2632 time_stamp->nsecs = 0;
2633 } else {
2634 time_stamp->secs = 0;
2635 time_stamp->nsecs = 0;
2636 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2637 }
2638 break;
2639
2640 default:
2641 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2641))
;
2642 break;
2643 }
2644}
2645
2646static void
2647tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2648{
2649 const header_field_info *hfinfo = fi->hfinfo;
2650
2651 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2652 GPtrArray *ptrs = NULL((void*)0);
2653
2654 if (tree_data->interesting_hfids == NULL((void*)0)) {
2655 /* Initialize the hash because we now know that it is needed */
2656 tree_data->interesting_hfids =
2657 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2658 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2659 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2660 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2661 }
2662
2663 if (!ptrs) {
2664 /* First element triggers the creation of pointer array */
2665 ptrs = g_ptr_array_new();
2666 g_hash_table_insert(tree_data->interesting_hfids,
2667 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2668 }
2669
2670 g_ptr_array_add(ptrs, fi);
2671 }
2672}
2673
2674
2675/*
2676 * Validates that field length bytes are available starting from
2677 * start (pos/neg). Throws an exception if they aren't.
2678 */
2679static void
2680test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2681 int start, int length, const unsigned encoding)
2682{
2683 int size = length;
2684
2685 if (!tvb)
2686 return;
2687
2688 if ((hfinfo->type == FT_STRINGZ) ||
2689 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2690 (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
))
))) {
2691 /* If we're fetching until the end of the TVB, only validate
2692 * that the offset is within range.
2693 */
2694 if (length == -1)
2695 size = 0;
2696 }
2697
2698 tvb_ensure_bytes_exist(tvb, start, size);
2699}
2700
2701static void
2702detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2703{
2704 bool_Bool found_stray_character = false0;
2705
2706 if (!string)
2707 return;
2708
2709 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2710 case ENC_ASCII0x00000000:
2711 case ENC_UTF_80x00000002:
2712 for (int i = (int)strlen(string); i < length; i++) {
2713 if (string[i] != '\0') {
2714 found_stray_character = true1;
2715 break;
2716 }
2717 }
2718 break;
2719
2720 default:
2721 break;
2722 }
2723
2724 if (found_stray_character) {
2725 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2726 }
2727}
2728
2729static void
2730free_fvalue_cb(void *data)
2731{
2732 fvalue_t *fv = (fvalue_t*)data;
2733 fvalue_free(fv);
2734}
2735
2736/* Add an item to a proto_tree, using the text label registered to that item;
2737 the item is extracted from the tvbuff handed to it. */
2738static proto_item *
2739proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2740 tvbuff_t *tvb, int start, int length,
2741 unsigned encoding)
2742{
2743 proto_item *pi;
2744 uint32_t value, n;
2745 uint64_t value64;
2746 ws_in4_addr ipv4_value;
2747 float floatval;
2748 double doubleval;
2749 const char *stringval = NULL((void*)0);
2750 nstime_t time_stamp;
2751 bool_Bool length_error;
2752
2753 /* Ensure that the newly created fvalue_t is freed if we throw an
2754 * exception before adding it to the tree. (gcc creates clobbering
2755 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2756 * XXX: Move the new_field_info() call inside here?
2757 */
2758 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))
;
2759
2760 switch (new_fi->hfinfo->type) {
2761 case FT_NONE:
2762 /* no value to set for FT_NONE */
2763 break;
2764
2765 case FT_PROTOCOL:
2766 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2767 break;
2768
2769 case FT_BYTES:
2770 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2771 break;
2772
2773 case FT_UINT_BYTES:
2774 n = get_uint_value(tree, tvb, start, length, encoding);
2775 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2776
2777 /* Instead of calling proto_item_set_len(), since we don't yet
2778 * have a proto_item, we set the field_info's length ourselves. */
2779 new_fi->length = n + length;
2780 break;
2781
2782 case FT_BOOLEAN:
2783 /*
2784 * Map all non-zero values to little-endian for
2785 * backwards compatibility.
2786 */
2787 if (encoding)
2788 encoding = ENC_LITTLE_ENDIAN0x80000000;
2789 proto_tree_set_boolean(new_fi,
2790 get_uint64_value(tree, tvb, start, length, encoding));
2791 break;
2792
2793 case FT_CHAR:
2794 /* XXX - make these just FT_UINT? */
2795 case FT_UINT8:
2796 case FT_UINT16:
2797 case FT_UINT24:
2798 case FT_UINT32:
2799 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2800 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2801 value = (uint32_t)value64;
2802 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2803 new_fi->flags |= FI_VARINT0x00040000;
2804 }
2805 }
2806 else {
2807 /*
2808 * Map all non-zero values to little-endian for
2809 * backwards compatibility.
2810 */
2811 if (encoding)
2812 encoding = ENC_LITTLE_ENDIAN0x80000000;
2813
2814 value = get_uint_value(tree, tvb, start, length, encoding);
2815 }
2816 proto_tree_set_uint(new_fi, value);
2817 break;
2818
2819 case FT_UINT40:
2820 case FT_UINT48:
2821 case FT_UINT56:
2822 case FT_UINT64:
2823 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2824 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2825 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2826 new_fi->flags |= FI_VARINT0x00040000;
2827 }
2828 }
2829 else {
2830 /*
2831 * Map all other non-zero values to little-endian for
2832 * backwards compatibility.
2833 */
2834 if (encoding)
2835 encoding = ENC_LITTLE_ENDIAN0x80000000;
2836
2837 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2838 }
2839 proto_tree_set_uint64(new_fi, value64);
2840 break;
2841
2842 /* XXX - make these just FT_INT? */
2843 case FT_INT8:
2844 case FT_INT16:
2845 case FT_INT24:
2846 case FT_INT32:
2847 /*
2848 * Map all non-zero values to little-endian for
2849 * backwards compatibility.
2850 */
2851 if (encoding)
2852 encoding = ENC_LITTLE_ENDIAN0x80000000;
2853 proto_tree_set_int(new_fi,
2854 get_int_value(tree, tvb, start, length, encoding));
2855 break;
2856
2857 case FT_INT40:
2858 case FT_INT48:
2859 case FT_INT56:
2860 case FT_INT64:
2861 /*
2862 * Map all non-zero values to little-endian for
2863 * backwards compatibility.
2864 */
2865 if (encoding)
2866 encoding = ENC_LITTLE_ENDIAN0x80000000;
2867 proto_tree_set_int64(new_fi,
2868 get_int64_value(tree, tvb, start, length, encoding));
2869 break;
2870
2871 case FT_IPv4:
2872 /*
2873 * Map all non-zero values to little-endian for
2874 * backwards compatibility.
2875 */
2876 if (encoding)
2877 encoding = ENC_LITTLE_ENDIAN0x80000000;
2878 if (length != FT_IPv4_LEN4) {
2879 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2880 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2881 }
2882 ipv4_value = tvb_get_ipv4(tvb, start);
2883 /*
2884 * NOTE: to support code written when
2885 * proto_tree_add_item() took a bool as its
2886 * last argument, with false meaning "big-endian"
2887 * and true meaning "little-endian", we treat any
2888 * non-zero value of "encoding" as meaning
2889 * "little-endian".
2890 */
2891 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);
2892 break;
2893
2894 case FT_IPXNET:
2895 if (length != FT_IPXNET_LEN4) {
2896 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2897 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2898 }
2899 proto_tree_set_ipxnet(new_fi,
2900 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2901 break;
2902
2903 case FT_IPv6:
2904 if (length != FT_IPv6_LEN16) {
2905 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2906 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2907 }
2908 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2909 break;
2910
2911 case FT_FCWWN:
2912 if (length != FT_FCWWN_LEN8) {
2913 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2914 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2915 }
2916 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2917 break;
2918
2919 case FT_AX25:
2920 if (length != 7) {
2921 length_error = length < 7 ? true1 : false0;
2922 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2923 }
2924 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2925 break;
2926
2927 case FT_VINES:
2928 if (length != VINES_ADDR_LEN6) {
2929 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
2930 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2931 }
2932 proto_tree_set_vines_tvb(new_fi, tvb, start);
2933 break;
2934
2935 case FT_ETHER:
2936 if (length != FT_ETHER_LEN6) {
2937 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
2938 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2939 }
2940 proto_tree_set_ether_tvb(new_fi, tvb, start);
2941 break;
2942
2943 case FT_EUI64:
2944 /*
2945 * Map all non-zero values to little-endian for
2946 * backwards compatibility.
2947 */
2948 if (encoding)
2949 encoding = ENC_LITTLE_ENDIAN0x80000000;
2950 if (length != FT_EUI64_LEN8) {
2951 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
2952 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2953 }
2954 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2955 break;
2956 case FT_GUID:
2957 /*
2958 * Map all non-zero values to little-endian for
2959 * backwards compatibility.
2960 */
2961 if (encoding)
2962 encoding = ENC_LITTLE_ENDIAN0x80000000;
2963 if (length != FT_GUID_LEN16) {
2964 length_error = length < FT_GUID_LEN16 ? true1 : false0;
2965 report_type_length_mismatch(tree, "a GUID", length, length_error);
2966 }
2967 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2968 break;
2969
2970 case FT_OID:
2971 case FT_REL_OID:
2972 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2973 break;
2974
2975 case FT_SYSTEM_ID:
2976 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2977 break;
2978
2979 case FT_FLOAT:
2980 /*
2981 * NOTE: to support code written when
2982 * proto_tree_add_item() took a bool as its
2983 * last argument, with false meaning "big-endian"
2984 * and true meaning "little-endian", we treat any
2985 * non-zero value of "encoding" as meaning
2986 * "little-endian".
2987 *
2988 * At some point in the future, we might
2989 * support non-IEEE-binary floating-point
2990 * formats in the encoding as well
2991 * (IEEE decimal, System/3x0, VAX).
2992 */
2993 if (encoding)
2994 encoding = ENC_LITTLE_ENDIAN0x80000000;
2995 if (length != 4) {
2996 length_error = length < 4 ? true1 : false0;
2997 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
2998 }
2999 if (encoding)
3000 floatval = tvb_get_letohieee_float(tvb, start);
3001 else
3002 floatval = tvb_get_ntohieee_float(tvb, start);
3003 proto_tree_set_float(new_fi, floatval);
3004 break;
3005
3006 case FT_DOUBLE:
3007 /*
3008 * NOTE: to support code written when
3009 * proto_tree_add_item() took a bool as its
3010 * last argument, with false meaning "big-endian"
3011 * and true meaning "little-endian", we treat any
3012 * non-zero value of "encoding" as meaning
3013 * "little-endian".
3014 *
3015 * At some point in the future, we might
3016 * support non-IEEE-binary floating-point
3017 * formats in the encoding as well
3018 * (IEEE decimal, System/3x0, VAX).
3019 */
3020 if (encoding == true1)
3021 encoding = ENC_LITTLE_ENDIAN0x80000000;
3022 if (length != 8) {
3023 length_error = length < 8 ? true1 : false0;
3024 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3025 }
3026 if (encoding)
3027 doubleval = tvb_get_letohieee_double(tvb, start);
3028 else
3029 doubleval = tvb_get_ntohieee_double(tvb, start);
3030 proto_tree_set_double(new_fi, doubleval);
3031 break;
3032
3033 case FT_STRING:
3034 stringval = get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3035 tvb, start, length, &length, encoding);
3036 proto_tree_set_string(new_fi, stringval);
3037
3038 /* Instead of calling proto_item_set_len(), since we
3039 * don't yet have a proto_item, we set the
3040 * field_info's length ourselves.
3041 *
3042 * XXX - our caller can't use that length to
3043 * advance an offset unless they arrange that
3044 * there always be a protocol tree into which
3045 * we're putting this item.
3046 */
3047 new_fi->length = length;
3048 break;
3049
3050 case FT_STRINGZ:
3051 stringval = get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3052 tree, tvb, start, length, &length, encoding);
3053 proto_tree_set_string(new_fi, stringval);
3054
3055 /* Instead of calling proto_item_set_len(),
3056 * since we don't yet have a proto_item, we
3057 * set the field_info's length ourselves.
3058 *
3059 * XXX - our caller can't use that length to
3060 * advance an offset unless they arrange that
3061 * there always be a protocol tree into which
3062 * we're putting this item.
3063 */
3064 new_fi->length = length;
3065 break;
3066
3067 case FT_UINT_STRING:
3068 /*
3069 * NOTE: to support code written when
3070 * proto_tree_add_item() took a bool as its
3071 * last argument, with false meaning "big-endian"
3072 * and true meaning "little-endian", if the
3073 * encoding value is true, treat that as
3074 * ASCII with a little-endian length.
3075 *
3076 * This won't work for code that passes
3077 * arbitrary non-zero values; that code
3078 * will need to be fixed.
3079 */
3080 if (encoding == true1)
3081 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3082 stringval = get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3083 tree, tvb, start, length, &length, encoding);
3084 proto_tree_set_string(new_fi, stringval);
3085
3086 /* Instead of calling proto_item_set_len(), since we
3087 * don't yet have a proto_item, we set the
3088 * field_info's length ourselves.
3089 *
3090 * XXX - our caller can't use that length to
3091 * advance an offset unless they arrange that
3092 * there always be a protocol tree into which
3093 * we're putting this item.
3094 */
3095 new_fi->length = length;
3096 break;
3097
3098 case FT_STRINGZPAD:
3099 stringval = get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3100 tvb, start, length, &length, encoding);
3101 proto_tree_set_string(new_fi, stringval);
3102
3103 /* Instead of calling proto_item_set_len(), since we
3104 * don't yet have a proto_item, we set the
3105 * field_info's length ourselves.
3106 *
3107 * XXX - our caller can't use that length to
3108 * advance an offset unless they arrange that
3109 * there always be a protocol tree into which
3110 * we're putting this item.
3111 */
3112 new_fi->length = length;
3113 break;
3114
3115 case FT_STRINGZTRUNC:
3116 stringval = get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3117 tvb, start, length, &length, encoding);
3118 proto_tree_set_string(new_fi, stringval);
3119
3120 /* Instead of calling proto_item_set_len(), since we
3121 * don't yet have a proto_item, we set the
3122 * field_info's length ourselves.
3123 *
3124 * XXX - our caller can't use that length to
3125 * advance an offset unless they arrange that
3126 * there always be a protocol tree into which
3127 * we're putting this item.
3128 */
3129 new_fi->length = length;
3130 break;
3131
3132 case FT_ABSOLUTE_TIME:
3133 /*
3134 * Absolute times can be in any of a number of
3135 * formats, and they can be big-endian or
3136 * little-endian.
3137 *
3138 * Historically FT_TIMEs were only timespecs;
3139 * the only question was whether they were stored
3140 * in big- or little-endian format.
3141 *
3142 * For backwards compatibility, we interpret an
3143 * encoding of 1 as meaning "little-endian timespec",
3144 * so that passing true is interpreted as that.
3145 */
3146 if (encoding == true1)
3147 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3148
3149 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3150
3151 proto_tree_set_time(new_fi, &time_stamp);
3152 break;
3153
3154 case FT_RELATIVE_TIME:
3155 /*
3156 * Relative times can be in any of a number of
3157 * formats, and they can be big-endian or
3158 * little-endian.
3159 *
3160 * Historically FT_TIMEs were only timespecs;
3161 * the only question was whether they were stored
3162 * in big- or little-endian format.
3163 *
3164 * For backwards compatibility, we interpret an
3165 * encoding of 1 as meaning "little-endian timespec",
3166 * so that passing true is interpreted as that.
3167 */
3168 if (encoding == true1)
3169 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3170
3171 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3172
3173 proto_tree_set_time(new_fi, &time_stamp);
3174 break;
3175 case FT_IEEE_11073_SFLOAT:
3176 if (encoding)
3177 encoding = ENC_LITTLE_ENDIAN0x80000000;
3178 if (length != 2) {
3179 length_error = length < 2 ? true1 : false0;
3180 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3181 }
3182
3183 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3184
3185 break;
3186 case FT_IEEE_11073_FLOAT:
3187 if (encoding)
3188 encoding = ENC_LITTLE_ENDIAN0x80000000;
3189 if (length != 4) {
3190 length_error = length < 4 ? true1 : false0;
3191 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3192 }
3193 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3194
3195 break;
3196 default:
3197 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))
3198 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))
3199 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 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))
;
3201 break;
3202 }
3203 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)
;
3204
3205 /* Don't add new node to proto_tree until now so that any exceptions
3206 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3207 /* XXX. wouldn't be better to add this item to tree, with some special
3208 * flag (FI_EXCEPTION?) to know which item caused exception? For
3209 * strings and bytes, we would have to set new_fi->value to something
3210 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3211 * could handle NULL values. */
3212 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3213 pi = proto_tree_add_node(tree, new_fi);
3214
3215 switch (new_fi->hfinfo->type) {
3216
3217 case FT_STRING:
3218 /* XXX: trailing stray character detection should be done
3219 * _before_ conversion to UTF-8, because conversion can change
3220 * the length, or else get_string_length should return a value
3221 * for the "length in bytes of the string after conversion
3222 * including internal nulls." (Noting that we do, for other
3223 * reasons, still need the "length in bytes in the field",
3224 * especially for FT_STRINGZ.)
3225 *
3226 * This is true even for ASCII and UTF-8, because
3227 * substituting REPLACEMENT CHARACTERS for illegal characters
3228 * can also do so (and for UTF-8 possibly even make the
3229 * string _shorter_).
3230 */
3231 detect_trailing_stray_characters(encoding, stringval, length, pi);
3232 break;
3233
3234 default:
3235 break;
3236 }
3237
3238 return pi;
3239}
3240
3241proto_item *
3242proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3243 const int start, int length,
3244 const unsigned encoding, int32_t *retval)
3245{
3246 header_field_info *hfinfo;
3247 field_info *new_fi;
3248 int32_t value;
3249
3250 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", 3250, __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", 3250,
"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", 3250, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3251
3252 switch (hfinfo->type) {
3253 case FT_INT8:
3254 case FT_INT16:
3255 case FT_INT24:
3256 case FT_INT32:
3257 break;
3258 case FT_INT64:
3259 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)
3260 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3261 default:
3262 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)
3263 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3264 }
3265
3266 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3267 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3268 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3269 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3270 *retval = 0;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 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3273
3274 if (encoding & ENC_STRING0x03000000) {
3275 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3276 }
3277 /* I believe it's ok if this is called with a NULL tree */
3278 value = get_int_value(tree, tvb, start, length, encoding);
3279
3280 if (retval) {
3281 int no_of_bits;
3282 *retval = value;
3283 if (hfinfo->bitmask) {
3284 /* Mask out irrelevant portions */
3285 *retval &= (uint32_t)(hfinfo->bitmask);
3286 /* Shift bits */
3287 *retval >>= hfinfo_bitshift(hfinfo);
3288 }
3289 no_of_bits = ws_count_ones(hfinfo->bitmask);
3290 *retval = ws_sign_ext32(*retval, no_of_bits);
3291 }
3292
3293 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3294
3295 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", 3295
, __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", 3295, "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", 3295, "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", 3295, __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)
; } } }
;
3296
3297 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3298
3299 proto_tree_set_int(new_fi, value);
3300
3301 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3302
3303 return proto_tree_add_node(tree, new_fi);
3304}
3305
3306proto_item *
3307proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3308 const int start, int length,
3309 const unsigned encoding, uint32_t *retval)
3310{
3311 header_field_info *hfinfo;
3312 field_info *new_fi;
3313 uint32_t value;
3314
3315 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", 3315, __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", 3315,
"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", 3315, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3316
3317 switch (hfinfo->type) {
3318 case FT_CHAR:
3319 case FT_UINT8:
3320 case FT_UINT16:
3321 case FT_UINT24:
3322 case FT_UINT32:
3323 break;
3324 default:
3325 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)
3326 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)
;
3327 }
3328
3329 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3330 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3331 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3332 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3333 *retval = 0;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 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3336
3337 if (encoding & ENC_STRING0x03000000) {
3338 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3339 }
3340 /* I believe it's ok if this is called with a NULL tree */
3341 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3342 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3343 uint64_t temp64;
3344 tvb_get_varint(tvb, start, length, &temp64, encoding);
3345 value = (uint32_t)temp64;
3346 } else {
3347 value = get_uint_value(tree, tvb, start, length, encoding);
3348 }
3349
3350 if (retval) {
3351 *retval = value;
3352 if (hfinfo->bitmask) {
3353 /* Mask out irrelevant portions */
3354 *retval &= (uint32_t)(hfinfo->bitmask);
3355 /* Shift bits */
3356 *retval >>= hfinfo_bitshift(hfinfo);
3357 }
3358 }
3359
3360 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3361
3362 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", 3362
, __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", 3362, "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", 3362, "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", 3362, __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)
; } } }
;
3363
3364 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3365
3366 proto_tree_set_uint(new_fi, value);
3367
3368 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3369 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3370 new_fi->flags |= FI_VARINT0x00040000;
3371 }
3372 return proto_tree_add_node(tree, new_fi);
3373}
3374
3375/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3376 * and returns proto_item* and uint value retreived*/
3377proto_item *
3378ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3379 const unsigned encoding, uint32_t *retval)
3380{
3381 field_info *new_fi;
3382 header_field_info *hfinfo;
3383 int item_length;
3384 int offset;
3385 uint32_t value;
3386
3387 offset = ptvc->offset;
3388 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", 3388, __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", 3388,
"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", 3388, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3389
3390 switch (hfinfo->type) {
3391 case FT_CHAR:
3392 case FT_UINT8:
3393 case FT_UINT16:
3394 case FT_UINT24:
3395 case FT_UINT32:
3396 break;
3397 default:
3398 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)
3399 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)
;
3400 }
3401
3402 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3403 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3404
3405 /* I believe it's ok if this is called with a NULL tree */
3406 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3407 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3408
3409 if (retval) {
3410 *retval = value;
3411 if (hfinfo->bitmask) {
3412 /* Mask out irrelevant portions */
3413 *retval &= (uint32_t)(hfinfo->bitmask);
3414 /* Shift bits */
3415 *retval >>= hfinfo_bitshift(hfinfo);
3416 }
3417 }
3418
3419 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3420 item_length, encoding);
3421
3422 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3423
3424 /* Coast clear. Try and fake it */
3425 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", 3425
, __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", 3425, "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", 3425, "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", 3425, __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); } } }
;
3426
3427 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3428
3429 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3430 offset, length, encoding);
3431}
3432
3433/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3434 * and returns proto_item* and int value retreived*/
3435proto_item *
3436ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3437 const unsigned encoding, int32_t *retval)
3438{
3439 field_info *new_fi;
3440 header_field_info *hfinfo;
3441 int item_length;
3442 int offset;
3443 uint32_t value;
3444
3445 offset = ptvc->offset;
3446 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", 3446, __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", 3446,
"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", 3446, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3447
3448 switch (hfinfo->type) {
3449 case FT_INT8:
3450 case FT_INT16:
3451 case FT_INT24:
3452 case FT_INT32:
3453 break;
3454 default:
3455 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)
3456 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3457 }
3458
3459 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3460 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3461
3462 /* I believe it's ok if this is called with a NULL tree */
3463 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3464 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3465
3466 if (retval) {
3467 int no_of_bits;
3468 *retval = value;
3469 if (hfinfo->bitmask) {
3470 /* Mask out irrelevant portions */
3471 *retval &= (uint32_t)(hfinfo->bitmask);
3472 /* Shift bits */
3473 *retval >>= hfinfo_bitshift(hfinfo);
3474 }
3475 no_of_bits = ws_count_ones(hfinfo->bitmask);
3476 *retval = ws_sign_ext32(*retval, no_of_bits);
3477 }
3478
3479 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3480 item_length, encoding);
3481
3482 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3483
3484 /* Coast clear. Try and fake it */
3485 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", 3485
, __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", 3485, "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", 3485, "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", 3485, __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); } } }
;
3486
3487 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3488
3489 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3490 offset, length, encoding);
3491}
3492
3493/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3494 * and returns proto_item* and string value retreived */
3495proto_item*
3496ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3497{
3498 header_field_info *hfinfo;
3499 field_info *new_fi;
3500 const uint8_t *value;
3501 int item_length;
3502 int offset;
3503
3504 offset = ptvc->offset;
3505
3506 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", 3506
, __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", 3506, "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", 3506, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3507
3508 switch (hfinfo->type) {
3509 case FT_STRING:
3510 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3511 break;
3512 case FT_STRINGZ:
3513 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3514 break;
3515 case FT_UINT_STRING:
3516 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3517 break;
3518 case FT_STRINGZPAD:
3519 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3520 break;
3521 case FT_STRINGZTRUNC:
3522 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3523 break;
3524 default:
3525 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)
3526 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)
;
3527 }
3528
3529 if (retval)
3530 *retval = value;
3531
3532 ptvc->offset += item_length;
3533
3534 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3535
3536 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", 3536, __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", 3536,
"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", 3536, "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", 3536
, __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); } } }
;
3537
3538 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3539
3540 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3541 offset, length, encoding);
3542}
3543
3544/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3545 * and returns proto_item* and boolean value retreived */
3546proto_item*
3547ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3548{
3549 header_field_info *hfinfo;
3550 field_info *new_fi;
3551 int item_length;
3552 int offset;
3553 uint64_t value, bitval;
3554
3555 offset = ptvc->offset;
3556 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", 3556, __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", 3556,
"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", 3556, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3557
3558 if (hfinfo->type != FT_BOOLEAN) {
3559 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)
3560 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3561 }
3562
3563 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3564 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3565 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3566 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3567 *retval = false;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 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3570
3571 if (encoding & ENC_STRING0x03000000) {
3572 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3573 }
3574
3575 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3576 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3577
3578 /* I believe it's ok if this is called with a NULL tree */
3579 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3580
3581 if (retval) {
3582 bitval = value;
3583 if (hfinfo->bitmask) {
3584 /* Mask out irrelevant portions */
3585 bitval &= hfinfo->bitmask;
3586 }
3587 *retval = (bitval != 0);
3588 }
3589
3590 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3591 item_length, encoding);
3592
3593 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3594
3595 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", 3595, __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", 3595,
"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", 3595, "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", 3595
, __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); } } }
;
3596
3597 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3598
3599 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3600 offset, length, encoding);
3601}
3602
3603proto_item *
3604proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3605 const int start, int length, const unsigned encoding, uint64_t *retval)
3606{
3607 header_field_info *hfinfo;
3608 field_info *new_fi;
3609 uint64_t value;
3610
3611 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", 3611, __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", 3611,
"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", 3611, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3612
3613 switch (hfinfo->type) {
3614 case FT_UINT40:
3615 case FT_UINT48:
3616 case FT_UINT56:
3617 case FT_UINT64:
3618 break;
3619 default:
3620 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)
3621 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3622 }
3623
3624 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3625 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3626 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3627 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3628 *retval = 0;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 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3631
3632 if (encoding & ENC_STRING0x03000000) {
3633 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3634 }
3635 /* I believe it's ok if this is called with a NULL tree */
3636 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3637 tvb_get_varint(tvb, start, length, &value, encoding);
3638 } else {
3639 value = get_uint64_value(tree, tvb, start, length, encoding);
3640 }
3641
3642 if (retval) {
3643 *retval = value;
3644 if (hfinfo->bitmask) {
3645 /* Mask out irrelevant portions */
3646 *retval &= hfinfo->bitmask;
3647 /* Shift bits */
3648 *retval >>= hfinfo_bitshift(hfinfo);
3649 }
3650 }
3651
3652 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3653
3654 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", 3654
, __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", 3654, "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", 3654, "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", 3654, __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)
; } } }
;
3655
3656 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3657
3658 proto_tree_set_uint64(new_fi, value);
3659
3660 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3661 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3662 new_fi->flags |= FI_VARINT0x00040000;
3663 }
3664
3665 return proto_tree_add_node(tree, new_fi);
3666}
3667
3668proto_item *
3669proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3670 const int start, int length, const unsigned encoding, int64_t *retval)
3671{
3672 header_field_info *hfinfo;
3673 field_info *new_fi;
3674 int64_t value;
3675
3676 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", 3676, __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", 3676,
"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", 3676, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3677
3678 switch (hfinfo->type) {
3679 case FT_INT40:
3680 case FT_INT48:
3681 case FT_INT56:
3682 case FT_INT64:
3683 break;
3684 default:
3685 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)
3686 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3687 }
3688
3689 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3690 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3691 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3692 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3693 *retval = 0;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 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3696
3697 if (encoding & ENC_STRING0x03000000) {
3698 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3699 }
3700 /* I believe it's ok if this is called with a NULL tree */
3701 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3702 tvb_get_varint(tvb, start, length, &value, encoding);
3703 }
3704 else {
3705 value = get_int64_value(tree, tvb, start, length, encoding);
3706 }
3707
3708 if (retval) {
3709 *retval = value;
3710 }
3711
3712 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3713
3714 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", 3714
, __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", 3714, "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", 3714, "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", 3714, __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)
; } } }
;
3715
3716 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3717
3718 proto_tree_set_int64(new_fi, value);
3719
3720 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3721 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3722 new_fi->flags |= FI_VARINT0x00040000;
3723 }
3724
3725 return proto_tree_add_node(tree, new_fi);
3726}
3727
3728proto_item *
3729proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3730 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3731{
3732 header_field_info *hfinfo;
3733 field_info *new_fi;
3734 uint64_t value;
3735
3736 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", 3736, __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", 3736,
"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", 3736, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3737
3738 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
))
)) {
3739 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)
3740 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3741 }
3742
3743 /* length validation for native number encoding caught by get_uint64_value() */
3744 /* length has to be -1 or > 0 regardless of encoding */
3745 if (length == 0)
3746 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)
3747 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3748
3749 if (encoding & ENC_STRING0x03000000) {
3750 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3751 }
3752
3753 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3754
3755 if (retval) {
3756 *retval = value;
3757 if (hfinfo->bitmask) {
3758 /* Mask out irrelevant portions */
3759 *retval &= hfinfo->bitmask;
3760 /* Shift bits */
3761 *retval >>= hfinfo_bitshift(hfinfo);
3762 }
3763 }
3764
3765 if (lenretval) {
3766 *lenretval = length;
3767 }
3768
3769 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3770
3771 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", 3771
, __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", 3771, "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", 3771, "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", 3771, __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)
; } } }
;
3772
3773 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3774
3775 proto_tree_set_uint64(new_fi, value);
3776
3777 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3778 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3779 new_fi->flags |= FI_VARINT0x00040000;
3780 }
3781
3782 return proto_tree_add_node(tree, new_fi);
3783
3784}
3785
3786proto_item *
3787proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3788 const int start, int length,
3789 const unsigned encoding, bool_Bool *retval)
3790{
3791 header_field_info *hfinfo;
3792 field_info *new_fi;
3793 uint64_t value, bitval;
3794
3795 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", 3795, __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", 3795,
"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", 3795, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3796
3797 if (hfinfo->type != FT_BOOLEAN) {
3798 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)
3799 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3800 }
3801
3802 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3803 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3804 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3805 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3806 *retval = false;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 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3809
3810 if (encoding & ENC_STRING0x03000000) {
3811 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3812 }
3813 /* I believe it's ok if this is called with a NULL tree */
3814 value = get_uint64_value(tree, tvb, start, length, encoding);
3815
3816 if (retval) {
3817 bitval = value;
3818 if (hfinfo->bitmask) {
3819 /* Mask out irrelevant portions */
3820 bitval &= hfinfo->bitmask;
3821 }
3822 *retval = (bitval != 0);
3823 }
3824
3825 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3826
3827 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", 3827
, __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", 3827, "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", 3827, "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", 3827, __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)
; } } }
;
3828
3829 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3830
3831 proto_tree_set_boolean(new_fi, value);
3832
3833 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3834
3835 return proto_tree_add_node(tree, new_fi);
3836}
3837
3838proto_item *
3839proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3840 const int start, int length,
3841 const unsigned encoding, float *retval)
3842{
3843 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3844 field_info *new_fi;
3845 float value;
3846
3847 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", 3847,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3848
3849 if (hfinfo->type != FT_FLOAT) {
3850 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)
;
3851 }
3852
3853 if (length != 4) {
3854 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3855 }
3856
3857 /* treat any nonzero encoding as little endian for backwards compatibility */
3858 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3859 if (retval) {
3860 *retval = value;
3861 }
3862
3863 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3864
3865 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", 3865
, __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", 3865, "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", 3865, "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", 3865, __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)
; } } }
;
3866
3867 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3868 if (encoding) {
3869 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3870 }
3871
3872 proto_tree_set_float(new_fi, value);
3873
3874 return proto_tree_add_node(tree, new_fi);
3875}
3876
3877proto_item *
3878proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3879 const int start, int length,
3880 const unsigned encoding, double *retval)
3881{
3882 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3883 field_info *new_fi;
3884 double value;
3885
3886 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", 3886,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3887
3888 if (hfinfo->type != FT_DOUBLE) {
3889 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)
;
3890 }
3891
3892 if (length != 8) {
3893 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3894 }
3895
3896 /* treat any nonzero encoding as little endian for backwards compatibility */
3897 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3898 if (retval) {
3899 *retval = value;
3900 }
3901
3902 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3903
3904 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", 3904
, __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", 3904, "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", 3904, "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", 3904, __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)
; } } }
;
3905
3906 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3907 if (encoding) {
3908 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3909 }
3910
3911 proto_tree_set_double(new_fi, value);
3912
3913 return proto_tree_add_node(tree, new_fi);
3914}
3915
3916proto_item *
3917proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3918 const int start, int length,
3919 const unsigned encoding, ws_in4_addr *retval)
3920{
3921 header_field_info *hfinfo;
3922 field_info *new_fi;
3923 ws_in4_addr value;
3924
3925 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", 3925, __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", 3925,
"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", 3925, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3926
3927 switch (hfinfo->type) {
3928 case FT_IPv4:
3929 break;
3930 default:
3931 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)
3932 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
3933 }
3934
3935 if (length != FT_IPv4_LEN4)
3936 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)
3937 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
3938
3939 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3940 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3941 }
3942
3943 /*
3944 * NOTE: to support code written when proto_tree_add_item() took
3945 * a bool as its last argument, with false meaning "big-endian"
3946 * and true meaning "little-endian", we treat any non-zero value
3947 * of "encoding" as meaning "little-endian".
3948 */
3949 value = tvb_get_ipv4(tvb, start);
3950 if (encoding)
3951 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))))
;
3952
3953 if (retval) {
3954 *retval = value;
3955 }
3956
3957 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3958
3959 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", 3959
, __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", 3959, "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", 3959, "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", 3959, __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)
; } } }
;
3960
3961 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3962
3963 proto_tree_set_ipv4(new_fi, value);
3964
3965 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3966 return proto_tree_add_node(tree, new_fi);
3967}
3968
3969proto_item *
3970proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3971 const int start, int length,
3972 const unsigned encoding, ws_in6_addr *addr)
3973{
3974 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3975 field_info *new_fi;
3976
3977 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", 3977,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3978
3979 switch (hfinfo->type) {
3980 case FT_IPv6:
3981 break;
3982 default:
3983 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)
3984 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
3985 }
3986
3987 if (length != FT_IPv6_LEN16)
3988 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)
3989 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
3990
3991 if (encoding) {
3992 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"
)
;
3993 }
3994
3995 tvb_get_ipv6(tvb, start, addr);
3996
3997 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3998
3999 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", 3999
, __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", 3999, "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", 3999, "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", 3999, __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)
; } } }
;
4000
4001 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4002
4003 proto_tree_set_ipv6(new_fi, addr);
4004
4005 return proto_tree_add_node(tree, new_fi);
4006}
4007
4008proto_item *
4009proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4010 const int start, int length, const unsigned encoding, uint8_t *retval) {
4011
4012 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4013 field_info *new_fi;
4014
4015 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", 4015,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4016
4017 switch (hfinfo->type) {
4018 case FT_ETHER:
4019 break;
4020 default:
4021 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)
4022 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4023 }
4024
4025 if (length != FT_ETHER_LEN6)
4026 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)
4027 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4028
4029 if (encoding) {
4030 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"
)
;
4031 }
4032
4033 tvb_memcpy(tvb, retval, start, length);
4034
4035 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4036
4037 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", 4037
, __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", 4037, "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", 4037, "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", 4037, __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)
; } } }
;
4038
4039 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4040
4041 proto_tree_set_ether(new_fi, retval);
4042
4043 return proto_tree_add_node(tree, new_fi);
4044}
4045
4046
4047proto_item *
4048proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4049 tvbuff_t *tvb,
4050 const int start, int length,
4051 const unsigned encoding,
4052 wmem_allocator_t *scope,
4053 const uint8_t **retval,
4054 int *lenretval)
4055{
4056 proto_item *pi;
4057 header_field_info *hfinfo;
4058 field_info *new_fi;
4059 const uint8_t *value;
4060
4061 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", 4061, __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", 4061,
"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", 4061, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4062
4063 switch (hfinfo->type) {
4064 case FT_STRING:
4065 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4066 break;
4067 case FT_STRINGZ:
4068 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4069 break;
4070 case FT_UINT_STRING:
4071 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4072 break;
4073 case FT_STRINGZPAD:
4074 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4075 break;
4076 case FT_STRINGZTRUNC:
4077 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4078 break;
4079 default:
4080 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)
4081 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)
;
4082 }
4083
4084 if (retval)
4085 *retval = value;
4086
4087 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4088
4089 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", 4089
, __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", 4089, "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", 4089, "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", 4089, __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)
; } } }
;
4090
4091 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4092
4093 proto_tree_set_string(new_fi, value);
4094
4095 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4096
4097 pi = proto_tree_add_node(tree, new_fi);
4098
4099 switch (hfinfo->type) {
4100
4101 case FT_STRINGZ:
4102 case FT_STRINGZPAD:
4103 case FT_STRINGZTRUNC:
4104 case FT_UINT_STRING:
4105 break;
4106
4107 case FT_STRING:
4108 detect_trailing_stray_characters(encoding, value, length, pi);
4109 break;
4110
4111 default:
4112 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4112
, __func__, "assertion \"not reached\" failed")
;
4113 }
4114
4115 return pi;
4116}
4117
4118proto_item *
4119proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4120 const int start, int length,
4121 const unsigned encoding, wmem_allocator_t *scope,
4122 const uint8_t **retval)
4123{
4124 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4125 tvb, start, length, encoding, scope, retval, &length);
4126}
4127
4128proto_item *
4129proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4130 tvbuff_t *tvb,
4131 const int start, int length,
4132 const unsigned encoding,
4133 wmem_allocator_t *scope,
4134 char **retval,
4135 int *lenretval)
4136{
4137 proto_item *pi;
4138 header_field_info *hfinfo;
4139 field_info *new_fi;
4140 const uint8_t *value;
4141 uint32_t n = 0;
4142
4143 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", 4143, __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", 4143,
"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", 4143, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4144
4145 switch (hfinfo->type) {
4146 case FT_STRING:
4147 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4148 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4149 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4150 break;
4151 case FT_STRINGZ:
4152 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4153 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4154 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4155 break;
4156 case FT_UINT_STRING:
4157 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4158 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4159 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4160 break;
4161 case FT_STRINGZPAD:
4162 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4163 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4164 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4165 break;
4166 case FT_STRINGZTRUNC:
4167 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4168 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4169 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4170 break;
4171 case FT_BYTES:
4172 tvb_ensure_bytes_exist(tvb, start, length);
4173 value = tvb_get_ptr(tvb, start, length);
4174 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4175 *lenretval = length;
4176 break;
4177 case FT_UINT_BYTES:
4178 n = get_uint_value(tree, tvb, start, length, encoding);
4179 tvb_ensure_bytes_exist(tvb, start + length, n);
4180 value = tvb_get_ptr(tvb, start + length, n);
4181 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4182 *lenretval = length + n;
4183 break;
4184 default:
4185 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)
4186 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)
;
4187 }
4188
4189 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4190
4191 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", 4191
, __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", 4191, "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", 4191, "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", 4191, __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)
; } } }
;
4192
4193 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4194
4195 switch (hfinfo->type) {
4196
4197 case FT_STRING:
4198 case FT_STRINGZ:
4199 case FT_UINT_STRING:
4200 case FT_STRINGZPAD:
4201 case FT_STRINGZTRUNC:
4202 proto_tree_set_string(new_fi, value);
4203 break;
4204
4205 case FT_BYTES:
4206 proto_tree_set_bytes(new_fi, value, length);
4207 break;
4208
4209 case FT_UINT_BYTES:
4210 proto_tree_set_bytes(new_fi, value, n);
4211 break;
4212
4213 default:
4214 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4214
, __func__, "assertion \"not reached\" failed")
;
4215 }
4216
4217 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4218
4219 pi = proto_tree_add_node(tree, new_fi);
4220
4221 switch (hfinfo->type) {
4222
4223 case FT_STRINGZ:
4224 case FT_STRINGZPAD:
4225 case FT_STRINGZTRUNC:
4226 case FT_UINT_STRING:
4227 break;
4228
4229 case FT_STRING:
4230 detect_trailing_stray_characters(encoding, value, length, pi);
4231 break;
4232
4233 case FT_BYTES:
4234 case FT_UINT_BYTES:
4235 break;
4236
4237 default:
4238 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4238
, __func__, "assertion \"not reached\" failed")
;
4239 }
4240
4241 return pi;
4242}
4243
4244proto_item *
4245proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4246 tvbuff_t *tvb,
4247 const int start, int length,
4248 const unsigned encoding,
4249 wmem_allocator_t *scope,
4250 char **retval)
4251{
4252 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4253 tvb, start, length, encoding, scope, retval, &length);
4254}
4255
4256proto_item *
4257proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4258 tvbuff_t *tvb,
4259 const int start, int length, const unsigned encoding,
4260 wmem_allocator_t *scope, char **retval)
4261{
4262 header_field_info *hfinfo;
4263 field_info *new_fi;
4264 nstime_t time_stamp;
4265 int flags;
4266
4267 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", 4267, __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", 4267,
"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", 4267, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4268
4269 switch (hfinfo->type) {
4270 case FT_ABSOLUTE_TIME:
4271 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4272 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4273 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4274 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4275 }
4276 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4277 break;
4278 case FT_RELATIVE_TIME:
4279 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4280 *retval = rel_time_to_secs_str(scope, &time_stamp);
4281 break;
4282 default:
4283 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)
4284 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4285 }
4286
4287 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4288
4289 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", 4289
, __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", 4289, "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", 4289, "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", 4289, __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)
; } } }
;
4290
4291 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4292
4293 switch (hfinfo->type) {
4294
4295 case FT_ABSOLUTE_TIME:
4296 case FT_RELATIVE_TIME:
4297 proto_tree_set_time(new_fi, &time_stamp);
4298 break;
4299 default:
4300 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4300
, __func__, "assertion \"not reached\" failed")
;
4301 }
4302
4303 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4304
4305 return proto_tree_add_node(tree, new_fi);
4306}
4307
4308/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4309 and returns proto_item* */
4310proto_item *
4311ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4312 const unsigned encoding)
4313{
4314 field_info *new_fi;
4315 header_field_info *hfinfo;
4316 int item_length;
4317 int offset;
4318
4319 offset = ptvc->offset;
4320 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", 4320, __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", 4320,
"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", 4320, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4321 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4322 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4323
4324 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
4325 item_length, encoding);
4326
4327 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4328
4329 /* Coast clear. Try and fake it */
4330 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", 4330
, __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", 4330, "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", 4330, "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", 4330, __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); } } }
;
4331
4332 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4333
4334 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4335 offset, length, encoding);
4336}
4337
4338/* Add an item to a proto_tree, using the text label registered to that item;
4339 the item is extracted from the tvbuff handed to it. */
4340proto_item *
4341proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4342 const int start, int length, const unsigned encoding)
4343{
4344 field_info *new_fi;
4345 int item_length;
4346
4347 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", 4347,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4348
4349 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4350 test_length(hfinfo, tvb, start, item_length, encoding);
4351
4352 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4353
4354 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", 4354
, __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", 4354, "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", 4354, "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", 4354, __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)
; } } }
;
4355
4356 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4357
4358 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4359}
4360
4361proto_item *
4362proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4363 const int start, int length, const unsigned encoding)
4364{
4365 register header_field_info *hfinfo;
4366
4367 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", 4367, __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", 4367,
"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", 4367, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4368 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4369}
4370
4371/* Add an item to a proto_tree, using the text label registered to that item;
4372 the item is extracted from the tvbuff handed to it.
4373
4374 Return the length of the item through the pointer. */
4375proto_item *
4376proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4377 tvbuff_t *tvb, const int start,
4378 int length, const unsigned encoding,
4379 int *lenretval)
4380{
4381 field_info *new_fi;
4382 int item_length;
4383 proto_item *item;
4384
4385 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", 4385,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4386
4387 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4388 test_length(hfinfo, tvb, start, item_length, encoding);
4389
4390 if (!tree) {
4391 /*
4392 * We need to get the correct item length here.
4393 * That's normally done by proto_tree_new_item(),
4394 * but we won't be calling it.
4395 */
4396 *lenretval = get_full_length(hfinfo, tvb, start, length,
4397 item_length, encoding);
4398 return NULL((void*)0);
4399 }
4400
4401 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", 4408
, __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", 4408, "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", 4408, "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", 4408
, __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 /*((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", 4408
, __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", 4408, "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", 4408, "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", 4408
, __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 * 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", 4408
, __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", 4408, "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", 4408, "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", 4408
, __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 * 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", 4408
, __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", 4408, "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", 4408, "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", 4408
, __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 */((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", 4408
, __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", 4408, "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", 4408, "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", 4408
, __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 *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", 4408
, __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", 4408, "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", 4408, "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", 4408
, __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 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", 4408
, __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", 4408, "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", 4408, "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", 4408
, __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 })((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", 4408
, __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", 4408, "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", 4408, "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", 4408
, __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); } } }
;
4409
4410 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4411
4412 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4413 *lenretval = new_fi->length;
4414 return item;
4415}
4416
4417proto_item *
4418proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4419 const int start, int length,
4420 const unsigned encoding, int *lenretval)
4421{
4422 register header_field_info *hfinfo;
4423
4424 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", 4424, __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", 4424,
"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", 4424, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4425 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4426}
4427
4428/* which FT_ types can use proto_tree_add_bytes_item() */
4429static inline bool_Bool
4430validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4431{
4432 return (type == FT_BYTES ||
4433 type == FT_UINT_BYTES ||
4434 type == FT_OID ||
4435 type == FT_REL_OID ||
4436 type == FT_SYSTEM_ID );
4437}
4438
4439/* Note: this does no validation that the byte array of an FT_OID or
4440 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4441 so I think it's ok to continue not validating it?
4442 */
4443proto_item *
4444proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4445 const int start, int length, const unsigned encoding,
4446 GByteArray *retval, int *endoff, int *err)
4447{
4448 field_info *new_fi;
4449 GByteArray *bytes = retval;
4450 GByteArray *created_bytes = NULL((void*)0);
4451 bool_Bool failed = false0;
4452 uint32_t n = 0;
4453 header_field_info *hfinfo;
4454 bool_Bool generate = (bytes || tree) ? true1 : false0;
4455
4456 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", 4456, __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", 4456,
"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", 4456, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4457
4458 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", 4458,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4459
4460 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", 4461, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4461 "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", 4461, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4462
4463 CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
;
4464
4465 if (encoding & ENC_STR_NUM0x01000000) {
4466 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"
)
;
4467 }
4468
4469 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4470 if (hfinfo->type == FT_UINT_BYTES) {
4471 /* can't decode FT_UINT_BYTES from strings */
4472 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")
4473 "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")
;
4474 }
4475
4476 unsigned hex_encoding = encoding;
4477 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4478 /* If none of the separator values are used,
4479 * assume no separator (the common case). */
4480 hex_encoding |= ENC_SEP_NONE0x00010000;
4481#if 0
4482 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")
4483 "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")
;
4484#endif
4485 }
4486
4487 if (!bytes) {
4488 /* caller doesn't care about return value, but we need it to
4489 call tvb_get_string_bytes() and set the tree later */
4490 bytes = created_bytes = g_byte_array_new();
4491 }
4492
4493 /*
4494 * bytes might be NULL after this, but can't add expert
4495 * error until later; if it's NULL, just note that
4496 * it failed.
4497 */
4498 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4499 if (bytes == NULL((void*)0))
4500 failed = true1;
4501 }
4502 else if (generate) {
4503 tvb_ensure_bytes_exist(tvb, start, length);
4504
4505 if (hfinfo->type == FT_UINT_BYTES) {
4506 n = length; /* n is now the "header" length */
4507 length = get_uint_value(tree, tvb, start, n, encoding);
4508 /* length is now the value's length; only store the value in the array */
4509 tvb_ensure_bytes_exist(tvb, start + n, length);
4510 if (!bytes) {
4511 /* caller doesn't care about return value, but
4512 * we may need it to set the tree later */
4513 bytes = created_bytes = g_byte_array_new();
4514 }
4515 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4516 }
4517 else if (length > 0) {
4518 if (!bytes) {
4519 /* caller doesn't care about return value, but
4520 * we may need it to set the tree later */
4521 bytes = created_bytes = g_byte_array_new();
4522 }
4523 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4524 }
4525
4526 if (endoff)
4527 *endoff = start + n + length;
4528 }
4529
4530 if (err)
4531 *err = failed ? EINVAL22 : 0;
4532
4533 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); }
4534 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4535 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); }
4536 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); }
4537 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); }
4538 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4539 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4540
4541 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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __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 {((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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __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 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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __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 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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __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 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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __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 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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __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 } )((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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __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); } } }
;
4548
4549 /* n will be zero except when it's a FT_UINT_BYTES */
4550 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4551
4552 if (encoding & ENC_STRING0x03000000) {
4553 if (failed)
4554 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4555
4556 if (bytes)
4557 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4558 else
4559 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4560
4561 if (created_bytes)
4562 g_byte_array_free(created_bytes, true1);
4563 }
4564 else {
4565 /* n will be zero except when it's a FT_UINT_BYTES */
4566 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4567
4568 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4569 * use the byte array created above in this case.
4570 */
4571 if (created_bytes)
4572 g_byte_array_free(created_bytes, true1);
4573
4574 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4575 (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)
;
4576 }
4577
4578 return proto_tree_add_node(tree, new_fi);
4579}
4580
4581
4582proto_item *
4583proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4584 const int start, int length, const unsigned encoding,
4585 nstime_t *retval, int *endoff, int *err)
4586{
4587 field_info *new_fi;
4588 nstime_t time_stamp;
4589 int saved_err = 0;
4590 header_field_info *hfinfo;
4591
4592 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", 4592, __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", 4592,
"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", 4592, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4593
4594 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", 4594,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4595
4596 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4597 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4598 if(retval)if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4599 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4600 nstime_set_zero(retval);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 } )if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
;
4603
4604 nstime_set_zero(&time_stamp);
4605
4606 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4607 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", 4607, ((hfinfo))->abbrev))))
;
4608 /* The only string format that could be a relative time is
4609 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4610 * relative to "now" currently.
4611 */
4612 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4613 saved_err = EINVAL22;
4614 }
4615 else {
4616 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", 4616, ((hfinfo))->abbrev))))
;
4617 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4618
4619 tvb_ensure_bytes_exist(tvb, start, length);
4620 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4621 if (endoff) *endoff = start + length;
4622 }
4623
4624 if (err) *err = saved_err;
4625
4626 if (retval) {
4627 retval->secs = time_stamp.secs;
4628 retval->nsecs = time_stamp.nsecs;
4629 }
4630
4631 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4632
4633 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", 4633
, __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", 4633, "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", 4633, "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", 4633, __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)
; } } }
;
4634
4635 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4636
4637 proto_tree_set_time(new_fi, &time_stamp);
4638
4639 if (encoding & ENC_STRING0x03000000) {
4640 if (saved_err)
4641 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4642 }
4643 else {
4644 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4645 (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)
;
4646 }
4647
4648 return proto_tree_add_node(tree, new_fi);
4649}
4650
4651/* Add a FT_NONE to a proto_tree */
4652proto_item *
4653proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4654 const int start, int length, const char *format,
4655 ...)
4656{
4657 proto_item *pi;
4658 va_list ap;
4659 header_field_info *hfinfo;
4660
4661 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4662
4663 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", 4663
, __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", 4663, "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", 4663, "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", 4663, __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)
; } } }
;
4664
4665 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", 4665
, ((hfinfo))->abbrev))))
;
4666
4667 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4668
4669 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4669, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4670
4671 va_start(ap, format)__builtin_va_start(ap, format);
4672 proto_tree_set_representation(pi, format, ap);
4673 va_end(ap)__builtin_va_end(ap);
4674
4675 /* no value to set for FT_NONE */
4676 return pi;
4677}
4678
4679/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4680 * offset, and returns proto_item* */
4681proto_item *
4682ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4683 const unsigned encoding)
4684{
4685 proto_item *item;
4686
4687 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4688 length, encoding);
4689
4690 return item;
4691}
4692
4693/* Advance the ptvcursor's offset within its tvbuff without
4694 * adding anything to the proto_tree. */
4695void
4696ptvcursor_advance(ptvcursor_t* ptvc, int length)
4697{
4698 ptvc->offset += length;
4699}
4700
4701
4702static void
4703proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4704{
4705 fvalue_set_protocol(fi->value, tvb, field_data, length);
4706}
4707
4708/* Add a FT_PROTOCOL to a proto_tree */
4709proto_item *
4710proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4711 int start, int length, const char *format, ...)
4712{
4713 proto_item *pi;
4714 tvbuff_t *protocol_tvb;
4715 va_list ap;
4716 header_field_info *hfinfo;
4717 char* protocol_rep;
4718
4719 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4720
4721 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", 4721
, __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", 4721, "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", 4721, "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", 4721, __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)
; } } }
;
4722
4723 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"
, 4723, ((hfinfo))->abbrev))))
;
4724
4725 /*
4726 * This can throw an exception, so do it before we allocate anything.
4727 */
4728 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4729
4730 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4731
4732 va_start(ap, format)__builtin_va_start(ap, format);
4733 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4734 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4735 g_free(protocol_rep);
4736 va_end(ap)__builtin_va_end(ap);
4737
4738 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4738, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4739
4740 va_start(ap, format)__builtin_va_start(ap, format);
4741 proto_tree_set_representation(pi, format, ap);
4742 va_end(ap)__builtin_va_end(ap);
4743
4744 return pi;
4745}
4746
4747/* Add a FT_BYTES to a proto_tree */
4748proto_item *
4749proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4750 int length, const uint8_t *start_ptr)
4751{
4752 proto_item *pi;
4753 header_field_info *hfinfo;
4754 int item_length;
4755
4756 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", 4756, __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", 4756,
"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", 4756, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4757 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4758 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4759
4760 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4761
4762 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", 4762
, __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", 4762, "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", 4762, "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", 4762, __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)
; } } }
;
4763
4764 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",
4764, ((hfinfo))->abbrev))))
;
4765
4766 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4767 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4768
4769 return pi;
4770}
4771
4772/* Add a FT_BYTES to a proto_tree */
4773proto_item *
4774proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4775 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4776{
4777 proto_item *pi;
4778 header_field_info *hfinfo;
4779 int item_length;
4780
4781 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", 4781, __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", 4781,
"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", 4781, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4782 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4783 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4784
4785 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4786
4787 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", 4787
, __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", 4787, "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", 4787, "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", 4787, __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)
; } } }
;
4788
4789 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",
4789, ((hfinfo))->abbrev))))
;
4790
4791 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4792 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4793
4794 return pi;
4795}
4796
4797proto_item *
4798proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4799 int start, int length,
4800 const uint8_t *start_ptr,
4801 const char *format, ...)
4802{
4803 proto_item *pi;
4804 va_list ap;
4805
4806 if (start_ptr == NULL((void*)0))
4807 start_ptr = tvb_get_ptr(tvb, start, length);
4808
4809 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4810
4811 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; }
;
4812
4813 va_start(ap, format)__builtin_va_start(ap, format);
4814 proto_tree_set_representation_value(pi, format, ap);
4815 va_end(ap)__builtin_va_end(ap);
4816
4817 return pi;
4818}
4819
4820proto_item *
4821proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4822 int start, int length, const uint8_t *start_ptr,
4823 const char *format, ...)
4824{
4825 proto_item *pi;
4826 va_list ap;
4827
4828 if (start_ptr == NULL((void*)0))
4829 start_ptr = tvb_get_ptr(tvb, start, length);
4830
4831 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4832
4833 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; }
;
4834
4835 va_start(ap, format)__builtin_va_start(ap, format);
4836 proto_tree_set_representation(pi, format, ap);
4837 va_end(ap)__builtin_va_end(ap);
4838
4839 return pi;
4840}
4841
4842static void
4843proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4844{
4845 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4845, "length >= 0"
))))
;
4846 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", 4846, "start_ptr != ((void*)0) || length == 0"
))))
;
4847
4848 fvalue_set_bytes_data(fi->value, start_ptr, length);
4849}
4850
4851
4852static void
4853proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4854{
4855 tvb_ensure_bytes_exist(tvb, offset, length);
4856 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4857}
4858
4859static void
4860proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4861{
4862 GByteArray *bytes;
4863
4864 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4864, "value != ((void*)0)"
))))
;
4865
4866 bytes = byte_array_dup(value);
4867
4868 fvalue_set_byte_array(fi->value, bytes);
4869}
4870
4871/* Add a FT_*TIME to a proto_tree */
4872proto_item *
4873proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4874 int length, const nstime_t *value_ptr)
4875{
4876 proto_item *pi;
4877 header_field_info *hfinfo;
4878
4879 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4880
4881 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", 4881
, __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", 4881, "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", 4881, "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", 4881, __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)
; } } }
;
4882
4883 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", 4883, ((hfinfo))->abbrev))))
;
4884
4885 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4886 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4887
4888 return pi;
4889}
4890
4891proto_item *
4892proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4893 int start, int length, nstime_t *value_ptr,
4894 const char *format, ...)
4895{
4896 proto_item *pi;
4897 va_list ap;
4898
4899 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4900 if (pi != tree) {
4901 va_start(ap, format)__builtin_va_start(ap, format);
4902 proto_tree_set_representation_value(pi, format, ap);
4903 va_end(ap)__builtin_va_end(ap);
4904 }
4905
4906 return pi;
4907}
4908
4909proto_item *
4910proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4911 int start, int length, nstime_t *value_ptr,
4912 const char *format, ...)
4913{
4914 proto_item *pi;
4915 va_list ap;
4916
4917 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4918 if (pi != tree) {
4919 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4919, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4920
4921 va_start(ap, format)__builtin_va_start(ap, format);
4922 proto_tree_set_representation(pi, format, ap);
4923 va_end(ap)__builtin_va_end(ap);
4924 }
4925
4926 return pi;
4927}
4928
4929/* Set the FT_*TIME value */
4930static void
4931proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4932{
4933 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4933, "value_ptr != ((void*)0)"
))))
;
4934
4935 fvalue_set_time(fi->value, value_ptr);
4936}
4937
4938/* Add a FT_IPXNET to a proto_tree */
4939proto_item *
4940proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4941 int length, uint32_t value)
4942{
4943 proto_item *pi;
4944 header_field_info *hfinfo;
4945
4946 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4947
4948 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", 4948
, __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", 4948, "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", 4948, "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", 4948, __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)
; } } }
;
4949
4950 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"
, 4950, ((hfinfo))->abbrev))))
;
4951
4952 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4953 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
4954
4955 return pi;
4956}
4957
4958proto_item *
4959proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4960 int start, int length, uint32_t value,
4961 const char *format, ...)
4962{
4963 proto_item *pi;
4964 va_list ap;
4965
4966 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4967 if (pi != tree) {
4968 va_start(ap, format)__builtin_va_start(ap, format);
4969 proto_tree_set_representation_value(pi, format, ap);
4970 va_end(ap)__builtin_va_end(ap);
4971 }
4972
4973 return pi;
4974}
4975
4976proto_item *
4977proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4978 int start, int length, uint32_t value,
4979 const char *format, ...)
4980{
4981 proto_item *pi;
4982 va_list ap;
4983
4984 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4985 if (pi != tree) {
4986 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4986, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4987
4988 va_start(ap, format)__builtin_va_start(ap, format);
4989 proto_tree_set_representation(pi, format, ap);
4990 va_end(ap)__builtin_va_end(ap);
4991 }
4992
4993 return pi;
4994}
4995
4996/* Set the FT_IPXNET value */
4997static void
4998proto_tree_set_ipxnet(field_info *fi, uint32_t value)
4999{
5000 fvalue_set_uinteger(fi->value, value);
5001}
5002
5003/* Add a FT_IPv4 to a proto_tree */
5004proto_item *
5005proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5006 int length, ws_in4_addr value)
5007{
5008 proto_item *pi;
5009 header_field_info *hfinfo;
5010
5011 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5012
5013 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", 5013
, __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", 5013, "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", 5013, "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", 5013, __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)
; } } }
;
5014
5015 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", 5015
, ((hfinfo))->abbrev))))
;
5016
5017 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5018 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5019
5020 return pi;
5021}
5022
5023proto_item *
5024proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5025 int start, int length, ws_in4_addr value,
5026 const char *format, ...)
5027{
5028 proto_item *pi;
5029 va_list ap;
5030
5031 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5032 if (pi != tree) {
5033 va_start(ap, format)__builtin_va_start(ap, format);
5034 proto_tree_set_representation_value(pi, format, ap);
5035 va_end(ap)__builtin_va_end(ap);
5036 }
5037
5038 return pi;
5039}
5040
5041proto_item *
5042proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5043 int start, int length, ws_in4_addr value,
5044 const char *format, ...)
5045{
5046 proto_item *pi;
5047 va_list ap;
5048
5049 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5050 if (pi != tree) {
5051 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5051, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5052
5053 va_start(ap, format)__builtin_va_start(ap, format);
5054 proto_tree_set_representation(pi, format, ap);
5055 va_end(ap)__builtin_va_end(ap);
5056 }
5057
5058 return pi;
5059}
5060
5061/* Set the FT_IPv4 value */
5062static void
5063proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5064{
5065 ipv4_addr_and_mask ipv4;
5066 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5067 fvalue_set_ipv4(fi->value, &ipv4);
5068}
5069
5070/* Add a FT_IPv6 to a proto_tree */
5071proto_item *
5072proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5073 int length, const ws_in6_addr *value)
5074{
5075 proto_item *pi;
5076 header_field_info *hfinfo;
5077
5078 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5079
5080 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", 5080
, __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", 5080, "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", 5080, "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", 5080, __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)
; } } }
;
5081
5082 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", 5082
, ((hfinfo))->abbrev))))
;
5083
5084 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5085 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5086
5087 return pi;
5088}
5089
5090proto_item *
5091proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5092 int start, int length,
5093 const ws_in6_addr *value_ptr,
5094 const char *format, ...)
5095{
5096 proto_item *pi;
5097 va_list ap;
5098
5099 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5100 if (pi != tree) {
5101 va_start(ap, format)__builtin_va_start(ap, format);
5102 proto_tree_set_representation_value(pi, format, ap);
5103 va_end(ap)__builtin_va_end(ap);
5104 }
5105
5106 return pi;
5107}
5108
5109proto_item *
5110proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5111 int start, int length,
5112 const ws_in6_addr *value_ptr,
5113 const char *format, ...)
5114{
5115 proto_item *pi;
5116 va_list ap;
5117
5118 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5119 if (pi != tree) {
5120 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5120, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5121
5122 va_start(ap, format)__builtin_va_start(ap, format);
5123 proto_tree_set_representation(pi, format, ap);
5124 va_end(ap)__builtin_va_end(ap);
5125 }
5126
5127 return pi;
5128}
5129
5130/* Set the FT_IPv6 value */
5131static void
5132proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5133{
5134 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5134, "value != ((void*)0)"
))))
;
5135 ipv6_addr_and_prefix ipv6;
5136 ipv6.addr = *value;
5137 ipv6.prefix = 128;
5138 fvalue_set_ipv6(fi->value, &ipv6);
5139}
5140
5141static void
5142proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5143{
5144 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5145}
5146
5147/* Set the FT_FCWWN value */
5148static void
5149proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5150{
5151 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5151, "value_ptr != ((void*)0)"
))))
;
5152 fvalue_set_fcwwn(fi->value, value_ptr);
5153}
5154
5155static void
5156proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5157{
5158 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5159}
5160
5161/* Add a FT_GUID to a proto_tree */
5162proto_item *
5163proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5164 int length, const e_guid_t *value_ptr)
5165{
5166 proto_item *pi;
5167 header_field_info *hfinfo;
5168
5169 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5170
5171 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", 5171
, __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", 5171, "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", 5171, "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", 5171, __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)
; } } }
;
5172
5173 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", 5173
, ((hfinfo))->abbrev))))
;
5174
5175 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5176 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5177
5178 return pi;
5179}
5180
5181proto_item *
5182proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5183 int start, int length,
5184 const e_guid_t *value_ptr,
5185 const char *format, ...)
5186{
5187 proto_item *pi;
5188 va_list ap;
5189
5190 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5191 if (pi != tree) {
5192 va_start(ap, format)__builtin_va_start(ap, format);
5193 proto_tree_set_representation_value(pi, format, ap);
5194 va_end(ap)__builtin_va_end(ap);
5195 }
5196
5197 return pi;
5198}
5199
5200proto_item *
5201proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5202 int start, int length, const e_guid_t *value_ptr,
5203 const char *format, ...)
5204{
5205 proto_item *pi;
5206 va_list ap;
5207
5208 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5209 if (pi != tree) {
5210 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5210, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5211
5212 va_start(ap, format)__builtin_va_start(ap, format);
5213 proto_tree_set_representation(pi, format, ap);
5214 va_end(ap)__builtin_va_end(ap);
5215 }
5216
5217 return pi;
5218}
5219
5220/* Set the FT_GUID value */
5221static void
5222proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5223{
5224 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5224, "value_ptr != ((void*)0)"
))))
;
5225 fvalue_set_guid(fi->value, value_ptr);
5226}
5227
5228static void
5229proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5230 const unsigned encoding)
5231{
5232 e_guid_t guid;
5233
5234 tvb_get_guid(tvb, start, &guid, encoding);
5235 proto_tree_set_guid(fi, &guid);
5236}
5237
5238/* Add a FT_OID to a proto_tree */
5239proto_item *
5240proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5241 int length, const uint8_t* value_ptr)
5242{
5243 proto_item *pi;
5244 header_field_info *hfinfo;
5245
5246 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5247
5248 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", 5248
, __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", 5248, "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", 5248, "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", 5248, __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)
; } } }
;
5249
5250 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", 5250
, ((hfinfo))->abbrev))))
;
5251
5252 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5253 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5254
5255 return pi;
5256}
5257
5258proto_item *
5259proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5260 int start, int length,
5261 const uint8_t* value_ptr,
5262 const char *format, ...)
5263{
5264 proto_item *pi;
5265 va_list ap;
5266
5267 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5268 if (pi != tree) {
5269 va_start(ap, format)__builtin_va_start(ap, format);
5270 proto_tree_set_representation_value(pi, format, ap);
5271 va_end(ap)__builtin_va_end(ap);
5272 }
5273
5274 return pi;
5275}
5276
5277proto_item *
5278proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5279 int start, int length, const uint8_t* value_ptr,
5280 const char *format, ...)
5281{
5282 proto_item *pi;
5283 va_list ap;
5284
5285 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5286 if (pi != tree) {
5287 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5287, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5288
5289 va_start(ap, format)__builtin_va_start(ap, format);
5290 proto_tree_set_representation(pi, format, ap);
5291 va_end(ap)__builtin_va_end(ap);
5292 }
5293
5294 return pi;
5295}
5296
5297/* Set the FT_OID value */
5298static void
5299proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5300{
5301 GByteArray *bytes;
5302
5303 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", 5303, "value_ptr != ((void*)0) || length == 0"
))))
;
5304
5305 bytes = g_byte_array_new();
5306 if (length > 0) {
5307 g_byte_array_append(bytes, value_ptr, length);
5308 }
5309 fvalue_set_byte_array(fi->value, bytes);
5310}
5311
5312static void
5313proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5314{
5315 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5316}
5317
5318/* Set the FT_SYSTEM_ID value */
5319static void
5320proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5321{
5322 GByteArray *bytes;
5323
5324 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", 5324, "value_ptr != ((void*)0) || length == 0"
))))
;
5325
5326 bytes = g_byte_array_new();
5327 if (length > 0) {
5328 g_byte_array_append(bytes, value_ptr, length);
5329 }
5330 fvalue_set_byte_array(fi->value, bytes);
5331}
5332
5333static void
5334proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5335{
5336 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5337}
5338
5339/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5340 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5341 * is destroyed. */
5342proto_item *
5343proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5344 int length, const char* value)
5345{
5346 proto_item *pi;
5347 header_field_info *hfinfo;
5348 int item_length;
5349
5350 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", 5350, __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", 5350,
"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", 5350, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5351 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5352 /*
5353 * Special case - if the length is 0, skip the test, so that
5354 * we can have an empty string right after the end of the
5355 * packet. (This handles URL-encoded forms where the last field
5356 * has no value so the form ends right after the =.)
5357 */
5358 if (item_length != 0)
5359 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5360
5361 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5362
5363 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", 5363
, __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", 5363, "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", 5363, "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", 5363, __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)
; } } }
;
5364
5365 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", 5365, ((hfinfo))->abbrev))))
;
5366
5367 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5368 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5368, "length >= 0"
))))
;
5369
5370 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", 5370, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5371 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5372
5373 return pi;
5374}
5375
5376proto_item *
5377proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5378 int start, int length, const char* value,
5379 const char *format,
5380 ...)
5381{
5382 proto_item *pi;
5383 va_list ap;
5384
5385 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5386 if (pi != tree) {
5387 va_start(ap, format)__builtin_va_start(ap, format);
5388 proto_tree_set_representation_value(pi, format, ap);
5389 va_end(ap)__builtin_va_end(ap);
5390 }
5391
5392 return pi;
5393}
5394
5395proto_item *
5396proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5397 int start, int length, const char* value,
5398 const char *format, ...)
5399{
5400 proto_item *pi;
5401 va_list ap;
5402
5403 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5404 if (pi != tree) {
5405 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5405, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5406
5407 va_start(ap, format)__builtin_va_start(ap, format);
5408 proto_tree_set_representation(pi, format, ap);
5409 va_end(ap)__builtin_va_end(ap);
5410 }
5411
5412 return pi;
5413}
5414
5415/* Set the FT_STRING value */
5416static void
5417proto_tree_set_string(field_info *fi, const char* value)
5418{
5419 if (value) {
5420 fvalue_set_string(fi->value, value);
5421 } else {
5422 /*
5423 * XXX - why is a null value for a string field
5424 * considered valid?
5425 */
5426 fvalue_set_string(fi->value, "[ Null ]");
5427 }
5428}
5429
5430/* Set the FT_AX25 value */
5431static void
5432proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5433{
5434 fvalue_set_ax25(fi->value, value);
5435}
5436
5437static void
5438proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5439{
5440 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5441}
5442
5443/* Set the FT_VINES value */
5444static void
5445proto_tree_set_vines(field_info *fi, const uint8_t* value)
5446{
5447 fvalue_set_vines(fi->value, value);
5448}
5449
5450static void
5451proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5452{
5453 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5454}
5455
5456/* Add a FT_ETHER to a proto_tree */
5457proto_item *
5458proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5459 int length, const uint8_t* value)
5460{
5461 proto_item *pi;
5462 header_field_info *hfinfo;
5463
5464 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5465
5466 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", 5466
, __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", 5466, "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", 5466, "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", 5466, __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)
; } } }
;
5467
5468 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",
5468, ((hfinfo))->abbrev))))
;
5469
5470 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5471 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5472
5473 return pi;
5474}
5475
5476proto_item *
5477proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5478 int start, int length, const uint8_t* value,
5479 const char *format, ...)
5480{
5481 proto_item *pi;
5482 va_list ap;
5483
5484 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5485 if (pi != tree) {
5486 va_start(ap, format)__builtin_va_start(ap, format);
5487 proto_tree_set_representation_value(pi, format, ap);
5488 va_end(ap)__builtin_va_end(ap);
5489 }
5490
5491 return pi;
5492}
5493
5494proto_item *
5495proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5496 int start, int length, const uint8_t* value,
5497 const char *format, ...)
5498{
5499 proto_item *pi;
5500 va_list ap;
5501
5502 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5503 if (pi != tree) {
5504 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5504, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5505
5506 va_start(ap, format)__builtin_va_start(ap, format);
5507 proto_tree_set_representation(pi, format, ap);
5508 va_end(ap)__builtin_va_end(ap);
5509 }
5510
5511 return pi;
5512}
5513
5514/* Set the FT_ETHER value */
5515static void
5516proto_tree_set_ether(field_info *fi, const uint8_t* value)
5517{
5518 fvalue_set_ether(fi->value, value);
5519}
5520
5521static void
5522proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5523{
5524 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5525}
5526
5527/* Add a FT_BOOLEAN to a proto_tree */
5528proto_item *
5529proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5530 int length, uint64_t value)
5531{
5532 proto_item *pi;
5533 header_field_info *hfinfo;
5534
5535 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5536
5537 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", 5537
, __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", 5537, "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", 5537, "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", 5537, __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)
; } } }
;
5538
5539 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"
, 5539, ((hfinfo))->abbrev))))
;
5540
5541 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5542 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5543
5544 return pi;
5545}
5546
5547proto_item *
5548proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5549 tvbuff_t *tvb, int start, int length,
5550 uint64_t value, const char *format, ...)
5551{
5552 proto_item *pi;
5553 va_list ap;
5554
5555 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5556 if (pi != tree) {
5557 va_start(ap, format)__builtin_va_start(ap, format);
5558 proto_tree_set_representation_value(pi, format, ap);
5559 va_end(ap)__builtin_va_end(ap);
5560 }
5561
5562 return pi;
5563}
5564
5565proto_item *
5566proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5567 int start, int length, uint64_t value,
5568 const char *format, ...)
5569{
5570 proto_item *pi;
5571 va_list ap;
5572
5573 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5574 if (pi != tree) {
5575 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5575, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5576
5577 va_start(ap, format)__builtin_va_start(ap, format);
5578 proto_tree_set_representation(pi, format, ap);
5579 va_end(ap)__builtin_va_end(ap);
5580 }
5581
5582 return pi;
5583}
5584
5585/* Set the FT_BOOLEAN value */
5586static void
5587proto_tree_set_boolean(field_info *fi, uint64_t value)
5588{
5589 proto_tree_set_uint64(fi, value);
5590}
5591
5592/* Generate, into "buf", a string showing the bits of a bitfield.
5593 Return a pointer to the character after that string. */
5594static char *
5595other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5596{
5597 int i = 0;
5598 uint64_t bit;
5599 char *p;
5600
5601 p = buf;
5602
5603 /* This is a devel error. It is safer to stop here. */
5604 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5604, "width >= 1"
))))
;
5605
5606 bit = UINT64_C(1)1UL << (width - 1);
5607 for (;;) {
5608 if (mask & bit) {
5609 /* This bit is part of the field. Show its value. */
5610 if (val & bit)
5611 *p++ = '1';
5612 else
5613 *p++ = '0';
5614 } else {
5615 /* This bit is not part of the field. */
5616 *p++ = '.';
5617 }
5618 bit >>= 1;
5619 i++;
5620 if (i >= width)
5621 break;
5622 if (i % 4 == 0)
5623 *p++ = ' ';
5624 }
5625 *p = '\0';
5626 return p;
5627}
5628
5629static char *
5630decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5631{
5632 char *p;
5633
5634 p = other_decode_bitfield_value(buf, val, mask, width);
5635 p = g_stpcpy(p, " = ");
5636
5637 return p;
5638}
5639
5640static char *
5641other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5642{
5643 int i = 0;
5644 uint64_t bit;
5645 char *p;
5646
5647 p = buf;
5648
5649 /* This is a devel error. It is safer to stop here. */
5650 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5650, "width >= 1"
))))
;
5651
5652 bit = UINT64_C(1)1UL << (width - 1);
5653 for (;;) {
5654 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5655 (mask & bit)) {
5656 /* This bit is part of the field. Show its value. */
5657 if (val & bit)
5658 *p++ = '1';
5659 else
5660 *p++ = '0';
5661 } else {
5662 /* This bit is not part of the field. */
5663 *p++ = '.';
5664 }
5665 bit >>= 1;
5666 i++;
5667 if (i >= width)
5668 break;
5669 if (i % 4 == 0)
5670 *p++ = ' ';
5671 }
5672
5673 *p = '\0';
5674 return p;
5675}
5676
5677static char *
5678decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5679{
5680 char *p;
5681
5682 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5683 p = g_stpcpy(p, " = ");
5684
5685 return p;
5686}
5687
5688/* Add a FT_FLOAT to a proto_tree */
5689proto_item *
5690proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5691 int length, float value)
5692{
5693 proto_item *pi;
5694 header_field_info *hfinfo;
5695
5696 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5697
5698 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", 5698
, __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", 5698, "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", 5698, "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", 5698, __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)
; } } }
;
5699
5700 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",
5700, ((hfinfo))->abbrev))))
;
5701
5702 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5703 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5704
5705 return pi;
5706}
5707
5708proto_item *
5709proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5710 int start, int length, float value,
5711 const char *format, ...)
5712{
5713 proto_item *pi;
5714 va_list ap;
5715
5716 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5717 if (pi != tree) {
5718 va_start(ap, format)__builtin_va_start(ap, format);
5719 proto_tree_set_representation_value(pi, format, ap);
5720 va_end(ap)__builtin_va_end(ap);
5721 }
5722
5723 return pi;
5724}
5725
5726proto_item *
5727proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5728 int start, int length, float value,
5729 const char *format, ...)
5730{
5731 proto_item *pi;
5732 va_list ap;
5733
5734 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5735 if (pi != tree) {
5736 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5736, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5737
5738 va_start(ap, format)__builtin_va_start(ap, format);
5739 proto_tree_set_representation(pi, format, ap);
5740 va_end(ap)__builtin_va_end(ap);
5741 }
5742
5743 return pi;
5744}
5745
5746/* Set the FT_FLOAT value */
5747static void
5748proto_tree_set_float(field_info *fi, float value)
5749{
5750 fvalue_set_floating(fi->value, value);
5751}
5752
5753/* Add a FT_DOUBLE to a proto_tree */
5754proto_item *
5755proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5756 int length, double value)
5757{
5758 proto_item *pi;
5759 header_field_info *hfinfo;
5760
5761 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5762
5763 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", 5763
, __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", 5763, "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", 5763, "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", 5763, __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)
; } } }
;
5764
5765 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"
, 5765, ((hfinfo))->abbrev))))
;
5766
5767 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5768 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5769
5770 return pi;
5771}
5772
5773proto_item *
5774proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5775 int start, int length, double value,
5776 const char *format, ...)
5777{
5778 proto_item *pi;
5779 va_list ap;
5780
5781 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5782 if (pi != tree) {
5783 va_start(ap, format)__builtin_va_start(ap, format);
5784 proto_tree_set_representation_value(pi, format, ap);
5785 va_end(ap)__builtin_va_end(ap);
5786 }
5787
5788 return pi;
5789}
5790
5791proto_item *
5792proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5793 int start, int length, double value,
5794 const char *format, ...)
5795{
5796 proto_item *pi;
5797 va_list ap;
5798
5799 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5800 if (pi != tree) {
5801 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5801, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5802
5803 va_start(ap, format)__builtin_va_start(ap, format);
5804 proto_tree_set_representation(pi, format, ap);
5805 va_end(ap)__builtin_va_end(ap);
5806 }
5807
5808 return pi;
5809}
5810
5811/* Set the FT_DOUBLE value */
5812static void
5813proto_tree_set_double(field_info *fi, double value)
5814{
5815 fvalue_set_floating(fi->value, value);
5816}
5817
5818/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5819proto_item *
5820proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5821 int length, uint32_t value)
5822{
5823 proto_item *pi = NULL((void*)0);
5824 header_field_info *hfinfo;
5825
5826 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5827
5828 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", 5828
, __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", 5828, "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", 5828, "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", 5828, __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)
; } } }
;
5829
5830 switch (hfinfo->type) {
5831 case FT_CHAR:
5832 case FT_UINT8:
5833 case FT_UINT16:
5834 case FT_UINT24:
5835 case FT_UINT32:
5836 case FT_FRAMENUM:
5837 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5838 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5839 break;
5840
5841 default:
5842 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)
5843 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)
;
5844 }
5845
5846 return pi;
5847}
5848
5849proto_item *
5850proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5851 int start, int length, uint32_t value,
5852 const char *format, ...)
5853{
5854 proto_item *pi;
5855 va_list ap;
5856
5857 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5858 if (pi != tree) {
5859 va_start(ap, format)__builtin_va_start(ap, format);
5860 proto_tree_set_representation_value(pi, format, ap);
5861 va_end(ap)__builtin_va_end(ap);
5862 }
5863
5864 return pi;
5865}
5866
5867proto_item *
5868proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5869 int start, int length, uint32_t value,
5870 const char *format, ...)
5871{
5872 proto_item *pi;
5873 va_list ap;
5874
5875 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5876 if (pi != tree) {
5877 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5877, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5878
5879 va_start(ap, format)__builtin_va_start(ap, format);
5880 proto_tree_set_representation(pi, format, ap);
5881 va_end(ap)__builtin_va_end(ap);
5882 }
5883
5884 return pi;
5885}
5886
5887/* Set the FT_UINT{8,16,24,32} value */
5888static void
5889proto_tree_set_uint(field_info *fi, uint32_t value)
5890{
5891 const header_field_info *hfinfo;
5892 uint32_t integer;
5893
5894 hfinfo = fi->hfinfo;
5895 integer = value;
5896
5897 if (hfinfo->bitmask) {
5898 /* Mask out irrelevant portions */
5899 integer &= (uint32_t)(hfinfo->bitmask);
5900
5901 /* Shift bits */
5902 integer >>= hfinfo_bitshift(hfinfo);
5903
5904 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5905 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)
;
5906 }
5907
5908 fvalue_set_uinteger(fi->value, integer);
5909}
5910
5911/* Add FT_UINT{40,48,56,64} to a proto_tree */
5912proto_item *
5913proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5914 int length, uint64_t value)
5915{
5916 proto_item *pi = NULL((void*)0);
5917 header_field_info *hfinfo;
5918
5919 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5920
5921 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", 5921
, __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", 5921, "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", 5921, "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", 5921, __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)
; } } }
;
5922
5923 switch (hfinfo->type) {
5924 case FT_UINT40:
5925 case FT_UINT48:
5926 case FT_UINT56:
5927 case FT_UINT64:
5928 case FT_FRAMENUM:
5929 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5930 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
5931 break;
5932
5933 default:
5934 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)
5935 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)
;
5936 }
5937
5938 return pi;
5939}
5940
5941proto_item *
5942proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5943 int start, int length, uint64_t value,
5944 const char *format, ...)
5945{
5946 proto_item *pi;
5947 va_list ap;
5948
5949 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5950 if (pi != tree) {
5951 va_start(ap, format)__builtin_va_start(ap, format);
5952 proto_tree_set_representation_value(pi, format, ap);
5953 va_end(ap)__builtin_va_end(ap);
5954 }
5955
5956 return pi;
5957}
5958
5959proto_item *
5960proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5961 int start, int length, uint64_t value,
5962 const char *format, ...)
5963{
5964 proto_item *pi;
5965 va_list ap;
5966
5967 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5968 if (pi != tree) {
5969 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5969, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5970
5971 va_start(ap, format)__builtin_va_start(ap, format);
5972 proto_tree_set_representation(pi, format, ap);
5973 va_end(ap)__builtin_va_end(ap);
5974 }
5975
5976 return pi;
5977}
5978
5979/* Set the FT_UINT{40,48,56,64} value */
5980static void
5981proto_tree_set_uint64(field_info *fi, uint64_t value)
5982{
5983 const header_field_info *hfinfo;
5984 uint64_t integer;
5985
5986 hfinfo = fi->hfinfo;
5987 integer = value;
5988
5989 if (hfinfo->bitmask) {
5990 /* Mask out irrelevant portions */
5991 integer &= hfinfo->bitmask;
5992
5993 /* Shift bits */
5994 integer >>= hfinfo_bitshift(hfinfo);
5995
5996 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5997 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)
;
5998 }
5999
6000 fvalue_set_uinteger64(fi->value, integer);
6001}
6002
6003/* Add FT_INT{8,16,24,32} to a proto_tree */
6004proto_item *
6005proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6006 int length, int32_t value)
6007{
6008 proto_item *pi = NULL((void*)0);
6009 header_field_info *hfinfo;
6010
6011 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6012
6013 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", 6013
, __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", 6013, "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", 6013, "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", 6013, __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)
; } } }
;
6014
6015 switch (hfinfo->type) {
6016 case FT_INT8:
6017 case FT_INT16:
6018 case FT_INT24:
6019 case FT_INT32:
6020 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6021 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6022 break;
6023
6024 default:
6025 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)
6026 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6027 }
6028
6029 return pi;
6030}
6031
6032proto_item *
6033proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6034 int start, int length, int32_t value,
6035 const char *format, ...)
6036{
6037 proto_item *pi;
6038 va_list ap;
6039
6040 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6041 if (pi != tree) {
6042 va_start(ap, format)__builtin_va_start(ap, format);
6043 proto_tree_set_representation_value(pi, format, ap);
6044 va_end(ap)__builtin_va_end(ap);
6045 }
6046
6047 return pi;
6048}
6049
6050proto_item *
6051proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6052 int start, int length, int32_t value,
6053 const char *format, ...)
6054{
6055 proto_item *pi;
6056 va_list ap;
6057
6058 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6059 if (pi != tree) {
6060 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6060, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6061
6062 va_start(ap, format)__builtin_va_start(ap, format);
6063 proto_tree_set_representation(pi, format, ap);
6064 va_end(ap)__builtin_va_end(ap);
6065 }
6066
6067 return pi;
6068}
6069
6070/* Set the FT_INT{8,16,24,32} value */
6071static void
6072proto_tree_set_int(field_info *fi, int32_t value)
6073{
6074 const header_field_info *hfinfo;
6075 uint32_t integer;
6076 int no_of_bits;
6077
6078 hfinfo = fi->hfinfo;
6079 integer = (uint32_t) value;
6080
6081 if (hfinfo->bitmask) {
6082 /* Mask out irrelevant portions */
6083 integer &= (uint32_t)(hfinfo->bitmask);
6084
6085 /* Shift bits */
6086 integer >>= hfinfo_bitshift(hfinfo);
6087
6088 no_of_bits = ws_count_ones(hfinfo->bitmask);
6089 integer = ws_sign_ext32(integer, no_of_bits);
6090
6091 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6092 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)
;
6093 }
6094
6095 fvalue_set_sinteger(fi->value, integer);
6096}
6097
6098/* Add FT_INT{40,48,56,64} to a proto_tree */
6099proto_item *
6100proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6101 int length, int64_t value)
6102{
6103 proto_item *pi = NULL((void*)0);
6104 header_field_info *hfinfo;
6105
6106 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6107
6108 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", 6108
, __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", 6108, "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", 6108, "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", 6108, __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)
; } } }
;
6109
6110 switch (hfinfo->type) {
6111 case FT_INT40:
6112 case FT_INT48:
6113 case FT_INT56:
6114 case FT_INT64:
6115 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6116 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6117 break;
6118
6119 default:
6120 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)
6121 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6122 }
6123
6124 return pi;
6125}
6126
6127proto_item *
6128proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6129 int start, int length, int64_t value,
6130 const char *format, ...)
6131{
6132 proto_item *pi;
6133 va_list ap;
6134
6135 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6136 if (pi != tree) {
6137 va_start(ap, format)__builtin_va_start(ap, format);
6138 proto_tree_set_representation_value(pi, format, ap);
6139 va_end(ap)__builtin_va_end(ap);
6140 }
6141
6142 return pi;
6143}
6144
6145/* Set the FT_INT{40,48,56,64} value */
6146static void
6147proto_tree_set_int64(field_info *fi, int64_t value)
6148{
6149 const header_field_info *hfinfo;
6150 uint64_t integer;
6151 int no_of_bits;
6152
6153 hfinfo = fi->hfinfo;
6154 integer = value;
6155
6156 if (hfinfo->bitmask) {
6157 /* Mask out irrelevant portions */
6158 integer &= hfinfo->bitmask;
6159
6160 /* Shift bits */
6161 integer >>= hfinfo_bitshift(hfinfo);
6162
6163 no_of_bits = ws_count_ones(hfinfo->bitmask);
6164 integer = ws_sign_ext64(integer, no_of_bits);
6165
6166 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6167 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)
;
6168 }
6169
6170 fvalue_set_sinteger64(fi->value, integer);
6171}
6172
6173proto_item *
6174proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6175 int start, int length, int64_t value,
6176 const char *format, ...)
6177{
6178 proto_item *pi;
6179 va_list ap;
6180
6181 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6182 if (pi != tree) {
6183 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6183, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6184
6185 va_start(ap, format)__builtin_va_start(ap, format);
6186 proto_tree_set_representation(pi, format, ap);
6187 va_end(ap)__builtin_va_end(ap);
6188 }
6189
6190 return pi;
6191}
6192
6193/* Add a FT_EUI64 to a proto_tree */
6194proto_item *
6195proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6196 int length, const uint64_t value)
6197{
6198 proto_item *pi;
6199 header_field_info *hfinfo;
6200
6201 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6202
6203 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", 6203
, __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", 6203, "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", 6203, "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", 6203, __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)
; } } }
;
6204
6205 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",
6205, ((hfinfo))->abbrev))))
;
6206
6207 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6208 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6209
6210 return pi;
6211}
6212
6213proto_item *
6214proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6215 int start, int length, const uint64_t value,
6216 const char *format, ...)
6217{
6218 proto_item *pi;
6219 va_list ap;
6220
6221 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6222 if (pi != tree) {
6223 va_start(ap, format)__builtin_va_start(ap, format);
6224 proto_tree_set_representation_value(pi, format, ap);
6225 va_end(ap)__builtin_va_end(ap);
6226 }
6227
6228 return pi;
6229}
6230
6231proto_item *
6232proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6233 int start, int length, const uint64_t value,
6234 const char *format, ...)
6235{
6236 proto_item *pi;
6237 va_list ap;
6238
6239 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6240 if (pi != tree) {
6241 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6241, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6242
6243 va_start(ap, format)__builtin_va_start(ap, format);
6244 proto_tree_set_representation(pi, format, ap);
6245 va_end(ap)__builtin_va_end(ap);
6246 }
6247
6248 return pi;
6249}
6250
6251/* Set the FT_EUI64 value */
6252static void
6253proto_tree_set_eui64(field_info *fi, const uint64_t value)
6254{
6255 uint8_t v[FT_EUI64_LEN8];
6256 phton64(v, value);
6257 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6258}
6259
6260static void
6261proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6262{
6263 if (encoding)
6264 {
6265 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6266 } else {
6267 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6268 }
6269}
6270
6271proto_item *
6272proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6273 const mac_hf_list_t *list_generic,
6274 int idx, tvbuff_t *tvb,
6275 proto_tree *tree, int offset)
6276{
6277 const uint8_t addr[6];
6278 const char *addr_name = NULL((void*)0);
6279 const char *oui_name = NULL((void*)0);
6280 proto_item *addr_item = NULL((void*)0);
6281 proto_tree *addr_tree = NULL((void*)0);
6282 proto_item *ret_val = NULL((void*)0);
6283
6284 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6285 return NULL((void*)0);
6286 }
6287
6288 /* Resolve what we can of the address */
6289 tvb_memcpy(tvb, (void *)addr, offset, 6);
6290 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6291 addr_name = get_ether_name(addr);
6292 }
6293 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6294 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6295 }
6296
6297 /* Add the item for the specific address type */
6298 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6299 if (idx >= 0) {
6300 addr_tree = proto_item_add_subtree(ret_val, idx);
6301 }
6302 else {
6303 addr_tree = tree;
6304 }
6305
6306 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6307 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6308 tvb, offset, 6, addr_name);
6309 proto_item_set_generated(addr_item);
6310 proto_item_set_hidden(addr_item);
6311 }
6312
6313 if (list_specific->hf_oui != NULL((void*)0)) {
6314 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6315 proto_item_set_generated(addr_item);
6316 proto_item_set_hidden(addr_item);
6317
6318 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6319 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6320 proto_item_set_generated(addr_item);
6321 proto_item_set_hidden(addr_item);
6322 }
6323 }
6324
6325 if (list_specific->hf_lg != NULL((void*)0)) {
6326 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6327 }
6328 if (list_specific->hf_ig != NULL((void*)0)) {
6329 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6330 }
6331
6332 /* Were we given a list for generic address fields? If not, stop here */
6333 if (list_generic == NULL((void*)0)) {
6334 return ret_val;
6335 }
6336
6337 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6338 proto_item_set_hidden(addr_item);
6339
6340 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6341 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6342 tvb, offset, 6, addr_name);
6343 proto_item_set_generated(addr_item);
6344 proto_item_set_hidden(addr_item);
6345 }
6346
6347 if (list_generic->hf_oui != NULL((void*)0)) {
6348 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6349 proto_item_set_generated(addr_item);
6350 proto_item_set_hidden(addr_item);
6351
6352 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6353 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6354 proto_item_set_generated(addr_item);
6355 proto_item_set_hidden(addr_item);
6356 }
6357 }
6358
6359 if (list_generic->hf_lg != NULL((void*)0)) {
6360 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6361 proto_item_set_hidden(addr_item);
6362 }
6363 if (list_generic->hf_ig != NULL((void*)0)) {
6364 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6365 proto_item_set_hidden(addr_item);
6366 }
6367 return ret_val;
6368}
6369
6370static proto_item *
6371proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6372{
6373 proto_node *pnode, *tnode, *sibling;
6374 field_info *tfi;
6375 unsigned depth = 1;
6376
6377 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6377, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6378
6379 /*
6380 * Restrict our depth. proto_tree_traverse_pre_order and
6381 * proto_tree_traverse_post_order (and possibly others) are recursive
6382 * so we need to be mindful of our stack size.
6383 */
6384 if (tree->first_child == NULL((void*)0)) {
6385 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6386 depth++;
6387 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6388 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__)), 6391)))
6389 "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__)), 6391)))
6390 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__)), 6391)))
6391 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__)), 6391)))
;
6392 }
6393 }
6394 }
6395
6396 /*
6397 * Make sure "tree" is ready to have subtrees under it, by
6398 * checking whether it's been given an ett_ value.
6399 *
6400 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6401 * node of the protocol tree. That node is not displayed,
6402 * so it doesn't need an ett_ value to remember whether it
6403 * was expanded.
6404 */
6405 tnode = tree;
6406 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6407 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6408 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"
, 6409)
6409 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"
, 6409)
;
6410 /* XXX - is it safe to continue here? */
6411 }
6412
6413 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6414 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6415 pnode->parent = tnode;
6416 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6417 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6418 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6419
6420 if (tnode->last_child != NULL((void*)0)) {
6421 sibling = tnode->last_child;
6422 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6422, "sibling->next == ((void*)0)"
))))
;
6423 sibling->next = pnode;
6424 } else
6425 tnode->first_child = pnode;
6426 tnode->last_child = pnode;
6427
6428 /* We should not be adding a fake node for an interesting field */
6429 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", 6429, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6430
6431 /* XXX - Should the proto_item have a header_field_info member, at least
6432 * for faked items, to know what hfi was faked? (Some dissectors look at
6433 * the tree items directly.)
6434 */
6435 return (proto_item *)pnode;
6436}
6437
6438/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6439static proto_item *
6440proto_tree_add_node(proto_tree *tree, field_info *fi)
6441{
6442 proto_node *pnode, *tnode, *sibling;
6443 field_info *tfi;
6444 unsigned depth = 1;
6445
6446 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6446, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6447
6448 /*
6449 * Restrict our depth. proto_tree_traverse_pre_order and
6450 * proto_tree_traverse_post_order (and possibly others) are recursive
6451 * so we need to be mindful of our stack size.
6452 */
6453 if (tree->first_child == NULL((void*)0)) {
6454 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6455 depth++;
6456 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6457 fvalue_free(fi->value);
6458 fi->value = NULL((void*)0);
6459 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__)), 6462)))
6460 "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__)), 6462)))
6461 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__)), 6462)))
6462 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__)), 6462)))
;
6463 }
6464 }
6465 }
6466
6467 /*
6468 * Make sure "tree" is ready to have subtrees under it, by
6469 * checking whether it's been given an ett_ value.
6470 *
6471 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6472 * node of the protocol tree. That node is not displayed,
6473 * so it doesn't need an ett_ value to remember whether it
6474 * was expanded.
6475 */
6476 tnode = tree;
6477 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6478 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6479 /* Since we are not adding fi to a node, its fvalue won't get
6480 * freed by proto_tree_free_node(), so free it now.
6481 */
6482 fvalue_free(fi->value);
6483 fi->value = NULL((void*)0);
6484 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", 6485)
6485 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", 6485)
;
6486 /* XXX - is it safe to continue here? */
6487 }
6488
6489 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6490 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6491 pnode->parent = tnode;
6492 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6493 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6494 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6495
6496 if (tnode->last_child != NULL((void*)0)) {
6497 sibling = tnode->last_child;
6498 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6498, "sibling->next == ((void*)0)"
))))
;
6499 sibling->next = pnode;
6500 } else
6501 tnode->first_child = pnode;
6502 tnode->last_child = pnode;
6503
6504 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6505
6506 return (proto_item *)pnode;
6507}
6508
6509
6510/* Generic way to allocate field_info and add to proto_tree.
6511 * Sets *pfi to address of newly-allocated field_info struct */
6512static proto_item *
6513proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6514 int *length)
6515{
6516 proto_item *pi;
6517 field_info *fi;
6518 int item_length;
6519
6520 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6521 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6522 pi = proto_tree_add_node(tree, fi);
6523
6524 return pi;
6525}
6526
6527
6528static void
6529get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6530 int *item_length, const unsigned encoding)
6531{
6532 int length_remaining;
6533
6534 /*
6535 * We only allow a null tvbuff if the item has a zero length,
6536 * i.e. if there's no data backing it.
6537 */
6538 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", 6538, "tvb != ((void*)0) || *length == 0"
))))
;
6539
6540 /*
6541 * XXX - in some protocols, there are 32-bit unsigned length
6542 * fields, so lengths in protocol tree and tvbuff routines
6543 * should really be unsigned. We should have, for those
6544 * field types for which "to the end of the tvbuff" makes sense,
6545 * additional routines that take no length argument and
6546 * add fields that run to the end of the tvbuff.
6547 */
6548 if (*length == -1) {
6549 /*
6550 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6551 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6552 * of -1 means "set the length to what remains in the
6553 * tvbuff".
6554 *
6555 * The assumption is either that
6556 *
6557 * 1) the length of the item can only be determined
6558 * by dissection (typically true of items with
6559 * subitems, which are probably FT_NONE or
6560 * FT_PROTOCOL)
6561 *
6562 * or
6563 *
6564 * 2) if the tvbuff is "short" (either due to a short
6565 * snapshot length or due to lack of reassembly of
6566 * fragments/segments/whatever), we want to display
6567 * what's available in the field (probably FT_BYTES
6568 * or FT_STRING) and then throw an exception later
6569 *
6570 * or
6571 *
6572 * 3) the field is defined to be "what's left in the
6573 * packet"
6574 *
6575 * so we set the length to what remains in the tvbuff so
6576 * that, if we throw an exception while dissecting, it
6577 * has what is probably the right value.
6578 *
6579 * For FT_STRINGZ, it means "the string is null-terminated,
6580 * not null-padded; set the length to the actual length
6581 * of the string", and if the tvbuff if short, we just
6582 * throw an exception.
6583 *
6584 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6585 * it means "find the end of the string",
6586 * and if the tvbuff if short, we just throw an exception.
6587 *
6588 * It's not valid for any other type of field. For those
6589 * fields, we treat -1 the same way we treat other
6590 * negative values - we assume the length is a Really
6591 * Big Positive Number, and throw a ReportedBoundsError
6592 * exception, under the assumption that the Really Big
6593 * Length would run past the end of the packet.
6594 */
6595 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
))
)) {
6596 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6597 /*
6598 * Leave the length as -1, so our caller knows
6599 * it was -1.
6600 */
6601 *item_length = *length;
6602 return;
6603 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6604 switch (tvb_get_uint8(tvb, start) >> 6)
6605 {
6606 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6607 *item_length = 1;
6608 break;
6609 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6610 *item_length = 2;
6611 break;
6612 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6613 *item_length = 4;
6614 break;
6615 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6616 *item_length = 8;
6617 break;
6618 }
6619 }
6620 }
6621
6622 switch (hfinfo->type) {
6623
6624 case FT_PROTOCOL:
6625 case FT_NONE:
6626 case FT_BYTES:
6627 case FT_STRING:
6628 case FT_STRINGZPAD:
6629 case FT_STRINGZTRUNC:
6630 /*
6631 * We allow FT_PROTOCOLs to be zero-length -
6632 * for example, an ONC RPC NULL procedure has
6633 * neither arguments nor reply, so the
6634 * payload for that protocol is empty.
6635 *
6636 * We also allow the others to be zero-length -
6637 * because that's the way the code has been for a
6638 * long, long time.
6639 *
6640 * However, we want to ensure that the start
6641 * offset is not *past* the byte past the end
6642 * of the tvbuff: we throw an exception in that
6643 * case.
6644 */
6645 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6646 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6646, "*length >= 0"
))))
;
6647 break;
6648
6649 case FT_STRINGZ:
6650 /*
6651 * Leave the length as -1, so our caller knows
6652 * it was -1.
6653 */
6654 break;
6655
6656 default:
6657 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6658 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6658))
;
6659 }
6660 *item_length = *length;
6661 } else {
6662 *item_length = *length;
6663 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6664 /*
6665 * These types are for interior nodes of the
6666 * tree, and don't have data associated with
6667 * them; if the length is negative (XXX - see
6668 * above) or goes past the end of the tvbuff,
6669 * cut it short at the end of the tvbuff.
6670 * That way, if this field is selected in
6671 * Wireshark, we don't highlight stuff past
6672 * the end of the data.
6673 */
6674 /* XXX - what to do, if we don't have a tvb? */
6675 if (tvb) {
6676 length_remaining = tvb_captured_length_remaining(tvb, start);
6677 if (*item_length < 0 ||
6678 (*item_length > 0 &&
6679 (length_remaining < *item_length)))
6680 *item_length = length_remaining;
6681 }
6682 }
6683 if (*item_length < 0) {
6684 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6685 }
6686 }
6687}
6688
6689static int
6690get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6691 int length, unsigned item_length, const int encoding)
6692{
6693 uint32_t n;
6694
6695 /*
6696 * We need to get the correct item length here.
6697 * That's normally done by proto_tree_new_item(),
6698 * but we won't be calling it.
6699 */
6700 switch (hfinfo->type) {
6701
6702 case FT_NONE:
6703 case FT_PROTOCOL:
6704 case FT_BYTES:
6705 /*
6706 * The length is the specified length.
6707 */
6708 break;
6709
6710 case FT_UINT_BYTES:
6711 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6712 item_length += n;
6713 if ((int)item_length < length) {
6714 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6715 }
6716 break;
6717
6718 /* XXX - make these just FT_UINT? */
6719 case FT_UINT8:
6720 case FT_UINT16:
6721 case FT_UINT24:
6722 case FT_UINT32:
6723 case FT_UINT40:
6724 case FT_UINT48:
6725 case FT_UINT56:
6726 case FT_UINT64:
6727 /* XXX - make these just FT_INT? */
6728 case FT_INT8:
6729 case FT_INT16:
6730 case FT_INT24:
6731 case FT_INT32:
6732 case FT_INT40:
6733 case FT_INT48:
6734 case FT_INT56:
6735 case FT_INT64:
6736 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6737 if (length < -1) {
6738 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6739 }
6740 if (length == -1) {
6741 uint64_t dummy;
6742 /* This can throw an exception */
6743 /* XXX - do this without fetching the varint? */
6744 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6745 if (length == 0) {
6746 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6747 }
6748 }
6749 item_length = length;
6750 break;
6751 }
6752
6753 /*
6754 * The length is the specified length.
6755 */
6756 break;
6757
6758 case FT_BOOLEAN:
6759 case FT_CHAR:
6760 case FT_IPv4:
6761 case FT_IPXNET:
6762 case FT_IPv6:
6763 case FT_FCWWN:
6764 case FT_AX25:
6765 case FT_VINES:
6766 case FT_ETHER:
6767 case FT_EUI64:
6768 case FT_GUID:
6769 case FT_OID:
6770 case FT_REL_OID:
6771 case FT_SYSTEM_ID:
6772 case FT_FLOAT:
6773 case FT_DOUBLE:
6774 case FT_STRING:
6775 /*
6776 * The length is the specified length.
6777 */
6778 break;
6779
6780 case FT_STRINGZ:
6781 if (length < -1) {
6782 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6783 }
6784 if (length == -1) {
6785 /* This can throw an exception */
6786 /* XXX - do this without fetching the string? */
6787 wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, &length, encoding));
6788 }
6789 item_length = length;
6790 break;
6791
6792 case FT_UINT_STRING:
6793 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6794 item_length += n;
6795 if ((int)item_length < length) {
6796 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6797 }
6798 break;
6799
6800 case FT_STRINGZPAD:
6801 case FT_STRINGZTRUNC:
6802 case FT_ABSOLUTE_TIME:
6803 case FT_RELATIVE_TIME:
6804 case FT_IEEE_11073_SFLOAT:
6805 case FT_IEEE_11073_FLOAT:
6806 /*
6807 * The length is the specified length.
6808 */
6809 break;
6810
6811 default:
6812 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
))
6813 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
))
6814 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 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
))
;
6816 break;
6817 }
6818 return item_length;
6819}
6820
6821// This was arbitrarily chosen, but if you're adding 50K items to the tree
6822// without advancing the offset you should probably take a long, hard look
6823// at what you're doing.
6824// We *could* make this a configurable option, but I (Gerald) would like to
6825// avoid adding yet another nerd knob.
6826# define PROTO_TREE_MAX_IDLE50000 50000
6827static field_info *
6828new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6829 const int start, const int item_length)
6830{
6831 field_info *fi;
6832
6833 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6834
6835 fi->hfinfo = hfinfo;
6836 fi->start = start;
6837 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6838 /* add the data source tvbuff */
6839 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6840
6841 // If our start offset hasn't advanced after adding many items it probably
6842 // means we're in a large or infinite loop.
6843 if (fi->start > 0) {
6844 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6845 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6846 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", 6846, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6847 } else {
6848 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6849 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6850 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6851 }
6852 }
6853 fi->length = item_length;
6854 fi->tree_type = -1;
6855 fi->flags = 0;
6856 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6857 /* If the tree is not visible, set the item hidden, unless we
6858 * need the representation or length and can't fake them.
6859 */
6860 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6861 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6862 }
6863 }
6864 fi->value = fvalue_new(fi->hfinfo->type);
6865 fi->rep = NULL((void*)0);
6866
6867 fi->appendix_start = 0;
6868 fi->appendix_length = 0;
6869
6870 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6871 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6872
6873 return fi;
6874}
6875
6876static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6877{
6878 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6879 return 0;
6880 }
6881
6882 /* Search for field name */
6883 char *ptr = strstr(representation, hfinfo->name);
6884 if (!ptr) {
6885 return 0;
6886 }
6887
6888 /* Check if field name ends with the ": " delimiter */
6889 ptr += strlen(hfinfo->name);
6890 if (strncmp(ptr, ": ", 2) == 0) {
6891 ptr += 2;
6892 }
6893
6894 /* Return offset to after field name */
6895 return ptr - representation;
6896}
6897
6898static size_t label_find_name_pos(const item_label_t *rep)
6899{
6900 size_t name_pos = 0;
6901
6902 /* If the value_pos is too small or too large, we can't find the expected format */
6903 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
6904 return 0;
6905 }
6906
6907 /* Check if the format looks like "label: value", then set name_pos before ':'. */
6908 if (rep->representation[rep->value_pos-2] == ':') {
6909 name_pos = rep->value_pos - 2;
6910 }
6911
6912 return name_pos;
6913}
6914
6915/* If the protocol tree is to be visible, set the representation of a
6916 proto_tree entry with the name of the field for the item and with
6917 the value formatted with the supplied printf-style format and
6918 argument list. */
6919static void
6920proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6921{
6922 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6922, __func__, "assertion failed: %s", "pi"
); } while (0)
;
6923
6924 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6925 * items string representation */
6926 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
6927 size_t name_pos, ret = 0;
6928 char *str;
6929 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6930 const header_field_info *hf;
6931
6932 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6932, "fi"))))
;
6933
6934 hf = fi->hfinfo;
6935
6936 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;
;
6937 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))
)) {
6938 uint64_t val;
6939 char *p;
6940
6941 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)
)
6942 val = fvalue_get_uinteger(fi->value);
6943 else
6944 val = fvalue_get_uinteger64(fi->value);
6945
6946 val <<= hfinfo_bitshift(hf);
6947
6948 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
6949 ret = (p - fi->rep->representation);
6950 }
6951
6952 /* put in the hf name */
6953 name_pos = ret = label_concat(fi->rep->representation, ret, hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, hf->
name, 0)
;
6954
6955 ret = label_concat(fi->rep->representation, ret, ": ")ws_label_strcpy(fi->rep->representation, 240, ret, ": "
, 0)
;
6956 /* If possible, Put in the value of the string */
6957 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
6958 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"
, 6958, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
6959 fi->rep->value_pos = ret;
6960 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, str, 0);
6961 if (ret >= ITEM_LABEL_LENGTH240) {
6962 /* Uh oh, we don't have enough room. Tell the user
6963 * that the field is truncated.
6964 */
6965 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
6966 }
6967 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
6968 }
6969}
6970
6971/* If the protocol tree is to be visible, set the representation of a
6972 proto_tree entry with the representation formatted with the supplied
6973 printf-style format and argument list. */
6974static void
6975proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
6976{
6977 size_t ret; /*tmp return value */
6978 char *str;
6979 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6980
6981 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6981, "fi"))))
;
6982
6983 if (!proto_item_is_hidden(pi)) {
6984 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;
;
6985
6986 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
6987 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"
, 6987, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
6988 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
6989 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
6990 if (ret >= ITEM_LABEL_LENGTH240) {
6991 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
6992 size_t name_pos = label_find_name_pos(fi->rep);
6993 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
6994 }
6995 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
6996 }
6997}
6998
6999static int
7000proto_strlcpy(char *dest, const char *src, size_t dest_size)
7001{
7002 if (dest_size == 0) return 0;
7003
7004 size_t res = g_strlcpy(dest, src, dest_size);
7005
7006 /* At most dest_size - 1 characters will be copied
7007 * (unless dest_size is 0). */
7008 if (res >= dest_size)
7009 res = dest_size - 1;
7010 return (int) res;
7011}
7012
7013static header_field_info *
7014hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7015{
7016 header_field_info *dup_hfinfo;
7017
7018 if (hfinfo->same_name_prev_id == -1)
7019 return NULL((void*)0);
7020 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", 7020
, __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", 7020, "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", 7020,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7021 return dup_hfinfo;
7022}
7023
7024static void
7025hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7026{
7027 g_free(last_field_name);
7028 last_field_name = NULL((void*)0);
7029
7030 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7031 /* No hfinfo with the same name */
7032 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7033 return;
7034 }
7035
7036 if (hfinfo->same_name_next) {
7037 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7038 }
7039
7040 if (hfinfo->same_name_prev_id != -1) {
7041 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7042 same_name_prev->same_name_next = hfinfo->same_name_next;
7043 if (!hfinfo->same_name_next) {
7044 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7045 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7046 }
7047 }
7048}
7049
7050int
7051proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7052{
7053 const header_field_info *hfinfo = finfo->hfinfo;
7054 int label_len = 0;
7055 char *tmp_str;
7056 const char *str;
7057 const uint8_t *bytes;
7058 uint32_t number;
7059 uint64_t number64;
7060 const char *hf_str_val;
7061 char number_buf[NUMBER_LABEL_LENGTH80];
7062 const char *number_out;
7063 address addr;
7064 const ipv4_addr_and_mask *ipv4;
7065 const ipv6_addr_and_prefix *ipv6;
7066
7067 switch (hfinfo->type) {
7068
7069 case FT_NONE:
7070 case FT_PROTOCOL:
7071 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7072
7073 case FT_UINT_BYTES:
7074 case FT_BYTES:
7075 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7076 hfinfo,
7077 fvalue_get_bytes_data(finfo->value),
7078 (unsigned)fvalue_length2(finfo->value),
7079 label_str_size);
7080 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7081 wmem_free(NULL((void*)0), tmp_str);
7082 break;
7083
7084 case FT_ABSOLUTE_TIME:
7085 {
7086 const nstime_t *value = fvalue_get_time(finfo->value);
7087 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7088 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7089 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7090 }
7091 if (hfinfo->strings) {
7092 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7093 if (time_string != NULL((void*)0)) {
7094 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7095 break;
7096 }
7097 }
7098 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7099 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7100 wmem_free(NULL((void*)0), tmp_str);
7101 break;
7102 }
7103
7104 case FT_RELATIVE_TIME:
7105 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7106 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7107 wmem_free(NULL((void*)0), tmp_str);
7108 break;
7109
7110 case FT_BOOLEAN:
7111 number64 = fvalue_get_uinteger64(finfo->value);
7112 label_len = proto_strlcpy(display_label_str,
7113 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7114 break;
7115
7116 case FT_CHAR:
7117 number = fvalue_get_uinteger(finfo->value);
7118
7119 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7120 char tmp[ITEM_LABEL_LENGTH240];
7121 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7122
7123 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7123, "fmtfunc"))))
;
7124 fmtfunc(tmp, number);
7125
7126 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7127
7128 } else if (hfinfo->strings) {
7129 number_out = hf_try_val_to_str(number, hfinfo);
7130
7131 if (!number_out) {
7132 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7133 }
7134
7135 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7136
7137 } else {
7138 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7139
7140 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7141 }
7142
7143 break;
7144
7145 /* XXX - make these just FT_NUMBER? */
7146 case FT_INT8:
7147 case FT_INT16:
7148 case FT_INT24:
7149 case FT_INT32:
7150 case FT_UINT8:
7151 case FT_UINT16:
7152 case FT_UINT24:
7153 case FT_UINT32:
7154 case FT_FRAMENUM:
7155 hf_str_val = NULL((void*)0);
7156 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
))
?
7157 (uint32_t) fvalue_get_sinteger(finfo->value) :
7158 fvalue_get_uinteger(finfo->value);
7159
7160 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7161 char tmp[ITEM_LABEL_LENGTH240];
7162 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7163
7164 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7164, "fmtfunc"))))
;
7165 fmtfunc(tmp, number);
7166
7167 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7168
7169 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7170 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7171 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7172 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7173 hf_str_val = hf_try_val_to_str(number, hfinfo);
7174 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7175 } else {
7176 number_out = hf_try_val_to_str(number, hfinfo);
7177
7178 if (!number_out) {
7179 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7180 }
7181
7182 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7183 }
7184 } else {
7185 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7186
7187 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7188 }
7189
7190 break;
7191
7192 case FT_INT40:
7193 case FT_INT48:
7194 case FT_INT56:
7195 case FT_INT64:
7196 case FT_UINT40:
7197 case FT_UINT48:
7198 case FT_UINT56:
7199 case FT_UINT64:
7200 hf_str_val = NULL((void*)0);
7201 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
))
?
7202 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7203 fvalue_get_uinteger64(finfo->value);
7204
7205 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7206 char tmp[ITEM_LABEL_LENGTH240];
7207 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7208
7209 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7209, "fmtfunc64"
))))
;
7210 fmtfunc64(tmp, number64);
7211
7212 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7213 } else if (hfinfo->strings) {
7214 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7215 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7216 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7217 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7218 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7219 } else {
7220 number_out = hf_try_val64_to_str(number64, hfinfo);
7221
7222 if (!number_out)
7223 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7224
7225 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7226 }
7227 } else {
7228 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7229
7230 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7231 }
7232
7233 break;
7234
7235 case FT_EUI64:
7236 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7237 tmp_str = address_to_display(NULL((void*)0), &addr);
7238 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7239 wmem_free(NULL((void*)0), tmp_str);
7240 break;
7241
7242 case FT_IPv4:
7243 ipv4 = fvalue_get_ipv4(finfo->value);
7244 //XXX: Should we ignore the mask?
7245 set_address_ipv4(&addr, ipv4);
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 free_address(&addr);
7250 break;
7251
7252 case FT_IPv6:
7253 ipv6 = fvalue_get_ipv6(finfo->value);
7254 set_address_ipv6(&addr, ipv6);
7255 tmp_str = address_to_display(NULL((void*)0), &addr);
7256 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7257 wmem_free(NULL((void*)0), tmp_str);
7258 free_address(&addr);
7259 break;
7260
7261 case FT_FCWWN:
7262 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7263 tmp_str = address_to_display(NULL((void*)0), &addr);
7264 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7265 wmem_free(NULL((void*)0), tmp_str);
7266 break;
7267
7268 case FT_ETHER:
7269 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7270 tmp_str = address_to_display(NULL((void*)0), &addr);
7271 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7272 wmem_free(NULL((void*)0), tmp_str);
7273 break;
7274
7275 case FT_GUID:
7276 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7277 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7278 wmem_free(NULL((void*)0), tmp_str);
7279 break;
7280
7281 case FT_REL_OID:
7282 bytes = fvalue_get_bytes_data(finfo->value);
7283 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7284 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7285 wmem_free(NULL((void*)0), tmp_str);
7286 break;
7287
7288 case FT_OID:
7289 bytes = fvalue_get_bytes_data(finfo->value);
7290 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7291 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7292 wmem_free(NULL((void*)0), tmp_str);
7293 break;
7294
7295 case FT_SYSTEM_ID:
7296 bytes = fvalue_get_bytes_data(finfo->value);
7297 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7298 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7299 wmem_free(NULL((void*)0), tmp_str);
7300 break;
7301
7302 case FT_FLOAT:
7303 case FT_DOUBLE:
7304 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7305 break;
7306
7307 case FT_IEEE_11073_SFLOAT:
7308 case FT_IEEE_11073_FLOAT:
7309 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7310 break;
7311
7312 case FT_STRING:
7313 case FT_STRINGZ:
7314 case FT_UINT_STRING:
7315 case FT_STRINGZPAD:
7316 case FT_STRINGZTRUNC:
7317 str = fvalue_get_string(finfo->value);
7318 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, str, label_strcat_flags(hfinfo));
7319 if (label_len >= label_str_size) {
7320 /* Truncation occurred. Get the real length
7321 * copied (not including '\0') */
7322 label_len = label_str_size ? label_str_size - 1 : 0;
7323 }
7324 break;
7325
7326 default:
7327 /* First try ftype string representation */
7328 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7329 if (!tmp_str) {
7330 /* Default to show as bytes */
7331 bytes = fvalue_get_bytes_data(finfo->value);
7332 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7333 }
7334 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7335 wmem_free(NULL((void*)0), tmp_str);
7336 break;
7337 }
7338 return label_len;
7339}
7340
7341const char *
7342proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7343 char *result, char *expr, const int size)
7344{
7345 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7346 GPtrArray *finfos;
7347 field_info *finfo = NULL((void*)0);
7348 header_field_info* hfinfo;
7349 const char *abbrev = NULL((void*)0);
7350
7351 char *str;
7352 col_custom_t *field_idx;
7353 int field_id;
7354 int ii = 0;
7355
7356 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7356, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7357 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7358 field_id = field_idx->field_id;
7359 if (field_id == 0) {
7360 GPtrArray *fvals = NULL((void*)0);
7361 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7362 if (fvals != NULL((void*)0)) {
7363
7364 // XXX - Handling occurrences is unusual when more
7365 // than one field is involved, e.g. there's four
7366 // results for tcp.port + tcp.port. We may really
7367 // want to apply it to the operands, not the output.
7368 // Note that occurrences are not quite the same as
7369 // the layer operator (should the grammar support
7370 // both?)
7371 /* Calculate single index or set outer boundaries */
7372 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7373 if (occurrence < 0) {
7374 i = occurrence + len;
7375 last = i;
7376 } else if (occurrence > 0) {
7377 i = occurrence - 1;
7378 last = i;
7379 } else {
7380 i = 0;
7381 last = len - 1;
7382 }
7383 if (i < 0 || i >= len) {
7384 g_ptr_array_unref(fvals);
7385 continue;
7386 }
7387 for (; i <= last; i++) {
7388 /* XXX - We could have a "resolved" result
7389 * for types where the value depends only
7390 * on the type, e.g. FT_IPv4, and not on
7391 * hfinfo->strings. Supporting the latter
7392 * requires knowing which hfinfo matched
7393 * if there are multiple with the same
7394 * abbreviation. In any case, we need to
7395 * know the expected return type of the
7396 * field expression.
7397 */
7398 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7399 if (offset_r && (offset_r < (size - 1)))
7400 result[offset_r++] = ',';
7401 if (offset_e && (offset_e < (size - 1)))
7402 expr[offset_e++] = ',';
7403 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7404 // col_{add,append,set}_* calls ws_label_strcpy
7405 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7406
7407 g_free(str);
7408 }
7409 g_ptr_array_unref(fvals);
7410 } else if (passed) {
7411 // XXX - Occurrence doesn't make sense for a test
7412 // output, it should be applied to the operands.
7413 if (offset_r && (offset_r < (size - 1)))
7414 result[offset_r++] = ',';
7415 if (offset_e && (offset_e < (size - 1)))
7416 expr[offset_e++] = ',';
7417 /* Prevent multiple check marks */
7418 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7419 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7420 } else {
7421 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7422 }
7423 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7424 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7425 } else {
7426 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7427 }
7428 }
7429 continue;
7430 }
7431 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", 7431
, __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", 7431,
"(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", 7431,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7432
7433 /* do we need to rewind ? */
7434 if (!hfinfo)
7435 return "";
7436
7437 if (occurrence < 0) {
7438 /* Search other direction */
7439 while (hfinfo->same_name_prev_id != -1) {
7440 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", 7440
, __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", 7440, "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", 7440,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7441 }
7442 }
7443
7444 prev_len = 0; /* Reset handled occurrences */
7445
7446 while (hfinfo) {
7447 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7448
7449 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7450 if (occurrence < 0) {
7451 hfinfo = hfinfo->same_name_next;
7452 } else {
7453 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7454 }
7455 continue;
7456 }
7457
7458 /* Are there enough occurrences of the field? */
7459 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7460 if (occurrence < 0) {
7461 hfinfo = hfinfo->same_name_next;
7462 } else {
7463 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7464 }
7465 prev_len += len;
7466 continue;
7467 }
7468
7469 /* Calculate single index or set outer boundaries */
7470 if (occurrence < 0) {
7471 i = occurrence + len + prev_len;
7472 last = i;
7473 } else if (occurrence > 0) {
7474 i = occurrence - 1 - prev_len;
7475 last = i;
7476 } else {
7477 i = 0;
7478 last = len - 1;
7479 }
7480
7481 prev_len += len; /* Count handled occurrences */
7482
7483 while (i <= last) {
7484 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7485
7486 if (offset_r && (offset_r < (size - 1)))
7487 result[offset_r++] = ',';
7488
7489 if (display_details) {
7490 char representation[ITEM_LABEL_LENGTH240];
7491 size_t offset = 0;
7492
7493 if (finfo->rep && finfo->rep->value_len) {
7494 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7495 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7496 } else {
7497 proto_item_fill_label(finfo, representation, &offset);
7498 }
7499 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7500 } else {
7501 switch (hfinfo->type) {
7502
7503 case FT_NONE:
7504 case FT_PROTOCOL:
7505 /* Prevent multiple check marks */
7506 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7507 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7508 } else {
7509 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7510 }
7511 break;
7512
7513 default:
7514 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7515 break;
7516 }
7517 }
7518
7519 if (offset_e && (offset_e < (size - 1)))
7520 expr[offset_e++] = ',';
7521
7522 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
))
)) {
7523 const char *hf_str_val;
7524 /* Integer types with BASE_NONE never get the numeric value. */
7525 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7526 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7527 } 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
)
) {
7528 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7529 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7530 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7531 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7532 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7533 }
7534 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7535 offset_e = (int)strlen(expr);
7536 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7537 /* Prevent multiple check marks */
7538 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7539 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7540 } else {
7541 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7542 }
7543 } else {
7544 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7545 // col_{add,append,set}_* calls ws_label_strcpy
7546 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7547 wmem_free(NULL((void*)0), str);
7548 }
7549 i++;
7550 }
7551
7552 /* XXX: Why is only the first abbreviation returned for a multifield
7553 * custom column? */
7554 if (!abbrev) {
7555 /* Store abbrev for return value */
7556 abbrev = hfinfo->abbrev;
7557 }
7558
7559 if (occurrence == 0) {
7560 /* Fetch next hfinfo with same name (abbrev) */
7561 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7562 } else {
7563 hfinfo = NULL((void*)0);
7564 }
7565 }
7566 }
7567
7568 if (offset_r >= (size - 1)) {
7569 mark_truncated(result, 0, size, NULL((void*)0));
7570 }
7571 if (offset_e >= (size - 1)) {
7572 mark_truncated(expr, 0, size, NULL((void*)0));
7573 }
7574 return abbrev ? abbrev : "";
7575}
7576
7577char *
7578proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7579{
7580 int len, prev_len, last, i;
7581 GPtrArray *finfos;
7582 field_info *finfo = NULL((void*)0);
7583 header_field_info* hfinfo;
7584
7585 char *filter = NULL((void*)0);
7586 GPtrArray *filter_array;
7587
7588 col_custom_t *col_custom;
7589 int field_id;
7590
7591 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7591, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7592 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7593 for (GSList *iter = field_ids; iter; iter = iter->next) {
7594 col_custom = (col_custom_t*)iter->data;
7595 field_id = col_custom->field_id;
7596 if (field_id == 0) {
7597 GPtrArray *fvals = NULL((void*)0);
7598 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7599 if (fvals != NULL((void*)0)) {
7600 // XXX - Handling occurrences is unusual when more
7601 // than one field is involved, e.g. there's four
7602 // results for tcp.port + tcp.port. We really
7603 // want to apply it to the operands, not the output.
7604 /* Calculate single index or set outer boundaries */
7605 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7606 if (occurrence < 0) {
7607 i = occurrence + len;
7608 last = i;
7609 } else if (occurrence > 0) {
7610 i = occurrence - 1;
7611 last = i;
7612 } else {
7613 i = 0;
7614 last = len - 1;
7615 }
7616 if (i < 0 || i >= len) {
7617 g_ptr_array_unref(fvals);
7618 continue;
7619 }
7620 for (; i <= last; i++) {
7621 /* XXX - Should multiple values for one
7622 * field use set membership to reduce
7623 * verbosity, here and below? */
7624 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7625 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7626 wmem_free(NULL((void*)0), str);
7627 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7628 g_ptr_array_add(filter_array, filter);
7629 }
7630 }
7631 g_ptr_array_unref(fvals);
7632 } else if (passed) {
7633 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7634 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7635 g_ptr_array_add(filter_array, filter);
7636 }
7637 } else {
7638 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7639 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7640 g_ptr_array_add(filter_array, filter);
7641 }
7642 }
7643 continue;
7644 }
7645
7646 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", 7646
, __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", 7646,
"(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", 7646,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7647
7648 /* do we need to rewind ? */
7649 if (!hfinfo)
7650 return NULL((void*)0);
7651
7652 if (occurrence < 0) {
7653 /* Search other direction */
7654 while (hfinfo->same_name_prev_id != -1) {
7655 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", 7655
, __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", 7655, "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", 7655,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7656 }
7657 }
7658
7659 prev_len = 0; /* Reset handled occurrences */
7660
7661 while (hfinfo) {
7662 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7663
7664 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7665 if (occurrence < 0) {
7666 hfinfo = hfinfo->same_name_next;
7667 } else {
7668 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7669 }
7670 continue;
7671 }
7672
7673 /* Are there enough occurrences of the field? */
7674 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7675 if (occurrence < 0) {
7676 hfinfo = hfinfo->same_name_next;
7677 } else {
7678 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7679 }
7680 prev_len += len;
7681 continue;
7682 }
7683
7684 /* Calculate single index or set outer boundaries */
7685 if (occurrence < 0) {
7686 i = occurrence + len + prev_len;
7687 last = i;
7688 } else if (occurrence > 0) {
7689 i = occurrence - 1 - prev_len;
7690 last = i;
7691 } else {
7692 i = 0;
7693 last = len - 1;
7694 }
7695
7696 prev_len += len; /* Count handled occurrences */
7697
7698 while (i <= last) {
7699 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7700
7701 filter = proto_construct_match_selected_string(finfo, edt);
7702 if (filter) {
7703 /* Only add the same expression once (especially for FT_PROTOCOL).
7704 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7705 */
7706 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7707 g_ptr_array_add(filter_array, filter);
7708 }
7709 }
7710 i++;
7711 }
7712
7713 if (occurrence == 0) {
7714 /* Fetch next hfinfo with same name (abbrev) */
7715 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7716 } else {
7717 hfinfo = NULL((void*)0);
7718 }
7719 }
7720 }
7721
7722 g_ptr_array_add(filter_array, NULL((void*)0));
7723
7724 /* XXX: Should this be || or && ? */
7725 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7726
7727 g_ptr_array_free(filter_array, true1);
7728
7729 return output;
7730}
7731
7732/* Set text of proto_item after having already been created. */
7733void
7734proto_item_set_text(proto_item *pi, const char *format, ...)
7735{
7736 field_info *fi = NULL((void*)0);
7737 va_list ap;
7738
7739 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7740
7741 fi = PITEM_FINFO(pi)((pi)->finfo);
7742 if (fi == NULL((void*)0))
7743 return;
7744
7745 if (fi->rep) {
7746 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7747 fi->rep = NULL((void*)0);
7748 }
7749
7750 va_start(ap, format)__builtin_va_start(ap, format);
7751 proto_tree_set_representation(pi, format, ap);
7752 va_end(ap)__builtin_va_end(ap);
7753}
7754
7755/* Append to text of proto_item after having already been created. */
7756void
7757proto_item_append_text(proto_item *pi, const char *format, ...)
7758{
7759 field_info *fi = NULL((void*)0);
7760 size_t curlen;
7761 char *str;
7762 va_list ap;
7763
7764 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7765
7766 fi = PITEM_FINFO(pi)((pi)->finfo);
7767 if (fi == NULL((void*)0)) {
7768 return;
7769 }
7770
7771 if (!proto_item_is_hidden(pi)) {
7772 /*
7773 * If we don't already have a representation,
7774 * generate the default representation.
7775 */
7776 if (fi->rep == NULL((void*)0)) {
7777 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;
;
7778 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7779 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7780 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7781 (strncmp(format, ": ", 2) == 0)) {
7782 fi->rep->value_pos += 2;
7783 }
7784 }
7785 if (fi->rep) {
7786 curlen = strlen(fi->rep->representation);
7787 /* curlen doesn't include the \0 byte.
7788 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7789 * the representation has already been truncated (of an up
7790 * to 4 byte UTF-8 character) or is just at the maximum length
7791 * unless we search for " [truncated]" (which may not be
7792 * at the start.)
7793 * It's safer to do nothing.
7794 */
7795 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7796 va_start(ap, format)__builtin_va_start(ap, format);
7797 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7798 va_end(ap)__builtin_va_end(ap);
7799 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"
, 7799, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7800 /* Keep fi->rep->value_pos */
7801 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, str, 0);
7802 if (curlen >= ITEM_LABEL_LENGTH240) {
7803 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7804 size_t name_pos = label_find_name_pos(fi->rep);
7805 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7806 }
7807 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7808 }
7809 }
7810 }
7811}
7812
7813/* Prepend to text of proto_item after having already been created. */
7814void
7815proto_item_prepend_text(proto_item *pi, const char *format, ...)
7816{
7817 field_info *fi = NULL((void*)0);
7818 size_t pos;
7819 char representation[ITEM_LABEL_LENGTH240];
7820 char *str;
7821 va_list ap;
7822
7823 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7824
7825 fi = PITEM_FINFO(pi)((pi)->finfo);
7826 if (fi == NULL((void*)0)) {
7827 return;
7828 }
7829
7830 if (!proto_item_is_hidden(pi)) {
7831 /*
7832 * If we don't already have a representation,
7833 * generate the default representation.
7834 */
7835 if (fi->rep == NULL((void*)0)) {
7836 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;
;
7837 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7838 } else
7839 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7840
7841 va_start(ap, format)__builtin_va_start(ap, format);
7842 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7843 va_end(ap)__builtin_va_end(ap);
7844 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"
, 7844, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7845 fi->rep->value_pos += strlen(str);
7846 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7847 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, representation, 0);
7848 /* XXX: As above, if the old representation is close to the label
7849 * length, it might already be marked as truncated. */
7850 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7851 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7852 size_t name_pos = label_find_name_pos(fi->rep);
7853 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7854 }
7855 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7856 }
7857}
7858
7859static void
7860finfo_set_len(field_info *fi, const int length)
7861{
7862 int length_remaining;
7863
7864 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", 7864,
"length >= 0", fi->hfinfo->abbrev))))
;
7865 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7866 if (length > length_remaining)
7867 fi->length = length_remaining;
7868 else
7869 fi->length = length;
7870
7871 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7872 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7873 fvalue_set_protocol_length(fi->value, fi->length);
7874 }
7875
7876 /*
7877 * You cannot just make the "len" field of a GByteArray
7878 * larger, if there's no data to back that length;
7879 * you can only make it smaller.
7880 */
7881 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7882 GBytes *bytes = fvalue_get_bytes(fi->value);
7883 size_t size;
7884 const void *data = g_bytes_get_data(bytes, &size);
7885 if ((size_t)fi->length <= size) {
7886 fvalue_set_bytes_data(fi->value, data, fi->length);
7887 }
7888 g_bytes_unref(bytes);
7889 }
7890}
7891
7892void
7893proto_item_set_len(proto_item *pi, const int length)
7894{
7895 field_info *fi;
7896
7897 if (pi == NULL((void*)0))
7898 return;
7899
7900 fi = PITEM_FINFO(pi)((pi)->finfo);
7901 if (fi == NULL((void*)0))
7902 return;
7903
7904 finfo_set_len(fi, length);
7905}
7906
7907/*
7908 * Sets the length of the item based on its start and on the specified
7909 * offset, which is the offset past the end of the item; as the start
7910 * in the item is relative to the beginning of the data source tvbuff,
7911 * we need to pass in a tvbuff - the end offset is relative to the beginning
7912 * of that tvbuff.
7913 */
7914void
7915proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7916{
7917 field_info *fi;
7918 int length;
7919
7920 if (pi == NULL((void*)0))
7921 return;
7922
7923 fi = PITEM_FINFO(pi)((pi)->finfo);
7924 if (fi == NULL((void*)0))
7925 return;
7926
7927 end += tvb_raw_offset(tvb);
7928 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7928, "end >= fi->start"
))))
;
7929 length = end - fi->start;
7930
7931 finfo_set_len(fi, length);
7932}
7933
7934int
7935proto_item_get_len(const proto_item *pi)
7936{
7937 field_info *fi;
7938
7939 if (!pi)
7940 return -1;
7941 fi = PITEM_FINFO(pi)((pi)->finfo);
7942 return fi ? fi->length : -1;
7943}
7944
7945void
7946proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
7947 if (!ti) {
7948 return;
7949 }
7950 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)
;
7951 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)
;
7952}
7953
7954char *
7955proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
7956{
7957 field_info *fi;
7958
7959 if (!pi)
7960 return wmem_strdup(scope, "");
7961 fi = PITEM_FINFO(pi)((pi)->finfo);
7962 if (!fi)
7963 return wmem_strdup(scope, "");
7964 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7964, "fi->hfinfo != ((void*)0)"
))))
;
7965 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
7966}
7967
7968proto_tree *
7969proto_tree_create_root(packet_info *pinfo)
7970{
7971 proto_node *pnode;
7972
7973 /* Initialize the proto_node */
7974 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
7975 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
7976 pnode->parent = NULL((void*)0);
7977 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
7978 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
7979
7980 /* Make sure we can access pinfo everywhere */
7981 pnode->tree_data->pinfo = pinfo;
7982
7983 /* Don't initialize the tree_data_t. Wait until we know we need it */
7984 pnode->tree_data->interesting_hfids = NULL((void*)0);
7985
7986 /* Set the default to false so it's easier to
7987 * find errors; if we expect to see the protocol tree
7988 * but for some reason the default 'visible' is not
7989 * changed, then we'll find out very quickly. */
7990 pnode->tree_data->visible = false0;
7991
7992 /* Make sure that we fake protocols (if possible) */
7993 pnode->tree_data->fake_protocols = true1;
7994
7995 /* Keep track of the number of children */
7996 pnode->tree_data->count = 0;
7997
7998 /* Initialize our loop checks */
7999 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8000 pnode->tree_data->max_start = 0;
8001 pnode->tree_data->start_idle_count = 0;
8002
8003 return (proto_tree *)pnode;
8004}
8005
8006
8007/* "prime" a proto_tree with a single hfid that a dfilter
8008 * is interested in. */
8009void
8010proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8011{
8012 header_field_info *hfinfo;
8013
8014 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", 8014, __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", 8014, "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", 8014, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8015 /* this field is referenced by a filter so increase the refcount.
8016 also increase the refcount for the parent, i.e the protocol.
8017 Don't increase the refcount if we're already printing the
8018 type, as that is a superset of direct reference.
8019 */
8020 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8021 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8022 }
8023 /* only increase the refcount if there is a parent.
8024 if this is a protocol and not a field then parent will be -1
8025 and there is no parent to add any refcounting for.
8026 */
8027 if (hfinfo->parent != -1) {
8028 header_field_info *parent_hfinfo;
8029 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", 8029
, __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", 8029,
"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", 8029,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8030
8031 /* Mark parent as indirectly referenced unless it is already directly
8032 * referenced, i.e. the user has specified the parent in a filter.
8033 */
8034 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8035 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8036 }
8037}
8038
8039/* "prime" a proto_tree with a single hfid that a dfilter
8040 * is interested in. */
8041void
8042proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8043{
8044 header_field_info *hfinfo;
8045
8046 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", 8046, __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", 8046, "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", 8046, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8047 /* this field is referenced by an (output) filter so increase the refcount.
8048 also increase the refcount for the parent, i.e the protocol.
8049 */
8050 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8051 /* only increase the refcount if there is a parent.
8052 if this is a protocol and not a field then parent will be -1
8053 and there is no parent to add any refcounting for.
8054 */
8055 if (hfinfo->parent != -1) {
8056 header_field_info *parent_hfinfo;
8057 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", 8057
, __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", 8057,
"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", 8057,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8058
8059 /* Mark parent as indirectly referenced unless it is already directly
8060 * referenced, i.e. the user has specified the parent in a filter.
8061 */
8062 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8063 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8064 }
8065}
8066
8067proto_tree *
8068proto_item_add_subtree(proto_item *pi, const int idx) {
8069 field_info *fi;
8070
8071 if (!pi)
8072 return NULL((void*)0);
8073
8074 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", 8074, "idx >= 0 && idx < num_tree_types"
))))
;
8075
8076 fi = PITEM_FINFO(pi)((pi)->finfo);
8077 if (!fi)
8078 return (proto_tree *)pi;
8079
8080 fi->tree_type = idx;
8081
8082 return (proto_tree *)pi;
8083}
8084
8085proto_tree *
8086proto_item_get_subtree(proto_item *pi) {
8087 field_info *fi;
8088
8089 if (!pi)
8090 return NULL((void*)0);
8091 fi = PITEM_FINFO(pi)((pi)->finfo);
8092 if ( (fi) && (fi->tree_type == -1) )
8093 return NULL((void*)0);
8094 return (proto_tree *)pi;
8095}
8096
8097proto_item *
8098proto_item_get_parent(const proto_item *ti) {
8099 if (!ti)
8100 return NULL((void*)0);
8101 return ti->parent;
8102}
8103
8104proto_item *
8105proto_item_get_parent_nth(proto_item *ti, int gen) {
8106 if (!ti)
8107 return NULL((void*)0);
8108 while (gen--) {
8109 ti = ti->parent;
8110 if (!ti)
8111 return NULL((void*)0);
8112 }
8113 return ti;
8114}
8115
8116
8117proto_item *
8118proto_tree_get_parent(proto_tree *tree) {
8119 if (!tree)
8120 return NULL((void*)0);
8121 return (proto_item *)tree;
8122}
8123
8124proto_tree *
8125proto_tree_get_parent_tree(proto_tree *tree) {
8126 if (!tree)
8127 return NULL((void*)0);
8128
8129 /* we're the root tree, there's no parent
8130 return ourselves so the caller has at least a tree to attach to */
8131 if (!tree->parent)
8132 return tree;
8133
8134 return (proto_tree *)tree->parent;
8135}
8136
8137proto_tree *
8138proto_tree_get_root(proto_tree *tree) {
8139 if (!tree)
8140 return NULL((void*)0);
8141 while (tree->parent) {
8142 tree = tree->parent;
8143 }
8144 return tree;
8145}
8146
8147void
8148proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8149 proto_item *item_to_move)
8150{
8151 /* This function doesn't generate any values. It only reorganizes the prococol tree
8152 * so we can bail out immediately if it isn't visible. */
8153 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8154 return;
8155
8156 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", 8156, "item_to_move->parent == tree"
))))
;
8157 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", 8157, "fixed_item->parent == tree"
))))
;
8158
8159 /*** cut item_to_move out ***/
8160
8161 /* is item_to_move the first? */
8162 if (tree->first_child == item_to_move) {
8163 /* simply change first child to next */
8164 tree->first_child = item_to_move->next;
8165
8166 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", 8166, "tree->last_child != item_to_move"
))))
;
8167 } else {
8168 proto_item *curr_item;
8169 /* find previous and change it's next */
8170 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8171 if (curr_item->next == item_to_move) {
8172 break;
8173 }
8174 }
8175
8176 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8176, "curr_item"
))))
;
8177
8178 curr_item->next = item_to_move->next;
8179
8180 /* fix last_child if required */
8181 if (tree->last_child == item_to_move) {
8182 tree->last_child = curr_item;
8183 }
8184 }
8185
8186 /*** insert to_move after fixed ***/
8187 item_to_move->next = fixed_item->next;
8188 fixed_item->next = item_to_move;
8189 if (tree->last_child == fixed_item) {
8190 tree->last_child = item_to_move;
8191 }
8192}
8193
8194void
8195proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8196 const int length)
8197{
8198 field_info *fi;
8199
8200 if (tree == NULL((void*)0))
8201 return;
8202
8203 fi = PTREE_FINFO(tree)((tree)->finfo);
8204 if (fi == NULL((void*)0))
8205 return;
8206
8207 start += tvb_raw_offset(tvb);
8208 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8208, "start >= 0"
))))
;
8209 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8209, "length >= 0"
))))
;
8210
8211 fi->appendix_start = start;
8212 fi->appendix_length = length;
8213}
8214
8215static void
8216check_protocol_filter_name_or_fail(const char *filter_name)
8217{
8218 /* Require at least two characters. */
8219 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8220 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)
;
8221 }
8222
8223 if (proto_check_field_name(filter_name) != '\0') {
8224 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)
8225 " 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)
8226 " 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)
;
8227 }
8228
8229 /* Check that it doesn't match some very common numeric forms. */
8230 if (filter_name[0] == '0' &&
8231 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8232 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8233 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])
8234 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])
;
8235 }
8236
8237 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8238
8239 /* Check that it contains at least one letter. */
8240 bool_Bool have_letter = false0;
8241 for (const char *s = filter_name; *s != '\0'; s++) {
8242 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8243 have_letter = true1;
8244 break;
8245 }
8246 }
8247 if (!have_letter) {
8248 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)
8249 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8250 }
8251
8252 /* Check for reserved keywords. */
8253 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8254 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)
8255 " 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)
;
8256 }
8257}
8258
8259int
8260proto_register_protocol(const char *name, const char *short_name,
8261 const char *filter_name)
8262{
8263 protocol_t *protocol;
8264 header_field_info *hfinfo;
8265
8266 check_protocol_filter_name_or_fail(filter_name);
8267
8268 /*
8269 * Add this protocol to the list of known protocols;
8270 * the list is sorted by protocol short name.
8271 */
8272 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8273 protocol->name = name;
8274 protocol->short_name = short_name;
8275 protocol->filter_name = filter_name;
8276 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8277 protocol->is_enabled = true1; /* protocol is enabled by default */
8278 protocol->enabled_by_default = true1; /* see previous comment */
8279 protocol->can_toggle = true1;
8280 protocol->parent_proto_id = -1;
8281 protocol->heur_list = NULL((void*)0);
8282
8283 /* List will be sorted later by name, when all protocols completed registering */
8284 protocols = g_list_prepend(protocols, protocol);
8285 /*
8286 * Make sure there's not already a protocol with any of those
8287 * names. Crash if there is, as that's an error in the code
8288 * or an inappropriate plugin.
8289 * This situation has to be fixed to not register more than one
8290 * protocol with the same name.
8291 */
8292 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8293 /* ws_error will terminate the program */
8294 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)
8295 " 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)
;
8296 }
8297 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8298 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)
8299 " 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)
;
8300 }
8301 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8302 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)
8303 " 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)
;
8304 }
8305
8306 /* Here we allocate a new header_field_info struct */
8307 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8308 hfinfo->name = name;
8309 hfinfo->abbrev = filter_name;
8310 hfinfo->type = FT_PROTOCOL;
8311 hfinfo->display = BASE_NONE;
8312 hfinfo->strings = protocol;
8313 hfinfo->bitmask = 0;
8314 hfinfo->ref_type = HF_REF_TYPE_NONE;
8315 hfinfo->blurb = NULL((void*)0);
8316 hfinfo->parent = -1; /* This field differentiates protos and fields */
8317
8318 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8319 return protocol->proto_id;
8320}
8321
8322int
8323proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8324{
8325 protocol_t *protocol;
8326 header_field_info *hfinfo;
8327
8328 /*
8329 * Helper protocols don't need the strict rules as a "regular" protocol
8330 * Just register it in a list and make a hf_ field from it
8331 */
8332 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8333 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)
;
8334 }
8335
8336 if (parent_proto <= 0) {
8337 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)
8338 " 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)
;
8339 }
8340
8341 check_protocol_filter_name_or_fail(filter_name);
8342
8343 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8344 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8345 protocol->name = name;
8346 protocol->short_name = short_name;
8347 protocol->filter_name = filter_name;
8348 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8349
8350 /* Enabling and toggling is really determined by parent protocol,
8351 but provide default values here */
8352 protocol->is_enabled = true1;
8353 protocol->enabled_by_default = true1;
8354 protocol->can_toggle = true1;
8355
8356 protocol->parent_proto_id = parent_proto;
8357 protocol->heur_list = NULL((void*)0);
8358
8359 /* List will be sorted later by name, when all protocols completed registering */
8360 protocols = g_list_prepend(protocols, protocol);
8361
8362 /* Here we allocate a new header_field_info struct */
8363 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8364 hfinfo->name = name;
8365 hfinfo->abbrev = filter_name;
8366 hfinfo->type = field_type;
8367 hfinfo->display = BASE_NONE;
8368 if (field_type == FT_BYTES) {
8369 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8370 }
8371 hfinfo->strings = protocol;
8372 hfinfo->bitmask = 0;
8373 hfinfo->ref_type = HF_REF_TYPE_NONE;
8374 hfinfo->blurb = NULL((void*)0);
8375 hfinfo->parent = -1; /* This field differentiates protos and fields */
8376
8377 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8378 return protocol->proto_id;
8379}
8380
8381bool_Bool
8382proto_deregister_protocol(const char *short_name)
8383{
8384 protocol_t *protocol;
8385 header_field_info *hfinfo;
8386 int proto_id;
8387 unsigned i;
8388
8389 proto_id = proto_get_id_by_short_name(short_name);
8390 protocol = find_protocol_by_id(proto_id);
8391 if (protocol == NULL((void*)0))
8392 return false0;
8393
8394 g_hash_table_remove(proto_names, protocol->name);
8395 g_hash_table_remove(proto_short_names, (void *)short_name);
8396 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8397
8398 if (protocol->fields) {
8399 for (i = 0; i < protocol->fields->len; i++) {
8400 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8401 hfinfo_remove_from_gpa_name_map(hfinfo);
8402 expert_deregister_expertinfo(hfinfo->abbrev);
8403 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8404 }
8405 g_ptr_array_free(protocol->fields, true1);
8406 protocol->fields = NULL((void*)0);
8407 }
8408
8409 g_list_free(protocol->heur_list);
8410
8411 /* Remove this protocol from the list of known protocols */
8412 protocols = g_list_remove(protocols, protocol);
8413
8414 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8415 wmem_map_remove(gpa_name_map, protocol->filter_name);
8416
8417 g_free(last_field_name);
8418 last_field_name = NULL((void*)0);
8419
8420 return true1;
8421}
8422
8423void
8424proto_register_alias(const int proto_id, const char *alias_name)
8425{
8426 protocol_t *protocol;
8427
8428 protocol = find_protocol_by_id(proto_id);
8429 if (alias_name && protocol) {
8430 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8431 }
8432}
8433
8434/*
8435 * Routines to use to iterate over the protocols.
8436 * The argument passed to the iterator routines is an opaque cookie to
8437 * their callers; it's the GList pointer for the current element in
8438 * the list.
8439 * The ID of the protocol is returned, or -1 if there is no protocol.
8440 */
8441int
8442proto_get_first_protocol(void **cookie)
8443{
8444 protocol_t *protocol;
8445
8446 if (protocols == NULL((void*)0))
8447 return -1;
8448 *cookie = protocols;
8449 protocol = (protocol_t *)protocols->data;
8450 return protocol->proto_id;
8451}
8452
8453int
8454proto_get_data_protocol(void *cookie)
8455{
8456 GList *list_item = (GList *)cookie;
8457
8458 protocol_t *protocol = (protocol_t *)list_item->data;
8459 return protocol->proto_id;
8460}
8461
8462int
8463proto_get_next_protocol(void **cookie)
8464{
8465 GList *list_item = (GList *)*cookie;
8466 protocol_t *protocol;
8467
8468 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8469 if (list_item == NULL((void*)0))
8470 return -1;
8471 *cookie = list_item;
8472 protocol = (protocol_t *)list_item->data;
8473 return protocol->proto_id;
8474}
8475
8476header_field_info *
8477proto_get_first_protocol_field(const int proto_id, void **cookie)
8478{
8479 protocol_t *protocol = find_protocol_by_id(proto_id);
8480
8481 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8482 return NULL((void*)0);
8483
8484 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8485 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8486}
8487
8488header_field_info *
8489proto_get_next_protocol_field(const int proto_id, void **cookie)
8490{
8491 protocol_t *protocol = find_protocol_by_id(proto_id);
8492 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8493
8494 i++;
8495
8496 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8497 return NULL((void*)0);
8498
8499 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8500 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8501}
8502
8503protocol_t *
8504find_protocol_by_id(const int proto_id)
8505{
8506 header_field_info *hfinfo;
8507
8508 if (proto_id <= 0)
8509 return NULL((void*)0);
8510
8511 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", 8511, __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", 8511,
"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", 8511, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8512 if (hfinfo->type != FT_PROTOCOL) {
8513 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", 8513, "hfinfo->display & 0x00004000"
))))
;
8514 }
8515 return (protocol_t *)hfinfo->strings;
8516}
8517
8518int
8519proto_get_id(const protocol_t *protocol)
8520{
8521 return protocol->proto_id;
8522}
8523
8524bool_Bool
8525proto_name_already_registered(const char *name)
8526{
8527 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8527, "name", "No name present"))))
;
8528
8529 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8530 return true1;
8531 return false0;
8532}
8533
8534int
8535proto_get_id_by_filter_name(const char *filter_name)
8536{
8537 const protocol_t *protocol = NULL((void*)0);
8538
8539 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", 8539,
"filter_name", "No filter name present"))))
;
8540
8541 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8542
8543 if (protocol == NULL((void*)0))
8544 return -1;
8545 return protocol->proto_id;
8546}
8547
8548int
8549proto_get_id_by_short_name(const char *short_name)
8550{
8551 const protocol_t *protocol = NULL((void*)0);
8552
8553 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", 8553,
"short_name", "No short name present"))))
;
8554
8555 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8556
8557 if (protocol == NULL((void*)0))
8558 return -1;
8559 return protocol->proto_id;
8560}
8561
8562const char *
8563proto_get_protocol_name(const int proto_id)
8564{
8565 protocol_t *protocol;
8566
8567 protocol = find_protocol_by_id(proto_id);
8568
8569 if (protocol == NULL((void*)0))
8570 return NULL((void*)0);
8571 return protocol->name;
8572}
8573
8574const char *
8575proto_get_protocol_short_name(const protocol_t *protocol)
8576{
8577 if (protocol == NULL((void*)0))
8578 return "(none)";
8579 return protocol->short_name;
8580}
8581
8582const char *
8583proto_get_protocol_long_name(const protocol_t *protocol)
8584{
8585 if (protocol == NULL((void*)0))
8586 return "(none)";
8587 return protocol->name;
8588}
8589
8590const char *
8591proto_get_protocol_filter_name(const int proto_id)
8592{
8593 protocol_t *protocol;
8594
8595 protocol = find_protocol_by_id(proto_id);
8596 if (protocol == NULL((void*)0))
8597 return "(none)";
8598 return protocol->filter_name;
8599}
8600
8601void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8602{
8603 heur_dtbl_entry_t* heuristic_dissector;
8604
8605 if (protocol == NULL((void*)0))
8606 return;
8607
8608 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8609 if (heuristic_dissector != NULL((void*)0))
8610 {
8611 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8612 }
8613}
8614
8615void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8616{
8617 if (protocol == NULL((void*)0))
8618 return;
8619
8620 g_list_foreach(protocol->heur_list, func, user_data);
8621}
8622
8623void
8624proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8625 bool_Bool *is_tcp, bool_Bool *is_udp,
8626 bool_Bool *is_sctp, bool_Bool *is_tls,
8627 bool_Bool *is_rtp,
8628 bool_Bool *is_lte_rlc)
8629{
8630 wmem_list_frame_t *protos = wmem_list_head(layers);
8631 int proto_id;
8632 const char *proto_name;
8633
8634 /* Walk the list of a available protocols in the packet and
8635 attempt to find "major" ones. */
8636 /* It might make more sense to assemble and return a bitfield. */
8637 while (protos != NULL((void*)0))
8638 {
8639 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8640 proto_name = proto_get_protocol_filter_name(proto_id);
8641
8642 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8643 (!strcmp(proto_name, "ipv6")))) {
8644 *is_ip = true1;
8645 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8646 *is_tcp = true1;
8647 } else if (is_udp && !strcmp(proto_name, "udp")) {
8648 *is_udp = true1;
8649 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8650 *is_sctp = true1;
8651 } else if (is_tls && !strcmp(proto_name, "tls")) {
8652 *is_tls = true1;
8653 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8654 *is_rtp = true1;
8655 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8656 *is_lte_rlc = true1;
8657 }
8658
8659 protos = wmem_list_frame_next(protos);
8660 }
8661}
8662
8663bool_Bool
8664proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8665{
8666 wmem_list_frame_t *protos = wmem_list_head(layers);
8667 int proto_id;
8668 const char *name;
8669
8670 /* Walk the list of a available protocols in the packet and
8671 attempt to find the specified protocol. */
8672 while (protos != NULL((void*)0))
8673 {
8674 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8675 name = proto_get_protocol_filter_name(proto_id);
8676
8677 if (!strcmp(name, proto_name))
8678 {
8679 return true1;
8680 }
8681
8682 protos = wmem_list_frame_next(protos);
8683 }
8684
8685 return false0;
8686}
8687
8688char *
8689proto_list_layers(const packet_info *pinfo)
8690{
8691 wmem_strbuf_t *buf;
8692 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8693
8694 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8695
8696 /* Walk the list of layers in the packet and
8697 return a string of all entries. */
8698 while (layers != NULL((void*)0))
8699 {
8700 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8701
8702 layers = wmem_list_frame_next(layers);
8703 if (layers != NULL((void*)0)) {
8704 wmem_strbuf_append_c(buf, ':');
8705 }
8706 }
8707
8708 return wmem_strbuf_finalize(buf);
8709}
8710
8711uint8_t
8712proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8713{
8714 int *proto_layer_num_ptr;
8715
8716 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8717 if (proto_layer_num_ptr == NULL((void*)0)) {
8718 return 0;
8719 }
8720
8721 return (uint8_t)*proto_layer_num_ptr;
8722}
8723
8724bool_Bool
8725proto_is_pino(const protocol_t *protocol)
8726{
8727 return (protocol->parent_proto_id != -1);
8728}
8729
8730bool_Bool
8731// NOLINTNEXTLINE(misc-no-recursion)
8732proto_is_protocol_enabled(const protocol_t *protocol)
8733{
8734 if (protocol == NULL((void*)0))
8735 return false0;
8736
8737 //parent protocol determines enable/disable for helper dissectors
8738 if (proto_is_pino(protocol))
8739 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8740
8741 return protocol->is_enabled;
8742}
8743
8744bool_Bool
8745// NOLINTNEXTLINE(misc-no-recursion)
8746proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8747{
8748 //parent protocol determines enable/disable for helper dissectors
8749 if (proto_is_pino(protocol))
8750 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8751
8752 return protocol->enabled_by_default;
8753}
8754
8755bool_Bool
8756// NOLINTNEXTLINE(misc-no-recursion)
8757proto_can_toggle_protocol(const int proto_id)
8758{
8759 protocol_t *protocol;
8760
8761 protocol = find_protocol_by_id(proto_id);
8762 //parent protocol determines toggling for helper dissectors
8763 if (proto_is_pino(protocol))
8764 return proto_can_toggle_protocol(protocol->parent_proto_id);
8765
8766 return protocol->can_toggle;
8767}
8768
8769void
8770proto_disable_by_default(const int proto_id)
8771{
8772 protocol_t *protocol;
8773
8774 protocol = find_protocol_by_id(proto_id);
8775 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8775, "protocol->can_toggle"
))))
;
8776 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", 8776, "proto_is_pino(protocol) == 0"
))))
;
8777 protocol->is_enabled = false0;
8778 protocol->enabled_by_default = false0;
8779}
8780
8781void
8782proto_set_decoding(const int proto_id, const bool_Bool enabled)
8783{
8784 protocol_t *protocol;
8785
8786 protocol = find_protocol_by_id(proto_id);
8787 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8787, "protocol->can_toggle"
))))
;
8788 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", 8788, "proto_is_pino(protocol) == 0"
))))
;
8789 protocol->is_enabled = enabled;
8790}
8791
8792void
8793proto_disable_all(void)
8794{
8795 /* This doesn't explicitly disable heuristic protocols,
8796 * but the heuristic doesn't get called if the parent
8797 * protocol isn't enabled.
8798 */
8799 protocol_t *protocol;
8800 GList *list_item = protocols;
8801
8802 if (protocols == NULL((void*)0))
8803 return;
8804
8805 while (list_item) {
8806 protocol = (protocol_t *)list_item->data;
8807 if (protocol->can_toggle) {
8808 protocol->is_enabled = false0;
8809 }
8810 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8811 }
8812}
8813
8814static void
8815heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8816{
8817 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8818
8819 heur->enabled = heur->enabled_by_default;
8820}
8821
8822void
8823proto_reenable_all(void)
8824{
8825 protocol_t *protocol;
8826 GList *list_item = protocols;
8827
8828 if (protocols == NULL((void*)0))
8829 return;
8830
8831 while (list_item) {
8832 protocol = (protocol_t *)list_item->data;
8833 if (protocol->can_toggle)
8834 protocol->is_enabled = protocol->enabled_by_default;
8835 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8836 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8837 }
8838}
8839
8840void
8841proto_set_cant_toggle(const int proto_id)
8842{
8843 protocol_t *protocol;
8844
8845 protocol = find_protocol_by_id(proto_id);
8846 protocol->can_toggle = false0;
8847}
8848
8849static int
8850proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8851{
8852 if (proto != NULL((void*)0)) {
8853 g_ptr_array_add(proto->fields, hfi);
8854 }
8855
8856 return proto_register_field_init(hfi, parent);
8857}
8858
8859/* for use with static arrays only, since we don't allocate our own copies
8860of the header_field_info struct contained within the hf_register_info struct */
8861void
8862proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8863{
8864 hf_register_info *ptr = hf;
8865 protocol_t *proto;
8866 int i;
8867
8868 proto = find_protocol_by_id(parent);
8869
8870 if (proto->fields == NULL((void*)0)) {
8871 proto->fields = g_ptr_array_sized_new(num_records);
8872 }
8873
8874 for (i = 0; i < num_records; i++, ptr++) {
8875 /*
8876 * Make sure we haven't registered this yet.
8877 * Most fields have variables associated with them
8878 * that are initialized to -1; some have array elements,
8879 * or possibly uninitialized variables, so we also allow
8880 * 0 (which is unlikely to be the field ID we get back
8881 * from "proto_register_field_init()").
8882 */
8883 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8884 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8885 "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)
8886 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8887 return;
8888 }
8889
8890 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8891 }
8892}
8893
8894/* deregister already registered fields */
8895void
8896proto_deregister_field (const int parent, int hf_id)
8897{
8898 header_field_info *hfi;
8899 protocol_t *proto;
8900 unsigned i;
8901
8902 g_free(last_field_name);
8903 last_field_name = NULL((void*)0);
8904
8905 if (hf_id == -1 || hf_id == 0)
8906 return;
8907
8908 proto = find_protocol_by_id (parent);
8909 if (!proto || proto->fields == NULL((void*)0)) {
8910 return;
8911 }
8912
8913 for (i = 0; i < proto->fields->len; i++) {
8914 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8915 if (hfi->id == hf_id) {
8916 /* Found the hf_id in this protocol */
8917 wmem_map_remove(gpa_name_map, hfi->abbrev);
8918 g_ptr_array_remove_index_fast(proto->fields, i);
8919 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8920 return;
8921 }
8922 }
8923}
8924
8925/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
8926void
8927proto_deregister_all_fields_with_prefix(const int parent, const gchar *prefix)
8928{
8929 header_field_info *hfinfo;
8930 protocol_t *proto;
8931
8932 g_free(last_field_name);
8933 last_field_name = NULL((void*)0);
8934
8935 proto = find_protocol_by_id(parent);
8936 if (proto && proto->fields && proto->fields->len > 0) {
8937 guint i = proto->fields->len;
8938 do {
8939 i--;
8940
8941 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8942 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) )
) {
8943 hfinfo_remove_from_gpa_name_map(hfinfo);
8944 expert_deregister_expertinfo(hfinfo->abbrev);
8945 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8946 g_ptr_array_remove_index_fast(proto->fields, i);
8947 }
8948 } while (i > 0);
8949 }
8950}
8951
8952void
8953proto_add_deregistered_data (void *data)
8954{
8955 g_ptr_array_add(deregistered_data, data);
8956}
8957
8958void
8959proto_add_deregistered_slice (size_t block_size, void *mem_block)
8960{
8961 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
)))
;
8962
8963 slice_data->block_size = block_size;
8964 slice_data->mem_block = mem_block;
8965
8966 g_ptr_array_add(deregistered_slice, slice_data);
8967}
8968
8969void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
8970{
8971 if (field_strings == NULL((void*)0)) {
8972 return;
8973 }
8974
8975 switch (field_type) {
8976 case FT_FRAMENUM:
8977 /* This is just an integer represented as a pointer */
8978 break;
8979 case FT_PROTOCOL: {
8980 protocol_t *protocol = (protocol_t *)field_strings;
8981 g_free((char *)protocol->short_name);
8982 break;
8983 }
8984 case FT_BOOLEAN: {
8985 true_false_string *tf = (true_false_string *)field_strings;
8986 g_free((char *)tf->true_string);
8987 g_free((char *)tf->false_string);
8988 break;
8989 }
8990 case FT_UINT40:
8991 case FT_INT40:
8992 case FT_UINT48:
8993 case FT_INT48:
8994 case FT_UINT56:
8995 case FT_INT56:
8996 case FT_UINT64:
8997 case FT_INT64: {
8998 if (field_display & BASE_UNIT_STRING0x00001000) {
8999 unit_name_string *unit = (unit_name_string *)field_strings;
9000 g_free((char *)unit->singular);
9001 g_free((char *)unit->plural);
9002 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9003 range_string *rs = (range_string *)field_strings;
9004 while (rs->strptr) {
9005 g_free((char *)rs->strptr);
9006 rs++;
9007 }
9008 } else if (field_display & BASE_EXT_STRING0x00000200) {
9009 val64_string_ext *vse = (val64_string_ext *)field_strings;
9010 val64_string *vs = (val64_string *)vse->_vs_p;
9011 while (vs->strptr) {
9012 g_free((char *)vs->strptr);
9013 vs++;
9014 }
9015 val64_string_ext_free(vse);
9016 field_strings = NULL((void*)0);
9017 } else if (field_display == BASE_CUSTOM) {
9018 /* this will be a pointer to a function, don't free that */
9019 field_strings = NULL((void*)0);
9020 } else {
9021 val64_string *vs64 = (val64_string *)field_strings;
9022 while (vs64->strptr) {
9023 g_free((char *)vs64->strptr);
9024 vs64++;
9025 }
9026 }
9027 break;
9028 }
9029 case FT_CHAR:
9030 case FT_UINT8:
9031 case FT_INT8:
9032 case FT_UINT16:
9033 case FT_INT16:
9034 case FT_UINT24:
9035 case FT_INT24:
9036 case FT_UINT32:
9037 case FT_INT32:
9038 case FT_FLOAT:
9039 case FT_DOUBLE: {
9040 if (field_display & BASE_UNIT_STRING0x00001000) {
9041 unit_name_string *unit = (unit_name_string *)field_strings;
9042 g_free((char *)unit->singular);
9043 g_free((char *)unit->plural);
9044 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9045 range_string *rs = (range_string *)field_strings;
9046 while (rs->strptr) {
9047 g_free((char *)rs->strptr);
9048 rs++;
9049 }
9050 } else if (field_display & BASE_EXT_STRING0x00000200) {
9051 value_string_ext *vse = (value_string_ext *)field_strings;
9052 value_string *vs = (value_string *)vse->_vs_p;
9053 while (vs->strptr) {
9054 g_free((char *)vs->strptr);
9055 vs++;
9056 }
9057 value_string_ext_free(vse);
9058 field_strings = NULL((void*)0);
9059 } else if (field_display == BASE_CUSTOM) {
9060 /* this will be a pointer to a function, don't free that */
9061 field_strings = NULL((void*)0);
9062 } else {
9063 value_string *vs = (value_string *)field_strings;
9064 while (vs->strptr) {
9065 g_free((char *)vs->strptr);
9066 vs++;
9067 }
9068 }
9069 break;
9070 default:
9071 break;
9072 }
9073 }
9074
9075 if (field_type != FT_FRAMENUM) {
9076 g_free((void *)field_strings);
9077 }
9078}
9079
9080static void
9081free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9082{
9083 header_field_info *hfi = (header_field_info *) data;
9084 int hf_id = hfi->id;
9085
9086 g_free((char *)hfi->name);
9087 g_free((char *)hfi->abbrev);
9088 g_free((char *)hfi->blurb);
9089
9090 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9091
9092 if (hfi->parent == -1)
9093 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)
;
9094
9095 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9096}
9097
9098static void
9099free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9100{
9101 g_free (data);
9102}
9103
9104static void
9105free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9106{
9107 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9108
9109 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9110 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)
;
9111}
9112
9113/* free deregistered fields and data */
9114void
9115proto_free_deregistered_fields (void)
9116{
9117 expert_free_deregistered_expertinfos();
9118
9119 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9120 g_ptr_array_free(deregistered_fields, true1);
9121 deregistered_fields = g_ptr_array_new();
9122
9123 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9124 g_ptr_array_free(deregistered_data, true1);
9125 deregistered_data = g_ptr_array_new();
9126
9127 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9128 g_ptr_array_free(deregistered_slice, true1);
9129 deregistered_slice = g_ptr_array_new();
9130}
9131
9132static const value_string hf_display[] = {
9133 { BASE_NONE, "BASE_NONE" },
9134 { BASE_DEC, "BASE_DEC" },
9135 { BASE_HEX, "BASE_HEX" },
9136 { BASE_OCT, "BASE_OCT" },
9137 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9138 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9139 { BASE_CUSTOM, "BASE_CUSTOM" },
9140 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9141 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9142 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9143 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9144 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9145 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9146 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9147 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9148 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9149 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9150 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9151 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9152 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9153 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9154 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9155 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9156 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9157 { BASE_PT_UDP, "BASE_PT_UDP" },
9158 { BASE_PT_TCP, "BASE_PT_TCP" },
9159 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9160 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9161 { BASE_OUI, "BASE_OUI" },
9162 { 0, NULL((void*)0) } };
9163
9164const char* proto_field_display_to_string(int field_display)
9165{
9166 return val_to_str_const(field_display, hf_display, "Unknown");
9167}
9168
9169static inline port_type
9170display_to_port_type(field_display_e e)
9171{
9172 switch (e) {
9173 case BASE_PT_UDP:
9174 return PT_UDP;
9175 case BASE_PT_TCP:
9176 return PT_TCP;
9177 case BASE_PT_DCCP:
9178 return PT_DCCP;
9179 case BASE_PT_SCTP:
9180 return PT_SCTP;
9181 default:
9182 break;
9183 }
9184 return PT_NONE;
9185}
9186
9187/* temporary function containing assert part for easier profiling */
9188static void
9189tmp_fld_check_assert(header_field_info *hfinfo)
9190{
9191 char* tmp_str;
9192
9193 /* The field must have a name (with length > 0) */
9194 if (!hfinfo->name || !hfinfo->name[0]) {
9195 if (hfinfo->abbrev)
9196 /* Try to identify the field */
9197 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)
9198 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9199 else
9200 /* Hum, no luck */
9201 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)"
)
;
9202 }
9203
9204 /* fields with an empty string for an abbreviation aren't filterable */
9205 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9206 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)
;
9207
9208 /* These types of fields are allowed to have value_strings,
9209 * true_false_strings or a protocol_t struct
9210 */
9211 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9212 switch (hfinfo->type) {
9213
9214 /*
9215 * These types are allowed to support display value_strings,
9216 * value64_strings, the extended versions of the previous
9217 * two, range strings, or unit strings.
9218 */
9219 case FT_CHAR:
9220 case FT_UINT8:
9221 case FT_UINT16:
9222 case FT_UINT24:
9223 case FT_UINT32:
9224 case FT_UINT40:
9225 case FT_UINT48:
9226 case FT_UINT56:
9227 case FT_UINT64:
9228 case FT_INT8:
9229 case FT_INT16:
9230 case FT_INT24:
9231 case FT_INT32:
9232 case FT_INT40:
9233 case FT_INT48:
9234 case FT_INT56:
9235 case FT_INT64:
9236 case FT_BOOLEAN:
9237 case FT_PROTOCOL:
9238 break;
9239
9240 /*
9241 * This is allowed to have a value of type
9242 * enum ft_framenum_type to indicate what relationship
9243 * the frame in question has to the frame in which
9244 * the field is put.
9245 */
9246 case FT_FRAMENUM:
9247 break;
9248
9249 /*
9250 * These types are allowed to support only unit strings.
9251 */
9252 case FT_FLOAT:
9253 case FT_DOUBLE:
9254 case FT_IEEE_11073_SFLOAT:
9255 case FT_IEEE_11073_FLOAT:
9256 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9257 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))
9258 " (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))
9259 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))
;
9260 }
9261 break;
9262
9263 /*
9264 * These types are allowed to support display
9265 * time_value_strings.
9266 */
9267 case FT_ABSOLUTE_TIME:
9268 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9269 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9270 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9271 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9272 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))
9273 " (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))
9274 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))
;
9275 }
9276 break;
9277
9278 /*
9279 * This type is only allowed to support a string if it's
9280 * a protocol (for pinos).
9281 */
9282 case FT_BYTES:
9283 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9284 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))
9285 " (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))
9286 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))
;
9287 }
9288 break;
9289
9290 default:
9291 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))
9292 " (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))
9293 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))
;
9294 }
9295 }
9296
9297 /* TODO: This check may slow down startup, and output quite a few warnings.
9298 It would be good to be able to enable this (and possibly other checks?)
9299 in non-release builds. */
9300#ifdef ENABLE_CHECK_FILTER
9301 /* Check for duplicate value_string values.
9302 There are lots that have the same value *and* string, so for now only
9303 report those that have same value but different string. */
9304 if ((hfinfo->strings != NULL((void*)0)) &&
9305 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9306 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9307 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9308 (
9309 (hfinfo->type == FT_CHAR) ||
9310 (hfinfo->type == FT_UINT8) ||
9311 (hfinfo->type == FT_UINT16) ||
9312 (hfinfo->type == FT_UINT24) ||
9313 (hfinfo->type == FT_UINT32) ||
9314 (hfinfo->type == FT_INT8) ||
9315 (hfinfo->type == FT_INT16) ||
9316 (hfinfo->type == FT_INT24) ||
9317 (hfinfo->type == FT_INT32) )) {
9318
9319 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9320 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9321 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9322 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9323 } else {
9324 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9325 CHECK_HF_VALUE(value_string, "u", start_values);
9326 }
9327 } else {
9328 const value_string *start_values = (const value_string*)hfinfo->strings;
9329 CHECK_HF_VALUE(value_string, "u", start_values);
9330 }
9331 }
9332
9333 if (hfinfo->type == FT_BOOLEAN) {
9334 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9335 if (tfs) {
9336 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9337 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"
, 9339, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9338 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9339, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9339 tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9339, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
;
9340 }
9341 }
9342 }
9343
9344 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9345 const range_string *rs = (const range_string*)(hfinfo->strings);
9346 if (rs) {
9347 const range_string *this_it = rs;
9348
9349 do {
9350 if (this_it->value_max < this_it->value_min) {
9351 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"
, 9355, __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)
9352 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9355, __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)
9353 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9355, __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)
9354 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9355, __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)
9355 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9355, __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)
;
9356 ++this_it;
9357 continue;
9358 }
9359
9360 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9361 /* Not OK if this one is completely hidden by an earlier one! */
9362 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9363 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"
, 9369, __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)
9364 "(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"
, 9369, __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)
9365 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9369, __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)
9366 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9369, __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)
9367 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9369, __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)
9368 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9369, __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)
9369 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9369, __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)
;
9370 }
9371 }
9372 ++this_it;
9373 } while (this_it->strptr);
9374 }
9375 }
9376#endif
9377
9378 switch (hfinfo->type) {
9379
9380 case FT_CHAR:
9381 /* Require the char type to have BASE_HEX, BASE_OCT,
9382 * BASE_CUSTOM, or BASE_NONE as its base.
9383 *
9384 * If the display value is BASE_NONE and there is a
9385 * strings conversion then the dissector writer is
9386 * telling us that the field's numerical value is
9387 * meaningless; we'll avoid showing the value to the
9388 * user.
9389 */
9390 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9391 case BASE_HEX:
9392 case BASE_OCT:
9393 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9394 break;
9395 case BASE_NONE:
9396 if (hfinfo->strings == NULL((void*)0))
9397 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
))
9398 " 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
))
9399 " 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
))
9400 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
))
9401 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
))
;
9402 break;
9403 default:
9404 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9405 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)
9406 " 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)
9407 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)
9408 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)
;
9409 //wmem_free(NULL, tmp_str);
9410 }
9411 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9412 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
))
9413 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
))
9414 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
))
;
9415 }
9416 break;
9417 case FT_INT8:
9418 case FT_INT16:
9419 case FT_INT24:
9420 case FT_INT32:
9421 case FT_INT40:
9422 case FT_INT48:
9423 case FT_INT56:
9424 case FT_INT64:
9425 /* Hexadecimal and octal are, in printf() and everywhere
9426 * else, unsigned so don't allow dissectors to register a
9427 * signed field to be displayed unsigned. (Else how would
9428 * we display negative values?)
9429 */
9430 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9431 case BASE_HEX:
9432 case BASE_OCT:
9433 case BASE_DEC_HEX:
9434 case BASE_HEX_DEC:
9435 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9436 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)
9437 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)
9438 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)
;
9439 //wmem_free(NULL, tmp_str);
9440 }
9441 /* FALL THROUGH */
9442 case FT_UINT8:
9443 case FT_UINT16:
9444 case FT_UINT24:
9445 case FT_UINT32:
9446 case FT_UINT40:
9447 case FT_UINT48:
9448 case FT_UINT56:
9449 case FT_UINT64:
9450 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
))
) {
9451 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9452 if (hfinfo->type != FT_UINT16) {
9453 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))
9454 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))
9455 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))
;
9456 }
9457 if (hfinfo->strings != NULL((void*)0)) {
9458 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)
9459 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)
9460 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)
;
9461 }
9462 if (hfinfo->bitmask != 0) {
9463 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)
9464 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)
9465 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)
;
9466 }
9467 wmem_free(NULL((void*)0), tmp_str);
9468 break;
9469 }
9470
9471 if (hfinfo->display == BASE_OUI) {
9472 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9473 if (hfinfo->type != FT_UINT24) {
9474 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))
9475 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))
9476 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))
;
9477 }
9478 if (hfinfo->strings != NULL((void*)0)) {
9479 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)
9480 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)
9481 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)
;
9482 }
9483 if (hfinfo->bitmask != 0) {
9484 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)
9485 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)
9486 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)
;
9487 }
9488 wmem_free(NULL((void*)0), tmp_str);
9489 break;
9490 }
9491
9492 /* Require integral types (other than frame number,
9493 * which is always displayed in decimal) to have a
9494 * number base.
9495 *
9496 * If the display value is BASE_NONE and there is a
9497 * strings conversion then the dissector writer is
9498 * telling us that the field's numerical value is
9499 * meaningless; we'll avoid showing the value to the
9500 * user.
9501 */
9502 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9503 case BASE_DEC:
9504 case BASE_HEX:
9505 case BASE_OCT:
9506 case BASE_DEC_HEX:
9507 case BASE_HEX_DEC:
9508 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9509 break;
9510 case BASE_NONE:
9511 if (hfinfo->strings == NULL((void*)0)) {
9512 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
))
9513 " 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
))
9514 " 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
))
9515 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
))
9516 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
))
;
9517 }
9518 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9519 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
))
9520 " 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
))
9521 " 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
))
9522 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
))
9523 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
))
;
9524 }
9525 break;
9526
9527 default:
9528 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9529 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)
9530 " 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)
9531 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)
9532 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)
;
9533 //wmem_free(NULL, tmp_str);
9534 }
9535 break;
9536 case FT_BYTES:
9537 case FT_UINT_BYTES:
9538 /* Require bytes to have a "display type" that could
9539 * add a character between displayed bytes.
9540 */
9541 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9542 case BASE_NONE:
9543 case SEP_DOT:
9544 case SEP_DASH:
9545 case SEP_COLON:
9546 case SEP_SPACE:
9547 break;
9548 default:
9549 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9550 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)
9551 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)
;
9552 //wmem_free(NULL, tmp_str);
9553 }
9554 if (hfinfo->bitmask != 0)
9555 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
))
9556 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
))
9557 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
))
;
9558 //allowed to support string if its a protocol (for pinos)
9559 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9560 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
))
9561 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
))
9562 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
))
;
9563 break;
9564
9565 case FT_PROTOCOL:
9566 case FT_FRAMENUM:
9567 if (hfinfo->display != BASE_NONE) {
9568 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9569 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)
9570 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)
9571 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)
;
9572 //wmem_free(NULL, tmp_str);
9573 }
9574 if (hfinfo->bitmask != 0)
9575 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
))
9576 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
))
9577 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
))
;
9578 break;
9579
9580 case FT_BOOLEAN:
9581 break;
9582
9583 case FT_ABSOLUTE_TIME:
9584 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9585 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9586 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)
9587 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)
;
9588 //wmem_free(NULL, tmp_str);
9589 }
9590 if (hfinfo->bitmask != 0)
9591 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
))
9592 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
))
9593 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
))
;
9594 break;
9595
9596 case FT_STRING:
9597 case FT_STRINGZ:
9598 case FT_UINT_STRING:
9599 case FT_STRINGZPAD:
9600 case FT_STRINGZTRUNC:
9601 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9602 case BASE_NONE:
9603 case BASE_STR_WSP:
9604 break;
9605
9606 default:
9607 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9608 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)
9609 " 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)
9610 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)
9611 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)
;
9612 //wmem_free(NULL, tmp_str);
9613 }
9614
9615 if (hfinfo->bitmask != 0)
9616 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
))
9617 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
))
9618 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
))
;
9619 if (hfinfo->strings != NULL((void*)0))
9620 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
))
9621 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
))
9622 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
))
;
9623 break;
9624
9625 case FT_IPv4:
9626 switch (hfinfo->display) {
9627 case BASE_NONE:
9628 case BASE_NETMASK:
9629 break;
9630
9631 default:
9632 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9633 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)
9634 " 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)
9635 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)
9636 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)
;
9637 //wmem_free(NULL, tmp_str);
9638 break;
9639 }
9640 break;
9641 case FT_FLOAT:
9642 case FT_DOUBLE:
9643 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9644 case BASE_NONE:
9645 case BASE_DEC:
9646 case BASE_HEX:
9647 case BASE_EXP:
9648 case BASE_CUSTOM:
9649 break;
9650 default:
9651 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9652 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)
9653 " 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)
9654 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)
9655 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)
;
9656 //wmem_free(NULL, tmp_str);
9657 }
9658 if (hfinfo->bitmask != 0)
9659 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
))
9660 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
))
9661 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
))
;
9662 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9663 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
))
9664 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
))
9665 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
))
;
9666 break;
9667 case FT_IEEE_11073_SFLOAT:
9668 case FT_IEEE_11073_FLOAT:
9669 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9670 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9671 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)
9672 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)
9673 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)
9674 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)
;
9675 //wmem_free(NULL, tmp_str);
9676 }
9677 if (hfinfo->bitmask != 0)
9678 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
))
9679 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
))
9680 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
))
;
9681 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9682 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
))
9683 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
))
9684 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
))
;
9685 break;
9686 default:
9687 if (hfinfo->display != BASE_NONE) {
9688 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9689 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)
9690 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)
9691 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)
9692 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)
;
9693 //wmem_free(NULL, tmp_str);
9694 }
9695 if (hfinfo->bitmask != 0)
9696 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
))
9697 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
))
9698 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
))
;
9699 if (hfinfo->strings != NULL((void*)0))
9700 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
))
9701 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
))
9702 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
))
;
9703 break;
9704 }
9705}
9706
9707static void
9708register_type_length_mismatch(void)
9709{
9710 static ei_register_info ei[] = {
9711 { &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)}}
}},
9712 { &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)}}
}},
9713 };
9714
9715 expert_module_t* expert_type_length_mismatch;
9716
9717 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9718
9719 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9720 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9721
9722 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9723 disabling them makes no sense. */
9724 proto_set_cant_toggle(proto_type_length_mismatch);
9725}
9726
9727static void
9728register_byte_array_string_decodinws_error(void)
9729{
9730 static ei_register_info ei[] = {
9731 { &ei_byte_array_string_decoding_failed_error,
9732 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9733 "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)}}
9734 }
9735 },
9736 };
9737
9738 expert_module_t* expert_byte_array_string_decoding_error;
9739
9740 proto_byte_array_string_decoding_error =
9741 proto_register_protocol("Byte Array-String Decoding Error",
9742 "Byte Array-string decoding error",
9743 "_ws.byte_array_string.decoding_error");
9744
9745 expert_byte_array_string_decoding_error =
9746 expert_register_protocol(proto_byte_array_string_decoding_error);
9747 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9748
9749 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9750 disabling them makes no sense. */
9751 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9752}
9753
9754static void
9755register_date_time_string_decodinws_error(void)
9756{
9757 static ei_register_info ei[] = {
9758 { &ei_date_time_string_decoding_failed_error,
9759 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9760 "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)}}
9761 }
9762 },
9763 };
9764
9765 expert_module_t* expert_date_time_string_decoding_error;
9766
9767 proto_date_time_string_decoding_error =
9768 proto_register_protocol("Date and Time-String Decoding Error",
9769 "Date and Time-string decoding error",
9770 "_ws.date_time_string.decoding_error");
9771
9772 expert_date_time_string_decoding_error =
9773 expert_register_protocol(proto_date_time_string_decoding_error);
9774 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9775
9776 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9777 disabling them makes no sense. */
9778 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9779}
9780
9781static void
9782register_string_errors(void)
9783{
9784 static ei_register_info ei[] = {
9785 { &ei_string_trailing_characters,
9786 { "_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)}}
}
9787 },
9788 };
9789
9790 expert_module_t* expert_string_errors;
9791
9792 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9793
9794 expert_string_errors = expert_register_protocol(proto_string_errors);
9795 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9796
9797 /* "String Errors" isn't really a protocol, it's an error indication;
9798 disabling them makes no sense. */
9799 proto_set_cant_toggle(proto_string_errors);
9800}
9801
9802static int
9803proto_register_field_init(header_field_info *hfinfo, const int parent)
9804{
9805
9806 tmp_fld_check_assert(hfinfo);
9807
9808 hfinfo->parent = parent;
9809 hfinfo->same_name_next = NULL((void*)0);
9810 hfinfo->same_name_prev_id = -1;
9811
9812 /* if we always add and never delete, then id == len - 1 is correct */
9813 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9814 if (!gpa_hfinfo.hfi) {
9815 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9816 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9817 /* The entry with index 0 is not used. */
9818 gpa_hfinfo.hfi[0] = NULL((void*)0);
9819 gpa_hfinfo.len = 1;
9820 } else {
9821 gpa_hfinfo.allocated_len += 1000;
9822 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9823 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9824 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9825 }
9826 }
9827 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9828 gpa_hfinfo.len++;
9829 hfinfo->id = gpa_hfinfo.len - 1;
9830
9831 /* if we have real names, enter this field in the name tree */
9832 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
9833
9834 header_field_info *same_name_next_hfinfo;
9835 unsigned char c;
9836
9837 /* Check that the filter name (abbreviation) is legal;
9838 * it must contain only alphanumerics, '-', "_", and ".". */
9839 c = proto_check_field_name(hfinfo->abbrev);
9840 if (c) {
9841 if (c == '.') {
9842 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)
;
9843 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9844 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)
;
9845 } else {
9846 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)
;
9847 }
9848 }
9849
9850 /* We allow multiple hfinfo's to be registered under the same
9851 * abbreviation. This was done for X.25, as, depending
9852 * on whether it's modulo-8 or modulo-128 operation,
9853 * some bitfield fields may be in different bits of
9854 * a byte, and we want to be able to refer to that field
9855 * with one name regardless of whether the packets
9856 * are modulo-8 or modulo-128 packets. */
9857
9858 /* wmem_map_insert - if key is already present the previous
9859 * hfinfo with the same key/name is returned, otherwise NULL */
9860 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9861 if (same_name_hfinfo) {
9862 /* There's already a field with this name.
9863 * Put the current field *before* that field
9864 * in the list of fields with this name, Thus,
9865 * we end up with an effectively
9866 * doubly-linked-list of same-named hfinfo's,
9867 * with the head of the list (stored in the
9868 * hash) being the last seen hfinfo.
9869 */
9870 same_name_next_hfinfo =
9871 same_name_hfinfo->same_name_next;
9872
9873 hfinfo->same_name_next = same_name_next_hfinfo;
9874 if (same_name_next_hfinfo)
9875 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9876
9877 same_name_hfinfo->same_name_next = hfinfo;
9878 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9879#ifdef ENABLE_CHECK_FILTER
9880 while (same_name_hfinfo) {
9881 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9882 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"
, 9882, __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)
;
9883 same_name_hfinfo = same_name_hfinfo->same_name_next;
9884 }
9885#endif
9886 }
9887 }
9888
9889 return hfinfo->id;
9890}
9891
9892void
9893proto_register_subtree_array(int * const *indices, const int num_indices)
9894{
9895 int i;
9896 int *const *ptr = indices;
9897
9898 /*
9899 * If we've already allocated the array of tree types, expand
9900 * it; this lets plugins such as mate add tree types after
9901 * the initial startup. (If we haven't already allocated it,
9902 * we don't allocate it; on the first pass, we just assign
9903 * ett values and keep track of how many we've assigned, and
9904 * when we're finished registering all dissectors we allocate
9905 * the array, so that we do only one allocation rather than
9906 * wasting CPU time and memory by growing the array for each
9907 * dissector that registers ett values.)
9908 */
9909 if (tree_is_expanded != NULL((void*)0)) {
9910 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9911
9912 /* set new items to 0 */
9913 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9914 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9915 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9916 }
9917
9918 /*
9919 * Assign "num_indices" subtree numbers starting at "num_tree_types",
9920 * returning the indices through the pointers in the array whose
9921 * first element is pointed to by "indices", and update
9922 * "num_tree_types" appropriately.
9923 */
9924 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9925 if (**ptr != -1 && **ptr != 0) {
9926 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.")
9927 " 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.")
9928 " 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.")
9929 " 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.")
;
9930 }
9931 **ptr = num_tree_types;
9932 }
9933}
9934
9935static void
9936mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
9937{
9938 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
9939 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
9940 char *last_char;
9941
9942 /* ..... field_name: dataaaaaaaaaaaaa
9943 * |
9944 * ^^^^^ name_pos
9945 *
9946 * ..... field_name […]: dataaaaaaaaaaaaa
9947 *
9948 * name_pos==0 means that we have only data or only a field_name
9949 */
9950
9951 ws_assert(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9951, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
9952
9953 if (name_pos >= size - trunc_len) {
9954 /* No room for trunc_str after the field_name, put it first. */
9955 name_pos = 0;
9956 }
9957
9958 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
9959 if (name_pos == 0) {
9960 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
9961 memcpy(label_str, trunc_str + 1, trunc_len);
9962 } else {
9963 memcpy(label_str + name_pos, trunc_str, trunc_len);
9964 }
9965 /* in general, label_str is UTF-8
9966 we can truncate it only at the beginning of a new character
9967 we go backwards from the byte right after our buffer and
9968 find the next starting byte of a UTF-8 character, this is
9969 where we cut
9970 there's no need to use g_utf8_find_prev_char(), the search
9971 will always succeed since we copied trunc_str into the
9972 buffer */
9973 /* g_utf8_prev_char does not deference the memory address
9974 * passed in (until after decrementing it, so it is perfectly
9975 * legal to pass in a pointer one past the last element.
9976 */
9977 last_char = g_utf8_prev_char(label_str + size);
9978 *last_char = '\0';
9979
9980 if (value_pos && *value_pos > 0) {
9981 if (name_pos == 0) {
9982 *value_pos += trunc_len;
9983 } else {
9984 /* Move one back to include trunc_str in the value. */
9985 *value_pos -= 1;
9986 }
9987 }
9988
9989 /* Check if value_pos is past label_str. */
9990 if (value_pos && *value_pos >= size) {
9991 *value_pos = size - 1;
9992 }
9993}
9994
9995static void
9996label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
9997{
9998 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
9999}
10000
10001static size_t
10002label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10003{
10004 size_t name_pos;
10005
10006 /* "%s: %s", hfinfo->name, text */
10007 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10008 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10009 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10010 if (value_pos) {
10011 *value_pos = pos;
10012 }
10013 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, text ? text : "(null)", label_strcat_flags(hfinfo));
10014 }
10015
10016 if (pos >= ITEM_LABEL_LENGTH240) {
10017 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10018 label_mark_truncated(label_str, name_pos, value_pos);
10019 }
10020
10021 return pos;
10022}
10023
10024static size_t
10025label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10026{
10027 size_t name_pos;
10028
10029 /* "%s: %s (%s)", hfinfo->name, text, descr */
10030 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10031 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10032 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10033 if (value_pos) {
10034 *value_pos = pos;
10035 }
10036 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10037 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10038 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10039 } else {
10040 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10041 pos = label_concat(label_str, pos, " (")ws_label_strcpy(label_str, 240, pos, " (", 0);
10042 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10043 pos = label_concat(label_str, pos, ")")ws_label_strcpy(label_str, 240, pos, ")", 0);
10044 }
10045 }
10046
10047 if (pos >= ITEM_LABEL_LENGTH240) {
10048 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10049 label_mark_truncated(label_str, name_pos, value_pos);
10050 }
10051
10052 return pos;
10053}
10054
10055void
10056proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10057{
10058 const header_field_info *hfinfo;
10059 const char *str;
10060 const uint8_t *bytes;
10061 uint32_t integer;
10062 const ipv4_addr_and_mask *ipv4;
10063 const ipv6_addr_and_prefix *ipv6;
10064 const e_guid_t *guid;
10065 char *name;
10066 address addr;
10067 char *addr_str;
10068 char *tmp;
10069
10070 if (!label_str) {
10071 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10071, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10072 return;
10073 }
10074
10075 label_str[0]= '\0';
10076
10077 if (!fi) {
10078 return;
10079 }
10080
10081 hfinfo = fi->hfinfo;
10082
10083 switch (hfinfo->type) {
10084 case FT_NONE:
10085 case FT_PROTOCOL:
10086 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10087 if (value_pos) {
10088 *value_pos = strlen(hfinfo->name);
10089 }
10090 break;
10091
10092 case FT_BOOLEAN:
10093 fill_label_boolean(fi, label_str, value_pos);
10094 break;
10095
10096 case FT_BYTES:
10097 case FT_UINT_BYTES:
10098 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10099 fvalue_get_bytes_data(fi->value),
10100 (unsigned)fvalue_length2(fi->value));
10101 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10102 wmem_free(NULL((void*)0), tmp);
10103 break;
10104
10105 case FT_CHAR:
10106 if (hfinfo->bitmask) {
10107 fill_label_bitfield_char(fi, label_str, value_pos);
10108 } else {
10109 fill_label_char(fi, label_str, value_pos);
10110 }
10111 break;
10112
10113 /* Four types of integers to take care of:
10114 * Bitfield, with val_string
10115 * Bitfield, w/o val_string
10116 * Non-bitfield, with val_string
10117 * Non-bitfield, w/o val_string
10118 */
10119 case FT_UINT8:
10120 case FT_UINT16:
10121 case FT_UINT24:
10122 case FT_UINT32:
10123 if (hfinfo->bitmask) {
10124 fill_label_bitfield(fi, label_str, value_pos, false0);
10125 } else {
10126 fill_label_number(fi, label_str, value_pos, false0);
10127 }
10128 break;
10129
10130 case FT_FRAMENUM:
10131 fill_label_number(fi, label_str, value_pos, false0);
10132 break;
10133
10134 case FT_UINT40:
10135 case FT_UINT48:
10136 case FT_UINT56:
10137 case FT_UINT64:
10138 if (hfinfo->bitmask) {
10139 fill_label_bitfield64(fi, label_str, value_pos, false0);
10140 } else {
10141 fill_label_number64(fi, label_str, value_pos, false0);
10142 }
10143 break;
10144
10145 case FT_INT8:
10146 case FT_INT16:
10147 case FT_INT24:
10148 case FT_INT32:
10149 if (hfinfo->bitmask) {
10150 fill_label_bitfield(fi, label_str, value_pos, true1);
10151 } else {
10152 fill_label_number(fi, label_str, value_pos, true1);
10153 }
10154 break;
10155
10156 case FT_INT40:
10157 case FT_INT48:
10158 case FT_INT56:
10159 case FT_INT64:
10160 if (hfinfo->bitmask) {
10161 fill_label_bitfield64(fi, label_str, value_pos, true1);
10162 } else {
10163 fill_label_number64(fi, label_str, value_pos, true1);
10164 }
10165 break;
10166
10167 case FT_FLOAT:
10168 case FT_DOUBLE:
10169 fill_label_float(fi, label_str, value_pos);
10170 break;
10171
10172 case FT_ABSOLUTE_TIME:
10173 {
10174 const nstime_t *value = fvalue_get_time(fi->value);
10175 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10176 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10177 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10178 }
10179 if (hfinfo->strings) {
10180 /*
10181 * Table of time valus to be displayed
10182 * specially.
10183 */
10184 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10185 if (time_string != NULL((void*)0)) {
10186 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10187 break;
10188 }
10189 }
10190 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10191 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10192 wmem_free(NULL((void*)0), tmp);
10193 break;
10194 }
10195 case FT_RELATIVE_TIME:
10196 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10197 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10198 wmem_free(NULL((void*)0), tmp);
10199 break;
10200
10201 case FT_IPXNET:
10202 integer = fvalue_get_uinteger(fi->value);
10203 tmp = get_ipxnet_name(NULL((void*)0), integer);
10204 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10205 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10206 wmem_free(NULL((void*)0), tmp);
10207 wmem_free(NULL((void*)0), addr_str);
10208 break;
10209
10210 case FT_VINES:
10211 addr.type = AT_VINES;
10212 addr.len = VINES_ADDR_LEN6;
10213 addr.data = fvalue_get_bytes_data(fi->value);
10214
10215 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10216 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10217 wmem_free(NULL((void*)0), addr_str);
10218 break;
10219
10220 case FT_ETHER:
10221 bytes = fvalue_get_bytes_data(fi->value);
10222
10223 addr.type = AT_ETHER;
10224 addr.len = 6;
10225 addr.data = bytes;
10226
10227 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10228 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10229 wmem_free(NULL((void*)0), addr_str);
10230 break;
10231
10232 case FT_IPv4:
10233 ipv4 = fvalue_get_ipv4(fi->value);
10234 set_address_ipv4(&addr, ipv4);
10235
10236 if (hfinfo->display == BASE_NETMASK) {
10237 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10238 } else {
10239 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10240 }
10241 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10242 wmem_free(NULL((void*)0), addr_str);
10243 free_address(&addr);
10244 break;
10245
10246 case FT_IPv6:
10247 ipv6 = fvalue_get_ipv6(fi->value);
10248 set_address_ipv6(&addr, ipv6);
10249
10250 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10251 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10252 wmem_free(NULL((void*)0), addr_str);
10253 free_address(&addr);
10254 break;
10255
10256 case FT_FCWWN:
10257 bytes = fvalue_get_bytes_data(fi->value);
10258 addr.type = AT_FCWWN;
10259 addr.len = FCWWN_ADDR_LEN8;
10260 addr.data = bytes;
10261
10262 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10263 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10264 wmem_free(NULL((void*)0), addr_str);
10265 break;
10266
10267 case FT_GUID:
10268 guid = fvalue_get_guid(fi->value);
10269 tmp = guid_to_str(NULL((void*)0), guid);
10270 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10271 wmem_free(NULL((void*)0), tmp);
10272 break;
10273
10274 case FT_OID:
10275 bytes = fvalue_get_bytes_data(fi->value);
10276 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10277 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10278 if (name) {
10279 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10280 wmem_free(NULL((void*)0), name);
10281 } else {
10282 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10283 }
10284 wmem_free(NULL((void*)0), tmp);
10285 break;
10286
10287 case FT_REL_OID:
10288 bytes = fvalue_get_bytes_data(fi->value);
10289 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10290 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10291 if (name) {
10292 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10293 wmem_free(NULL((void*)0), name);
10294 } else {
10295 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10296 }
10297 wmem_free(NULL((void*)0), tmp);
10298 break;
10299
10300 case FT_SYSTEM_ID:
10301 bytes = fvalue_get_bytes_data(fi->value);
10302 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10303 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10304 wmem_free(NULL((void*)0), tmp);
10305 break;
10306
10307 case FT_EUI64:
10308 bytes = fvalue_get_bytes_data(fi->value);
10309 addr.type = AT_EUI64;
10310 addr.len = EUI64_ADDR_LEN8;
10311 addr.data = bytes;
10312
10313 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10314 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10315 wmem_free(NULL((void*)0), addr_str);
10316 break;
10317 case FT_STRING:
10318 case FT_STRINGZ:
10319 case FT_UINT_STRING:
10320 case FT_STRINGZPAD:
10321 case FT_STRINGZTRUNC:
10322 case FT_AX25:
10323 str = fvalue_get_string(fi->value);
10324 label_fill(label_str, 0, hfinfo, str, value_pos);
10325 break;
10326
10327 case FT_IEEE_11073_SFLOAT:
10328 case FT_IEEE_11073_FLOAT:
10329 fill_label_ieee_11073_float(fi, label_str, value_pos);
10330 break;
10331
10332 default:
10333 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
))
10334 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
))
10335 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
))
10336 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
))
;
10337 break;
10338 }
10339}
10340
10341static void
10342fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10343{
10344 char *p;
10345 int bitfield_byte_length = 0, bitwidth;
10346 uint64_t unshifted_value;
10347 uint64_t value;
10348
10349 const header_field_info *hfinfo = fi->hfinfo;
10350
10351 value = fvalue_get_uinteger64(fi->value);
10352 if (hfinfo->bitmask) {
10353 /* Figure out the bit width */
10354 bitwidth = hfinfo_container_bitwidth(hfinfo);
10355
10356 /* Un-shift bits */
10357 unshifted_value = value;
10358 unshifted_value <<= hfinfo_bitshift(hfinfo);
10359
10360 /* Create the bitfield first */
10361 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10362 bitfield_byte_length = (int) (p - label_str);
10363 }
10364
10365 /* Fill in the textual info */
10366 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10367}
10368
10369static const char *
10370hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10371{
10372 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10373 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10374
10375 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10376 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10377 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10378 else
10379 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10380 }
10381
10382 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10383 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10384
10385 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10386 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10387
10388 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10389}
10390
10391static const char *
10392hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10393{
10394 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10395 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10396 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10397 else
10398 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10399 }
10400
10401 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10402 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10403
10404 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10405 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10406
10407 /* If this is reached somebody registered a 64-bit field with a 32-bit
10408 * value-string, which isn't right. */
10409 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)
10410 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10411
10412 /* This is necessary to squelch MSVC errors; is there
10413 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10414 never returns? */
10415 return NULL((void*)0);
10416}
10417
10418static const char *
10419hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10420{
10421 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10422 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10423
10424 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)
;
10425
10426 /* This is necessary to squelch MSVC errors; is there
10427 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10428 never returns? */
10429 return NULL((void*)0);
10430}
10431
10432static const char *
10433hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10434{
10435 const char *str = hf_try_val_to_str(value, hfinfo);
10436
10437 return (str) ? str : unknown_str;
10438}
10439
10440static const char *
10441hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10442{
10443 const char *str = hf_try_val64_to_str(value, hfinfo);
10444
10445 return (str) ? str : unknown_str;
10446}
10447
10448/* Fills data for bitfield chars with val_strings */
10449static void
10450fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10451{
10452 char *p;
10453 int bitfield_byte_length, bitwidth;
10454 uint32_t unshifted_value;
10455 uint32_t value;
10456
10457 char buf[32];
10458 const char *out;
10459
10460 const header_field_info *hfinfo = fi->hfinfo;
10461
10462 /* Figure out the bit width */
10463 bitwidth = hfinfo_container_bitwidth(hfinfo);
10464
10465 /* Un-shift bits */
10466 value = fvalue_get_uinteger(fi->value);
10467
10468 unshifted_value = value;
10469 if (hfinfo->bitmask) {
10470 unshifted_value <<= hfinfo_bitshift(hfinfo);
10471 }
10472
10473 /* Create the bitfield first */
10474 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10475 bitfield_byte_length = (int) (p - label_str);
10476
10477 /* Fill in the textual info using stored (shifted) value */
10478 if (hfinfo->display == BASE_CUSTOM) {
10479 char tmp[ITEM_LABEL_LENGTH240];
10480 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10481
10482 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10482, "fmtfunc"))))
;
10483 fmtfunc(tmp, value);
10484 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10485 }
10486 else if (hfinfo->strings) {
10487 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10488
10489 out = hfinfo_char_vals_format(hfinfo, buf, value);
10490 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10491 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10492 else
10493 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10494 }
10495 else {
10496 out = hfinfo_char_value_format(hfinfo, buf, value);
10497
10498 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10499 }
10500}
10501
10502/* Fills data for bitfield ints with val_strings */
10503static void
10504fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10505{
10506 char *p;
10507 int bitfield_byte_length, bitwidth;
10508 uint32_t value, unshifted_value;
10509 char buf[NUMBER_LABEL_LENGTH80];
10510 const char *out;
10511
10512 const header_field_info *hfinfo = fi->hfinfo;
10513
10514 /* Figure out the bit width */
10515 if (fi->flags & FI_VARINT0x00040000)
10516 bitwidth = fi->length*8;
10517 else
10518 bitwidth = hfinfo_container_bitwidth(hfinfo);
10519
10520 /* Un-shift bits */
10521 if (is_signed)
10522 value = fvalue_get_sinteger(fi->value);
10523 else
10524 value = fvalue_get_uinteger(fi->value);
10525
10526 unshifted_value = value;
10527 if (hfinfo->bitmask) {
10528 unshifted_value <<= hfinfo_bitshift(hfinfo);
10529 }
10530
10531 /* Create the bitfield first */
10532 if (fi->flags & FI_VARINT0x00040000)
10533 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10534 else
10535 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10536 bitfield_byte_length = (int) (p - label_str);
10537
10538 /* Fill in the textual info using stored (shifted) value */
10539 if (hfinfo->display == BASE_CUSTOM) {
10540 char tmp[ITEM_LABEL_LENGTH240];
10541 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10542
10543 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10543, "fmtfunc"))))
;
10544 fmtfunc(tmp, value);
10545 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10546 }
10547 else if (hfinfo->strings) {
10548 const char *val_str = hf_try_val_to_str(value, hfinfo);
10549
10550 out = hfinfo_number_vals_format(hfinfo, buf, value);
10551 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10552 /*
10553 * Unique values only display value_string string
10554 * if there is a match. Otherwise it's just a number
10555 */
10556 if (val_str) {
10557 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10558 } else {
10559 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10560 }
10561 } else {
10562 if (val_str == NULL((void*)0))
10563 val_str = "Unknown";
10564
10565 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10566 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10567 else
10568 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10569 }
10570 }
10571 else {
10572 out = hfinfo_number_value_format(hfinfo, buf, value);
10573
10574 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10575 }
10576}
10577
10578static void
10579fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10580{
10581 char *p;
10582 int bitfield_byte_length, bitwidth;
10583 uint64_t value, unshifted_value;
10584 char buf[NUMBER_LABEL_LENGTH80];
10585 const char *out;
10586
10587 const header_field_info *hfinfo = fi->hfinfo;
10588
10589 /* Figure out the bit width */
10590 if (fi->flags & FI_VARINT0x00040000)
10591 bitwidth = fi->length*8;
10592 else
10593 bitwidth = hfinfo_container_bitwidth(hfinfo);
10594
10595 /* Un-shift bits */
10596 if (is_signed)
10597 value = fvalue_get_sinteger64(fi->value);
10598 else
10599 value = fvalue_get_uinteger64(fi->value);
10600
10601 unshifted_value = value;
10602 if (hfinfo->bitmask) {
10603 unshifted_value <<= hfinfo_bitshift(hfinfo);
10604 }
10605
10606 /* Create the bitfield first */
10607 if (fi->flags & FI_VARINT0x00040000)
10608 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10609 else
10610 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10611 bitfield_byte_length = (int) (p - label_str);
10612
10613 /* Fill in the textual info using stored (shifted) value */
10614 if (hfinfo->display == BASE_CUSTOM) {
10615 char tmp[ITEM_LABEL_LENGTH240];
10616 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10617
10618 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10618, "fmtfunc64"
))))
;
10619 fmtfunc64(tmp, value);
10620 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10621 }
10622 else if (hfinfo->strings) {
10623 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10624
10625 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10626 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10627 /*
10628 * Unique values only display value_string string
10629 * if there is a match. Otherwise it's just a number
10630 */
10631 if (val_str) {
10632 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10633 } else {
10634 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10635 }
10636 } else {
10637 if (val_str == NULL((void*)0))
10638 val_str = "Unknown";
10639
10640 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10641 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10642 else
10643 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10644 }
10645 }
10646 else {
10647 out = hfinfo_number_value_format64(hfinfo, buf, value);
10648
10649 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10650 }
10651}
10652
10653static void
10654fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10655{
10656 const header_field_info *hfinfo = fi->hfinfo;
10657 uint32_t value;
10658
10659 char buf[32];
10660 const char *out;
10661
10662 value = fvalue_get_uinteger(fi->value);
10663
10664 /* Fill in the textual info */
10665 if (hfinfo->display == BASE_CUSTOM) {
10666 char tmp[ITEM_LABEL_LENGTH240];
10667 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10668
10669 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10669, "fmtfunc"))))
;
10670 fmtfunc(tmp, value);
10671 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10672 }
10673 else if (hfinfo->strings) {
10674 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10675
10676 out = hfinfo_char_vals_format(hfinfo, buf, value);
10677 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10678 }
10679 else {
10680 out = hfinfo_char_value_format(hfinfo, buf, value);
10681
10682 label_fill(label_str, 0, hfinfo, out, value_pos);
10683 }
10684}
10685
10686static void
10687fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10688{
10689 const header_field_info *hfinfo = fi->hfinfo;
10690 uint32_t value;
10691
10692 char buf[NUMBER_LABEL_LENGTH80];
10693 const char *out;
10694
10695 if (is_signed)
10696 value = fvalue_get_sinteger(fi->value);
10697 else
10698 value = fvalue_get_uinteger(fi->value);
10699
10700 /* Fill in the textual info */
10701 if (hfinfo->display == BASE_CUSTOM) {
10702 char tmp[ITEM_LABEL_LENGTH240];
10703 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10704
10705 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10705, "fmtfunc"))))
;
10706 fmtfunc(tmp, value);
10707 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10708 }
10709 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10710 /*
10711 * It makes no sense to have a value-string table for a
10712 * frame-number field - they're just integers giving
10713 * the ordinal frame number.
10714 */
10715 const char *val_str = hf_try_val_to_str(value, hfinfo);
10716
10717 out = hfinfo_number_vals_format(hfinfo, buf, value);
10718 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10719 /*
10720 * Unique values only display value_string string
10721 * if there is a match. Otherwise it's just a number
10722 */
10723 if (val_str) {
10724 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10725 } else {
10726 label_fill(label_str, 0, hfinfo, out, value_pos);
10727 }
10728 } else {
10729 if (val_str == NULL((void*)0))
10730 val_str = "Unknown";
10731
10732 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10733 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10734 else
10735 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10736 }
10737 }
10738 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
))
) {
10739 char tmp[ITEM_LABEL_LENGTH240];
10740
10741 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10742 display_to_port_type((field_display_e)hfinfo->display), value);
10743 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10744 }
10745 else {
10746 out = hfinfo_number_value_format(hfinfo, buf, value);
10747
10748 label_fill(label_str, 0, hfinfo, out, value_pos);
10749 }
10750}
10751
10752static void
10753fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10754{
10755 const header_field_info *hfinfo = fi->hfinfo;
10756 uint64_t value;
10757
10758 char buf[NUMBER_LABEL_LENGTH80];
10759 const char *out;
10760
10761 if (is_signed)
10762 value = fvalue_get_sinteger64(fi->value);
10763 else
10764 value = fvalue_get_uinteger64(fi->value);
10765
10766 /* Fill in the textual info */
10767 if (hfinfo->display == BASE_CUSTOM) {
10768 char tmp[ITEM_LABEL_LENGTH240];
10769 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10770
10771 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10771, "fmtfunc64"
))))
;
10772 fmtfunc64(tmp, value);
10773 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10774 }
10775 else if (hfinfo->strings) {
10776 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10777
10778 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10779 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10780 /*
10781 * Unique values only display value_string string
10782 * if there is a match. Otherwise it's just a number
10783 */
10784 if (val_str) {
10785 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10786 } else {
10787 label_fill(label_str, 0, hfinfo, out, value_pos);
10788 }
10789 } else {
10790 if (val_str == NULL((void*)0))
10791 val_str = "Unknown";
10792
10793 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10794 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10795 else
10796 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10797 }
10798 }
10799 else {
10800 out = hfinfo_number_value_format64(hfinfo, buf, value);
10801
10802 label_fill(label_str, 0, hfinfo, out, value_pos);
10803 }
10804}
10805
10806static size_t
10807fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10808{
10809 int display;
10810 int n;
10811 double value;
10812
10813 if (label_str_size < 12) {
10814 /* Not enough room to write an entire floating point value. */
10815 return 0;
10816 }
10817
10818 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10819 value = fvalue_get_floating(fi->value);
10820
10821 if (display == BASE_CUSTOM) {
10822 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10823 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10823, "fmtfunc"))))
;
10824 fmtfunc(label_str, value);
10825 return strlen(label_str);
10826 }
10827
10828 switch (display) {
10829 case BASE_NONE:
10830 if (fi->hfinfo->type == FT_FLOAT) {
10831 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10832 } else {
10833 n = (int)strlen(dtoa_g_fmt(label_str, value));
10834 }
10835 break;
10836 case BASE_DEC:
10837 n = snprintf(label_str, label_str_size, "%f", value);
10838 break;
10839 case BASE_HEX:
10840 n = snprintf(label_str, label_str_size, "%a", value);
10841 break;
10842 case BASE_EXP:
10843 n = snprintf(label_str, label_str_size, "%e", value);
10844 break;
10845 default:
10846 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10846
, __func__, "assertion \"not reached\" failed")
;
10847 }
10848 if (n < 0) {
10849 return 0; /* error */
10850 }
10851 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10852 const char *hf_str_val;
10853 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10854 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10855 }
10856 if (n > label_str_size) {
10857 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10857, __func__, "label length too small"); } } while (0)
;
10858 return strlen(label_str);
10859 }
10860
10861 return n;
10862}
10863
10864void
10865fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10866{
10867 char tmp[ITEM_LABEL_LENGTH240];
10868
10869 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10870 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10871}
10872
10873static size_t
10874fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10875{
10876 int display;
10877 size_t pos = 0;
10878 double value;
10879 char* tmp_str;
10880
10881 if (label_str_size < 12) {
10882 /* Not enough room to write an entire floating point value. */
10883 return 0;
10884 }
10885
10886 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10887 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10888 pos = label_concat(label_str, pos, tmp_str)ws_label_strcpy(label_str, 240, pos, tmp_str, 0);
10889 wmem_free(NULL((void*)0), tmp_str);
10890
10891 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10892 const char *hf_str_val;
10893 fvalue_to_double(fi->value, &value);
10894 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10895 pos = label_concat(label_str, pos, hf_str_val)ws_label_strcpy(label_str, 240, pos, hf_str_val, 0);
10896 }
10897 if ((int)pos > label_str_size) {
10898 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10898, __func__, "label length too small"); } } while (0)
;
10899 return strlen(label_str);
10900 }
10901
10902 return pos;
10903}
10904
10905void
10906fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
10907{
10908 char tmp[ITEM_LABEL_LENGTH240];
10909
10910 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
10911 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10912}
10913
10914int
10915hfinfo_bitshift(const header_field_info *hfinfo)
10916{
10917 return ws_ctz(hfinfo->bitmask);
10918}
10919
10920
10921static int
10922hfinfo_bitoffset(const header_field_info *hfinfo)
10923{
10924 if (!hfinfo->bitmask) {
10925 return 0;
10926 }
10927
10928 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
10929 * as the first bit */
10930 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
10931}
10932
10933static int
10934hfinfo_mask_bitwidth(const header_field_info *hfinfo)
10935{
10936 if (!hfinfo->bitmask) {
10937 return 0;
10938 }
10939
10940 /* ilog2 = first set bit, ctz = last set bit */
10941 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
10942}
10943
10944static int
10945hfinfo_type_bitwidth(enum ftenum type)
10946{
10947 int bitwidth = 0;
10948
10949 switch (type) {
10950 case FT_CHAR:
10951 case FT_UINT8:
10952 case FT_INT8:
10953 bitwidth = 8;
10954 break;
10955 case FT_UINT16:
10956 case FT_INT16:
10957 bitwidth = 16;
10958 break;
10959 case FT_UINT24:
10960 case FT_INT24:
10961 bitwidth = 24;
10962 break;
10963 case FT_UINT32:
10964 case FT_INT32:
10965 bitwidth = 32;
10966 break;
10967 case FT_UINT40:
10968 case FT_INT40:
10969 bitwidth = 40;
10970 break;
10971 case FT_UINT48:
10972 case FT_INT48:
10973 bitwidth = 48;
10974 break;
10975 case FT_UINT56:
10976 case FT_INT56:
10977 bitwidth = 56;
10978 break;
10979 case FT_UINT64:
10980 case FT_INT64:
10981 bitwidth = 64;
10982 break;
10983 default:
10984 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 10984))
;
10985 ;
10986 }
10987 return bitwidth;
10988}
10989
10990
10991static int
10992hfinfo_container_bitwidth(const header_field_info *hfinfo)
10993{
10994 if (!hfinfo->bitmask) {
10995 return 0;
10996 }
10997
10998 if (hfinfo->type == FT_BOOLEAN) {
10999 return hfinfo->display; /* hacky? :) */
11000 }
11001
11002 return hfinfo_type_bitwidth(hfinfo->type);
11003}
11004
11005static int
11006hfinfo_hex_digits(const header_field_info *hfinfo)
11007{
11008 int bitwidth;
11009
11010 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11011 * appropriate to determine the number of hex digits for the field.
11012 * So instead, we compute it from the bitmask.
11013 */
11014 if (hfinfo->bitmask != 0) {
11015 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11016 } else {
11017 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11018 }
11019
11020 /* Divide by 4, rounding up, to get number of hex digits. */
11021 return (bitwidth + 3) / 4;
11022}
11023
11024const char *
11025hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11026{
11027 char *ptr = &buf[6];
11028 static const char hex_digits[16] =
11029 { '0', '1', '2', '3', '4', '5', '6', '7',
11030 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11031
11032 *ptr = '\0';
11033 *(--ptr) = '\'';
11034 /* Properly format value */
11035 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11036 /*
11037 * Printable, so just show the character, and, if it needs
11038 * to be escaped, escape it.
11039 */
11040 *(--ptr) = value;
11041 if (value == '\\' || value == '\'')
11042 *(--ptr) = '\\';
11043 } else {
11044 /*
11045 * Non-printable; show it as an escape sequence.
11046 */
11047 switch (value) {
11048
11049 case '\0':
11050 /*
11051 * Show a NUL with only one digit.
11052 */
11053 *(--ptr) = '0';
11054 break;
11055
11056 case '\a':
11057 case '\b':
11058 case '\f':
11059 case '\n':
11060 case '\r':
11061 case '\t':
11062 case '\v':
11063 *(--ptr) = value - '\a' + 'a';
11064 break;
11065
11066 default:
11067 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11068
11069 case BASE_OCT:
11070 *(--ptr) = (value & 0x7) + '0';
11071 value >>= 3;
11072 *(--ptr) = (value & 0x7) + '0';
11073 value >>= 3;
11074 *(--ptr) = (value & 0x7) + '0';
11075 break;
11076
11077 case BASE_HEX:
11078 *(--ptr) = hex_digits[value & 0x0F];
11079 value >>= 4;
11080 *(--ptr) = hex_digits[value & 0x0F];
11081 *(--ptr) = 'x';
11082 break;
11083
11084 default:
11085 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11086 }
11087 }
11088 *(--ptr) = '\\';
11089 }
11090 *(--ptr) = '\'';
11091 return ptr;
11092}
11093
11094static const char *
11095hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11096{
11097 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11098 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
))
;
11099
11100 *ptr = '\0';
11101 /* Properly format value */
11102 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11103 case BASE_DEC:
11104 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11105
11106 case BASE_DEC_HEX:
11107 *(--ptr) = ')';
11108 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11109 *(--ptr) = '(';
11110 *(--ptr) = ' ';
11111 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11112 return ptr;
11113
11114 case BASE_OCT:
11115 return oct_to_str_back(ptr, value);
11116
11117 case BASE_HEX:
11118 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11119
11120 case BASE_HEX_DEC:
11121 *(--ptr) = ')';
11122 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11123 *(--ptr) = '(';
11124 *(--ptr) = ' ';
11125 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11126 return ptr;
11127
11128 case BASE_PT_UDP:
11129 case BASE_PT_TCP:
11130 case BASE_PT_DCCP:
11131 case BASE_PT_SCTP:
11132 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11133 display_to_port_type((field_display_e)display), value);
11134 return buf;
11135 case BASE_OUI:
11136 {
11137 uint8_t p_oui[3];
11138 const char *manuf_name;
11139
11140 p_oui[0] = value >> 16 & 0xFF;
11141 p_oui[1] = value >> 8 & 0xFF;
11142 p_oui[2] = value & 0xFF;
11143
11144 /* Attempt an OUI lookup. */
11145 manuf_name = uint_get_manuf_name_if_known(value);
11146 if (manuf_name == NULL((void*)0)) {
11147 /* Could not find an OUI. */
11148 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11149 }
11150 else {
11151 /* Found an address string. */
11152 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11153 }
11154 return buf;
11155 }
11156
11157 default:
11158 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11159 }
11160 return ptr;
11161}
11162
11163static const char *
11164hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11165{
11166 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11167 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
))
;
11168
11169 *ptr = '\0';
11170 /* Properly format value */
11171 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11172 case BASE_DEC:
11173 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11174
11175 case BASE_DEC_HEX:
11176 *(--ptr) = ')';
11177 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11178 *(--ptr) = '(';
11179 *(--ptr) = ' ';
11180 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11181 return ptr;
11182
11183 case BASE_OCT:
11184 return oct64_to_str_back(ptr, value);
11185
11186 case BASE_HEX:
11187 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11188
11189 case BASE_HEX_DEC:
11190 *(--ptr) = ')';
11191 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11192 *(--ptr) = '(';
11193 *(--ptr) = ' ';
11194 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11195 return ptr;
11196
11197 default:
11198 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11199 }
11200
11201 return ptr;
11202}
11203
11204static const char *
11205hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11206{
11207 int display = hfinfo->display;
11208
11209 if (hfinfo->type == FT_FRAMENUM) {
11210 /*
11211 * Frame numbers are always displayed in decimal.
11212 */
11213 display = BASE_DEC;
11214 }
11215
11216 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11217}
11218
11219static const char *
11220hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11221{
11222 int display = hfinfo->display;
11223
11224 if (hfinfo->type == FT_FRAMENUM) {
11225 /*
11226 * Frame numbers are always displayed in decimal.
11227 */
11228 display = BASE_DEC;
11229 }
11230
11231 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11232}
11233
11234static const char *
11235hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11236{
11237 /* Get the underlying BASE_ value */
11238 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11239
11240 return hfinfo_char_value_format_display(display, buf, value);
11241}
11242
11243static const char *
11244hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11245{
11246 /* Get the underlying BASE_ value */
11247 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11248
11249 if (hfinfo->type == FT_FRAMENUM) {
11250 /*
11251 * Frame numbers are always displayed in decimal.
11252 */
11253 display = BASE_DEC;
11254 }
11255
11256 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11257 display = BASE_DEC;
11258 } else if (display == BASE_OUI) {
11259 display = BASE_HEX;
11260 }
11261
11262 switch (display) {
11263 case BASE_NONE:
11264 /* case BASE_DEC: */
11265 case BASE_DEC_HEX:
11266 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11267 case BASE_CUSTOM:
11268 display = BASE_DEC;
11269 break;
11270
11271 /* case BASE_HEX: */
11272 case BASE_HEX_DEC:
11273 display = BASE_HEX;
11274 break;
11275 }
11276
11277 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11278}
11279
11280static const char *
11281hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11282{
11283 /* Get the underlying BASE_ value */
11284 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11285
11286 if (hfinfo->type == FT_FRAMENUM) {
11287 /*
11288 * Frame numbers are always displayed in decimal.
11289 */
11290 display = BASE_DEC;
11291 }
11292
11293 switch (display) {
11294 case BASE_NONE:
11295 /* case BASE_DEC: */
11296 case BASE_DEC_HEX:
11297 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11298 case BASE_CUSTOM:
11299 display = BASE_DEC;
11300 break;
11301
11302 /* case BASE_HEX: */
11303 case BASE_HEX_DEC:
11304 display = BASE_HEX;
11305 break;
11306 }
11307
11308 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11309}
11310
11311static const char *
11312hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11313{
11314 /* Get the underlying BASE_ value */
11315 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11316
11317 return hfinfo_char_value_format_display(display, buf, value);
11318}
11319
11320static const char *
11321hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_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_display(hfinfo, display, buf, value);
11335}
11336
11337static const char *
11338hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11339{
11340 /* Get the underlying BASE_ value */
11341 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11342
11343 if (display == BASE_NONE)
11344 return NULL((void*)0);
11345
11346 if (display == BASE_DEC_HEX)
11347 display = BASE_DEC;
11348 if (display == BASE_HEX_DEC)
11349 display = BASE_HEX;
11350
11351 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11352}
11353
11354const char *
11355proto_registrar_get_name(const int n)
11356{
11357 header_field_info *hfinfo;
11358
11359 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", 11359
, __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", 11359
, "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", 11359, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11360 return hfinfo->name;
11361}
11362
11363const char *
11364proto_registrar_get_abbrev(const int n)
11365{
11366 header_field_info *hfinfo;
11367
11368 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", 11368
, __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", 11368
, "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", 11368, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11369 return hfinfo->abbrev;
11370}
11371
11372enum ftenum
11373proto_registrar_get_ftype(const int n)
11374{
11375 header_field_info *hfinfo;
11376
11377 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", 11377
, __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", 11377
, "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", 11377, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11378 return hfinfo->type;
11379}
11380
11381int
11382proto_registrar_get_parent(const int n)
11383{
11384 header_field_info *hfinfo;
11385
11386 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", 11386
, __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", 11386
, "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", 11386, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11387 return hfinfo->parent;
11388}
11389
11390bool_Bool
11391proto_registrar_is_protocol(const int n)
11392{
11393 header_field_info *hfinfo;
11394
11395 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", 11395
, __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", 11395
, "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", 11395, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11396 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11397}
11398
11399/* Returns length of field in packet (not necessarily the length
11400 * in our internal representation, as in the case of IPv4).
11401 * 0 means undeterminable at time of registration
11402 * -1 means the field is not registered. */
11403int
11404proto_registrar_get_length(const int n)
11405{
11406 header_field_info *hfinfo;
11407
11408 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", 11408
, __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", 11408
, "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", 11408, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11409 return ftype_wire_size(hfinfo->type);
11410}
11411
11412/* Looks for a protocol or a field in a proto_tree. Returns true if
11413 * it exists anywhere, or false if it exists nowhere. */
11414bool_Bool
11415proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11416{
11417 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11418
11419 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11420 return true1;
11421 }
11422 else {
11423 return false0;
11424 }
11425}
11426
11427/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11428 * This only works if the hfindex was "primed" before the dissection
11429 * took place, as we just pass back the already-created GPtrArray*.
11430 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11431 * handles that. */
11432GPtrArray *
11433proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11434{
11435 if (!tree)
11436 return NULL((void*)0);
11437
11438 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11439 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11440 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11441 else
11442 return NULL((void*)0);
11443}
11444
11445bool_Bool
11446proto_tracking_interesting_fields(const proto_tree *tree)
11447{
11448 GHashTable *interesting_hfids;
11449
11450 if (!tree)
11451 return false0;
11452
11453 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11454
11455 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11456}
11457
11458/* Helper struct for proto_find_info() and proto_all_finfos() */
11459typedef struct {
11460 GPtrArray *array;
11461 int id;
11462} ffdata_t;
11463
11464/* Helper function for proto_find_info() */
11465static bool_Bool
11466find_finfo(proto_node *node, void * data)
11467{
11468 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11469 if (fi && fi->hfinfo) {
11470 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11471 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11472 }
11473 }
11474
11475 /* Don't stop traversing. */
11476 return false0;
11477}
11478
11479/* Helper function for proto_find_first_info() */
11480static bool_Bool
11481find_first_finfo(proto_node *node, void *data)
11482{
11483 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11484 if (fi && fi->hfinfo) {
11485 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11486 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11487
11488 /* Stop traversing. */
11489 return true1;
11490 }
11491 }
11492
11493 /* Continue traversing. */
11494 return false0;
11495}
11496
11497/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11498* This works on any proto_tree, primed or unprimed, but actually searches
11499* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11500* The caller does need to free the returned GPtrArray with
11501* g_ptr_array_free(<array>, true).
11502*/
11503GPtrArray *
11504proto_find_finfo(proto_tree *tree, const int id)
11505{
11506 ffdata_t ffdata;
11507
11508 ffdata.array = g_ptr_array_new();
11509 ffdata.id = id;
11510
11511 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11512
11513 return ffdata.array;
11514}
11515
11516/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11517* This works on any proto_tree, primed or unprimed, but actually searches
11518* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11519* The caller does need to free the returned GPtrArray with
11520* g_ptr_array_free(<array>, true).
11521*/
11522GPtrArray *
11523proto_find_first_finfo(proto_tree *tree, const int id)
11524{
11525 ffdata_t ffdata;
11526
11527 ffdata.array = g_ptr_array_new();
11528 ffdata.id = id;
11529
11530 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11531
11532 return ffdata.array;
11533}
11534
11535/* Helper function for proto_all_finfos() */
11536static bool_Bool
11537every_finfo(proto_node *node, void * data)
11538{
11539 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11540 if (fi && fi->hfinfo) {
11541 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11542 }
11543
11544 /* Don't stop traversing. */
11545 return false0;
11546}
11547
11548/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11549 * The caller does need to free the returned GPtrArray with
11550 * g_ptr_array_free(<array>, true).
11551 */
11552GPtrArray *
11553proto_all_finfos(proto_tree *tree)
11554{
11555 ffdata_t ffdata;
11556
11557 /* Pre allocate enough space to hold all fields in most cases */
11558 ffdata.array = g_ptr_array_sized_new(512);
11559 ffdata.id = 0;
11560
11561 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11562
11563 return ffdata.array;
11564}
11565
11566
11567typedef struct {
11568 unsigned offset;
11569 field_info *finfo;
11570 tvbuff_t *tvb;
11571} offset_search_t;
11572
11573static bool_Bool
11574check_for_offset(proto_node *node, void * data)
11575{
11576 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11577 offset_search_t *offsearch = (offset_search_t *)data;
11578
11579 /* !fi == the top most container node which holds nothing */
11580 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11581 if (offsearch->offset >= (unsigned) fi->start &&
11582 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11583
11584 offsearch->finfo = fi;
11585 return false0; /* keep traversing */
11586 }
11587 }
11588 return false0; /* keep traversing */
11589}
11590
11591/* Search a proto_tree backwards (from leaves to root) looking for the field
11592 * whose start/length occupies 'offset' */
11593/* XXX - I couldn't find an easy way to search backwards, so I search
11594 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11595 * the one I want to return to the user. This algorithm is inefficient
11596 * and could be re-done, but I'd have to handle all the children and
11597 * siblings of each node myself. When I have more time I'll do that.
11598 * (yeah right) */
11599field_info *
11600proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11601{
11602 offset_search_t offsearch;
11603
11604 offsearch.offset = offset;
11605 offsearch.finfo = NULL((void*)0);
11606 offsearch.tvb = tvb;
11607
11608 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11609
11610 return offsearch.finfo;
11611}
11612
11613typedef struct {
11614 int length;
11615 char *buf;
11616} decoded_data_t;
11617
11618static bool_Bool
11619check_for_undecoded(proto_node *node, void * data)
11620{
11621 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11622 decoded_data_t* decoded = (decoded_data_t*)data;
11623 int i;
11624 unsigned byte;
11625 unsigned bit;
11626
11627 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11628 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11629 byte = i / 8;
11630 bit = i % 8;
11631 decoded->buf[byte] |= (1 << bit);
11632 }
11633 }
11634
11635 return false0;
11636}
11637
11638char*
11639proto_find_undecoded_data(proto_tree *tree, unsigned length)
11640{
11641 decoded_data_t decoded;
11642 decoded.length = length;
11643 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11644
11645 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11646 return decoded.buf;
11647}
11648
11649/* Dumps the protocols in the registration database to stdout. An independent
11650 * program can take this output and format it into nice tables or HTML or
11651 * whatever.
11652 *
11653 * There is one record per line. The fields are tab-delimited.
11654 *
11655 * Field 1 = protocol name
11656 * Field 2 = protocol short name
11657 * Field 3 = protocol filter name
11658 * Field 4 = protocol enabled
11659 * Field 5 = protocol enabled by default
11660 * Field 6 = protocol can toggle
11661 */
11662void
11663proto_registrar_dump_protocols(void)
11664{
11665 protocol_t *protocol;
11666 int i;
11667 void *cookie = NULL((void*)0);
11668
11669
11670 i = proto_get_first_protocol(&cookie);
11671 while (i != -1) {
11672 protocol = find_protocol_by_id(i);
11673 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11674 protocol->name,
11675 protocol->short_name,
11676 protocol->filter_name,
11677 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11678 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11679 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11680 i = proto_get_next_protocol(&cookie);
11681 }
11682}
11683
11684/* Dumps the value_strings, extended value string headers, range_strings
11685 * or true/false strings for fields that have them.
11686 * There is one record per line. Fields are tab-delimited.
11687 * There are four types of records: Value String, Extended Value String Header,
11688 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11689 * the type of record.
11690 *
11691 * Note that a record will be generated only if the value_string,... is referenced
11692 * in a registered hfinfo entry.
11693 *
11694 *
11695 * Value Strings
11696 * -------------
11697 * Field 1 = 'V'
11698 * Field 2 = Field abbreviation to which this value string corresponds
11699 * Field 3 = Integer value
11700 * Field 4 = String
11701 *
11702 * Extended Value String Headers
11703 * -----------------------------
11704 * Field 1 = 'E'
11705 * Field 2 = Field abbreviation to which this extended value string header corresponds
11706 * Field 3 = Extended Value String "Name"
11707 * Field 4 = Number of entries in the associated value_string array
11708 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11709 *
11710 * Range Strings
11711 * -------------
11712 * Field 1 = 'R'
11713 * Field 2 = Field abbreviation to which this range string corresponds
11714 * Field 3 = Integer value: lower bound
11715 * Field 4 = Integer value: upper bound
11716 * Field 5 = String
11717 *
11718 * True/False Strings
11719 * ------------------
11720 * Field 1 = 'T'
11721 * Field 2 = Field abbreviation to which this true/false string corresponds
11722 * Field 3 = True String
11723 * Field 4 = False String
11724 */
11725void
11726proto_registrar_dump_values(void)
11727{
11728 header_field_info *hfinfo;
11729 int i, len, vi;
11730 const value_string *vals;
11731 const val64_string *vals64;
11732 const range_string *range;
11733 const true_false_string *tfs;
11734 const unit_name_string *units;
11735
11736 len = gpa_hfinfo.len;
11737 for (i = 0; i < len ; i++) {
11738 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11739 continue; /* This is a deregistered protocol or field */
11740
11741 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", 11741
, __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", 11741
, "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", 11741, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11742
11743 if (hfinfo->id == hf_text_only) {
11744 continue;
11745 }
11746
11747 /* ignore protocols */
11748 if (proto_registrar_is_protocol(i)) {
11749 continue;
11750 }
11751 /* process header fields */
11752#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11753 /*
11754 * If this field isn't at the head of the list of
11755 * fields with this name, skip this field - all
11756 * fields with the same name are really just versions
11757 * of the same field stored in different bits, and
11758 * should have the same type/radix/value list, and
11759 * just differ in their bit masks. (If a field isn't
11760 * a bitfield, but can be, say, 1 or 2 bytes long,
11761 * it can just be made FT_UINT16, meaning the
11762 * *maximum* length is 2 bytes, and be used
11763 * for all lengths.)
11764 */
11765 if (hfinfo->same_name_prev_id != -1)
11766 continue;
11767#endif
11768 vals = NULL((void*)0);
11769 vals64 = NULL((void*)0);
11770 range = NULL((void*)0);
11771 tfs = NULL((void*)0);
11772 units = NULL((void*)0);
11773
11774 if (hfinfo->strings != NULL((void*)0)) {
11775 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11776 (hfinfo->type == FT_CHAR ||
11777 hfinfo->type == FT_UINT8 ||
11778 hfinfo->type == FT_UINT16 ||
11779 hfinfo->type == FT_UINT24 ||
11780 hfinfo->type == FT_UINT32 ||
11781 hfinfo->type == FT_UINT40 ||
11782 hfinfo->type == FT_UINT48 ||
11783 hfinfo->type == FT_UINT56 ||
11784 hfinfo->type == FT_UINT64 ||
11785 hfinfo->type == FT_INT8 ||
11786 hfinfo->type == FT_INT16 ||
11787 hfinfo->type == FT_INT24 ||
11788 hfinfo->type == FT_INT32 ||
11789 hfinfo->type == FT_INT40 ||
11790 hfinfo->type == FT_INT48 ||
11791 hfinfo->type == FT_INT56 ||
11792 hfinfo->type == FT_INT64 ||
11793 hfinfo->type == FT_FLOAT ||
11794 hfinfo->type == FT_DOUBLE)) {
11795
11796 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11797 range = (const range_string *)hfinfo->strings;
11798 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11799 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11800 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11801 } else {
11802 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11803 }
11804 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11805 vals64 = (const val64_string *)hfinfo->strings;
11806 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11807 units = (const unit_name_string *)hfinfo->strings;
11808 } else {
11809 vals = (const value_string *)hfinfo->strings;
11810 }
11811 }
11812 else if (hfinfo->type == FT_BOOLEAN) {
11813 tfs = (const struct true_false_string *)hfinfo->strings;
11814 }
11815 }
11816
11817 /* Print value strings? */
11818 if (vals) {
11819 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11820 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11821 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11822 if (!val64_string_ext_validate(vse_p)) {
11823 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11823, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11824 continue;
11825 }
11826 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11827 printf("E\t%s\t%u\t%s\t%s\n",
11828 hfinfo->abbrev,
11829 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11830 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11831 val64_string_ext_match_type_str(vse_p));
11832 } else {
11833 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11834 if (!value_string_ext_validate(vse_p)) {
11835 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11835, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11836 continue;
11837 }
11838 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11839 printf("E\t%s\t%u\t%s\t%s\n",
11840 hfinfo->abbrev,
11841 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11842 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11843 value_string_ext_match_type_str(vse_p));
11844 }
11845 }
11846 vi = 0;
11847 while (vals[vi].strptr) {
11848 /* Print in the proper base */
11849 if (hfinfo->type == FT_CHAR) {
11850 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11851 printf("V\t%s\t'%c'\t%s\n",
11852 hfinfo->abbrev,
11853 vals[vi].value,
11854 vals[vi].strptr);
11855 } else {
11856 if (hfinfo->display == BASE_HEX) {
11857 printf("V\t%s\t'\\x%02x'\t%s\n",
11858 hfinfo->abbrev,
11859 vals[vi].value,
11860 vals[vi].strptr);
11861 }
11862 else {
11863 printf("V\t%s\t'\\%03o'\t%s\n",
11864 hfinfo->abbrev,
11865 vals[vi].value,
11866 vals[vi].strptr);
11867 }
11868 }
11869 } else {
11870 if (hfinfo->display == BASE_HEX) {
11871 printf("V\t%s\t0x%x\t%s\n",
11872 hfinfo->abbrev,
11873 vals[vi].value,
11874 vals[vi].strptr);
11875 }
11876 else {
11877 printf("V\t%s\t%u\t%s\n",
11878 hfinfo->abbrev,
11879 vals[vi].value,
11880 vals[vi].strptr);
11881 }
11882 }
11883 vi++;
11884 }
11885 }
11886 else if (vals64) {
11887 vi = 0;
11888 while (vals64[vi].strptr) {
11889 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11890 hfinfo->abbrev,
11891 vals64[vi].value,
11892 vals64[vi].strptr);
11893 vi++;
11894 }
11895 }
11896
11897 /* print range strings? */
11898 else if (range) {
11899 vi = 0;
11900 while (range[vi].strptr) {
11901 /* Print in the proper base */
11902 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
11903 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
11904 hfinfo->abbrev,
11905 range[vi].value_min,
11906 range[vi].value_max,
11907 range[vi].strptr);
11908 }
11909 else {
11910 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
11911 hfinfo->abbrev,
11912 range[vi].value_min,
11913 range[vi].value_max,
11914 range[vi].strptr);
11915 }
11916 vi++;
11917 }
11918 }
11919
11920 /* Print true/false strings? */
11921 else if (tfs) {
11922 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
11923 tfs->true_string, tfs->false_string);
11924 }
11925 /* Print unit strings? */
11926 else if (units) {
11927 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
11928 units->singular, units->plural ? units->plural : "(no plural)");
11929 }
11930 }
11931}
11932
11933/* Prints the number of registered fields.
11934 * Useful for determining an appropriate value for
11935 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
11936 *
11937 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
11938 * the number of fields, true otherwise.
11939 */
11940bool_Bool
11941proto_registrar_dump_fieldcount(void)
11942{
11943 uint32_t i;
11944 header_field_info *hfinfo;
11945 uint32_t deregistered_count = 0;
11946 uint32_t same_name_count = 0;
11947 uint32_t protocol_count = 0;
11948
11949 for (i = 0; i < gpa_hfinfo.len; i++) {
11950 if (gpa_hfinfo.hfi[i] == NULL((void*)0)) {
11951 deregistered_count++;
11952 continue; /* This is a deregistered protocol or header field */
11953 }
11954
11955 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", 11955
, __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", 11955
, "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", 11955, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11956
11957 if (proto_registrar_is_protocol(i))
11958 protocol_count++;
11959
11960 if (hfinfo->same_name_prev_id != -1)
11961 same_name_count++;
11962 }
11963
11964 printf("There are %u header fields registered, of which:\n"
11965 "\t%u are deregistered\n"
11966 "\t%u are protocols\n"
11967 "\t%u have the same name as another field\n\n",
11968 gpa_hfinfo.len, deregistered_count, protocol_count,
11969 same_name_count);
11970
11971 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
11972 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
11973 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
11974 "\n");
11975
11976 printf("The header field table consumes %u KiB of memory.\n",
11977 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
11978 printf("The fields themselves consume %u KiB of memory.\n",
11979 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
11980
11981 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
11982}
11983
11984static void
11985elastic_add_base_mapping(json_dumper *dumper)
11986{
11987 json_dumper_set_member_name(dumper, "index_patterns");
11988 json_dumper_begin_array(dumper);
11989 // The index names from write_json_index() in print.c
11990 json_dumper_value_string(dumper, "packets-*");
11991 json_dumper_end_array(dumper);
11992
11993 json_dumper_set_member_name(dumper, "settings");
11994 json_dumper_begin_object(dumper);
11995 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
11996 json_dumper_value_anyf(dumper, "%d", 1000000);
11997 json_dumper_end_object(dumper);
11998}
11999
12000static char*
12001ws_type_to_elastic(unsigned type)
12002{
12003 switch(type) {
12004 case FT_INT8:
12005 return "byte";
12006 case FT_UINT8:
12007 case FT_INT16:
12008 return "short";
12009 case FT_UINT16:
12010 case FT_INT32:
12011 case FT_UINT24:
12012 case FT_INT24:
12013 return "integer";
12014 case FT_FRAMENUM:
12015 case FT_UINT32:
12016 case FT_UINT40:
12017 case FT_UINT48:
12018 case FT_UINT56:
12019 case FT_INT40:
12020 case FT_INT48:
12021 case FT_INT56:
12022 case FT_INT64:
12023 return "long";
12024 case FT_UINT64:
12025 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12026 case FT_FLOAT:
12027 return "float";
12028 case FT_DOUBLE:
12029 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12030 return "double";
12031 case FT_IPv6:
12032 case FT_IPv4:
12033 return "ip";
12034 case FT_ABSOLUTE_TIME:
12035 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12036 case FT_BOOLEAN:
12037 return "boolean";
12038 default:
12039 return NULL((void*)0);
12040 }
12041}
12042
12043static char*
12044dot_to_underscore(char* str)
12045{
12046 unsigned i;
12047 for (i = 0; i < strlen(str); i++) {
12048 if (str[i] == '.')
12049 str[i] = '_';
12050 }
12051 return str;
12052}
12053
12054/* Dumps a mapping file for ElasticSearch
12055 * This is the v1 (legacy) _template API.
12056 * At some point it may need to be updated with the composable templates
12057 * introduced in Elasticsearch 7.8 (_index_template)
12058 */
12059void
12060proto_registrar_dump_elastic(const char* filter)
12061{
12062 header_field_info *hfinfo;
12063 header_field_info *parent_hfinfo;
12064 unsigned i;
12065 bool_Bool open_object = true1;
12066 const char* prev_proto = NULL((void*)0);
12067 char* str;
12068 char** protos = NULL((void*)0);
12069 char* proto;
12070 bool_Bool found;
12071 unsigned j;
12072 char* type;
12073 char* prev_item = NULL((void*)0);
12074
12075 /* We have filtering protocols. Extract them. */
12076 if (filter) {
12077 protos = g_strsplit(filter, ",", -1);
12078 }
12079
12080 /*
12081 * To help tracking down the json tree, objects have been appended with a comment:
12082 * n.label -> where n is the indentation level and label the name of the object
12083 */
12084
12085 json_dumper dumper = {
12086 .output_file = stdoutstdout,
12087 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12088 };
12089 json_dumper_begin_object(&dumper); // 1.root
12090 elastic_add_base_mapping(&dumper);
12091
12092 json_dumper_set_member_name(&dumper, "mappings");
12093 json_dumper_begin_object(&dumper); // 2.mappings
12094
12095 json_dumper_set_member_name(&dumper, "properties");
12096 json_dumper_begin_object(&dumper); // 3.properties
12097 json_dumper_set_member_name(&dumper, "timestamp");
12098 json_dumper_begin_object(&dumper); // 4.timestamp
12099 json_dumper_set_member_name(&dumper, "type");
12100 json_dumper_value_string(&dumper, "date");
12101 json_dumper_end_object(&dumper); // 4.timestamp
12102
12103 json_dumper_set_member_name(&dumper, "layers");
12104 json_dumper_begin_object(&dumper); // 4.layers
12105 json_dumper_set_member_name(&dumper, "properties");
12106 json_dumper_begin_object(&dumper); // 5.properties
12107
12108 for (i = 0; i < gpa_hfinfo.len; i++) {
12109 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12110 continue; /* This is a deregistered protocol or header field */
12111
12112 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", 12112
, __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", 12112
, "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", 12112, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12113
12114 /*
12115 * Skip the pseudo-field for "proto_tree_add_text()" since
12116 * we don't want it in the list of filterable protocols.
12117 */
12118 if (hfinfo->id == hf_text_only)
12119 continue;
12120
12121 if (!proto_registrar_is_protocol(i)) {
12122 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", 12122
, __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", 12122
, "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", 12122
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12123
12124 /*
12125 * Skip the field if filter protocols have been set and this one's
12126 * parent is not listed.
12127 */
12128 if (protos) {
12129 found = false0;
12130 j = 0;
12131 proto = protos[0];
12132 while(proto) {
12133 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12134 found = true1;
12135 break;
12136 }
12137 j++;
12138 proto = protos[j];
12139 }
12140 if (!found)
12141 continue;
12142 }
12143
12144 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12145 json_dumper_end_object(&dumper); // 7.properties
12146 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12147 open_object = true1;
12148 }
12149
12150 prev_proto = parent_hfinfo->abbrev;
12151
12152 if (open_object) {
12153 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12154 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12155 json_dumper_set_member_name(&dumper, "properties");
12156 json_dumper_begin_object(&dumper); // 7.properties
12157 open_object = false0;
12158 }
12159 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12160 type = ws_type_to_elastic(hfinfo->type);
12161 /* when type is NULL, we have the default mapping: string */
12162 if (type) {
12163 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12164 dot_to_underscore(str);
12165 if (g_strcmp0(prev_item, str)) {
12166 json_dumper_set_member_name(&dumper, str);
12167 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12168 json_dumper_set_member_name(&dumper, "type");
12169 json_dumper_value_string(&dumper, type);
12170 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12171 }
12172 g_free(prev_item);
12173 prev_item = str;
12174 }
12175 }
12176 }
12177 g_free(prev_item);
12178
12179 if (prev_proto) {
12180 json_dumper_end_object(&dumper); // 7.properties
12181 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12182 }
12183
12184 json_dumper_end_object(&dumper); // 5.properties
12185 json_dumper_end_object(&dumper); // 4.layers
12186 json_dumper_end_object(&dumper); // 3.properties
12187 json_dumper_end_object(&dumper); // 2.mappings
12188 json_dumper_end_object(&dumper); // 1.root
12189 bool_Bool ret = json_dumper_finish(&dumper);
12190 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12190, "ret"))))
;
12191
12192 g_strfreev(protos);
12193}
12194
12195/* Dumps the contents of the registration database to stdout. An independent
12196 * program can take this output and format it into nice tables or HTML or
12197 * whatever.
12198 *
12199 * There is one record per line. Each record is either a protocol or a header
12200 * field, differentiated by the first field. The fields are tab-delimited.
12201 *
12202 * Protocols
12203 * ---------
12204 * Field 1 = 'P'
12205 * Field 2 = descriptive protocol name
12206 * Field 3 = protocol abbreviation
12207 *
12208 * Header Fields
12209 * -------------
12210 * Field 1 = 'F'
12211 * Field 2 = descriptive field name
12212 * Field 3 = field abbreviation
12213 * Field 4 = type ( textual representation of the ftenum type )
12214 * Field 5 = parent protocol abbreviation
12215 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12216 * Field 7 = bitmask: format: hex: 0x....
12217 * Field 8 = blurb describing field
12218 */
12219void
12220proto_registrar_dump_fields(void)
12221{
12222 header_field_info *hfinfo, *parent_hfinfo;
12223 int i, len;
12224 const char *enum_name;
12225 const char *base_name;
12226 const char *blurb;
12227 char width[5];
12228
12229 len = gpa_hfinfo.len;
12230 for (i = 0; i < len ; i++) {
12231 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12232 continue; /* This is a deregistered protocol or header field */
12233
12234 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", 12234
, __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", 12234
, "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", 12234, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12235
12236 /*
12237 * Skip the pseudo-field for "proto_tree_add_text()" since
12238 * we don't want it in the list of filterable fields.
12239 */
12240 if (hfinfo->id == hf_text_only)
12241 continue;
12242
12243 /* format for protocols */
12244 if (proto_registrar_is_protocol(i)) {
12245 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12246 }
12247 /* format for header fields */
12248 else {
12249 /*
12250 * If this field isn't at the head of the list of
12251 * fields with this name, skip this field - all
12252 * fields with the same name are really just versions
12253 * of the same field stored in different bits, and
12254 * should have the same type/radix/value list, and
12255 * just differ in their bit masks. (If a field isn't
12256 * a bitfield, but can be, say, 1 or 2 bytes long,
12257 * it can just be made FT_UINT16, meaning the
12258 * *maximum* length is 2 bytes, and be used
12259 * for all lengths.)
12260 */
12261 if (hfinfo->same_name_prev_id != -1)
12262 continue;
12263
12264 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", 12264
, __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", 12264
, "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", 12264
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12265
12266 enum_name = ftype_name(hfinfo->type);
12267 base_name = "";
12268
12269 if (hfinfo->type == FT_CHAR ||
12270 hfinfo->type == FT_UINT8 ||
12271 hfinfo->type == FT_UINT16 ||
12272 hfinfo->type == FT_UINT24 ||
12273 hfinfo->type == FT_UINT32 ||
12274 hfinfo->type == FT_UINT40 ||
12275 hfinfo->type == FT_UINT48 ||
12276 hfinfo->type == FT_UINT56 ||
12277 hfinfo->type == FT_UINT64 ||
12278 hfinfo->type == FT_INT8 ||
12279 hfinfo->type == FT_INT16 ||
12280 hfinfo->type == FT_INT24 ||
12281 hfinfo->type == FT_INT32 ||
12282 hfinfo->type == FT_INT40 ||
12283 hfinfo->type == FT_INT48 ||
12284 hfinfo->type == FT_INT56 ||
12285 hfinfo->type == FT_INT64) {
12286
12287 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12288 case BASE_NONE:
12289 case BASE_DEC:
12290 case BASE_HEX:
12291 case BASE_OCT:
12292 case BASE_DEC_HEX:
12293 case BASE_HEX_DEC:
12294 case BASE_CUSTOM:
12295 case BASE_PT_UDP:
12296 case BASE_PT_TCP:
12297 case BASE_PT_DCCP:
12298 case BASE_PT_SCTP:
12299 case BASE_OUI:
12300 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12301 break;
12302 default:
12303 base_name = "????";
12304 break;
12305 }
12306 } else if (hfinfo->type == FT_BOOLEAN) {
12307 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12308 snprintf(width, sizeof(width), "%d", hfinfo->display);
12309 base_name = width;
12310 }
12311
12312 blurb = hfinfo->blurb;
12313 if (blurb == NULL((void*)0))
12314 blurb = "";
12315 else if (strlen(blurb) == 0)
12316 blurb = "\"\"";
12317
12318 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12319 hfinfo->name, hfinfo->abbrev, enum_name,
12320 parent_hfinfo->abbrev, base_name,
12321 hfinfo->bitmask, blurb);
12322 }
12323 }
12324}
12325
12326/* Dumps all abbreviated field and protocol completions of the given string to
12327 * stdout. An independent program may use this for command-line tab completion
12328 * of fields.
12329 */
12330bool_Bool
12331proto_registrar_dump_field_completions(const char *prefix)
12332{
12333 header_field_info *hfinfo;
12334 int i, len;
12335 size_t prefix_len;
12336 bool_Bool matched = false0;
12337
12338 prefix_len = strlen(prefix);
12339 len = gpa_hfinfo.len;
12340 for (i = 0; i < len ; i++) {
12341 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12342 continue; /* This is a deregistered protocol or header field */
12343
12344 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", 12344
, __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", 12344
, "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", 12344, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12345
12346 /*
12347 * Skip the pseudo-field for "proto_tree_add_text()" since
12348 * we don't want it in the list of filterable fields.
12349 */
12350 if (hfinfo->id == hf_text_only)
12351 continue;
12352
12353 /* format for protocols */
12354 if (proto_registrar_is_protocol(i)) {
12355 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12356 matched = true1;
12357 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12358 }
12359 }
12360 /* format for header fields */
12361 else {
12362 /*
12363 * If this field isn't at the head of the list of
12364 * fields with this name, skip this field - all
12365 * fields with the same name are really just versions
12366 * of the same field stored in different bits, and
12367 * should have the same type/radix/value list, and
12368 * just differ in their bit masks. (If a field isn't
12369 * a bitfield, but can be, say, 1 or 2 bytes long,
12370 * it can just be made FT_UINT16, meaning the
12371 * *maximum* length is 2 bytes, and be used
12372 * for all lengths.)
12373 */
12374 if (hfinfo->same_name_prev_id != -1)
12375 continue;
12376
12377 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12378 matched = true1;
12379 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12380 }
12381 }
12382 }
12383 return matched;
12384}
12385
12386/* Dumps field types and descriptive names to stdout. An independent
12387 * program can take this output and format it into nice tables or HTML or
12388 * whatever.
12389 *
12390 * There is one record per line. The fields are tab-delimited.
12391 *
12392 * Field 1 = field type name, e.g. FT_UINT8
12393 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12394 */
12395void
12396proto_registrar_dump_ftypes(void)
12397{
12398 int fte;
12399
12400 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12401 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12402 }
12403}
12404
12405/* This function indicates whether it's possible to construct a
12406 * "match selected" display filter string for the specified field,
12407 * returns an indication of whether it's possible, and, if it's
12408 * possible and "filter" is non-null, constructs the filter and
12409 * sets "*filter" to point to it.
12410 * You do not need to [g_]free() this string since it will be automatically
12411 * freed once the next packet is dissected.
12412 */
12413static bool_Bool
12414construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12415 char **filter)
12416{
12417 const header_field_info *hfinfo;
12418 char *ptr;
12419 int buf_len;
12420 int i;
12421 int start, length, length_remaining;
12422 uint8_t c;
12423
12424 if (!finfo)
12425 return false0;
12426
12427 hfinfo = finfo->hfinfo;
12428 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12428, "hfinfo"))))
;
12429
12430 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12431 * then "the numeric value ... is not used when preparing
12432 * filters for the field in question." If it's any other
12433 * base, we'll generate the filter normally (which will
12434 * be numeric, even though the human-readable string does
12435 * work for filtering.)
12436 *
12437 * XXX - It might be nice to use fvalue_to_string_repr() in
12438 * "proto_item_fill_label()" as well, although, there, you'd
12439 * have to deal with the base *and* with resolved values for
12440 * addresses.
12441 *
12442 * Perhaps in addition to taking the repr type (DISPLAY
12443 * or DFILTER) and the display (base), fvalue_to_string_repr()
12444 * should have the the "strings" values in the header_field_info
12445 * structure for the field as a parameter, so it can have
12446 * if the field is Boolean or an enumerated integer type,
12447 * the tables used to generate human-readable values.
12448 */
12449 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12450 const char *str = NULL((void*)0);
12451
12452 switch (hfinfo->type) {
12453
12454 case FT_INT8:
12455 case FT_INT16:
12456 case FT_INT24:
12457 case FT_INT32:
12458 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12459 break;
12460
12461 case FT_CHAR:
12462 case FT_UINT8:
12463 case FT_UINT16:
12464 case FT_UINT24:
12465 case FT_UINT32:
12466 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12467 break;
12468
12469 default:
12470 break;
12471 }
12472
12473 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12474 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12475 return true1;
12476 }
12477 }
12478
12479 switch (hfinfo->type) {
12480
12481 case FT_PROTOCOL:
12482 if (filter != NULL((void*)0))
12483 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12484 break;
12485
12486 case FT_NONE:
12487 /*
12488 * If the length is 0, just match the name of the
12489 * field.
12490 *
12491 * (Also check for negative values, just in case,
12492 * as we'll cast it to an unsigned value later.)
12493 */
12494 length = finfo->length;
12495 if (length == 0) {
12496 if (filter != NULL((void*)0))
12497 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12498 break;
12499 }
12500 if (length < 0)
12501 return false0;
12502
12503 /*
12504 * This doesn't have a value, so we'd match
12505 * on the raw bytes at this address.
12506 *
12507 * Should we be allowed to access to the raw bytes?
12508 * If "edt" is NULL, the answer is "no".
12509 */
12510 if (edt == NULL((void*)0))
12511 return false0;
12512
12513 /*
12514 * Is this field part of the raw frame tvbuff?
12515 * If not, we can't use "frame[N:M]" to match
12516 * it.
12517 *
12518 * XXX - should this be frame-relative, or
12519 * protocol-relative?
12520 *
12521 * XXX - does this fallback for non-registered
12522 * fields even make sense?
12523 */
12524 if (finfo->ds_tvb != edt->tvb)
12525 return false0; /* you lose */
12526
12527 /*
12528 * Don't go past the end of that tvbuff.
12529 */
12530 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12531 if (length > length_remaining)
12532 length = length_remaining;
12533 if (length <= 0)
12534 return false0;
12535
12536 if (filter != NULL((void*)0)) {
12537 start = finfo->start;
12538 buf_len = 32 + length * 3;
12539 *filter = (char *)wmem_alloc0(NULL((void*)0), buf_len);
12540 ptr = *filter;
12541
12542 ptr += snprintf(ptr, buf_len-(ptr-*filter),
12543 "frame[%d:%d] == ", finfo->start, length);
12544 for (i=0; i<length; i++) {
12545 c = tvb_get_uint8(finfo->ds_tvb, start);
12546 start++;
12547 if (i == 0 ) {
12548 ptr += snprintf(ptr, buf_len-(ptr-*filter), "%02x", c);
12549 }
12550 else {
12551 ptr += snprintf(ptr, buf_len-(ptr-*filter), ":%02x", c);
12552 }
12553 }
12554 }
12555 break;
12556
12557 /* By default, use the fvalue's "to_string_repr" method. */
12558 default:
12559 if (filter != NULL((void*)0)) {
12560 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12561 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12562 wmem_free(NULL((void*)0), str);
12563 }
12564 break;
12565 }
12566
12567 return true1;
12568}
12569
12570/*
12571 * Returns true if we can do a "match selected" on the field, false
12572 * otherwise.
12573 */
12574bool_Bool
12575proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12576{
12577 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12578}
12579
12580/* This function attempts to construct a "match selected" display filter
12581 * string for the specified field; if it can do so, it returns a pointer
12582 * to the string, otherwise it returns NULL.
12583 *
12584 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12585 */
12586char *
12587proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12588{
12589 char *filter = NULL((void*)0);
12590
12591 if (!construct_match_selected_string(finfo, edt, &filter))
12592 {
12593 wmem_free(NULL((void*)0), filter);
12594 return NULL((void*)0);
12595 }
12596 return filter;
12597}
12598
12599/* This function is common code for all proto_tree_add_bitmask... functions.
12600 */
12601
12602static bool_Bool
12603proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12604 const int len, const int ett, int * const *fields,
12605 const int flags, bool_Bool first,
12606 bool_Bool use_parent_tree,
12607 proto_tree* tree, uint64_t value)
12608{
12609 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12610 uint64_t bitmask = 0;
12611 uint64_t tmpval;
12612 header_field_info *hf;
12613 uint32_t integer32;
12614 int bit_offset;
12615 int no_of_bits;
12616
12617 if (!*fields)
12618 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"
)
;
12619
12620 if (len < 0 || len > 8)
12621 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12622 /**
12623 * packet-frame.c uses len=0 since the value is taken from the packet
12624 * metadata, not the packet bytes. In that case, assume that all bits
12625 * in the provided value are valid.
12626 */
12627 if (len > 0) {
12628 available_bits >>= (8 - (unsigned)len)*8;
12629 }
12630
12631 if (use_parent_tree == false0)
12632 tree = proto_item_add_subtree(item, ett);
12633
12634 while (*fields) {
12635 uint64_t present_bits;
12636 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", 12636, __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", 12636
, "**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", 12636, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12637 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", 12637
, "hf->bitmask != 0", hf->abbrev))))
;
12638
12639 bitmask |= hf->bitmask;
12640
12641 /* Skip fields that aren't fully present */
12642 present_bits = available_bits & hf->bitmask;
12643 if (present_bits != hf->bitmask) {
12644 fields++;
12645 continue;
12646 }
12647
12648 switch (hf->type) {
12649 case FT_CHAR:
12650 case FT_UINT8:
12651 case FT_UINT16:
12652 case FT_UINT24:
12653 case FT_UINT32:
12654 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12655 break;
12656
12657 case FT_INT8:
12658 case FT_INT16:
12659 case FT_INT24:
12660 case FT_INT32:
12661 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12662 break;
12663
12664 case FT_UINT40:
12665 case FT_UINT48:
12666 case FT_UINT56:
12667 case FT_UINT64:
12668 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12669 break;
12670
12671 case FT_INT40:
12672 case FT_INT48:
12673 case FT_INT56:
12674 case FT_INT64:
12675 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12676 break;
12677
12678 case FT_BOOLEAN:
12679 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12680 break;
12681
12682 default:
12683 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))
12684 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))
12685 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))
12686 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))
;
12687 break;
12688 }
12689 if (flags & BMT_NO_APPEND0x01) {
12690 fields++;
12691 continue;
12692 }
12693 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12694
12695 /* XXX: README.developer and the comments have always defined
12696 * BMT_NO_INT as "only boolean flags are added to the title /
12697 * don't add non-boolean (integral) fields", but the
12698 * implementation has always added BASE_CUSTOM and fields with
12699 * value_strings, though not fields with unit_strings.
12700 * Possibly this is because some dissectors use a FT_UINT8
12701 * with a value_string for fields that should be a FT_BOOLEAN.
12702 */
12703 switch (hf->type) {
12704 case FT_CHAR:
12705 if (hf->display == BASE_CUSTOM) {
12706 char lbl[ITEM_LABEL_LENGTH240];
12707 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12708
12709 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12709, "fmtfunc"))))
;
12710 fmtfunc(lbl, (uint32_t) tmpval);
12711 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12712 hf->name, lbl);
12713 first = false0;
12714 }
12715 else if (hf->strings) {
12716 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12717 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12718 first = false0;
12719 }
12720 else if (!(flags & BMT_NO_INT0x02)) {
12721 char buf[32];
12722 const char *out;
12723
12724 if (!first) {
12725 proto_item_append_text(item, ", ");
12726 }
12727
12728 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12729 proto_item_append_text(item, "%s: %s", hf->name, out);
12730 first = false0;
12731 }
12732
12733 break;
12734
12735 case FT_UINT8:
12736 case FT_UINT16:
12737 case FT_UINT24:
12738 case FT_UINT32:
12739 if (hf->display == BASE_CUSTOM) {
12740 char lbl[ITEM_LABEL_LENGTH240];
12741 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12742
12743 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12743, "fmtfunc"))))
;
12744 fmtfunc(lbl, (uint32_t) tmpval);
12745 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12746 hf->name, lbl);
12747 first = false0;
12748 }
12749 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12750 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12751 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12752 first = false0;
12753 }
12754 else if (!(flags & BMT_NO_INT0x02)) {
12755 char buf[NUMBER_LABEL_LENGTH80];
12756 const char *out = NULL((void*)0);
12757
12758 if (!first) {
12759 proto_item_append_text(item, ", ");
12760 }
12761
12762 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12763 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12764 }
12765 if (out == NULL((void*)0)) {
12766 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12767 }
12768 proto_item_append_text(item, "%s: %s", hf->name, out);
12769 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12770 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12771 }
12772 first = false0;
12773 }
12774
12775 break;
12776
12777 case FT_INT8:
12778 case FT_INT16:
12779 case FT_INT24:
12780 case FT_INT32:
12781 integer32 = (uint32_t) tmpval;
12782 if (hf->bitmask) {
12783 no_of_bits = ws_count_ones(hf->bitmask);
12784 integer32 = ws_sign_ext32(integer32, no_of_bits);
12785 }
12786 if (hf->display == BASE_CUSTOM) {
12787 char lbl[ITEM_LABEL_LENGTH240];
12788 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12789
12790 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12790, "fmtfunc"))))
;
12791 fmtfunc(lbl, (int32_t) integer32);
12792 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12793 hf->name, lbl);
12794 first = false0;
12795 }
12796 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12797 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12798 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12799 first = false0;
12800 }
12801 else if (!(flags & BMT_NO_INT0x02)) {
12802 char buf[NUMBER_LABEL_LENGTH80];
12803 const char *out = NULL((void*)0);
12804
12805 if (!first) {
12806 proto_item_append_text(item, ", ");
12807 }
12808
12809 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12810 out = hf_try_val_to_str((int32_t) integer32, hf);
12811 }
12812 if (out == NULL((void*)0)) {
12813 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12814 }
12815 proto_item_append_text(item, "%s: %s", hf->name, out);
12816 if (hf->display & BASE_UNIT_STRING0x00001000) {
12817 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12818 }
12819 first = false0;
12820 }
12821
12822 break;
12823
12824 case FT_UINT40:
12825 case FT_UINT48:
12826 case FT_UINT56:
12827 case FT_UINT64:
12828 if (hf->display == BASE_CUSTOM) {
12829 char lbl[ITEM_LABEL_LENGTH240];
12830 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12831
12832 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12832, "fmtfunc"))))
;
12833 fmtfunc(lbl, tmpval);
12834 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12835 hf->name, lbl);
12836 first = false0;
12837 }
12838 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12839 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12840 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12841 first = false0;
12842 }
12843 else if (!(flags & BMT_NO_INT0x02)) {
12844 char buf[NUMBER_LABEL_LENGTH80];
12845 const char *out = NULL((void*)0);
12846
12847 if (!first) {
12848 proto_item_append_text(item, ", ");
12849 }
12850
12851 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12852 out = hf_try_val64_to_str(tmpval, hf);
12853 }
12854 if (out == NULL((void*)0)) {
12855 out = hfinfo_number_value_format64(hf, buf, tmpval);
12856 }
12857 proto_item_append_text(item, "%s: %s", hf->name, out);
12858 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12859 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12860 }
12861 first = false0;
12862 }
12863
12864 break;
12865
12866 case FT_INT40:
12867 case FT_INT48:
12868 case FT_INT56:
12869 case FT_INT64:
12870 if (hf->bitmask) {
12871 no_of_bits = ws_count_ones(hf->bitmask);
12872 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12873 }
12874 if (hf->display == BASE_CUSTOM) {
12875 char lbl[ITEM_LABEL_LENGTH240];
12876 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12877
12878 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12878, "fmtfunc"))))
;
12879 fmtfunc(lbl, (int64_t) tmpval);
12880 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12881 hf->name, lbl);
12882 first = false0;
12883 }
12884 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12885 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12886 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12887 first = false0;
12888 }
12889 else if (!(flags & BMT_NO_INT0x02)) {
12890 char buf[NUMBER_LABEL_LENGTH80];
12891 const char *out = NULL((void*)0);
12892
12893 if (!first) {
12894 proto_item_append_text(item, ", ");
12895 }
12896
12897 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12898 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12899 }
12900 if (out == NULL((void*)0)) {
12901 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12902 }
12903 proto_item_append_text(item, "%s: %s", hf->name, out);
12904 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12905 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12906 }
12907 first = false0;
12908 }
12909
12910 break;
12911
12912 case FT_BOOLEAN:
12913 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12914 /* If we have true/false strings, emit full - otherwise messages
12915 might look weird */
12916 const struct true_false_string *tfs =
12917 (const struct true_false_string *)hf->strings;
12918
12919 if (tmpval) {
12920 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12921 hf->name, tfs->true_string);
12922 first = false0;
12923 } else if (!(flags & BMT_NO_FALSE0x04)) {
12924 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12925 hf->name, tfs->false_string);
12926 first = false0;
12927 }
12928 } else if (hf->bitmask & value) {
12929 /* If the flag is set, show the name */
12930 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
12931 first = false0;
12932 }
12933 break;
12934 default:
12935 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))
12936 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))
12937 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))
12938 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))
;
12939 break;
12940 }
12941
12942 fields++;
12943 }
12944
12945 /* XXX: We don't pass the hfi into this function. Perhaps we should,
12946 * but then again most dissectors don't set the bitmask field for
12947 * the higher level bitmask hfi, so calculate the bitmask from the
12948 * fields present. */
12949 if (item) {
12950 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
12951 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
12952 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)
;
12953 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)
;
12954 }
12955 return first;
12956}
12957
12958/* This function will dissect a sequence of bytes that describe a
12959 * bitmask and supply the value of that sequence through a pointer.
12960 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12961 * to be dissected.
12962 * This field will form an expansion under which the individual fields of the
12963 * bitmask is dissected and displayed.
12964 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12965 *
12966 * fields is an array of pointers to int that lists all the fields of the
12967 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12968 * or another integer of the same type/size as hf_hdr with a mask specified.
12969 * This array is terminated by a NULL entry.
12970 *
12971 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
12972 * FT_integer fields that have a value_string attached will have the
12973 * matched string displayed on the expansion line.
12974 */
12975proto_item *
12976proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
12977 const unsigned offset, const int hf_hdr,
12978 const int ett, int * const *fields,
12979 const unsigned encoding, uint64_t *retval)
12980{
12981 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);
12982}
12983
12984/* This function will dissect a sequence of bytes that describe a
12985 * bitmask.
12986 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12987 * to be dissected.
12988 * This field will form an expansion under which the individual fields of the
12989 * bitmask is dissected and displayed.
12990 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12991 *
12992 * fields is an array of pointers to int that lists all the fields of the
12993 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12994 * or another integer of the same type/size as hf_hdr with a mask specified.
12995 * This array is terminated by a NULL entry.
12996 *
12997 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
12998 * FT_integer fields that have a value_string attached will have the
12999 * matched string displayed on the expansion line.
13000 */
13001proto_item *
13002proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13003 const unsigned offset, const int hf_hdr,
13004 const int ett, int * const *fields,
13005 const unsigned encoding)
13006{
13007 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13008}
13009
13010/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13011 * what data is appended to the header.
13012 */
13013proto_item *
13014proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13015 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13016 uint64_t *retval)
13017{
13018 proto_item *item = NULL((void*)0);
13019 header_field_info *hf;
13020 int len;
13021 uint64_t value;
13022
13023 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", 13023, __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", 13023
, "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", 13023, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13024 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", 13024, (hf)->abbrev)))
;
13025 len = ftype_wire_size(hf->type);
13026 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13027
13028 if (parent_tree) {
13029 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13030 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13031 flags, false0, false0, NULL((void*)0), value);
13032 }
13033
13034 *retval = value;
13035 if (hf->bitmask) {
13036 /* Mask out irrelevant portions */
13037 *retval &= hf->bitmask;
13038 /* Shift bits */
13039 *retval >>= hfinfo_bitshift(hf);
13040 }
13041
13042 return item;
13043}
13044
13045/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13046 * what data is appended to the header.
13047 */
13048proto_item *
13049proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13050 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13051{
13052 proto_item *item = NULL((void*)0);
13053 header_field_info *hf;
13054 int len;
13055 uint64_t value;
13056
13057 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", 13057, __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", 13057
, "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", 13057, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13058 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", 13058, (hf)->abbrev)))
;
13059
13060 if (parent_tree) {
13061 len = ftype_wire_size(hf->type);
13062 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13063 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13064 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13065 flags, false0, false0, NULL((void*)0), value);
13066 }
13067
13068 return item;
13069}
13070
13071/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13072 can't be retrieved directly from tvb) */
13073proto_item *
13074proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13075 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13076{
13077 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13078 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13079}
13080
13081/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13082WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13083proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13084 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13085{
13086 proto_item *item = NULL((void*)0);
13087 header_field_info *hf;
13088 int len;
13089
13090 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", 13090, __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", 13090
, "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", 13090, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13091 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", 13091, (hf)->abbrev)))
;
13092 /* the proto_tree_add_uint/_uint64() calls below
13093 will fail if tvb==NULL and len!=0 */
13094 len = tvb ? ftype_wire_size(hf->type) : 0;
13095
13096 if (parent_tree) {
13097 if (len <= 4)
13098 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13099 else
13100 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13101
13102 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13103 flags, false0, false0, NULL((void*)0), value);
13104 }
13105
13106 return item;
13107}
13108
13109/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13110void
13111proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13112 const int len, int * const *fields, const unsigned encoding)
13113{
13114 uint64_t value;
13115
13116 if (tree) {
13117 value = get_uint64_value(tree, tvb, offset, len, encoding);
13118 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13119 BMT_NO_APPEND0x01, false0, true1, tree, value);
13120 }
13121}
13122
13123WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13124proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13125 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13126{
13127 uint64_t value;
13128
13129 value = get_uint64_value(tree, tvb, offset, len, encoding);
13130 if (tree) {
13131 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13132 BMT_NO_APPEND0x01, false0, true1, tree, value);
13133 }
13134 if (retval) {
13135 *retval = value;
13136 }
13137}
13138
13139WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13140proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13141 const int len, int * const *fields, const uint64_t value)
13142{
13143 if (tree) {
13144 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13145 BMT_NO_APPEND0x01, false0, true1, tree, value);
13146 }
13147}
13148
13149
13150/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13151 * This is intended to support bitmask fields whose lengths can vary, perhaps
13152 * as the underlying standard evolves over time.
13153 * With this API there is the possibility of being called to display more or
13154 * less data than the dissector was coded to support.
13155 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13156 * Thus when presented with "too much" or "too little" data, MSbits will be
13157 * ignored or MSfields sacrificed.
13158 *
13159 * Only fields for which all defined bits are available are displayed.
13160 */
13161proto_item *
13162proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13163 const unsigned offset, const unsigned len, const int hf_hdr,
13164 const int ett, int * const *fields, struct expert_field* exp,
13165 const unsigned encoding)
13166{
13167 proto_item *item = NULL((void*)0);
13168 header_field_info *hf;
13169 unsigned decodable_len;
13170 unsigned decodable_offset;
13171 uint32_t decodable_value;
13172 uint64_t value;
13173
13174 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", 13174, __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", 13174
, "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", 13174, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13175 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", 13175, (hf)->abbrev)))
;
13176
13177 decodable_offset = offset;
13178 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13179
13180 /* If we are ftype_wire_size-limited,
13181 * make sure we decode as many LSBs as possible.
13182 */
13183 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13184 decodable_offset += (len - decodable_len);
13185 }
13186
13187 if (parent_tree) {
13188 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13189 decodable_len, encoding);
13190
13191 /* The root item covers all the bytes even if we can't decode them all */
13192 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13193 decodable_value);
13194 }
13195
13196 if (decodable_len < len) {
13197 /* Dissector likely requires updating for new protocol revision */
13198 expert_add_info_format(NULL((void*)0), item, exp,
13199 "Only least-significant %d of %d bytes decoded",
13200 decodable_len, len);
13201 }
13202
13203 if (item) {
13204 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13205 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13206 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13207 }
13208
13209 return item;
13210}
13211
13212/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13213proto_item *
13214proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13215 const unsigned offset, const unsigned len,
13216 const char *name, const char *fallback,
13217 const int ett, int * const *fields,
13218 const unsigned encoding, const int flags)
13219{
13220 proto_item *item = NULL((void*)0);
13221 uint64_t value;
13222
13223 if (parent_tree) {
13224 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13225 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13226 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13227 flags, true1, false0, NULL((void*)0), value) && fallback) {
13228 /* Still at first item - append 'fallback' text if any */
13229 proto_item_append_text(item, "%s", fallback);
13230 }
13231 }
13232
13233 return item;
13234}
13235
13236proto_item *
13237proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13238 const unsigned bit_offset, const int no_of_bits,
13239 const unsigned encoding)
13240{
13241 header_field_info *hfinfo;
13242 int octet_length;
13243 int octet_offset;
13244
13245 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", 13245, __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", 13245
, "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", 13245, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13246
13247 if (no_of_bits < 0) {
13248 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13249 }
13250 octet_length = (no_of_bits + 7) >> 3;
13251 octet_offset = bit_offset >> 3;
13252 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13253
13254 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13255 * but only after doing a bunch more work (which we can, in the common
13256 * case, shortcut here).
13257 */
13258 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13259 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", 13259
, __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", 13259, "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", 13259, "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", 13259, __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)
; } } }
;
13260
13261 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13262}
13263
13264/*
13265 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13266 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13267 * Offset should be given in bits from the start of the tvb.
13268 */
13269
13270static proto_item *
13271_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13272 const unsigned bit_offset, const int no_of_bits,
13273 uint64_t *return_value, const unsigned encoding)
13274{
13275 int offset;
13276 unsigned length;
13277 uint8_t tot_no_bits;
13278 char *bf_str;
13279 char lbl_str[ITEM_LABEL_LENGTH240];
13280 uint64_t value = 0;
13281 uint8_t *bytes = NULL((void*)0);
13282 size_t bytes_length = 0;
13283
13284 proto_item *pi;
13285 header_field_info *hf_field;
13286
13287 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13288 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", 13288, __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", 13288
, "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", 13288, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13289
13290 if (hf_field->bitmask != 0) {
13291 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)
13292 " 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)
13293 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)
;
13294 }
13295
13296 if (no_of_bits < 0) {
13297 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13298 } else if (no_of_bits == 0) {
13299 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)
13300 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)
;
13301 }
13302
13303 /* Byte align offset */
13304 offset = bit_offset>>3;
13305
13306 /*
13307 * Calculate the number of octets used to hold the bits
13308 */
13309 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13310 length = (tot_no_bits + 7) >> 3;
13311
13312 if (no_of_bits < 65) {
13313 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13314 } else if (hf_field->type != FT_BYTES) {
13315 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)
13316 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)
;
13317 return NULL((void*)0);
13318 }
13319
13320 /* Sign extend for signed types */
13321 switch (hf_field->type) {
13322 case FT_INT8:
13323 case FT_INT16:
13324 case FT_INT24:
13325 case FT_INT32:
13326 case FT_INT40:
13327 case FT_INT48:
13328 case FT_INT56:
13329 case FT_INT64:
13330 value = ws_sign_ext64(value, no_of_bits);
13331 break;
13332
13333 default:
13334 break;
13335 }
13336
13337 if (return_value) {
13338 *return_value = value;
13339 }
13340
13341 /* Coast clear. Try and fake it */
13342 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13343 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", 13343
, __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", 13343, "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", 13343, "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", 13343, __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); } } }
;
13344
13345 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13346
13347 switch (hf_field->type) {
13348 case FT_BOOLEAN:
13349 /* Boolean field */
13350 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13351 "%s = %s: %s",
13352 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13353 break;
13354
13355 case FT_CHAR:
13356 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13357 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13358 break;
13359
13360 case FT_UINT8:
13361 case FT_UINT16:
13362 case FT_UINT24:
13363 case FT_UINT32:
13364 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13365 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13366 break;
13367
13368 case FT_INT8:
13369 case FT_INT16:
13370 case FT_INT24:
13371 case FT_INT32:
13372 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13373 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13374 break;
13375
13376 case FT_UINT40:
13377 case FT_UINT48:
13378 case FT_UINT56:
13379 case FT_UINT64:
13380 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13381 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13382 break;
13383
13384 case FT_INT40:
13385 case FT_INT48:
13386 case FT_INT56:
13387 case FT_INT64:
13388 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13389 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13390 break;
13391
13392 case FT_BYTES:
13393 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13394 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13395 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13396 proto_item_set_text(pi, "%s", lbl_str);
13397 return pi;
13398
13399 /* TODO: should handle FT_UINT_BYTES ? */
13400
13401 default:
13402 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))
13403 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))
13404 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))
13405 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))
;
13406 return NULL((void*)0);
13407 }
13408
13409 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13410 return pi;
13411}
13412
13413proto_item *
13414proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13415 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13416 uint64_t *return_value)
13417{
13418 proto_item *pi;
13419 int no_of_bits;
13420 int octet_offset;
13421 unsigned mask_initial_bit_offset;
13422 unsigned mask_greatest_bit_offset;
13423 unsigned octet_length;
13424 uint8_t i;
13425 char bf_str[256];
13426 char lbl_str[ITEM_LABEL_LENGTH240];
13427 uint64_t value;
13428 uint64_t composite_bitmask;
13429 uint64_t composite_bitmap;
13430
13431 header_field_info *hf_field;
13432
13433 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13434 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", 13434, __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", 13434
, "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", 13434, "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
13435
13436 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13437 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)
13438 " 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)
13439 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)
;
13440 }
13441
13442 mask_initial_bit_offset = bit_offset % 8;
13443
13444 no_of_bits = 0;
13445 value = 0;
13446 i = 0;
13447 mask_greatest_bit_offset = 0;
13448 composite_bitmask = 0;
13449 composite_bitmap = 0;
13450
13451 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
13452 uint64_t crumb_mask, crumb_value;
13453 uint8_t crumb_end_bit_offset;
13454
13455 crumb_value = tvb_get_bits64(tvb,
13456 bit_offset + crumb_spec[i].crumb_bit_offset,
13457 crumb_spec[i].crumb_bit_length,
13458 ENC_BIG_ENDIAN0x00000000);
13459 value += crumb_value;
13460 no_of_bits += crumb_spec[i].crumb_bit_length;
13461 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", 13461
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13462
13463 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13464 octet containing the initial offset.
13465 If the mask is beyond 32 bits, then give up on bit map display.
13466 This could be improved in future, probably showing a table
13467 of 32 or 64 bits per row */
13468 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13469 crumb_end_bit_offset = mask_initial_bit_offset
13470 + crumb_spec[i].crumb_bit_offset
13471 + crumb_spec[i].crumb_bit_length;
13472 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'
13473
13474 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13475 mask_greatest_bit_offset = crumb_end_bit_offset;
13476 }
13477 /* Currently the bitmap of the crumbs are only shown if
13478 * smaller than 32 bits. Do not bother calculating the
13479 * mask if it is larger than that. */
13480 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13481 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'
13482 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13483 }
13484 }
13485 /* Shift left for the next segment */
13486 value <<= crumb_spec[++i].crumb_bit_length;
13487 }
13488
13489 /* Sign extend for signed types */
13490 switch (hf_field->type) {
13491 case FT_INT8:
13492 case FT_INT16:
13493 case FT_INT24:
13494 case FT_INT32:
13495 case FT_INT40:
13496 case FT_INT48:
13497 case FT_INT56:
13498 case FT_INT64:
13499 value = ws_sign_ext64(value, no_of_bits);
13500 break;
13501 default:
13502 break;
13503 }
13504
13505 if (return_value) {
13506 *return_value = value;
13507 }
13508
13509 /* Coast clear. Try and fake it */
13510 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13511 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", 13511
, __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", 13511, "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", 13511, "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", 13511, __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); } } }
;
13512
13513 /* initialise the format string */
13514 bf_str[0] = '\0';
13515
13516 octet_offset = bit_offset >> 3;
13517
13518 /* Round up mask length to nearest octet */
13519 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13520 mask_greatest_bit_offset = octet_length << 3;
13521
13522 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13523 It would be a useful enhancement to eliminate this restriction. */
13524 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13525 other_decode_bitfield_value(bf_str,
13526 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13527 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13528 mask_greatest_bit_offset);
13529 } else {
13530 /* If the bitmask is too large, try to describe its contents. */
13531 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13532 }
13533
13534 switch (hf_field->type) {
13535 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13536 /* Boolean field */
13537 return proto_tree_add_boolean_format(tree, hfindex,
13538 tvb, octet_offset, octet_length, value,
13539 "%s = %s: %s",
13540 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13541 break;
13542
13543 case FT_CHAR:
13544 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13545 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13546 break;
13547
13548 case FT_UINT8:
13549 case FT_UINT16:
13550 case FT_UINT24:
13551 case FT_UINT32:
13552 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13553 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13554 break;
13555
13556 case FT_INT8:
13557 case FT_INT16:
13558 case FT_INT24:
13559 case FT_INT32:
13560 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13561 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13562 break;
13563
13564 case FT_UINT40:
13565 case FT_UINT48:
13566 case FT_UINT56:
13567 case FT_UINT64:
13568 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13569 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13570 break;
13571
13572 case FT_INT40:
13573 case FT_INT48:
13574 case FT_INT56:
13575 case FT_INT64:
13576 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13577 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13578 break;
13579
13580 default:
13581 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))
13582 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))
13583 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))
13584 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))
;
13585 return NULL((void*)0);
13586 }
13587 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13588 return pi;
13589}
13590
13591void
13592proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13593 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13594{
13595 header_field_info *hfinfo;
13596 int start = bit_offset >> 3;
13597 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13598
13599 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13600 * so that we can use the tree's memory scope in calculating the string */
13601 if (length == -1) {
13602 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13603 } else {
13604 tvb_ensure_bytes_exist(tvb, start, length);
13605 }
13606 if (!tree) return;
13607
13608 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", 13608, __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", 13608
, "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", 13608, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13609 proto_tree_add_text_internal(tree, tvb, start, length,
13610 "%s crumb %d of %s (decoded above)",
13611 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13612 tvb_get_bits32(tvb,
13613 bit_offset,
13614 crumb_spec[crumb_index].crumb_bit_length,
13615 ENC_BIG_ENDIAN0x00000000),
13616 ENC_BIG_ENDIAN0x00000000),
13617 crumb_index,
13618 hfinfo->name);
13619}
13620
13621proto_item *
13622proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13623 const unsigned bit_offset, const int no_of_bits,
13624 uint64_t *return_value, const unsigned encoding)
13625{
13626 proto_item *item;
13627
13628 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13629 bit_offset, no_of_bits,
13630 return_value, encoding))) {
13631 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)
;
13632 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)
;
13633 }
13634 return item;
13635}
13636
13637static proto_item *
13638_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13639 tvbuff_t *tvb, const unsigned bit_offset,
13640 const int no_of_bits, void *value_ptr,
13641 const unsigned encoding, char *value_str)
13642{
13643 int offset;
13644 unsigned length;
13645 uint8_t tot_no_bits;
13646 char *str;
13647 uint64_t value = 0;
13648 header_field_info *hf_field;
13649
13650 /* We do not have to return a value, try to fake it as soon as possible */
13651 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13652 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", 13652
, __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", 13652, "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", 13652, "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", 13652, __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); } } }
;
13653
13654 if (hf_field->bitmask != 0) {
13655 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)
13656 " 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)
13657 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)
;
13658 }
13659
13660 if (no_of_bits < 0) {
13661 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13662 } else if (no_of_bits == 0) {
13663 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)
13664 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)
;
13665 }
13666
13667 /* Byte align offset */
13668 offset = bit_offset>>3;
13669
13670 /*
13671 * Calculate the number of octets used to hold the bits
13672 */
13673 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13674 length = tot_no_bits>>3;
13675 /* If we are using part of the next octet, increase length by 1 */
13676 if (tot_no_bits & 0x07)
13677 length++;
13678
13679 if (no_of_bits < 65) {
13680 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13681 } else {
13682 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)
13683 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)
;
13684 return NULL((void*)0);
13685 }
13686
13687 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13688
13689 (void) g_strlcat(str, " = ", 256+64);
13690 (void) g_strlcat(str, hf_field->name, 256+64);
13691
13692 /*
13693 * This function does not receive an actual value but a dimensionless pointer to that value.
13694 * For this reason, the type of the header field is examined in order to determine
13695 * what kind of value we should read from this address.
13696 * The caller of this function must make sure that for the specific header field type the address of
13697 * a compatible value is provided.
13698 */
13699 switch (hf_field->type) {
13700 case FT_BOOLEAN:
13701 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13702 "%s: %s", str, value_str);
13703 break;
13704
13705 case FT_CHAR:
13706 case FT_UINT8:
13707 case FT_UINT16:
13708 case FT_UINT24:
13709 case FT_UINT32:
13710 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13711 "%s: %s", str, value_str);
13712 break;
13713
13714 case FT_UINT40:
13715 case FT_UINT48:
13716 case FT_UINT56:
13717 case FT_UINT64:
13718 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13719 "%s: %s", str, value_str);
13720 break;
13721
13722 case FT_INT8:
13723 case FT_INT16:
13724 case FT_INT24:
13725 case FT_INT32:
13726 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13727 "%s: %s", str, value_str);
13728 break;
13729
13730 case FT_INT40:
13731 case FT_INT48:
13732 case FT_INT56:
13733 case FT_INT64:
13734 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13735 "%s: %s", str, value_str);
13736 break;
13737
13738 case FT_FLOAT:
13739 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13740 "%s: %s", str, value_str);
13741 break;
13742
13743 default:
13744 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))
13745 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))
13746 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))
13747 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))
;
13748 return NULL((void*)0);
13749 }
13750}
13751
13752static proto_item *
13753proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13754 tvbuff_t *tvb, const unsigned bit_offset,
13755 const int no_of_bits, void *value_ptr,
13756 const unsigned encoding, char *value_str)
13757{
13758 proto_item *item;
13759
13760 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13761 tvb, bit_offset, no_of_bits,
13762 value_ptr, encoding, value_str))) {
13763 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)
;
13764 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)
;
13765 }
13766 return item;
13767}
13768
13769#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);
\
13770 va_start(ap, format)__builtin_va_start(ap, format); \
13771 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13772 va_end(ap)__builtin_va_end(ap);
13773
13774proto_item *
13775proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13776 tvbuff_t *tvb, const unsigned bit_offset,
13777 const int no_of_bits, uint32_t value,
13778 const unsigned encoding,
13779 const char *format, ...)
13780{
13781 va_list ap;
13782 char *dst;
13783 header_field_info *hf_field;
13784
13785 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13786
13787 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", 13787
, __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", 13787, "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", 13787, "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", 13787, __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); } } }
;
13788
13789 switch (hf_field->type) {
13790 case FT_UINT8:
13791 case FT_UINT16:
13792 case FT_UINT24:
13793 case FT_UINT32:
13794 break;
13795
13796 default:
13797 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)
13798 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)
;
13799 return NULL((void*)0);
13800 }
13801
13802 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);
;
13803
13804 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13805}
13806
13807proto_item *
13808proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13809 tvbuff_t *tvb, const unsigned bit_offset,
13810 const int no_of_bits, uint64_t value,
13811 const unsigned encoding,
13812 const char *format, ...)
13813{
13814 va_list ap;
13815 char *dst;
13816 header_field_info *hf_field;
13817
13818 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13819
13820 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", 13820
, __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", 13820, "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", 13820, "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", 13820, __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); } } }
;
13821
13822 switch (hf_field->type) {
13823 case FT_UINT40:
13824 case FT_UINT48:
13825 case FT_UINT56:
13826 case FT_UINT64:
13827 break;
13828
13829 default:
13830 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)
13831 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)
;
13832 return NULL((void*)0);
13833 }
13834
13835 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);
;
13836
13837 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13838}
13839
13840proto_item *
13841proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13842 tvbuff_t *tvb, const unsigned bit_offset,
13843 const int no_of_bits, float value,
13844 const unsigned encoding,
13845 const char *format, ...)
13846{
13847 va_list ap;
13848 char *dst;
13849 header_field_info *hf_field;
13850
13851 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13852
13853 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", 13853
, __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", 13853, "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", 13853, "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", 13853, __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); } } }
;
13854
13855 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",
13855, ((hf_field))->abbrev))))
;
13856
13857 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);
;
13858
13859 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13860}
13861
13862proto_item *
13863proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13864 tvbuff_t *tvb, const unsigned bit_offset,
13865 const int no_of_bits, int32_t value,
13866 const unsigned encoding,
13867 const char *format, ...)
13868{
13869 va_list ap;
13870 char *dst;
13871 header_field_info *hf_field;
13872
13873 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13874
13875 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", 13875
, __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", 13875, "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", 13875, "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", 13875, __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); } } }
;
13876
13877 switch (hf_field->type) {
13878 case FT_INT8:
13879 case FT_INT16:
13880 case FT_INT24:
13881 case FT_INT32:
13882 break;
13883
13884 default:
13885 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)
13886 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)
;
13887 return NULL((void*)0);
13888 }
13889
13890 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);
;
13891
13892 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13893}
13894
13895proto_item *
13896proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13897 tvbuff_t *tvb, const unsigned bit_offset,
13898 const int no_of_bits, int64_t value,
13899 const unsigned encoding,
13900 const char *format, ...)
13901{
13902 va_list ap;
13903 char *dst;
13904 header_field_info *hf_field;
13905
13906 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13907
13908 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", 13908
, __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", 13908, "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", 13908, "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", 13908, __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); } } }
;
13909
13910 switch (hf_field->type) {
13911 case FT_INT40:
13912 case FT_INT48:
13913 case FT_INT56:
13914 case FT_INT64:
13915 break;
13916
13917 default:
13918 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)
13919 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)
;
13920 return NULL((void*)0);
13921 }
13922
13923 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);
;
13924
13925 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13926}
13927
13928proto_item *
13929proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
13930 tvbuff_t *tvb, const unsigned bit_offset,
13931 const int no_of_bits, uint64_t value,
13932 const unsigned encoding,
13933 const char *format, ...)
13934{
13935 va_list ap;
13936 char *dst;
13937 header_field_info *hf_field;
13938
13939 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13940
13941 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", 13941
, __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", 13941, "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", 13941, "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", 13941, __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); } } }
;
13942
13943 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"
, 13943, ((hf_field))->abbrev))))
;
13944
13945 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);
;
13946
13947 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13948}
13949
13950proto_item *
13951proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13952 const unsigned bit_offset, const int no_of_chars)
13953{
13954 proto_item *pi;
13955 header_field_info *hfinfo;
13956 int byte_length;
13957 int byte_offset;
13958 char *string;
13959
13960 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13961
13962 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", 13962
, __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", 13962, "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", 13962, "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", 13962, __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)
; } } }
;
13963
13964 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"
, 13964, ((hfinfo))->abbrev))))
;
13965
13966 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13967 byte_offset = bit_offset >> 3;
13968
13969 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
13970
13971 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
13972 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 13972, "byte_length >= 0"
))))
;
13973 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
13974
13975 return pi;
13976}
13977
13978proto_item *
13979proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13980 const unsigned bit_offset, const int no_of_chars)
13981{
13982 proto_item *pi;
13983 header_field_info *hfinfo;
13984 int byte_length;
13985 int byte_offset;
13986 char *string;
13987
13988 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13989
13990 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", 13990
, __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", 13990, "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", 13990, "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", 13990, __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)
; } } }
;
13991
13992 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"
, 13992, ((hfinfo))->abbrev))))
;
13993
13994 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13995 byte_offset = bit_offset >> 3;
13996
13997 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
13998
13999 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14000 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14000, "byte_length >= 0"
))))
;
14001 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14002
14003 return pi;
14004}
14005
14006const value_string proto_checksum_vals[] = {
14007 { PROTO_CHECKSUM_E_BAD, "Bad" },
14008 { PROTO_CHECKSUM_E_GOOD, "Good" },
14009 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14010 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14011 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14012
14013 { 0, NULL((void*)0) }
14014};
14015
14016proto_item *
14017proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14018 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14019 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14020{
14021 header_field_info *hfinfo;
14022 uint32_t checksum;
14023 uint32_t len;
14024 proto_item* ti = NULL((void*)0);
14025 proto_item* ti2;
14026 bool_Bool incorrect_checksum = true1;
14027
14028 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", 14028, __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", 14028
, "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", 14028, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14029
14030 switch (hfinfo->type) {
14031 case FT_UINT8:
14032 len = 1;
14033 break;
14034 case FT_UINT16:
14035 len = 2;
14036 break;
14037 case FT_UINT24:
14038 len = 3;
14039 break;
14040 case FT_UINT32:
14041 len = 4;
14042 break;
14043 default:
14044 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)
14045 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14046 }
14047
14048 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14049 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14050 proto_item_set_generated(ti);
14051 if (hf_checksum_status != -1) {
14052 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14053 proto_item_set_generated(ti2);
14054 }
14055 return ti;
14056 }
14057
14058 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14059 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14060 proto_item_set_generated(ti);
14061 } else {
14062 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14063 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14064 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14065 if (computed_checksum == 0) {
14066 proto_item_append_text(ti, " [correct]");
14067 if (hf_checksum_status != -1) {
14068 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14069 proto_item_set_generated(ti2);
14070 }
14071 incorrect_checksum = false0;
14072 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14073 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14074 /* XXX - This can't distinguish between "shouldbe"
14075 * 0x0000 and 0xFFFF unless we know whether there
14076 * were any nonzero bits (other than the checksum).
14077 * Protocols should not use this path if they might
14078 * have an all zero packet.
14079 * Some implementations put the wrong zero; maybe
14080 * we should have a special expert info for that?
14081 */
14082 }
14083 } else {
14084 if (checksum == computed_checksum) {
14085 proto_item_append_text(ti, " [correct]");
14086 if (hf_checksum_status != -1) {
14087 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14088 proto_item_set_generated(ti2);
14089 }
14090 incorrect_checksum = false0;
14091 }
14092 }
14093
14094 if (incorrect_checksum) {
14095 if (hf_checksum_status != -1) {
14096 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14097 proto_item_set_generated(ti2);
14098 }
14099 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14100 proto_item_append_text(ti, " [incorrect]");
14101 if (bad_checksum_expert != NULL((void*)0))
14102 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14103 } else {
14104 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14105 if (bad_checksum_expert != NULL((void*)0))
14106 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);
14107 }
14108 }
14109 } else {
14110 if (hf_checksum_status != -1) {
14111 proto_item_append_text(ti, " [unverified]");
14112 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14113 proto_item_set_generated(ti2);
14114 }
14115 }
14116 }
14117
14118 return ti;
14119}
14120
14121proto_item *
14122proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14123 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14124 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14125{
14126 header_field_info *hfinfo;
14127 uint8_t *checksum = NULL((void*)0);
14128 proto_item* ti = NULL((void*)0);
14129 proto_item* ti2;
14130 bool_Bool incorrect_checksum = true1;
14131
14132 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", 14132, __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", 14132
, "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", 14132, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14133
14134 if (hfinfo->type != FT_BYTES) {
14135 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)
14136 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
14137 }
14138
14139 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14140 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14141 proto_item_set_generated(ti);
14142 if (hf_checksum_status != -1) {
14143 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14144 proto_item_set_generated(ti2);
14145 }
14146 return ti;
14147 }
14148
14149 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14150 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14151 proto_item_set_generated(ti);
14152 } else {
14153 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
))))))
;
14154 tvb_memcpy(tvb, checksum, offset, checksum_len);
14155 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14156 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14157 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14158 if (computed_checksum == 0) {
14159 proto_item_append_text(ti, " [correct]");
14160 if (hf_checksum_status != -1) {
14161 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14162 proto_item_set_generated(ti2);
14163 }
14164 incorrect_checksum = false0;
14165 }
14166 } else {
14167 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14168 proto_item_append_text(ti, " [correct]");
14169 if (hf_checksum_status != -1) {
14170 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14171 proto_item_set_generated(ti2);
14172 }
14173 incorrect_checksum = false0;
14174 }
14175 }
14176
14177 if (incorrect_checksum) {
14178 if (hf_checksum_status != -1) {
14179 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14180 proto_item_set_generated(ti2);
14181 }
14182 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14183 proto_item_append_text(ti, " [incorrect]");
14184 if (bad_checksum_expert != NULL((void*)0))
14185 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14186 } else {
14187 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14188 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))))))
;
14189 for (size_t counter = 0; counter < checksum_len; ++counter) {
14190 snprintf(
14191 /* On ecah iteration inserts two characters */
14192 (char*)&computed_checksum_str[counter << 1],
14193 computed_checksum_str_len - (counter << 1),
14194 "%02x",
14195 computed_checksum[counter]);
14196 }
14197 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14198 if (bad_checksum_expert != NULL((void*)0))
14199 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14200 }
14201 }
14202 } else {
14203 if (hf_checksum_status != -1) {
14204 proto_item_append_text(ti, " [unverified]");
14205 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14206 proto_item_set_generated(ti2);
14207 }
14208 }
14209 }
14210
14211 return ti;
14212}
14213
14214unsigned char
14215proto_check_field_name(const char *field_name)
14216{
14217 return module_check_valid_name(field_name, false0);
14218}
14219
14220unsigned char
14221proto_check_field_name_lower(const char *field_name)
14222{
14223 return module_check_valid_name(field_name, true1);
14224}
14225
14226bool_Bool
14227tree_expanded(int tree_type)
14228{
14229 if (tree_type <= 0) {
14230 return false0;
14231 }
14232 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", 14232, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14233 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14234}
14235
14236void
14237tree_expanded_set(int tree_type, bool_Bool value)
14238{
14239 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", 14239, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14240
14241 if (value)
14242 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14243 else
14244 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14245}
14246
14247/*
14248 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14249 *
14250 * Local variables:
14251 * c-basic-offset: 8
14252 * tab-width: 8
14253 * indent-tabs-mode: t
14254 * End:
14255 *
14256 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14257 * :indentSize=8:tabSize=8:noTabs=false:
14258 */