Bug Summary

File:epan/proto.c
Warning:line 13550, 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-20/lib/clang/20 -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-20/lib/clang/20/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 -fwrapv-pointer -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-08-29-100438-3933-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#include <wsutil/filesystem.h>
31#ifdef HAVE_UNISTD_H1
32#include <unistd.h>
33#endif
34
35#include <ftypes/ftypes.h>
36
37#include "packet.h"
38#include "exceptions.h"
39#include "ptvcursor.h"
40#include "strutil.h"
41#include "addr_resolv.h"
42#include "address_types.h"
43#include "oids.h"
44#include "proto.h"
45#include "epan_dissect.h"
46#include "dfilter/dfilter.h"
47#include "tvbuff.h"
48#include "charsets.h"
49#include "column-info.h"
50#include "to_str.h"
51#include "osi-utils.h"
52#include "expert.h"
53#include "show_exception.h"
54#include "in_cksum.h"
55#include "register-int.h"
56
57#include <wsutil/crash_info.h>
58#include <wsutil/epochs.h>
59
60/* Ptvcursor limits */
61#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
62#define SUBTREE_MAX_LEVELS256 256
63
64typedef struct __subtree_lvl {
65 int cursor_offset;
66 proto_item *it;
67 proto_tree *tree;
68} subtree_lvl;
69
70struct ptvcursor {
71 wmem_allocator_t *scope;
72 subtree_lvl *pushed_tree;
73 uint8_t pushed_tree_index;
74 uint8_t pushed_tree_max;
75 proto_tree *tree;
76 tvbuff_t *tvb;
77 int offset;
78};
79
80#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
81
82/** See inlined comments.
83 @param tree the tree to append this item to
84 @param free_block a code block to call to free resources if this returns
85 @return NULL if 'tree' is null */
86#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
87 if (!tree) { \
88 free_block; \
89 return NULL((void*)0); \
90 }
91
92/** See inlined comments.
93 @param tree the tree to append this item to
94 @return NULL if 'tree' is null */
95#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
96 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
97
98/** See inlined comments.
99 @param length the length of this item
100 @param cleanup_block a code block to call to free resources if this returns
101 @return NULL if 'length' is lower -1 or equal 0 */
102#define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return (
(void*)0); }
\
103 if (length < -1 || length == 0 ) { \
104 cleanup_block; \
105 return NULL((void*)0); \
106 }
107
108/** See inlined comments.
109 @param length the length of this item
110 @return NULL if 'length' is lower -1 or equal 0 */
111#define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
\
112 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
113
114/** See inlined comments.
115 @param tree the tree to append this item to
116 @param hfindex field index
117 @param hfinfo header_field
118 @param free_block a code block to call to free resources if this returns
119 @return the header field matching 'hfinfo' */
120#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", 120
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "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", 120, __func__, "Adding %s would put more than %d 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
); } } }
\
121 /* If the tree is not visible and this item is not referenced \
122 we don't have to do much work at all but we should still \
123 return a node so that referenced field items below this node \
124 (think proto_item_add_subtree()) will still have somewhere \
125 to attach to or else filtering will not work (they would be \
126 ignored since tree would be NULL). \
127 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
128 because that means we can change its length or repr, and we \
129 don't want to do so with calls intended for this faked new \
130 item, so this item needs a new (hidden) child node. \
131 We fake FT_PROTOCOL unless some clients have requested us \
132 not to do so. \
133 */ \
134 PTREE_DATA(tree)((tree)->tree_data)->count++; \
135 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", 135, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 135, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
136 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
137 free_block; \
138 if (wireshark_abort_on_too_many_items) \
139 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", 140
, __func__, "Adding %s would put more than %d 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 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d 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 /* Let the exception handler add items to the tree */ \
142 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
143 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)))
144 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)))
145 "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)))
146 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)))
; \
147 } \
148 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
149 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
150 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
151 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
152 && (hfinfo->type != FT_PROTOCOL || \
153 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
154 free_block; \
155 /* return fake node with no field info */\
156 return proto_tree_add_fake_node(tree, hfinfo); \
157 } \
158 } \
159 }
160
161/** See inlined comments.
162 @param tree the tree to append this item to
163 @param hfindex field index
164 @param hfinfo header_field
165 @return the header field matching 'hfinfo' */
166#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", 166
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "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", 166, __func__, "Adding %s would put more than %d 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)
; } } }
\
167 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", 167
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "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", 167, __func__, "Adding %s would put more than %d 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)
; } } }
168
169
170/** See inlined comments.
171 @param pi the created protocol item we're about to return */
172#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 172, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
173 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 173, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
174 if (!PITEM_FINFO(pi)((pi)->finfo)) \
175 return pi; \
176 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
177 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
178 /* If the tree (GUI) or item isn't visible it's pointless for \
179 * us to generate the protocol item's string representation */ \
180 return pi; \
181 }
182/* Same as above but returning void */
183#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
184 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
185 return; \
186 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
187 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
188 /* If the tree (GUI) or item isn't visible it's pointless for \
189 * us to generate the protocol item's string representation */ \
190 return; \
191 }
192/* Similar to above, but allows a NULL tree */
193#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; }
\
194 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
195 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
196 /* If the tree (GUI) or item isn't visible it's pointless for \
197 * us to generate the protocol item's string representation */ \
198 return pi; \
199 }
200
201#ifdef ENABLE_CHECK_FILTER
202#define CHECK_HF_VALUE(type, spec, start_values) \
203{ \
204 const type *current; \
205 int n, m; \
206 current = start_values; \
207 for (n=0; current; n++, current++) { \
208 /* Drop out if we reached the end. */ \
209 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
210 break; \
211 } \
212 /* Check value against all previous */ \
213 for (m=0; m < n; m++) { \
214 /* There are lots of duplicates with the same string, \
215 so only report if different... */ \
216 if ((start_values[m].value == current->value) && \
217 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218 ws_warning("Field '%s' (%s) has a conflicting entry in its" \do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 221, __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)
219 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 221, __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)
220 hfinfo->name, hfinfo->abbrev, \do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 221, __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)
221 current->value, m, start_values[m].strptr, n, current->strptr)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 221, __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)
; \
222 } \
223 } \
224 } \
225}
226#endif
227
228/* The longest NUMBER-like field label we have is for BASE_OUI, which
229 * can have up to 64 bytes for the manufacturer name if resolved plus
230 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
231 */
232#define NUMBER_LABEL_LENGTH80 80
233
234static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
235static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
236static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
237static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
238static int hfinfo_bitoffset(const header_field_info *hfinfo);
239static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
240static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
241
242#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
243 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
244
245static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
246static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
247
248static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
249static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
250static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
253static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
254static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255
256static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
257static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
258static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
259static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
260
261static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
265static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
268static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
269static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
271static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
272
273static void proto_cleanup_base(void);
274
275static proto_item *
276proto_tree_add_node(proto_tree *tree, field_info *fi);
277
278static proto_item *
279proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
280
281static void
282get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
283 int *item_length, const unsigned encoding);
284
285static int
286get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
287 int length, unsigned item_length, const int encoding);
288
289static field_info *
290new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
291 const int start, const int item_length);
292
293static proto_item *
294proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
295 int start, int *length);
296
297static void
298proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
299static void
300proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
301
302static void
303proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
304static void
305proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
306static void
307proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
308static void
309proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
310static void
311proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
312static void
313proto_tree_set_string(field_info *fi, const char* value);
314static void
315proto_tree_set_ax25(field_info *fi, const uint8_t* value);
316static void
317proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
318static void
319proto_tree_set_vines(field_info *fi, const uint8_t* value);
320static void
321proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
322static void
323proto_tree_set_ether(field_info *fi, const uint8_t* value);
324static void
325proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
326static void
327proto_tree_set_ipxnet(field_info *fi, uint32_t value);
328static void
329proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
330static void
331proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
332static void
333proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
334static void
335proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
336static void
337proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
338static void
339proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
340static void
341proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
342static void
343proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
344static void
345proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
346static void
347proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
348static void
349proto_tree_set_boolean(field_info *fi, uint64_t value);
350static void
351proto_tree_set_float(field_info *fi, float value);
352static void
353proto_tree_set_double(field_info *fi, double value);
354static void
355proto_tree_set_uint(field_info *fi, uint32_t value);
356static void
357proto_tree_set_int(field_info *fi, int32_t value);
358static void
359proto_tree_set_uint64(field_info *fi, uint64_t value);
360static void
361proto_tree_set_int64(field_info *fi, int64_t value);
362static void
363proto_tree_set_eui64(field_info *fi, const uint64_t value);
364static void
365proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
366
367/* Handle type length mismatch (now filterable) expert info */
368static int proto_type_length_mismatch;
369static expert_field ei_type_length_mismatch_error;
370static expert_field ei_type_length_mismatch_warn;
371static void register_type_length_mismatch(void);
372
373/* Handle byte array string decoding errors with expert info */
374static int proto_byte_array_string_decoding_error;
375static expert_field ei_byte_array_string_decoding_failed_error;
376static void register_byte_array_string_decodinws_error(void);
377
378/* Handle date and time string decoding errors with expert info */
379static int proto_date_time_string_decoding_error;
380static expert_field ei_date_time_string_decoding_failed_error;
381static void register_date_time_string_decodinws_error(void);
382
383/* Handle string errors expert info */
384static int proto_string_errors;
385static expert_field ei_string_trailing_characters;
386static void register_string_errors(void);
387
388static int proto_register_field_init(header_field_info *hfinfo, const int parent);
389
390/* special-case header field used within proto.c */
391static header_field_info hfi_text_only =
392 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
393int hf_text_only;
394
395/* Structure for information about a protocol */
396struct _protocol {
397 const char *name; /* long description */
398 const char *short_name; /* short description */
399 const char *filter_name; /* name of this protocol in filters */
400 GPtrArray *fields; /* fields for this protocol */
401 int proto_id; /* field ID for this protocol */
402 bool_Bool is_enabled; /* true if protocol is enabled */
403 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
404 bool_Bool can_toggle; /* true if is_enabled can be changed */
405 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
406 For dissectors that need a protocol name so they
407 can be added to a dissector table, but use the
408 parent_proto_id for things like enable/disable */
409 GList *heur_list; /* Heuristic dissectors associated with this protocol */
410};
411
412/* List of all protocols */
413static GList *protocols;
414
415/* Structure stored for deregistered g_slice */
416struct g_slice_data {
417 size_t block_size;
418 void *mem_block;
419};
420
421/* Deregistered fields */
422static GPtrArray *deregistered_fields;
423static GPtrArray *deregistered_data;
424static GPtrArray *deregistered_slice;
425
426/* indexed by prefix, contains initializers */
427static GHashTable* prefixes;
428
429/* Contains information about a field when a dissector calls
430 * proto_tree_add_item. */
431#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)))
432#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
433
434/* Contains the space for proto_nodes. */
435#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
436 node->first_child = NULL((void*)0); \
437 node->last_child = NULL((void*)0); \
438 node->next = NULL((void*)0);
439
440#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
441 wmem_free(pool, node)
442
443/* String space for protocol and field items for the GUI */
444#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;
\
445 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
446 il->value_pos = 0; \
447 il->value_len = 0;
448#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
449 wmem_free(pool, il);
450
451#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", 451, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 451, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 451, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
452 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
453 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 453
, __func__, "Unregistered hf! index=%d", hfindex)
; \
454 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", 454, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
455 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", 455, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
456 hfinfo = gpa_hfinfo.hfi[hfindex];
457
458#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
459
460/* List which stores protocols and fields that have been registered */
461typedef struct _gpa_hfinfo_t {
462 uint32_t len;
463 uint32_t allocated_len;
464 header_field_info **hfi;
465} gpa_hfinfo_t;
466
467static gpa_hfinfo_t gpa_hfinfo;
468
469/* Hash table of abbreviations and IDs */
470static wmem_map_t *gpa_name_map;
471static header_field_info *same_name_hfinfo;
472
473/* Hash table protocol aliases. const char * -> const char * */
474static GHashTable *gpa_protocol_aliases;
475
476/*
477 * We're called repeatedly with the same field name when sorting a column.
478 * Cache our last gpa_name_map hit for faster lookups.
479 */
480static char *last_field_name;
481static header_field_info *last_hfinfo;
482
483/* Points to the first element of an array of bits, indexed by
484 a subtree item type; that array element is true if subtrees of
485 an item of that type are to be expanded. */
486static uint32_t *tree_is_expanded;
487
488/* Number of elements in that array. The entry with index 0 is not used. */
489int num_tree_types = 1;
490
491/* Name hashtables for fast detection of duplicate names */
492static GHashTable* proto_names;
493static GHashTable* proto_short_names;
494static GHashTable* proto_filter_names;
495
496static const char *reserved_filter_names[] = {
497 /* Display filter keywords. */
498 "eq",
499 "ne",
500 "all_eq",
501 "any_eq",
502 "all_ne",
503 "any_ne",
504 "gt",
505 "ge",
506 "lt",
507 "le",
508 "bitand",
509 "bitwise_and",
510 "contains",
511 "matches",
512 "not",
513 "and",
514 "or",
515 "xor",
516 "in",
517 "any",
518 "all",
519 "true",
520 "false",
521 "nan",
522 "inf",
523 "infinity",
524 NULL((void*)0)
525};
526
527static GHashTable *proto_reserved_filter_names;
528static GQueue* saved_dir_queue;
529
530static int
531proto_compare_name(const void *p1_arg, const void *p2_arg)
532{
533 const protocol_t *p1 = (const protocol_t *)p1_arg;
534 const protocol_t *p2 = (const protocol_t *)p2_arg;
535
536 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
537}
538
539static GSList *dissector_plugins;
540
541#ifdef HAVE_PLUGINS1
542void
543proto_register_plugin(const proto_plugin *plug)
544{
545 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
546}
547#else /* HAVE_PLUGINS */
548void
549proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
550{
551 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 551, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
552}
553#endif /* HAVE_PLUGINS */
554
555static void
556call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
557{
558 proto_plugin *plug = (proto_plugin *)data;
559
560 if (plug->register_protoinfo) {
561 plug->register_protoinfo();
562 }
563}
564
565static void
566call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
567{
568 proto_plugin *plug = (proto_plugin *)data;
569
570 if (plug->register_handoff) {
571 plug->register_handoff();
572 }
573}
574
575/* initialize data structures and register protocols and fields */
576void
577proto_init(GSList *register_all_plugin_protocols_list,
578 GSList *register_all_plugin_handoffs_list,
579 register_cb cb,
580 void *client_data)
581{
582 proto_cleanup_base();
583 saved_dir_queue = g_queue_new();
584
585 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
586 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
587 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
588
589 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
590 for (const char **ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
591 /* GHashTable has no key destructor so the cast is safe. */
592 g_hash_table_add(proto_reserved_filter_names, *(char **)ptr);
593 }
594
595 gpa_hfinfo.len = 0;
596 gpa_hfinfo.allocated_len = 0;
597 gpa_hfinfo.hfi = NULL((void*)0);
598 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
599 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
600 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
601 deregistered_fields = g_ptr_array_new();
602 deregistered_data = g_ptr_array_new();
603 deregistered_slice = g_ptr_array_new();
604
605 /* Initialize the ftype subsystem */
606 ftypes_initialize();
607
608 /* Initialize the address type subsystem */
609 address_types_initialize();
610
611 /* Register one special-case FT_TEXT_ONLY field for use when
612 converting wireshark to new-style proto_tree. These fields
613 are merely strings on the GUI tree; they are not filterable */
614 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
615
616 /* Register the pseudo-protocols used for exceptions. */
617 register_show_exception();
618 register_type_length_mismatch();
619 register_byte_array_string_decodinws_error();
620 register_date_time_string_decodinws_error();
621 register_string_errors();
622 ftypes_register_pseudofields();
623 col_register_protocol();
624
625 /* Have each built-in dissector register its protocols, fields,
626 dissector tables, and dissectors to be called through a
627 handle, and do whatever one-time initialization it needs to
628 do. */
629 register_all_protocols(cb, client_data);
630
631 /* Now call the registration routines for all epan plugins. */
632 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
633 ((void (*)(register_cb, void *))l->data)(cb, client_data);
634 }
635
636 /* Now call the registration routines for all dissector plugins. */
637 if (cb)
638 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
639 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
640
641 /* Now call the "handoff registration" routines of all built-in
642 dissectors; those routines register the dissector in other
643 dissectors' handoff tables, and fetch any dissector handles
644 they need. */
645 register_all_protocol_handoffs(cb, client_data);
646
647 /* Now do the same with epan plugins. */
648 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
649 ((void (*)(register_cb, void *))l->data)(cb, client_data);
650 }
651
652 /* Now do the same with dissector plugins. */
653 if (cb)
654 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
655 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
656
657 /* sort the protocols by protocol name */
658 protocols = g_list_sort(protocols, proto_compare_name);
659
660 /* sort the dissector handles in dissector tables (for -G reports
661 * and -d error messages. The GUI sorts the handles itself.) */
662 packet_all_tables_sort_handles();
663
664 /* We've assigned all the subtree type values; allocate the array
665 for them, and zero it out. */
666 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
)))
;
667}
668
669static void
670proto_cleanup_base(void)
671{
672 protocol_t *protocol;
673 header_field_info *hfinfo;
674
675 /* Free the abbrev/ID hash table */
676 if (gpa_name_map) {
677 // XXX - We don't have a wmem_map_destroy, but
678 // it does get cleaned up when epan scope is
679 // destroyed
680 //g_hash_table_destroy(gpa_name_map);
681 gpa_name_map = NULL((void*)0);
682 }
683 if (gpa_protocol_aliases) {
684 g_hash_table_destroy(gpa_protocol_aliases);
685 gpa_protocol_aliases = NULL((void*)0);
686 }
687 g_free(last_field_name);
688 last_field_name = NULL((void*)0);
689
690 while (protocols) {
691 protocol = (protocol_t *)protocols->data;
692 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", 692
, __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", 692, "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", 692, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
693 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", 693, "protocol->proto_id == hfinfo->id"
))))
;
694
695 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)
;
696 if (protocol->parent_proto_id != -1) {
697 // pino protocol
698 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 698, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
699 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"
, 699, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
700 } else {
701 if (protocol->fields) {
702 g_ptr_array_free(protocol->fields, true1);
703 }
704 g_list_free(protocol->heur_list);
705 }
706 protocols = g_list_remove(protocols, protocol);
707 g_free(protocol);
708 }
709
710 if (proto_names) {
711 g_hash_table_destroy(proto_names);
712 proto_names = NULL((void*)0);
713 }
714
715 if (proto_short_names) {
716 g_hash_table_destroy(proto_short_names);
717 proto_short_names = NULL((void*)0);
718 }
719
720 if (proto_filter_names) {
721 g_hash_table_destroy(proto_filter_names);
722 proto_filter_names = NULL((void*)0);
723 }
724
725 if (proto_reserved_filter_names) {
726 g_hash_table_destroy(proto_reserved_filter_names);
727 proto_reserved_filter_names = NULL((void*)0);
728 }
729
730 if (gpa_hfinfo.allocated_len) {
731 gpa_hfinfo.len = 0;
732 gpa_hfinfo.allocated_len = 0;
733 g_free(gpa_hfinfo.hfi);
734 gpa_hfinfo.hfi = NULL((void*)0);
735 }
736
737 if (deregistered_fields) {
738 g_ptr_array_free(deregistered_fields, true1);
739 deregistered_fields = NULL((void*)0);
740 }
741
742 if (deregistered_data) {
743 g_ptr_array_free(deregistered_data, true1);
744 deregistered_data = NULL((void*)0);
745 }
746
747 if (deregistered_slice) {
748 g_ptr_array_free(deregistered_slice, true1);
749 deregistered_slice = NULL((void*)0);
750 }
751
752 g_free(tree_is_expanded);
753 tree_is_expanded = NULL((void*)0);
754
755 if (prefixes)
756 g_hash_table_destroy(prefixes);
757
758 if (saved_dir_queue != NULL((void*)0)) {
759 g_queue_clear_full(saved_dir_queue, g_free);
760 g_queue_free(saved_dir_queue);
761 saved_dir_queue = NULL((void*)0);
762 }
763}
764
765void
766proto_cleanup(void)
767{
768 proto_free_deregistered_fields();
769 proto_cleanup_base();
770
771 g_slist_free(dissector_plugins);
772 dissector_plugins = NULL((void*)0);
773}
774
775static bool_Bool
776ws_pushd(const char* dir)
777{
778 //Save the current working directory
779 const char* save_wd = get_current_working_dir();
780 if (save_wd != NULL((void*)0))
781 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
782
783 //Change to the new one
784#ifdef _WIN32
785 SetCurrentDirectory(utf_8to16(dir));
786 return true1;
787#else
788 return (chdir(dir) == 0);
789#endif
790}
791
792static bool_Bool
793ws_popd(void)
794{
795 int ret = 0;
796 char* saved_wd = g_queue_pop_head(saved_dir_queue);
797 if (saved_wd == NULL((void*)0))
798 return false0;
799
800 //Restore the previous one
801#ifdef _WIN32
802 SetCurrentDirectory(utf_8to16(saved_wd));
803#else
804 ret = chdir(saved_wd);
805#endif
806 g_free(saved_wd);
807 return (ret == 0);
808}
809
810void
811proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
812{
813 if (ws_pushd(dir))
814 {
815 func(param);
816 ws_popd();
817 }
818}
819
820static bool_Bool
821// NOLINTNEXTLINE(misc-no-recursion)
822proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
823 void *data)
824{
825 proto_node *pnode = tree;
826 proto_node *child;
827 proto_node *current;
828
829 if (func(pnode, data))
830 return true1;
831
832 child = pnode->first_child;
833 while (child != NULL((void*)0)) {
834 /*
835 * The routine we call might modify the child, e.g. by
836 * freeing it, so we get the child's successor before
837 * calling that routine.
838 */
839 current = child;
840 child = current->next;
841 // We recurse here, but we're limited by prefs.gui_max_tree_depth
842 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
843 return true1;
844 }
845
846 return false0;
847}
848
849void
850proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
851 void *data)
852{
853 proto_node *node = tree;
854 proto_node *current;
855
856 if (!node)
857 return;
858
859 node = node->first_child;
860 while (node != NULL((void*)0)) {
861 current = node;
862 node = current->next;
863 func((proto_tree *)current, data);
864 }
865}
866
867static void
868free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
869{
870 GPtrArray *ptrs = (GPtrArray *)value;
871 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
872 header_field_info *hfinfo;
873
874 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", 874, __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", 874, "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", 874, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
875 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
876 /* when a field is referenced by a filter this also
877 affects the refcount for the parent protocol so we need
878 to adjust the refcount for the parent as well
879 */
880 if (hfinfo->parent != -1) {
881 header_field_info *parent_hfinfo;
882 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", 882
, __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", 882, "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", 882, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
883 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
884 }
885 hfinfo->ref_type = HF_REF_TYPE_NONE;
886 }
887
888 g_ptr_array_free(ptrs, true1);
889}
890
891static void
892proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
893{
894 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
895
896 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
897
898 if (finfo) {
899 fvalue_free(finfo->value);
900 finfo->value = NULL((void*)0);
901 }
902}
903
904void
905proto_tree_reset(proto_tree *tree)
906{
907 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
908
909 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
910
911 /* free tree data */
912 if (tree_data->interesting_hfids) {
913 /* Free all the GPtrArray's in the interesting_hfids hash. */
914 g_hash_table_foreach(tree_data->interesting_hfids,
915 free_GPtrArray_value, NULL((void*)0));
916
917 /* And then remove all values. */
918 g_hash_table_remove_all(tree_data->interesting_hfids);
919 }
920
921 /* Reset track of the number of children */
922 tree_data->count = 0;
923
924 /* Reset our loop checks */
925 tree_data->idle_count_ds_tvb = NULL((void*)0);
926 tree_data->max_start = 0;
927 tree_data->start_idle_count = 0;
928
929 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
930}
931
932/* frees the resources that the dissection a proto_tree uses */
933void
934proto_tree_free(proto_tree *tree)
935{
936 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
937
938 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
939
940 /* free tree data */
941 if (tree_data->interesting_hfids) {
942 /* Free all the GPtrArray's in the interesting_hfids hash. */
943 g_hash_table_foreach(tree_data->interesting_hfids,
944 free_GPtrArray_value, NULL((void*)0));
945
946 /* And then destroy the hash. */
947 g_hash_table_destroy(tree_data->interesting_hfids);
948 }
949
950 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)
;
951
952 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
953}
954
955/* Is the parsing being done for a visible proto_tree or an invisible one?
956 * By setting this correctly, the proto_tree creation is sped up by not
957 * having to call vsnprintf and copy strings around.
958 */
959bool_Bool
960proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
961{
962 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
963
964 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
965
966 return old_visible;
967}
968
969void
970proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
971{
972 if (tree)
973 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
974}
975
976/* Assume dissector set only its protocol fields.
977 This function is called by dissectors and allows the speeding up of filtering
978 in wireshark; if this function returns false it is safe to reset tree to NULL
979 and thus skip calling most of the expensive proto_tree_add_...()
980 functions.
981 If the tree is visible we implicitly assume the field is referenced.
982*/
983bool_Bool
984proto_field_is_referenced(proto_tree *tree, int proto_id)
985{
986 register header_field_info *hfinfo;
987
988
989 if (!tree)
990 return false0;
991
992 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
993 return true1;
994
995 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", 995, __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", 995, "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", 995, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
996 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
997 return true1;
998
999 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1000 return true1;
1001
1002 return false0;
1003}
1004
1005
1006/* Finds a record in the hfinfo array by id. */
1007header_field_info *
1008proto_registrar_get_nth(unsigned hfindex)
1009{
1010 register header_field_info *hfinfo;
1011
1012 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", 1012, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1012,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1012, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1013 return hfinfo;
1014}
1015
1016
1017/* Prefix initialization
1018 * this allows for a dissector to register a display filter name prefix
1019 * so that it can delay the initialization of the hf array as long as
1020 * possible.
1021 */
1022
1023/* compute a hash for the part before the dot of a display filter */
1024static unsigned
1025prefix_hash (const void *key) {
1026 /* end the string at the dot and compute its hash */
1027 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1028 char* c = copy;
1029 unsigned tmp;
1030
1031 for (; *c; c++) {
1032 if (*c == '.') {
1033 *c = 0;
1034 break;
1035 }
1036 }
1037
1038 tmp = wmem_str_hash(copy);
1039 g_free(copy);
1040 return tmp;
1041}
1042
1043/* are both strings equal up to the end or the dot? */
1044static gboolean
1045prefix_equal (const void *ap, const void *bp) {
1046 const char* a = (const char *)ap;
1047 const char* b = (const char *)bp;
1048
1049 do {
1050 char ac = *a++;
1051 char bc = *b++;
1052
1053 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1054
1055 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1056 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1057
1058 if (ac != bc) return FALSE(0);
1059 } while (1);
1060
1061 return FALSE(0);
1062}
1063
1064/* Register a new prefix for "delayed" initialization of field arrays */
1065void
1066proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1067 if (! prefixes ) {
1068 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1069 }
1070
1071 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1072}
1073
1074/* helper to call all prefix initializers */
1075static gboolean
1076initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1077 ((prefix_initializer_t)v)((const char *)k);
1078 return TRUE(!(0));
1079}
1080
1081/** Initialize every remaining uninitialized prefix. */
1082void
1083proto_initialize_all_prefixes(void) {
1084 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1085}
1086
1087/* Finds a record in the hfinfo array by name.
1088 * If it fails to find it in the already registered fields,
1089 * it tries to find and call an initializer in the prefixes
1090 * table and if so it looks again.
1091 */
1092
1093header_field_info *
1094proto_registrar_get_byname(const char *field_name)
1095{
1096 header_field_info *hfinfo;
1097 prefix_initializer_t pi;
1098
1099 if (!field_name)
1100 return NULL((void*)0);
1101
1102 if (g_strcmp0(field_name, last_field_name) == 0) {
1103 return last_hfinfo;
1104 }
1105
1106 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1107
1108 if (hfinfo) {
1109 g_free(last_field_name);
1110 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1111 last_hfinfo = hfinfo;
1112 return hfinfo;
1113 }
1114
1115 if (!prefixes)
1116 return NULL((void*)0);
1117
1118 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1119 pi(field_name);
1120 g_hash_table_remove(prefixes, field_name);
1121 } else {
1122 return NULL((void*)0);
1123 }
1124
1125 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1126
1127 if (hfinfo) {
1128 g_free(last_field_name);
1129 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1130 last_hfinfo = hfinfo;
1131 }
1132 return hfinfo;
1133}
1134
1135header_field_info*
1136proto_registrar_get_byalias(const char *alias_name)
1137{
1138 if (!alias_name) {
1139 return NULL((void*)0);
1140 }
1141
1142 /* Find our aliased protocol. */
1143 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1144 char *dot = strchr(an_copy, '.');
1145 if (dot) {
1146 *dot = '\0';
1147 }
1148 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1149 if (!proto_pfx) {
1150 g_free(an_copy);
1151 return NULL((void*)0);
1152 }
1153
1154 /* Construct our aliased field and look it up. */
1155 GString *filter_name = g_string_new(proto_pfx);
1156 if (dot) {
1157 g_string_append_printf(filter_name, ".%s", dot+1);
1158 }
1159 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1160 g_free(an_copy);
1161 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)))))
;
1162
1163 return hfinfo;
1164}
1165
1166int
1167proto_registrar_get_id_byname(const char *field_name)
1168{
1169 header_field_info *hfinfo;
1170
1171 hfinfo = proto_registrar_get_byname(field_name);
1172
1173 if (!hfinfo)
1174 return -1;
1175
1176 return hfinfo->id;
1177}
1178
1179static int
1180label_strcat_flags(const header_field_info *hfinfo)
1181{
1182 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1183 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1184
1185 return 0;
1186}
1187
1188static char *
1189format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1190 const uint8_t *bytes, unsigned length, size_t max_str_len)
1191{
1192 char *str = NULL((void*)0);
1193 const uint8_t *p;
1194 bool_Bool is_printable;
1195
1196 if (bytes) {
1197 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1198 /*
1199 * If all bytes are valid and printable UTF-8, show the
1200 * bytes as a string - in quotes to indicate that it's
1201 * a string.
1202 */
1203 if (isprint_utf8_string(bytes, length)) {
1204 str = wmem_strdup_printf(scope, "\"%.*s\"",
1205 (int)length, bytes);
1206 return str;
1207 }
1208 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1209 /*
1210 * Check whether all bytes are printable.
1211 */
1212 is_printable = true1;
1213 for (p = bytes; p < bytes+length; p++) {
1214 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1215 /* Not printable. */
1216 is_printable = false0;
1217 break;
1218 }
1219 }
1220
1221 /*
1222 * If all bytes are printable ASCII, show the bytes
1223 * as a string - in quotes to indicate that it's
1224 * a string.
1225 */
1226 if (is_printable) {
1227 str = wmem_strdup_printf(scope, "\"%.*s\"",
1228 (int)length, bytes);
1229 return str;
1230 }
1231 }
1232
1233 /*
1234 * Either it's not printable ASCII, or we don't care whether
1235 * it's printable ASCII; show it as hex bytes.
1236 */
1237 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1238 case SEP_DOT:
1239 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1240 break;
1241 case SEP_DASH:
1242 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1243 break;
1244 case SEP_COLON:
1245 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1246 break;
1247 case SEP_SPACE:
1248 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1249 break;
1250 case BASE_NONE:
1251 default:
1252 if (prefs.display_byte_fields_with_spaces) {
1253 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1254 } else {
1255 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1256 }
1257 break;
1258 }
1259 }
1260 else {
1261 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1262 str = wmem_strdup(scope, "<none>");
1263 } else {
1264 str = wmem_strdup(scope, "<MISSING>");
1265 }
1266 }
1267 return str;
1268}
1269
1270static char *
1271format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1272 const uint8_t *bytes, unsigned length)
1273{
1274 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1275}
1276
1277static void
1278ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1279{
1280 subtree_lvl *pushed_tree;
1281
1282 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"
, 1282, "ptvc->pushed_tree_max <= 256-8"))))
;
1283 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1284
1285 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1286 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1286, "pushed_tree != ((void*)0)"
))))
;
1287 ptvc->pushed_tree = pushed_tree;
1288}
1289
1290static void
1291ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1292{
1293 ptvc->pushed_tree = NULL((void*)0);
1294 ptvc->pushed_tree_max = 0;
1295 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", 1295, "ptvc->pushed_tree_index == 0"
))))
;
1296 ptvc->pushed_tree_index = 0;
1297}
1298
1299/* Allocates an initializes a ptvcursor_t with 3 variables:
1300 * proto_tree, tvbuff, and offset. */
1301ptvcursor_t *
1302ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, int offset)
1303{
1304 ptvcursor_t *ptvc;
1305
1306 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1307 ptvc->scope = scope;
1308 ptvc->tree = tree;
1309 ptvc->tvb = tvb;
1310 ptvc->offset = offset;
1311 ptvc->pushed_tree = NULL((void*)0);
1312 ptvc->pushed_tree_max = 0;
1313 ptvc->pushed_tree_index = 0;
1314 return ptvc;
1315}
1316
1317
1318/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1319void
1320ptvcursor_free(ptvcursor_t *ptvc)
1321{
1322 ptvcursor_free_subtree_levels(ptvc);
1323 /*g_free(ptvc);*/
1324}
1325
1326/* Returns tvbuff. */
1327tvbuff_t *
1328ptvcursor_tvbuff(ptvcursor_t *ptvc)
1329{
1330 return ptvc->tvb;
1331}
1332
1333/* Returns current offset. */
1334int
1335ptvcursor_current_offset(ptvcursor_t *ptvc)
1336{
1337 return ptvc->offset;
1338}
1339
1340proto_tree *
1341ptvcursor_tree(ptvcursor_t *ptvc)
1342{
1343 if (!ptvc)
1344 return NULL((void*)0);
1345
1346 return ptvc->tree;
1347}
1348
1349void
1350ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1351{
1352 ptvc->tree = tree;
1353}
1354
1355/* creates a subtree, sets it as the working tree and pushes the old working tree */
1356proto_tree *
1357ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1358{
1359 subtree_lvl *subtree;
1360 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1361 ptvcursor_new_subtree_levels(ptvc);
1362
1363 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1364 subtree->tree = ptvc->tree;
1365 subtree->it= NULL((void*)0);
1366 ptvc->pushed_tree_index++;
1367 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1368}
1369
1370/* pops a subtree */
1371void
1372ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1373{
1374 subtree_lvl *subtree;
1375
1376 if (ptvc->pushed_tree_index <= 0)
1377 return;
1378
1379 ptvc->pushed_tree_index--;
1380 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1381 if (subtree->it != NULL((void*)0))
1382 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1383
1384 ptvc->tree = subtree->tree;
1385}
1386
1387/* saves the current tvb offset and the item in the current subtree level */
1388static void
1389ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1390{
1391 subtree_lvl *subtree;
1392
1393 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", 1393, "ptvc->pushed_tree_index > 0"
))))
;
1394
1395 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1396 subtree->it = it;
1397 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1398}
1399
1400/* Creates a subtree and adds it to the cursor as the working tree but does not
1401 * save the old working tree */
1402proto_tree *
1403ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1404{
1405 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1406 return ptvc->tree;
1407}
1408
1409static proto_tree *
1410ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1411{
1412 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1413 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1414 ptvcursor_subtree_set_item(ptvc, it);
1415 return ptvcursor_tree(ptvc);
1416}
1417
1418/* Add an item to the tree and create a subtree
1419 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1420 * In this case, when the subtree will be closed, the parent item length will
1421 * be equal to the advancement of the cursor since the creation of the subtree.
1422 */
1423proto_tree *
1424ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1425 const unsigned encoding, int ett_subtree)
1426{
1427 proto_item *it;
1428
1429 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1430 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1431}
1432
1433static proto_item *
1434proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1435
1436/* Add a text node to the tree and create a subtree
1437 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1438 * In this case, when the subtree will be closed, the item length will be equal
1439 * to the advancement of the cursor since the creation of the subtree.
1440 */
1441proto_tree *
1442ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1443 int ett_subtree, const char *format, ...)
1444{
1445 proto_item *pi;
1446 va_list ap;
1447 header_field_info *hfinfo;
1448 proto_tree *tree;
1449
1450 tree = ptvcursor_tree(ptvc);
1451
1452 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1453
1454 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", 1454
, __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", 1454, "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", 1454, "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", 1454, __func__, "Adding %s would put more than %d 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)
; } } }
;
1455
1456 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1457 ptvcursor_current_offset(ptvc), length);
1458
1459 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1459, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1460
1461 va_start(ap, format)__builtin_va_start(ap, format);
1462 proto_tree_set_representation(pi, format, ap);
1463 va_end(ap)__builtin_va_end(ap);
1464
1465 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1466}
1467
1468/* Add a text-only node, leaving it to our caller to fill the text in */
1469static proto_item *
1470proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1471{
1472 proto_item *pi;
1473
1474 if (tree == NULL((void*)0))
1475 return NULL((void*)0);
1476
1477 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1478
1479 return pi;
1480}
1481
1482/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1483proto_item *
1484proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1485 const char *format, ...)
1486{
1487 proto_item *pi;
1488 va_list ap;
1489 header_field_info *hfinfo;
1490
1491 if (length == -1) {
1492 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1493 } else {
1494 tvb_ensure_bytes_exist(tvb, start, length);
1495 }
1496
1497 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1498
1499 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", 1499
, __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", 1499, "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", 1499, "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", 1499, __func__, "Adding %s would put more than %d 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)
; } } }
;
1500
1501 pi = proto_tree_add_text_node(tree, tvb, start, length);
1502
1503 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1503, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1504
1505 va_start(ap, format)__builtin_va_start(ap, format);
1506 proto_tree_set_representation(pi, format, ap);
1507 va_end(ap)__builtin_va_end(ap);
1508
1509 return pi;
1510}
1511
1512/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1513proto_item *
1514proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1515 int length, const char *format, va_list ap)
1516{
1517 proto_item *pi;
1518 header_field_info *hfinfo;
1519
1520 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1521 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1522 * the length to be what's in the tvbuff if length is -1, and the
1523 * minimum of length and what's in the tvbuff if not.
1524 */
1525
1526 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1527
1528 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", 1528
, __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", 1528, "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", 1528, "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", 1528, __func__, "Adding %s would put more than %d 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)
; } } }
;
1529
1530 pi = proto_tree_add_text_node(tree, tvb, start, length);
1531
1532 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1532, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1533
1534 proto_tree_set_representation(pi, format, ap);
1535
1536 return pi;
1537}
1538
1539/* Add a text-only node that creates a subtree underneath.
1540 */
1541proto_tree *
1542proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1543{
1544 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1545}
1546
1547/* Add a text-only node that creates a subtree underneath.
1548 */
1549proto_tree *
1550proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1551{
1552 proto_tree *pt;
1553 proto_item *pi;
1554 va_list ap;
1555
1556 va_start(ap, format)__builtin_va_start(ap, format);
1557 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1558 va_end(ap)__builtin_va_end(ap);
1559
1560 if (tree_item != NULL((void*)0))
1561 *tree_item = pi;
1562
1563 pt = proto_item_add_subtree(pi, idx);
1564
1565 return pt;
1566}
1567
1568/* Add a text-only node for debugging purposes. The caller doesn't need
1569 * to worry about tvbuff, start, or length. Debug message gets sent to
1570 * STDOUT, too */
1571proto_item *
1572proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1573{
1574 proto_item *pi;
1575 va_list ap;
1576
1577 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1578
1579 if (pi) {
1580 va_start(ap, format)__builtin_va_start(ap, format);
1581 proto_tree_set_representation(pi, format, ap);
1582 va_end(ap)__builtin_va_end(ap);
1583 }
1584 va_start(ap, format)__builtin_va_start(ap, format);
1585 vprintf(format, ap);
1586 va_end(ap)__builtin_va_end(ap);
1587 printf("\n");
1588
1589 return pi;
1590}
1591
1592proto_item *
1593proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1594{
1595 proto_item *pi;
1596 header_field_info *hfinfo;
1597
1598 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1599
1600 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", 1600
, __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", 1600, "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", 1600, "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", 1600, __func__, "Adding %s would put more than %d 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)
; } } }
;
1601
1602 pi = proto_tree_add_text_node(tree, tvb, start, length);
1603
1604 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1604, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1605
1606 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1607
1608 return pi;
1609}
1610
1611proto_item *
1612proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1613{
1614 proto_item *pi;
1615 header_field_info *hfinfo;
1616 char *str;
1617
1618 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1619
1620 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", 1620
, __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", 1620, "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", 1620, "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", 1620, __func__, "Adding %s would put more than %d 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)
; } } }
;
1621
1622 pi = proto_tree_add_text_node(tree, tvb, start, length);
1623
1624 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1624, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1625
1626 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1627 proto_item_set_text(pi, "%s", str);
1628 wmem_free(NULL((void*)0), str);
1629
1630 return pi;
1631}
1632
1633void proto_report_dissector_bug(const char *format, ...)
1634{
1635 va_list args;
1636
1637 if (wireshark_abort_on_dissector_bug) {
1638 /*
1639 * Try to have the error message show up in the crash
1640 * information.
1641 */
1642 va_start(args, format)__builtin_va_start(args, format);
1643 ws_vadd_crash_info(format, args);
1644 va_end(args)__builtin_va_end(args);
1645
1646 /*
1647 * Print the error message.
1648 */
1649 va_start(args, format)__builtin_va_start(args, format);
1650 vfprintf(stderrstderr, format, args);
1651 va_end(args)__builtin_va_end(args);
1652 putc('\n', stderrstderr);
1653
1654 /*
1655 * And crash.
1656 */
1657 abort();
1658 } else {
1659 va_start(args, format)__builtin_va_start(args, format);
1660 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1661 va_end(args)__builtin_va_end(args);
1662 }
1663}
1664
1665/* We could probably get away with changing is_error to a minimum length value. */
1666static void
1667report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1668{
1669 if (is_error) {
1670 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1671 } else {
1672 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1673 }
1674
1675 if (is_error) {
1676 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1677 }
1678}
1679
1680static uint32_t
1681get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1682{
1683 uint32_t value;
1684 bool_Bool length_error;
1685
1686 switch (length) {
1687
1688 case 1:
1689 value = tvb_get_uint8(tvb, offset);
1690 if (encoding & ENC_ZIGBEE0x40000000) {
1691 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1692 value = 0;
1693 }
1694 }
1695 break;
1696
1697 case 2:
1698 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1699 : tvb_get_ntohs(tvb, offset);
1700 if (encoding & ENC_ZIGBEE0x40000000) {
1701 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1702 value = 0;
1703 }
1704 }
1705 break;
1706
1707 case 3:
1708 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1709 : tvb_get_ntoh24(tvb, offset);
1710 break;
1711
1712 case 4:
1713 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1714 : tvb_get_ntohl(tvb, offset);
1715 break;
1716
1717 default:
1718 if (length < 1) {
1719 length_error = true1;
1720 value = 0;
1721 } else {
1722 length_error = false0;
1723 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1724 : tvb_get_ntohl(tvb, offset);
1725 }
1726 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1727 break;
1728 }
1729 return value;
1730}
1731
1732static inline uint64_t
1733get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1734{
1735 uint64_t value;
1736
1737 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1738
1739 if (length < 1 || length > 8) {
1740 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1741 }
1742
1743 return value;
1744}
1745
1746static int32_t
1747get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1748{
1749 int32_t value;
1750 bool_Bool length_error;
1751
1752 switch (length) {
1753
1754 case 1:
1755 value = tvb_get_int8(tvb, offset);
1756 break;
1757
1758 case 2:
1759 value = encoding ? tvb_get_letohis(tvb, offset)
1760 : tvb_get_ntohis(tvb, offset);
1761 break;
1762
1763 case 3:
1764 value = encoding ? tvb_get_letohi24(tvb, offset)
1765 : tvb_get_ntohi24(tvb, offset);
1766 break;
1767
1768 case 4:
1769 value = encoding ? tvb_get_letohil(tvb, offset)
1770 : tvb_get_ntohil(tvb, offset);
1771 break;
1772
1773 default:
1774 if (length < 1) {
1775 length_error = true1;
1776 value = 0;
1777 } else {
1778 length_error = false0;
1779 value = encoding ? tvb_get_letohil(tvb, offset)
1780 : tvb_get_ntohil(tvb, offset);
1781 }
1782 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1783 break;
1784 }
1785 return value;
1786}
1787
1788/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1789 * be cast-able as a int64_t. This is weird, but what the code has always done.
1790 */
1791static inline uint64_t
1792get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1793{
1794 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1795
1796 switch (length) {
1797 case 7:
1798 value = ws_sign_ext64(value, 56);
1799 break;
1800 case 6:
1801 value = ws_sign_ext64(value, 48);
1802 break;
1803 case 5:
1804 value = ws_sign_ext64(value, 40);
1805 break;
1806 case 4:
1807 value = ws_sign_ext64(value, 32);
1808 break;
1809 case 3:
1810 value = ws_sign_ext64(value, 24);
1811 break;
1812 case 2:
1813 value = ws_sign_ext64(value, 16);
1814 break;
1815 case 1:
1816 value = ws_sign_ext64(value, 8);
1817 break;
1818 }
1819
1820 return value;
1821}
1822
1823/* For FT_STRING */
1824static inline const uint8_t *
1825get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1826 int length, int *ret_length, const unsigned encoding)
1827{
1828 if (length == -1) {
1829 length = tvb_ensure_captured_length_remaining(tvb, start);
1830 }
1831 *ret_length = length;
1832 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1833}
1834
1835/* For FT_STRINGZ */
1836static inline const uint8_t *
1837get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1838 int start, int length, int *ret_length, const unsigned encoding)
1839{
1840 const uint8_t *value;
1841
1842 if (length < -1) {
1843 report_type_length_mismatch(tree, "a string", length, true1);
1844 }
1845 if (length == -1) {
1846 /* This can throw an exception */
1847 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1848 } else {
1849 /* In this case, length signifies the length of the string.
1850 *
1851 * This could either be a null-padded string, which doesn't
1852 * necessarily have a '\0' at the end, or a null-terminated
1853 * string, with a trailing '\0'. (Yes, there are cases
1854 * where you have a string that's both counted and null-
1855 * terminated.)
1856 *
1857 * In the first case, we must allocate a buffer of length
1858 * "length+1", to make room for a trailing '\0'.
1859 *
1860 * In the second case, we don't assume that there is a
1861 * trailing '\0' there, as the packet might be malformed.
1862 * (XXX - should we throw an exception if there's no
1863 * trailing '\0'?) Therefore, we allocate a buffer of
1864 * length "length+1", and put in a trailing '\0', just to
1865 * be safe.
1866 *
1867 * (XXX - this would change if we made string values counted
1868 * rather than null-terminated.)
1869 */
1870 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1871 }
1872 *ret_length = length;
1873 return value;
1874}
1875
1876/* For FT_UINT_STRING */
1877static inline const uint8_t *
1878get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1879 tvbuff_t *tvb, int start, int length, int *ret_length,
1880 const unsigned encoding)
1881{
1882 uint32_t n;
1883 const uint8_t *value;
1884
1885 /* I believe it's ok if this is called with a NULL tree */
1886 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1887 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1888 length += n;
1889 *ret_length = length;
1890 return value;
1891}
1892
1893/* For FT_STRINGZPAD */
1894static inline const uint8_t *
1895get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1896 int length, int *ret_length, const unsigned encoding)
1897{
1898 /*
1899 * XXX - currently, string values are null-
1900 * terminated, so a "zero-padded" string
1901 * isn't special. If we represent string
1902 * values as something that includes a counted
1903 * array of bytes, we'll need to strip the
1904 * trailing NULs.
1905 */
1906 if (length == -1) {
1907 length = tvb_ensure_captured_length_remaining(tvb, start);
1908 }
1909 *ret_length = length;
1910 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1911}
1912
1913/* For FT_STRINGZTRUNC */
1914static inline const uint8_t *
1915get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1916 int length, int *ret_length, const unsigned encoding)
1917{
1918 /*
1919 * XXX - currently, string values are null-
1920 * terminated, so a "zero-truncated" string
1921 * isn't special. If we represent string
1922 * values as something that includes a counted
1923 * array of bytes, we'll need to strip everything
1924 * starting with the terminating NUL.
1925 */
1926 if (length == -1) {
1927 length = tvb_ensure_captured_length_remaining(tvb, start);
1928 }
1929 *ret_length = length;
1930 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1931}
1932
1933/*
1934 * Deltas between the epochs for various non-UN*X time stamp formats and
1935 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1936 * stamp format.
1937 */
1938
1939/*
1940 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1941 * XXX - if it's OK if this is unsigned, can we just use
1942 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1943 */
1944#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1945
1946/*
1947 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1948 */
1949#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1950
1951/* this can be called when there is no tree, so tree may be null */
1952static void
1953get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1954 const int length, const unsigned encoding, nstime_t *time_stamp,
1955 const bool_Bool is_relative)
1956{
1957 uint32_t tmpsecs;
1958 uint64_t tmp64secs;
1959 uint64_t todusecs;
1960
1961 switch (encoding) {
1962
1963 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1964 /*
1965 * If the length is 16, 8-byte seconds, followed
1966 * by 8-byte fractional time in nanoseconds,
1967 * both big-endian.
1968 *
1969 * If the length is 12, 8-byte seconds, followed
1970 * by 4-byte fractional time in nanoseconds,
1971 * both big-endian.
1972 *
1973 * If the length is 8, 4-byte seconds, followed
1974 * by 4-byte fractional time in nanoseconds,
1975 * both big-endian.
1976 *
1977 * For absolute times, the seconds are seconds
1978 * since the UN*X epoch.
1979 */
1980 if (length == 16) {
1981 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1982 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1983 } else if (length == 12) {
1984 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1985 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1986 } else if (length == 8) {
1987 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1988 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1989 } else if (length == 4) {
1990 /*
1991 * Backwards compatibility.
1992 * ENC_TIME_SECS_NSECS is 0; using
1993 * ENC_BIG_ENDIAN by itself with a 4-byte
1994 * time-in-seconds value was done in the
1995 * past.
1996 */
1997 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1998 time_stamp->nsecs = 0;
1999 } else {
2000 time_stamp->secs = 0;
2001 time_stamp->nsecs = 0;
2002 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2003 }
2004 break;
2005
2006 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2007 /*
2008 * If the length is 16, 8-byte seconds, followed
2009 * by 8-byte fractional time in nanoseconds,
2010 * both little-endian.
2011 *
2012 * If the length is 12, 8-byte seconds, followed
2013 * by 4-byte fractional time in nanoseconds,
2014 * both little-endian.
2015 *
2016 * If the length is 8, 4-byte seconds, followed
2017 * by 4-byte fractional time in nanoseconds,
2018 * both little-endian.
2019 *
2020 * For absolute times, the seconds are seconds
2021 * since the UN*X epoch.
2022 */
2023 if (length == 16) {
2024 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2025 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2026 } else if (length == 12) {
2027 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2028 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2029 } else if (length == 8) {
2030 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2031 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2032 } else if (length == 4) {
2033 /*
2034 * Backwards compatibility.
2035 * ENC_TIME_SECS_NSECS is 0; using
2036 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2037 * time-in-seconds value was done in the
2038 * past.
2039 */
2040 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2041 time_stamp->nsecs = 0;
2042 } else {
2043 time_stamp->secs = 0;
2044 time_stamp->nsecs = 0;
2045 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2046 }
2047 break;
2048
2049 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2050 /*
2051 * NTP time stamp, big-endian.
2052 * Only supported for absolute times.
2053 */
2054 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2054, "!is_relative"
))))
;
2055
2056 /* We need a temporary variable here so the unsigned math
2057 * works correctly (for years > 2036 according to RFC 2030
2058 * chapter 3).
2059 *
2060 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2061 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2062 * If bit 0 is not set, the time is in the range 2036-2104 and
2063 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2064 */
2065 tmpsecs = tvb_get_ntohl(tvb, start);
2066 if ((tmpsecs & 0x80000000) != 0)
2067 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2068 else
2069 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2070
2071 if (length == 8) {
2072 tmp64secs = tvb_get_ntoh64(tvb, start);
2073 if (tmp64secs == 0) {
2074 //This is "NULL" time
2075 time_stamp->secs = 0;
2076 time_stamp->nsecs = 0;
2077 } else {
2078 /*
2079 * Convert 1/2^32s of a second to
2080 * nanoseconds.
2081 */
2082 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2083 }
2084 } else if (length == 4) {
2085 /*
2086 * Backwards compatibility.
2087 */
2088 if (tmpsecs == 0) {
2089 //This is "NULL" time
2090 time_stamp->secs = 0;
2091 }
2092 time_stamp->nsecs = 0;
2093 } else {
2094 time_stamp->secs = 0;
2095 time_stamp->nsecs = 0;
2096 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2097 }
2098 break;
2099
2100 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2101 /*
2102 * NTP time stamp, little-endian.
2103 * Only supported for absolute times.
2104 *
2105 * NTP doesn't use this, because it's an Internet format
2106 * and hence big-endian. Any implementation must decide
2107 * whether the NTP timestamp is a 64-bit unsigned fixed
2108 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2109 * with a 32-bit unsigned seconds field followed by a
2110 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2111 * the previous two).
2112 *
2113 * XXX: We do the latter, but no dissector uses this format.
2114 * OTOH, ERF timestamps do the former, so perhaps we
2115 * should switch the interpretation so that packet-erf.c
2116 * could use this directly?
2117 */
2118 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2118, "!is_relative"
))))
;
2119
2120 /* We need a temporary variable here so the unsigned math
2121 * works correctly (for years > 2036 according to RFC 2030
2122 * chapter 3).
2123 *
2124 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2125 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2126 * If bit 0 is not set, the time is in the range 2036-2104 and
2127 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2128 */
2129 tmpsecs = tvb_get_letohl(tvb, start);
2130 if ((tmpsecs & 0x80000000) != 0)
2131 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2132 else
2133 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2134
2135 if (length == 8) {
2136 tmp64secs = tvb_get_letoh64(tvb, start);
2137 if (tmp64secs == 0) {
2138 //This is "NULL" time
2139 time_stamp->secs = 0;
2140 time_stamp->nsecs = 0;
2141 } else {
2142 /*
2143 * Convert 1/2^32s of a second to
2144 * nanoseconds.
2145 */
2146 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2147 }
2148 } else if (length == 4) {
2149 /*
2150 * Backwards compatibility.
2151 */
2152 if (tmpsecs == 0) {
2153 //This is "NULL" time
2154 time_stamp->secs = 0;
2155 }
2156 time_stamp->nsecs = 0;
2157 } else {
2158 time_stamp->secs = 0;
2159 time_stamp->nsecs = 0;
2160 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2161 }
2162 break;
2163
2164 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2165 /*
2166 * S/3x0 and z/Architecture TOD clock time stamp,
2167 * big-endian. The epoch is January 1, 1900,
2168 * 00:00:00 (proleptic?) UTC.
2169 *
2170 * Only supported for absolute times.
2171 */
2172 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2172, "!is_relative"
))))
;
2173 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2173, "length == 8"
))))
;
2174
2175 if (length == 8) {
2176 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2177 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2178 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2179 } else {
2180 time_stamp->secs = 0;
2181 time_stamp->nsecs = 0;
2182 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2183 }
2184 break;
2185
2186 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2187 /*
2188 * S/3x0 and z/Architecture TOD clock time stamp,
2189 * little-endian. The epoch is January 1, 1900,
2190 * 00:00:00 (proleptic?) UTC.
2191 *
2192 * Only supported for absolute times.
2193 */
2194 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2194, "!is_relative"
))))
;
2195
2196 if (length == 8) {
2197 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2198 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2199 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2200 } else {
2201 time_stamp->secs = 0;
2202 time_stamp->nsecs = 0;
2203 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2204 }
2205 break;
2206
2207 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2208 /*
2209 * Time stamp using the same seconds/fraction format
2210 * as NTP, but with the origin of the time stamp being
2211 * the UNIX epoch rather than the NTP epoch; big-
2212 * endian.
2213 *
2214 * Only supported for absolute times.
2215 */
2216 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2216, "!is_relative"
))))
;
2217
2218 if (length == 8) {
2219 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2220 /*
2221 * Convert 1/2^32s of a second to nanoseconds.
2222 */
2223 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2224 } else {
2225 time_stamp->secs = 0;
2226 time_stamp->nsecs = 0;
2227 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2228 }
2229 break;
2230
2231 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2232 /*
2233 * Time stamp using the same seconds/fraction format
2234 * as NTP, but with the origin of the time stamp being
2235 * the UNIX epoch rather than the NTP epoch; little-
2236 * endian.
2237 *
2238 * Only supported for absolute times.
2239 *
2240 * The RTPS specification explicitly supports Little
2241 * Endian encoding. In one place, it states that its
2242 * Time_t representation "is the one defined by ...
2243 * RFC 1305", but in another explicitly defines it as
2244 * a struct consisting of an 32 bit unsigned seconds
2245 * field and a 32 bit unsigned fraction field, not a 64
2246 * bit fixed point, so we do that here.
2247 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2248 */
2249 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2249, "!is_relative"
))))
;
2250
2251 if (length == 8) {
2252 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2253 /*
2254 * Convert 1/2^32s of a second to nanoseconds.
2255 */
2256 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2257 } else {
2258 time_stamp->secs = 0;
2259 time_stamp->nsecs = 0;
2260 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2261 }
2262 break;
2263
2264 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2265 /*
2266 * MIP6 time stamp, big-endian.
2267 * A 64-bit unsigned integer field containing a timestamp. The
2268 * value indicates the number of seconds since January 1, 1970,
2269 * 00:00 UTC, by using a fixed point format. In this format, the
2270 * integer number of seconds is contained in the first 48 bits of
2271 * the field, and the remaining 16 bits indicate the number of
2272 * 1/65536 fractions of a second.
2273
2274 * Only supported for absolute times.
2275 */
2276 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2276, "!is_relative"
))))
;
2277
2278 if (length == 8) {
2279 /* We need a temporary variable here so the casting and fractions
2280 * of a second work correctly.
2281 */
2282 tmp64secs = tvb_get_ntoh48(tvb, start);
2283 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2284 tmpsecs <<= 16;
2285
2286 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2287 //This is "NULL" time
2288 time_stamp->secs = 0;
2289 time_stamp->nsecs = 0;
2290 } else {
2291 time_stamp->secs = (time_t)tmp64secs;
2292 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2293 }
2294 } else {
2295 time_stamp->secs = 0;
2296 time_stamp->nsecs = 0;
2297 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2298 }
2299 break;
2300
2301 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2302 /*
2303 * If the length is 16, 8-byte seconds, followed
2304 * by 8-byte fractional time in microseconds,
2305 * both big-endian.
2306 *
2307 * If the length is 12, 8-byte seconds, followed
2308 * by 4-byte fractional time in microseconds,
2309 * both big-endian.
2310 *
2311 * If the length is 8, 4-byte seconds, followed
2312 * by 4-byte fractional time in microseconds,
2313 * both big-endian.
2314 *
2315 * For absolute times, the seconds are seconds
2316 * since the UN*X epoch.
2317 */
2318 if (length == 16) {
2319 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2320 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2321 } else if (length == 12) {
2322 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2323 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2324 } else if (length == 8) {
2325 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2326 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2327 } else {
2328 time_stamp->secs = 0;
2329 time_stamp->nsecs = 0;
2330 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2331 }
2332 break;
2333
2334 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2335 /*
2336 * If the length is 16, 8-byte seconds, followed
2337 * by 8-byte fractional time in microseconds,
2338 * both little-endian.
2339 *
2340 * If the length is 12, 8-byte seconds, followed
2341 * by 4-byte fractional time in microseconds,
2342 * both little-endian.
2343 *
2344 * If the length is 8, 4-byte seconds, followed
2345 * by 4-byte fractional time in microseconds,
2346 * both little-endian.
2347 *
2348 * For absolute times, the seconds are seconds
2349 * since the UN*X epoch.
2350 */
2351 if (length == 16) {
2352 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2353 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2354 } else if (length == 12) {
2355 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2356 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2357 } else if (length == 8) {
2358 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2359 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2360 } else {
2361 time_stamp->secs = 0;
2362 time_stamp->nsecs = 0;
2363 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2364 }
2365 break;
2366
2367 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2368 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2369 /*
2370 * Seconds, 1 to 8 bytes.
2371 * For absolute times, it's seconds since the
2372 * UN*X epoch.
2373 */
2374 if (length >= 1 && length <= 8) {
2375 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2376 time_stamp->nsecs = 0;
2377 } else {
2378 time_stamp->secs = 0;
2379 time_stamp->nsecs = 0;
2380 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2381 }
2382 break;
2383
2384 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2385 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2386 /*
2387 * Milliseconds, 1 to 8 bytes.
2388 * For absolute times, it's milliseconds since the
2389 * UN*X epoch.
2390 */
2391 if (length >= 1 && length <= 8) {
2392 uint64_t msecs;
2393
2394 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2395 time_stamp->secs = (time_t)(msecs / 1000);
2396 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2397 } else {
2398 time_stamp->secs = 0;
2399 time_stamp->nsecs = 0;
2400 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2401 }
2402 break;
2403
2404 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2405 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2406 /*
2407 * Microseconds, 1 to 8 bytes.
2408 * For absolute times, it's microseconds since the
2409 * UN*X epoch.
2410 */
2411 if (length >= 1 && length <= 8) {
2412 uint64_t usecs;
2413
2414 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2415 time_stamp->secs = (time_t)(usecs / 1000000);
2416 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2417 } else {
2418 time_stamp->secs = 0;
2419 time_stamp->nsecs = 0;
2420 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2421 }
2422 break;
2423
2424 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2425 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2426 /*
2427 * nanoseconds, 1 to 8 bytes.
2428 * For absolute times, it's nanoseconds since the
2429 * UN*X epoch.
2430 */
2431
2432 if (length >= 1 && length <= 8) {
2433 uint64_t nsecs;
2434
2435 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2436 time_stamp->secs = (time_t)(nsecs / 1000000000);
2437 time_stamp->nsecs = (int)(nsecs % 1000000000);
2438 } else {
2439 time_stamp->secs = 0;
2440 time_stamp->nsecs = 0;
2441 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2442 }
2443 break;
2444
2445 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2446 /*
2447 * 1/64ths of a second since the UN*X epoch,
2448 * big-endian.
2449 *
2450 * Only supported for absolute times.
2451 */
2452 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2452, "!is_relative"
))))
;
2453
2454 if (length == 8) {
2455 /*
2456 * The upper 48 bits are seconds since the
2457 * UN*X epoch.
2458 */
2459 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2460 /*
2461 * The lower 16 bits are 1/2^16s of a second;
2462 * convert them to nanoseconds.
2463 *
2464 * XXX - this may give the impression of higher
2465 * precision than you actually get.
2466 */
2467 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2468 } else {
2469 time_stamp->secs = 0;
2470 time_stamp->nsecs = 0;
2471 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2472 }
2473 break;
2474
2475 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2476 /*
2477 * 1/64ths of a second since the UN*X epoch,
2478 * little-endian.
2479 *
2480 * Only supported for absolute times.
2481 */
2482 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2482, "!is_relative"
))))
;
2483
2484 if (length == 8) {
2485 /*
2486 * XXX - this is assuming that, if anybody
2487 * were ever to use this format - RFC 3971
2488 * doesn't, because that's an Internet
2489 * protocol, and those use network byte
2490 * order, i.e. big-endian - they'd treat it
2491 * as a 64-bit count of 1/2^16s of a second,
2492 * putting the upper 48 bits at the end.
2493 *
2494 * The lower 48 bits are seconds since the
2495 * UN*X epoch.
2496 */
2497 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2498 /*
2499 * The upper 16 bits are 1/2^16s of a second;
2500 * convert them to nanoseconds.
2501 *
2502 * XXX - this may give the impression of higher
2503 * precision than you actually get.
2504 */
2505 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2506 } else {
2507 time_stamp->secs = 0;
2508 time_stamp->nsecs = 0;
2509 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2510 }
2511 break;
2512
2513 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2514 /*
2515 * NTP time stamp, with 1-second resolution (i.e.,
2516 * seconds since the NTP epoch), big-endian.
2517 * Only supported for absolute times.
2518 */
2519 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2519, "!is_relative"
))))
;
2520
2521 if (length == 4) {
2522 /*
2523 * We need a temporary variable here so the unsigned math
2524 * works correctly (for years > 2036 according to RFC 2030
2525 * chapter 3).
2526 *
2527 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2528 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2529 * If bit 0 is not set, the time is in the range 2036-2104 and
2530 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2531 */
2532 tmpsecs = tvb_get_ntohl(tvb, start);
2533 if ((tmpsecs & 0x80000000) != 0)
2534 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2535 else
2536 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2537 time_stamp->nsecs = 0;
2538 } else {
2539 time_stamp->secs = 0;
2540 time_stamp->nsecs = 0;
2541 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2542 }
2543 break;
2544
2545 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2546 /*
2547 * NTP time stamp, with 1-second resolution (i.e.,
2548 * seconds since the NTP epoch), little-endian.
2549 * Only supported for absolute times.
2550 */
2551 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2551, "!is_relative"
))))
;
2552
2553 /*
2554 * We need a temporary variable here so the unsigned math
2555 * works correctly (for years > 2036 according to RFC 2030
2556 * chapter 3).
2557 *
2558 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2559 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2560 * If bit 0 is not set, the time is in the range 2036-2104 and
2561 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2562 */
2563 if (length == 4) {
2564 tmpsecs = tvb_get_letohl(tvb, start);
2565 if ((tmpsecs & 0x80000000) != 0)
2566 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2567 else
2568 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2569 time_stamp->nsecs = 0;
2570 } else {
2571 time_stamp->secs = 0;
2572 time_stamp->nsecs = 0;
2573 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2574 }
2575 break;
2576
2577 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2578 /*
2579 * Milliseconds, 6 to 8 bytes.
2580 * For absolute times, it's milliseconds since the
2581 * NTP epoch.
2582 *
2583 * ETSI TS 129.274 8.119 defines this as:
2584 * "a 48 bit unsigned integer in network order format
2585 * ...encoded as the number of milliseconds since
2586 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2587 * rounded value of 1000 x the value of the 64-bit
2588 * timestamp (Seconds + (Fraction / (1<<32))) defined
2589 * in clause 6 of IETF RFC 5905."
2590 *
2591 * Taken literally, the part after "i.e." would
2592 * mean that the value rolls over before reaching
2593 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2594 * when the 64 bit timestamp rolls over, and we have
2595 * to pick an NTP Era equivalence class to support
2596 * (such as 1968-01-20 to 2104-02-06).
2597 *
2598 * OTOH, the extra room might be used to store Era
2599 * information instead, in which case times until
2600 * 10819-08-03 can be represented with 6 bytes without
2601 * ambiguity. We handle both implementations, and assume
2602 * that times before 1968-01-20 are not represented.
2603 *
2604 * Only 6 bytes or more makes sense as an absolute
2605 * time. 5 bytes or fewer could express a span of
2606 * less than 35 years, either 1900-1934 or 2036-2070.
2607 */
2608 if (length >= 6 && length <= 8) {
2609 uint64_t msecs;
2610
2611 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2612 tmp64secs = (msecs / 1000);
2613 /*
2614 * Assume that times in the first half of NTP
2615 * Era 0 really represent times in the NTP
2616 * Era 1.
2617 */
2618 if (tmp64secs >= 0x80000000)
2619 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2620 else
2621 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2622 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2623 }
2624 else {
2625 time_stamp->secs = 0;
2626 time_stamp->nsecs = 0;
2627 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2628 }
2629 break;
2630
2631 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2632 /*
2633 * MP4 file time stamps, big-endian.
2634 * Only supported for absolute times.
2635 */
2636 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2636, "!is_relative"
))))
;
2637
2638 if (length == 8) {
2639 tmp64secs = tvb_get_ntoh64(tvb, start);
2640 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2641 time_stamp->nsecs = 0;
2642 } else if (length == 4) {
2643 tmpsecs = tvb_get_ntohl(tvb, start);
2644 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2645 time_stamp->nsecs = 0;
2646 } else {
2647 time_stamp->secs = 0;
2648 time_stamp->nsecs = 0;
2649 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2650 }
2651 break;
2652
2653 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2654 /*
2655 * Zigbee ZCL time stamps, big-endian.
2656 * Only supported for absolute times.
2657 */
2658 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2658, "!is_relative"
))))
;
2659
2660 if (length == 8) {
2661 tmp64secs = tvb_get_ntoh64(tvb, start);
2662 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);
2663 time_stamp->nsecs = 0;
2664 } else if (length == 4) {
2665 tmpsecs = tvb_get_ntohl(tvb, start);
2666 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2667 time_stamp->nsecs = 0;
2668 } else {
2669 time_stamp->secs = 0;
2670 time_stamp->nsecs = 0;
2671 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2672 }
2673 break;
2674
2675 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2676 /*
2677 * Zigbee ZCL time stamps, little-endian.
2678 * Only supported for absolute times.
2679 */
2680 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2680, "!is_relative"
))))
;
2681
2682 if (length == 8) {
2683 tmp64secs = tvb_get_letoh64(tvb, start);
2684 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);
2685 time_stamp->nsecs = 0;
2686 } else if (length == 4) {
2687 tmpsecs = tvb_get_letohl(tvb, start);
2688 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2689 time_stamp->nsecs = 0;
2690 } else {
2691 time_stamp->secs = 0;
2692 time_stamp->nsecs = 0;
2693 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2694 }
2695 break;
2696
2697 default:
2698 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2698))
;
2699 break;
2700 }
2701}
2702
2703static void
2704tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2705{
2706 const header_field_info *hfinfo = fi->hfinfo;
2707
2708 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2709 GPtrArray *ptrs = NULL((void*)0);
2710
2711 if (tree_data->interesting_hfids == NULL((void*)0)) {
2712 /* Initialize the hash because we now know that it is needed */
2713 tree_data->interesting_hfids =
2714 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2715 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2716 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2717 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2718 }
2719
2720 if (!ptrs) {
2721 /* First element triggers the creation of pointer array */
2722 ptrs = g_ptr_array_new();
2723 g_hash_table_insert(tree_data->interesting_hfids,
2724 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2725 }
2726
2727 g_ptr_array_add(ptrs, fi);
2728 }
2729}
2730
2731
2732/*
2733 * Validates that field length bytes are available starting from
2734 * start (pos/neg). Throws an exception if they aren't.
2735 */
2736static void
2737test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2738 int start, int length, const unsigned encoding)
2739{
2740 int size = length;
2741
2742 if (!tvb)
2743 return;
2744
2745 if ((hfinfo->type == FT_STRINGZ) ||
2746 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2747 (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
))
))) {
2748 /* If we're fetching until the end of the TVB, only validate
2749 * that the offset is within range.
2750 */
2751 if (length == -1)
2752 size = 0;
2753 }
2754
2755 tvb_ensure_bytes_exist(tvb, start, size);
2756}
2757
2758static void
2759detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2760{
2761 bool_Bool found_stray_character = false0;
2762
2763 if (!string)
2764 return;
2765
2766 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2767 case ENC_ASCII0x00000000:
2768 case ENC_UTF_80x00000002:
2769 for (int i = (int)strlen(string); i < length; i++) {
2770 if (string[i] != '\0') {
2771 found_stray_character = true1;
2772 break;
2773 }
2774 }
2775 break;
2776
2777 default:
2778 break;
2779 }
2780
2781 if (found_stray_character) {
2782 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2783 }
2784}
2785
2786static void
2787free_fvalue_cb(void *data)
2788{
2789 fvalue_t *fv = (fvalue_t*)data;
2790 fvalue_free(fv);
2791}
2792
2793/* Add an item to a proto_tree, using the text label registered to that item;
2794 the item is extracted from the tvbuff handed to it. */
2795static proto_item *
2796proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2797 tvbuff_t *tvb, int start, int length,
2798 unsigned encoding)
2799{
2800 proto_item *pi;
2801 uint32_t value, n;
2802 uint64_t value64;
2803 ws_in4_addr ipv4_value;
2804 float floatval;
2805 double doubleval;
2806 const char *stringval = NULL((void*)0);
2807 nstime_t time_stamp;
2808 bool_Bool length_error;
2809
2810 /* Ensure that the newly created fvalue_t is freed if we throw an
2811 * exception before adding it to the tree. (gcc creates clobbering
2812 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2813 * XXX: Move the new_field_info() call inside here?
2814 */
2815 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))
;
2816
2817 switch (new_fi->hfinfo->type) {
2818 case FT_NONE:
2819 /* no value to set for FT_NONE */
2820 break;
2821
2822 case FT_PROTOCOL:
2823 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2824 break;
2825
2826 case FT_BYTES:
2827 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2828 break;
2829
2830 case FT_UINT_BYTES:
2831 n = get_uint_value(tree, tvb, start, length, encoding);
2832 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2833
2834 /* Instead of calling proto_item_set_len(), since we don't yet
2835 * have a proto_item, we set the field_info's length ourselves. */
2836 new_fi->length = n + length;
2837 break;
2838
2839 case FT_BOOLEAN:
2840 /*
2841 * Map all non-zero values to little-endian for
2842 * backwards compatibility.
2843 */
2844 if (encoding)
2845 encoding = ENC_LITTLE_ENDIAN0x80000000;
2846 proto_tree_set_boolean(new_fi,
2847 get_uint64_value(tree, tvb, start, length, encoding));
2848 break;
2849
2850 case FT_CHAR:
2851 /* XXX - make these just FT_UINT? */
2852 case FT_UINT8:
2853 case FT_UINT16:
2854 case FT_UINT24:
2855 case FT_UINT32:
2856 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2857 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2858 value = (uint32_t)value64;
2859 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2860 new_fi->flags |= FI_VARINT0x00040000;
2861 }
2862 }
2863 else {
2864 /*
2865 * Map all non-zero values to little-endian for
2866 * backwards compatibility.
2867 */
2868 if (encoding)
2869 encoding = ENC_LITTLE_ENDIAN0x80000000;
2870
2871 value = get_uint_value(tree, tvb, start, length, encoding);
2872 }
2873 proto_tree_set_uint(new_fi, value);
2874 break;
2875
2876 case FT_UINT40:
2877 case FT_UINT48:
2878 case FT_UINT56:
2879 case FT_UINT64:
2880 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2881 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2882 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2883 new_fi->flags |= FI_VARINT0x00040000;
2884 }
2885 }
2886 else {
2887 /*
2888 * Map all other non-zero values to little-endian for
2889 * backwards compatibility.
2890 */
2891 if (encoding)
2892 encoding = ENC_LITTLE_ENDIAN0x80000000;
2893
2894 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2895 }
2896 proto_tree_set_uint64(new_fi, value64);
2897 break;
2898
2899 /* XXX - make these just FT_INT? */
2900 case FT_INT8:
2901 case FT_INT16:
2902 case FT_INT24:
2903 case FT_INT32:
2904 /*
2905 * Map all non-zero values to little-endian for
2906 * backwards compatibility.
2907 */
2908 if (encoding)
2909 encoding = ENC_LITTLE_ENDIAN0x80000000;
2910 proto_tree_set_int(new_fi,
2911 get_int_value(tree, tvb, start, length, encoding));
2912 break;
2913
2914 case FT_INT40:
2915 case FT_INT48:
2916 case FT_INT56:
2917 case FT_INT64:
2918 /*
2919 * Map all non-zero values to little-endian for
2920 * backwards compatibility.
2921 */
2922 if (encoding)
2923 encoding = ENC_LITTLE_ENDIAN0x80000000;
2924 proto_tree_set_int64(new_fi,
2925 get_int64_value(tree, tvb, start, length, encoding));
2926 break;
2927
2928 case FT_IPv4:
2929 /*
2930 * Map all non-zero values to little-endian for
2931 * backwards compatibility.
2932 */
2933 if (encoding)
2934 encoding = ENC_LITTLE_ENDIAN0x80000000;
2935 if (length != FT_IPv4_LEN4) {
2936 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2937 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2938 }
2939 ipv4_value = tvb_get_ipv4(tvb, start);
2940 /*
2941 * NOTE: to support code written when
2942 * proto_tree_add_item() took a bool as its
2943 * last argument, with false meaning "big-endian"
2944 * and true meaning "little-endian", we treat any
2945 * non-zero value of "encoding" as meaning
2946 * "little-endian".
2947 */
2948 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);
2949 break;
2950
2951 case FT_IPXNET:
2952 if (length != FT_IPXNET_LEN4) {
2953 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2954 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2955 }
2956 proto_tree_set_ipxnet(new_fi,
2957 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2958 break;
2959
2960 case FT_IPv6:
2961 if (length != FT_IPv6_LEN16) {
2962 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2963 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2964 }
2965 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2966 break;
2967
2968 case FT_FCWWN:
2969 if (length != FT_FCWWN_LEN8) {
2970 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2971 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2972 }
2973 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2974 break;
2975
2976 case FT_AX25:
2977 if (length != 7) {
2978 length_error = length < 7 ? true1 : false0;
2979 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2980 }
2981 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2982 break;
2983
2984 case FT_VINES:
2985 if (length != VINES_ADDR_LEN6) {
2986 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
2987 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2988 }
2989 proto_tree_set_vines_tvb(new_fi, tvb, start);
2990 break;
2991
2992 case FT_ETHER:
2993 if (length != FT_ETHER_LEN6) {
2994 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
2995 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2996 }
2997 proto_tree_set_ether_tvb(new_fi, tvb, start);
2998 break;
2999
3000 case FT_EUI64:
3001 /*
3002 * Map all non-zero values to little-endian for
3003 * backwards compatibility.
3004 */
3005 if (encoding)
3006 encoding = ENC_LITTLE_ENDIAN0x80000000;
3007 if (length != FT_EUI64_LEN8) {
3008 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3009 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3010 }
3011 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3012 break;
3013 case FT_GUID:
3014 /*
3015 * Map all non-zero values to little-endian for
3016 * backwards compatibility.
3017 */
3018 if (encoding)
3019 encoding = ENC_LITTLE_ENDIAN0x80000000;
3020 if (length != FT_GUID_LEN16) {
3021 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3022 report_type_length_mismatch(tree, "a GUID", length, length_error);
3023 }
3024 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3025 break;
3026
3027 case FT_OID:
3028 case FT_REL_OID:
3029 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3030 break;
3031
3032 case FT_SYSTEM_ID:
3033 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3034 break;
3035
3036 case FT_FLOAT:
3037 /*
3038 * NOTE: to support code written when
3039 * proto_tree_add_item() took a bool as its
3040 * last argument, with false meaning "big-endian"
3041 * and true meaning "little-endian", we treat any
3042 * non-zero value of "encoding" as meaning
3043 * "little-endian".
3044 *
3045 * At some point in the future, we might
3046 * support non-IEEE-binary floating-point
3047 * formats in the encoding as well
3048 * (IEEE decimal, System/3x0, VAX).
3049 */
3050 if (encoding)
3051 encoding = ENC_LITTLE_ENDIAN0x80000000;
3052 if (length != 4) {
3053 length_error = length < 4 ? true1 : false0;
3054 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3055 }
3056 if (encoding)
3057 floatval = tvb_get_letohieee_float(tvb, start);
3058 else
3059 floatval = tvb_get_ntohieee_float(tvb, start);
3060 proto_tree_set_float(new_fi, floatval);
3061 break;
3062
3063 case FT_DOUBLE:
3064 /*
3065 * NOTE: to support code written when
3066 * proto_tree_add_item() took a bool as its
3067 * last argument, with false meaning "big-endian"
3068 * and true meaning "little-endian", we treat any
3069 * non-zero value of "encoding" as meaning
3070 * "little-endian".
3071 *
3072 * At some point in the future, we might
3073 * support non-IEEE-binary floating-point
3074 * formats in the encoding as well
3075 * (IEEE decimal, System/3x0, VAX).
3076 */
3077 if (encoding == true1)
3078 encoding = ENC_LITTLE_ENDIAN0x80000000;
3079 if (length != 8) {
3080 length_error = length < 8 ? true1 : false0;
3081 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3082 }
3083 if (encoding)
3084 doubleval = tvb_get_letohieee_double(tvb, start);
3085 else
3086 doubleval = tvb_get_ntohieee_double(tvb, start);
3087 proto_tree_set_double(new_fi, doubleval);
3088 break;
3089
3090 case FT_STRING:
3091 stringval = get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3092 tvb, start, length, &length, encoding);
3093 proto_tree_set_string(new_fi, stringval);
3094
3095 /* Instead of calling proto_item_set_len(), since we
3096 * don't yet have a proto_item, we set the
3097 * field_info's length ourselves.
3098 *
3099 * XXX - our caller can't use that length to
3100 * advance an offset unless they arrange that
3101 * there always be a protocol tree into which
3102 * we're putting this item.
3103 */
3104 new_fi->length = length;
3105 break;
3106
3107 case FT_STRINGZ:
3108 stringval = get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3109 tree, tvb, start, length, &length, encoding);
3110 proto_tree_set_string(new_fi, stringval);
3111
3112 /* Instead of calling proto_item_set_len(),
3113 * since we don't yet have a proto_item, we
3114 * set the field_info's length ourselves.
3115 *
3116 * XXX - our caller can't use that length to
3117 * advance an offset unless they arrange that
3118 * there always be a protocol tree into which
3119 * we're putting this item.
3120 */
3121 new_fi->length = length;
3122 break;
3123
3124 case FT_UINT_STRING:
3125 /*
3126 * NOTE: to support code written when
3127 * proto_tree_add_item() took a bool as its
3128 * last argument, with false meaning "big-endian"
3129 * and true meaning "little-endian", if the
3130 * encoding value is true, treat that as
3131 * ASCII with a little-endian length.
3132 *
3133 * This won't work for code that passes
3134 * arbitrary non-zero values; that code
3135 * will need to be fixed.
3136 */
3137 if (encoding == true1)
3138 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3139 stringval = get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3140 tree, tvb, start, length, &length, encoding);
3141 proto_tree_set_string(new_fi, stringval);
3142
3143 /* Instead of calling proto_item_set_len(), since we
3144 * don't yet have a proto_item, we set the
3145 * field_info's length ourselves.
3146 *
3147 * XXX - our caller can't use that length to
3148 * advance an offset unless they arrange that
3149 * there always be a protocol tree into which
3150 * we're putting this item.
3151 */
3152 new_fi->length = length;
3153 break;
3154
3155 case FT_STRINGZPAD:
3156 stringval = get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3157 tvb, start, length, &length, encoding);
3158 proto_tree_set_string(new_fi, stringval);
3159
3160 /* Instead of calling proto_item_set_len(), since we
3161 * don't yet have a proto_item, we set the
3162 * field_info's length ourselves.
3163 *
3164 * XXX - our caller can't use that length to
3165 * advance an offset unless they arrange that
3166 * there always be a protocol tree into which
3167 * we're putting this item.
3168 */
3169 new_fi->length = length;
3170 break;
3171
3172 case FT_STRINGZTRUNC:
3173 stringval = get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3174 tvb, start, length, &length, encoding);
3175 proto_tree_set_string(new_fi, stringval);
3176
3177 /* Instead of calling proto_item_set_len(), since we
3178 * don't yet have a proto_item, we set the
3179 * field_info's length ourselves.
3180 *
3181 * XXX - our caller can't use that length to
3182 * advance an offset unless they arrange that
3183 * there always be a protocol tree into which
3184 * we're putting this item.
3185 */
3186 new_fi->length = length;
3187 break;
3188
3189 case FT_ABSOLUTE_TIME:
3190 /*
3191 * Absolute times can be in any of a number of
3192 * formats, and they can be big-endian or
3193 * little-endian.
3194 *
3195 * Historically FT_TIMEs were only timespecs;
3196 * the only question was whether they were stored
3197 * in big- or little-endian format.
3198 *
3199 * For backwards compatibility, we interpret an
3200 * encoding of 1 as meaning "little-endian timespec",
3201 * so that passing true is interpreted as that.
3202 */
3203 if (encoding == true1)
3204 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3205
3206 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3207
3208 proto_tree_set_time(new_fi, &time_stamp);
3209 break;
3210
3211 case FT_RELATIVE_TIME:
3212 /*
3213 * Relative times can be in any of a number of
3214 * formats, and they can be big-endian or
3215 * little-endian.
3216 *
3217 * Historically FT_TIMEs were only timespecs;
3218 * the only question was whether they were stored
3219 * in big- or little-endian format.
3220 *
3221 * For backwards compatibility, we interpret an
3222 * encoding of 1 as meaning "little-endian timespec",
3223 * so that passing true is interpreted as that.
3224 */
3225 if (encoding == true1)
3226 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3227
3228 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3229
3230 proto_tree_set_time(new_fi, &time_stamp);
3231 break;
3232 case FT_IEEE_11073_SFLOAT:
3233 if (encoding)
3234 encoding = ENC_LITTLE_ENDIAN0x80000000;
3235 if (length != 2) {
3236 length_error = length < 2 ? true1 : false0;
3237 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3238 }
3239
3240 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3241
3242 break;
3243 case FT_IEEE_11073_FLOAT:
3244 if (encoding)
3245 encoding = ENC_LITTLE_ENDIAN0x80000000;
3246 if (length != 4) {
3247 length_error = length < 4 ? true1 : false0;
3248 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3249 }
3250 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3251
3252 break;
3253 default:
3254 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))
3255 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))
3256 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))
3257 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))
;
3258 break;
3259 }
3260 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)
;
3261
3262 /* Don't add new node to proto_tree until now so that any exceptions
3263 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3264 /* XXX. wouldn't be better to add this item to tree, with some special
3265 * flag (FI_EXCEPTION?) to know which item caused exception? For
3266 * strings and bytes, we would have to set new_fi->value to something
3267 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3268 * could handle NULL values. */
3269 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3270 pi = proto_tree_add_node(tree, new_fi);
3271
3272 switch (new_fi->hfinfo->type) {
3273
3274 case FT_STRING:
3275 /* XXX: trailing stray character detection should be done
3276 * _before_ conversion to UTF-8, because conversion can change
3277 * the length, or else get_string_length should return a value
3278 * for the "length in bytes of the string after conversion
3279 * including internal nulls." (Noting that we do, for other
3280 * reasons, still need the "length in bytes in the field",
3281 * especially for FT_STRINGZ.)
3282 *
3283 * This is true even for ASCII and UTF-8, because
3284 * substituting REPLACEMENT CHARACTERS for illegal characters
3285 * can also do so (and for UTF-8 possibly even make the
3286 * string _shorter_).
3287 */
3288 detect_trailing_stray_characters(encoding, stringval, length, pi);
3289 break;
3290
3291 default:
3292 break;
3293 }
3294
3295 return pi;
3296}
3297
3298proto_item *
3299proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3300 const int start, int length,
3301 const unsigned encoding, int32_t *retval)
3302{
3303 header_field_info *hfinfo;
3304 field_info *new_fi;
3305 int32_t value;
3306
3307 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", 3307, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3307,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3307, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3308
3309 switch (hfinfo->type) {
3310 case FT_INT8:
3311 case FT_INT16:
3312 case FT_INT24:
3313 case FT_INT32:
3314 break;
3315 case FT_INT64:
3316 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)
3317 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3318 default:
3319 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)
3320 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3321 }
3322
3323 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3324 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3325 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3326 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3327 *retval = 0;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 (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3330
3331 if (encoding & ENC_STRING0x03000000) {
3332 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3333 }
3334 /* I believe it's ok if this is called with a NULL tree */
3335 value = get_int_value(tree, tvb, start, length, encoding);
3336
3337 if (retval) {
3338 int no_of_bits;
3339 *retval = value;
3340 if (hfinfo->bitmask) {
3341 /* Mask out irrelevant portions */
3342 *retval &= (uint32_t)(hfinfo->bitmask);
3343 /* Shift bits */
3344 *retval >>= hfinfo_bitshift(hfinfo);
3345 }
3346 no_of_bits = ws_count_ones(hfinfo->bitmask);
3347 *retval = ws_sign_ext32(*retval, no_of_bits);
3348 }
3349
3350 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3351
3352 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", 3352
, __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", 3352, "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", 3352, "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", 3352, __func__, "Adding %s would put more than %d 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)
; } } }
;
3353
3354 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3355
3356 proto_tree_set_int(new_fi, value);
3357
3358 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3359
3360 return proto_tree_add_node(tree, new_fi);
3361}
3362
3363proto_item *
3364proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3365 const int start, int length,
3366 const unsigned encoding, uint32_t *retval)
3367{
3368 header_field_info *hfinfo;
3369 field_info *new_fi;
3370 uint32_t value;
3371
3372 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", 3372, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3372,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3372, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3373
3374 switch (hfinfo->type) {
3375 case FT_CHAR:
3376 case FT_UINT8:
3377 case FT_UINT16:
3378 case FT_UINT24:
3379 case FT_UINT32:
3380 break;
3381 default:
3382 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)
3383 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)
;
3384 }
3385
3386 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3387 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3388 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3389 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3390 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3391 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3392 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3393
3394 if (encoding & ENC_STRING0x03000000) {
3395 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3396 }
3397 /* I believe it's ok if this is called with a NULL tree */
3398 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3399 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3400 uint64_t temp64;
3401 tvb_get_varint(tvb, start, length, &temp64, encoding);
3402 value = (uint32_t)temp64;
3403 } else {
3404 value = get_uint_value(tree, tvb, start, length, encoding);
3405 }
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 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3418
3419 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", 3419
, __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", 3419, "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", 3419, "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", 3419, __func__, "Adding %s would put more than %d 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)
; } } }
;
3420
3421 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3422
3423 proto_tree_set_uint(new_fi, value);
3424
3425 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3426 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3427 new_fi->flags |= FI_VARINT0x00040000;
3428 }
3429 return proto_tree_add_node(tree, new_fi);
3430}
3431
3432/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3433 * and returns proto_item* and uint value retreived*/
3434proto_item *
3435ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3436 const unsigned encoding, uint32_t *retval)
3437{
3438 field_info *new_fi;
3439 header_field_info *hfinfo;
3440 int item_length;
3441 int offset;
3442 uint32_t value;
3443
3444 offset = ptvc->offset;
3445 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3445, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3445,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3445, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3446
3447 switch (hfinfo->type) {
3448 case FT_CHAR:
3449 case FT_UINT8:
3450 case FT_UINT16:
3451 case FT_UINT24:
3452 case FT_UINT32:
3453 break;
3454 default:
3455 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)
3456 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)
;
3457 }
3458
3459 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3460 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3461
3462 /* I believe it's ok if this is called with a NULL tree */
3463 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3464 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3465
3466 if (retval) {
3467 *retval = value;
3468 if (hfinfo->bitmask) {
3469 /* Mask out irrelevant portions */
3470 *retval &= (uint32_t)(hfinfo->bitmask);
3471 /* Shift bits */
3472 *retval >>= hfinfo_bitshift(hfinfo);
3473 }
3474 }
3475
3476 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3477 item_length, encoding);
3478
3479 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3480
3481 /* Coast clear. Try and fake it */
3482 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", 3482
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3482, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3482, "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", 3482, __func__, "Adding %s would put more than %d 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); } } }
;
3483
3484 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3485
3486 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3487 offset, length, encoding);
3488}
3489
3490/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3491 * and returns proto_item* and int value retreived*/
3492proto_item *
3493ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3494 const unsigned encoding, int32_t *retval)
3495{
3496 field_info *new_fi;
3497 header_field_info *hfinfo;
3498 int item_length;
3499 int offset;
3500 uint32_t value;
3501
3502 offset = ptvc->offset;
3503 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", 3503, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3503,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3503, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3504
3505 switch (hfinfo->type) {
3506 case FT_INT8:
3507 case FT_INT16:
3508 case FT_INT24:
3509 case FT_INT32:
3510 break;
3511 default:
3512 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)
3513 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3514 }
3515
3516 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3517 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3518
3519 /* I believe it's ok if this is called with a NULL tree */
3520 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3521 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3522
3523 if (retval) {
3524 int no_of_bits;
3525 *retval = value;
3526 if (hfinfo->bitmask) {
3527 /* Mask out irrelevant portions */
3528 *retval &= (uint32_t)(hfinfo->bitmask);
3529 /* Shift bits */
3530 *retval >>= hfinfo_bitshift(hfinfo);
3531 }
3532 no_of_bits = ws_count_ones(hfinfo->bitmask);
3533 *retval = ws_sign_ext32(*retval, no_of_bits);
3534 }
3535
3536 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3537 item_length, encoding);
3538
3539 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3540
3541 /* Coast clear. Try and fake it */
3542 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", 3542
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3542, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3542, "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", 3542, __func__, "Adding %s would put more than %d 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); } } }
;
3543
3544 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3545
3546 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3547 offset, length, encoding);
3548}
3549
3550/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3551 * and returns proto_item* and string value retreived */
3552proto_item*
3553ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3554{
3555 header_field_info *hfinfo;
3556 field_info *new_fi;
3557 const uint8_t *value;
3558 int item_length;
3559 int offset;
3560
3561 offset = ptvc->offset;
3562
3563 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", 3563
, __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", 3563, "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", 3563, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3564
3565 switch (hfinfo->type) {
3566 case FT_STRING:
3567 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3568 break;
3569 case FT_STRINGZ:
3570 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3571 break;
3572 case FT_UINT_STRING:
3573 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3574 break;
3575 case FT_STRINGZPAD:
3576 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3577 break;
3578 case FT_STRINGZTRUNC:
3579 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3580 break;
3581 default:
3582 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)
3583 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)
;
3584 }
3585
3586 if (retval)
3587 *retval = value;
3588
3589 ptvc->offset += item_length;
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
3601/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3602 * and returns proto_item* and boolean value retreived */
3603proto_item*
3604ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3605{
3606 header_field_info *hfinfo;
3607 field_info *new_fi;
3608 int item_length;
3609 int offset;
3610 uint64_t value, bitval;
3611
3612 offset = ptvc->offset;
3613 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", 3613, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3613,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3613, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3614
3615 if (hfinfo->type != FT_BOOLEAN) {
3616 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)
3617 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3618 }
3619
3620 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3621 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3622 if(retval)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 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3625 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3626 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3627
3628 if (encoding & ENC_STRING0x03000000) {
3629 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3630 }
3631
3632 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3633 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3634
3635 /* I believe it's ok if this is called with a NULL tree */
3636 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3637
3638 if (retval) {
3639 bitval = value;
3640 if (hfinfo->bitmask) {
3641 /* Mask out irrelevant portions */
3642 bitval &= hfinfo->bitmask;
3643 }
3644 *retval = (bitval != 0);
3645 }
3646
3647 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3648 item_length, encoding);
3649
3650 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3651
3652 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", 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 (((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", 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); ((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); } } }
;
3653
3654 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3655
3656 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3657 offset, length, encoding);
3658}
3659
3660proto_item *
3661proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3662 const int start, int length, const unsigned encoding, uint64_t *retval)
3663{
3664 header_field_info *hfinfo;
3665 field_info *new_fi;
3666 uint64_t value;
3667
3668 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", 3668, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3668,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3668, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3669
3670 switch (hfinfo->type) {
3671 case FT_UINT40:
3672 case FT_UINT48:
3673 case FT_UINT56:
3674 case FT_UINT64:
3675 break;
3676 default:
3677 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)
3678 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3679 }
3680
3681 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3682 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3683 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3684 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3685 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3686 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3687 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3688
3689 if (encoding & ENC_STRING0x03000000) {
3690 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3691 }
3692 /* I believe it's ok if this is called with a NULL tree */
3693 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3694 tvb_get_varint(tvb, start, length, &value, encoding);
3695 } else {
3696 value = get_uint64_value(tree, tvb, start, length, encoding);
3697 }
3698
3699 if (retval) {
3700 *retval = value;
3701 if (hfinfo->bitmask) {
3702 /* Mask out irrelevant portions */
3703 *retval &= hfinfo->bitmask;
3704 /* Shift bits */
3705 *retval >>= hfinfo_bitshift(hfinfo);
3706 }
3707 }
3708
3709 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3710
3711 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", 3711
, __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", 3711, "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", 3711, "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", 3711, __func__, "Adding %s would put more than %d 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)
; } } }
;
3712
3713 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3714
3715 proto_tree_set_uint64(new_fi, value);
3716
3717 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3718 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3719 new_fi->flags |= FI_VARINT0x00040000;
3720 }
3721
3722 return proto_tree_add_node(tree, new_fi);
3723}
3724
3725proto_item *
3726proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3727 const int start, int length, const unsigned encoding, int64_t *retval)
3728{
3729 header_field_info *hfinfo;
3730 field_info *new_fi;
3731 int64_t value;
3732
3733 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", 3733, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3733,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3733, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3734
3735 switch (hfinfo->type) {
3736 case FT_INT40:
3737 case FT_INT48:
3738 case FT_INT56:
3739 case FT_INT64:
3740 break;
3741 default:
3742 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)
3743 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3744 }
3745
3746 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3747 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3748 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3749 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3750 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3751 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3752 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3753
3754 if (encoding & ENC_STRING0x03000000) {
3755 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3756 }
3757 /* I believe it's ok if this is called with a NULL tree */
3758 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3759 tvb_get_varint(tvb, start, length, &value, encoding);
3760 }
3761 else {
3762 value = get_int64_value(tree, tvb, start, length, encoding);
3763 }
3764
3765 if (retval) {
3766 *retval = value;
3767 }
3768
3769 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3770
3771 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3771
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3771, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3771, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3771, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3772
3773 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3774
3775 proto_tree_set_int64(new_fi, value);
3776
3777 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3778 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3779 new_fi->flags |= FI_VARINT0x00040000;
3780 }
3781
3782 return proto_tree_add_node(tree, new_fi);
3783}
3784
3785proto_item *
3786proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3787 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3788{
3789 header_field_info *hfinfo;
3790 field_info *new_fi;
3791 uint64_t value;
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 ((!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
))
)) {
3796 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)
3797 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3798 }
3799
3800 /* length validation for native number encoding caught by get_uint64_value() */
3801 /* length has to be -1 or > 0 regardless of encoding */
3802 if (length == 0)
3803 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)
3804 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3805
3806 if (encoding & ENC_STRING0x03000000) {
3807 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3808 }
3809
3810 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3811
3812 if (retval) {
3813 *retval = value;
3814 if (hfinfo->bitmask) {
3815 /* Mask out irrelevant portions */
3816 *retval &= hfinfo->bitmask;
3817 /* Shift bits */
3818 *retval >>= hfinfo_bitshift(hfinfo);
3819 }
3820 }
3821
3822 if (lenretval) {
3823 *lenretval = length;
3824 }
3825
3826 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3827
3828 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", 3828
, __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", 3828, "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", 3828, "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", 3828, __func__, "Adding %s would put more than %d 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)
; } } }
;
3829
3830 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3831
3832 proto_tree_set_uint64(new_fi, value);
3833
3834 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3835 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3836 new_fi->flags |= FI_VARINT0x00040000;
3837 }
3838
3839 return proto_tree_add_node(tree, new_fi);
3840
3841}
3842
3843proto_item *
3844proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3845 const int start, int length,
3846 const unsigned encoding, bool_Bool *retval)
3847{
3848 header_field_info *hfinfo;
3849 field_info *new_fi;
3850 uint64_t value, bitval;
3851
3852 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", 3852, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3852,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3852, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3853
3854 if (hfinfo->type != FT_BOOLEAN) {
3855 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)
3856 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3857 }
3858
3859 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3860 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3861 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3862 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3863 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3864 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3865 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3866
3867 if (encoding & ENC_STRING0x03000000) {
3868 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3869 }
3870 /* I believe it's ok if this is called with a NULL tree */
3871 value = get_uint64_value(tree, tvb, start, length, encoding);
3872
3873 if (retval) {
3874 bitval = value;
3875 if (hfinfo->bitmask) {
3876 /* Mask out irrelevant portions */
3877 bitval &= hfinfo->bitmask;
3878 }
3879 *retval = (bitval != 0);
3880 }
3881
3882 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3883
3884 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", 3884
, __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", 3884, "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", 3884, "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", 3884, __func__, "Adding %s would put more than %d 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)
; } } }
;
3885
3886 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3887
3888 proto_tree_set_boolean(new_fi, value);
3889
3890 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3891
3892 return proto_tree_add_node(tree, new_fi);
3893}
3894
3895proto_item *
3896proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3897 const int start, int length,
3898 const unsigned encoding, float *retval)
3899{
3900 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3901 field_info *new_fi;
3902 float value;
3903
3904 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", 3904,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3905
3906 if (hfinfo->type != FT_FLOAT) {
3907 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)
;
3908 }
3909
3910 if (length != 4) {
3911 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3912 }
3913
3914 /* treat any nonzero encoding as little endian for backwards compatibility */
3915 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3916 if (retval) {
3917 *retval = value;
3918 }
3919
3920 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3921
3922 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", 3922
, __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", 3922, "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", 3922, "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", 3922, __func__, "Adding %s would put more than %d 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)
; } } }
;
3923
3924 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3925 if (encoding) {
3926 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3927 }
3928
3929 proto_tree_set_float(new_fi, value);
3930
3931 return proto_tree_add_node(tree, new_fi);
3932}
3933
3934proto_item *
3935proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3936 const int start, int length,
3937 const unsigned encoding, double *retval)
3938{
3939 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3940 field_info *new_fi;
3941 double value;
3942
3943 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", 3943,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3944
3945 if (hfinfo->type != FT_DOUBLE) {
3946 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)
;
3947 }
3948
3949 if (length != 8) {
3950 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3951 }
3952
3953 /* treat any nonzero encoding as little endian for backwards compatibility */
3954 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3955 if (retval) {
3956 *retval = value;
3957 }
3958
3959 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3960
3961 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", 3961
, __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", 3961, "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", 3961, "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", 3961, __func__, "Adding %s would put more than %d 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)
; } } }
;
3962
3963 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3964 if (encoding) {
3965 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3966 }
3967
3968 proto_tree_set_double(new_fi, value);
3969
3970 return proto_tree_add_node(tree, new_fi);
3971}
3972
3973proto_item *
3974proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3975 const int start, int length,
3976 const unsigned encoding, ws_in4_addr *retval)
3977{
3978 header_field_info *hfinfo;
3979 field_info *new_fi;
3980 ws_in4_addr value;
3981
3982 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", 3982, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3982,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3982, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3983
3984 switch (hfinfo->type) {
3985 case FT_IPv4:
3986 break;
3987 default:
3988 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)
3989 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
3990 }
3991
3992 if (length != FT_IPv4_LEN4)
3993 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)
3994 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
3995
3996 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3997 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3998 }
3999
4000 /*
4001 * NOTE: to support code written when proto_tree_add_item() took
4002 * a bool as its last argument, with false meaning "big-endian"
4003 * and true meaning "little-endian", we treat any non-zero value
4004 * of "encoding" as meaning "little-endian".
4005 */
4006 value = tvb_get_ipv4(tvb, start);
4007 if (encoding)
4008 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))))
;
4009
4010 if (retval) {
4011 *retval = value;
4012 }
4013
4014 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4015
4016 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", 4016
, __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", 4016, "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", 4016, "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", 4016, __func__, "Adding %s would put more than %d 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)
; } } }
;
4017
4018 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4019
4020 proto_tree_set_ipv4(new_fi, value);
4021
4022 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4023 return proto_tree_add_node(tree, new_fi);
4024}
4025
4026proto_item *
4027proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4028 const int start, int length,
4029 const unsigned encoding, ws_in6_addr *addr)
4030{
4031 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4032 field_info *new_fi;
4033
4034 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", 4034,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4035
4036 switch (hfinfo->type) {
4037 case FT_IPv6:
4038 break;
4039 default:
4040 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)
4041 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4042 }
4043
4044 if (length != FT_IPv6_LEN16)
4045 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)
4046 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4047
4048 if (encoding) {
4049 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"
)
;
4050 }
4051
4052 tvb_get_ipv6(tvb, start, addr);
4053
4054 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4055
4056 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", 4056
, __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", 4056, "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", 4056, "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", 4056, __func__, "Adding %s would put more than %d 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)
; } } }
;
4057
4058 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4059
4060 proto_tree_set_ipv6(new_fi, addr);
4061
4062 return proto_tree_add_node(tree, new_fi);
4063}
4064
4065proto_item *
4066proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4067 const int start, int length, const unsigned encoding, uint8_t *retval) {
4068
4069 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4070 field_info *new_fi;
4071
4072 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", 4072,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4073
4074 switch (hfinfo->type) {
4075 case FT_ETHER:
4076 break;
4077 default:
4078 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)
4079 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4080 }
4081
4082 if (length != FT_ETHER_LEN6)
4083 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)
4084 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4085
4086 if (encoding) {
4087 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"
)
;
4088 }
4089
4090 tvb_memcpy(tvb, retval, start, length);
4091
4092 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4093
4094 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", 4094
, __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", 4094, "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", 4094, "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", 4094, __func__, "Adding %s would put more than %d 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)
; } } }
;
4095
4096 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4097
4098 proto_tree_set_ether(new_fi, retval);
4099
4100 return proto_tree_add_node(tree, new_fi);
4101}
4102
4103
4104proto_item *
4105proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4106 tvbuff_t *tvb,
4107 const int start, int length,
4108 const unsigned encoding,
4109 wmem_allocator_t *scope,
4110 const uint8_t **retval,
4111 int *lenretval)
4112{
4113 proto_item *pi;
4114 header_field_info *hfinfo;
4115 field_info *new_fi;
4116 const uint8_t *value;
4117
4118 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", 4118, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4118,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4118, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4119
4120 switch (hfinfo->type) {
4121 case FT_STRING:
4122 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4123 break;
4124 case FT_STRINGZ:
4125 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4126 break;
4127 case FT_UINT_STRING:
4128 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4129 break;
4130 case FT_STRINGZPAD:
4131 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4132 break;
4133 case FT_STRINGZTRUNC:
4134 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4135 break;
4136 default:
4137 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)
4138 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)
;
4139 }
4140
4141 if (retval)
4142 *retval = value;
4143
4144 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4145
4146 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", 4146
, __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", 4146, "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", 4146, "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", 4146, __func__, "Adding %s would put more than %d 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)
; } } }
;
4147
4148 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4149
4150 proto_tree_set_string(new_fi, value);
4151
4152 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4153
4154 pi = proto_tree_add_node(tree, new_fi);
4155
4156 switch (hfinfo->type) {
4157
4158 case FT_STRINGZ:
4159 case FT_STRINGZPAD:
4160 case FT_STRINGZTRUNC:
4161 case FT_UINT_STRING:
4162 break;
4163
4164 case FT_STRING:
4165 detect_trailing_stray_characters(encoding, value, length, pi);
4166 break;
4167
4168 default:
4169 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4169
, __func__, "assertion \"not reached\" failed")
;
4170 }
4171
4172 return pi;
4173}
4174
4175proto_item *
4176proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4177 const int start, int length,
4178 const unsigned encoding, wmem_allocator_t *scope,
4179 const uint8_t **retval)
4180{
4181 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4182 tvb, start, length, encoding, scope, retval, &length);
4183}
4184
4185proto_item *
4186proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4187 tvbuff_t *tvb,
4188 const int start, int length,
4189 const unsigned encoding,
4190 wmem_allocator_t *scope,
4191 char **retval,
4192 int *lenretval)
4193{
4194 proto_item *pi;
4195 header_field_info *hfinfo;
4196 field_info *new_fi;
4197 const uint8_t *value;
4198 uint32_t n = 0;
4199
4200 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", 4200, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4200,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4200, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4201
4202 switch (hfinfo->type) {
4203 case FT_STRING:
4204 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4205 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4206 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4207 break;
4208 case FT_STRINGZ:
4209 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4210 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4211 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4212 break;
4213 case FT_UINT_STRING:
4214 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4215 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4216 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4217 break;
4218 case FT_STRINGZPAD:
4219 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4220 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4221 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4222 break;
4223 case FT_STRINGZTRUNC:
4224 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4225 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4226 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4227 break;
4228 case FT_BYTES:
4229 tvb_ensure_bytes_exist(tvb, start, length);
4230 value = tvb_get_ptr(tvb, start, length);
4231 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4232 *lenretval = length;
4233 break;
4234 case FT_UINT_BYTES:
4235 n = get_uint_value(tree, tvb, start, length, encoding);
4236 tvb_ensure_bytes_exist(tvb, start + length, n);
4237 value = tvb_get_ptr(tvb, start + length, n);
4238 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4239 *lenretval = length + n;
4240 break;
4241 default:
4242 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)
4243 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)
;
4244 }
4245
4246 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4247
4248 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", 4248
, __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", 4248, "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", 4248, "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", 4248, __func__, "Adding %s would put more than %d 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)
; } } }
;
4249
4250 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4251
4252 switch (hfinfo->type) {
4253
4254 case FT_STRING:
4255 case FT_STRINGZ:
4256 case FT_UINT_STRING:
4257 case FT_STRINGZPAD:
4258 case FT_STRINGZTRUNC:
4259 proto_tree_set_string(new_fi, value);
4260 break;
4261
4262 case FT_BYTES:
4263 proto_tree_set_bytes(new_fi, value, length);
4264 break;
4265
4266 case FT_UINT_BYTES:
4267 proto_tree_set_bytes(new_fi, value, n);
4268 break;
4269
4270 default:
4271 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4271
, __func__, "assertion \"not reached\" failed")
;
4272 }
4273
4274 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4275
4276 pi = proto_tree_add_node(tree, new_fi);
4277
4278 switch (hfinfo->type) {
4279
4280 case FT_STRINGZ:
4281 case FT_STRINGZPAD:
4282 case FT_STRINGZTRUNC:
4283 case FT_UINT_STRING:
4284 break;
4285
4286 case FT_STRING:
4287 detect_trailing_stray_characters(encoding, value, length, pi);
4288 break;
4289
4290 case FT_BYTES:
4291 case FT_UINT_BYTES:
4292 break;
4293
4294 default:
4295 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4295
, __func__, "assertion \"not reached\" failed")
;
4296 }
4297
4298 return pi;
4299}
4300
4301proto_item *
4302proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4303 tvbuff_t *tvb,
4304 const int start, int length,
4305 const unsigned encoding,
4306 wmem_allocator_t *scope,
4307 char **retval)
4308{
4309 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4310 tvb, start, length, encoding, scope, retval, &length);
4311}
4312
4313proto_item *
4314proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4315 tvbuff_t *tvb,
4316 const int start, int length, const unsigned encoding,
4317 wmem_allocator_t *scope, char **retval)
4318{
4319 header_field_info *hfinfo;
4320 field_info *new_fi;
4321 nstime_t time_stamp;
4322 int flags;
4323
4324 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", 4324, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4324,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4324, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4325
4326 switch (hfinfo->type) {
4327 case FT_ABSOLUTE_TIME:
4328 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4329 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4330 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4331 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4332 }
4333 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4334 break;
4335 case FT_RELATIVE_TIME:
4336 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4337 *retval = rel_time_to_secs_str(scope, &time_stamp);
4338 break;
4339 default:
4340 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)
4341 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4342 }
4343
4344 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4345
4346 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", 4346
, __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", 4346, "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", 4346, "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", 4346, __func__, "Adding %s would put more than %d 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)
; } } }
;
4347
4348 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4349
4350 switch (hfinfo->type) {
4351
4352 case FT_ABSOLUTE_TIME:
4353 case FT_RELATIVE_TIME:
4354 proto_tree_set_time(new_fi, &time_stamp);
4355 break;
4356 default:
4357 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4357
, __func__, "assertion \"not reached\" failed")
;
4358 }
4359
4360 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4361
4362 return proto_tree_add_node(tree, new_fi);
4363}
4364
4365/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4366 and returns proto_item* */
4367proto_item *
4368ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4369 const unsigned encoding)
4370{
4371 field_info *new_fi;
4372 header_field_info *hfinfo;
4373 int item_length;
4374 int offset;
4375
4376 offset = ptvc->offset;
4377 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", 4377, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4377,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4377, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4378 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4379 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4380
4381 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
4382 item_length, encoding);
4383
4384 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4385
4386 /* Coast clear. Try and fake it */
4387 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", 4387
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4387, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4387, "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", 4387, __func__, "Adding %s would put more than %d 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); } } }
;
4388
4389 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4390
4391 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4392 offset, length, encoding);
4393}
4394
4395/* Add an item to a proto_tree, using the text label registered to that item;
4396 the item is extracted from the tvbuff handed to it. */
4397proto_item *
4398proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4399 const int start, int length, const unsigned encoding)
4400{
4401 field_info *new_fi;
4402 int item_length;
4403
4404 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", 4404,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4405
4406 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4407 test_length(hfinfo, tvb, start, item_length, encoding);
4408
4409 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4410
4411 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", 4411
, __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", 4411, "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", 4411, "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", 4411, __func__, "Adding %s would put more than %d 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)
; } } }
;
4412
4413 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4414
4415 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4416}
4417
4418proto_item *
4419proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4420 const int start, int length, const unsigned encoding)
4421{
4422 register header_field_info *hfinfo;
4423
4424 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4424, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4424,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4424, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4425 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4426}
4427
4428/* Add an item to a proto_tree, using the text label registered to that item;
4429 the item is extracted from the tvbuff handed to it.
4430
4431 Return the length of the item through the pointer. */
4432proto_item *
4433proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4434 tvbuff_t *tvb, const int start,
4435 int length, const unsigned encoding,
4436 int *lenretval)
4437{
4438 field_info *new_fi;
4439 int item_length;
4440 proto_item *item;
4441
4442 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", 4442,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4443
4444 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4445 test_length(hfinfo, tvb, start, item_length, encoding);
4446
4447 if (!tree) {
4448 /*
4449 * We need to get the correct item length here.
4450 * That's normally done by proto_tree_new_item(),
4451 * but we won't be calling it.
4452 */
4453 *lenretval = get_full_length(hfinfo, tvb, start, length,
4454 item_length, encoding);
4455 return NULL((void*)0);
4456 }
4457
4458 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", 4465
, __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", 4465, "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", 4465, "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", 4465
, __func__, "Adding %s would put more than %d 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); } } }
4459 /*((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", 4465
, __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", 4465, "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", 4465, "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", 4465
, __func__, "Adding %s would put more than %d 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); } } }
4460 * 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", 4465
, __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", 4465, "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", 4465, "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", 4465
, __func__, "Adding %s would put more than %d 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); } } }
4461 * 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", 4465
, __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", 4465, "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", 4465, "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", 4465
, __func__, "Adding %s would put more than %d 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); } } }
4462 */((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", 4465
, __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", 4465, "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", 4465, "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", 4465
, __func__, "Adding %s would put more than %d 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); } } }
4463 *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", 4465
, __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", 4465, "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", 4465, "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", 4465
, __func__, "Adding %s would put more than %d 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); } } }
4464 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", 4465
, __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", 4465, "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", 4465, "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", 4465
, __func__, "Adding %s would put more than %d 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); } } }
4465 })((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", 4465
, __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", 4465, "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", 4465, "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", 4465
, __func__, "Adding %s would put more than %d 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); } } }
;
4466
4467 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4468
4469 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4470 *lenretval = new_fi->length;
4471 return item;
4472}
4473
4474proto_item *
4475proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4476 const int start, int length,
4477 const unsigned encoding, int *lenretval)
4478{
4479 register header_field_info *hfinfo;
4480
4481 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", 4481, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4481,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4481, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4482 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4483}
4484
4485/* which FT_ types can use proto_tree_add_bytes_item() */
4486static inline bool_Bool
4487validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4488{
4489 return (type == FT_BYTES ||
4490 type == FT_UINT_BYTES ||
4491 type == FT_OID ||
4492 type == FT_REL_OID ||
4493 type == FT_SYSTEM_ID );
4494}
4495
4496/* Note: this does no validation that the byte array of an FT_OID or
4497 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4498 so I think it's ok to continue not validating it?
4499 */
4500proto_item *
4501proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4502 const int start, int length, const unsigned encoding,
4503 GByteArray *retval, int *endoff, int *err)
4504{
4505 field_info *new_fi;
4506 GByteArray *bytes = retval;
4507 GByteArray *created_bytes = NULL((void*)0);
4508 bool_Bool failed = false0;
4509 uint32_t n = 0;
4510 header_field_info *hfinfo;
4511 bool_Bool generate = (bytes || tree) ? true1 : false0;
4512
4513 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", 4513, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4513,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4513, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4514
4515 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", 4515,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4516
4517 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", 4518, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4518 "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", 4518, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4519
4520 CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
;
4521
4522 if (encoding & ENC_STR_NUM0x01000000) {
4523 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"
)
;
4524 }
4525
4526 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4527 if (hfinfo->type == FT_UINT_BYTES) {
4528 /* can't decode FT_UINT_BYTES from strings */
4529 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")
4530 "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")
;
4531 }
4532
4533 unsigned hex_encoding = encoding;
4534 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4535 /* If none of the separator values are used,
4536 * assume no separator (the common case). */
4537 hex_encoding |= ENC_SEP_NONE0x00010000;
4538#if 0
4539 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")
4540 "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")
;
4541#endif
4542 }
4543
4544 if (!bytes) {
4545 /* caller doesn't care about return value, but we need it to
4546 call tvb_get_string_bytes() and set the tree later */
4547 bytes = created_bytes = g_byte_array_new();
4548 }
4549
4550 /*
4551 * bytes might be NULL after this, but can't add expert
4552 * error until later; if it's NULL, just note that
4553 * it failed.
4554 */
4555 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4556 if (bytes == NULL((void*)0))
4557 failed = true1;
4558 }
4559 else if (generate) {
4560 tvb_ensure_bytes_exist(tvb, start, length);
4561
4562 if (hfinfo->type == FT_UINT_BYTES) {
4563 n = length; /* n is now the "header" length */
4564 length = get_uint_value(tree, tvb, start, n, encoding);
4565 /* length is now the value's length; only store the value in the array */
4566 tvb_ensure_bytes_exist(tvb, start + n, length);
4567 if (!bytes) {
4568 /* caller doesn't care about return value, but
4569 * we may need it to set the tree later */
4570 bytes = created_bytes = g_byte_array_new();
4571 }
4572 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4573 }
4574 else if (length > 0) {
4575 if (!bytes) {
4576 /* caller doesn't care about return value, but
4577 * we may need it to set the tree later */
4578 bytes = created_bytes = g_byte_array_new();
4579 }
4580 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4581 }
4582
4583 if (endoff)
4584 *endoff = start + n + length;
4585 }
4586
4587 if (err)
4588 *err = failed ? EINVAL22 : 0;
4589
4590 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); }
4591 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4592 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); }
4593 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); }
4594 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); }
4595 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4596 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4597
4598 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", 4604
, __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", 4604, "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", 4604, "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", 4604
, __func__, "Adding %s would put more than %d 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); } } }
4599 {((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", 4604
, __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", 4604, "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", 4604, "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", 4604
, __func__, "Adding %s would put more than %d 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); } } }
4600 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", 4604
, __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", 4604, "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", 4604, "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", 4604
, __func__, "Adding %s would put more than %d 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); } } }
4601 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", 4604
, __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", 4604, "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", 4604, "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", 4604
, __func__, "Adding %s would put more than %d 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); } } }
4602 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", 4604
, __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", 4604, "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", 4604, "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", 4604
, __func__, "Adding %s would put more than %d 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); } } }
4603 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", 4604
, __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", 4604, "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", 4604, "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", 4604
, __func__, "Adding %s would put more than %d 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); } } }
4604 } )((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", 4604
, __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", 4604, "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", 4604, "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", 4604
, __func__, "Adding %s would put more than %d 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); } } }
;
4605
4606 /* n will be zero except when it's a FT_UINT_BYTES */
4607 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4608
4609 if (encoding & ENC_STRING0x03000000) {
4610 if (failed)
4611 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4612
4613 if (bytes)
4614 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4615 else
4616 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4617
4618 if (created_bytes)
4619 g_byte_array_free(created_bytes, true1);
4620 }
4621 else {
4622 /* n will be zero except when it's a FT_UINT_BYTES */
4623 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4624
4625 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4626 * use the byte array created above in this case.
4627 */
4628 if (created_bytes)
4629 g_byte_array_free(created_bytes, true1);
4630
4631 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4632 (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)
;
4633 }
4634
4635 return proto_tree_add_node(tree, new_fi);
4636}
4637
4638
4639proto_item *
4640proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4641 const int start, int length, const unsigned encoding,
4642 nstime_t *retval, int *endoff, int *err)
4643{
4644 field_info *new_fi;
4645 nstime_t time_stamp;
4646 int saved_err = 0;
4647 header_field_info *hfinfo;
4648
4649 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", 4649, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4649,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4649, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4650
4651 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", 4651,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4652
4653 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4654 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4655 if(retval)if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4656 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4657 nstime_set_zero(retval);if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4658 }if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4659 } )if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
;
4660
4661 nstime_set_zero(&time_stamp);
4662
4663 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4664 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", 4664, ((hfinfo))->abbrev))))
;
4665 /* The only string format that could be a relative time is
4666 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4667 * relative to "now" currently.
4668 */
4669 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4670 saved_err = EINVAL22;
4671 }
4672 else {
4673 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", 4673, ((hfinfo))->abbrev))))
;
4674 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4675
4676 tvb_ensure_bytes_exist(tvb, start, length);
4677 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4678 if (endoff) *endoff = start + length;
4679 }
4680
4681 if (err) *err = saved_err;
4682
4683 if (retval) {
4684 retval->secs = time_stamp.secs;
4685 retval->nsecs = time_stamp.nsecs;
4686 }
4687
4688 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4689
4690 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", 4690
, __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", 4690, "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", 4690, "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", 4690, __func__, "Adding %s would put more than %d 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)
; } } }
;
4691
4692 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4693
4694 proto_tree_set_time(new_fi, &time_stamp);
4695
4696 if (encoding & ENC_STRING0x03000000) {
4697 if (saved_err)
4698 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4699 }
4700 else {
4701 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4702 (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)
;
4703 }
4704
4705 return proto_tree_add_node(tree, new_fi);
4706}
4707
4708/* Add a FT_NONE to a proto_tree */
4709proto_item *
4710proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4711 const int start, int length, const char *format,
4712 ...)
4713{
4714 proto_item *pi;
4715 va_list ap;
4716 header_field_info *hfinfo;
4717
4718 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4719
4720 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4720
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4720, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4720, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4720, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4721
4722 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_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", 4722
, ((hfinfo))->abbrev))))
;
4723
4724 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4725
4726 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4726, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4727
4728 va_start(ap, format)__builtin_va_start(ap, format);
4729 proto_tree_set_representation(pi, format, ap);
4730 va_end(ap)__builtin_va_end(ap);
4731
4732 /* no value to set for FT_NONE */
4733 return pi;
4734}
4735
4736/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4737 * offset, and returns proto_item* */
4738proto_item *
4739ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4740 const unsigned encoding)
4741{
4742 proto_item *item;
4743
4744 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4745 length, encoding);
4746
4747 return item;
4748}
4749
4750/* Advance the ptvcursor's offset within its tvbuff without
4751 * adding anything to the proto_tree. */
4752void
4753ptvcursor_advance(ptvcursor_t* ptvc, int length)
4754{
4755 ptvc->offset += length;
4756}
4757
4758
4759static void
4760proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4761{
4762 fvalue_set_protocol(fi->value, tvb, field_data, length);
4763}
4764
4765/* Add a FT_PROTOCOL to a proto_tree */
4766proto_item *
4767proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4768 int start, int length, const char *format, ...)
4769{
4770 proto_item *pi;
4771 tvbuff_t *protocol_tvb;
4772 va_list ap;
4773 header_field_info *hfinfo;
4774 char* protocol_rep;
4775
4776 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4777
4778 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", 4778
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4778, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4778, "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", 4778, __func__, "Adding %s would put more than %d 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)
; } } }
;
4779
4780 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"
, 4780, ((hfinfo))->abbrev))))
;
4781
4782 /*
4783 * This can throw an exception, so do it before we allocate anything.
4784 */
4785 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4786
4787 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4788
4789 va_start(ap, format)__builtin_va_start(ap, format);
4790 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4791 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4792 g_free(protocol_rep);
4793 va_end(ap)__builtin_va_end(ap);
4794
4795 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4795, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4796
4797 va_start(ap, format)__builtin_va_start(ap, format);
4798 proto_tree_set_representation(pi, format, ap);
4799 va_end(ap)__builtin_va_end(ap);
4800
4801 return pi;
4802}
4803
4804/* Add a FT_BYTES to a proto_tree */
4805proto_item *
4806proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4807 int length, const uint8_t *start_ptr)
4808{
4809 proto_item *pi;
4810 header_field_info *hfinfo;
4811 int item_length;
4812
4813 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", 4813, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4813,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4813, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4814 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4815 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4816
4817 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4818
4819 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", 4819
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4819, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4819, "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", 4819, __func__, "Adding %s would put more than %d 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)
; } } }
;
4820
4821 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",
4821, ((hfinfo))->abbrev))))
;
4822
4823 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4824 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4825
4826 return pi;
4827}
4828
4829/* Add a FT_BYTES to a proto_tree */
4830proto_item *
4831proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4832 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4833{
4834 proto_item *pi;
4835 header_field_info *hfinfo;
4836 int item_length;
4837
4838 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", 4838, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4838,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4838, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4839 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4840 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4841
4842 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4843
4844 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", 4844
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4844, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4844, "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", 4844, __func__, "Adding %s would put more than %d 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)
; } } }
;
4845
4846 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",
4846, ((hfinfo))->abbrev))))
;
4847
4848 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4849 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4850
4851 return pi;
4852}
4853
4854proto_item *
4855proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4856 int start, int length,
4857 const uint8_t *start_ptr,
4858 const char *format, ...)
4859{
4860 proto_item *pi;
4861 va_list ap;
4862
4863 if (start_ptr == NULL((void*)0))
4864 start_ptr = tvb_get_ptr(tvb, start, length);
4865
4866 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4867
4868 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; }
;
4869
4870 va_start(ap, format)__builtin_va_start(ap, format);
4871 proto_tree_set_representation_value(pi, format, ap);
4872 va_end(ap)__builtin_va_end(ap);
4873
4874 return pi;
4875}
4876
4877proto_item *
4878proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4879 int start, int length, const uint8_t *start_ptr,
4880 const char *format, ...)
4881{
4882 proto_item *pi;
4883 va_list ap;
4884
4885 if (start_ptr == NULL((void*)0))
4886 start_ptr = tvb_get_ptr(tvb, start, length);
4887
4888 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4889
4890 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; }
;
4891
4892 va_start(ap, format)__builtin_va_start(ap, format);
4893 proto_tree_set_representation(pi, format, ap);
4894 va_end(ap)__builtin_va_end(ap);
4895
4896 return pi;
4897}
4898
4899static void
4900proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4901{
4902 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4902, "length >= 0"
))))
;
4903 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", 4903, "start_ptr != ((void*)0) || length == 0"
))))
;
4904
4905 fvalue_set_bytes_data(fi->value, start_ptr, length);
4906}
4907
4908
4909static void
4910proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4911{
4912 tvb_ensure_bytes_exist(tvb, offset, length);
4913 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4914}
4915
4916static void
4917proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4918{
4919 GByteArray *bytes;
4920
4921 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4921, "value != ((void*)0)"
))))
;
4922
4923 bytes = byte_array_dup(value);
4924
4925 fvalue_set_byte_array(fi->value, bytes);
4926}
4927
4928/* Add a FT_*TIME to a proto_tree */
4929proto_item *
4930proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4931 int length, const nstime_t *value_ptr)
4932{
4933 proto_item *pi;
4934 header_field_info *hfinfo;
4935
4936 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4937
4938 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", 4938
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4938, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4938, "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", 4938, __func__, "Adding %s would put more than %d 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)
; } } }
;
4939
4940 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", 4940, ((hfinfo))->abbrev))))
;
4941
4942 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4943 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4944
4945 return pi;
4946}
4947
4948proto_item *
4949proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4950 int start, int length, nstime_t *value_ptr,
4951 const char *format, ...)
4952{
4953 proto_item *pi;
4954 va_list ap;
4955
4956 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4957 if (pi != tree) {
4958 va_start(ap, format)__builtin_va_start(ap, format);
4959 proto_tree_set_representation_value(pi, format, ap);
4960 va_end(ap)__builtin_va_end(ap);
4961 }
4962
4963 return pi;
4964}
4965
4966proto_item *
4967proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4968 int start, int length, nstime_t *value_ptr,
4969 const char *format, ...)
4970{
4971 proto_item *pi;
4972 va_list ap;
4973
4974 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4975 if (pi != tree) {
4976 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4976, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4977
4978 va_start(ap, format)__builtin_va_start(ap, format);
4979 proto_tree_set_representation(pi, format, ap);
4980 va_end(ap)__builtin_va_end(ap);
4981 }
4982
4983 return pi;
4984}
4985
4986/* Set the FT_*TIME value */
4987static void
4988proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4989{
4990 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4990, "value_ptr != ((void*)0)"
))))
;
4991
4992 fvalue_set_time(fi->value, value_ptr);
4993}
4994
4995/* Add a FT_IPXNET to a proto_tree */
4996proto_item *
4997proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4998 int length, uint32_t value)
4999{
5000 proto_item *pi;
5001 header_field_info *hfinfo;
5002
5003 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5004
5005 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", 5005
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5005, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5005, "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", 5005, __func__, "Adding %s would put more than %d 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)
; } } }
;
5006
5007 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"
, 5007, ((hfinfo))->abbrev))))
;
5008
5009 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5010 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5011
5012 return pi;
5013}
5014
5015proto_item *
5016proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5017 int start, int length, uint32_t value,
5018 const char *format, ...)
5019{
5020 proto_item *pi;
5021 va_list ap;
5022
5023 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5024 if (pi != tree) {
5025 va_start(ap, format)__builtin_va_start(ap, format);
5026 proto_tree_set_representation_value(pi, format, ap);
5027 va_end(ap)__builtin_va_end(ap);
5028 }
5029
5030 return pi;
5031}
5032
5033proto_item *
5034proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5035 int start, int length, uint32_t value,
5036 const char *format, ...)
5037{
5038 proto_item *pi;
5039 va_list ap;
5040
5041 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5042 if (pi != tree) {
5043 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5043, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5044
5045 va_start(ap, format)__builtin_va_start(ap, format);
5046 proto_tree_set_representation(pi, format, ap);
5047 va_end(ap)__builtin_va_end(ap);
5048 }
5049
5050 return pi;
5051}
5052
5053/* Set the FT_IPXNET value */
5054static void
5055proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5056{
5057 fvalue_set_uinteger(fi->value, value);
5058}
5059
5060/* Add a FT_IPv4 to a proto_tree */
5061proto_item *
5062proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5063 int length, ws_in4_addr value)
5064{
5065 proto_item *pi;
5066 header_field_info *hfinfo;
5067
5068 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5069
5070 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", 5070
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5070, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5070, "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", 5070, __func__, "Adding %s would put more than %d 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)
; } } }
;
5071
5072 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", 5072
, ((hfinfo))->abbrev))))
;
5073
5074 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5075 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5076
5077 return pi;
5078}
5079
5080proto_item *
5081proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5082 int start, int length, ws_in4_addr value,
5083 const char *format, ...)
5084{
5085 proto_item *pi;
5086 va_list ap;
5087
5088 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5089 if (pi != tree) {
5090 va_start(ap, format)__builtin_va_start(ap, format);
5091 proto_tree_set_representation_value(pi, format, ap);
5092 va_end(ap)__builtin_va_end(ap);
5093 }
5094
5095 return pi;
5096}
5097
5098proto_item *
5099proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5100 int start, int length, ws_in4_addr value,
5101 const char *format, ...)
5102{
5103 proto_item *pi;
5104 va_list ap;
5105
5106 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5107 if (pi != tree) {
5108 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5108, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5109
5110 va_start(ap, format)__builtin_va_start(ap, format);
5111 proto_tree_set_representation(pi, format, ap);
5112 va_end(ap)__builtin_va_end(ap);
5113 }
5114
5115 return pi;
5116}
5117
5118/* Set the FT_IPv4 value */
5119static void
5120proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5121{
5122 ipv4_addr_and_mask ipv4;
5123 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5124 fvalue_set_ipv4(fi->value, &ipv4);
5125}
5126
5127/* Add a FT_IPv6 to a proto_tree */
5128proto_item *
5129proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5130 int length, const ws_in6_addr *value)
5131{
5132 proto_item *pi;
5133 header_field_info *hfinfo;
5134
5135 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5136
5137 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", 5137
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5137, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5137, "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", 5137, __func__, "Adding %s would put more than %d 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)
; } } }
;
5138
5139 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", 5139
, ((hfinfo))->abbrev))))
;
5140
5141 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5142 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5143
5144 return pi;
5145}
5146
5147proto_item *
5148proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5149 int start, int length,
5150 const ws_in6_addr *value_ptr,
5151 const char *format, ...)
5152{
5153 proto_item *pi;
5154 va_list ap;
5155
5156 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5157 if (pi != tree) {
5158 va_start(ap, format)__builtin_va_start(ap, format);
5159 proto_tree_set_representation_value(pi, format, ap);
5160 va_end(ap)__builtin_va_end(ap);
5161 }
5162
5163 return pi;
5164}
5165
5166proto_item *
5167proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5168 int start, int length,
5169 const ws_in6_addr *value_ptr,
5170 const char *format, ...)
5171{
5172 proto_item *pi;
5173 va_list ap;
5174
5175 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5176 if (pi != tree) {
5177 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5177, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5178
5179 va_start(ap, format)__builtin_va_start(ap, format);
5180 proto_tree_set_representation(pi, format, ap);
5181 va_end(ap)__builtin_va_end(ap);
5182 }
5183
5184 return pi;
5185}
5186
5187/* Set the FT_IPv6 value */
5188static void
5189proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5190{
5191 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5191, "value != ((void*)0)"
))))
;
5192 ipv6_addr_and_prefix ipv6;
5193 ipv6.addr = *value;
5194 ipv6.prefix = 128;
5195 fvalue_set_ipv6(fi->value, &ipv6);
5196}
5197
5198static void
5199proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5200{
5201 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5202}
5203
5204/* Set the FT_FCWWN value */
5205static void
5206proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5207{
5208 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5208, "value_ptr != ((void*)0)"
))))
;
5209 fvalue_set_fcwwn(fi->value, value_ptr);
5210}
5211
5212static void
5213proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5214{
5215 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5216}
5217
5218/* Add a FT_GUID to a proto_tree */
5219proto_item *
5220proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5221 int length, const e_guid_t *value_ptr)
5222{
5223 proto_item *pi;
5224 header_field_info *hfinfo;
5225
5226 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5227
5228 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", 5228
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5228, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5228, "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", 5228, __func__, "Adding %s would put more than %d 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)
; } } }
;
5229
5230 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", 5230
, ((hfinfo))->abbrev))))
;
5231
5232 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5233 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5234
5235 return pi;
5236}
5237
5238proto_item *
5239proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5240 int start, int length,
5241 const e_guid_t *value_ptr,
5242 const char *format, ...)
5243{
5244 proto_item *pi;
5245 va_list ap;
5246
5247 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5248 if (pi != tree) {
5249 va_start(ap, format)__builtin_va_start(ap, format);
5250 proto_tree_set_representation_value(pi, format, ap);
5251 va_end(ap)__builtin_va_end(ap);
5252 }
5253
5254 return pi;
5255}
5256
5257proto_item *
5258proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5259 int start, int length, const e_guid_t *value_ptr,
5260 const char *format, ...)
5261{
5262 proto_item *pi;
5263 va_list ap;
5264
5265 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5266 if (pi != tree) {
5267 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5267, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5268
5269 va_start(ap, format)__builtin_va_start(ap, format);
5270 proto_tree_set_representation(pi, format, ap);
5271 va_end(ap)__builtin_va_end(ap);
5272 }
5273
5274 return pi;
5275}
5276
5277/* Set the FT_GUID value */
5278static void
5279proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5280{
5281 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5281, "value_ptr != ((void*)0)"
))))
;
5282 fvalue_set_guid(fi->value, value_ptr);
5283}
5284
5285static void
5286proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5287 const unsigned encoding)
5288{
5289 e_guid_t guid;
5290
5291 tvb_get_guid(tvb, start, &guid, encoding);
5292 proto_tree_set_guid(fi, &guid);
5293}
5294
5295/* Add a FT_OID to a proto_tree */
5296proto_item *
5297proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5298 int length, const uint8_t* value_ptr)
5299{
5300 proto_item *pi;
5301 header_field_info *hfinfo;
5302
5303 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5304
5305 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", 5305
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5305, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5305, "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", 5305, __func__, "Adding %s would put more than %d 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)
; } } }
;
5306
5307 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", 5307
, ((hfinfo))->abbrev))))
;
5308
5309 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5310 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5311
5312 return pi;
5313}
5314
5315proto_item *
5316proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5317 int start, int length,
5318 const uint8_t* value_ptr,
5319 const char *format, ...)
5320{
5321 proto_item *pi;
5322 va_list ap;
5323
5324 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5325 if (pi != tree) {
5326 va_start(ap, format)__builtin_va_start(ap, format);
5327 proto_tree_set_representation_value(pi, format, ap);
5328 va_end(ap)__builtin_va_end(ap);
5329 }
5330
5331 return pi;
5332}
5333
5334proto_item *
5335proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5336 int start, int length, const uint8_t* value_ptr,
5337 const char *format, ...)
5338{
5339 proto_item *pi;
5340 va_list ap;
5341
5342 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5343 if (pi != tree) {
5344 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5344, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5345
5346 va_start(ap, format)__builtin_va_start(ap, format);
5347 proto_tree_set_representation(pi, format, ap);
5348 va_end(ap)__builtin_va_end(ap);
5349 }
5350
5351 return pi;
5352}
5353
5354/* Set the FT_OID value */
5355static void
5356proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5357{
5358 GByteArray *bytes;
5359
5360 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", 5360, "value_ptr != ((void*)0) || length == 0"
))))
;
5361
5362 bytes = g_byte_array_new();
5363 if (length > 0) {
5364 g_byte_array_append(bytes, value_ptr, length);
5365 }
5366 fvalue_set_byte_array(fi->value, bytes);
5367}
5368
5369static void
5370proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5371{
5372 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5373}
5374
5375/* Set the FT_SYSTEM_ID value */
5376static void
5377proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5378{
5379 GByteArray *bytes;
5380
5381 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", 5381, "value_ptr != ((void*)0) || length == 0"
))))
;
5382
5383 bytes = g_byte_array_new();
5384 if (length > 0) {
5385 g_byte_array_append(bytes, value_ptr, length);
5386 }
5387 fvalue_set_byte_array(fi->value, bytes);
5388}
5389
5390static void
5391proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5392{
5393 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5394}
5395
5396/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5397 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5398 * is destroyed. */
5399proto_item *
5400proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5401 int length, const char* value)
5402{
5403 proto_item *pi;
5404 header_field_info *hfinfo;
5405 int item_length;
5406
5407 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", 5407, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5407,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5407, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5408 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5409 /*
5410 * Special case - if the length is 0, skip the test, so that
5411 * we can have an empty string right after the end of the
5412 * packet. (This handles URL-encoded forms where the last field
5413 * has no value so the form ends right after the =.)
5414 */
5415 if (item_length != 0)
5416 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5417
5418 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5419
5420 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", 5420
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5420, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5420, "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", 5420, __func__, "Adding %s would put more than %d 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)
; } } }
;
5421
5422 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", 5422, ((hfinfo))->abbrev))))
;
5423
5424 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5425 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5425, "length >= 0"
))))
;
5426
5427 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", 5427, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5428 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5429
5430 return pi;
5431}
5432
5433proto_item *
5434proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5435 int start, int length, const char* value,
5436 const char *format,
5437 ...)
5438{
5439 proto_item *pi;
5440 va_list ap;
5441
5442 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5443 if (pi != tree) {
5444 va_start(ap, format)__builtin_va_start(ap, format);
5445 proto_tree_set_representation_value(pi, format, ap);
5446 va_end(ap)__builtin_va_end(ap);
5447 }
5448
5449 return pi;
5450}
5451
5452proto_item *
5453proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5454 int start, int length, const char* value,
5455 const char *format, ...)
5456{
5457 proto_item *pi;
5458 va_list ap;
5459
5460 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5461 if (pi != tree) {
5462 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5462, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5463
5464 va_start(ap, format)__builtin_va_start(ap, format);
5465 proto_tree_set_representation(pi, format, ap);
5466 va_end(ap)__builtin_va_end(ap);
5467 }
5468
5469 return pi;
5470}
5471
5472/* Set the FT_STRING value */
5473static void
5474proto_tree_set_string(field_info *fi, const char* value)
5475{
5476 if (value) {
5477 fvalue_set_string(fi->value, value);
5478 } else {
5479 /*
5480 * XXX - why is a null value for a string field
5481 * considered valid?
5482 */
5483 fvalue_set_string(fi->value, "[ Null ]");
5484 }
5485}
5486
5487/* Set the FT_AX25 value */
5488static void
5489proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5490{
5491 fvalue_set_ax25(fi->value, value);
5492}
5493
5494static void
5495proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5496{
5497 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5498}
5499
5500/* Set the FT_VINES value */
5501static void
5502proto_tree_set_vines(field_info *fi, const uint8_t* value)
5503{
5504 fvalue_set_vines(fi->value, value);
5505}
5506
5507static void
5508proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5509{
5510 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5511}
5512
5513/* Add a FT_ETHER to a proto_tree */
5514proto_item *
5515proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5516 int length, const uint8_t* value)
5517{
5518 proto_item *pi;
5519 header_field_info *hfinfo;
5520
5521 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5522
5523 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", 5523
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5523, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5523, "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", 5523, __func__, "Adding %s would put more than %d 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)
; } } }
;
5524
5525 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",
5525, ((hfinfo))->abbrev))))
;
5526
5527 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5528 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5529
5530 return pi;
5531}
5532
5533proto_item *
5534proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5535 int start, int length, const uint8_t* value,
5536 const char *format, ...)
5537{
5538 proto_item *pi;
5539 va_list ap;
5540
5541 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5542 if (pi != tree) {
5543 va_start(ap, format)__builtin_va_start(ap, format);
5544 proto_tree_set_representation_value(pi, format, ap);
5545 va_end(ap)__builtin_va_end(ap);
5546 }
5547
5548 return pi;
5549}
5550
5551proto_item *
5552proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5553 int start, int length, const uint8_t* value,
5554 const char *format, ...)
5555{
5556 proto_item *pi;
5557 va_list ap;
5558
5559 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5560 if (pi != tree) {
5561 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5561, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5562
5563 va_start(ap, format)__builtin_va_start(ap, format);
5564 proto_tree_set_representation(pi, format, ap);
5565 va_end(ap)__builtin_va_end(ap);
5566 }
5567
5568 return pi;
5569}
5570
5571/* Set the FT_ETHER value */
5572static void
5573proto_tree_set_ether(field_info *fi, const uint8_t* value)
5574{
5575 fvalue_set_ether(fi->value, value);
5576}
5577
5578static void
5579proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5580{
5581 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5582}
5583
5584/* Add a FT_BOOLEAN to a proto_tree */
5585proto_item *
5586proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5587 int length, uint64_t value)
5588{
5589 proto_item *pi;
5590 header_field_info *hfinfo;
5591
5592 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5593
5594 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", 5594
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5594, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5594, "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", 5594, __func__, "Adding %s would put more than %d 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)
; } } }
;
5595
5596 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"
, 5596, ((hfinfo))->abbrev))))
;
5597
5598 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5599 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5600
5601 return pi;
5602}
5603
5604proto_item *
5605proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5606 tvbuff_t *tvb, int start, int length,
5607 uint64_t value, const char *format, ...)
5608{
5609 proto_item *pi;
5610 va_list ap;
5611
5612 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5613 if (pi != tree) {
5614 va_start(ap, format)__builtin_va_start(ap, format);
5615 proto_tree_set_representation_value(pi, format, ap);
5616 va_end(ap)__builtin_va_end(ap);
5617 }
5618
5619 return pi;
5620}
5621
5622proto_item *
5623proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5624 int start, int length, uint64_t value,
5625 const char *format, ...)
5626{
5627 proto_item *pi;
5628 va_list ap;
5629
5630 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5631 if (pi != tree) {
5632 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5632, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5633
5634 va_start(ap, format)__builtin_va_start(ap, format);
5635 proto_tree_set_representation(pi, format, ap);
5636 va_end(ap)__builtin_va_end(ap);
5637 }
5638
5639 return pi;
5640}
5641
5642/* Set the FT_BOOLEAN value */
5643static void
5644proto_tree_set_boolean(field_info *fi, uint64_t value)
5645{
5646 proto_tree_set_uint64(fi, value);
5647}
5648
5649/* Generate, into "buf", a string showing the bits of a bitfield.
5650 Return a pointer to the character after that string. */
5651static char *
5652other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5653{
5654 int i = 0;
5655 uint64_t bit;
5656 char *p;
5657
5658 p = buf;
5659
5660 /* This is a devel error. It is safer to stop here. */
5661 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5661, "width >= 1"
))))
;
5662
5663 bit = UINT64_C(1)1UL << (width - 1);
5664 for (;;) {
5665 if (mask & bit) {
5666 /* This bit is part of the field. Show its value. */
5667 if (val & bit)
5668 *p++ = '1';
5669 else
5670 *p++ = '0';
5671 } else {
5672 /* This bit is not part of the field. */
5673 *p++ = '.';
5674 }
5675 bit >>= 1;
5676 i++;
5677 if (i >= width)
5678 break;
5679 if (i % 4 == 0)
5680 *p++ = ' ';
5681 }
5682 *p = '\0';
5683 return p;
5684}
5685
5686static char *
5687decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5688{
5689 char *p;
5690
5691 p = other_decode_bitfield_value(buf, val, mask, width);
5692 p = g_stpcpy(p, " = ");
5693
5694 return p;
5695}
5696
5697static char *
5698other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5699{
5700 int i = 0;
5701 uint64_t bit;
5702 char *p;
5703
5704 p = buf;
5705
5706 /* This is a devel error. It is safer to stop here. */
5707 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5707, "width >= 1"
))))
;
5708
5709 bit = UINT64_C(1)1UL << (width - 1);
5710 for (;;) {
5711 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5712 (mask & bit)) {
5713 /* This bit is part of the field. Show its value. */
5714 if (val & bit)
5715 *p++ = '1';
5716 else
5717 *p++ = '0';
5718 } else {
5719 /* This bit is not part of the field. */
5720 *p++ = '.';
5721 }
5722 bit >>= 1;
5723 i++;
5724 if (i >= width)
5725 break;
5726 if (i % 4 == 0)
5727 *p++ = ' ';
5728 }
5729
5730 *p = '\0';
5731 return p;
5732}
5733
5734static char *
5735decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5736{
5737 char *p;
5738
5739 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5740 p = g_stpcpy(p, " = ");
5741
5742 return p;
5743}
5744
5745/* Add a FT_FLOAT to a proto_tree */
5746proto_item *
5747proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5748 int length, float value)
5749{
5750 proto_item *pi;
5751 header_field_info *hfinfo;
5752
5753 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5754
5755 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", 5755
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5755, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5755, "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", 5755, __func__, "Adding %s would put more than %d 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)
; } } }
;
5756
5757 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",
5757, ((hfinfo))->abbrev))))
;
5758
5759 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5760 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5761
5762 return pi;
5763}
5764
5765proto_item *
5766proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5767 int start, int length, float value,
5768 const char *format, ...)
5769{
5770 proto_item *pi;
5771 va_list ap;
5772
5773 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5774 if (pi != tree) {
5775 va_start(ap, format)__builtin_va_start(ap, format);
5776 proto_tree_set_representation_value(pi, format, ap);
5777 va_end(ap)__builtin_va_end(ap);
5778 }
5779
5780 return pi;
5781}
5782
5783proto_item *
5784proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5785 int start, int length, float value,
5786 const char *format, ...)
5787{
5788 proto_item *pi;
5789 va_list ap;
5790
5791 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5792 if (pi != tree) {
5793 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5793, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5794
5795 va_start(ap, format)__builtin_va_start(ap, format);
5796 proto_tree_set_representation(pi, format, ap);
5797 va_end(ap)__builtin_va_end(ap);
5798 }
5799
5800 return pi;
5801}
5802
5803/* Set the FT_FLOAT value */
5804static void
5805proto_tree_set_float(field_info *fi, float value)
5806{
5807 fvalue_set_floating(fi->value, value);
5808}
5809
5810/* Add a FT_DOUBLE to a proto_tree */
5811proto_item *
5812proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5813 int length, double value)
5814{
5815 proto_item *pi;
5816 header_field_info *hfinfo;
5817
5818 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5819
5820 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", 5820
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5820, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5820, "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", 5820, __func__, "Adding %s would put more than %d 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)
; } } }
;
5821
5822 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"
, 5822, ((hfinfo))->abbrev))))
;
5823
5824 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5825 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5826
5827 return pi;
5828}
5829
5830proto_item *
5831proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5832 int start, int length, double value,
5833 const char *format, ...)
5834{
5835 proto_item *pi;
5836 va_list ap;
5837
5838 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5839 if (pi != tree) {
5840 va_start(ap, format)__builtin_va_start(ap, format);
5841 proto_tree_set_representation_value(pi, format, ap);
5842 va_end(ap)__builtin_va_end(ap);
5843 }
5844
5845 return pi;
5846}
5847
5848proto_item *
5849proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5850 int start, int length, double value,
5851 const char *format, ...)
5852{
5853 proto_item *pi;
5854 va_list ap;
5855
5856 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5857 if (pi != tree) {
5858 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5858, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5859
5860 va_start(ap, format)__builtin_va_start(ap, format);
5861 proto_tree_set_representation(pi, format, ap);
5862 va_end(ap)__builtin_va_end(ap);
5863 }
5864
5865 return pi;
5866}
5867
5868/* Set the FT_DOUBLE value */
5869static void
5870proto_tree_set_double(field_info *fi, double value)
5871{
5872 fvalue_set_floating(fi->value, value);
5873}
5874
5875/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5876proto_item *
5877proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5878 int length, uint32_t value)
5879{
5880 proto_item *pi = NULL((void*)0);
5881 header_field_info *hfinfo;
5882
5883 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5884
5885 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", 5885
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5885, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5885, "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", 5885, __func__, "Adding %s would put more than %d 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)
; } } }
;
5886
5887 switch (hfinfo->type) {
5888 case FT_CHAR:
5889 case FT_UINT8:
5890 case FT_UINT16:
5891 case FT_UINT24:
5892 case FT_UINT32:
5893 case FT_FRAMENUM:
5894 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5895 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5896 break;
5897
5898 default:
5899 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)
5900 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)
;
5901 }
5902
5903 return pi;
5904}
5905
5906proto_item *
5907proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5908 int start, int length, uint32_t value,
5909 const char *format, ...)
5910{
5911 proto_item *pi;
5912 va_list ap;
5913
5914 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5915 if (pi != tree) {
5916 va_start(ap, format)__builtin_va_start(ap, format);
5917 proto_tree_set_representation_value(pi, format, ap);
5918 va_end(ap)__builtin_va_end(ap);
5919 }
5920
5921 return pi;
5922}
5923
5924proto_item *
5925proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5926 int start, int length, uint32_t value,
5927 const char *format, ...)
5928{
5929 proto_item *pi;
5930 va_list ap;
5931
5932 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5933 if (pi != tree) {
5934 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5934, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5935
5936 va_start(ap, format)__builtin_va_start(ap, format);
5937 proto_tree_set_representation(pi, format, ap);
5938 va_end(ap)__builtin_va_end(ap);
5939 }
5940
5941 return pi;
5942}
5943
5944/* Set the FT_UINT{8,16,24,32} value */
5945static void
5946proto_tree_set_uint(field_info *fi, uint32_t value)
5947{
5948 const header_field_info *hfinfo;
5949 uint32_t integer;
5950
5951 hfinfo = fi->hfinfo;
5952 integer = value;
5953
5954 if (hfinfo->bitmask) {
5955 /* Mask out irrelevant portions */
5956 integer &= (uint32_t)(hfinfo->bitmask);
5957
5958 /* Shift bits */
5959 integer >>= hfinfo_bitshift(hfinfo);
5960
5961 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5962 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)
;
5963 }
5964
5965 fvalue_set_uinteger(fi->value, integer);
5966}
5967
5968/* Add FT_UINT{40,48,56,64} to a proto_tree */
5969proto_item *
5970proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5971 int length, uint64_t value)
5972{
5973 proto_item *pi = NULL((void*)0);
5974 header_field_info *hfinfo;
5975
5976 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5977
5978 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", 5978
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5978, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5978, "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", 5978, __func__, "Adding %s would put more than %d 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)
; } } }
;
5979
5980 switch (hfinfo->type) {
5981 case FT_UINT40:
5982 case FT_UINT48:
5983 case FT_UINT56:
5984 case FT_UINT64:
5985 case FT_FRAMENUM:
5986 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5987 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
5988 break;
5989
5990 default:
5991 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)
5992 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)
;
5993 }
5994
5995 return pi;
5996}
5997
5998proto_item *
5999proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6000 int start, int length, uint64_t value,
6001 const char *format, ...)
6002{
6003 proto_item *pi;
6004 va_list ap;
6005
6006 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6007 if (pi != tree) {
6008 va_start(ap, format)__builtin_va_start(ap, format);
6009 proto_tree_set_representation_value(pi, format, ap);
6010 va_end(ap)__builtin_va_end(ap);
6011 }
6012
6013 return pi;
6014}
6015
6016proto_item *
6017proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6018 int start, int length, uint64_t value,
6019 const char *format, ...)
6020{
6021 proto_item *pi;
6022 va_list ap;
6023
6024 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6025 if (pi != tree) {
6026 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6026, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6027
6028 va_start(ap, format)__builtin_va_start(ap, format);
6029 proto_tree_set_representation(pi, format, ap);
6030 va_end(ap)__builtin_va_end(ap);
6031 }
6032
6033 return pi;
6034}
6035
6036/* Set the FT_UINT{40,48,56,64} value */
6037static void
6038proto_tree_set_uint64(field_info *fi, uint64_t value)
6039{
6040 const header_field_info *hfinfo;
6041 uint64_t integer;
6042
6043 hfinfo = fi->hfinfo;
6044 integer = value;
6045
6046 if (hfinfo->bitmask) {
6047 /* Mask out irrelevant portions */
6048 integer &= hfinfo->bitmask;
6049
6050 /* Shift bits */
6051 integer >>= hfinfo_bitshift(hfinfo);
6052
6053 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6054 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)
;
6055 }
6056
6057 fvalue_set_uinteger64(fi->value, integer);
6058}
6059
6060/* Add FT_INT{8,16,24,32} to a proto_tree */
6061proto_item *
6062proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6063 int length, int32_t value)
6064{
6065 proto_item *pi = NULL((void*)0);
6066 header_field_info *hfinfo;
6067
6068 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6069
6070 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", 6070
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6070, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6070, "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", 6070, __func__, "Adding %s would put more than %d 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)
; } } }
;
6071
6072 switch (hfinfo->type) {
6073 case FT_INT8:
6074 case FT_INT16:
6075 case FT_INT24:
6076 case FT_INT32:
6077 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6078 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6079 break;
6080
6081 default:
6082 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)
6083 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6084 }
6085
6086 return pi;
6087}
6088
6089proto_item *
6090proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6091 int start, int length, int32_t value,
6092 const char *format, ...)
6093{
6094 proto_item *pi;
6095 va_list ap;
6096
6097 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6098 if (pi != tree) {
6099 va_start(ap, format)__builtin_va_start(ap, format);
6100 proto_tree_set_representation_value(pi, format, ap);
6101 va_end(ap)__builtin_va_end(ap);
6102 }
6103
6104 return pi;
6105}
6106
6107proto_item *
6108proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6109 int start, int length, int32_t value,
6110 const char *format, ...)
6111{
6112 proto_item *pi;
6113 va_list ap;
6114
6115 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6116 if (pi != tree) {
6117 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6117, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6118
6119 va_start(ap, format)__builtin_va_start(ap, format);
6120 proto_tree_set_representation(pi, format, ap);
6121 va_end(ap)__builtin_va_end(ap);
6122 }
6123
6124 return pi;
6125}
6126
6127/* Set the FT_INT{8,16,24,32} value */
6128static void
6129proto_tree_set_int(field_info *fi, int32_t value)
6130{
6131 const header_field_info *hfinfo;
6132 uint32_t integer;
6133 int no_of_bits;
6134
6135 hfinfo = fi->hfinfo;
6136 integer = (uint32_t) value;
6137
6138 if (hfinfo->bitmask) {
6139 /* Mask out irrelevant portions */
6140 integer &= (uint32_t)(hfinfo->bitmask);
6141
6142 /* Shift bits */
6143 integer >>= hfinfo_bitshift(hfinfo);
6144
6145 no_of_bits = ws_count_ones(hfinfo->bitmask);
6146 integer = ws_sign_ext32(integer, no_of_bits);
6147
6148 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6149 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)
;
6150 }
6151
6152 fvalue_set_sinteger(fi->value, integer);
6153}
6154
6155/* Add FT_INT{40,48,56,64} to a proto_tree */
6156proto_item *
6157proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6158 int length, int64_t value)
6159{
6160 proto_item *pi = NULL((void*)0);
6161 header_field_info *hfinfo;
6162
6163 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6164
6165 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", 6165
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6165, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6165, "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", 6165, __func__, "Adding %s would put more than %d 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)
; } } }
;
6166
6167 switch (hfinfo->type) {
6168 case FT_INT40:
6169 case FT_INT48:
6170 case FT_INT56:
6171 case FT_INT64:
6172 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6173 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6174 break;
6175
6176 default:
6177 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)
6178 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6179 }
6180
6181 return pi;
6182}
6183
6184proto_item *
6185proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6186 int start, int length, int64_t value,
6187 const char *format, ...)
6188{
6189 proto_item *pi;
6190 va_list ap;
6191
6192 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6193 if (pi != tree) {
6194 va_start(ap, format)__builtin_va_start(ap, format);
6195 proto_tree_set_representation_value(pi, format, ap);
6196 va_end(ap)__builtin_va_end(ap);
6197 }
6198
6199 return pi;
6200}
6201
6202/* Set the FT_INT{40,48,56,64} value */
6203static void
6204proto_tree_set_int64(field_info *fi, int64_t value)
6205{
6206 const header_field_info *hfinfo;
6207 uint64_t integer;
6208 int no_of_bits;
6209
6210 hfinfo = fi->hfinfo;
6211 integer = value;
6212
6213 if (hfinfo->bitmask) {
6214 /* Mask out irrelevant portions */
6215 integer &= hfinfo->bitmask;
6216
6217 /* Shift bits */
6218 integer >>= hfinfo_bitshift(hfinfo);
6219
6220 no_of_bits = ws_count_ones(hfinfo->bitmask);
6221 integer = ws_sign_ext64(integer, no_of_bits);
6222
6223 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6224 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)
;
6225 }
6226
6227 fvalue_set_sinteger64(fi->value, integer);
6228}
6229
6230proto_item *
6231proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6232 int start, int length, int64_t value,
6233 const char *format, ...)
6234{
6235 proto_item *pi;
6236 va_list ap;
6237
6238 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6239 if (pi != tree) {
6240 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6240, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6241
6242 va_start(ap, format)__builtin_va_start(ap, format);
6243 proto_tree_set_representation(pi, format, ap);
6244 va_end(ap)__builtin_va_end(ap);
6245 }
6246
6247 return pi;
6248}
6249
6250/* Add a FT_EUI64 to a proto_tree */
6251proto_item *
6252proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6253 int length, const uint64_t value)
6254{
6255 proto_item *pi;
6256 header_field_info *hfinfo;
6257
6258 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6259
6260 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", 6260
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6260, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6260, "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", 6260, __func__, "Adding %s would put more than %d 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)
; } } }
;
6261
6262 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",
6262, ((hfinfo))->abbrev))))
;
6263
6264 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6265 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6266
6267 return pi;
6268}
6269
6270proto_item *
6271proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6272 int start, int length, const uint64_t value,
6273 const char *format, ...)
6274{
6275 proto_item *pi;
6276 va_list ap;
6277
6278 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6279 if (pi != tree) {
6280 va_start(ap, format)__builtin_va_start(ap, format);
6281 proto_tree_set_representation_value(pi, format, ap);
6282 va_end(ap)__builtin_va_end(ap);
6283 }
6284
6285 return pi;
6286}
6287
6288proto_item *
6289proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6290 int start, int length, const uint64_t value,
6291 const char *format, ...)
6292{
6293 proto_item *pi;
6294 va_list ap;
6295
6296 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6297 if (pi != tree) {
6298 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6298, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6299
6300 va_start(ap, format)__builtin_va_start(ap, format);
6301 proto_tree_set_representation(pi, format, ap);
6302 va_end(ap)__builtin_va_end(ap);
6303 }
6304
6305 return pi;
6306}
6307
6308/* Set the FT_EUI64 value */
6309static void
6310proto_tree_set_eui64(field_info *fi, const uint64_t value)
6311{
6312 uint8_t v[FT_EUI64_LEN8];
6313 phtonu64(v, value);
6314 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6315}
6316
6317static void
6318proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6319{
6320 if (encoding)
6321 {
6322 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6323 } else {
6324 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6325 }
6326}
6327
6328proto_item *
6329proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6330 const mac_hf_list_t *list_generic,
6331 int idx, tvbuff_t *tvb,
6332 proto_tree *tree, int offset)
6333{
6334 uint8_t addr[6];
6335 const char *addr_name = NULL((void*)0);
6336 const char *oui_name = NULL((void*)0);
6337 proto_item *addr_item = NULL((void*)0);
6338 proto_tree *addr_tree = NULL((void*)0);
6339 proto_item *ret_val = NULL((void*)0);
6340
6341 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6342 return NULL((void*)0);
6343 }
6344
6345 /* Resolve what we can of the address */
6346 tvb_memcpy(tvb, (void *)addr, offset, 6);
6347 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6348 addr_name = get_ether_name(addr);
6349 }
6350 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6351 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6352 }
6353
6354 /* Add the item for the specific address type */
6355 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6356 if (idx >= 0) {
6357 addr_tree = proto_item_add_subtree(ret_val, idx);
6358 }
6359 else {
6360 addr_tree = tree;
6361 }
6362
6363 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6364 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6365 tvb, offset, 6, addr_name);
6366 proto_item_set_generated(addr_item);
6367 proto_item_set_hidden(addr_item);
6368 }
6369
6370 if (list_specific->hf_oui != NULL((void*)0)) {
6371 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6372 proto_item_set_generated(addr_item);
6373 proto_item_set_hidden(addr_item);
6374
6375 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6376 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6377 proto_item_set_generated(addr_item);
6378 proto_item_set_hidden(addr_item);
6379 }
6380 }
6381
6382 if (list_specific->hf_lg != NULL((void*)0)) {
6383 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6384 }
6385 if (list_specific->hf_ig != NULL((void*)0)) {
6386 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6387 }
6388
6389 /* Were we given a list for generic address fields? If not, stop here */
6390 if (list_generic == NULL((void*)0)) {
6391 return ret_val;
6392 }
6393
6394 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6395 proto_item_set_hidden(addr_item);
6396
6397 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6398 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6399 tvb, offset, 6, addr_name);
6400 proto_item_set_generated(addr_item);
6401 proto_item_set_hidden(addr_item);
6402 }
6403
6404 if (list_generic->hf_oui != NULL((void*)0)) {
6405 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6406 proto_item_set_generated(addr_item);
6407 proto_item_set_hidden(addr_item);
6408
6409 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6410 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6411 proto_item_set_generated(addr_item);
6412 proto_item_set_hidden(addr_item);
6413 }
6414 }
6415
6416 if (list_generic->hf_lg != NULL((void*)0)) {
6417 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6418 proto_item_set_hidden(addr_item);
6419 }
6420 if (list_generic->hf_ig != NULL((void*)0)) {
6421 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6422 proto_item_set_hidden(addr_item);
6423 }
6424 return ret_val;
6425}
6426
6427static proto_item *
6428proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6429{
6430 proto_node *pnode, *tnode, *sibling;
6431 field_info *tfi;
6432 unsigned depth = 1;
6433
6434 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6434, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6435
6436 /*
6437 * Restrict our depth. proto_tree_traverse_pre_order and
6438 * proto_tree_traverse_post_order (and possibly others) are recursive
6439 * so we need to be mindful of our stack size.
6440 */
6441 if (tree->first_child == NULL((void*)0)) {
6442 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6443 depth++;
6444 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6445 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__)), 6448)))
6446 "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__)), 6448)))
6447 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__)), 6448)))
6448 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__)), 6448)))
;
6449 }
6450 }
6451 }
6452
6453 /*
6454 * Make sure "tree" is ready to have subtrees under it, by
6455 * checking whether it's been given an ett_ value.
6456 *
6457 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6458 * node of the protocol tree. That node is not displayed,
6459 * so it doesn't need an ett_ value to remember whether it
6460 * was expanded.
6461 */
6462 tnode = tree;
6463 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6464 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6465 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"
, 6466)
6466 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"
, 6466)
;
6467 /* XXX - is it safe to continue here? */
6468 }
6469
6470 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6471 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6472 pnode->parent = tnode;
6473 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6474 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6475 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6476
6477 if (tnode->last_child != NULL((void*)0)) {
6478 sibling = tnode->last_child;
6479 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6479, "sibling->next == ((void*)0)"
))))
;
6480 sibling->next = pnode;
6481 } else
6482 tnode->first_child = pnode;
6483 tnode->last_child = pnode;
6484
6485 /* We should not be adding a fake node for an interesting field */
6486 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", 6486, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6487
6488 /* XXX - Should the proto_item have a header_field_info member, at least
6489 * for faked items, to know what hfi was faked? (Some dissectors look at
6490 * the tree items directly.)
6491 */
6492 return (proto_item *)pnode;
6493}
6494
6495/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6496static proto_item *
6497proto_tree_add_node(proto_tree *tree, field_info *fi)
6498{
6499 proto_node *pnode, *tnode, *sibling;
6500 field_info *tfi;
6501 unsigned depth = 1;
6502
6503 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6503, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6504
6505 /*
6506 * Restrict our depth. proto_tree_traverse_pre_order and
6507 * proto_tree_traverse_post_order (and possibly others) are recursive
6508 * so we need to be mindful of our stack size.
6509 */
6510 if (tree->first_child == NULL((void*)0)) {
6511 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6512 depth++;
6513 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6514 fvalue_free(fi->value);
6515 fi->value = NULL((void*)0);
6516 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__)), 6519)))
6517 "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__)), 6519)))
6518 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__)), 6519)))
6519 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__)), 6519)))
;
6520 }
6521 }
6522 }
6523
6524 /*
6525 * Make sure "tree" is ready to have subtrees under it, by
6526 * checking whether it's been given an ett_ value.
6527 *
6528 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6529 * node of the protocol tree. That node is not displayed,
6530 * so it doesn't need an ett_ value to remember whether it
6531 * was expanded.
6532 */
6533 tnode = tree;
6534 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6535 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6536 /* Since we are not adding fi to a node, its fvalue won't get
6537 * freed by proto_tree_free_node(), so free it now.
6538 */
6539 fvalue_free(fi->value);
6540 fi->value = NULL((void*)0);
6541 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", 6542)
6542 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", 6542)
;
6543 /* XXX - is it safe to continue here? */
6544 }
6545
6546 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6547 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6548 pnode->parent = tnode;
6549 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6550 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6551 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6552
6553 if (tnode->last_child != NULL((void*)0)) {
6554 sibling = tnode->last_child;
6555 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6555, "sibling->next == ((void*)0)"
))))
;
6556 sibling->next = pnode;
6557 } else
6558 tnode->first_child = pnode;
6559 tnode->last_child = pnode;
6560
6561 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6562
6563 return (proto_item *)pnode;
6564}
6565
6566
6567/* Generic way to allocate field_info and add to proto_tree.
6568 * Sets *pfi to address of newly-allocated field_info struct */
6569static proto_item *
6570proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6571 int *length)
6572{
6573 proto_item *pi;
6574 field_info *fi;
6575 int item_length;
6576
6577 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6578 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6579 pi = proto_tree_add_node(tree, fi);
6580
6581 return pi;
6582}
6583
6584
6585static void
6586get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6587 int *item_length, const unsigned encoding)
6588{
6589 int length_remaining;
6590
6591 /*
6592 * We only allow a null tvbuff if the item has a zero length,
6593 * i.e. if there's no data backing it.
6594 */
6595 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", 6595, "tvb != ((void*)0) || *length == 0"
))))
;
6596
6597 /*
6598 * XXX - in some protocols, there are 32-bit unsigned length
6599 * fields, so lengths in protocol tree and tvbuff routines
6600 * should really be unsigned. We should have, for those
6601 * field types for which "to the end of the tvbuff" makes sense,
6602 * additional routines that take no length argument and
6603 * add fields that run to the end of the tvbuff.
6604 */
6605 if (*length == -1) {
6606 /*
6607 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6608 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6609 * of -1 means "set the length to what remains in the
6610 * tvbuff".
6611 *
6612 * The assumption is either that
6613 *
6614 * 1) the length of the item can only be determined
6615 * by dissection (typically true of items with
6616 * subitems, which are probably FT_NONE or
6617 * FT_PROTOCOL)
6618 *
6619 * or
6620 *
6621 * 2) if the tvbuff is "short" (either due to a short
6622 * snapshot length or due to lack of reassembly of
6623 * fragments/segments/whatever), we want to display
6624 * what's available in the field (probably FT_BYTES
6625 * or FT_STRING) and then throw an exception later
6626 *
6627 * or
6628 *
6629 * 3) the field is defined to be "what's left in the
6630 * packet"
6631 *
6632 * so we set the length to what remains in the tvbuff so
6633 * that, if we throw an exception while dissecting, it
6634 * has what is probably the right value.
6635 *
6636 * For FT_STRINGZ, it means "the string is null-terminated,
6637 * not null-padded; set the length to the actual length
6638 * of the string", and if the tvbuff if short, we just
6639 * throw an exception.
6640 *
6641 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6642 * it means "find the end of the string",
6643 * and if the tvbuff if short, we just throw an exception.
6644 *
6645 * It's not valid for any other type of field. For those
6646 * fields, we treat -1 the same way we treat other
6647 * negative values - we assume the length is a Really
6648 * Big Positive Number, and throw a ReportedBoundsError
6649 * exception, under the assumption that the Really Big
6650 * Length would run past the end of the packet.
6651 */
6652 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
))
)) {
6653 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6654 /*
6655 * Leave the length as -1, so our caller knows
6656 * it was -1.
6657 */
6658 *item_length = *length;
6659 return;
6660 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6661 switch (tvb_get_uint8(tvb, start) >> 6)
6662 {
6663 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6664 *item_length = 1;
6665 break;
6666 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6667 *item_length = 2;
6668 break;
6669 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6670 *item_length = 4;
6671 break;
6672 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6673 *item_length = 8;
6674 break;
6675 }
6676 }
6677 }
6678
6679 switch (hfinfo->type) {
6680
6681 case FT_PROTOCOL:
6682 case FT_NONE:
6683 case FT_BYTES:
6684 case FT_STRING:
6685 case FT_STRINGZPAD:
6686 case FT_STRINGZTRUNC:
6687 /*
6688 * We allow FT_PROTOCOLs to be zero-length -
6689 * for example, an ONC RPC NULL procedure has
6690 * neither arguments nor reply, so the
6691 * payload for that protocol is empty.
6692 *
6693 * We also allow the others to be zero-length -
6694 * because that's the way the code has been for a
6695 * long, long time.
6696 *
6697 * However, we want to ensure that the start
6698 * offset is not *past* the byte past the end
6699 * of the tvbuff: we throw an exception in that
6700 * case.
6701 */
6702 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6703 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6703, "*length >= 0"
))))
;
6704 break;
6705
6706 case FT_STRINGZ:
6707 /*
6708 * Leave the length as -1, so our caller knows
6709 * it was -1.
6710 */
6711 break;
6712
6713 default:
6714 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6715 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6715))
;
6716 }
6717 *item_length = *length;
6718 } else {
6719 *item_length = *length;
6720 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6721 /*
6722 * These types are for interior nodes of the
6723 * tree, and don't have data associated with
6724 * them; if the length is negative (XXX - see
6725 * above) or goes past the end of the tvbuff,
6726 * cut it short at the end of the tvbuff.
6727 * That way, if this field is selected in
6728 * Wireshark, we don't highlight stuff past
6729 * the end of the data.
6730 */
6731 /* XXX - what to do, if we don't have a tvb? */
6732 if (tvb) {
6733 length_remaining = tvb_captured_length_remaining(tvb, start);
6734 if (*item_length < 0 ||
6735 (*item_length > 0 &&
6736 (length_remaining < *item_length)))
6737 *item_length = length_remaining;
6738 }
6739 }
6740 if (*item_length < 0) {
6741 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6742 }
6743 }
6744}
6745
6746static int
6747get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6748 int length, unsigned item_length, const int encoding)
6749{
6750 uint32_t n;
6751
6752 /*
6753 * We need to get the correct item length here.
6754 * That's normally done by proto_tree_new_item(),
6755 * but we won't be calling it.
6756 */
6757 switch (hfinfo->type) {
6758
6759 case FT_NONE:
6760 case FT_PROTOCOL:
6761 case FT_BYTES:
6762 /*
6763 * The length is the specified length.
6764 */
6765 break;
6766
6767 case FT_UINT_BYTES:
6768 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6769 item_length += n;
6770 if ((int)item_length < length) {
6771 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6772 }
6773 break;
6774
6775 /* XXX - make these just FT_UINT? */
6776 case FT_UINT8:
6777 case FT_UINT16:
6778 case FT_UINT24:
6779 case FT_UINT32:
6780 case FT_UINT40:
6781 case FT_UINT48:
6782 case FT_UINT56:
6783 case FT_UINT64:
6784 /* XXX - make these just FT_INT? */
6785 case FT_INT8:
6786 case FT_INT16:
6787 case FT_INT24:
6788 case FT_INT32:
6789 case FT_INT40:
6790 case FT_INT48:
6791 case FT_INT56:
6792 case FT_INT64:
6793 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6794 if (length < -1) {
6795 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6796 }
6797 if (length == -1) {
6798 uint64_t dummy;
6799 /* This can throw an exception */
6800 /* XXX - do this without fetching the varint? */
6801 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6802 if (length == 0) {
6803 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6804 }
6805 }
6806 item_length = length;
6807 break;
6808 }
6809
6810 /*
6811 * The length is the specified length.
6812 */
6813 break;
6814
6815 case FT_BOOLEAN:
6816 case FT_CHAR:
6817 case FT_IPv4:
6818 case FT_IPXNET:
6819 case FT_IPv6:
6820 case FT_FCWWN:
6821 case FT_AX25:
6822 case FT_VINES:
6823 case FT_ETHER:
6824 case FT_EUI64:
6825 case FT_GUID:
6826 case FT_OID:
6827 case FT_REL_OID:
6828 case FT_SYSTEM_ID:
6829 case FT_FLOAT:
6830 case FT_DOUBLE:
6831 case FT_STRING:
6832 /*
6833 * The length is the specified length.
6834 */
6835 break;
6836
6837 case FT_STRINGZ:
6838 if (length < -1) {
6839 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6840 }
6841 if (length == -1) {
6842 /* This can throw an exception */
6843 /* XXX - do this without fetching the string? */
6844 wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, &length, encoding));
6845 }
6846 item_length = length;
6847 break;
6848
6849 case FT_UINT_STRING:
6850 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6851 item_length += n;
6852 if ((int)item_length < length) {
6853 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6854 }
6855 break;
6856
6857 case FT_STRINGZPAD:
6858 case FT_STRINGZTRUNC:
6859 case FT_ABSOLUTE_TIME:
6860 case FT_RELATIVE_TIME:
6861 case FT_IEEE_11073_SFLOAT:
6862 case FT_IEEE_11073_FLOAT:
6863 /*
6864 * The length is the specified length.
6865 */
6866 break;
6867
6868 default:
6869 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
))
6870 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
))
6871 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
))
6872 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
))
;
6873 break;
6874 }
6875 return item_length;
6876}
6877
6878// This was arbitrarily chosen, but if you're adding 50K items to the tree
6879// without advancing the offset you should probably take a long, hard look
6880// at what you're doing.
6881// We *could* make this a configurable option, but I (Gerald) would like to
6882// avoid adding yet another nerd knob.
6883# define PROTO_TREE_MAX_IDLE50000 50000
6884static field_info *
6885new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6886 const int start, const int item_length)
6887{
6888 field_info *fi;
6889
6890 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6891
6892 fi->hfinfo = hfinfo;
6893 fi->start = start;
6894 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6895 /* add the data source tvbuff */
6896 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6897
6898 // If our start offset hasn't advanced after adding many items it probably
6899 // means we're in a large or infinite loop.
6900 if (fi->start > 0) {
6901 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6902 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6903 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", 6903, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6904 } else {
6905 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6906 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6907 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6908 }
6909 }
6910 fi->length = item_length;
6911 fi->tree_type = -1;
6912 fi->flags = 0;
6913 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6914 /* If the tree is not visible, set the item hidden, unless we
6915 * need the representation or length and can't fake them.
6916 */
6917 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6918 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6919 }
6920 }
6921 fi->value = fvalue_new(fi->hfinfo->type);
6922 fi->rep = NULL((void*)0);
6923
6924 fi->appendix_start = 0;
6925 fi->appendix_length = 0;
6926
6927 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6928 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6929
6930 return fi;
6931}
6932
6933static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6934{
6935 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6936 return 0;
6937 }
6938
6939 /* Search for field name */
6940 char *ptr = strstr(representation, hfinfo->name);
6941 if (!ptr) {
6942 return 0;
6943 }
6944
6945 /* Check if field name ends with the ": " delimiter */
6946 ptr += strlen(hfinfo->name);
6947 if (strncmp(ptr, ": ", 2) == 0) {
6948 ptr += 2;
6949 }
6950
6951 /* Return offset to after field name */
6952 return ptr - representation;
6953}
6954
6955static size_t label_find_name_pos(const item_label_t *rep)
6956{
6957 size_t name_pos = 0;
6958
6959 /* If the value_pos is too small or too large, we can't find the expected format */
6960 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
6961 return 0;
6962 }
6963
6964 /* Check if the format looks like "label: value", then set name_pos before ':'. */
6965 if (rep->representation[rep->value_pos-2] == ':') {
6966 name_pos = rep->value_pos - 2;
6967 }
6968
6969 return name_pos;
6970}
6971
6972/* If the protocol tree is to be visible, set the representation of a
6973 proto_tree entry with the name of the field for the item and with
6974 the value formatted with the supplied printf-style format and
6975 argument list. */
6976static void
6977proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6978{
6979 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6979, __func__, "assertion failed: %s", "pi"
); } while (0)
;
6980
6981 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6982 * items string representation */
6983 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
6984 size_t name_pos, ret = 0;
6985 char *str;
6986 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6987 const header_field_info *hf;
6988
6989 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6989, "fi"))))
;
6990
6991 hf = fi->hfinfo;
6992
6993 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;
;
6994 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))
)) {
6995 uint64_t val;
6996 char *p;
6997
6998 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)
)
6999 val = fvalue_get_uinteger(fi->value);
7000 else
7001 val = fvalue_get_uinteger64(fi->value);
7002
7003 val <<= hfinfo_bitshift(hf);
7004
7005 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7006 ret = (p - fi->rep->representation);
7007 }
7008
7009 /* put in the hf name */
7010 name_pos = ret = label_concat(fi->rep->representation, ret, hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, hf->
name, 0)
;
7011
7012 ret = label_concat(fi->rep->representation, ret, ": ")ws_label_strcpy(fi->rep->representation, 240, ret, ": "
, 0)
;
7013 /* If possible, Put in the value of the string */
7014 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7015 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"
, 7015, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7016 fi->rep->value_pos = ret;
7017 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, str, 0);
7018 if (ret >= ITEM_LABEL_LENGTH240) {
7019 /* Uh oh, we don't have enough room. Tell the user
7020 * that the field is truncated.
7021 */
7022 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7023 }
7024 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7025 }
7026}
7027
7028/* If the protocol tree is to be visible, set the representation of a
7029 proto_tree entry with the representation formatted with the supplied
7030 printf-style format and argument list. */
7031static void
7032proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7033{
7034 size_t ret; /*tmp return value */
7035 char *str;
7036 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7037
7038 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7038, "fi"))))
;
7039
7040 if (!proto_item_is_hidden(pi)) {
7041 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;
;
7042
7043 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7044 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"
, 7044, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7045 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7046 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7047 if (ret >= ITEM_LABEL_LENGTH240) {
7048 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7049 size_t name_pos = label_find_name_pos(fi->rep);
7050 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7051 }
7052 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7053 }
7054}
7055
7056static int
7057proto_strlcpy(char *dest, const char *src, size_t dest_size)
7058{
7059 if (dest_size == 0) return 0;
7060
7061 size_t res = g_strlcpy(dest, src, dest_size);
7062
7063 /* At most dest_size - 1 characters will be copied
7064 * (unless dest_size is 0). */
7065 if (res >= dest_size)
7066 res = dest_size - 1;
7067 return (int) res;
7068}
7069
7070static header_field_info *
7071hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7072{
7073 header_field_info *dup_hfinfo;
7074
7075 if (hfinfo->same_name_prev_id == -1)
7076 return NULL((void*)0);
7077 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", 7077
, __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", 7077, "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", 7077,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7078 return dup_hfinfo;
7079}
7080
7081static void
7082hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7083{
7084 g_free(last_field_name);
7085 last_field_name = NULL((void*)0);
7086
7087 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7088 /* No hfinfo with the same name */
7089 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7090 return;
7091 }
7092
7093 if (hfinfo->same_name_next) {
7094 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7095 }
7096
7097 if (hfinfo->same_name_prev_id != -1) {
7098 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7099 same_name_prev->same_name_next = hfinfo->same_name_next;
7100 if (!hfinfo->same_name_next) {
7101 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7102 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7103 }
7104 }
7105}
7106
7107int
7108proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7109{
7110 const header_field_info *hfinfo = finfo->hfinfo;
7111 int label_len = 0;
7112 char *tmp_str;
7113 const char *str;
7114 const uint8_t *bytes;
7115 uint32_t number;
7116 uint64_t number64;
7117 const char *hf_str_val;
7118 char number_buf[NUMBER_LABEL_LENGTH80];
7119 const char *number_out;
7120 address addr;
7121 const ipv4_addr_and_mask *ipv4;
7122 const ipv6_addr_and_prefix *ipv6;
7123
7124 switch (hfinfo->type) {
7125
7126 case FT_NONE:
7127 case FT_PROTOCOL:
7128 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7129
7130 case FT_UINT_BYTES:
7131 case FT_BYTES:
7132 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7133 hfinfo,
7134 fvalue_get_bytes_data(finfo->value),
7135 (unsigned)fvalue_length2(finfo->value),
7136 label_str_size);
7137 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7138 wmem_free(NULL((void*)0), tmp_str);
7139 break;
7140
7141 case FT_ABSOLUTE_TIME:
7142 {
7143 const nstime_t *value = fvalue_get_time(finfo->value);
7144 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7145 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7146 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7147 }
7148 if (hfinfo->strings) {
7149 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7150 if (time_string != NULL((void*)0)) {
7151 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7152 break;
7153 }
7154 }
7155 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7156 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7157 wmem_free(NULL((void*)0), tmp_str);
7158 break;
7159 }
7160
7161 case FT_RELATIVE_TIME:
7162 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7163 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7164 wmem_free(NULL((void*)0), tmp_str);
7165 break;
7166
7167 case FT_BOOLEAN:
7168 number64 = fvalue_get_uinteger64(finfo->value);
7169 label_len = proto_strlcpy(display_label_str,
7170 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7171 break;
7172
7173 case FT_CHAR:
7174 number = fvalue_get_uinteger(finfo->value);
7175
7176 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7177 char tmp[ITEM_LABEL_LENGTH240];
7178 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7179
7180 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7180, "fmtfunc"))))
;
7181 fmtfunc(tmp, number);
7182
7183 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7184
7185 } else if (hfinfo->strings) {
7186 number_out = hf_try_val_to_str(number, hfinfo);
7187
7188 if (!number_out) {
7189 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7190 }
7191
7192 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7193
7194 } else {
7195 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7196
7197 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7198 }
7199
7200 break;
7201
7202 /* XXX - make these just FT_NUMBER? */
7203 case FT_INT8:
7204 case FT_INT16:
7205 case FT_INT24:
7206 case FT_INT32:
7207 case FT_UINT8:
7208 case FT_UINT16:
7209 case FT_UINT24:
7210 case FT_UINT32:
7211 case FT_FRAMENUM:
7212 hf_str_val = NULL((void*)0);
7213 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
))
?
7214 (uint32_t) fvalue_get_sinteger(finfo->value) :
7215 fvalue_get_uinteger(finfo->value);
7216
7217 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7218 char tmp[ITEM_LABEL_LENGTH240];
7219 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7220
7221 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7221, "fmtfunc"))))
;
7222 fmtfunc(tmp, number);
7223
7224 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7225
7226 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7227 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7228 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7229 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7230 hf_str_val = hf_try_val_to_str(number, hfinfo);
7231 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7232 } else {
7233 number_out = hf_try_val_to_str(number, hfinfo);
7234
7235 if (!number_out) {
7236 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7237 }
7238
7239 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7240 }
7241 } else {
7242 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7243
7244 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7245 }
7246
7247 break;
7248
7249 case FT_INT40:
7250 case FT_INT48:
7251 case FT_INT56:
7252 case FT_INT64:
7253 case FT_UINT40:
7254 case FT_UINT48:
7255 case FT_UINT56:
7256 case FT_UINT64:
7257 hf_str_val = NULL((void*)0);
7258 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
))
?
7259 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7260 fvalue_get_uinteger64(finfo->value);
7261
7262 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7263 char tmp[ITEM_LABEL_LENGTH240];
7264 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7265
7266 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7266, "fmtfunc64"
))))
;
7267 fmtfunc64(tmp, number64);
7268
7269 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7270 } else if (hfinfo->strings) {
7271 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7272 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7273 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7274 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7275 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7276 } else {
7277 number_out = hf_try_val64_to_str(number64, hfinfo);
7278
7279 if (!number_out)
7280 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7281
7282 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7283 }
7284 } else {
7285 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7286
7287 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7288 }
7289
7290 break;
7291
7292 case FT_EUI64:
7293 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7294 tmp_str = address_to_display(NULL((void*)0), &addr);
7295 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7296 wmem_free(NULL((void*)0), tmp_str);
7297 break;
7298
7299 case FT_IPv4:
7300 ipv4 = fvalue_get_ipv4(finfo->value);
7301 //XXX: Should we ignore the mask?
7302 set_address_ipv4(&addr, ipv4);
7303 tmp_str = address_to_display(NULL((void*)0), &addr);
7304 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7305 wmem_free(NULL((void*)0), tmp_str);
7306 free_address(&addr);
7307 break;
7308
7309 case FT_IPv6:
7310 ipv6 = fvalue_get_ipv6(finfo->value);
7311 set_address_ipv6(&addr, ipv6);
7312 tmp_str = address_to_display(NULL((void*)0), &addr);
7313 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7314 wmem_free(NULL((void*)0), tmp_str);
7315 free_address(&addr);
7316 break;
7317
7318 case FT_FCWWN:
7319 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7320 tmp_str = address_to_display(NULL((void*)0), &addr);
7321 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7322 wmem_free(NULL((void*)0), tmp_str);
7323 break;
7324
7325 case FT_ETHER:
7326 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7327 tmp_str = address_to_display(NULL((void*)0), &addr);
7328 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7329 wmem_free(NULL((void*)0), tmp_str);
7330 break;
7331
7332 case FT_GUID:
7333 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7334 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7335 wmem_free(NULL((void*)0), tmp_str);
7336 break;
7337
7338 case FT_REL_OID:
7339 bytes = fvalue_get_bytes_data(finfo->value);
7340 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7341 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7342 wmem_free(NULL((void*)0), tmp_str);
7343 break;
7344
7345 case FT_OID:
7346 bytes = fvalue_get_bytes_data(finfo->value);
7347 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7348 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7349 wmem_free(NULL((void*)0), tmp_str);
7350 break;
7351
7352 case FT_SYSTEM_ID:
7353 bytes = fvalue_get_bytes_data(finfo->value);
7354 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7355 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7356 wmem_free(NULL((void*)0), tmp_str);
7357 break;
7358
7359 case FT_FLOAT:
7360 case FT_DOUBLE:
7361 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7362 break;
7363
7364 case FT_IEEE_11073_SFLOAT:
7365 case FT_IEEE_11073_FLOAT:
7366 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7367 break;
7368
7369 case FT_STRING:
7370 case FT_STRINGZ:
7371 case FT_UINT_STRING:
7372 case FT_STRINGZPAD:
7373 case FT_STRINGZTRUNC:
7374 str = fvalue_get_string(finfo->value);
7375 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, str, label_strcat_flags(hfinfo));
7376 if (label_len >= label_str_size) {
7377 /* Truncation occurred. Get the real length
7378 * copied (not including '\0') */
7379 label_len = label_str_size ? label_str_size - 1 : 0;
7380 }
7381 break;
7382
7383 default:
7384 /* First try ftype string representation */
7385 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7386 if (!tmp_str) {
7387 /* Default to show as bytes */
7388 bytes = fvalue_get_bytes_data(finfo->value);
7389 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7390 }
7391 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7392 wmem_free(NULL((void*)0), tmp_str);
7393 break;
7394 }
7395 return label_len;
7396}
7397
7398const char *
7399proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7400 char *result, char *expr, const int size)
7401{
7402 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7403 GPtrArray *finfos;
7404 field_info *finfo = NULL((void*)0);
7405 header_field_info* hfinfo;
7406 const char *abbrev = NULL((void*)0);
7407
7408 char *str;
7409 col_custom_t *field_idx;
7410 int field_id;
7411 int ii = 0;
7412
7413 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7413, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7414 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7415 field_id = field_idx->field_id;
7416 if (field_id == 0) {
7417 GPtrArray *fvals = NULL((void*)0);
7418 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7419 if (fvals != NULL((void*)0)) {
7420
7421 // XXX - Handling occurrences is unusual when more
7422 // than one field is involved, e.g. there's four
7423 // results for tcp.port + tcp.port. We may really
7424 // want to apply it to the operands, not the output.
7425 // Note that occurrences are not quite the same as
7426 // the layer operator (should the grammar support
7427 // both?)
7428 /* Calculate single index or set outer boundaries */
7429 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7430 if (occurrence < 0) {
7431 i = occurrence + len;
7432 last = i;
7433 } else if (occurrence > 0) {
7434 i = occurrence - 1;
7435 last = i;
7436 } else {
7437 i = 0;
7438 last = len - 1;
7439 }
7440 if (i < 0 || i >= len) {
7441 g_ptr_array_unref(fvals);
7442 continue;
7443 }
7444 for (; i <= last; i++) {
7445 /* XXX - We could have a "resolved" result
7446 * for types where the value depends only
7447 * on the type, e.g. FT_IPv4, and not on
7448 * hfinfo->strings. Supporting the latter
7449 * requires knowing which hfinfo matched
7450 * if there are multiple with the same
7451 * abbreviation. In any case, we need to
7452 * know the expected return type of the
7453 * field expression.
7454 */
7455 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7456 if (offset_r && (offset_r < (size - 1)))
7457 result[offset_r++] = ',';
7458 if (offset_e && (offset_e < (size - 1)))
7459 expr[offset_e++] = ',';
7460 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7461 // col_{add,append,set}_* calls ws_label_strcpy
7462 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7463
7464 g_free(str);
7465 }
7466 g_ptr_array_unref(fvals);
7467 } else if (passed) {
7468 // XXX - Occurrence doesn't make sense for a test
7469 // output, it should be applied to the operands.
7470 if (offset_r && (offset_r < (size - 1)))
7471 result[offset_r++] = ',';
7472 if (offset_e && (offset_e < (size - 1)))
7473 expr[offset_e++] = ',';
7474 /* Prevent multiple check marks */
7475 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7476 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7477 } else {
7478 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7479 }
7480 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7481 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7482 } else {
7483 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7484 }
7485 }
7486 continue;
7487 }
7488 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", 7488
, __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", 7488,
"(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", 7488,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7489
7490 /* do we need to rewind ? */
7491 if (!hfinfo)
7492 return "";
7493
7494 if (occurrence < 0) {
7495 /* Search other direction */
7496 while (hfinfo->same_name_prev_id != -1) {
7497 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", 7497
, __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", 7497, "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", 7497,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7498 }
7499 }
7500
7501 prev_len = 0; /* Reset handled occurrences */
7502
7503 while (hfinfo) {
7504 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7505
7506 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7507 if (occurrence < 0) {
7508 hfinfo = hfinfo->same_name_next;
7509 } else {
7510 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7511 }
7512 continue;
7513 }
7514
7515 /* Are there enough occurrences of the field? */
7516 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7517 if (occurrence < 0) {
7518 hfinfo = hfinfo->same_name_next;
7519 } else {
7520 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7521 }
7522 prev_len += len;
7523 continue;
7524 }
7525
7526 /* Calculate single index or set outer boundaries */
7527 if (occurrence < 0) {
7528 i = occurrence + len + prev_len;
7529 last = i;
7530 } else if (occurrence > 0) {
7531 i = occurrence - 1 - prev_len;
7532 last = i;
7533 } else {
7534 i = 0;
7535 last = len - 1;
7536 }
7537
7538 prev_len += len; /* Count handled occurrences */
7539
7540 while (i <= last) {
7541 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7542
7543 if (offset_r && (offset_r < (size - 1)))
7544 result[offset_r++] = ',';
7545
7546 if (display_details) {
7547 char representation[ITEM_LABEL_LENGTH240];
7548 size_t offset = 0;
7549
7550 if (finfo->rep && finfo->rep->value_len) {
7551 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7552 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7553 } else {
7554 proto_item_fill_label(finfo, representation, &offset);
7555 }
7556 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7557 } else {
7558 switch (hfinfo->type) {
7559
7560 case FT_NONE:
7561 case FT_PROTOCOL:
7562 /* Prevent multiple check marks */
7563 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7564 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7565 } else {
7566 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7567 }
7568 break;
7569
7570 default:
7571 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7572 break;
7573 }
7574 }
7575
7576 if (offset_e && (offset_e < (size - 1)))
7577 expr[offset_e++] = ',';
7578
7579 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
))
)) {
7580 const char *hf_str_val;
7581 /* Integer types with BASE_NONE never get the numeric value. */
7582 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7583 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7584 } 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
)
) {
7585 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7586 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7587 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7588 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7589 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7590 }
7591 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7592 offset_e = (int)strlen(expr);
7593 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7594 /* Prevent multiple check marks */
7595 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7596 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7597 } else {
7598 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7599 }
7600 } else {
7601 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7602 // col_{add,append,set}_* calls ws_label_strcpy
7603 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7604 wmem_free(NULL((void*)0), str);
7605 }
7606 i++;
7607 }
7608
7609 /* XXX: Why is only the first abbreviation returned for a multifield
7610 * custom column? */
7611 if (!abbrev) {
7612 /* Store abbrev for return value */
7613 abbrev = hfinfo->abbrev;
7614 }
7615
7616 if (occurrence == 0) {
7617 /* Fetch next hfinfo with same name (abbrev) */
7618 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7619 } else {
7620 hfinfo = NULL((void*)0);
7621 }
7622 }
7623 }
7624
7625 if (offset_r >= (size - 1)) {
7626 mark_truncated(result, 0, size, NULL((void*)0));
7627 }
7628 if (offset_e >= (size - 1)) {
7629 mark_truncated(expr, 0, size, NULL((void*)0));
7630 }
7631 return abbrev ? abbrev : "";
7632}
7633
7634char *
7635proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7636{
7637 int len, prev_len, last, i;
7638 GPtrArray *finfos;
7639 field_info *finfo = NULL((void*)0);
7640 header_field_info* hfinfo;
7641
7642 char *filter = NULL((void*)0);
7643 GPtrArray *filter_array;
7644
7645 col_custom_t *col_custom;
7646 int field_id;
7647
7648 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7648, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7649 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7650 for (GSList *iter = field_ids; iter; iter = iter->next) {
7651 col_custom = (col_custom_t*)iter->data;
7652 field_id = col_custom->field_id;
7653 if (field_id == 0) {
7654 GPtrArray *fvals = NULL((void*)0);
7655 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7656 if (fvals != NULL((void*)0)) {
7657 // XXX - Handling occurrences is unusual when more
7658 // than one field is involved, e.g. there's four
7659 // results for tcp.port + tcp.port. We really
7660 // want to apply it to the operands, not the output.
7661 /* Calculate single index or set outer boundaries */
7662 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7663 if (occurrence < 0) {
7664 i = occurrence + len;
7665 last = i;
7666 } else if (occurrence > 0) {
7667 i = occurrence - 1;
7668 last = i;
7669 } else {
7670 i = 0;
7671 last = len - 1;
7672 }
7673 if (i < 0 || i >= len) {
7674 g_ptr_array_unref(fvals);
7675 continue;
7676 }
7677 for (; i <= last; i++) {
7678 /* XXX - Should multiple values for one
7679 * field use set membership to reduce
7680 * verbosity, here and below? */
7681 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7682 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7683 wmem_free(NULL((void*)0), str);
7684 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7685 g_ptr_array_add(filter_array, filter);
7686 }
7687 }
7688 g_ptr_array_unref(fvals);
7689 } else if (passed) {
7690 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7691 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7692 g_ptr_array_add(filter_array, filter);
7693 }
7694 } else {
7695 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7696 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7697 g_ptr_array_add(filter_array, filter);
7698 }
7699 }
7700 continue;
7701 }
7702
7703 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", 7703
, __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", 7703,
"(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", 7703,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7704
7705 /* do we need to rewind ? */
7706 if (!hfinfo)
7707 return NULL((void*)0);
7708
7709 if (occurrence < 0) {
7710 /* Search other direction */
7711 while (hfinfo->same_name_prev_id != -1) {
7712 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", 7712
, __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", 7712, "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", 7712,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7713 }
7714 }
7715
7716 prev_len = 0; /* Reset handled occurrences */
7717
7718 while (hfinfo) {
7719 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7720
7721 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7722 if (occurrence < 0) {
7723 hfinfo = hfinfo->same_name_next;
7724 } else {
7725 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7726 }
7727 continue;
7728 }
7729
7730 /* Are there enough occurrences of the field? */
7731 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7732 if (occurrence < 0) {
7733 hfinfo = hfinfo->same_name_next;
7734 } else {
7735 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7736 }
7737 prev_len += len;
7738 continue;
7739 }
7740
7741 /* Calculate single index or set outer boundaries */
7742 if (occurrence < 0) {
7743 i = occurrence + len + prev_len;
7744 last = i;
7745 } else if (occurrence > 0) {
7746 i = occurrence - 1 - prev_len;
7747 last = i;
7748 } else {
7749 i = 0;
7750 last = len - 1;
7751 }
7752
7753 prev_len += len; /* Count handled occurrences */
7754
7755 while (i <= last) {
7756 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7757
7758 filter = proto_construct_match_selected_string(finfo, edt);
7759 if (filter) {
7760 /* Only add the same expression once (especially for FT_PROTOCOL).
7761 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7762 */
7763 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7764 g_ptr_array_add(filter_array, filter);
7765 }
7766 }
7767 i++;
7768 }
7769
7770 if (occurrence == 0) {
7771 /* Fetch next hfinfo with same name (abbrev) */
7772 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7773 } else {
7774 hfinfo = NULL((void*)0);
7775 }
7776 }
7777 }
7778
7779 g_ptr_array_add(filter_array, NULL((void*)0));
7780
7781 /* XXX: Should this be || or && ? */
7782 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7783
7784 g_ptr_array_free(filter_array, true1);
7785
7786 return output;
7787}
7788
7789/* Set text of proto_item after having already been created. */
7790void
7791proto_item_set_text(proto_item *pi, const char *format, ...)
7792{
7793 field_info *fi = NULL((void*)0);
7794 va_list ap;
7795
7796 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7797
7798 fi = PITEM_FINFO(pi)((pi)->finfo);
7799 if (fi == NULL((void*)0))
7800 return;
7801
7802 if (fi->rep) {
7803 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7804 fi->rep = NULL((void*)0);
7805 }
7806
7807 va_start(ap, format)__builtin_va_start(ap, format);
7808 proto_tree_set_representation(pi, format, ap);
7809 va_end(ap)__builtin_va_end(ap);
7810}
7811
7812/* Append to text of proto_item after having already been created. */
7813void
7814proto_item_append_text(proto_item *pi, const char *format, ...)
7815{
7816 field_info *fi = NULL((void*)0);
7817 size_t curlen;
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, fi->rep->representation, &fi->rep->value_pos);
7836 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7837 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7838 (strncmp(format, ": ", 2) == 0)) {
7839 fi->rep->value_pos += 2;
7840 }
7841 }
7842 if (fi->rep) {
7843 curlen = strlen(fi->rep->representation);
7844 /* curlen doesn't include the \0 byte.
7845 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7846 * the representation has already been truncated (of an up
7847 * to 4 byte UTF-8 character) or is just at the maximum length
7848 * unless we search for " [truncated]" (which may not be
7849 * at the start.)
7850 * It's safer to do nothing.
7851 */
7852 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7853 va_start(ap, format)__builtin_va_start(ap, format);
7854 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7855 va_end(ap)__builtin_va_end(ap);
7856 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"
, 7856, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7857 /* Keep fi->rep->value_pos */
7858 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, str, 0);
7859 if (curlen >= ITEM_LABEL_LENGTH240) {
7860 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7861 size_t name_pos = label_find_name_pos(fi->rep);
7862 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7863 }
7864 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7865 }
7866 }
7867 }
7868}
7869
7870/* Prepend to text of proto_item after having already been created. */
7871void
7872proto_item_prepend_text(proto_item *pi, const char *format, ...)
7873{
7874 field_info *fi = NULL((void*)0);
7875 size_t pos;
7876 char representation[ITEM_LABEL_LENGTH240];
7877 char *str;
7878 va_list ap;
7879
7880 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7881
7882 fi = PITEM_FINFO(pi)((pi)->finfo);
7883 if (fi == NULL((void*)0)) {
7884 return;
7885 }
7886
7887 if (!proto_item_is_hidden(pi)) {
7888 /*
7889 * If we don't already have a representation,
7890 * generate the default representation.
7891 */
7892 if (fi->rep == NULL((void*)0)) {
7893 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;
;
7894 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7895 } else
7896 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7897
7898 va_start(ap, format)__builtin_va_start(ap, format);
7899 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7900 va_end(ap)__builtin_va_end(ap);
7901 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"
, 7901, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7902 fi->rep->value_pos += strlen(str);
7903 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7904 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, representation, 0);
7905 /* XXX: As above, if the old representation is close to the label
7906 * length, it might already be marked as truncated. */
7907 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7908 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7909 size_t name_pos = label_find_name_pos(fi->rep);
7910 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7911 }
7912 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7913 }
7914}
7915
7916static void
7917finfo_set_len(field_info *fi, const int length)
7918{
7919 int length_remaining;
7920
7921 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", 7921,
"length >= 0", fi->hfinfo->abbrev))))
;
7922 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7923 if (length > length_remaining)
7924 fi->length = length_remaining;
7925 else
7926 fi->length = length;
7927
7928 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7929 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7930 fvalue_set_protocol_length(fi->value, fi->length);
7931 }
7932
7933 /*
7934 * You cannot just make the "len" field of a GByteArray
7935 * larger, if there's no data to back that length;
7936 * you can only make it smaller.
7937 */
7938 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7939 GBytes *bytes = fvalue_get_bytes(fi->value);
7940 size_t size;
7941 const void *data = g_bytes_get_data(bytes, &size);
7942 if ((size_t)fi->length <= size) {
7943 fvalue_set_bytes_data(fi->value, data, fi->length);
7944 }
7945 g_bytes_unref(bytes);
7946 }
7947}
7948
7949void
7950proto_item_set_len(proto_item *pi, const int length)
7951{
7952 field_info *fi;
7953
7954 if (pi == NULL((void*)0))
7955 return;
7956
7957 fi = PITEM_FINFO(pi)((pi)->finfo);
7958 if (fi == NULL((void*)0))
7959 return;
7960
7961 finfo_set_len(fi, length);
7962}
7963
7964/*
7965 * Sets the length of the item based on its start and on the specified
7966 * offset, which is the offset past the end of the item; as the start
7967 * in the item is relative to the beginning of the data source tvbuff,
7968 * we need to pass in a tvbuff - the end offset is relative to the beginning
7969 * of that tvbuff.
7970 */
7971void
7972proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7973{
7974 field_info *fi;
7975 int length;
7976
7977 if (pi == NULL((void*)0))
7978 return;
7979
7980 fi = PITEM_FINFO(pi)((pi)->finfo);
7981 if (fi == NULL((void*)0))
7982 return;
7983
7984 end += tvb_raw_offset(tvb);
7985 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7985, "end >= fi->start"
))))
;
7986 length = end - fi->start;
7987
7988 finfo_set_len(fi, length);
7989}
7990
7991int
7992proto_item_get_len(const proto_item *pi)
7993{
7994 field_info *fi;
7995
7996 if (!pi)
7997 return -1;
7998 fi = PITEM_FINFO(pi)((pi)->finfo);
7999 return fi ? fi->length : -1;
8000}
8001
8002void
8003proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8004 if (!ti) {
8005 return;
8006 }
8007 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)
;
8008 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)
;
8009}
8010
8011char *
8012proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8013{
8014 field_info *fi;
8015
8016 if (!pi)
8017 return wmem_strdup(scope, "");
8018 fi = PITEM_FINFO(pi)((pi)->finfo);
8019 if (!fi)
8020 return wmem_strdup(scope, "");
8021 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8021, "fi->hfinfo != ((void*)0)"
))))
;
8022 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8023}
8024
8025proto_tree *
8026proto_tree_create_root(packet_info *pinfo)
8027{
8028 proto_node *pnode;
8029
8030 /* Initialize the proto_node */
8031 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
8032 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8033 pnode->parent = NULL((void*)0);
8034 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8035 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
8036
8037 /* Make sure we can access pinfo everywhere */
8038 pnode->tree_data->pinfo = pinfo;
8039
8040 /* Don't initialize the tree_data_t. Wait until we know we need it */
8041 pnode->tree_data->interesting_hfids = NULL((void*)0);
8042
8043 /* Set the default to false so it's easier to
8044 * find errors; if we expect to see the protocol tree
8045 * but for some reason the default 'visible' is not
8046 * changed, then we'll find out very quickly. */
8047 pnode->tree_data->visible = false0;
8048
8049 /* Make sure that we fake protocols (if possible) */
8050 pnode->tree_data->fake_protocols = true1;
8051
8052 /* Keep track of the number of children */
8053 pnode->tree_data->count = 0;
8054
8055 /* Initialize our loop checks */
8056 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8057 pnode->tree_data->max_start = 0;
8058 pnode->tree_data->start_idle_count = 0;
8059
8060 return (proto_tree *)pnode;
8061}
8062
8063
8064/* "prime" a proto_tree with a single hfid that a dfilter
8065 * is interested in. */
8066void
8067proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8068{
8069 header_field_info *hfinfo;
8070
8071 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", 8071, __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", 8071, "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", 8071, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8072 /* this field is referenced by a filter so increase the refcount.
8073 also increase the refcount for the parent, i.e the protocol.
8074 Don't increase the refcount if we're already printing the
8075 type, as that is a superset of direct reference.
8076 */
8077 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8078 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8079 }
8080 /* only increase the refcount if there is a parent.
8081 if this is a protocol and not a field then parent will be -1
8082 and there is no parent to add any refcounting for.
8083 */
8084 if (hfinfo->parent != -1) {
8085 header_field_info *parent_hfinfo;
8086 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", 8086
, __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", 8086,
"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", 8086,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8087
8088 /* Mark parent as indirectly referenced unless it is already directly
8089 * referenced, i.e. the user has specified the parent in a filter.
8090 */
8091 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8092 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8093 }
8094}
8095
8096/* "prime" a proto_tree with a single hfid that a dfilter
8097 * is interested in. */
8098void
8099proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8100{
8101 header_field_info *hfinfo;
8102
8103 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", 8103, __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", 8103, "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", 8103, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8104 /* this field is referenced by an (output) filter so increase the refcount.
8105 also increase the refcount for the parent, i.e the protocol.
8106 */
8107 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8108 /* only increase the refcount if there is a parent.
8109 if this is a protocol and not a field then parent will be -1
8110 and there is no parent to add any refcounting for.
8111 */
8112 if (hfinfo->parent != -1) {
8113 header_field_info *parent_hfinfo;
8114 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", 8114
, __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", 8114,
"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", 8114,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8115
8116 /* Mark parent as indirectly referenced unless it is already directly
8117 * referenced, i.e. the user has specified the parent in a filter.
8118 */
8119 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8120 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8121 }
8122}
8123
8124proto_tree *
8125proto_item_add_subtree(proto_item *pi, const int idx) {
8126 field_info *fi;
8127
8128 if (!pi)
8129 return NULL((void*)0);
8130
8131 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", 8131, "idx >= 0 && idx < num_tree_types"
))))
;
8132
8133 fi = PITEM_FINFO(pi)((pi)->finfo);
8134 if (!fi)
8135 return (proto_tree *)pi;
8136
8137 fi->tree_type = idx;
8138
8139 return (proto_tree *)pi;
8140}
8141
8142proto_tree *
8143proto_item_get_subtree(proto_item *pi) {
8144 field_info *fi;
8145
8146 if (!pi)
8147 return NULL((void*)0);
8148 fi = PITEM_FINFO(pi)((pi)->finfo);
8149 if ( (fi) && (fi->tree_type == -1) )
8150 return NULL((void*)0);
8151 return (proto_tree *)pi;
8152}
8153
8154proto_item *
8155proto_item_get_parent(const proto_item *ti) {
8156 if (!ti)
8157 return NULL((void*)0);
8158 return ti->parent;
8159}
8160
8161proto_item *
8162proto_item_get_parent_nth(proto_item *ti, int gen) {
8163 if (!ti)
8164 return NULL((void*)0);
8165 while (gen--) {
8166 ti = ti->parent;
8167 if (!ti)
8168 return NULL((void*)0);
8169 }
8170 return ti;
8171}
8172
8173
8174proto_item *
8175proto_tree_get_parent(proto_tree *tree) {
8176 if (!tree)
8177 return NULL((void*)0);
8178 return (proto_item *)tree;
8179}
8180
8181proto_tree *
8182proto_tree_get_parent_tree(proto_tree *tree) {
8183 if (!tree)
8184 return NULL((void*)0);
8185
8186 /* we're the root tree, there's no parent
8187 return ourselves so the caller has at least a tree to attach to */
8188 if (!tree->parent)
8189 return tree;
8190
8191 return (proto_tree *)tree->parent;
8192}
8193
8194proto_tree *
8195proto_tree_get_root(proto_tree *tree) {
8196 if (!tree)
8197 return NULL((void*)0);
8198 while (tree->parent) {
8199 tree = tree->parent;
8200 }
8201 return tree;
8202}
8203
8204void
8205proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8206 proto_item *item_to_move)
8207{
8208 /* This function doesn't generate any values. It only reorganizes the prococol tree
8209 * so we can bail out immediately if it isn't visible. */
8210 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8211 return;
8212
8213 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", 8213, "item_to_move->parent == tree"
))))
;
8214 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", 8214, "fixed_item->parent == tree"
))))
;
8215
8216 /*** cut item_to_move out ***/
8217
8218 /* is item_to_move the first? */
8219 if (tree->first_child == item_to_move) {
8220 /* simply change first child to next */
8221 tree->first_child = item_to_move->next;
8222
8223 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", 8223, "tree->last_child != item_to_move"
))))
;
8224 } else {
8225 proto_item *curr_item;
8226 /* find previous and change it's next */
8227 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8228 if (curr_item->next == item_to_move) {
8229 break;
8230 }
8231 }
8232
8233 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8233, "curr_item"
))))
;
8234
8235 curr_item->next = item_to_move->next;
8236
8237 /* fix last_child if required */
8238 if (tree->last_child == item_to_move) {
8239 tree->last_child = curr_item;
8240 }
8241 }
8242
8243 /*** insert to_move after fixed ***/
8244 item_to_move->next = fixed_item->next;
8245 fixed_item->next = item_to_move;
8246 if (tree->last_child == fixed_item) {
8247 tree->last_child = item_to_move;
8248 }
8249}
8250
8251void
8252proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8253 const int length)
8254{
8255 field_info *fi;
8256
8257 if (tree == NULL((void*)0))
8258 return;
8259
8260 fi = PTREE_FINFO(tree)((tree)->finfo);
8261 if (fi == NULL((void*)0))
8262 return;
8263
8264 start += tvb_raw_offset(tvb);
8265 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8265, "start >= 0"
))))
;
8266 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8266, "length >= 0"
))))
;
8267
8268 fi->appendix_start = start;
8269 fi->appendix_length = length;
8270}
8271
8272static void
8273check_protocol_filter_name_or_fail(const char *filter_name)
8274{
8275 /* Require at least two characters. */
8276 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8277 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)
;
8278 }
8279
8280 if (proto_check_field_name(filter_name) != '\0') {
8281 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)
8282 " 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)
8283 " 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)
;
8284 }
8285
8286 /* Check that it doesn't match some very common numeric forms. */
8287 if (filter_name[0] == '0' &&
8288 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8289 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8290 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])
8291 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])
;
8292 }
8293
8294 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8295
8296 /* Check that it contains at least one letter. */
8297 bool_Bool have_letter = false0;
8298 for (const char *s = filter_name; *s != '\0'; s++) {
8299 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8300 have_letter = true1;
8301 break;
8302 }
8303 }
8304 if (!have_letter) {
8305 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)
8306 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8307 }
8308
8309 /* Check for reserved keywords. */
8310 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8311 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)
8312 " 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)
;
8313 }
8314}
8315
8316int
8317proto_register_protocol(const char *name, const char *short_name,
8318 const char *filter_name)
8319{
8320 protocol_t *protocol;
8321 header_field_info *hfinfo;
8322
8323 check_protocol_filter_name_or_fail(filter_name);
8324
8325 /*
8326 * Add this protocol to the list of known protocols;
8327 * the list is sorted by protocol short name.
8328 */
8329 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8330 protocol->name = name;
8331 protocol->short_name = short_name;
8332 protocol->filter_name = filter_name;
8333 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8334 protocol->is_enabled = true1; /* protocol is enabled by default */
8335 protocol->enabled_by_default = true1; /* see previous comment */
8336 protocol->can_toggle = true1;
8337 protocol->parent_proto_id = -1;
8338 protocol->heur_list = NULL((void*)0);
8339
8340 /* List will be sorted later by name, when all protocols completed registering */
8341 protocols = g_list_prepend(protocols, protocol);
8342 /*
8343 * Make sure there's not already a protocol with any of those
8344 * names. Crash if there is, as that's an error in the code
8345 * or an inappropriate plugin.
8346 * This situation has to be fixed to not register more than one
8347 * protocol with the same name.
8348 */
8349 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8350 /* ws_error will terminate the program */
8351 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)
8352 " 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)
;
8353 }
8354 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8355 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)
8356 " 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)
;
8357 }
8358 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8359 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)
8360 " 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)
;
8361 }
8362
8363 /* Here we allocate a new header_field_info struct */
8364 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8365 hfinfo->name = name;
8366 hfinfo->abbrev = filter_name;
8367 hfinfo->type = FT_PROTOCOL;
8368 hfinfo->display = BASE_NONE;
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
8379int
8380proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8381{
8382 protocol_t *protocol;
8383 header_field_info *hfinfo;
8384
8385 /*
8386 * Helper protocols don't need the strict rules as a "regular" protocol
8387 * Just register it in a list and make a hf_ field from it
8388 */
8389 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8390 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)
;
8391 }
8392
8393 if (parent_proto <= 0) {
8394 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)
8395 " 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)
;
8396 }
8397
8398 check_protocol_filter_name_or_fail(filter_name);
8399
8400 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8401 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8402 protocol->name = name;
8403 protocol->short_name = short_name;
8404 protocol->filter_name = filter_name;
8405 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8406
8407 /* Enabling and toggling is really determined by parent protocol,
8408 but provide default values here */
8409 protocol->is_enabled = true1;
8410 protocol->enabled_by_default = true1;
8411 protocol->can_toggle = true1;
8412
8413 protocol->parent_proto_id = parent_proto;
8414 protocol->heur_list = NULL((void*)0);
8415
8416 /* List will be sorted later by name, when all protocols completed registering */
8417 protocols = g_list_prepend(protocols, protocol);
8418
8419 /* Here we allocate a new header_field_info struct */
8420 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8421 hfinfo->name = name;
8422 hfinfo->abbrev = filter_name;
8423 hfinfo->type = field_type;
8424 hfinfo->display = BASE_NONE;
8425 if (field_type == FT_BYTES) {
8426 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8427 }
8428 hfinfo->strings = protocol;
8429 hfinfo->bitmask = 0;
8430 hfinfo->ref_type = HF_REF_TYPE_NONE;
8431 hfinfo->blurb = NULL((void*)0);
8432 hfinfo->parent = -1; /* This field differentiates protos and fields */
8433
8434 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8435 return protocol->proto_id;
8436}
8437
8438bool_Bool
8439proto_deregister_protocol(const char *short_name)
8440{
8441 protocol_t *protocol;
8442 header_field_info *hfinfo;
8443 int proto_id;
8444 unsigned i;
8445
8446 proto_id = proto_get_id_by_short_name(short_name);
8447 protocol = find_protocol_by_id(proto_id);
8448 if (protocol == NULL((void*)0))
8449 return false0;
8450
8451 g_hash_table_remove(proto_names, protocol->name);
8452 g_hash_table_remove(proto_short_names, (void *)short_name);
8453 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8454
8455 if (protocol->fields) {
8456 for (i = 0; i < protocol->fields->len; i++) {
8457 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8458 hfinfo_remove_from_gpa_name_map(hfinfo);
8459 expert_deregister_expertinfo(hfinfo->abbrev);
8460 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8461 }
8462 g_ptr_array_free(protocol->fields, true1);
8463 protocol->fields = NULL((void*)0);
8464 }
8465
8466 g_list_free(protocol->heur_list);
8467
8468 /* Remove this protocol from the list of known protocols */
8469 protocols = g_list_remove(protocols, protocol);
8470
8471 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8472 wmem_map_remove(gpa_name_map, protocol->filter_name);
8473
8474 g_free(last_field_name);
8475 last_field_name = NULL((void*)0);
8476
8477 return true1;
8478}
8479
8480void
8481proto_register_alias(const int proto_id, const char *alias_name)
8482{
8483 protocol_t *protocol;
8484
8485 protocol = find_protocol_by_id(proto_id);
8486 if (alias_name && protocol) {
8487 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8488 }
8489}
8490
8491/*
8492 * Routines to use to iterate over the protocols.
8493 * The argument passed to the iterator routines is an opaque cookie to
8494 * their callers; it's the GList pointer for the current element in
8495 * the list.
8496 * The ID of the protocol is returned, or -1 if there is no protocol.
8497 */
8498int
8499proto_get_first_protocol(void **cookie)
8500{
8501 protocol_t *protocol;
8502
8503 if (protocols == NULL((void*)0))
8504 return -1;
8505 *cookie = protocols;
8506 protocol = (protocol_t *)protocols->data;
8507 return protocol->proto_id;
8508}
8509
8510int
8511proto_get_data_protocol(void *cookie)
8512{
8513 GList *list_item = (GList *)cookie;
8514
8515 protocol_t *protocol = (protocol_t *)list_item->data;
8516 return protocol->proto_id;
8517}
8518
8519int
8520proto_get_next_protocol(void **cookie)
8521{
8522 GList *list_item = (GList *)*cookie;
8523 protocol_t *protocol;
8524
8525 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8526 if (list_item == NULL((void*)0))
8527 return -1;
8528 *cookie = list_item;
8529 protocol = (protocol_t *)list_item->data;
8530 return protocol->proto_id;
8531}
8532
8533header_field_info *
8534proto_get_first_protocol_field(const int proto_id, void **cookie)
8535{
8536 protocol_t *protocol = find_protocol_by_id(proto_id);
8537
8538 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8539 return NULL((void*)0);
8540
8541 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8542 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8543}
8544
8545header_field_info *
8546proto_get_next_protocol_field(const int proto_id, void **cookie)
8547{
8548 protocol_t *protocol = find_protocol_by_id(proto_id);
8549 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8550
8551 i++;
8552
8553 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8554 return NULL((void*)0);
8555
8556 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8557 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8558}
8559
8560protocol_t *
8561find_protocol_by_id(const int proto_id)
8562{
8563 header_field_info *hfinfo;
8564
8565 if (proto_id <= 0)
8566 return NULL((void*)0);
8567
8568 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", 8568, __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", 8568,
"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", 8568, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8569 if (hfinfo->type != FT_PROTOCOL) {
8570 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", 8570, "hfinfo->display & 0x00004000"
))))
;
8571 }
8572 return (protocol_t *)hfinfo->strings;
8573}
8574
8575int
8576proto_get_id(const protocol_t *protocol)
8577{
8578 return protocol->proto_id;
8579}
8580
8581bool_Bool
8582proto_name_already_registered(const char *name)
8583{
8584 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8584, "name", "No name present"))))
;
8585
8586 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8587 return true1;
8588 return false0;
8589}
8590
8591int
8592proto_get_id_by_filter_name(const char *filter_name)
8593{
8594 const protocol_t *protocol = NULL((void*)0);
8595
8596 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", 8596,
"filter_name", "No filter name present"))))
;
8597
8598 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8599
8600 if (protocol == NULL((void*)0))
8601 return -1;
8602 return protocol->proto_id;
8603}
8604
8605int
8606proto_get_id_by_short_name(const char *short_name)
8607{
8608 const protocol_t *protocol = NULL((void*)0);
8609
8610 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", 8610,
"short_name", "No short name present"))))
;
8611
8612 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8613
8614 if (protocol == NULL((void*)0))
8615 return -1;
8616 return protocol->proto_id;
8617}
8618
8619const char *
8620proto_get_protocol_name(const int proto_id)
8621{
8622 protocol_t *protocol;
8623
8624 protocol = find_protocol_by_id(proto_id);
8625
8626 if (protocol == NULL((void*)0))
8627 return NULL((void*)0);
8628 return protocol->name;
8629}
8630
8631const char *
8632proto_get_protocol_short_name(const protocol_t *protocol)
8633{
8634 if (protocol == NULL((void*)0))
8635 return "(none)";
8636 return protocol->short_name;
8637}
8638
8639const char *
8640proto_get_protocol_long_name(const protocol_t *protocol)
8641{
8642 if (protocol == NULL((void*)0))
8643 return "(none)";
8644 return protocol->name;
8645}
8646
8647const char *
8648proto_get_protocol_filter_name(const int proto_id)
8649{
8650 protocol_t *protocol;
8651
8652 protocol = find_protocol_by_id(proto_id);
8653 if (protocol == NULL((void*)0))
8654 return "(none)";
8655 return protocol->filter_name;
8656}
8657
8658void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8659{
8660 heur_dtbl_entry_t* heuristic_dissector;
8661
8662 if (protocol == NULL((void*)0))
8663 return;
8664
8665 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8666 if (heuristic_dissector != NULL((void*)0))
8667 {
8668 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8669 }
8670}
8671
8672void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8673{
8674 if (protocol == NULL((void*)0))
8675 return;
8676
8677 g_list_foreach(protocol->heur_list, func, user_data);
8678}
8679
8680void
8681proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8682 bool_Bool *is_tcp, bool_Bool *is_udp,
8683 bool_Bool *is_sctp, bool_Bool *is_tls,
8684 bool_Bool *is_rtp,
8685 bool_Bool *is_lte_rlc)
8686{
8687 wmem_list_frame_t *protos = wmem_list_head(layers);
8688 int proto_id;
8689 const char *proto_name;
8690
8691 /* Walk the list of a available protocols in the packet and
8692 attempt to find "major" ones. */
8693 /* It might make more sense to assemble and return a bitfield. */
8694 while (protos != NULL((void*)0))
8695 {
8696 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8697 proto_name = proto_get_protocol_filter_name(proto_id);
8698
8699 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8700 (!strcmp(proto_name, "ipv6")))) {
8701 *is_ip = true1;
8702 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8703 *is_tcp = true1;
8704 } else if (is_udp && !strcmp(proto_name, "udp")) {
8705 *is_udp = true1;
8706 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8707 *is_sctp = true1;
8708 } else if (is_tls && !strcmp(proto_name, "tls")) {
8709 *is_tls = true1;
8710 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8711 *is_rtp = true1;
8712 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8713 *is_lte_rlc = true1;
8714 }
8715
8716 protos = wmem_list_frame_next(protos);
8717 }
8718}
8719
8720bool_Bool
8721proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8722{
8723 wmem_list_frame_t *protos = wmem_list_head(layers);
8724 int proto_id;
8725 const char *name;
8726
8727 /* Walk the list of a available protocols in the packet and
8728 attempt to find the specified protocol. */
8729 while (protos != NULL((void*)0))
8730 {
8731 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8732 name = proto_get_protocol_filter_name(proto_id);
8733
8734 if (!strcmp(name, proto_name))
8735 {
8736 return true1;
8737 }
8738
8739 protos = wmem_list_frame_next(protos);
8740 }
8741
8742 return false0;
8743}
8744
8745char *
8746proto_list_layers(const packet_info *pinfo)
8747{
8748 wmem_strbuf_t *buf;
8749 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8750
8751 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8752
8753 /* Walk the list of layers in the packet and
8754 return a string of all entries. */
8755 while (layers != NULL((void*)0))
8756 {
8757 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8758
8759 layers = wmem_list_frame_next(layers);
8760 if (layers != NULL((void*)0)) {
8761 wmem_strbuf_append_c(buf, ':');
8762 }
8763 }
8764
8765 return wmem_strbuf_finalize(buf);
8766}
8767
8768uint8_t
8769proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8770{
8771 int *proto_layer_num_ptr;
8772
8773 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8774 if (proto_layer_num_ptr == NULL((void*)0)) {
8775 return 0;
8776 }
8777
8778 return (uint8_t)*proto_layer_num_ptr;
8779}
8780
8781bool_Bool
8782proto_is_pino(const protocol_t *protocol)
8783{
8784 return (protocol->parent_proto_id != -1);
8785}
8786
8787bool_Bool
8788// NOLINTNEXTLINE(misc-no-recursion)
8789proto_is_protocol_enabled(const protocol_t *protocol)
8790{
8791 if (protocol == NULL((void*)0))
8792 return false0;
8793
8794 //parent protocol determines enable/disable for helper dissectors
8795 if (proto_is_pino(protocol))
8796 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8797
8798 return protocol->is_enabled;
8799}
8800
8801bool_Bool
8802// NOLINTNEXTLINE(misc-no-recursion)
8803proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8804{
8805 //parent protocol determines enable/disable for helper dissectors
8806 if (proto_is_pino(protocol))
8807 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8808
8809 return protocol->enabled_by_default;
8810}
8811
8812bool_Bool
8813// NOLINTNEXTLINE(misc-no-recursion)
8814proto_can_toggle_protocol(const int proto_id)
8815{
8816 protocol_t *protocol;
8817
8818 protocol = find_protocol_by_id(proto_id);
8819 //parent protocol determines toggling for helper dissectors
8820 if (proto_is_pino(protocol))
8821 return proto_can_toggle_protocol(protocol->parent_proto_id);
8822
8823 return protocol->can_toggle;
8824}
8825
8826void
8827proto_disable_by_default(const int proto_id)
8828{
8829 protocol_t *protocol;
8830
8831 protocol = find_protocol_by_id(proto_id);
8832 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8832, "protocol->can_toggle"
))))
;
8833 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", 8833, "proto_is_pino(protocol) == 0"
))))
;
8834 protocol->is_enabled = false0;
8835 protocol->enabled_by_default = false0;
8836}
8837
8838void
8839proto_set_decoding(const int proto_id, const bool_Bool enabled)
8840{
8841 protocol_t *protocol;
8842
8843 protocol = find_protocol_by_id(proto_id);
8844 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8844, "protocol->can_toggle"
))))
;
8845 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", 8845, "proto_is_pino(protocol) == 0"
))))
;
8846 protocol->is_enabled = enabled;
8847}
8848
8849void
8850proto_disable_all(void)
8851{
8852 /* This doesn't explicitly disable heuristic protocols,
8853 * but the heuristic doesn't get called if the parent
8854 * protocol isn't enabled.
8855 */
8856 protocol_t *protocol;
8857 GList *list_item = protocols;
8858
8859 if (protocols == NULL((void*)0))
8860 return;
8861
8862 while (list_item) {
8863 protocol = (protocol_t *)list_item->data;
8864 if (protocol->can_toggle) {
8865 protocol->is_enabled = false0;
8866 }
8867 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8868 }
8869}
8870
8871static void
8872heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8873{
8874 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8875
8876 heur->enabled = heur->enabled_by_default;
8877}
8878
8879void
8880proto_reenable_all(void)
8881{
8882 protocol_t *protocol;
8883 GList *list_item = protocols;
8884
8885 if (protocols == NULL((void*)0))
8886 return;
8887
8888 while (list_item) {
8889 protocol = (protocol_t *)list_item->data;
8890 if (protocol->can_toggle)
8891 protocol->is_enabled = protocol->enabled_by_default;
8892 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8893 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8894 }
8895}
8896
8897void
8898proto_set_cant_toggle(const int proto_id)
8899{
8900 protocol_t *protocol;
8901
8902 protocol = find_protocol_by_id(proto_id);
8903 protocol->can_toggle = false0;
8904}
8905
8906static int
8907proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8908{
8909 g_ptr_array_add(proto->fields, hfi);
8910
8911 return proto_register_field_init(hfi, parent);
8912}
8913
8914/* for use with static arrays only, since we don't allocate our own copies
8915of the header_field_info struct contained within the hf_register_info struct */
8916void
8917proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8918{
8919 hf_register_info *ptr = hf;
8920 protocol_t *proto;
8921 int i;
8922
8923 proto = find_protocol_by_id(parent);
8924
8925 /* if (proto == NULL) - error or return? */
8926
8927 if (proto->fields == NULL((void*)0)) {
8928 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
8929 * GLib introduced g_ptr_array_new_from_array, which might have
8930 * given a reason to actually use it. (#17774)
8931 */
8932 proto->fields = g_ptr_array_sized_new(num_records);
8933 }
8934
8935 for (i = 0; i < num_records; i++, ptr++) {
8936 /*
8937 * Make sure we haven't registered this yet.
8938 * Most fields have variables associated with them that
8939 * are initialized to 0; some are initialized to -1 (which
8940 * was the standard before 4.4).
8941 *
8942 * XXX - Since this is called almost 300000 times at startup,
8943 * it might be nice to compare to only 0 and require
8944 * dissectors to pass in zero for unregistered fields.
8945 */
8946 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8947 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8948 "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)
8949 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8950 return;
8951 }
8952
8953 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8954 }
8955}
8956
8957/* deregister already registered fields */
8958void
8959proto_deregister_field (const int parent, int hf_id)
8960{
8961 header_field_info *hfi;
8962 protocol_t *proto;
8963 unsigned i;
8964
8965 g_free(last_field_name);
8966 last_field_name = NULL((void*)0);
8967
8968 if (hf_id == -1 || hf_id == 0)
8969 return;
8970
8971 proto = find_protocol_by_id (parent);
8972 if (!proto || proto->fields == NULL((void*)0)) {
8973 return;
8974 }
8975
8976 for (i = 0; i < proto->fields->len; i++) {
8977 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8978 if (hfi->id == hf_id) {
8979 /* Found the hf_id in this protocol */
8980 wmem_map_remove(gpa_name_map, hfi->abbrev);
8981 g_ptr_array_remove_index_fast(proto->fields, i);
8982 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8983 return;
8984 }
8985 }
8986}
8987
8988/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
8989void
8990proto_deregister_all_fields_with_prefix(const int parent, const gchar *prefix)
8991{
8992 header_field_info *hfinfo;
8993 protocol_t *proto;
8994
8995 g_free(last_field_name);
8996 last_field_name = NULL((void*)0);
8997
8998 proto = find_protocol_by_id(parent);
8999 if (proto && proto->fields && proto->fields->len > 0) {
9000 guint i = proto->fields->len;
9001 do {
9002 i--;
9003
9004 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9005 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) )
) {
9006 hfinfo_remove_from_gpa_name_map(hfinfo);
9007 expert_deregister_expertinfo(hfinfo->abbrev);
9008 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9009 g_ptr_array_remove_index_fast(proto->fields, i);
9010 }
9011 } while (i > 0);
9012 }
9013}
9014
9015void
9016proto_add_deregistered_data (void *data)
9017{
9018 g_ptr_array_add(deregistered_data, data);
9019}
9020
9021void
9022proto_add_deregistered_slice (size_t block_size, void *mem_block)
9023{
9024 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
)))
;
9025
9026 slice_data->block_size = block_size;
9027 slice_data->mem_block = mem_block;
9028
9029 g_ptr_array_add(deregistered_slice, slice_data);
9030}
9031
9032void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9033{
9034 if (field_strings == NULL((void*)0)) {
9035 return;
9036 }
9037
9038 switch (field_type) {
9039 case FT_FRAMENUM:
9040 /* This is just an integer represented as a pointer */
9041 break;
9042 case FT_PROTOCOL: {
9043 protocol_t *protocol = (protocol_t *)field_strings;
9044 g_free((char *)protocol->short_name);
9045 break;
9046 }
9047 case FT_BOOLEAN: {
9048 true_false_string *tf = (true_false_string *)field_strings;
9049 g_free((char *)tf->true_string);
9050 g_free((char *)tf->false_string);
9051 break;
9052 }
9053 case FT_UINT40:
9054 case FT_INT40:
9055 case FT_UINT48:
9056 case FT_INT48:
9057 case FT_UINT56:
9058 case FT_INT56:
9059 case FT_UINT64:
9060 case FT_INT64: {
9061 if (field_display & BASE_UNIT_STRING0x00001000) {
9062 unit_name_string *unit = (unit_name_string *)field_strings;
9063 g_free((char *)unit->singular);
9064 g_free((char *)unit->plural);
9065 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9066 range_string *rs = (range_string *)field_strings;
9067 while (rs->strptr) {
9068 g_free((char *)rs->strptr);
9069 rs++;
9070 }
9071 } else if (field_display & BASE_EXT_STRING0x00000200) {
9072 val64_string_ext *vse = (val64_string_ext *)field_strings;
9073 val64_string *vs = (val64_string *)vse->_vs_p;
9074 while (vs->strptr) {
9075 g_free((char *)vs->strptr);
9076 vs++;
9077 }
9078 val64_string_ext_free(vse);
9079 field_strings = NULL((void*)0);
9080 } else if (field_display == BASE_CUSTOM) {
9081 /* this will be a pointer to a function, don't free that */
9082 field_strings = NULL((void*)0);
9083 } else {
9084 val64_string *vs64 = (val64_string *)field_strings;
9085 while (vs64->strptr) {
9086 g_free((char *)vs64->strptr);
9087 vs64++;
9088 }
9089 }
9090 break;
9091 }
9092 case FT_CHAR:
9093 case FT_UINT8:
9094 case FT_INT8:
9095 case FT_UINT16:
9096 case FT_INT16:
9097 case FT_UINT24:
9098 case FT_INT24:
9099 case FT_UINT32:
9100 case FT_INT32:
9101 case FT_FLOAT:
9102 case FT_DOUBLE: {
9103 if (field_display & BASE_UNIT_STRING0x00001000) {
9104 unit_name_string *unit = (unit_name_string *)field_strings;
9105 g_free((char *)unit->singular);
9106 g_free((char *)unit->plural);
9107 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9108 range_string *rs = (range_string *)field_strings;
9109 while (rs->strptr) {
9110 g_free((char *)rs->strptr);
9111 rs++;
9112 }
9113 } else if (field_display & BASE_EXT_STRING0x00000200) {
9114 value_string_ext *vse = (value_string_ext *)field_strings;
9115 value_string *vs = (value_string *)vse->_vs_p;
9116 while (vs->strptr) {
9117 g_free((char *)vs->strptr);
9118 vs++;
9119 }
9120 value_string_ext_free(vse);
9121 field_strings = NULL((void*)0);
9122 } else if (field_display == BASE_CUSTOM) {
9123 /* this will be a pointer to a function, don't free that */
9124 field_strings = NULL((void*)0);
9125 } else {
9126 value_string *vs = (value_string *)field_strings;
9127 while (vs->strptr) {
9128 g_free((char *)vs->strptr);
9129 vs++;
9130 }
9131 }
9132 break;
9133 default:
9134 break;
9135 }
9136 }
9137
9138 if (field_type != FT_FRAMENUM) {
9139 g_free((void *)field_strings);
9140 }
9141}
9142
9143static void
9144free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9145{
9146 header_field_info *hfi = (header_field_info *) data;
9147 int hf_id = hfi->id;
9148
9149 g_free((char *)hfi->name);
9150 g_free((char *)hfi->abbrev);
9151 g_free((char *)hfi->blurb);
9152
9153 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9154
9155 if (hfi->parent == -1)
9156 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)
;
9157
9158 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9159}
9160
9161static void
9162free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9163{
9164 g_free (data);
9165}
9166
9167static void
9168free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9169{
9170 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9171
9172 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9173 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)
;
9174}
9175
9176/* free deregistered fields and data */
9177void
9178proto_free_deregistered_fields (void)
9179{
9180 expert_free_deregistered_expertinfos();
9181
9182 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9183 g_ptr_array_free(deregistered_fields, true1);
9184 deregistered_fields = g_ptr_array_new();
9185
9186 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9187 g_ptr_array_free(deregistered_data, true1);
9188 deregistered_data = g_ptr_array_new();
9189
9190 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9191 g_ptr_array_free(deregistered_slice, true1);
9192 deregistered_slice = g_ptr_array_new();
9193}
9194
9195static const value_string hf_display[] = {
9196 { BASE_NONE, "BASE_NONE" },
9197 { BASE_DEC, "BASE_DEC" },
9198 { BASE_HEX, "BASE_HEX" },
9199 { BASE_OCT, "BASE_OCT" },
9200 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9201 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9202 { BASE_CUSTOM, "BASE_CUSTOM" },
9203 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9204 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9205 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9206 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9207 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9208 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9209 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9210 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9211 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9212 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9213 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9214 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9215 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9216 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9217 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9218 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9219 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9220 { BASE_PT_UDP, "BASE_PT_UDP" },
9221 { BASE_PT_TCP, "BASE_PT_TCP" },
9222 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9223 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9224 { BASE_OUI, "BASE_OUI" },
9225 { 0, NULL((void*)0) } };
9226
9227const char* proto_field_display_to_string(int field_display)
9228{
9229 return val_to_str_const(field_display, hf_display, "Unknown");
9230}
9231
9232static inline port_type
9233display_to_port_type(field_display_e e)
9234{
9235 switch (e) {
9236 case BASE_PT_UDP:
9237 return PT_UDP;
9238 case BASE_PT_TCP:
9239 return PT_TCP;
9240 case BASE_PT_DCCP:
9241 return PT_DCCP;
9242 case BASE_PT_SCTP:
9243 return PT_SCTP;
9244 default:
9245 break;
9246 }
9247 return PT_NONE;
9248}
9249
9250/* temporary function containing assert part for easier profiling */
9251static void
9252tmp_fld_check_assert(header_field_info *hfinfo)
9253{
9254 char* tmp_str;
9255
9256 /* The field must have a name (with length > 0) */
9257 if (!hfinfo->name || !hfinfo->name[0]) {
9258 if (hfinfo->abbrev)
9259 /* Try to identify the field */
9260 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)
9261 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9262 else
9263 /* Hum, no luck */
9264 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)"
)
;
9265 }
9266
9267 /* fields with an empty string for an abbreviation aren't filterable */
9268 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9269 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)
;
9270
9271 /* TODO: This check is a significant percentage of startup time (~10%),
9272 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9273 It might be nice to have a way to disable this check when, e.g.,
9274 running TShark many times with the same configuration. */
9275 /* Check that the filter name (abbreviation) is legal;
9276 * it must contain only alphanumerics, '-', "_", and ".". */
9277 unsigned char c;
9278 c = module_check_valid_name(hfinfo->abbrev, false0);
9279 if (c) {
9280 if (c == '.') {
9281 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)
;
9282 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9283 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)
;
9284 } else {
9285 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)
;
9286 }
9287 }
9288
9289 /* These types of fields are allowed to have value_strings,
9290 * true_false_strings or a protocol_t struct
9291 */
9292 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9293 switch (hfinfo->type) {
9294
9295 /*
9296 * These types are allowed to support display value_strings,
9297 * value64_strings, the extended versions of the previous
9298 * two, range strings, or unit strings.
9299 */
9300 case FT_CHAR:
9301 case FT_UINT8:
9302 case FT_UINT16:
9303 case FT_UINT24:
9304 case FT_UINT32:
9305 case FT_UINT40:
9306 case FT_UINT48:
9307 case FT_UINT56:
9308 case FT_UINT64:
9309 case FT_INT8:
9310 case FT_INT16:
9311 case FT_INT24:
9312 case FT_INT32:
9313 case FT_INT40:
9314 case FT_INT48:
9315 case FT_INT56:
9316 case FT_INT64:
9317 case FT_BOOLEAN:
9318 case FT_PROTOCOL:
9319 break;
9320
9321 /*
9322 * This is allowed to have a value of type
9323 * enum ft_framenum_type to indicate what relationship
9324 * the frame in question has to the frame in which
9325 * the field is put.
9326 */
9327 case FT_FRAMENUM:
9328 break;
9329
9330 /*
9331 * These types are allowed to support only unit strings.
9332 */
9333 case FT_FLOAT:
9334 case FT_DOUBLE:
9335 case FT_IEEE_11073_SFLOAT:
9336 case FT_IEEE_11073_FLOAT:
9337 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9338 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))
9339 " (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))
9340 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))
;
9341 }
9342 break;
9343
9344 /*
9345 * These types are allowed to support display
9346 * time_value_strings.
9347 */
9348 case FT_ABSOLUTE_TIME:
9349 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9350 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9351 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9352 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9353 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))
9354 " (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))
9355 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))
;
9356 }
9357 break;
9358
9359 /*
9360 * This type is only allowed to support a string if it's
9361 * a protocol (for pinos).
9362 */
9363 case FT_BYTES:
9364 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9365 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))
9366 " (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))
9367 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))
;
9368 }
9369 break;
9370
9371 default:
9372 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))
9373 " (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))
9374 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))
;
9375 }
9376 }
9377
9378 /* TODO: This check may slow down startup, and output quite a few warnings.
9379 It would be good to be able to enable this (and possibly other checks?)
9380 in non-release builds. */
9381#ifdef ENABLE_CHECK_FILTER
9382 /* Check for duplicate value_string values.
9383 There are lots that have the same value *and* string, so for now only
9384 report those that have same value but different string. */
9385 if ((hfinfo->strings != NULL((void*)0)) &&
9386 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9387 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9388 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9389 (
9390 (hfinfo->type == FT_CHAR) ||
9391 (hfinfo->type == FT_UINT8) ||
9392 (hfinfo->type == FT_UINT16) ||
9393 (hfinfo->type == FT_UINT24) ||
9394 (hfinfo->type == FT_UINT32) ||
9395 (hfinfo->type == FT_INT8) ||
9396 (hfinfo->type == FT_INT16) ||
9397 (hfinfo->type == FT_INT24) ||
9398 (hfinfo->type == FT_INT32) )) {
9399
9400 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9401 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9402 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9403 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9404 } else {
9405 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9406 CHECK_HF_VALUE(value_string, "u", start_values);
9407 }
9408 } else {
9409 const value_string *start_values = (const value_string*)hfinfo->strings;
9410 CHECK_HF_VALUE(value_string, "u", start_values);
9411 }
9412 }
9413
9414 if (hfinfo->type == FT_BOOLEAN) {
9415 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9416 if (tfs) {
9417 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9418 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"
, 9420, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9419 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9420, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9420 tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9420, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
;
9421 }
9422 }
9423 }
9424
9425 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9426 const range_string *rs = (const range_string*)(hfinfo->strings);
9427 if (rs) {
9428 const range_string *this_it = rs;
9429
9430 do {
9431 if (this_it->value_max < this_it->value_min) {
9432 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"
, 9436, __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)
9433 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9436, __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)
9434 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9436, __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)
9435 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9436, __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)
9436 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9436, __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)
;
9437 ++this_it;
9438 continue;
9439 }
9440
9441 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9442 /* Not OK if this one is completely hidden by an earlier one! */
9443 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9444 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"
, 9450, __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)
9445 "(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"
, 9450, __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)
9446 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9450, __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)
9447 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9450, __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)
9448 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9450, __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)
9449 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9450, __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)
9450 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9450, __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)
;
9451 }
9452 }
9453 ++this_it;
9454 } while (this_it->strptr);
9455 }
9456 }
9457#endif
9458
9459 switch (hfinfo->type) {
9460
9461 case FT_CHAR:
9462 /* Require the char type to have BASE_HEX, BASE_OCT,
9463 * BASE_CUSTOM, or BASE_NONE as its base.
9464 *
9465 * If the display value is BASE_NONE and there is a
9466 * strings conversion then the dissector writer is
9467 * telling us that the field's numerical value is
9468 * meaningless; we'll avoid showing the value to the
9469 * user.
9470 */
9471 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9472 case BASE_HEX:
9473 case BASE_OCT:
9474 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9475 break;
9476 case BASE_NONE:
9477 if (hfinfo->strings == NULL((void*)0))
9478 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
))
9479 " 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
))
9480 " 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
))
9481 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
))
9482 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
))
;
9483 break;
9484 default:
9485 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9486 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)
9487 " 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)
9488 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)
9489 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)
;
9490 //wmem_free(NULL, tmp_str);
9491 }
9492 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9493 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
))
9494 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
))
9495 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
))
;
9496 }
9497 break;
9498 case FT_INT8:
9499 case FT_INT16:
9500 case FT_INT24:
9501 case FT_INT32:
9502 case FT_INT40:
9503 case FT_INT48:
9504 case FT_INT56:
9505 case FT_INT64:
9506 /* Hexadecimal and octal are, in printf() and everywhere
9507 * else, unsigned so don't allow dissectors to register a
9508 * signed field to be displayed unsigned. (Else how would
9509 * we display negative values?)
9510 */
9511 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9512 case BASE_HEX:
9513 case BASE_OCT:
9514 case BASE_DEC_HEX:
9515 case BASE_HEX_DEC:
9516 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9517 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)
9518 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)
9519 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)
;
9520 //wmem_free(NULL, tmp_str);
9521 }
9522 /* FALL THROUGH */
9523 case FT_UINT8:
9524 case FT_UINT16:
9525 case FT_UINT24:
9526 case FT_UINT32:
9527 case FT_UINT40:
9528 case FT_UINT48:
9529 case FT_UINT56:
9530 case FT_UINT64:
9531 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
))
) {
9532 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9533 if (hfinfo->type != FT_UINT16) {
9534 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))
9535 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))
9536 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))
;
9537 }
9538 if (hfinfo->strings != NULL((void*)0)) {
9539 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)
9540 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)
9541 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)
;
9542 }
9543 if (hfinfo->bitmask != 0) {
9544 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)
9545 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)
9546 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)
;
9547 }
9548 wmem_free(NULL((void*)0), tmp_str);
9549 break;
9550 }
9551
9552 if (hfinfo->display == BASE_OUI) {
9553 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9554 if (hfinfo->type != FT_UINT24) {
9555 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))
9556 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))
9557 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))
;
9558 }
9559 if (hfinfo->strings != NULL((void*)0)) {
9560 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)
9561 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)
9562 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)
;
9563 }
9564 if (hfinfo->bitmask != 0) {
9565 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)
9566 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)
9567 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)
;
9568 }
9569 wmem_free(NULL((void*)0), tmp_str);
9570 break;
9571 }
9572
9573 /* Require integral types (other than frame number,
9574 * which is always displayed in decimal) to have a
9575 * number base.
9576 *
9577 * If the display value is BASE_NONE and there is a
9578 * strings conversion then the dissector writer is
9579 * telling us that the field's numerical value is
9580 * meaningless; we'll avoid showing the value to the
9581 * user.
9582 */
9583 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9584 case BASE_DEC:
9585 case BASE_HEX:
9586 case BASE_OCT:
9587 case BASE_DEC_HEX:
9588 case BASE_HEX_DEC:
9589 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9590 break;
9591 case BASE_NONE:
9592 if (hfinfo->strings == NULL((void*)0)) {
9593 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
))
9594 " 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
))
9595 " 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
))
9596 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
))
9597 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
))
;
9598 }
9599 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9600 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
))
9601 " 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
))
9602 " 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
))
9603 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
))
9604 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
))
;
9605 }
9606 break;
9607
9608 default:
9609 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9610 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)
9611 " 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)
9612 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)
9613 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)
;
9614 //wmem_free(NULL, tmp_str);
9615 }
9616 break;
9617 case FT_BYTES:
9618 case FT_UINT_BYTES:
9619 /* Require bytes to have a "display type" that could
9620 * add a character between displayed bytes.
9621 */
9622 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9623 case BASE_NONE:
9624 case SEP_DOT:
9625 case SEP_DASH:
9626 case SEP_COLON:
9627 case SEP_SPACE:
9628 break;
9629 default:
9630 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9631 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)
9632 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)
;
9633 //wmem_free(NULL, tmp_str);
9634 }
9635 if (hfinfo->bitmask != 0)
9636 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
))
9637 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
))
9638 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
))
;
9639 //allowed to support string if its a protocol (for pinos)
9640 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9641 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
))
9642 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
))
9643 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
))
;
9644 break;
9645
9646 case FT_PROTOCOL:
9647 case FT_FRAMENUM:
9648 if (hfinfo->display != BASE_NONE) {
9649 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9650 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)
9651 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)
9652 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)
;
9653 //wmem_free(NULL, tmp_str);
9654 }
9655 if (hfinfo->bitmask != 0)
9656 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
))
9657 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
))
9658 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
))
;
9659 break;
9660
9661 case FT_BOOLEAN:
9662 break;
9663
9664 case FT_ABSOLUTE_TIME:
9665 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9666 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9667 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)
9668 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)
;
9669 //wmem_free(NULL, tmp_str);
9670 }
9671 if (hfinfo->bitmask != 0)
9672 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
))
9673 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
))
9674 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
))
;
9675 break;
9676
9677 case FT_STRING:
9678 case FT_STRINGZ:
9679 case FT_UINT_STRING:
9680 case FT_STRINGZPAD:
9681 case FT_STRINGZTRUNC:
9682 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9683 case BASE_NONE:
9684 case BASE_STR_WSP:
9685 break;
9686
9687 default:
9688 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9689 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)
9690 " 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)
9691 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)
9692 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)
;
9693 //wmem_free(NULL, tmp_str);
9694 }
9695
9696 if (hfinfo->bitmask != 0)
9697 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
))
9698 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
))
9699 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
))
;
9700 if (hfinfo->strings != NULL((void*)0))
9701 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
))
9702 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
))
9703 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
))
;
9704 break;
9705
9706 case FT_IPv4:
9707 switch (hfinfo->display) {
9708 case BASE_NONE:
9709 case BASE_NETMASK:
9710 break;
9711
9712 default:
9713 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9714 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)
9715 " 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)
9716 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)
9717 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)
;
9718 //wmem_free(NULL, tmp_str);
9719 break;
9720 }
9721 break;
9722 case FT_FLOAT:
9723 case FT_DOUBLE:
9724 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9725 case BASE_NONE:
9726 case BASE_DEC:
9727 case BASE_HEX:
9728 case BASE_EXP:
9729 case BASE_CUSTOM:
9730 break;
9731 default:
9732 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9733 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)
9734 " 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)
9735 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)
9736 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)
;
9737 //wmem_free(NULL, tmp_str);
9738 }
9739 if (hfinfo->bitmask != 0)
9740 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
))
9741 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
))
9742 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
))
;
9743 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9744 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
))
9745 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
))
9746 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
))
;
9747 break;
9748 case FT_IEEE_11073_SFLOAT:
9749 case FT_IEEE_11073_FLOAT:
9750 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9751 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9752 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)
9753 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)
9754 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)
9755 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)
;
9756 //wmem_free(NULL, tmp_str);
9757 }
9758 if (hfinfo->bitmask != 0)
9759 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
))
9760 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
))
9761 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
))
;
9762 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9763 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
))
9764 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
))
9765 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
))
;
9766 break;
9767 default:
9768 if (hfinfo->display != BASE_NONE) {
9769 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9770 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)
9771 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)
9772 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)
9773 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)
;
9774 //wmem_free(NULL, tmp_str);
9775 }
9776 if (hfinfo->bitmask != 0)
9777 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
))
9778 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
))
9779 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
))
;
9780 if (hfinfo->strings != NULL((void*)0))
9781 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
))
9782 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
))
9783 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
))
;
9784 break;
9785 }
9786}
9787
9788static void
9789register_type_length_mismatch(void)
9790{
9791 static ei_register_info ei[] = {
9792 { &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)}}
}},
9793 { &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)}}
}},
9794 };
9795
9796 expert_module_t* expert_type_length_mismatch;
9797
9798 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9799
9800 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9801 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9802
9803 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9804 disabling them makes no sense. */
9805 proto_set_cant_toggle(proto_type_length_mismatch);
9806}
9807
9808static void
9809register_byte_array_string_decodinws_error(void)
9810{
9811 static ei_register_info ei[] = {
9812 { &ei_byte_array_string_decoding_failed_error,
9813 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9814 "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)}}
9815 }
9816 },
9817 };
9818
9819 expert_module_t* expert_byte_array_string_decoding_error;
9820
9821 proto_byte_array_string_decoding_error =
9822 proto_register_protocol("Byte Array-String Decoding Error",
9823 "Byte Array-string decoding error",
9824 "_ws.byte_array_string.decoding_error");
9825
9826 expert_byte_array_string_decoding_error =
9827 expert_register_protocol(proto_byte_array_string_decoding_error);
9828 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9829
9830 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9831 disabling them makes no sense. */
9832 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9833}
9834
9835static void
9836register_date_time_string_decodinws_error(void)
9837{
9838 static ei_register_info ei[] = {
9839 { &ei_date_time_string_decoding_failed_error,
9840 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9841 "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)}}
9842 }
9843 },
9844 };
9845
9846 expert_module_t* expert_date_time_string_decoding_error;
9847
9848 proto_date_time_string_decoding_error =
9849 proto_register_protocol("Date and Time-String Decoding Error",
9850 "Date and Time-string decoding error",
9851 "_ws.date_time_string.decoding_error");
9852
9853 expert_date_time_string_decoding_error =
9854 expert_register_protocol(proto_date_time_string_decoding_error);
9855 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9856
9857 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9858 disabling them makes no sense. */
9859 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9860}
9861
9862static void
9863register_string_errors(void)
9864{
9865 static ei_register_info ei[] = {
9866 { &ei_string_trailing_characters,
9867 { "_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)}}
}
9868 },
9869 };
9870
9871 expert_module_t* expert_string_errors;
9872
9873 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9874
9875 expert_string_errors = expert_register_protocol(proto_string_errors);
9876 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9877
9878 /* "String Errors" isn't really a protocol, it's an error indication;
9879 disabling them makes no sense. */
9880 proto_set_cant_toggle(proto_string_errors);
9881}
9882
9883static int
9884proto_register_field_init(header_field_info *hfinfo, const int parent)
9885{
9886
9887 tmp_fld_check_assert(hfinfo);
9888
9889 hfinfo->parent = parent;
9890 hfinfo->same_name_next = NULL((void*)0);
9891 hfinfo->same_name_prev_id = -1;
9892
9893 /* if we always add and never delete, then id == len - 1 is correct */
9894 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9895 if (!gpa_hfinfo.hfi) {
9896 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9897 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9898 /* The entry with index 0 is not used. */
9899 gpa_hfinfo.hfi[0] = NULL((void*)0);
9900 gpa_hfinfo.len = 1;
9901 } else {
9902 gpa_hfinfo.allocated_len += 1000;
9903 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9904 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9905 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9906 }
9907 }
9908 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9909 gpa_hfinfo.len++;
9910 hfinfo->id = gpa_hfinfo.len - 1;
9911
9912 /* if we have real names, enter this field in the name tree */
9913 /* Already checked in tmp_fld_check_assert */
9914 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
9915 {
9916
9917 header_field_info *same_name_next_hfinfo;
9918
9919 /* We allow multiple hfinfo's to be registered under the same
9920 * abbreviation. This was done for X.25, as, depending
9921 * on whether it's modulo-8 or modulo-128 operation,
9922 * some bitfield fields may be in different bits of
9923 * a byte, and we want to be able to refer to that field
9924 * with one name regardless of whether the packets
9925 * are modulo-8 or modulo-128 packets. */
9926
9927 /* wmem_map_insert - if key is already present the previous
9928 * hfinfo with the same key/name is returned, otherwise NULL */
9929 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9930 if (same_name_hfinfo) {
9931 /* There's already a field with this name.
9932 * Put the current field *before* that field
9933 * in the list of fields with this name, Thus,
9934 * we end up with an effectively
9935 * doubly-linked-list of same-named hfinfo's,
9936 * with the head of the list (stored in the
9937 * hash) being the last seen hfinfo.
9938 */
9939 same_name_next_hfinfo =
9940 same_name_hfinfo->same_name_next;
9941
9942 hfinfo->same_name_next = same_name_next_hfinfo;
9943 if (same_name_next_hfinfo)
9944 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9945
9946 same_name_hfinfo->same_name_next = hfinfo;
9947 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9948#ifdef ENABLE_CHECK_FILTER
9949 while (same_name_hfinfo) {
9950 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9951 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"
, 9951, __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)
;
9952 same_name_hfinfo = same_name_hfinfo->same_name_next;
9953 }
9954#endif
9955 }
9956 }
9957
9958 return hfinfo->id;
9959}
9960
9961void
9962proto_register_subtree_array(int * const *indices, const int num_indices)
9963{
9964 int i;
9965 int *const *ptr = indices;
9966
9967 /*
9968 * If we've already allocated the array of tree types, expand
9969 * it; this lets plugins such as mate add tree types after
9970 * the initial startup. (If we haven't already allocated it,
9971 * we don't allocate it; on the first pass, we just assign
9972 * ett values and keep track of how many we've assigned, and
9973 * when we're finished registering all dissectors we allocate
9974 * the array, so that we do only one allocation rather than
9975 * wasting CPU time and memory by growing the array for each
9976 * dissector that registers ett values.)
9977 */
9978 if (tree_is_expanded != NULL((void*)0)) {
9979 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9980
9981 /* set new items to 0 */
9982 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9983 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9984 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9985 }
9986
9987 /*
9988 * Assign "num_indices" subtree numbers starting at "num_tree_types",
9989 * returning the indices through the pointers in the array whose
9990 * first element is pointed to by "indices", and update
9991 * "num_tree_types" appropriately.
9992 */
9993 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9994 if (**ptr != -1 && **ptr != 0) {
9995 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.")
9996 " 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.")
9997 " 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.")
9998 " 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.")
;
9999 }
10000 **ptr = num_tree_types;
10001 }
10002}
10003
10004static void
10005mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10006{
10007 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10008 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10009 char *last_char;
10010
10011 /* ..... field_name: dataaaaaaaaaaaaa
10012 * |
10013 * ^^^^^ name_pos
10014 *
10015 * ..... field_name […]: dataaaaaaaaaaaaa
10016 *
10017 * name_pos==0 means that we have only data or only a field_name
10018 */
10019
10020 ws_assert(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10020, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10021
10022 if (name_pos >= size - trunc_len) {
10023 /* No room for trunc_str after the field_name, put it first. */
10024 name_pos = 0;
10025 }
10026
10027 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10028 if (name_pos == 0) {
10029 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10030 memcpy(label_str, trunc_str + 1, trunc_len);
10031 } else {
10032 memcpy(label_str + name_pos, trunc_str, trunc_len);
10033 }
10034 /* in general, label_str is UTF-8
10035 we can truncate it only at the beginning of a new character
10036 we go backwards from the byte right after our buffer and
10037 find the next starting byte of a UTF-8 character, this is
10038 where we cut
10039 there's no need to use g_utf8_find_prev_char(), the search
10040 will always succeed since we copied trunc_str into the
10041 buffer */
10042 /* g_utf8_prev_char does not deference the memory address
10043 * passed in (until after decrementing it, so it is perfectly
10044 * legal to pass in a pointer one past the last element.
10045 */
10046 last_char = g_utf8_prev_char(label_str + size);
10047 *last_char = '\0';
10048
10049 if (value_pos && *value_pos > 0) {
10050 if (name_pos == 0) {
10051 *value_pos += trunc_len;
10052 } else {
10053 /* Move one back to include trunc_str in the value. */
10054 *value_pos -= 1;
10055 }
10056 }
10057
10058 /* Check if value_pos is past label_str. */
10059 if (value_pos && *value_pos >= size) {
10060 *value_pos = size - 1;
10061 }
10062}
10063
10064static void
10065label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10066{
10067 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10068}
10069
10070static size_t
10071label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10072{
10073 size_t name_pos;
10074
10075 /* "%s: %s", hfinfo->name, text */
10076 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10077 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10078 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10079 if (value_pos) {
10080 *value_pos = pos;
10081 }
10082 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, text ? text : "(null)", label_strcat_flags(hfinfo));
10083 }
10084
10085 if (pos >= ITEM_LABEL_LENGTH240) {
10086 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10087 label_mark_truncated(label_str, name_pos, value_pos);
10088 }
10089
10090 return pos;
10091}
10092
10093static size_t
10094label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10095{
10096 size_t name_pos;
10097
10098 /* "%s: %s (%s)", hfinfo->name, text, descr */
10099 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10100 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10101 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10102 if (value_pos) {
10103 *value_pos = pos;
10104 }
10105 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10106 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10107 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10108 } else {
10109 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10110 pos = label_concat(label_str, pos, " (")ws_label_strcpy(label_str, 240, pos, " (", 0);
10111 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10112 pos = label_concat(label_str, pos, ")")ws_label_strcpy(label_str, 240, pos, ")", 0);
10113 }
10114 }
10115
10116 if (pos >= ITEM_LABEL_LENGTH240) {
10117 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10118 label_mark_truncated(label_str, name_pos, value_pos);
10119 }
10120
10121 return pos;
10122}
10123
10124void
10125proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10126{
10127 const header_field_info *hfinfo;
10128 const char *str;
10129 const uint8_t *bytes;
10130 uint32_t integer;
10131 const ipv4_addr_and_mask *ipv4;
10132 const ipv6_addr_and_prefix *ipv6;
10133 const e_guid_t *guid;
10134 char *name;
10135 address addr;
10136 char *addr_str;
10137 char *tmp;
10138
10139 if (!label_str) {
10140 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10140, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10141 return;
10142 }
10143
10144 label_str[0]= '\0';
10145
10146 if (!fi) {
10147 return;
10148 }
10149
10150 hfinfo = fi->hfinfo;
10151
10152 switch (hfinfo->type) {
10153 case FT_NONE:
10154 case FT_PROTOCOL:
10155 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10156 if (value_pos) {
10157 *value_pos = strlen(hfinfo->name);
10158 }
10159 break;
10160
10161 case FT_BOOLEAN:
10162 fill_label_boolean(fi, label_str, value_pos);
10163 break;
10164
10165 case FT_BYTES:
10166 case FT_UINT_BYTES:
10167 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10168 fvalue_get_bytes_data(fi->value),
10169 (unsigned)fvalue_length2(fi->value));
10170 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10171 wmem_free(NULL((void*)0), tmp);
10172 break;
10173
10174 case FT_CHAR:
10175 if (hfinfo->bitmask) {
10176 fill_label_bitfield_char(fi, label_str, value_pos);
10177 } else {
10178 fill_label_char(fi, label_str, value_pos);
10179 }
10180 break;
10181
10182 /* Four types of integers to take care of:
10183 * Bitfield, with val_string
10184 * Bitfield, w/o val_string
10185 * Non-bitfield, with val_string
10186 * Non-bitfield, w/o val_string
10187 */
10188 case FT_UINT8:
10189 case FT_UINT16:
10190 case FT_UINT24:
10191 case FT_UINT32:
10192 if (hfinfo->bitmask) {
10193 fill_label_bitfield(fi, label_str, value_pos, false0);
10194 } else {
10195 fill_label_number(fi, label_str, value_pos, false0);
10196 }
10197 break;
10198
10199 case FT_FRAMENUM:
10200 fill_label_number(fi, label_str, value_pos, false0);
10201 break;
10202
10203 case FT_UINT40:
10204 case FT_UINT48:
10205 case FT_UINT56:
10206 case FT_UINT64:
10207 if (hfinfo->bitmask) {
10208 fill_label_bitfield64(fi, label_str, value_pos, false0);
10209 } else {
10210 fill_label_number64(fi, label_str, value_pos, false0);
10211 }
10212 break;
10213
10214 case FT_INT8:
10215 case FT_INT16:
10216 case FT_INT24:
10217 case FT_INT32:
10218 if (hfinfo->bitmask) {
10219 fill_label_bitfield(fi, label_str, value_pos, true1);
10220 } else {
10221 fill_label_number(fi, label_str, value_pos, true1);
10222 }
10223 break;
10224
10225 case FT_INT40:
10226 case FT_INT48:
10227 case FT_INT56:
10228 case FT_INT64:
10229 if (hfinfo->bitmask) {
10230 fill_label_bitfield64(fi, label_str, value_pos, true1);
10231 } else {
10232 fill_label_number64(fi, label_str, value_pos, true1);
10233 }
10234 break;
10235
10236 case FT_FLOAT:
10237 case FT_DOUBLE:
10238 fill_label_float(fi, label_str, value_pos);
10239 break;
10240
10241 case FT_ABSOLUTE_TIME:
10242 {
10243 const nstime_t *value = fvalue_get_time(fi->value);
10244 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10245 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10246 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10247 }
10248 if (hfinfo->strings) {
10249 /*
10250 * Table of time valus to be displayed
10251 * specially.
10252 */
10253 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10254 if (time_string != NULL((void*)0)) {
10255 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10256 break;
10257 }
10258 }
10259 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10260 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10261 wmem_free(NULL((void*)0), tmp);
10262 break;
10263 }
10264 case FT_RELATIVE_TIME:
10265 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10266 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10267 wmem_free(NULL((void*)0), tmp);
10268 break;
10269
10270 case FT_IPXNET:
10271 integer = fvalue_get_uinteger(fi->value);
10272 tmp = get_ipxnet_name(NULL((void*)0), integer);
10273 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10274 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10275 wmem_free(NULL((void*)0), tmp);
10276 wmem_free(NULL((void*)0), addr_str);
10277 break;
10278
10279 case FT_VINES:
10280 addr.type = AT_VINES;
10281 addr.len = VINES_ADDR_LEN6;
10282 addr.data = fvalue_get_bytes_data(fi->value);
10283
10284 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10285 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10286 wmem_free(NULL((void*)0), addr_str);
10287 break;
10288
10289 case FT_ETHER:
10290 bytes = fvalue_get_bytes_data(fi->value);
10291
10292 addr.type = AT_ETHER;
10293 addr.len = 6;
10294 addr.data = bytes;
10295
10296 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10297 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10298 wmem_free(NULL((void*)0), addr_str);
10299 break;
10300
10301 case FT_IPv4:
10302 ipv4 = fvalue_get_ipv4(fi->value);
10303 set_address_ipv4(&addr, ipv4);
10304
10305 if (hfinfo->display == BASE_NETMASK) {
10306 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10307 } else {
10308 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10309 }
10310 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10311 wmem_free(NULL((void*)0), addr_str);
10312 free_address(&addr);
10313 break;
10314
10315 case FT_IPv6:
10316 ipv6 = fvalue_get_ipv6(fi->value);
10317 set_address_ipv6(&addr, ipv6);
10318
10319 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10320 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10321 wmem_free(NULL((void*)0), addr_str);
10322 free_address(&addr);
10323 break;
10324
10325 case FT_FCWWN:
10326 bytes = fvalue_get_bytes_data(fi->value);
10327 addr.type = AT_FCWWN;
10328 addr.len = FCWWN_ADDR_LEN8;
10329 addr.data = bytes;
10330
10331 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10332 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10333 wmem_free(NULL((void*)0), addr_str);
10334 break;
10335
10336 case FT_GUID:
10337 guid = fvalue_get_guid(fi->value);
10338 tmp = guid_to_str(NULL((void*)0), guid);
10339 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10340 wmem_free(NULL((void*)0), tmp);
10341 break;
10342
10343 case FT_OID:
10344 bytes = fvalue_get_bytes_data(fi->value);
10345 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10346 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10347 if (name) {
10348 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10349 wmem_free(NULL((void*)0), name);
10350 } else {
10351 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10352 }
10353 wmem_free(NULL((void*)0), tmp);
10354 break;
10355
10356 case FT_REL_OID:
10357 bytes = fvalue_get_bytes_data(fi->value);
10358 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10359 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10360 if (name) {
10361 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10362 wmem_free(NULL((void*)0), name);
10363 } else {
10364 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10365 }
10366 wmem_free(NULL((void*)0), tmp);
10367 break;
10368
10369 case FT_SYSTEM_ID:
10370 bytes = fvalue_get_bytes_data(fi->value);
10371 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10372 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10373 wmem_free(NULL((void*)0), tmp);
10374 break;
10375
10376 case FT_EUI64:
10377 bytes = fvalue_get_bytes_data(fi->value);
10378 addr.type = AT_EUI64;
10379 addr.len = EUI64_ADDR_LEN8;
10380 addr.data = bytes;
10381
10382 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10383 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10384 wmem_free(NULL((void*)0), addr_str);
10385 break;
10386 case FT_STRING:
10387 case FT_STRINGZ:
10388 case FT_UINT_STRING:
10389 case FT_STRINGZPAD:
10390 case FT_STRINGZTRUNC:
10391 case FT_AX25:
10392 str = fvalue_get_string(fi->value);
10393 label_fill(label_str, 0, hfinfo, str, value_pos);
10394 break;
10395
10396 case FT_IEEE_11073_SFLOAT:
10397 case FT_IEEE_11073_FLOAT:
10398 fill_label_ieee_11073_float(fi, label_str, value_pos);
10399 break;
10400
10401 default:
10402 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
))
10403 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
))
10404 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
))
10405 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
))
;
10406 break;
10407 }
10408}
10409
10410static void
10411fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10412{
10413 char *p;
10414 int bitfield_byte_length = 0, bitwidth;
10415 uint64_t unshifted_value;
10416 uint64_t value;
10417
10418 const header_field_info *hfinfo = fi->hfinfo;
10419
10420 value = fvalue_get_uinteger64(fi->value);
10421 if (hfinfo->bitmask) {
10422 /* Figure out the bit width */
10423 bitwidth = hfinfo_container_bitwidth(hfinfo);
10424
10425 /* Un-shift bits */
10426 unshifted_value = value;
10427 unshifted_value <<= hfinfo_bitshift(hfinfo);
10428
10429 /* Create the bitfield first */
10430 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10431 bitfield_byte_length = (int) (p - label_str);
10432 }
10433
10434 /* Fill in the textual info */
10435 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10436}
10437
10438static const char *
10439hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10440{
10441 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10442 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10443
10444 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10445 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10446 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10447 else
10448 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10449 }
10450
10451 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10452 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10453
10454 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10455 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10456
10457 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10458}
10459
10460static const char *
10461hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10462{
10463 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10464 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10465 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10466 else
10467 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10468 }
10469
10470 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10471 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10472
10473 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10474 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10475
10476 /* If this is reached somebody registered a 64-bit field with a 32-bit
10477 * value-string, which isn't right. */
10478 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)
10479 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10480
10481 /* This is necessary to squelch MSVC errors; is there
10482 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10483 never returns? */
10484 return NULL((void*)0);
10485}
10486
10487static const char *
10488hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10489{
10490 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10491 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10492
10493 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)
;
10494
10495 /* This is necessary to squelch MSVC errors; is there
10496 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10497 never returns? */
10498 return NULL((void*)0);
10499}
10500
10501static const char *
10502hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10503{
10504 const char *str = hf_try_val_to_str(value, hfinfo);
10505
10506 return (str) ? str : unknown_str;
10507}
10508
10509static const char *
10510hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10511{
10512 const char *str = hf_try_val64_to_str(value, hfinfo);
10513
10514 return (str) ? str : unknown_str;
10515}
10516
10517/* Fills data for bitfield chars with val_strings */
10518static void
10519fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10520{
10521 char *p;
10522 int bitfield_byte_length, bitwidth;
10523 uint32_t unshifted_value;
10524 uint32_t value;
10525
10526 char buf[32];
10527 const char *out;
10528
10529 const header_field_info *hfinfo = fi->hfinfo;
10530
10531 /* Figure out the bit width */
10532 bitwidth = hfinfo_container_bitwidth(hfinfo);
10533
10534 /* Un-shift bits */
10535 value = fvalue_get_uinteger(fi->value);
10536
10537 unshifted_value = value;
10538 if (hfinfo->bitmask) {
10539 unshifted_value <<= hfinfo_bitshift(hfinfo);
10540 }
10541
10542 /* Create the bitfield first */
10543 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10544 bitfield_byte_length = (int) (p - label_str);
10545
10546 /* Fill in the textual info using stored (shifted) value */
10547 if (hfinfo->display == BASE_CUSTOM) {
10548 char tmp[ITEM_LABEL_LENGTH240];
10549 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10550
10551 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10551, "fmtfunc"))))
;
10552 fmtfunc(tmp, value);
10553 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10554 }
10555 else if (hfinfo->strings) {
10556 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10557
10558 out = hfinfo_char_vals_format(hfinfo, buf, value);
10559 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10560 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10561 else
10562 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10563 }
10564 else {
10565 out = hfinfo_char_value_format(hfinfo, buf, value);
10566
10567 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10568 }
10569}
10570
10571/* Fills data for bitfield ints with val_strings */
10572static void
10573fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10574{
10575 char *p;
10576 int bitfield_byte_length, bitwidth;
10577 uint32_t value, unshifted_value;
10578 char buf[NUMBER_LABEL_LENGTH80];
10579 const char *out;
10580
10581 const header_field_info *hfinfo = fi->hfinfo;
10582
10583 /* Figure out the bit width */
10584 if (fi->flags & FI_VARINT0x00040000)
10585 bitwidth = fi->length*8;
10586 else
10587 bitwidth = hfinfo_container_bitwidth(hfinfo);
10588
10589 /* Un-shift bits */
10590 if (is_signed)
10591 value = fvalue_get_sinteger(fi->value);
10592 else
10593 value = fvalue_get_uinteger(fi->value);
10594
10595 unshifted_value = value;
10596 if (hfinfo->bitmask) {
10597 unshifted_value <<= hfinfo_bitshift(hfinfo);
10598 }
10599
10600 /* Create the bitfield first */
10601 if (fi->flags & FI_VARINT0x00040000)
10602 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10603 else
10604 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10605 bitfield_byte_length = (int) (p - label_str);
10606
10607 /* Fill in the textual info using stored (shifted) value */
10608 if (hfinfo->display == BASE_CUSTOM) {
10609 char tmp[ITEM_LABEL_LENGTH240];
10610 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10611
10612 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10612, "fmtfunc"))))
;
10613 fmtfunc(tmp, value);
10614 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10615 }
10616 else if (hfinfo->strings) {
10617 const char *val_str = hf_try_val_to_str(value, hfinfo);
10618
10619 out = hfinfo_number_vals_format(hfinfo, buf, value);
10620 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10621 /*
10622 * Unique values only display value_string string
10623 * if there is a match. Otherwise it's just a number
10624 */
10625 if (val_str) {
10626 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10627 } else {
10628 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10629 }
10630 } else {
10631 if (val_str == NULL((void*)0))
10632 val_str = "Unknown";
10633
10634 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10635 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10636 else
10637 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10638 }
10639 }
10640 else {
10641 out = hfinfo_number_value_format(hfinfo, buf, value);
10642
10643 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10644 }
10645}
10646
10647static void
10648fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10649{
10650 char *p;
10651 int bitfield_byte_length, bitwidth;
10652 uint64_t value, unshifted_value;
10653 char buf[NUMBER_LABEL_LENGTH80];
10654 const char *out;
10655
10656 const header_field_info *hfinfo = fi->hfinfo;
10657
10658 /* Figure out the bit width */
10659 if (fi->flags & FI_VARINT0x00040000)
10660 bitwidth = fi->length*8;
10661 else
10662 bitwidth = hfinfo_container_bitwidth(hfinfo);
10663
10664 /* Un-shift bits */
10665 if (is_signed)
10666 value = fvalue_get_sinteger64(fi->value);
10667 else
10668 value = fvalue_get_uinteger64(fi->value);
10669
10670 unshifted_value = value;
10671 if (hfinfo->bitmask) {
10672 unshifted_value <<= hfinfo_bitshift(hfinfo);
10673 }
10674
10675 /* Create the bitfield first */
10676 if (fi->flags & FI_VARINT0x00040000)
10677 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10678 else
10679 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10680 bitfield_byte_length = (int) (p - label_str);
10681
10682 /* Fill in the textual info using stored (shifted) value */
10683 if (hfinfo->display == BASE_CUSTOM) {
10684 char tmp[ITEM_LABEL_LENGTH240];
10685 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10686
10687 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10687, "fmtfunc64"
))))
;
10688 fmtfunc64(tmp, value);
10689 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10690 }
10691 else if (hfinfo->strings) {
10692 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10693
10694 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10695 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10696 /*
10697 * Unique values only display value_string string
10698 * if there is a match. Otherwise it's just a number
10699 */
10700 if (val_str) {
10701 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10702 } else {
10703 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10704 }
10705 } else {
10706 if (val_str == NULL((void*)0))
10707 val_str = "Unknown";
10708
10709 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10710 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10711 else
10712 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10713 }
10714 }
10715 else {
10716 out = hfinfo_number_value_format64(hfinfo, buf, value);
10717
10718 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10719 }
10720}
10721
10722static void
10723fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10724{
10725 const header_field_info *hfinfo = fi->hfinfo;
10726 uint32_t value;
10727
10728 char buf[32];
10729 const char *out;
10730
10731 value = fvalue_get_uinteger(fi->value);
10732
10733 /* Fill in the textual info */
10734 if (hfinfo->display == BASE_CUSTOM) {
10735 char tmp[ITEM_LABEL_LENGTH240];
10736 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10737
10738 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10738, "fmtfunc"))))
;
10739 fmtfunc(tmp, value);
10740 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10741 }
10742 else if (hfinfo->strings) {
10743 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10744
10745 out = hfinfo_char_vals_format(hfinfo, buf, value);
10746 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10747 }
10748 else {
10749 out = hfinfo_char_value_format(hfinfo, buf, value);
10750
10751 label_fill(label_str, 0, hfinfo, out, value_pos);
10752 }
10753}
10754
10755static void
10756fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10757{
10758 const header_field_info *hfinfo = fi->hfinfo;
10759 uint32_t value;
10760
10761 char buf[NUMBER_LABEL_LENGTH80];
10762 const char *out;
10763
10764 if (is_signed)
10765 value = fvalue_get_sinteger(fi->value);
10766 else
10767 value = fvalue_get_uinteger(fi->value);
10768
10769 /* Fill in the textual info */
10770 if (hfinfo->display == BASE_CUSTOM) {
10771 char tmp[ITEM_LABEL_LENGTH240];
10772 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10773
10774 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10774, "fmtfunc"))))
;
10775 fmtfunc(tmp, value);
10776 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10777 }
10778 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10779 /*
10780 * It makes no sense to have a value-string table for a
10781 * frame-number field - they're just integers giving
10782 * the ordinal frame number.
10783 */
10784 const char *val_str = hf_try_val_to_str(value, hfinfo);
10785
10786 out = hfinfo_number_vals_format(hfinfo, buf, value);
10787 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10788 /*
10789 * Unique values only display value_string string
10790 * if there is a match. Otherwise it's just a number
10791 */
10792 if (val_str) {
10793 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10794 } else {
10795 label_fill(label_str, 0, hfinfo, out, value_pos);
10796 }
10797 } else {
10798 if (val_str == NULL((void*)0))
10799 val_str = "Unknown";
10800
10801 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10802 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10803 else
10804 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10805 }
10806 }
10807 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
))
) {
10808 char tmp[ITEM_LABEL_LENGTH240];
10809
10810 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10811 display_to_port_type((field_display_e)hfinfo->display), value);
10812 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10813 }
10814 else {
10815 out = hfinfo_number_value_format(hfinfo, buf, value);
10816
10817 label_fill(label_str, 0, hfinfo, out, value_pos);
10818 }
10819}
10820
10821static void
10822fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10823{
10824 const header_field_info *hfinfo = fi->hfinfo;
10825 uint64_t value;
10826
10827 char buf[NUMBER_LABEL_LENGTH80];
10828 const char *out;
10829
10830 if (is_signed)
10831 value = fvalue_get_sinteger64(fi->value);
10832 else
10833 value = fvalue_get_uinteger64(fi->value);
10834
10835 /* Fill in the textual info */
10836 if (hfinfo->display == BASE_CUSTOM) {
10837 char tmp[ITEM_LABEL_LENGTH240];
10838 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10839
10840 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10840, "fmtfunc64"
))))
;
10841 fmtfunc64(tmp, value);
10842 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10843 }
10844 else if (hfinfo->strings) {
10845 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10846
10847 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10848 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10849 /*
10850 * Unique values only display value_string string
10851 * if there is a match. Otherwise it's just a number
10852 */
10853 if (val_str) {
10854 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10855 } else {
10856 label_fill(label_str, 0, hfinfo, out, value_pos);
10857 }
10858 } else {
10859 if (val_str == NULL((void*)0))
10860 val_str = "Unknown";
10861
10862 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10863 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10864 else
10865 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10866 }
10867 }
10868 else {
10869 out = hfinfo_number_value_format64(hfinfo, buf, value);
10870
10871 label_fill(label_str, 0, hfinfo, out, value_pos);
10872 }
10873}
10874
10875static size_t
10876fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10877{
10878 int display;
10879 int n;
10880 double value;
10881
10882 if (label_str_size < 12) {
10883 /* Not enough room to write an entire floating point value. */
10884 return 0;
10885 }
10886
10887 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10888 value = fvalue_get_floating(fi->value);
10889
10890 if (display == BASE_CUSTOM) {
10891 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10892 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10892, "fmtfunc"))))
;
10893 fmtfunc(label_str, value);
10894 return strlen(label_str);
10895 }
10896
10897 switch (display) {
10898 case BASE_NONE:
10899 if (fi->hfinfo->type == FT_FLOAT) {
10900 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10901 } else {
10902 n = (int)strlen(dtoa_g_fmt(label_str, value));
10903 }
10904 break;
10905 case BASE_DEC:
10906 n = snprintf(label_str, label_str_size, "%f", value);
10907 break;
10908 case BASE_HEX:
10909 n = snprintf(label_str, label_str_size, "%a", value);
10910 break;
10911 case BASE_EXP:
10912 n = snprintf(label_str, label_str_size, "%e", value);
10913 break;
10914 default:
10915 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10915
, __func__, "assertion \"not reached\" failed")
;
10916 }
10917 if (n < 0) {
10918 return 0; /* error */
10919 }
10920 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10921 const char *hf_str_val;
10922 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10923 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10924 }
10925 if (n > label_str_size) {
10926 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10926, __func__, "label length too small"); } } while (0)
;
10927 return strlen(label_str);
10928 }
10929
10930 return n;
10931}
10932
10933void
10934fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10935{
10936 char tmp[ITEM_LABEL_LENGTH240];
10937
10938 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10939 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10940}
10941
10942static size_t
10943fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10944{
10945 int display;
10946 size_t pos = 0;
10947 double value;
10948 char* tmp_str;
10949
10950 if (label_str_size < 12) {
10951 /* Not enough room to write an entire floating point value. */
10952 return 0;
10953 }
10954
10955 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10956 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10957 pos = label_concat(label_str, pos, tmp_str)ws_label_strcpy(label_str, 240, pos, tmp_str, 0);
10958 wmem_free(NULL((void*)0), tmp_str);
10959
10960 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10961 const char *hf_str_val;
10962 fvalue_to_double(fi->value, &value);
10963 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10964 pos = label_concat(label_str, pos, hf_str_val)ws_label_strcpy(label_str, 240, pos, hf_str_val, 0);
10965 }
10966 if ((int)pos > label_str_size) {
10967 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10967, __func__, "label length too small"); } } while (0)
;
10968 return strlen(label_str);
10969 }
10970
10971 return pos;
10972}
10973
10974void
10975fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
10976{
10977 char tmp[ITEM_LABEL_LENGTH240];
10978
10979 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
10980 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10981}
10982
10983int
10984hfinfo_bitshift(const header_field_info *hfinfo)
10985{
10986 return ws_ctz(hfinfo->bitmask);
10987}
10988
10989
10990static int
10991hfinfo_bitoffset(const header_field_info *hfinfo)
10992{
10993 if (!hfinfo->bitmask) {
10994 return 0;
10995 }
10996
10997 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
10998 * as the first bit */
10999 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11000}
11001
11002static int
11003hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11004{
11005 if (!hfinfo->bitmask) {
11006 return 0;
11007 }
11008
11009 /* ilog2 = first set bit, ctz = last set bit */
11010 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11011}
11012
11013static int
11014hfinfo_type_bitwidth(enum ftenum type)
11015{
11016 int bitwidth = 0;
11017
11018 switch (type) {
11019 case FT_CHAR:
11020 case FT_UINT8:
11021 case FT_INT8:
11022 bitwidth = 8;
11023 break;
11024 case FT_UINT16:
11025 case FT_INT16:
11026 bitwidth = 16;
11027 break;
11028 case FT_UINT24:
11029 case FT_INT24:
11030 bitwidth = 24;
11031 break;
11032 case FT_UINT32:
11033 case FT_INT32:
11034 bitwidth = 32;
11035 break;
11036 case FT_UINT40:
11037 case FT_INT40:
11038 bitwidth = 40;
11039 break;
11040 case FT_UINT48:
11041 case FT_INT48:
11042 bitwidth = 48;
11043 break;
11044 case FT_UINT56:
11045 case FT_INT56:
11046 bitwidth = 56;
11047 break;
11048 case FT_UINT64:
11049 case FT_INT64:
11050 bitwidth = 64;
11051 break;
11052 default:
11053 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11053))
;
11054 ;
11055 }
11056 return bitwidth;
11057}
11058
11059
11060static int
11061hfinfo_container_bitwidth(const header_field_info *hfinfo)
11062{
11063 if (!hfinfo->bitmask) {
11064 return 0;
11065 }
11066
11067 if (hfinfo->type == FT_BOOLEAN) {
11068 return hfinfo->display; /* hacky? :) */
11069 }
11070
11071 return hfinfo_type_bitwidth(hfinfo->type);
11072}
11073
11074static int
11075hfinfo_hex_digits(const header_field_info *hfinfo)
11076{
11077 int bitwidth;
11078
11079 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11080 * appropriate to determine the number of hex digits for the field.
11081 * So instead, we compute it from the bitmask.
11082 */
11083 if (hfinfo->bitmask != 0) {
11084 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11085 } else {
11086 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11087 }
11088
11089 /* Divide by 4, rounding up, to get number of hex digits. */
11090 return (bitwidth + 3) / 4;
11091}
11092
11093const char *
11094hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11095{
11096 char *ptr = &buf[6];
11097 static const char hex_digits[16] =
11098 { '0', '1', '2', '3', '4', '5', '6', '7',
11099 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11100
11101 *ptr = '\0';
11102 *(--ptr) = '\'';
11103 /* Properly format value */
11104 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11105 /*
11106 * Printable, so just show the character, and, if it needs
11107 * to be escaped, escape it.
11108 */
11109 *(--ptr) = value;
11110 if (value == '\\' || value == '\'')
11111 *(--ptr) = '\\';
11112 } else {
11113 /*
11114 * Non-printable; show it as an escape sequence.
11115 */
11116 switch (value) {
11117
11118 case '\0':
11119 /*
11120 * Show a NUL with only one digit.
11121 */
11122 *(--ptr) = '0';
11123 break;
11124
11125 case '\a':
11126 case '\b':
11127 case '\f':
11128 case '\n':
11129 case '\r':
11130 case '\t':
11131 case '\v':
11132 *(--ptr) = value - '\a' + 'a';
11133 break;
11134
11135 default:
11136 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11137
11138 case BASE_OCT:
11139 *(--ptr) = (value & 0x7) + '0';
11140 value >>= 3;
11141 *(--ptr) = (value & 0x7) + '0';
11142 value >>= 3;
11143 *(--ptr) = (value & 0x7) + '0';
11144 break;
11145
11146 case BASE_HEX:
11147 *(--ptr) = hex_digits[value & 0x0F];
11148 value >>= 4;
11149 *(--ptr) = hex_digits[value & 0x0F];
11150 *(--ptr) = 'x';
11151 break;
11152
11153 default:
11154 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11155 }
11156 }
11157 *(--ptr) = '\\';
11158 }
11159 *(--ptr) = '\'';
11160 return ptr;
11161}
11162
11163static const char *
11164hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11165{
11166 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11167 bool_Bool isint = FT_IS_INT(hfinfo->type)(((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
) || ((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
))
;
11168
11169 *ptr = '\0';
11170 /* Properly format value */
11171 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11172 case BASE_DEC:
11173 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11174
11175 case BASE_DEC_HEX:
11176 *(--ptr) = ')';
11177 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11178 *(--ptr) = '(';
11179 *(--ptr) = ' ';
11180 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11181 return ptr;
11182
11183 case BASE_OCT:
11184 return oct_to_str_back(ptr, value);
11185
11186 case BASE_HEX:
11187 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11188
11189 case BASE_HEX_DEC:
11190 *(--ptr) = ')';
11191 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11192 *(--ptr) = '(';
11193 *(--ptr) = ' ';
11194 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11195 return ptr;
11196
11197 case BASE_PT_UDP:
11198 case BASE_PT_TCP:
11199 case BASE_PT_DCCP:
11200 case BASE_PT_SCTP:
11201 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11202 display_to_port_type((field_display_e)display), value);
11203 return buf;
11204 case BASE_OUI:
11205 {
11206 uint8_t p_oui[3];
11207 const char *manuf_name;
11208
11209 p_oui[0] = value >> 16 & 0xFF;
11210 p_oui[1] = value >> 8 & 0xFF;
11211 p_oui[2] = value & 0xFF;
11212
11213 /* Attempt an OUI lookup. */
11214 manuf_name = uint_get_manuf_name_if_known(value);
11215 if (manuf_name == NULL((void*)0)) {
11216 /* Could not find an OUI. */
11217 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11218 }
11219 else {
11220 /* Found an address string. */
11221 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11222 }
11223 return buf;
11224 }
11225
11226 default:
11227 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11228 }
11229 return ptr;
11230}
11231
11232static const char *
11233hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11234{
11235 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11236 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
))
;
11237
11238 *ptr = '\0';
11239 /* Properly format value */
11240 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11241 case BASE_DEC:
11242 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11243
11244 case BASE_DEC_HEX:
11245 *(--ptr) = ')';
11246 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11247 *(--ptr) = '(';
11248 *(--ptr) = ' ';
11249 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11250 return ptr;
11251
11252 case BASE_OCT:
11253 return oct64_to_str_back(ptr, value);
11254
11255 case BASE_HEX:
11256 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11257
11258 case BASE_HEX_DEC:
11259 *(--ptr) = ')';
11260 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11261 *(--ptr) = '(';
11262 *(--ptr) = ' ';
11263 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11264 return ptr;
11265
11266 default:
11267 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11268 }
11269
11270 return ptr;
11271}
11272
11273static const char *
11274hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11275{
11276 int display = hfinfo->display;
11277
11278 if (hfinfo->type == FT_FRAMENUM) {
11279 /*
11280 * Frame numbers are always displayed in decimal.
11281 */
11282 display = BASE_DEC;
11283 }
11284
11285 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11286}
11287
11288static const char *
11289hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11290{
11291 int display = hfinfo->display;
11292
11293 if (hfinfo->type == FT_FRAMENUM) {
11294 /*
11295 * Frame numbers are always displayed in decimal.
11296 */
11297 display = BASE_DEC;
11298 }
11299
11300 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11301}
11302
11303static const char *
11304hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11305{
11306 /* Get the underlying BASE_ value */
11307 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11308
11309 return hfinfo_char_value_format_display(display, buf, value);
11310}
11311
11312static const char *
11313hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11314{
11315 /* Get the underlying BASE_ value */
11316 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11317
11318 if (hfinfo->type == FT_FRAMENUM) {
11319 /*
11320 * Frame numbers are always displayed in decimal.
11321 */
11322 display = BASE_DEC;
11323 }
11324
11325 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11326 display = BASE_DEC;
11327 } else if (display == BASE_OUI) {
11328 display = BASE_HEX;
11329 }
11330
11331 switch (display) {
11332 case BASE_NONE:
11333 /* case BASE_DEC: */
11334 case BASE_DEC_HEX:
11335 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11336 case BASE_CUSTOM:
11337 display = BASE_DEC;
11338 break;
11339
11340 /* case BASE_HEX: */
11341 case BASE_HEX_DEC:
11342 display = BASE_HEX;
11343 break;
11344 }
11345
11346 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11347}
11348
11349static const char *
11350hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11351{
11352 /* Get the underlying BASE_ value */
11353 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11354
11355 if (hfinfo->type == FT_FRAMENUM) {
11356 /*
11357 * Frame numbers are always displayed in decimal.
11358 */
11359 display = BASE_DEC;
11360 }
11361
11362 switch (display) {
11363 case BASE_NONE:
11364 /* case BASE_DEC: */
11365 case BASE_DEC_HEX:
11366 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11367 case BASE_CUSTOM:
11368 display = BASE_DEC;
11369 break;
11370
11371 /* case BASE_HEX: */
11372 case BASE_HEX_DEC:
11373 display = BASE_HEX;
11374 break;
11375 }
11376
11377 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11378}
11379
11380static const char *
11381hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11382{
11383 /* Get the underlying BASE_ value */
11384 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11385
11386 return hfinfo_char_value_format_display(display, buf, value);
11387}
11388
11389static const char *
11390hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11391{
11392 /* Get the underlying BASE_ value */
11393 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11394
11395 if (display == BASE_NONE)
11396 return NULL((void*)0);
11397
11398 if (display == BASE_DEC_HEX)
11399 display = BASE_DEC;
11400 if (display == BASE_HEX_DEC)
11401 display = BASE_HEX;
11402
11403 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11404}
11405
11406static const char *
11407hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11408{
11409 /* Get the underlying BASE_ value */
11410 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11411
11412 if (display == BASE_NONE)
11413 return NULL((void*)0);
11414
11415 if (display == BASE_DEC_HEX)
11416 display = BASE_DEC;
11417 if (display == BASE_HEX_DEC)
11418 display = BASE_HEX;
11419
11420 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11421}
11422
11423const char *
11424proto_registrar_get_name(const int n)
11425{
11426 header_field_info *hfinfo;
11427
11428 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", 11428
, __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", 11428
, "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", 11428, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11429 return hfinfo->name;
11430}
11431
11432const char *
11433proto_registrar_get_abbrev(const int n)
11434{
11435 header_field_info *hfinfo;
11436
11437 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", 11437
, __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", 11437
, "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", 11437, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11438 return hfinfo->abbrev;
11439}
11440
11441enum ftenum
11442proto_registrar_get_ftype(const int n)
11443{
11444 header_field_info *hfinfo;
11445
11446 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", 11446
, __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", 11446
, "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", 11446, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11447 return hfinfo->type;
11448}
11449
11450int
11451proto_registrar_get_parent(const int n)
11452{
11453 header_field_info *hfinfo;
11454
11455 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", 11455
, __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", 11455
, "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", 11455, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11456 return hfinfo->parent;
11457}
11458
11459bool_Bool
11460proto_registrar_is_protocol(const int n)
11461{
11462 header_field_info *hfinfo;
11463
11464 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", 11464
, __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", 11464
, "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", 11464, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11465 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11466}
11467
11468/* Returns length of field in packet (not necessarily the length
11469 * in our internal representation, as in the case of IPv4).
11470 * 0 means undeterminable at time of registration
11471 * -1 means the field is not registered. */
11472int
11473proto_registrar_get_length(const int n)
11474{
11475 header_field_info *hfinfo;
11476
11477 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", 11477
, __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", 11477
, "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", 11477, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11478 return ftype_wire_size(hfinfo->type);
11479}
11480
11481/* Looks for a protocol or a field in a proto_tree. Returns true if
11482 * it exists anywhere, or false if it exists nowhere. */
11483bool_Bool
11484proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11485{
11486 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11487
11488 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11489 return true1;
11490 }
11491 else {
11492 return false0;
11493 }
11494}
11495
11496/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11497 * This only works if the hfindex was "primed" before the dissection
11498 * took place, as we just pass back the already-created GPtrArray*.
11499 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11500 * handles that. */
11501GPtrArray *
11502proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11503{
11504 if (!tree)
11505 return NULL((void*)0);
11506
11507 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11508 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11509 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11510 else
11511 return NULL((void*)0);
11512}
11513
11514bool_Bool
11515proto_tracking_interesting_fields(const proto_tree *tree)
11516{
11517 GHashTable *interesting_hfids;
11518
11519 if (!tree)
11520 return false0;
11521
11522 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11523
11524 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11525}
11526
11527/* Helper struct for proto_find_info() and proto_all_finfos() */
11528typedef struct {
11529 GPtrArray *array;
11530 int id;
11531} ffdata_t;
11532
11533/* Helper function for proto_find_info() */
11534static bool_Bool
11535find_finfo(proto_node *node, void * data)
11536{
11537 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11538 if (fi && fi->hfinfo) {
11539 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11540 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11541 }
11542 }
11543
11544 /* Don't stop traversing. */
11545 return false0;
11546}
11547
11548/* Helper function for proto_find_first_info() */
11549static bool_Bool
11550find_first_finfo(proto_node *node, void *data)
11551{
11552 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11553 if (fi && fi->hfinfo) {
11554 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11555 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11556
11557 /* Stop traversing. */
11558 return true1;
11559 }
11560 }
11561
11562 /* Continue traversing. */
11563 return false0;
11564}
11565
11566/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11567* This works on any proto_tree, primed or unprimed, but actually searches
11568* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11569* The caller does need to free the returned GPtrArray with
11570* g_ptr_array_free(<array>, true).
11571*/
11572GPtrArray *
11573proto_find_finfo(proto_tree *tree, const int id)
11574{
11575 ffdata_t ffdata;
11576
11577 ffdata.array = g_ptr_array_new();
11578 ffdata.id = id;
11579
11580 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11581
11582 return ffdata.array;
11583}
11584
11585/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11586* This works on any proto_tree, primed or unprimed, but actually searches
11587* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11588* The caller does need to free the returned GPtrArray with
11589* g_ptr_array_free(<array>, true).
11590*/
11591GPtrArray *
11592proto_find_first_finfo(proto_tree *tree, const int id)
11593{
11594 ffdata_t ffdata;
11595
11596 ffdata.array = g_ptr_array_new();
11597 ffdata.id = id;
11598
11599 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11600
11601 return ffdata.array;
11602}
11603
11604/* Helper function for proto_all_finfos() */
11605static bool_Bool
11606every_finfo(proto_node *node, void * data)
11607{
11608 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11609 if (fi && fi->hfinfo) {
11610 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11611 }
11612
11613 /* Don't stop traversing. */
11614 return false0;
11615}
11616
11617/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11618 * The caller does need to free the returned GPtrArray with
11619 * g_ptr_array_free(<array>, true).
11620 */
11621GPtrArray *
11622proto_all_finfos(proto_tree *tree)
11623{
11624 ffdata_t ffdata;
11625
11626 /* Pre allocate enough space to hold all fields in most cases */
11627 ffdata.array = g_ptr_array_sized_new(512);
11628 ffdata.id = 0;
11629
11630 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11631
11632 return ffdata.array;
11633}
11634
11635
11636typedef struct {
11637 unsigned offset;
11638 field_info *finfo;
11639 tvbuff_t *tvb;
11640} offset_search_t;
11641
11642static bool_Bool
11643check_for_offset(proto_node *node, void * data)
11644{
11645 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11646 offset_search_t *offsearch = (offset_search_t *)data;
11647
11648 /* !fi == the top most container node which holds nothing */
11649 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11650 if (offsearch->offset >= (unsigned) fi->start &&
11651 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11652
11653 offsearch->finfo = fi;
11654 return false0; /* keep traversing */
11655 }
11656 }
11657 return false0; /* keep traversing */
11658}
11659
11660/* Search a proto_tree backwards (from leaves to root) looking for the field
11661 * whose start/length occupies 'offset' */
11662/* XXX - I couldn't find an easy way to search backwards, so I search
11663 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11664 * the one I want to return to the user. This algorithm is inefficient
11665 * and could be re-done, but I'd have to handle all the children and
11666 * siblings of each node myself. When I have more time I'll do that.
11667 * (yeah right) */
11668field_info *
11669proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11670{
11671 offset_search_t offsearch;
11672
11673 offsearch.offset = offset;
11674 offsearch.finfo = NULL((void*)0);
11675 offsearch.tvb = tvb;
11676
11677 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11678
11679 return offsearch.finfo;
11680}
11681
11682typedef struct {
11683 int length;
11684 char *buf;
11685} decoded_data_t;
11686
11687static bool_Bool
11688check_for_undecoded(proto_node *node, void * data)
11689{
11690 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11691 decoded_data_t* decoded = (decoded_data_t*)data;
11692 int i;
11693 unsigned byte;
11694 unsigned bit;
11695
11696 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11697 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11698 byte = i / 8;
11699 bit = i % 8;
11700 decoded->buf[byte] |= (1 << bit);
11701 }
11702 }
11703
11704 return false0;
11705}
11706
11707char*
11708proto_find_undecoded_data(proto_tree *tree, unsigned length)
11709{
11710 decoded_data_t decoded;
11711 decoded.length = length;
11712 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11713
11714 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11715 return decoded.buf;
11716}
11717
11718/* Dumps the protocols in the registration database to stdout. An independent
11719 * program can take this output and format it into nice tables or HTML or
11720 * whatever.
11721 *
11722 * There is one record per line. The fields are tab-delimited.
11723 *
11724 * Field 1 = protocol name
11725 * Field 2 = protocol short name
11726 * Field 3 = protocol filter name
11727 * Field 4 = protocol enabled
11728 * Field 5 = protocol enabled by default
11729 * Field 6 = protocol can toggle
11730 */
11731void
11732proto_registrar_dump_protocols(void)
11733{
11734 protocol_t *protocol;
11735 int i;
11736 void *cookie = NULL((void*)0);
11737
11738
11739 i = proto_get_first_protocol(&cookie);
11740 while (i != -1) {
11741 protocol = find_protocol_by_id(i);
11742 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11743 protocol->name,
11744 protocol->short_name,
11745 protocol->filter_name,
11746 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11747 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11748 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11749 i = proto_get_next_protocol(&cookie);
11750 }
11751}
11752
11753/* Dumps the value_strings, extended value string headers, range_strings
11754 * or true/false strings for fields that have them.
11755 * There is one record per line. Fields are tab-delimited.
11756 * There are four types of records: Value String, Extended Value String Header,
11757 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11758 * the type of record.
11759 *
11760 * Note that a record will be generated only if the value_string,... is referenced
11761 * in a registered hfinfo entry.
11762 *
11763 *
11764 * Value Strings
11765 * -------------
11766 * Field 1 = 'V'
11767 * Field 2 = Field abbreviation to which this value string corresponds
11768 * Field 3 = Integer value
11769 * Field 4 = String
11770 *
11771 * Extended Value String Headers
11772 * -----------------------------
11773 * Field 1 = 'E'
11774 * Field 2 = Field abbreviation to which this extended value string header corresponds
11775 * Field 3 = Extended Value String "Name"
11776 * Field 4 = Number of entries in the associated value_string array
11777 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11778 *
11779 * Range Strings
11780 * -------------
11781 * Field 1 = 'R'
11782 * Field 2 = Field abbreviation to which this range string corresponds
11783 * Field 3 = Integer value: lower bound
11784 * Field 4 = Integer value: upper bound
11785 * Field 5 = String
11786 *
11787 * True/False Strings
11788 * ------------------
11789 * Field 1 = 'T'
11790 * Field 2 = Field abbreviation to which this true/false string corresponds
11791 * Field 3 = True String
11792 * Field 4 = False String
11793 */
11794void
11795proto_registrar_dump_values(void)
11796{
11797 header_field_info *hfinfo;
11798 int i, len, vi;
11799 const value_string *vals;
11800 const val64_string *vals64;
11801 const range_string *range;
11802 const true_false_string *tfs;
11803 const unit_name_string *units;
11804
11805 len = gpa_hfinfo.len;
11806 for (i = 0; i < len ; i++) {
11807 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11808 continue; /* This is a deregistered protocol or field */
11809
11810 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", 11810
, __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", 11810
, "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", 11810, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11811
11812 if (hfinfo->id == hf_text_only) {
11813 continue;
11814 }
11815
11816 /* ignore protocols */
11817 if (proto_registrar_is_protocol(i)) {
11818 continue;
11819 }
11820 /* process header fields */
11821#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11822 /*
11823 * If this field isn't at the head of the list of
11824 * fields with this name, skip this field - all
11825 * fields with the same name are really just versions
11826 * of the same field stored in different bits, and
11827 * should have the same type/radix/value list, and
11828 * just differ in their bit masks. (If a field isn't
11829 * a bitfield, but can be, say, 1 or 2 bytes long,
11830 * it can just be made FT_UINT16, meaning the
11831 * *maximum* length is 2 bytes, and be used
11832 * for all lengths.)
11833 */
11834 if (hfinfo->same_name_prev_id != -1)
11835 continue;
11836#endif
11837 vals = NULL((void*)0);
11838 vals64 = NULL((void*)0);
11839 range = NULL((void*)0);
11840 tfs = NULL((void*)0);
11841 units = NULL((void*)0);
11842
11843 if (hfinfo->strings != NULL((void*)0)) {
11844 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11845 (hfinfo->type == FT_CHAR ||
11846 hfinfo->type == FT_UINT8 ||
11847 hfinfo->type == FT_UINT16 ||
11848 hfinfo->type == FT_UINT24 ||
11849 hfinfo->type == FT_UINT32 ||
11850 hfinfo->type == FT_UINT40 ||
11851 hfinfo->type == FT_UINT48 ||
11852 hfinfo->type == FT_UINT56 ||
11853 hfinfo->type == FT_UINT64 ||
11854 hfinfo->type == FT_INT8 ||
11855 hfinfo->type == FT_INT16 ||
11856 hfinfo->type == FT_INT24 ||
11857 hfinfo->type == FT_INT32 ||
11858 hfinfo->type == FT_INT40 ||
11859 hfinfo->type == FT_INT48 ||
11860 hfinfo->type == FT_INT56 ||
11861 hfinfo->type == FT_INT64 ||
11862 hfinfo->type == FT_FLOAT ||
11863 hfinfo->type == FT_DOUBLE)) {
11864
11865 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11866 range = (const range_string *)hfinfo->strings;
11867 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11868 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11869 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11870 } else {
11871 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11872 }
11873 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11874 vals64 = (const val64_string *)hfinfo->strings;
11875 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11876 units = (const unit_name_string *)hfinfo->strings;
11877 } else {
11878 vals = (const value_string *)hfinfo->strings;
11879 }
11880 }
11881 else if (hfinfo->type == FT_BOOLEAN) {
11882 tfs = (const struct true_false_string *)hfinfo->strings;
11883 }
11884 }
11885
11886 /* Print value strings? */
11887 if (vals) {
11888 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11889 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11890 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11891 if (!val64_string_ext_validate(vse_p)) {
11892 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11892, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11893 continue;
11894 }
11895 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11896 printf("E\t%s\t%u\t%s\t%s\n",
11897 hfinfo->abbrev,
11898 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11899 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11900 val64_string_ext_match_type_str(vse_p));
11901 } else {
11902 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11903 if (!value_string_ext_validate(vse_p)) {
11904 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11904, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11905 continue;
11906 }
11907 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11908 printf("E\t%s\t%u\t%s\t%s\n",
11909 hfinfo->abbrev,
11910 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11911 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11912 value_string_ext_match_type_str(vse_p));
11913 }
11914 }
11915 vi = 0;
11916 while (vals[vi].strptr) {
11917 /* Print in the proper base */
11918 if (hfinfo->type == FT_CHAR) {
11919 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11920 printf("V\t%s\t'%c'\t%s\n",
11921 hfinfo->abbrev,
11922 vals[vi].value,
11923 vals[vi].strptr);
11924 } else {
11925 if (hfinfo->display == BASE_HEX) {
11926 printf("V\t%s\t'\\x%02x'\t%s\n",
11927 hfinfo->abbrev,
11928 vals[vi].value,
11929 vals[vi].strptr);
11930 }
11931 else {
11932 printf("V\t%s\t'\\%03o'\t%s\n",
11933 hfinfo->abbrev,
11934 vals[vi].value,
11935 vals[vi].strptr);
11936 }
11937 }
11938 } else {
11939 if (hfinfo->display == BASE_HEX) {
11940 printf("V\t%s\t0x%x\t%s\n",
11941 hfinfo->abbrev,
11942 vals[vi].value,
11943 vals[vi].strptr);
11944 }
11945 else {
11946 printf("V\t%s\t%u\t%s\n",
11947 hfinfo->abbrev,
11948 vals[vi].value,
11949 vals[vi].strptr);
11950 }
11951 }
11952 vi++;
11953 }
11954 }
11955 else if (vals64) {
11956 vi = 0;
11957 while (vals64[vi].strptr) {
11958 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11959 hfinfo->abbrev,
11960 vals64[vi].value,
11961 vals64[vi].strptr);
11962 vi++;
11963 }
11964 }
11965
11966 /* print range strings? */
11967 else if (range) {
11968 vi = 0;
11969 while (range[vi].strptr) {
11970 /* Print in the proper base */
11971 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
11972 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
11973 hfinfo->abbrev,
11974 range[vi].value_min,
11975 range[vi].value_max,
11976 range[vi].strptr);
11977 }
11978 else {
11979 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
11980 hfinfo->abbrev,
11981 range[vi].value_min,
11982 range[vi].value_max,
11983 range[vi].strptr);
11984 }
11985 vi++;
11986 }
11987 }
11988
11989 /* Print true/false strings? */
11990 else if (tfs) {
11991 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
11992 tfs->true_string, tfs->false_string);
11993 }
11994 /* Print unit strings? */
11995 else if (units) {
11996 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
11997 units->singular, units->plural ? units->plural : "(no plural)");
11998 }
11999 }
12000}
12001
12002/* Prints the number of registered fields.
12003 * Useful for determining an appropriate value for
12004 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12005 *
12006 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12007 * the number of fields, true otherwise.
12008 */
12009bool_Bool
12010proto_registrar_dump_fieldcount(void)
12011{
12012 uint32_t i;
12013 header_field_info *hfinfo;
12014 uint32_t deregistered_count = 0;
12015 uint32_t same_name_count = 0;
12016 uint32_t protocol_count = 0;
12017
12018 for (i = 0; i < gpa_hfinfo.len; i++) {
12019 if (gpa_hfinfo.hfi[i] == NULL((void*)0)) {
12020 deregistered_count++;
12021 continue; /* This is a deregistered protocol or header field */
12022 }
12023
12024 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", 12024
, __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", 12024
, "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", 12024, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12025
12026 if (proto_registrar_is_protocol(i))
12027 protocol_count++;
12028
12029 if (hfinfo->same_name_prev_id != -1)
12030 same_name_count++;
12031 }
12032
12033 printf("There are %u header fields registered, of which:\n"
12034 "\t%u are deregistered\n"
12035 "\t%u are protocols\n"
12036 "\t%u have the same name as another field\n\n",
12037 gpa_hfinfo.len, deregistered_count, protocol_count,
12038 same_name_count);
12039
12040 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12041 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12042 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12043 "\n");
12044
12045 printf("The header field table consumes %u KiB of memory.\n",
12046 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12047 printf("The fields themselves consume %u KiB of memory.\n",
12048 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12049
12050 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12051}
12052
12053static void
12054elastic_add_base_mapping(json_dumper *dumper)
12055{
12056 json_dumper_set_member_name(dumper, "index_patterns");
12057 json_dumper_begin_array(dumper);
12058 // The index names from write_json_index() in print.c
12059 json_dumper_value_string(dumper, "packets-*");
12060 json_dumper_end_array(dumper);
12061
12062 json_dumper_set_member_name(dumper, "settings");
12063 json_dumper_begin_object(dumper);
12064 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12065 json_dumper_value_anyf(dumper, "%d", 1000000);
12066 json_dumper_end_object(dumper);
12067}
12068
12069static char*
12070ws_type_to_elastic(unsigned type)
12071{
12072 switch(type) {
12073 case FT_INT8:
12074 return "byte";
12075 case FT_UINT8:
12076 case FT_INT16:
12077 return "short";
12078 case FT_UINT16:
12079 case FT_INT32:
12080 case FT_UINT24:
12081 case FT_INT24:
12082 return "integer";
12083 case FT_FRAMENUM:
12084 case FT_UINT32:
12085 case FT_UINT40:
12086 case FT_UINT48:
12087 case FT_UINT56:
12088 case FT_INT40:
12089 case FT_INT48:
12090 case FT_INT56:
12091 case FT_INT64:
12092 return "long";
12093 case FT_UINT64:
12094 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12095 case FT_FLOAT:
12096 return "float";
12097 case FT_DOUBLE:
12098 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12099 return "double";
12100 case FT_IPv6:
12101 case FT_IPv4:
12102 return "ip";
12103 case FT_ABSOLUTE_TIME:
12104 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12105 case FT_BOOLEAN:
12106 return "boolean";
12107 default:
12108 return NULL((void*)0);
12109 }
12110}
12111
12112static char*
12113dot_to_underscore(char* str)
12114{
12115 unsigned i;
12116 for (i = 0; i < strlen(str); i++) {
12117 if (str[i] == '.')
12118 str[i] = '_';
12119 }
12120 return str;
12121}
12122
12123/* Dumps a mapping file for ElasticSearch
12124 * This is the v1 (legacy) _template API.
12125 * At some point it may need to be updated with the composable templates
12126 * introduced in Elasticsearch 7.8 (_index_template)
12127 */
12128void
12129proto_registrar_dump_elastic(const char* filter)
12130{
12131 header_field_info *hfinfo;
12132 header_field_info *parent_hfinfo;
12133 unsigned i;
12134 bool_Bool open_object = true1;
12135 const char* prev_proto = NULL((void*)0);
12136 char* str;
12137 char** protos = NULL((void*)0);
12138 char* proto;
12139 bool_Bool found;
12140 unsigned j;
12141 char* type;
12142 char* prev_item = NULL((void*)0);
12143
12144 /* We have filtering protocols. Extract them. */
12145 if (filter) {
12146 protos = g_strsplit(filter, ",", -1);
12147 }
12148
12149 /*
12150 * To help tracking down the json tree, objects have been appended with a comment:
12151 * n.label -> where n is the indentation level and label the name of the object
12152 */
12153
12154 json_dumper dumper = {
12155 .output_file = stdoutstdout,
12156 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12157 };
12158 json_dumper_begin_object(&dumper); // 1.root
12159 elastic_add_base_mapping(&dumper);
12160
12161 json_dumper_set_member_name(&dumper, "mappings");
12162 json_dumper_begin_object(&dumper); // 2.mappings
12163
12164 json_dumper_set_member_name(&dumper, "properties");
12165 json_dumper_begin_object(&dumper); // 3.properties
12166 json_dumper_set_member_name(&dumper, "timestamp");
12167 json_dumper_begin_object(&dumper); // 4.timestamp
12168 json_dumper_set_member_name(&dumper, "type");
12169 json_dumper_value_string(&dumper, "date");
12170 json_dumper_end_object(&dumper); // 4.timestamp
12171
12172 json_dumper_set_member_name(&dumper, "layers");
12173 json_dumper_begin_object(&dumper); // 4.layers
12174 json_dumper_set_member_name(&dumper, "properties");
12175 json_dumper_begin_object(&dumper); // 5.properties
12176
12177 for (i = 0; i < gpa_hfinfo.len; i++) {
12178 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12179 continue; /* This is a deregistered protocol or header field */
12180
12181 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", 12181
, __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", 12181
, "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", 12181, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12182
12183 /*
12184 * Skip the pseudo-field for "proto_tree_add_text()" since
12185 * we don't want it in the list of filterable protocols.
12186 */
12187 if (hfinfo->id == hf_text_only)
12188 continue;
12189
12190 if (!proto_registrar_is_protocol(i)) {
12191 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", 12191
, __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", 12191
, "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", 12191
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12192
12193 /*
12194 * Skip the field if filter protocols have been set and this one's
12195 * parent is not listed.
12196 */
12197 if (protos) {
12198 found = false0;
12199 j = 0;
12200 proto = protos[0];
12201 while(proto) {
12202 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12203 found = true1;
12204 break;
12205 }
12206 j++;
12207 proto = protos[j];
12208 }
12209 if (!found)
12210 continue;
12211 }
12212
12213 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12214 json_dumper_end_object(&dumper); // 7.properties
12215 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12216 open_object = true1;
12217 }
12218
12219 prev_proto = parent_hfinfo->abbrev;
12220
12221 if (open_object) {
12222 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12223 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12224 json_dumper_set_member_name(&dumper, "properties");
12225 json_dumper_begin_object(&dumper); // 7.properties
12226 open_object = false0;
12227 }
12228 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12229 type = ws_type_to_elastic(hfinfo->type);
12230 /* when type is NULL, we have the default mapping: string */
12231 if (type) {
12232 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12233 dot_to_underscore(str);
12234 if (g_strcmp0(prev_item, str)) {
12235 json_dumper_set_member_name(&dumper, str);
12236 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12237 json_dumper_set_member_name(&dumper, "type");
12238 json_dumper_value_string(&dumper, type);
12239 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12240 }
12241 g_free(prev_item);
12242 prev_item = str;
12243 }
12244 }
12245 }
12246 g_free(prev_item);
12247
12248 if (prev_proto) {
12249 json_dumper_end_object(&dumper); // 7.properties
12250 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12251 }
12252
12253 json_dumper_end_object(&dumper); // 5.properties
12254 json_dumper_end_object(&dumper); // 4.layers
12255 json_dumper_end_object(&dumper); // 3.properties
12256 json_dumper_end_object(&dumper); // 2.mappings
12257 json_dumper_end_object(&dumper); // 1.root
12258 bool_Bool ret = json_dumper_finish(&dumper);
12259 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12259, "ret"))))
;
12260
12261 g_strfreev(protos);
12262}
12263
12264/* Dumps the contents of the registration database to stdout. An independent
12265 * program can take this output and format it into nice tables or HTML or
12266 * whatever.
12267 *
12268 * There is one record per line. Each record is either a protocol or a header
12269 * field, differentiated by the first field. The fields are tab-delimited.
12270 *
12271 * Protocols
12272 * ---------
12273 * Field 1 = 'P'
12274 * Field 2 = descriptive protocol name
12275 * Field 3 = protocol abbreviation
12276 *
12277 * Header Fields
12278 * -------------
12279 * Field 1 = 'F'
12280 * Field 2 = descriptive field name
12281 * Field 3 = field abbreviation
12282 * Field 4 = type ( textual representation of the ftenum type )
12283 * Field 5 = parent protocol abbreviation
12284 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12285 * Field 7 = bitmask: format: hex: 0x....
12286 * Field 8 = blurb describing field
12287 */
12288void
12289proto_registrar_dump_fields(void)
12290{
12291 header_field_info *hfinfo, *parent_hfinfo;
12292 int i, len;
12293 const char *enum_name;
12294 const char *base_name;
12295 const char *blurb;
12296 char width[5];
12297
12298 len = gpa_hfinfo.len;
12299 for (i = 0; i < len ; i++) {
12300 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12301 continue; /* This is a deregistered protocol or header field */
12302
12303 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", 12303
, __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", 12303
, "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", 12303, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12304
12305 /*
12306 * Skip the pseudo-field for "proto_tree_add_text()" since
12307 * we don't want it in the list of filterable fields.
12308 */
12309 if (hfinfo->id == hf_text_only)
12310 continue;
12311
12312 /* format for protocols */
12313 if (proto_registrar_is_protocol(i)) {
12314 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12315 }
12316 /* format for header fields */
12317 else {
12318 /*
12319 * If this field isn't at the head of the list of
12320 * fields with this name, skip this field - all
12321 * fields with the same name are really just versions
12322 * of the same field stored in different bits, and
12323 * should have the same type/radix/value list, and
12324 * just differ in their bit masks. (If a field isn't
12325 * a bitfield, but can be, say, 1 or 2 bytes long,
12326 * it can just be made FT_UINT16, meaning the
12327 * *maximum* length is 2 bytes, and be used
12328 * for all lengths.)
12329 */
12330 if (hfinfo->same_name_prev_id != -1)
12331 continue;
12332
12333 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", 12333
, __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", 12333
, "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", 12333
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12334
12335 enum_name = ftype_name(hfinfo->type);
12336 base_name = "";
12337
12338 if (hfinfo->type == FT_CHAR ||
12339 hfinfo->type == FT_UINT8 ||
12340 hfinfo->type == FT_UINT16 ||
12341 hfinfo->type == FT_UINT24 ||
12342 hfinfo->type == FT_UINT32 ||
12343 hfinfo->type == FT_UINT40 ||
12344 hfinfo->type == FT_UINT48 ||
12345 hfinfo->type == FT_UINT56 ||
12346 hfinfo->type == FT_UINT64 ||
12347 hfinfo->type == FT_INT8 ||
12348 hfinfo->type == FT_INT16 ||
12349 hfinfo->type == FT_INT24 ||
12350 hfinfo->type == FT_INT32 ||
12351 hfinfo->type == FT_INT40 ||
12352 hfinfo->type == FT_INT48 ||
12353 hfinfo->type == FT_INT56 ||
12354 hfinfo->type == FT_INT64) {
12355
12356 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12357 case BASE_NONE:
12358 case BASE_DEC:
12359 case BASE_HEX:
12360 case BASE_OCT:
12361 case BASE_DEC_HEX:
12362 case BASE_HEX_DEC:
12363 case BASE_CUSTOM:
12364 case BASE_PT_UDP:
12365 case BASE_PT_TCP:
12366 case BASE_PT_DCCP:
12367 case BASE_PT_SCTP:
12368 case BASE_OUI:
12369 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12370 break;
12371 default:
12372 base_name = "????";
12373 break;
12374 }
12375 } else if (hfinfo->type == FT_BOOLEAN) {
12376 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12377 snprintf(width, sizeof(width), "%d", hfinfo->display);
12378 base_name = width;
12379 }
12380
12381 blurb = hfinfo->blurb;
12382 if (blurb == NULL((void*)0))
12383 blurb = "";
12384 else if (strlen(blurb) == 0)
12385 blurb = "\"\"";
12386
12387 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12388 hfinfo->name, hfinfo->abbrev, enum_name,
12389 parent_hfinfo->abbrev, base_name,
12390 hfinfo->bitmask, blurb);
12391 }
12392 }
12393}
12394
12395/* Dumps all abbreviated field and protocol completions of the given string to
12396 * stdout. An independent program may use this for command-line tab completion
12397 * of fields.
12398 */
12399bool_Bool
12400proto_registrar_dump_field_completions(const char *prefix)
12401{
12402 header_field_info *hfinfo;
12403 int i, len;
12404 size_t prefix_len;
12405 bool_Bool matched = false0;
12406
12407 prefix_len = strlen(prefix);
12408 len = gpa_hfinfo.len;
12409 for (i = 0; i < len ; i++) {
12410 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12411 continue; /* This is a deregistered protocol or header field */
12412
12413 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", 12413
, __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", 12413
, "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", 12413, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12414
12415 /*
12416 * Skip the pseudo-field for "proto_tree_add_text()" since
12417 * we don't want it in the list of filterable fields.
12418 */
12419 if (hfinfo->id == hf_text_only)
12420 continue;
12421
12422 /* format for protocols */
12423 if (proto_registrar_is_protocol(i)) {
12424 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12425 matched = true1;
12426 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12427 }
12428 }
12429 /* format for header fields */
12430 else {
12431 /*
12432 * If this field isn't at the head of the list of
12433 * fields with this name, skip this field - all
12434 * fields with the same name are really just versions
12435 * of the same field stored in different bits, and
12436 * should have the same type/radix/value list, and
12437 * just differ in their bit masks. (If a field isn't
12438 * a bitfield, but can be, say, 1 or 2 bytes long,
12439 * it can just be made FT_UINT16, meaning the
12440 * *maximum* length is 2 bytes, and be used
12441 * for all lengths.)
12442 */
12443 if (hfinfo->same_name_prev_id != -1)
12444 continue;
12445
12446 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12447 matched = true1;
12448 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12449 }
12450 }
12451 }
12452 return matched;
12453}
12454
12455/* Dumps field types and descriptive names to stdout. An independent
12456 * program can take this output and format it into nice tables or HTML or
12457 * whatever.
12458 *
12459 * There is one record per line. The fields are tab-delimited.
12460 *
12461 * Field 1 = field type name, e.g. FT_UINT8
12462 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12463 */
12464void
12465proto_registrar_dump_ftypes(void)
12466{
12467 int fte;
12468
12469 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12470 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12471 }
12472}
12473
12474/* This function indicates whether it's possible to construct a
12475 * "match selected" display filter string for the specified field,
12476 * returns an indication of whether it's possible, and, if it's
12477 * possible and "filter" is non-null, constructs the filter and
12478 * sets "*filter" to point to it.
12479 * You do not need to [g_]free() this string since it will be automatically
12480 * freed once the next packet is dissected.
12481 */
12482static bool_Bool
12483construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12484 char **filter)
12485{
12486 const header_field_info *hfinfo;
12487 char *ptr;
12488 int buf_len;
12489 int i;
12490 int start, length, length_remaining;
12491 uint8_t c;
12492
12493 if (!finfo)
12494 return false0;
12495
12496 hfinfo = finfo->hfinfo;
12497 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12497, "hfinfo"))))
;
12498
12499 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12500 * then "the numeric value ... is not used when preparing
12501 * filters for the field in question." If it's any other
12502 * base, we'll generate the filter normally (which will
12503 * be numeric, even though the human-readable string does
12504 * work for filtering.)
12505 *
12506 * XXX - It might be nice to use fvalue_to_string_repr() in
12507 * "proto_item_fill_label()" as well, although, there, you'd
12508 * have to deal with the base *and* with resolved values for
12509 * addresses.
12510 *
12511 * Perhaps in addition to taking the repr type (DISPLAY
12512 * or DFILTER) and the display (base), fvalue_to_string_repr()
12513 * should have the the "strings" values in the header_field_info
12514 * structure for the field as a parameter, so it can have
12515 * if the field is Boolean or an enumerated integer type,
12516 * the tables used to generate human-readable values.
12517 */
12518 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12519 const char *str = NULL((void*)0);
12520
12521 switch (hfinfo->type) {
12522
12523 case FT_INT8:
12524 case FT_INT16:
12525 case FT_INT24:
12526 case FT_INT32:
12527 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12528 break;
12529
12530 case FT_CHAR:
12531 case FT_UINT8:
12532 case FT_UINT16:
12533 case FT_UINT24:
12534 case FT_UINT32:
12535 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12536 break;
12537
12538 default:
12539 break;
12540 }
12541
12542 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12543 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12544 return true1;
12545 }
12546 }
12547
12548 switch (hfinfo->type) {
12549
12550 case FT_PROTOCOL:
12551 if (filter != NULL((void*)0))
12552 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12553 break;
12554
12555 case FT_NONE:
12556 /*
12557 * If the length is 0, just match the name of the
12558 * field.
12559 *
12560 * (Also check for negative values, just in case,
12561 * as we'll cast it to an unsigned value later.)
12562 */
12563 length = finfo->length;
12564 if (length == 0) {
12565 if (filter != NULL((void*)0))
12566 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12567 break;
12568 }
12569 if (length < 0)
12570 return false0;
12571
12572 /*
12573 * This doesn't have a value, so we'd match
12574 * on the raw bytes at this address.
12575 *
12576 * Should we be allowed to access to the raw bytes?
12577 * If "edt" is NULL, the answer is "no".
12578 */
12579 if (edt == NULL((void*)0))
12580 return false0;
12581
12582 /*
12583 * Is this field part of the raw frame tvbuff?
12584 * If not, we can't use "frame[N:M]" to match
12585 * it.
12586 *
12587 * XXX - should this be frame-relative, or
12588 * protocol-relative?
12589 *
12590 * XXX - does this fallback for non-registered
12591 * fields even make sense?
12592 */
12593 if (finfo->ds_tvb != edt->tvb)
12594 return false0; /* you lose */
12595
12596 /*
12597 * Don't go past the end of that tvbuff.
12598 */
12599 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12600 if (length > length_remaining)
12601 length = length_remaining;
12602 if (length <= 0)
12603 return false0;
12604
12605 if (filter != NULL((void*)0)) {
12606 start = finfo->start;
12607 buf_len = 32 + length * 3;
12608 *filter = (char *)wmem_alloc0(NULL((void*)0), buf_len);
12609 ptr = *filter;
12610
12611 ptr += snprintf(ptr, buf_len-(ptr-*filter),
12612 "frame[%d:%d] == ", finfo->start, length);
12613 for (i=0; i<length; i++) {
12614 c = tvb_get_uint8(finfo->ds_tvb, start);
12615 start++;
12616 if (i == 0 ) {
12617 ptr += snprintf(ptr, buf_len-(ptr-*filter), "%02x", c);
12618 }
12619 else {
12620 ptr += snprintf(ptr, buf_len-(ptr-*filter), ":%02x", c);
12621 }
12622 }
12623 }
12624 break;
12625
12626 /* By default, use the fvalue's "to_string_repr" method. */
12627 default:
12628 if (filter != NULL((void*)0)) {
12629 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12630 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12631 wmem_free(NULL((void*)0), str);
12632 }
12633 break;
12634 }
12635
12636 return true1;
12637}
12638
12639/*
12640 * Returns true if we can do a "match selected" on the field, false
12641 * otherwise.
12642 */
12643bool_Bool
12644proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12645{
12646 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12647}
12648
12649/* This function attempts to construct a "match selected" display filter
12650 * string for the specified field; if it can do so, it returns a pointer
12651 * to the string, otherwise it returns NULL.
12652 *
12653 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12654 */
12655char *
12656proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12657{
12658 char *filter = NULL((void*)0);
12659
12660 if (!construct_match_selected_string(finfo, edt, &filter))
12661 {
12662 wmem_free(NULL((void*)0), filter);
12663 return NULL((void*)0);
12664 }
12665 return filter;
12666}
12667
12668/* This function is common code for all proto_tree_add_bitmask... functions.
12669 */
12670
12671static bool_Bool
12672proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12673 const int len, const int ett, int * const *fields,
12674 const int flags, bool_Bool first,
12675 bool_Bool use_parent_tree,
12676 proto_tree* tree, uint64_t value)
12677{
12678 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12679 uint64_t bitmask = 0;
12680 uint64_t tmpval;
12681 header_field_info *hf;
12682 uint32_t integer32;
12683 int bit_offset;
12684 int no_of_bits;
12685
12686 if (!*fields)
12687 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"
)
;
12688
12689 if (len < 0 || len > 8)
12690 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12691 /**
12692 * packet-frame.c uses len=0 since the value is taken from the packet
12693 * metadata, not the packet bytes. In that case, assume that all bits
12694 * in the provided value are valid.
12695 */
12696 if (len > 0) {
12697 available_bits >>= (8 - (unsigned)len)*8;
12698 }
12699
12700 if (use_parent_tree == false0)
12701 tree = proto_item_add_subtree(item, ett);
12702
12703 while (*fields) {
12704 uint64_t present_bits;
12705 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", 12705, __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", 12705
, "**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", 12705, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12706 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", 12706
, "hf->bitmask != 0", hf->abbrev))))
;
12707
12708 bitmask |= hf->bitmask;
12709
12710 /* Skip fields that aren't fully present */
12711 present_bits = available_bits & hf->bitmask;
12712 if (present_bits != hf->bitmask) {
12713 fields++;
12714 continue;
12715 }
12716
12717 switch (hf->type) {
12718 case FT_CHAR:
12719 case FT_UINT8:
12720 case FT_UINT16:
12721 case FT_UINT24:
12722 case FT_UINT32:
12723 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12724 break;
12725
12726 case FT_INT8:
12727 case FT_INT16:
12728 case FT_INT24:
12729 case FT_INT32:
12730 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12731 break;
12732
12733 case FT_UINT40:
12734 case FT_UINT48:
12735 case FT_UINT56:
12736 case FT_UINT64:
12737 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12738 break;
12739
12740 case FT_INT40:
12741 case FT_INT48:
12742 case FT_INT56:
12743 case FT_INT64:
12744 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12745 break;
12746
12747 case FT_BOOLEAN:
12748 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12749 break;
12750
12751 default:
12752 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))
12753 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))
12754 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))
12755 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))
;
12756 break;
12757 }
12758 if (flags & BMT_NO_APPEND0x01) {
12759 fields++;
12760 continue;
12761 }
12762 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12763
12764 /* XXX: README.developer and the comments have always defined
12765 * BMT_NO_INT as "only boolean flags are added to the title /
12766 * don't add non-boolean (integral) fields", but the
12767 * implementation has always added BASE_CUSTOM and fields with
12768 * value_strings, though not fields with unit_strings.
12769 * Possibly this is because some dissectors use a FT_UINT8
12770 * with a value_string for fields that should be a FT_BOOLEAN.
12771 */
12772 switch (hf->type) {
12773 case FT_CHAR:
12774 if (hf->display == BASE_CUSTOM) {
12775 char lbl[ITEM_LABEL_LENGTH240];
12776 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12777
12778 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12778, "fmtfunc"))))
;
12779 fmtfunc(lbl, (uint32_t) tmpval);
12780 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12781 hf->name, lbl);
12782 first = false0;
12783 }
12784 else if (hf->strings) {
12785 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12786 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12787 first = false0;
12788 }
12789 else if (!(flags & BMT_NO_INT0x02)) {
12790 char buf[32];
12791 const char *out;
12792
12793 if (!first) {
12794 proto_item_append_text(item, ", ");
12795 }
12796
12797 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12798 proto_item_append_text(item, "%s: %s", hf->name, out);
12799 first = false0;
12800 }
12801
12802 break;
12803
12804 case FT_UINT8:
12805 case FT_UINT16:
12806 case FT_UINT24:
12807 case FT_UINT32:
12808 if (hf->display == BASE_CUSTOM) {
12809 char lbl[ITEM_LABEL_LENGTH240];
12810 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12811
12812 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12812, "fmtfunc"))))
;
12813 fmtfunc(lbl, (uint32_t) tmpval);
12814 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12815 hf->name, lbl);
12816 first = false0;
12817 }
12818 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12819 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12820 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12821 first = false0;
12822 }
12823 else if (!(flags & BMT_NO_INT0x02)) {
12824 char buf[NUMBER_LABEL_LENGTH80];
12825 const char *out = NULL((void*)0);
12826
12827 if (!first) {
12828 proto_item_append_text(item, ", ");
12829 }
12830
12831 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12832 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12833 }
12834 if (out == NULL((void*)0)) {
12835 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12836 }
12837 proto_item_append_text(item, "%s: %s", hf->name, out);
12838 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12839 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12840 }
12841 first = false0;
12842 }
12843
12844 break;
12845
12846 case FT_INT8:
12847 case FT_INT16:
12848 case FT_INT24:
12849 case FT_INT32:
12850 integer32 = (uint32_t) tmpval;
12851 if (hf->bitmask) {
12852 no_of_bits = ws_count_ones(hf->bitmask);
12853 integer32 = ws_sign_ext32(integer32, no_of_bits);
12854 }
12855 if (hf->display == BASE_CUSTOM) {
12856 char lbl[ITEM_LABEL_LENGTH240];
12857 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12858
12859 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12859, "fmtfunc"))))
;
12860 fmtfunc(lbl, (int32_t) integer32);
12861 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12862 hf->name, lbl);
12863 first = false0;
12864 }
12865 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12866 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12867 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12868 first = false0;
12869 }
12870 else if (!(flags & BMT_NO_INT0x02)) {
12871 char buf[NUMBER_LABEL_LENGTH80];
12872 const char *out = NULL((void*)0);
12873
12874 if (!first) {
12875 proto_item_append_text(item, ", ");
12876 }
12877
12878 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12879 out = hf_try_val_to_str((int32_t) integer32, hf);
12880 }
12881 if (out == NULL((void*)0)) {
12882 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12883 }
12884 proto_item_append_text(item, "%s: %s", hf->name, out);
12885 if (hf->display & BASE_UNIT_STRING0x00001000) {
12886 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12887 }
12888 first = false0;
12889 }
12890
12891 break;
12892
12893 case FT_UINT40:
12894 case FT_UINT48:
12895 case FT_UINT56:
12896 case FT_UINT64:
12897 if (hf->display == BASE_CUSTOM) {
12898 char lbl[ITEM_LABEL_LENGTH240];
12899 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12900
12901 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12901, "fmtfunc"))))
;
12902 fmtfunc(lbl, tmpval);
12903 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12904 hf->name, lbl);
12905 first = false0;
12906 }
12907 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12908 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12909 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12910 first = false0;
12911 }
12912 else if (!(flags & BMT_NO_INT0x02)) {
12913 char buf[NUMBER_LABEL_LENGTH80];
12914 const char *out = NULL((void*)0);
12915
12916 if (!first) {
12917 proto_item_append_text(item, ", ");
12918 }
12919
12920 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12921 out = hf_try_val64_to_str(tmpval, hf);
12922 }
12923 if (out == NULL((void*)0)) {
12924 out = hfinfo_number_value_format64(hf, buf, tmpval);
12925 }
12926 proto_item_append_text(item, "%s: %s", hf->name, out);
12927 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12928 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12929 }
12930 first = false0;
12931 }
12932
12933 break;
12934
12935 case FT_INT40:
12936 case FT_INT48:
12937 case FT_INT56:
12938 case FT_INT64:
12939 if (hf->bitmask) {
12940 no_of_bits = ws_count_ones(hf->bitmask);
12941 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12942 }
12943 if (hf->display == BASE_CUSTOM) {
12944 char lbl[ITEM_LABEL_LENGTH240];
12945 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12946
12947 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12947, "fmtfunc"))))
;
12948 fmtfunc(lbl, (int64_t) tmpval);
12949 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12950 hf->name, lbl);
12951 first = false0;
12952 }
12953 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12954 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12955 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12956 first = false0;
12957 }
12958 else if (!(flags & BMT_NO_INT0x02)) {
12959 char buf[NUMBER_LABEL_LENGTH80];
12960 const char *out = NULL((void*)0);
12961
12962 if (!first) {
12963 proto_item_append_text(item, ", ");
12964 }
12965
12966 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12967 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12968 }
12969 if (out == NULL((void*)0)) {
12970 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12971 }
12972 proto_item_append_text(item, "%s: %s", hf->name, out);
12973 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12974 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12975 }
12976 first = false0;
12977 }
12978
12979 break;
12980
12981 case FT_BOOLEAN:
12982 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12983 /* If we have true/false strings, emit full - otherwise messages
12984 might look weird */
12985 const struct true_false_string *tfs =
12986 (const struct true_false_string *)hf->strings;
12987
12988 if (tmpval) {
12989 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12990 hf->name, tfs->true_string);
12991 first = false0;
12992 } else if (!(flags & BMT_NO_FALSE0x04)) {
12993 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12994 hf->name, tfs->false_string);
12995 first = false0;
12996 }
12997 } else if (hf->bitmask & value) {
12998 /* If the flag is set, show the name */
12999 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13000 first = false0;
13001 }
13002 break;
13003 default:
13004 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))
13005 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))
13006 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))
13007 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))
;
13008 break;
13009 }
13010
13011 fields++;
13012 }
13013
13014 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13015 * but then again most dissectors don't set the bitmask field for
13016 * the higher level bitmask hfi, so calculate the bitmask from the
13017 * fields present. */
13018 if (item) {
13019 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13020 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13021 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)
;
13022 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)
;
13023 }
13024 return first;
13025}
13026
13027/* This function will dissect a sequence of bytes that describe a
13028 * bitmask and supply the value of that sequence through a pointer.
13029 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13030 * to be dissected.
13031 * This field will form an expansion under which the individual fields of the
13032 * bitmask is dissected and displayed.
13033 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13034 *
13035 * fields is an array of pointers to int that lists all the fields of the
13036 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13037 * or another integer of the same type/size as hf_hdr with a mask specified.
13038 * This array is terminated by a NULL entry.
13039 *
13040 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13041 * FT_integer fields that have a value_string attached will have the
13042 * matched string displayed on the expansion line.
13043 */
13044proto_item *
13045proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13046 const unsigned offset, const int hf_hdr,
13047 const int ett, int * const *fields,
13048 const unsigned encoding, uint64_t *retval)
13049{
13050 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);
13051}
13052
13053/* This function will dissect a sequence of bytes that describe a
13054 * bitmask.
13055 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13056 * to be dissected.
13057 * This field will form an expansion under which the individual fields of the
13058 * bitmask is dissected and displayed.
13059 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13060 *
13061 * fields is an array of pointers to int that lists all the fields of the
13062 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13063 * or another integer of the same type/size as hf_hdr with a mask specified.
13064 * This array is terminated by a NULL entry.
13065 *
13066 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13067 * FT_integer fields that have a value_string attached will have the
13068 * matched string displayed on the expansion line.
13069 */
13070proto_item *
13071proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13072 const unsigned offset, const int hf_hdr,
13073 const int ett, int * const *fields,
13074 const unsigned encoding)
13075{
13076 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13077}
13078
13079/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13080 * what data is appended to the header.
13081 */
13082proto_item *
13083proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13084 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13085 uint64_t *retval)
13086{
13087 proto_item *item = NULL((void*)0);
13088 header_field_info *hf;
13089 int len;
13090 uint64_t value;
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 len = ftype_wire_size(hf->type);
13095 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13096
13097 if (parent_tree) {
13098 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13099 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13100 flags, false0, false0, NULL((void*)0), value);
13101 }
13102
13103 *retval = value;
13104 if (hf->bitmask) {
13105 /* Mask out irrelevant portions */
13106 *retval &= hf->bitmask;
13107 /* Shift bits */
13108 *retval >>= hfinfo_bitshift(hf);
13109 }
13110
13111 return item;
13112}
13113
13114/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13115 * what data is appended to the header.
13116 */
13117proto_item *
13118proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13119 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13120{
13121 proto_item *item = NULL((void*)0);
13122 header_field_info *hf;
13123 int len;
13124 uint64_t value;
13125
13126 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", 13126, __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", 13126
, "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", 13126, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13127 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", 13127, (hf)->abbrev)))
;
13128
13129 if (parent_tree) {
13130 len = ftype_wire_size(hf->type);
13131 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13132 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13133 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13134 flags, false0, false0, NULL((void*)0), value);
13135 }
13136
13137 return item;
13138}
13139
13140/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13141 can't be retrieved directly from tvb) */
13142proto_item *
13143proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13144 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13145{
13146 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13147 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13148}
13149
13150/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13151WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13152proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13153 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13154{
13155 proto_item *item = NULL((void*)0);
13156 header_field_info *hf;
13157 int len;
13158
13159 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", 13159, __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", 13159
, "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", 13159, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13160 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", 13160, (hf)->abbrev)))
;
13161 /* the proto_tree_add_uint/_uint64() calls below
13162 will fail if tvb==NULL and len!=0 */
13163 len = tvb ? ftype_wire_size(hf->type) : 0;
13164
13165 if (parent_tree) {
13166 if (len <= 4)
13167 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13168 else
13169 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13170
13171 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13172 flags, false0, false0, NULL((void*)0), value);
13173 }
13174
13175 return item;
13176}
13177
13178/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13179void
13180proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13181 const int len, int * const *fields, const unsigned encoding)
13182{
13183 uint64_t value;
13184
13185 if (tree) {
13186 value = get_uint64_value(tree, tvb, offset, len, encoding);
13187 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13188 BMT_NO_APPEND0x01, false0, true1, tree, value);
13189 }
13190}
13191
13192WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13193proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13194 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13195{
13196 uint64_t value;
13197
13198 value = get_uint64_value(tree, tvb, offset, len, encoding);
13199 if (tree) {
13200 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13201 BMT_NO_APPEND0x01, false0, true1, tree, value);
13202 }
13203 if (retval) {
13204 *retval = value;
13205 }
13206}
13207
13208WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13209proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13210 const int len, int * const *fields, const uint64_t value)
13211{
13212 if (tree) {
13213 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13214 BMT_NO_APPEND0x01, false0, true1, tree, value);
13215 }
13216}
13217
13218
13219/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13220 * This is intended to support bitmask fields whose lengths can vary, perhaps
13221 * as the underlying standard evolves over time.
13222 * With this API there is the possibility of being called to display more or
13223 * less data than the dissector was coded to support.
13224 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13225 * Thus when presented with "too much" or "too little" data, MSbits will be
13226 * ignored or MSfields sacrificed.
13227 *
13228 * Only fields for which all defined bits are available are displayed.
13229 */
13230proto_item *
13231proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13232 const unsigned offset, const unsigned len, const int hf_hdr,
13233 const int ett, int * const *fields, struct expert_field* exp,
13234 const unsigned encoding)
13235{
13236 proto_item *item = NULL((void*)0);
13237 header_field_info *hf;
13238 unsigned decodable_len;
13239 unsigned decodable_offset;
13240 uint32_t decodable_value;
13241 uint64_t value;
13242
13243 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", 13243, __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", 13243
, "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", 13243, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13244 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", 13244, (hf)->abbrev)))
;
13245
13246 decodable_offset = offset;
13247 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13248
13249 /* If we are ftype_wire_size-limited,
13250 * make sure we decode as many LSBs as possible.
13251 */
13252 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13253 decodable_offset += (len - decodable_len);
13254 }
13255
13256 if (parent_tree) {
13257 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13258 decodable_len, encoding);
13259
13260 /* The root item covers all the bytes even if we can't decode them all */
13261 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13262 decodable_value);
13263 }
13264
13265 if (decodable_len < len) {
13266 /* Dissector likely requires updating for new protocol revision */
13267 expert_add_info_format(NULL((void*)0), item, exp,
13268 "Only least-significant %d of %d bytes decoded",
13269 decodable_len, len);
13270 }
13271
13272 if (item) {
13273 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13274 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13275 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13276 }
13277
13278 return item;
13279}
13280
13281/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13282proto_item *
13283proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13284 const unsigned offset, const unsigned len,
13285 const char *name, const char *fallback,
13286 const int ett, int * const *fields,
13287 const unsigned encoding, const int flags)
13288{
13289 proto_item *item = NULL((void*)0);
13290 uint64_t value;
13291
13292 if (parent_tree) {
13293 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13294 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13295 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13296 flags, true1, false0, NULL((void*)0), value) && fallback) {
13297 /* Still at first item - append 'fallback' text if any */
13298 proto_item_append_text(item, "%s", fallback);
13299 }
13300 }
13301
13302 return item;
13303}
13304
13305proto_item *
13306proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13307 const unsigned bit_offset, const int no_of_bits,
13308 const unsigned encoding)
13309{
13310 header_field_info *hfinfo;
13311 int octet_length;
13312 int octet_offset;
13313
13314 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", 13314, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13314
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13314, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13315
13316 if (no_of_bits < 0) {
13317 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13318 }
13319 octet_length = (no_of_bits + 7) >> 3;
13320 octet_offset = bit_offset >> 3;
13321 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13322
13323 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13324 * but only after doing a bunch more work (which we can, in the common
13325 * case, shortcut here).
13326 */
13327 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13328 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", 13328
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13328, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13328, "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", 13328, __func__, "Adding %s would put more than %d 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)
; } } }
;
13329
13330 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13331}
13332
13333/*
13334 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13335 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13336 * Offset should be given in bits from the start of the tvb.
13337 */
13338
13339static proto_item *
13340_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13341 const unsigned bit_offset, const int no_of_bits,
13342 uint64_t *return_value, const unsigned encoding)
13343{
13344 int offset;
13345 unsigned length;
13346 uint8_t tot_no_bits;
13347 char *bf_str;
13348 char lbl_str[ITEM_LABEL_LENGTH240];
13349 uint64_t value = 0;
13350 uint8_t *bytes = NULL((void*)0);
13351 size_t bytes_length = 0;
13352
13353 proto_item *pi;
13354 header_field_info *hf_field;
13355
13356 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13357 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", 13357, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13357
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13357, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13358
13359 if (hf_field->bitmask != 0) {
13360 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)
13361 " 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)
13362 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)
;
13363 }
13364
13365 if (no_of_bits < 0) {
13366 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13367 } else if (no_of_bits == 0) {
13368 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)
13369 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)
;
13370 }
13371
13372 /* Byte align offset */
13373 offset = bit_offset>>3;
13374
13375 /*
13376 * Calculate the number of octets used to hold the bits
13377 */
13378 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13379 length = (tot_no_bits + 7) >> 3;
13380
13381 if (no_of_bits < 65) {
13382 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13383 } else if (hf_field->type != FT_BYTES) {
13384 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)
13385 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)
;
13386 return NULL((void*)0);
13387 }
13388
13389 /* Sign extend for signed types */
13390 switch (hf_field->type) {
13391 case FT_INT8:
13392 case FT_INT16:
13393 case FT_INT24:
13394 case FT_INT32:
13395 case FT_INT40:
13396 case FT_INT48:
13397 case FT_INT56:
13398 case FT_INT64:
13399 value = ws_sign_ext64(value, no_of_bits);
13400 break;
13401
13402 default:
13403 break;
13404 }
13405
13406 if (return_value) {
13407 *return_value = value;
13408 }
13409
13410 /* Coast clear. Try and fake it */
13411 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13412 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", 13412
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13412, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13412, "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", 13412, __func__, "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); } } }
;
13413
13414 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13415
13416 switch (hf_field->type) {
13417 case FT_BOOLEAN:
13418 /* Boolean field */
13419 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13420 "%s = %s: %s",
13421 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13422 break;
13423
13424 case FT_CHAR:
13425 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13426 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13427 break;
13428
13429 case FT_UINT8:
13430 case FT_UINT16:
13431 case FT_UINT24:
13432 case FT_UINT32:
13433 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13434 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13435 break;
13436
13437 case FT_INT8:
13438 case FT_INT16:
13439 case FT_INT24:
13440 case FT_INT32:
13441 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13442 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13443 break;
13444
13445 case FT_UINT40:
13446 case FT_UINT48:
13447 case FT_UINT56:
13448 case FT_UINT64:
13449 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13450 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13451 break;
13452
13453 case FT_INT40:
13454 case FT_INT48:
13455 case FT_INT56:
13456 case FT_INT64:
13457 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13458 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13459 break;
13460
13461 case FT_BYTES:
13462 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13463 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13464 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13465 proto_item_set_text(pi, "%s", lbl_str);
13466 return pi;
13467
13468 /* TODO: should handle FT_UINT_BYTES ? */
13469
13470 default:
13471 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))
13472 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))
13473 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))
13474 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))
;
13475 return NULL((void*)0);
13476 }
13477
13478 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13479 return pi;
13480}
13481
13482proto_item *
13483proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13484 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13485 uint64_t *return_value)
13486{
13487 proto_item *pi;
13488 int no_of_bits;
13489 int octet_offset;
13490 unsigned mask_initial_bit_offset;
13491 unsigned mask_greatest_bit_offset;
13492 unsigned octet_length;
13493 uint8_t i;
13494 char bf_str[256];
13495 char lbl_str[ITEM_LABEL_LENGTH240];
13496 uint64_t value;
13497 uint64_t composite_bitmask;
13498 uint64_t composite_bitmap;
13499
13500 header_field_info *hf_field;
13501
13502 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13503 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", 13503, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13503
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13503, "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
13504
13505 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13506 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)
13507 " 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)
13508 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)
;
13509 }
13510
13511 mask_initial_bit_offset = bit_offset % 8;
13512
13513 no_of_bits = 0;
13514 value = 0;
13515 i = 0;
13516 mask_greatest_bit_offset = 0;
13517 composite_bitmask = 0;
13518 composite_bitmap = 0;
13519
13520 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
13521 uint64_t crumb_mask, crumb_value;
13522 uint8_t crumb_end_bit_offset;
13523
13524 crumb_value = tvb_get_bits64(tvb,
13525 bit_offset + crumb_spec[i].crumb_bit_offset,
13526 crumb_spec[i].crumb_bit_length,
13527 ENC_BIG_ENDIAN0x00000000);
13528 value += crumb_value;
13529 no_of_bits += crumb_spec[i].crumb_bit_length;
13530 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", 13530
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13531
13532 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13533 octet containing the initial offset.
13534 If the mask is beyond 32 bits, then give up on bit map display.
13535 This could be improved in future, probably showing a table
13536 of 32 or 64 bits per row */
13537 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13538 crumb_end_bit_offset = mask_initial_bit_offset
13539 + crumb_spec[i].crumb_bit_offset
13540 + crumb_spec[i].crumb_bit_length;
13541 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'
13542
13543 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13544 mask_greatest_bit_offset = crumb_end_bit_offset;
13545 }
13546 /* Currently the bitmap of the crumbs are only shown if
13547 * smaller than 32 bits. Do not bother calculating the
13548 * mask if it is larger than that. */
13549 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13550 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'
13551 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13552 }
13553 }
13554 /* Shift left for the next segment */
13555 value <<= crumb_spec[++i].crumb_bit_length;
13556 }
13557
13558 /* Sign extend for signed types */
13559 switch (hf_field->type) {
13560 case FT_INT8:
13561 case FT_INT16:
13562 case FT_INT24:
13563 case FT_INT32:
13564 case FT_INT40:
13565 case FT_INT48:
13566 case FT_INT56:
13567 case FT_INT64:
13568 value = ws_sign_ext64(value, no_of_bits);
13569 break;
13570 default:
13571 break;
13572 }
13573
13574 if (return_value) {
13575 *return_value = value;
13576 }
13577
13578 /* Coast clear. Try and fake it */
13579 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13580 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", 13580
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13580, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13580, "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", 13580, __func__, "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); } } }
;
13581
13582 /* initialise the format string */
13583 bf_str[0] = '\0';
13584
13585 octet_offset = bit_offset >> 3;
13586
13587 /* Round up mask length to nearest octet */
13588 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13589 mask_greatest_bit_offset = octet_length << 3;
13590
13591 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13592 It would be a useful enhancement to eliminate this restriction. */
13593 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13594 other_decode_bitfield_value(bf_str,
13595 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13596 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13597 mask_greatest_bit_offset);
13598 } else {
13599 /* If the bitmask is too large, try to describe its contents. */
13600 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13601 }
13602
13603 switch (hf_field->type) {
13604 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13605 /* Boolean field */
13606 return proto_tree_add_boolean_format(tree, hfindex,
13607 tvb, octet_offset, octet_length, value,
13608 "%s = %s: %s",
13609 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13610 break;
13611
13612 case FT_CHAR:
13613 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13614 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13615 break;
13616
13617 case FT_UINT8:
13618 case FT_UINT16:
13619 case FT_UINT24:
13620 case FT_UINT32:
13621 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13622 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13623 break;
13624
13625 case FT_INT8:
13626 case FT_INT16:
13627 case FT_INT24:
13628 case FT_INT32:
13629 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13630 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13631 break;
13632
13633 case FT_UINT40:
13634 case FT_UINT48:
13635 case FT_UINT56:
13636 case FT_UINT64:
13637 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13638 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13639 break;
13640
13641 case FT_INT40:
13642 case FT_INT48:
13643 case FT_INT56:
13644 case FT_INT64:
13645 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13646 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13647 break;
13648
13649 default:
13650 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))
13651 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))
13652 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))
13653 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))
;
13654 return NULL((void*)0);
13655 }
13656 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13657 return pi;
13658}
13659
13660void
13661proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13662 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13663{
13664 header_field_info *hfinfo;
13665 int start = bit_offset >> 3;
13666 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13667
13668 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13669 * so that we can use the tree's memory scope in calculating the string */
13670 if (length == -1) {
13671 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13672 } else {
13673 tvb_ensure_bytes_exist(tvb, start, length);
13674 }
13675 if (!tree) return;
13676
13677 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", 13677, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13677
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13677, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13678 proto_tree_add_text_internal(tree, tvb, start, length,
13679 "%s crumb %d of %s (decoded above)",
13680 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13681 tvb_get_bits32(tvb,
13682 bit_offset,
13683 crumb_spec[crumb_index].crumb_bit_length,
13684 ENC_BIG_ENDIAN0x00000000),
13685 ENC_BIG_ENDIAN0x00000000),
13686 crumb_index,
13687 hfinfo->name);
13688}
13689
13690proto_item *
13691proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13692 const unsigned bit_offset, const int no_of_bits,
13693 uint64_t *return_value, const unsigned encoding)
13694{
13695 proto_item *item;
13696
13697 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13698 bit_offset, no_of_bits,
13699 return_value, encoding))) {
13700 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)
;
13701 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)
;
13702 }
13703 return item;
13704}
13705
13706static proto_item *
13707_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13708 tvbuff_t *tvb, const unsigned bit_offset,
13709 const int no_of_bits, void *value_ptr,
13710 const unsigned encoding, char *value_str)
13711{
13712 int offset;
13713 unsigned length;
13714 uint8_t tot_no_bits;
13715 char *str;
13716 uint64_t value = 0;
13717 header_field_info *hf_field;
13718
13719 /* We do not have to return a value, try to fake it as soon as possible */
13720 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13721 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", 13721
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13721, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13721, "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", 13721, __func__, "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); } } }
;
13722
13723 if (hf_field->bitmask != 0) {
13724 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)
13725 " 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)
13726 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)
;
13727 }
13728
13729 if (no_of_bits < 0) {
13730 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13731 } else if (no_of_bits == 0) {
13732 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)
13733 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)
;
13734 }
13735
13736 /* Byte align offset */
13737 offset = bit_offset>>3;
13738
13739 /*
13740 * Calculate the number of octets used to hold the bits
13741 */
13742 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13743 length = tot_no_bits>>3;
13744 /* If we are using part of the next octet, increase length by 1 */
13745 if (tot_no_bits & 0x07)
13746 length++;
13747
13748 if (no_of_bits < 65) {
13749 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13750 } else {
13751 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)
13752 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)
;
13753 return NULL((void*)0);
13754 }
13755
13756 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13757
13758 (void) g_strlcat(str, " = ", 256+64);
13759 (void) g_strlcat(str, hf_field->name, 256+64);
13760
13761 /*
13762 * This function does not receive an actual value but a dimensionless pointer to that value.
13763 * For this reason, the type of the header field is examined in order to determine
13764 * what kind of value we should read from this address.
13765 * The caller of this function must make sure that for the specific header field type the address of
13766 * a compatible value is provided.
13767 */
13768 switch (hf_field->type) {
13769 case FT_BOOLEAN:
13770 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13771 "%s: %s", str, value_str);
13772 break;
13773
13774 case FT_CHAR:
13775 case FT_UINT8:
13776 case FT_UINT16:
13777 case FT_UINT24:
13778 case FT_UINT32:
13779 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13780 "%s: %s", str, value_str);
13781 break;
13782
13783 case FT_UINT40:
13784 case FT_UINT48:
13785 case FT_UINT56:
13786 case FT_UINT64:
13787 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13788 "%s: %s", str, value_str);
13789 break;
13790
13791 case FT_INT8:
13792 case FT_INT16:
13793 case FT_INT24:
13794 case FT_INT32:
13795 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13796 "%s: %s", str, value_str);
13797 break;
13798
13799 case FT_INT40:
13800 case FT_INT48:
13801 case FT_INT56:
13802 case FT_INT64:
13803 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13804 "%s: %s", str, value_str);
13805 break;
13806
13807 case FT_FLOAT:
13808 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13809 "%s: %s", str, value_str);
13810 break;
13811
13812 default:
13813 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))
13814 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))
13815 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))
13816 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))
;
13817 return NULL((void*)0);
13818 }
13819}
13820
13821static proto_item *
13822proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13823 tvbuff_t *tvb, const unsigned bit_offset,
13824 const int no_of_bits, void *value_ptr,
13825 const unsigned encoding, char *value_str)
13826{
13827 proto_item *item;
13828
13829 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13830 tvb, bit_offset, no_of_bits,
13831 value_ptr, encoding, value_str))) {
13832 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)
;
13833 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)
;
13834 }
13835 return item;
13836}
13837
13838#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);
\
13839 va_start(ap, format)__builtin_va_start(ap, format); \
13840 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13841 va_end(ap)__builtin_va_end(ap);
13842
13843proto_item *
13844proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13845 tvbuff_t *tvb, const unsigned bit_offset,
13846 const int no_of_bits, uint32_t value,
13847 const unsigned encoding,
13848 const char *format, ...)
13849{
13850 va_list ap;
13851 char *dst;
13852 header_field_info *hf_field;
13853
13854 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13855
13856 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", 13856
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13856, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13856, "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", 13856, __func__, "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); } } }
;
13857
13858 switch (hf_field->type) {
13859 case FT_UINT8:
13860 case FT_UINT16:
13861 case FT_UINT24:
13862 case FT_UINT32:
13863 break;
13864
13865 default:
13866 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)
13867 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)
;
13868 return NULL((void*)0);
13869 }
13870
13871 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);
;
13872
13873 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13874}
13875
13876proto_item *
13877proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13878 tvbuff_t *tvb, const unsigned bit_offset,
13879 const int no_of_bits, uint64_t value,
13880 const unsigned encoding,
13881 const char *format, ...)
13882{
13883 va_list ap;
13884 char *dst;
13885 header_field_info *hf_field;
13886
13887 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13888
13889 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", 13889
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13889, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13889, "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", 13889, __func__, "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); } } }
;
13890
13891 switch (hf_field->type) {
13892 case FT_UINT40:
13893 case FT_UINT48:
13894 case FT_UINT56:
13895 case FT_UINT64:
13896 break;
13897
13898 default:
13899 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)
13900 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)
;
13901 return NULL((void*)0);
13902 }
13903
13904 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);
;
13905
13906 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13907}
13908
13909proto_item *
13910proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13911 tvbuff_t *tvb, const unsigned bit_offset,
13912 const int no_of_bits, float value,
13913 const unsigned encoding,
13914 const char *format, ...)
13915{
13916 va_list ap;
13917 char *dst;
13918 header_field_info *hf_field;
13919
13920 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13921
13922 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", 13922
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13922, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13922, "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", 13922, __func__, "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); } } }
;
13923
13924 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",
13924, ((hf_field))->abbrev))))
;
13925
13926 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);
;
13927
13928 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13929}
13930
13931proto_item *
13932proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13933 tvbuff_t *tvb, const unsigned bit_offset,
13934 const int no_of_bits, int32_t value,
13935 const unsigned encoding,
13936 const char *format, ...)
13937{
13938 va_list ap;
13939 char *dst;
13940 header_field_info *hf_field;
13941
13942 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13943
13944 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", 13944
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13944, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13944, "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", 13944, __func__, "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); } } }
;
13945
13946 switch (hf_field->type) {
13947 case FT_INT8:
13948 case FT_INT16:
13949 case FT_INT24:
13950 case FT_INT32:
13951 break;
13952
13953 default:
13954 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)
13955 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)
;
13956 return NULL((void*)0);
13957 }
13958
13959 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);
;
13960
13961 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13962}
13963
13964proto_item *
13965proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13966 tvbuff_t *tvb, const unsigned bit_offset,
13967 const int no_of_bits, int64_t value,
13968 const unsigned encoding,
13969 const char *format, ...)
13970{
13971 va_list ap;
13972 char *dst;
13973 header_field_info *hf_field;
13974
13975 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13976
13977 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", 13977
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13977, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13977, "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", 13977, __func__, "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); } } }
;
13978
13979 switch (hf_field->type) {
13980 case FT_INT40:
13981 case FT_INT48:
13982 case FT_INT56:
13983 case FT_INT64:
13984 break;
13985
13986 default:
13987 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)
13988 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)
;
13989 return NULL((void*)0);
13990 }
13991
13992 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);
;
13993
13994 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13995}
13996
13997proto_item *
13998proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
13999 tvbuff_t *tvb, const unsigned bit_offset,
14000 const int no_of_bits, uint64_t value,
14001 const unsigned encoding,
14002 const char *format, ...)
14003{
14004 va_list ap;
14005 char *dst;
14006 header_field_info *hf_field;
14007
14008 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14009
14010 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", 14010
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14010, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14010, "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", 14010, __func__, "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); } } }
;
14011
14012 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"
, 14012, ((hf_field))->abbrev))))
;
14013
14014 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);
;
14015
14016 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14017}
14018
14019proto_item *
14020proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14021 const unsigned bit_offset, const int no_of_chars)
14022{
14023 proto_item *pi;
14024 header_field_info *hfinfo;
14025 int byte_length;
14026 int byte_offset;
14027 char *string;
14028
14029 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14030
14031 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", 14031
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14031, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14031, "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", 14031, __func__, "Adding %s would put more than %d 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)
; } } }
;
14032
14033 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"
, 14033, ((hfinfo))->abbrev))))
;
14034
14035 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14036 byte_offset = bit_offset >> 3;
14037
14038 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14039
14040 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14041 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14041, "byte_length >= 0"
))))
;
14042 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14043
14044 return pi;
14045}
14046
14047proto_item *
14048proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14049 const unsigned bit_offset, const int no_of_chars)
14050{
14051 proto_item *pi;
14052 header_field_info *hfinfo;
14053 int byte_length;
14054 int byte_offset;
14055 char *string;
14056
14057 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14058
14059 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", 14059
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14059, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14059, "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", 14059, __func__, "Adding %s would put more than %d 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)
; } } }
;
14060
14061 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"
, 14061, ((hfinfo))->abbrev))))
;
14062
14063 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14064 byte_offset = bit_offset >> 3;
14065
14066 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14067
14068 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14069 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14069, "byte_length >= 0"
))))
;
14070 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14071
14072 return pi;
14073}
14074
14075const value_string proto_checksum_vals[] = {
14076 { PROTO_CHECKSUM_E_BAD, "Bad" },
14077 { PROTO_CHECKSUM_E_GOOD, "Good" },
14078 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14079 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14080 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14081
14082 { 0, NULL((void*)0) }
14083};
14084
14085proto_item *
14086proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14087 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14088 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14089{
14090 header_field_info *hfinfo;
14091 uint32_t checksum;
14092 uint32_t len;
14093 proto_item* ti = NULL((void*)0);
14094 proto_item* ti2;
14095 bool_Bool incorrect_checksum = true1;
14096
14097 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", 14097, __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", 14097
, "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", 14097, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14098
14099 switch (hfinfo->type) {
14100 case FT_UINT8:
14101 len = 1;
14102 break;
14103 case FT_UINT16:
14104 len = 2;
14105 break;
14106 case FT_UINT24:
14107 len = 3;
14108 break;
14109 case FT_UINT32:
14110 len = 4;
14111 break;
14112 default:
14113 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)
14114 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14115 }
14116
14117 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14118 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14119 proto_item_set_generated(ti);
14120 if (hf_checksum_status != -1) {
14121 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14122 proto_item_set_generated(ti2);
14123 }
14124 return ti;
14125 }
14126
14127 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14128 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14129 proto_item_set_generated(ti);
14130 } else {
14131 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14132 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14133 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14134 if (computed_checksum == 0) {
14135 proto_item_append_text(ti, " [correct]");
14136 if (hf_checksum_status != -1) {
14137 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14138 proto_item_set_generated(ti2);
14139 }
14140 incorrect_checksum = false0;
14141 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14142 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14143 /* XXX - This can't distinguish between "shouldbe"
14144 * 0x0000 and 0xFFFF unless we know whether there
14145 * were any nonzero bits (other than the checksum).
14146 * Protocols should not use this path if they might
14147 * have an all zero packet.
14148 * Some implementations put the wrong zero; maybe
14149 * we should have a special expert info for that?
14150 */
14151 }
14152 } else {
14153 if (checksum == computed_checksum) {
14154 proto_item_append_text(ti, " [correct]");
14155 if (hf_checksum_status != -1) {
14156 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14157 proto_item_set_generated(ti2);
14158 }
14159 incorrect_checksum = false0;
14160 }
14161 }
14162
14163 if (incorrect_checksum) {
14164 if (hf_checksum_status != -1) {
14165 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14166 proto_item_set_generated(ti2);
14167 }
14168 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14169 proto_item_append_text(ti, " [incorrect]");
14170 if (bad_checksum_expert != NULL((void*)0))
14171 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14172 } else {
14173 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14174 if (bad_checksum_expert != NULL((void*)0))
14175 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);
14176 }
14177 }
14178 } else {
14179 if (hf_checksum_status != -1) {
14180 proto_item_append_text(ti, " [unverified]");
14181 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14182 proto_item_set_generated(ti2);
14183 }
14184 }
14185 }
14186
14187 return ti;
14188}
14189
14190proto_item *
14191proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14192 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14193 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14194{
14195 header_field_info *hfinfo;
14196 uint8_t *checksum = NULL((void*)0);
14197 proto_item* ti = NULL((void*)0);
14198 proto_item* ti2;
14199 bool_Bool incorrect_checksum = true1;
14200
14201 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", 14201, __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", 14201
, "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", 14201, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14202
14203 if (hfinfo->type != FT_BYTES) {
14204 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)
14205 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
14206 }
14207
14208 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14209 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14210 proto_item_set_generated(ti);
14211 if (hf_checksum_status != -1) {
14212 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14213 proto_item_set_generated(ti2);
14214 }
14215 return ti;
14216 }
14217
14218 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14219 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14220 proto_item_set_generated(ti);
14221 } else {
14222 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
))))))
;
14223 tvb_memcpy(tvb, checksum, offset, checksum_len);
14224 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14225 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14226 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14227 if (computed_checksum == 0) {
14228 proto_item_append_text(ti, " [correct]");
14229 if (hf_checksum_status != -1) {
14230 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14231 proto_item_set_generated(ti2);
14232 }
14233 incorrect_checksum = false0;
14234 }
14235 } else {
14236 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14237 proto_item_append_text(ti, " [correct]");
14238 if (hf_checksum_status != -1) {
14239 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14240 proto_item_set_generated(ti2);
14241 }
14242 incorrect_checksum = false0;
14243 }
14244 }
14245
14246 if (incorrect_checksum) {
14247 if (hf_checksum_status != -1) {
14248 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14249 proto_item_set_generated(ti2);
14250 }
14251 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14252 proto_item_append_text(ti, " [incorrect]");
14253 if (bad_checksum_expert != NULL((void*)0))
14254 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14255 } else {
14256 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14257 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))))))
;
14258 for (size_t counter = 0; counter < checksum_len; ++counter) {
14259 snprintf(
14260 /* On ecah iteration inserts two characters */
14261 (char*)&computed_checksum_str[counter << 1],
14262 computed_checksum_str_len - (counter << 1),
14263 "%02x",
14264 computed_checksum[counter]);
14265 }
14266 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14267 if (bad_checksum_expert != NULL((void*)0))
14268 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14269 }
14270 }
14271 } else {
14272 if (hf_checksum_status != -1) {
14273 proto_item_append_text(ti, " [unverified]");
14274 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14275 proto_item_set_generated(ti2);
14276 }
14277 }
14278 }
14279
14280 return ti;
14281}
14282
14283unsigned char
14284proto_check_field_name(const char *field_name)
14285{
14286 return module_check_valid_name(field_name, false0);
14287}
14288
14289unsigned char
14290proto_check_field_name_lower(const char *field_name)
14291{
14292 return module_check_valid_name(field_name, true1);
14293}
14294
14295bool_Bool
14296tree_expanded(int tree_type)
14297{
14298 if (tree_type <= 0) {
14299 return false0;
14300 }
14301 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", 14301, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14302 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14303}
14304
14305void
14306tree_expanded_set(int tree_type, bool_Bool value)
14307{
14308 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", 14308, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14309
14310 if (value)
14311 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14312 else
14313 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14314}
14315
14316/*
14317 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14318 *
14319 * Local variables:
14320 * c-basic-offset: 8
14321 * tab-width: 8
14322 * indent-tabs-mode: t
14323 * End:
14324 *
14325 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14326 * :indentSize=8:tabSize=8:noTabs=false:
14327 */