Bug Summary

File:epan/proto.c
Warning:line 13488, 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-10-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_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
261static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
262static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
263static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
264static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
265static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267
268static void proto_cleanup_base(void);
269
270static proto_item *
271proto_tree_add_node(proto_tree *tree, field_info *fi);
272
273static proto_item *
274proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
275
276static void
277get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
278 int *item_length, const unsigned encoding);
279
280static int
281get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
282 int length, unsigned item_length, const int encoding);
283
284static field_info *
285new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
286 const int start, const int item_length);
287
288static proto_item *
289proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
290 int start, int *length);
291
292static void
293proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
294static void
295proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
296
297static void
298proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
299static void
300proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
301static void
302proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
303static void
304proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
305static void
306proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
307static void
308proto_tree_set_string(field_info *fi, const char* value);
309static void
310proto_tree_set_ax25(field_info *fi, const uint8_t* value);
311static void
312proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
313static void
314proto_tree_set_vines(field_info *fi, const uint8_t* value);
315static void
316proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
317static void
318proto_tree_set_ether(field_info *fi, const uint8_t* value);
319static void
320proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
321static void
322proto_tree_set_ipxnet(field_info *fi, uint32_t value);
323static void
324proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
325static void
326proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
327static void
328proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
329static void
330proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
331static void
332proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
333static void
334proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
335static void
336proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
337static void
338proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
339static void
340proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
341static void
342proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
343static void
344proto_tree_set_boolean(field_info *fi, uint64_t value);
345static void
346proto_tree_set_float(field_info *fi, float value);
347static void
348proto_tree_set_double(field_info *fi, double value);
349static void
350proto_tree_set_uint(field_info *fi, uint32_t value);
351static void
352proto_tree_set_int(field_info *fi, int32_t value);
353static void
354proto_tree_set_uint64(field_info *fi, uint64_t value);
355static void
356proto_tree_set_int64(field_info *fi, int64_t value);
357static void
358proto_tree_set_eui64(field_info *fi, const uint64_t value);
359static void
360proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
361
362/* Handle type length mismatch (now filterable) expert info */
363static int proto_type_length_mismatch;
364static expert_field ei_type_length_mismatch_error;
365static expert_field ei_type_length_mismatch_warn;
366static void register_type_length_mismatch(void);
367
368/* Handle byte array string decoding errors with expert info */
369static int proto_byte_array_string_decoding_error;
370static expert_field ei_byte_array_string_decoding_failed_error;
371static void register_byte_array_string_decodinws_error(void);
372
373/* Handle date and time string decoding errors with expert info */
374static int proto_date_time_string_decoding_error;
375static expert_field ei_date_time_string_decoding_failed_error;
376static void register_date_time_string_decodinws_error(void);
377
378/* Handle string errors expert info */
379static int proto_string_errors;
380static expert_field ei_string_trailing_characters;
381static void register_string_errors(void);
382
383static int proto_register_field_init(header_field_info *hfinfo, const int parent);
384
385/* special-case header field used within proto.c */
386static header_field_info hfi_text_only =
387 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
388int hf_text_only;
389
390/* Structure for information about a protocol */
391struct _protocol {
392 const char *name; /* long description */
393 const char *short_name; /* short description */
394 const char *filter_name; /* name of this protocol in filters */
395 GPtrArray *fields; /* fields for this protocol */
396 int proto_id; /* field ID for this protocol */
397 bool_Bool is_enabled; /* true if protocol is enabled */
398 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
399 bool_Bool can_toggle; /* true if is_enabled can be changed */
400 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
401 For dissectors that need a protocol name so they
402 can be added to a dissector table, but use the
403 parent_proto_id for things like enable/disable */
404 GList *heur_list; /* Heuristic dissectors associated with this protocol */
405};
406
407/* List of all protocols */
408static GList *protocols;
409
410/* Structure stored for deregistered g_slice */
411struct g_slice_data {
412 size_t block_size;
413 void *mem_block;
414};
415
416/* Deregistered fields */
417static GPtrArray *deregistered_fields;
418static GPtrArray *deregistered_data;
419static GPtrArray *deregistered_slice;
420
421/* indexed by prefix, contains initializers */
422static GHashTable* prefixes;
423
424/* Contains information about a field when a dissector calls
425 * proto_tree_add_item. */
426#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)))
427#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
428
429/* Contains the space for proto_nodes. */
430#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
431 node->first_child = NULL((void*)0); \
432 node->last_child = NULL((void*)0); \
433 node->next = NULL((void*)0);
434
435#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
436 wmem_free(pool, node)
437
438/* String space for protocol and field items for the GUI */
439#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;
\
440 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
441 il->value_pos = 0; \
442 il->value_len = 0;
443#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
444 wmem_free(pool, il);
445
446#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", 446, __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", 446, "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", 446, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
447 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
448 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 448
, __func__, "Unregistered hf! index=%d", hfindex)
; \
449 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", 449, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
450 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", 450, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
451 hfinfo = gpa_hfinfo.hfi[hfindex];
452
453/* List which stores protocols and fields that have been registered */
454typedef struct _gpa_hfinfo_t {
455 uint32_t len;
456 uint32_t allocated_len;
457 header_field_info **hfi;
458} gpa_hfinfo_t;
459
460static gpa_hfinfo_t gpa_hfinfo;
461
462/* Hash table of abbreviations and IDs */
463static GHashTable *gpa_name_map;
464static header_field_info *same_name_hfinfo;
465
466/* Hash table protocol aliases. const char * -> const char * */
467static GHashTable *gpa_protocol_aliases;
468
469/*
470 * We're called repeatedly with the same field name when sorting a column.
471 * Cache our last gpa_name_map hit for faster lookups.
472 */
473static char *last_field_name;
474static header_field_info *last_hfinfo;
475
476static void save_same_name_hfinfo(void *data)
477{
478 same_name_hfinfo = (header_field_info*)data;
479}
480
481/* Points to the first element of an array of bits, indexed by
482 a subtree item type; that array element is true if subtrees of
483 an item of that type are to be expanded. */
484static uint32_t *tree_is_expanded;
485
486/* Number of elements in that array. The entry with index 0 is not used. */
487int num_tree_types = 1;
488
489/* Name hashtables for fast detection of duplicate names */
490static GHashTable* proto_names;
491static GHashTable* proto_short_names;
492static GHashTable* proto_filter_names;
493
494static const char *reserved_filter_names[] = {
495 /* Display filter keywords. */
496 "eq",
497 "ne",
498 "all_eq",
499 "any_eq",
500 "all_ne",
501 "any_ne",
502 "gt",
503 "ge",
504 "lt",
505 "le",
506 "bitand",
507 "bitwise_and",
508 "contains",
509 "matches",
510 "not",
511 "and",
512 "or",
513 "xor",
514 "in",
515 "any",
516 "all",
517 "true",
518 "false",
519 "nan",
520 "inf",
521 "infinity",
522 NULL((void*)0)
523};
524
525static GHashTable *proto_reserved_filter_names;
526
527static int
528proto_compare_name(const void *p1_arg, const void *p2_arg)
529{
530 const protocol_t *p1 = (const protocol_t *)p1_arg;
531 const protocol_t *p2 = (const protocol_t *)p2_arg;
532
533 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
534}
535
536static GSList *dissector_plugins;
537
538#ifdef HAVE_PLUGINS1
539void
540proto_register_plugin(const proto_plugin *plug)
541{
542 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
543}
544#else /* HAVE_PLUGINS */
545void
546proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
547{
548 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 548, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
549}
550#endif /* HAVE_PLUGINS */
551
552static void
553call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
554{
555 proto_plugin *plug = (proto_plugin *)data;
556
557 if (plug->register_protoinfo) {
558 plug->register_protoinfo();
559 }
560}
561
562static void
563call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
564{
565 proto_plugin *plug = (proto_plugin *)data;
566
567 if (plug->register_handoff) {
568 plug->register_handoff();
569 }
570}
571
572/* initialize data structures and register protocols and fields */
573void
574proto_init(GSList *register_all_plugin_protocols_list,
575 GSList *register_all_plugin_handoffs_list,
576 register_cb cb,
577 void *client_data)
578{
579 proto_cleanup_base();
580
581 proto_names = g_hash_table_new(g_str_hash, g_str_equal);
582 proto_short_names = g_hash_table_new(g_str_hash, g_str_equal);
583 proto_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
584
585 proto_reserved_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
586 for (const char **ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
587 /* GHashTable has no key destructor so the cast is safe. */
588 g_hash_table_add(proto_reserved_filter_names, *(char **)ptr);
589 }
590
591 gpa_hfinfo.len = 0;
592 gpa_hfinfo.allocated_len = 0;
593 gpa_hfinfo.hfi = NULL((void*)0);
594 gpa_name_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL((void*)0), save_same_name_hfinfo);
595 gpa_protocol_aliases = g_hash_table_new(g_str_hash, g_str_equal);
596 deregistered_fields = g_ptr_array_new();
597 deregistered_data = g_ptr_array_new();
598 deregistered_slice = g_ptr_array_new();
599
600 /* Initialize the ftype subsystem */
601 ftypes_initialize();
602
603 /* Initialize the address type subsystem */
604 address_types_initialize();
605
606 /* Register one special-case FT_TEXT_ONLY field for use when
607 converting wireshark to new-style proto_tree. These fields
608 are merely strings on the GUI tree; they are not filterable */
609 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
610
611 /* Register the pseudo-protocols used for exceptions. */
612 register_show_exception();
613 register_type_length_mismatch();
614 register_byte_array_string_decodinws_error();
615 register_date_time_string_decodinws_error();
616 register_string_errors();
617 ftypes_register_pseudofields();
618 col_register_protocol();
619
620 /* Have each built-in dissector register its protocols, fields,
621 dissector tables, and dissectors to be called through a
622 handle, and do whatever one-time initialization it needs to
623 do. */
624 register_all_protocols(cb, client_data);
625
626 /* Now call the registration routines for all epan plugins. */
627 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
628 ((void (*)(register_cb, void *))l->data)(cb, client_data);
629 }
630
631 /* Now call the registration routines for all dissector plugins. */
632 if (cb)
633 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
634 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
635
636 /* Now call the "handoff registration" routines of all built-in
637 dissectors; those routines register the dissector in other
638 dissectors' handoff tables, and fetch any dissector handles
639 they need. */
640 register_all_protocol_handoffs(cb, client_data);
641
642 /* Now do the same with epan plugins. */
643 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
644 ((void (*)(register_cb, void *))l->data)(cb, client_data);
645 }
646
647 /* Now do the same with dissector plugins. */
648 if (cb)
649 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
650 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
651
652 /* sort the protocols by protocol name */
653 protocols = g_list_sort(protocols, proto_compare_name);
654
655 /* sort the dissector handles in dissector tables (for -G reports
656 * and -d error messages. The GUI sorts the handles itself.) */
657 packet_all_tables_sort_handles();
658
659 /* We've assigned all the subtree type values; allocate the array
660 for them, and zero it out. */
661 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
)))
;
662}
663
664static void
665proto_cleanup_base(void)
666{
667 protocol_t *protocol;
668 header_field_info *hfinfo;
669
670 /* Free the abbrev/ID hash table */
671 if (gpa_name_map) {
672 g_hash_table_destroy(gpa_name_map);
673 gpa_name_map = NULL((void*)0);
674 }
675 if (gpa_protocol_aliases) {
676 g_hash_table_destroy(gpa_protocol_aliases);
677 gpa_protocol_aliases = NULL((void*)0);
678 }
679 g_free(last_field_name);
680 last_field_name = NULL((void*)0);
681
682 while (protocols) {
683 protocol = (protocol_t *)protocols->data;
684 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", 684
, __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", 684, "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", 684, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
685 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", 685, "protocol->proto_id == hfinfo->id"
))))
;
686
687 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)
;
688 if (protocol->parent_proto_id != -1) {
689 // pino protocol
690 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 690, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
691 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"
, 691, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
692 } else {
693 if (protocol->fields) {
694 g_ptr_array_free(protocol->fields, true1);
695 }
696 g_list_free(protocol->heur_list);
697 }
698 protocols = g_list_remove(protocols, protocol);
699 g_free(protocol);
700 }
701
702 if (proto_names) {
703 g_hash_table_destroy(proto_names);
704 proto_names = NULL((void*)0);
705 }
706
707 if (proto_short_names) {
708 g_hash_table_destroy(proto_short_names);
709 proto_short_names = NULL((void*)0);
710 }
711
712 if (proto_filter_names) {
713 g_hash_table_destroy(proto_filter_names);
714 proto_filter_names = NULL((void*)0);
715 }
716
717 if (proto_reserved_filter_names) {
718 g_hash_table_destroy(proto_reserved_filter_names);
719 proto_reserved_filter_names = NULL((void*)0);
720 }
721
722 if (gpa_hfinfo.allocated_len) {
723 gpa_hfinfo.len = 0;
724 gpa_hfinfo.allocated_len = 0;
725 g_free(gpa_hfinfo.hfi);
726 gpa_hfinfo.hfi = NULL((void*)0);
727 }
728
729 if (deregistered_fields) {
730 g_ptr_array_free(deregistered_fields, true1);
731 deregistered_fields = NULL((void*)0);
732 }
733
734 if (deregistered_data) {
735 g_ptr_array_free(deregistered_data, true1);
736 deregistered_data = NULL((void*)0);
737 }
738
739 if (deregistered_slice) {
740 g_ptr_array_free(deregistered_slice, true1);
741 deregistered_slice = NULL((void*)0);
742 }
743
744 g_free(tree_is_expanded);
745 tree_is_expanded = NULL((void*)0);
746
747 if (prefixes)
748 g_hash_table_destroy(prefixes);
749}
750
751void
752proto_cleanup(void)
753{
754 proto_free_deregistered_fields();
755 proto_cleanup_base();
756
757 g_slist_free(dissector_plugins);
758 dissector_plugins = NULL((void*)0);
759}
760
761static bool_Bool
762// NOLINTNEXTLINE(misc-no-recursion)
763proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
764 void *data)
765{
766 proto_node *pnode = tree;
767 proto_node *child;
768 proto_node *current;
769
770 if (func(pnode, data))
771 return true1;
772
773 child = pnode->first_child;
774 while (child != NULL((void*)0)) {
775 /*
776 * The routine we call might modify the child, e.g. by
777 * freeing it, so we get the child's successor before
778 * calling that routine.
779 */
780 current = child;
781 child = current->next;
782 // We recurse here, but we're limited by prefs.gui_max_tree_depth
783 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
784 return true1;
785 }
786
787 return false0;
788}
789
790void
791proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
792 void *data)
793{
794 proto_node *node = tree;
795 proto_node *current;
796
797 if (!node)
798 return;
799
800 node = node->first_child;
801 while (node != NULL((void*)0)) {
802 current = node;
803 node = current->next;
804 func((proto_tree *)current, data);
805 }
806}
807
808static void
809free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
810{
811 GPtrArray *ptrs = (GPtrArray *)value;
812 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
813 header_field_info *hfinfo;
814
815 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", 815, __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", 815, "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", 815, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
816 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
817 /* when a field is referenced by a filter this also
818 affects the refcount for the parent protocol so we need
819 to adjust the refcount for the parent as well
820 */
821 if (hfinfo->parent != -1) {
822 header_field_info *parent_hfinfo;
823 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", 823
, __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", 823, "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", 823, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
824 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
825 }
826 hfinfo->ref_type = HF_REF_TYPE_NONE;
827 }
828
829 g_ptr_array_free(ptrs, true1);
830}
831
832static void
833proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
834{
835 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
836
837 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
838
839 if (finfo) {
840 fvalue_free(finfo->value);
841 finfo->value = NULL((void*)0);
842 }
843}
844
845void
846proto_tree_reset(proto_tree *tree)
847{
848 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
849
850 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
851
852 /* free tree data */
853 if (tree_data->interesting_hfids) {
854 /* Free all the GPtrArray's in the interesting_hfids hash. */
855 g_hash_table_foreach(tree_data->interesting_hfids,
856 free_GPtrArray_value, NULL((void*)0));
857
858 /* And then remove all values. */
859 g_hash_table_remove_all(tree_data->interesting_hfids);
860 }
861
862 /* Reset track of the number of children */
863 tree_data->count = 0;
864
865 /* Reset our loop checks */
866 tree_data->idle_count_ds_tvb = NULL((void*)0);
867 tree_data->max_start = 0;
868 tree_data->start_idle_count = 0;
869
870 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
871}
872
873/* frees the resources that the dissection a proto_tree uses */
874void
875proto_tree_free(proto_tree *tree)
876{
877 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
878
879 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
880
881 /* free tree data */
882 if (tree_data->interesting_hfids) {
883 /* Free all the GPtrArray's in the interesting_hfids hash. */
884 g_hash_table_foreach(tree_data->interesting_hfids,
885 free_GPtrArray_value, NULL((void*)0));
886
887 /* And then destroy the hash. */
888 g_hash_table_destroy(tree_data->interesting_hfids);
889 }
890
891 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)
;
892
893 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
894}
895
896/* Is the parsing being done for a visible proto_tree or an invisible one?
897 * By setting this correctly, the proto_tree creation is sped up by not
898 * having to call vsnprintf and copy strings around.
899 */
900bool_Bool
901proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
902{
903 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
904
905 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
906
907 return old_visible;
908}
909
910void
911proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
912{
913 if (tree)
914 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
915}
916
917/* Assume dissector set only its protocol fields.
918 This function is called by dissectors and allows the speeding up of filtering
919 in wireshark; if this function returns false it is safe to reset tree to NULL
920 and thus skip calling most of the expensive proto_tree_add_...()
921 functions.
922 If the tree is visible we implicitly assume the field is referenced.
923*/
924bool_Bool
925proto_field_is_referenced(proto_tree *tree, int proto_id)
926{
927 register header_field_info *hfinfo;
928
929
930 if (!tree)
931 return false0;
932
933 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
934 return true1;
935
936 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", 936, __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", 936, "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", 936, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
937 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
938 return true1;
939
940 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
941 return true1;
942
943 return false0;
944}
945
946
947/* Finds a record in the hfinfo array by id. */
948header_field_info *
949proto_registrar_get_nth(unsigned hfindex)
950{
951 register header_field_info *hfinfo;
952
953 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", 953, __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", 953, "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", 953, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
954 return hfinfo;
955}
956
957
958/* Prefix initialization
959 * this allows for a dissector to register a display filter name prefix
960 * so that it can delay the initialization of the hf array as long as
961 * possible.
962 */
963
964/* compute a hash for the part before the dot of a display filter */
965static unsigned
966prefix_hash (const void *key) {
967 /* end the string at the dot and compute its hash */
968 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
969 char* c = copy;
970 unsigned tmp;
971
972 for (; *c; c++) {
973 if (*c == '.') {
974 *c = 0;
975 break;
976 }
977 }
978
979 tmp = g_str_hash(copy);
980 g_free(copy);
981 return tmp;
982}
983
984/* are both strings equal up to the end or the dot? */
985static gboolean
986prefix_equal (const void *ap, const void *bp) {
987 const char* a = (const char *)ap;
988 const char* b = (const char *)bp;
989
990 do {
991 char ac = *a++;
992 char bc = *b++;
993
994 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
995
996 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
997 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
998
999 if (ac != bc) return FALSE(0);
1000 } while (1);
1001
1002 return FALSE(0);
1003}
1004
1005/* Register a new prefix for "delayed" initialization of field arrays */
1006void
1007proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1008 if (! prefixes ) {
1009 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1010 }
1011
1012 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1013}
1014
1015/* helper to call all prefix initializers */
1016static gboolean
1017initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1018 ((prefix_initializer_t)v)((const char *)k);
1019 return TRUE(!(0));
1020}
1021
1022/** Initialize every remaining uninitialized prefix. */
1023void
1024proto_initialize_all_prefixes(void) {
1025 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1026}
1027
1028/* Finds a record in the hfinfo array by name.
1029 * If it fails to find it in the already registered fields,
1030 * it tries to find and call an initializer in the prefixes
1031 * table and if so it looks again.
1032 */
1033
1034header_field_info *
1035proto_registrar_get_byname(const char *field_name)
1036{
1037 header_field_info *hfinfo;
1038 prefix_initializer_t pi;
1039
1040 if (!field_name)
1041 return NULL((void*)0);
1042
1043 if (g_strcmp0(field_name, last_field_name) == 0) {
1044 return last_hfinfo;
1045 }
1046
1047 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
1048
1049 if (hfinfo) {
1050 g_free(last_field_name);
1051 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1052 last_hfinfo = hfinfo;
1053 return hfinfo;
1054 }
1055
1056 if (!prefixes)
1057 return NULL((void*)0);
1058
1059 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1060 pi(field_name);
1061 g_hash_table_remove(prefixes, field_name);
1062 } else {
1063 return NULL((void*)0);
1064 }
1065
1066 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
1067
1068 if (hfinfo) {
1069 g_free(last_field_name);
1070 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1071 last_hfinfo = hfinfo;
1072 }
1073 return hfinfo;
1074}
1075
1076header_field_info*
1077proto_registrar_get_byalias(const char *alias_name)
1078{
1079 if (!alias_name) {
1080 return NULL((void*)0);
1081 }
1082
1083 /* Find our aliased protocol. */
1084 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1085 char *dot = strchr(an_copy, '.');
1086 if (dot) {
1087 *dot = '\0';
1088 }
1089 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1090 if (!proto_pfx) {
1091 g_free(an_copy);
1092 return NULL((void*)0);
1093 }
1094
1095 /* Construct our aliased field and look it up. */
1096 GString *filter_name = g_string_new(proto_pfx);
1097 if (dot) {
1098 g_string_append_printf(filter_name, ".%s", dot+1);
1099 }
1100 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1101 g_free(an_copy);
1102 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)))))
;
1103
1104 return hfinfo;
1105}
1106
1107int
1108proto_registrar_get_id_byname(const char *field_name)
1109{
1110 header_field_info *hfinfo;
1111
1112 hfinfo = proto_registrar_get_byname(field_name);
1113
1114 if (!hfinfo)
1115 return -1;
1116
1117 return hfinfo->id;
1118}
1119
1120static int
1121label_strcat_flags(const header_field_info *hfinfo)
1122{
1123 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1124 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1125
1126 return 0;
1127}
1128
1129static char *
1130format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1131 const uint8_t *bytes, unsigned length, size_t max_str_len)
1132{
1133 char *str = NULL((void*)0);
1134 const uint8_t *p;
1135 bool_Bool is_printable;
1136
1137 if (bytes) {
1138 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1139 /*
1140 * If all bytes are valid and printable UTF-8, show the
1141 * bytes as a string - in quotes to indicate that it's
1142 * a string.
1143 */
1144 if (isprint_utf8_string(bytes, length)) {
1145 str = wmem_strdup_printf(scope, "\"%.*s\"",
1146 (int)length, bytes);
1147 return str;
1148 }
1149 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1150 /*
1151 * Check whether all bytes are printable.
1152 */
1153 is_printable = true1;
1154 for (p = bytes; p < bytes+length; p++) {
1155 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1156 /* Not printable. */
1157 is_printable = false0;
1158 break;
1159 }
1160 }
1161
1162 /*
1163 * If all bytes are printable ASCII, show the bytes
1164 * as a string - in quotes to indicate that it's
1165 * a string.
1166 */
1167 if (is_printable) {
1168 str = wmem_strdup_printf(scope, "\"%.*s\"",
1169 (int)length, bytes);
1170 return str;
1171 }
1172 }
1173
1174 /*
1175 * Either it's not printable ASCII, or we don't care whether
1176 * it's printable ASCII; show it as hex bytes.
1177 */
1178 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1179 case SEP_DOT:
1180 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1181 break;
1182 case SEP_DASH:
1183 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1184 break;
1185 case SEP_COLON:
1186 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1187 break;
1188 case SEP_SPACE:
1189 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1190 break;
1191 case BASE_NONE:
1192 default:
1193 if (prefs.display_byte_fields_with_spaces) {
1194 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1195 } else {
1196 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1197 }
1198 break;
1199 }
1200 }
1201 else {
1202 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1203 str = wmem_strdup(scope, "<none>");
1204 } else {
1205 str = wmem_strdup(scope, "<MISSING>");
1206 }
1207 }
1208 return str;
1209}
1210
1211static char *
1212format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1213 const uint8_t *bytes, unsigned length)
1214{
1215 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1216}
1217
1218static void
1219ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1220{
1221 subtree_lvl *pushed_tree;
1222
1223 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"
, 1223, "ptvc->pushed_tree_max <= 256-8"))))
;
1224 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1225
1226 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1227 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1227, "pushed_tree != ((void*)0)"
))))
;
1228 ptvc->pushed_tree = pushed_tree;
1229}
1230
1231static void
1232ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1233{
1234 ptvc->pushed_tree = NULL((void*)0);
1235 ptvc->pushed_tree_max = 0;
1236 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", 1236, "ptvc->pushed_tree_index == 0"
))))
;
1237 ptvc->pushed_tree_index = 0;
1238}
1239
1240/* Allocates an initializes a ptvcursor_t with 3 variables:
1241 * proto_tree, tvbuff, and offset. */
1242ptvcursor_t *
1243ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, int offset)
1244{
1245 ptvcursor_t *ptvc;
1246
1247 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1248 ptvc->scope = scope;
1249 ptvc->tree = tree;
1250 ptvc->tvb = tvb;
1251 ptvc->offset = offset;
1252 ptvc->pushed_tree = NULL((void*)0);
1253 ptvc->pushed_tree_max = 0;
1254 ptvc->pushed_tree_index = 0;
1255 return ptvc;
1256}
1257
1258
1259/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1260void
1261ptvcursor_free(ptvcursor_t *ptvc)
1262{
1263 ptvcursor_free_subtree_levels(ptvc);
1264 /*g_free(ptvc);*/
1265}
1266
1267/* Returns tvbuff. */
1268tvbuff_t *
1269ptvcursor_tvbuff(ptvcursor_t *ptvc)
1270{
1271 return ptvc->tvb;
1272}
1273
1274/* Returns current offset. */
1275int
1276ptvcursor_current_offset(ptvcursor_t *ptvc)
1277{
1278 return ptvc->offset;
1279}
1280
1281proto_tree *
1282ptvcursor_tree(ptvcursor_t *ptvc)
1283{
1284 if (!ptvc)
1285 return NULL((void*)0);
1286
1287 return ptvc->tree;
1288}
1289
1290void
1291ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1292{
1293 ptvc->tree = tree;
1294}
1295
1296/* creates a subtree, sets it as the working tree and pushes the old working tree */
1297proto_tree *
1298ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1299{
1300 subtree_lvl *subtree;
1301 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1302 ptvcursor_new_subtree_levels(ptvc);
1303
1304 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1305 subtree->tree = ptvc->tree;
1306 subtree->it= NULL((void*)0);
1307 ptvc->pushed_tree_index++;
1308 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1309}
1310
1311/* pops a subtree */
1312void
1313ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1314{
1315 subtree_lvl *subtree;
1316
1317 if (ptvc->pushed_tree_index <= 0)
1318 return;
1319
1320 ptvc->pushed_tree_index--;
1321 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1322 if (subtree->it != NULL((void*)0))
1323 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1324
1325 ptvc->tree = subtree->tree;
1326}
1327
1328/* saves the current tvb offset and the item in the current subtree level */
1329static void
1330ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1331{
1332 subtree_lvl *subtree;
1333
1334 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", 1334, "ptvc->pushed_tree_index > 0"
))))
;
1335
1336 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1337 subtree->it = it;
1338 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1339}
1340
1341/* Creates a subtree and adds it to the cursor as the working tree but does not
1342 * save the old working tree */
1343proto_tree *
1344ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1345{
1346 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1347 return ptvc->tree;
1348}
1349
1350static proto_tree *
1351ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1352{
1353 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1354 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1355 ptvcursor_subtree_set_item(ptvc, it);
1356 return ptvcursor_tree(ptvc);
1357}
1358
1359/* Add an item to the tree and create a subtree
1360 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1361 * In this case, when the subtree will be closed, the parent item length will
1362 * be equal to the advancement of the cursor since the creation of the subtree.
1363 */
1364proto_tree *
1365ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1366 const unsigned encoding, int ett_subtree)
1367{
1368 proto_item *it;
1369
1370 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1371 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1372}
1373
1374static proto_item *
1375proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1376
1377/* Add a text node to the tree and create a subtree
1378 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1379 * In this case, when the subtree will be closed, the item length will be equal
1380 * to the advancement of the cursor since the creation of the subtree.
1381 */
1382proto_tree *
1383ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1384 int ett_subtree, const char *format, ...)
1385{
1386 proto_item *pi;
1387 va_list ap;
1388 header_field_info *hfinfo;
1389 proto_tree *tree;
1390
1391 tree = ptvcursor_tree(ptvc);
1392
1393 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1394
1395 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", 1395
, __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", 1395, "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", 1395, "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", 1395, __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)
; } } }
;
1396
1397 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1398 ptvcursor_current_offset(ptvc), length);
1399
1400 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1400, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1401
1402 va_start(ap, format)__builtin_va_start(ap, format);
1403 proto_tree_set_representation(pi, format, ap);
1404 va_end(ap)__builtin_va_end(ap);
1405
1406 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1407}
1408
1409/* Add a text-only node, leaving it to our caller to fill the text in */
1410static proto_item *
1411proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1412{
1413 proto_item *pi;
1414
1415 if (tree == NULL((void*)0))
1416 return NULL((void*)0);
1417
1418 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1419
1420 return pi;
1421}
1422
1423/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1424proto_item *
1425proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1426 const char *format, ...)
1427{
1428 proto_item *pi;
1429 va_list ap;
1430 header_field_info *hfinfo;
1431
1432 if (length == -1) {
1433 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1434 } else {
1435 tvb_ensure_bytes_exist(tvb, start, length);
1436 }
1437
1438 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1439
1440 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", 1440
, __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", 1440, "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", 1440, "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", 1440, __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)
; } } }
;
1441
1442 pi = proto_tree_add_text_node(tree, tvb, start, length);
1443
1444 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1444, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1445
1446 va_start(ap, format)__builtin_va_start(ap, format);
1447 proto_tree_set_representation(pi, format, ap);
1448 va_end(ap)__builtin_va_end(ap);
1449
1450 return pi;
1451}
1452
1453/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1454proto_item *
1455proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1456 int length, const char *format, va_list ap)
1457{
1458 proto_item *pi;
1459 header_field_info *hfinfo;
1460
1461 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1462 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1463 * the length to be what's in the tvbuff if length is -1, and the
1464 * minimum of length and what's in the tvbuff if not.
1465 */
1466
1467 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1468
1469 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", 1469
, __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", 1469, "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", 1469, "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", 1469, __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)
; } } }
;
1470
1471 pi = proto_tree_add_text_node(tree, tvb, start, length);
1472
1473 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1473, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1474
1475 proto_tree_set_representation(pi, format, ap);
1476
1477 return pi;
1478}
1479
1480/* Add a text-only node that creates a subtree underneath.
1481 */
1482proto_tree *
1483proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1484{
1485 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1486}
1487
1488/* Add a text-only node that creates a subtree underneath.
1489 */
1490proto_tree *
1491proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1492{
1493 proto_tree *pt;
1494 proto_item *pi;
1495 va_list ap;
1496
1497 va_start(ap, format)__builtin_va_start(ap, format);
1498 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1499 va_end(ap)__builtin_va_end(ap);
1500
1501 if (tree_item != NULL((void*)0))
1502 *tree_item = pi;
1503
1504 pt = proto_item_add_subtree(pi, idx);
1505
1506 return pt;
1507}
1508
1509/* Add a text-only node for debugging purposes. The caller doesn't need
1510 * to worry about tvbuff, start, or length. Debug message gets sent to
1511 * STDOUT, too */
1512proto_item *
1513proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1514{
1515 proto_item *pi;
1516 va_list ap;
1517
1518 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1519
1520 if (pi) {
1521 va_start(ap, format)__builtin_va_start(ap, format);
1522 proto_tree_set_representation(pi, format, ap);
1523 va_end(ap)__builtin_va_end(ap);
1524 }
1525 va_start(ap, format)__builtin_va_start(ap, format);
1526 vprintf(format, ap);
1527 va_end(ap)__builtin_va_end(ap);
1528 printf("\n");
1529
1530 return pi;
1531}
1532
1533proto_item *
1534proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1535{
1536 proto_item *pi;
1537 header_field_info *hfinfo;
1538
1539 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1540
1541 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", 1541
, __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", 1541, "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", 1541, "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", 1541, __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)
; } } }
;
1542
1543 pi = proto_tree_add_text_node(tree, tvb, start, length);
1544
1545 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1545, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1546
1547 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1548
1549 return pi;
1550}
1551
1552proto_item *
1553proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1554{
1555 proto_item *pi;
1556 header_field_info *hfinfo;
1557 char *str;
1558
1559 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1560
1561 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", 1561
, __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", 1561, "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", 1561, "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", 1561, __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)
; } } }
;
1562
1563 pi = proto_tree_add_text_node(tree, tvb, start, length);
1564
1565 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1565, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1566
1567 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1568 proto_item_set_text(pi, "%s", str);
1569 wmem_free(NULL((void*)0), str);
1570
1571 return pi;
1572}
1573
1574void proto_report_dissector_bug(const char *format, ...)
1575{
1576 va_list args;
1577
1578 if (wireshark_abort_on_dissector_bug) {
1579 /*
1580 * Try to have the error message show up in the crash
1581 * information.
1582 */
1583 va_start(args, format)__builtin_va_start(args, format);
1584 ws_vadd_crash_info(format, args);
1585 va_end(args)__builtin_va_end(args);
1586
1587 /*
1588 * Print the error message.
1589 */
1590 va_start(args, format)__builtin_va_start(args, format);
1591 vfprintf(stderrstderr, format, args);
1592 va_end(args)__builtin_va_end(args);
1593 putc('\n', stderrstderr);
1594
1595 /*
1596 * And crash.
1597 */
1598 abort();
1599 } else {
1600 va_start(args, format)__builtin_va_start(args, format);
1601 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1602 va_end(args)__builtin_va_end(args);
1603 }
1604}
1605
1606/* We could probably get away with changing is_error to a minimum length value. */
1607static void
1608report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1609{
1610 if (is_error) {
1611 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1612 } else {
1613 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1614 }
1615
1616 if (is_error) {
1617 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1618 }
1619}
1620
1621static uint32_t
1622get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1623{
1624 uint32_t value;
1625 bool_Bool length_error;
1626
1627 switch (length) {
1628
1629 case 1:
1630 value = tvb_get_uint8(tvb, offset);
1631 if (encoding & ENC_ZIGBEE0x40000000) {
1632 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1633 value = 0;
1634 }
1635 }
1636 break;
1637
1638 case 2:
1639 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1640 : tvb_get_ntohs(tvb, offset);
1641 if (encoding & ENC_ZIGBEE0x40000000) {
1642 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1643 value = 0;
1644 }
1645 }
1646 break;
1647
1648 case 3:
1649 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1650 : tvb_get_ntoh24(tvb, offset);
1651 break;
1652
1653 case 4:
1654 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1655 : tvb_get_ntohl(tvb, offset);
1656 break;
1657
1658 default:
1659 if (length < 1) {
1660 length_error = true1;
1661 value = 0;
1662 } else {
1663 length_error = false0;
1664 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1665 : tvb_get_ntohl(tvb, offset);
1666 }
1667 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1668 break;
1669 }
1670 return value;
1671}
1672
1673static inline uint64_t
1674get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1675{
1676 uint64_t value;
1677
1678 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1679
1680 if (length < 1 || length > 8) {
1681 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1682 }
1683
1684 return value;
1685}
1686
1687static int32_t
1688get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1689{
1690 int32_t value;
1691 bool_Bool length_error;
1692
1693 switch (length) {
1694
1695 case 1:
1696 value = tvb_get_int8(tvb, offset);
1697 break;
1698
1699 case 2:
1700 value = encoding ? tvb_get_letohis(tvb, offset)
1701 : tvb_get_ntohis(tvb, offset);
1702 break;
1703
1704 case 3:
1705 value = encoding ? tvb_get_letohi24(tvb, offset)
1706 : tvb_get_ntohi24(tvb, offset);
1707 break;
1708
1709 case 4:
1710 value = encoding ? tvb_get_letohil(tvb, offset)
1711 : tvb_get_ntohil(tvb, offset);
1712 break;
1713
1714 default:
1715 if (length < 1) {
1716 length_error = true1;
1717 value = 0;
1718 } else {
1719 length_error = false0;
1720 value = encoding ? tvb_get_letohil(tvb, offset)
1721 : tvb_get_ntohil(tvb, offset);
1722 }
1723 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1724 break;
1725 }
1726 return value;
1727}
1728
1729/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1730 * be cast-able as a int64_t. This is weird, but what the code has always done.
1731 */
1732static inline uint64_t
1733get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1734{
1735 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1736
1737 switch (length) {
1738 case 7:
1739 value = ws_sign_ext64(value, 56);
1740 break;
1741 case 6:
1742 value = ws_sign_ext64(value, 48);
1743 break;
1744 case 5:
1745 value = ws_sign_ext64(value, 40);
1746 break;
1747 case 4:
1748 value = ws_sign_ext64(value, 32);
1749 break;
1750 case 3:
1751 value = ws_sign_ext64(value, 24);
1752 break;
1753 case 2:
1754 value = ws_sign_ext64(value, 16);
1755 break;
1756 case 1:
1757 value = ws_sign_ext64(value, 8);
1758 break;
1759 }
1760
1761 return value;
1762}
1763
1764/* For FT_STRING */
1765static inline const uint8_t *
1766get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1767 int length, int *ret_length, const unsigned encoding)
1768{
1769 if (length == -1) {
1770 length = tvb_ensure_captured_length_remaining(tvb, start);
1771 }
1772 *ret_length = length;
1773 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1774}
1775
1776/* For FT_STRINGZ */
1777static inline const uint8_t *
1778get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1779 int start, int length, int *ret_length, const unsigned encoding)
1780{
1781 const uint8_t *value;
1782
1783 if (length < -1) {
1784 report_type_length_mismatch(tree, "a string", length, true1);
1785 }
1786 if (length == -1) {
1787 /* This can throw an exception */
1788 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1789 } else {
1790 /* In this case, length signifies the length of the string.
1791 *
1792 * This could either be a null-padded string, which doesn't
1793 * necessarily have a '\0' at the end, or a null-terminated
1794 * string, with a trailing '\0'. (Yes, there are cases
1795 * where you have a string that's both counted and null-
1796 * terminated.)
1797 *
1798 * In the first case, we must allocate a buffer of length
1799 * "length+1", to make room for a trailing '\0'.
1800 *
1801 * In the second case, we don't assume that there is a
1802 * trailing '\0' there, as the packet might be malformed.
1803 * (XXX - should we throw an exception if there's no
1804 * trailing '\0'?) Therefore, we allocate a buffer of
1805 * length "length+1", and put in a trailing '\0', just to
1806 * be safe.
1807 *
1808 * (XXX - this would change if we made string values counted
1809 * rather than null-terminated.)
1810 */
1811 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1812 }
1813 *ret_length = length;
1814 return value;
1815}
1816
1817/* For FT_UINT_STRING */
1818static inline const uint8_t *
1819get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1820 tvbuff_t *tvb, int start, int length, int *ret_length,
1821 const unsigned encoding)
1822{
1823 uint32_t n;
1824 const uint8_t *value;
1825
1826 /* I believe it's ok if this is called with a NULL tree */
1827 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1828 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1829 length += n;
1830 *ret_length = length;
1831 return value;
1832}
1833
1834/* For FT_STRINGZPAD */
1835static inline const uint8_t *
1836get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1837 int length, int *ret_length, const unsigned encoding)
1838{
1839 /*
1840 * XXX - currently, string values are null-
1841 * terminated, so a "zero-padded" string
1842 * isn't special. If we represent string
1843 * values as something that includes a counted
1844 * array of bytes, we'll need to strip the
1845 * trailing NULs.
1846 */
1847 if (length == -1) {
1848 length = tvb_ensure_captured_length_remaining(tvb, start);
1849 }
1850 *ret_length = length;
1851 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1852}
1853
1854/* For FT_STRINGZTRUNC */
1855static inline const uint8_t *
1856get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1857 int length, int *ret_length, const unsigned encoding)
1858{
1859 /*
1860 * XXX - currently, string values are null-
1861 * terminated, so a "zero-truncated" string
1862 * isn't special. If we represent string
1863 * values as something that includes a counted
1864 * array of bytes, we'll need to strip everything
1865 * starting with the terminating NUL.
1866 */
1867 if (length == -1) {
1868 length = tvb_ensure_captured_length_remaining(tvb, start);
1869 }
1870 *ret_length = length;
1871 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1872}
1873
1874/*
1875 * Deltas between the epochs for various non-UN*X time stamp formats and
1876 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1877 * stamp format.
1878 */
1879
1880/*
1881 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1882 * XXX - if it's OK if this is unsigned, can we just use
1883 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1884 */
1885#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1886
1887/*
1888 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1889 */
1890#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1891
1892/* this can be called when there is no tree, so tree may be null */
1893static void
1894get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1895 const int length, const unsigned encoding, nstime_t *time_stamp,
1896 const bool_Bool is_relative)
1897{
1898 uint32_t tmpsecs;
1899 uint64_t tmp64secs;
1900 uint64_t todusecs;
1901
1902 switch (encoding) {
1903
1904 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1905 /*
1906 * If the length is 16, 8-byte seconds, followed
1907 * by 8-byte fractional time in nanoseconds,
1908 * both big-endian.
1909 *
1910 * If the length is 12, 8-byte seconds, followed
1911 * by 4-byte fractional time in nanoseconds,
1912 * both big-endian.
1913 *
1914 * If the length is 8, 4-byte seconds, followed
1915 * by 4-byte fractional time in nanoseconds,
1916 * both big-endian.
1917 *
1918 * For absolute times, the seconds are seconds
1919 * since the UN*X epoch.
1920 */
1921 if (length == 16) {
1922 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1923 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1924 } else if (length == 12) {
1925 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1926 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1927 } else if (length == 8) {
1928 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1929 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1930 } else if (length == 4) {
1931 /*
1932 * Backwards compatibility.
1933 * ENC_TIME_SECS_NSECS is 0; using
1934 * ENC_BIG_ENDIAN by itself with a 4-byte
1935 * time-in-seconds value was done in the
1936 * past.
1937 */
1938 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1939 time_stamp->nsecs = 0;
1940 } else {
1941 time_stamp->secs = 0;
1942 time_stamp->nsecs = 0;
1943 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1944 }
1945 break;
1946
1947 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
1948 /*
1949 * If the length is 16, 8-byte seconds, followed
1950 * by 8-byte fractional time in nanoseconds,
1951 * both little-endian.
1952 *
1953 * If the length is 12, 8-byte seconds, followed
1954 * by 4-byte fractional time in nanoseconds,
1955 * both little-endian.
1956 *
1957 * If the length is 8, 4-byte seconds, followed
1958 * by 4-byte fractional time in nanoseconds,
1959 * both little-endian.
1960 *
1961 * For absolute times, the seconds are seconds
1962 * since the UN*X epoch.
1963 */
1964 if (length == 16) {
1965 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
1966 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
1967 } else if (length == 12) {
1968 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
1969 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
1970 } else if (length == 8) {
1971 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1972 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1973 } else if (length == 4) {
1974 /*
1975 * Backwards compatibility.
1976 * ENC_TIME_SECS_NSECS is 0; using
1977 * ENC_LITTLE_ENDIAN by itself with a 4-byte
1978 * time-in-seconds value was done in the
1979 * past.
1980 */
1981 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1982 time_stamp->nsecs = 0;
1983 } else {
1984 time_stamp->secs = 0;
1985 time_stamp->nsecs = 0;
1986 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1987 }
1988 break;
1989
1990 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
1991 /*
1992 * NTP time stamp, big-endian.
1993 * Only supported for absolute times.
1994 */
1995 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1995, "!is_relative"
))))
;
1996
1997 /* We need a temporary variable here so the unsigned math
1998 * works correctly (for years > 2036 according to RFC 2030
1999 * chapter 3).
2000 *
2001 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2002 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2003 * If bit 0 is not set, the time is in the range 2036-2104 and
2004 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2005 */
2006 tmpsecs = tvb_get_ntohl(tvb, start);
2007 if ((tmpsecs & 0x80000000) != 0)
2008 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2009 else
2010 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2011
2012 if (length == 8) {
2013 tmp64secs = tvb_get_ntoh64(tvb, start);
2014 if (tmp64secs == 0) {
2015 //This is "NULL" time
2016 time_stamp->secs = 0;
2017 time_stamp->nsecs = 0;
2018 } else {
2019 /*
2020 * Convert 1/2^32s of a second to
2021 * nanoseconds.
2022 */
2023 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2024 }
2025 } else if (length == 4) {
2026 /*
2027 * Backwards compatibility.
2028 */
2029 if (tmpsecs == 0) {
2030 //This is "NULL" time
2031 time_stamp->secs = 0;
2032 }
2033 time_stamp->nsecs = 0;
2034 } else {
2035 time_stamp->secs = 0;
2036 time_stamp->nsecs = 0;
2037 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2038 }
2039 break;
2040
2041 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2042 /*
2043 * NTP time stamp, little-endian.
2044 * Only supported for absolute times.
2045 *
2046 * NTP doesn't use this, because it's an Internet format
2047 * and hence big-endian. Any implementation must decide
2048 * whether the NTP timestamp is a 64-bit unsigned fixed
2049 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2050 * with a 32-bit unsigned seconds field followed by a
2051 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2052 * the previous two).
2053 *
2054 * XXX: We do the latter, but no dissector uses this format.
2055 * OTOH, ERF timestamps do the former, so perhaps we
2056 * should switch the interpretation so that packet-erf.c
2057 * could use this directly?
2058 */
2059 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2059, "!is_relative"
))))
;
2060
2061 /* We need a temporary variable here so the unsigned math
2062 * works correctly (for years > 2036 according to RFC 2030
2063 * chapter 3).
2064 *
2065 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2066 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2067 * If bit 0 is not set, the time is in the range 2036-2104 and
2068 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2069 */
2070 tmpsecs = tvb_get_letohl(tvb, start);
2071 if ((tmpsecs & 0x80000000) != 0)
2072 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2073 else
2074 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2075
2076 if (length == 8) {
2077 tmp64secs = tvb_get_letoh64(tvb, start);
2078 if (tmp64secs == 0) {
2079 //This is "NULL" time
2080 time_stamp->secs = 0;
2081 time_stamp->nsecs = 0;
2082 } else {
2083 /*
2084 * Convert 1/2^32s of a second to
2085 * nanoseconds.
2086 */
2087 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2088 }
2089 } else if (length == 4) {
2090 /*
2091 * Backwards compatibility.
2092 */
2093 if (tmpsecs == 0) {
2094 //This is "NULL" time
2095 time_stamp->secs = 0;
2096 }
2097 time_stamp->nsecs = 0;
2098 } else {
2099 time_stamp->secs = 0;
2100 time_stamp->nsecs = 0;
2101 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2102 }
2103 break;
2104
2105 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2106 /*
2107 * S/3x0 and z/Architecture TOD clock time stamp,
2108 * big-endian. The epoch is January 1, 1900,
2109 * 00:00:00 (proleptic?) UTC.
2110 *
2111 * Only supported for absolute times.
2112 */
2113 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2113, "!is_relative"
))))
;
2114 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2114, "length == 8"
))))
;
2115
2116 if (length == 8) {
2117 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2118 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2119 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2120 } else {
2121 time_stamp->secs = 0;
2122 time_stamp->nsecs = 0;
2123 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2124 }
2125 break;
2126
2127 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2128 /*
2129 * S/3x0 and z/Architecture TOD clock time stamp,
2130 * little-endian. The epoch is January 1, 1900,
2131 * 00:00:00 (proleptic?) UTC.
2132 *
2133 * Only supported for absolute times.
2134 */
2135 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2135, "!is_relative"
))))
;
2136
2137 if (length == 8) {
2138 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2139 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2140 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2141 } else {
2142 time_stamp->secs = 0;
2143 time_stamp->nsecs = 0;
2144 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2145 }
2146 break;
2147
2148 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2149 /*
2150 * Time stamp using the same seconds/fraction format
2151 * as NTP, but with the origin of the time stamp being
2152 * the UNIX epoch rather than the NTP epoch; big-
2153 * endian.
2154 *
2155 * Only supported for absolute times.
2156 */
2157 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2157, "!is_relative"
))))
;
2158
2159 if (length == 8) {
2160 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2161 /*
2162 * Convert 1/2^32s of a second to nanoseconds.
2163 */
2164 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2165 } else {
2166 time_stamp->secs = 0;
2167 time_stamp->nsecs = 0;
2168 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2169 }
2170 break;
2171
2172 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2173 /*
2174 * Time stamp using the same seconds/fraction format
2175 * as NTP, but with the origin of the time stamp being
2176 * the UNIX epoch rather than the NTP epoch; little-
2177 * endian.
2178 *
2179 * Only supported for absolute times.
2180 *
2181 * The RTPS specification explicitly supports Little
2182 * Endian encoding. In one place, it states that its
2183 * Time_t representation "is the one defined by ...
2184 * RFC 1305", but in another explicitly defines it as
2185 * a struct consisting of an 32 bit unsigned seconds
2186 * field and a 32 bit unsigned fraction field, not a 64
2187 * bit fixed point, so we do that here.
2188 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2189 */
2190 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2190, "!is_relative"
))))
;
2191
2192 if (length == 8) {
2193 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2194 /*
2195 * Convert 1/2^32s of a second to nanoseconds.
2196 */
2197 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2198 } else {
2199 time_stamp->secs = 0;
2200 time_stamp->nsecs = 0;
2201 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2202 }
2203 break;
2204
2205 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2206 /*
2207 * MIP6 time stamp, big-endian.
2208 * A 64-bit unsigned integer field containing a timestamp. The
2209 * value indicates the number of seconds since January 1, 1970,
2210 * 00:00 UTC, by using a fixed point format. In this format, the
2211 * integer number of seconds is contained in the first 48 bits of
2212 * the field, and the remaining 16 bits indicate the number of
2213 * 1/65536 fractions of a second.
2214
2215 * Only supported for absolute times.
2216 */
2217 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2217, "!is_relative"
))))
;
2218
2219 if (length == 8) {
2220 /* We need a temporary variable here so the casting and fractions
2221 * of a second work correctly.
2222 */
2223 tmp64secs = tvb_get_ntoh48(tvb, start);
2224 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2225 tmpsecs <<= 16;
2226
2227 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2228 //This is "NULL" time
2229 time_stamp->secs = 0;
2230 time_stamp->nsecs = 0;
2231 } else {
2232 time_stamp->secs = (time_t)tmp64secs;
2233 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2234 }
2235 } else {
2236 time_stamp->secs = 0;
2237 time_stamp->nsecs = 0;
2238 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2239 }
2240 break;
2241
2242 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2243 /*
2244 * If the length is 16, 8-byte seconds, followed
2245 * by 8-byte fractional time in microseconds,
2246 * both big-endian.
2247 *
2248 * If the length is 12, 8-byte seconds, followed
2249 * by 4-byte fractional time in microseconds,
2250 * both big-endian.
2251 *
2252 * If the length is 8, 4-byte seconds, followed
2253 * by 4-byte fractional time in microseconds,
2254 * both big-endian.
2255 *
2256 * For absolute times, the seconds are seconds
2257 * since the UN*X epoch.
2258 */
2259 if (length == 16) {
2260 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2261 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2262 } else if (length == 12) {
2263 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2264 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2265 } else if (length == 8) {
2266 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2267 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2268 } else {
2269 time_stamp->secs = 0;
2270 time_stamp->nsecs = 0;
2271 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2272 }
2273 break;
2274
2275 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2276 /*
2277 * If the length is 16, 8-byte seconds, followed
2278 * by 8-byte fractional time in microseconds,
2279 * both little-endian.
2280 *
2281 * If the length is 12, 8-byte seconds, followed
2282 * by 4-byte fractional time in microseconds,
2283 * both little-endian.
2284 *
2285 * If the length is 8, 4-byte seconds, followed
2286 * by 4-byte fractional time in microseconds,
2287 * both little-endian.
2288 *
2289 * For absolute times, the seconds are seconds
2290 * since the UN*X epoch.
2291 */
2292 if (length == 16) {
2293 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2294 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2295 } else if (length == 12) {
2296 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2297 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2298 } else if (length == 8) {
2299 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2300 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2301 } else {
2302 time_stamp->secs = 0;
2303 time_stamp->nsecs = 0;
2304 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2305 }
2306 break;
2307
2308 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2309 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2310 /*
2311 * Seconds, 1 to 8 bytes.
2312 * For absolute times, it's seconds since the
2313 * UN*X epoch.
2314 */
2315 if (length >= 1 && length <= 8) {
2316 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2317 time_stamp->nsecs = 0;
2318 } else {
2319 time_stamp->secs = 0;
2320 time_stamp->nsecs = 0;
2321 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2322 }
2323 break;
2324
2325 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2326 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2327 /*
2328 * Milliseconds, 1 to 8 bytes.
2329 * For absolute times, it's milliseconds since the
2330 * UN*X epoch.
2331 */
2332 if (length >= 1 && length <= 8) {
2333 uint64_t msecs;
2334
2335 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2336 time_stamp->secs = (time_t)(msecs / 1000);
2337 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2338 } else {
2339 time_stamp->secs = 0;
2340 time_stamp->nsecs = 0;
2341 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2342 }
2343 break;
2344
2345 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2346 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2347 /*
2348 * Microseconds, 1 to 8 bytes.
2349 * For absolute times, it's microseconds since the
2350 * UN*X epoch.
2351 */
2352 if (length >= 1 && length <= 8) {
2353 uint64_t usecs;
2354
2355 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2356 time_stamp->secs = (time_t)(usecs / 1000000);
2357 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2358 } else {
2359 time_stamp->secs = 0;
2360 time_stamp->nsecs = 0;
2361 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2362 }
2363 break;
2364
2365 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2366 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2367 /*
2368 * nanoseconds, 1 to 8 bytes.
2369 * For absolute times, it's nanoseconds since the
2370 * UN*X epoch.
2371 */
2372
2373 if (length >= 1 && length <= 8) {
2374 uint64_t nsecs;
2375
2376 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2377 time_stamp->secs = (time_t)(nsecs / 1000000000);
2378 time_stamp->nsecs = (int)(nsecs % 1000000000);
2379 } else {
2380 time_stamp->secs = 0;
2381 time_stamp->nsecs = 0;
2382 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2383 }
2384 break;
2385
2386 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2387 /*
2388 * 1/64ths of a second since the UN*X epoch,
2389 * big-endian.
2390 *
2391 * Only supported for absolute times.
2392 */
2393 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2393, "!is_relative"
))))
;
2394
2395 if (length == 8) {
2396 /*
2397 * The upper 48 bits are seconds since the
2398 * UN*X epoch.
2399 */
2400 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2401 /*
2402 * The lower 16 bits are 1/2^16s of a second;
2403 * convert them to nanoseconds.
2404 *
2405 * XXX - this may give the impression of higher
2406 * precision than you actually get.
2407 */
2408 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2409 } else {
2410 time_stamp->secs = 0;
2411 time_stamp->nsecs = 0;
2412 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2413 }
2414 break;
2415
2416 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2417 /*
2418 * 1/64ths of a second since the UN*X epoch,
2419 * little-endian.
2420 *
2421 * Only supported for absolute times.
2422 */
2423 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2423, "!is_relative"
))))
;
2424
2425 if (length == 8) {
2426 /*
2427 * XXX - this is assuming that, if anybody
2428 * were ever to use this format - RFC 3971
2429 * doesn't, because that's an Internet
2430 * protocol, and those use network byte
2431 * order, i.e. big-endian - they'd treat it
2432 * as a 64-bit count of 1/2^16s of a second,
2433 * putting the upper 48 bits at the end.
2434 *
2435 * The lower 48 bits are seconds since the
2436 * UN*X epoch.
2437 */
2438 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2439 /*
2440 * The upper 16 bits are 1/2^16s of a second;
2441 * convert them to nanoseconds.
2442 *
2443 * XXX - this may give the impression of higher
2444 * precision than you actually get.
2445 */
2446 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2447 } else {
2448 time_stamp->secs = 0;
2449 time_stamp->nsecs = 0;
2450 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2451 }
2452 break;
2453
2454 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2455 /*
2456 * NTP time stamp, with 1-second resolution (i.e.,
2457 * seconds since the NTP epoch), big-endian.
2458 * Only supported for absolute times.
2459 */
2460 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2460, "!is_relative"
))))
;
2461
2462 if (length == 4) {
2463 /*
2464 * We need a temporary variable here so the unsigned math
2465 * works correctly (for years > 2036 according to RFC 2030
2466 * chapter 3).
2467 *
2468 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2469 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2470 * If bit 0 is not set, the time is in the range 2036-2104 and
2471 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2472 */
2473 tmpsecs = tvb_get_ntohl(tvb, start);
2474 if ((tmpsecs & 0x80000000) != 0)
2475 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2476 else
2477 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2478 time_stamp->nsecs = 0;
2479 } else {
2480 time_stamp->secs = 0;
2481 time_stamp->nsecs = 0;
2482 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2483 }
2484 break;
2485
2486 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2487 /*
2488 * NTP time stamp, with 1-second resolution (i.e.,
2489 * seconds since the NTP epoch), little-endian.
2490 * Only supported for absolute times.
2491 */
2492 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2492, "!is_relative"
))))
;
2493
2494 /*
2495 * We need a temporary variable here so the unsigned math
2496 * works correctly (for years > 2036 according to RFC 2030
2497 * chapter 3).
2498 *
2499 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2500 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2501 * If bit 0 is not set, the time is in the range 2036-2104 and
2502 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2503 */
2504 if (length == 4) {
2505 tmpsecs = tvb_get_letohl(tvb, start);
2506 if ((tmpsecs & 0x80000000) != 0)
2507 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2508 else
2509 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2510 time_stamp->nsecs = 0;
2511 } else {
2512 time_stamp->secs = 0;
2513 time_stamp->nsecs = 0;
2514 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2515 }
2516 break;
2517
2518 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2519 /*
2520 * Milliseconds, 6 to 8 bytes.
2521 * For absolute times, it's milliseconds since the
2522 * NTP epoch.
2523 *
2524 * ETSI TS 129.274 8.119 defines this as:
2525 * "a 48 bit unsigned integer in network order format
2526 * ...encoded as the number of milliseconds since
2527 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2528 * rounded value of 1000 x the value of the 64-bit
2529 * timestamp (Seconds + (Fraction / (1<<32))) defined
2530 * in clause 6 of IETF RFC 5905."
2531 *
2532 * Taken literally, the part after "i.e." would
2533 * mean that the value rolls over before reaching
2534 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2535 * when the 64 bit timestamp rolls over, and we have
2536 * to pick an NTP Era equivalence class to support
2537 * (such as 1968-01-20 to 2104-02-06).
2538 *
2539 * OTOH, the extra room might be used to store Era
2540 * information instead, in which case times until
2541 * 10819-08-03 can be represented with 6 bytes without
2542 * ambiguity. We handle both implementations, and assume
2543 * that times before 1968-01-20 are not represented.
2544 *
2545 * Only 6 bytes or more makes sense as an absolute
2546 * time. 5 bytes or fewer could express a span of
2547 * less than 35 years, either 1900-1934 or 2036-2070.
2548 */
2549 if (length >= 6 && length <= 8) {
2550 uint64_t msecs;
2551
2552 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2553 tmp64secs = (msecs / 1000);
2554 /*
2555 * Assume that times in the first half of NTP
2556 * Era 0 really represent times in the NTP
2557 * Era 1.
2558 */
2559 if (tmp64secs >= 0x80000000)
2560 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2561 else
2562 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2563 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2564 }
2565 else {
2566 time_stamp->secs = 0;
2567 time_stamp->nsecs = 0;
2568 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2569 }
2570 break;
2571
2572 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2573 /*
2574 * MP4 file time stamps, big-endian.
2575 * Only supported for absolute times.
2576 */
2577 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2577, "!is_relative"
))))
;
2578
2579 if (length == 8) {
2580 tmp64secs = tvb_get_ntoh64(tvb, start);
2581 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2582 time_stamp->nsecs = 0;
2583 } else if (length == 4) {
2584 tmpsecs = tvb_get_ntohl(tvb, start);
2585 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2586 time_stamp->nsecs = 0;
2587 } else {
2588 time_stamp->secs = 0;
2589 time_stamp->nsecs = 0;
2590 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2591 }
2592 break;
2593
2594 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2595 /*
2596 * Zigbee ZCL time stamps, big-endian.
2597 * Only supported for absolute times.
2598 */
2599 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2599, "!is_relative"
))))
;
2600
2601 if (length == 8) {
2602 tmp64secs = tvb_get_ntoh64(tvb, start);
2603 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);
2604 time_stamp->nsecs = 0;
2605 } else if (length == 4) {
2606 tmpsecs = tvb_get_ntohl(tvb, start);
2607 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2608 time_stamp->nsecs = 0;
2609 } else {
2610 time_stamp->secs = 0;
2611 time_stamp->nsecs = 0;
2612 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2613 }
2614 break;
2615
2616 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2617 /*
2618 * Zigbee ZCL time stamps, little-endian.
2619 * Only supported for absolute times.
2620 */
2621 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2621, "!is_relative"
))))
;
2622
2623 if (length == 8) {
2624 tmp64secs = tvb_get_letoh64(tvb, start);
2625 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);
2626 time_stamp->nsecs = 0;
2627 } else if (length == 4) {
2628 tmpsecs = tvb_get_letohl(tvb, start);
2629 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2630 time_stamp->nsecs = 0;
2631 } else {
2632 time_stamp->secs = 0;
2633 time_stamp->nsecs = 0;
2634 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2635 }
2636 break;
2637
2638 default:
2639 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2639))
;
2640 break;
2641 }
2642}
2643
2644static void
2645tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2646{
2647 const header_field_info *hfinfo = fi->hfinfo;
2648
2649 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2650 GPtrArray *ptrs = NULL((void*)0);
2651
2652 if (tree_data->interesting_hfids == NULL((void*)0)) {
2653 /* Initialize the hash because we now know that it is needed */
2654 tree_data->interesting_hfids =
2655 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2656 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2657 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2658 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2659 }
2660
2661 if (!ptrs) {
2662 /* First element triggers the creation of pointer array */
2663 ptrs = g_ptr_array_new();
2664 g_hash_table_insert(tree_data->interesting_hfids,
2665 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2666 }
2667
2668 g_ptr_array_add(ptrs, fi);
2669 }
2670}
2671
2672
2673/*
2674 * Validates that field length bytes are available starting from
2675 * start (pos/neg). Throws an exception if they aren't.
2676 */
2677static void
2678test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2679 int start, int length, const unsigned encoding)
2680{
2681 int size = length;
2682
2683 if (!tvb)
2684 return;
2685
2686 if ((hfinfo->type == FT_STRINGZ) ||
2687 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2688 (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
))
))) {
2689 /* If we're fetching until the end of the TVB, only validate
2690 * that the offset is within range.
2691 */
2692 if (length == -1)
2693 size = 0;
2694 }
2695
2696 tvb_ensure_bytes_exist(tvb, start, size);
2697}
2698
2699static void
2700detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2701{
2702 bool_Bool found_stray_character = false0;
2703
2704 if (!string)
2705 return;
2706
2707 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2708 case ENC_ASCII0x00000000:
2709 case ENC_UTF_80x00000002:
2710 for (int i = (int)strlen(string); i < length; i++) {
2711 if (string[i] != '\0') {
2712 found_stray_character = true1;
2713 break;
2714 }
2715 }
2716 break;
2717
2718 default:
2719 break;
2720 }
2721
2722 if (found_stray_character) {
2723 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2724 }
2725}
2726
2727static void
2728free_fvalue_cb(void *data)
2729{
2730 fvalue_t *fv = (fvalue_t*)data;
2731 fvalue_free(fv);
2732}
2733
2734/* Add an item to a proto_tree, using the text label registered to that item;
2735 the item is extracted from the tvbuff handed to it. */
2736static proto_item *
2737proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2738 tvbuff_t *tvb, int start, int length,
2739 unsigned encoding)
2740{
2741 proto_item *pi;
2742 uint32_t value, n;
2743 uint64_t value64;
2744 ws_in4_addr ipv4_value;
2745 float floatval;
2746 double doubleval;
2747 const char *stringval = NULL((void*)0);
2748 nstime_t time_stamp;
2749 bool_Bool length_error;
2750
2751 /* Ensure that the newly created fvalue_t is freed if we throw an
2752 * exception before adding it to the tree. (gcc creates clobbering
2753 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2754 * XXX: Move the new_field_info() call inside here?
2755 */
2756 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))
;
2757
2758 switch (new_fi->hfinfo->type) {
2759 case FT_NONE:
2760 /* no value to set for FT_NONE */
2761 break;
2762
2763 case FT_PROTOCOL:
2764 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2765 break;
2766
2767 case FT_BYTES:
2768 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2769 break;
2770
2771 case FT_UINT_BYTES:
2772 n = get_uint_value(tree, tvb, start, length, encoding);
2773 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2774
2775 /* Instead of calling proto_item_set_len(), since we don't yet
2776 * have a proto_item, we set the field_info's length ourselves. */
2777 new_fi->length = n + length;
2778 break;
2779
2780 case FT_BOOLEAN:
2781 /*
2782 * Map all non-zero values to little-endian for
2783 * backwards compatibility.
2784 */
2785 if (encoding)
2786 encoding = ENC_LITTLE_ENDIAN0x80000000;
2787 proto_tree_set_boolean(new_fi,
2788 get_uint64_value(tree, tvb, start, length, encoding));
2789 break;
2790
2791 case FT_CHAR:
2792 /* XXX - make these just FT_UINT? */
2793 case FT_UINT8:
2794 case FT_UINT16:
2795 case FT_UINT24:
2796 case FT_UINT32:
2797 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2798 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2799 value = (uint32_t)value64;
2800 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2801 new_fi->flags |= FI_VARINT0x00040000;
2802 }
2803 }
2804 else {
2805 /*
2806 * Map all non-zero values to little-endian for
2807 * backwards compatibility.
2808 */
2809 if (encoding)
2810 encoding = ENC_LITTLE_ENDIAN0x80000000;
2811
2812 value = get_uint_value(tree, tvb, start, length, encoding);
2813 }
2814 proto_tree_set_uint(new_fi, value);
2815 break;
2816
2817 case FT_UINT40:
2818 case FT_UINT48:
2819 case FT_UINT56:
2820 case FT_UINT64:
2821 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2822 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2823 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2824 new_fi->flags |= FI_VARINT0x00040000;
2825 }
2826 }
2827 else {
2828 /*
2829 * Map all other non-zero values to little-endian for
2830 * backwards compatibility.
2831 */
2832 if (encoding)
2833 encoding = ENC_LITTLE_ENDIAN0x80000000;
2834
2835 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2836 }
2837 proto_tree_set_uint64(new_fi, value64);
2838 break;
2839
2840 /* XXX - make these just FT_INT? */
2841 case FT_INT8:
2842 case FT_INT16:
2843 case FT_INT24:
2844 case FT_INT32:
2845 /*
2846 * Map all non-zero values to little-endian for
2847 * backwards compatibility.
2848 */
2849 if (encoding)
2850 encoding = ENC_LITTLE_ENDIAN0x80000000;
2851 proto_tree_set_int(new_fi,
2852 get_int_value(tree, tvb, start, length, encoding));
2853 break;
2854
2855 case FT_INT40:
2856 case FT_INT48:
2857 case FT_INT56:
2858 case FT_INT64:
2859 /*
2860 * Map all non-zero values to little-endian for
2861 * backwards compatibility.
2862 */
2863 if (encoding)
2864 encoding = ENC_LITTLE_ENDIAN0x80000000;
2865 proto_tree_set_int64(new_fi,
2866 get_int64_value(tree, tvb, start, length, encoding));
2867 break;
2868
2869 case FT_IPv4:
2870 /*
2871 * Map all non-zero values to little-endian for
2872 * backwards compatibility.
2873 */
2874 if (encoding)
2875 encoding = ENC_LITTLE_ENDIAN0x80000000;
2876 if (length != FT_IPv4_LEN4) {
2877 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2878 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2879 }
2880 ipv4_value = tvb_get_ipv4(tvb, start);
2881 /*
2882 * NOTE: to support code written when
2883 * proto_tree_add_item() took a bool as its
2884 * last argument, with false meaning "big-endian"
2885 * and true meaning "little-endian", we treat any
2886 * non-zero value of "encoding" as meaning
2887 * "little-endian".
2888 */
2889 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);
2890 break;
2891
2892 case FT_IPXNET:
2893 if (length != FT_IPXNET_LEN4) {
2894 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2895 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2896 }
2897 proto_tree_set_ipxnet(new_fi,
2898 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2899 break;
2900
2901 case FT_IPv6:
2902 if (length != FT_IPv6_LEN16) {
2903 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2904 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2905 }
2906 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2907 break;
2908
2909 case FT_FCWWN:
2910 if (length != FT_FCWWN_LEN8) {
2911 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2912 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2913 }
2914 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2915 break;
2916
2917 case FT_AX25:
2918 if (length != 7) {
2919 length_error = length < 7 ? true1 : false0;
2920 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2921 }
2922 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2923 break;
2924
2925 case FT_VINES:
2926 if (length != VINES_ADDR_LEN6) {
2927 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
2928 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2929 }
2930 proto_tree_set_vines_tvb(new_fi, tvb, start);
2931 break;
2932
2933 case FT_ETHER:
2934 if (length != FT_ETHER_LEN6) {
2935 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
2936 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2937 }
2938 proto_tree_set_ether_tvb(new_fi, tvb, start);
2939 break;
2940
2941 case FT_EUI64:
2942 /*
2943 * Map all non-zero values to little-endian for
2944 * backwards compatibility.
2945 */
2946 if (encoding)
2947 encoding = ENC_LITTLE_ENDIAN0x80000000;
2948 if (length != FT_EUI64_LEN8) {
2949 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
2950 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2951 }
2952 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2953 break;
2954 case FT_GUID:
2955 /*
2956 * Map all non-zero values to little-endian for
2957 * backwards compatibility.
2958 */
2959 if (encoding)
2960 encoding = ENC_LITTLE_ENDIAN0x80000000;
2961 if (length != FT_GUID_LEN16) {
2962 length_error = length < FT_GUID_LEN16 ? true1 : false0;
2963 report_type_length_mismatch(tree, "a GUID", length, length_error);
2964 }
2965 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2966 break;
2967
2968 case FT_OID:
2969 case FT_REL_OID:
2970 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2971 break;
2972
2973 case FT_SYSTEM_ID:
2974 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2975 break;
2976
2977 case FT_FLOAT:
2978 /*
2979 * NOTE: to support code written when
2980 * proto_tree_add_item() took a bool as its
2981 * last argument, with false meaning "big-endian"
2982 * and true meaning "little-endian", we treat any
2983 * non-zero value of "encoding" as meaning
2984 * "little-endian".
2985 *
2986 * At some point in the future, we might
2987 * support non-IEEE-binary floating-point
2988 * formats in the encoding as well
2989 * (IEEE decimal, System/3x0, VAX).
2990 */
2991 if (encoding)
2992 encoding = ENC_LITTLE_ENDIAN0x80000000;
2993 if (length != 4) {
2994 length_error = length < 4 ? true1 : false0;
2995 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
2996 }
2997 if (encoding)
2998 floatval = tvb_get_letohieee_float(tvb, start);
2999 else
3000 floatval = tvb_get_ntohieee_float(tvb, start);
3001 proto_tree_set_float(new_fi, floatval);
3002 break;
3003
3004 case FT_DOUBLE:
3005 /*
3006 * NOTE: to support code written when
3007 * proto_tree_add_item() took a bool as its
3008 * last argument, with false meaning "big-endian"
3009 * and true meaning "little-endian", we treat any
3010 * non-zero value of "encoding" as meaning
3011 * "little-endian".
3012 *
3013 * At some point in the future, we might
3014 * support non-IEEE-binary floating-point
3015 * formats in the encoding as well
3016 * (IEEE decimal, System/3x0, VAX).
3017 */
3018 if (encoding == true1)
3019 encoding = ENC_LITTLE_ENDIAN0x80000000;
3020 if (length != 8) {
3021 length_error = length < 8 ? true1 : false0;
3022 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3023 }
3024 if (encoding)
3025 doubleval = tvb_get_letohieee_double(tvb, start);
3026 else
3027 doubleval = tvb_get_ntohieee_double(tvb, start);
3028 proto_tree_set_double(new_fi, doubleval);
3029 break;
3030
3031 case FT_STRING:
3032 stringval = get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3033 tvb, start, length, &length, encoding);
3034 proto_tree_set_string(new_fi, stringval);
3035
3036 /* Instead of calling proto_item_set_len(), since we
3037 * don't yet have a proto_item, we set the
3038 * field_info's length ourselves.
3039 *
3040 * XXX - our caller can't use that length to
3041 * advance an offset unless they arrange that
3042 * there always be a protocol tree into which
3043 * we're putting this item.
3044 */
3045 new_fi->length = length;
3046 break;
3047
3048 case FT_STRINGZ:
3049 stringval = get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3050 tree, tvb, start, length, &length, encoding);
3051 proto_tree_set_string(new_fi, stringval);
3052
3053 /* Instead of calling proto_item_set_len(),
3054 * since we don't yet have a proto_item, we
3055 * set the field_info's length ourselves.
3056 *
3057 * XXX - our caller can't use that length to
3058 * advance an offset unless they arrange that
3059 * there always be a protocol tree into which
3060 * we're putting this item.
3061 */
3062 new_fi->length = length;
3063 break;
3064
3065 case FT_UINT_STRING:
3066 /*
3067 * NOTE: to support code written when
3068 * proto_tree_add_item() took a bool as its
3069 * last argument, with false meaning "big-endian"
3070 * and true meaning "little-endian", if the
3071 * encoding value is true, treat that as
3072 * ASCII with a little-endian length.
3073 *
3074 * This won't work for code that passes
3075 * arbitrary non-zero values; that code
3076 * will need to be fixed.
3077 */
3078 if (encoding == true1)
3079 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3080 stringval = get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3081 tree, tvb, start, length, &length, encoding);
3082 proto_tree_set_string(new_fi, stringval);
3083
3084 /* Instead of calling proto_item_set_len(), since we
3085 * don't yet have a proto_item, we set the
3086 * field_info's length ourselves.
3087 *
3088 * XXX - our caller can't use that length to
3089 * advance an offset unless they arrange that
3090 * there always be a protocol tree into which
3091 * we're putting this item.
3092 */
3093 new_fi->length = length;
3094 break;
3095
3096 case FT_STRINGZPAD:
3097 stringval = get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3098 tvb, start, length, &length, encoding);
3099 proto_tree_set_string(new_fi, stringval);
3100
3101 /* Instead of calling proto_item_set_len(), since we
3102 * don't yet have a proto_item, we set the
3103 * field_info's length ourselves.
3104 *
3105 * XXX - our caller can't use that length to
3106 * advance an offset unless they arrange that
3107 * there always be a protocol tree into which
3108 * we're putting this item.
3109 */
3110 new_fi->length = length;
3111 break;
3112
3113 case FT_STRINGZTRUNC:
3114 stringval = get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3115 tvb, start, length, &length, encoding);
3116 proto_tree_set_string(new_fi, stringval);
3117
3118 /* Instead of calling proto_item_set_len(), since we
3119 * don't yet have a proto_item, we set the
3120 * field_info's length ourselves.
3121 *
3122 * XXX - our caller can't use that length to
3123 * advance an offset unless they arrange that
3124 * there always be a protocol tree into which
3125 * we're putting this item.
3126 */
3127 new_fi->length = length;
3128 break;
3129
3130 case FT_ABSOLUTE_TIME:
3131 /*
3132 * Absolute times can be in any of a number of
3133 * formats, and they can be big-endian or
3134 * little-endian.
3135 *
3136 * Historically FT_TIMEs were only timespecs;
3137 * the only question was whether they were stored
3138 * in big- or little-endian format.
3139 *
3140 * For backwards compatibility, we interpret an
3141 * encoding of 1 as meaning "little-endian timespec",
3142 * so that passing true is interpreted as that.
3143 */
3144 if (encoding == true1)
3145 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3146
3147 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3148
3149 proto_tree_set_time(new_fi, &time_stamp);
3150 break;
3151
3152 case FT_RELATIVE_TIME:
3153 /*
3154 * Relative times can be in any of a number of
3155 * formats, and they can be big-endian or
3156 * little-endian.
3157 *
3158 * Historically FT_TIMEs were only timespecs;
3159 * the only question was whether they were stored
3160 * in big- or little-endian format.
3161 *
3162 * For backwards compatibility, we interpret an
3163 * encoding of 1 as meaning "little-endian timespec",
3164 * so that passing true is interpreted as that.
3165 */
3166 if (encoding == true1)
3167 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3168
3169 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3170
3171 proto_tree_set_time(new_fi, &time_stamp);
3172 break;
3173 case FT_IEEE_11073_SFLOAT:
3174 if (encoding)
3175 encoding = ENC_LITTLE_ENDIAN0x80000000;
3176 if (length != 2) {
3177 length_error = length < 2 ? true1 : false0;
3178 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3179 }
3180
3181 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3182
3183 break;
3184 case FT_IEEE_11073_FLOAT:
3185 if (encoding)
3186 encoding = ENC_LITTLE_ENDIAN0x80000000;
3187 if (length != 4) {
3188 length_error = length < 4 ? true1 : false0;
3189 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3190 }
3191 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3192
3193 break;
3194 default:
3195 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))
3196 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))
3197 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))
3198 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))
;
3199 break;
3200 }
3201 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)
;
3202
3203 /* Don't add new node to proto_tree until now so that any exceptions
3204 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3205 /* XXX. wouldn't be better to add this item to tree, with some special
3206 * flag (FI_EXCEPTION?) to know which item caused exception? For
3207 * strings and bytes, we would have to set new_fi->value to something
3208 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3209 * could handle NULL values. */
3210 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3211 pi = proto_tree_add_node(tree, new_fi);
3212
3213 switch (new_fi->hfinfo->type) {
3214
3215 case FT_STRING:
3216 /* XXX: trailing stray character detection should be done
3217 * _before_ conversion to UTF-8, because conversion can change
3218 * the length, or else get_string_length should return a value
3219 * for the "length in bytes of the string after conversion
3220 * including internal nulls." (Noting that we do, for other
3221 * reasons, still need the "length in bytes in the field",
3222 * especially for FT_STRINGZ.)
3223 *
3224 * This is true even for ASCII and UTF-8, because
3225 * substituting REPLACEMENT CHARACTERS for illegal characters
3226 * can also do so (and for UTF-8 possibly even make the
3227 * string _shorter_).
3228 */
3229 detect_trailing_stray_characters(encoding, stringval, length, pi);
3230 break;
3231
3232 default:
3233 break;
3234 }
3235
3236 return pi;
3237}
3238
3239proto_item *
3240proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3241 const int start, int length,
3242 const unsigned encoding, int32_t *retval)
3243{
3244 header_field_info *hfinfo;
3245 field_info *new_fi;
3246 int32_t value;
3247
3248 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", 3248, __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", 3248,
"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", 3248, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3249
3250 switch (hfinfo->type) {
3251 case FT_INT8:
3252 case FT_INT16:
3253 case FT_INT24:
3254 case FT_INT32:
3255 break;
3256 case FT_INT64:
3257 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)
3258 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3259 default:
3260 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)
3261 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3262 }
3263
3264 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3265 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3266 if(retval)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 *retval = 0;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 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3271
3272 if (encoding & ENC_STRING0x03000000) {
3273 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3274 }
3275 /* I believe it's ok if this is called with a NULL tree */
3276 value = get_int_value(tree, tvb, start, length, encoding);
3277
3278 if (retval) {
3279 int no_of_bits;
3280 *retval = value;
3281 if (hfinfo->bitmask) {
3282 /* Mask out irrelevant portions */
3283 *retval &= (uint32_t)(hfinfo->bitmask);
3284 /* Shift bits */
3285 *retval >>= hfinfo_bitshift(hfinfo);
3286 }
3287 no_of_bits = ws_count_ones(hfinfo->bitmask);
3288 *retval = ws_sign_ext32(*retval, no_of_bits);
3289 }
3290
3291 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3292
3293 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", 3293
, __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", 3293, "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", 3293, "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", 3293, __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)
; } } }
;
3294
3295 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3296
3297 proto_tree_set_int(new_fi, value);
3298
3299 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3300
3301 return proto_tree_add_node(tree, new_fi);
3302}
3303
3304proto_item *
3305proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3306 const int start, int length,
3307 const unsigned encoding, uint32_t *retval)
3308{
3309 header_field_info *hfinfo;
3310 field_info *new_fi;
3311 uint32_t value;
3312
3313 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", 3313, __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", 3313,
"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", 3313, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3314
3315 switch (hfinfo->type) {
3316 case FT_CHAR:
3317 case FT_UINT8:
3318 case FT_UINT16:
3319 case FT_UINT24:
3320 case FT_UINT32:
3321 break;
3322 default:
3323 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)
3324 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)
;
3325 }
3326
3327 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3328 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3329 if(retval)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 *retval = 0;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 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3334
3335 if (encoding & ENC_STRING0x03000000) {
3336 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3337 }
3338 /* I believe it's ok if this is called with a NULL tree */
3339 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3340 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3341 uint64_t temp64;
3342 tvb_get_varint(tvb, start, length, &temp64, encoding);
3343 value = (uint32_t)temp64;
3344 } else {
3345 value = get_uint_value(tree, tvb, start, length, encoding);
3346 }
3347
3348 if (retval) {
3349 *retval = value;
3350 if (hfinfo->bitmask) {
3351 /* Mask out irrelevant portions */
3352 *retval &= (uint32_t)(hfinfo->bitmask);
3353 /* Shift bits */
3354 *retval >>= hfinfo_bitshift(hfinfo);
3355 }
3356 }
3357
3358 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3359
3360 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", 3360
, __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", 3360, "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", 3360, "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", 3360, __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)
; } } }
;
3361
3362 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3363
3364 proto_tree_set_uint(new_fi, value);
3365
3366 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3367 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3368 new_fi->flags |= FI_VARINT0x00040000;
3369 }
3370 return proto_tree_add_node(tree, new_fi);
3371}
3372
3373/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3374 * and returns proto_item* and uint value retreived*/
3375proto_item *
3376ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3377 const unsigned encoding, uint32_t *retval)
3378{
3379 field_info *new_fi;
3380 header_field_info *hfinfo;
3381 int item_length;
3382 int offset;
3383 uint32_t value;
3384
3385 offset = ptvc->offset;
3386 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", 3386, __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", 3386,
"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", 3386, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3387
3388 switch (hfinfo->type) {
3389 case FT_CHAR:
3390 case FT_UINT8:
3391 case FT_UINT16:
3392 case FT_UINT24:
3393 case FT_UINT32:
3394 break;
3395 default:
3396 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)
3397 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)
;
3398 }
3399
3400 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3401 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3402
3403 /* I believe it's ok if this is called with a NULL tree */
3404 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3405 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3406
3407 if (retval) {
3408 *retval = value;
3409 if (hfinfo->bitmask) {
3410 /* Mask out irrelevant portions */
3411 *retval &= (uint32_t)(hfinfo->bitmask);
3412 /* Shift bits */
3413 *retval >>= hfinfo_bitshift(hfinfo);
3414 }
3415 }
3416
3417 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3418 item_length, encoding);
3419
3420 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3421
3422 /* Coast clear. Try and fake it */
3423 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", 3423
, __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", 3423, "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", 3423, "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", 3423, __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); } } }
;
3424
3425 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3426
3427 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3428 offset, length, encoding);
3429}
3430
3431/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3432 * and returns proto_item* and int value retreived*/
3433proto_item *
3434ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3435 const unsigned encoding, int32_t *retval)
3436{
3437 field_info *new_fi;
3438 header_field_info *hfinfo;
3439 int item_length;
3440 int offset;
3441 uint32_t value;
3442
3443 offset = ptvc->offset;
3444 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", 3444, __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", 3444,
"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", 3444, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3445
3446 switch (hfinfo->type) {
3447 case FT_INT8:
3448 case FT_INT16:
3449 case FT_INT24:
3450 case FT_INT32:
3451 break;
3452 default:
3453 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)
3454 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3455 }
3456
3457 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3458 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3459
3460 /* I believe it's ok if this is called with a NULL tree */
3461 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3462 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3463
3464 if (retval) {
3465 int no_of_bits;
3466 *retval = value;
3467 if (hfinfo->bitmask) {
3468 /* Mask out irrelevant portions */
3469 *retval &= (uint32_t)(hfinfo->bitmask);
3470 /* Shift bits */
3471 *retval >>= hfinfo_bitshift(hfinfo);
3472 }
3473 no_of_bits = ws_count_ones(hfinfo->bitmask);
3474 *retval = ws_sign_ext32(*retval, no_of_bits);
3475 }
3476
3477 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3478 item_length, encoding);
3479
3480 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3481
3482 /* Coast clear. Try and fake it */
3483 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", 3483
, __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", 3483, "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", 3483, "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", 3483, __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); } } }
;
3484
3485 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3486
3487 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3488 offset, length, encoding);
3489}
3490
3491/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3492 * and returns proto_item* and string value retreived */
3493proto_item*
3494ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3495{
3496 header_field_info *hfinfo;
3497 field_info *new_fi;
3498 const uint8_t *value;
3499 int item_length;
3500 int offset;
3501
3502 offset = ptvc->offset;
3503
3504 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", 3504
, __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", 3504, "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", 3504, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3505
3506 switch (hfinfo->type) {
3507 case FT_STRING:
3508 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3509 break;
3510 case FT_STRINGZ:
3511 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3512 break;
3513 case FT_UINT_STRING:
3514 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3515 break;
3516 case FT_STRINGZPAD:
3517 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3518 break;
3519 case FT_STRINGZTRUNC:
3520 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3521 break;
3522 default:
3523 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)
3524 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)
;
3525 }
3526
3527 if (retval)
3528 *retval = value;
3529
3530 ptvc->offset += item_length;
3531
3532 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3533
3534 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", 3534, __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", 3534,
"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", 3534, "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", 3534
, __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); } } }
;
3535
3536 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3537
3538 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3539 offset, length, encoding);
3540}
3541
3542/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3543 * and returns proto_item* and boolean value retreived */
3544proto_item*
3545ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3546{
3547 header_field_info *hfinfo;
3548 field_info *new_fi;
3549 int item_length;
3550 int offset;
3551 uint64_t value, bitval;
3552
3553 offset = ptvc->offset;
3554 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", 3554, __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", 3554,
"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", 3554, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3555
3556 if (hfinfo->type != FT_BOOLEAN) {
3557 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)
3558 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3559 }
3560
3561 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3562 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3563 if(retval)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 *retval = false;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 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3568
3569 if (encoding & ENC_STRING0x03000000) {
3570 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3571 }
3572
3573 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3574 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3575
3576 /* I believe it's ok if this is called with a NULL tree */
3577 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3578
3579 if (retval) {
3580 bitval = value;
3581 if (hfinfo->bitmask) {
3582 /* Mask out irrelevant portions */
3583 bitval &= hfinfo->bitmask;
3584 }
3585 *retval = (bitval != 0);
3586 }
3587
3588 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3589 item_length, encoding);
3590
3591 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3592
3593 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", 3593, __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", 3593,
"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", 3593, "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", 3593
, __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); } } }
;
3594
3595 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3596
3597 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3598 offset, length, encoding);
3599}
3600
3601proto_item *
3602proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3603 const int start, int length, const unsigned encoding, uint64_t *retval)
3604{
3605 header_field_info *hfinfo;
3606 field_info *new_fi;
3607 uint64_t value;
3608
3609 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", 3609, __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", 3609,
"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", 3609, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3610
3611 switch (hfinfo->type) {
3612 case FT_UINT40:
3613 case FT_UINT48:
3614 case FT_UINT56:
3615 case FT_UINT64:
3616 break;
3617 default:
3618 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)
3619 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3620 }
3621
3622 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3623 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3624 if(retval)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 *retval = 0;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 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3629
3630 if (encoding & ENC_STRING0x03000000) {
3631 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3632 }
3633 /* I believe it's ok if this is called with a NULL tree */
3634 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3635 tvb_get_varint(tvb, start, length, &value, encoding);
3636 } else {
3637 value = get_uint64_value(tree, tvb, start, length, encoding);
3638 }
3639
3640 if (retval) {
3641 *retval = value;
3642 if (hfinfo->bitmask) {
3643 /* Mask out irrelevant portions */
3644 *retval &= hfinfo->bitmask;
3645 /* Shift bits */
3646 *retval >>= hfinfo_bitshift(hfinfo);
3647 }
3648 }
3649
3650 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3651
3652 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", 3652
, __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", 3652, "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", 3652, "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", 3652, __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)
; } } }
;
3653
3654 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3655
3656 proto_tree_set_uint64(new_fi, value);
3657
3658 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3659 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3660 new_fi->flags |= FI_VARINT0x00040000;
3661 }
3662
3663 return proto_tree_add_node(tree, new_fi);
3664}
3665
3666proto_item *
3667proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3668 const int start, int length, const unsigned encoding, int64_t *retval)
3669{
3670 header_field_info *hfinfo;
3671 field_info *new_fi;
3672 int64_t value;
3673
3674 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", 3674, __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", 3674,
"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", 3674, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3675
3676 switch (hfinfo->type) {
3677 case FT_INT40:
3678 case FT_INT48:
3679 case FT_INT56:
3680 case FT_INT64:
3681 break;
3682 default:
3683 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)
3684 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3685 }
3686
3687 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3688 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3689 if(retval)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 *retval = 0;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 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3694
3695 if (encoding & ENC_STRING0x03000000) {
3696 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3697 }
3698 /* I believe it's ok if this is called with a NULL tree */
3699 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3700 tvb_get_varint(tvb, start, length, &value, encoding);
3701 }
3702 else {
3703 value = get_int64_value(tree, tvb, start, length, encoding);
3704 }
3705
3706 if (retval) {
3707 *retval = value;
3708 }
3709
3710 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3711
3712 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", 3712
, __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", 3712, "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", 3712, "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", 3712, __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)
; } } }
;
3713
3714 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3715
3716 proto_tree_set_int64(new_fi, value);
3717
3718 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3719 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3720 new_fi->flags |= FI_VARINT0x00040000;
3721 }
3722
3723 return proto_tree_add_node(tree, new_fi);
3724}
3725
3726proto_item *
3727proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3728 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3729{
3730 header_field_info *hfinfo;
3731 field_info *new_fi;
3732 uint64_t value;
3733
3734 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", 3734, __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", 3734,
"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", 3734, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3735
3736 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
))
)) {
3737 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)
3738 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3739 }
3740
3741 /* length validation for native number encoding caught by get_uint64_value() */
3742 /* length has to be -1 or > 0 regardless of encoding */
3743 if (length == 0)
3744 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)
3745 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3746
3747 if (encoding & ENC_STRING0x03000000) {
3748 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3749 }
3750
3751 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3752
3753 if (retval) {
3754 *retval = value;
3755 if (hfinfo->bitmask) {
3756 /* Mask out irrelevant portions */
3757 *retval &= hfinfo->bitmask;
3758 /* Shift bits */
3759 *retval >>= hfinfo_bitshift(hfinfo);
3760 }
3761 }
3762
3763 if (lenretval) {
3764 *lenretval = length;
3765 }
3766
3767 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3768
3769 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", 3769
, __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", 3769, "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", 3769, "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", 3769, __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)
; } } }
;
3770
3771 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3772
3773 proto_tree_set_uint64(new_fi, value);
3774
3775 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3776 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3777 new_fi->flags |= FI_VARINT0x00040000;
3778 }
3779
3780 return proto_tree_add_node(tree, new_fi);
3781
3782}
3783
3784proto_item *
3785proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3786 const int start, int length,
3787 const unsigned encoding, bool_Bool *retval)
3788{
3789 header_field_info *hfinfo;
3790 field_info *new_fi;
3791 uint64_t value, bitval;
3792
3793 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", 3793, __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", 3793,
"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", 3793, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3794
3795 if (hfinfo->type != FT_BOOLEAN) {
3796 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)
3797 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3798 }
3799
3800 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3801 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3802 if(retval)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 *retval = false;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 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3807
3808 if (encoding & ENC_STRING0x03000000) {
3809 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3810 }
3811 /* I believe it's ok if this is called with a NULL tree */
3812 value = get_uint64_value(tree, tvb, start, length, encoding);
3813
3814 if (retval) {
3815 bitval = value;
3816 if (hfinfo->bitmask) {
3817 /* Mask out irrelevant portions */
3818 bitval &= hfinfo->bitmask;
3819 }
3820 *retval = (bitval != 0);
3821 }
3822
3823 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3824
3825 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", 3825
, __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", 3825, "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", 3825, "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", 3825, __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)
; } } }
;
3826
3827 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3828
3829 proto_tree_set_boolean(new_fi, value);
3830
3831 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3832
3833 return proto_tree_add_node(tree, new_fi);
3834}
3835
3836proto_item *
3837proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3838 const int start, int length,
3839 const unsigned encoding, float *retval)
3840{
3841 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3842 field_info *new_fi;
3843 float value;
3844
3845 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", 3845,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3846
3847 if (hfinfo->type != FT_FLOAT) {
3848 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)
;
3849 }
3850
3851 if (length != 4) {
3852 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3853 }
3854
3855 /* treat any nonzero encoding as little endian for backwards compatibility */
3856 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3857 if (retval) {
3858 *retval = value;
3859 }
3860
3861 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3862
3863 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", 3863
, __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", 3863, "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", 3863, "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", 3863, __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)
; } } }
;
3864
3865 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3866 if (encoding) {
3867 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3868 }
3869
3870 proto_tree_set_float(new_fi, value);
3871
3872 return proto_tree_add_node(tree, new_fi);
3873}
3874
3875proto_item *
3876proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3877 const int start, int length,
3878 const unsigned encoding, double *retval)
3879{
3880 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3881 field_info *new_fi;
3882 double value;
3883
3884 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", 3884,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3885
3886 if (hfinfo->type != FT_DOUBLE) {
3887 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)
;
3888 }
3889
3890 if (length != 8) {
3891 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3892 }
3893
3894 /* treat any nonzero encoding as little endian for backwards compatibility */
3895 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3896 if (retval) {
3897 *retval = value;
3898 }
3899
3900 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3901
3902 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", 3902
, __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", 3902, "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", 3902, "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", 3902, __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)
; } } }
;
3903
3904 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3905 if (encoding) {
3906 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3907 }
3908
3909 proto_tree_set_double(new_fi, value);
3910
3911 return proto_tree_add_node(tree, new_fi);
3912}
3913
3914proto_item *
3915proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3916 const int start, int length,
3917 const unsigned encoding, ws_in4_addr *retval)
3918{
3919 header_field_info *hfinfo;
3920 field_info *new_fi;
3921 ws_in4_addr value;
3922
3923 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", 3923, __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", 3923,
"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", 3923, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3924
3925 switch (hfinfo->type) {
3926 case FT_IPv4:
3927 break;
3928 default:
3929 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)
3930 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
3931 }
3932
3933 if (length != FT_IPv4_LEN4)
3934 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)
3935 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
3936
3937 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3938 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3939 }
3940
3941 /*
3942 * NOTE: to support code written when proto_tree_add_item() took
3943 * a bool as its last argument, with false meaning "big-endian"
3944 * and true meaning "little-endian", we treat any non-zero value
3945 * of "encoding" as meaning "little-endian".
3946 */
3947 value = tvb_get_ipv4(tvb, start);
3948 if (encoding)
3949 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))))
;
3950
3951 if (retval) {
3952 *retval = value;
3953 }
3954
3955 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3956
3957 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", 3957
, __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", 3957, "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", 3957, "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", 3957, __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)
; } } }
;
3958
3959 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3960
3961 proto_tree_set_ipv4(new_fi, value);
3962
3963 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3964 return proto_tree_add_node(tree, new_fi);
3965}
3966
3967proto_item *
3968proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3969 const int start, int length,
3970 const unsigned encoding, ws_in6_addr *addr)
3971{
3972 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3973 field_info *new_fi;
3974
3975 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", 3975,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3976
3977 switch (hfinfo->type) {
3978 case FT_IPv6:
3979 break;
3980 default:
3981 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)
3982 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
3983 }
3984
3985 if (length != FT_IPv6_LEN16)
3986 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)
3987 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
3988
3989 if (encoding) {
3990 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"
)
;
3991 }
3992
3993 tvb_get_ipv6(tvb, start, addr);
3994
3995 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3996
3997 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", 3997
, __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", 3997, "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", 3997, "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", 3997, __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)
; } } }
;
3998
3999 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4000
4001 proto_tree_set_ipv6(new_fi, addr);
4002
4003 return proto_tree_add_node(tree, new_fi);
4004}
4005
4006proto_item *
4007proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4008 const int start, int length, const unsigned encoding, uint8_t *retval) {
4009
4010 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4011 field_info *new_fi;
4012
4013 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", 4013,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4014
4015 switch (hfinfo->type) {
4016 case FT_ETHER:
4017 break;
4018 default:
4019 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)
4020 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4021 }
4022
4023 if (length != FT_ETHER_LEN6)
4024 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)
4025 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4026
4027 if (encoding) {
4028 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"
)
;
4029 }
4030
4031 tvb_memcpy(tvb, retval, start, length);
4032
4033 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4034
4035 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", 4035
, __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", 4035, "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", 4035, "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", 4035, __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)
; } } }
;
4036
4037 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4038
4039 proto_tree_set_ether(new_fi, retval);
4040
4041 return proto_tree_add_node(tree, new_fi);
4042}
4043
4044
4045proto_item *
4046proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4047 tvbuff_t *tvb,
4048 const int start, int length,
4049 const unsigned encoding,
4050 wmem_allocator_t *scope,
4051 const uint8_t **retval,
4052 int *lenretval)
4053{
4054 proto_item *pi;
4055 header_field_info *hfinfo;
4056 field_info *new_fi;
4057 const uint8_t *value;
4058
4059 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", 4059, __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", 4059,
"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", 4059, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4060
4061 switch (hfinfo->type) {
4062 case FT_STRING:
4063 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4064 break;
4065 case FT_STRINGZ:
4066 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4067 break;
4068 case FT_UINT_STRING:
4069 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4070 break;
4071 case FT_STRINGZPAD:
4072 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4073 break;
4074 case FT_STRINGZTRUNC:
4075 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4076 break;
4077 default:
4078 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)
4079 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)
;
4080 }
4081
4082 if (retval)
4083 *retval = value;
4084
4085 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4086
4087 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", 4087
, __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", 4087, "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", 4087, "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", 4087, __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)
; } } }
;
4088
4089 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4090
4091 proto_tree_set_string(new_fi, value);
4092
4093 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4094
4095 pi = proto_tree_add_node(tree, new_fi);
4096
4097 switch (hfinfo->type) {
4098
4099 case FT_STRINGZ:
4100 case FT_STRINGZPAD:
4101 case FT_STRINGZTRUNC:
4102 case FT_UINT_STRING:
4103 break;
4104
4105 case FT_STRING:
4106 detect_trailing_stray_characters(encoding, value, length, pi);
4107 break;
4108
4109 default:
4110 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4110
, __func__, "assertion \"not reached\" failed")
;
4111 }
4112
4113 return pi;
4114}
4115
4116proto_item *
4117proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4118 const int start, int length,
4119 const unsigned encoding, wmem_allocator_t *scope,
4120 const uint8_t **retval)
4121{
4122 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4123 tvb, start, length, encoding, scope, retval, &length);
4124}
4125
4126proto_item *
4127proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4128 tvbuff_t *tvb,
4129 const int start, int length,
4130 const unsigned encoding,
4131 wmem_allocator_t *scope,
4132 char **retval,
4133 int *lenretval)
4134{
4135 proto_item *pi;
4136 header_field_info *hfinfo;
4137 field_info *new_fi;
4138 const uint8_t *value;
4139 uint32_t n = 0;
4140
4141 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", 4141, __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", 4141,
"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", 4141, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4142
4143 switch (hfinfo->type) {
4144 case FT_STRING:
4145 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4146 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4147 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4148 break;
4149 case FT_STRINGZ:
4150 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4151 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4152 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4153 break;
4154 case FT_UINT_STRING:
4155 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4156 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4157 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4158 break;
4159 case FT_STRINGZPAD:
4160 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4161 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4162 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4163 break;
4164 case FT_STRINGZTRUNC:
4165 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4166 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4167 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4168 break;
4169 case FT_BYTES:
4170 tvb_ensure_bytes_exist(tvb, start, length);
4171 value = tvb_get_ptr(tvb, start, length);
4172 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4173 *lenretval = length;
4174 break;
4175 case FT_UINT_BYTES:
4176 n = get_uint_value(tree, tvb, start, length, encoding);
4177 tvb_ensure_bytes_exist(tvb, start + length, n);
4178 value = tvb_get_ptr(tvb, start + length, n);
4179 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4180 *lenretval = length + n;
4181 break;
4182 default:
4183 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)
4184 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)
;
4185 }
4186
4187 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4188
4189 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", 4189
, __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", 4189, "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", 4189, "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", 4189, __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)
; } } }
;
4190
4191 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4192
4193 switch (hfinfo->type) {
4194
4195 case FT_STRING:
4196 case FT_STRINGZ:
4197 case FT_UINT_STRING:
4198 case FT_STRINGZPAD:
4199 case FT_STRINGZTRUNC:
4200 proto_tree_set_string(new_fi, value);
4201 break;
4202
4203 case FT_BYTES:
4204 proto_tree_set_bytes(new_fi, value, length);
4205 break;
4206
4207 case FT_UINT_BYTES:
4208 proto_tree_set_bytes(new_fi, value, n);
4209 break;
4210
4211 default:
4212 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4212
, __func__, "assertion \"not reached\" failed")
;
4213 }
4214
4215 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4216
4217 pi = proto_tree_add_node(tree, new_fi);
4218
4219 switch (hfinfo->type) {
4220
4221 case FT_STRINGZ:
4222 case FT_STRINGZPAD:
4223 case FT_STRINGZTRUNC:
4224 case FT_UINT_STRING:
4225 break;
4226
4227 case FT_STRING:
4228 detect_trailing_stray_characters(encoding, value, length, pi);
4229 break;
4230
4231 case FT_BYTES:
4232 case FT_UINT_BYTES:
4233 break;
4234
4235 default:
4236 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4236
, __func__, "assertion \"not reached\" failed")
;
4237 }
4238
4239 return pi;
4240}
4241
4242proto_item *
4243proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4244 tvbuff_t *tvb,
4245 const int start, int length,
4246 const unsigned encoding,
4247 wmem_allocator_t *scope,
4248 char **retval)
4249{
4250 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4251 tvb, start, length, encoding, scope, retval, &length);
4252}
4253
4254proto_item *
4255proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4256 tvbuff_t *tvb,
4257 const int start, int length, const unsigned encoding,
4258 wmem_allocator_t *scope, char **retval)
4259{
4260 header_field_info *hfinfo;
4261 field_info *new_fi;
4262 nstime_t time_stamp;
4263 int flags;
4264
4265 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", 4265, __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", 4265,
"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", 4265, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4266
4267 switch (hfinfo->type) {
4268 case FT_ABSOLUTE_TIME:
4269 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4270 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4271 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4272 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4273 }
4274 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4275 break;
4276 case FT_RELATIVE_TIME:
4277 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4278 *retval = rel_time_to_secs_str(scope, &time_stamp);
4279 break;
4280 default:
4281 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)
4282 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4283 }
4284
4285 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4286
4287 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", 4287
, __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", 4287, "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", 4287, "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", 4287, __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)
; } } }
;
4288
4289 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4290
4291 switch (hfinfo->type) {
4292
4293 case FT_ABSOLUTE_TIME:
4294 case FT_RELATIVE_TIME:
4295 proto_tree_set_time(new_fi, &time_stamp);
4296 break;
4297 default:
4298 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4298
, __func__, "assertion \"not reached\" failed")
;
4299 }
4300
4301 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4302
4303 return proto_tree_add_node(tree, new_fi);
4304}
4305
4306/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4307 and returns proto_item* */
4308proto_item *
4309ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4310 const unsigned encoding)
4311{
4312 field_info *new_fi;
4313 header_field_info *hfinfo;
4314 int item_length;
4315 int offset;
4316
4317 offset = ptvc->offset;
4318 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", 4318, __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", 4318,
"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", 4318, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4319 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4320 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4321
4322 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
4323 item_length, encoding);
4324
4325 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4326
4327 /* Coast clear. Try and fake it */
4328 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", 4328
, __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", 4328, "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", 4328, "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", 4328, __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); } } }
;
4329
4330 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4331
4332 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4333 offset, length, encoding);
4334}
4335
4336/* Add an item to a proto_tree, using the text label registered to that item;
4337 the item is extracted from the tvbuff handed to it. */
4338proto_item *
4339proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4340 const int start, int length, const unsigned encoding)
4341{
4342 field_info *new_fi;
4343 int item_length;
4344
4345 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", 4345,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4346
4347 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4348 test_length(hfinfo, tvb, start, item_length, encoding);
4349
4350 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4351
4352 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", 4352
, __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", 4352, "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", 4352, "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", 4352, __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)
; } } }
;
4353
4354 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4355
4356 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4357}
4358
4359proto_item *
4360proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4361 const int start, int length, const unsigned encoding)
4362{
4363 register header_field_info *hfinfo;
4364
4365 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", 4365, __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", 4365,
"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", 4365, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4366 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4367}
4368
4369/* Add an item to a proto_tree, using the text label registered to that item;
4370 the item is extracted from the tvbuff handed to it.
4371
4372 Return the length of the item through the pointer. */
4373proto_item *
4374proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4375 tvbuff_t *tvb, const int start,
4376 int length, const unsigned encoding,
4377 int *lenretval)
4378{
4379 field_info *new_fi;
4380 int item_length;
4381 proto_item *item;
4382
4383 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", 4383,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4384
4385 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4386 test_length(hfinfo, tvb, start, item_length, encoding);
4387
4388 if (!tree) {
4389 /*
4390 * We need to get the correct item length here.
4391 * That's normally done by proto_tree_new_item(),
4392 * but we won't be calling it.
4393 */
4394 *lenretval = get_full_length(hfinfo, tvb, start, length,
4395 item_length, encoding);
4396 return NULL((void*)0);
4397 }
4398
4399 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", 4406
, __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", 4406, "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", 4406, "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", 4406
, __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); } } }
4400 /*((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", 4406
, __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", 4406, "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", 4406, "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", 4406
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4401 * 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", 4406
, __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", 4406, "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", 4406, "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", 4406
, __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 * 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", 4406
, __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", 4406, "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", 4406, "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", 4406
, __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 */((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", 4406
, __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", 4406, "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", 4406, "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", 4406
, __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 *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", 4406
, __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", 4406, "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", 4406, "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", 4406
, __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 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", 4406
, __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", 4406, "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", 4406, "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", 4406
, __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 })((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", 4406
, __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", 4406, "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", 4406, "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", 4406
, __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
4408 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4409
4410 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4411 *lenretval = new_fi->length;
4412 return item;
4413}
4414
4415proto_item *
4416proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4417 const int start, int length,
4418 const unsigned encoding, int *lenretval)
4419{
4420 register header_field_info *hfinfo;
4421
4422 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", 4422, __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", 4422,
"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", 4422, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4423 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4424}
4425
4426/* which FT_ types can use proto_tree_add_bytes_item() */
4427static inline bool_Bool
4428validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4429{
4430 return (type == FT_BYTES ||
4431 type == FT_UINT_BYTES ||
4432 type == FT_OID ||
4433 type == FT_REL_OID ||
4434 type == FT_SYSTEM_ID );
4435}
4436
4437/* Note: this does no validation that the byte array of an FT_OID or
4438 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4439 so I think it's ok to continue not validating it?
4440 */
4441proto_item *
4442proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4443 const int start, int length, const unsigned encoding,
4444 GByteArray *retval, int *endoff, int *err)
4445{
4446 field_info *new_fi;
4447 GByteArray *bytes = retval;
4448 GByteArray *created_bytes = NULL((void*)0);
4449 bool_Bool failed = false0;
4450 uint32_t n = 0;
4451 header_field_info *hfinfo;
4452 bool_Bool generate = (bytes || tree) ? true1 : false0;
4453
4454 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", 4454, __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", 4454,
"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", 4454, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4455
4456 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", 4456,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4457
4458 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", 4459, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4459 "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", 4459, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4460
4461 CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
;
4462
4463 if (encoding & ENC_STR_NUM0x01000000) {
4464 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"
)
;
4465 }
4466
4467 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4468 if (hfinfo->type == FT_UINT_BYTES) {
4469 /* can't decode FT_UINT_BYTES from strings */
4470 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")
4471 "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")
;
4472 }
4473
4474 unsigned hex_encoding = encoding;
4475 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4476 /* If none of the separator values are used,
4477 * assume no separator (the common case). */
4478 hex_encoding |= ENC_SEP_NONE0x00010000;
4479#if 0
4480 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")
4481 "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")
;
4482#endif
4483 }
4484
4485 if (!bytes) {
4486 /* caller doesn't care about return value, but we need it to
4487 call tvb_get_string_bytes() and set the tree later */
4488 bytes = created_bytes = g_byte_array_new();
4489 }
4490
4491 /*
4492 * bytes might be NULL after this, but can't add expert
4493 * error until later; if it's NULL, just note that
4494 * it failed.
4495 */
4496 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4497 if (bytes == NULL((void*)0))
4498 failed = true1;
4499 }
4500 else if (generate) {
4501 tvb_ensure_bytes_exist(tvb, start, length);
4502
4503 if (hfinfo->type == FT_UINT_BYTES) {
4504 n = length; /* n is now the "header" length */
4505 length = get_uint_value(tree, tvb, start, n, encoding);
4506 /* length is now the value's length; only store the value in the array */
4507 tvb_ensure_bytes_exist(tvb, start + n, length);
4508 if (!bytes) {
4509 /* caller doesn't care about return value, but
4510 * we may need it to set the tree later */
4511 bytes = created_bytes = g_byte_array_new();
4512 }
4513 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4514 }
4515 else if (length > 0) {
4516 if (!bytes) {
4517 /* caller doesn't care about return value, but
4518 * we may need it to set the tree later */
4519 bytes = created_bytes = g_byte_array_new();
4520 }
4521 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4522 }
4523
4524 if (endoff)
4525 *endoff = start + n + length;
4526 }
4527
4528 if (err)
4529 *err = failed ? EINVAL22 : 0;
4530
4531 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); }
4532 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4533 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); }
4534 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); }
4535 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); }
4536 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4537 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4538
4539 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", 4545
, __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", 4545, "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", 4545, "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", 4545
, __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); } } }
4540 {((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", 4545
, __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", 4545, "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", 4545, "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", 4545
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4541 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", 4545
, __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", 4545, "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", 4545, "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", 4545
, __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 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", 4545
, __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", 4545, "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", 4545, "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", 4545
, __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 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", 4545
, __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", 4545, "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", 4545, "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", 4545
, __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 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", 4545
, __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", 4545, "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", 4545, "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", 4545
, __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 } )((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", 4545
, __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", 4545, "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", 4545, "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", 4545
, __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
4547 /* n will be zero except when it's a FT_UINT_BYTES */
4548 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4549
4550 if (encoding & ENC_STRING0x03000000) {
4551 if (failed)
4552 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4553
4554 if (bytes)
4555 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4556 else
4557 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4558
4559 if (created_bytes)
4560 g_byte_array_free(created_bytes, true1);
4561 }
4562 else {
4563 /* n will be zero except when it's a FT_UINT_BYTES */
4564 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4565
4566 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4567 * use the byte array created above in this case.
4568 */
4569 if (created_bytes)
4570 g_byte_array_free(created_bytes, true1);
4571
4572 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4573 (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)
;
4574 }
4575
4576 return proto_tree_add_node(tree, new_fi);
4577}
4578
4579
4580proto_item *
4581proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4582 const int start, int length, const unsigned encoding,
4583 nstime_t *retval, int *endoff, int *err)
4584{
4585 field_info *new_fi;
4586 nstime_t time_stamp;
4587 int saved_err = 0;
4588 header_field_info *hfinfo;
4589
4590 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", 4590, __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", 4590,
"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", 4590, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4591
4592 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", 4592,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4593
4594 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4595 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4596 if(retval)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 nstime_set_zero(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 } )if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
;
4601
4602 nstime_set_zero(&time_stamp);
4603
4604 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4605 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", 4605, ((hfinfo))->abbrev))))
;
4606 /* The only string format that could be a relative time is
4607 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4608 * relative to "now" currently.
4609 */
4610 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4611 saved_err = EINVAL22;
4612 }
4613 else {
4614 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", 4614, ((hfinfo))->abbrev))))
;
4615 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4616
4617 tvb_ensure_bytes_exist(tvb, start, length);
4618 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4619 if (endoff) *endoff = start + length;
4620 }
4621
4622 if (err) *err = saved_err;
4623
4624 if (retval) {
4625 retval->secs = time_stamp.secs;
4626 retval->nsecs = time_stamp.nsecs;
4627 }
4628
4629 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4630
4631 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", 4631
, __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", 4631, "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", 4631, "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", 4631, __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)
; } } }
;
4632
4633 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4634
4635 proto_tree_set_time(new_fi, &time_stamp);
4636
4637 if (encoding & ENC_STRING0x03000000) {
4638 if (saved_err)
4639 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4640 }
4641 else {
4642 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4643 (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)
;
4644 }
4645
4646 return proto_tree_add_node(tree, new_fi);
4647}
4648
4649/* Add a FT_NONE to a proto_tree */
4650proto_item *
4651proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4652 const int start, int length, const char *format,
4653 ...)
4654{
4655 proto_item *pi;
4656 va_list ap;
4657 header_field_info *hfinfo;
4658
4659 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4660
4661 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", 4661
, __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", 4661, "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", 4661, "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", 4661, __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)
; } } }
;
4662
4663 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", 4663
, ((hfinfo))->abbrev))))
;
4664
4665 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4666
4667 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4667, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4668
4669 va_start(ap, format)__builtin_va_start(ap, format);
4670 proto_tree_set_representation(pi, format, ap);
4671 va_end(ap)__builtin_va_end(ap);
4672
4673 /* no value to set for FT_NONE */
4674 return pi;
4675}
4676
4677/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4678 * offset, and returns proto_item* */
4679proto_item *
4680ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4681 const unsigned encoding)
4682{
4683 proto_item *item;
4684
4685 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4686 length, encoding);
4687
4688 return item;
4689}
4690
4691/* Advance the ptvcursor's offset within its tvbuff without
4692 * adding anything to the proto_tree. */
4693void
4694ptvcursor_advance(ptvcursor_t* ptvc, int length)
4695{
4696 ptvc->offset += length;
4697}
4698
4699
4700static void
4701proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4702{
4703 fvalue_set_protocol(fi->value, tvb, field_data, length);
4704}
4705
4706/* Add a FT_PROTOCOL to a proto_tree */
4707proto_item *
4708proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4709 int start, int length, const char *format, ...)
4710{
4711 proto_item *pi;
4712 tvbuff_t *protocol_tvb;
4713 va_list ap;
4714 header_field_info *hfinfo;
4715 char* protocol_rep;
4716
4717 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4718
4719 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", 4719
, __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", 4719, "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", 4719, "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", 4719, __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)
; } } }
;
4720
4721 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"
, 4721, ((hfinfo))->abbrev))))
;
4722
4723 /*
4724 * This can throw an exception, so do it before we allocate anything.
4725 */
4726 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4727
4728 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4729
4730 va_start(ap, format)__builtin_va_start(ap, format);
4731 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4732 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4733 g_free(protocol_rep);
4734 va_end(ap)__builtin_va_end(ap);
4735
4736 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4736, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4737
4738 va_start(ap, format)__builtin_va_start(ap, format);
4739 proto_tree_set_representation(pi, format, ap);
4740 va_end(ap)__builtin_va_end(ap);
4741
4742 return pi;
4743}
4744
4745/* Add a FT_BYTES to a proto_tree */
4746proto_item *
4747proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4748 int length, const uint8_t *start_ptr)
4749{
4750 proto_item *pi;
4751 header_field_info *hfinfo;
4752 int item_length;
4753
4754 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", 4754, __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", 4754,
"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", 4754, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4755 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4756 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4757
4758 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4759
4760 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", 4760
, __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", 4760, "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", 4760, "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", 4760, __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)
; } } }
;
4761
4762 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",
4762, ((hfinfo))->abbrev))))
;
4763
4764 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4765 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4766
4767 return pi;
4768}
4769
4770/* Add a FT_BYTES to a proto_tree */
4771proto_item *
4772proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4773 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4774{
4775 proto_item *pi;
4776 header_field_info *hfinfo;
4777 int item_length;
4778
4779 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", 4779, __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", 4779,
"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", 4779, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4780 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4781 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4782
4783 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4784
4785 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", 4785
, __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", 4785, "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", 4785, "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", 4785, __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)
; } } }
;
4786
4787 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",
4787, ((hfinfo))->abbrev))))
;
4788
4789 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4790 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4791
4792 return pi;
4793}
4794
4795proto_item *
4796proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4797 int start, int length,
4798 const uint8_t *start_ptr,
4799 const char *format, ...)
4800{
4801 proto_item *pi;
4802 va_list ap;
4803
4804 if (start_ptr == NULL((void*)0))
4805 start_ptr = tvb_get_ptr(tvb, start, length);
4806
4807 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4808
4809 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; }
;
4810
4811 va_start(ap, format)__builtin_va_start(ap, format);
4812 proto_tree_set_representation_value(pi, format, ap);
4813 va_end(ap)__builtin_va_end(ap);
4814
4815 return pi;
4816}
4817
4818proto_item *
4819proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4820 int start, int length, const uint8_t *start_ptr,
4821 const char *format, ...)
4822{
4823 proto_item *pi;
4824 va_list ap;
4825
4826 if (start_ptr == NULL((void*)0))
4827 start_ptr = tvb_get_ptr(tvb, start, length);
4828
4829 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4830
4831 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; }
;
4832
4833 va_start(ap, format)__builtin_va_start(ap, format);
4834 proto_tree_set_representation(pi, format, ap);
4835 va_end(ap)__builtin_va_end(ap);
4836
4837 return pi;
4838}
4839
4840static void
4841proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4842{
4843 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4843, "length >= 0"
))))
;
4844 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", 4844, "start_ptr != ((void*)0) || length == 0"
))))
;
4845
4846 fvalue_set_bytes_data(fi->value, start_ptr, length);
4847}
4848
4849
4850static void
4851proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4852{
4853 tvb_ensure_bytes_exist(tvb, offset, length);
4854 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4855}
4856
4857static void
4858proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4859{
4860 GByteArray *bytes;
4861
4862 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4862, "value != ((void*)0)"
))))
;
4863
4864 bytes = byte_array_dup(value);
4865
4866 fvalue_set_byte_array(fi->value, bytes);
4867}
4868
4869/* Add a FT_*TIME to a proto_tree */
4870proto_item *
4871proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4872 int length, const nstime_t *value_ptr)
4873{
4874 proto_item *pi;
4875 header_field_info *hfinfo;
4876
4877 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4878
4879 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", 4879
, __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", 4879, "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", 4879, "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", 4879, __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)
; } } }
;
4880
4881 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", 4881, ((hfinfo))->abbrev))))
;
4882
4883 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4884 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4885
4886 return pi;
4887}
4888
4889proto_item *
4890proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4891 int start, int length, nstime_t *value_ptr,
4892 const char *format, ...)
4893{
4894 proto_item *pi;
4895 va_list ap;
4896
4897 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4898 if (pi != tree) {
4899 va_start(ap, format)__builtin_va_start(ap, format);
4900 proto_tree_set_representation_value(pi, format, ap);
4901 va_end(ap)__builtin_va_end(ap);
4902 }
4903
4904 return pi;
4905}
4906
4907proto_item *
4908proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4909 int start, int length, nstime_t *value_ptr,
4910 const char *format, ...)
4911{
4912 proto_item *pi;
4913 va_list ap;
4914
4915 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4916 if (pi != tree) {
4917 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4917, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4918
4919 va_start(ap, format)__builtin_va_start(ap, format);
4920 proto_tree_set_representation(pi, format, ap);
4921 va_end(ap)__builtin_va_end(ap);
4922 }
4923
4924 return pi;
4925}
4926
4927/* Set the FT_*TIME value */
4928static void
4929proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4930{
4931 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4931, "value_ptr != ((void*)0)"
))))
;
4932
4933 fvalue_set_time(fi->value, value_ptr);
4934}
4935
4936/* Add a FT_IPXNET to a proto_tree */
4937proto_item *
4938proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4939 int length, uint32_t value)
4940{
4941 proto_item *pi;
4942 header_field_info *hfinfo;
4943
4944 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4945
4946 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", 4946
, __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", 4946, "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", 4946, "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", 4946, __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)
; } } }
;
4947
4948 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"
, 4948, ((hfinfo))->abbrev))))
;
4949
4950 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4951 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
4952
4953 return pi;
4954}
4955
4956proto_item *
4957proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4958 int start, int length, uint32_t value,
4959 const char *format, ...)
4960{
4961 proto_item *pi;
4962 va_list ap;
4963
4964 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4965 if (pi != tree) {
4966 va_start(ap, format)__builtin_va_start(ap, format);
4967 proto_tree_set_representation_value(pi, format, ap);
4968 va_end(ap)__builtin_va_end(ap);
4969 }
4970
4971 return pi;
4972}
4973
4974proto_item *
4975proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4976 int start, int length, uint32_t value,
4977 const char *format, ...)
4978{
4979 proto_item *pi;
4980 va_list ap;
4981
4982 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4983 if (pi != tree) {
4984 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4984, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4985
4986 va_start(ap, format)__builtin_va_start(ap, format);
4987 proto_tree_set_representation(pi, format, ap);
4988 va_end(ap)__builtin_va_end(ap);
4989 }
4990
4991 return pi;
4992}
4993
4994/* Set the FT_IPXNET value */
4995static void
4996proto_tree_set_ipxnet(field_info *fi, uint32_t value)
4997{
4998 fvalue_set_uinteger(fi->value, value);
4999}
5000
5001/* Add a FT_IPv4 to a proto_tree */
5002proto_item *
5003proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5004 int length, ws_in4_addr value)
5005{
5006 proto_item *pi;
5007 header_field_info *hfinfo;
5008
5009 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5010
5011 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", 5011
, __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", 5011, "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", 5011, "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", 5011, __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)
; } } }
;
5012
5013 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", 5013
, ((hfinfo))->abbrev))))
;
5014
5015 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5016 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5017
5018 return pi;
5019}
5020
5021proto_item *
5022proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5023 int start, int length, ws_in4_addr value,
5024 const char *format, ...)
5025{
5026 proto_item *pi;
5027 va_list ap;
5028
5029 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5030 if (pi != tree) {
5031 va_start(ap, format)__builtin_va_start(ap, format);
5032 proto_tree_set_representation_value(pi, format, ap);
5033 va_end(ap)__builtin_va_end(ap);
5034 }
5035
5036 return pi;
5037}
5038
5039proto_item *
5040proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5041 int start, int length, ws_in4_addr value,
5042 const char *format, ...)
5043{
5044 proto_item *pi;
5045 va_list ap;
5046
5047 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5048 if (pi != tree) {
5049 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5049, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5050
5051 va_start(ap, format)__builtin_va_start(ap, format);
5052 proto_tree_set_representation(pi, format, ap);
5053 va_end(ap)__builtin_va_end(ap);
5054 }
5055
5056 return pi;
5057}
5058
5059/* Set the FT_IPv4 value */
5060static void
5061proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5062{
5063 ipv4_addr_and_mask ipv4;
5064 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5065 fvalue_set_ipv4(fi->value, &ipv4);
5066}
5067
5068/* Add a FT_IPv6 to a proto_tree */
5069proto_item *
5070proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5071 int length, const ws_in6_addr *value)
5072{
5073 proto_item *pi;
5074 header_field_info *hfinfo;
5075
5076 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5077
5078 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", 5078
, __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", 5078, "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", 5078, "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", 5078, __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)
; } } }
;
5079
5080 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", 5080
, ((hfinfo))->abbrev))))
;
5081
5082 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5083 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5084
5085 return pi;
5086}
5087
5088proto_item *
5089proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5090 int start, int length,
5091 const ws_in6_addr *value_ptr,
5092 const char *format, ...)
5093{
5094 proto_item *pi;
5095 va_list ap;
5096
5097 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5098 if (pi != tree) {
5099 va_start(ap, format)__builtin_va_start(ap, format);
5100 proto_tree_set_representation_value(pi, format, ap);
5101 va_end(ap)__builtin_va_end(ap);
5102 }
5103
5104 return pi;
5105}
5106
5107proto_item *
5108proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5109 int start, int length,
5110 const ws_in6_addr *value_ptr,
5111 const char *format, ...)
5112{
5113 proto_item *pi;
5114 va_list ap;
5115
5116 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5117 if (pi != tree) {
5118 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5118, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5119
5120 va_start(ap, format)__builtin_va_start(ap, format);
5121 proto_tree_set_representation(pi, format, ap);
5122 va_end(ap)__builtin_va_end(ap);
5123 }
5124
5125 return pi;
5126}
5127
5128/* Set the FT_IPv6 value */
5129static void
5130proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5131{
5132 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5132, "value != ((void*)0)"
))))
;
5133 ipv6_addr_and_prefix ipv6;
5134 ipv6.addr = *value;
5135 ipv6.prefix = 128;
5136 fvalue_set_ipv6(fi->value, &ipv6);
5137}
5138
5139static void
5140proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5141{
5142 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5143}
5144
5145/* Set the FT_FCWWN value */
5146static void
5147proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5148{
5149 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5149, "value_ptr != ((void*)0)"
))))
;
5150 fvalue_set_fcwwn(fi->value, value_ptr);
5151}
5152
5153static void
5154proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5155{
5156 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5157}
5158
5159/* Add a FT_GUID to a proto_tree */
5160proto_item *
5161proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5162 int length, const e_guid_t *value_ptr)
5163{
5164 proto_item *pi;
5165 header_field_info *hfinfo;
5166
5167 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5168
5169 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", 5169
, __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", 5169, "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", 5169, "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", 5169, __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)
; } } }
;
5170
5171 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", 5171
, ((hfinfo))->abbrev))))
;
5172
5173 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5174 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5175
5176 return pi;
5177}
5178
5179proto_item *
5180proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5181 int start, int length,
5182 const e_guid_t *value_ptr,
5183 const char *format, ...)
5184{
5185 proto_item *pi;
5186 va_list ap;
5187
5188 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5189 if (pi != tree) {
5190 va_start(ap, format)__builtin_va_start(ap, format);
5191 proto_tree_set_representation_value(pi, format, ap);
5192 va_end(ap)__builtin_va_end(ap);
5193 }
5194
5195 return pi;
5196}
5197
5198proto_item *
5199proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5200 int start, int length, const e_guid_t *value_ptr,
5201 const char *format, ...)
5202{
5203 proto_item *pi;
5204 va_list ap;
5205
5206 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5207 if (pi != tree) {
5208 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5208, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5209
5210 va_start(ap, format)__builtin_va_start(ap, format);
5211 proto_tree_set_representation(pi, format, ap);
5212 va_end(ap)__builtin_va_end(ap);
5213 }
5214
5215 return pi;
5216}
5217
5218/* Set the FT_GUID value */
5219static void
5220proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5221{
5222 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5222, "value_ptr != ((void*)0)"
))))
;
5223 fvalue_set_guid(fi->value, value_ptr);
5224}
5225
5226static void
5227proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5228 const unsigned encoding)
5229{
5230 e_guid_t guid;
5231
5232 tvb_get_guid(tvb, start, &guid, encoding);
5233 proto_tree_set_guid(fi, &guid);
5234}
5235
5236/* Add a FT_OID to a proto_tree */
5237proto_item *
5238proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5239 int length, const uint8_t* value_ptr)
5240{
5241 proto_item *pi;
5242 header_field_info *hfinfo;
5243
5244 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5245
5246 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", 5246
, __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", 5246, "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", 5246, "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", 5246, __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)
; } } }
;
5247
5248 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", 5248
, ((hfinfo))->abbrev))))
;
5249
5250 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5251 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5252
5253 return pi;
5254}
5255
5256proto_item *
5257proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5258 int start, int length,
5259 const uint8_t* value_ptr,
5260 const char *format, ...)
5261{
5262 proto_item *pi;
5263 va_list ap;
5264
5265 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5266 if (pi != tree) {
5267 va_start(ap, format)__builtin_va_start(ap, format);
5268 proto_tree_set_representation_value(pi, format, ap);
5269 va_end(ap)__builtin_va_end(ap);
5270 }
5271
5272 return pi;
5273}
5274
5275proto_item *
5276proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5277 int start, int length, const uint8_t* value_ptr,
5278 const char *format, ...)
5279{
5280 proto_item *pi;
5281 va_list ap;
5282
5283 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5284 if (pi != tree) {
5285 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5285, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5286
5287 va_start(ap, format)__builtin_va_start(ap, format);
5288 proto_tree_set_representation(pi, format, ap);
5289 va_end(ap)__builtin_va_end(ap);
5290 }
5291
5292 return pi;
5293}
5294
5295/* Set the FT_OID value */
5296static void
5297proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5298{
5299 GByteArray *bytes;
5300
5301 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", 5301, "value_ptr != ((void*)0) || length == 0"
))))
;
5302
5303 bytes = g_byte_array_new();
5304 if (length > 0) {
5305 g_byte_array_append(bytes, value_ptr, length);
5306 }
5307 fvalue_set_byte_array(fi->value, bytes);
5308}
5309
5310static void
5311proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5312{
5313 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5314}
5315
5316/* Set the FT_SYSTEM_ID value */
5317static void
5318proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5319{
5320 GByteArray *bytes;
5321
5322 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", 5322, "value_ptr != ((void*)0) || length == 0"
))))
;
5323
5324 bytes = g_byte_array_new();
5325 if (length > 0) {
5326 g_byte_array_append(bytes, value_ptr, length);
5327 }
5328 fvalue_set_byte_array(fi->value, bytes);
5329}
5330
5331static void
5332proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5333{
5334 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5335}
5336
5337/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5338 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5339 * is destroyed. */
5340proto_item *
5341proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5342 int length, const char* value)
5343{
5344 proto_item *pi;
5345 header_field_info *hfinfo;
5346 int item_length;
5347
5348 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", 5348, __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", 5348,
"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", 5348, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5349 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5350 /*
5351 * Special case - if the length is 0, skip the test, so that
5352 * we can have an empty string right after the end of the
5353 * packet. (This handles URL-encoded forms where the last field
5354 * has no value so the form ends right after the =.)
5355 */
5356 if (item_length != 0)
5357 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5358
5359 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5360
5361 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", 5361
, __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", 5361, "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", 5361, "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", 5361, __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)
; } } }
;
5362
5363 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", 5363, ((hfinfo))->abbrev))))
;
5364
5365 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5366 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5366, "length >= 0"
))))
;
5367
5368 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", 5368, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5369 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5370
5371 return pi;
5372}
5373
5374proto_item *
5375proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5376 int start, int length, const char* value,
5377 const char *format,
5378 ...)
5379{
5380 proto_item *pi;
5381 va_list ap;
5382
5383 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5384 if (pi != tree) {
5385 va_start(ap, format)__builtin_va_start(ap, format);
5386 proto_tree_set_representation_value(pi, format, ap);
5387 va_end(ap)__builtin_va_end(ap);
5388 }
5389
5390 return pi;
5391}
5392
5393proto_item *
5394proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5395 int start, int length, const char* value,
5396 const char *format, ...)
5397{
5398 proto_item *pi;
5399 va_list ap;
5400
5401 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5402 if (pi != tree) {
5403 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5403, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5404
5405 va_start(ap, format)__builtin_va_start(ap, format);
5406 proto_tree_set_representation(pi, format, ap);
5407 va_end(ap)__builtin_va_end(ap);
5408 }
5409
5410 return pi;
5411}
5412
5413/* Set the FT_STRING value */
5414static void
5415proto_tree_set_string(field_info *fi, const char* value)
5416{
5417 if (value) {
5418 fvalue_set_string(fi->value, value);
5419 } else {
5420 /*
5421 * XXX - why is a null value for a string field
5422 * considered valid?
5423 */
5424 fvalue_set_string(fi->value, "[ Null ]");
5425 }
5426}
5427
5428/* Set the FT_AX25 value */
5429static void
5430proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5431{
5432 fvalue_set_ax25(fi->value, value);
5433}
5434
5435static void
5436proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5437{
5438 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5439}
5440
5441/* Set the FT_VINES value */
5442static void
5443proto_tree_set_vines(field_info *fi, const uint8_t* value)
5444{
5445 fvalue_set_vines(fi->value, value);
5446}
5447
5448static void
5449proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5450{
5451 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5452}
5453
5454/* Add a FT_ETHER to a proto_tree */
5455proto_item *
5456proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5457 int length, const uint8_t* value)
5458{
5459 proto_item *pi;
5460 header_field_info *hfinfo;
5461
5462 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5463
5464 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", 5464
, __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", 5464, "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", 5464, "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", 5464, __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)
; } } }
;
5465
5466 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",
5466, ((hfinfo))->abbrev))))
;
5467
5468 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5469 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5470
5471 return pi;
5472}
5473
5474proto_item *
5475proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5476 int start, int length, const uint8_t* value,
5477 const char *format, ...)
5478{
5479 proto_item *pi;
5480 va_list ap;
5481
5482 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5483 if (pi != tree) {
5484 va_start(ap, format)__builtin_va_start(ap, format);
5485 proto_tree_set_representation_value(pi, format, ap);
5486 va_end(ap)__builtin_va_end(ap);
5487 }
5488
5489 return pi;
5490}
5491
5492proto_item *
5493proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5494 int start, int length, const uint8_t* value,
5495 const char *format, ...)
5496{
5497 proto_item *pi;
5498 va_list ap;
5499
5500 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5501 if (pi != tree) {
5502 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5502, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5503
5504 va_start(ap, format)__builtin_va_start(ap, format);
5505 proto_tree_set_representation(pi, format, ap);
5506 va_end(ap)__builtin_va_end(ap);
5507 }
5508
5509 return pi;
5510}
5511
5512/* Set the FT_ETHER value */
5513static void
5514proto_tree_set_ether(field_info *fi, const uint8_t* value)
5515{
5516 fvalue_set_ether(fi->value, value);
5517}
5518
5519static void
5520proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5521{
5522 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5523}
5524
5525/* Add a FT_BOOLEAN to a proto_tree */
5526proto_item *
5527proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5528 int length, uint64_t value)
5529{
5530 proto_item *pi;
5531 header_field_info *hfinfo;
5532
5533 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5534
5535 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", 5535
, __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", 5535, "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", 5535, "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", 5535, __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)
; } } }
;
5536
5537 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"
, 5537, ((hfinfo))->abbrev))))
;
5538
5539 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5540 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5541
5542 return pi;
5543}
5544
5545proto_item *
5546proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5547 tvbuff_t *tvb, int start, int length,
5548 uint64_t value, const char *format, ...)
5549{
5550 proto_item *pi;
5551 va_list ap;
5552
5553 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5554 if (pi != tree) {
5555 va_start(ap, format)__builtin_va_start(ap, format);
5556 proto_tree_set_representation_value(pi, format, ap);
5557 va_end(ap)__builtin_va_end(ap);
5558 }
5559
5560 return pi;
5561}
5562
5563proto_item *
5564proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5565 int start, int length, uint64_t value,
5566 const char *format, ...)
5567{
5568 proto_item *pi;
5569 va_list ap;
5570
5571 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5572 if (pi != tree) {
5573 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5573, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5574
5575 va_start(ap, format)__builtin_va_start(ap, format);
5576 proto_tree_set_representation(pi, format, ap);
5577 va_end(ap)__builtin_va_end(ap);
5578 }
5579
5580 return pi;
5581}
5582
5583/* Set the FT_BOOLEAN value */
5584static void
5585proto_tree_set_boolean(field_info *fi, uint64_t value)
5586{
5587 proto_tree_set_uint64(fi, value);
5588}
5589
5590/* Generate, into "buf", a string showing the bits of a bitfield.
5591 Return a pointer to the character after that string. */
5592static char *
5593other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5594{
5595 int i = 0;
5596 uint64_t bit;
5597 char *p;
5598
5599 p = buf;
5600
5601 /* This is a devel error. It is safer to stop here. */
5602 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5602, "width >= 1"
))))
;
5603
5604 bit = UINT64_C(1)1UL << (width - 1);
5605 for (;;) {
5606 if (mask & bit) {
5607 /* This bit is part of the field. Show its value. */
5608 if (val & bit)
5609 *p++ = '1';
5610 else
5611 *p++ = '0';
5612 } else {
5613 /* This bit is not part of the field. */
5614 *p++ = '.';
5615 }
5616 bit >>= 1;
5617 i++;
5618 if (i >= width)
5619 break;
5620 if (i % 4 == 0)
5621 *p++ = ' ';
5622 }
5623 *p = '\0';
5624 return p;
5625}
5626
5627static char *
5628decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5629{
5630 char *p;
5631
5632 p = other_decode_bitfield_value(buf, val, mask, width);
5633 p = g_stpcpy(p, " = ");
5634
5635 return p;
5636}
5637
5638static char *
5639other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5640{
5641 int i = 0;
5642 uint64_t bit;
5643 char *p;
5644
5645 p = buf;
5646
5647 /* This is a devel error. It is safer to stop here. */
5648 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5648, "width >= 1"
))))
;
5649
5650 bit = UINT64_C(1)1UL << (width - 1);
5651 for (;;) {
5652 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5653 (mask & bit)) {
5654 /* This bit is part of the field. Show its value. */
5655 if (val & bit)
5656 *p++ = '1';
5657 else
5658 *p++ = '0';
5659 } else {
5660 /* This bit is not part of the field. */
5661 *p++ = '.';
5662 }
5663 bit >>= 1;
5664 i++;
5665 if (i >= width)
5666 break;
5667 if (i % 4 == 0)
5668 *p++ = ' ';
5669 }
5670
5671 *p = '\0';
5672 return p;
5673}
5674
5675static char *
5676decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5677{
5678 char *p;
5679
5680 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5681 p = g_stpcpy(p, " = ");
5682
5683 return p;
5684}
5685
5686/* Add a FT_FLOAT to a proto_tree */
5687proto_item *
5688proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5689 int length, float value)
5690{
5691 proto_item *pi;
5692 header_field_info *hfinfo;
5693
5694 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5695
5696 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", 5696
, __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", 5696, "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", 5696, "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", 5696, __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)
; } } }
;
5697
5698 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",
5698, ((hfinfo))->abbrev))))
;
5699
5700 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5701 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5702
5703 return pi;
5704}
5705
5706proto_item *
5707proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5708 int start, int length, float value,
5709 const char *format, ...)
5710{
5711 proto_item *pi;
5712 va_list ap;
5713
5714 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5715 if (pi != tree) {
5716 va_start(ap, format)__builtin_va_start(ap, format);
5717 proto_tree_set_representation_value(pi, format, ap);
5718 va_end(ap)__builtin_va_end(ap);
5719 }
5720
5721 return pi;
5722}
5723
5724proto_item *
5725proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5726 int start, int length, float value,
5727 const char *format, ...)
5728{
5729 proto_item *pi;
5730 va_list ap;
5731
5732 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5733 if (pi != tree) {
5734 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5734, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5735
5736 va_start(ap, format)__builtin_va_start(ap, format);
5737 proto_tree_set_representation(pi, format, ap);
5738 va_end(ap)__builtin_va_end(ap);
5739 }
5740
5741 return pi;
5742}
5743
5744/* Set the FT_FLOAT value */
5745static void
5746proto_tree_set_float(field_info *fi, float value)
5747{
5748 fvalue_set_floating(fi->value, value);
5749}
5750
5751/* Add a FT_DOUBLE to a proto_tree */
5752proto_item *
5753proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5754 int length, double value)
5755{
5756 proto_item *pi;
5757 header_field_info *hfinfo;
5758
5759 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5760
5761 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", 5761
, __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", 5761, "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", 5761, "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", 5761, __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)
; } } }
;
5762
5763 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"
, 5763, ((hfinfo))->abbrev))))
;
5764
5765 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5766 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5767
5768 return pi;
5769}
5770
5771proto_item *
5772proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5773 int start, int length, double value,
5774 const char *format, ...)
5775{
5776 proto_item *pi;
5777 va_list ap;
5778
5779 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5780 if (pi != tree) {
5781 va_start(ap, format)__builtin_va_start(ap, format);
5782 proto_tree_set_representation_value(pi, format, ap);
5783 va_end(ap)__builtin_va_end(ap);
5784 }
5785
5786 return pi;
5787}
5788
5789proto_item *
5790proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5791 int start, int length, double value,
5792 const char *format, ...)
5793{
5794 proto_item *pi;
5795 va_list ap;
5796
5797 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5798 if (pi != tree) {
5799 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5799, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5800
5801 va_start(ap, format)__builtin_va_start(ap, format);
5802 proto_tree_set_representation(pi, format, ap);
5803 va_end(ap)__builtin_va_end(ap);
5804 }
5805
5806 return pi;
5807}
5808
5809/* Set the FT_DOUBLE value */
5810static void
5811proto_tree_set_double(field_info *fi, double value)
5812{
5813 fvalue_set_floating(fi->value, value);
5814}
5815
5816/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5817proto_item *
5818proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5819 int length, uint32_t value)
5820{
5821 proto_item *pi = NULL((void*)0);
5822 header_field_info *hfinfo;
5823
5824 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5825
5826 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", 5826
, __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", 5826, "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", 5826, "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", 5826, __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)
; } } }
;
5827
5828 switch (hfinfo->type) {
5829 case FT_CHAR:
5830 case FT_UINT8:
5831 case FT_UINT16:
5832 case FT_UINT24:
5833 case FT_UINT32:
5834 case FT_FRAMENUM:
5835 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5836 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5837 break;
5838
5839 default:
5840 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)
5841 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)
;
5842 }
5843
5844 return pi;
5845}
5846
5847proto_item *
5848proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5849 int start, int length, uint32_t value,
5850 const char *format, ...)
5851{
5852 proto_item *pi;
5853 va_list ap;
5854
5855 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5856 if (pi != tree) {
5857 va_start(ap, format)__builtin_va_start(ap, format);
5858 proto_tree_set_representation_value(pi, format, ap);
5859 va_end(ap)__builtin_va_end(ap);
5860 }
5861
5862 return pi;
5863}
5864
5865proto_item *
5866proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5867 int start, int length, uint32_t value,
5868 const char *format, ...)
5869{
5870 proto_item *pi;
5871 va_list ap;
5872
5873 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5874 if (pi != tree) {
5875 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5875, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5876
5877 va_start(ap, format)__builtin_va_start(ap, format);
5878 proto_tree_set_representation(pi, format, ap);
5879 va_end(ap)__builtin_va_end(ap);
5880 }
5881
5882 return pi;
5883}
5884
5885/* Set the FT_UINT{8,16,24,32} value */
5886static void
5887proto_tree_set_uint(field_info *fi, uint32_t value)
5888{
5889 const header_field_info *hfinfo;
5890 uint32_t integer;
5891
5892 hfinfo = fi->hfinfo;
5893 integer = value;
5894
5895 if (hfinfo->bitmask) {
5896 /* Mask out irrelevant portions */
5897 integer &= (uint32_t)(hfinfo->bitmask);
5898
5899 /* Shift bits */
5900 integer >>= hfinfo_bitshift(hfinfo);
5901
5902 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5903 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)
;
5904 }
5905
5906 fvalue_set_uinteger(fi->value, integer);
5907}
5908
5909/* Add FT_UINT{40,48,56,64} to a proto_tree */
5910proto_item *
5911proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5912 int length, uint64_t value)
5913{
5914 proto_item *pi = NULL((void*)0);
5915 header_field_info *hfinfo;
5916
5917 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5918
5919 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", 5919
, __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", 5919, "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", 5919, "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", 5919, __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)
; } } }
;
5920
5921 switch (hfinfo->type) {
5922 case FT_UINT40:
5923 case FT_UINT48:
5924 case FT_UINT56:
5925 case FT_UINT64:
5926 case FT_FRAMENUM:
5927 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5928 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
5929 break;
5930
5931 default:
5932 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)
5933 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)
;
5934 }
5935
5936 return pi;
5937}
5938
5939proto_item *
5940proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5941 int start, int length, uint64_t value,
5942 const char *format, ...)
5943{
5944 proto_item *pi;
5945 va_list ap;
5946
5947 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5948 if (pi != tree) {
5949 va_start(ap, format)__builtin_va_start(ap, format);
5950 proto_tree_set_representation_value(pi, format, ap);
5951 va_end(ap)__builtin_va_end(ap);
5952 }
5953
5954 return pi;
5955}
5956
5957proto_item *
5958proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5959 int start, int length, uint64_t value,
5960 const char *format, ...)
5961{
5962 proto_item *pi;
5963 va_list ap;
5964
5965 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5966 if (pi != tree) {
5967 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5967, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5968
5969 va_start(ap, format)__builtin_va_start(ap, format);
5970 proto_tree_set_representation(pi, format, ap);
5971 va_end(ap)__builtin_va_end(ap);
5972 }
5973
5974 return pi;
5975}
5976
5977/* Set the FT_UINT{40,48,56,64} value */
5978static void
5979proto_tree_set_uint64(field_info *fi, uint64_t value)
5980{
5981 const header_field_info *hfinfo;
5982 uint64_t integer;
5983
5984 hfinfo = fi->hfinfo;
5985 integer = value;
5986
5987 if (hfinfo->bitmask) {
5988 /* Mask out irrelevant portions */
5989 integer &= hfinfo->bitmask;
5990
5991 /* Shift bits */
5992 integer >>= hfinfo_bitshift(hfinfo);
5993
5994 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5995 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)
;
5996 }
5997
5998 fvalue_set_uinteger64(fi->value, integer);
5999}
6000
6001/* Add FT_INT{8,16,24,32} to a proto_tree */
6002proto_item *
6003proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6004 int length, int32_t value)
6005{
6006 proto_item *pi = NULL((void*)0);
6007 header_field_info *hfinfo;
6008
6009 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6010
6011 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", 6011
, __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", 6011, "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", 6011, "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", 6011, __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)
; } } }
;
6012
6013 switch (hfinfo->type) {
6014 case FT_INT8:
6015 case FT_INT16:
6016 case FT_INT24:
6017 case FT_INT32:
6018 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6019 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6020 break;
6021
6022 default:
6023 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)
6024 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6025 }
6026
6027 return pi;
6028}
6029
6030proto_item *
6031proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6032 int start, int length, int32_t value,
6033 const char *format, ...)
6034{
6035 proto_item *pi;
6036 va_list ap;
6037
6038 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6039 if (pi != tree) {
6040 va_start(ap, format)__builtin_va_start(ap, format);
6041 proto_tree_set_representation_value(pi, format, ap);
6042 va_end(ap)__builtin_va_end(ap);
6043 }
6044
6045 return pi;
6046}
6047
6048proto_item *
6049proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6050 int start, int length, int32_t value,
6051 const char *format, ...)
6052{
6053 proto_item *pi;
6054 va_list ap;
6055
6056 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6057 if (pi != tree) {
6058 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6058, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6059
6060 va_start(ap, format)__builtin_va_start(ap, format);
6061 proto_tree_set_representation(pi, format, ap);
6062 va_end(ap)__builtin_va_end(ap);
6063 }
6064
6065 return pi;
6066}
6067
6068/* Set the FT_INT{8,16,24,32} value */
6069static void
6070proto_tree_set_int(field_info *fi, int32_t value)
6071{
6072 const header_field_info *hfinfo;
6073 uint32_t integer;
6074 int no_of_bits;
6075
6076 hfinfo = fi->hfinfo;
6077 integer = (uint32_t) value;
6078
6079 if (hfinfo->bitmask) {
6080 /* Mask out irrelevant portions */
6081 integer &= (uint32_t)(hfinfo->bitmask);
6082
6083 /* Shift bits */
6084 integer >>= hfinfo_bitshift(hfinfo);
6085
6086 no_of_bits = ws_count_ones(hfinfo->bitmask);
6087 integer = ws_sign_ext32(integer, no_of_bits);
6088
6089 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6090 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)
;
6091 }
6092
6093 fvalue_set_sinteger(fi->value, integer);
6094}
6095
6096/* Add FT_INT{40,48,56,64} to a proto_tree */
6097proto_item *
6098proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6099 int length, int64_t value)
6100{
6101 proto_item *pi = NULL((void*)0);
6102 header_field_info *hfinfo;
6103
6104 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6105
6106 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", 6106
, __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", 6106, "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", 6106, "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", 6106, __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)
; } } }
;
6107
6108 switch (hfinfo->type) {
6109 case FT_INT40:
6110 case FT_INT48:
6111 case FT_INT56:
6112 case FT_INT64:
6113 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6114 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6115 break;
6116
6117 default:
6118 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)
6119 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6120 }
6121
6122 return pi;
6123}
6124
6125proto_item *
6126proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6127 int start, int length, int64_t value,
6128 const char *format, ...)
6129{
6130 proto_item *pi;
6131 va_list ap;
6132
6133 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6134 if (pi != tree) {
6135 va_start(ap, format)__builtin_va_start(ap, format);
6136 proto_tree_set_representation_value(pi, format, ap);
6137 va_end(ap)__builtin_va_end(ap);
6138 }
6139
6140 return pi;
6141}
6142
6143/* Set the FT_INT{40,48,56,64} value */
6144static void
6145proto_tree_set_int64(field_info *fi, int64_t value)
6146{
6147 const header_field_info *hfinfo;
6148 uint64_t integer;
6149 int no_of_bits;
6150
6151 hfinfo = fi->hfinfo;
6152 integer = value;
6153
6154 if (hfinfo->bitmask) {
6155 /* Mask out irrelevant portions */
6156 integer &= hfinfo->bitmask;
6157
6158 /* Shift bits */
6159 integer >>= hfinfo_bitshift(hfinfo);
6160
6161 no_of_bits = ws_count_ones(hfinfo->bitmask);
6162 integer = ws_sign_ext64(integer, no_of_bits);
6163
6164 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6165 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)
;
6166 }
6167
6168 fvalue_set_sinteger64(fi->value, integer);
6169}
6170
6171proto_item *
6172proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6173 int start, int length, int64_t value,
6174 const char *format, ...)
6175{
6176 proto_item *pi;
6177 va_list ap;
6178
6179 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6180 if (pi != tree) {
6181 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6181, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6182
6183 va_start(ap, format)__builtin_va_start(ap, format);
6184 proto_tree_set_representation(pi, format, ap);
6185 va_end(ap)__builtin_va_end(ap);
6186 }
6187
6188 return pi;
6189}
6190
6191/* Add a FT_EUI64 to a proto_tree */
6192proto_item *
6193proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6194 int length, const uint64_t value)
6195{
6196 proto_item *pi;
6197 header_field_info *hfinfo;
6198
6199 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6200
6201 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", 6201
, __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", 6201, "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", 6201, "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", 6201, __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)
; } } }
;
6202
6203 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",
6203, ((hfinfo))->abbrev))))
;
6204
6205 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6206 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6207
6208 return pi;
6209}
6210
6211proto_item *
6212proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6213 int start, int length, const uint64_t value,
6214 const char *format, ...)
6215{
6216 proto_item *pi;
6217 va_list ap;
6218
6219 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6220 if (pi != tree) {
6221 va_start(ap, format)__builtin_va_start(ap, format);
6222 proto_tree_set_representation_value(pi, format, ap);
6223 va_end(ap)__builtin_va_end(ap);
6224 }
6225
6226 return pi;
6227}
6228
6229proto_item *
6230proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6231 int start, int length, const uint64_t value,
6232 const char *format, ...)
6233{
6234 proto_item *pi;
6235 va_list ap;
6236
6237 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6238 if (pi != tree) {
6239 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6239, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6240
6241 va_start(ap, format)__builtin_va_start(ap, format);
6242 proto_tree_set_representation(pi, format, ap);
6243 va_end(ap)__builtin_va_end(ap);
6244 }
6245
6246 return pi;
6247}
6248
6249/* Set the FT_EUI64 value */
6250static void
6251proto_tree_set_eui64(field_info *fi, const uint64_t value)
6252{
6253 uint8_t v[FT_EUI64_LEN8];
6254 phton64(v, value);
6255 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6256}
6257
6258static void
6259proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6260{
6261 if (encoding)
6262 {
6263 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6264 } else {
6265 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6266 }
6267}
6268
6269proto_item *
6270proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6271 const mac_hf_list_t *list_generic,
6272 int idx, tvbuff_t *tvb,
6273 proto_tree *tree, int offset)
6274{
6275 const uint8_t addr[6];
6276 const char *addr_name = NULL((void*)0);
6277 const char *oui_name = NULL((void*)0);
6278 proto_item *addr_item = NULL((void*)0);
6279 proto_tree *addr_tree = NULL((void*)0);
6280 proto_item *ret_val = NULL((void*)0);
6281
6282 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6283 return NULL((void*)0);
6284 }
6285
6286 /* Resolve what we can of the address */
6287 tvb_memcpy(tvb, (void *)addr, offset, 6);
6288 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6289 addr_name = get_ether_name(addr);
6290 }
6291 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6292 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6293 }
6294
6295 /* Add the item for the specific address type */
6296 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6297 if (idx >= 0) {
6298 addr_tree = proto_item_add_subtree(ret_val, idx);
6299 }
6300 else {
6301 addr_tree = tree;
6302 }
6303
6304 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6305 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6306 tvb, offset, 6, addr_name);
6307 proto_item_set_generated(addr_item);
6308 proto_item_set_hidden(addr_item);
6309 }
6310
6311 if (list_specific->hf_oui != NULL((void*)0)) {
6312 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6313 proto_item_set_generated(addr_item);
6314 proto_item_set_hidden(addr_item);
6315
6316 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6317 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6318 proto_item_set_generated(addr_item);
6319 proto_item_set_hidden(addr_item);
6320 }
6321 }
6322
6323 if (list_specific->hf_lg != NULL((void*)0)) {
6324 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6325 }
6326 if (list_specific->hf_ig != NULL((void*)0)) {
6327 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6328 }
6329
6330 /* Were we given a list for generic address fields? If not, stop here */
6331 if (list_generic == NULL((void*)0)) {
6332 return ret_val;
6333 }
6334
6335 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6336 proto_item_set_hidden(addr_item);
6337
6338 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6339 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6340 tvb, offset, 6, addr_name);
6341 proto_item_set_generated(addr_item);
6342 proto_item_set_hidden(addr_item);
6343 }
6344
6345 if (list_generic->hf_oui != NULL((void*)0)) {
6346 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6347 proto_item_set_generated(addr_item);
6348 proto_item_set_hidden(addr_item);
6349
6350 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6351 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6352 proto_item_set_generated(addr_item);
6353 proto_item_set_hidden(addr_item);
6354 }
6355 }
6356
6357 if (list_generic->hf_lg != NULL((void*)0)) {
6358 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6359 proto_item_set_hidden(addr_item);
6360 }
6361 if (list_generic->hf_ig != NULL((void*)0)) {
6362 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6363 proto_item_set_hidden(addr_item);
6364 }
6365 return ret_val;
6366}
6367
6368static proto_item *
6369proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6370{
6371 proto_node *pnode, *tnode, *sibling;
6372 field_info *tfi;
6373 unsigned depth = 1;
6374
6375 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6375, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6376
6377 /*
6378 * Restrict our depth. proto_tree_traverse_pre_order and
6379 * proto_tree_traverse_post_order (and possibly others) are recursive
6380 * so we need to be mindful of our stack size.
6381 */
6382 if (tree->first_child == NULL((void*)0)) {
6383 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6384 depth++;
6385 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6386 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__)), 6389)))
6387 "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__)), 6389)))
6388 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__)), 6389)))
6389 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__)), 6389)))
;
6390 }
6391 }
6392 }
6393
6394 /*
6395 * Make sure "tree" is ready to have subtrees under it, by
6396 * checking whether it's been given an ett_ value.
6397 *
6398 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6399 * node of the protocol tree. That node is not displayed,
6400 * so it doesn't need an ett_ value to remember whether it
6401 * was expanded.
6402 */
6403 tnode = tree;
6404 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6405 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6406 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"
, 6407)
6407 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"
, 6407)
;
6408 /* XXX - is it safe to continue here? */
6409 }
6410
6411 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6412 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6413 pnode->parent = tnode;
6414 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6415 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6416 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6417
6418 if (tnode->last_child != NULL((void*)0)) {
6419 sibling = tnode->last_child;
6420 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6420, "sibling->next == ((void*)0)"
))))
;
6421 sibling->next = pnode;
6422 } else
6423 tnode->first_child = pnode;
6424 tnode->last_child = pnode;
6425
6426 /* We should not be adding a fake node for an interesting field */
6427 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", 6427, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6428
6429 /* XXX - Should the proto_item have a header_field_info member, at least
6430 * for faked items, to know what hfi was faked? (Some dissectors look at
6431 * the tree items directly.)
6432 */
6433 return (proto_item *)pnode;
6434}
6435
6436/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6437static proto_item *
6438proto_tree_add_node(proto_tree *tree, field_info *fi)
6439{
6440 proto_node *pnode, *tnode, *sibling;
6441 field_info *tfi;
6442 unsigned depth = 1;
6443
6444 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6444, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6445
6446 /*
6447 * Restrict our depth. proto_tree_traverse_pre_order and
6448 * proto_tree_traverse_post_order (and possibly others) are recursive
6449 * so we need to be mindful of our stack size.
6450 */
6451 if (tree->first_child == NULL((void*)0)) {
6452 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6453 depth++;
6454 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6455 fvalue_free(fi->value);
6456 fi->value = NULL((void*)0);
6457 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__)), 6460)))
6458 "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__)), 6460)))
6459 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__)), 6460)))
6460 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__)), 6460)))
;
6461 }
6462 }
6463 }
6464
6465 /*
6466 * Make sure "tree" is ready to have subtrees under it, by
6467 * checking whether it's been given an ett_ value.
6468 *
6469 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6470 * node of the protocol tree. That node is not displayed,
6471 * so it doesn't need an ett_ value to remember whether it
6472 * was expanded.
6473 */
6474 tnode = tree;
6475 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6476 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6477 /* Since we are not adding fi to a node, its fvalue won't get
6478 * freed by proto_tree_free_node(), so free it now.
6479 */
6480 fvalue_free(fi->value);
6481 fi->value = NULL((void*)0);
6482 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", 6483)
6483 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", 6483)
;
6484 /* XXX - is it safe to continue here? */
6485 }
6486
6487 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6488 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6489 pnode->parent = tnode;
6490 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6491 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6492 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6493
6494 if (tnode->last_child != NULL((void*)0)) {
6495 sibling = tnode->last_child;
6496 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6496, "sibling->next == ((void*)0)"
))))
;
6497 sibling->next = pnode;
6498 } else
6499 tnode->first_child = pnode;
6500 tnode->last_child = pnode;
6501
6502 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6503
6504 return (proto_item *)pnode;
6505}
6506
6507
6508/* Generic way to allocate field_info and add to proto_tree.
6509 * Sets *pfi to address of newly-allocated field_info struct */
6510static proto_item *
6511proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6512 int *length)
6513{
6514 proto_item *pi;
6515 field_info *fi;
6516 int item_length;
6517
6518 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6519 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6520 pi = proto_tree_add_node(tree, fi);
6521
6522 return pi;
6523}
6524
6525
6526static void
6527get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6528 int *item_length, const unsigned encoding)
6529{
6530 int length_remaining;
6531
6532 /*
6533 * We only allow a null tvbuff if the item has a zero length,
6534 * i.e. if there's no data backing it.
6535 */
6536 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", 6536, "tvb != ((void*)0) || *length == 0"
))))
;
6537
6538 /*
6539 * XXX - in some protocols, there are 32-bit unsigned length
6540 * fields, so lengths in protocol tree and tvbuff routines
6541 * should really be unsigned. We should have, for those
6542 * field types for which "to the end of the tvbuff" makes sense,
6543 * additional routines that take no length argument and
6544 * add fields that run to the end of the tvbuff.
6545 */
6546 if (*length == -1) {
6547 /*
6548 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6549 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6550 * of -1 means "set the length to what remains in the
6551 * tvbuff".
6552 *
6553 * The assumption is either that
6554 *
6555 * 1) the length of the item can only be determined
6556 * by dissection (typically true of items with
6557 * subitems, which are probably FT_NONE or
6558 * FT_PROTOCOL)
6559 *
6560 * or
6561 *
6562 * 2) if the tvbuff is "short" (either due to a short
6563 * snapshot length or due to lack of reassembly of
6564 * fragments/segments/whatever), we want to display
6565 * what's available in the field (probably FT_BYTES
6566 * or FT_STRING) and then throw an exception later
6567 *
6568 * or
6569 *
6570 * 3) the field is defined to be "what's left in the
6571 * packet"
6572 *
6573 * so we set the length to what remains in the tvbuff so
6574 * that, if we throw an exception while dissecting, it
6575 * has what is probably the right value.
6576 *
6577 * For FT_STRINGZ, it means "the string is null-terminated,
6578 * not null-padded; set the length to the actual length
6579 * of the string", and if the tvbuff if short, we just
6580 * throw an exception.
6581 *
6582 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6583 * it means "find the end of the string",
6584 * and if the tvbuff if short, we just throw an exception.
6585 *
6586 * It's not valid for any other type of field. For those
6587 * fields, we treat -1 the same way we treat other
6588 * negative values - we assume the length is a Really
6589 * Big Positive Number, and throw a ReportedBoundsError
6590 * exception, under the assumption that the Really Big
6591 * Length would run past the end of the packet.
6592 */
6593 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
))
)) {
6594 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6595 /*
6596 * Leave the length as -1, so our caller knows
6597 * it was -1.
6598 */
6599 *item_length = *length;
6600 return;
6601 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6602 switch (tvb_get_uint8(tvb, start) >> 6)
6603 {
6604 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6605 *item_length = 1;
6606 break;
6607 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6608 *item_length = 2;
6609 break;
6610 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6611 *item_length = 4;
6612 break;
6613 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6614 *item_length = 8;
6615 break;
6616 }
6617 }
6618 }
6619
6620 switch (hfinfo->type) {
6621
6622 case FT_PROTOCOL:
6623 case FT_NONE:
6624 case FT_BYTES:
6625 case FT_STRING:
6626 case FT_STRINGZPAD:
6627 case FT_STRINGZTRUNC:
6628 /*
6629 * We allow FT_PROTOCOLs to be zero-length -
6630 * for example, an ONC RPC NULL procedure has
6631 * neither arguments nor reply, so the
6632 * payload for that protocol is empty.
6633 *
6634 * We also allow the others to be zero-length -
6635 * because that's the way the code has been for a
6636 * long, long time.
6637 *
6638 * However, we want to ensure that the start
6639 * offset is not *past* the byte past the end
6640 * of the tvbuff: we throw an exception in that
6641 * case.
6642 */
6643 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6644 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6644, "*length >= 0"
))))
;
6645 break;
6646
6647 case FT_STRINGZ:
6648 /*
6649 * Leave the length as -1, so our caller knows
6650 * it was -1.
6651 */
6652 break;
6653
6654 default:
6655 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6656 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6656))
;
6657 }
6658 *item_length = *length;
6659 } else {
6660 *item_length = *length;
6661 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6662 /*
6663 * These types are for interior nodes of the
6664 * tree, and don't have data associated with
6665 * them; if the length is negative (XXX - see
6666 * above) or goes past the end of the tvbuff,
6667 * cut it short at the end of the tvbuff.
6668 * That way, if this field is selected in
6669 * Wireshark, we don't highlight stuff past
6670 * the end of the data.
6671 */
6672 /* XXX - what to do, if we don't have a tvb? */
6673 if (tvb) {
6674 length_remaining = tvb_captured_length_remaining(tvb, start);
6675 if (*item_length < 0 ||
6676 (*item_length > 0 &&
6677 (length_remaining < *item_length)))
6678 *item_length = length_remaining;
6679 }
6680 }
6681 if (*item_length < 0) {
6682 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6683 }
6684 }
6685}
6686
6687static int
6688get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6689 int length, unsigned item_length, const int encoding)
6690{
6691 uint32_t n;
6692
6693 /*
6694 * We need to get the correct item length here.
6695 * That's normally done by proto_tree_new_item(),
6696 * but we won't be calling it.
6697 */
6698 switch (hfinfo->type) {
6699
6700 case FT_NONE:
6701 case FT_PROTOCOL:
6702 case FT_BYTES:
6703 /*
6704 * The length is the specified length.
6705 */
6706 break;
6707
6708 case FT_UINT_BYTES:
6709 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6710 item_length += n;
6711 if ((int)item_length < length) {
6712 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6713 }
6714 break;
6715
6716 /* XXX - make these just FT_UINT? */
6717 case FT_UINT8:
6718 case FT_UINT16:
6719 case FT_UINT24:
6720 case FT_UINT32:
6721 case FT_UINT40:
6722 case FT_UINT48:
6723 case FT_UINT56:
6724 case FT_UINT64:
6725 /* XXX - make these just FT_INT? */
6726 case FT_INT8:
6727 case FT_INT16:
6728 case FT_INT24:
6729 case FT_INT32:
6730 case FT_INT40:
6731 case FT_INT48:
6732 case FT_INT56:
6733 case FT_INT64:
6734 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6735 if (length < -1) {
6736 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6737 }
6738 if (length == -1) {
6739 uint64_t dummy;
6740 /* This can throw an exception */
6741 /* XXX - do this without fetching the varint? */
6742 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6743 if (length == 0) {
6744 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6745 }
6746 }
6747 item_length = length;
6748 break;
6749 }
6750
6751 /*
6752 * The length is the specified length.
6753 */
6754 break;
6755
6756 case FT_BOOLEAN:
6757 case FT_CHAR:
6758 case FT_IPv4:
6759 case FT_IPXNET:
6760 case FT_IPv6:
6761 case FT_FCWWN:
6762 case FT_AX25:
6763 case FT_VINES:
6764 case FT_ETHER:
6765 case FT_EUI64:
6766 case FT_GUID:
6767 case FT_OID:
6768 case FT_REL_OID:
6769 case FT_SYSTEM_ID:
6770 case FT_FLOAT:
6771 case FT_DOUBLE:
6772 case FT_STRING:
6773 /*
6774 * The length is the specified length.
6775 */
6776 break;
6777
6778 case FT_STRINGZ:
6779 if (length < -1) {
6780 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6781 }
6782 if (length == -1) {
6783 /* This can throw an exception */
6784 /* XXX - do this without fetching the string? */
6785 wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, &length, encoding));
6786 }
6787 item_length = length;
6788 break;
6789
6790 case FT_UINT_STRING:
6791 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6792 item_length += n;
6793 if ((int)item_length < length) {
6794 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6795 }
6796 break;
6797
6798 case FT_STRINGZPAD:
6799 case FT_STRINGZTRUNC:
6800 case FT_ABSOLUTE_TIME:
6801 case FT_RELATIVE_TIME:
6802 case FT_IEEE_11073_SFLOAT:
6803 case FT_IEEE_11073_FLOAT:
6804 /*
6805 * The length is the specified length.
6806 */
6807 break;
6808
6809 default:
6810 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
))
6811 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
))
6812 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
))
6813 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
))
;
6814 break;
6815 }
6816 return item_length;
6817}
6818
6819// This was arbitrarily chosen, but if you're adding 50K items to the tree
6820// without advancing the offset you should probably take a long, hard look
6821// at what you're doing.
6822// We *could* make this a configurable option, but I (Gerald) would like to
6823// avoid adding yet another nerd knob.
6824# define PROTO_TREE_MAX_IDLE50000 50000
6825static field_info *
6826new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6827 const int start, const int item_length)
6828{
6829 field_info *fi;
6830
6831 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6832
6833 fi->hfinfo = hfinfo;
6834 fi->start = start;
6835 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6836 /* add the data source tvbuff */
6837 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6838
6839 // If our start offset hasn't advanced after adding many items it probably
6840 // means we're in a large or infinite loop.
6841 if (fi->start > 0) {
6842 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6843 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6844 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", 6844, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6845 } else {
6846 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6847 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6848 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6849 }
6850 }
6851 fi->length = item_length;
6852 fi->tree_type = -1;
6853 fi->flags = 0;
6854 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6855 /* If the tree is not visible, set the item hidden, unless we
6856 * need the representation or length and can't fake them.
6857 */
6858 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6859 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6860 }
6861 }
6862 fi->value = fvalue_new(fi->hfinfo->type);
6863 fi->rep = NULL((void*)0);
6864
6865 fi->appendix_start = 0;
6866 fi->appendix_length = 0;
6867
6868 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6869 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6870
6871 return fi;
6872}
6873
6874static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6875{
6876 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6877 return 0;
6878 }
6879
6880 /* Search for field name */
6881 char *ptr = strstr(representation, hfinfo->name);
6882 if (!ptr) {
6883 return 0;
6884 }
6885
6886 /* Check if field name ends with the ": " delimiter */
6887 ptr += strlen(hfinfo->name);
6888 if (strncmp(ptr, ": ", 2) == 0) {
6889 ptr += 2;
6890 }
6891
6892 /* Return offset to after field name */
6893 return ptr - representation;
6894}
6895
6896static size_t label_find_name_pos(const item_label_t *rep)
6897{
6898 size_t name_pos = 0;
6899
6900 /* If the value_pos is too small or too large, we can't find the expected format */
6901 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
6902 return 0;
6903 }
6904
6905 /* Check if the format looks like "label: value", then set name_pos before ':'. */
6906 if (rep->representation[rep->value_pos-2] == ':') {
6907 name_pos = rep->value_pos - 2;
6908 }
6909
6910 return name_pos;
6911}
6912
6913/* If the protocol tree is to be visible, set the representation of a
6914 proto_tree entry with the name of the field for the item and with
6915 the value formatted with the supplied printf-style format and
6916 argument list. */
6917static void
6918proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6919{
6920 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6920, __func__, "assertion failed: %s", "pi"
); } while (0)
;
6921
6922 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6923 * items string representation */
6924 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
6925 size_t name_pos, ret = 0;
6926 char *str;
6927 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6928 const header_field_info *hf;
6929
6930 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6930, "fi"))))
;
6931
6932 hf = fi->hfinfo;
6933
6934 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;
;
6935 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))
)) {
6936 uint64_t val;
6937 char *p;
6938
6939 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)
)
6940 val = fvalue_get_uinteger(fi->value);
6941 else
6942 val = fvalue_get_uinteger64(fi->value);
6943
6944 val <<= hfinfo_bitshift(hf);
6945
6946 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
6947 ret = (p - fi->rep->representation);
6948 }
6949
6950 /* put in the hf name */
6951 name_pos = ret = label_concat(fi->rep->representation, ret, hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, hf->
name, 0)
;
6952
6953 ret = label_concat(fi->rep->representation, ret, ": ")ws_label_strcpy(fi->rep->representation, 240, ret, ": "
, 0)
;
6954 /* If possible, Put in the value of the string */
6955 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
6956 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"
, 6956, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
6957 fi->rep->value_pos = ret;
6958 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, str, 0);
6959 if (ret >= ITEM_LABEL_LENGTH240) {
6960 /* Uh oh, we don't have enough room. Tell the user
6961 * that the field is truncated.
6962 */
6963 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
6964 }
6965 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
6966 }
6967}
6968
6969/* If the protocol tree is to be visible, set the representation of a
6970 proto_tree entry with the representation formatted with the supplied
6971 printf-style format and argument list. */
6972static void
6973proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
6974{
6975 size_t ret; /*tmp return value */
6976 char *str;
6977 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6978
6979 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6979, "fi"))))
;
6980
6981 if (!proto_item_is_hidden(pi)) {
6982 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;
;
6983
6984 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
6985 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"
, 6985, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
6986 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
6987 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
6988 if (ret >= ITEM_LABEL_LENGTH240) {
6989 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
6990 size_t name_pos = label_find_name_pos(fi->rep);
6991 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
6992 }
6993 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
6994 }
6995}
6996
6997static int
6998proto_strlcpy(char *dest, const char *src, size_t dest_size)
6999{
7000 if (dest_size == 0) return 0;
7001
7002 size_t res = g_strlcpy(dest, src, dest_size);
7003
7004 /* At most dest_size - 1 characters will be copied
7005 * (unless dest_size is 0). */
7006 if (res >= dest_size)
7007 res = dest_size - 1;
7008 return (int) res;
7009}
7010
7011static header_field_info *
7012hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7013{
7014 header_field_info *dup_hfinfo;
7015
7016 if (hfinfo->same_name_prev_id == -1)
7017 return NULL((void*)0);
7018 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", 7018
, __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", 7018, "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", 7018,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7019 return dup_hfinfo;
7020}
7021
7022static void
7023hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7024{
7025 g_free(last_field_name);
7026 last_field_name = NULL((void*)0);
7027
7028 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7029 /* No hfinfo with the same name */
7030 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
7031 return;
7032 }
7033
7034 if (hfinfo->same_name_next) {
7035 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7036 }
7037
7038 if (hfinfo->same_name_prev_id != -1) {
7039 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7040 same_name_prev->same_name_next = hfinfo->same_name_next;
7041 if (!hfinfo->same_name_next) {
7042 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7043 g_hash_table_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7044 }
7045 }
7046}
7047
7048int
7049proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7050{
7051 const header_field_info *hfinfo = finfo->hfinfo;
7052 int label_len = 0;
7053 char *tmp_str;
7054 const char *str;
7055 const uint8_t *bytes;
7056 uint32_t number;
7057 uint64_t number64;
7058 const char *hf_str_val;
7059 char number_buf[NUMBER_LABEL_LENGTH80];
7060 const char *number_out;
7061 address addr;
7062 const ipv4_addr_and_mask *ipv4;
7063 const ipv6_addr_and_prefix *ipv6;
7064
7065 switch (hfinfo->type) {
7066
7067 case FT_NONE:
7068 case FT_PROTOCOL:
7069 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7070
7071 case FT_UINT_BYTES:
7072 case FT_BYTES:
7073 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7074 hfinfo,
7075 fvalue_get_bytes_data(finfo->value),
7076 (unsigned)fvalue_length2(finfo->value),
7077 label_str_size);
7078 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7079 wmem_free(NULL((void*)0), tmp_str);
7080 break;
7081
7082 case FT_ABSOLUTE_TIME:
7083 {
7084 const nstime_t *value = fvalue_get_time(finfo->value);
7085 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7086 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7087 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7088 }
7089 if (hfinfo->strings) {
7090 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7091 if (time_string != NULL((void*)0)) {
7092 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7093 break;
7094 }
7095 }
7096 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7097 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7098 wmem_free(NULL((void*)0), tmp_str);
7099 break;
7100 }
7101
7102 case FT_RELATIVE_TIME:
7103 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7104 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7105 wmem_free(NULL((void*)0), tmp_str);
7106 break;
7107
7108 case FT_BOOLEAN:
7109 number64 = fvalue_get_uinteger64(finfo->value);
7110 label_len = proto_strlcpy(display_label_str,
7111 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7112 break;
7113
7114 case FT_CHAR:
7115 number = fvalue_get_uinteger(finfo->value);
7116
7117 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7118 char tmp[ITEM_LABEL_LENGTH240];
7119 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7120
7121 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7121, "fmtfunc"))))
;
7122 fmtfunc(tmp, number);
7123
7124 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7125
7126 } else if (hfinfo->strings) {
7127 number_out = hf_try_val_to_str(number, hfinfo);
7128
7129 if (!number_out) {
7130 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7131 }
7132
7133 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7134
7135 } else {
7136 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7137
7138 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7139 }
7140
7141 break;
7142
7143 /* XXX - make these just FT_NUMBER? */
7144 case FT_INT8:
7145 case FT_INT16:
7146 case FT_INT24:
7147 case FT_INT32:
7148 case FT_UINT8:
7149 case FT_UINT16:
7150 case FT_UINT24:
7151 case FT_UINT32:
7152 case FT_FRAMENUM:
7153 hf_str_val = NULL((void*)0);
7154 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
))
?
7155 (uint32_t) fvalue_get_sinteger(finfo->value) :
7156 fvalue_get_uinteger(finfo->value);
7157
7158 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7159 char tmp[ITEM_LABEL_LENGTH240];
7160 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7161
7162 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7162, "fmtfunc"))))
;
7163 fmtfunc(tmp, number);
7164
7165 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7166
7167 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7168 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7169 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7170 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7171 hf_str_val = hf_try_val_to_str(number, hfinfo);
7172 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7173 } else {
7174 number_out = hf_try_val_to_str(number, hfinfo);
7175
7176 if (!number_out) {
7177 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7178 }
7179
7180 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7181 }
7182 } else {
7183 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7184
7185 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7186 }
7187
7188 break;
7189
7190 case FT_INT40:
7191 case FT_INT48:
7192 case FT_INT56:
7193 case FT_INT64:
7194 case FT_UINT40:
7195 case FT_UINT48:
7196 case FT_UINT56:
7197 case FT_UINT64:
7198 hf_str_val = NULL((void*)0);
7199 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
))
?
7200 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7201 fvalue_get_uinteger64(finfo->value);
7202
7203 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7204 char tmp[ITEM_LABEL_LENGTH240];
7205 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7206
7207 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7207, "fmtfunc64"
))))
;
7208 fmtfunc64(tmp, number64);
7209
7210 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7211 } else if (hfinfo->strings) {
7212 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7213 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7214 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7215 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7216 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7217 } else {
7218 number_out = hf_try_val64_to_str(number64, hfinfo);
7219
7220 if (!number_out)
7221 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7222
7223 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7224 }
7225 } else {
7226 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7227
7228 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7229 }
7230
7231 break;
7232
7233 case FT_EUI64:
7234 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7235 tmp_str = address_to_display(NULL((void*)0), &addr);
7236 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7237 wmem_free(NULL((void*)0), tmp_str);
7238 break;
7239
7240 case FT_IPv4:
7241 ipv4 = fvalue_get_ipv4(finfo->value);
7242 //XXX: Should we ignore the mask?
7243 set_address_ipv4(&addr, ipv4);
7244 tmp_str = address_to_display(NULL((void*)0), &addr);
7245 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7246 wmem_free(NULL((void*)0), tmp_str);
7247 free_address(&addr);
7248 break;
7249
7250 case FT_IPv6:
7251 ipv6 = fvalue_get_ipv6(finfo->value);
7252 set_address_ipv6(&addr, ipv6);
7253 tmp_str = address_to_display(NULL((void*)0), &addr);
7254 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7255 wmem_free(NULL((void*)0), tmp_str);
7256 free_address(&addr);
7257 break;
7258
7259 case FT_FCWWN:
7260 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7261 tmp_str = address_to_display(NULL((void*)0), &addr);
7262 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7263 wmem_free(NULL((void*)0), tmp_str);
7264 break;
7265
7266 case FT_ETHER:
7267 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7268 tmp_str = address_to_display(NULL((void*)0), &addr);
7269 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7270 wmem_free(NULL((void*)0), tmp_str);
7271 break;
7272
7273 case FT_GUID:
7274 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7275 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7276 wmem_free(NULL((void*)0), tmp_str);
7277 break;
7278
7279 case FT_REL_OID:
7280 bytes = fvalue_get_bytes_data(finfo->value);
7281 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7282 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7283 wmem_free(NULL((void*)0), tmp_str);
7284 break;
7285
7286 case FT_OID:
7287 bytes = fvalue_get_bytes_data(finfo->value);
7288 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7289 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7290 wmem_free(NULL((void*)0), tmp_str);
7291 break;
7292
7293 case FT_SYSTEM_ID:
7294 bytes = fvalue_get_bytes_data(finfo->value);
7295 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7296 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7297 wmem_free(NULL((void*)0), tmp_str);
7298 break;
7299
7300 case FT_FLOAT:
7301 case FT_DOUBLE:
7302 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7303 break;
7304
7305 case FT_IEEE_11073_SFLOAT:
7306 case FT_IEEE_11073_FLOAT:
7307 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7308 break;
7309
7310 case FT_STRING:
7311 case FT_STRINGZ:
7312 case FT_UINT_STRING:
7313 case FT_STRINGZPAD:
7314 case FT_STRINGZTRUNC:
7315 str = fvalue_get_string(finfo->value);
7316 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, str, label_strcat_flags(hfinfo));
7317 if (label_len >= label_str_size) {
7318 /* Truncation occurred. Get the real length
7319 * copied (not including '\0') */
7320 label_len = label_str_size ? label_str_size - 1 : 0;
7321 }
7322 break;
7323
7324 default:
7325 /* First try ftype string representation */
7326 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7327 if (!tmp_str) {
7328 /* Default to show as bytes */
7329 bytes = fvalue_get_bytes_data(finfo->value);
7330 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7331 }
7332 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7333 wmem_free(NULL((void*)0), tmp_str);
7334 break;
7335 }
7336 return label_len;
7337}
7338
7339const char *
7340proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7341 char *result, char *expr, const int size)
7342{
7343 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7344 GPtrArray *finfos;
7345 field_info *finfo = NULL((void*)0);
7346 header_field_info* hfinfo;
7347 const char *abbrev = NULL((void*)0);
7348
7349 char *str;
7350 col_custom_t *field_idx;
7351 int field_id;
7352 int ii = 0;
7353
7354 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7354, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7355 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7356 field_id = field_idx->field_id;
7357 if (field_id == 0) {
7358 GPtrArray *fvals = NULL((void*)0);
7359 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7360 if (fvals != NULL((void*)0)) {
7361
7362 // XXX - Handling occurrences is unusual when more
7363 // than one field is involved, e.g. there's four
7364 // results for tcp.port + tcp.port. We may really
7365 // want to apply it to the operands, not the output.
7366 // Note that occurrences are not quite the same as
7367 // the layer operator (should the grammar support
7368 // both?)
7369 /* Calculate single index or set outer boundaries */
7370 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7371 if (occurrence < 0) {
7372 i = occurrence + len;
7373 last = i;
7374 } else if (occurrence > 0) {
7375 i = occurrence - 1;
7376 last = i;
7377 } else {
7378 i = 0;
7379 last = len - 1;
7380 }
7381 if (i < 0 || i >= len) {
7382 g_ptr_array_unref(fvals);
7383 continue;
7384 }
7385 for (; i <= last; i++) {
7386 /* XXX - We could have a "resolved" result
7387 * for types where the value depends only
7388 * on the type, e.g. FT_IPv4, and not on
7389 * hfinfo->strings. Supporting the latter
7390 * requires knowing which hfinfo matched
7391 * if there are multiple with the same
7392 * abbreviation. In any case, we need to
7393 * know the expected return type of the
7394 * field expression.
7395 */
7396 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7397 if (offset_r && (offset_r < (size - 1)))
7398 result[offset_r++] = ',';
7399 if (offset_e && (offset_e < (size - 1)))
7400 expr[offset_e++] = ',';
7401 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7402 // col_{add,append,set}_* calls ws_label_strcpy
7403 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7404
7405 g_free(str);
7406 }
7407 g_ptr_array_unref(fvals);
7408 } else if (passed) {
7409 // XXX - Occurrence doesn't make sense for a test
7410 // output, it should be applied to the operands.
7411 if (offset_r && (offset_r < (size - 1)))
7412 result[offset_r++] = ',';
7413 if (offset_e && (offset_e < (size - 1)))
7414 expr[offset_e++] = ',';
7415 /* Prevent multiple check marks */
7416 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7417 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7418 } else {
7419 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7420 }
7421 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7422 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7423 } else {
7424 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7425 }
7426 }
7427 continue;
7428 }
7429 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", 7429
, __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", 7429,
"(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", 7429,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7430
7431 /* do we need to rewind ? */
7432 if (!hfinfo)
7433 return "";
7434
7435 if (occurrence < 0) {
7436 /* Search other direction */
7437 while (hfinfo->same_name_prev_id != -1) {
7438 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", 7438
, __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", 7438, "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", 7438,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7439 }
7440 }
7441
7442 prev_len = 0; /* Reset handled occurrences */
7443
7444 while (hfinfo) {
7445 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7446
7447 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7448 if (occurrence < 0) {
7449 hfinfo = hfinfo->same_name_next;
7450 } else {
7451 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7452 }
7453 continue;
7454 }
7455
7456 /* Are there enough occurrences of the field? */
7457 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7458 if (occurrence < 0) {
7459 hfinfo = hfinfo->same_name_next;
7460 } else {
7461 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7462 }
7463 prev_len += len;
7464 continue;
7465 }
7466
7467 /* Calculate single index or set outer boundaries */
7468 if (occurrence < 0) {
7469 i = occurrence + len + prev_len;
7470 last = i;
7471 } else if (occurrence > 0) {
7472 i = occurrence - 1 - prev_len;
7473 last = i;
7474 } else {
7475 i = 0;
7476 last = len - 1;
7477 }
7478
7479 prev_len += len; /* Count handled occurrences */
7480
7481 while (i <= last) {
7482 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7483
7484 if (offset_r && (offset_r < (size - 1)))
7485 result[offset_r++] = ',';
7486
7487 if (display_details) {
7488 char representation[ITEM_LABEL_LENGTH240];
7489 size_t offset = 0;
7490
7491 if (finfo->rep && finfo->rep->value_len) {
7492 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7493 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7494 } else {
7495 proto_item_fill_label(finfo, representation, &offset);
7496 }
7497 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7498 } else {
7499 switch (hfinfo->type) {
7500
7501 case FT_NONE:
7502 case FT_PROTOCOL:
7503 /* Prevent multiple check marks */
7504 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7505 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7506 } else {
7507 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7508 }
7509 break;
7510
7511 default:
7512 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7513 break;
7514 }
7515 }
7516
7517 if (offset_e && (offset_e < (size - 1)))
7518 expr[offset_e++] = ',';
7519
7520 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
))
)) {
7521 const char *hf_str_val;
7522 /* Integer types with BASE_NONE never get the numeric value. */
7523 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7524 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7525 } 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
)
) {
7526 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7527 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7528 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7529 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7530 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7531 }
7532 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7533 offset_e = (int)strlen(expr);
7534 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7535 /* Prevent multiple check marks */
7536 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7537 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7538 } else {
7539 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7540 }
7541 } else {
7542 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7543 // col_{add,append,set}_* calls ws_label_strcpy
7544 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7545 wmem_free(NULL((void*)0), str);
7546 }
7547 i++;
7548 }
7549
7550 /* XXX: Why is only the first abbreviation returned for a multifield
7551 * custom column? */
7552 if (!abbrev) {
7553 /* Store abbrev for return value */
7554 abbrev = hfinfo->abbrev;
7555 }
7556
7557 if (occurrence == 0) {
7558 /* Fetch next hfinfo with same name (abbrev) */
7559 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7560 } else {
7561 hfinfo = NULL((void*)0);
7562 }
7563 }
7564 }
7565
7566 if (offset_r >= (size - 1)) {
7567 mark_truncated(result, 0, size, NULL((void*)0));
7568 }
7569 if (offset_e >= (size - 1)) {
7570 mark_truncated(expr, 0, size, NULL((void*)0));
7571 }
7572 return abbrev ? abbrev : "";
7573}
7574
7575char *
7576proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7577{
7578 int len, prev_len, last, i;
7579 GPtrArray *finfos;
7580 field_info *finfo = NULL((void*)0);
7581 header_field_info* hfinfo;
7582
7583 char *filter = NULL((void*)0);
7584 GPtrArray *filter_array;
7585
7586 col_custom_t *col_custom;
7587 int field_id;
7588
7589 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7589, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7590 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7591 for (GSList *iter = field_ids; iter; iter = iter->next) {
7592 col_custom = (col_custom_t*)iter->data;
7593 field_id = col_custom->field_id;
7594 if (field_id == 0) {
7595 GPtrArray *fvals = NULL((void*)0);
7596 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7597 if (fvals != NULL((void*)0)) {
7598 // XXX - Handling occurrences is unusual when more
7599 // than one field is involved, e.g. there's four
7600 // results for tcp.port + tcp.port. We really
7601 // want to apply it to the operands, not the output.
7602 /* Calculate single index or set outer boundaries */
7603 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7604 if (occurrence < 0) {
7605 i = occurrence + len;
7606 last = i;
7607 } else if (occurrence > 0) {
7608 i = occurrence - 1;
7609 last = i;
7610 } else {
7611 i = 0;
7612 last = len - 1;
7613 }
7614 if (i < 0 || i >= len) {
7615 g_ptr_array_unref(fvals);
7616 continue;
7617 }
7618 for (; i <= last; i++) {
7619 /* XXX - Should multiple values for one
7620 * field use set membership to reduce
7621 * verbosity, here and below? */
7622 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7623 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7624 wmem_free(NULL((void*)0), str);
7625 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7626 g_ptr_array_add(filter_array, filter);
7627 }
7628 }
7629 g_ptr_array_unref(fvals);
7630 } else if (passed) {
7631 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7632 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7633 g_ptr_array_add(filter_array, filter);
7634 }
7635 } else {
7636 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7637 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7638 g_ptr_array_add(filter_array, filter);
7639 }
7640 }
7641 continue;
7642 }
7643
7644 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", 7644
, __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", 7644,
"(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", 7644,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7645
7646 /* do we need to rewind ? */
7647 if (!hfinfo)
7648 return NULL((void*)0);
7649
7650 if (occurrence < 0) {
7651 /* Search other direction */
7652 while (hfinfo->same_name_prev_id != -1) {
7653 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", 7653
, __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", 7653, "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", 7653,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7654 }
7655 }
7656
7657 prev_len = 0; /* Reset handled occurrences */
7658
7659 while (hfinfo) {
7660 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7661
7662 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7663 if (occurrence < 0) {
7664 hfinfo = hfinfo->same_name_next;
7665 } else {
7666 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7667 }
7668 continue;
7669 }
7670
7671 /* Are there enough occurrences of the field? */
7672 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7673 if (occurrence < 0) {
7674 hfinfo = hfinfo->same_name_next;
7675 } else {
7676 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7677 }
7678 prev_len += len;
7679 continue;
7680 }
7681
7682 /* Calculate single index or set outer boundaries */
7683 if (occurrence < 0) {
7684 i = occurrence + len + prev_len;
7685 last = i;
7686 } else if (occurrence > 0) {
7687 i = occurrence - 1 - prev_len;
7688 last = i;
7689 } else {
7690 i = 0;
7691 last = len - 1;
7692 }
7693
7694 prev_len += len; /* Count handled occurrences */
7695
7696 while (i <= last) {
7697 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7698
7699 filter = proto_construct_match_selected_string(finfo, edt);
7700 if (filter) {
7701 /* Only add the same expression once (especially for FT_PROTOCOL).
7702 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7703 */
7704 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7705 g_ptr_array_add(filter_array, filter);
7706 }
7707 }
7708 i++;
7709 }
7710
7711 if (occurrence == 0) {
7712 /* Fetch next hfinfo with same name (abbrev) */
7713 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7714 } else {
7715 hfinfo = NULL((void*)0);
7716 }
7717 }
7718 }
7719
7720 g_ptr_array_add(filter_array, NULL((void*)0));
7721
7722 /* XXX: Should this be || or && ? */
7723 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7724
7725 g_ptr_array_free(filter_array, true1);
7726
7727 return output;
7728}
7729
7730/* Set text of proto_item after having already been created. */
7731void
7732proto_item_set_text(proto_item *pi, const char *format, ...)
7733{
7734 field_info *fi = NULL((void*)0);
7735 va_list ap;
7736
7737 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7738
7739 fi = PITEM_FINFO(pi)((pi)->finfo);
7740 if (fi == NULL((void*)0))
7741 return;
7742
7743 if (fi->rep) {
7744 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7745 fi->rep = NULL((void*)0);
7746 }
7747
7748 va_start(ap, format)__builtin_va_start(ap, format);
7749 proto_tree_set_representation(pi, format, ap);
7750 va_end(ap)__builtin_va_end(ap);
7751}
7752
7753/* Append to text of proto_item after having already been created. */
7754void
7755proto_item_append_text(proto_item *pi, const char *format, ...)
7756{
7757 field_info *fi = NULL((void*)0);
7758 size_t curlen;
7759 char *str;
7760 va_list ap;
7761
7762 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7763
7764 fi = PITEM_FINFO(pi)((pi)->finfo);
7765 if (fi == NULL((void*)0)) {
7766 return;
7767 }
7768
7769 if (!proto_item_is_hidden(pi)) {
7770 /*
7771 * If we don't already have a representation,
7772 * generate the default representation.
7773 */
7774 if (fi->rep == NULL((void*)0)) {
7775 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;
;
7776 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7777 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7778 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7779 (strncmp(format, ": ", 2) == 0)) {
7780 fi->rep->value_pos += 2;
7781 }
7782 }
7783 if (fi->rep) {
7784 curlen = strlen(fi->rep->representation);
7785 /* curlen doesn't include the \0 byte.
7786 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7787 * the representation has already been truncated (of an up
7788 * to 4 byte UTF-8 character) or is just at the maximum length
7789 * unless we search for " [truncated]" (which may not be
7790 * at the start.)
7791 * It's safer to do nothing.
7792 */
7793 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7794 va_start(ap, format)__builtin_va_start(ap, format);
7795 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7796 va_end(ap)__builtin_va_end(ap);
7797 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"
, 7797, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7798 /* Keep fi->rep->value_pos */
7799 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, str, 0);
7800 if (curlen >= ITEM_LABEL_LENGTH240) {
7801 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7802 size_t name_pos = label_find_name_pos(fi->rep);
7803 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7804 }
7805 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7806 }
7807 }
7808 }
7809}
7810
7811/* Prepend to text of proto_item after having already been created. */
7812void
7813proto_item_prepend_text(proto_item *pi, const char *format, ...)
7814{
7815 field_info *fi = NULL((void*)0);
7816 size_t pos;
7817 char representation[ITEM_LABEL_LENGTH240];
7818 char *str;
7819 va_list ap;
7820
7821 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7822
7823 fi = PITEM_FINFO(pi)((pi)->finfo);
7824 if (fi == NULL((void*)0)) {
7825 return;
7826 }
7827
7828 if (!proto_item_is_hidden(pi)) {
7829 /*
7830 * If we don't already have a representation,
7831 * generate the default representation.
7832 */
7833 if (fi->rep == NULL((void*)0)) {
7834 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;
;
7835 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7836 } else
7837 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7838
7839 va_start(ap, format)__builtin_va_start(ap, format);
7840 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7841 va_end(ap)__builtin_va_end(ap);
7842 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"
, 7842, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7843 fi->rep->value_pos += strlen(str);
7844 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7845 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, representation, 0);
7846 /* XXX: As above, if the old representation is close to the label
7847 * length, it might already be marked as truncated. */
7848 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7849 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7850 size_t name_pos = label_find_name_pos(fi->rep);
7851 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7852 }
7853 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7854 }
7855}
7856
7857static void
7858finfo_set_len(field_info *fi, const int length)
7859{
7860 int length_remaining;
7861
7862 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", 7862,
"length >= 0", fi->hfinfo->abbrev))))
;
7863 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7864 if (length > length_remaining)
7865 fi->length = length_remaining;
7866 else
7867 fi->length = length;
7868
7869 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7870 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7871 fvalue_set_protocol_length(fi->value, fi->length);
7872 }
7873
7874 /*
7875 * You cannot just make the "len" field of a GByteArray
7876 * larger, if there's no data to back that length;
7877 * you can only make it smaller.
7878 */
7879 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7880 GBytes *bytes = fvalue_get_bytes(fi->value);
7881 size_t size;
7882 const void *data = g_bytes_get_data(bytes, &size);
7883 if ((size_t)fi->length <= size) {
7884 fvalue_set_bytes_data(fi->value, data, fi->length);
7885 }
7886 g_bytes_unref(bytes);
7887 }
7888}
7889
7890void
7891proto_item_set_len(proto_item *pi, const int length)
7892{
7893 field_info *fi;
7894
7895 if (pi == NULL((void*)0))
7896 return;
7897
7898 fi = PITEM_FINFO(pi)((pi)->finfo);
7899 if (fi == NULL((void*)0))
7900 return;
7901
7902 finfo_set_len(fi, length);
7903}
7904
7905/*
7906 * Sets the length of the item based on its start and on the specified
7907 * offset, which is the offset past the end of the item; as the start
7908 * in the item is relative to the beginning of the data source tvbuff,
7909 * we need to pass in a tvbuff - the end offset is relative to the beginning
7910 * of that tvbuff.
7911 */
7912void
7913proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7914{
7915 field_info *fi;
7916 int length;
7917
7918 if (pi == NULL((void*)0))
7919 return;
7920
7921 fi = PITEM_FINFO(pi)((pi)->finfo);
7922 if (fi == NULL((void*)0))
7923 return;
7924
7925 end += tvb_raw_offset(tvb);
7926 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7926, "end >= fi->start"
))))
;
7927 length = end - fi->start;
7928
7929 finfo_set_len(fi, length);
7930}
7931
7932int
7933proto_item_get_len(const proto_item *pi)
7934{
7935 field_info *fi;
7936
7937 if (!pi)
7938 return -1;
7939 fi = PITEM_FINFO(pi)((pi)->finfo);
7940 return fi ? fi->length : -1;
7941}
7942
7943void
7944proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
7945 if (!ti) {
7946 return;
7947 }
7948 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)
;
7949 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)
;
7950}
7951
7952char *
7953proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
7954{
7955 field_info *fi;
7956
7957 if (!pi)
7958 return wmem_strdup(scope, "");
7959 fi = PITEM_FINFO(pi)((pi)->finfo);
7960 if (!fi)
7961 return wmem_strdup(scope, "");
7962 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7962, "fi->hfinfo != ((void*)0)"
))))
;
7963 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
7964}
7965
7966proto_tree *
7967proto_tree_create_root(packet_info *pinfo)
7968{
7969 proto_node *pnode;
7970
7971 /* Initialize the proto_node */
7972 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
7973 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
7974 pnode->parent = NULL((void*)0);
7975 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
7976 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
7977
7978 /* Make sure we can access pinfo everywhere */
7979 pnode->tree_data->pinfo = pinfo;
7980
7981 /* Don't initialize the tree_data_t. Wait until we know we need it */
7982 pnode->tree_data->interesting_hfids = NULL((void*)0);
7983
7984 /* Set the default to false so it's easier to
7985 * find errors; if we expect to see the protocol tree
7986 * but for some reason the default 'visible' is not
7987 * changed, then we'll find out very quickly. */
7988 pnode->tree_data->visible = false0;
7989
7990 /* Make sure that we fake protocols (if possible) */
7991 pnode->tree_data->fake_protocols = true1;
7992
7993 /* Keep track of the number of children */
7994 pnode->tree_data->count = 0;
7995
7996 /* Initialize our loop checks */
7997 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
7998 pnode->tree_data->max_start = 0;
7999 pnode->tree_data->start_idle_count = 0;
8000
8001 return (proto_tree *)pnode;
8002}
8003
8004
8005/* "prime" a proto_tree with a single hfid that a dfilter
8006 * is interested in. */
8007void
8008proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8009{
8010 header_field_info *hfinfo;
8011
8012 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", 8012, __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", 8012, "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", 8012, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8013 /* this field is referenced by a filter so increase the refcount.
8014 also increase the refcount for the parent, i.e the protocol.
8015 Don't increase the refcount if we're already printing the
8016 type, as that is a superset of direct reference.
8017 */
8018 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8019 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8020 }
8021 /* only increase the refcount if there is a parent.
8022 if this is a protocol and not a field then parent will be -1
8023 and there is no parent to add any refcounting for.
8024 */
8025 if (hfinfo->parent != -1) {
8026 header_field_info *parent_hfinfo;
8027 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", 8027
, __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", 8027,
"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", 8027,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8028
8029 /* Mark parent as indirectly referenced unless it is already directly
8030 * referenced, i.e. the user has specified the parent in a filter.
8031 */
8032 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8033 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8034 }
8035}
8036
8037/* "prime" a proto_tree with a single hfid that a dfilter
8038 * is interested in. */
8039void
8040proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8041{
8042 header_field_info *hfinfo;
8043
8044 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", 8044, __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", 8044, "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", 8044, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8045 /* this field is referenced by an (output) filter so increase the refcount.
8046 also increase the refcount for the parent, i.e the protocol.
8047 */
8048 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8049 /* only increase the refcount if there is a parent.
8050 if this is a protocol and not a field then parent will be -1
8051 and there is no parent to add any refcounting for.
8052 */
8053 if (hfinfo->parent != -1) {
8054 header_field_info *parent_hfinfo;
8055 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", 8055
, __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", 8055,
"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", 8055,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8056
8057 /* Mark parent as indirectly referenced unless it is already directly
8058 * referenced, i.e. the user has specified the parent in a filter.
8059 */
8060 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8061 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8062 }
8063}
8064
8065proto_tree *
8066proto_item_add_subtree(proto_item *pi, const int idx) {
8067 field_info *fi;
8068
8069 if (!pi)
8070 return NULL((void*)0);
8071
8072 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", 8072, "idx >= 0 && idx < num_tree_types"
))))
;
8073
8074 fi = PITEM_FINFO(pi)((pi)->finfo);
8075 if (!fi)
8076 return (proto_tree *)pi;
8077
8078 fi->tree_type = idx;
8079
8080 return (proto_tree *)pi;
8081}
8082
8083proto_tree *
8084proto_item_get_subtree(proto_item *pi) {
8085 field_info *fi;
8086
8087 if (!pi)
8088 return NULL((void*)0);
8089 fi = PITEM_FINFO(pi)((pi)->finfo);
8090 if ( (fi) && (fi->tree_type == -1) )
8091 return NULL((void*)0);
8092 return (proto_tree *)pi;
8093}
8094
8095proto_item *
8096proto_item_get_parent(const proto_item *ti) {
8097 if (!ti)
8098 return NULL((void*)0);
8099 return ti->parent;
8100}
8101
8102proto_item *
8103proto_item_get_parent_nth(proto_item *ti, int gen) {
8104 if (!ti)
8105 return NULL((void*)0);
8106 while (gen--) {
8107 ti = ti->parent;
8108 if (!ti)
8109 return NULL((void*)0);
8110 }
8111 return ti;
8112}
8113
8114
8115proto_item *
8116proto_tree_get_parent(proto_tree *tree) {
8117 if (!tree)
8118 return NULL((void*)0);
8119 return (proto_item *)tree;
8120}
8121
8122proto_tree *
8123proto_tree_get_parent_tree(proto_tree *tree) {
8124 if (!tree)
8125 return NULL((void*)0);
8126
8127 /* we're the root tree, there's no parent
8128 return ourselves so the caller has at least a tree to attach to */
8129 if (!tree->parent)
8130 return tree;
8131
8132 return (proto_tree *)tree->parent;
8133}
8134
8135proto_tree *
8136proto_tree_get_root(proto_tree *tree) {
8137 if (!tree)
8138 return NULL((void*)0);
8139 while (tree->parent) {
8140 tree = tree->parent;
8141 }
8142 return tree;
8143}
8144
8145void
8146proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8147 proto_item *item_to_move)
8148{
8149 /* This function doesn't generate any values. It only reorganizes the prococol tree
8150 * so we can bail out immediately if it isn't visible. */
8151 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8152 return;
8153
8154 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", 8154, "item_to_move->parent == tree"
))))
;
8155 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", 8155, "fixed_item->parent == tree"
))))
;
8156
8157 /*** cut item_to_move out ***/
8158
8159 /* is item_to_move the first? */
8160 if (tree->first_child == item_to_move) {
8161 /* simply change first child to next */
8162 tree->first_child = item_to_move->next;
8163
8164 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", 8164, "tree->last_child != item_to_move"
))))
;
8165 } else {
8166 proto_item *curr_item;
8167 /* find previous and change it's next */
8168 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8169 if (curr_item->next == item_to_move) {
8170 break;
8171 }
8172 }
8173
8174 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8174, "curr_item"
))))
;
8175
8176 curr_item->next = item_to_move->next;
8177
8178 /* fix last_child if required */
8179 if (tree->last_child == item_to_move) {
8180 tree->last_child = curr_item;
8181 }
8182 }
8183
8184 /*** insert to_move after fixed ***/
8185 item_to_move->next = fixed_item->next;
8186 fixed_item->next = item_to_move;
8187 if (tree->last_child == fixed_item) {
8188 tree->last_child = item_to_move;
8189 }
8190}
8191
8192void
8193proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8194 const int length)
8195{
8196 field_info *fi;
8197
8198 if (tree == NULL((void*)0))
8199 return;
8200
8201 fi = PTREE_FINFO(tree)((tree)->finfo);
8202 if (fi == NULL((void*)0))
8203 return;
8204
8205 start += tvb_raw_offset(tvb);
8206 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8206, "start >= 0"
))))
;
8207 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8207, "length >= 0"
))))
;
8208
8209 fi->appendix_start = start;
8210 fi->appendix_length = length;
8211}
8212
8213static void
8214check_protocol_filter_name_or_fail(const char *filter_name)
8215{
8216 /* Require at least two characters. */
8217 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8218 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)
;
8219 }
8220
8221 if (proto_check_field_name(filter_name) != '\0') {
8222 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)
8223 " 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)
8224 " 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)
;
8225 }
8226
8227 /* Check that it doesn't match some very common numeric forms. */
8228 if (filter_name[0] == '0' &&
8229 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8230 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8231 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])
8232 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])
;
8233 }
8234
8235 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8236
8237 /* Check that it contains at least one letter. */
8238 bool_Bool have_letter = false0;
8239 for (const char *s = filter_name; *s != '\0'; s++) {
8240 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8241 have_letter = true1;
8242 break;
8243 }
8244 }
8245 if (!have_letter) {
8246 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)
8247 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8248 }
8249
8250 /* Check for reserved keywords. */
8251 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8252 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)
8253 " 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)
;
8254 }
8255}
8256
8257int
8258proto_register_protocol(const char *name, const char *short_name,
8259 const char *filter_name)
8260{
8261 protocol_t *protocol;
8262 header_field_info *hfinfo;
8263
8264 /*
8265 * Make sure there's not already a protocol with any of those
8266 * names. Crash if there is, as that's an error in the code
8267 * or an inappropriate plugin.
8268 * This situation has to be fixed to not register more than one
8269 * protocol with the same name.
8270 */
8271
8272 if (g_hash_table_lookup(proto_names, name)) {
8273 /* ws_error will terminate the program */
8274 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)
8275 " 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)
;
8276 }
8277
8278 if (g_hash_table_lookup(proto_short_names, short_name)) {
8279 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)
8280 " 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)
;
8281 }
8282
8283 check_protocol_filter_name_or_fail(filter_name);
8284
8285 if (g_hash_table_lookup(proto_filter_names, filter_name)) {
8286 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)
8287 " 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)
;
8288 }
8289
8290 /*
8291 * Add this protocol to the list of known protocols;
8292 * the list is sorted by protocol short name.
8293 */
8294 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8295 protocol->name = name;
8296 protocol->short_name = short_name;
8297 protocol->filter_name = filter_name;
8298 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8299 protocol->is_enabled = true1; /* protocol is enabled by default */
8300 protocol->enabled_by_default = true1; /* see previous comment */
8301 protocol->can_toggle = true1;
8302 protocol->parent_proto_id = -1;
8303 protocol->heur_list = NULL((void*)0);
8304
8305 /* List will be sorted later by name, when all protocols completed registering */
8306 protocols = g_list_prepend(protocols, protocol);
8307 g_hash_table_insert(proto_names, (void *)name, protocol);
8308 g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol);
8309 g_hash_table_insert(proto_short_names, (void *)short_name, protocol);
8310
8311 /* Here we allocate a new header_field_info struct */
8312 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8313 hfinfo->name = name;
8314 hfinfo->abbrev = filter_name;
8315 hfinfo->type = FT_PROTOCOL;
8316 hfinfo->display = BASE_NONE;
8317 hfinfo->strings = protocol;
8318 hfinfo->bitmask = 0;
8319 hfinfo->ref_type = HF_REF_TYPE_NONE;
8320 hfinfo->blurb = NULL((void*)0);
8321 hfinfo->parent = -1; /* This field differentiates protos and fields */
8322
8323 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8324 return protocol->proto_id;
8325}
8326
8327int
8328proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8329{
8330 protocol_t *protocol;
8331 header_field_info *hfinfo;
8332
8333 /*
8334 * Helper protocols don't need the strict rules as a "regular" protocol
8335 * Just register it in a list and make a hf_ field from it
8336 */
8337 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8338 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)
;
8339 }
8340
8341 if (parent_proto <= 0) {
8342 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)
8343 " 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)
;
8344 }
8345
8346 check_protocol_filter_name_or_fail(filter_name);
8347
8348 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8349 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8350 protocol->name = name;
8351 protocol->short_name = short_name;
8352 protocol->filter_name = filter_name;
8353 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8354
8355 /* Enabling and toggling is really determined by parent protocol,
8356 but provide default values here */
8357 protocol->is_enabled = true1;
8358 protocol->enabled_by_default = true1;
8359 protocol->can_toggle = true1;
8360
8361 protocol->parent_proto_id = parent_proto;
8362 protocol->heur_list = NULL((void*)0);
8363
8364 /* List will be sorted later by name, when all protocols completed registering */
8365 protocols = g_list_prepend(protocols, protocol);
8366
8367 /* Here we allocate a new header_field_info struct */
8368 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8369 hfinfo->name = name;
8370 hfinfo->abbrev = filter_name;
8371 hfinfo->type = field_type;
8372 hfinfo->display = BASE_NONE;
8373 if (field_type == FT_BYTES) {
8374 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8375 }
8376 hfinfo->strings = protocol;
8377 hfinfo->bitmask = 0;
8378 hfinfo->ref_type = HF_REF_TYPE_NONE;
8379 hfinfo->blurb = NULL((void*)0);
8380 hfinfo->parent = -1; /* This field differentiates protos and fields */
8381
8382 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8383 return protocol->proto_id;
8384}
8385
8386bool_Bool
8387proto_deregister_protocol(const char *short_name)
8388{
8389 protocol_t *protocol;
8390 header_field_info *hfinfo;
8391 int proto_id;
8392 unsigned i;
8393
8394 proto_id = proto_get_id_by_short_name(short_name);
8395 protocol = find_protocol_by_id(proto_id);
8396 if (protocol == NULL((void*)0))
8397 return false0;
8398
8399 g_hash_table_remove(proto_names, protocol->name);
8400 g_hash_table_remove(proto_short_names, (void *)short_name);
8401 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8402
8403 if (protocol->fields) {
8404 for (i = 0; i < protocol->fields->len; i++) {
8405 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8406 hfinfo_remove_from_gpa_name_map(hfinfo);
8407 expert_deregister_expertinfo(hfinfo->abbrev);
8408 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8409 }
8410 g_ptr_array_free(protocol->fields, true1);
8411 protocol->fields = NULL((void*)0);
8412 }
8413
8414 g_list_free(protocol->heur_list);
8415
8416 /* Remove this protocol from the list of known protocols */
8417 protocols = g_list_remove(protocols, protocol);
8418
8419 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8420 g_hash_table_steal(gpa_name_map, protocol->filter_name);
8421
8422 g_free(last_field_name);
8423 last_field_name = NULL((void*)0);
8424
8425 return true1;
8426}
8427
8428void
8429proto_register_alias(const int proto_id, const char *alias_name)
8430{
8431 protocol_t *protocol;
8432
8433 protocol = find_protocol_by_id(proto_id);
8434 if (alias_name && protocol) {
8435 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8436 }
8437}
8438
8439/*
8440 * Routines to use to iterate over the protocols.
8441 * The argument passed to the iterator routines is an opaque cookie to
8442 * their callers; it's the GList pointer for the current element in
8443 * the list.
8444 * The ID of the protocol is returned, or -1 if there is no protocol.
8445 */
8446int
8447proto_get_first_protocol(void **cookie)
8448{
8449 protocol_t *protocol;
8450
8451 if (protocols == NULL((void*)0))
8452 return -1;
8453 *cookie = protocols;
8454 protocol = (protocol_t *)protocols->data;
8455 return protocol->proto_id;
8456}
8457
8458int
8459proto_get_data_protocol(void *cookie)
8460{
8461 GList *list_item = (GList *)cookie;
8462
8463 protocol_t *protocol = (protocol_t *)list_item->data;
8464 return protocol->proto_id;
8465}
8466
8467int
8468proto_get_next_protocol(void **cookie)
8469{
8470 GList *list_item = (GList *)*cookie;
8471 protocol_t *protocol;
8472
8473 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8474 if (list_item == NULL((void*)0))
8475 return -1;
8476 *cookie = list_item;
8477 protocol = (protocol_t *)list_item->data;
8478 return protocol->proto_id;
8479}
8480
8481header_field_info *
8482proto_get_first_protocol_field(const int proto_id, void **cookie)
8483{
8484 protocol_t *protocol = find_protocol_by_id(proto_id);
8485
8486 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8487 return NULL((void*)0);
8488
8489 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8490 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8491}
8492
8493header_field_info *
8494proto_get_next_protocol_field(const int proto_id, void **cookie)
8495{
8496 protocol_t *protocol = find_protocol_by_id(proto_id);
8497 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8498
8499 i++;
8500
8501 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8502 return NULL((void*)0);
8503
8504 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8505 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8506}
8507
8508protocol_t *
8509find_protocol_by_id(const int proto_id)
8510{
8511 header_field_info *hfinfo;
8512
8513 if (proto_id <= 0)
8514 return NULL((void*)0);
8515
8516 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", 8516, __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", 8516,
"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", 8516, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8517 if (hfinfo->type != FT_PROTOCOL) {
8518 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", 8518, "hfinfo->display & 0x00004000"
))))
;
8519 }
8520 return (protocol_t *)hfinfo->strings;
8521}
8522
8523int
8524proto_get_id(const protocol_t *protocol)
8525{
8526 return protocol->proto_id;
8527}
8528
8529bool_Bool
8530proto_name_already_registered(const char *name)
8531{
8532 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8532, "name", "No name present"))))
;
8533
8534 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8535 return true1;
8536 return false0;
8537}
8538
8539int
8540proto_get_id_by_filter_name(const char *filter_name)
8541{
8542 const protocol_t *protocol = NULL((void*)0);
8543
8544 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", 8544,
"filter_name", "No filter name present"))))
;
8545
8546 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8547
8548 if (protocol == NULL((void*)0))
8549 return -1;
8550 return protocol->proto_id;
8551}
8552
8553int
8554proto_get_id_by_short_name(const char *short_name)
8555{
8556 const protocol_t *protocol = NULL((void*)0);
8557
8558 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", 8558,
"short_name", "No short name present"))))
;
8559
8560 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8561
8562 if (protocol == NULL((void*)0))
8563 return -1;
8564 return protocol->proto_id;
8565}
8566
8567const char *
8568proto_get_protocol_name(const int proto_id)
8569{
8570 protocol_t *protocol;
8571
8572 protocol = find_protocol_by_id(proto_id);
8573
8574 if (protocol == NULL((void*)0))
8575 return NULL((void*)0);
8576 return protocol->name;
8577}
8578
8579const char *
8580proto_get_protocol_short_name(const protocol_t *protocol)
8581{
8582 if (protocol == NULL((void*)0))
8583 return "(none)";
8584 return protocol->short_name;
8585}
8586
8587const char *
8588proto_get_protocol_long_name(const protocol_t *protocol)
8589{
8590 if (protocol == NULL((void*)0))
8591 return "(none)";
8592 return protocol->name;
8593}
8594
8595const char *
8596proto_get_protocol_filter_name(const int proto_id)
8597{
8598 protocol_t *protocol;
8599
8600 protocol = find_protocol_by_id(proto_id);
8601 if (protocol == NULL((void*)0))
8602 return "(none)";
8603 return protocol->filter_name;
8604}
8605
8606void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8607{
8608 heur_dtbl_entry_t* heuristic_dissector;
8609
8610 if (protocol == NULL((void*)0))
8611 return;
8612
8613 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8614 if (heuristic_dissector != NULL((void*)0))
8615 {
8616 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8617 }
8618}
8619
8620void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8621{
8622 if (protocol == NULL((void*)0))
8623 return;
8624
8625 g_list_foreach(protocol->heur_list, func, user_data);
8626}
8627
8628void
8629proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8630 bool_Bool *is_tcp, bool_Bool *is_udp,
8631 bool_Bool *is_sctp, bool_Bool *is_tls,
8632 bool_Bool *is_rtp,
8633 bool_Bool *is_lte_rlc)
8634{
8635 wmem_list_frame_t *protos = wmem_list_head(layers);
8636 int proto_id;
8637 const char *proto_name;
8638
8639 /* Walk the list of a available protocols in the packet and
8640 attempt to find "major" ones. */
8641 /* It might make more sense to assemble and return a bitfield. */
8642 while (protos != NULL((void*)0))
8643 {
8644 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8645 proto_name = proto_get_protocol_filter_name(proto_id);
8646
8647 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8648 (!strcmp(proto_name, "ipv6")))) {
8649 *is_ip = true1;
8650 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8651 *is_tcp = true1;
8652 } else if (is_udp && !strcmp(proto_name, "udp")) {
8653 *is_udp = true1;
8654 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8655 *is_sctp = true1;
8656 } else if (is_tls && !strcmp(proto_name, "tls")) {
8657 *is_tls = true1;
8658 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8659 *is_rtp = true1;
8660 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8661 *is_lte_rlc = true1;
8662 }
8663
8664 protos = wmem_list_frame_next(protos);
8665 }
8666}
8667
8668bool_Bool
8669proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8670{
8671 wmem_list_frame_t *protos = wmem_list_head(layers);
8672 int proto_id;
8673 const char *name;
8674
8675 /* Walk the list of a available protocols in the packet and
8676 attempt to find the specified protocol. */
8677 while (protos != NULL((void*)0))
8678 {
8679 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8680 name = proto_get_protocol_filter_name(proto_id);
8681
8682 if (!strcmp(name, proto_name))
8683 {
8684 return true1;
8685 }
8686
8687 protos = wmem_list_frame_next(protos);
8688 }
8689
8690 return false0;
8691}
8692
8693char *
8694proto_list_layers(const packet_info *pinfo)
8695{
8696 wmem_strbuf_t *buf;
8697 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8698
8699 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8700
8701 /* Walk the list of layers in the packet and
8702 return a string of all entries. */
8703 while (layers != NULL((void*)0))
8704 {
8705 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8706
8707 layers = wmem_list_frame_next(layers);
8708 if (layers != NULL((void*)0)) {
8709 wmem_strbuf_append_c(buf, ':');
8710 }
8711 }
8712
8713 return wmem_strbuf_finalize(buf);
8714}
8715
8716uint8_t
8717proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8718{
8719 int *proto_layer_num_ptr;
8720
8721 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8722 if (proto_layer_num_ptr == NULL((void*)0)) {
8723 return 0;
8724 }
8725
8726 return (uint8_t)*proto_layer_num_ptr;
8727}
8728
8729bool_Bool
8730proto_is_pino(const protocol_t *protocol)
8731{
8732 return (protocol->parent_proto_id != -1);
8733}
8734
8735bool_Bool
8736// NOLINTNEXTLINE(misc-no-recursion)
8737proto_is_protocol_enabled(const protocol_t *protocol)
8738{
8739 if (protocol == NULL((void*)0))
8740 return false0;
8741
8742 //parent protocol determines enable/disable for helper dissectors
8743 if (proto_is_pino(protocol))
8744 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8745
8746 return protocol->is_enabled;
8747}
8748
8749bool_Bool
8750// NOLINTNEXTLINE(misc-no-recursion)
8751proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8752{
8753 //parent protocol determines enable/disable for helper dissectors
8754 if (proto_is_pino(protocol))
8755 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8756
8757 return protocol->enabled_by_default;
8758}
8759
8760bool_Bool
8761// NOLINTNEXTLINE(misc-no-recursion)
8762proto_can_toggle_protocol(const int proto_id)
8763{
8764 protocol_t *protocol;
8765
8766 protocol = find_protocol_by_id(proto_id);
8767 //parent protocol determines toggling for helper dissectors
8768 if (proto_is_pino(protocol))
8769 return proto_can_toggle_protocol(protocol->parent_proto_id);
8770
8771 return protocol->can_toggle;
8772}
8773
8774void
8775proto_disable_by_default(const int proto_id)
8776{
8777 protocol_t *protocol;
8778
8779 protocol = find_protocol_by_id(proto_id);
8780 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8780, "protocol->can_toggle"
))))
;
8781 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", 8781, "proto_is_pino(protocol) == 0"
))))
;
8782 protocol->is_enabled = false0;
8783 protocol->enabled_by_default = false0;
8784}
8785
8786void
8787proto_set_decoding(const int proto_id, const bool_Bool enabled)
8788{
8789 protocol_t *protocol;
8790
8791 protocol = find_protocol_by_id(proto_id);
8792 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8792, "protocol->can_toggle"
))))
;
8793 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", 8793, "proto_is_pino(protocol) == 0"
))))
;
8794 protocol->is_enabled = enabled;
8795}
8796
8797void
8798proto_disable_all(void)
8799{
8800 /* This doesn't explicitly disable heuristic protocols,
8801 * but the heuristic doesn't get called if the parent
8802 * protocol isn't enabled.
8803 */
8804 protocol_t *protocol;
8805 GList *list_item = protocols;
8806
8807 if (protocols == NULL((void*)0))
8808 return;
8809
8810 while (list_item) {
8811 protocol = (protocol_t *)list_item->data;
8812 if (protocol->can_toggle) {
8813 protocol->is_enabled = false0;
8814 }
8815 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8816 }
8817}
8818
8819static void
8820heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8821{
8822 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8823
8824 heur->enabled = heur->enabled_by_default;
8825}
8826
8827void
8828proto_reenable_all(void)
8829{
8830 protocol_t *protocol;
8831 GList *list_item = protocols;
8832
8833 if (protocols == NULL((void*)0))
8834 return;
8835
8836 while (list_item) {
8837 protocol = (protocol_t *)list_item->data;
8838 if (protocol->can_toggle)
8839 protocol->is_enabled = protocol->enabled_by_default;
8840 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8841 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8842 }
8843}
8844
8845void
8846proto_set_cant_toggle(const int proto_id)
8847{
8848 protocol_t *protocol;
8849
8850 protocol = find_protocol_by_id(proto_id);
8851 protocol->can_toggle = false0;
8852}
8853
8854static int
8855proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8856{
8857 if (proto != NULL((void*)0)) {
8858 g_ptr_array_add(proto->fields, hfi);
8859 }
8860
8861 return proto_register_field_init(hfi, parent);
8862}
8863
8864/* for use with static arrays only, since we don't allocate our own copies
8865of the header_field_info struct contained within the hf_register_info struct */
8866void
8867proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8868{
8869 hf_register_info *ptr = hf;
8870 protocol_t *proto;
8871 int i;
8872
8873 proto = find_protocol_by_id(parent);
8874
8875 if (proto->fields == NULL((void*)0)) {
8876 proto->fields = g_ptr_array_sized_new(num_records);
8877 }
8878
8879 for (i = 0; i < num_records; i++, ptr++) {
8880 /*
8881 * Make sure we haven't registered this yet.
8882 * Most fields have variables associated with them
8883 * that are initialized to -1; some have array elements,
8884 * or possibly uninitialized variables, so we also allow
8885 * 0 (which is unlikely to be the field ID we get back
8886 * from "proto_register_field_init()").
8887 */
8888 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8889 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8890 "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)
8891 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8892 return;
8893 }
8894
8895 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8896 }
8897}
8898
8899/* deregister already registered fields */
8900void
8901proto_deregister_field (const int parent, int hf_id)
8902{
8903 header_field_info *hfi;
8904 protocol_t *proto;
8905 unsigned i;
8906
8907 g_free(last_field_name);
8908 last_field_name = NULL((void*)0);
8909
8910 if (hf_id == -1 || hf_id == 0)
8911 return;
8912
8913 proto = find_protocol_by_id (parent);
8914 if (!proto || proto->fields == NULL((void*)0)) {
8915 return;
8916 }
8917
8918 for (i = 0; i < proto->fields->len; i++) {
8919 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8920 if (hfi->id == hf_id) {
8921 /* Found the hf_id in this protocol */
8922 g_hash_table_steal(gpa_name_map, hfi->abbrev);
8923 g_ptr_array_remove_index_fast(proto->fields, i);
8924 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8925 return;
8926 }
8927 }
8928}
8929
8930/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
8931void
8932proto_deregister_all_fields_with_prefix(const int parent, const gchar *prefix)
8933{
8934 header_field_info *hfinfo;
8935 protocol_t *proto;
8936
8937 g_free(last_field_name);
8938 last_field_name = NULL((void*)0);
8939
8940 proto = find_protocol_by_id(parent);
8941 if (proto && proto->fields && proto->fields->len > 0) {
8942 guint i = proto->fields->len;
8943 do {
8944 i--;
8945
8946 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8947 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) )
) {
8948 hfinfo_remove_from_gpa_name_map(hfinfo);
8949 expert_deregister_expertinfo(hfinfo->abbrev);
8950 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8951 g_ptr_array_remove_index_fast(proto->fields, i);
8952 }
8953 } while (i > 0);
8954 }
8955}
8956
8957void
8958proto_add_deregistered_data (void *data)
8959{
8960 g_ptr_array_add(deregistered_data, data);
8961}
8962
8963void
8964proto_add_deregistered_slice (size_t block_size, void *mem_block)
8965{
8966 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
)))
;
8967
8968 slice_data->block_size = block_size;
8969 slice_data->mem_block = mem_block;
8970
8971 g_ptr_array_add(deregistered_slice, slice_data);
8972}
8973
8974void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
8975{
8976 if (field_strings == NULL((void*)0)) {
8977 return;
8978 }
8979
8980 switch (field_type) {
8981 case FT_FRAMENUM:
8982 /* This is just an integer represented as a pointer */
8983 break;
8984 case FT_PROTOCOL: {
8985 protocol_t *protocol = (protocol_t *)field_strings;
8986 g_free((char *)protocol->short_name);
8987 break;
8988 }
8989 case FT_BOOLEAN: {
8990 true_false_string *tf = (true_false_string *)field_strings;
8991 g_free((char *)tf->true_string);
8992 g_free((char *)tf->false_string);
8993 break;
8994 }
8995 case FT_UINT40:
8996 case FT_INT40:
8997 case FT_UINT48:
8998 case FT_INT48:
8999 case FT_UINT56:
9000 case FT_INT56:
9001 case FT_UINT64:
9002 case FT_INT64: {
9003 if (field_display & BASE_UNIT_STRING0x00001000) {
9004 unit_name_string *unit = (unit_name_string *)field_strings;
9005 g_free((char *)unit->singular);
9006 g_free((char *)unit->plural);
9007 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9008 range_string *rs = (range_string *)field_strings;
9009 while (rs->strptr) {
9010 g_free((char *)rs->strptr);
9011 rs++;
9012 }
9013 } else if (field_display & BASE_EXT_STRING0x00000200) {
9014 val64_string_ext *vse = (val64_string_ext *)field_strings;
9015 val64_string *vs = (val64_string *)vse->_vs_p;
9016 while (vs->strptr) {
9017 g_free((char *)vs->strptr);
9018 vs++;
9019 }
9020 val64_string_ext_free(vse);
9021 field_strings = NULL((void*)0);
9022 } else if (field_display == BASE_CUSTOM) {
9023 /* this will be a pointer to a function, don't free that */
9024 field_strings = NULL((void*)0);
9025 } else {
9026 val64_string *vs64 = (val64_string *)field_strings;
9027 while (vs64->strptr) {
9028 g_free((char *)vs64->strptr);
9029 vs64++;
9030 }
9031 }
9032 break;
9033 }
9034 case FT_CHAR:
9035 case FT_UINT8:
9036 case FT_INT8:
9037 case FT_UINT16:
9038 case FT_INT16:
9039 case FT_UINT24:
9040 case FT_INT24:
9041 case FT_UINT32:
9042 case FT_INT32:
9043 case FT_FLOAT:
9044 case FT_DOUBLE: {
9045 if (field_display & BASE_UNIT_STRING0x00001000) {
9046 unit_name_string *unit = (unit_name_string *)field_strings;
9047 g_free((char *)unit->singular);
9048 g_free((char *)unit->plural);
9049 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9050 range_string *rs = (range_string *)field_strings;
9051 while (rs->strptr) {
9052 g_free((char *)rs->strptr);
9053 rs++;
9054 }
9055 } else if (field_display & BASE_EXT_STRING0x00000200) {
9056 value_string_ext *vse = (value_string_ext *)field_strings;
9057 value_string *vs = (value_string *)vse->_vs_p;
9058 while (vs->strptr) {
9059 g_free((char *)vs->strptr);
9060 vs++;
9061 }
9062 value_string_ext_free(vse);
9063 field_strings = NULL((void*)0);
9064 } else if (field_display == BASE_CUSTOM) {
9065 /* this will be a pointer to a function, don't free that */
9066 field_strings = NULL((void*)0);
9067 } else {
9068 value_string *vs = (value_string *)field_strings;
9069 while (vs->strptr) {
9070 g_free((char *)vs->strptr);
9071 vs++;
9072 }
9073 }
9074 break;
9075 default:
9076 break;
9077 }
9078 }
9079
9080 if (field_type != FT_FRAMENUM) {
9081 g_free((void *)field_strings);
9082 }
9083}
9084
9085static void
9086free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9087{
9088 header_field_info *hfi = (header_field_info *) data;
9089 int hf_id = hfi->id;
9090
9091 g_free((char *)hfi->name);
9092 g_free((char *)hfi->abbrev);
9093 g_free((char *)hfi->blurb);
9094
9095 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9096
9097 if (hfi->parent == -1)
9098 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)
;
9099
9100 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9101}
9102
9103static void
9104free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9105{
9106 g_free (data);
9107}
9108
9109static void
9110free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9111{
9112 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9113
9114 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9115 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)
;
9116}
9117
9118/* free deregistered fields and data */
9119void
9120proto_free_deregistered_fields (void)
9121{
9122 expert_free_deregistered_expertinfos();
9123
9124 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9125 g_ptr_array_free(deregistered_fields, true1);
9126 deregistered_fields = g_ptr_array_new();
9127
9128 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9129 g_ptr_array_free(deregistered_data, true1);
9130 deregistered_data = g_ptr_array_new();
9131
9132 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9133 g_ptr_array_free(deregistered_slice, true1);
9134 deregistered_slice = g_ptr_array_new();
9135}
9136
9137static const value_string hf_display[] = {
9138 { BASE_NONE, "BASE_NONE" },
9139 { BASE_DEC, "BASE_DEC" },
9140 { BASE_HEX, "BASE_HEX" },
9141 { BASE_OCT, "BASE_OCT" },
9142 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9143 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9144 { BASE_CUSTOM, "BASE_CUSTOM" },
9145 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9146 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9147 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9148 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9149 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9150 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9151 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9152 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9153 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9154 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9155 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9156 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9157 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9158 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9159 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9160 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9161 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9162 { BASE_PT_UDP, "BASE_PT_UDP" },
9163 { BASE_PT_TCP, "BASE_PT_TCP" },
9164 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9165 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9166 { BASE_OUI, "BASE_OUI" },
9167 { 0, NULL((void*)0) } };
9168
9169const char* proto_field_display_to_string(int field_display)
9170{
9171 return val_to_str_const(field_display, hf_display, "Unknown");
9172}
9173
9174static inline port_type
9175display_to_port_type(field_display_e e)
9176{
9177 switch (e) {
9178 case BASE_PT_UDP:
9179 return PT_UDP;
9180 case BASE_PT_TCP:
9181 return PT_TCP;
9182 case BASE_PT_DCCP:
9183 return PT_DCCP;
9184 case BASE_PT_SCTP:
9185 return PT_SCTP;
9186 default:
9187 break;
9188 }
9189 return PT_NONE;
9190}
9191
9192/* temporary function containing assert part for easier profiling */
9193static void
9194tmp_fld_check_assert(header_field_info *hfinfo)
9195{
9196 char* tmp_str;
9197
9198 /* The field must have a name (with length > 0) */
9199 if (!hfinfo->name || !hfinfo->name[0]) {
9200 if (hfinfo->abbrev)
9201 /* Try to identify the field */
9202 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)
9203 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9204 else
9205 /* Hum, no luck */
9206 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)"
)
;
9207 }
9208
9209 /* fields with an empty string for an abbreviation aren't filterable */
9210 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9211 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)
;
9212
9213 /* These types of fields are allowed to have value_strings,
9214 * true_false_strings or a protocol_t struct
9215 */
9216 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9217 switch (hfinfo->type) {
9218
9219 /*
9220 * These types are allowed to support display value_strings,
9221 * value64_strings, the extended versions of the previous
9222 * two, range strings, or unit strings.
9223 */
9224 case FT_CHAR:
9225 case FT_UINT8:
9226 case FT_UINT16:
9227 case FT_UINT24:
9228 case FT_UINT32:
9229 case FT_UINT40:
9230 case FT_UINT48:
9231 case FT_UINT56:
9232 case FT_UINT64:
9233 case FT_INT8:
9234 case FT_INT16:
9235 case FT_INT24:
9236 case FT_INT32:
9237 case FT_INT40:
9238 case FT_INT48:
9239 case FT_INT56:
9240 case FT_INT64:
9241 case FT_BOOLEAN:
9242 case FT_PROTOCOL:
9243 break;
9244
9245 /*
9246 * This is allowed to have a value of type
9247 * enum ft_framenum_type to indicate what relationship
9248 * the frame in question has to the frame in which
9249 * the field is put.
9250 */
9251 case FT_FRAMENUM:
9252 break;
9253
9254 /*
9255 * These types are allowed to support only unit strings.
9256 */
9257 case FT_FLOAT:
9258 case FT_DOUBLE:
9259 case FT_IEEE_11073_SFLOAT:
9260 case FT_IEEE_11073_FLOAT:
9261 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9262 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))
9263 " (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))
9264 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))
;
9265 }
9266 break;
9267
9268 /*
9269 * These types are allowed to support display
9270 * time_value_strings.
9271 */
9272 case FT_ABSOLUTE_TIME:
9273 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9274 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9275 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9276 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9277 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))
9278 " (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))
9279 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))
;
9280 }
9281 break;
9282
9283 /*
9284 * This type is only allowed to support a string if it's
9285 * a protocol (for pinos).
9286 */
9287 case FT_BYTES:
9288 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9289 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))
9290 " (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))
9291 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))
;
9292 }
9293 break;
9294
9295 default:
9296 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))
9297 " (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))
9298 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))
;
9299 }
9300 }
9301
9302 /* TODO: This check may slow down startup, and output quite a few warnings.
9303 It would be good to be able to enable this (and possibly other checks?)
9304 in non-release builds. */
9305#ifdef ENABLE_CHECK_FILTER
9306 /* Check for duplicate value_string values.
9307 There are lots that have the same value *and* string, so for now only
9308 report those that have same value but different string. */
9309 if ((hfinfo->strings != NULL((void*)0)) &&
9310 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9311 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9312 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9313 (
9314 (hfinfo->type == FT_CHAR) ||
9315 (hfinfo->type == FT_UINT8) ||
9316 (hfinfo->type == FT_UINT16) ||
9317 (hfinfo->type == FT_UINT24) ||
9318 (hfinfo->type == FT_UINT32) ||
9319 (hfinfo->type == FT_INT8) ||
9320 (hfinfo->type == FT_INT16) ||
9321 (hfinfo->type == FT_INT24) ||
9322 (hfinfo->type == FT_INT32) )) {
9323
9324 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9325 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9326 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9327 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9328 } else {
9329 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9330 CHECK_HF_VALUE(value_string, "u", start_values);
9331 }
9332 } else {
9333 const value_string *start_values = (const value_string*)hfinfo->strings;
9334 CHECK_HF_VALUE(value_string, "u", start_values);
9335 }
9336 }
9337
9338 if (hfinfo->type == FT_BOOLEAN) {
9339 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9340 if (tfs) {
9341 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9342 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"
, 9344, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9343 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9344, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9344 tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9344, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
;
9345 }
9346 }
9347 }
9348
9349 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9350 const range_string *rs = (const range_string*)(hfinfo->strings);
9351 if (rs) {
9352 const range_string *this_it = rs;
9353
9354 do {
9355 if (this_it->value_max < this_it->value_min) {
9356 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"
, 9360, __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)
9357 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9360, __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)
9358 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9360, __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)
9359 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9360, __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)
9360 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9360, __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)
;
9361 ++this_it;
9362 continue;
9363 }
9364
9365 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9366 /* Not OK if this one is completely hidden by an earlier one! */
9367 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9368 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"
, 9374, __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 "(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"
, 9374, __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 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9374, __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)
9371 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9374, __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)
9372 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9374, __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)
9373 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9374, __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)
9374 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9374, __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)
;
9375 }
9376 }
9377 ++this_it;
9378 } while (this_it->strptr);
9379 }
9380 }
9381#endif
9382
9383 switch (hfinfo->type) {
9384
9385 case FT_CHAR:
9386 /* Require the char type to have BASE_HEX, BASE_OCT,
9387 * BASE_CUSTOM, or BASE_NONE as its base.
9388 *
9389 * If the display value is BASE_NONE and there is a
9390 * strings conversion then the dissector writer is
9391 * telling us that the field's numerical value is
9392 * meaningless; we'll avoid showing the value to the
9393 * user.
9394 */
9395 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9396 case BASE_HEX:
9397 case BASE_OCT:
9398 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9399 break;
9400 case BASE_NONE:
9401 if (hfinfo->strings == NULL((void*)0))
9402 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
))
9403 " 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
))
9404 " 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
))
9405 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
))
9406 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
))
;
9407 break;
9408 default:
9409 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9410 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)
9411 " 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)
9412 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)
9413 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)
;
9414 //wmem_free(NULL, tmp_str);
9415 }
9416 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9417 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
))
9418 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
))
9419 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
))
;
9420 }
9421 break;
9422 case FT_INT8:
9423 case FT_INT16:
9424 case FT_INT24:
9425 case FT_INT32:
9426 case FT_INT40:
9427 case FT_INT48:
9428 case FT_INT56:
9429 case FT_INT64:
9430 /* Hexadecimal and octal are, in printf() and everywhere
9431 * else, unsigned so don't allow dissectors to register a
9432 * signed field to be displayed unsigned. (Else how would
9433 * we display negative values?)
9434 */
9435 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9436 case BASE_HEX:
9437 case BASE_OCT:
9438 case BASE_DEC_HEX:
9439 case BASE_HEX_DEC:
9440 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9441 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)
9442 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)
9443 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)
;
9444 //wmem_free(NULL, tmp_str);
9445 }
9446 /* FALL THROUGH */
9447 case FT_UINT8:
9448 case FT_UINT16:
9449 case FT_UINT24:
9450 case FT_UINT32:
9451 case FT_UINT40:
9452 case FT_UINT48:
9453 case FT_UINT56:
9454 case FT_UINT64:
9455 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
))
) {
9456 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9457 if (hfinfo->type != FT_UINT16) {
9458 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))
9459 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))
9460 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))
;
9461 }
9462 if (hfinfo->strings != NULL((void*)0)) {
9463 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)
9464 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)
9465 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)
;
9466 }
9467 if (hfinfo->bitmask != 0) {
9468 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)
9469 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)
9470 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)
;
9471 }
9472 wmem_free(NULL((void*)0), tmp_str);
9473 break;
9474 }
9475
9476 if (hfinfo->display == BASE_OUI) {
9477 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9478 if (hfinfo->type != FT_UINT24) {
9479 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))
9480 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))
9481 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))
;
9482 }
9483 if (hfinfo->strings != NULL((void*)0)) {
9484 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)
9485 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)
9486 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)
;
9487 }
9488 if (hfinfo->bitmask != 0) {
9489 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)
9490 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)
9491 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)
;
9492 }
9493 wmem_free(NULL((void*)0), tmp_str);
9494 break;
9495 }
9496
9497 /* Require integral types (other than frame number,
9498 * which is always displayed in decimal) to have a
9499 * number base.
9500 *
9501 * If the display value is BASE_NONE and there is a
9502 * strings conversion then the dissector writer is
9503 * telling us that the field's numerical value is
9504 * meaningless; we'll avoid showing the value to the
9505 * user.
9506 */
9507 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9508 case BASE_DEC:
9509 case BASE_HEX:
9510 case BASE_OCT:
9511 case BASE_DEC_HEX:
9512 case BASE_HEX_DEC:
9513 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9514 break;
9515 case BASE_NONE:
9516 if (hfinfo->strings == NULL((void*)0)) {
9517 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
))
9518 " 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
))
9519 " 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
))
9520 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
))
9521 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
))
;
9522 }
9523 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9524 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
))
9525 " 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
))
9526 " 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
))
9527 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
))
9528 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
))
;
9529 }
9530 break;
9531
9532 default:
9533 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9534 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)
9535 " 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)
9536 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)
9537 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)
;
9538 //wmem_free(NULL, tmp_str);
9539 }
9540 break;
9541 case FT_BYTES:
9542 case FT_UINT_BYTES:
9543 /* Require bytes to have a "display type" that could
9544 * add a character between displayed bytes.
9545 */
9546 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9547 case BASE_NONE:
9548 case SEP_DOT:
9549 case SEP_DASH:
9550 case SEP_COLON:
9551 case SEP_SPACE:
9552 break;
9553 default:
9554 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9555 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)
9556 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)
;
9557 //wmem_free(NULL, tmp_str);
9558 }
9559 if (hfinfo->bitmask != 0)
9560 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
))
9561 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
))
9562 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
))
;
9563 //allowed to support string if its a protocol (for pinos)
9564 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9565 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
))
9566 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
))
9567 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
))
;
9568 break;
9569
9570 case FT_PROTOCOL:
9571 case FT_FRAMENUM:
9572 if (hfinfo->display != BASE_NONE) {
9573 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9574 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)
9575 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)
9576 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)
;
9577 //wmem_free(NULL, tmp_str);
9578 }
9579 if (hfinfo->bitmask != 0)
9580 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
))
9581 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
))
9582 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
))
;
9583 break;
9584
9585 case FT_BOOLEAN:
9586 break;
9587
9588 case FT_ABSOLUTE_TIME:
9589 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9590 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9591 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)
9592 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)
;
9593 //wmem_free(NULL, tmp_str);
9594 }
9595 if (hfinfo->bitmask != 0)
9596 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
))
9597 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
))
9598 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
))
;
9599 break;
9600
9601 case FT_STRING:
9602 case FT_STRINGZ:
9603 case FT_UINT_STRING:
9604 case FT_STRINGZPAD:
9605 case FT_STRINGZTRUNC:
9606 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9607 case BASE_NONE:
9608 case BASE_STR_WSP:
9609 break;
9610
9611 default:
9612 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9613 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)
9614 " 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)
9615 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)
9616 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)
;
9617 //wmem_free(NULL, tmp_str);
9618 }
9619
9620 if (hfinfo->bitmask != 0)
9621 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
))
9622 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
))
9623 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
))
;
9624 if (hfinfo->strings != NULL((void*)0))
9625 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
))
9626 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
))
9627 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
))
;
9628 break;
9629
9630 case FT_IPv4:
9631 switch (hfinfo->display) {
9632 case BASE_NONE:
9633 case BASE_NETMASK:
9634 break;
9635
9636 default:
9637 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9638 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)
9639 " 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)
9640 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)
9641 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)
;
9642 //wmem_free(NULL, tmp_str);
9643 break;
9644 }
9645 break;
9646 case FT_FLOAT:
9647 case FT_DOUBLE:
9648 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9649 case BASE_NONE:
9650 case BASE_DEC:
9651 case BASE_HEX:
9652 case BASE_EXP:
9653 case BASE_CUSTOM:
9654 break;
9655 default:
9656 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9657 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)
9658 " 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)
9659 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)
9660 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)
;
9661 //wmem_free(NULL, tmp_str);
9662 }
9663 if (hfinfo->bitmask != 0)
9664 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
))
9665 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
))
9666 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
))
;
9667 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9668 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
))
9669 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
))
9670 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
))
;
9671 break;
9672 case FT_IEEE_11073_SFLOAT:
9673 case FT_IEEE_11073_FLOAT:
9674 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9675 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9676 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)
9677 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)
9678 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)
9679 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)
;
9680 //wmem_free(NULL, tmp_str);
9681 }
9682 if (hfinfo->bitmask != 0)
9683 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
))
9684 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
))
9685 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
))
;
9686 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9687 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
))
9688 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
))
9689 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
))
;
9690 break;
9691 default:
9692 if (hfinfo->display != BASE_NONE) {
9693 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9694 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)
9695 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)
9696 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)
9697 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)
;
9698 //wmem_free(NULL, tmp_str);
9699 }
9700 if (hfinfo->bitmask != 0)
9701 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
))
9702 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
))
9703 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
))
;
9704 if (hfinfo->strings != NULL((void*)0))
9705 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
))
9706 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
))
9707 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
))
;
9708 break;
9709 }
9710}
9711
9712static void
9713register_type_length_mismatch(void)
9714{
9715 static ei_register_info ei[] = {
9716 { &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)}}
}},
9717 { &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)}}
}},
9718 };
9719
9720 expert_module_t* expert_type_length_mismatch;
9721
9722 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9723
9724 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9725 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9726
9727 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9728 disabling them makes no sense. */
9729 proto_set_cant_toggle(proto_type_length_mismatch);
9730}
9731
9732static void
9733register_byte_array_string_decodinws_error(void)
9734{
9735 static ei_register_info ei[] = {
9736 { &ei_byte_array_string_decoding_failed_error,
9737 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9738 "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)}}
9739 }
9740 },
9741 };
9742
9743 expert_module_t* expert_byte_array_string_decoding_error;
9744
9745 proto_byte_array_string_decoding_error =
9746 proto_register_protocol("Byte Array-String Decoding Error",
9747 "Byte Array-string decoding error",
9748 "_ws.byte_array_string.decoding_error");
9749
9750 expert_byte_array_string_decoding_error =
9751 expert_register_protocol(proto_byte_array_string_decoding_error);
9752 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9753
9754 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9755 disabling them makes no sense. */
9756 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9757}
9758
9759static void
9760register_date_time_string_decodinws_error(void)
9761{
9762 static ei_register_info ei[] = {
9763 { &ei_date_time_string_decoding_failed_error,
9764 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9765 "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)}}
9766 }
9767 },
9768 };
9769
9770 expert_module_t* expert_date_time_string_decoding_error;
9771
9772 proto_date_time_string_decoding_error =
9773 proto_register_protocol("Date and Time-String Decoding Error",
9774 "Date and Time-string decoding error",
9775 "_ws.date_time_string.decoding_error");
9776
9777 expert_date_time_string_decoding_error =
9778 expert_register_protocol(proto_date_time_string_decoding_error);
9779 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9780
9781 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9782 disabling them makes no sense. */
9783 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9784}
9785
9786static void
9787register_string_errors(void)
9788{
9789 static ei_register_info ei[] = {
9790 { &ei_string_trailing_characters,
9791 { "_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)}}
}
9792 },
9793 };
9794
9795 expert_module_t* expert_string_errors;
9796
9797 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9798
9799 expert_string_errors = expert_register_protocol(proto_string_errors);
9800 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9801
9802 /* "String Errors" isn't really a protocol, it's an error indication;
9803 disabling them makes no sense. */
9804 proto_set_cant_toggle(proto_string_errors);
9805}
9806
9807#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
9808static int
9809proto_register_field_init(header_field_info *hfinfo, const int parent)
9810{
9811
9812 tmp_fld_check_assert(hfinfo);
9813
9814 hfinfo->parent = parent;
9815 hfinfo->same_name_next = NULL((void*)0);
9816 hfinfo->same_name_prev_id = -1;
9817
9818 /* if we always add and never delete, then id == len - 1 is correct */
9819 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9820 if (!gpa_hfinfo.hfi) {
9821 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9822 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9823 /* The entry with index 0 is not used. */
9824 gpa_hfinfo.hfi[0] = NULL((void*)0);
9825 gpa_hfinfo.len = 1;
9826 } else {
9827 gpa_hfinfo.allocated_len += 1000;
9828 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9829 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9830 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9831 }
9832 }
9833 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9834 gpa_hfinfo.len++;
9835 hfinfo->id = gpa_hfinfo.len - 1;
9836
9837 /* if we have real names, enter this field in the name tree */
9838 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
9839
9840 header_field_info *same_name_next_hfinfo;
9841 unsigned char c;
9842
9843 /* Check that the filter name (abbreviation) is legal;
9844 * it must contain only alphanumerics, '-', "_", and ".". */
9845 c = proto_check_field_name(hfinfo->abbrev);
9846 if (c) {
9847 if (c == '.') {
9848 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)
;
9849 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9850 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)
;
9851 } else {
9852 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)
;
9853 }
9854 }
9855
9856 /* We allow multiple hfinfo's to be registered under the same
9857 * abbreviation. This was done for X.25, as, depending
9858 * on whether it's modulo-8 or modulo-128 operation,
9859 * some bitfield fields may be in different bits of
9860 * a byte, and we want to be able to refer to that field
9861 * with one name regardless of whether the packets
9862 * are modulo-8 or modulo-128 packets. */
9863
9864 same_name_hfinfo = NULL((void*)0);
9865
9866 g_hash_table_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9867 /* GLIB 2.x - if it is already present
9868 * the previous hfinfo with the same name is saved
9869 * to same_name_hfinfo by value destroy callback */
9870 if (same_name_hfinfo) {
9871 /* There's already a field with this name.
9872 * Put the current field *before* that field
9873 * in the list of fields with this name, Thus,
9874 * we end up with an effectively
9875 * doubly-linked-list of same-named hfinfo's,
9876 * with the head of the list (stored in the
9877 * hash) being the last seen hfinfo.
9878 */
9879 same_name_next_hfinfo =
9880 same_name_hfinfo->same_name_next;
9881
9882 hfinfo->same_name_next = same_name_next_hfinfo;
9883 if (same_name_next_hfinfo)
9884 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9885
9886 same_name_hfinfo->same_name_next = hfinfo;
9887 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9888#ifdef ENABLE_CHECK_FILTER
9889 while (same_name_hfinfo) {
9890 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9891 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"
, 9891, __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)
;
9892 same_name_hfinfo = same_name_hfinfo->same_name_next;
9893 }
9894#endif
9895 }
9896 }
9897
9898 return hfinfo->id;
9899}
9900
9901void
9902proto_register_subtree_array(int * const *indices, const int num_indices)
9903{
9904 int i;
9905 int *const *ptr = indices;
9906
9907 /*
9908 * If we've already allocated the array of tree types, expand
9909 * it; this lets plugins such as mate add tree types after
9910 * the initial startup. (If we haven't already allocated it,
9911 * we don't allocate it; on the first pass, we just assign
9912 * ett values and keep track of how many we've assigned, and
9913 * when we're finished registering all dissectors we allocate
9914 * the array, so that we do only one allocation rather than
9915 * wasting CPU time and memory by growing the array for each
9916 * dissector that registers ett values.)
9917 */
9918 if (tree_is_expanded != NULL((void*)0)) {
9919 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9920
9921 /* set new items to 0 */
9922 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9923 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9924 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9925 }
9926
9927 /*
9928 * Assign "num_indices" subtree numbers starting at "num_tree_types",
9929 * returning the indices through the pointers in the array whose
9930 * first element is pointed to by "indices", and update
9931 * "num_tree_types" appropriately.
9932 */
9933 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9934 if (**ptr != -1 && **ptr != 0) {
9935 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.")
9936 " 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.")
9937 " 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.")
9938 " 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.")
;
9939 }
9940 **ptr = num_tree_types;
9941 }
9942}
9943
9944static void
9945mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
9946{
9947 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
9948 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
9949 char *last_char;
9950
9951 /* ..... field_name: dataaaaaaaaaaaaa
9952 * |
9953 * ^^^^^ name_pos
9954 *
9955 * ..... field_name […]: dataaaaaaaaaaaaa
9956 *
9957 * name_pos==0 means that we have only data or only a field_name
9958 */
9959
9960 if (name_pos >= size - trunc_len) {
9961 /* No room for trunc_str after the field_name, put it first. */
9962 name_pos = 0;
9963 }
9964
9965 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
9966 if (name_pos == 0) {
9967 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
9968 memcpy(label_str, trunc_str + 1, trunc_len);
9969 } else {
9970 memcpy(label_str + name_pos, trunc_str, trunc_len);
9971 }
9972 /* in general, label_str is UTF-8
9973 we can truncate it only at the beginning of a new character
9974 we go backwards from the byte right after our buffer and
9975 find the next starting byte of a UTF-8 character, this is
9976 where we cut
9977 there's no need to use g_utf8_find_prev_char(), the search
9978 will always succeed since we copied trunc_str into the
9979 buffer */
9980 /* g_utf8_prev_char does not deference the memory address
9981 * passed in (until after decrementing it, so it is perfectly
9982 * legal to pass in a pointer one past the last element.
9983 */
9984 last_char = g_utf8_prev_char(label_str + size);
9985 *last_char = '\0';
9986
9987 if (value_pos && *value_pos > 0) {
9988 if (name_pos == 0) {
9989 *value_pos += trunc_len;
9990 } else {
9991 /* Move one back to include trunc_str in the value. */
9992 *value_pos -= 1;
9993 }
9994 }
9995
9996 /* Check if value_pos is past label_str. */
9997 if (value_pos && *value_pos >= size) {
9998 *value_pos = size - 1;
9999 }
10000}
10001
10002static void
10003label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10004{
10005 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10006}
10007
10008static size_t
10009label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10010{
10011 size_t name_pos;
10012
10013 /* "%s: %s", hfinfo->name, text */
10014 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10015 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10016 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10017 if (value_pos) {
10018 *value_pos = pos;
10019 }
10020 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, text ? text : "(null)", label_strcat_flags(hfinfo));
10021 }
10022
10023 if (pos >= ITEM_LABEL_LENGTH240) {
10024 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10025 label_mark_truncated(label_str, name_pos, value_pos);
10026 }
10027
10028 return pos;
10029}
10030
10031static size_t
10032label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10033{
10034 size_t name_pos;
10035
10036 /* "%s: %s (%s)", hfinfo->name, text, descr */
10037 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10038 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10039 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10040 if (value_pos) {
10041 *value_pos = pos;
10042 }
10043 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10044 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10045 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10046 } else {
10047 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10048 pos = label_concat(label_str, pos, " (")ws_label_strcpy(label_str, 240, pos, " (", 0);
10049 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10050 pos = label_concat(label_str, pos, ")")ws_label_strcpy(label_str, 240, pos, ")", 0);
10051 }
10052 }
10053
10054 if (pos >= ITEM_LABEL_LENGTH240) {
10055 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10056 label_mark_truncated(label_str, name_pos, value_pos);
10057 }
10058
10059 return pos;
10060}
10061
10062void
10063proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10064{
10065 const header_field_info *hfinfo;
10066 const char *str;
10067 const uint8_t *bytes;
10068 uint32_t integer;
10069 const ipv4_addr_and_mask *ipv4;
10070 const ipv6_addr_and_prefix *ipv6;
10071 const e_guid_t *guid;
10072 char *name;
10073 address addr;
10074 char *addr_str;
10075 char *tmp;
10076
10077 if (!label_str) {
10078 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10078, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10079 return;
10080 }
10081
10082 label_str[0]= '\0';
10083
10084 if (!fi) {
10085 return;
10086 }
10087
10088 hfinfo = fi->hfinfo;
10089
10090 switch (hfinfo->type) {
10091 case FT_NONE:
10092 case FT_PROTOCOL:
10093 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10094 if (value_pos) {
10095 *value_pos = strlen(hfinfo->name);
10096 }
10097 break;
10098
10099 case FT_BOOLEAN:
10100 fill_label_boolean(fi, label_str, value_pos);
10101 break;
10102
10103 case FT_BYTES:
10104 case FT_UINT_BYTES:
10105 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10106 fvalue_get_bytes_data(fi->value),
10107 (unsigned)fvalue_length2(fi->value));
10108 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10109 wmem_free(NULL((void*)0), tmp);
10110 break;
10111
10112 case FT_CHAR:
10113 if (hfinfo->bitmask) {
10114 fill_label_bitfield_char(fi, label_str, value_pos);
10115 } else {
10116 fill_label_char(fi, label_str, value_pos);
10117 }
10118 break;
10119
10120 /* Four types of integers to take care of:
10121 * Bitfield, with val_string
10122 * Bitfield, w/o val_string
10123 * Non-bitfield, with val_string
10124 * Non-bitfield, w/o val_string
10125 */
10126 case FT_UINT8:
10127 case FT_UINT16:
10128 case FT_UINT24:
10129 case FT_UINT32:
10130 if (hfinfo->bitmask) {
10131 fill_label_bitfield(fi, label_str, value_pos, false0);
10132 } else {
10133 fill_label_number(fi, label_str, value_pos, false0);
10134 }
10135 break;
10136
10137 case FT_FRAMENUM:
10138 fill_label_number(fi, label_str, value_pos, false0);
10139 break;
10140
10141 case FT_UINT40:
10142 case FT_UINT48:
10143 case FT_UINT56:
10144 case FT_UINT64:
10145 if (hfinfo->bitmask) {
10146 fill_label_bitfield64(fi, label_str, value_pos, false0);
10147 } else {
10148 fill_label_number64(fi, label_str, value_pos, false0);
10149 }
10150 break;
10151
10152 case FT_INT8:
10153 case FT_INT16:
10154 case FT_INT24:
10155 case FT_INT32:
10156 if (hfinfo->bitmask) {
10157 fill_label_bitfield(fi, label_str, value_pos, true1);
10158 } else {
10159 fill_label_number(fi, label_str, value_pos, true1);
10160 }
10161 break;
10162
10163 case FT_INT40:
10164 case FT_INT48:
10165 case FT_INT56:
10166 case FT_INT64:
10167 if (hfinfo->bitmask) {
10168 fill_label_bitfield64(fi, label_str, value_pos, true1);
10169 } else {
10170 fill_label_number64(fi, label_str, value_pos, true1);
10171 }
10172 break;
10173
10174 case FT_FLOAT:
10175 case FT_DOUBLE:
10176 fill_label_float(fi, label_str, value_pos);
10177 break;
10178
10179 case FT_ABSOLUTE_TIME:
10180 {
10181 const nstime_t *value = fvalue_get_time(fi->value);
10182 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10183 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10184 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10185 }
10186 if (hfinfo->strings) {
10187 /*
10188 * Table of time valus to be displayed
10189 * specially.
10190 */
10191 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10192 if (time_string != NULL((void*)0)) {
10193 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10194 break;
10195 }
10196 }
10197 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10198 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10199 wmem_free(NULL((void*)0), tmp);
10200 break;
10201 }
10202 case FT_RELATIVE_TIME:
10203 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10204 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10205 wmem_free(NULL((void*)0), tmp);
10206 break;
10207
10208 case FT_IPXNET:
10209 integer = fvalue_get_uinteger(fi->value);
10210 tmp = get_ipxnet_name(NULL((void*)0), integer);
10211 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10212 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10213 wmem_free(NULL((void*)0), tmp);
10214 wmem_free(NULL((void*)0), addr_str);
10215 break;
10216
10217 case FT_VINES:
10218 addr.type = AT_VINES;
10219 addr.len = VINES_ADDR_LEN6;
10220 addr.data = fvalue_get_bytes_data(fi->value);
10221
10222 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10223 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10224 wmem_free(NULL((void*)0), addr_str);
10225 break;
10226
10227 case FT_ETHER:
10228 bytes = fvalue_get_bytes_data(fi->value);
10229
10230 addr.type = AT_ETHER;
10231 addr.len = 6;
10232 addr.data = bytes;
10233
10234 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10235 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10236 wmem_free(NULL((void*)0), addr_str);
10237 break;
10238
10239 case FT_IPv4:
10240 ipv4 = fvalue_get_ipv4(fi->value);
10241 set_address_ipv4(&addr, ipv4);
10242
10243 if (hfinfo->display == BASE_NETMASK) {
10244 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10245 } else {
10246 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10247 }
10248 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10249 wmem_free(NULL((void*)0), addr_str);
10250 free_address(&addr);
10251 break;
10252
10253 case FT_IPv6:
10254 ipv6 = fvalue_get_ipv6(fi->value);
10255 set_address_ipv6(&addr, ipv6);
10256
10257 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10258 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10259 wmem_free(NULL((void*)0), addr_str);
10260 free_address(&addr);
10261 break;
10262
10263 case FT_FCWWN:
10264 bytes = fvalue_get_bytes_data(fi->value);
10265 addr.type = AT_FCWWN;
10266 addr.len = FCWWN_ADDR_LEN8;
10267 addr.data = bytes;
10268
10269 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10270 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10271 wmem_free(NULL((void*)0), addr_str);
10272 break;
10273
10274 case FT_GUID:
10275 guid = fvalue_get_guid(fi->value);
10276 tmp = guid_to_str(NULL((void*)0), guid);
10277 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10278 wmem_free(NULL((void*)0), tmp);
10279 break;
10280
10281 case FT_OID:
10282 bytes = fvalue_get_bytes_data(fi->value);
10283 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10284 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10285 if (name) {
10286 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10287 wmem_free(NULL((void*)0), name);
10288 } else {
10289 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10290 }
10291 wmem_free(NULL((void*)0), tmp);
10292 break;
10293
10294 case FT_REL_OID:
10295 bytes = fvalue_get_bytes_data(fi->value);
10296 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10297 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10298 if (name) {
10299 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10300 wmem_free(NULL((void*)0), name);
10301 } else {
10302 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10303 }
10304 wmem_free(NULL((void*)0), tmp);
10305 break;
10306
10307 case FT_SYSTEM_ID:
10308 bytes = fvalue_get_bytes_data(fi->value);
10309 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10310 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10311 wmem_free(NULL((void*)0), tmp);
10312 break;
10313
10314 case FT_EUI64:
10315 bytes = fvalue_get_bytes_data(fi->value);
10316 addr.type = AT_EUI64;
10317 addr.len = EUI64_ADDR_LEN8;
10318 addr.data = bytes;
10319
10320 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10321 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10322 wmem_free(NULL((void*)0), addr_str);
10323 break;
10324 case FT_STRING:
10325 case FT_STRINGZ:
10326 case FT_UINT_STRING:
10327 case FT_STRINGZPAD:
10328 case FT_STRINGZTRUNC:
10329 case FT_AX25:
10330 str = fvalue_get_string(fi->value);
10331 label_fill(label_str, 0, hfinfo, str, value_pos);
10332 break;
10333
10334 case FT_IEEE_11073_SFLOAT:
10335 case FT_IEEE_11073_FLOAT:
10336 fill_label_ieee_11073_float(fi, label_str, value_pos);
10337 break;
10338
10339 default:
10340 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
))
10341 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
))
10342 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
))
10343 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
))
;
10344 break;
10345 }
10346}
10347
10348static void
10349fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10350{
10351 char *p;
10352 int bitfield_byte_length = 0, bitwidth;
10353 uint64_t unshifted_value;
10354 uint64_t value;
10355
10356 const header_field_info *hfinfo = fi->hfinfo;
10357
10358 value = fvalue_get_uinteger64(fi->value);
10359 if (hfinfo->bitmask) {
10360 /* Figure out the bit width */
10361 bitwidth = hfinfo_container_bitwidth(hfinfo);
10362
10363 /* Un-shift bits */
10364 unshifted_value = value;
10365 unshifted_value <<= hfinfo_bitshift(hfinfo);
10366
10367 /* Create the bitfield first */
10368 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10369 bitfield_byte_length = (int) (p - label_str);
10370 }
10371
10372 /* Fill in the textual info */
10373 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10374}
10375
10376static const char *
10377hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10378{
10379 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10380 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10381
10382 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10383 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10384 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10385 else
10386 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10387 }
10388
10389 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10390 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10391
10392 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10393 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10394
10395 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10396}
10397
10398static const char *
10399hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10400{
10401 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10402 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10403 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10404 else
10405 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10406 }
10407
10408 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10409 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10410
10411 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10412 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10413
10414 /* If this is reached somebody registered a 64-bit field with a 32-bit
10415 * value-string, which isn't right. */
10416 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)
10417 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10418
10419 /* This is necessary to squelch MSVC errors; is there
10420 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10421 never returns? */
10422 return NULL((void*)0);
10423}
10424
10425static const char *
10426hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10427{
10428 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10429 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10430
10431 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)
;
10432
10433 /* This is necessary to squelch MSVC errors; is there
10434 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10435 never returns? */
10436 return NULL((void*)0);
10437}
10438
10439static const char *
10440hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10441{
10442 const char *str = hf_try_val_to_str(value, hfinfo);
10443
10444 return (str) ? str : unknown_str;
10445}
10446
10447static const char *
10448hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10449{
10450 const char *str = hf_try_val64_to_str(value, hfinfo);
10451
10452 return (str) ? str : unknown_str;
10453}
10454
10455/* Fills data for bitfield chars with val_strings */
10456static void
10457fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10458{
10459 char *p;
10460 int bitfield_byte_length, bitwidth;
10461 uint32_t unshifted_value;
10462 uint32_t value;
10463
10464 char buf[32];
10465 const char *out;
10466
10467 const header_field_info *hfinfo = fi->hfinfo;
10468
10469 /* Figure out the bit width */
10470 bitwidth = hfinfo_container_bitwidth(hfinfo);
10471
10472 /* Un-shift bits */
10473 value = fvalue_get_uinteger(fi->value);
10474
10475 unshifted_value = value;
10476 if (hfinfo->bitmask) {
10477 unshifted_value <<= hfinfo_bitshift(hfinfo);
10478 }
10479
10480 /* Create the bitfield first */
10481 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10482 bitfield_byte_length = (int) (p - label_str);
10483
10484 /* Fill in the textual info using stored (shifted) value */
10485 if (hfinfo->display == BASE_CUSTOM) {
10486 char tmp[ITEM_LABEL_LENGTH240];
10487 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10488
10489 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10489, "fmtfunc"))))
;
10490 fmtfunc(tmp, value);
10491 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10492 }
10493 else if (hfinfo->strings) {
10494 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10495
10496 out = hfinfo_char_vals_format(hfinfo, buf, value);
10497 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10498 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10499 else
10500 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10501 }
10502 else {
10503 out = hfinfo_char_value_format(hfinfo, buf, value);
10504
10505 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10506 }
10507}
10508
10509/* Fills data for bitfield ints with val_strings */
10510static void
10511fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10512{
10513 char *p;
10514 int bitfield_byte_length, bitwidth;
10515 uint32_t value, unshifted_value;
10516 char buf[NUMBER_LABEL_LENGTH80];
10517 const char *out;
10518
10519 const header_field_info *hfinfo = fi->hfinfo;
10520
10521 /* Figure out the bit width */
10522 if (fi->flags & FI_VARINT0x00040000)
10523 bitwidth = fi->length*8;
10524 else
10525 bitwidth = hfinfo_container_bitwidth(hfinfo);
10526
10527 /* Un-shift bits */
10528 if (is_signed)
10529 value = fvalue_get_sinteger(fi->value);
10530 else
10531 value = fvalue_get_uinteger(fi->value);
10532
10533 unshifted_value = value;
10534 if (hfinfo->bitmask) {
10535 unshifted_value <<= hfinfo_bitshift(hfinfo);
10536 }
10537
10538 /* Create the bitfield first */
10539 if (fi->flags & FI_VARINT0x00040000)
10540 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10541 else
10542 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10543 bitfield_byte_length = (int) (p - label_str);
10544
10545 /* Fill in the textual info using stored (shifted) value */
10546 if (hfinfo->display == BASE_CUSTOM) {
10547 char tmp[ITEM_LABEL_LENGTH240];
10548 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10549
10550 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10550, "fmtfunc"))))
;
10551 fmtfunc(tmp, value);
10552 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10553 }
10554 else if (hfinfo->strings) {
10555 const char *val_str = hf_try_val_to_str(value, hfinfo);
10556
10557 out = hfinfo_number_vals_format(hfinfo, buf, value);
10558 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10559 /*
10560 * Unique values only display value_string string
10561 * if there is a match. Otherwise it's just a number
10562 */
10563 if (val_str) {
10564 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10565 } else {
10566 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10567 }
10568 } else {
10569 if (val_str == NULL((void*)0))
10570 val_str = "Unknown";
10571
10572 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10573 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10574 else
10575 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10576 }
10577 }
10578 else {
10579 out = hfinfo_number_value_format(hfinfo, buf, value);
10580
10581 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10582 }
10583}
10584
10585static void
10586fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10587{
10588 char *p;
10589 int bitfield_byte_length, bitwidth;
10590 uint64_t value, unshifted_value;
10591 char buf[NUMBER_LABEL_LENGTH80];
10592 const char *out;
10593
10594 const header_field_info *hfinfo = fi->hfinfo;
10595
10596 /* Figure out the bit width */
10597 if (fi->flags & FI_VARINT0x00040000)
10598 bitwidth = fi->length*8;
10599 else
10600 bitwidth = hfinfo_container_bitwidth(hfinfo);
10601
10602 /* Un-shift bits */
10603 if (is_signed)
10604 value = fvalue_get_sinteger64(fi->value);
10605 else
10606 value = fvalue_get_uinteger64(fi->value);
10607
10608 unshifted_value = value;
10609 if (hfinfo->bitmask) {
10610 unshifted_value <<= hfinfo_bitshift(hfinfo);
10611 }
10612
10613 /* Create the bitfield first */
10614 if (fi->flags & FI_VARINT0x00040000)
10615 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10616 else
10617 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10618 bitfield_byte_length = (int) (p - label_str);
10619
10620 /* Fill in the textual info using stored (shifted) value */
10621 if (hfinfo->display == BASE_CUSTOM) {
10622 char tmp[ITEM_LABEL_LENGTH240];
10623 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10624
10625 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10625, "fmtfunc64"
))))
;
10626 fmtfunc64(tmp, value);
10627 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10628 }
10629 else if (hfinfo->strings) {
10630 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10631
10632 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10633 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10634 /*
10635 * Unique values only display value_string string
10636 * if there is a match. Otherwise it's just a number
10637 */
10638 if (val_str) {
10639 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10640 } else {
10641 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10642 }
10643 } else {
10644 if (val_str == NULL((void*)0))
10645 val_str = "Unknown";
10646
10647 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10648 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10649 else
10650 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10651 }
10652 }
10653 else {
10654 out = hfinfo_number_value_format64(hfinfo, buf, value);
10655
10656 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10657 }
10658}
10659
10660static void
10661fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10662{
10663 const header_field_info *hfinfo = fi->hfinfo;
10664 uint32_t value;
10665
10666 char buf[32];
10667 const char *out;
10668
10669 value = fvalue_get_uinteger(fi->value);
10670
10671 /* Fill in the textual info */
10672 if (hfinfo->display == BASE_CUSTOM) {
10673 char tmp[ITEM_LABEL_LENGTH240];
10674 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10675
10676 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10676, "fmtfunc"))))
;
10677 fmtfunc(tmp, value);
10678 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10679 }
10680 else if (hfinfo->strings) {
10681 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10682
10683 out = hfinfo_char_vals_format(hfinfo, buf, value);
10684 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10685 }
10686 else {
10687 out = hfinfo_char_value_format(hfinfo, buf, value);
10688
10689 label_fill(label_str, 0, hfinfo, out, value_pos);
10690 }
10691}
10692
10693static void
10694fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10695{
10696 const header_field_info *hfinfo = fi->hfinfo;
10697 uint32_t value;
10698
10699 char buf[NUMBER_LABEL_LENGTH80];
10700 const char *out;
10701
10702 if (is_signed)
10703 value = fvalue_get_sinteger(fi->value);
10704 else
10705 value = fvalue_get_uinteger(fi->value);
10706
10707 /* Fill in the textual info */
10708 if (hfinfo->display == BASE_CUSTOM) {
10709 char tmp[ITEM_LABEL_LENGTH240];
10710 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10711
10712 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10712, "fmtfunc"))))
;
10713 fmtfunc(tmp, value);
10714 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10715 }
10716 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10717 /*
10718 * It makes no sense to have a value-string table for a
10719 * frame-number field - they're just integers giving
10720 * the ordinal frame number.
10721 */
10722 const char *val_str = hf_try_val_to_str(value, hfinfo);
10723
10724 out = hfinfo_number_vals_format(hfinfo, buf, value);
10725 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10726 /*
10727 * Unique values only display value_string string
10728 * if there is a match. Otherwise it's just a number
10729 */
10730 if (val_str) {
10731 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10732 } else {
10733 label_fill(label_str, 0, hfinfo, out, value_pos);
10734 }
10735 } else {
10736 if (val_str == NULL((void*)0))
10737 val_str = "Unknown";
10738
10739 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10740 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10741 else
10742 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10743 }
10744 }
10745 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
))
) {
10746 char tmp[ITEM_LABEL_LENGTH240];
10747
10748 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10749 display_to_port_type((field_display_e)hfinfo->display), value);
10750 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10751 }
10752 else {
10753 out = hfinfo_number_value_format(hfinfo, buf, value);
10754
10755 label_fill(label_str, 0, hfinfo, out, value_pos);
10756 }
10757}
10758
10759static void
10760fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10761{
10762 const header_field_info *hfinfo = fi->hfinfo;
10763 uint64_t value;
10764
10765 char buf[NUMBER_LABEL_LENGTH80];
10766 const char *out;
10767
10768 if (is_signed)
10769 value = fvalue_get_sinteger64(fi->value);
10770 else
10771 value = fvalue_get_uinteger64(fi->value);
10772
10773 /* Fill in the textual info */
10774 if (hfinfo->display == BASE_CUSTOM) {
10775 char tmp[ITEM_LABEL_LENGTH240];
10776 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10777
10778 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10778, "fmtfunc64"
))))
;
10779 fmtfunc64(tmp, value);
10780 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10781 }
10782 else if (hfinfo->strings) {
10783 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10784
10785 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10786 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10787 /*
10788 * Unique values only display value_string string
10789 * if there is a match. Otherwise it's just a number
10790 */
10791 if (val_str) {
10792 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10793 } else {
10794 label_fill(label_str, 0, hfinfo, out, value_pos);
10795 }
10796 } else {
10797 if (val_str == NULL((void*)0))
10798 val_str = "Unknown";
10799
10800 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10801 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10802 else
10803 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10804 }
10805 }
10806 else {
10807 out = hfinfo_number_value_format64(hfinfo, buf, value);
10808
10809 label_fill(label_str, 0, hfinfo, out, value_pos);
10810 }
10811}
10812
10813static size_t
10814fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10815{
10816 int display;
10817 int n;
10818 double value;
10819
10820 if (label_str_size < 12) {
10821 /* Not enough room to write an entire floating point value. */
10822 return 0;
10823 }
10824
10825 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10826 value = fvalue_get_floating(fi->value);
10827
10828 if (display == BASE_CUSTOM) {
10829 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10830 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10830, "fmtfunc"))))
;
10831 fmtfunc(label_str, value);
10832 return strlen(label_str);
10833 }
10834
10835 switch (display) {
10836 case BASE_NONE:
10837 if (fi->hfinfo->type == FT_FLOAT) {
10838 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10839 } else {
10840 n = (int)strlen(dtoa_g_fmt(label_str, value));
10841 }
10842 break;
10843 case BASE_DEC:
10844 n = snprintf(label_str, label_str_size, "%f", value);
10845 break;
10846 case BASE_HEX:
10847 n = snprintf(label_str, label_str_size, "%a", value);
10848 break;
10849 case BASE_EXP:
10850 n = snprintf(label_str, label_str_size, "%e", value);
10851 break;
10852 default:
10853 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10853
, __func__, "assertion \"not reached\" failed")
;
10854 }
10855 if (n < 0) {
10856 return 0; /* error */
10857 }
10858 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10859 const char *hf_str_val;
10860 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10861 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10862 }
10863 if (n > label_str_size) {
10864 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10864, __func__, "label length too small"); } } while (0)
;
10865 return strlen(label_str);
10866 }
10867
10868 return n;
10869}
10870
10871void
10872fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10873{
10874 char tmp[ITEM_LABEL_LENGTH240];
10875
10876 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10877 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10878}
10879
10880static size_t
10881fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10882{
10883 int display;
10884 size_t pos = 0;
10885 double value;
10886 char* tmp_str;
10887
10888 if (label_str_size < 12) {
10889 /* Not enough room to write an entire floating point value. */
10890 return 0;
10891 }
10892
10893 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10894 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10895 pos = label_concat(label_str, pos, tmp_str)ws_label_strcpy(label_str, 240, pos, tmp_str, 0);
10896 wmem_free(NULL((void*)0), tmp_str);
10897
10898 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10899 const char *hf_str_val;
10900 fvalue_to_double(fi->value, &value);
10901 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10902 pos = label_concat(label_str, pos, hf_str_val)ws_label_strcpy(label_str, 240, pos, hf_str_val, 0);
10903 }
10904 if ((int)pos > label_str_size) {
10905 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10905, __func__, "label length too small"); } } while (0)
;
10906 return strlen(label_str);
10907 }
10908
10909 return pos;
10910}
10911
10912void
10913fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
10914{
10915 char tmp[ITEM_LABEL_LENGTH240];
10916
10917 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
10918 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10919}
10920
10921int
10922hfinfo_bitshift(const header_field_info *hfinfo)
10923{
10924 return ws_ctz(hfinfo->bitmask);
10925}
10926
10927
10928static int
10929hfinfo_bitoffset(const header_field_info *hfinfo)
10930{
10931 if (!hfinfo->bitmask) {
10932 return 0;
10933 }
10934
10935 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
10936 * as the first bit */
10937 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
10938}
10939
10940static int
10941hfinfo_mask_bitwidth(const header_field_info *hfinfo)
10942{
10943 if (!hfinfo->bitmask) {
10944 return 0;
10945 }
10946
10947 /* ilog2 = first set bit, ctz = last set bit */
10948 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
10949}
10950
10951static int
10952hfinfo_type_bitwidth(enum ftenum type)
10953{
10954 int bitwidth = 0;
10955
10956 switch (type) {
10957 case FT_CHAR:
10958 case FT_UINT8:
10959 case FT_INT8:
10960 bitwidth = 8;
10961 break;
10962 case FT_UINT16:
10963 case FT_INT16:
10964 bitwidth = 16;
10965 break;
10966 case FT_UINT24:
10967 case FT_INT24:
10968 bitwidth = 24;
10969 break;
10970 case FT_UINT32:
10971 case FT_INT32:
10972 bitwidth = 32;
10973 break;
10974 case FT_UINT40:
10975 case FT_INT40:
10976 bitwidth = 40;
10977 break;
10978 case FT_UINT48:
10979 case FT_INT48:
10980 bitwidth = 48;
10981 break;
10982 case FT_UINT56:
10983 case FT_INT56:
10984 bitwidth = 56;
10985 break;
10986 case FT_UINT64:
10987 case FT_INT64:
10988 bitwidth = 64;
10989 break;
10990 default:
10991 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 10991))
;
10992 ;
10993 }
10994 return bitwidth;
10995}
10996
10997
10998static int
10999hfinfo_container_bitwidth(const header_field_info *hfinfo)
11000{
11001 if (!hfinfo->bitmask) {
11002 return 0;
11003 }
11004
11005 if (hfinfo->type == FT_BOOLEAN) {
11006 return hfinfo->display; /* hacky? :) */
11007 }
11008
11009 return hfinfo_type_bitwidth(hfinfo->type);
11010}
11011
11012static int
11013hfinfo_hex_digits(const header_field_info *hfinfo)
11014{
11015 int bitwidth;
11016
11017 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11018 * appropriate to determine the number of hex digits for the field.
11019 * So instead, we compute it from the bitmask.
11020 */
11021 if (hfinfo->bitmask != 0) {
11022 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11023 } else {
11024 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11025 }
11026
11027 /* Divide by 4, rounding up, to get number of hex digits. */
11028 return (bitwidth + 3) / 4;
11029}
11030
11031const char *
11032hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11033{
11034 char *ptr = &buf[6];
11035 static const char hex_digits[16] =
11036 { '0', '1', '2', '3', '4', '5', '6', '7',
11037 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11038
11039 *ptr = '\0';
11040 *(--ptr) = '\'';
11041 /* Properly format value */
11042 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11043 /*
11044 * Printable, so just show the character, and, if it needs
11045 * to be escaped, escape it.
11046 */
11047 *(--ptr) = value;
11048 if (value == '\\' || value == '\'')
11049 *(--ptr) = '\\';
11050 } else {
11051 /*
11052 * Non-printable; show it as an escape sequence.
11053 */
11054 switch (value) {
11055
11056 case '\0':
11057 /*
11058 * Show a NUL with only one digit.
11059 */
11060 *(--ptr) = '0';
11061 break;
11062
11063 case '\a':
11064 case '\b':
11065 case '\f':
11066 case '\n':
11067 case '\r':
11068 case '\t':
11069 case '\v':
11070 *(--ptr) = value - '\a' + 'a';
11071 break;
11072
11073 default:
11074 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11075
11076 case BASE_OCT:
11077 *(--ptr) = (value & 0x7) + '0';
11078 value >>= 3;
11079 *(--ptr) = (value & 0x7) + '0';
11080 value >>= 3;
11081 *(--ptr) = (value & 0x7) + '0';
11082 break;
11083
11084 case BASE_HEX:
11085 *(--ptr) = hex_digits[value & 0x0F];
11086 value >>= 4;
11087 *(--ptr) = hex_digits[value & 0x0F];
11088 *(--ptr) = 'x';
11089 break;
11090
11091 default:
11092 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11093 }
11094 }
11095 *(--ptr) = '\\';
11096 }
11097 *(--ptr) = '\'';
11098 return ptr;
11099}
11100
11101static const char *
11102hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11103{
11104 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11105 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
))
;
11106
11107 *ptr = '\0';
11108 /* Properly format value */
11109 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11110 case BASE_DEC:
11111 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11112
11113 case BASE_DEC_HEX:
11114 *(--ptr) = ')';
11115 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11116 *(--ptr) = '(';
11117 *(--ptr) = ' ';
11118 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11119 return ptr;
11120
11121 case BASE_OCT:
11122 return oct_to_str_back(ptr, value);
11123
11124 case BASE_HEX:
11125 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11126
11127 case BASE_HEX_DEC:
11128 *(--ptr) = ')';
11129 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11130 *(--ptr) = '(';
11131 *(--ptr) = ' ';
11132 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11133 return ptr;
11134
11135 case BASE_PT_UDP:
11136 case BASE_PT_TCP:
11137 case BASE_PT_DCCP:
11138 case BASE_PT_SCTP:
11139 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11140 display_to_port_type((field_display_e)display), value);
11141 return buf;
11142 case BASE_OUI:
11143 {
11144 uint8_t p_oui[3];
11145 const char *manuf_name;
11146
11147 p_oui[0] = value >> 16 & 0xFF;
11148 p_oui[1] = value >> 8 & 0xFF;
11149 p_oui[2] = value & 0xFF;
11150
11151 /* Attempt an OUI lookup. */
11152 manuf_name = uint_get_manuf_name_if_known(value);
11153 if (manuf_name == NULL((void*)0)) {
11154 /* Could not find an OUI. */
11155 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11156 }
11157 else {
11158 /* Found an address string. */
11159 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11160 }
11161 return buf;
11162 }
11163
11164 default:
11165 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11166 }
11167 return ptr;
11168}
11169
11170static const char *
11171hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11172{
11173 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11174 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
))
;
11175
11176 *ptr = '\0';
11177 /* Properly format value */
11178 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11179 case BASE_DEC:
11180 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11181
11182 case BASE_DEC_HEX:
11183 *(--ptr) = ')';
11184 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11185 *(--ptr) = '(';
11186 *(--ptr) = ' ';
11187 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11188 return ptr;
11189
11190 case BASE_OCT:
11191 return oct64_to_str_back(ptr, value);
11192
11193 case BASE_HEX:
11194 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11195
11196 case BASE_HEX_DEC:
11197 *(--ptr) = ')';
11198 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11199 *(--ptr) = '(';
11200 *(--ptr) = ' ';
11201 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11202 return ptr;
11203
11204 default:
11205 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11206 }
11207
11208 return ptr;
11209}
11210
11211static const char *
11212hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11213{
11214 int display = hfinfo->display;
11215
11216 if (hfinfo->type == FT_FRAMENUM) {
11217 /*
11218 * Frame numbers are always displayed in decimal.
11219 */
11220 display = BASE_DEC;
11221 }
11222
11223 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11224}
11225
11226static const char *
11227hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11228{
11229 int display = hfinfo->display;
11230
11231 if (hfinfo->type == FT_FRAMENUM) {
11232 /*
11233 * Frame numbers are always displayed in decimal.
11234 */
11235 display = BASE_DEC;
11236 }
11237
11238 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11239}
11240
11241static const char *
11242hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11243{
11244 /* Get the underlying BASE_ value */
11245 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11246
11247 return hfinfo_char_value_format_display(display, buf, value);
11248}
11249
11250static const char *
11251hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11252{
11253 /* Get the underlying BASE_ value */
11254 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11255
11256 if (hfinfo->type == FT_FRAMENUM) {
11257 /*
11258 * Frame numbers are always displayed in decimal.
11259 */
11260 display = BASE_DEC;
11261 }
11262
11263 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11264 display = BASE_DEC;
11265 } else if (display == BASE_OUI) {
11266 display = BASE_HEX;
11267 }
11268
11269 switch (display) {
11270 case BASE_NONE:
11271 /* case BASE_DEC: */
11272 case BASE_DEC_HEX:
11273 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11274 case BASE_CUSTOM:
11275 display = BASE_DEC;
11276 break;
11277
11278 /* case BASE_HEX: */
11279 case BASE_HEX_DEC:
11280 display = BASE_HEX;
11281 break;
11282 }
11283
11284 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11285}
11286
11287static const char *
11288hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11289{
11290 /* Get the underlying BASE_ value */
11291 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11292
11293 if (hfinfo->type == FT_FRAMENUM) {
11294 /*
11295 * Frame numbers are always displayed in decimal.
11296 */
11297 display = BASE_DEC;
11298 }
11299
11300 switch (display) {
11301 case BASE_NONE:
11302 /* case BASE_DEC: */
11303 case BASE_DEC_HEX:
11304 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11305 case BASE_CUSTOM:
11306 display = BASE_DEC;
11307 break;
11308
11309 /* case BASE_HEX: */
11310 case BASE_HEX_DEC:
11311 display = BASE_HEX;
11312 break;
11313 }
11314
11315 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11316}
11317
11318static const char *
11319hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11320{
11321 /* Get the underlying BASE_ value */
11322 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11323
11324 return hfinfo_char_value_format_display(display, buf, value);
11325}
11326
11327static const char *
11328hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11329{
11330 /* Get the underlying BASE_ value */
11331 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11332
11333 if (display == BASE_NONE)
11334 return NULL((void*)0);
11335
11336 if (display == BASE_DEC_HEX)
11337 display = BASE_DEC;
11338 if (display == BASE_HEX_DEC)
11339 display = BASE_HEX;
11340
11341 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11342}
11343
11344static const char *
11345hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11346{
11347 /* Get the underlying BASE_ value */
11348 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11349
11350 if (display == BASE_NONE)
11351 return NULL((void*)0);
11352
11353 if (display == BASE_DEC_HEX)
11354 display = BASE_DEC;
11355 if (display == BASE_HEX_DEC)
11356 display = BASE_HEX;
11357
11358 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11359}
11360
11361const char *
11362proto_registrar_get_name(const int n)
11363{
11364 header_field_info *hfinfo;
11365
11366 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", 11366
, __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", 11366
, "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", 11366, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11367 return hfinfo->name;
11368}
11369
11370const char *
11371proto_registrar_get_abbrev(const int n)
11372{
11373 header_field_info *hfinfo;
11374
11375 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", 11375
, __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", 11375
, "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", 11375, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11376 return hfinfo->abbrev;
11377}
11378
11379enum ftenum
11380proto_registrar_get_ftype(const int n)
11381{
11382 header_field_info *hfinfo;
11383
11384 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", 11384
, __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", 11384
, "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", 11384, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11385 return hfinfo->type;
11386}
11387
11388int
11389proto_registrar_get_parent(const int n)
11390{
11391 header_field_info *hfinfo;
11392
11393 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", 11393
, __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", 11393
, "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", 11393, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11394 return hfinfo->parent;
11395}
11396
11397bool_Bool
11398proto_registrar_is_protocol(const int n)
11399{
11400 header_field_info *hfinfo;
11401
11402 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", 11402
, __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", 11402
, "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", 11402, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11403 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11404}
11405
11406/* Returns length of field in packet (not necessarily the length
11407 * in our internal representation, as in the case of IPv4).
11408 * 0 means undeterminable at time of registration
11409 * -1 means the field is not registered. */
11410int
11411proto_registrar_get_length(const int n)
11412{
11413 header_field_info *hfinfo;
11414
11415 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", 11415
, __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", 11415
, "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", 11415, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11416 return ftype_wire_size(hfinfo->type);
11417}
11418
11419/* Looks for a protocol or a field in a proto_tree. Returns true if
11420 * it exists anywhere, or false if it exists nowhere. */
11421bool_Bool
11422proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11423{
11424 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11425
11426 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11427 return true1;
11428 }
11429 else {
11430 return false0;
11431 }
11432}
11433
11434/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11435 * This only works if the hfindex was "primed" before the dissection
11436 * took place, as we just pass back the already-created GPtrArray*.
11437 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11438 * handles that. */
11439GPtrArray *
11440proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11441{
11442 if (!tree)
11443 return NULL((void*)0);
11444
11445 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11446 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11447 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11448 else
11449 return NULL((void*)0);
11450}
11451
11452bool_Bool
11453proto_tracking_interesting_fields(const proto_tree *tree)
11454{
11455 GHashTable *interesting_hfids;
11456
11457 if (!tree)
11458 return false0;
11459
11460 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11461
11462 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11463}
11464
11465/* Helper struct for proto_find_info() and proto_all_finfos() */
11466typedef struct {
11467 GPtrArray *array;
11468 int id;
11469} ffdata_t;
11470
11471/* Helper function for proto_find_info() */
11472static bool_Bool
11473find_finfo(proto_node *node, void * data)
11474{
11475 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11476 if (fi && fi->hfinfo) {
11477 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11478 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11479 }
11480 }
11481
11482 /* Don't stop traversing. */
11483 return false0;
11484}
11485
11486/* Helper function for proto_find_first_info() */
11487static bool_Bool
11488find_first_finfo(proto_node *node, void *data)
11489{
11490 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11491 if (fi && fi->hfinfo) {
11492 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11493 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11494
11495 /* Stop traversing. */
11496 return true1;
11497 }
11498 }
11499
11500 /* Continue traversing. */
11501 return false0;
11502}
11503
11504/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11505* This works on any proto_tree, primed or unprimed, but actually searches
11506* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11507* The caller does need to free the returned GPtrArray with
11508* g_ptr_array_free(<array>, true).
11509*/
11510GPtrArray *
11511proto_find_finfo(proto_tree *tree, const int id)
11512{
11513 ffdata_t ffdata;
11514
11515 ffdata.array = g_ptr_array_new();
11516 ffdata.id = id;
11517
11518 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11519
11520 return ffdata.array;
11521}
11522
11523/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11524* This works on any proto_tree, primed or unprimed, but actually searches
11525* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11526* The caller does need to free the returned GPtrArray with
11527* g_ptr_array_free(<array>, true).
11528*/
11529GPtrArray *
11530proto_find_first_finfo(proto_tree *tree, const int id)
11531{
11532 ffdata_t ffdata;
11533
11534 ffdata.array = g_ptr_array_new();
11535 ffdata.id = id;
11536
11537 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11538
11539 return ffdata.array;
11540}
11541
11542/* Helper function for proto_all_finfos() */
11543static bool_Bool
11544every_finfo(proto_node *node, void * data)
11545{
11546 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11547 if (fi && fi->hfinfo) {
11548 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11549 }
11550
11551 /* Don't stop traversing. */
11552 return false0;
11553}
11554
11555/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11556 * The caller does need to free the returned GPtrArray with
11557 * g_ptr_array_free(<array>, true).
11558 */
11559GPtrArray *
11560proto_all_finfos(proto_tree *tree)
11561{
11562 ffdata_t ffdata;
11563
11564 /* Pre allocate enough space to hold all fields in most cases */
11565 ffdata.array = g_ptr_array_sized_new(512);
11566 ffdata.id = 0;
11567
11568 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11569
11570 return ffdata.array;
11571}
11572
11573
11574typedef struct {
11575 unsigned offset;
11576 field_info *finfo;
11577 tvbuff_t *tvb;
11578} offset_search_t;
11579
11580static bool_Bool
11581check_for_offset(proto_node *node, void * data)
11582{
11583 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11584 offset_search_t *offsearch = (offset_search_t *)data;
11585
11586 /* !fi == the top most container node which holds nothing */
11587 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11588 if (offsearch->offset >= (unsigned) fi->start &&
11589 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11590
11591 offsearch->finfo = fi;
11592 return false0; /* keep traversing */
11593 }
11594 }
11595 return false0; /* keep traversing */
11596}
11597
11598/* Search a proto_tree backwards (from leaves to root) looking for the field
11599 * whose start/length occupies 'offset' */
11600/* XXX - I couldn't find an easy way to search backwards, so I search
11601 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11602 * the one I want to return to the user. This algorithm is inefficient
11603 * and could be re-done, but I'd have to handle all the children and
11604 * siblings of each node myself. When I have more time I'll do that.
11605 * (yeah right) */
11606field_info *
11607proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11608{
11609 offset_search_t offsearch;
11610
11611 offsearch.offset = offset;
11612 offsearch.finfo = NULL((void*)0);
11613 offsearch.tvb = tvb;
11614
11615 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11616
11617 return offsearch.finfo;
11618}
11619
11620typedef struct {
11621 int length;
11622 char *buf;
11623} decoded_data_t;
11624
11625static bool_Bool
11626check_for_undecoded(proto_node *node, void * data)
11627{
11628 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11629 decoded_data_t* decoded = (decoded_data_t*)data;
11630 int i;
11631 unsigned byte;
11632 unsigned bit;
11633
11634 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11635 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11636 byte = i / 8;
11637 bit = i % 8;
11638 decoded->buf[byte] |= (1 << bit);
11639 }
11640 }
11641
11642 return false0;
11643}
11644
11645char*
11646proto_find_undecoded_data(proto_tree *tree, unsigned length)
11647{
11648 decoded_data_t decoded;
11649 decoded.length = length;
11650 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11651
11652 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11653 return decoded.buf;
11654}
11655
11656/* Dumps the protocols in the registration database to stdout. An independent
11657 * program can take this output and format it into nice tables or HTML or
11658 * whatever.
11659 *
11660 * There is one record per line. The fields are tab-delimited.
11661 *
11662 * Field 1 = protocol name
11663 * Field 2 = protocol short name
11664 * Field 3 = protocol filter name
11665 * Field 4 = protocol enabled
11666 * Field 5 = protocol enabled by default
11667 * Field 6 = protocol can toggle
11668 */
11669void
11670proto_registrar_dump_protocols(void)
11671{
11672 protocol_t *protocol;
11673 int i;
11674 void *cookie = NULL((void*)0);
11675
11676
11677 i = proto_get_first_protocol(&cookie);
11678 while (i != -1) {
11679 protocol = find_protocol_by_id(i);
11680 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11681 protocol->name,
11682 protocol->short_name,
11683 protocol->filter_name,
11684 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11685 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11686 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11687 i = proto_get_next_protocol(&cookie);
11688 }
11689}
11690
11691/* Dumps the value_strings, extended value string headers, range_strings
11692 * or true/false strings for fields that have them.
11693 * There is one record per line. Fields are tab-delimited.
11694 * There are four types of records: Value String, Extended Value String Header,
11695 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11696 * the type of record.
11697 *
11698 * Note that a record will be generated only if the value_string,... is referenced
11699 * in a registered hfinfo entry.
11700 *
11701 *
11702 * Value Strings
11703 * -------------
11704 * Field 1 = 'V'
11705 * Field 2 = Field abbreviation to which this value string corresponds
11706 * Field 3 = Integer value
11707 * Field 4 = String
11708 *
11709 * Extended Value String Headers
11710 * -----------------------------
11711 * Field 1 = 'E'
11712 * Field 2 = Field abbreviation to which this extended value string header corresponds
11713 * Field 3 = Extended Value String "Name"
11714 * Field 4 = Number of entries in the associated value_string array
11715 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11716 *
11717 * Range Strings
11718 * -------------
11719 * Field 1 = 'R'
11720 * Field 2 = Field abbreviation to which this range string corresponds
11721 * Field 3 = Integer value: lower bound
11722 * Field 4 = Integer value: upper bound
11723 * Field 5 = String
11724 *
11725 * True/False Strings
11726 * ------------------
11727 * Field 1 = 'T'
11728 * Field 2 = Field abbreviation to which this true/false string corresponds
11729 * Field 3 = True String
11730 * Field 4 = False String
11731 */
11732void
11733proto_registrar_dump_values(void)
11734{
11735 header_field_info *hfinfo;
11736 int i, len, vi;
11737 const value_string *vals;
11738 const val64_string *vals64;
11739 const range_string *range;
11740 const true_false_string *tfs;
11741 const unit_name_string *units;
11742
11743 len = gpa_hfinfo.len;
11744 for (i = 0; i < len ; i++) {
11745 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11746 continue; /* This is a deregistered protocol or field */
11747
11748 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", 11748
, __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", 11748
, "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", 11748, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11749
11750 if (hfinfo->id == hf_text_only) {
11751 continue;
11752 }
11753
11754 /* ignore protocols */
11755 if (proto_registrar_is_protocol(i)) {
11756 continue;
11757 }
11758 /* process header fields */
11759#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11760 /*
11761 * If this field isn't at the head of the list of
11762 * fields with this name, skip this field - all
11763 * fields with the same name are really just versions
11764 * of the same field stored in different bits, and
11765 * should have the same type/radix/value list, and
11766 * just differ in their bit masks. (If a field isn't
11767 * a bitfield, but can be, say, 1 or 2 bytes long,
11768 * it can just be made FT_UINT16, meaning the
11769 * *maximum* length is 2 bytes, and be used
11770 * for all lengths.)
11771 */
11772 if (hfinfo->same_name_prev_id != -1)
11773 continue;
11774#endif
11775 vals = NULL((void*)0);
11776 vals64 = NULL((void*)0);
11777 range = NULL((void*)0);
11778 tfs = NULL((void*)0);
11779 units = NULL((void*)0);
11780
11781 if (hfinfo->strings != NULL((void*)0)) {
11782 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11783 (hfinfo->type == FT_CHAR ||
11784 hfinfo->type == FT_UINT8 ||
11785 hfinfo->type == FT_UINT16 ||
11786 hfinfo->type == FT_UINT24 ||
11787 hfinfo->type == FT_UINT32 ||
11788 hfinfo->type == FT_UINT40 ||
11789 hfinfo->type == FT_UINT48 ||
11790 hfinfo->type == FT_UINT56 ||
11791 hfinfo->type == FT_UINT64 ||
11792 hfinfo->type == FT_INT8 ||
11793 hfinfo->type == FT_INT16 ||
11794 hfinfo->type == FT_INT24 ||
11795 hfinfo->type == FT_INT32 ||
11796 hfinfo->type == FT_INT40 ||
11797 hfinfo->type == FT_INT48 ||
11798 hfinfo->type == FT_INT56 ||
11799 hfinfo->type == FT_INT64 ||
11800 hfinfo->type == FT_FLOAT ||
11801 hfinfo->type == FT_DOUBLE)) {
11802
11803 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11804 range = (const range_string *)hfinfo->strings;
11805 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11806 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11807 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11808 } else {
11809 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11810 }
11811 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11812 vals64 = (const val64_string *)hfinfo->strings;
11813 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11814 units = (const unit_name_string *)hfinfo->strings;
11815 } else {
11816 vals = (const value_string *)hfinfo->strings;
11817 }
11818 }
11819 else if (hfinfo->type == FT_BOOLEAN) {
11820 tfs = (const struct true_false_string *)hfinfo->strings;
11821 }
11822 }
11823
11824 /* Print value strings? */
11825 if (vals) {
11826 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11827 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11828 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11829 if (!val64_string_ext_validate(vse_p)) {
11830 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11830, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11831 continue;
11832 }
11833 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11834 printf("E\t%s\t%u\t%s\t%s\n",
11835 hfinfo->abbrev,
11836 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11837 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11838 val64_string_ext_match_type_str(vse_p));
11839 } else {
11840 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11841 if (!value_string_ext_validate(vse_p)) {
11842 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11842, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11843 continue;
11844 }
11845 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11846 printf("E\t%s\t%u\t%s\t%s\n",
11847 hfinfo->abbrev,
11848 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11849 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11850 value_string_ext_match_type_str(vse_p));
11851 }
11852 }
11853 vi = 0;
11854 while (vals[vi].strptr) {
11855 /* Print in the proper base */
11856 if (hfinfo->type == FT_CHAR) {
11857 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11858 printf("V\t%s\t'%c'\t%s\n",
11859 hfinfo->abbrev,
11860 vals[vi].value,
11861 vals[vi].strptr);
11862 } else {
11863 if (hfinfo->display == BASE_HEX) {
11864 printf("V\t%s\t'\\x%02x'\t%s\n",
11865 hfinfo->abbrev,
11866 vals[vi].value,
11867 vals[vi].strptr);
11868 }
11869 else {
11870 printf("V\t%s\t'\\%03o'\t%s\n",
11871 hfinfo->abbrev,
11872 vals[vi].value,
11873 vals[vi].strptr);
11874 }
11875 }
11876 } else {
11877 if (hfinfo->display == BASE_HEX) {
11878 printf("V\t%s\t0x%x\t%s\n",
11879 hfinfo->abbrev,
11880 vals[vi].value,
11881 vals[vi].strptr);
11882 }
11883 else {
11884 printf("V\t%s\t%u\t%s\n",
11885 hfinfo->abbrev,
11886 vals[vi].value,
11887 vals[vi].strptr);
11888 }
11889 }
11890 vi++;
11891 }
11892 }
11893 else if (vals64) {
11894 vi = 0;
11895 while (vals64[vi].strptr) {
11896 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11897 hfinfo->abbrev,
11898 vals64[vi].value,
11899 vals64[vi].strptr);
11900 vi++;
11901 }
11902 }
11903
11904 /* print range strings? */
11905 else if (range) {
11906 vi = 0;
11907 while (range[vi].strptr) {
11908 /* Print in the proper base */
11909 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
11910 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
11911 hfinfo->abbrev,
11912 range[vi].value_min,
11913 range[vi].value_max,
11914 range[vi].strptr);
11915 }
11916 else {
11917 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
11918 hfinfo->abbrev,
11919 range[vi].value_min,
11920 range[vi].value_max,
11921 range[vi].strptr);
11922 }
11923 vi++;
11924 }
11925 }
11926
11927 /* Print true/false strings? */
11928 else if (tfs) {
11929 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
11930 tfs->true_string, tfs->false_string);
11931 }
11932 /* Print unit strings? */
11933 else if (units) {
11934 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
11935 units->singular, units->plural ? units->plural : "(no plural)");
11936 }
11937 }
11938}
11939
11940/* Prints the number of registered fields.
11941 * Useful for determining an appropriate value for
11942 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
11943 *
11944 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
11945 * the number of fields, true otherwise.
11946 */
11947bool_Bool
11948proto_registrar_dump_fieldcount(void)
11949{
11950 uint32_t i;
11951 header_field_info *hfinfo;
11952 uint32_t deregistered_count = 0;
11953 uint32_t same_name_count = 0;
11954 uint32_t protocol_count = 0;
11955
11956 for (i = 0; i < gpa_hfinfo.len; i++) {
11957 if (gpa_hfinfo.hfi[i] == NULL((void*)0)) {
11958 deregistered_count++;
11959 continue; /* This is a deregistered protocol or header field */
11960 }
11961
11962 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", 11962
, __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", 11962
, "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", 11962, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11963
11964 if (proto_registrar_is_protocol(i))
11965 protocol_count++;
11966
11967 if (hfinfo->same_name_prev_id != -1)
11968 same_name_count++;
11969 }
11970
11971 printf("There are %u header fields registered, of which:\n"
11972 "\t%u are deregistered\n"
11973 "\t%u are protocols\n"
11974 "\t%u have the same name as another field\n\n",
11975 gpa_hfinfo.len, deregistered_count, protocol_count,
11976 same_name_count);
11977
11978 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
11979 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
11980 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
11981 "\n");
11982
11983 printf("The header field table consumes %u KiB of memory.\n",
11984 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
11985 printf("The fields themselves consume %u KiB of memory.\n",
11986 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
11987
11988 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
11989}
11990
11991static void
11992elastic_add_base_mapping(json_dumper *dumper)
11993{
11994 json_dumper_set_member_name(dumper, "index_patterns");
11995 json_dumper_begin_array(dumper);
11996 // The index names from write_json_index() in print.c
11997 json_dumper_value_string(dumper, "packets-*");
11998 json_dumper_end_array(dumper);
11999
12000 json_dumper_set_member_name(dumper, "settings");
12001 json_dumper_begin_object(dumper);
12002 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12003 json_dumper_value_anyf(dumper, "%d", 1000000);
12004 json_dumper_end_object(dumper);
12005}
12006
12007static char*
12008ws_type_to_elastic(unsigned type)
12009{
12010 switch(type) {
12011 case FT_INT8:
12012 return "byte";
12013 case FT_UINT8:
12014 case FT_INT16:
12015 return "short";
12016 case FT_UINT16:
12017 case FT_INT32:
12018 case FT_UINT24:
12019 case FT_INT24:
12020 return "integer";
12021 case FT_FRAMENUM:
12022 case FT_UINT32:
12023 case FT_UINT40:
12024 case FT_UINT48:
12025 case FT_UINT56:
12026 case FT_INT40:
12027 case FT_INT48:
12028 case FT_INT56:
12029 case FT_INT64:
12030 return "long";
12031 case FT_UINT64:
12032 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12033 case FT_FLOAT:
12034 return "float";
12035 case FT_DOUBLE:
12036 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12037 return "double";
12038 case FT_IPv6:
12039 case FT_IPv4:
12040 return "ip";
12041 case FT_ABSOLUTE_TIME:
12042 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12043 case FT_BOOLEAN:
12044 return "boolean";
12045 default:
12046 return NULL((void*)0);
12047 }
12048}
12049
12050static char*
12051dot_to_underscore(char* str)
12052{
12053 unsigned i;
12054 for (i = 0; i < strlen(str); i++) {
12055 if (str[i] == '.')
12056 str[i] = '_';
12057 }
12058 return str;
12059}
12060
12061/* Dumps a mapping file for ElasticSearch
12062 * This is the v1 (legacy) _template API.
12063 * At some point it may need to be updated with the composable templates
12064 * introduced in Elasticsearch 7.8 (_index_template)
12065 */
12066void
12067proto_registrar_dump_elastic(const char* filter)
12068{
12069 header_field_info *hfinfo;
12070 header_field_info *parent_hfinfo;
12071 unsigned i;
12072 bool_Bool open_object = true1;
12073 const char* prev_proto = NULL((void*)0);
12074 char* str;
12075 char** protos = NULL((void*)0);
12076 char* proto;
12077 bool_Bool found;
12078 unsigned j;
12079 char* type;
12080 char* prev_item = NULL((void*)0);
12081
12082 /* We have filtering protocols. Extract them. */
12083 if (filter) {
12084 protos = g_strsplit(filter, ",", -1);
12085 }
12086
12087 /*
12088 * To help tracking down the json tree, objects have been appended with a comment:
12089 * n.label -> where n is the indentation level and label the name of the object
12090 */
12091
12092 json_dumper dumper = {
12093 .output_file = stdoutstdout,
12094 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12095 };
12096 json_dumper_begin_object(&dumper); // 1.root
12097 elastic_add_base_mapping(&dumper);
12098
12099 json_dumper_set_member_name(&dumper, "mappings");
12100 json_dumper_begin_object(&dumper); // 2.mappings
12101
12102 json_dumper_set_member_name(&dumper, "properties");
12103 json_dumper_begin_object(&dumper); // 3.properties
12104 json_dumper_set_member_name(&dumper, "timestamp");
12105 json_dumper_begin_object(&dumper); // 4.timestamp
12106 json_dumper_set_member_name(&dumper, "type");
12107 json_dumper_value_string(&dumper, "date");
12108 json_dumper_end_object(&dumper); // 4.timestamp
12109
12110 json_dumper_set_member_name(&dumper, "layers");
12111 json_dumper_begin_object(&dumper); // 4.layers
12112 json_dumper_set_member_name(&dumper, "properties");
12113 json_dumper_begin_object(&dumper); // 5.properties
12114
12115 for (i = 0; i < gpa_hfinfo.len; i++) {
12116 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12117 continue; /* This is a deregistered protocol or header field */
12118
12119 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", 12119
, __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", 12119
, "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", 12119, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12120
12121 /*
12122 * Skip the pseudo-field for "proto_tree_add_text()" since
12123 * we don't want it in the list of filterable protocols.
12124 */
12125 if (hfinfo->id == hf_text_only)
12126 continue;
12127
12128 if (!proto_registrar_is_protocol(i)) {
12129 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", 12129
, __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", 12129
, "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", 12129
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12130
12131 /*
12132 * Skip the field if filter protocols have been set and this one's
12133 * parent is not listed.
12134 */
12135 if (protos) {
12136 found = false0;
12137 j = 0;
12138 proto = protos[0];
12139 while(proto) {
12140 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12141 found = true1;
12142 break;
12143 }
12144 j++;
12145 proto = protos[j];
12146 }
12147 if (!found)
12148 continue;
12149 }
12150
12151 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12152 json_dumper_end_object(&dumper); // 7.properties
12153 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12154 open_object = true1;
12155 }
12156
12157 prev_proto = parent_hfinfo->abbrev;
12158
12159 if (open_object) {
12160 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12161 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12162 json_dumper_set_member_name(&dumper, "properties");
12163 json_dumper_begin_object(&dumper); // 7.properties
12164 open_object = false0;
12165 }
12166 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12167 type = ws_type_to_elastic(hfinfo->type);
12168 /* when type is NULL, we have the default mapping: string */
12169 if (type) {
12170 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12171 dot_to_underscore(str);
12172 if (g_strcmp0(prev_item, str)) {
12173 json_dumper_set_member_name(&dumper, str);
12174 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12175 json_dumper_set_member_name(&dumper, "type");
12176 json_dumper_value_string(&dumper, type);
12177 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12178 }
12179 g_free(prev_item);
12180 prev_item = str;
12181 }
12182 }
12183 }
12184 g_free(prev_item);
12185
12186 if (prev_proto) {
12187 json_dumper_end_object(&dumper); // 7.properties
12188 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12189 }
12190
12191 json_dumper_end_object(&dumper); // 5.properties
12192 json_dumper_end_object(&dumper); // 4.layers
12193 json_dumper_end_object(&dumper); // 3.properties
12194 json_dumper_end_object(&dumper); // 2.mappings
12195 json_dumper_end_object(&dumper); // 1.root
12196 bool_Bool ret = json_dumper_finish(&dumper);
12197 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12197, "ret"))))
;
12198
12199 g_strfreev(protos);
12200}
12201
12202/* Dumps the contents of the registration database to stdout. An independent
12203 * program can take this output and format it into nice tables or HTML or
12204 * whatever.
12205 *
12206 * There is one record per line. Each record is either a protocol or a header
12207 * field, differentiated by the first field. The fields are tab-delimited.
12208 *
12209 * Protocols
12210 * ---------
12211 * Field 1 = 'P'
12212 * Field 2 = descriptive protocol name
12213 * Field 3 = protocol abbreviation
12214 *
12215 * Header Fields
12216 * -------------
12217 * Field 1 = 'F'
12218 * Field 2 = descriptive field name
12219 * Field 3 = field abbreviation
12220 * Field 4 = type ( textual representation of the ftenum type )
12221 * Field 5 = parent protocol abbreviation
12222 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12223 * Field 7 = bitmask: format: hex: 0x....
12224 * Field 8 = blurb describing field
12225 */
12226void
12227proto_registrar_dump_fields(void)
12228{
12229 header_field_info *hfinfo, *parent_hfinfo;
12230 int i, len;
12231 const char *enum_name;
12232 const char *base_name;
12233 const char *blurb;
12234 char width[5];
12235
12236 len = gpa_hfinfo.len;
12237 for (i = 0; i < len ; i++) {
12238 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12239 continue; /* This is a deregistered protocol or header field */
12240
12241 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", 12241
, __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", 12241
, "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", 12241, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12242
12243 /*
12244 * Skip the pseudo-field for "proto_tree_add_text()" since
12245 * we don't want it in the list of filterable fields.
12246 */
12247 if (hfinfo->id == hf_text_only)
12248 continue;
12249
12250 /* format for protocols */
12251 if (proto_registrar_is_protocol(i)) {
12252 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12253 }
12254 /* format for header fields */
12255 else {
12256 /*
12257 * If this field isn't at the head of the list of
12258 * fields with this name, skip this field - all
12259 * fields with the same name are really just versions
12260 * of the same field stored in different bits, and
12261 * should have the same type/radix/value list, and
12262 * just differ in their bit masks. (If a field isn't
12263 * a bitfield, but can be, say, 1 or 2 bytes long,
12264 * it can just be made FT_UINT16, meaning the
12265 * *maximum* length is 2 bytes, and be used
12266 * for all lengths.)
12267 */
12268 if (hfinfo->same_name_prev_id != -1)
12269 continue;
12270
12271 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", 12271
, __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", 12271
, "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", 12271
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12272
12273 enum_name = ftype_name(hfinfo->type);
12274 base_name = "";
12275
12276 if (hfinfo->type == FT_CHAR ||
12277 hfinfo->type == FT_UINT8 ||
12278 hfinfo->type == FT_UINT16 ||
12279 hfinfo->type == FT_UINT24 ||
12280 hfinfo->type == FT_UINT32 ||
12281 hfinfo->type == FT_UINT40 ||
12282 hfinfo->type == FT_UINT48 ||
12283 hfinfo->type == FT_UINT56 ||
12284 hfinfo->type == FT_UINT64 ||
12285 hfinfo->type == FT_INT8 ||
12286 hfinfo->type == FT_INT16 ||
12287 hfinfo->type == FT_INT24 ||
12288 hfinfo->type == FT_INT32 ||
12289 hfinfo->type == FT_INT40 ||
12290 hfinfo->type == FT_INT48 ||
12291 hfinfo->type == FT_INT56 ||
12292 hfinfo->type == FT_INT64) {
12293
12294 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12295 case BASE_NONE:
12296 case BASE_DEC:
12297 case BASE_HEX:
12298 case BASE_OCT:
12299 case BASE_DEC_HEX:
12300 case BASE_HEX_DEC:
12301 case BASE_CUSTOM:
12302 case BASE_PT_UDP:
12303 case BASE_PT_TCP:
12304 case BASE_PT_DCCP:
12305 case BASE_PT_SCTP:
12306 case BASE_OUI:
12307 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12308 break;
12309 default:
12310 base_name = "????";
12311 break;
12312 }
12313 } else if (hfinfo->type == FT_BOOLEAN) {
12314 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12315 snprintf(width, sizeof(width), "%d", hfinfo->display);
12316 base_name = width;
12317 }
12318
12319 blurb = hfinfo->blurb;
12320 if (blurb == NULL((void*)0))
12321 blurb = "";
12322 else if (strlen(blurb) == 0)
12323 blurb = "\"\"";
12324
12325 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12326 hfinfo->name, hfinfo->abbrev, enum_name,
12327 parent_hfinfo->abbrev, base_name,
12328 hfinfo->bitmask, blurb);
12329 }
12330 }
12331}
12332
12333/* Dumps all abbreviated field and protocol completions of the given string to
12334 * stdout. An independent program may use this for command-line tab completion
12335 * of fields.
12336 */
12337bool_Bool
12338proto_registrar_dump_field_completions(const char *prefix)
12339{
12340 header_field_info *hfinfo;
12341 int i, len;
12342 size_t prefix_len;
12343 bool_Bool matched = false0;
12344
12345 prefix_len = strlen(prefix);
12346 len = gpa_hfinfo.len;
12347 for (i = 0; i < len ; i++) {
12348 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12349 continue; /* This is a deregistered protocol or header field */
12350
12351 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", 12351
, __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", 12351
, "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", 12351, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12352
12353 /*
12354 * Skip the pseudo-field for "proto_tree_add_text()" since
12355 * we don't want it in the list of filterable fields.
12356 */
12357 if (hfinfo->id == hf_text_only)
12358 continue;
12359
12360 /* format for protocols */
12361 if (proto_registrar_is_protocol(i)) {
12362 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12363 matched = true1;
12364 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12365 }
12366 }
12367 /* format for header fields */
12368 else {
12369 /*
12370 * If this field isn't at the head of the list of
12371 * fields with this name, skip this field - all
12372 * fields with the same name are really just versions
12373 * of the same field stored in different bits, and
12374 * should have the same type/radix/value list, and
12375 * just differ in their bit masks. (If a field isn't
12376 * a bitfield, but can be, say, 1 or 2 bytes long,
12377 * it can just be made FT_UINT16, meaning the
12378 * *maximum* length is 2 bytes, and be used
12379 * for all lengths.)
12380 */
12381 if (hfinfo->same_name_prev_id != -1)
12382 continue;
12383
12384 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12385 matched = true1;
12386 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12387 }
12388 }
12389 }
12390 return matched;
12391}
12392
12393/* Dumps field types and descriptive names to stdout. An independent
12394 * program can take this output and format it into nice tables or HTML or
12395 * whatever.
12396 *
12397 * There is one record per line. The fields are tab-delimited.
12398 *
12399 * Field 1 = field type name, e.g. FT_UINT8
12400 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12401 */
12402void
12403proto_registrar_dump_ftypes(void)
12404{
12405 int fte;
12406
12407 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12408 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12409 }
12410}
12411
12412/* This function indicates whether it's possible to construct a
12413 * "match selected" display filter string for the specified field,
12414 * returns an indication of whether it's possible, and, if it's
12415 * possible and "filter" is non-null, constructs the filter and
12416 * sets "*filter" to point to it.
12417 * You do not need to [g_]free() this string since it will be automatically
12418 * freed once the next packet is dissected.
12419 */
12420static bool_Bool
12421construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12422 char **filter)
12423{
12424 const header_field_info *hfinfo;
12425 char *ptr;
12426 int buf_len;
12427 int i;
12428 int start, length, length_remaining;
12429 uint8_t c;
12430
12431 if (!finfo)
12432 return false0;
12433
12434 hfinfo = finfo->hfinfo;
12435 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12435, "hfinfo"))))
;
12436
12437 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12438 * then "the numeric value ... is not used when preparing
12439 * filters for the field in question." If it's any other
12440 * base, we'll generate the filter normally (which will
12441 * be numeric, even though the human-readable string does
12442 * work for filtering.)
12443 *
12444 * XXX - It might be nice to use fvalue_to_string_repr() in
12445 * "proto_item_fill_label()" as well, although, there, you'd
12446 * have to deal with the base *and* with resolved values for
12447 * addresses.
12448 *
12449 * Perhaps in addition to taking the repr type (DISPLAY
12450 * or DFILTER) and the display (base), fvalue_to_string_repr()
12451 * should have the the "strings" values in the header_field_info
12452 * structure for the field as a parameter, so it can have
12453 * if the field is Boolean or an enumerated integer type,
12454 * the tables used to generate human-readable values.
12455 */
12456 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12457 const char *str = NULL((void*)0);
12458
12459 switch (hfinfo->type) {
12460
12461 case FT_INT8:
12462 case FT_INT16:
12463 case FT_INT24:
12464 case FT_INT32:
12465 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12466 break;
12467
12468 case FT_CHAR:
12469 case FT_UINT8:
12470 case FT_UINT16:
12471 case FT_UINT24:
12472 case FT_UINT32:
12473 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12474 break;
12475
12476 default:
12477 break;
12478 }
12479
12480 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12481 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12482 return true1;
12483 }
12484 }
12485
12486 switch (hfinfo->type) {
12487
12488 case FT_PROTOCOL:
12489 if (filter != NULL((void*)0))
12490 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12491 break;
12492
12493 case FT_NONE:
12494 /*
12495 * If the length is 0, just match the name of the
12496 * field.
12497 *
12498 * (Also check for negative values, just in case,
12499 * as we'll cast it to an unsigned value later.)
12500 */
12501 length = finfo->length;
12502 if (length == 0) {
12503 if (filter != NULL((void*)0))
12504 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12505 break;
12506 }
12507 if (length < 0)
12508 return false0;
12509
12510 /*
12511 * This doesn't have a value, so we'd match
12512 * on the raw bytes at this address.
12513 *
12514 * Should we be allowed to access to the raw bytes?
12515 * If "edt" is NULL, the answer is "no".
12516 */
12517 if (edt == NULL((void*)0))
12518 return false0;
12519
12520 /*
12521 * Is this field part of the raw frame tvbuff?
12522 * If not, we can't use "frame[N:M]" to match
12523 * it.
12524 *
12525 * XXX - should this be frame-relative, or
12526 * protocol-relative?
12527 *
12528 * XXX - does this fallback for non-registered
12529 * fields even make sense?
12530 */
12531 if (finfo->ds_tvb != edt->tvb)
12532 return false0; /* you lose */
12533
12534 /*
12535 * Don't go past the end of that tvbuff.
12536 */
12537 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12538 if (length > length_remaining)
12539 length = length_remaining;
12540 if (length <= 0)
12541 return false0;
12542
12543 if (filter != NULL((void*)0)) {
12544 start = finfo->start;
12545 buf_len = 32 + length * 3;
12546 *filter = (char *)wmem_alloc0(NULL((void*)0), buf_len);
12547 ptr = *filter;
12548
12549 ptr += snprintf(ptr, buf_len-(ptr-*filter),
12550 "frame[%d:%d] == ", finfo->start, length);
12551 for (i=0; i<length; i++) {
12552 c = tvb_get_uint8(finfo->ds_tvb, start);
12553 start++;
12554 if (i == 0 ) {
12555 ptr += snprintf(ptr, buf_len-(ptr-*filter), "%02x", c);
12556 }
12557 else {
12558 ptr += snprintf(ptr, buf_len-(ptr-*filter), ":%02x", c);
12559 }
12560 }
12561 }
12562 break;
12563
12564 /* By default, use the fvalue's "to_string_repr" method. */
12565 default:
12566 if (filter != NULL((void*)0)) {
12567 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12568 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12569 wmem_free(NULL((void*)0), str);
12570 }
12571 break;
12572 }
12573
12574 return true1;
12575}
12576
12577/*
12578 * Returns true if we can do a "match selected" on the field, false
12579 * otherwise.
12580 */
12581bool_Bool
12582proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12583{
12584 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12585}
12586
12587/* This function attempts to construct a "match selected" display filter
12588 * string for the specified field; if it can do so, it returns a pointer
12589 * to the string, otherwise it returns NULL.
12590 *
12591 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12592 */
12593char *
12594proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12595{
12596 char *filter = NULL((void*)0);
12597
12598 if (!construct_match_selected_string(finfo, edt, &filter))
12599 {
12600 wmem_free(NULL((void*)0), filter);
12601 return NULL((void*)0);
12602 }
12603 return filter;
12604}
12605
12606/* This function is common code for all proto_tree_add_bitmask... functions.
12607 */
12608
12609static bool_Bool
12610proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12611 const int len, const int ett, int * const *fields,
12612 const int flags, bool_Bool first,
12613 bool_Bool use_parent_tree,
12614 proto_tree* tree, uint64_t value)
12615{
12616 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12617 uint64_t bitmask = 0;
12618 uint64_t tmpval;
12619 header_field_info *hf;
12620 uint32_t integer32;
12621 int bit_offset;
12622 int no_of_bits;
12623
12624 if (!*fields)
12625 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"
)
;
12626
12627 if (len < 0 || len > 8)
12628 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12629 /**
12630 * packet-frame.c uses len=0 since the value is taken from the packet
12631 * metadata, not the packet bytes. In that case, assume that all bits
12632 * in the provided value are valid.
12633 */
12634 if (len > 0) {
12635 available_bits >>= (8 - (unsigned)len)*8;
12636 }
12637
12638 if (use_parent_tree == false0)
12639 tree = proto_item_add_subtree(item, ett);
12640
12641 while (*fields) {
12642 uint64_t present_bits;
12643 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", 12643, __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", 12643
, "**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", 12643, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12644 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", 12644
, "hf->bitmask != 0", hf->abbrev))))
;
12645
12646 bitmask |= hf->bitmask;
12647
12648 /* Skip fields that aren't fully present */
12649 present_bits = available_bits & hf->bitmask;
12650 if (present_bits != hf->bitmask) {
12651 fields++;
12652 continue;
12653 }
12654
12655 switch (hf->type) {
12656 case FT_CHAR:
12657 case FT_UINT8:
12658 case FT_UINT16:
12659 case FT_UINT24:
12660 case FT_UINT32:
12661 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12662 break;
12663
12664 case FT_INT8:
12665 case FT_INT16:
12666 case FT_INT24:
12667 case FT_INT32:
12668 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12669 break;
12670
12671 case FT_UINT40:
12672 case FT_UINT48:
12673 case FT_UINT56:
12674 case FT_UINT64:
12675 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12676 break;
12677
12678 case FT_INT40:
12679 case FT_INT48:
12680 case FT_INT56:
12681 case FT_INT64:
12682 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12683 break;
12684
12685 case FT_BOOLEAN:
12686 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12687 break;
12688
12689 default:
12690 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))
12691 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))
12692 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))
12693 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))
;
12694 break;
12695 }
12696 if (flags & BMT_NO_APPEND0x01) {
12697 fields++;
12698 continue;
12699 }
12700 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12701
12702 /* XXX: README.developer and the comments have always defined
12703 * BMT_NO_INT as "only boolean flags are added to the title /
12704 * don't add non-boolean (integral) fields", but the
12705 * implementation has always added BASE_CUSTOM and fields with
12706 * value_strings, though not fields with unit_strings.
12707 * Possibly this is because some dissectors use a FT_UINT8
12708 * with a value_string for fields that should be a FT_BOOLEAN.
12709 */
12710 switch (hf->type) {
12711 case FT_CHAR:
12712 if (hf->display == BASE_CUSTOM) {
12713 char lbl[ITEM_LABEL_LENGTH240];
12714 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12715
12716 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12716, "fmtfunc"))))
;
12717 fmtfunc(lbl, (uint32_t) tmpval);
12718 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12719 hf->name, lbl);
12720 first = false0;
12721 }
12722 else if (hf->strings) {
12723 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12724 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12725 first = false0;
12726 }
12727 else if (!(flags & BMT_NO_INT0x02)) {
12728 char buf[32];
12729 const char *out;
12730
12731 if (!first) {
12732 proto_item_append_text(item, ", ");
12733 }
12734
12735 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12736 proto_item_append_text(item, "%s: %s", hf->name, out);
12737 first = false0;
12738 }
12739
12740 break;
12741
12742 case FT_UINT8:
12743 case FT_UINT16:
12744 case FT_UINT24:
12745 case FT_UINT32:
12746 if (hf->display == BASE_CUSTOM) {
12747 char lbl[ITEM_LABEL_LENGTH240];
12748 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12749
12750 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12750, "fmtfunc"))))
;
12751 fmtfunc(lbl, (uint32_t) tmpval);
12752 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12753 hf->name, lbl);
12754 first = false0;
12755 }
12756 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12757 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12758 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12759 first = false0;
12760 }
12761 else if (!(flags & BMT_NO_INT0x02)) {
12762 char buf[NUMBER_LABEL_LENGTH80];
12763 const char *out = NULL((void*)0);
12764
12765 if (!first) {
12766 proto_item_append_text(item, ", ");
12767 }
12768
12769 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12770 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12771 }
12772 if (out == NULL((void*)0)) {
12773 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12774 }
12775 proto_item_append_text(item, "%s: %s", hf->name, out);
12776 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12777 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12778 }
12779 first = false0;
12780 }
12781
12782 break;
12783
12784 case FT_INT8:
12785 case FT_INT16:
12786 case FT_INT24:
12787 case FT_INT32:
12788 integer32 = (uint32_t) tmpval;
12789 if (hf->bitmask) {
12790 no_of_bits = ws_count_ones(hf->bitmask);
12791 integer32 = ws_sign_ext32(integer32, no_of_bits);
12792 }
12793 if (hf->display == BASE_CUSTOM) {
12794 char lbl[ITEM_LABEL_LENGTH240];
12795 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12796
12797 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12797, "fmtfunc"))))
;
12798 fmtfunc(lbl, (int32_t) integer32);
12799 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12800 hf->name, lbl);
12801 first = false0;
12802 }
12803 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12804 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12805 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12806 first = false0;
12807 }
12808 else if (!(flags & BMT_NO_INT0x02)) {
12809 char buf[NUMBER_LABEL_LENGTH80];
12810 const char *out = NULL((void*)0);
12811
12812 if (!first) {
12813 proto_item_append_text(item, ", ");
12814 }
12815
12816 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12817 out = hf_try_val_to_str((int32_t) integer32, hf);
12818 }
12819 if (out == NULL((void*)0)) {
12820 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12821 }
12822 proto_item_append_text(item, "%s: %s", hf->name, out);
12823 if (hf->display & BASE_UNIT_STRING0x00001000) {
12824 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12825 }
12826 first = false0;
12827 }
12828
12829 break;
12830
12831 case FT_UINT40:
12832 case FT_UINT48:
12833 case FT_UINT56:
12834 case FT_UINT64:
12835 if (hf->display == BASE_CUSTOM) {
12836 char lbl[ITEM_LABEL_LENGTH240];
12837 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12838
12839 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12839, "fmtfunc"))))
;
12840 fmtfunc(lbl, tmpval);
12841 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12842 hf->name, lbl);
12843 first = false0;
12844 }
12845 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12846 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12847 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12848 first = false0;
12849 }
12850 else if (!(flags & BMT_NO_INT0x02)) {
12851 char buf[NUMBER_LABEL_LENGTH80];
12852 const char *out = NULL((void*)0);
12853
12854 if (!first) {
12855 proto_item_append_text(item, ", ");
12856 }
12857
12858 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12859 out = hf_try_val64_to_str(tmpval, hf);
12860 }
12861 if (out == NULL((void*)0)) {
12862 out = hfinfo_number_value_format64(hf, buf, tmpval);
12863 }
12864 proto_item_append_text(item, "%s: %s", hf->name, out);
12865 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12866 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12867 }
12868 first = false0;
12869 }
12870
12871 break;
12872
12873 case FT_INT40:
12874 case FT_INT48:
12875 case FT_INT56:
12876 case FT_INT64:
12877 if (hf->bitmask) {
12878 no_of_bits = ws_count_ones(hf->bitmask);
12879 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12880 }
12881 if (hf->display == BASE_CUSTOM) {
12882 char lbl[ITEM_LABEL_LENGTH240];
12883 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12884
12885 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12885, "fmtfunc"))))
;
12886 fmtfunc(lbl, (int64_t) tmpval);
12887 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12888 hf->name, lbl);
12889 first = false0;
12890 }
12891 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12892 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12893 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12894 first = false0;
12895 }
12896 else if (!(flags & BMT_NO_INT0x02)) {
12897 char buf[NUMBER_LABEL_LENGTH80];
12898 const char *out = NULL((void*)0);
12899
12900 if (!first) {
12901 proto_item_append_text(item, ", ");
12902 }
12903
12904 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12905 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12906 }
12907 if (out == NULL((void*)0)) {
12908 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12909 }
12910 proto_item_append_text(item, "%s: %s", hf->name, out);
12911 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12912 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12913 }
12914 first = false0;
12915 }
12916
12917 break;
12918
12919 case FT_BOOLEAN:
12920 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12921 /* If we have true/false strings, emit full - otherwise messages
12922 might look weird */
12923 const struct true_false_string *tfs =
12924 (const struct true_false_string *)hf->strings;
12925
12926 if (tmpval) {
12927 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12928 hf->name, tfs->true_string);
12929 first = false0;
12930 } else if (!(flags & BMT_NO_FALSE0x04)) {
12931 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12932 hf->name, tfs->false_string);
12933 first = false0;
12934 }
12935 } else if (hf->bitmask & value) {
12936 /* If the flag is set, show the name */
12937 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
12938 first = false0;
12939 }
12940 break;
12941 default:
12942 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))
12943 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))
12944 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))
12945 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))
;
12946 break;
12947 }
12948
12949 fields++;
12950 }
12951
12952 /* XXX: We don't pass the hfi into this function. Perhaps we should,
12953 * but then again most dissectors don't set the bitmask field for
12954 * the higher level bitmask hfi, so calculate the bitmask from the
12955 * fields present. */
12956 if (item) {
12957 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
12958 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
12959 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)
;
12960 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)
;
12961 }
12962 return first;
12963}
12964
12965/* This function will dissect a sequence of bytes that describe a
12966 * bitmask and supply the value of that sequence through a pointer.
12967 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12968 * to be dissected.
12969 * This field will form an expansion under which the individual fields of the
12970 * bitmask is dissected and displayed.
12971 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12972 *
12973 * fields is an array of pointers to int that lists all the fields of the
12974 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12975 * or another integer of the same type/size as hf_hdr with a mask specified.
12976 * This array is terminated by a NULL entry.
12977 *
12978 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
12979 * FT_integer fields that have a value_string attached will have the
12980 * matched string displayed on the expansion line.
12981 */
12982proto_item *
12983proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
12984 const unsigned offset, const int hf_hdr,
12985 const int ett, int * const *fields,
12986 const unsigned encoding, uint64_t *retval)
12987{
12988 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);
12989}
12990
12991/* This function will dissect a sequence of bytes that describe a
12992 * bitmask.
12993 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12994 * to be dissected.
12995 * This field will form an expansion under which the individual fields of the
12996 * bitmask is dissected and displayed.
12997 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12998 *
12999 * fields is an array of pointers to int that lists all the fields of the
13000 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13001 * or another integer of the same type/size as hf_hdr with a mask specified.
13002 * This array is terminated by a NULL entry.
13003 *
13004 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13005 * FT_integer fields that have a value_string attached will have the
13006 * matched string displayed on the expansion line.
13007 */
13008proto_item *
13009proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13010 const unsigned offset, const int hf_hdr,
13011 const int ett, int * const *fields,
13012 const unsigned encoding)
13013{
13014 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13015}
13016
13017/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13018 * what data is appended to the header.
13019 */
13020proto_item *
13021proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13022 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13023 uint64_t *retval)
13024{
13025 proto_item *item = NULL((void*)0);
13026 header_field_info *hf;
13027 int len;
13028 uint64_t value;
13029
13030 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", 13030, __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", 13030
, "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", 13030, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13031 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", 13031, (hf)->abbrev)))
;
13032 len = ftype_wire_size(hf->type);
13033 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13034
13035 if (parent_tree) {
13036 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13037 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13038 flags, false0, false0, NULL((void*)0), value);
13039 }
13040
13041 *retval = value;
13042 if (hf->bitmask) {
13043 /* Mask out irrelevant portions */
13044 *retval &= hf->bitmask;
13045 /* Shift bits */
13046 *retval >>= hfinfo_bitshift(hf);
13047 }
13048
13049 return item;
13050}
13051
13052/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13053 * what data is appended to the header.
13054 */
13055proto_item *
13056proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13057 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13058{
13059 proto_item *item = NULL((void*)0);
13060 header_field_info *hf;
13061 int len;
13062 uint64_t value;
13063
13064 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", 13064, __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", 13064
, "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", 13064, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13065 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", 13065, (hf)->abbrev)))
;
13066
13067 if (parent_tree) {
13068 len = ftype_wire_size(hf->type);
13069 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13070 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13071 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13072 flags, false0, false0, NULL((void*)0), value);
13073 }
13074
13075 return item;
13076}
13077
13078/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13079 can't be retrieved directly from tvb) */
13080proto_item *
13081proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13082 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13083{
13084 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13085 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13086}
13087
13088/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13089WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13090proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13091 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13092{
13093 proto_item *item = NULL((void*)0);
13094 header_field_info *hf;
13095 int len;
13096
13097 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", 13097, __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", 13097
, "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", 13097, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13098 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", 13098, (hf)->abbrev)))
;
13099 /* the proto_tree_add_uint/_uint64() calls below
13100 will fail if tvb==NULL and len!=0 */
13101 len = tvb ? ftype_wire_size(hf->type) : 0;
13102
13103 if (parent_tree) {
13104 if (len <= 4)
13105 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13106 else
13107 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13108
13109 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13110 flags, false0, false0, NULL((void*)0), value);
13111 }
13112
13113 return item;
13114}
13115
13116/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13117void
13118proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13119 const int len, int * const *fields, const unsigned encoding)
13120{
13121 uint64_t value;
13122
13123 if (tree) {
13124 value = get_uint64_value(tree, tvb, offset, len, encoding);
13125 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13126 BMT_NO_APPEND0x01, false0, true1, tree, value);
13127 }
13128}
13129
13130WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13131proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13132 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13133{
13134 uint64_t value;
13135
13136 value = get_uint64_value(tree, tvb, offset, len, encoding);
13137 if (tree) {
13138 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13139 BMT_NO_APPEND0x01, false0, true1, tree, value);
13140 }
13141 if (retval) {
13142 *retval = value;
13143 }
13144}
13145
13146WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13147proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13148 const int len, int * const *fields, const uint64_t value)
13149{
13150 if (tree) {
13151 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13152 BMT_NO_APPEND0x01, false0, true1, tree, value);
13153 }
13154}
13155
13156
13157/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13158 * This is intended to support bitmask fields whose lengths can vary, perhaps
13159 * as the underlying standard evolves over time.
13160 * With this API there is the possibility of being called to display more or
13161 * less data than the dissector was coded to support.
13162 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13163 * Thus when presented with "too much" or "too little" data, MSbits will be
13164 * ignored or MSfields sacrificed.
13165 *
13166 * Only fields for which all defined bits are available are displayed.
13167 */
13168proto_item *
13169proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13170 const unsigned offset, const unsigned len, const int hf_hdr,
13171 const int ett, int * const *fields, struct expert_field* exp,
13172 const unsigned encoding)
13173{
13174 proto_item *item = NULL((void*)0);
13175 header_field_info *hf;
13176 unsigned decodable_len;
13177 unsigned decodable_offset;
13178 uint32_t decodable_value;
13179 uint64_t value;
13180
13181 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", 13181, __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", 13181
, "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", 13181, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13182 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", 13182, (hf)->abbrev)))
;
13183
13184 decodable_offset = offset;
13185 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13186
13187 /* If we are ftype_wire_size-limited,
13188 * make sure we decode as many LSBs as possible.
13189 */
13190 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13191 decodable_offset += (len - decodable_len);
13192 }
13193
13194 if (parent_tree) {
13195 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13196 decodable_len, encoding);
13197
13198 /* The root item covers all the bytes even if we can't decode them all */
13199 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13200 decodable_value);
13201 }
13202
13203 if (decodable_len < len) {
13204 /* Dissector likely requires updating for new protocol revision */
13205 expert_add_info_format(NULL((void*)0), item, exp,
13206 "Only least-significant %d of %d bytes decoded",
13207 decodable_len, len);
13208 }
13209
13210 if (item) {
13211 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13212 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13213 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13214 }
13215
13216 return item;
13217}
13218
13219/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13220proto_item *
13221proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13222 const unsigned offset, const unsigned len,
13223 const char *name, const char *fallback,
13224 const int ett, int * const *fields,
13225 const unsigned encoding, const int flags)
13226{
13227 proto_item *item = NULL((void*)0);
13228 uint64_t value;
13229
13230 if (parent_tree) {
13231 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13232 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13233 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13234 flags, true1, false0, NULL((void*)0), value) && fallback) {
13235 /* Still at first item - append 'fallback' text if any */
13236 proto_item_append_text(item, "%s", fallback);
13237 }
13238 }
13239
13240 return item;
13241}
13242
13243proto_item *
13244proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13245 const unsigned bit_offset, const int no_of_bits,
13246 const unsigned encoding)
13247{
13248 header_field_info *hfinfo;
13249 int octet_length;
13250 int octet_offset;
13251
13252 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", 13252, __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", 13252
, "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", 13252, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13253
13254 if (no_of_bits < 0) {
13255 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13256 }
13257 octet_length = (no_of_bits + 7) >> 3;
13258 octet_offset = bit_offset >> 3;
13259 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13260
13261 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13262 * but only after doing a bunch more work (which we can, in the common
13263 * case, shortcut here).
13264 */
13265 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13266 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", 13266
, __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", 13266, "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", 13266, "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", 13266, __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)
; } } }
;
13267
13268 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13269}
13270
13271/*
13272 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13273 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13274 * Offset should be given in bits from the start of the tvb.
13275 */
13276
13277static proto_item *
13278_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13279 const unsigned bit_offset, const int no_of_bits,
13280 uint64_t *return_value, const unsigned encoding)
13281{
13282 int offset;
13283 unsigned length;
13284 uint8_t tot_no_bits;
13285 char *bf_str;
13286 char lbl_str[ITEM_LABEL_LENGTH240];
13287 uint64_t value = 0;
13288 uint8_t *bytes = NULL((void*)0);
13289 size_t bytes_length = 0;
13290
13291 proto_item *pi;
13292 header_field_info *hf_field;
13293
13294 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13295 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", 13295, __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", 13295
, "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", 13295, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13296
13297 if (hf_field->bitmask != 0) {
13298 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)
13299 " 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)
13300 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)
;
13301 }
13302
13303 if (no_of_bits < 0) {
13304 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13305 } else if (no_of_bits == 0) {
13306 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)
13307 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)
;
13308 }
13309
13310 /* Byte align offset */
13311 offset = bit_offset>>3;
13312
13313 /*
13314 * Calculate the number of octets used to hold the bits
13315 */
13316 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13317 length = (tot_no_bits + 7) >> 3;
13318
13319 if (no_of_bits < 65) {
13320 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13321 } else if (hf_field->type != FT_BYTES) {
13322 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)
13323 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)
;
13324 return NULL((void*)0);
13325 }
13326
13327 /* Sign extend for signed types */
13328 switch (hf_field->type) {
13329 case FT_INT8:
13330 case FT_INT16:
13331 case FT_INT24:
13332 case FT_INT32:
13333 case FT_INT40:
13334 case FT_INT48:
13335 case FT_INT56:
13336 case FT_INT64:
13337 value = ws_sign_ext64(value, no_of_bits);
13338 break;
13339
13340 default:
13341 break;
13342 }
13343
13344 if (return_value) {
13345 *return_value = value;
13346 }
13347
13348 /* Coast clear. Try and fake it */
13349 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13350 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", 13350
, __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", 13350, "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", 13350, "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", 13350, __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); } } }
;
13351
13352 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13353
13354 switch (hf_field->type) {
13355 case FT_BOOLEAN:
13356 /* Boolean field */
13357 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13358 "%s = %s: %s",
13359 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13360 break;
13361
13362 case FT_CHAR:
13363 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13364 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13365 break;
13366
13367 case FT_UINT8:
13368 case FT_UINT16:
13369 case FT_UINT24:
13370 case FT_UINT32:
13371 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13372 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13373 break;
13374
13375 case FT_INT8:
13376 case FT_INT16:
13377 case FT_INT24:
13378 case FT_INT32:
13379 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13380 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13381 break;
13382
13383 case FT_UINT40:
13384 case FT_UINT48:
13385 case FT_UINT56:
13386 case FT_UINT64:
13387 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13388 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13389 break;
13390
13391 case FT_INT40:
13392 case FT_INT48:
13393 case FT_INT56:
13394 case FT_INT64:
13395 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13396 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13397 break;
13398
13399 case FT_BYTES:
13400 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13401 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13402 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13403 proto_item_set_text(pi, "%s", lbl_str);
13404 return pi;
13405
13406 /* TODO: should handle FT_UINT_BYTES ? */
13407
13408 default:
13409 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))
13410 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))
13411 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))
13412 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))
;
13413 return NULL((void*)0);
13414 }
13415
13416 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13417 return pi;
13418}
13419
13420proto_item *
13421proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13422 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13423 uint64_t *return_value)
13424{
13425 proto_item *pi;
13426 int no_of_bits;
13427 int octet_offset;
13428 unsigned mask_initial_bit_offset;
13429 unsigned mask_greatest_bit_offset;
13430 unsigned octet_length;
13431 uint8_t i;
13432 char bf_str[256];
13433 char lbl_str[ITEM_LABEL_LENGTH240];
13434 uint64_t value;
13435 uint64_t composite_bitmask;
13436 uint64_t composite_bitmap;
13437
13438 header_field_info *hf_field;
13439
13440 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13441 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", 13441, __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", 13441
, "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", 13441, "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
13442
13443 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13444 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)
13445 " 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)
13446 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)
;
13447 }
13448
13449 mask_initial_bit_offset = bit_offset % 8;
13450
13451 no_of_bits = 0;
13452 value = 0;
13453 i = 0;
13454 mask_greatest_bit_offset = 0;
13455 composite_bitmask = 0;
13456 composite_bitmap = 0;
13457
13458 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
13459 uint64_t crumb_mask, crumb_value;
13460 uint8_t crumb_end_bit_offset;
13461
13462 crumb_value = tvb_get_bits64(tvb,
13463 bit_offset + crumb_spec[i].crumb_bit_offset,
13464 crumb_spec[i].crumb_bit_length,
13465 ENC_BIG_ENDIAN0x00000000);
13466 value += crumb_value;
13467 no_of_bits += crumb_spec[i].crumb_bit_length;
13468 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", 13468
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13469
13470 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13471 octet containing the initial offset.
13472 If the mask is beyond 32 bits, then give up on bit map display.
13473 This could be improved in future, probably showing a table
13474 of 32 or 64 bits per row */
13475 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13476 crumb_end_bit_offset = mask_initial_bit_offset
13477 + crumb_spec[i].crumb_bit_offset
13478 + crumb_spec[i].crumb_bit_length;
13479 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'
13480
13481 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13482 mask_greatest_bit_offset = crumb_end_bit_offset;
13483 }
13484 /* Currently the bitmap of the crumbs are only shown if
13485 * smaller than 32 bits. Do not bother calculating the
13486 * mask if it is larger than that. */
13487 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13488 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'
13489 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13490 }
13491 }
13492 /* Shift left for the next segment */
13493 value <<= crumb_spec[++i].crumb_bit_length;
13494 }
13495
13496 /* Sign extend for signed types */
13497 switch (hf_field->type) {
13498 case FT_INT8:
13499 case FT_INT16:
13500 case FT_INT24:
13501 case FT_INT32:
13502 case FT_INT40:
13503 case FT_INT48:
13504 case FT_INT56:
13505 case FT_INT64:
13506 value = ws_sign_ext64(value, no_of_bits);
13507 break;
13508 default:
13509 break;
13510 }
13511
13512 if (return_value) {
13513 *return_value = value;
13514 }
13515
13516 /* Coast clear. Try and fake it */
13517 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13518 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", 13518
, __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", 13518, "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", 13518, "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", 13518, __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); } } }
;
13519
13520 /* initialise the format string */
13521 bf_str[0] = '\0';
13522
13523 octet_offset = bit_offset >> 3;
13524
13525 /* Round up mask length to nearest octet */
13526 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13527 mask_greatest_bit_offset = octet_length << 3;
13528
13529 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13530 It would be a useful enhancement to eliminate this restriction. */
13531 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13532 other_decode_bitfield_value(bf_str,
13533 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13534 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13535 mask_greatest_bit_offset);
13536 } else {
13537 /* If the bitmask is too large, try to describe its contents. */
13538 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13539 }
13540
13541 switch (hf_field->type) {
13542 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13543 /* Boolean field */
13544 return proto_tree_add_boolean_format(tree, hfindex,
13545 tvb, octet_offset, octet_length, value,
13546 "%s = %s: %s",
13547 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13548 break;
13549
13550 case FT_CHAR:
13551 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13552 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13553 break;
13554
13555 case FT_UINT8:
13556 case FT_UINT16:
13557 case FT_UINT24:
13558 case FT_UINT32:
13559 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13560 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13561 break;
13562
13563 case FT_INT8:
13564 case FT_INT16:
13565 case FT_INT24:
13566 case FT_INT32:
13567 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13568 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13569 break;
13570
13571 case FT_UINT40:
13572 case FT_UINT48:
13573 case FT_UINT56:
13574 case FT_UINT64:
13575 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13576 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13577 break;
13578
13579 case FT_INT40:
13580 case FT_INT48:
13581 case FT_INT56:
13582 case FT_INT64:
13583 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13584 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13585 break;
13586
13587 default:
13588 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))
13589 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))
13590 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))
13591 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))
;
13592 return NULL((void*)0);
13593 }
13594 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13595 return pi;
13596}
13597
13598void
13599proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13600 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13601{
13602 header_field_info *hfinfo;
13603 int start = bit_offset >> 3;
13604 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13605
13606 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13607 * so that we can use the tree's memory scope in calculating the string */
13608 if (length == -1) {
13609 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13610 } else {
13611 tvb_ensure_bytes_exist(tvb, start, length);
13612 }
13613 if (!tree) return;
13614
13615 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", 13615, __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", 13615
, "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", 13615, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13616 proto_tree_add_text_internal(tree, tvb, start, length,
13617 "%s crumb %d of %s (decoded above)",
13618 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13619 tvb_get_bits32(tvb,
13620 bit_offset,
13621 crumb_spec[crumb_index].crumb_bit_length,
13622 ENC_BIG_ENDIAN0x00000000),
13623 ENC_BIG_ENDIAN0x00000000),
13624 crumb_index,
13625 hfinfo->name);
13626}
13627
13628proto_item *
13629proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13630 const unsigned bit_offset, const int no_of_bits,
13631 uint64_t *return_value, const unsigned encoding)
13632{
13633 proto_item *item;
13634
13635 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13636 bit_offset, no_of_bits,
13637 return_value, encoding))) {
13638 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)
;
13639 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)
;
13640 }
13641 return item;
13642}
13643
13644static proto_item *
13645_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13646 tvbuff_t *tvb, const unsigned bit_offset,
13647 const int no_of_bits, void *value_ptr,
13648 const unsigned encoding, char *value_str)
13649{
13650 int offset;
13651 unsigned length;
13652 uint8_t tot_no_bits;
13653 char *str;
13654 uint64_t value = 0;
13655 header_field_info *hf_field;
13656
13657 /* We do not have to return a value, try to fake it as soon as possible */
13658 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13659 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", 13659
, __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", 13659, "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", 13659, "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", 13659, __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); } } }
;
13660
13661 if (hf_field->bitmask != 0) {
13662 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)
13663 " 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)
13664 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)
;
13665 }
13666
13667 if (no_of_bits < 0) {
13668 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13669 } else if (no_of_bits == 0) {
13670 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)
13671 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)
;
13672 }
13673
13674 /* Byte align offset */
13675 offset = bit_offset>>3;
13676
13677 /*
13678 * Calculate the number of octets used to hold the bits
13679 */
13680 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13681 length = tot_no_bits>>3;
13682 /* If we are using part of the next octet, increase length by 1 */
13683 if (tot_no_bits & 0x07)
13684 length++;
13685
13686 if (no_of_bits < 65) {
13687 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13688 } else {
13689 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)
13690 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)
;
13691 return NULL((void*)0);
13692 }
13693
13694 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13695
13696 (void) g_strlcat(str, " = ", 256+64);
13697 (void) g_strlcat(str, hf_field->name, 256+64);
13698
13699 /*
13700 * This function does not receive an actual value but a dimensionless pointer to that value.
13701 * For this reason, the type of the header field is examined in order to determine
13702 * what kind of value we should read from this address.
13703 * The caller of this function must make sure that for the specific header field type the address of
13704 * a compatible value is provided.
13705 */
13706 switch (hf_field->type) {
13707 case FT_BOOLEAN:
13708 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13709 "%s: %s", str, value_str);
13710 break;
13711
13712 case FT_CHAR:
13713 case FT_UINT8:
13714 case FT_UINT16:
13715 case FT_UINT24:
13716 case FT_UINT32:
13717 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13718 "%s: %s", str, value_str);
13719 break;
13720
13721 case FT_UINT40:
13722 case FT_UINT48:
13723 case FT_UINT56:
13724 case FT_UINT64:
13725 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13726 "%s: %s", str, value_str);
13727 break;
13728
13729 case FT_INT8:
13730 case FT_INT16:
13731 case FT_INT24:
13732 case FT_INT32:
13733 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13734 "%s: %s", str, value_str);
13735 break;
13736
13737 case FT_INT40:
13738 case FT_INT48:
13739 case FT_INT56:
13740 case FT_INT64:
13741 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13742 "%s: %s", str, value_str);
13743 break;
13744
13745 case FT_FLOAT:
13746 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13747 "%s: %s", str, value_str);
13748 break;
13749
13750 default:
13751 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))
13752 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))
13753 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))
13754 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))
;
13755 return NULL((void*)0);
13756 }
13757}
13758
13759static proto_item *
13760proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13761 tvbuff_t *tvb, const unsigned bit_offset,
13762 const int no_of_bits, void *value_ptr,
13763 const unsigned encoding, char *value_str)
13764{
13765 proto_item *item;
13766
13767 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13768 tvb, bit_offset, no_of_bits,
13769 value_ptr, encoding, value_str))) {
13770 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)
;
13771 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)
;
13772 }
13773 return item;
13774}
13775
13776#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);
\
13777 va_start(ap, format)__builtin_va_start(ap, format); \
13778 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13779 va_end(ap)__builtin_va_end(ap);
13780
13781proto_item *
13782proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13783 tvbuff_t *tvb, const unsigned bit_offset,
13784 const int no_of_bits, uint32_t value,
13785 const unsigned encoding,
13786 const char *format, ...)
13787{
13788 va_list ap;
13789 char *dst;
13790 header_field_info *hf_field;
13791
13792 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13793
13794 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", 13794
, __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", 13794, "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", 13794, "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", 13794, __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); } } }
;
13795
13796 switch (hf_field->type) {
13797 case FT_UINT8:
13798 case FT_UINT16:
13799 case FT_UINT24:
13800 case FT_UINT32:
13801 break;
13802
13803 default:
13804 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)
13805 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)
;
13806 return NULL((void*)0);
13807 }
13808
13809 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);
;
13810
13811 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13812}
13813
13814proto_item *
13815proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13816 tvbuff_t *tvb, const unsigned bit_offset,
13817 const int no_of_bits, uint64_t value,
13818 const unsigned encoding,
13819 const char *format, ...)
13820{
13821 va_list ap;
13822 char *dst;
13823 header_field_info *hf_field;
13824
13825 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13826
13827 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", 13827
, __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", 13827, "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", 13827, "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", 13827, __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); } } }
;
13828
13829 switch (hf_field->type) {
13830 case FT_UINT40:
13831 case FT_UINT48:
13832 case FT_UINT56:
13833 case FT_UINT64:
13834 break;
13835
13836 default:
13837 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)
13838 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)
;
13839 return NULL((void*)0);
13840 }
13841
13842 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);
;
13843
13844 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13845}
13846
13847proto_item *
13848proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13849 tvbuff_t *tvb, const unsigned bit_offset,
13850 const int no_of_bits, float value,
13851 const unsigned encoding,
13852 const char *format, ...)
13853{
13854 va_list ap;
13855 char *dst;
13856 header_field_info *hf_field;
13857
13858 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13859
13860 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", 13860
, __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", 13860, "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", 13860, "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", 13860, __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); } } }
;
13861
13862 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",
13862, ((hf_field))->abbrev))))
;
13863
13864 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);
;
13865
13866 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13867}
13868
13869proto_item *
13870proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13871 tvbuff_t *tvb, const unsigned bit_offset,
13872 const int no_of_bits, int32_t value,
13873 const unsigned encoding,
13874 const char *format, ...)
13875{
13876 va_list ap;
13877 char *dst;
13878 header_field_info *hf_field;
13879
13880 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13881
13882 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", 13882
, __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", 13882, "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", 13882, "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", 13882, __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); } } }
;
13883
13884 switch (hf_field->type) {
13885 case FT_INT8:
13886 case FT_INT16:
13887 case FT_INT24:
13888 case FT_INT32:
13889 break;
13890
13891 default:
13892 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)
13893 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)
;
13894 return NULL((void*)0);
13895 }
13896
13897 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);
;
13898
13899 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13900}
13901
13902proto_item *
13903proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13904 tvbuff_t *tvb, const unsigned bit_offset,
13905 const int no_of_bits, int64_t value,
13906 const unsigned encoding,
13907 const char *format, ...)
13908{
13909 va_list ap;
13910 char *dst;
13911 header_field_info *hf_field;
13912
13913 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13914
13915 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", 13915
, __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", 13915, "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", 13915, "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", 13915, __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); } } }
;
13916
13917 switch (hf_field->type) {
13918 case FT_INT40:
13919 case FT_INT48:
13920 case FT_INT56:
13921 case FT_INT64:
13922 break;
13923
13924 default:
13925 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)
13926 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)
;
13927 return NULL((void*)0);
13928 }
13929
13930 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);
;
13931
13932 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13933}
13934
13935proto_item *
13936proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
13937 tvbuff_t *tvb, const unsigned bit_offset,
13938 const int no_of_bits, uint64_t value,
13939 const unsigned encoding,
13940 const char *format, ...)
13941{
13942 va_list ap;
13943 char *dst;
13944 header_field_info *hf_field;
13945
13946 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13947
13948 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", 13948
, __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", 13948, "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", 13948, "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", 13948, __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); } } }
;
13949
13950 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"
, 13950, ((hf_field))->abbrev))))
;
13951
13952 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);
;
13953
13954 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13955}
13956
13957proto_item *
13958proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13959 const unsigned bit_offset, const int no_of_chars)
13960{
13961 proto_item *pi;
13962 header_field_info *hfinfo;
13963 int byte_length;
13964 int byte_offset;
13965 char *string;
13966
13967 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13968
13969 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", 13969
, __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", 13969, "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", 13969, "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", 13969, __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)
; } } }
;
13970
13971 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"
, 13971, ((hfinfo))->abbrev))))
;
13972
13973 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13974 byte_offset = bit_offset >> 3;
13975
13976 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
13977
13978 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
13979 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 13979, "byte_length >= 0"
))))
;
13980 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
13981
13982 return pi;
13983}
13984
13985proto_item *
13986proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13987 const unsigned bit_offset, const int no_of_chars)
13988{
13989 proto_item *pi;
13990 header_field_info *hfinfo;
13991 int byte_length;
13992 int byte_offset;
13993 char *string;
13994
13995 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13996
13997 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", 13997
, __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", 13997, "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", 13997, "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", 13997, __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)
; } } }
;
13998
13999 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"
, 13999, ((hfinfo))->abbrev))))
;
14000
14001 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14002 byte_offset = bit_offset >> 3;
14003
14004 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14005
14006 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14007 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14007, "byte_length >= 0"
))))
;
14008 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14009
14010 return pi;
14011}
14012
14013const value_string proto_checksum_vals[] = {
14014 { PROTO_CHECKSUM_E_BAD, "Bad" },
14015 { PROTO_CHECKSUM_E_GOOD, "Good" },
14016 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14017 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14018 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14019
14020 { 0, NULL((void*)0) }
14021};
14022
14023proto_item *
14024proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14025 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14026 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14027{
14028 header_field_info *hfinfo;
14029 uint32_t checksum;
14030 uint32_t len;
14031 proto_item* ti = NULL((void*)0);
14032 proto_item* ti2;
14033 bool_Bool incorrect_checksum = true1;
14034
14035 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", 14035, __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", 14035
, "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", 14035, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14036
14037 switch (hfinfo->type) {
14038 case FT_UINT8:
14039 len = 1;
14040 break;
14041 case FT_UINT16:
14042 len = 2;
14043 break;
14044 case FT_UINT24:
14045 len = 3;
14046 break;
14047 case FT_UINT32:
14048 len = 4;
14049 break;
14050 default:
14051 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)
14052 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14053 }
14054
14055 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14056 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14057 proto_item_set_generated(ti);
14058 if (hf_checksum_status != -1) {
14059 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14060 proto_item_set_generated(ti2);
14061 }
14062 return ti;
14063 }
14064
14065 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14066 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14067 proto_item_set_generated(ti);
14068 } else {
14069 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14070 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14071 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14072 if (computed_checksum == 0) {
14073 proto_item_append_text(ti, " [correct]");
14074 if (hf_checksum_status != -1) {
14075 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14076 proto_item_set_generated(ti2);
14077 }
14078 incorrect_checksum = false0;
14079 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14080 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14081 /* XXX - This can't distinguish between "shouldbe"
14082 * 0x0000 and 0xFFFF unless we know whether there
14083 * were any nonzero bits (other than the checksum).
14084 * Protocols should not use this path if they might
14085 * have an all zero packet.
14086 * Some implementations put the wrong zero; maybe
14087 * we should have a special expert info for that?
14088 */
14089 }
14090 } else {
14091 if (checksum == computed_checksum) {
14092 proto_item_append_text(ti, " [correct]");
14093 if (hf_checksum_status != -1) {
14094 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14095 proto_item_set_generated(ti2);
14096 }
14097 incorrect_checksum = false0;
14098 }
14099 }
14100
14101 if (incorrect_checksum) {
14102 if (hf_checksum_status != -1) {
14103 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14104 proto_item_set_generated(ti2);
14105 }
14106 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14107 proto_item_append_text(ti, " [incorrect]");
14108 if (bad_checksum_expert != NULL((void*)0))
14109 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14110 } else {
14111 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14112 if (bad_checksum_expert != NULL((void*)0))
14113 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);
14114 }
14115 }
14116 } else {
14117 if (hf_checksum_status != -1) {
14118 proto_item_append_text(ti, " [unverified]");
14119 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14120 proto_item_set_generated(ti2);
14121 }
14122 }
14123 }
14124
14125 return ti;
14126}
14127
14128proto_item *
14129proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14130 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14131 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14132{
14133 header_field_info *hfinfo;
14134 uint8_t *checksum = NULL((void*)0);
14135 proto_item* ti = NULL((void*)0);
14136 proto_item* ti2;
14137 bool_Bool incorrect_checksum = true1;
14138
14139 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", 14139, __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", 14139
, "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", 14139, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14140
14141 if (hfinfo->type != FT_BYTES) {
14142 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)
14143 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
14144 }
14145
14146 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14147 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14148 proto_item_set_generated(ti);
14149 if (hf_checksum_status != -1) {
14150 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14151 proto_item_set_generated(ti2);
14152 }
14153 return ti;
14154 }
14155
14156 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14157 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14158 proto_item_set_generated(ti);
14159 } else {
14160 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
))))))
;
14161 tvb_memcpy(tvb, checksum, offset, checksum_len);
14162 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14163 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14164 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14165 if (computed_checksum == 0) {
14166 proto_item_append_text(ti, " [correct]");
14167 if (hf_checksum_status != -1) {
14168 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14169 proto_item_set_generated(ti2);
14170 }
14171 incorrect_checksum = false0;
14172 }
14173 } else {
14174 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14175 proto_item_append_text(ti, " [correct]");
14176 if (hf_checksum_status != -1) {
14177 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14178 proto_item_set_generated(ti2);
14179 }
14180 incorrect_checksum = false0;
14181 }
14182 }
14183
14184 if (incorrect_checksum) {
14185 if (hf_checksum_status != -1) {
14186 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14187 proto_item_set_generated(ti2);
14188 }
14189 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14190 proto_item_append_text(ti, " [incorrect]");
14191 if (bad_checksum_expert != NULL((void*)0))
14192 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14193 } else {
14194 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14195 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))))))
;
14196 for (size_t counter = 0; counter < checksum_len; ++counter) {
14197 snprintf(
14198 /* On ecah iteration inserts two characters */
14199 (char*)&computed_checksum_str[counter << 1],
14200 computed_checksum_str_len - (counter << 1),
14201 "%02x",
14202 computed_checksum[counter]);
14203 }
14204 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14205 if (bad_checksum_expert != NULL((void*)0))
14206 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14207 }
14208 }
14209 } else {
14210 if (hf_checksum_status != -1) {
14211 proto_item_append_text(ti, " [unverified]");
14212 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14213 proto_item_set_generated(ti2);
14214 }
14215 }
14216 }
14217
14218 return ti;
14219}
14220
14221unsigned char
14222proto_check_field_name(const char *field_name)
14223{
14224 return module_check_valid_name(field_name, false0);
14225}
14226
14227unsigned char
14228proto_check_field_name_lower(const char *field_name)
14229{
14230 return module_check_valid_name(field_name, true1);
14231}
14232
14233bool_Bool
14234tree_expanded(int tree_type)
14235{
14236 if (tree_type <= 0) {
14237 return false0;
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 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14241}
14242
14243void
14244tree_expanded_set(int tree_type, bool_Bool value)
14245{
14246 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", 14246, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14247
14248 if (value)
14249 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14250 else
14251 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14252}
14253
14254/*
14255 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14256 *
14257 * Local variables:
14258 * c-basic-offset: 8
14259 * tab-width: 8
14260 * indent-tabs-mode: t
14261 * End:
14262 *
14263 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14264 * :indentSize=8:tabSize=8:noTabs=false:
14265 */