Bug Summary

File:epan/proto.c
Warning:line 13483, 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-11-100317-3848-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 check_protocol_filter_name_or_fail(filter_name);
8265
8266 /*
8267 * Add this protocol to the list of known protocols;
8268 * the list is sorted by protocol short name.
8269 */
8270 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8271 protocol->name = name;
8272 protocol->short_name = short_name;
8273 protocol->filter_name = filter_name;
8274 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8275 protocol->is_enabled = true1; /* protocol is enabled by default */
8276 protocol->enabled_by_default = true1; /* see previous comment */
8277 protocol->can_toggle = true1;
8278 protocol->parent_proto_id = -1;
8279 protocol->heur_list = NULL((void*)0);
8280
8281 /* List will be sorted later by name, when all protocols completed registering */
8282 protocols = g_list_prepend(protocols, protocol);
8283 /*
8284 * Make sure there's not already a protocol with any of those
8285 * names. Crash if there is, as that's an error in the code
8286 * or an inappropriate plugin.
8287 * This situation has to be fixed to not register more than one
8288 * protocol with the same name.
8289 */
8290 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8291 /* ws_error will terminate the program */
8292 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)
8293 " 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)
;
8294 }
8295 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8296 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)
8297 " 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)
;
8298 }
8299 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8300 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)
8301 " 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)
;
8302 }
8303
8304 /* Here we allocate a new header_field_info struct */
8305 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8306 hfinfo->name = name;
8307 hfinfo->abbrev = filter_name;
8308 hfinfo->type = FT_PROTOCOL;
8309 hfinfo->display = BASE_NONE;
8310 hfinfo->strings = protocol;
8311 hfinfo->bitmask = 0;
8312 hfinfo->ref_type = HF_REF_TYPE_NONE;
8313 hfinfo->blurb = NULL((void*)0);
8314 hfinfo->parent = -1; /* This field differentiates protos and fields */
8315
8316 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8317 return protocol->proto_id;
8318}
8319
8320int
8321proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8322{
8323 protocol_t *protocol;
8324 header_field_info *hfinfo;
8325
8326 /*
8327 * Helper protocols don't need the strict rules as a "regular" protocol
8328 * Just register it in a list and make a hf_ field from it
8329 */
8330 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8331 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)
;
8332 }
8333
8334 if (parent_proto <= 0) {
8335 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)
8336 " 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)
;
8337 }
8338
8339 check_protocol_filter_name_or_fail(filter_name);
8340
8341 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8342 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8343 protocol->name = name;
8344 protocol->short_name = short_name;
8345 protocol->filter_name = filter_name;
8346 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8347
8348 /* Enabling and toggling is really determined by parent protocol,
8349 but provide default values here */
8350 protocol->is_enabled = true1;
8351 protocol->enabled_by_default = true1;
8352 protocol->can_toggle = true1;
8353
8354 protocol->parent_proto_id = parent_proto;
8355 protocol->heur_list = NULL((void*)0);
8356
8357 /* List will be sorted later by name, when all protocols completed registering */
8358 protocols = g_list_prepend(protocols, protocol);
8359
8360 /* Here we allocate a new header_field_info struct */
8361 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8362 hfinfo->name = name;
8363 hfinfo->abbrev = filter_name;
8364 hfinfo->type = field_type;
8365 hfinfo->display = BASE_NONE;
8366 if (field_type == FT_BYTES) {
8367 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8368 }
8369 hfinfo->strings = protocol;
8370 hfinfo->bitmask = 0;
8371 hfinfo->ref_type = HF_REF_TYPE_NONE;
8372 hfinfo->blurb = NULL((void*)0);
8373 hfinfo->parent = -1; /* This field differentiates protos and fields */
8374
8375 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8376 return protocol->proto_id;
8377}
8378
8379bool_Bool
8380proto_deregister_protocol(const char *short_name)
8381{
8382 protocol_t *protocol;
8383 header_field_info *hfinfo;
8384 int proto_id;
8385 unsigned i;
8386
8387 proto_id = proto_get_id_by_short_name(short_name);
8388 protocol = find_protocol_by_id(proto_id);
8389 if (protocol == NULL((void*)0))
8390 return false0;
8391
8392 g_hash_table_remove(proto_names, protocol->name);
8393 g_hash_table_remove(proto_short_names, (void *)short_name);
8394 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8395
8396 if (protocol->fields) {
8397 for (i = 0; i < protocol->fields->len; i++) {
8398 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8399 hfinfo_remove_from_gpa_name_map(hfinfo);
8400 expert_deregister_expertinfo(hfinfo->abbrev);
8401 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8402 }
8403 g_ptr_array_free(protocol->fields, true1);
8404 protocol->fields = NULL((void*)0);
8405 }
8406
8407 g_list_free(protocol->heur_list);
8408
8409 /* Remove this protocol from the list of known protocols */
8410 protocols = g_list_remove(protocols, protocol);
8411
8412 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8413 g_hash_table_steal(gpa_name_map, protocol->filter_name);
8414
8415 g_free(last_field_name);
8416 last_field_name = NULL((void*)0);
8417
8418 return true1;
8419}
8420
8421void
8422proto_register_alias(const int proto_id, const char *alias_name)
8423{
8424 protocol_t *protocol;
8425
8426 protocol = find_protocol_by_id(proto_id);
8427 if (alias_name && protocol) {
8428 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8429 }
8430}
8431
8432/*
8433 * Routines to use to iterate over the protocols.
8434 * The argument passed to the iterator routines is an opaque cookie to
8435 * their callers; it's the GList pointer for the current element in
8436 * the list.
8437 * The ID of the protocol is returned, or -1 if there is no protocol.
8438 */
8439int
8440proto_get_first_protocol(void **cookie)
8441{
8442 protocol_t *protocol;
8443
8444 if (protocols == NULL((void*)0))
8445 return -1;
8446 *cookie = protocols;
8447 protocol = (protocol_t *)protocols->data;
8448 return protocol->proto_id;
8449}
8450
8451int
8452proto_get_data_protocol(void *cookie)
8453{
8454 GList *list_item = (GList *)cookie;
8455
8456 protocol_t *protocol = (protocol_t *)list_item->data;
8457 return protocol->proto_id;
8458}
8459
8460int
8461proto_get_next_protocol(void **cookie)
8462{
8463 GList *list_item = (GList *)*cookie;
8464 protocol_t *protocol;
8465
8466 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8467 if (list_item == NULL((void*)0))
8468 return -1;
8469 *cookie = list_item;
8470 protocol = (protocol_t *)list_item->data;
8471 return protocol->proto_id;
8472}
8473
8474header_field_info *
8475proto_get_first_protocol_field(const int proto_id, void **cookie)
8476{
8477 protocol_t *protocol = find_protocol_by_id(proto_id);
8478
8479 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8480 return NULL((void*)0);
8481
8482 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8483 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8484}
8485
8486header_field_info *
8487proto_get_next_protocol_field(const int proto_id, void **cookie)
8488{
8489 protocol_t *protocol = find_protocol_by_id(proto_id);
8490 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8491
8492 i++;
8493
8494 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8495 return NULL((void*)0);
8496
8497 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8498 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8499}
8500
8501protocol_t *
8502find_protocol_by_id(const int proto_id)
8503{
8504 header_field_info *hfinfo;
8505
8506 if (proto_id <= 0)
8507 return NULL((void*)0);
8508
8509 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", 8509, __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", 8509,
"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", 8509, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8510 if (hfinfo->type != FT_PROTOCOL) {
8511 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", 8511, "hfinfo->display & 0x00004000"
))))
;
8512 }
8513 return (protocol_t *)hfinfo->strings;
8514}
8515
8516int
8517proto_get_id(const protocol_t *protocol)
8518{
8519 return protocol->proto_id;
8520}
8521
8522bool_Bool
8523proto_name_already_registered(const char *name)
8524{
8525 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8525, "name", "No name present"))))
;
8526
8527 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8528 return true1;
8529 return false0;
8530}
8531
8532int
8533proto_get_id_by_filter_name(const char *filter_name)
8534{
8535 const protocol_t *protocol = NULL((void*)0);
8536
8537 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", 8537,
"filter_name", "No filter name present"))))
;
8538
8539 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8540
8541 if (protocol == NULL((void*)0))
8542 return -1;
8543 return protocol->proto_id;
8544}
8545
8546int
8547proto_get_id_by_short_name(const char *short_name)
8548{
8549 const protocol_t *protocol = NULL((void*)0);
8550
8551 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", 8551,
"short_name", "No short name present"))))
;
8552
8553 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8554
8555 if (protocol == NULL((void*)0))
8556 return -1;
8557 return protocol->proto_id;
8558}
8559
8560const char *
8561proto_get_protocol_name(const int proto_id)
8562{
8563 protocol_t *protocol;
8564
8565 protocol = find_protocol_by_id(proto_id);
8566
8567 if (protocol == NULL((void*)0))
8568 return NULL((void*)0);
8569 return protocol->name;
8570}
8571
8572const char *
8573proto_get_protocol_short_name(const protocol_t *protocol)
8574{
8575 if (protocol == NULL((void*)0))
8576 return "(none)";
8577 return protocol->short_name;
8578}
8579
8580const char *
8581proto_get_protocol_long_name(const protocol_t *protocol)
8582{
8583 if (protocol == NULL((void*)0))
8584 return "(none)";
8585 return protocol->name;
8586}
8587
8588const char *
8589proto_get_protocol_filter_name(const int proto_id)
8590{
8591 protocol_t *protocol;
8592
8593 protocol = find_protocol_by_id(proto_id);
8594 if (protocol == NULL((void*)0))
8595 return "(none)";
8596 return protocol->filter_name;
8597}
8598
8599void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8600{
8601 heur_dtbl_entry_t* heuristic_dissector;
8602
8603 if (protocol == NULL((void*)0))
8604 return;
8605
8606 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8607 if (heuristic_dissector != NULL((void*)0))
8608 {
8609 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8610 }
8611}
8612
8613void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8614{
8615 if (protocol == NULL((void*)0))
8616 return;
8617
8618 g_list_foreach(protocol->heur_list, func, user_data);
8619}
8620
8621void
8622proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8623 bool_Bool *is_tcp, bool_Bool *is_udp,
8624 bool_Bool *is_sctp, bool_Bool *is_tls,
8625 bool_Bool *is_rtp,
8626 bool_Bool *is_lte_rlc)
8627{
8628 wmem_list_frame_t *protos = wmem_list_head(layers);
8629 int proto_id;
8630 const char *proto_name;
8631
8632 /* Walk the list of a available protocols in the packet and
8633 attempt to find "major" ones. */
8634 /* It might make more sense to assemble and return a bitfield. */
8635 while (protos != NULL((void*)0))
8636 {
8637 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8638 proto_name = proto_get_protocol_filter_name(proto_id);
8639
8640 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8641 (!strcmp(proto_name, "ipv6")))) {
8642 *is_ip = true1;
8643 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8644 *is_tcp = true1;
8645 } else if (is_udp && !strcmp(proto_name, "udp")) {
8646 *is_udp = true1;
8647 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8648 *is_sctp = true1;
8649 } else if (is_tls && !strcmp(proto_name, "tls")) {
8650 *is_tls = true1;
8651 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8652 *is_rtp = true1;
8653 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8654 *is_lte_rlc = true1;
8655 }
8656
8657 protos = wmem_list_frame_next(protos);
8658 }
8659}
8660
8661bool_Bool
8662proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8663{
8664 wmem_list_frame_t *protos = wmem_list_head(layers);
8665 int proto_id;
8666 const char *name;
8667
8668 /* Walk the list of a available protocols in the packet and
8669 attempt to find the specified protocol. */
8670 while (protos != NULL((void*)0))
8671 {
8672 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8673 name = proto_get_protocol_filter_name(proto_id);
8674
8675 if (!strcmp(name, proto_name))
8676 {
8677 return true1;
8678 }
8679
8680 protos = wmem_list_frame_next(protos);
8681 }
8682
8683 return false0;
8684}
8685
8686char *
8687proto_list_layers(const packet_info *pinfo)
8688{
8689 wmem_strbuf_t *buf;
8690 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8691
8692 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8693
8694 /* Walk the list of layers in the packet and
8695 return a string of all entries. */
8696 while (layers != NULL((void*)0))
8697 {
8698 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8699
8700 layers = wmem_list_frame_next(layers);
8701 if (layers != NULL((void*)0)) {
8702 wmem_strbuf_append_c(buf, ':');
8703 }
8704 }
8705
8706 return wmem_strbuf_finalize(buf);
8707}
8708
8709uint8_t
8710proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8711{
8712 int *proto_layer_num_ptr;
8713
8714 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8715 if (proto_layer_num_ptr == NULL((void*)0)) {
8716 return 0;
8717 }
8718
8719 return (uint8_t)*proto_layer_num_ptr;
8720}
8721
8722bool_Bool
8723proto_is_pino(const protocol_t *protocol)
8724{
8725 return (protocol->parent_proto_id != -1);
8726}
8727
8728bool_Bool
8729// NOLINTNEXTLINE(misc-no-recursion)
8730proto_is_protocol_enabled(const protocol_t *protocol)
8731{
8732 if (protocol == NULL((void*)0))
8733 return false0;
8734
8735 //parent protocol determines enable/disable for helper dissectors
8736 if (proto_is_pino(protocol))
8737 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8738
8739 return protocol->is_enabled;
8740}
8741
8742bool_Bool
8743// NOLINTNEXTLINE(misc-no-recursion)
8744proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8745{
8746 //parent protocol determines enable/disable for helper dissectors
8747 if (proto_is_pino(protocol))
8748 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8749
8750 return protocol->enabled_by_default;
8751}
8752
8753bool_Bool
8754// NOLINTNEXTLINE(misc-no-recursion)
8755proto_can_toggle_protocol(const int proto_id)
8756{
8757 protocol_t *protocol;
8758
8759 protocol = find_protocol_by_id(proto_id);
8760 //parent protocol determines toggling for helper dissectors
8761 if (proto_is_pino(protocol))
8762 return proto_can_toggle_protocol(protocol->parent_proto_id);
8763
8764 return protocol->can_toggle;
8765}
8766
8767void
8768proto_disable_by_default(const int proto_id)
8769{
8770 protocol_t *protocol;
8771
8772 protocol = find_protocol_by_id(proto_id);
8773 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8773, "protocol->can_toggle"
))))
;
8774 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", 8774, "proto_is_pino(protocol) == 0"
))))
;
8775 protocol->is_enabled = false0;
8776 protocol->enabled_by_default = false0;
8777}
8778
8779void
8780proto_set_decoding(const int proto_id, const bool_Bool enabled)
8781{
8782 protocol_t *protocol;
8783
8784 protocol = find_protocol_by_id(proto_id);
8785 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8785, "protocol->can_toggle"
))))
;
8786 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", 8786, "proto_is_pino(protocol) == 0"
))))
;
8787 protocol->is_enabled = enabled;
8788}
8789
8790void
8791proto_disable_all(void)
8792{
8793 /* This doesn't explicitly disable heuristic protocols,
8794 * but the heuristic doesn't get called if the parent
8795 * protocol isn't enabled.
8796 */
8797 protocol_t *protocol;
8798 GList *list_item = protocols;
8799
8800 if (protocols == NULL((void*)0))
8801 return;
8802
8803 while (list_item) {
8804 protocol = (protocol_t *)list_item->data;
8805 if (protocol->can_toggle) {
8806 protocol->is_enabled = false0;
8807 }
8808 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8809 }
8810}
8811
8812static void
8813heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8814{
8815 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8816
8817 heur->enabled = heur->enabled_by_default;
8818}
8819
8820void
8821proto_reenable_all(void)
8822{
8823 protocol_t *protocol;
8824 GList *list_item = protocols;
8825
8826 if (protocols == NULL((void*)0))
8827 return;
8828
8829 while (list_item) {
8830 protocol = (protocol_t *)list_item->data;
8831 if (protocol->can_toggle)
8832 protocol->is_enabled = protocol->enabled_by_default;
8833 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8834 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8835 }
8836}
8837
8838void
8839proto_set_cant_toggle(const int proto_id)
8840{
8841 protocol_t *protocol;
8842
8843 protocol = find_protocol_by_id(proto_id);
8844 protocol->can_toggle = false0;
8845}
8846
8847static int
8848proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8849{
8850 if (proto != NULL((void*)0)) {
8851 g_ptr_array_add(proto->fields, hfi);
8852 }
8853
8854 return proto_register_field_init(hfi, parent);
8855}
8856
8857/* for use with static arrays only, since we don't allocate our own copies
8858of the header_field_info struct contained within the hf_register_info struct */
8859void
8860proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8861{
8862 hf_register_info *ptr = hf;
8863 protocol_t *proto;
8864 int i;
8865
8866 proto = find_protocol_by_id(parent);
8867
8868 if (proto->fields == NULL((void*)0)) {
8869 proto->fields = g_ptr_array_sized_new(num_records);
8870 }
8871
8872 for (i = 0; i < num_records; i++, ptr++) {
8873 /*
8874 * Make sure we haven't registered this yet.
8875 * Most fields have variables associated with them
8876 * that are initialized to -1; some have array elements,
8877 * or possibly uninitialized variables, so we also allow
8878 * 0 (which is unlikely to be the field ID we get back
8879 * from "proto_register_field_init()").
8880 */
8881 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8882 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8883 "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)
8884 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8885 return;
8886 }
8887
8888 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8889 }
8890}
8891
8892/* deregister already registered fields */
8893void
8894proto_deregister_field (const int parent, int hf_id)
8895{
8896 header_field_info *hfi;
8897 protocol_t *proto;
8898 unsigned i;
8899
8900 g_free(last_field_name);
8901 last_field_name = NULL((void*)0);
8902
8903 if (hf_id == -1 || hf_id == 0)
8904 return;
8905
8906 proto = find_protocol_by_id (parent);
8907 if (!proto || proto->fields == NULL((void*)0)) {
8908 return;
8909 }
8910
8911 for (i = 0; i < proto->fields->len; i++) {
8912 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8913 if (hfi->id == hf_id) {
8914 /* Found the hf_id in this protocol */
8915 g_hash_table_steal(gpa_name_map, hfi->abbrev);
8916 g_ptr_array_remove_index_fast(proto->fields, i);
8917 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8918 return;
8919 }
8920 }
8921}
8922
8923/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
8924void
8925proto_deregister_all_fields_with_prefix(const int parent, const gchar *prefix)
8926{
8927 header_field_info *hfinfo;
8928 protocol_t *proto;
8929
8930 g_free(last_field_name);
8931 last_field_name = NULL((void*)0);
8932
8933 proto = find_protocol_by_id(parent);
8934 if (proto && proto->fields && proto->fields->len > 0) {
8935 guint i = proto->fields->len;
8936 do {
8937 i--;
8938
8939 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8940 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) )
) {
8941 hfinfo_remove_from_gpa_name_map(hfinfo);
8942 expert_deregister_expertinfo(hfinfo->abbrev);
8943 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8944 g_ptr_array_remove_index_fast(proto->fields, i);
8945 }
8946 } while (i > 0);
8947 }
8948}
8949
8950void
8951proto_add_deregistered_data (void *data)
8952{
8953 g_ptr_array_add(deregistered_data, data);
8954}
8955
8956void
8957proto_add_deregistered_slice (size_t block_size, void *mem_block)
8958{
8959 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
)))
;
8960
8961 slice_data->block_size = block_size;
8962 slice_data->mem_block = mem_block;
8963
8964 g_ptr_array_add(deregistered_slice, slice_data);
8965}
8966
8967void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
8968{
8969 if (field_strings == NULL((void*)0)) {
8970 return;
8971 }
8972
8973 switch (field_type) {
8974 case FT_FRAMENUM:
8975 /* This is just an integer represented as a pointer */
8976 break;
8977 case FT_PROTOCOL: {
8978 protocol_t *protocol = (protocol_t *)field_strings;
8979 g_free((char *)protocol->short_name);
8980 break;
8981 }
8982 case FT_BOOLEAN: {
8983 true_false_string *tf = (true_false_string *)field_strings;
8984 g_free((char *)tf->true_string);
8985 g_free((char *)tf->false_string);
8986 break;
8987 }
8988 case FT_UINT40:
8989 case FT_INT40:
8990 case FT_UINT48:
8991 case FT_INT48:
8992 case FT_UINT56:
8993 case FT_INT56:
8994 case FT_UINT64:
8995 case FT_INT64: {
8996 if (field_display & BASE_UNIT_STRING0x00001000) {
8997 unit_name_string *unit = (unit_name_string *)field_strings;
8998 g_free((char *)unit->singular);
8999 g_free((char *)unit->plural);
9000 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9001 range_string *rs = (range_string *)field_strings;
9002 while (rs->strptr) {
9003 g_free((char *)rs->strptr);
9004 rs++;
9005 }
9006 } else if (field_display & BASE_EXT_STRING0x00000200) {
9007 val64_string_ext *vse = (val64_string_ext *)field_strings;
9008 val64_string *vs = (val64_string *)vse->_vs_p;
9009 while (vs->strptr) {
9010 g_free((char *)vs->strptr);
9011 vs++;
9012 }
9013 val64_string_ext_free(vse);
9014 field_strings = NULL((void*)0);
9015 } else if (field_display == BASE_CUSTOM) {
9016 /* this will be a pointer to a function, don't free that */
9017 field_strings = NULL((void*)0);
9018 } else {
9019 val64_string *vs64 = (val64_string *)field_strings;
9020 while (vs64->strptr) {
9021 g_free((char *)vs64->strptr);
9022 vs64++;
9023 }
9024 }
9025 break;
9026 }
9027 case FT_CHAR:
9028 case FT_UINT8:
9029 case FT_INT8:
9030 case FT_UINT16:
9031 case FT_INT16:
9032 case FT_UINT24:
9033 case FT_INT24:
9034 case FT_UINT32:
9035 case FT_INT32:
9036 case FT_FLOAT:
9037 case FT_DOUBLE: {
9038 if (field_display & BASE_UNIT_STRING0x00001000) {
9039 unit_name_string *unit = (unit_name_string *)field_strings;
9040 g_free((char *)unit->singular);
9041 g_free((char *)unit->plural);
9042 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9043 range_string *rs = (range_string *)field_strings;
9044 while (rs->strptr) {
9045 g_free((char *)rs->strptr);
9046 rs++;
9047 }
9048 } else if (field_display & BASE_EXT_STRING0x00000200) {
9049 value_string_ext *vse = (value_string_ext *)field_strings;
9050 value_string *vs = (value_string *)vse->_vs_p;
9051 while (vs->strptr) {
9052 g_free((char *)vs->strptr);
9053 vs++;
9054 }
9055 value_string_ext_free(vse);
9056 field_strings = NULL((void*)0);
9057 } else if (field_display == BASE_CUSTOM) {
9058 /* this will be a pointer to a function, don't free that */
9059 field_strings = NULL((void*)0);
9060 } else {
9061 value_string *vs = (value_string *)field_strings;
9062 while (vs->strptr) {
9063 g_free((char *)vs->strptr);
9064 vs++;
9065 }
9066 }
9067 break;
9068 default:
9069 break;
9070 }
9071 }
9072
9073 if (field_type != FT_FRAMENUM) {
9074 g_free((void *)field_strings);
9075 }
9076}
9077
9078static void
9079free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9080{
9081 header_field_info *hfi = (header_field_info *) data;
9082 int hf_id = hfi->id;
9083
9084 g_free((char *)hfi->name);
9085 g_free((char *)hfi->abbrev);
9086 g_free((char *)hfi->blurb);
9087
9088 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9089
9090 if (hfi->parent == -1)
9091 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)
;
9092
9093 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9094}
9095
9096static void
9097free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9098{
9099 g_free (data);
9100}
9101
9102static void
9103free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9104{
9105 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9106
9107 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9108 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)
;
9109}
9110
9111/* free deregistered fields and data */
9112void
9113proto_free_deregistered_fields (void)
9114{
9115 expert_free_deregistered_expertinfos();
9116
9117 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9118 g_ptr_array_free(deregistered_fields, true1);
9119 deregistered_fields = g_ptr_array_new();
9120
9121 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9122 g_ptr_array_free(deregistered_data, true1);
9123 deregistered_data = g_ptr_array_new();
9124
9125 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9126 g_ptr_array_free(deregistered_slice, true1);
9127 deregistered_slice = g_ptr_array_new();
9128}
9129
9130static const value_string hf_display[] = {
9131 { BASE_NONE, "BASE_NONE" },
9132 { BASE_DEC, "BASE_DEC" },
9133 { BASE_HEX, "BASE_HEX" },
9134 { BASE_OCT, "BASE_OCT" },
9135 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9136 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9137 { BASE_CUSTOM, "BASE_CUSTOM" },
9138 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9139 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9140 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9141 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9142 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9143 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9144 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9145 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9146 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9147 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9148 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9149 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9150 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9151 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9152 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9153 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9154 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9155 { BASE_PT_UDP, "BASE_PT_UDP" },
9156 { BASE_PT_TCP, "BASE_PT_TCP" },
9157 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9158 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9159 { BASE_OUI, "BASE_OUI" },
9160 { 0, NULL((void*)0) } };
9161
9162const char* proto_field_display_to_string(int field_display)
9163{
9164 return val_to_str_const(field_display, hf_display, "Unknown");
9165}
9166
9167static inline port_type
9168display_to_port_type(field_display_e e)
9169{
9170 switch (e) {
9171 case BASE_PT_UDP:
9172 return PT_UDP;
9173 case BASE_PT_TCP:
9174 return PT_TCP;
9175 case BASE_PT_DCCP:
9176 return PT_DCCP;
9177 case BASE_PT_SCTP:
9178 return PT_SCTP;
9179 default:
9180 break;
9181 }
9182 return PT_NONE;
9183}
9184
9185/* temporary function containing assert part for easier profiling */
9186static void
9187tmp_fld_check_assert(header_field_info *hfinfo)
9188{
9189 char* tmp_str;
9190
9191 /* The field must have a name (with length > 0) */
9192 if (!hfinfo->name || !hfinfo->name[0]) {
9193 if (hfinfo->abbrev)
9194 /* Try to identify the field */
9195 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)
9196 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9197 else
9198 /* Hum, no luck */
9199 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)"
)
;
9200 }
9201
9202 /* fields with an empty string for an abbreviation aren't filterable */
9203 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9204 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)
;
9205
9206 /* These types of fields are allowed to have value_strings,
9207 * true_false_strings or a protocol_t struct
9208 */
9209 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9210 switch (hfinfo->type) {
9211
9212 /*
9213 * These types are allowed to support display value_strings,
9214 * value64_strings, the extended versions of the previous
9215 * two, range strings, or unit strings.
9216 */
9217 case FT_CHAR:
9218 case FT_UINT8:
9219 case FT_UINT16:
9220 case FT_UINT24:
9221 case FT_UINT32:
9222 case FT_UINT40:
9223 case FT_UINT48:
9224 case FT_UINT56:
9225 case FT_UINT64:
9226 case FT_INT8:
9227 case FT_INT16:
9228 case FT_INT24:
9229 case FT_INT32:
9230 case FT_INT40:
9231 case FT_INT48:
9232 case FT_INT56:
9233 case FT_INT64:
9234 case FT_BOOLEAN:
9235 case FT_PROTOCOL:
9236 break;
9237
9238 /*
9239 * This is allowed to have a value of type
9240 * enum ft_framenum_type to indicate what relationship
9241 * the frame in question has to the frame in which
9242 * the field is put.
9243 */
9244 case FT_FRAMENUM:
9245 break;
9246
9247 /*
9248 * These types are allowed to support only unit strings.
9249 */
9250 case FT_FLOAT:
9251 case FT_DOUBLE:
9252 case FT_IEEE_11073_SFLOAT:
9253 case FT_IEEE_11073_FLOAT:
9254 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9255 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))
9256 " (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))
9257 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))
;
9258 }
9259 break;
9260
9261 /*
9262 * These types are allowed to support display
9263 * time_value_strings.
9264 */
9265 case FT_ABSOLUTE_TIME:
9266 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9267 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9268 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9269 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9270 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))
9271 " (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))
9272 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))
;
9273 }
9274 break;
9275
9276 /*
9277 * This type is only allowed to support a string if it's
9278 * a protocol (for pinos).
9279 */
9280 case FT_BYTES:
9281 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9282 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))
9283 " (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))
9284 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))
;
9285 }
9286 break;
9287
9288 default:
9289 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))
9290 " (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))
9291 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))
;
9292 }
9293 }
9294
9295 /* TODO: This check may slow down startup, and output quite a few warnings.
9296 It would be good to be able to enable this (and possibly other checks?)
9297 in non-release builds. */
9298#ifdef ENABLE_CHECK_FILTER
9299 /* Check for duplicate value_string values.
9300 There are lots that have the same value *and* string, so for now only
9301 report those that have same value but different string. */
9302 if ((hfinfo->strings != NULL((void*)0)) &&
9303 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9304 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9305 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9306 (
9307 (hfinfo->type == FT_CHAR) ||
9308 (hfinfo->type == FT_UINT8) ||
9309 (hfinfo->type == FT_UINT16) ||
9310 (hfinfo->type == FT_UINT24) ||
9311 (hfinfo->type == FT_UINT32) ||
9312 (hfinfo->type == FT_INT8) ||
9313 (hfinfo->type == FT_INT16) ||
9314 (hfinfo->type == FT_INT24) ||
9315 (hfinfo->type == FT_INT32) )) {
9316
9317 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9318 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9319 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9320 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9321 } else {
9322 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9323 CHECK_HF_VALUE(value_string, "u", start_values);
9324 }
9325 } else {
9326 const value_string *start_values = (const value_string*)hfinfo->strings;
9327 CHECK_HF_VALUE(value_string, "u", start_values);
9328 }
9329 }
9330
9331 if (hfinfo->type == FT_BOOLEAN) {
9332 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9333 if (tfs) {
9334 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9335 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"
, 9337, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9336 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9337, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9337 tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9337, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
;
9338 }
9339 }
9340 }
9341
9342 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9343 const range_string *rs = (const range_string*)(hfinfo->strings);
9344 if (rs) {
9345 const range_string *this_it = rs;
9346
9347 do {
9348 if (this_it->value_max < this_it->value_min) {
9349 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"
, 9353, __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)
9350 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9353, __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)
9351 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9353, __func__, "value_range_string error: %s (%s) entry for \"%s\" - max(%"
"l" "u"" 0x%""l" "x"") is less than min(%""l" "u"" 0x%""l" "x"
")", hfinfo->name, hfinfo->abbrev, this_it->strptr, this_it
->value_max, this_it->value_max, this_it->value_min,
this_it->value_min); } } while (0)
9352 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9353, __func__, "value_range_string error: %s (%s) entry for \"%s\" - max(%"
"l" "u"" 0x%""l" "x"") is less than min(%""l" "u"" 0x%""l" "x"
")", hfinfo->name, hfinfo->abbrev, this_it->strptr, this_it
->value_max, this_it->value_max, this_it->value_min,
this_it->value_min); } } while (0)
9353 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9353, __func__, "value_range_string error: %s (%s) entry for \"%s\" - max(%"
"l" "u"" 0x%""l" "x"") is less than min(%""l" "u"" 0x%""l" "x"
")", hfinfo->name, hfinfo->abbrev, this_it->strptr, this_it
->value_max, this_it->value_max, this_it->value_min,
this_it->value_min); } } while (0)
;
9354 ++this_it;
9355 continue;
9356 }
9357
9358 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9359 /* Not OK if this one is completely hidden by an earlier one! */
9360 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9361 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"
, 9367, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9362 "(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"
, 9367, __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)
9363 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9367, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9364 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9367, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9365 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9367, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9366 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9367, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9367 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9367, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
;
9368 }
9369 }
9370 ++this_it;
9371 } while (this_it->strptr);
9372 }
9373 }
9374#endif
9375
9376 switch (hfinfo->type) {
9377
9378 case FT_CHAR:
9379 /* Require the char type to have BASE_HEX, BASE_OCT,
9380 * BASE_CUSTOM, or BASE_NONE as its base.
9381 *
9382 * If the display value is BASE_NONE and there is a
9383 * strings conversion then the dissector writer is
9384 * telling us that the field's numerical value is
9385 * meaningless; we'll avoid showing the value to the
9386 * user.
9387 */
9388 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9389 case BASE_HEX:
9390 case BASE_OCT:
9391 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9392 break;
9393 case BASE_NONE:
9394 if (hfinfo->strings == NULL((void*)0))
9395 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
))
9396 " 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
))
9397 " 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
))
9398 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
))
9399 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
))
;
9400 break;
9401 default:
9402 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9403 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)
9404 " 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)
9405 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)
9406 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)
;
9407 //wmem_free(NULL, tmp_str);
9408 }
9409 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9410 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
))
9411 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
))
9412 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
))
;
9413 }
9414 break;
9415 case FT_INT8:
9416 case FT_INT16:
9417 case FT_INT24:
9418 case FT_INT32:
9419 case FT_INT40:
9420 case FT_INT48:
9421 case FT_INT56:
9422 case FT_INT64:
9423 /* Hexadecimal and octal are, in printf() and everywhere
9424 * else, unsigned so don't allow dissectors to register a
9425 * signed field to be displayed unsigned. (Else how would
9426 * we display negative values?)
9427 */
9428 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9429 case BASE_HEX:
9430 case BASE_OCT:
9431 case BASE_DEC_HEX:
9432 case BASE_HEX_DEC:
9433 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9434 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)
9435 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)
9436 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)
;
9437 //wmem_free(NULL, tmp_str);
9438 }
9439 /* FALL THROUGH */
9440 case FT_UINT8:
9441 case FT_UINT16:
9442 case FT_UINT24:
9443 case FT_UINT32:
9444 case FT_UINT40:
9445 case FT_UINT48:
9446 case FT_UINT56:
9447 case FT_UINT64:
9448 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
))
) {
9449 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9450 if (hfinfo->type != FT_UINT16) {
9451 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))
9452 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))
9453 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))
;
9454 }
9455 if (hfinfo->strings != NULL((void*)0)) {
9456 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)
9457 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)
9458 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)
;
9459 }
9460 if (hfinfo->bitmask != 0) {
9461 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)
9462 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)
9463 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)
;
9464 }
9465 wmem_free(NULL((void*)0), tmp_str);
9466 break;
9467 }
9468
9469 if (hfinfo->display == BASE_OUI) {
9470 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9471 if (hfinfo->type != FT_UINT24) {
9472 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))
9473 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))
9474 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))
;
9475 }
9476 if (hfinfo->strings != NULL((void*)0)) {
9477 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)
9478 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)
9479 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)
;
9480 }
9481 if (hfinfo->bitmask != 0) {
9482 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)
9483 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)
9484 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)
;
9485 }
9486 wmem_free(NULL((void*)0), tmp_str);
9487 break;
9488 }
9489
9490 /* Require integral types (other than frame number,
9491 * which is always displayed in decimal) to have a
9492 * number base.
9493 *
9494 * If the display value is BASE_NONE and there is a
9495 * strings conversion then the dissector writer is
9496 * telling us that the field's numerical value is
9497 * meaningless; we'll avoid showing the value to the
9498 * user.
9499 */
9500 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9501 case BASE_DEC:
9502 case BASE_HEX:
9503 case BASE_OCT:
9504 case BASE_DEC_HEX:
9505 case BASE_HEX_DEC:
9506 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9507 break;
9508 case BASE_NONE:
9509 if (hfinfo->strings == NULL((void*)0)) {
9510 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
))
9511 " 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
))
9512 " 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
))
9513 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
))
9514 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
))
;
9515 }
9516 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9517 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
))
9518 " 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
))
9519 " 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
))
9520 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
))
9521 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
))
;
9522 }
9523 break;
9524
9525 default:
9526 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9527 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)
9528 " 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)
9529 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)
9530 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)
;
9531 //wmem_free(NULL, tmp_str);
9532 }
9533 break;
9534 case FT_BYTES:
9535 case FT_UINT_BYTES:
9536 /* Require bytes to have a "display type" that could
9537 * add a character between displayed bytes.
9538 */
9539 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9540 case BASE_NONE:
9541 case SEP_DOT:
9542 case SEP_DASH:
9543 case SEP_COLON:
9544 case SEP_SPACE:
9545 break;
9546 default:
9547 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9548 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)
9549 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)
;
9550 //wmem_free(NULL, tmp_str);
9551 }
9552 if (hfinfo->bitmask != 0)
9553 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
))
9554 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
))
9555 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
))
;
9556 //allowed to support string if its a protocol (for pinos)
9557 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9558 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
))
9559 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
))
9560 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
))
;
9561 break;
9562
9563 case FT_PROTOCOL:
9564 case FT_FRAMENUM:
9565 if (hfinfo->display != BASE_NONE) {
9566 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9567 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)
9568 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)
9569 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)
;
9570 //wmem_free(NULL, tmp_str);
9571 }
9572 if (hfinfo->bitmask != 0)
9573 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
))
9574 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
))
9575 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
))
;
9576 break;
9577
9578 case FT_BOOLEAN:
9579 break;
9580
9581 case FT_ABSOLUTE_TIME:
9582 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9583 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9584 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)
9585 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)
;
9586 //wmem_free(NULL, tmp_str);
9587 }
9588 if (hfinfo->bitmask != 0)
9589 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
))
9590 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
))
9591 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
))
;
9592 break;
9593
9594 case FT_STRING:
9595 case FT_STRINGZ:
9596 case FT_UINT_STRING:
9597 case FT_STRINGZPAD:
9598 case FT_STRINGZTRUNC:
9599 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9600 case BASE_NONE:
9601 case BASE_STR_WSP:
9602 break;
9603
9604 default:
9605 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9606 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)
9607 " 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)
9608 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)
9609 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)
;
9610 //wmem_free(NULL, tmp_str);
9611 }
9612
9613 if (hfinfo->bitmask != 0)
9614 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
))
9615 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
))
9616 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
))
;
9617 if (hfinfo->strings != NULL((void*)0))
9618 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
))
9619 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
))
9620 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
))
;
9621 break;
9622
9623 case FT_IPv4:
9624 switch (hfinfo->display) {
9625 case BASE_NONE:
9626 case BASE_NETMASK:
9627 break;
9628
9629 default:
9630 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9631 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)
9632 " 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)
9633 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)
9634 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)
;
9635 //wmem_free(NULL, tmp_str);
9636 break;
9637 }
9638 break;
9639 case FT_FLOAT:
9640 case FT_DOUBLE:
9641 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9642 case BASE_NONE:
9643 case BASE_DEC:
9644 case BASE_HEX:
9645 case BASE_EXP:
9646 case BASE_CUSTOM:
9647 break;
9648 default:
9649 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9650 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)
9651 " 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)
9652 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)
9653 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)
;
9654 //wmem_free(NULL, tmp_str);
9655 }
9656 if (hfinfo->bitmask != 0)
9657 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
))
9658 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
))
9659 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
))
;
9660 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9661 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
))
9662 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
))
9663 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
))
;
9664 break;
9665 case FT_IEEE_11073_SFLOAT:
9666 case FT_IEEE_11073_FLOAT:
9667 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9668 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9669 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)
9670 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)
9671 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)
9672 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)
;
9673 //wmem_free(NULL, tmp_str);
9674 }
9675 if (hfinfo->bitmask != 0)
9676 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
))
9677 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
))
9678 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
))
;
9679 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9680 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
))
9681 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
))
9682 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
))
;
9683 break;
9684 default:
9685 if (hfinfo->display != BASE_NONE) {
9686 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9687 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)
9688 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)
9689 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)
9690 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)
;
9691 //wmem_free(NULL, tmp_str);
9692 }
9693 if (hfinfo->bitmask != 0)
9694 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
))
9695 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
))
9696 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
))
;
9697 if (hfinfo->strings != NULL((void*)0))
9698 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
))
9699 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
))
9700 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
))
;
9701 break;
9702 }
9703}
9704
9705static void
9706register_type_length_mismatch(void)
9707{
9708 static ei_register_info ei[] = {
9709 { &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)}}
}},
9710 { &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)}}
}},
9711 };
9712
9713 expert_module_t* expert_type_length_mismatch;
9714
9715 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9716
9717 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9718 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9719
9720 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9721 disabling them makes no sense. */
9722 proto_set_cant_toggle(proto_type_length_mismatch);
9723}
9724
9725static void
9726register_byte_array_string_decodinws_error(void)
9727{
9728 static ei_register_info ei[] = {
9729 { &ei_byte_array_string_decoding_failed_error,
9730 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9731 "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)}}
9732 }
9733 },
9734 };
9735
9736 expert_module_t* expert_byte_array_string_decoding_error;
9737
9738 proto_byte_array_string_decoding_error =
9739 proto_register_protocol("Byte Array-String Decoding Error",
9740 "Byte Array-string decoding error",
9741 "_ws.byte_array_string.decoding_error");
9742
9743 expert_byte_array_string_decoding_error =
9744 expert_register_protocol(proto_byte_array_string_decoding_error);
9745 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9746
9747 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9748 disabling them makes no sense. */
9749 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9750}
9751
9752static void
9753register_date_time_string_decodinws_error(void)
9754{
9755 static ei_register_info ei[] = {
9756 { &ei_date_time_string_decoding_failed_error,
9757 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9758 "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)}}
9759 }
9760 },
9761 };
9762
9763 expert_module_t* expert_date_time_string_decoding_error;
9764
9765 proto_date_time_string_decoding_error =
9766 proto_register_protocol("Date and Time-String Decoding Error",
9767 "Date and Time-string decoding error",
9768 "_ws.date_time_string.decoding_error");
9769
9770 expert_date_time_string_decoding_error =
9771 expert_register_protocol(proto_date_time_string_decoding_error);
9772 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9773
9774 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9775 disabling them makes no sense. */
9776 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9777}
9778
9779static void
9780register_string_errors(void)
9781{
9782 static ei_register_info ei[] = {
9783 { &ei_string_trailing_characters,
9784 { "_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)}}
}
9785 },
9786 };
9787
9788 expert_module_t* expert_string_errors;
9789
9790 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9791
9792 expert_string_errors = expert_register_protocol(proto_string_errors);
9793 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9794
9795 /* "String Errors" isn't really a protocol, it's an error indication;
9796 disabling them makes no sense. */
9797 proto_set_cant_toggle(proto_string_errors);
9798}
9799
9800#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
9801static int
9802proto_register_field_init(header_field_info *hfinfo, const int parent)
9803{
9804
9805 tmp_fld_check_assert(hfinfo);
9806
9807 hfinfo->parent = parent;
9808 hfinfo->same_name_next = NULL((void*)0);
9809 hfinfo->same_name_prev_id = -1;
9810
9811 /* if we always add and never delete, then id == len - 1 is correct */
9812 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9813 if (!gpa_hfinfo.hfi) {
9814 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9815 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9816 /* The entry with index 0 is not used. */
9817 gpa_hfinfo.hfi[0] = NULL((void*)0);
9818 gpa_hfinfo.len = 1;
9819 } else {
9820 gpa_hfinfo.allocated_len += 1000;
9821 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9822 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9823 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9824 }
9825 }
9826 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9827 gpa_hfinfo.len++;
9828 hfinfo->id = gpa_hfinfo.len - 1;
9829
9830 /* if we have real names, enter this field in the name tree */
9831 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
9832
9833 header_field_info *same_name_next_hfinfo;
9834 unsigned char c;
9835
9836 /* Check that the filter name (abbreviation) is legal;
9837 * it must contain only alphanumerics, '-', "_", and ".". */
9838 c = proto_check_field_name(hfinfo->abbrev);
9839 if (c) {
9840 if (c == '.') {
9841 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)
;
9842 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9843 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)
;
9844 } else {
9845 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)
;
9846 }
9847 }
9848
9849 /* We allow multiple hfinfo's to be registered under the same
9850 * abbreviation. This was done for X.25, as, depending
9851 * on whether it's modulo-8 or modulo-128 operation,
9852 * some bitfield fields may be in different bits of
9853 * a byte, and we want to be able to refer to that field
9854 * with one name regardless of whether the packets
9855 * are modulo-8 or modulo-128 packets. */
9856
9857 same_name_hfinfo = NULL((void*)0);
9858
9859 g_hash_table_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9860 /* GLIB 2.x - if it is already present
9861 * the previous hfinfo with the same name is saved
9862 * to same_name_hfinfo by value destroy callback */
9863 if (same_name_hfinfo) {
9864 /* There's already a field with this name.
9865 * Put the current field *before* that field
9866 * in the list of fields with this name, Thus,
9867 * we end up with an effectively
9868 * doubly-linked-list of same-named hfinfo's,
9869 * with the head of the list (stored in the
9870 * hash) being the last seen hfinfo.
9871 */
9872 same_name_next_hfinfo =
9873 same_name_hfinfo->same_name_next;
9874
9875 hfinfo->same_name_next = same_name_next_hfinfo;
9876 if (same_name_next_hfinfo)
9877 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9878
9879 same_name_hfinfo->same_name_next = hfinfo;
9880 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9881#ifdef ENABLE_CHECK_FILTER
9882 while (same_name_hfinfo) {
9883 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9884 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"
, 9884, __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)
;
9885 same_name_hfinfo = same_name_hfinfo->same_name_next;
9886 }
9887#endif
9888 }
9889 }
9890
9891 return hfinfo->id;
9892}
9893
9894void
9895proto_register_subtree_array(int * const *indices, const int num_indices)
9896{
9897 int i;
9898 int *const *ptr = indices;
9899
9900 /*
9901 * If we've already allocated the array of tree types, expand
9902 * it; this lets plugins such as mate add tree types after
9903 * the initial startup. (If we haven't already allocated it,
9904 * we don't allocate it; on the first pass, we just assign
9905 * ett values and keep track of how many we've assigned, and
9906 * when we're finished registering all dissectors we allocate
9907 * the array, so that we do only one allocation rather than
9908 * wasting CPU time and memory by growing the array for each
9909 * dissector that registers ett values.)
9910 */
9911 if (tree_is_expanded != NULL((void*)0)) {
9912 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9913
9914 /* set new items to 0 */
9915 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9916 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9917 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9918 }
9919
9920 /*
9921 * Assign "num_indices" subtree numbers starting at "num_tree_types",
9922 * returning the indices through the pointers in the array whose
9923 * first element is pointed to by "indices", and update
9924 * "num_tree_types" appropriately.
9925 */
9926 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9927 if (**ptr != -1 && **ptr != 0) {
9928 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.")
9929 " 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.")
9930 " 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.")
9931 " 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.")
;
9932 }
9933 **ptr = num_tree_types;
9934 }
9935}
9936
9937static void
9938mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
9939{
9940 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
9941 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
9942 char *last_char;
9943
9944 /* ..... field_name: dataaaaaaaaaaaaa
9945 * |
9946 * ^^^^^ name_pos
9947 *
9948 * ..... field_name […]: dataaaaaaaaaaaaa
9949 *
9950 * name_pos==0 means that we have only data or only a field_name
9951 */
9952
9953 ws_assert(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9953, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
9954
9955 if (name_pos >= size - trunc_len) {
9956 /* No room for trunc_str after the field_name, put it first. */
9957 name_pos = 0;
9958 }
9959
9960 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
9961 if (name_pos == 0) {
9962 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
9963 memcpy(label_str, trunc_str + 1, trunc_len);
9964 } else {
9965 memcpy(label_str + name_pos, trunc_str, trunc_len);
9966 }
9967 /* in general, label_str is UTF-8
9968 we can truncate it only at the beginning of a new character
9969 we go backwards from the byte right after our buffer and
9970 find the next starting byte of a UTF-8 character, this is
9971 where we cut
9972 there's no need to use g_utf8_find_prev_char(), the search
9973 will always succeed since we copied trunc_str into the
9974 buffer */
9975 /* g_utf8_prev_char does not deference the memory address
9976 * passed in (until after decrementing it, so it is perfectly
9977 * legal to pass in a pointer one past the last element.
9978 */
9979 last_char = g_utf8_prev_char(label_str + size);
9980 *last_char = '\0';
9981
9982 if (value_pos && *value_pos > 0) {
9983 if (name_pos == 0) {
9984 *value_pos += trunc_len;
9985 } else {
9986 /* Move one back to include trunc_str in the value. */
9987 *value_pos -= 1;
9988 }
9989 }
9990
9991 /* Check if value_pos is past label_str. */
9992 if (value_pos && *value_pos >= size) {
9993 *value_pos = size - 1;
9994 }
9995}
9996
9997static void
9998label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
9999{
10000 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10001}
10002
10003static size_t
10004label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10005{
10006 size_t name_pos;
10007
10008 /* "%s: %s", hfinfo->name, text */
10009 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10010 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10011 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10012 if (value_pos) {
10013 *value_pos = pos;
10014 }
10015 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, text ? text : "(null)", label_strcat_flags(hfinfo));
10016 }
10017
10018 if (pos >= ITEM_LABEL_LENGTH240) {
10019 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10020 label_mark_truncated(label_str, name_pos, value_pos);
10021 }
10022
10023 return pos;
10024}
10025
10026static size_t
10027label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10028{
10029 size_t name_pos;
10030
10031 /* "%s: %s (%s)", hfinfo->name, text, descr */
10032 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10033 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10034 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10035 if (value_pos) {
10036 *value_pos = pos;
10037 }
10038 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10039 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10040 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10041 } else {
10042 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10043 pos = label_concat(label_str, pos, " (")ws_label_strcpy(label_str, 240, pos, " (", 0);
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, ")")ws_label_strcpy(label_str, 240, pos, ")", 0);
10046 }
10047 }
10048
10049 if (pos >= ITEM_LABEL_LENGTH240) {
10050 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10051 label_mark_truncated(label_str, name_pos, value_pos);
10052 }
10053
10054 return pos;
10055}
10056
10057void
10058proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10059{
10060 const header_field_info *hfinfo;
10061 const char *str;
10062 const uint8_t *bytes;
10063 uint32_t integer;
10064 const ipv4_addr_and_mask *ipv4;
10065 const ipv6_addr_and_prefix *ipv6;
10066 const e_guid_t *guid;
10067 char *name;
10068 address addr;
10069 char *addr_str;
10070 char *tmp;
10071
10072 if (!label_str) {
10073 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10073, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10074 return;
10075 }
10076
10077 label_str[0]= '\0';
10078
10079 if (!fi) {
10080 return;
10081 }
10082
10083 hfinfo = fi->hfinfo;
10084
10085 switch (hfinfo->type) {
10086 case FT_NONE:
10087 case FT_PROTOCOL:
10088 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10089 if (value_pos) {
10090 *value_pos = strlen(hfinfo->name);
10091 }
10092 break;
10093
10094 case FT_BOOLEAN:
10095 fill_label_boolean(fi, label_str, value_pos);
10096 break;
10097
10098 case FT_BYTES:
10099 case FT_UINT_BYTES:
10100 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10101 fvalue_get_bytes_data(fi->value),
10102 (unsigned)fvalue_length2(fi->value));
10103 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10104 wmem_free(NULL((void*)0), tmp);
10105 break;
10106
10107 case FT_CHAR:
10108 if (hfinfo->bitmask) {
10109 fill_label_bitfield_char(fi, label_str, value_pos);
10110 } else {
10111 fill_label_char(fi, label_str, value_pos);
10112 }
10113 break;
10114
10115 /* Four types of integers to take care of:
10116 * Bitfield, with val_string
10117 * Bitfield, w/o val_string
10118 * Non-bitfield, with val_string
10119 * Non-bitfield, w/o val_string
10120 */
10121 case FT_UINT8:
10122 case FT_UINT16:
10123 case FT_UINT24:
10124 case FT_UINT32:
10125 if (hfinfo->bitmask) {
10126 fill_label_bitfield(fi, label_str, value_pos, false0);
10127 } else {
10128 fill_label_number(fi, label_str, value_pos, false0);
10129 }
10130 break;
10131
10132 case FT_FRAMENUM:
10133 fill_label_number(fi, label_str, value_pos, false0);
10134 break;
10135
10136 case FT_UINT40:
10137 case FT_UINT48:
10138 case FT_UINT56:
10139 case FT_UINT64:
10140 if (hfinfo->bitmask) {
10141 fill_label_bitfield64(fi, label_str, value_pos, false0);
10142 } else {
10143 fill_label_number64(fi, label_str, value_pos, false0);
10144 }
10145 break;
10146
10147 case FT_INT8:
10148 case FT_INT16:
10149 case FT_INT24:
10150 case FT_INT32:
10151 if (hfinfo->bitmask) {
10152 fill_label_bitfield(fi, label_str, value_pos, true1);
10153 } else {
10154 fill_label_number(fi, label_str, value_pos, true1);
10155 }
10156 break;
10157
10158 case FT_INT40:
10159 case FT_INT48:
10160 case FT_INT56:
10161 case FT_INT64:
10162 if (hfinfo->bitmask) {
10163 fill_label_bitfield64(fi, label_str, value_pos, true1);
10164 } else {
10165 fill_label_number64(fi, label_str, value_pos, true1);
10166 }
10167 break;
10168
10169 case FT_FLOAT:
10170 case FT_DOUBLE:
10171 fill_label_float(fi, label_str, value_pos);
10172 break;
10173
10174 case FT_ABSOLUTE_TIME:
10175 {
10176 const nstime_t *value = fvalue_get_time(fi->value);
10177 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10178 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10179 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10180 }
10181 if (hfinfo->strings) {
10182 /*
10183 * Table of time valus to be displayed
10184 * specially.
10185 */
10186 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10187 if (time_string != NULL((void*)0)) {
10188 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10189 break;
10190 }
10191 }
10192 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10193 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10194 wmem_free(NULL((void*)0), tmp);
10195 break;
10196 }
10197 case FT_RELATIVE_TIME:
10198 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10199 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10200 wmem_free(NULL((void*)0), tmp);
10201 break;
10202
10203 case FT_IPXNET:
10204 integer = fvalue_get_uinteger(fi->value);
10205 tmp = get_ipxnet_name(NULL((void*)0), integer);
10206 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10207 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10208 wmem_free(NULL((void*)0), tmp);
10209 wmem_free(NULL((void*)0), addr_str);
10210 break;
10211
10212 case FT_VINES:
10213 addr.type = AT_VINES;
10214 addr.len = VINES_ADDR_LEN6;
10215 addr.data = fvalue_get_bytes_data(fi->value);
10216
10217 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10218 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10219 wmem_free(NULL((void*)0), addr_str);
10220 break;
10221
10222 case FT_ETHER:
10223 bytes = fvalue_get_bytes_data(fi->value);
10224
10225 addr.type = AT_ETHER;
10226 addr.len = 6;
10227 addr.data = bytes;
10228
10229 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10230 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10231 wmem_free(NULL((void*)0), addr_str);
10232 break;
10233
10234 case FT_IPv4:
10235 ipv4 = fvalue_get_ipv4(fi->value);
10236 set_address_ipv4(&addr, ipv4);
10237
10238 if (hfinfo->display == BASE_NETMASK) {
10239 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10240 } else {
10241 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10242 }
10243 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10244 wmem_free(NULL((void*)0), addr_str);
10245 free_address(&addr);
10246 break;
10247
10248 case FT_IPv6:
10249 ipv6 = fvalue_get_ipv6(fi->value);
10250 set_address_ipv6(&addr, ipv6);
10251
10252 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10253 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10254 wmem_free(NULL((void*)0), addr_str);
10255 free_address(&addr);
10256 break;
10257
10258 case FT_FCWWN:
10259 bytes = fvalue_get_bytes_data(fi->value);
10260 addr.type = AT_FCWWN;
10261 addr.len = FCWWN_ADDR_LEN8;
10262 addr.data = bytes;
10263
10264 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10265 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10266 wmem_free(NULL((void*)0), addr_str);
10267 break;
10268
10269 case FT_GUID:
10270 guid = fvalue_get_guid(fi->value);
10271 tmp = guid_to_str(NULL((void*)0), guid);
10272 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10273 wmem_free(NULL((void*)0), tmp);
10274 break;
10275
10276 case FT_OID:
10277 bytes = fvalue_get_bytes_data(fi->value);
10278 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10279 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10280 if (name) {
10281 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10282 wmem_free(NULL((void*)0), name);
10283 } else {
10284 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10285 }
10286 wmem_free(NULL((void*)0), tmp);
10287 break;
10288
10289 case FT_REL_OID:
10290 bytes = fvalue_get_bytes_data(fi->value);
10291 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10292 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10293 if (name) {
10294 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10295 wmem_free(NULL((void*)0), name);
10296 } else {
10297 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10298 }
10299 wmem_free(NULL((void*)0), tmp);
10300 break;
10301
10302 case FT_SYSTEM_ID:
10303 bytes = fvalue_get_bytes_data(fi->value);
10304 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10305 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10306 wmem_free(NULL((void*)0), tmp);
10307 break;
10308
10309 case FT_EUI64:
10310 bytes = fvalue_get_bytes_data(fi->value);
10311 addr.type = AT_EUI64;
10312 addr.len = EUI64_ADDR_LEN8;
10313 addr.data = bytes;
10314
10315 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10316 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10317 wmem_free(NULL((void*)0), addr_str);
10318 break;
10319 case FT_STRING:
10320 case FT_STRINGZ:
10321 case FT_UINT_STRING:
10322 case FT_STRINGZPAD:
10323 case FT_STRINGZTRUNC:
10324 case FT_AX25:
10325 str = fvalue_get_string(fi->value);
10326 label_fill(label_str, 0, hfinfo, str, value_pos);
10327 break;
10328
10329 case FT_IEEE_11073_SFLOAT:
10330 case FT_IEEE_11073_FLOAT:
10331 fill_label_ieee_11073_float(fi, label_str, value_pos);
10332 break;
10333
10334 default:
10335 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
))
10336 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
))
10337 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
))
10338 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
))
;
10339 break;
10340 }
10341}
10342
10343static void
10344fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10345{
10346 char *p;
10347 int bitfield_byte_length = 0, bitwidth;
10348 uint64_t unshifted_value;
10349 uint64_t value;
10350
10351 const header_field_info *hfinfo = fi->hfinfo;
10352
10353 value = fvalue_get_uinteger64(fi->value);
10354 if (hfinfo->bitmask) {
10355 /* Figure out the bit width */
10356 bitwidth = hfinfo_container_bitwidth(hfinfo);
10357
10358 /* Un-shift bits */
10359 unshifted_value = value;
10360 unshifted_value <<= hfinfo_bitshift(hfinfo);
10361
10362 /* Create the bitfield first */
10363 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10364 bitfield_byte_length = (int) (p - label_str);
10365 }
10366
10367 /* Fill in the textual info */
10368 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10369}
10370
10371static const char *
10372hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10373{
10374 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10375 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10376
10377 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10378 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10379 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10380 else
10381 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10382 }
10383
10384 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10385 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10386
10387 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10388 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10389
10390 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10391}
10392
10393static const char *
10394hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10395{
10396 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10397 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10398 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10399 else
10400 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10401 }
10402
10403 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10404 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10405
10406 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10407 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10408
10409 /* If this is reached somebody registered a 64-bit field with a 32-bit
10410 * value-string, which isn't right. */
10411 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)
10412 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10413
10414 /* This is necessary to squelch MSVC errors; is there
10415 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10416 never returns? */
10417 return NULL((void*)0);
10418}
10419
10420static const char *
10421hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10422{
10423 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10424 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10425
10426 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)
;
10427
10428 /* This is necessary to squelch MSVC errors; is there
10429 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10430 never returns? */
10431 return NULL((void*)0);
10432}
10433
10434static const char *
10435hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10436{
10437 const char *str = hf_try_val_to_str(value, hfinfo);
10438
10439 return (str) ? str : unknown_str;
10440}
10441
10442static const char *
10443hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10444{
10445 const char *str = hf_try_val64_to_str(value, hfinfo);
10446
10447 return (str) ? str : unknown_str;
10448}
10449
10450/* Fills data for bitfield chars with val_strings */
10451static void
10452fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10453{
10454 char *p;
10455 int bitfield_byte_length, bitwidth;
10456 uint32_t unshifted_value;
10457 uint32_t value;
10458
10459 char buf[32];
10460 const char *out;
10461
10462 const header_field_info *hfinfo = fi->hfinfo;
10463
10464 /* Figure out the bit width */
10465 bitwidth = hfinfo_container_bitwidth(hfinfo);
10466
10467 /* Un-shift bits */
10468 value = fvalue_get_uinteger(fi->value);
10469
10470 unshifted_value = value;
10471 if (hfinfo->bitmask) {
10472 unshifted_value <<= hfinfo_bitshift(hfinfo);
10473 }
10474
10475 /* Create the bitfield first */
10476 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10477 bitfield_byte_length = (int) (p - label_str);
10478
10479 /* Fill in the textual info using stored (shifted) value */
10480 if (hfinfo->display == BASE_CUSTOM) {
10481 char tmp[ITEM_LABEL_LENGTH240];
10482 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10483
10484 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10484, "fmtfunc"))))
;
10485 fmtfunc(tmp, value);
10486 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10487 }
10488 else if (hfinfo->strings) {
10489 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10490
10491 out = hfinfo_char_vals_format(hfinfo, buf, value);
10492 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10493 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10494 else
10495 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10496 }
10497 else {
10498 out = hfinfo_char_value_format(hfinfo, buf, value);
10499
10500 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10501 }
10502}
10503
10504/* Fills data for bitfield ints with val_strings */
10505static void
10506fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10507{
10508 char *p;
10509 int bitfield_byte_length, bitwidth;
10510 uint32_t value, unshifted_value;
10511 char buf[NUMBER_LABEL_LENGTH80];
10512 const char *out;
10513
10514 const header_field_info *hfinfo = fi->hfinfo;
10515
10516 /* Figure out the bit width */
10517 if (fi->flags & FI_VARINT0x00040000)
10518 bitwidth = fi->length*8;
10519 else
10520 bitwidth = hfinfo_container_bitwidth(hfinfo);
10521
10522 /* Un-shift bits */
10523 if (is_signed)
10524 value = fvalue_get_sinteger(fi->value);
10525 else
10526 value = fvalue_get_uinteger(fi->value);
10527
10528 unshifted_value = value;
10529 if (hfinfo->bitmask) {
10530 unshifted_value <<= hfinfo_bitshift(hfinfo);
10531 }
10532
10533 /* Create the bitfield first */
10534 if (fi->flags & FI_VARINT0x00040000)
10535 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10536 else
10537 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10538 bitfield_byte_length = (int) (p - label_str);
10539
10540 /* Fill in the textual info using stored (shifted) value */
10541 if (hfinfo->display == BASE_CUSTOM) {
10542 char tmp[ITEM_LABEL_LENGTH240];
10543 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10544
10545 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10545, "fmtfunc"))))
;
10546 fmtfunc(tmp, value);
10547 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10548 }
10549 else if (hfinfo->strings) {
10550 const char *val_str = hf_try_val_to_str(value, hfinfo);
10551
10552 out = hfinfo_number_vals_format(hfinfo, buf, value);
10553 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10554 /*
10555 * Unique values only display value_string string
10556 * if there is a match. Otherwise it's just a number
10557 */
10558 if (val_str) {
10559 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10560 } else {
10561 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10562 }
10563 } else {
10564 if (val_str == NULL((void*)0))
10565 val_str = "Unknown";
10566
10567 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10568 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10569 else
10570 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10571 }
10572 }
10573 else {
10574 out = hfinfo_number_value_format(hfinfo, buf, value);
10575
10576 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10577 }
10578}
10579
10580static void
10581fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10582{
10583 char *p;
10584 int bitfield_byte_length, bitwidth;
10585 uint64_t value, unshifted_value;
10586 char buf[NUMBER_LABEL_LENGTH80];
10587 const char *out;
10588
10589 const header_field_info *hfinfo = fi->hfinfo;
10590
10591 /* Figure out the bit width */
10592 if (fi->flags & FI_VARINT0x00040000)
10593 bitwidth = fi->length*8;
10594 else
10595 bitwidth = hfinfo_container_bitwidth(hfinfo);
10596
10597 /* Un-shift bits */
10598 if (is_signed)
10599 value = fvalue_get_sinteger64(fi->value);
10600 else
10601 value = fvalue_get_uinteger64(fi->value);
10602
10603 unshifted_value = value;
10604 if (hfinfo->bitmask) {
10605 unshifted_value <<= hfinfo_bitshift(hfinfo);
10606 }
10607
10608 /* Create the bitfield first */
10609 if (fi->flags & FI_VARINT0x00040000)
10610 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10611 else
10612 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10613 bitfield_byte_length = (int) (p - label_str);
10614
10615 /* Fill in the textual info using stored (shifted) value */
10616 if (hfinfo->display == BASE_CUSTOM) {
10617 char tmp[ITEM_LABEL_LENGTH240];
10618 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10619
10620 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10620, "fmtfunc64"
))))
;
10621 fmtfunc64(tmp, value);
10622 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10623 }
10624 else if (hfinfo->strings) {
10625 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10626
10627 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10628 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10629 /*
10630 * Unique values only display value_string string
10631 * if there is a match. Otherwise it's just a number
10632 */
10633 if (val_str) {
10634 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10635 } else {
10636 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10637 }
10638 } else {
10639 if (val_str == NULL((void*)0))
10640 val_str = "Unknown";
10641
10642 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10643 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10644 else
10645 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10646 }
10647 }
10648 else {
10649 out = hfinfo_number_value_format64(hfinfo, buf, value);
10650
10651 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10652 }
10653}
10654
10655static void
10656fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10657{
10658 const header_field_info *hfinfo = fi->hfinfo;
10659 uint32_t value;
10660
10661 char buf[32];
10662 const char *out;
10663
10664 value = fvalue_get_uinteger(fi->value);
10665
10666 /* Fill in the textual info */
10667 if (hfinfo->display == BASE_CUSTOM) {
10668 char tmp[ITEM_LABEL_LENGTH240];
10669 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10670
10671 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10671, "fmtfunc"))))
;
10672 fmtfunc(tmp, value);
10673 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10674 }
10675 else if (hfinfo->strings) {
10676 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10677
10678 out = hfinfo_char_vals_format(hfinfo, buf, value);
10679 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10680 }
10681 else {
10682 out = hfinfo_char_value_format(hfinfo, buf, value);
10683
10684 label_fill(label_str, 0, hfinfo, out, value_pos);
10685 }
10686}
10687
10688static void
10689fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10690{
10691 const header_field_info *hfinfo = fi->hfinfo;
10692 uint32_t value;
10693
10694 char buf[NUMBER_LABEL_LENGTH80];
10695 const char *out;
10696
10697 if (is_signed)
10698 value = fvalue_get_sinteger(fi->value);
10699 else
10700 value = fvalue_get_uinteger(fi->value);
10701
10702 /* Fill in the textual info */
10703 if (hfinfo->display == BASE_CUSTOM) {
10704 char tmp[ITEM_LABEL_LENGTH240];
10705 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10706
10707 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10707, "fmtfunc"))))
;
10708 fmtfunc(tmp, value);
10709 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10710 }
10711 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10712 /*
10713 * It makes no sense to have a value-string table for a
10714 * frame-number field - they're just integers giving
10715 * the ordinal frame number.
10716 */
10717 const char *val_str = hf_try_val_to_str(value, hfinfo);
10718
10719 out = hfinfo_number_vals_format(hfinfo, buf, value);
10720 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10721 /*
10722 * Unique values only display value_string string
10723 * if there is a match. Otherwise it's just a number
10724 */
10725 if (val_str) {
10726 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10727 } else {
10728 label_fill(label_str, 0, hfinfo, out, value_pos);
10729 }
10730 } else {
10731 if (val_str == NULL((void*)0))
10732 val_str = "Unknown";
10733
10734 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10735 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10736 else
10737 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10738 }
10739 }
10740 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
))
) {
10741 char tmp[ITEM_LABEL_LENGTH240];
10742
10743 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10744 display_to_port_type((field_display_e)hfinfo->display), value);
10745 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10746 }
10747 else {
10748 out = hfinfo_number_value_format(hfinfo, buf, value);
10749
10750 label_fill(label_str, 0, hfinfo, out, value_pos);
10751 }
10752}
10753
10754static void
10755fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10756{
10757 const header_field_info *hfinfo = fi->hfinfo;
10758 uint64_t value;
10759
10760 char buf[NUMBER_LABEL_LENGTH80];
10761 const char *out;
10762
10763 if (is_signed)
10764 value = fvalue_get_sinteger64(fi->value);
10765 else
10766 value = fvalue_get_uinteger64(fi->value);
10767
10768 /* Fill in the textual info */
10769 if (hfinfo->display == BASE_CUSTOM) {
10770 char tmp[ITEM_LABEL_LENGTH240];
10771 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10772
10773 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10773, "fmtfunc64"
))))
;
10774 fmtfunc64(tmp, value);
10775 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10776 }
10777 else if (hfinfo->strings) {
10778 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10779
10780 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10781 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10782 /*
10783 * Unique values only display value_string string
10784 * if there is a match. Otherwise it's just a number
10785 */
10786 if (val_str) {
10787 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10788 } else {
10789 label_fill(label_str, 0, hfinfo, out, value_pos);
10790 }
10791 } else {
10792 if (val_str == NULL((void*)0))
10793 val_str = "Unknown";
10794
10795 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10796 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10797 else
10798 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10799 }
10800 }
10801 else {
10802 out = hfinfo_number_value_format64(hfinfo, buf, value);
10803
10804 label_fill(label_str, 0, hfinfo, out, value_pos);
10805 }
10806}
10807
10808static size_t
10809fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10810{
10811 int display;
10812 int n;
10813 double value;
10814
10815 if (label_str_size < 12) {
10816 /* Not enough room to write an entire floating point value. */
10817 return 0;
10818 }
10819
10820 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10821 value = fvalue_get_floating(fi->value);
10822
10823 if (display == BASE_CUSTOM) {
10824 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10825 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10825, "fmtfunc"))))
;
10826 fmtfunc(label_str, value);
10827 return strlen(label_str);
10828 }
10829
10830 switch (display) {
10831 case BASE_NONE:
10832 if (fi->hfinfo->type == FT_FLOAT) {
10833 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10834 } else {
10835 n = (int)strlen(dtoa_g_fmt(label_str, value));
10836 }
10837 break;
10838 case BASE_DEC:
10839 n = snprintf(label_str, label_str_size, "%f", value);
10840 break;
10841 case BASE_HEX:
10842 n = snprintf(label_str, label_str_size, "%a", value);
10843 break;
10844 case BASE_EXP:
10845 n = snprintf(label_str, label_str_size, "%e", value);
10846 break;
10847 default:
10848 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10848
, __func__, "assertion \"not reached\" failed")
;
10849 }
10850 if (n < 0) {
10851 return 0; /* error */
10852 }
10853 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10854 const char *hf_str_val;
10855 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10856 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10857 }
10858 if (n > label_str_size) {
10859 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10859, __func__, "label length too small"); } } while (0)
;
10860 return strlen(label_str);
10861 }
10862
10863 return n;
10864}
10865
10866void
10867fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10868{
10869 char tmp[ITEM_LABEL_LENGTH240];
10870
10871 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10872 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10873}
10874
10875static size_t
10876fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10877{
10878 int display;
10879 size_t pos = 0;
10880 double value;
10881 char* tmp_str;
10882
10883 if (label_str_size < 12) {
10884 /* Not enough room to write an entire floating point value. */
10885 return 0;
10886 }
10887
10888 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10889 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10890 pos = label_concat(label_str, pos, tmp_str)ws_label_strcpy(label_str, 240, pos, tmp_str, 0);
10891 wmem_free(NULL((void*)0), tmp_str);
10892
10893 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10894 const char *hf_str_val;
10895 fvalue_to_double(fi->value, &value);
10896 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10897 pos = label_concat(label_str, pos, hf_str_val)ws_label_strcpy(label_str, 240, pos, hf_str_val, 0);
10898 }
10899 if ((int)pos > label_str_size) {
10900 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10900, __func__, "label length too small"); } } while (0)
;
10901 return strlen(label_str);
10902 }
10903
10904 return pos;
10905}
10906
10907void
10908fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
10909{
10910 char tmp[ITEM_LABEL_LENGTH240];
10911
10912 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
10913 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10914}
10915
10916int
10917hfinfo_bitshift(const header_field_info *hfinfo)
10918{
10919 return ws_ctz(hfinfo->bitmask);
10920}
10921
10922
10923static int
10924hfinfo_bitoffset(const header_field_info *hfinfo)
10925{
10926 if (!hfinfo->bitmask) {
10927 return 0;
10928 }
10929
10930 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
10931 * as the first bit */
10932 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
10933}
10934
10935static int
10936hfinfo_mask_bitwidth(const header_field_info *hfinfo)
10937{
10938 if (!hfinfo->bitmask) {
10939 return 0;
10940 }
10941
10942 /* ilog2 = first set bit, ctz = last set bit */
10943 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
10944}
10945
10946static int
10947hfinfo_type_bitwidth(enum ftenum type)
10948{
10949 int bitwidth = 0;
10950
10951 switch (type) {
10952 case FT_CHAR:
10953 case FT_UINT8:
10954 case FT_INT8:
10955 bitwidth = 8;
10956 break;
10957 case FT_UINT16:
10958 case FT_INT16:
10959 bitwidth = 16;
10960 break;
10961 case FT_UINT24:
10962 case FT_INT24:
10963 bitwidth = 24;
10964 break;
10965 case FT_UINT32:
10966 case FT_INT32:
10967 bitwidth = 32;
10968 break;
10969 case FT_UINT40:
10970 case FT_INT40:
10971 bitwidth = 40;
10972 break;
10973 case FT_UINT48:
10974 case FT_INT48:
10975 bitwidth = 48;
10976 break;
10977 case FT_UINT56:
10978 case FT_INT56:
10979 bitwidth = 56;
10980 break;
10981 case FT_UINT64:
10982 case FT_INT64:
10983 bitwidth = 64;
10984 break;
10985 default:
10986 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 10986))
;
10987 ;
10988 }
10989 return bitwidth;
10990}
10991
10992
10993static int
10994hfinfo_container_bitwidth(const header_field_info *hfinfo)
10995{
10996 if (!hfinfo->bitmask) {
10997 return 0;
10998 }
10999
11000 if (hfinfo->type == FT_BOOLEAN) {
11001 return hfinfo->display; /* hacky? :) */
11002 }
11003
11004 return hfinfo_type_bitwidth(hfinfo->type);
11005}
11006
11007static int
11008hfinfo_hex_digits(const header_field_info *hfinfo)
11009{
11010 int bitwidth;
11011
11012 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11013 * appropriate to determine the number of hex digits for the field.
11014 * So instead, we compute it from the bitmask.
11015 */
11016 if (hfinfo->bitmask != 0) {
11017 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11018 } else {
11019 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11020 }
11021
11022 /* Divide by 4, rounding up, to get number of hex digits. */
11023 return (bitwidth + 3) / 4;
11024}
11025
11026const char *
11027hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11028{
11029 char *ptr = &buf[6];
11030 static const char hex_digits[16] =
11031 { '0', '1', '2', '3', '4', '5', '6', '7',
11032 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11033
11034 *ptr = '\0';
11035 *(--ptr) = '\'';
11036 /* Properly format value */
11037 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11038 /*
11039 * Printable, so just show the character, and, if it needs
11040 * to be escaped, escape it.
11041 */
11042 *(--ptr) = value;
11043 if (value == '\\' || value == '\'')
11044 *(--ptr) = '\\';
11045 } else {
11046 /*
11047 * Non-printable; show it as an escape sequence.
11048 */
11049 switch (value) {
11050
11051 case '\0':
11052 /*
11053 * Show a NUL with only one digit.
11054 */
11055 *(--ptr) = '0';
11056 break;
11057
11058 case '\a':
11059 case '\b':
11060 case '\f':
11061 case '\n':
11062 case '\r':
11063 case '\t':
11064 case '\v':
11065 *(--ptr) = value - '\a' + 'a';
11066 break;
11067
11068 default:
11069 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11070
11071 case BASE_OCT:
11072 *(--ptr) = (value & 0x7) + '0';
11073 value >>= 3;
11074 *(--ptr) = (value & 0x7) + '0';
11075 value >>= 3;
11076 *(--ptr) = (value & 0x7) + '0';
11077 break;
11078
11079 case BASE_HEX:
11080 *(--ptr) = hex_digits[value & 0x0F];
11081 value >>= 4;
11082 *(--ptr) = hex_digits[value & 0x0F];
11083 *(--ptr) = 'x';
11084 break;
11085
11086 default:
11087 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11088 }
11089 }
11090 *(--ptr) = '\\';
11091 }
11092 *(--ptr) = '\'';
11093 return ptr;
11094}
11095
11096static const char *
11097hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11098{
11099 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11100 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
))
;
11101
11102 *ptr = '\0';
11103 /* Properly format value */
11104 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11105 case BASE_DEC:
11106 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11107
11108 case BASE_DEC_HEX:
11109 *(--ptr) = ')';
11110 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11111 *(--ptr) = '(';
11112 *(--ptr) = ' ';
11113 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11114 return ptr;
11115
11116 case BASE_OCT:
11117 return oct_to_str_back(ptr, value);
11118
11119 case BASE_HEX:
11120 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11121
11122 case BASE_HEX_DEC:
11123 *(--ptr) = ')';
11124 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11125 *(--ptr) = '(';
11126 *(--ptr) = ' ';
11127 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11128 return ptr;
11129
11130 case BASE_PT_UDP:
11131 case BASE_PT_TCP:
11132 case BASE_PT_DCCP:
11133 case BASE_PT_SCTP:
11134 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11135 display_to_port_type((field_display_e)display), value);
11136 return buf;
11137 case BASE_OUI:
11138 {
11139 uint8_t p_oui[3];
11140 const char *manuf_name;
11141
11142 p_oui[0] = value >> 16 & 0xFF;
11143 p_oui[1] = value >> 8 & 0xFF;
11144 p_oui[2] = value & 0xFF;
11145
11146 /* Attempt an OUI lookup. */
11147 manuf_name = uint_get_manuf_name_if_known(value);
11148 if (manuf_name == NULL((void*)0)) {
11149 /* Could not find an OUI. */
11150 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11151 }
11152 else {
11153 /* Found an address string. */
11154 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11155 }
11156 return buf;
11157 }
11158
11159 default:
11160 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11161 }
11162 return ptr;
11163}
11164
11165static const char *
11166hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11167{
11168 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11169 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
))
;
11170
11171 *ptr = '\0';
11172 /* Properly format value */
11173 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11174 case BASE_DEC:
11175 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11176
11177 case BASE_DEC_HEX:
11178 *(--ptr) = ')';
11179 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11180 *(--ptr) = '(';
11181 *(--ptr) = ' ';
11182 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11183 return ptr;
11184
11185 case BASE_OCT:
11186 return oct64_to_str_back(ptr, value);
11187
11188 case BASE_HEX:
11189 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11190
11191 case BASE_HEX_DEC:
11192 *(--ptr) = ')';
11193 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11194 *(--ptr) = '(';
11195 *(--ptr) = ' ';
11196 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11197 return ptr;
11198
11199 default:
11200 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11201 }
11202
11203 return ptr;
11204}
11205
11206static const char *
11207hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11208{
11209 int display = hfinfo->display;
11210
11211 if (hfinfo->type == FT_FRAMENUM) {
11212 /*
11213 * Frame numbers are always displayed in decimal.
11214 */
11215 display = BASE_DEC;
11216 }
11217
11218 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11219}
11220
11221static const char *
11222hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11223{
11224 int display = hfinfo->display;
11225
11226 if (hfinfo->type == FT_FRAMENUM) {
11227 /*
11228 * Frame numbers are always displayed in decimal.
11229 */
11230 display = BASE_DEC;
11231 }
11232
11233 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11234}
11235
11236static const char *
11237hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11238{
11239 /* Get the underlying BASE_ value */
11240 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11241
11242 return hfinfo_char_value_format_display(display, buf, value);
11243}
11244
11245static const char *
11246hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11247{
11248 /* Get the underlying BASE_ value */
11249 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11250
11251 if (hfinfo->type == FT_FRAMENUM) {
11252 /*
11253 * Frame numbers are always displayed in decimal.
11254 */
11255 display = BASE_DEC;
11256 }
11257
11258 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11259 display = BASE_DEC;
11260 } else if (display == BASE_OUI) {
11261 display = BASE_HEX;
11262 }
11263
11264 switch (display) {
11265 case BASE_NONE:
11266 /* case BASE_DEC: */
11267 case BASE_DEC_HEX:
11268 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11269 case BASE_CUSTOM:
11270 display = BASE_DEC;
11271 break;
11272
11273 /* case BASE_HEX: */
11274 case BASE_HEX_DEC:
11275 display = BASE_HEX;
11276 break;
11277 }
11278
11279 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11280}
11281
11282static const char *
11283hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11284{
11285 /* Get the underlying BASE_ value */
11286 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11287
11288 if (hfinfo->type == FT_FRAMENUM) {
11289 /*
11290 * Frame numbers are always displayed in decimal.
11291 */
11292 display = BASE_DEC;
11293 }
11294
11295 switch (display) {
11296 case BASE_NONE:
11297 /* case BASE_DEC: */
11298 case BASE_DEC_HEX:
11299 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11300 case BASE_CUSTOM:
11301 display = BASE_DEC;
11302 break;
11303
11304 /* case BASE_HEX: */
11305 case BASE_HEX_DEC:
11306 display = BASE_HEX;
11307 break;
11308 }
11309
11310 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11311}
11312
11313static const char *
11314hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11315{
11316 /* Get the underlying BASE_ value */
11317 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11318
11319 return hfinfo_char_value_format_display(display, buf, value);
11320}
11321
11322static const char *
11323hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11324{
11325 /* Get the underlying BASE_ value */
11326 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11327
11328 if (display == BASE_NONE)
11329 return NULL((void*)0);
11330
11331 if (display == BASE_DEC_HEX)
11332 display = BASE_DEC;
11333 if (display == BASE_HEX_DEC)
11334 display = BASE_HEX;
11335
11336 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11337}
11338
11339static const char *
11340hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11341{
11342 /* Get the underlying BASE_ value */
11343 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11344
11345 if (display == BASE_NONE)
11346 return NULL((void*)0);
11347
11348 if (display == BASE_DEC_HEX)
11349 display = BASE_DEC;
11350 if (display == BASE_HEX_DEC)
11351 display = BASE_HEX;
11352
11353 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11354}
11355
11356const char *
11357proto_registrar_get_name(const int n)
11358{
11359 header_field_info *hfinfo;
11360
11361 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", 11361
, __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", 11361
, "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", 11361, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11362 return hfinfo->name;
11363}
11364
11365const char *
11366proto_registrar_get_abbrev(const int n)
11367{
11368 header_field_info *hfinfo;
11369
11370 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", 11370
, __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", 11370
, "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", 11370, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11371 return hfinfo->abbrev;
11372}
11373
11374enum ftenum
11375proto_registrar_get_ftype(const int n)
11376{
11377 header_field_info *hfinfo;
11378
11379 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", 11379
, __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", 11379
, "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", 11379, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11380 return hfinfo->type;
11381}
11382
11383int
11384proto_registrar_get_parent(const int n)
11385{
11386 header_field_info *hfinfo;
11387
11388 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", 11388
, __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", 11388
, "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", 11388, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11389 return hfinfo->parent;
11390}
11391
11392bool_Bool
11393proto_registrar_is_protocol(const int n)
11394{
11395 header_field_info *hfinfo;
11396
11397 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", 11397
, __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", 11397
, "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", 11397, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11398 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11399}
11400
11401/* Returns length of field in packet (not necessarily the length
11402 * in our internal representation, as in the case of IPv4).
11403 * 0 means undeterminable at time of registration
11404 * -1 means the field is not registered. */
11405int
11406proto_registrar_get_length(const int n)
11407{
11408 header_field_info *hfinfo;
11409
11410 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", 11410
, __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", 11410
, "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", 11410, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11411 return ftype_wire_size(hfinfo->type);
11412}
11413
11414/* Looks for a protocol or a field in a proto_tree. Returns true if
11415 * it exists anywhere, or false if it exists nowhere. */
11416bool_Bool
11417proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11418{
11419 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11420
11421 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11422 return true1;
11423 }
11424 else {
11425 return false0;
11426 }
11427}
11428
11429/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11430 * This only works if the hfindex was "primed" before the dissection
11431 * took place, as we just pass back the already-created GPtrArray*.
11432 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11433 * handles that. */
11434GPtrArray *
11435proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11436{
11437 if (!tree)
11438 return NULL((void*)0);
11439
11440 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11441 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11442 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11443 else
11444 return NULL((void*)0);
11445}
11446
11447bool_Bool
11448proto_tracking_interesting_fields(const proto_tree *tree)
11449{
11450 GHashTable *interesting_hfids;
11451
11452 if (!tree)
11453 return false0;
11454
11455 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11456
11457 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11458}
11459
11460/* Helper struct for proto_find_info() and proto_all_finfos() */
11461typedef struct {
11462 GPtrArray *array;
11463 int id;
11464} ffdata_t;
11465
11466/* Helper function for proto_find_info() */
11467static bool_Bool
11468find_finfo(proto_node *node, void * data)
11469{
11470 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11471 if (fi && fi->hfinfo) {
11472 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11473 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11474 }
11475 }
11476
11477 /* Don't stop traversing. */
11478 return false0;
11479}
11480
11481/* Helper function for proto_find_first_info() */
11482static bool_Bool
11483find_first_finfo(proto_node *node, void *data)
11484{
11485 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11486 if (fi && fi->hfinfo) {
11487 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11488 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11489
11490 /* Stop traversing. */
11491 return true1;
11492 }
11493 }
11494
11495 /* Continue traversing. */
11496 return false0;
11497}
11498
11499/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11500* This works on any proto_tree, primed or unprimed, but actually searches
11501* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11502* The caller does need to free the returned GPtrArray with
11503* g_ptr_array_free(<array>, true).
11504*/
11505GPtrArray *
11506proto_find_finfo(proto_tree *tree, const int id)
11507{
11508 ffdata_t ffdata;
11509
11510 ffdata.array = g_ptr_array_new();
11511 ffdata.id = id;
11512
11513 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11514
11515 return ffdata.array;
11516}
11517
11518/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11519* This works on any proto_tree, primed or unprimed, but actually searches
11520* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11521* The caller does need to free the returned GPtrArray with
11522* g_ptr_array_free(<array>, true).
11523*/
11524GPtrArray *
11525proto_find_first_finfo(proto_tree *tree, const int id)
11526{
11527 ffdata_t ffdata;
11528
11529 ffdata.array = g_ptr_array_new();
11530 ffdata.id = id;
11531
11532 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11533
11534 return ffdata.array;
11535}
11536
11537/* Helper function for proto_all_finfos() */
11538static bool_Bool
11539every_finfo(proto_node *node, void * data)
11540{
11541 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11542 if (fi && fi->hfinfo) {
11543 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11544 }
11545
11546 /* Don't stop traversing. */
11547 return false0;
11548}
11549
11550/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11551 * The caller does need to free the returned GPtrArray with
11552 * g_ptr_array_free(<array>, true).
11553 */
11554GPtrArray *
11555proto_all_finfos(proto_tree *tree)
11556{
11557 ffdata_t ffdata;
11558
11559 /* Pre allocate enough space to hold all fields in most cases */
11560 ffdata.array = g_ptr_array_sized_new(512);
11561 ffdata.id = 0;
11562
11563 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11564
11565 return ffdata.array;
11566}
11567
11568
11569typedef struct {
11570 unsigned offset;
11571 field_info *finfo;
11572 tvbuff_t *tvb;
11573} offset_search_t;
11574
11575static bool_Bool
11576check_for_offset(proto_node *node, void * data)
11577{
11578 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11579 offset_search_t *offsearch = (offset_search_t *)data;
11580
11581 /* !fi == the top most container node which holds nothing */
11582 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11583 if (offsearch->offset >= (unsigned) fi->start &&
11584 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11585
11586 offsearch->finfo = fi;
11587 return false0; /* keep traversing */
11588 }
11589 }
11590 return false0; /* keep traversing */
11591}
11592
11593/* Search a proto_tree backwards (from leaves to root) looking for the field
11594 * whose start/length occupies 'offset' */
11595/* XXX - I couldn't find an easy way to search backwards, so I search
11596 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11597 * the one I want to return to the user. This algorithm is inefficient
11598 * and could be re-done, but I'd have to handle all the children and
11599 * siblings of each node myself. When I have more time I'll do that.
11600 * (yeah right) */
11601field_info *
11602proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11603{
11604 offset_search_t offsearch;
11605
11606 offsearch.offset = offset;
11607 offsearch.finfo = NULL((void*)0);
11608 offsearch.tvb = tvb;
11609
11610 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11611
11612 return offsearch.finfo;
11613}
11614
11615typedef struct {
11616 int length;
11617 char *buf;
11618} decoded_data_t;
11619
11620static bool_Bool
11621check_for_undecoded(proto_node *node, void * data)
11622{
11623 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11624 decoded_data_t* decoded = (decoded_data_t*)data;
11625 int i;
11626 unsigned byte;
11627 unsigned bit;
11628
11629 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11630 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11631 byte = i / 8;
11632 bit = i % 8;
11633 decoded->buf[byte] |= (1 << bit);
11634 }
11635 }
11636
11637 return false0;
11638}
11639
11640char*
11641proto_find_undecoded_data(proto_tree *tree, unsigned length)
11642{
11643 decoded_data_t decoded;
11644 decoded.length = length;
11645 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11646
11647 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11648 return decoded.buf;
11649}
11650
11651/* Dumps the protocols in the registration database to stdout. An independent
11652 * program can take this output and format it into nice tables or HTML or
11653 * whatever.
11654 *
11655 * There is one record per line. The fields are tab-delimited.
11656 *
11657 * Field 1 = protocol name
11658 * Field 2 = protocol short name
11659 * Field 3 = protocol filter name
11660 * Field 4 = protocol enabled
11661 * Field 5 = protocol enabled by default
11662 * Field 6 = protocol can toggle
11663 */
11664void
11665proto_registrar_dump_protocols(void)
11666{
11667 protocol_t *protocol;
11668 int i;
11669 void *cookie = NULL((void*)0);
11670
11671
11672 i = proto_get_first_protocol(&cookie);
11673 while (i != -1) {
11674 protocol = find_protocol_by_id(i);
11675 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11676 protocol->name,
11677 protocol->short_name,
11678 protocol->filter_name,
11679 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11680 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11681 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11682 i = proto_get_next_protocol(&cookie);
11683 }
11684}
11685
11686/* Dumps the value_strings, extended value string headers, range_strings
11687 * or true/false strings for fields that have them.
11688 * There is one record per line. Fields are tab-delimited.
11689 * There are four types of records: Value String, Extended Value String Header,
11690 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11691 * the type of record.
11692 *
11693 * Note that a record will be generated only if the value_string,... is referenced
11694 * in a registered hfinfo entry.
11695 *
11696 *
11697 * Value Strings
11698 * -------------
11699 * Field 1 = 'V'
11700 * Field 2 = Field abbreviation to which this value string corresponds
11701 * Field 3 = Integer value
11702 * Field 4 = String
11703 *
11704 * Extended Value String Headers
11705 * -----------------------------
11706 * Field 1 = 'E'
11707 * Field 2 = Field abbreviation to which this extended value string header corresponds
11708 * Field 3 = Extended Value String "Name"
11709 * Field 4 = Number of entries in the associated value_string array
11710 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11711 *
11712 * Range Strings
11713 * -------------
11714 * Field 1 = 'R'
11715 * Field 2 = Field abbreviation to which this range string corresponds
11716 * Field 3 = Integer value: lower bound
11717 * Field 4 = Integer value: upper bound
11718 * Field 5 = String
11719 *
11720 * True/False Strings
11721 * ------------------
11722 * Field 1 = 'T'
11723 * Field 2 = Field abbreviation to which this true/false string corresponds
11724 * Field 3 = True String
11725 * Field 4 = False String
11726 */
11727void
11728proto_registrar_dump_values(void)
11729{
11730 header_field_info *hfinfo;
11731 int i, len, vi;
11732 const value_string *vals;
11733 const val64_string *vals64;
11734 const range_string *range;
11735 const true_false_string *tfs;
11736 const unit_name_string *units;
11737
11738 len = gpa_hfinfo.len;
11739 for (i = 0; i < len ; i++) {
11740 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11741 continue; /* This is a deregistered protocol or field */
11742
11743 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", 11743
, __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", 11743
, "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", 11743, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11744
11745 if (hfinfo->id == hf_text_only) {
11746 continue;
11747 }
11748
11749 /* ignore protocols */
11750 if (proto_registrar_is_protocol(i)) {
11751 continue;
11752 }
11753 /* process header fields */
11754#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11755 /*
11756 * If this field isn't at the head of the list of
11757 * fields with this name, skip this field - all
11758 * fields with the same name are really just versions
11759 * of the same field stored in different bits, and
11760 * should have the same type/radix/value list, and
11761 * just differ in their bit masks. (If a field isn't
11762 * a bitfield, but can be, say, 1 or 2 bytes long,
11763 * it can just be made FT_UINT16, meaning the
11764 * *maximum* length is 2 bytes, and be used
11765 * for all lengths.)
11766 */
11767 if (hfinfo->same_name_prev_id != -1)
11768 continue;
11769#endif
11770 vals = NULL((void*)0);
11771 vals64 = NULL((void*)0);
11772 range = NULL((void*)0);
11773 tfs = NULL((void*)0);
11774 units = NULL((void*)0);
11775
11776 if (hfinfo->strings != NULL((void*)0)) {
11777 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11778 (hfinfo->type == FT_CHAR ||
11779 hfinfo->type == FT_UINT8 ||
11780 hfinfo->type == FT_UINT16 ||
11781 hfinfo->type == FT_UINT24 ||
11782 hfinfo->type == FT_UINT32 ||
11783 hfinfo->type == FT_UINT40 ||
11784 hfinfo->type == FT_UINT48 ||
11785 hfinfo->type == FT_UINT56 ||
11786 hfinfo->type == FT_UINT64 ||
11787 hfinfo->type == FT_INT8 ||
11788 hfinfo->type == FT_INT16 ||
11789 hfinfo->type == FT_INT24 ||
11790 hfinfo->type == FT_INT32 ||
11791 hfinfo->type == FT_INT40 ||
11792 hfinfo->type == FT_INT48 ||
11793 hfinfo->type == FT_INT56 ||
11794 hfinfo->type == FT_INT64 ||
11795 hfinfo->type == FT_FLOAT ||
11796 hfinfo->type == FT_DOUBLE)) {
11797
11798 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11799 range = (const range_string *)hfinfo->strings;
11800 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11801 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11802 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11803 } else {
11804 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11805 }
11806 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11807 vals64 = (const val64_string *)hfinfo->strings;
11808 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11809 units = (const unit_name_string *)hfinfo->strings;
11810 } else {
11811 vals = (const value_string *)hfinfo->strings;
11812 }
11813 }
11814 else if (hfinfo->type == FT_BOOLEAN) {
11815 tfs = (const struct true_false_string *)hfinfo->strings;
11816 }
11817 }
11818
11819 /* Print value strings? */
11820 if (vals) {
11821 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11822 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11823 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11824 if (!val64_string_ext_validate(vse_p)) {
11825 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11825, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11826 continue;
11827 }
11828 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11829 printf("E\t%s\t%u\t%s\t%s\n",
11830 hfinfo->abbrev,
11831 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11832 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11833 val64_string_ext_match_type_str(vse_p));
11834 } else {
11835 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11836 if (!value_string_ext_validate(vse_p)) {
11837 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11837, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11838 continue;
11839 }
11840 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11841 printf("E\t%s\t%u\t%s\t%s\n",
11842 hfinfo->abbrev,
11843 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11844 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11845 value_string_ext_match_type_str(vse_p));
11846 }
11847 }
11848 vi = 0;
11849 while (vals[vi].strptr) {
11850 /* Print in the proper base */
11851 if (hfinfo->type == FT_CHAR) {
11852 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11853 printf("V\t%s\t'%c'\t%s\n",
11854 hfinfo->abbrev,
11855 vals[vi].value,
11856 vals[vi].strptr);
11857 } else {
11858 if (hfinfo->display == BASE_HEX) {
11859 printf("V\t%s\t'\\x%02x'\t%s\n",
11860 hfinfo->abbrev,
11861 vals[vi].value,
11862 vals[vi].strptr);
11863 }
11864 else {
11865 printf("V\t%s\t'\\%03o'\t%s\n",
11866 hfinfo->abbrev,
11867 vals[vi].value,
11868 vals[vi].strptr);
11869 }
11870 }
11871 } else {
11872 if (hfinfo->display == BASE_HEX) {
11873 printf("V\t%s\t0x%x\t%s\n",
11874 hfinfo->abbrev,
11875 vals[vi].value,
11876 vals[vi].strptr);
11877 }
11878 else {
11879 printf("V\t%s\t%u\t%s\n",
11880 hfinfo->abbrev,
11881 vals[vi].value,
11882 vals[vi].strptr);
11883 }
11884 }
11885 vi++;
11886 }
11887 }
11888 else if (vals64) {
11889 vi = 0;
11890 while (vals64[vi].strptr) {
11891 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11892 hfinfo->abbrev,
11893 vals64[vi].value,
11894 vals64[vi].strptr);
11895 vi++;
11896 }
11897 }
11898
11899 /* print range strings? */
11900 else if (range) {
11901 vi = 0;
11902 while (range[vi].strptr) {
11903 /* Print in the proper base */
11904 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
11905 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
11906 hfinfo->abbrev,
11907 range[vi].value_min,
11908 range[vi].value_max,
11909 range[vi].strptr);
11910 }
11911 else {
11912 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
11913 hfinfo->abbrev,
11914 range[vi].value_min,
11915 range[vi].value_max,
11916 range[vi].strptr);
11917 }
11918 vi++;
11919 }
11920 }
11921
11922 /* Print true/false strings? */
11923 else if (tfs) {
11924 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
11925 tfs->true_string, tfs->false_string);
11926 }
11927 /* Print unit strings? */
11928 else if (units) {
11929 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
11930 units->singular, units->plural ? units->plural : "(no plural)");
11931 }
11932 }
11933}
11934
11935/* Prints the number of registered fields.
11936 * Useful for determining an appropriate value for
11937 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
11938 *
11939 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
11940 * the number of fields, true otherwise.
11941 */
11942bool_Bool
11943proto_registrar_dump_fieldcount(void)
11944{
11945 uint32_t i;
11946 header_field_info *hfinfo;
11947 uint32_t deregistered_count = 0;
11948 uint32_t same_name_count = 0;
11949 uint32_t protocol_count = 0;
11950
11951 for (i = 0; i < gpa_hfinfo.len; i++) {
11952 if (gpa_hfinfo.hfi[i] == NULL((void*)0)) {
11953 deregistered_count++;
11954 continue; /* This is a deregistered protocol or header field */
11955 }
11956
11957 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", 11957
, __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", 11957
, "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", 11957, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11958
11959 if (proto_registrar_is_protocol(i))
11960 protocol_count++;
11961
11962 if (hfinfo->same_name_prev_id != -1)
11963 same_name_count++;
11964 }
11965
11966 printf("There are %u header fields registered, of which:\n"
11967 "\t%u are deregistered\n"
11968 "\t%u are protocols\n"
11969 "\t%u have the same name as another field\n\n",
11970 gpa_hfinfo.len, deregistered_count, protocol_count,
11971 same_name_count);
11972
11973 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
11974 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
11975 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
11976 "\n");
11977
11978 printf("The header field table consumes %u KiB of memory.\n",
11979 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
11980 printf("The fields themselves consume %u KiB of memory.\n",
11981 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
11982
11983 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
11984}
11985
11986static void
11987elastic_add_base_mapping(json_dumper *dumper)
11988{
11989 json_dumper_set_member_name(dumper, "index_patterns");
11990 json_dumper_begin_array(dumper);
11991 // The index names from write_json_index() in print.c
11992 json_dumper_value_string(dumper, "packets-*");
11993 json_dumper_end_array(dumper);
11994
11995 json_dumper_set_member_name(dumper, "settings");
11996 json_dumper_begin_object(dumper);
11997 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
11998 json_dumper_value_anyf(dumper, "%d", 1000000);
11999 json_dumper_end_object(dumper);
12000}
12001
12002static char*
12003ws_type_to_elastic(unsigned type)
12004{
12005 switch(type) {
12006 case FT_INT8:
12007 return "byte";
12008 case FT_UINT8:
12009 case FT_INT16:
12010 return "short";
12011 case FT_UINT16:
12012 case FT_INT32:
12013 case FT_UINT24:
12014 case FT_INT24:
12015 return "integer";
12016 case FT_FRAMENUM:
12017 case FT_UINT32:
12018 case FT_UINT40:
12019 case FT_UINT48:
12020 case FT_UINT56:
12021 case FT_INT40:
12022 case FT_INT48:
12023 case FT_INT56:
12024 case FT_INT64:
12025 return "long";
12026 case FT_UINT64:
12027 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12028 case FT_FLOAT:
12029 return "float";
12030 case FT_DOUBLE:
12031 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12032 return "double";
12033 case FT_IPv6:
12034 case FT_IPv4:
12035 return "ip";
12036 case FT_ABSOLUTE_TIME:
12037 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12038 case FT_BOOLEAN:
12039 return "boolean";
12040 default:
12041 return NULL((void*)0);
12042 }
12043}
12044
12045static char*
12046dot_to_underscore(char* str)
12047{
12048 unsigned i;
12049 for (i = 0; i < strlen(str); i++) {
12050 if (str[i] == '.')
12051 str[i] = '_';
12052 }
12053 return str;
12054}
12055
12056/* Dumps a mapping file for ElasticSearch
12057 * This is the v1 (legacy) _template API.
12058 * At some point it may need to be updated with the composable templates
12059 * introduced in Elasticsearch 7.8 (_index_template)
12060 */
12061void
12062proto_registrar_dump_elastic(const char* filter)
12063{
12064 header_field_info *hfinfo;
12065 header_field_info *parent_hfinfo;
12066 unsigned i;
12067 bool_Bool open_object = true1;
12068 const char* prev_proto = NULL((void*)0);
12069 char* str;
12070 char** protos = NULL((void*)0);
12071 char* proto;
12072 bool_Bool found;
12073 unsigned j;
12074 char* type;
12075 char* prev_item = NULL((void*)0);
12076
12077 /* We have filtering protocols. Extract them. */
12078 if (filter) {
12079 protos = g_strsplit(filter, ",", -1);
12080 }
12081
12082 /*
12083 * To help tracking down the json tree, objects have been appended with a comment:
12084 * n.label -> where n is the indentation level and label the name of the object
12085 */
12086
12087 json_dumper dumper = {
12088 .output_file = stdoutstdout,
12089 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12090 };
12091 json_dumper_begin_object(&dumper); // 1.root
12092 elastic_add_base_mapping(&dumper);
12093
12094 json_dumper_set_member_name(&dumper, "mappings");
12095 json_dumper_begin_object(&dumper); // 2.mappings
12096
12097 json_dumper_set_member_name(&dumper, "properties");
12098 json_dumper_begin_object(&dumper); // 3.properties
12099 json_dumper_set_member_name(&dumper, "timestamp");
12100 json_dumper_begin_object(&dumper); // 4.timestamp
12101 json_dumper_set_member_name(&dumper, "type");
12102 json_dumper_value_string(&dumper, "date");
12103 json_dumper_end_object(&dumper); // 4.timestamp
12104
12105 json_dumper_set_member_name(&dumper, "layers");
12106 json_dumper_begin_object(&dumper); // 4.layers
12107 json_dumper_set_member_name(&dumper, "properties");
12108 json_dumper_begin_object(&dumper); // 5.properties
12109
12110 for (i = 0; i < gpa_hfinfo.len; i++) {
12111 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12112 continue; /* This is a deregistered protocol or header field */
12113
12114 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", 12114
, __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", 12114
, "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", 12114, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12115
12116 /*
12117 * Skip the pseudo-field for "proto_tree_add_text()" since
12118 * we don't want it in the list of filterable protocols.
12119 */
12120 if (hfinfo->id == hf_text_only)
12121 continue;
12122
12123 if (!proto_registrar_is_protocol(i)) {
12124 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", 12124
, __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", 12124
, "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", 12124
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12125
12126 /*
12127 * Skip the field if filter protocols have been set and this one's
12128 * parent is not listed.
12129 */
12130 if (protos) {
12131 found = false0;
12132 j = 0;
12133 proto = protos[0];
12134 while(proto) {
12135 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12136 found = true1;
12137 break;
12138 }
12139 j++;
12140 proto = protos[j];
12141 }
12142 if (!found)
12143 continue;
12144 }
12145
12146 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12147 json_dumper_end_object(&dumper); // 7.properties
12148 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12149 open_object = true1;
12150 }
12151
12152 prev_proto = parent_hfinfo->abbrev;
12153
12154 if (open_object) {
12155 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12156 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12157 json_dumper_set_member_name(&dumper, "properties");
12158 json_dumper_begin_object(&dumper); // 7.properties
12159 open_object = false0;
12160 }
12161 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12162 type = ws_type_to_elastic(hfinfo->type);
12163 /* when type is NULL, we have the default mapping: string */
12164 if (type) {
12165 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12166 dot_to_underscore(str);
12167 if (g_strcmp0(prev_item, str)) {
12168 json_dumper_set_member_name(&dumper, str);
12169 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12170 json_dumper_set_member_name(&dumper, "type");
12171 json_dumper_value_string(&dumper, type);
12172 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12173 }
12174 g_free(prev_item);
12175 prev_item = str;
12176 }
12177 }
12178 }
12179 g_free(prev_item);
12180
12181 if (prev_proto) {
12182 json_dumper_end_object(&dumper); // 7.properties
12183 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12184 }
12185
12186 json_dumper_end_object(&dumper); // 5.properties
12187 json_dumper_end_object(&dumper); // 4.layers
12188 json_dumper_end_object(&dumper); // 3.properties
12189 json_dumper_end_object(&dumper); // 2.mappings
12190 json_dumper_end_object(&dumper); // 1.root
12191 bool_Bool ret = json_dumper_finish(&dumper);
12192 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12192, "ret"))))
;
12193
12194 g_strfreev(protos);
12195}
12196
12197/* Dumps the contents of the registration database to stdout. An independent
12198 * program can take this output and format it into nice tables or HTML or
12199 * whatever.
12200 *
12201 * There is one record per line. Each record is either a protocol or a header
12202 * field, differentiated by the first field. The fields are tab-delimited.
12203 *
12204 * Protocols
12205 * ---------
12206 * Field 1 = 'P'
12207 * Field 2 = descriptive protocol name
12208 * Field 3 = protocol abbreviation
12209 *
12210 * Header Fields
12211 * -------------
12212 * Field 1 = 'F'
12213 * Field 2 = descriptive field name
12214 * Field 3 = field abbreviation
12215 * Field 4 = type ( textual representation of the ftenum type )
12216 * Field 5 = parent protocol abbreviation
12217 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12218 * Field 7 = bitmask: format: hex: 0x....
12219 * Field 8 = blurb describing field
12220 */
12221void
12222proto_registrar_dump_fields(void)
12223{
12224 header_field_info *hfinfo, *parent_hfinfo;
12225 int i, len;
12226 const char *enum_name;
12227 const char *base_name;
12228 const char *blurb;
12229 char width[5];
12230
12231 len = gpa_hfinfo.len;
12232 for (i = 0; i < len ; i++) {
12233 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12234 continue; /* This is a deregistered protocol or header field */
12235
12236 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", 12236
, __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", 12236
, "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", 12236, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12237
12238 /*
12239 * Skip the pseudo-field for "proto_tree_add_text()" since
12240 * we don't want it in the list of filterable fields.
12241 */
12242 if (hfinfo->id == hf_text_only)
12243 continue;
12244
12245 /* format for protocols */
12246 if (proto_registrar_is_protocol(i)) {
12247 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12248 }
12249 /* format for header fields */
12250 else {
12251 /*
12252 * If this field isn't at the head of the list of
12253 * fields with this name, skip this field - all
12254 * fields with the same name are really just versions
12255 * of the same field stored in different bits, and
12256 * should have the same type/radix/value list, and
12257 * just differ in their bit masks. (If a field isn't
12258 * a bitfield, but can be, say, 1 or 2 bytes long,
12259 * it can just be made FT_UINT16, meaning the
12260 * *maximum* length is 2 bytes, and be used
12261 * for all lengths.)
12262 */
12263 if (hfinfo->same_name_prev_id != -1)
12264 continue;
12265
12266 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", 12266
, __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", 12266
, "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", 12266
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12267
12268 enum_name = ftype_name(hfinfo->type);
12269 base_name = "";
12270
12271 if (hfinfo->type == FT_CHAR ||
12272 hfinfo->type == FT_UINT8 ||
12273 hfinfo->type == FT_UINT16 ||
12274 hfinfo->type == FT_UINT24 ||
12275 hfinfo->type == FT_UINT32 ||
12276 hfinfo->type == FT_UINT40 ||
12277 hfinfo->type == FT_UINT48 ||
12278 hfinfo->type == FT_UINT56 ||
12279 hfinfo->type == FT_UINT64 ||
12280 hfinfo->type == FT_INT8 ||
12281 hfinfo->type == FT_INT16 ||
12282 hfinfo->type == FT_INT24 ||
12283 hfinfo->type == FT_INT32 ||
12284 hfinfo->type == FT_INT40 ||
12285 hfinfo->type == FT_INT48 ||
12286 hfinfo->type == FT_INT56 ||
12287 hfinfo->type == FT_INT64) {
12288
12289 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12290 case BASE_NONE:
12291 case BASE_DEC:
12292 case BASE_HEX:
12293 case BASE_OCT:
12294 case BASE_DEC_HEX:
12295 case BASE_HEX_DEC:
12296 case BASE_CUSTOM:
12297 case BASE_PT_UDP:
12298 case BASE_PT_TCP:
12299 case BASE_PT_DCCP:
12300 case BASE_PT_SCTP:
12301 case BASE_OUI:
12302 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12303 break;
12304 default:
12305 base_name = "????";
12306 break;
12307 }
12308 } else if (hfinfo->type == FT_BOOLEAN) {
12309 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12310 snprintf(width, sizeof(width), "%d", hfinfo->display);
12311 base_name = width;
12312 }
12313
12314 blurb = hfinfo->blurb;
12315 if (blurb == NULL((void*)0))
12316 blurb = "";
12317 else if (strlen(blurb) == 0)
12318 blurb = "\"\"";
12319
12320 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12321 hfinfo->name, hfinfo->abbrev, enum_name,
12322 parent_hfinfo->abbrev, base_name,
12323 hfinfo->bitmask, blurb);
12324 }
12325 }
12326}
12327
12328/* Dumps all abbreviated field and protocol completions of the given string to
12329 * stdout. An independent program may use this for command-line tab completion
12330 * of fields.
12331 */
12332bool_Bool
12333proto_registrar_dump_field_completions(const char *prefix)
12334{
12335 header_field_info *hfinfo;
12336 int i, len;
12337 size_t prefix_len;
12338 bool_Bool matched = false0;
12339
12340 prefix_len = strlen(prefix);
12341 len = gpa_hfinfo.len;
12342 for (i = 0; i < len ; i++) {
12343 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12344 continue; /* This is a deregistered protocol or header field */
12345
12346 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", 12346
, __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", 12346
, "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", 12346, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12347
12348 /*
12349 * Skip the pseudo-field for "proto_tree_add_text()" since
12350 * we don't want it in the list of filterable fields.
12351 */
12352 if (hfinfo->id == hf_text_only)
12353 continue;
12354
12355 /* format for protocols */
12356 if (proto_registrar_is_protocol(i)) {
12357 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12358 matched = true1;
12359 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12360 }
12361 }
12362 /* format for header fields */
12363 else {
12364 /*
12365 * If this field isn't at the head of the list of
12366 * fields with this name, skip this field - all
12367 * fields with the same name are really just versions
12368 * of the same field stored in different bits, and
12369 * should have the same type/radix/value list, and
12370 * just differ in their bit masks. (If a field isn't
12371 * a bitfield, but can be, say, 1 or 2 bytes long,
12372 * it can just be made FT_UINT16, meaning the
12373 * *maximum* length is 2 bytes, and be used
12374 * for all lengths.)
12375 */
12376 if (hfinfo->same_name_prev_id != -1)
12377 continue;
12378
12379 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12380 matched = true1;
12381 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12382 }
12383 }
12384 }
12385 return matched;
12386}
12387
12388/* Dumps field types and descriptive names to stdout. An independent
12389 * program can take this output and format it into nice tables or HTML or
12390 * whatever.
12391 *
12392 * There is one record per line. The fields are tab-delimited.
12393 *
12394 * Field 1 = field type name, e.g. FT_UINT8
12395 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12396 */
12397void
12398proto_registrar_dump_ftypes(void)
12399{
12400 int fte;
12401
12402 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12403 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12404 }
12405}
12406
12407/* This function indicates whether it's possible to construct a
12408 * "match selected" display filter string for the specified field,
12409 * returns an indication of whether it's possible, and, if it's
12410 * possible and "filter" is non-null, constructs the filter and
12411 * sets "*filter" to point to it.
12412 * You do not need to [g_]free() this string since it will be automatically
12413 * freed once the next packet is dissected.
12414 */
12415static bool_Bool
12416construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12417 char **filter)
12418{
12419 const header_field_info *hfinfo;
12420 char *ptr;
12421 int buf_len;
12422 int i;
12423 int start, length, length_remaining;
12424 uint8_t c;
12425
12426 if (!finfo)
12427 return false0;
12428
12429 hfinfo = finfo->hfinfo;
12430 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12430, "hfinfo"))))
;
12431
12432 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12433 * then "the numeric value ... is not used when preparing
12434 * filters for the field in question." If it's any other
12435 * base, we'll generate the filter normally (which will
12436 * be numeric, even though the human-readable string does
12437 * work for filtering.)
12438 *
12439 * XXX - It might be nice to use fvalue_to_string_repr() in
12440 * "proto_item_fill_label()" as well, although, there, you'd
12441 * have to deal with the base *and* with resolved values for
12442 * addresses.
12443 *
12444 * Perhaps in addition to taking the repr type (DISPLAY
12445 * or DFILTER) and the display (base), fvalue_to_string_repr()
12446 * should have the the "strings" values in the header_field_info
12447 * structure for the field as a parameter, so it can have
12448 * if the field is Boolean or an enumerated integer type,
12449 * the tables used to generate human-readable values.
12450 */
12451 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12452 const char *str = NULL((void*)0);
12453
12454 switch (hfinfo->type) {
12455
12456 case FT_INT8:
12457 case FT_INT16:
12458 case FT_INT24:
12459 case FT_INT32:
12460 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12461 break;
12462
12463 case FT_CHAR:
12464 case FT_UINT8:
12465 case FT_UINT16:
12466 case FT_UINT24:
12467 case FT_UINT32:
12468 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12469 break;
12470
12471 default:
12472 break;
12473 }
12474
12475 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12476 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12477 return true1;
12478 }
12479 }
12480
12481 switch (hfinfo->type) {
12482
12483 case FT_PROTOCOL:
12484 if (filter != NULL((void*)0))
12485 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12486 break;
12487
12488 case FT_NONE:
12489 /*
12490 * If the length is 0, just match the name of the
12491 * field.
12492 *
12493 * (Also check for negative values, just in case,
12494 * as we'll cast it to an unsigned value later.)
12495 */
12496 length = finfo->length;
12497 if (length == 0) {
12498 if (filter != NULL((void*)0))
12499 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12500 break;
12501 }
12502 if (length < 0)
12503 return false0;
12504
12505 /*
12506 * This doesn't have a value, so we'd match
12507 * on the raw bytes at this address.
12508 *
12509 * Should we be allowed to access to the raw bytes?
12510 * If "edt" is NULL, the answer is "no".
12511 */
12512 if (edt == NULL((void*)0))
12513 return false0;
12514
12515 /*
12516 * Is this field part of the raw frame tvbuff?
12517 * If not, we can't use "frame[N:M]" to match
12518 * it.
12519 *
12520 * XXX - should this be frame-relative, or
12521 * protocol-relative?
12522 *
12523 * XXX - does this fallback for non-registered
12524 * fields even make sense?
12525 */
12526 if (finfo->ds_tvb != edt->tvb)
12527 return false0; /* you lose */
12528
12529 /*
12530 * Don't go past the end of that tvbuff.
12531 */
12532 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12533 if (length > length_remaining)
12534 length = length_remaining;
12535 if (length <= 0)
12536 return false0;
12537
12538 if (filter != NULL((void*)0)) {
12539 start = finfo->start;
12540 buf_len = 32 + length * 3;
12541 *filter = (char *)wmem_alloc0(NULL((void*)0), buf_len);
12542 ptr = *filter;
12543
12544 ptr += snprintf(ptr, buf_len-(ptr-*filter),
12545 "frame[%d:%d] == ", finfo->start, length);
12546 for (i=0; i<length; i++) {
12547 c = tvb_get_uint8(finfo->ds_tvb, start);
12548 start++;
12549 if (i == 0 ) {
12550 ptr += snprintf(ptr, buf_len-(ptr-*filter), "%02x", c);
12551 }
12552 else {
12553 ptr += snprintf(ptr, buf_len-(ptr-*filter), ":%02x", c);
12554 }
12555 }
12556 }
12557 break;
12558
12559 /* By default, use the fvalue's "to_string_repr" method. */
12560 default:
12561 if (filter != NULL((void*)0)) {
12562 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12563 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12564 wmem_free(NULL((void*)0), str);
12565 }
12566 break;
12567 }
12568
12569 return true1;
12570}
12571
12572/*
12573 * Returns true if we can do a "match selected" on the field, false
12574 * otherwise.
12575 */
12576bool_Bool
12577proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12578{
12579 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12580}
12581
12582/* This function attempts to construct a "match selected" display filter
12583 * string for the specified field; if it can do so, it returns a pointer
12584 * to the string, otherwise it returns NULL.
12585 *
12586 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12587 */
12588char *
12589proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12590{
12591 char *filter = NULL((void*)0);
12592
12593 if (!construct_match_selected_string(finfo, edt, &filter))
12594 {
12595 wmem_free(NULL((void*)0), filter);
12596 return NULL((void*)0);
12597 }
12598 return filter;
12599}
12600
12601/* This function is common code for all proto_tree_add_bitmask... functions.
12602 */
12603
12604static bool_Bool
12605proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12606 const int len, const int ett, int * const *fields,
12607 const int flags, bool_Bool first,
12608 bool_Bool use_parent_tree,
12609 proto_tree* tree, uint64_t value)
12610{
12611 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12612 uint64_t bitmask = 0;
12613 uint64_t tmpval;
12614 header_field_info *hf;
12615 uint32_t integer32;
12616 int bit_offset;
12617 int no_of_bits;
12618
12619 if (!*fields)
12620 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"
)
;
12621
12622 if (len < 0 || len > 8)
12623 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12624 /**
12625 * packet-frame.c uses len=0 since the value is taken from the packet
12626 * metadata, not the packet bytes. In that case, assume that all bits
12627 * in the provided value are valid.
12628 */
12629 if (len > 0) {
12630 available_bits >>= (8 - (unsigned)len)*8;
12631 }
12632
12633 if (use_parent_tree == false0)
12634 tree = proto_item_add_subtree(item, ett);
12635
12636 while (*fields) {
12637 uint64_t present_bits;
12638 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", 12638, __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", 12638
, "**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", 12638, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12639 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", 12639
, "hf->bitmask != 0", hf->abbrev))))
;
12640
12641 bitmask |= hf->bitmask;
12642
12643 /* Skip fields that aren't fully present */
12644 present_bits = available_bits & hf->bitmask;
12645 if (present_bits != hf->bitmask) {
12646 fields++;
12647 continue;
12648 }
12649
12650 switch (hf->type) {
12651 case FT_CHAR:
12652 case FT_UINT8:
12653 case FT_UINT16:
12654 case FT_UINT24:
12655 case FT_UINT32:
12656 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12657 break;
12658
12659 case FT_INT8:
12660 case FT_INT16:
12661 case FT_INT24:
12662 case FT_INT32:
12663 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12664 break;
12665
12666 case FT_UINT40:
12667 case FT_UINT48:
12668 case FT_UINT56:
12669 case FT_UINT64:
12670 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12671 break;
12672
12673 case FT_INT40:
12674 case FT_INT48:
12675 case FT_INT56:
12676 case FT_INT64:
12677 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12678 break;
12679
12680 case FT_BOOLEAN:
12681 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12682 break;
12683
12684 default:
12685 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))
12686 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))
12687 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))
12688 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))
;
12689 break;
12690 }
12691 if (flags & BMT_NO_APPEND0x01) {
12692 fields++;
12693 continue;
12694 }
12695 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12696
12697 /* XXX: README.developer and the comments have always defined
12698 * BMT_NO_INT as "only boolean flags are added to the title /
12699 * don't add non-boolean (integral) fields", but the
12700 * implementation has always added BASE_CUSTOM and fields with
12701 * value_strings, though not fields with unit_strings.
12702 * Possibly this is because some dissectors use a FT_UINT8
12703 * with a value_string for fields that should be a FT_BOOLEAN.
12704 */
12705 switch (hf->type) {
12706 case FT_CHAR:
12707 if (hf->display == BASE_CUSTOM) {
12708 char lbl[ITEM_LABEL_LENGTH240];
12709 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12710
12711 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12711, "fmtfunc"))))
;
12712 fmtfunc(lbl, (uint32_t) tmpval);
12713 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12714 hf->name, lbl);
12715 first = false0;
12716 }
12717 else if (hf->strings) {
12718 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12719 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12720 first = false0;
12721 }
12722 else if (!(flags & BMT_NO_INT0x02)) {
12723 char buf[32];
12724 const char *out;
12725
12726 if (!first) {
12727 proto_item_append_text(item, ", ");
12728 }
12729
12730 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12731 proto_item_append_text(item, "%s: %s", hf->name, out);
12732 first = false0;
12733 }
12734
12735 break;
12736
12737 case FT_UINT8:
12738 case FT_UINT16:
12739 case FT_UINT24:
12740 case FT_UINT32:
12741 if (hf->display == BASE_CUSTOM) {
12742 char lbl[ITEM_LABEL_LENGTH240];
12743 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12744
12745 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12745, "fmtfunc"))))
;
12746 fmtfunc(lbl, (uint32_t) tmpval);
12747 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12748 hf->name, lbl);
12749 first = false0;
12750 }
12751 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12752 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12753 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12754 first = false0;
12755 }
12756 else if (!(flags & BMT_NO_INT0x02)) {
12757 char buf[NUMBER_LABEL_LENGTH80];
12758 const char *out = NULL((void*)0);
12759
12760 if (!first) {
12761 proto_item_append_text(item, ", ");
12762 }
12763
12764 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12765 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12766 }
12767 if (out == NULL((void*)0)) {
12768 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12769 }
12770 proto_item_append_text(item, "%s: %s", hf->name, out);
12771 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12772 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12773 }
12774 first = false0;
12775 }
12776
12777 break;
12778
12779 case FT_INT8:
12780 case FT_INT16:
12781 case FT_INT24:
12782 case FT_INT32:
12783 integer32 = (uint32_t) tmpval;
12784 if (hf->bitmask) {
12785 no_of_bits = ws_count_ones(hf->bitmask);
12786 integer32 = ws_sign_ext32(integer32, no_of_bits);
12787 }
12788 if (hf->display == BASE_CUSTOM) {
12789 char lbl[ITEM_LABEL_LENGTH240];
12790 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12791
12792 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12792, "fmtfunc"))))
;
12793 fmtfunc(lbl, (int32_t) integer32);
12794 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12795 hf->name, lbl);
12796 first = false0;
12797 }
12798 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12799 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12800 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12801 first = false0;
12802 }
12803 else if (!(flags & BMT_NO_INT0x02)) {
12804 char buf[NUMBER_LABEL_LENGTH80];
12805 const char *out = NULL((void*)0);
12806
12807 if (!first) {
12808 proto_item_append_text(item, ", ");
12809 }
12810
12811 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12812 out = hf_try_val_to_str((int32_t) integer32, hf);
12813 }
12814 if (out == NULL((void*)0)) {
12815 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12816 }
12817 proto_item_append_text(item, "%s: %s", hf->name, out);
12818 if (hf->display & BASE_UNIT_STRING0x00001000) {
12819 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12820 }
12821 first = false0;
12822 }
12823
12824 break;
12825
12826 case FT_UINT40:
12827 case FT_UINT48:
12828 case FT_UINT56:
12829 case FT_UINT64:
12830 if (hf->display == BASE_CUSTOM) {
12831 char lbl[ITEM_LABEL_LENGTH240];
12832 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12833
12834 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12834, "fmtfunc"))))
;
12835 fmtfunc(lbl, tmpval);
12836 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12837 hf->name, lbl);
12838 first = false0;
12839 }
12840 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12841 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12842 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12843 first = false0;
12844 }
12845 else if (!(flags & BMT_NO_INT0x02)) {
12846 char buf[NUMBER_LABEL_LENGTH80];
12847 const char *out = NULL((void*)0);
12848
12849 if (!first) {
12850 proto_item_append_text(item, ", ");
12851 }
12852
12853 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12854 out = hf_try_val64_to_str(tmpval, hf);
12855 }
12856 if (out == NULL((void*)0)) {
12857 out = hfinfo_number_value_format64(hf, buf, tmpval);
12858 }
12859 proto_item_append_text(item, "%s: %s", hf->name, out);
12860 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12861 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12862 }
12863 first = false0;
12864 }
12865
12866 break;
12867
12868 case FT_INT40:
12869 case FT_INT48:
12870 case FT_INT56:
12871 case FT_INT64:
12872 if (hf->bitmask) {
12873 no_of_bits = ws_count_ones(hf->bitmask);
12874 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12875 }
12876 if (hf->display == BASE_CUSTOM) {
12877 char lbl[ITEM_LABEL_LENGTH240];
12878 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12879
12880 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12880, "fmtfunc"))))
;
12881 fmtfunc(lbl, (int64_t) tmpval);
12882 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12883 hf->name, lbl);
12884 first = false0;
12885 }
12886 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12887 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12888 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12889 first = false0;
12890 }
12891 else if (!(flags & BMT_NO_INT0x02)) {
12892 char buf[NUMBER_LABEL_LENGTH80];
12893 const char *out = NULL((void*)0);
12894
12895 if (!first) {
12896 proto_item_append_text(item, ", ");
12897 }
12898
12899 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12900 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12901 }
12902 if (out == NULL((void*)0)) {
12903 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12904 }
12905 proto_item_append_text(item, "%s: %s", hf->name, out);
12906 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12907 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12908 }
12909 first = false0;
12910 }
12911
12912 break;
12913
12914 case FT_BOOLEAN:
12915 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12916 /* If we have true/false strings, emit full - otherwise messages
12917 might look weird */
12918 const struct true_false_string *tfs =
12919 (const struct true_false_string *)hf->strings;
12920
12921 if (tmpval) {
12922 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12923 hf->name, tfs->true_string);
12924 first = false0;
12925 } else if (!(flags & BMT_NO_FALSE0x04)) {
12926 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12927 hf->name, tfs->false_string);
12928 first = false0;
12929 }
12930 } else if (hf->bitmask & value) {
12931 /* If the flag is set, show the name */
12932 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
12933 first = false0;
12934 }
12935 break;
12936 default:
12937 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))
12938 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))
12939 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))
12940 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))
;
12941 break;
12942 }
12943
12944 fields++;
12945 }
12946
12947 /* XXX: We don't pass the hfi into this function. Perhaps we should,
12948 * but then again most dissectors don't set the bitmask field for
12949 * the higher level bitmask hfi, so calculate the bitmask from the
12950 * fields present. */
12951 if (item) {
12952 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
12953 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
12954 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)
;
12955 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)
;
12956 }
12957 return first;
12958}
12959
12960/* This function will dissect a sequence of bytes that describe a
12961 * bitmask and supply the value of that sequence through a pointer.
12962 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12963 * to be dissected.
12964 * This field will form an expansion under which the individual fields of the
12965 * bitmask is dissected and displayed.
12966 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12967 *
12968 * fields is an array of pointers to int that lists all the fields of the
12969 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12970 * or another integer of the same type/size as hf_hdr with a mask specified.
12971 * This array is terminated by a NULL entry.
12972 *
12973 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
12974 * FT_integer fields that have a value_string attached will have the
12975 * matched string displayed on the expansion line.
12976 */
12977proto_item *
12978proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
12979 const unsigned offset, const int hf_hdr,
12980 const int ett, int * const *fields,
12981 const unsigned encoding, uint64_t *retval)
12982{
12983 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);
12984}
12985
12986/* This function will dissect a sequence of bytes that describe a
12987 * bitmask.
12988 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12989 * to be dissected.
12990 * This field will form an expansion under which the individual fields of the
12991 * bitmask is dissected and displayed.
12992 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12993 *
12994 * fields is an array of pointers to int that lists all the fields of the
12995 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12996 * or another integer of the same type/size as hf_hdr with a mask specified.
12997 * This array is terminated by a NULL entry.
12998 *
12999 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13000 * FT_integer fields that have a value_string attached will have the
13001 * matched string displayed on the expansion line.
13002 */
13003proto_item *
13004proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13005 const unsigned offset, const int hf_hdr,
13006 const int ett, int * const *fields,
13007 const unsigned encoding)
13008{
13009 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13010}
13011
13012/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13013 * what data is appended to the header.
13014 */
13015proto_item *
13016proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13017 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13018 uint64_t *retval)
13019{
13020 proto_item *item = NULL((void*)0);
13021 header_field_info *hf;
13022 int len;
13023 uint64_t value;
13024
13025 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", 13025, __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", 13025
, "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", 13025, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13026 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", 13026, (hf)->abbrev)))
;
13027 len = ftype_wire_size(hf->type);
13028 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13029
13030 if (parent_tree) {
13031 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13032 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13033 flags, false0, false0, NULL((void*)0), value);
13034 }
13035
13036 *retval = value;
13037 if (hf->bitmask) {
13038 /* Mask out irrelevant portions */
13039 *retval &= hf->bitmask;
13040 /* Shift bits */
13041 *retval >>= hfinfo_bitshift(hf);
13042 }
13043
13044 return item;
13045}
13046
13047/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13048 * what data is appended to the header.
13049 */
13050proto_item *
13051proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13052 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13053{
13054 proto_item *item = NULL((void*)0);
13055 header_field_info *hf;
13056 int len;
13057 uint64_t value;
13058
13059 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", 13059, __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", 13059
, "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", 13059, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13060 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", 13060, (hf)->abbrev)))
;
13061
13062 if (parent_tree) {
13063 len = ftype_wire_size(hf->type);
13064 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13065 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13066 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13067 flags, false0, false0, NULL((void*)0), value);
13068 }
13069
13070 return item;
13071}
13072
13073/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13074 can't be retrieved directly from tvb) */
13075proto_item *
13076proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13077 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13078{
13079 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13080 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13081}
13082
13083/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13084WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13085proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13086 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13087{
13088 proto_item *item = NULL((void*)0);
13089 header_field_info *hf;
13090 int len;
13091
13092 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", 13092, __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", 13092
, "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", 13092, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13093 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", 13093, (hf)->abbrev)))
;
13094 /* the proto_tree_add_uint/_uint64() calls below
13095 will fail if tvb==NULL and len!=0 */
13096 len = tvb ? ftype_wire_size(hf->type) : 0;
13097
13098 if (parent_tree) {
13099 if (len <= 4)
13100 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13101 else
13102 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13103
13104 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13105 flags, false0, false0, NULL((void*)0), value);
13106 }
13107
13108 return item;
13109}
13110
13111/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13112void
13113proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13114 const int len, int * const *fields, const unsigned encoding)
13115{
13116 uint64_t value;
13117
13118 if (tree) {
13119 value = get_uint64_value(tree, tvb, offset, len, encoding);
13120 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13121 BMT_NO_APPEND0x01, false0, true1, tree, value);
13122 }
13123}
13124
13125WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13126proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13127 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13128{
13129 uint64_t value;
13130
13131 value = get_uint64_value(tree, tvb, offset, len, encoding);
13132 if (tree) {
13133 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13134 BMT_NO_APPEND0x01, false0, true1, tree, value);
13135 }
13136 if (retval) {
13137 *retval = value;
13138 }
13139}
13140
13141WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13142proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13143 const int len, int * const *fields, const uint64_t value)
13144{
13145 if (tree) {
13146 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13147 BMT_NO_APPEND0x01, false0, true1, tree, value);
13148 }
13149}
13150
13151
13152/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13153 * This is intended to support bitmask fields whose lengths can vary, perhaps
13154 * as the underlying standard evolves over time.
13155 * With this API there is the possibility of being called to display more or
13156 * less data than the dissector was coded to support.
13157 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13158 * Thus when presented with "too much" or "too little" data, MSbits will be
13159 * ignored or MSfields sacrificed.
13160 *
13161 * Only fields for which all defined bits are available are displayed.
13162 */
13163proto_item *
13164proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13165 const unsigned offset, const unsigned len, const int hf_hdr,
13166 const int ett, int * const *fields, struct expert_field* exp,
13167 const unsigned encoding)
13168{
13169 proto_item *item = NULL((void*)0);
13170 header_field_info *hf;
13171 unsigned decodable_len;
13172 unsigned decodable_offset;
13173 uint32_t decodable_value;
13174 uint64_t value;
13175
13176 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", 13176, __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", 13176
, "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", 13176, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13177 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", 13177, (hf)->abbrev)))
;
13178
13179 decodable_offset = offset;
13180 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13181
13182 /* If we are ftype_wire_size-limited,
13183 * make sure we decode as many LSBs as possible.
13184 */
13185 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13186 decodable_offset += (len - decodable_len);
13187 }
13188
13189 if (parent_tree) {
13190 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13191 decodable_len, encoding);
13192
13193 /* The root item covers all the bytes even if we can't decode them all */
13194 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13195 decodable_value);
13196 }
13197
13198 if (decodable_len < len) {
13199 /* Dissector likely requires updating for new protocol revision */
13200 expert_add_info_format(NULL((void*)0), item, exp,
13201 "Only least-significant %d of %d bytes decoded",
13202 decodable_len, len);
13203 }
13204
13205 if (item) {
13206 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13207 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13208 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13209 }
13210
13211 return item;
13212}
13213
13214/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13215proto_item *
13216proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13217 const unsigned offset, const unsigned len,
13218 const char *name, const char *fallback,
13219 const int ett, int * const *fields,
13220 const unsigned encoding, const int flags)
13221{
13222 proto_item *item = NULL((void*)0);
13223 uint64_t value;
13224
13225 if (parent_tree) {
13226 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13227 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13228 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13229 flags, true1, false0, NULL((void*)0), value) && fallback) {
13230 /* Still at first item - append 'fallback' text if any */
13231 proto_item_append_text(item, "%s", fallback);
13232 }
13233 }
13234
13235 return item;
13236}
13237
13238proto_item *
13239proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13240 const unsigned bit_offset, const int no_of_bits,
13241 const unsigned encoding)
13242{
13243 header_field_info *hfinfo;
13244 int octet_length;
13245 int octet_offset;
13246
13247 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", 13247, __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", 13247
, "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", 13247, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13248
13249 if (no_of_bits < 0) {
13250 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13251 }
13252 octet_length = (no_of_bits + 7) >> 3;
13253 octet_offset = bit_offset >> 3;
13254 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13255
13256 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13257 * but only after doing a bunch more work (which we can, in the common
13258 * case, shortcut here).
13259 */
13260 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13261 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", 13261
, __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", 13261, "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", 13261, "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", 13261, __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)
; } } }
;
13262
13263 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13264}
13265
13266/*
13267 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13268 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13269 * Offset should be given in bits from the start of the tvb.
13270 */
13271
13272static proto_item *
13273_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13274 const unsigned bit_offset, const int no_of_bits,
13275 uint64_t *return_value, const unsigned encoding)
13276{
13277 int offset;
13278 unsigned length;
13279 uint8_t tot_no_bits;
13280 char *bf_str;
13281 char lbl_str[ITEM_LABEL_LENGTH240];
13282 uint64_t value = 0;
13283 uint8_t *bytes = NULL((void*)0);
13284 size_t bytes_length = 0;
13285
13286 proto_item *pi;
13287 header_field_info *hf_field;
13288
13289 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13290 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", 13290, __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", 13290
, "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", 13290, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13291
13292 if (hf_field->bitmask != 0) {
13293 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)
13294 " 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)
13295 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)
;
13296 }
13297
13298 if (no_of_bits < 0) {
13299 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13300 } else if (no_of_bits == 0) {
13301 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)
13302 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)
;
13303 }
13304
13305 /* Byte align offset */
13306 offset = bit_offset>>3;
13307
13308 /*
13309 * Calculate the number of octets used to hold the bits
13310 */
13311 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13312 length = (tot_no_bits + 7) >> 3;
13313
13314 if (no_of_bits < 65) {
13315 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13316 } else if (hf_field->type != FT_BYTES) {
13317 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)
13318 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)
;
13319 return NULL((void*)0);
13320 }
13321
13322 /* Sign extend for signed types */
13323 switch (hf_field->type) {
13324 case FT_INT8:
13325 case FT_INT16:
13326 case FT_INT24:
13327 case FT_INT32:
13328 case FT_INT40:
13329 case FT_INT48:
13330 case FT_INT56:
13331 case FT_INT64:
13332 value = ws_sign_ext64(value, no_of_bits);
13333 break;
13334
13335 default:
13336 break;
13337 }
13338
13339 if (return_value) {
13340 *return_value = value;
13341 }
13342
13343 /* Coast clear. Try and fake it */
13344 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13345 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", 13345
, __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", 13345, "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", 13345, "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", 13345, __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); } } }
;
13346
13347 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13348
13349 switch (hf_field->type) {
13350 case FT_BOOLEAN:
13351 /* Boolean field */
13352 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13353 "%s = %s: %s",
13354 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13355 break;
13356
13357 case FT_CHAR:
13358 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13359 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13360 break;
13361
13362 case FT_UINT8:
13363 case FT_UINT16:
13364 case FT_UINT24:
13365 case FT_UINT32:
13366 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13367 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13368 break;
13369
13370 case FT_INT8:
13371 case FT_INT16:
13372 case FT_INT24:
13373 case FT_INT32:
13374 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13375 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13376 break;
13377
13378 case FT_UINT40:
13379 case FT_UINT48:
13380 case FT_UINT56:
13381 case FT_UINT64:
13382 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13383 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13384 break;
13385
13386 case FT_INT40:
13387 case FT_INT48:
13388 case FT_INT56:
13389 case FT_INT64:
13390 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13391 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13392 break;
13393
13394 case FT_BYTES:
13395 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13396 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13397 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13398 proto_item_set_text(pi, "%s", lbl_str);
13399 return pi;
13400
13401 /* TODO: should handle FT_UINT_BYTES ? */
13402
13403 default:
13404 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))
13405 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))
13406 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))
13407 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))
;
13408 return NULL((void*)0);
13409 }
13410
13411 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13412 return pi;
13413}
13414
13415proto_item *
13416proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13417 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13418 uint64_t *return_value)
13419{
13420 proto_item *pi;
13421 int no_of_bits;
13422 int octet_offset;
13423 unsigned mask_initial_bit_offset;
13424 unsigned mask_greatest_bit_offset;
13425 unsigned octet_length;
13426 uint8_t i;
13427 char bf_str[256];
13428 char lbl_str[ITEM_LABEL_LENGTH240];
13429 uint64_t value;
13430 uint64_t composite_bitmask;
13431 uint64_t composite_bitmap;
13432
13433 header_field_info *hf_field;
13434
13435 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13436 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", 13436, __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", 13436
, "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", 13436, "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
13437
13438 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13439 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)
13440 " 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)
13441 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)
;
13442 }
13443
13444 mask_initial_bit_offset = bit_offset % 8;
13445
13446 no_of_bits = 0;
13447 value = 0;
13448 i = 0;
13449 mask_greatest_bit_offset = 0;
13450 composite_bitmask = 0;
13451 composite_bitmap = 0;
13452
13453 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
13454 uint64_t crumb_mask, crumb_value;
13455 uint8_t crumb_end_bit_offset;
13456
13457 crumb_value = tvb_get_bits64(tvb,
13458 bit_offset + crumb_spec[i].crumb_bit_offset,
13459 crumb_spec[i].crumb_bit_length,
13460 ENC_BIG_ENDIAN0x00000000);
13461 value += crumb_value;
13462 no_of_bits += crumb_spec[i].crumb_bit_length;
13463 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", 13463
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13464
13465 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13466 octet containing the initial offset.
13467 If the mask is beyond 32 bits, then give up on bit map display.
13468 This could be improved in future, probably showing a table
13469 of 32 or 64 bits per row */
13470 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13471 crumb_end_bit_offset = mask_initial_bit_offset
13472 + crumb_spec[i].crumb_bit_offset
13473 + crumb_spec[i].crumb_bit_length;
13474 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'
13475
13476 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13477 mask_greatest_bit_offset = crumb_end_bit_offset;
13478 }
13479 /* Currently the bitmap of the crumbs are only shown if
13480 * smaller than 32 bits. Do not bother calculating the
13481 * mask if it is larger than that. */
13482 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13483 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'
13484 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13485 }
13486 }
13487 /* Shift left for the next segment */
13488 value <<= crumb_spec[++i].crumb_bit_length;
13489 }
13490
13491 /* Sign extend for signed types */
13492 switch (hf_field->type) {
13493 case FT_INT8:
13494 case FT_INT16:
13495 case FT_INT24:
13496 case FT_INT32:
13497 case FT_INT40:
13498 case FT_INT48:
13499 case FT_INT56:
13500 case FT_INT64:
13501 value = ws_sign_ext64(value, no_of_bits);
13502 break;
13503 default:
13504 break;
13505 }
13506
13507 if (return_value) {
13508 *return_value = value;
13509 }
13510
13511 /* Coast clear. Try and fake it */
13512 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13513 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", 13513
, __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", 13513, "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", 13513, "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", 13513, __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); } } }
;
13514
13515 /* initialise the format string */
13516 bf_str[0] = '\0';
13517
13518 octet_offset = bit_offset >> 3;
13519
13520 /* Round up mask length to nearest octet */
13521 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13522 mask_greatest_bit_offset = octet_length << 3;
13523
13524 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13525 It would be a useful enhancement to eliminate this restriction. */
13526 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13527 other_decode_bitfield_value(bf_str,
13528 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13529 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13530 mask_greatest_bit_offset);
13531 } else {
13532 /* If the bitmask is too large, try to describe its contents. */
13533 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13534 }
13535
13536 switch (hf_field->type) {
13537 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13538 /* Boolean field */
13539 return proto_tree_add_boolean_format(tree, hfindex,
13540 tvb, octet_offset, octet_length, value,
13541 "%s = %s: %s",
13542 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13543 break;
13544
13545 case FT_CHAR:
13546 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13547 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13548 break;
13549
13550 case FT_UINT8:
13551 case FT_UINT16:
13552 case FT_UINT24:
13553 case FT_UINT32:
13554 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13555 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13556 break;
13557
13558 case FT_INT8:
13559 case FT_INT16:
13560 case FT_INT24:
13561 case FT_INT32:
13562 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13563 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13564 break;
13565
13566 case FT_UINT40:
13567 case FT_UINT48:
13568 case FT_UINT56:
13569 case FT_UINT64:
13570 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13571 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13572 break;
13573
13574 case FT_INT40:
13575 case FT_INT48:
13576 case FT_INT56:
13577 case FT_INT64:
13578 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13579 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13580 break;
13581
13582 default:
13583 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))
13584 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))
13585 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))
13586 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))
;
13587 return NULL((void*)0);
13588 }
13589 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13590 return pi;
13591}
13592
13593void
13594proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13595 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13596{
13597 header_field_info *hfinfo;
13598 int start = bit_offset >> 3;
13599 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13600
13601 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13602 * so that we can use the tree's memory scope in calculating the string */
13603 if (length == -1) {
13604 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13605 } else {
13606 tvb_ensure_bytes_exist(tvb, start, length);
13607 }
13608 if (!tree) return;
13609
13610 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", 13610, __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", 13610
, "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", 13610, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13611 proto_tree_add_text_internal(tree, tvb, start, length,
13612 "%s crumb %d of %s (decoded above)",
13613 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13614 tvb_get_bits32(tvb,
13615 bit_offset,
13616 crumb_spec[crumb_index].crumb_bit_length,
13617 ENC_BIG_ENDIAN0x00000000),
13618 ENC_BIG_ENDIAN0x00000000),
13619 crumb_index,
13620 hfinfo->name);
13621}
13622
13623proto_item *
13624proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13625 const unsigned bit_offset, const int no_of_bits,
13626 uint64_t *return_value, const unsigned encoding)
13627{
13628 proto_item *item;
13629
13630 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13631 bit_offset, no_of_bits,
13632 return_value, encoding))) {
13633 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)
;
13634 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)
;
13635 }
13636 return item;
13637}
13638
13639static proto_item *
13640_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13641 tvbuff_t *tvb, const unsigned bit_offset,
13642 const int no_of_bits, void *value_ptr,
13643 const unsigned encoding, char *value_str)
13644{
13645 int offset;
13646 unsigned length;
13647 uint8_t tot_no_bits;
13648 char *str;
13649 uint64_t value = 0;
13650 header_field_info *hf_field;
13651
13652 /* We do not have to return a value, try to fake it as soon as possible */
13653 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13654 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", 13654
, __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", 13654, "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", 13654, "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", 13654, __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); } } }
;
13655
13656 if (hf_field->bitmask != 0) {
13657 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)
13658 " 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)
13659 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)
;
13660 }
13661
13662 if (no_of_bits < 0) {
13663 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13664 } else if (no_of_bits == 0) {
13665 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)
13666 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)
;
13667 }
13668
13669 /* Byte align offset */
13670 offset = bit_offset>>3;
13671
13672 /*
13673 * Calculate the number of octets used to hold the bits
13674 */
13675 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13676 length = tot_no_bits>>3;
13677 /* If we are using part of the next octet, increase length by 1 */
13678 if (tot_no_bits & 0x07)
13679 length++;
13680
13681 if (no_of_bits < 65) {
13682 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13683 } else {
13684 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)
13685 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)
;
13686 return NULL((void*)0);
13687 }
13688
13689 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13690
13691 (void) g_strlcat(str, " = ", 256+64);
13692 (void) g_strlcat(str, hf_field->name, 256+64);
13693
13694 /*
13695 * This function does not receive an actual value but a dimensionless pointer to that value.
13696 * For this reason, the type of the header field is examined in order to determine
13697 * what kind of value we should read from this address.
13698 * The caller of this function must make sure that for the specific header field type the address of
13699 * a compatible value is provided.
13700 */
13701 switch (hf_field->type) {
13702 case FT_BOOLEAN:
13703 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13704 "%s: %s", str, value_str);
13705 break;
13706
13707 case FT_CHAR:
13708 case FT_UINT8:
13709 case FT_UINT16:
13710 case FT_UINT24:
13711 case FT_UINT32:
13712 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13713 "%s: %s", str, value_str);
13714 break;
13715
13716 case FT_UINT40:
13717 case FT_UINT48:
13718 case FT_UINT56:
13719 case FT_UINT64:
13720 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13721 "%s: %s", str, value_str);
13722 break;
13723
13724 case FT_INT8:
13725 case FT_INT16:
13726 case FT_INT24:
13727 case FT_INT32:
13728 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13729 "%s: %s", str, value_str);
13730 break;
13731
13732 case FT_INT40:
13733 case FT_INT48:
13734 case FT_INT56:
13735 case FT_INT64:
13736 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13737 "%s: %s", str, value_str);
13738 break;
13739
13740 case FT_FLOAT:
13741 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13742 "%s: %s", str, value_str);
13743 break;
13744
13745 default:
13746 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))
13747 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))
13748 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))
13749 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))
;
13750 return NULL((void*)0);
13751 }
13752}
13753
13754static proto_item *
13755proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13756 tvbuff_t *tvb, const unsigned bit_offset,
13757 const int no_of_bits, void *value_ptr,
13758 const unsigned encoding, char *value_str)
13759{
13760 proto_item *item;
13761
13762 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13763 tvb, bit_offset, no_of_bits,
13764 value_ptr, encoding, value_str))) {
13765 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)
;
13766 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)
;
13767 }
13768 return item;
13769}
13770
13771#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);
\
13772 va_start(ap, format)__builtin_va_start(ap, format); \
13773 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13774 va_end(ap)__builtin_va_end(ap);
13775
13776proto_item *
13777proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13778 tvbuff_t *tvb, const unsigned bit_offset,
13779 const int no_of_bits, uint32_t value,
13780 const unsigned encoding,
13781 const char *format, ...)
13782{
13783 va_list ap;
13784 char *dst;
13785 header_field_info *hf_field;
13786
13787 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13788
13789 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", 13789
, __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", 13789, "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", 13789, "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", 13789, __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); } } }
;
13790
13791 switch (hf_field->type) {
13792 case FT_UINT8:
13793 case FT_UINT16:
13794 case FT_UINT24:
13795 case FT_UINT32:
13796 break;
13797
13798 default:
13799 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)
13800 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)
;
13801 return NULL((void*)0);
13802 }
13803
13804 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);
;
13805
13806 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13807}
13808
13809proto_item *
13810proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13811 tvbuff_t *tvb, const unsigned bit_offset,
13812 const int no_of_bits, uint64_t value,
13813 const unsigned encoding,
13814 const char *format, ...)
13815{
13816 va_list ap;
13817 char *dst;
13818 header_field_info *hf_field;
13819
13820 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13821
13822 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", 13822
, __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", 13822, "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", 13822, "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", 13822, __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); } } }
;
13823
13824 switch (hf_field->type) {
13825 case FT_UINT40:
13826 case FT_UINT48:
13827 case FT_UINT56:
13828 case FT_UINT64:
13829 break;
13830
13831 default:
13832 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)
13833 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)
;
13834 return NULL((void*)0);
13835 }
13836
13837 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);
;
13838
13839 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13840}
13841
13842proto_item *
13843proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13844 tvbuff_t *tvb, const unsigned bit_offset,
13845 const int no_of_bits, float value,
13846 const unsigned encoding,
13847 const char *format, ...)
13848{
13849 va_list ap;
13850 char *dst;
13851 header_field_info *hf_field;
13852
13853 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13854
13855 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", 13855
, __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", 13855, "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", 13855, "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", 13855, __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); } } }
;
13856
13857 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",
13857, ((hf_field))->abbrev))))
;
13858
13859 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);
;
13860
13861 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13862}
13863
13864proto_item *
13865proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13866 tvbuff_t *tvb, const unsigned bit_offset,
13867 const int no_of_bits, int32_t value,
13868 const unsigned encoding,
13869 const char *format, ...)
13870{
13871 va_list ap;
13872 char *dst;
13873 header_field_info *hf_field;
13874
13875 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13876
13877 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", 13877
, __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", 13877, "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", 13877, "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", 13877, __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); } } }
;
13878
13879 switch (hf_field->type) {
13880 case FT_INT8:
13881 case FT_INT16:
13882 case FT_INT24:
13883 case FT_INT32:
13884 break;
13885
13886 default:
13887 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)
13888 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)
;
13889 return NULL((void*)0);
13890 }
13891
13892 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);
;
13893
13894 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13895}
13896
13897proto_item *
13898proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13899 tvbuff_t *tvb, const unsigned bit_offset,
13900 const int no_of_bits, int64_t value,
13901 const unsigned encoding,
13902 const char *format, ...)
13903{
13904 va_list ap;
13905 char *dst;
13906 header_field_info *hf_field;
13907
13908 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13909
13910 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", 13910
, __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", 13910, "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", 13910, "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", 13910, __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); } } }
;
13911
13912 switch (hf_field->type) {
13913 case FT_INT40:
13914 case FT_INT48:
13915 case FT_INT56:
13916 case FT_INT64:
13917 break;
13918
13919 default:
13920 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)
13921 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)
;
13922 return NULL((void*)0);
13923 }
13924
13925 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);
;
13926
13927 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13928}
13929
13930proto_item *
13931proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
13932 tvbuff_t *tvb, const unsigned bit_offset,
13933 const int no_of_bits, uint64_t value,
13934 const unsigned encoding,
13935 const char *format, ...)
13936{
13937 va_list ap;
13938 char *dst;
13939 header_field_info *hf_field;
13940
13941 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13942
13943 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", 13943
, __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", 13943, "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", 13943, "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", 13943, __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); } } }
;
13944
13945 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"
, 13945, ((hf_field))->abbrev))))
;
13946
13947 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);
;
13948
13949 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13950}
13951
13952proto_item *
13953proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13954 const unsigned bit_offset, const int no_of_chars)
13955{
13956 proto_item *pi;
13957 header_field_info *hfinfo;
13958 int byte_length;
13959 int byte_offset;
13960 char *string;
13961
13962 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13963
13964 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", 13964
, __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", 13964, "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", 13964, "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", 13964, __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)
; } } }
;
13965
13966 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"
, 13966, ((hfinfo))->abbrev))))
;
13967
13968 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13969 byte_offset = bit_offset >> 3;
13970
13971 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
13972
13973 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
13974 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 13974, "byte_length >= 0"
))))
;
13975 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
13976
13977 return pi;
13978}
13979
13980proto_item *
13981proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13982 const unsigned bit_offset, const int no_of_chars)
13983{
13984 proto_item *pi;
13985 header_field_info *hfinfo;
13986 int byte_length;
13987 int byte_offset;
13988 char *string;
13989
13990 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13991
13992 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", 13992
, __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", 13992, "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", 13992, "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", 13992, __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)
; } } }
;
13993
13994 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"
, 13994, ((hfinfo))->abbrev))))
;
13995
13996 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13997 byte_offset = bit_offset >> 3;
13998
13999 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14000
14001 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14002 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14002, "byte_length >= 0"
))))
;
14003 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14004
14005 return pi;
14006}
14007
14008const value_string proto_checksum_vals[] = {
14009 { PROTO_CHECKSUM_E_BAD, "Bad" },
14010 { PROTO_CHECKSUM_E_GOOD, "Good" },
14011 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14012 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14013 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14014
14015 { 0, NULL((void*)0) }
14016};
14017
14018proto_item *
14019proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14020 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14021 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14022{
14023 header_field_info *hfinfo;
14024 uint32_t checksum;
14025 uint32_t len;
14026 proto_item* ti = NULL((void*)0);
14027 proto_item* ti2;
14028 bool_Bool incorrect_checksum = true1;
14029
14030 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", 14030, __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", 14030
, "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", 14030, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14031
14032 switch (hfinfo->type) {
14033 case FT_UINT8:
14034 len = 1;
14035 break;
14036 case FT_UINT16:
14037 len = 2;
14038 break;
14039 case FT_UINT24:
14040 len = 3;
14041 break;
14042 case FT_UINT32:
14043 len = 4;
14044 break;
14045 default:
14046 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)
14047 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14048 }
14049
14050 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14051 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14052 proto_item_set_generated(ti);
14053 if (hf_checksum_status != -1) {
14054 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14055 proto_item_set_generated(ti2);
14056 }
14057 return ti;
14058 }
14059
14060 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14061 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14062 proto_item_set_generated(ti);
14063 } else {
14064 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14065 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14066 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14067 if (computed_checksum == 0) {
14068 proto_item_append_text(ti, " [correct]");
14069 if (hf_checksum_status != -1) {
14070 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14071 proto_item_set_generated(ti2);
14072 }
14073 incorrect_checksum = false0;
14074 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14075 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14076 /* XXX - This can't distinguish between "shouldbe"
14077 * 0x0000 and 0xFFFF unless we know whether there
14078 * were any nonzero bits (other than the checksum).
14079 * Protocols should not use this path if they might
14080 * have an all zero packet.
14081 * Some implementations put the wrong zero; maybe
14082 * we should have a special expert info for that?
14083 */
14084 }
14085 } else {
14086 if (checksum == computed_checksum) {
14087 proto_item_append_text(ti, " [correct]");
14088 if (hf_checksum_status != -1) {
14089 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14090 proto_item_set_generated(ti2);
14091 }
14092 incorrect_checksum = false0;
14093 }
14094 }
14095
14096 if (incorrect_checksum) {
14097 if (hf_checksum_status != -1) {
14098 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14099 proto_item_set_generated(ti2);
14100 }
14101 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14102 proto_item_append_text(ti, " [incorrect]");
14103 if (bad_checksum_expert != NULL((void*)0))
14104 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14105 } else {
14106 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14107 if (bad_checksum_expert != NULL((void*)0))
14108 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);
14109 }
14110 }
14111 } else {
14112 if (hf_checksum_status != -1) {
14113 proto_item_append_text(ti, " [unverified]");
14114 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14115 proto_item_set_generated(ti2);
14116 }
14117 }
14118 }
14119
14120 return ti;
14121}
14122
14123proto_item *
14124proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14125 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14126 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14127{
14128 header_field_info *hfinfo;
14129 uint8_t *checksum = NULL((void*)0);
14130 proto_item* ti = NULL((void*)0);
14131 proto_item* ti2;
14132 bool_Bool incorrect_checksum = true1;
14133
14134 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", 14134, __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", 14134
, "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", 14134, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14135
14136 if (hfinfo->type != FT_BYTES) {
14137 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)
14138 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
14139 }
14140
14141 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14142 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14143 proto_item_set_generated(ti);
14144 if (hf_checksum_status != -1) {
14145 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14146 proto_item_set_generated(ti2);
14147 }
14148 return ti;
14149 }
14150
14151 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14152 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14153 proto_item_set_generated(ti);
14154 } else {
14155 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
))))))
;
14156 tvb_memcpy(tvb, checksum, offset, checksum_len);
14157 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14158 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14159 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14160 if (computed_checksum == 0) {
14161 proto_item_append_text(ti, " [correct]");
14162 if (hf_checksum_status != -1) {
14163 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14164 proto_item_set_generated(ti2);
14165 }
14166 incorrect_checksum = false0;
14167 }
14168 } else {
14169 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14170 proto_item_append_text(ti, " [correct]");
14171 if (hf_checksum_status != -1) {
14172 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14173 proto_item_set_generated(ti2);
14174 }
14175 incorrect_checksum = false0;
14176 }
14177 }
14178
14179 if (incorrect_checksum) {
14180 if (hf_checksum_status != -1) {
14181 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14182 proto_item_set_generated(ti2);
14183 }
14184 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14185 proto_item_append_text(ti, " [incorrect]");
14186 if (bad_checksum_expert != NULL((void*)0))
14187 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14188 } else {
14189 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14190 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))))))
;
14191 for (size_t counter = 0; counter < checksum_len; ++counter) {
14192 snprintf(
14193 /* On ecah iteration inserts two characters */
14194 (char*)&computed_checksum_str[counter << 1],
14195 computed_checksum_str_len - (counter << 1),
14196 "%02x",
14197 computed_checksum[counter]);
14198 }
14199 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14200 if (bad_checksum_expert != NULL((void*)0))
14201 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14202 }
14203 }
14204 } else {
14205 if (hf_checksum_status != -1) {
14206 proto_item_append_text(ti, " [unverified]");
14207 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14208 proto_item_set_generated(ti2);
14209 }
14210 }
14211 }
14212
14213 return ti;
14214}
14215
14216unsigned char
14217proto_check_field_name(const char *field_name)
14218{
14219 return module_check_valid_name(field_name, false0);
14220}
14221
14222unsigned char
14223proto_check_field_name_lower(const char *field_name)
14224{
14225 return module_check_valid_name(field_name, true1);
14226}
14227
14228bool_Bool
14229tree_expanded(int tree_type)
14230{
14231 if (tree_type <= 0) {
14232 return false0;
14233 }
14234 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", 14234, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14235 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14236}
14237
14238void
14239tree_expanded_set(int tree_type, bool_Bool value)
14240{
14241 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", 14241, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14242
14243 if (value)
14244 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14245 else
14246 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14247}
14248
14249/*
14250 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14251 *
14252 * Local variables:
14253 * c-basic-offset: 8
14254 * tab-width: 8
14255 * indent-tabs-mode: t
14256 * End:
14257 *
14258 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14259 * :indentSize=8:tabSize=8:noTabs=false:
14260 */