Bug Summary

File:epan/proto.c
Warning:line 13543, 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-07-30-100434-3867-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 saved_dir_queue = NULL((void*)0);
761 }
762}
763
764void
765proto_cleanup(void)
766{
767 proto_free_deregistered_fields();
768 proto_cleanup_base();
769
770 g_slist_free(dissector_plugins);
771 dissector_plugins = NULL((void*)0);
772}
773
774static bool_Bool
775ws_pushd(const char* dir)
776{
777 //Save the current working directory
778 const char* save_wd = get_current_working_dir();
779 if (save_wd != NULL((void*)0))
780 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
781
782 //Change to the new one
783#ifdef _WIN32
784 SetCurrentDirectory(utf_8to16(dir));
785 return true1;
786#else
787 return (chdir(dir) == 0);
788#endif
789}
790
791static bool_Bool
792ws_popd(void)
793{
794 int ret = 0;
795 char* saved_wd = g_queue_pop_head(saved_dir_queue);
796 if (saved_wd == NULL((void*)0))
797 return false0;
798
799 //Restore the previous one
800#ifdef _WIN32
801 SetCurrentDirectory(utf_8to16(saved_wd));
802#else
803 ret = chdir(saved_wd);
804#endif
805 g_free(saved_wd);
806 return (ret == 0);
807}
808
809void
810proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
811{
812 if (ws_pushd(dir))
813 {
814 func(param);
815 ws_popd();
816 }
817}
818
819static bool_Bool
820// NOLINTNEXTLINE(misc-no-recursion)
821proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
822 void *data)
823{
824 proto_node *pnode = tree;
825 proto_node *child;
826 proto_node *current;
827
828 if (func(pnode, data))
829 return true1;
830
831 child = pnode->first_child;
832 while (child != NULL((void*)0)) {
833 /*
834 * The routine we call might modify the child, e.g. by
835 * freeing it, so we get the child's successor before
836 * calling that routine.
837 */
838 current = child;
839 child = current->next;
840 // We recurse here, but we're limited by prefs.gui_max_tree_depth
841 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
842 return true1;
843 }
844
845 return false0;
846}
847
848void
849proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
850 void *data)
851{
852 proto_node *node = tree;
853 proto_node *current;
854
855 if (!node)
856 return;
857
858 node = node->first_child;
859 while (node != NULL((void*)0)) {
860 current = node;
861 node = current->next;
862 func((proto_tree *)current, data);
863 }
864}
865
866static void
867free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
868{
869 GPtrArray *ptrs = (GPtrArray *)value;
870 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
871 header_field_info *hfinfo;
872
873 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", 873, __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", 873, "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", 873, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
874 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
875 /* when a field is referenced by a filter this also
876 affects the refcount for the parent protocol so we need
877 to adjust the refcount for the parent as well
878 */
879 if (hfinfo->parent != -1) {
880 header_field_info *parent_hfinfo;
881 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", 881
, __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", 881, "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", 881, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
882 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
883 }
884 hfinfo->ref_type = HF_REF_TYPE_NONE;
885 }
886
887 g_ptr_array_free(ptrs, true1);
888}
889
890static void
891proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
892{
893 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
894
895 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
896
897 if (finfo) {
898 fvalue_free(finfo->value);
899 finfo->value = NULL((void*)0);
900 }
901}
902
903void
904proto_tree_reset(proto_tree *tree)
905{
906 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
907
908 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
909
910 /* free tree data */
911 if (tree_data->interesting_hfids) {
912 /* Free all the GPtrArray's in the interesting_hfids hash. */
913 g_hash_table_foreach(tree_data->interesting_hfids,
914 free_GPtrArray_value, NULL((void*)0));
915
916 /* And then remove all values. */
917 g_hash_table_remove_all(tree_data->interesting_hfids);
918 }
919
920 /* Reset track of the number of children */
921 tree_data->count = 0;
922
923 /* Reset our loop checks */
924 tree_data->idle_count_ds_tvb = NULL((void*)0);
925 tree_data->max_start = 0;
926 tree_data->start_idle_count = 0;
927
928 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
929}
930
931/* frees the resources that the dissection a proto_tree uses */
932void
933proto_tree_free(proto_tree *tree)
934{
935 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
936
937 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
938
939 /* free tree data */
940 if (tree_data->interesting_hfids) {
941 /* Free all the GPtrArray's in the interesting_hfids hash. */
942 g_hash_table_foreach(tree_data->interesting_hfids,
943 free_GPtrArray_value, NULL((void*)0));
944
945 /* And then destroy the hash. */
946 g_hash_table_destroy(tree_data->interesting_hfids);
947 }
948
949 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)
;
950
951 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
952}
953
954/* Is the parsing being done for a visible proto_tree or an invisible one?
955 * By setting this correctly, the proto_tree creation is sped up by not
956 * having to call vsnprintf and copy strings around.
957 */
958bool_Bool
959proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
960{
961 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
962
963 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
964
965 return old_visible;
966}
967
968void
969proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
970{
971 if (tree)
972 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
973}
974
975/* Assume dissector set only its protocol fields.
976 This function is called by dissectors and allows the speeding up of filtering
977 in wireshark; if this function returns false it is safe to reset tree to NULL
978 and thus skip calling most of the expensive proto_tree_add_...()
979 functions.
980 If the tree is visible we implicitly assume the field is referenced.
981*/
982bool_Bool
983proto_field_is_referenced(proto_tree *tree, int proto_id)
984{
985 register header_field_info *hfinfo;
986
987
988 if (!tree)
989 return false0;
990
991 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
992 return true1;
993
994 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", 994, __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", 994, "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", 994, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
995 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
996 return true1;
997
998 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
999 return true1;
1000
1001 return false0;
1002}
1003
1004
1005/* Finds a record in the hfinfo array by id. */
1006header_field_info *
1007proto_registrar_get_nth(unsigned hfindex)
1008{
1009 register header_field_info *hfinfo;
1010
1011 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", 1011, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1011,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1011, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1012 return hfinfo;
1013}
1014
1015
1016/* Prefix initialization
1017 * this allows for a dissector to register a display filter name prefix
1018 * so that it can delay the initialization of the hf array as long as
1019 * possible.
1020 */
1021
1022/* compute a hash for the part before the dot of a display filter */
1023static unsigned
1024prefix_hash (const void *key) {
1025 /* end the string at the dot and compute its hash */
1026 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1027 char* c = copy;
1028 unsigned tmp;
1029
1030 for (; *c; c++) {
1031 if (*c == '.') {
1032 *c = 0;
1033 break;
1034 }
1035 }
1036
1037 tmp = wmem_str_hash(copy);
1038 g_free(copy);
1039 return tmp;
1040}
1041
1042/* are both strings equal up to the end or the dot? */
1043static gboolean
1044prefix_equal (const void *ap, const void *bp) {
1045 const char* a = (const char *)ap;
1046 const char* b = (const char *)bp;
1047
1048 do {
1049 char ac = *a++;
1050 char bc = *b++;
1051
1052 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1053
1054 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1055 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1056
1057 if (ac != bc) return FALSE(0);
1058 } while (1);
1059
1060 return FALSE(0);
1061}
1062
1063/* Register a new prefix for "delayed" initialization of field arrays */
1064void
1065proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1066 if (! prefixes ) {
1067 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1068 }
1069
1070 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1071}
1072
1073/* helper to call all prefix initializers */
1074static gboolean
1075initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1076 ((prefix_initializer_t)v)((const char *)k);
1077 return TRUE(!(0));
1078}
1079
1080/** Initialize every remaining uninitialized prefix. */
1081void
1082proto_initialize_all_prefixes(void) {
1083 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1084}
1085
1086/* Finds a record in the hfinfo array by name.
1087 * If it fails to find it in the already registered fields,
1088 * it tries to find and call an initializer in the prefixes
1089 * table and if so it looks again.
1090 */
1091
1092header_field_info *
1093proto_registrar_get_byname(const char *field_name)
1094{
1095 header_field_info *hfinfo;
1096 prefix_initializer_t pi;
1097
1098 if (!field_name)
1099 return NULL((void*)0);
1100
1101 if (g_strcmp0(field_name, last_field_name) == 0) {
1102 return last_hfinfo;
1103 }
1104
1105 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1106
1107 if (hfinfo) {
1108 g_free(last_field_name);
1109 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1110 last_hfinfo = hfinfo;
1111 return hfinfo;
1112 }
1113
1114 if (!prefixes)
1115 return NULL((void*)0);
1116
1117 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1118 pi(field_name);
1119 g_hash_table_remove(prefixes, field_name);
1120 } else {
1121 return NULL((void*)0);
1122 }
1123
1124 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1125
1126 if (hfinfo) {
1127 g_free(last_field_name);
1128 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1129 last_hfinfo = hfinfo;
1130 }
1131 return hfinfo;
1132}
1133
1134header_field_info*
1135proto_registrar_get_byalias(const char *alias_name)
1136{
1137 if (!alias_name) {
1138 return NULL((void*)0);
1139 }
1140
1141 /* Find our aliased protocol. */
1142 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1143 char *dot = strchr(an_copy, '.');
1144 if (dot) {
1145 *dot = '\0';
1146 }
1147 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1148 if (!proto_pfx) {
1149 g_free(an_copy);
1150 return NULL((void*)0);
1151 }
1152
1153 /* Construct our aliased field and look it up. */
1154 GString *filter_name = g_string_new(proto_pfx);
1155 if (dot) {
1156 g_string_append_printf(filter_name, ".%s", dot+1);
1157 }
1158 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1159 g_free(an_copy);
1160 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)))))
;
1161
1162 return hfinfo;
1163}
1164
1165int
1166proto_registrar_get_id_byname(const char *field_name)
1167{
1168 header_field_info *hfinfo;
1169
1170 hfinfo = proto_registrar_get_byname(field_name);
1171
1172 if (!hfinfo)
1173 return -1;
1174
1175 return hfinfo->id;
1176}
1177
1178static int
1179label_strcat_flags(const header_field_info *hfinfo)
1180{
1181 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1182 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1183
1184 return 0;
1185}
1186
1187static char *
1188format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1189 const uint8_t *bytes, unsigned length, size_t max_str_len)
1190{
1191 char *str = NULL((void*)0);
1192 const uint8_t *p;
1193 bool_Bool is_printable;
1194
1195 if (bytes) {
1196 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1197 /*
1198 * If all bytes are valid and printable UTF-8, show the
1199 * bytes as a string - in quotes to indicate that it's
1200 * a string.
1201 */
1202 if (isprint_utf8_string(bytes, length)) {
1203 str = wmem_strdup_printf(scope, "\"%.*s\"",
1204 (int)length, bytes);
1205 return str;
1206 }
1207 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1208 /*
1209 * Check whether all bytes are printable.
1210 */
1211 is_printable = true1;
1212 for (p = bytes; p < bytes+length; p++) {
1213 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1214 /* Not printable. */
1215 is_printable = false0;
1216 break;
1217 }
1218 }
1219
1220 /*
1221 * If all bytes are printable ASCII, show the bytes
1222 * as a string - in quotes to indicate that it's
1223 * a string.
1224 */
1225 if (is_printable) {
1226 str = wmem_strdup_printf(scope, "\"%.*s\"",
1227 (int)length, bytes);
1228 return str;
1229 }
1230 }
1231
1232 /*
1233 * Either it's not printable ASCII, or we don't care whether
1234 * it's printable ASCII; show it as hex bytes.
1235 */
1236 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1237 case SEP_DOT:
1238 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1239 break;
1240 case SEP_DASH:
1241 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1242 break;
1243 case SEP_COLON:
1244 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1245 break;
1246 case SEP_SPACE:
1247 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1248 break;
1249 case BASE_NONE:
1250 default:
1251 if (prefs.display_byte_fields_with_spaces) {
1252 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1253 } else {
1254 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1255 }
1256 break;
1257 }
1258 }
1259 else {
1260 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1261 str = wmem_strdup(scope, "<none>");
1262 } else {
1263 str = wmem_strdup(scope, "<MISSING>");
1264 }
1265 }
1266 return str;
1267}
1268
1269static char *
1270format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1271 const uint8_t *bytes, unsigned length)
1272{
1273 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1274}
1275
1276static void
1277ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1278{
1279 subtree_lvl *pushed_tree;
1280
1281 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"
, 1281, "ptvc->pushed_tree_max <= 256-8"))))
;
1282 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1283
1284 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1285 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1285, "pushed_tree != ((void*)0)"
))))
;
1286 ptvc->pushed_tree = pushed_tree;
1287}
1288
1289static void
1290ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1291{
1292 ptvc->pushed_tree = NULL((void*)0);
1293 ptvc->pushed_tree_max = 0;
1294 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", 1294, "ptvc->pushed_tree_index == 0"
))))
;
1295 ptvc->pushed_tree_index = 0;
1296}
1297
1298/* Allocates an initializes a ptvcursor_t with 3 variables:
1299 * proto_tree, tvbuff, and offset. */
1300ptvcursor_t *
1301ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, int offset)
1302{
1303 ptvcursor_t *ptvc;
1304
1305 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1306 ptvc->scope = scope;
1307 ptvc->tree = tree;
1308 ptvc->tvb = tvb;
1309 ptvc->offset = offset;
1310 ptvc->pushed_tree = NULL((void*)0);
1311 ptvc->pushed_tree_max = 0;
1312 ptvc->pushed_tree_index = 0;
1313 return ptvc;
1314}
1315
1316
1317/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1318void
1319ptvcursor_free(ptvcursor_t *ptvc)
1320{
1321 ptvcursor_free_subtree_levels(ptvc);
1322 /*g_free(ptvc);*/
1323}
1324
1325/* Returns tvbuff. */
1326tvbuff_t *
1327ptvcursor_tvbuff(ptvcursor_t *ptvc)
1328{
1329 return ptvc->tvb;
1330}
1331
1332/* Returns current offset. */
1333int
1334ptvcursor_current_offset(ptvcursor_t *ptvc)
1335{
1336 return ptvc->offset;
1337}
1338
1339proto_tree *
1340ptvcursor_tree(ptvcursor_t *ptvc)
1341{
1342 if (!ptvc)
1343 return NULL((void*)0);
1344
1345 return ptvc->tree;
1346}
1347
1348void
1349ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1350{
1351 ptvc->tree = tree;
1352}
1353
1354/* creates a subtree, sets it as the working tree and pushes the old working tree */
1355proto_tree *
1356ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1357{
1358 subtree_lvl *subtree;
1359 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1360 ptvcursor_new_subtree_levels(ptvc);
1361
1362 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1363 subtree->tree = ptvc->tree;
1364 subtree->it= NULL((void*)0);
1365 ptvc->pushed_tree_index++;
1366 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1367}
1368
1369/* pops a subtree */
1370void
1371ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1372{
1373 subtree_lvl *subtree;
1374
1375 if (ptvc->pushed_tree_index <= 0)
1376 return;
1377
1378 ptvc->pushed_tree_index--;
1379 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1380 if (subtree->it != NULL((void*)0))
1381 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1382
1383 ptvc->tree = subtree->tree;
1384}
1385
1386/* saves the current tvb offset and the item in the current subtree level */
1387static void
1388ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1389{
1390 subtree_lvl *subtree;
1391
1392 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", 1392, "ptvc->pushed_tree_index > 0"
))))
;
1393
1394 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1395 subtree->it = it;
1396 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1397}
1398
1399/* Creates a subtree and adds it to the cursor as the working tree but does not
1400 * save the old working tree */
1401proto_tree *
1402ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1403{
1404 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1405 return ptvc->tree;
1406}
1407
1408static proto_tree *
1409ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1410{
1411 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1412 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1413 ptvcursor_subtree_set_item(ptvc, it);
1414 return ptvcursor_tree(ptvc);
1415}
1416
1417/* Add an item to the tree and create a subtree
1418 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1419 * In this case, when the subtree will be closed, the parent item length will
1420 * be equal to the advancement of the cursor since the creation of the subtree.
1421 */
1422proto_tree *
1423ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1424 const unsigned encoding, int ett_subtree)
1425{
1426 proto_item *it;
1427
1428 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1429 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1430}
1431
1432static proto_item *
1433proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1434
1435/* Add a text node to the tree and create a subtree
1436 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1437 * In this case, when the subtree will be closed, the item length will be equal
1438 * to the advancement of the cursor since the creation of the subtree.
1439 */
1440proto_tree *
1441ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1442 int ett_subtree, const char *format, ...)
1443{
1444 proto_item *pi;
1445 va_list ap;
1446 header_field_info *hfinfo;
1447 proto_tree *tree;
1448
1449 tree = ptvcursor_tree(ptvc);
1450
1451 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1452
1453 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", 1453
, __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", 1453, "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", 1453, "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", 1453, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1454
1455 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1456 ptvcursor_current_offset(ptvc), length);
1457
1458 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1458, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1459
1460 va_start(ap, format)__builtin_va_start(ap, format);
1461 proto_tree_set_representation(pi, format, ap);
1462 va_end(ap)__builtin_va_end(ap);
1463
1464 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1465}
1466
1467/* Add a text-only node, leaving it to our caller to fill the text in */
1468static proto_item *
1469proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1470{
1471 proto_item *pi;
1472
1473 if (tree == NULL((void*)0))
1474 return NULL((void*)0);
1475
1476 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1477
1478 return pi;
1479}
1480
1481/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1482proto_item *
1483proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1484 const char *format, ...)
1485{
1486 proto_item *pi;
1487 va_list ap;
1488 header_field_info *hfinfo;
1489
1490 if (length == -1) {
1491 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1492 } else {
1493 tvb_ensure_bytes_exist(tvb, start, length);
1494 }
1495
1496 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1497
1498 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", 1498
, __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", 1498, "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", 1498, "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", 1498, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1499
1500 pi = proto_tree_add_text_node(tree, tvb, start, length);
1501
1502 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1502, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1503
1504 va_start(ap, format)__builtin_va_start(ap, format);
1505 proto_tree_set_representation(pi, format, ap);
1506 va_end(ap)__builtin_va_end(ap);
1507
1508 return pi;
1509}
1510
1511/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1512proto_item *
1513proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1514 int length, const char *format, va_list ap)
1515{
1516 proto_item *pi;
1517 header_field_info *hfinfo;
1518
1519 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1520 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1521 * the length to be what's in the tvbuff if length is -1, and the
1522 * minimum of length and what's in the tvbuff if not.
1523 */
1524
1525 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1526
1527 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", 1527
, __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", 1527, "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", 1527, "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", 1527, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1528
1529 pi = proto_tree_add_text_node(tree, tvb, start, length);
1530
1531 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1531, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1532
1533 proto_tree_set_representation(pi, format, ap);
1534
1535 return pi;
1536}
1537
1538/* Add a text-only node that creates a subtree underneath.
1539 */
1540proto_tree *
1541proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1542{
1543 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1544}
1545
1546/* Add a text-only node that creates a subtree underneath.
1547 */
1548proto_tree *
1549proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1550{
1551 proto_tree *pt;
1552 proto_item *pi;
1553 va_list ap;
1554
1555 va_start(ap, format)__builtin_va_start(ap, format);
1556 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1557 va_end(ap)__builtin_va_end(ap);
1558
1559 if (tree_item != NULL((void*)0))
1560 *tree_item = pi;
1561
1562 pt = proto_item_add_subtree(pi, idx);
1563
1564 return pt;
1565}
1566
1567/* Add a text-only node for debugging purposes. The caller doesn't need
1568 * to worry about tvbuff, start, or length. Debug message gets sent to
1569 * STDOUT, too */
1570proto_item *
1571proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1572{
1573 proto_item *pi;
1574 va_list ap;
1575
1576 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1577
1578 if (pi) {
1579 va_start(ap, format)__builtin_va_start(ap, format);
1580 proto_tree_set_representation(pi, format, ap);
1581 va_end(ap)__builtin_va_end(ap);
1582 }
1583 va_start(ap, format)__builtin_va_start(ap, format);
1584 vprintf(format, ap);
1585 va_end(ap)__builtin_va_end(ap);
1586 printf("\n");
1587
1588 return pi;
1589}
1590
1591proto_item *
1592proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1593{
1594 proto_item *pi;
1595 header_field_info *hfinfo;
1596
1597 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1598
1599 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", 1599
, __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", 1599, "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", 1599, "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", 1599, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1600
1601 pi = proto_tree_add_text_node(tree, tvb, start, length);
1602
1603 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1603, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1604
1605 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1606
1607 return pi;
1608}
1609
1610proto_item *
1611proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1612{
1613 proto_item *pi;
1614 header_field_info *hfinfo;
1615 char *str;
1616
1617 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1618
1619 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", 1619
, __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", 1619, "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", 1619, "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", 1619, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1620
1621 pi = proto_tree_add_text_node(tree, tvb, start, length);
1622
1623 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1623, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1624
1625 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1626 proto_item_set_text(pi, "%s", str);
1627 wmem_free(NULL((void*)0), str);
1628
1629 return pi;
1630}
1631
1632void proto_report_dissector_bug(const char *format, ...)
1633{
1634 va_list args;
1635
1636 if (wireshark_abort_on_dissector_bug) {
1637 /*
1638 * Try to have the error message show up in the crash
1639 * information.
1640 */
1641 va_start(args, format)__builtin_va_start(args, format);
1642 ws_vadd_crash_info(format, args);
1643 va_end(args)__builtin_va_end(args);
1644
1645 /*
1646 * Print the error message.
1647 */
1648 va_start(args, format)__builtin_va_start(args, format);
1649 vfprintf(stderrstderr, format, args);
1650 va_end(args)__builtin_va_end(args);
1651 putc('\n', stderrstderr);
1652
1653 /*
1654 * And crash.
1655 */
1656 abort();
1657 } else {
1658 va_start(args, format)__builtin_va_start(args, format);
1659 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1660 va_end(args)__builtin_va_end(args);
1661 }
1662}
1663
1664/* We could probably get away with changing is_error to a minimum length value. */
1665static void
1666report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1667{
1668 if (is_error) {
1669 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1670 } else {
1671 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1672 }
1673
1674 if (is_error) {
1675 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1676 }
1677}
1678
1679static uint32_t
1680get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1681{
1682 uint32_t value;
1683 bool_Bool length_error;
1684
1685 switch (length) {
1686
1687 case 1:
1688 value = tvb_get_uint8(tvb, offset);
1689 if (encoding & ENC_ZIGBEE0x40000000) {
1690 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1691 value = 0;
1692 }
1693 }
1694 break;
1695
1696 case 2:
1697 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1698 : tvb_get_ntohs(tvb, offset);
1699 if (encoding & ENC_ZIGBEE0x40000000) {
1700 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1701 value = 0;
1702 }
1703 }
1704 break;
1705
1706 case 3:
1707 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1708 : tvb_get_ntoh24(tvb, offset);
1709 break;
1710
1711 case 4:
1712 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1713 : tvb_get_ntohl(tvb, offset);
1714 break;
1715
1716 default:
1717 if (length < 1) {
1718 length_error = true1;
1719 value = 0;
1720 } else {
1721 length_error = false0;
1722 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1723 : tvb_get_ntohl(tvb, offset);
1724 }
1725 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1726 break;
1727 }
1728 return value;
1729}
1730
1731static inline uint64_t
1732get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1733{
1734 uint64_t value;
1735
1736 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1737
1738 if (length < 1 || length > 8) {
1739 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1740 }
1741
1742 return value;
1743}
1744
1745static int32_t
1746get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1747{
1748 int32_t value;
1749 bool_Bool length_error;
1750
1751 switch (length) {
1752
1753 case 1:
1754 value = tvb_get_int8(tvb, offset);
1755 break;
1756
1757 case 2:
1758 value = encoding ? tvb_get_letohis(tvb, offset)
1759 : tvb_get_ntohis(tvb, offset);
1760 break;
1761
1762 case 3:
1763 value = encoding ? tvb_get_letohi24(tvb, offset)
1764 : tvb_get_ntohi24(tvb, offset);
1765 break;
1766
1767 case 4:
1768 value = encoding ? tvb_get_letohil(tvb, offset)
1769 : tvb_get_ntohil(tvb, offset);
1770 break;
1771
1772 default:
1773 if (length < 1) {
1774 length_error = true1;
1775 value = 0;
1776 } else {
1777 length_error = false0;
1778 value = encoding ? tvb_get_letohil(tvb, offset)
1779 : tvb_get_ntohil(tvb, offset);
1780 }
1781 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1782 break;
1783 }
1784 return value;
1785}
1786
1787/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1788 * be cast-able as a int64_t. This is weird, but what the code has always done.
1789 */
1790static inline uint64_t
1791get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1792{
1793 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1794
1795 switch (length) {
1796 case 7:
1797 value = ws_sign_ext64(value, 56);
1798 break;
1799 case 6:
1800 value = ws_sign_ext64(value, 48);
1801 break;
1802 case 5:
1803 value = ws_sign_ext64(value, 40);
1804 break;
1805 case 4:
1806 value = ws_sign_ext64(value, 32);
1807 break;
1808 case 3:
1809 value = ws_sign_ext64(value, 24);
1810 break;
1811 case 2:
1812 value = ws_sign_ext64(value, 16);
1813 break;
1814 case 1:
1815 value = ws_sign_ext64(value, 8);
1816 break;
1817 }
1818
1819 return value;
1820}
1821
1822/* For FT_STRING */
1823static inline const uint8_t *
1824get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1825 int length, int *ret_length, const unsigned encoding)
1826{
1827 if (length == -1) {
1828 length = tvb_ensure_captured_length_remaining(tvb, start);
1829 }
1830 *ret_length = length;
1831 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1832}
1833
1834/* For FT_STRINGZ */
1835static inline const uint8_t *
1836get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1837 int start, int length, int *ret_length, const unsigned encoding)
1838{
1839 const uint8_t *value;
1840
1841 if (length < -1) {
1842 report_type_length_mismatch(tree, "a string", length, true1);
1843 }
1844 if (length == -1) {
1845 /* This can throw an exception */
1846 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1847 } else {
1848 /* In this case, length signifies the length of the string.
1849 *
1850 * This could either be a null-padded string, which doesn't
1851 * necessarily have a '\0' at the end, or a null-terminated
1852 * string, with a trailing '\0'. (Yes, there are cases
1853 * where you have a string that's both counted and null-
1854 * terminated.)
1855 *
1856 * In the first case, we must allocate a buffer of length
1857 * "length+1", to make room for a trailing '\0'.
1858 *
1859 * In the second case, we don't assume that there is a
1860 * trailing '\0' there, as the packet might be malformed.
1861 * (XXX - should we throw an exception if there's no
1862 * trailing '\0'?) Therefore, we allocate a buffer of
1863 * length "length+1", and put in a trailing '\0', just to
1864 * be safe.
1865 *
1866 * (XXX - this would change if we made string values counted
1867 * rather than null-terminated.)
1868 */
1869 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1870 }
1871 *ret_length = length;
1872 return value;
1873}
1874
1875/* For FT_UINT_STRING */
1876static inline const uint8_t *
1877get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1878 tvbuff_t *tvb, int start, int length, int *ret_length,
1879 const unsigned encoding)
1880{
1881 uint32_t n;
1882 const uint8_t *value;
1883
1884 /* I believe it's ok if this is called with a NULL tree */
1885 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1886 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1887 length += n;
1888 *ret_length = length;
1889 return value;
1890}
1891
1892/* For FT_STRINGZPAD */
1893static inline const uint8_t *
1894get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1895 int length, int *ret_length, const unsigned encoding)
1896{
1897 /*
1898 * XXX - currently, string values are null-
1899 * terminated, so a "zero-padded" string
1900 * isn't special. If we represent string
1901 * values as something that includes a counted
1902 * array of bytes, we'll need to strip the
1903 * trailing NULs.
1904 */
1905 if (length == -1) {
1906 length = tvb_ensure_captured_length_remaining(tvb, start);
1907 }
1908 *ret_length = length;
1909 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1910}
1911
1912/* For FT_STRINGZTRUNC */
1913static inline const uint8_t *
1914get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1915 int length, int *ret_length, const unsigned encoding)
1916{
1917 /*
1918 * XXX - currently, string values are null-
1919 * terminated, so a "zero-truncated" string
1920 * isn't special. If we represent string
1921 * values as something that includes a counted
1922 * array of bytes, we'll need to strip everything
1923 * starting with the terminating NUL.
1924 */
1925 if (length == -1) {
1926 length = tvb_ensure_captured_length_remaining(tvb, start);
1927 }
1928 *ret_length = length;
1929 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1930}
1931
1932/*
1933 * Deltas between the epochs for various non-UN*X time stamp formats and
1934 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1935 * stamp format.
1936 */
1937
1938/*
1939 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1940 * XXX - if it's OK if this is unsigned, can we just use
1941 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1942 */
1943#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1944
1945/*
1946 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1947 */
1948#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1949
1950/* this can be called when there is no tree, so tree may be null */
1951static void
1952get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1953 const int length, const unsigned encoding, nstime_t *time_stamp,
1954 const bool_Bool is_relative)
1955{
1956 uint32_t tmpsecs;
1957 uint64_t tmp64secs;
1958 uint64_t todusecs;
1959
1960 switch (encoding) {
1961
1962 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1963 /*
1964 * If the length is 16, 8-byte seconds, followed
1965 * by 8-byte fractional time in nanoseconds,
1966 * both big-endian.
1967 *
1968 * If the length is 12, 8-byte seconds, followed
1969 * by 4-byte fractional time in nanoseconds,
1970 * both big-endian.
1971 *
1972 * If the length is 8, 4-byte seconds, followed
1973 * by 4-byte fractional time in nanoseconds,
1974 * both big-endian.
1975 *
1976 * For absolute times, the seconds are seconds
1977 * since the UN*X epoch.
1978 */
1979 if (length == 16) {
1980 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1981 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1982 } else if (length == 12) {
1983 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1984 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1985 } else if (length == 8) {
1986 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1987 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1988 } else if (length == 4) {
1989 /*
1990 * Backwards compatibility.
1991 * ENC_TIME_SECS_NSECS is 0; using
1992 * ENC_BIG_ENDIAN by itself with a 4-byte
1993 * time-in-seconds value was done in the
1994 * past.
1995 */
1996 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1997 time_stamp->nsecs = 0;
1998 } else {
1999 time_stamp->secs = 0;
2000 time_stamp->nsecs = 0;
2001 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2002 }
2003 break;
2004
2005 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2006 /*
2007 * If the length is 16, 8-byte seconds, followed
2008 * by 8-byte fractional time in nanoseconds,
2009 * both little-endian.
2010 *
2011 * If the length is 12, 8-byte seconds, followed
2012 * by 4-byte fractional time in nanoseconds,
2013 * both little-endian.
2014 *
2015 * If the length is 8, 4-byte seconds, followed
2016 * by 4-byte fractional time in nanoseconds,
2017 * both little-endian.
2018 *
2019 * For absolute times, the seconds are seconds
2020 * since the UN*X epoch.
2021 */
2022 if (length == 16) {
2023 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2024 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2025 } else if (length == 12) {
2026 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2027 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2028 } else if (length == 8) {
2029 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2030 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2031 } else if (length == 4) {
2032 /*
2033 * Backwards compatibility.
2034 * ENC_TIME_SECS_NSECS is 0; using
2035 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2036 * time-in-seconds value was done in the
2037 * past.
2038 */
2039 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2040 time_stamp->nsecs = 0;
2041 } else {
2042 time_stamp->secs = 0;
2043 time_stamp->nsecs = 0;
2044 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2045 }
2046 break;
2047
2048 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2049 /*
2050 * NTP time stamp, big-endian.
2051 * Only supported for absolute times.
2052 */
2053 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2053, "!is_relative"
))))
;
2054
2055 /* We need a temporary variable here so the unsigned math
2056 * works correctly (for years > 2036 according to RFC 2030
2057 * chapter 3).
2058 *
2059 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2060 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2061 * If bit 0 is not set, the time is in the range 2036-2104 and
2062 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2063 */
2064 tmpsecs = tvb_get_ntohl(tvb, start);
2065 if ((tmpsecs & 0x80000000) != 0)
2066 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2067 else
2068 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2069
2070 if (length == 8) {
2071 tmp64secs = tvb_get_ntoh64(tvb, start);
2072 if (tmp64secs == 0) {
2073 //This is "NULL" time
2074 time_stamp->secs = 0;
2075 time_stamp->nsecs = 0;
2076 } else {
2077 /*
2078 * Convert 1/2^32s of a second to
2079 * nanoseconds.
2080 */
2081 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2082 }
2083 } else if (length == 4) {
2084 /*
2085 * Backwards compatibility.
2086 */
2087 if (tmpsecs == 0) {
2088 //This is "NULL" time
2089 time_stamp->secs = 0;
2090 }
2091 time_stamp->nsecs = 0;
2092 } else {
2093 time_stamp->secs = 0;
2094 time_stamp->nsecs = 0;
2095 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2096 }
2097 break;
2098
2099 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2100 /*
2101 * NTP time stamp, little-endian.
2102 * Only supported for absolute times.
2103 *
2104 * NTP doesn't use this, because it's an Internet format
2105 * and hence big-endian. Any implementation must decide
2106 * whether the NTP timestamp is a 64-bit unsigned fixed
2107 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2108 * with a 32-bit unsigned seconds field followed by a
2109 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2110 * the previous two).
2111 *
2112 * XXX: We do the latter, but no dissector uses this format.
2113 * OTOH, ERF timestamps do the former, so perhaps we
2114 * should switch the interpretation so that packet-erf.c
2115 * could use this directly?
2116 */
2117 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2117, "!is_relative"
))))
;
2118
2119 /* We need a temporary variable here so the unsigned math
2120 * works correctly (for years > 2036 according to RFC 2030
2121 * chapter 3).
2122 *
2123 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2124 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2125 * If bit 0 is not set, the time is in the range 2036-2104 and
2126 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2127 */
2128 tmpsecs = tvb_get_letohl(tvb, start);
2129 if ((tmpsecs & 0x80000000) != 0)
2130 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2131 else
2132 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2133
2134 if (length == 8) {
2135 tmp64secs = tvb_get_letoh64(tvb, start);
2136 if (tmp64secs == 0) {
2137 //This is "NULL" time
2138 time_stamp->secs = 0;
2139 time_stamp->nsecs = 0;
2140 } else {
2141 /*
2142 * Convert 1/2^32s of a second to
2143 * nanoseconds.
2144 */
2145 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2146 }
2147 } else if (length == 4) {
2148 /*
2149 * Backwards compatibility.
2150 */
2151 if (tmpsecs == 0) {
2152 //This is "NULL" time
2153 time_stamp->secs = 0;
2154 }
2155 time_stamp->nsecs = 0;
2156 } else {
2157 time_stamp->secs = 0;
2158 time_stamp->nsecs = 0;
2159 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2160 }
2161 break;
2162
2163 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2164 /*
2165 * S/3x0 and z/Architecture TOD clock time stamp,
2166 * big-endian. The epoch is January 1, 1900,
2167 * 00:00:00 (proleptic?) UTC.
2168 *
2169 * Only supported for absolute times.
2170 */
2171 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2171, "!is_relative"
))))
;
2172 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2172, "length == 8"
))))
;
2173
2174 if (length == 8) {
2175 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2176 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2177 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2178 } else {
2179 time_stamp->secs = 0;
2180 time_stamp->nsecs = 0;
2181 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2182 }
2183 break;
2184
2185 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2186 /*
2187 * S/3x0 and z/Architecture TOD clock time stamp,
2188 * little-endian. The epoch is January 1, 1900,
2189 * 00:00:00 (proleptic?) UTC.
2190 *
2191 * Only supported for absolute times.
2192 */
2193 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2193, "!is_relative"
))))
;
2194
2195 if (length == 8) {
2196 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2197 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2198 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2199 } else {
2200 time_stamp->secs = 0;
2201 time_stamp->nsecs = 0;
2202 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2203 }
2204 break;
2205
2206 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2207 /*
2208 * Time stamp using the same seconds/fraction format
2209 * as NTP, but with the origin of the time stamp being
2210 * the UNIX epoch rather than the NTP epoch; big-
2211 * endian.
2212 *
2213 * Only supported for absolute times.
2214 */
2215 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2215, "!is_relative"
))))
;
2216
2217 if (length == 8) {
2218 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2219 /*
2220 * Convert 1/2^32s of a second to nanoseconds.
2221 */
2222 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2223 } else {
2224 time_stamp->secs = 0;
2225 time_stamp->nsecs = 0;
2226 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2227 }
2228 break;
2229
2230 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2231 /*
2232 * Time stamp using the same seconds/fraction format
2233 * as NTP, but with the origin of the time stamp being
2234 * the UNIX epoch rather than the NTP epoch; little-
2235 * endian.
2236 *
2237 * Only supported for absolute times.
2238 *
2239 * The RTPS specification explicitly supports Little
2240 * Endian encoding. In one place, it states that its
2241 * Time_t representation "is the one defined by ...
2242 * RFC 1305", but in another explicitly defines it as
2243 * a struct consisting of an 32 bit unsigned seconds
2244 * field and a 32 bit unsigned fraction field, not a 64
2245 * bit fixed point, so we do that here.
2246 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2247 */
2248 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2248, "!is_relative"
))))
;
2249
2250 if (length == 8) {
2251 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2252 /*
2253 * Convert 1/2^32s of a second to nanoseconds.
2254 */
2255 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2256 } else {
2257 time_stamp->secs = 0;
2258 time_stamp->nsecs = 0;
2259 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2260 }
2261 break;
2262
2263 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2264 /*
2265 * MIP6 time stamp, big-endian.
2266 * A 64-bit unsigned integer field containing a timestamp. The
2267 * value indicates the number of seconds since January 1, 1970,
2268 * 00:00 UTC, by using a fixed point format. In this format, the
2269 * integer number of seconds is contained in the first 48 bits of
2270 * the field, and the remaining 16 bits indicate the number of
2271 * 1/65536 fractions of a second.
2272
2273 * Only supported for absolute times.
2274 */
2275 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2275, "!is_relative"
))))
;
2276
2277 if (length == 8) {
2278 /* We need a temporary variable here so the casting and fractions
2279 * of a second work correctly.
2280 */
2281 tmp64secs = tvb_get_ntoh48(tvb, start);
2282 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2283 tmpsecs <<= 16;
2284
2285 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2286 //This is "NULL" time
2287 time_stamp->secs = 0;
2288 time_stamp->nsecs = 0;
2289 } else {
2290 time_stamp->secs = (time_t)tmp64secs;
2291 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2292 }
2293 } else {
2294 time_stamp->secs = 0;
2295 time_stamp->nsecs = 0;
2296 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2297 }
2298 break;
2299
2300 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2301 /*
2302 * If the length is 16, 8-byte seconds, followed
2303 * by 8-byte fractional time in microseconds,
2304 * both big-endian.
2305 *
2306 * If the length is 12, 8-byte seconds, followed
2307 * by 4-byte fractional time in microseconds,
2308 * both big-endian.
2309 *
2310 * If the length is 8, 4-byte seconds, followed
2311 * by 4-byte fractional time in microseconds,
2312 * both big-endian.
2313 *
2314 * For absolute times, the seconds are seconds
2315 * since the UN*X epoch.
2316 */
2317 if (length == 16) {
2318 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2319 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2320 } else if (length == 12) {
2321 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2322 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2323 } else if (length == 8) {
2324 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2325 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2326 } else {
2327 time_stamp->secs = 0;
2328 time_stamp->nsecs = 0;
2329 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2330 }
2331 break;
2332
2333 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2334 /*
2335 * If the length is 16, 8-byte seconds, followed
2336 * by 8-byte fractional time in microseconds,
2337 * both little-endian.
2338 *
2339 * If the length is 12, 8-byte seconds, followed
2340 * by 4-byte fractional time in microseconds,
2341 * both little-endian.
2342 *
2343 * If the length is 8, 4-byte seconds, followed
2344 * by 4-byte fractional time in microseconds,
2345 * both little-endian.
2346 *
2347 * For absolute times, the seconds are seconds
2348 * since the UN*X epoch.
2349 */
2350 if (length == 16) {
2351 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2352 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2353 } else if (length == 12) {
2354 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2355 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2356 } else if (length == 8) {
2357 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2358 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2359 } else {
2360 time_stamp->secs = 0;
2361 time_stamp->nsecs = 0;
2362 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2363 }
2364 break;
2365
2366 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2367 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2368 /*
2369 * Seconds, 1 to 8 bytes.
2370 * For absolute times, it's seconds since the
2371 * UN*X epoch.
2372 */
2373 if (length >= 1 && length <= 8) {
2374 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2375 time_stamp->nsecs = 0;
2376 } else {
2377 time_stamp->secs = 0;
2378 time_stamp->nsecs = 0;
2379 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2380 }
2381 break;
2382
2383 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2384 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2385 /*
2386 * Milliseconds, 1 to 8 bytes.
2387 * For absolute times, it's milliseconds since the
2388 * UN*X epoch.
2389 */
2390 if (length >= 1 && length <= 8) {
2391 uint64_t msecs;
2392
2393 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2394 time_stamp->secs = (time_t)(msecs / 1000);
2395 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2396 } else {
2397 time_stamp->secs = 0;
2398 time_stamp->nsecs = 0;
2399 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2400 }
2401 break;
2402
2403 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2404 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2405 /*
2406 * Microseconds, 1 to 8 bytes.
2407 * For absolute times, it's microseconds since the
2408 * UN*X epoch.
2409 */
2410 if (length >= 1 && length <= 8) {
2411 uint64_t usecs;
2412
2413 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2414 time_stamp->secs = (time_t)(usecs / 1000000);
2415 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2416 } else {
2417 time_stamp->secs = 0;
2418 time_stamp->nsecs = 0;
2419 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2420 }
2421 break;
2422
2423 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2424 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2425 /*
2426 * nanoseconds, 1 to 8 bytes.
2427 * For absolute times, it's nanoseconds since the
2428 * UN*X epoch.
2429 */
2430
2431 if (length >= 1 && length <= 8) {
2432 uint64_t nsecs;
2433
2434 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2435 time_stamp->secs = (time_t)(nsecs / 1000000000);
2436 time_stamp->nsecs = (int)(nsecs % 1000000000);
2437 } else {
2438 time_stamp->secs = 0;
2439 time_stamp->nsecs = 0;
2440 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2441 }
2442 break;
2443
2444 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2445 /*
2446 * 1/64ths of a second since the UN*X epoch,
2447 * big-endian.
2448 *
2449 * Only supported for absolute times.
2450 */
2451 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2451, "!is_relative"
))))
;
2452
2453 if (length == 8) {
2454 /*
2455 * The upper 48 bits are seconds since the
2456 * UN*X epoch.
2457 */
2458 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2459 /*
2460 * The lower 16 bits are 1/2^16s of a second;
2461 * convert them to nanoseconds.
2462 *
2463 * XXX - this may give the impression of higher
2464 * precision than you actually get.
2465 */
2466 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2467 } else {
2468 time_stamp->secs = 0;
2469 time_stamp->nsecs = 0;
2470 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2471 }
2472 break;
2473
2474 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2475 /*
2476 * 1/64ths of a second since the UN*X epoch,
2477 * little-endian.
2478 *
2479 * Only supported for absolute times.
2480 */
2481 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2481, "!is_relative"
))))
;
2482
2483 if (length == 8) {
2484 /*
2485 * XXX - this is assuming that, if anybody
2486 * were ever to use this format - RFC 3971
2487 * doesn't, because that's an Internet
2488 * protocol, and those use network byte
2489 * order, i.e. big-endian - they'd treat it
2490 * as a 64-bit count of 1/2^16s of a second,
2491 * putting the upper 48 bits at the end.
2492 *
2493 * The lower 48 bits are seconds since the
2494 * UN*X epoch.
2495 */
2496 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2497 /*
2498 * The upper 16 bits are 1/2^16s of a second;
2499 * convert them to nanoseconds.
2500 *
2501 * XXX - this may give the impression of higher
2502 * precision than you actually get.
2503 */
2504 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2505 } else {
2506 time_stamp->secs = 0;
2507 time_stamp->nsecs = 0;
2508 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2509 }
2510 break;
2511
2512 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2513 /*
2514 * NTP time stamp, with 1-second resolution (i.e.,
2515 * seconds since the NTP epoch), big-endian.
2516 * Only supported for absolute times.
2517 */
2518 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2518, "!is_relative"
))))
;
2519
2520 if (length == 4) {
2521 /*
2522 * We need a temporary variable here so the unsigned math
2523 * works correctly (for years > 2036 according to RFC 2030
2524 * chapter 3).
2525 *
2526 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2527 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2528 * If bit 0 is not set, the time is in the range 2036-2104 and
2529 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2530 */
2531 tmpsecs = tvb_get_ntohl(tvb, start);
2532 if ((tmpsecs & 0x80000000) != 0)
2533 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2534 else
2535 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2536 time_stamp->nsecs = 0;
2537 } else {
2538 time_stamp->secs = 0;
2539 time_stamp->nsecs = 0;
2540 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2541 }
2542 break;
2543
2544 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2545 /*
2546 * NTP time stamp, with 1-second resolution (i.e.,
2547 * seconds since the NTP epoch), little-endian.
2548 * Only supported for absolute times.
2549 */
2550 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2550, "!is_relative"
))))
;
2551
2552 /*
2553 * We need a temporary variable here so the unsigned math
2554 * works correctly (for years > 2036 according to RFC 2030
2555 * chapter 3).
2556 *
2557 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2558 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2559 * If bit 0 is not set, the time is in the range 2036-2104 and
2560 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2561 */
2562 if (length == 4) {
2563 tmpsecs = tvb_get_letohl(tvb, start);
2564 if ((tmpsecs & 0x80000000) != 0)
2565 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2566 else
2567 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2568 time_stamp->nsecs = 0;
2569 } else {
2570 time_stamp->secs = 0;
2571 time_stamp->nsecs = 0;
2572 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2573 }
2574 break;
2575
2576 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2577 /*
2578 * Milliseconds, 6 to 8 bytes.
2579 * For absolute times, it's milliseconds since the
2580 * NTP epoch.
2581 *
2582 * ETSI TS 129.274 8.119 defines this as:
2583 * "a 48 bit unsigned integer in network order format
2584 * ...encoded as the number of milliseconds since
2585 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2586 * rounded value of 1000 x the value of the 64-bit
2587 * timestamp (Seconds + (Fraction / (1<<32))) defined
2588 * in clause 6 of IETF RFC 5905."
2589 *
2590 * Taken literally, the part after "i.e." would
2591 * mean that the value rolls over before reaching
2592 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2593 * when the 64 bit timestamp rolls over, and we have
2594 * to pick an NTP Era equivalence class to support
2595 * (such as 1968-01-20 to 2104-02-06).
2596 *
2597 * OTOH, the extra room might be used to store Era
2598 * information instead, in which case times until
2599 * 10819-08-03 can be represented with 6 bytes without
2600 * ambiguity. We handle both implementations, and assume
2601 * that times before 1968-01-20 are not represented.
2602 *
2603 * Only 6 bytes or more makes sense as an absolute
2604 * time. 5 bytes or fewer could express a span of
2605 * less than 35 years, either 1900-1934 or 2036-2070.
2606 */
2607 if (length >= 6 && length <= 8) {
2608 uint64_t msecs;
2609
2610 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2611 tmp64secs = (msecs / 1000);
2612 /*
2613 * Assume that times in the first half of NTP
2614 * Era 0 really represent times in the NTP
2615 * Era 1.
2616 */
2617 if (tmp64secs >= 0x80000000)
2618 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2619 else
2620 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2621 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2622 }
2623 else {
2624 time_stamp->secs = 0;
2625 time_stamp->nsecs = 0;
2626 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2627 }
2628 break;
2629
2630 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2631 /*
2632 * MP4 file time stamps, big-endian.
2633 * Only supported for absolute times.
2634 */
2635 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2635, "!is_relative"
))))
;
2636
2637 if (length == 8) {
2638 tmp64secs = tvb_get_ntoh64(tvb, start);
2639 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2640 time_stamp->nsecs = 0;
2641 } else if (length == 4) {
2642 tmpsecs = tvb_get_ntohl(tvb, start);
2643 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2644 time_stamp->nsecs = 0;
2645 } else {
2646 time_stamp->secs = 0;
2647 time_stamp->nsecs = 0;
2648 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2649 }
2650 break;
2651
2652 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2653 /*
2654 * Zigbee ZCL time stamps, big-endian.
2655 * Only supported for absolute times.
2656 */
2657 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2657, "!is_relative"
))))
;
2658
2659 if (length == 8) {
2660 tmp64secs = tvb_get_ntoh64(tvb, start);
2661 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);
2662 time_stamp->nsecs = 0;
2663 } else if (length == 4) {
2664 tmpsecs = tvb_get_ntohl(tvb, start);
2665 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2666 time_stamp->nsecs = 0;
2667 } else {
2668 time_stamp->secs = 0;
2669 time_stamp->nsecs = 0;
2670 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2671 }
2672 break;
2673
2674 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2675 /*
2676 * Zigbee ZCL time stamps, little-endian.
2677 * Only supported for absolute times.
2678 */
2679 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2679, "!is_relative"
))))
;
2680
2681 if (length == 8) {
2682 tmp64secs = tvb_get_letoh64(tvb, start);
2683 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);
2684 time_stamp->nsecs = 0;
2685 } else if (length == 4) {
2686 tmpsecs = tvb_get_letohl(tvb, start);
2687 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2688 time_stamp->nsecs = 0;
2689 } else {
2690 time_stamp->secs = 0;
2691 time_stamp->nsecs = 0;
2692 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2693 }
2694 break;
2695
2696 default:
2697 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2697))
;
2698 break;
2699 }
2700}
2701
2702static void
2703tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2704{
2705 const header_field_info *hfinfo = fi->hfinfo;
2706
2707 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2708 GPtrArray *ptrs = NULL((void*)0);
2709
2710 if (tree_data->interesting_hfids == NULL((void*)0)) {
2711 /* Initialize the hash because we now know that it is needed */
2712 tree_data->interesting_hfids =
2713 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2714 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2715 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2716 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2717 }
2718
2719 if (!ptrs) {
2720 /* First element triggers the creation of pointer array */
2721 ptrs = g_ptr_array_new();
2722 g_hash_table_insert(tree_data->interesting_hfids,
2723 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2724 }
2725
2726 g_ptr_array_add(ptrs, fi);
2727 }
2728}
2729
2730
2731/*
2732 * Validates that field length bytes are available starting from
2733 * start (pos/neg). Throws an exception if they aren't.
2734 */
2735static void
2736test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2737 int start, int length, const unsigned encoding)
2738{
2739 int size = length;
2740
2741 if (!tvb)
2742 return;
2743
2744 if ((hfinfo->type == FT_STRINGZ) ||
2745 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2746 (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
))
))) {
2747 /* If we're fetching until the end of the TVB, only validate
2748 * that the offset is within range.
2749 */
2750 if (length == -1)
2751 size = 0;
2752 }
2753
2754 tvb_ensure_bytes_exist(tvb, start, size);
2755}
2756
2757static void
2758detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2759{
2760 bool_Bool found_stray_character = false0;
2761
2762 if (!string)
2763 return;
2764
2765 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2766 case ENC_ASCII0x00000000:
2767 case ENC_UTF_80x00000002:
2768 for (int i = (int)strlen(string); i < length; i++) {
2769 if (string[i] != '\0') {
2770 found_stray_character = true1;
2771 break;
2772 }
2773 }
2774 break;
2775
2776 default:
2777 break;
2778 }
2779
2780 if (found_stray_character) {
2781 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2782 }
2783}
2784
2785static void
2786free_fvalue_cb(void *data)
2787{
2788 fvalue_t *fv = (fvalue_t*)data;
2789 fvalue_free(fv);
2790}
2791
2792/* Add an item to a proto_tree, using the text label registered to that item;
2793 the item is extracted from the tvbuff handed to it. */
2794static proto_item *
2795proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2796 tvbuff_t *tvb, int start, int length,
2797 unsigned encoding)
2798{
2799 proto_item *pi;
2800 uint32_t value, n;
2801 uint64_t value64;
2802 ws_in4_addr ipv4_value;
2803 float floatval;
2804 double doubleval;
2805 const char *stringval = NULL((void*)0);
2806 nstime_t time_stamp;
2807 bool_Bool length_error;
2808
2809 /* Ensure that the newly created fvalue_t is freed if we throw an
2810 * exception before adding it to the tree. (gcc creates clobbering
2811 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2812 * XXX: Move the new_field_info() call inside here?
2813 */
2814 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))
;
2815
2816 switch (new_fi->hfinfo->type) {
2817 case FT_NONE:
2818 /* no value to set for FT_NONE */
2819 break;
2820
2821 case FT_PROTOCOL:
2822 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2823 break;
2824
2825 case FT_BYTES:
2826 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2827 break;
2828
2829 case FT_UINT_BYTES:
2830 n = get_uint_value(tree, tvb, start, length, encoding);
2831 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2832
2833 /* Instead of calling proto_item_set_len(), since we don't yet
2834 * have a proto_item, we set the field_info's length ourselves. */
2835 new_fi->length = n + length;
2836 break;
2837
2838 case FT_BOOLEAN:
2839 /*
2840 * Map all non-zero values to little-endian for
2841 * backwards compatibility.
2842 */
2843 if (encoding)
2844 encoding = ENC_LITTLE_ENDIAN0x80000000;
2845 proto_tree_set_boolean(new_fi,
2846 get_uint64_value(tree, tvb, start, length, encoding));
2847 break;
2848
2849 case FT_CHAR:
2850 /* XXX - make these just FT_UINT? */
2851 case FT_UINT8:
2852 case FT_UINT16:
2853 case FT_UINT24:
2854 case FT_UINT32:
2855 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2856 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2857 value = (uint32_t)value64;
2858 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2859 new_fi->flags |= FI_VARINT0x00040000;
2860 }
2861 }
2862 else {
2863 /*
2864 * Map all non-zero values to little-endian for
2865 * backwards compatibility.
2866 */
2867 if (encoding)
2868 encoding = ENC_LITTLE_ENDIAN0x80000000;
2869
2870 value = get_uint_value(tree, tvb, start, length, encoding);
2871 }
2872 proto_tree_set_uint(new_fi, value);
2873 break;
2874
2875 case FT_UINT40:
2876 case FT_UINT48:
2877 case FT_UINT56:
2878 case FT_UINT64:
2879 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2880 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2881 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2882 new_fi->flags |= FI_VARINT0x00040000;
2883 }
2884 }
2885 else {
2886 /*
2887 * Map all other non-zero values to little-endian for
2888 * backwards compatibility.
2889 */
2890 if (encoding)
2891 encoding = ENC_LITTLE_ENDIAN0x80000000;
2892
2893 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2894 }
2895 proto_tree_set_uint64(new_fi, value64);
2896 break;
2897
2898 /* XXX - make these just FT_INT? */
2899 case FT_INT8:
2900 case FT_INT16:
2901 case FT_INT24:
2902 case FT_INT32:
2903 /*
2904 * Map all non-zero values to little-endian for
2905 * backwards compatibility.
2906 */
2907 if (encoding)
2908 encoding = ENC_LITTLE_ENDIAN0x80000000;
2909 proto_tree_set_int(new_fi,
2910 get_int_value(tree, tvb, start, length, encoding));
2911 break;
2912
2913 case FT_INT40:
2914 case FT_INT48:
2915 case FT_INT56:
2916 case FT_INT64:
2917 /*
2918 * Map all non-zero values to little-endian for
2919 * backwards compatibility.
2920 */
2921 if (encoding)
2922 encoding = ENC_LITTLE_ENDIAN0x80000000;
2923 proto_tree_set_int64(new_fi,
2924 get_int64_value(tree, tvb, start, length, encoding));
2925 break;
2926
2927 case FT_IPv4:
2928 /*
2929 * Map all non-zero values to little-endian for
2930 * backwards compatibility.
2931 */
2932 if (encoding)
2933 encoding = ENC_LITTLE_ENDIAN0x80000000;
2934 if (length != FT_IPv4_LEN4) {
2935 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2936 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2937 }
2938 ipv4_value = tvb_get_ipv4(tvb, start);
2939 /*
2940 * NOTE: to support code written when
2941 * proto_tree_add_item() took a bool as its
2942 * last argument, with false meaning "big-endian"
2943 * and true meaning "little-endian", we treat any
2944 * non-zero value of "encoding" as meaning
2945 * "little-endian".
2946 */
2947 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);
2948 break;
2949
2950 case FT_IPXNET:
2951 if (length != FT_IPXNET_LEN4) {
2952 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2953 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2954 }
2955 proto_tree_set_ipxnet(new_fi,
2956 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2957 break;
2958
2959 case FT_IPv6:
2960 if (length != FT_IPv6_LEN16) {
2961 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2962 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2963 }
2964 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2965 break;
2966
2967 case FT_FCWWN:
2968 if (length != FT_FCWWN_LEN8) {
2969 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2970 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2971 }
2972 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2973 break;
2974
2975 case FT_AX25:
2976 if (length != 7) {
2977 length_error = length < 7 ? true1 : false0;
2978 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2979 }
2980 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2981 break;
2982
2983 case FT_VINES:
2984 if (length != VINES_ADDR_LEN6) {
2985 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
2986 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2987 }
2988 proto_tree_set_vines_tvb(new_fi, tvb, start);
2989 break;
2990
2991 case FT_ETHER:
2992 if (length != FT_ETHER_LEN6) {
2993 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
2994 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2995 }
2996 proto_tree_set_ether_tvb(new_fi, tvb, start);
2997 break;
2998
2999 case FT_EUI64:
3000 /*
3001 * Map all non-zero values to little-endian for
3002 * backwards compatibility.
3003 */
3004 if (encoding)
3005 encoding = ENC_LITTLE_ENDIAN0x80000000;
3006 if (length != FT_EUI64_LEN8) {
3007 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3008 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3009 }
3010 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3011 break;
3012 case FT_GUID:
3013 /*
3014 * Map all non-zero values to little-endian for
3015 * backwards compatibility.
3016 */
3017 if (encoding)
3018 encoding = ENC_LITTLE_ENDIAN0x80000000;
3019 if (length != FT_GUID_LEN16) {
3020 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3021 report_type_length_mismatch(tree, "a GUID", length, length_error);
3022 }
3023 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3024 break;
3025
3026 case FT_OID:
3027 case FT_REL_OID:
3028 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3029 break;
3030
3031 case FT_SYSTEM_ID:
3032 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3033 break;
3034
3035 case FT_FLOAT:
3036 /*
3037 * NOTE: to support code written when
3038 * proto_tree_add_item() took a bool as its
3039 * last argument, with false meaning "big-endian"
3040 * and true meaning "little-endian", we treat any
3041 * non-zero value of "encoding" as meaning
3042 * "little-endian".
3043 *
3044 * At some point in the future, we might
3045 * support non-IEEE-binary floating-point
3046 * formats in the encoding as well
3047 * (IEEE decimal, System/3x0, VAX).
3048 */
3049 if (encoding)
3050 encoding = ENC_LITTLE_ENDIAN0x80000000;
3051 if (length != 4) {
3052 length_error = length < 4 ? true1 : false0;
3053 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3054 }
3055 if (encoding)
3056 floatval = tvb_get_letohieee_float(tvb, start);
3057 else
3058 floatval = tvb_get_ntohieee_float(tvb, start);
3059 proto_tree_set_float(new_fi, floatval);
3060 break;
3061
3062 case FT_DOUBLE:
3063 /*
3064 * NOTE: to support code written when
3065 * proto_tree_add_item() took a bool as its
3066 * last argument, with false meaning "big-endian"
3067 * and true meaning "little-endian", we treat any
3068 * non-zero value of "encoding" as meaning
3069 * "little-endian".
3070 *
3071 * At some point in the future, we might
3072 * support non-IEEE-binary floating-point
3073 * formats in the encoding as well
3074 * (IEEE decimal, System/3x0, VAX).
3075 */
3076 if (encoding == true1)
3077 encoding = ENC_LITTLE_ENDIAN0x80000000;
3078 if (length != 8) {
3079 length_error = length < 8 ? true1 : false0;
3080 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3081 }
3082 if (encoding)
3083 doubleval = tvb_get_letohieee_double(tvb, start);
3084 else
3085 doubleval = tvb_get_ntohieee_double(tvb, start);
3086 proto_tree_set_double(new_fi, doubleval);
3087 break;
3088
3089 case FT_STRING:
3090 stringval = get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3091 tvb, start, length, &length, encoding);
3092 proto_tree_set_string(new_fi, stringval);
3093
3094 /* Instead of calling proto_item_set_len(), since we
3095 * don't yet have a proto_item, we set the
3096 * field_info's length ourselves.
3097 *
3098 * XXX - our caller can't use that length to
3099 * advance an offset unless they arrange that
3100 * there always be a protocol tree into which
3101 * we're putting this item.
3102 */
3103 new_fi->length = length;
3104 break;
3105
3106 case FT_STRINGZ:
3107 stringval = get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3108 tree, tvb, start, length, &length, encoding);
3109 proto_tree_set_string(new_fi, stringval);
3110
3111 /* Instead of calling proto_item_set_len(),
3112 * since we don't yet have a proto_item, we
3113 * set the field_info's length ourselves.
3114 *
3115 * XXX - our caller can't use that length to
3116 * advance an offset unless they arrange that
3117 * there always be a protocol tree into which
3118 * we're putting this item.
3119 */
3120 new_fi->length = length;
3121 break;
3122
3123 case FT_UINT_STRING:
3124 /*
3125 * NOTE: to support code written when
3126 * proto_tree_add_item() took a bool as its
3127 * last argument, with false meaning "big-endian"
3128 * and true meaning "little-endian", if the
3129 * encoding value is true, treat that as
3130 * ASCII with a little-endian length.
3131 *
3132 * This won't work for code that passes
3133 * arbitrary non-zero values; that code
3134 * will need to be fixed.
3135 */
3136 if (encoding == true1)
3137 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3138 stringval = get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3139 tree, tvb, start, length, &length, encoding);
3140 proto_tree_set_string(new_fi, stringval);
3141
3142 /* Instead of calling proto_item_set_len(), since we
3143 * don't yet have a proto_item, we set the
3144 * field_info's length ourselves.
3145 *
3146 * XXX - our caller can't use that length to
3147 * advance an offset unless they arrange that
3148 * there always be a protocol tree into which
3149 * we're putting this item.
3150 */
3151 new_fi->length = length;
3152 break;
3153
3154 case FT_STRINGZPAD:
3155 stringval = get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3156 tvb, start, length, &length, encoding);
3157 proto_tree_set_string(new_fi, stringval);
3158
3159 /* Instead of calling proto_item_set_len(), since we
3160 * don't yet have a proto_item, we set the
3161 * field_info's length ourselves.
3162 *
3163 * XXX - our caller can't use that length to
3164 * advance an offset unless they arrange that
3165 * there always be a protocol tree into which
3166 * we're putting this item.
3167 */
3168 new_fi->length = length;
3169 break;
3170
3171 case FT_STRINGZTRUNC:
3172 stringval = get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3173 tvb, start, length, &length, encoding);
3174 proto_tree_set_string(new_fi, stringval);
3175
3176 /* Instead of calling proto_item_set_len(), since we
3177 * don't yet have a proto_item, we set the
3178 * field_info's length ourselves.
3179 *
3180 * XXX - our caller can't use that length to
3181 * advance an offset unless they arrange that
3182 * there always be a protocol tree into which
3183 * we're putting this item.
3184 */
3185 new_fi->length = length;
3186 break;
3187
3188 case FT_ABSOLUTE_TIME:
3189 /*
3190 * Absolute times can be in any of a number of
3191 * formats, and they can be big-endian or
3192 * little-endian.
3193 *
3194 * Historically FT_TIMEs were only timespecs;
3195 * the only question was whether they were stored
3196 * in big- or little-endian format.
3197 *
3198 * For backwards compatibility, we interpret an
3199 * encoding of 1 as meaning "little-endian timespec",
3200 * so that passing true is interpreted as that.
3201 */
3202 if (encoding == true1)
3203 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3204
3205 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3206
3207 proto_tree_set_time(new_fi, &time_stamp);
3208 break;
3209
3210 case FT_RELATIVE_TIME:
3211 /*
3212 * Relative times can be in any of a number of
3213 * formats, and they can be big-endian or
3214 * little-endian.
3215 *
3216 * Historically FT_TIMEs were only timespecs;
3217 * the only question was whether they were stored
3218 * in big- or little-endian format.
3219 *
3220 * For backwards compatibility, we interpret an
3221 * encoding of 1 as meaning "little-endian timespec",
3222 * so that passing true is interpreted as that.
3223 */
3224 if (encoding == true1)
3225 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3226
3227 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3228
3229 proto_tree_set_time(new_fi, &time_stamp);
3230 break;
3231 case FT_IEEE_11073_SFLOAT:
3232 if (encoding)
3233 encoding = ENC_LITTLE_ENDIAN0x80000000;
3234 if (length != 2) {
3235 length_error = length < 2 ? true1 : false0;
3236 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3237 }
3238
3239 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3240
3241 break;
3242 case FT_IEEE_11073_FLOAT:
3243 if (encoding)
3244 encoding = ENC_LITTLE_ENDIAN0x80000000;
3245 if (length != 4) {
3246 length_error = length < 4 ? true1 : false0;
3247 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3248 }
3249 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3250
3251 break;
3252 default:
3253 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))
3254 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))
3255 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))
3256 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))
;
3257 break;
3258 }
3259 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)
;
3260
3261 /* Don't add new node to proto_tree until now so that any exceptions
3262 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3263 /* XXX. wouldn't be better to add this item to tree, with some special
3264 * flag (FI_EXCEPTION?) to know which item caused exception? For
3265 * strings and bytes, we would have to set new_fi->value to something
3266 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3267 * could handle NULL values. */
3268 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3269 pi = proto_tree_add_node(tree, new_fi);
3270
3271 switch (new_fi->hfinfo->type) {
3272
3273 case FT_STRING:
3274 /* XXX: trailing stray character detection should be done
3275 * _before_ conversion to UTF-8, because conversion can change
3276 * the length, or else get_string_length should return a value
3277 * for the "length in bytes of the string after conversion
3278 * including internal nulls." (Noting that we do, for other
3279 * reasons, still need the "length in bytes in the field",
3280 * especially for FT_STRINGZ.)
3281 *
3282 * This is true even for ASCII and UTF-8, because
3283 * substituting REPLACEMENT CHARACTERS for illegal characters
3284 * can also do so (and for UTF-8 possibly even make the
3285 * string _shorter_).
3286 */
3287 detect_trailing_stray_characters(encoding, stringval, length, pi);
3288 break;
3289
3290 default:
3291 break;
3292 }
3293
3294 return pi;
3295}
3296
3297proto_item *
3298proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3299 const int start, int length,
3300 const unsigned encoding, int32_t *retval)
3301{
3302 header_field_info *hfinfo;
3303 field_info *new_fi;
3304 int32_t value;
3305
3306 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", 3306, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3306,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3306, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3307
3308 switch (hfinfo->type) {
3309 case FT_INT8:
3310 case FT_INT16:
3311 case FT_INT24:
3312 case FT_INT32:
3313 break;
3314 case FT_INT64:
3315 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)
3316 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3317 default:
3318 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)
3319 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3320 }
3321
3322 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3323 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3324 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3325 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3326 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3327 }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
3330 if (encoding & ENC_STRING0x03000000) {
3331 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3332 }
3333 /* I believe it's ok if this is called with a NULL tree */
3334 value = get_int_value(tree, tvb, start, length, encoding);
3335
3336 if (retval) {
3337 int no_of_bits;
3338 *retval = value;
3339 if (hfinfo->bitmask) {
3340 /* Mask out irrelevant portions */
3341 *retval &= (uint32_t)(hfinfo->bitmask);
3342 /* Shift bits */
3343 *retval >>= hfinfo_bitshift(hfinfo);
3344 }
3345 no_of_bits = ws_count_ones(hfinfo->bitmask);
3346 *retval = ws_sign_ext32(*retval, no_of_bits);
3347 }
3348
3349 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3350
3351 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", 3351
, __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", 3351, "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", 3351, "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", 3351, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3352
3353 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3354
3355 proto_tree_set_int(new_fi, value);
3356
3357 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3358
3359 return proto_tree_add_node(tree, new_fi);
3360}
3361
3362proto_item *
3363proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3364 const int start, int length,
3365 const unsigned encoding, uint32_t *retval)
3366{
3367 header_field_info *hfinfo;
3368 field_info *new_fi;
3369 uint32_t value;
3370
3371 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", 3371, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3371,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3371, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3372
3373 switch (hfinfo->type) {
3374 case FT_CHAR:
3375 case FT_UINT8:
3376 case FT_UINT16:
3377 case FT_UINT24:
3378 case FT_UINT32:
3379 break;
3380 default:
3381 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)
3382 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)
;
3383 }
3384
3385 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3386 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3387 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3388 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3389 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3390 }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
3393 if (encoding & ENC_STRING0x03000000) {
3394 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3395 }
3396 /* I believe it's ok if this is called with a NULL tree */
3397 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3398 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3399 uint64_t temp64;
3400 tvb_get_varint(tvb, start, length, &temp64, encoding);
3401 value = (uint32_t)temp64;
3402 } else {
3403 value = get_uint_value(tree, tvb, start, length, encoding);
3404 }
3405
3406 if (retval) {
3407 *retval = value;
3408 if (hfinfo->bitmask) {
3409 /* Mask out irrelevant portions */
3410 *retval &= (uint32_t)(hfinfo->bitmask);
3411 /* Shift bits */
3412 *retval >>= hfinfo_bitshift(hfinfo);
3413 }
3414 }
3415
3416 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3417
3418 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", 3418
, __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", 3418, "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", 3418, "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", 3418, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3419
3420 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3421
3422 proto_tree_set_uint(new_fi, value);
3423
3424 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3425 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3426 new_fi->flags |= FI_VARINT0x00040000;
3427 }
3428 return proto_tree_add_node(tree, new_fi);
3429}
3430
3431/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3432 * and returns proto_item* and uint value retreived*/
3433proto_item *
3434ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3435 const unsigned encoding, uint32_t *retval)
3436{
3437 field_info *new_fi;
3438 header_field_info *hfinfo;
3439 int item_length;
3440 int offset;
3441 uint32_t value;
3442
3443 offset = ptvc->offset;
3444 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3444, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3444,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3444, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3445
3446 switch (hfinfo->type) {
3447 case FT_CHAR:
3448 case FT_UINT8:
3449 case FT_UINT16:
3450 case FT_UINT24:
3451 case FT_UINT32:
3452 break;
3453 default:
3454 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)
3455 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)
;
3456 }
3457
3458 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3459 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3460
3461 /* I believe it's ok if this is called with a NULL tree */
3462 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3463 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3464
3465 if (retval) {
3466 *retval = value;
3467 if (hfinfo->bitmask) {
3468 /* Mask out irrelevant portions */
3469 *retval &= (uint32_t)(hfinfo->bitmask);
3470 /* Shift bits */
3471 *retval >>= hfinfo_bitshift(hfinfo);
3472 }
3473 }
3474
3475 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3476 item_length, encoding);
3477
3478 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3479
3480 /* Coast clear. Try and fake it */
3481 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", 3481
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3481, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3481, "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", 3481, __func__, "Adding %s would put more than %d 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); } } }
;
3482
3483 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3484
3485 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3486 offset, length, encoding);
3487}
3488
3489/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3490 * and returns proto_item* and int value retreived*/
3491proto_item *
3492ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3493 const unsigned encoding, int32_t *retval)
3494{
3495 field_info *new_fi;
3496 header_field_info *hfinfo;
3497 int item_length;
3498 int offset;
3499 uint32_t value;
3500
3501 offset = ptvc->offset;
3502 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", 3502, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3502,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3502, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3503
3504 switch (hfinfo->type) {
3505 case FT_INT8:
3506 case FT_INT16:
3507 case FT_INT24:
3508 case FT_INT32:
3509 break;
3510 default:
3511 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)
3512 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3513 }
3514
3515 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3516 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3517
3518 /* I believe it's ok if this is called with a NULL tree */
3519 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3520 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3521
3522 if (retval) {
3523 int no_of_bits;
3524 *retval = value;
3525 if (hfinfo->bitmask) {
3526 /* Mask out irrelevant portions */
3527 *retval &= (uint32_t)(hfinfo->bitmask);
3528 /* Shift bits */
3529 *retval >>= hfinfo_bitshift(hfinfo);
3530 }
3531 no_of_bits = ws_count_ones(hfinfo->bitmask);
3532 *retval = ws_sign_ext32(*retval, no_of_bits);
3533 }
3534
3535 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3536 item_length, encoding);
3537
3538 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3539
3540 /* Coast clear. Try and fake it */
3541 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", 3541
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3541, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3541, "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", 3541, __func__, "Adding %s would put more than %d 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); } } }
;
3542
3543 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3544
3545 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3546 offset, length, encoding);
3547}
3548
3549/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3550 * and returns proto_item* and string value retreived */
3551proto_item*
3552ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3553{
3554 header_field_info *hfinfo;
3555 field_info *new_fi;
3556 const uint8_t *value;
3557 int item_length;
3558 int offset;
3559
3560 offset = ptvc->offset;
3561
3562 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", 3562
, __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", 3562, "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", 3562, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3563
3564 switch (hfinfo->type) {
3565 case FT_STRING:
3566 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3567 break;
3568 case FT_STRINGZ:
3569 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3570 break;
3571 case FT_UINT_STRING:
3572 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3573 break;
3574 case FT_STRINGZPAD:
3575 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3576 break;
3577 case FT_STRINGZTRUNC:
3578 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3579 break;
3580 default:
3581 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)
3582 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)
;
3583 }
3584
3585 if (retval)
3586 *retval = value;
3587
3588 ptvc->offset += item_length;
3589
3590 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3591
3592 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", 3592, __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", 3592,
"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", 3592, "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", 3592
, __func__, "Adding %s would put more than %d 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); } } }
;
3593
3594 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3595
3596 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3597 offset, length, encoding);
3598}
3599
3600/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3601 * and returns proto_item* and boolean value retreived */
3602proto_item*
3603ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3604{
3605 header_field_info *hfinfo;
3606 field_info *new_fi;
3607 int item_length;
3608 int offset;
3609 uint64_t value, bitval;
3610
3611 offset = ptvc->offset;
3612 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", 3612, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3612,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3612, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3613
3614 if (hfinfo->type != FT_BOOLEAN) {
3615 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)
3616 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3617 }
3618
3619 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3620 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3621 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3622 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3623 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3624 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3625 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3626
3627 if (encoding & ENC_STRING0x03000000) {
3628 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3629 }
3630
3631 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3632 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3633
3634 /* I believe it's ok if this is called with a NULL tree */
3635 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3636
3637 if (retval) {
3638 bitval = value;
3639 if (hfinfo->bitmask) {
3640 /* Mask out irrelevant portions */
3641 bitval &= hfinfo->bitmask;
3642 }
3643 *retval = (bitval != 0);
3644 }
3645
3646 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3647 item_length, encoding);
3648
3649 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3650
3651 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", 3651, __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", 3651,
"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", 3651, "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", 3651
, __func__, "Adding %s would put more than %d 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); } } }
;
3652
3653 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3654
3655 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3656 offset, length, encoding);
3657}
3658
3659proto_item *
3660proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3661 const int start, int length, const unsigned encoding, uint64_t *retval)
3662{
3663 header_field_info *hfinfo;
3664 field_info *new_fi;
3665 uint64_t value;
3666
3667 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", 3667, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3667,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3667, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3668
3669 switch (hfinfo->type) {
3670 case FT_UINT40:
3671 case FT_UINT48:
3672 case FT_UINT56:
3673 case FT_UINT64:
3674 break;
3675 default:
3676 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)
3677 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3678 }
3679
3680 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3681 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3682 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3683 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3684 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3685 }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
3688 if (encoding & ENC_STRING0x03000000) {
3689 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3690 }
3691 /* I believe it's ok if this is called with a NULL tree */
3692 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3693 tvb_get_varint(tvb, start, length, &value, encoding);
3694 } else {
3695 value = get_uint64_value(tree, tvb, start, length, encoding);
3696 }
3697
3698 if (retval) {
3699 *retval = value;
3700 if (hfinfo->bitmask) {
3701 /* Mask out irrelevant portions */
3702 *retval &= hfinfo->bitmask;
3703 /* Shift bits */
3704 *retval >>= hfinfo_bitshift(hfinfo);
3705 }
3706 }
3707
3708 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3709
3710 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", 3710
, __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", 3710, "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", 3710, "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", 3710, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3711
3712 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3713
3714 proto_tree_set_uint64(new_fi, value);
3715
3716 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3717 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3718 new_fi->flags |= FI_VARINT0x00040000;
3719 }
3720
3721 return proto_tree_add_node(tree, new_fi);
3722}
3723
3724proto_item *
3725proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3726 const int start, int length, const unsigned encoding, int64_t *retval)
3727{
3728 header_field_info *hfinfo;
3729 field_info *new_fi;
3730 int64_t value;
3731
3732 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", 3732, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3732,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3732, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3733
3734 switch (hfinfo->type) {
3735 case FT_INT40:
3736 case FT_INT48:
3737 case FT_INT56:
3738 case FT_INT64:
3739 break;
3740 default:
3741 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)
3742 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3743 }
3744
3745 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3746 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3747 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3748 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3749 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3750 }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
3753 if (encoding & ENC_STRING0x03000000) {
3754 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3755 }
3756 /* I believe it's ok if this is called with a NULL tree */
3757 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3758 tvb_get_varint(tvb, start, length, &value, encoding);
3759 }
3760 else {
3761 value = get_int64_value(tree, tvb, start, length, encoding);
3762 }
3763
3764 if (retval) {
3765 *retval = value;
3766 }
3767
3768 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3769
3770 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3770
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3770, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3770, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3770, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3771
3772 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3773
3774 proto_tree_set_int64(new_fi, value);
3775
3776 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3777 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3778 new_fi->flags |= FI_VARINT0x00040000;
3779 }
3780
3781 return proto_tree_add_node(tree, new_fi);
3782}
3783
3784proto_item *
3785proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3786 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3787{
3788 header_field_info *hfinfo;
3789 field_info *new_fi;
3790 uint64_t value;
3791
3792 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", 3792, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3792,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3792, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3793
3794 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
))
)) {
3795 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)
3796 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3797 }
3798
3799 /* length validation for native number encoding caught by get_uint64_value() */
3800 /* length has to be -1 or > 0 regardless of encoding */
3801 if (length == 0)
3802 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)
3803 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3804
3805 if (encoding & ENC_STRING0x03000000) {
3806 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3807 }
3808
3809 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3810
3811 if (retval) {
3812 *retval = value;
3813 if (hfinfo->bitmask) {
3814 /* Mask out irrelevant portions */
3815 *retval &= hfinfo->bitmask;
3816 /* Shift bits */
3817 *retval >>= hfinfo_bitshift(hfinfo);
3818 }
3819 }
3820
3821 if (lenretval) {
3822 *lenretval = length;
3823 }
3824
3825 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3826
3827 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3827
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3827, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3827, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3827, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3828
3829 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3830
3831 proto_tree_set_uint64(new_fi, value);
3832
3833 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3834 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3835 new_fi->flags |= FI_VARINT0x00040000;
3836 }
3837
3838 return proto_tree_add_node(tree, new_fi);
3839
3840}
3841
3842proto_item *
3843proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3844 const int start, int length,
3845 const unsigned encoding, bool_Bool *retval)
3846{
3847 header_field_info *hfinfo;
3848 field_info *new_fi;
3849 uint64_t value, bitval;
3850
3851 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", 3851, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3851,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3851, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3852
3853 if (hfinfo->type != FT_BOOLEAN) {
3854 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)
3855 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3856 }
3857
3858 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3859 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3860 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3861 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3862 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3863 }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
3866 if (encoding & ENC_STRING0x03000000) {
3867 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3868 }
3869 /* I believe it's ok if this is called with a NULL tree */
3870 value = get_uint64_value(tree, tvb, start, length, encoding);
3871
3872 if (retval) {
3873 bitval = value;
3874 if (hfinfo->bitmask) {
3875 /* Mask out irrelevant portions */
3876 bitval &= hfinfo->bitmask;
3877 }
3878 *retval = (bitval != 0);
3879 }
3880
3881 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3882
3883 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", 3883
, __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", 3883, "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", 3883, "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", 3883, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3884
3885 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3886
3887 proto_tree_set_boolean(new_fi, value);
3888
3889 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3890
3891 return proto_tree_add_node(tree, new_fi);
3892}
3893
3894proto_item *
3895proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3896 const int start, int length,
3897 const unsigned encoding, float *retval)
3898{
3899 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3900 field_info *new_fi;
3901 float value;
3902
3903 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", 3903,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3904
3905 if (hfinfo->type != FT_FLOAT) {
3906 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)
;
3907 }
3908
3909 if (length != 4) {
3910 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3911 }
3912
3913 /* treat any nonzero encoding as little endian for backwards compatibility */
3914 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3915 if (retval) {
3916 *retval = value;
3917 }
3918
3919 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3920
3921 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", 3921
, __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", 3921, "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", 3921, "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", 3921, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3922
3923 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3924 if (encoding) {
3925 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3926 }
3927
3928 proto_tree_set_float(new_fi, value);
3929
3930 return proto_tree_add_node(tree, new_fi);
3931}
3932
3933proto_item *
3934proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3935 const int start, int length,
3936 const unsigned encoding, double *retval)
3937{
3938 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3939 field_info *new_fi;
3940 double value;
3941
3942 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", 3942,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3943
3944 if (hfinfo->type != FT_DOUBLE) {
3945 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)
;
3946 }
3947
3948 if (length != 8) {
3949 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3950 }
3951
3952 /* treat any nonzero encoding as little endian for backwards compatibility */
3953 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3954 if (retval) {
3955 *retval = value;
3956 }
3957
3958 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3959
3960 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", 3960
, __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", 3960, "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", 3960, "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", 3960, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3961
3962 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3963 if (encoding) {
3964 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3965 }
3966
3967 proto_tree_set_double(new_fi, value);
3968
3969 return proto_tree_add_node(tree, new_fi);
3970}
3971
3972proto_item *
3973proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3974 const int start, int length,
3975 const unsigned encoding, ws_in4_addr *retval)
3976{
3977 header_field_info *hfinfo;
3978 field_info *new_fi;
3979 ws_in4_addr value;
3980
3981 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", 3981, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3981,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3981, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3982
3983 switch (hfinfo->type) {
3984 case FT_IPv4:
3985 break;
3986 default:
3987 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)
3988 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
3989 }
3990
3991 if (length != FT_IPv4_LEN4)
3992 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)
3993 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
3994
3995 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3996 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3997 }
3998
3999 /*
4000 * NOTE: to support code written when proto_tree_add_item() took
4001 * a bool as its last argument, with false meaning "big-endian"
4002 * and true meaning "little-endian", we treat any non-zero value
4003 * of "encoding" as meaning "little-endian".
4004 */
4005 value = tvb_get_ipv4(tvb, start);
4006 if (encoding)
4007 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))))
;
4008
4009 if (retval) {
4010 *retval = value;
4011 }
4012
4013 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4014
4015 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", 4015
, __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", 4015, "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", 4015, "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", 4015, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4016
4017 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4018
4019 proto_tree_set_ipv4(new_fi, value);
4020
4021 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4022 return proto_tree_add_node(tree, new_fi);
4023}
4024
4025proto_item *
4026proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4027 const int start, int length,
4028 const unsigned encoding, ws_in6_addr *addr)
4029{
4030 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4031 field_info *new_fi;
4032
4033 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", 4033,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4034
4035 switch (hfinfo->type) {
4036 case FT_IPv6:
4037 break;
4038 default:
4039 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)
4040 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4041 }
4042
4043 if (length != FT_IPv6_LEN16)
4044 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)
4045 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4046
4047 if (encoding) {
4048 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"
)
;
4049 }
4050
4051 tvb_get_ipv6(tvb, start, addr);
4052
4053 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4054
4055 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", 4055
, __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", 4055, "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", 4055, "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", 4055, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4056
4057 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4058
4059 proto_tree_set_ipv6(new_fi, addr);
4060
4061 return proto_tree_add_node(tree, new_fi);
4062}
4063
4064proto_item *
4065proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4066 const int start, int length, const unsigned encoding, uint8_t *retval) {
4067
4068 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4069 field_info *new_fi;
4070
4071 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", 4071,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4072
4073 switch (hfinfo->type) {
4074 case FT_ETHER:
4075 break;
4076 default:
4077 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)
4078 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4079 }
4080
4081 if (length != FT_ETHER_LEN6)
4082 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)
4083 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4084
4085 if (encoding) {
4086 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"
)
;
4087 }
4088
4089 tvb_memcpy(tvb, retval, start, length);
4090
4091 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4092
4093 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", 4093
, __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", 4093, "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", 4093, "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", 4093, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4094
4095 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4096
4097 proto_tree_set_ether(new_fi, retval);
4098
4099 return proto_tree_add_node(tree, new_fi);
4100}
4101
4102
4103proto_item *
4104proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4105 tvbuff_t *tvb,
4106 const int start, int length,
4107 const unsigned encoding,
4108 wmem_allocator_t *scope,
4109 const uint8_t **retval,
4110 int *lenretval)
4111{
4112 proto_item *pi;
4113 header_field_info *hfinfo;
4114 field_info *new_fi;
4115 const uint8_t *value;
4116
4117 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", 4117, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4117,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4117, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4118
4119 switch (hfinfo->type) {
4120 case FT_STRING:
4121 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4122 break;
4123 case FT_STRINGZ:
4124 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4125 break;
4126 case FT_UINT_STRING:
4127 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4128 break;
4129 case FT_STRINGZPAD:
4130 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4131 break;
4132 case FT_STRINGZTRUNC:
4133 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4134 break;
4135 default:
4136 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)
4137 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)
;
4138 }
4139
4140 if (retval)
4141 *retval = value;
4142
4143 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4144
4145 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", 4145
, __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", 4145, "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", 4145, "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", 4145, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4146
4147 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4148
4149 proto_tree_set_string(new_fi, value);
4150
4151 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4152
4153 pi = proto_tree_add_node(tree, new_fi);
4154
4155 switch (hfinfo->type) {
4156
4157 case FT_STRINGZ:
4158 case FT_STRINGZPAD:
4159 case FT_STRINGZTRUNC:
4160 case FT_UINT_STRING:
4161 break;
4162
4163 case FT_STRING:
4164 detect_trailing_stray_characters(encoding, value, length, pi);
4165 break;
4166
4167 default:
4168 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4168
, __func__, "assertion \"not reached\" failed")
;
4169 }
4170
4171 return pi;
4172}
4173
4174proto_item *
4175proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4176 const int start, int length,
4177 const unsigned encoding, wmem_allocator_t *scope,
4178 const uint8_t **retval)
4179{
4180 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4181 tvb, start, length, encoding, scope, retval, &length);
4182}
4183
4184proto_item *
4185proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4186 tvbuff_t *tvb,
4187 const int start, int length,
4188 const unsigned encoding,
4189 wmem_allocator_t *scope,
4190 char **retval,
4191 int *lenretval)
4192{
4193 proto_item *pi;
4194 header_field_info *hfinfo;
4195 field_info *new_fi;
4196 const uint8_t *value;
4197 uint32_t n = 0;
4198
4199 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", 4199, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4199,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4199, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4200
4201 switch (hfinfo->type) {
4202 case FT_STRING:
4203 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4204 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4205 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4206 break;
4207 case FT_STRINGZ:
4208 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4209 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4210 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4211 break;
4212 case FT_UINT_STRING:
4213 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4214 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4215 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4216 break;
4217 case FT_STRINGZPAD:
4218 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4219 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4220 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4221 break;
4222 case FT_STRINGZTRUNC:
4223 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4224 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4225 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4226 break;
4227 case FT_BYTES:
4228 tvb_ensure_bytes_exist(tvb, start, length);
4229 value = tvb_get_ptr(tvb, start, length);
4230 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4231 *lenretval = length;
4232 break;
4233 case FT_UINT_BYTES:
4234 n = get_uint_value(tree, tvb, start, length, encoding);
4235 tvb_ensure_bytes_exist(tvb, start + length, n);
4236 value = tvb_get_ptr(tvb, start + length, n);
4237 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4238 *lenretval = length + n;
4239 break;
4240 default:
4241 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)
4242 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)
;
4243 }
4244
4245 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4246
4247 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", 4247
, __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", 4247, "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", 4247, "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", 4247, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4248
4249 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4250
4251 switch (hfinfo->type) {
4252
4253 case FT_STRING:
4254 case FT_STRINGZ:
4255 case FT_UINT_STRING:
4256 case FT_STRINGZPAD:
4257 case FT_STRINGZTRUNC:
4258 proto_tree_set_string(new_fi, value);
4259 break;
4260
4261 case FT_BYTES:
4262 proto_tree_set_bytes(new_fi, value, length);
4263 break;
4264
4265 case FT_UINT_BYTES:
4266 proto_tree_set_bytes(new_fi, value, n);
4267 break;
4268
4269 default:
4270 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4270
, __func__, "assertion \"not reached\" failed")
;
4271 }
4272
4273 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4274
4275 pi = proto_tree_add_node(tree, new_fi);
4276
4277 switch (hfinfo->type) {
4278
4279 case FT_STRINGZ:
4280 case FT_STRINGZPAD:
4281 case FT_STRINGZTRUNC:
4282 case FT_UINT_STRING:
4283 break;
4284
4285 case FT_STRING:
4286 detect_trailing_stray_characters(encoding, value, length, pi);
4287 break;
4288
4289 case FT_BYTES:
4290 case FT_UINT_BYTES:
4291 break;
4292
4293 default:
4294 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4294
, __func__, "assertion \"not reached\" failed")
;
4295 }
4296
4297 return pi;
4298}
4299
4300proto_item *
4301proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4302 tvbuff_t *tvb,
4303 const int start, int length,
4304 const unsigned encoding,
4305 wmem_allocator_t *scope,
4306 char **retval)
4307{
4308 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4309 tvb, start, length, encoding, scope, retval, &length);
4310}
4311
4312proto_item *
4313proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4314 tvbuff_t *tvb,
4315 const int start, int length, const unsigned encoding,
4316 wmem_allocator_t *scope, char **retval)
4317{
4318 header_field_info *hfinfo;
4319 field_info *new_fi;
4320 nstime_t time_stamp;
4321 int flags;
4322
4323 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", 4323, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4323,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4323, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4324
4325 switch (hfinfo->type) {
4326 case FT_ABSOLUTE_TIME:
4327 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4328 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4329 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4330 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4331 }
4332 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4333 break;
4334 case FT_RELATIVE_TIME:
4335 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4336 *retval = rel_time_to_secs_str(scope, &time_stamp);
4337 break;
4338 default:
4339 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)
4340 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4341 }
4342
4343 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4344
4345 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", 4345
, __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", 4345, "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", 4345, "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", 4345, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4346
4347 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4348
4349 switch (hfinfo->type) {
4350
4351 case FT_ABSOLUTE_TIME:
4352 case FT_RELATIVE_TIME:
4353 proto_tree_set_time(new_fi, &time_stamp);
4354 break;
4355 default:
4356 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4356
, __func__, "assertion \"not reached\" failed")
;
4357 }
4358
4359 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4360
4361 return proto_tree_add_node(tree, new_fi);
4362}
4363
4364/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4365 and returns proto_item* */
4366proto_item *
4367ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4368 const unsigned encoding)
4369{
4370 field_info *new_fi;
4371 header_field_info *hfinfo;
4372 int item_length;
4373 int offset;
4374
4375 offset = ptvc->offset;
4376 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", 4376, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4376,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4376, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4377 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4378 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4379
4380 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
4381 item_length, encoding);
4382
4383 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4384
4385 /* Coast clear. Try and fake it */
4386 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", 4386
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4386, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4386, "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", 4386, __func__, "Adding %s would put more than %d 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); } } }
;
4387
4388 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4389
4390 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4391 offset, length, encoding);
4392}
4393
4394/* Add an item to a proto_tree, using the text label registered to that item;
4395 the item is extracted from the tvbuff handed to it. */
4396proto_item *
4397proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4398 const int start, int length, const unsigned encoding)
4399{
4400 field_info *new_fi;
4401 int item_length;
4402
4403 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", 4403,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4404
4405 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4406 test_length(hfinfo, tvb, start, item_length, encoding);
4407
4408 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4409
4410 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", 4410
, __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", 4410, "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", 4410, "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", 4410, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4411
4412 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4413
4414 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4415}
4416
4417proto_item *
4418proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4419 const int start, int length, const unsigned encoding)
4420{
4421 register header_field_info *hfinfo;
4422
4423 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4423, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4423,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4423, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4424 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4425}
4426
4427/* Add an item to a proto_tree, using the text label registered to that item;
4428 the item is extracted from the tvbuff handed to it.
4429
4430 Return the length of the item through the pointer. */
4431proto_item *
4432proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4433 tvbuff_t *tvb, const int start,
4434 int length, const unsigned encoding,
4435 int *lenretval)
4436{
4437 field_info *new_fi;
4438 int item_length;
4439 proto_item *item;
4440
4441 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", 4441,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4442
4443 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4444 test_length(hfinfo, tvb, start, item_length, encoding);
4445
4446 if (!tree) {
4447 /*
4448 * We need to get the correct item length here.
4449 * That's normally done by proto_tree_new_item(),
4450 * but we won't be calling it.
4451 */
4452 *lenretval = get_full_length(hfinfo, tvb, start, length,
4453 item_length, encoding);
4454 return NULL((void*)0);
4455 }
4456
4457 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", 4464
, __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", 4464, "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", 4464, "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", 4464
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4458 /*((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", 4464
, __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", 4464, "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", 4464, "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", 4464
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 * 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", 4464
, __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", 4464, "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", 4464, "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", 4464
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 * 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", 4464
, __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", 4464, "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", 4464, "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", 4464
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 */((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", 4464
, __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", 4464, "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", 4464, "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", 4464
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 *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", 4464
, __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", 4464, "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", 4464, "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", 4464
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4464
, __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", 4464, "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", 4464, "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", 4464
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 })((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", 4464
, __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", 4464, "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", 4464, "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", 4464
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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
4466 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4467
4468 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4469 *lenretval = new_fi->length;
4470 return item;
4471}
4472
4473proto_item *
4474proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4475 const int start, int length,
4476 const unsigned encoding, int *lenretval)
4477{
4478 register header_field_info *hfinfo;
4479
4480 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", 4480, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4480,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4480, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4481 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4482}
4483
4484/* which FT_ types can use proto_tree_add_bytes_item() */
4485static inline bool_Bool
4486validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4487{
4488 return (type == FT_BYTES ||
4489 type == FT_UINT_BYTES ||
4490 type == FT_OID ||
4491 type == FT_REL_OID ||
4492 type == FT_SYSTEM_ID );
4493}
4494
4495/* Note: this does no validation that the byte array of an FT_OID or
4496 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4497 so I think it's ok to continue not validating it?
4498 */
4499proto_item *
4500proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4501 const int start, int length, const unsigned encoding,
4502 GByteArray *retval, int *endoff, int *err)
4503{
4504 field_info *new_fi;
4505 GByteArray *bytes = retval;
4506 GByteArray *created_bytes = NULL((void*)0);
4507 bool_Bool failed = false0;
4508 uint32_t n = 0;
4509 header_field_info *hfinfo;
4510 bool_Bool generate = (bytes || tree) ? true1 : false0;
4511
4512 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", 4512, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4512,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4512, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4513
4514 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", 4514,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4515
4516 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", 4517, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4517 "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", 4517, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4518
4519 CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
;
4520
4521 if (encoding & ENC_STR_NUM0x01000000) {
4522 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"
)
;
4523 }
4524
4525 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4526 if (hfinfo->type == FT_UINT_BYTES) {
4527 /* can't decode FT_UINT_BYTES from strings */
4528 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")
4529 "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")
;
4530 }
4531
4532 unsigned hex_encoding = encoding;
4533 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4534 /* If none of the separator values are used,
4535 * assume no separator (the common case). */
4536 hex_encoding |= ENC_SEP_NONE0x00010000;
4537#if 0
4538 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")
4539 "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")
;
4540#endif
4541 }
4542
4543 if (!bytes) {
4544 /* caller doesn't care about return value, but we need it to
4545 call tvb_get_string_bytes() and set the tree later */
4546 bytes = created_bytes = g_byte_array_new();
4547 }
4548
4549 /*
4550 * bytes might be NULL after this, but can't add expert
4551 * error until later; if it's NULL, just note that
4552 * it failed.
4553 */
4554 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4555 if (bytes == NULL((void*)0))
4556 failed = true1;
4557 }
4558 else if (generate) {
4559 tvb_ensure_bytes_exist(tvb, start, length);
4560
4561 if (hfinfo->type == FT_UINT_BYTES) {
4562 n = length; /* n is now the "header" length */
4563 length = get_uint_value(tree, tvb, start, n, encoding);
4564 /* length is now the value's length; only store the value in the array */
4565 tvb_ensure_bytes_exist(tvb, start + n, length);
4566 if (!bytes) {
4567 /* caller doesn't care about return value, but
4568 * we may need it to set the tree later */
4569 bytes = created_bytes = g_byte_array_new();
4570 }
4571 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4572 }
4573 else if (length > 0) {
4574 if (!bytes) {
4575 /* caller doesn't care about return value, but
4576 * we may need it to set the tree later */
4577 bytes = created_bytes = g_byte_array_new();
4578 }
4579 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4580 }
4581
4582 if (endoff)
4583 *endoff = start + n + length;
4584 }
4585
4586 if (err)
4587 *err = failed ? EINVAL22 : 0;
4588
4589 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); }
4590 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4591 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); }
4592 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); }
4593 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); }
4594 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 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4596
4597 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", 4603
, __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", 4603, "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", 4603, "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", 4603
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4598 {((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", 4603
, __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", 4603, "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", 4603, "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", 4603
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4603
, __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", 4603, "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", 4603, "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", 4603
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4603
, __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", 4603, "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", 4603, "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", 4603
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4603
, __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", 4603, "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", 4603, "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", 4603
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4603
, __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", 4603, "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", 4603, "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", 4603
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 } )((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", 4603
, __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", 4603, "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", 4603, "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", 4603
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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
4605 /* n will be zero except when it's a FT_UINT_BYTES */
4606 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4607
4608 if (encoding & ENC_STRING0x03000000) {
4609 if (failed)
4610 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4611
4612 if (bytes)
4613 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4614 else
4615 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4616
4617 if (created_bytes)
4618 g_byte_array_free(created_bytes, true1);
4619 }
4620 else {
4621 /* n will be zero except when it's a FT_UINT_BYTES */
4622 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4623
4624 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4625 * use the byte array created above in this case.
4626 */
4627 if (created_bytes)
4628 g_byte_array_free(created_bytes, true1);
4629
4630 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4631 (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)
;
4632 }
4633
4634 return proto_tree_add_node(tree, new_fi);
4635}
4636
4637
4638proto_item *
4639proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4640 const int start, int length, const unsigned encoding,
4641 nstime_t *retval, int *endoff, int *err)
4642{
4643 field_info *new_fi;
4644 nstime_t time_stamp;
4645 int saved_err = 0;
4646 header_field_info *hfinfo;
4647
4648 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", 4648, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4648,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4648, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4649
4650 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", 4650,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4651
4652 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4653 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4654 if(retval)if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4655 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4656 nstime_set_zero(retval);if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4657 }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
4660 nstime_set_zero(&time_stamp);
4661
4662 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4663 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", 4663, ((hfinfo))->abbrev))))
;
4664 /* The only string format that could be a relative time is
4665 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4666 * relative to "now" currently.
4667 */
4668 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4669 saved_err = EINVAL22;
4670 }
4671 else {
4672 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", 4672, ((hfinfo))->abbrev))))
;
4673 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4674
4675 tvb_ensure_bytes_exist(tvb, start, length);
4676 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4677 if (endoff) *endoff = start + length;
4678 }
4679
4680 if (err) *err = saved_err;
4681
4682 if (retval) {
4683 retval->secs = time_stamp.secs;
4684 retval->nsecs = time_stamp.nsecs;
4685 }
4686
4687 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4688
4689 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", 4689
, __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", 4689, "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", 4689, "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", 4689, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4690
4691 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4692
4693 proto_tree_set_time(new_fi, &time_stamp);
4694
4695 if (encoding & ENC_STRING0x03000000) {
4696 if (saved_err)
4697 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4698 }
4699 else {
4700 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4701 (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)
;
4702 }
4703
4704 return proto_tree_add_node(tree, new_fi);
4705}
4706
4707/* Add a FT_NONE to a proto_tree */
4708proto_item *
4709proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4710 const int start, int length, const char *format,
4711 ...)
4712{
4713 proto_item *pi;
4714 va_list ap;
4715 header_field_info *hfinfo;
4716
4717 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4718
4719 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4719
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4719, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4719, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4719, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4720
4721 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_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", 4721
, ((hfinfo))->abbrev))))
;
4722
4723 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4724
4725 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4725, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4726
4727 va_start(ap, format)__builtin_va_start(ap, format);
4728 proto_tree_set_representation(pi, format, ap);
4729 va_end(ap)__builtin_va_end(ap);
4730
4731 /* no value to set for FT_NONE */
4732 return pi;
4733}
4734
4735/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4736 * offset, and returns proto_item* */
4737proto_item *
4738ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4739 const unsigned encoding)
4740{
4741 proto_item *item;
4742
4743 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4744 length, encoding);
4745
4746 return item;
4747}
4748
4749/* Advance the ptvcursor's offset within its tvbuff without
4750 * adding anything to the proto_tree. */
4751void
4752ptvcursor_advance(ptvcursor_t* ptvc, int length)
4753{
4754 ptvc->offset += length;
4755}
4756
4757
4758static void
4759proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4760{
4761 fvalue_set_protocol(fi->value, tvb, field_data, length);
4762}
4763
4764/* Add a FT_PROTOCOL to a proto_tree */
4765proto_item *
4766proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4767 int start, int length, const char *format, ...)
4768{
4769 proto_item *pi;
4770 tvbuff_t *protocol_tvb;
4771 va_list ap;
4772 header_field_info *hfinfo;
4773 char* protocol_rep;
4774
4775 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4776
4777 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", 4777
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4777, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4777, "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", 4777, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4778
4779 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"
, 4779, ((hfinfo))->abbrev))))
;
4780
4781 /*
4782 * This can throw an exception, so do it before we allocate anything.
4783 */
4784 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4785
4786 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4787
4788 va_start(ap, format)__builtin_va_start(ap, format);
4789 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4790 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4791 g_free(protocol_rep);
4792 va_end(ap)__builtin_va_end(ap);
4793
4794 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4794, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4795
4796 va_start(ap, format)__builtin_va_start(ap, format);
4797 proto_tree_set_representation(pi, format, ap);
4798 va_end(ap)__builtin_va_end(ap);
4799
4800 return pi;
4801}
4802
4803/* Add a FT_BYTES to a proto_tree */
4804proto_item *
4805proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4806 int length, const uint8_t *start_ptr)
4807{
4808 proto_item *pi;
4809 header_field_info *hfinfo;
4810 int item_length;
4811
4812 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", 4812, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4812,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4812, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4813 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4814 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4815
4816 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4817
4818 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", 4818
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4818, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4818, "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", 4818, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4819
4820 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",
4820, ((hfinfo))->abbrev))))
;
4821
4822 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4823 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4824
4825 return pi;
4826}
4827
4828/* Add a FT_BYTES to a proto_tree */
4829proto_item *
4830proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4831 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4832{
4833 proto_item *pi;
4834 header_field_info *hfinfo;
4835 int item_length;
4836
4837 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", 4837, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4837,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4837, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4838 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4839 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4840
4841 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4842
4843 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", 4843
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4843, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4843, "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", 4843, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4844
4845 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",
4845, ((hfinfo))->abbrev))))
;
4846
4847 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4848 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4849
4850 return pi;
4851}
4852
4853proto_item *
4854proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4855 int start, int length,
4856 const uint8_t *start_ptr,
4857 const char *format, ...)
4858{
4859 proto_item *pi;
4860 va_list ap;
4861
4862 if (start_ptr == NULL((void*)0))
4863 start_ptr = tvb_get_ptr(tvb, start, length);
4864
4865 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4866
4867 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; }
;
4868
4869 va_start(ap, format)__builtin_va_start(ap, format);
4870 proto_tree_set_representation_value(pi, format, ap);
4871 va_end(ap)__builtin_va_end(ap);
4872
4873 return pi;
4874}
4875
4876proto_item *
4877proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4878 int start, int length, const uint8_t *start_ptr,
4879 const char *format, ...)
4880{
4881 proto_item *pi;
4882 va_list ap;
4883
4884 if (start_ptr == NULL((void*)0))
4885 start_ptr = tvb_get_ptr(tvb, start, length);
4886
4887 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4888
4889 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; }
;
4890
4891 va_start(ap, format)__builtin_va_start(ap, format);
4892 proto_tree_set_representation(pi, format, ap);
4893 va_end(ap)__builtin_va_end(ap);
4894
4895 return pi;
4896}
4897
4898static void
4899proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4900{
4901 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4901, "length >= 0"
))))
;
4902 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", 4902, "start_ptr != ((void*)0) || length == 0"
))))
;
4903
4904 fvalue_set_bytes_data(fi->value, start_ptr, length);
4905}
4906
4907
4908static void
4909proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4910{
4911 tvb_ensure_bytes_exist(tvb, offset, length);
4912 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4913}
4914
4915static void
4916proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4917{
4918 GByteArray *bytes;
4919
4920 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4920, "value != ((void*)0)"
))))
;
4921
4922 bytes = byte_array_dup(value);
4923
4924 fvalue_set_byte_array(fi->value, bytes);
4925}
4926
4927/* Add a FT_*TIME to a proto_tree */
4928proto_item *
4929proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4930 int length, const nstime_t *value_ptr)
4931{
4932 proto_item *pi;
4933 header_field_info *hfinfo;
4934
4935 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4936
4937 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", 4937
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4937, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4937, "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", 4937, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4938
4939 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", 4939, ((hfinfo))->abbrev))))
;
4940
4941 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4942 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4943
4944 return pi;
4945}
4946
4947proto_item *
4948proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4949 int start, int length, nstime_t *value_ptr,
4950 const char *format, ...)
4951{
4952 proto_item *pi;
4953 va_list ap;
4954
4955 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4956 if (pi != tree) {
4957 va_start(ap, format)__builtin_va_start(ap, format);
4958 proto_tree_set_representation_value(pi, format, ap);
4959 va_end(ap)__builtin_va_end(ap);
4960 }
4961
4962 return pi;
4963}
4964
4965proto_item *
4966proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4967 int start, int length, nstime_t *value_ptr,
4968 const char *format, ...)
4969{
4970 proto_item *pi;
4971 va_list ap;
4972
4973 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4974 if (pi != tree) {
4975 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4975, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4976
4977 va_start(ap, format)__builtin_va_start(ap, format);
4978 proto_tree_set_representation(pi, format, ap);
4979 va_end(ap)__builtin_va_end(ap);
4980 }
4981
4982 return pi;
4983}
4984
4985/* Set the FT_*TIME value */
4986static void
4987proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4988{
4989 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4989, "value_ptr != ((void*)0)"
))))
;
4990
4991 fvalue_set_time(fi->value, value_ptr);
4992}
4993
4994/* Add a FT_IPXNET to a proto_tree */
4995proto_item *
4996proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4997 int length, uint32_t value)
4998{
4999 proto_item *pi;
5000 header_field_info *hfinfo;
5001
5002 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5003
5004 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", 5004
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5004, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5004, "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", 5004, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5005
5006 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"
, 5006, ((hfinfo))->abbrev))))
;
5007
5008 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5009 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5010
5011 return pi;
5012}
5013
5014proto_item *
5015proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5016 int start, int length, uint32_t value,
5017 const char *format, ...)
5018{
5019 proto_item *pi;
5020 va_list ap;
5021
5022 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5023 if (pi != tree) {
5024 va_start(ap, format)__builtin_va_start(ap, format);
5025 proto_tree_set_representation_value(pi, format, ap);
5026 va_end(ap)__builtin_va_end(ap);
5027 }
5028
5029 return pi;
5030}
5031
5032proto_item *
5033proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5034 int start, int length, uint32_t value,
5035 const char *format, ...)
5036{
5037 proto_item *pi;
5038 va_list ap;
5039
5040 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5041 if (pi != tree) {
5042 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5042, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5043
5044 va_start(ap, format)__builtin_va_start(ap, format);
5045 proto_tree_set_representation(pi, format, ap);
5046 va_end(ap)__builtin_va_end(ap);
5047 }
5048
5049 return pi;
5050}
5051
5052/* Set the FT_IPXNET value */
5053static void
5054proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5055{
5056 fvalue_set_uinteger(fi->value, value);
5057}
5058
5059/* Add a FT_IPv4 to a proto_tree */
5060proto_item *
5061proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5062 int length, ws_in4_addr value)
5063{
5064 proto_item *pi;
5065 header_field_info *hfinfo;
5066
5067 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5068
5069 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", 5069
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5069, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5069, "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", 5069, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5070
5071 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", 5071
, ((hfinfo))->abbrev))))
;
5072
5073 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5074 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5075
5076 return pi;
5077}
5078
5079proto_item *
5080proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5081 int start, int length, ws_in4_addr value,
5082 const char *format, ...)
5083{
5084 proto_item *pi;
5085 va_list ap;
5086
5087 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5088 if (pi != tree) {
5089 va_start(ap, format)__builtin_va_start(ap, format);
5090 proto_tree_set_representation_value(pi, format, ap);
5091 va_end(ap)__builtin_va_end(ap);
5092 }
5093
5094 return pi;
5095}
5096
5097proto_item *
5098proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5099 int start, int length, ws_in4_addr value,
5100 const char *format, ...)
5101{
5102 proto_item *pi;
5103 va_list ap;
5104
5105 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5106 if (pi != tree) {
5107 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5107, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5108
5109 va_start(ap, format)__builtin_va_start(ap, format);
5110 proto_tree_set_representation(pi, format, ap);
5111 va_end(ap)__builtin_va_end(ap);
5112 }
5113
5114 return pi;
5115}
5116
5117/* Set the FT_IPv4 value */
5118static void
5119proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5120{
5121 ipv4_addr_and_mask ipv4;
5122 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5123 fvalue_set_ipv4(fi->value, &ipv4);
5124}
5125
5126/* Add a FT_IPv6 to a proto_tree */
5127proto_item *
5128proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5129 int length, const ws_in6_addr *value)
5130{
5131 proto_item *pi;
5132 header_field_info *hfinfo;
5133
5134 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5135
5136 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", 5136
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5136, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5136, "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", 5136, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5137
5138 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", 5138
, ((hfinfo))->abbrev))))
;
5139
5140 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5141 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5142
5143 return pi;
5144}
5145
5146proto_item *
5147proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5148 int start, int length,
5149 const ws_in6_addr *value_ptr,
5150 const char *format, ...)
5151{
5152 proto_item *pi;
5153 va_list ap;
5154
5155 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5156 if (pi != tree) {
5157 va_start(ap, format)__builtin_va_start(ap, format);
5158 proto_tree_set_representation_value(pi, format, ap);
5159 va_end(ap)__builtin_va_end(ap);
5160 }
5161
5162 return pi;
5163}
5164
5165proto_item *
5166proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5167 int start, int length,
5168 const ws_in6_addr *value_ptr,
5169 const char *format, ...)
5170{
5171 proto_item *pi;
5172 va_list ap;
5173
5174 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5175 if (pi != tree) {
5176 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5176, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5177
5178 va_start(ap, format)__builtin_va_start(ap, format);
5179 proto_tree_set_representation(pi, format, ap);
5180 va_end(ap)__builtin_va_end(ap);
5181 }
5182
5183 return pi;
5184}
5185
5186/* Set the FT_IPv6 value */
5187static void
5188proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5189{
5190 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5190, "value != ((void*)0)"
))))
;
5191 ipv6_addr_and_prefix ipv6;
5192 ipv6.addr = *value;
5193 ipv6.prefix = 128;
5194 fvalue_set_ipv6(fi->value, &ipv6);
5195}
5196
5197static void
5198proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5199{
5200 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5201}
5202
5203/* Set the FT_FCWWN value */
5204static void
5205proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5206{
5207 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5207, "value_ptr != ((void*)0)"
))))
;
5208 fvalue_set_fcwwn(fi->value, value_ptr);
5209}
5210
5211static void
5212proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5213{
5214 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5215}
5216
5217/* Add a FT_GUID to a proto_tree */
5218proto_item *
5219proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5220 int length, const e_guid_t *value_ptr)
5221{
5222 proto_item *pi;
5223 header_field_info *hfinfo;
5224
5225 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5226
5227 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", 5227
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5227, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5227, "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", 5227, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5228
5229 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", 5229
, ((hfinfo))->abbrev))))
;
5230
5231 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5232 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5233
5234 return pi;
5235}
5236
5237proto_item *
5238proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5239 int start, int length,
5240 const e_guid_t *value_ptr,
5241 const char *format, ...)
5242{
5243 proto_item *pi;
5244 va_list ap;
5245
5246 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5247 if (pi != tree) {
5248 va_start(ap, format)__builtin_va_start(ap, format);
5249 proto_tree_set_representation_value(pi, format, ap);
5250 va_end(ap)__builtin_va_end(ap);
5251 }
5252
5253 return pi;
5254}
5255
5256proto_item *
5257proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5258 int start, int length, const e_guid_t *value_ptr,
5259 const char *format, ...)
5260{
5261 proto_item *pi;
5262 va_list ap;
5263
5264 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5265 if (pi != tree) {
5266 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5266, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5267
5268 va_start(ap, format)__builtin_va_start(ap, format);
5269 proto_tree_set_representation(pi, format, ap);
5270 va_end(ap)__builtin_va_end(ap);
5271 }
5272
5273 return pi;
5274}
5275
5276/* Set the FT_GUID value */
5277static void
5278proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5279{
5280 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5280, "value_ptr != ((void*)0)"
))))
;
5281 fvalue_set_guid(fi->value, value_ptr);
5282}
5283
5284static void
5285proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5286 const unsigned encoding)
5287{
5288 e_guid_t guid;
5289
5290 tvb_get_guid(tvb, start, &guid, encoding);
5291 proto_tree_set_guid(fi, &guid);
5292}
5293
5294/* Add a FT_OID to a proto_tree */
5295proto_item *
5296proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5297 int length, const uint8_t* value_ptr)
5298{
5299 proto_item *pi;
5300 header_field_info *hfinfo;
5301
5302 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5303
5304 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", 5304
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5304, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5304, "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", 5304, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5305
5306 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", 5306
, ((hfinfo))->abbrev))))
;
5307
5308 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5309 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5310
5311 return pi;
5312}
5313
5314proto_item *
5315proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5316 int start, int length,
5317 const uint8_t* value_ptr,
5318 const char *format, ...)
5319{
5320 proto_item *pi;
5321 va_list ap;
5322
5323 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5324 if (pi != tree) {
5325 va_start(ap, format)__builtin_va_start(ap, format);
5326 proto_tree_set_representation_value(pi, format, ap);
5327 va_end(ap)__builtin_va_end(ap);
5328 }
5329
5330 return pi;
5331}
5332
5333proto_item *
5334proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5335 int start, int length, const uint8_t* value_ptr,
5336 const char *format, ...)
5337{
5338 proto_item *pi;
5339 va_list ap;
5340
5341 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5342 if (pi != tree) {
5343 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5343, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5344
5345 va_start(ap, format)__builtin_va_start(ap, format);
5346 proto_tree_set_representation(pi, format, ap);
5347 va_end(ap)__builtin_va_end(ap);
5348 }
5349
5350 return pi;
5351}
5352
5353/* Set the FT_OID value */
5354static void
5355proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5356{
5357 GByteArray *bytes;
5358
5359 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", 5359, "value_ptr != ((void*)0) || length == 0"
))))
;
5360
5361 bytes = g_byte_array_new();
5362 if (length > 0) {
5363 g_byte_array_append(bytes, value_ptr, length);
5364 }
5365 fvalue_set_byte_array(fi->value, bytes);
5366}
5367
5368static void
5369proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5370{
5371 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5372}
5373
5374/* Set the FT_SYSTEM_ID value */
5375static void
5376proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5377{
5378 GByteArray *bytes;
5379
5380 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", 5380, "value_ptr != ((void*)0) || length == 0"
))))
;
5381
5382 bytes = g_byte_array_new();
5383 if (length > 0) {
5384 g_byte_array_append(bytes, value_ptr, length);
5385 }
5386 fvalue_set_byte_array(fi->value, bytes);
5387}
5388
5389static void
5390proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5391{
5392 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5393}
5394
5395/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5396 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5397 * is destroyed. */
5398proto_item *
5399proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5400 int length, const char* value)
5401{
5402 proto_item *pi;
5403 header_field_info *hfinfo;
5404 int item_length;
5405
5406 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", 5406, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5406,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5406, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5407 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5408 /*
5409 * Special case - if the length is 0, skip the test, so that
5410 * we can have an empty string right after the end of the
5411 * packet. (This handles URL-encoded forms where the last field
5412 * has no value so the form ends right after the =.)
5413 */
5414 if (item_length != 0)
5415 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5416
5417 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5418
5419 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", 5419
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5419, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5419, "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", 5419, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5420
5421 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", 5421, ((hfinfo))->abbrev))))
;
5422
5423 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5424 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5424, "length >= 0"
))))
;
5425
5426 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", 5426, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5427 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5428
5429 return pi;
5430}
5431
5432proto_item *
5433proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5434 int start, int length, const char* value,
5435 const char *format,
5436 ...)
5437{
5438 proto_item *pi;
5439 va_list ap;
5440
5441 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5442 if (pi != tree) {
5443 va_start(ap, format)__builtin_va_start(ap, format);
5444 proto_tree_set_representation_value(pi, format, ap);
5445 va_end(ap)__builtin_va_end(ap);
5446 }
5447
5448 return pi;
5449}
5450
5451proto_item *
5452proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5453 int start, int length, const char* value,
5454 const char *format, ...)
5455{
5456 proto_item *pi;
5457 va_list ap;
5458
5459 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5460 if (pi != tree) {
5461 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5461, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5462
5463 va_start(ap, format)__builtin_va_start(ap, format);
5464 proto_tree_set_representation(pi, format, ap);
5465 va_end(ap)__builtin_va_end(ap);
5466 }
5467
5468 return pi;
5469}
5470
5471/* Set the FT_STRING value */
5472static void
5473proto_tree_set_string(field_info *fi, const char* value)
5474{
5475 if (value) {
5476 fvalue_set_string(fi->value, value);
5477 } else {
5478 /*
5479 * XXX - why is a null value for a string field
5480 * considered valid?
5481 */
5482 fvalue_set_string(fi->value, "[ Null ]");
5483 }
5484}
5485
5486/* Set the FT_AX25 value */
5487static void
5488proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5489{
5490 fvalue_set_ax25(fi->value, value);
5491}
5492
5493static void
5494proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5495{
5496 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5497}
5498
5499/* Set the FT_VINES value */
5500static void
5501proto_tree_set_vines(field_info *fi, const uint8_t* value)
5502{
5503 fvalue_set_vines(fi->value, value);
5504}
5505
5506static void
5507proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5508{
5509 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5510}
5511
5512/* Add a FT_ETHER to a proto_tree */
5513proto_item *
5514proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5515 int length, const uint8_t* value)
5516{
5517 proto_item *pi;
5518 header_field_info *hfinfo;
5519
5520 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5521
5522 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", 5522
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5522, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5522, "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", 5522, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5523
5524 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",
5524, ((hfinfo))->abbrev))))
;
5525
5526 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5527 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5528
5529 return pi;
5530}
5531
5532proto_item *
5533proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5534 int start, int length, const uint8_t* value,
5535 const char *format, ...)
5536{
5537 proto_item *pi;
5538 va_list ap;
5539
5540 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5541 if (pi != tree) {
5542 va_start(ap, format)__builtin_va_start(ap, format);
5543 proto_tree_set_representation_value(pi, format, ap);
5544 va_end(ap)__builtin_va_end(ap);
5545 }
5546
5547 return pi;
5548}
5549
5550proto_item *
5551proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5552 int start, int length, const uint8_t* value,
5553 const char *format, ...)
5554{
5555 proto_item *pi;
5556 va_list ap;
5557
5558 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5559 if (pi != tree) {
5560 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5560, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5561
5562 va_start(ap, format)__builtin_va_start(ap, format);
5563 proto_tree_set_representation(pi, format, ap);
5564 va_end(ap)__builtin_va_end(ap);
5565 }
5566
5567 return pi;
5568}
5569
5570/* Set the FT_ETHER value */
5571static void
5572proto_tree_set_ether(field_info *fi, const uint8_t* value)
5573{
5574 fvalue_set_ether(fi->value, value);
5575}
5576
5577static void
5578proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5579{
5580 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5581}
5582
5583/* Add a FT_BOOLEAN to a proto_tree */
5584proto_item *
5585proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5586 int length, uint64_t value)
5587{
5588 proto_item *pi;
5589 header_field_info *hfinfo;
5590
5591 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5592
5593 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", 5593
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5593, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5593, "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", 5593, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5594
5595 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"
, 5595, ((hfinfo))->abbrev))))
;
5596
5597 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5598 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5599
5600 return pi;
5601}
5602
5603proto_item *
5604proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5605 tvbuff_t *tvb, int start, int length,
5606 uint64_t value, const char *format, ...)
5607{
5608 proto_item *pi;
5609 va_list ap;
5610
5611 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5612 if (pi != tree) {
5613 va_start(ap, format)__builtin_va_start(ap, format);
5614 proto_tree_set_representation_value(pi, format, ap);
5615 va_end(ap)__builtin_va_end(ap);
5616 }
5617
5618 return pi;
5619}
5620
5621proto_item *
5622proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5623 int start, int length, uint64_t value,
5624 const char *format, ...)
5625{
5626 proto_item *pi;
5627 va_list ap;
5628
5629 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5630 if (pi != tree) {
5631 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5631, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5632
5633 va_start(ap, format)__builtin_va_start(ap, format);
5634 proto_tree_set_representation(pi, format, ap);
5635 va_end(ap)__builtin_va_end(ap);
5636 }
5637
5638 return pi;
5639}
5640
5641/* Set the FT_BOOLEAN value */
5642static void
5643proto_tree_set_boolean(field_info *fi, uint64_t value)
5644{
5645 proto_tree_set_uint64(fi, value);
5646}
5647
5648/* Generate, into "buf", a string showing the bits of a bitfield.
5649 Return a pointer to the character after that string. */
5650static char *
5651other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5652{
5653 int i = 0;
5654 uint64_t bit;
5655 char *p;
5656
5657 p = buf;
5658
5659 /* This is a devel error. It is safer to stop here. */
5660 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5660, "width >= 1"
))))
;
5661
5662 bit = UINT64_C(1)1UL << (width - 1);
5663 for (;;) {
5664 if (mask & bit) {
5665 /* This bit is part of the field. Show its value. */
5666 if (val & bit)
5667 *p++ = '1';
5668 else
5669 *p++ = '0';
5670 } else {
5671 /* This bit is not part of the field. */
5672 *p++ = '.';
5673 }
5674 bit >>= 1;
5675 i++;
5676 if (i >= width)
5677 break;
5678 if (i % 4 == 0)
5679 *p++ = ' ';
5680 }
5681 *p = '\0';
5682 return p;
5683}
5684
5685static char *
5686decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5687{
5688 char *p;
5689
5690 p = other_decode_bitfield_value(buf, val, mask, width);
5691 p = g_stpcpy(p, " = ");
5692
5693 return p;
5694}
5695
5696static char *
5697other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5698{
5699 int i = 0;
5700 uint64_t bit;
5701 char *p;
5702
5703 p = buf;
5704
5705 /* This is a devel error. It is safer to stop here. */
5706 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5706, "width >= 1"
))))
;
5707
5708 bit = UINT64_C(1)1UL << (width - 1);
5709 for (;;) {
5710 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5711 (mask & bit)) {
5712 /* This bit is part of the field. Show its value. */
5713 if (val & bit)
5714 *p++ = '1';
5715 else
5716 *p++ = '0';
5717 } else {
5718 /* This bit is not part of the field. */
5719 *p++ = '.';
5720 }
5721 bit >>= 1;
5722 i++;
5723 if (i >= width)
5724 break;
5725 if (i % 4 == 0)
5726 *p++ = ' ';
5727 }
5728
5729 *p = '\0';
5730 return p;
5731}
5732
5733static char *
5734decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5735{
5736 char *p;
5737
5738 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5739 p = g_stpcpy(p, " = ");
5740
5741 return p;
5742}
5743
5744/* Add a FT_FLOAT to a proto_tree */
5745proto_item *
5746proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5747 int length, float value)
5748{
5749 proto_item *pi;
5750 header_field_info *hfinfo;
5751
5752 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5753
5754 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", 5754
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5754, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5754, "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", 5754, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5755
5756 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",
5756, ((hfinfo))->abbrev))))
;
5757
5758 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5759 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5760
5761 return pi;
5762}
5763
5764proto_item *
5765proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5766 int start, int length, float value,
5767 const char *format, ...)
5768{
5769 proto_item *pi;
5770 va_list ap;
5771
5772 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5773 if (pi != tree) {
5774 va_start(ap, format)__builtin_va_start(ap, format);
5775 proto_tree_set_representation_value(pi, format, ap);
5776 va_end(ap)__builtin_va_end(ap);
5777 }
5778
5779 return pi;
5780}
5781
5782proto_item *
5783proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5784 int start, int length, float value,
5785 const char *format, ...)
5786{
5787 proto_item *pi;
5788 va_list ap;
5789
5790 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5791 if (pi != tree) {
5792 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5792, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5793
5794 va_start(ap, format)__builtin_va_start(ap, format);
5795 proto_tree_set_representation(pi, format, ap);
5796 va_end(ap)__builtin_va_end(ap);
5797 }
5798
5799 return pi;
5800}
5801
5802/* Set the FT_FLOAT value */
5803static void
5804proto_tree_set_float(field_info *fi, float value)
5805{
5806 fvalue_set_floating(fi->value, value);
5807}
5808
5809/* Add a FT_DOUBLE to a proto_tree */
5810proto_item *
5811proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5812 int length, double value)
5813{
5814 proto_item *pi;
5815 header_field_info *hfinfo;
5816
5817 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5818
5819 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", 5819
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5819, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5819, "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", 5819, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5820
5821 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"
, 5821, ((hfinfo))->abbrev))))
;
5822
5823 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5824 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5825
5826 return pi;
5827}
5828
5829proto_item *
5830proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5831 int start, int length, double value,
5832 const char *format, ...)
5833{
5834 proto_item *pi;
5835 va_list ap;
5836
5837 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5838 if (pi != tree) {
5839 va_start(ap, format)__builtin_va_start(ap, format);
5840 proto_tree_set_representation_value(pi, format, ap);
5841 va_end(ap)__builtin_va_end(ap);
5842 }
5843
5844 return pi;
5845}
5846
5847proto_item *
5848proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5849 int start, int length, double value,
5850 const char *format, ...)
5851{
5852 proto_item *pi;
5853 va_list ap;
5854
5855 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5856 if (pi != tree) {
5857 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5857, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5858
5859 va_start(ap, format)__builtin_va_start(ap, format);
5860 proto_tree_set_representation(pi, format, ap);
5861 va_end(ap)__builtin_va_end(ap);
5862 }
5863
5864 return pi;
5865}
5866
5867/* Set the FT_DOUBLE value */
5868static void
5869proto_tree_set_double(field_info *fi, double value)
5870{
5871 fvalue_set_floating(fi->value, value);
5872}
5873
5874/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5875proto_item *
5876proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5877 int length, uint32_t value)
5878{
5879 proto_item *pi = NULL((void*)0);
5880 header_field_info *hfinfo;
5881
5882 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5883
5884 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", 5884
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5884, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5884, "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", 5884, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5885
5886 switch (hfinfo->type) {
5887 case FT_CHAR:
5888 case FT_UINT8:
5889 case FT_UINT16:
5890 case FT_UINT24:
5891 case FT_UINT32:
5892 case FT_FRAMENUM:
5893 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5894 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5895 break;
5896
5897 default:
5898 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)
5899 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)
;
5900 }
5901
5902 return pi;
5903}
5904
5905proto_item *
5906proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5907 int start, int length, uint32_t value,
5908 const char *format, ...)
5909{
5910 proto_item *pi;
5911 va_list ap;
5912
5913 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5914 if (pi != tree) {
5915 va_start(ap, format)__builtin_va_start(ap, format);
5916 proto_tree_set_representation_value(pi, format, ap);
5917 va_end(ap)__builtin_va_end(ap);
5918 }
5919
5920 return pi;
5921}
5922
5923proto_item *
5924proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5925 int start, int length, uint32_t value,
5926 const char *format, ...)
5927{
5928 proto_item *pi;
5929 va_list ap;
5930
5931 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5932 if (pi != tree) {
5933 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5933, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5934
5935 va_start(ap, format)__builtin_va_start(ap, format);
5936 proto_tree_set_representation(pi, format, ap);
5937 va_end(ap)__builtin_va_end(ap);
5938 }
5939
5940 return pi;
5941}
5942
5943/* Set the FT_UINT{8,16,24,32} value */
5944static void
5945proto_tree_set_uint(field_info *fi, uint32_t value)
5946{
5947 const header_field_info *hfinfo;
5948 uint32_t integer;
5949
5950 hfinfo = fi->hfinfo;
5951 integer = value;
5952
5953 if (hfinfo->bitmask) {
5954 /* Mask out irrelevant portions */
5955 integer &= (uint32_t)(hfinfo->bitmask);
5956
5957 /* Shift bits */
5958 integer >>= hfinfo_bitshift(hfinfo);
5959
5960 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5961 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)
;
5962 }
5963
5964 fvalue_set_uinteger(fi->value, integer);
5965}
5966
5967/* Add FT_UINT{40,48,56,64} to a proto_tree */
5968proto_item *
5969proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5970 int length, uint64_t value)
5971{
5972 proto_item *pi = NULL((void*)0);
5973 header_field_info *hfinfo;
5974
5975 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5976
5977 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", 5977
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5977, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5977, "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", 5977, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5978
5979 switch (hfinfo->type) {
5980 case FT_UINT40:
5981 case FT_UINT48:
5982 case FT_UINT56:
5983 case FT_UINT64:
5984 case FT_FRAMENUM:
5985 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5986 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
5987 break;
5988
5989 default:
5990 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)
5991 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)
;
5992 }
5993
5994 return pi;
5995}
5996
5997proto_item *
5998proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5999 int start, int length, uint64_t value,
6000 const char *format, ...)
6001{
6002 proto_item *pi;
6003 va_list ap;
6004
6005 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6006 if (pi != tree) {
6007 va_start(ap, format)__builtin_va_start(ap, format);
6008 proto_tree_set_representation_value(pi, format, ap);
6009 va_end(ap)__builtin_va_end(ap);
6010 }
6011
6012 return pi;
6013}
6014
6015proto_item *
6016proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6017 int start, int length, uint64_t value,
6018 const char *format, ...)
6019{
6020 proto_item *pi;
6021 va_list ap;
6022
6023 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6024 if (pi != tree) {
6025 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6025, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6026
6027 va_start(ap, format)__builtin_va_start(ap, format);
6028 proto_tree_set_representation(pi, format, ap);
6029 va_end(ap)__builtin_va_end(ap);
6030 }
6031
6032 return pi;
6033}
6034
6035/* Set the FT_UINT{40,48,56,64} value */
6036static void
6037proto_tree_set_uint64(field_info *fi, uint64_t value)
6038{
6039 const header_field_info *hfinfo;
6040 uint64_t integer;
6041
6042 hfinfo = fi->hfinfo;
6043 integer = value;
6044
6045 if (hfinfo->bitmask) {
6046 /* Mask out irrelevant portions */
6047 integer &= hfinfo->bitmask;
6048
6049 /* Shift bits */
6050 integer >>= hfinfo_bitshift(hfinfo);
6051
6052 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6053 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)
;
6054 }
6055
6056 fvalue_set_uinteger64(fi->value, integer);
6057}
6058
6059/* Add FT_INT{8,16,24,32} to a proto_tree */
6060proto_item *
6061proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6062 int length, int32_t value)
6063{
6064 proto_item *pi = NULL((void*)0);
6065 header_field_info *hfinfo;
6066
6067 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6068
6069 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", 6069
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6069, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6069, "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", 6069, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6070
6071 switch (hfinfo->type) {
6072 case FT_INT8:
6073 case FT_INT16:
6074 case FT_INT24:
6075 case FT_INT32:
6076 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6077 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6078 break;
6079
6080 default:
6081 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)
6082 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6083 }
6084
6085 return pi;
6086}
6087
6088proto_item *
6089proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6090 int start, int length, int32_t value,
6091 const char *format, ...)
6092{
6093 proto_item *pi;
6094 va_list ap;
6095
6096 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6097 if (pi != tree) {
6098 va_start(ap, format)__builtin_va_start(ap, format);
6099 proto_tree_set_representation_value(pi, format, ap);
6100 va_end(ap)__builtin_va_end(ap);
6101 }
6102
6103 return pi;
6104}
6105
6106proto_item *
6107proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6108 int start, int length, int32_t value,
6109 const char *format, ...)
6110{
6111 proto_item *pi;
6112 va_list ap;
6113
6114 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6115 if (pi != tree) {
6116 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6116, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6117
6118 va_start(ap, format)__builtin_va_start(ap, format);
6119 proto_tree_set_representation(pi, format, ap);
6120 va_end(ap)__builtin_va_end(ap);
6121 }
6122
6123 return pi;
6124}
6125
6126/* Set the FT_INT{8,16,24,32} value */
6127static void
6128proto_tree_set_int(field_info *fi, int32_t value)
6129{
6130 const header_field_info *hfinfo;
6131 uint32_t integer;
6132 int no_of_bits;
6133
6134 hfinfo = fi->hfinfo;
6135 integer = (uint32_t) value;
6136
6137 if (hfinfo->bitmask) {
6138 /* Mask out irrelevant portions */
6139 integer &= (uint32_t)(hfinfo->bitmask);
6140
6141 /* Shift bits */
6142 integer >>= hfinfo_bitshift(hfinfo);
6143
6144 no_of_bits = ws_count_ones(hfinfo->bitmask);
6145 integer = ws_sign_ext32(integer, no_of_bits);
6146
6147 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6148 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)
;
6149 }
6150
6151 fvalue_set_sinteger(fi->value, integer);
6152}
6153
6154/* Add FT_INT{40,48,56,64} to a proto_tree */
6155proto_item *
6156proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6157 int length, int64_t value)
6158{
6159 proto_item *pi = NULL((void*)0);
6160 header_field_info *hfinfo;
6161
6162 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6163
6164 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", 6164
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6164, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6164, "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", 6164, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6165
6166 switch (hfinfo->type) {
6167 case FT_INT40:
6168 case FT_INT48:
6169 case FT_INT56:
6170 case FT_INT64:
6171 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6172 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6173 break;
6174
6175 default:
6176 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)
6177 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6178 }
6179
6180 return pi;
6181}
6182
6183proto_item *
6184proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6185 int start, int length, int64_t value,
6186 const char *format, ...)
6187{
6188 proto_item *pi;
6189 va_list ap;
6190
6191 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6192 if (pi != tree) {
6193 va_start(ap, format)__builtin_va_start(ap, format);
6194 proto_tree_set_representation_value(pi, format, ap);
6195 va_end(ap)__builtin_va_end(ap);
6196 }
6197
6198 return pi;
6199}
6200
6201/* Set the FT_INT{40,48,56,64} value */
6202static void
6203proto_tree_set_int64(field_info *fi, int64_t value)
6204{
6205 const header_field_info *hfinfo;
6206 uint64_t integer;
6207 int no_of_bits;
6208
6209 hfinfo = fi->hfinfo;
6210 integer = value;
6211
6212 if (hfinfo->bitmask) {
6213 /* Mask out irrelevant portions */
6214 integer &= hfinfo->bitmask;
6215
6216 /* Shift bits */
6217 integer >>= hfinfo_bitshift(hfinfo);
6218
6219 no_of_bits = ws_count_ones(hfinfo->bitmask);
6220 integer = ws_sign_ext64(integer, no_of_bits);
6221
6222 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6223 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)
;
6224 }
6225
6226 fvalue_set_sinteger64(fi->value, integer);
6227}
6228
6229proto_item *
6230proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6231 int start, int length, int64_t value,
6232 const char *format, ...)
6233{
6234 proto_item *pi;
6235 va_list ap;
6236
6237 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6238 if (pi != tree) {
6239 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6239, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6240
6241 va_start(ap, format)__builtin_va_start(ap, format);
6242 proto_tree_set_representation(pi, format, ap);
6243 va_end(ap)__builtin_va_end(ap);
6244 }
6245
6246 return pi;
6247}
6248
6249/* Add a FT_EUI64 to a proto_tree */
6250proto_item *
6251proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6252 int length, const uint64_t value)
6253{
6254 proto_item *pi;
6255 header_field_info *hfinfo;
6256
6257 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6258
6259 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", 6259
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6259, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6259, "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", 6259, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6260
6261 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",
6261, ((hfinfo))->abbrev))))
;
6262
6263 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6264 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6265
6266 return pi;
6267}
6268
6269proto_item *
6270proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6271 int start, int length, const uint64_t value,
6272 const char *format, ...)
6273{
6274 proto_item *pi;
6275 va_list ap;
6276
6277 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6278 if (pi != tree) {
6279 va_start(ap, format)__builtin_va_start(ap, format);
6280 proto_tree_set_representation_value(pi, format, ap);
6281 va_end(ap)__builtin_va_end(ap);
6282 }
6283
6284 return pi;
6285}
6286
6287proto_item *
6288proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6289 int start, int length, const uint64_t value,
6290 const char *format, ...)
6291{
6292 proto_item *pi;
6293 va_list ap;
6294
6295 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6296 if (pi != tree) {
6297 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6297, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6298
6299 va_start(ap, format)__builtin_va_start(ap, format);
6300 proto_tree_set_representation(pi, format, ap);
6301 va_end(ap)__builtin_va_end(ap);
6302 }
6303
6304 return pi;
6305}
6306
6307/* Set the FT_EUI64 value */
6308static void
6309proto_tree_set_eui64(field_info *fi, const uint64_t value)
6310{
6311 uint8_t v[FT_EUI64_LEN8];
6312 phton64(v, value);
6313 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6314}
6315
6316static void
6317proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6318{
6319 if (encoding)
6320 {
6321 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6322 } else {
6323 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6324 }
6325}
6326
6327proto_item *
6328proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6329 const mac_hf_list_t *list_generic,
6330 int idx, tvbuff_t *tvb,
6331 proto_tree *tree, int offset)
6332{
6333 const uint8_t addr[6];
6334 const char *addr_name = NULL((void*)0);
6335 const char *oui_name = NULL((void*)0);
6336 proto_item *addr_item = NULL((void*)0);
6337 proto_tree *addr_tree = NULL((void*)0);
6338 proto_item *ret_val = NULL((void*)0);
6339
6340 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6341 return NULL((void*)0);
6342 }
6343
6344 /* Resolve what we can of the address */
6345 tvb_memcpy(tvb, (void *)addr, offset, 6);
6346 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6347 addr_name = get_ether_name(addr);
6348 }
6349 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6350 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6351 }
6352
6353 /* Add the item for the specific address type */
6354 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6355 if (idx >= 0) {
6356 addr_tree = proto_item_add_subtree(ret_val, idx);
6357 }
6358 else {
6359 addr_tree = tree;
6360 }
6361
6362 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6363 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6364 tvb, offset, 6, addr_name);
6365 proto_item_set_generated(addr_item);
6366 proto_item_set_hidden(addr_item);
6367 }
6368
6369 if (list_specific->hf_oui != NULL((void*)0)) {
6370 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6371 proto_item_set_generated(addr_item);
6372 proto_item_set_hidden(addr_item);
6373
6374 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6375 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6376 proto_item_set_generated(addr_item);
6377 proto_item_set_hidden(addr_item);
6378 }
6379 }
6380
6381 if (list_specific->hf_lg != NULL((void*)0)) {
6382 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6383 }
6384 if (list_specific->hf_ig != NULL((void*)0)) {
6385 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6386 }
6387
6388 /* Were we given a list for generic address fields? If not, stop here */
6389 if (list_generic == NULL((void*)0)) {
6390 return ret_val;
6391 }
6392
6393 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6394 proto_item_set_hidden(addr_item);
6395
6396 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6397 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6398 tvb, offset, 6, addr_name);
6399 proto_item_set_generated(addr_item);
6400 proto_item_set_hidden(addr_item);
6401 }
6402
6403 if (list_generic->hf_oui != NULL((void*)0)) {
6404 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6405 proto_item_set_generated(addr_item);
6406 proto_item_set_hidden(addr_item);
6407
6408 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6409 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6410 proto_item_set_generated(addr_item);
6411 proto_item_set_hidden(addr_item);
6412 }
6413 }
6414
6415 if (list_generic->hf_lg != NULL((void*)0)) {
6416 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6417 proto_item_set_hidden(addr_item);
6418 }
6419 if (list_generic->hf_ig != NULL((void*)0)) {
6420 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6421 proto_item_set_hidden(addr_item);
6422 }
6423 return ret_val;
6424}
6425
6426static proto_item *
6427proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6428{
6429 proto_node *pnode, *tnode, *sibling;
6430 field_info *tfi;
6431 unsigned depth = 1;
6432
6433 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6433, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6434
6435 /*
6436 * Restrict our depth. proto_tree_traverse_pre_order and
6437 * proto_tree_traverse_post_order (and possibly others) are recursive
6438 * so we need to be mindful of our stack size.
6439 */
6440 if (tree->first_child == NULL((void*)0)) {
6441 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6442 depth++;
6443 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6444 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__)), 6447)))
6445 "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__)), 6447)))
6446 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__)), 6447)))
6447 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__)), 6447)))
;
6448 }
6449 }
6450 }
6451
6452 /*
6453 * Make sure "tree" is ready to have subtrees under it, by
6454 * checking whether it's been given an ett_ value.
6455 *
6456 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6457 * node of the protocol tree. That node is not displayed,
6458 * so it doesn't need an ett_ value to remember whether it
6459 * was expanded.
6460 */
6461 tnode = tree;
6462 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6463 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6464 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"
, 6465)
6465 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"
, 6465)
;
6466 /* XXX - is it safe to continue here? */
6467 }
6468
6469 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6470 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6471 pnode->parent = tnode;
6472 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6473 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6474 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6475
6476 if (tnode->last_child != NULL((void*)0)) {
6477 sibling = tnode->last_child;
6478 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6478, "sibling->next == ((void*)0)"
))))
;
6479 sibling->next = pnode;
6480 } else
6481 tnode->first_child = pnode;
6482 tnode->last_child = pnode;
6483
6484 /* We should not be adding a fake node for an interesting field */
6485 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", 6485, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6486
6487 /* XXX - Should the proto_item have a header_field_info member, at least
6488 * for faked items, to know what hfi was faked? (Some dissectors look at
6489 * the tree items directly.)
6490 */
6491 return (proto_item *)pnode;
6492}
6493
6494/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6495static proto_item *
6496proto_tree_add_node(proto_tree *tree, field_info *fi)
6497{
6498 proto_node *pnode, *tnode, *sibling;
6499 field_info *tfi;
6500 unsigned depth = 1;
6501
6502 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6502, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6503
6504 /*
6505 * Restrict our depth. proto_tree_traverse_pre_order and
6506 * proto_tree_traverse_post_order (and possibly others) are recursive
6507 * so we need to be mindful of our stack size.
6508 */
6509 if (tree->first_child == NULL((void*)0)) {
6510 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6511 depth++;
6512 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6513 fvalue_free(fi->value);
6514 fi->value = NULL((void*)0);
6515 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__)), 6518)))
6516 "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__)), 6518)))
6517 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__)), 6518)))
6518 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__)), 6518)))
;
6519 }
6520 }
6521 }
6522
6523 /*
6524 * Make sure "tree" is ready to have subtrees under it, by
6525 * checking whether it's been given an ett_ value.
6526 *
6527 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6528 * node of the protocol tree. That node is not displayed,
6529 * so it doesn't need an ett_ value to remember whether it
6530 * was expanded.
6531 */
6532 tnode = tree;
6533 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6534 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6535 /* Since we are not adding fi to a node, its fvalue won't get
6536 * freed by proto_tree_free_node(), so free it now.
6537 */
6538 fvalue_free(fi->value);
6539 fi->value = NULL((void*)0);
6540 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", 6541)
6541 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", 6541)
;
6542 /* XXX - is it safe to continue here? */
6543 }
6544
6545 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6546 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6547 pnode->parent = tnode;
6548 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6549 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6550 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6551
6552 if (tnode->last_child != NULL((void*)0)) {
6553 sibling = tnode->last_child;
6554 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6554, "sibling->next == ((void*)0)"
))))
;
6555 sibling->next = pnode;
6556 } else
6557 tnode->first_child = pnode;
6558 tnode->last_child = pnode;
6559
6560 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6561
6562 return (proto_item *)pnode;
6563}
6564
6565
6566/* Generic way to allocate field_info and add to proto_tree.
6567 * Sets *pfi to address of newly-allocated field_info struct */
6568static proto_item *
6569proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6570 int *length)
6571{
6572 proto_item *pi;
6573 field_info *fi;
6574 int item_length;
6575
6576 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6577 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6578 pi = proto_tree_add_node(tree, fi);
6579
6580 return pi;
6581}
6582
6583
6584static void
6585get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6586 int *item_length, const unsigned encoding)
6587{
6588 int length_remaining;
6589
6590 /*
6591 * We only allow a null tvbuff if the item has a zero length,
6592 * i.e. if there's no data backing it.
6593 */
6594 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", 6594, "tvb != ((void*)0) || *length == 0"
))))
;
6595
6596 /*
6597 * XXX - in some protocols, there are 32-bit unsigned length
6598 * fields, so lengths in protocol tree and tvbuff routines
6599 * should really be unsigned. We should have, for those
6600 * field types for which "to the end of the tvbuff" makes sense,
6601 * additional routines that take no length argument and
6602 * add fields that run to the end of the tvbuff.
6603 */
6604 if (*length == -1) {
6605 /*
6606 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6607 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6608 * of -1 means "set the length to what remains in the
6609 * tvbuff".
6610 *
6611 * The assumption is either that
6612 *
6613 * 1) the length of the item can only be determined
6614 * by dissection (typically true of items with
6615 * subitems, which are probably FT_NONE or
6616 * FT_PROTOCOL)
6617 *
6618 * or
6619 *
6620 * 2) if the tvbuff is "short" (either due to a short
6621 * snapshot length or due to lack of reassembly of
6622 * fragments/segments/whatever), we want to display
6623 * what's available in the field (probably FT_BYTES
6624 * or FT_STRING) and then throw an exception later
6625 *
6626 * or
6627 *
6628 * 3) the field is defined to be "what's left in the
6629 * packet"
6630 *
6631 * so we set the length to what remains in the tvbuff so
6632 * that, if we throw an exception while dissecting, it
6633 * has what is probably the right value.
6634 *
6635 * For FT_STRINGZ, it means "the string is null-terminated,
6636 * not null-padded; set the length to the actual length
6637 * of the string", and if the tvbuff if short, we just
6638 * throw an exception.
6639 *
6640 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6641 * it means "find the end of the string",
6642 * and if the tvbuff if short, we just throw an exception.
6643 *
6644 * It's not valid for any other type of field. For those
6645 * fields, we treat -1 the same way we treat other
6646 * negative values - we assume the length is a Really
6647 * Big Positive Number, and throw a ReportedBoundsError
6648 * exception, under the assumption that the Really Big
6649 * Length would run past the end of the packet.
6650 */
6651 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
))
)) {
6652 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6653 /*
6654 * Leave the length as -1, so our caller knows
6655 * it was -1.
6656 */
6657 *item_length = *length;
6658 return;
6659 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6660 switch (tvb_get_uint8(tvb, start) >> 6)
6661 {
6662 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6663 *item_length = 1;
6664 break;
6665 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6666 *item_length = 2;
6667 break;
6668 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6669 *item_length = 4;
6670 break;
6671 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6672 *item_length = 8;
6673 break;
6674 }
6675 }
6676 }
6677
6678 switch (hfinfo->type) {
6679
6680 case FT_PROTOCOL:
6681 case FT_NONE:
6682 case FT_BYTES:
6683 case FT_STRING:
6684 case FT_STRINGZPAD:
6685 case FT_STRINGZTRUNC:
6686 /*
6687 * We allow FT_PROTOCOLs to be zero-length -
6688 * for example, an ONC RPC NULL procedure has
6689 * neither arguments nor reply, so the
6690 * payload for that protocol is empty.
6691 *
6692 * We also allow the others to be zero-length -
6693 * because that's the way the code has been for a
6694 * long, long time.
6695 *
6696 * However, we want to ensure that the start
6697 * offset is not *past* the byte past the end
6698 * of the tvbuff: we throw an exception in that
6699 * case.
6700 */
6701 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6702 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6702, "*length >= 0"
))))
;
6703 break;
6704
6705 case FT_STRINGZ:
6706 /*
6707 * Leave the length as -1, so our caller knows
6708 * it was -1.
6709 */
6710 break;
6711
6712 default:
6713 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6714 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6714))
;
6715 }
6716 *item_length = *length;
6717 } else {
6718 *item_length = *length;
6719 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6720 /*
6721 * These types are for interior nodes of the
6722 * tree, and don't have data associated with
6723 * them; if the length is negative (XXX - see
6724 * above) or goes past the end of the tvbuff,
6725 * cut it short at the end of the tvbuff.
6726 * That way, if this field is selected in
6727 * Wireshark, we don't highlight stuff past
6728 * the end of the data.
6729 */
6730 /* XXX - what to do, if we don't have a tvb? */
6731 if (tvb) {
6732 length_remaining = tvb_captured_length_remaining(tvb, start);
6733 if (*item_length < 0 ||
6734 (*item_length > 0 &&
6735 (length_remaining < *item_length)))
6736 *item_length = length_remaining;
6737 }
6738 }
6739 if (*item_length < 0) {
6740 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6741 }
6742 }
6743}
6744
6745static int
6746get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6747 int length, unsigned item_length, const int encoding)
6748{
6749 uint32_t n;
6750
6751 /*
6752 * We need to get the correct item length here.
6753 * That's normally done by proto_tree_new_item(),
6754 * but we won't be calling it.
6755 */
6756 switch (hfinfo->type) {
6757
6758 case FT_NONE:
6759 case FT_PROTOCOL:
6760 case FT_BYTES:
6761 /*
6762 * The length is the specified length.
6763 */
6764 break;
6765
6766 case FT_UINT_BYTES:
6767 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6768 item_length += n;
6769 if ((int)item_length < length) {
6770 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6771 }
6772 break;
6773
6774 /* XXX - make these just FT_UINT? */
6775 case FT_UINT8:
6776 case FT_UINT16:
6777 case FT_UINT24:
6778 case FT_UINT32:
6779 case FT_UINT40:
6780 case FT_UINT48:
6781 case FT_UINT56:
6782 case FT_UINT64:
6783 /* XXX - make these just FT_INT? */
6784 case FT_INT8:
6785 case FT_INT16:
6786 case FT_INT24:
6787 case FT_INT32:
6788 case FT_INT40:
6789 case FT_INT48:
6790 case FT_INT56:
6791 case FT_INT64:
6792 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6793 if (length < -1) {
6794 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6795 }
6796 if (length == -1) {
6797 uint64_t dummy;
6798 /* This can throw an exception */
6799 /* XXX - do this without fetching the varint? */
6800 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6801 if (length == 0) {
6802 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6803 }
6804 }
6805 item_length = length;
6806 break;
6807 }
6808
6809 /*
6810 * The length is the specified length.
6811 */
6812 break;
6813
6814 case FT_BOOLEAN:
6815 case FT_CHAR:
6816 case FT_IPv4:
6817 case FT_IPXNET:
6818 case FT_IPv6:
6819 case FT_FCWWN:
6820 case FT_AX25:
6821 case FT_VINES:
6822 case FT_ETHER:
6823 case FT_EUI64:
6824 case FT_GUID:
6825 case FT_OID:
6826 case FT_REL_OID:
6827 case FT_SYSTEM_ID:
6828 case FT_FLOAT:
6829 case FT_DOUBLE:
6830 case FT_STRING:
6831 /*
6832 * The length is the specified length.
6833 */
6834 break;
6835
6836 case FT_STRINGZ:
6837 if (length < -1) {
6838 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6839 }
6840 if (length == -1) {
6841 /* This can throw an exception */
6842 /* XXX - do this without fetching the string? */
6843 wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, &length, encoding));
6844 }
6845 item_length = length;
6846 break;
6847
6848 case FT_UINT_STRING:
6849 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6850 item_length += n;
6851 if ((int)item_length < length) {
6852 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6853 }
6854 break;
6855
6856 case FT_STRINGZPAD:
6857 case FT_STRINGZTRUNC:
6858 case FT_ABSOLUTE_TIME:
6859 case FT_RELATIVE_TIME:
6860 case FT_IEEE_11073_SFLOAT:
6861 case FT_IEEE_11073_FLOAT:
6862 /*
6863 * The length is the specified length.
6864 */
6865 break;
6866
6867 default:
6868 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
))
6869 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
))
6870 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
))
6871 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
))
;
6872 break;
6873 }
6874 return item_length;
6875}
6876
6877// This was arbitrarily chosen, but if you're adding 50K items to the tree
6878// without advancing the offset you should probably take a long, hard look
6879// at what you're doing.
6880// We *could* make this a configurable option, but I (Gerald) would like to
6881// avoid adding yet another nerd knob.
6882# define PROTO_TREE_MAX_IDLE50000 50000
6883static field_info *
6884new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6885 const int start, const int item_length)
6886{
6887 field_info *fi;
6888
6889 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6890
6891 fi->hfinfo = hfinfo;
6892 fi->start = start;
6893 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6894 /* add the data source tvbuff */
6895 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6896
6897 // If our start offset hasn't advanced after adding many items it probably
6898 // means we're in a large or infinite loop.
6899 if (fi->start > 0) {
6900 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6901 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6902 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", 6902, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6903 } else {
6904 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6905 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6906 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6907 }
6908 }
6909 fi->length = item_length;
6910 fi->tree_type = -1;
6911 fi->flags = 0;
6912 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6913 /* If the tree is not visible, set the item hidden, unless we
6914 * need the representation or length and can't fake them.
6915 */
6916 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6917 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6918 }
6919 }
6920 fi->value = fvalue_new(fi->hfinfo->type);
6921 fi->rep = NULL((void*)0);
6922
6923 fi->appendix_start = 0;
6924 fi->appendix_length = 0;
6925
6926 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6927 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6928
6929 return fi;
6930}
6931
6932static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6933{
6934 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6935 return 0;
6936 }
6937
6938 /* Search for field name */
6939 char *ptr = strstr(representation, hfinfo->name);
6940 if (!ptr) {
6941 return 0;
6942 }
6943
6944 /* Check if field name ends with the ": " delimiter */
6945 ptr += strlen(hfinfo->name);
6946 if (strncmp(ptr, ": ", 2) == 0) {
6947 ptr += 2;
6948 }
6949
6950 /* Return offset to after field name */
6951 return ptr - representation;
6952}
6953
6954static size_t label_find_name_pos(const item_label_t *rep)
6955{
6956 size_t name_pos = 0;
6957
6958 /* If the value_pos is too small or too large, we can't find the expected format */
6959 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
6960 return 0;
6961 }
6962
6963 /* Check if the format looks like "label: value", then set name_pos before ':'. */
6964 if (rep->representation[rep->value_pos-2] == ':') {
6965 name_pos = rep->value_pos - 2;
6966 }
6967
6968 return name_pos;
6969}
6970
6971/* If the protocol tree is to be visible, set the representation of a
6972 proto_tree entry with the name of the field for the item and with
6973 the value formatted with the supplied printf-style format and
6974 argument list. */
6975static void
6976proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6977{
6978 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6978, __func__, "assertion failed: %s", "pi"
); } while (0)
;
6979
6980 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6981 * items string representation */
6982 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
6983 size_t name_pos, ret = 0;
6984 char *str;
6985 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6986 const header_field_info *hf;
6987
6988 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6988, "fi"))))
;
6989
6990 hf = fi->hfinfo;
6991
6992 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;
;
6993 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))
)) {
6994 uint64_t val;
6995 char *p;
6996
6997 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)
)
6998 val = fvalue_get_uinteger(fi->value);
6999 else
7000 val = fvalue_get_uinteger64(fi->value);
7001
7002 val <<= hfinfo_bitshift(hf);
7003
7004 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7005 ret = (p - fi->rep->representation);
7006 }
7007
7008 /* put in the hf name */
7009 name_pos = ret = label_concat(fi->rep->representation, ret, hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, hf->
name, 0)
;
7010
7011 ret = label_concat(fi->rep->representation, ret, ": ")ws_label_strcpy(fi->rep->representation, 240, ret, ": "
, 0)
;
7012 /* If possible, Put in the value of the string */
7013 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7014 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"
, 7014, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7015 fi->rep->value_pos = ret;
7016 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, str, 0);
7017 if (ret >= ITEM_LABEL_LENGTH240) {
7018 /* Uh oh, we don't have enough room. Tell the user
7019 * that the field is truncated.
7020 */
7021 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7022 }
7023 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7024 }
7025}
7026
7027/* If the protocol tree is to be visible, set the representation of a
7028 proto_tree entry with the representation formatted with the supplied
7029 printf-style format and argument list. */
7030static void
7031proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7032{
7033 size_t ret; /*tmp return value */
7034 char *str;
7035 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7036
7037 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7037, "fi"))))
;
7038
7039 if (!proto_item_is_hidden(pi)) {
7040 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;
;
7041
7042 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7043 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"
, 7043, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7044 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7045 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7046 if (ret >= ITEM_LABEL_LENGTH240) {
7047 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7048 size_t name_pos = label_find_name_pos(fi->rep);
7049 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7050 }
7051 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7052 }
7053}
7054
7055static int
7056proto_strlcpy(char *dest, const char *src, size_t dest_size)
7057{
7058 if (dest_size == 0) return 0;
7059
7060 size_t res = g_strlcpy(dest, src, dest_size);
7061
7062 /* At most dest_size - 1 characters will be copied
7063 * (unless dest_size is 0). */
7064 if (res >= dest_size)
7065 res = dest_size - 1;
7066 return (int) res;
7067}
7068
7069static header_field_info *
7070hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7071{
7072 header_field_info *dup_hfinfo;
7073
7074 if (hfinfo->same_name_prev_id == -1)
7075 return NULL((void*)0);
7076 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", 7076
, __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", 7076, "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", 7076,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7077 return dup_hfinfo;
7078}
7079
7080static void
7081hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7082{
7083 g_free(last_field_name);
7084 last_field_name = NULL((void*)0);
7085
7086 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7087 /* No hfinfo with the same name */
7088 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7089 return;
7090 }
7091
7092 if (hfinfo->same_name_next) {
7093 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7094 }
7095
7096 if (hfinfo->same_name_prev_id != -1) {
7097 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7098 same_name_prev->same_name_next = hfinfo->same_name_next;
7099 if (!hfinfo->same_name_next) {
7100 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7101 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7102 }
7103 }
7104}
7105
7106int
7107proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7108{
7109 const header_field_info *hfinfo = finfo->hfinfo;
7110 int label_len = 0;
7111 char *tmp_str;
7112 const char *str;
7113 const uint8_t *bytes;
7114 uint32_t number;
7115 uint64_t number64;
7116 const char *hf_str_val;
7117 char number_buf[NUMBER_LABEL_LENGTH80];
7118 const char *number_out;
7119 address addr;
7120 const ipv4_addr_and_mask *ipv4;
7121 const ipv6_addr_and_prefix *ipv6;
7122
7123 switch (hfinfo->type) {
7124
7125 case FT_NONE:
7126 case FT_PROTOCOL:
7127 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7128
7129 case FT_UINT_BYTES:
7130 case FT_BYTES:
7131 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7132 hfinfo,
7133 fvalue_get_bytes_data(finfo->value),
7134 (unsigned)fvalue_length2(finfo->value),
7135 label_str_size);
7136 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7137 wmem_free(NULL((void*)0), tmp_str);
7138 break;
7139
7140 case FT_ABSOLUTE_TIME:
7141 {
7142 const nstime_t *value = fvalue_get_time(finfo->value);
7143 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7144 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7145 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7146 }
7147 if (hfinfo->strings) {
7148 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7149 if (time_string != NULL((void*)0)) {
7150 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7151 break;
7152 }
7153 }
7154 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7155 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7156 wmem_free(NULL((void*)0), tmp_str);
7157 break;
7158 }
7159
7160 case FT_RELATIVE_TIME:
7161 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7162 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7163 wmem_free(NULL((void*)0), tmp_str);
7164 break;
7165
7166 case FT_BOOLEAN:
7167 number64 = fvalue_get_uinteger64(finfo->value);
7168 label_len = proto_strlcpy(display_label_str,
7169 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7170 break;
7171
7172 case FT_CHAR:
7173 number = fvalue_get_uinteger(finfo->value);
7174
7175 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7176 char tmp[ITEM_LABEL_LENGTH240];
7177 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7178
7179 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7179, "fmtfunc"))))
;
7180 fmtfunc(tmp, number);
7181
7182 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7183
7184 } else if (hfinfo->strings) {
7185 number_out = hf_try_val_to_str(number, hfinfo);
7186
7187 if (!number_out) {
7188 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7189 }
7190
7191 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7192
7193 } else {
7194 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7195
7196 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7197 }
7198
7199 break;
7200
7201 /* XXX - make these just FT_NUMBER? */
7202 case FT_INT8:
7203 case FT_INT16:
7204 case FT_INT24:
7205 case FT_INT32:
7206 case FT_UINT8:
7207 case FT_UINT16:
7208 case FT_UINT24:
7209 case FT_UINT32:
7210 case FT_FRAMENUM:
7211 hf_str_val = NULL((void*)0);
7212 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
))
?
7213 (uint32_t) fvalue_get_sinteger(finfo->value) :
7214 fvalue_get_uinteger(finfo->value);
7215
7216 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7217 char tmp[ITEM_LABEL_LENGTH240];
7218 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7219
7220 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7220, "fmtfunc"))))
;
7221 fmtfunc(tmp, number);
7222
7223 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7224
7225 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7226 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7227 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7228 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7229 hf_str_val = hf_try_val_to_str(number, hfinfo);
7230 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7231 } else {
7232 number_out = hf_try_val_to_str(number, hfinfo);
7233
7234 if (!number_out) {
7235 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7236 }
7237
7238 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7239 }
7240 } else {
7241 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7242
7243 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7244 }
7245
7246 break;
7247
7248 case FT_INT40:
7249 case FT_INT48:
7250 case FT_INT56:
7251 case FT_INT64:
7252 case FT_UINT40:
7253 case FT_UINT48:
7254 case FT_UINT56:
7255 case FT_UINT64:
7256 hf_str_val = NULL((void*)0);
7257 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
))
?
7258 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7259 fvalue_get_uinteger64(finfo->value);
7260
7261 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7262 char tmp[ITEM_LABEL_LENGTH240];
7263 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7264
7265 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7265, "fmtfunc64"
))))
;
7266 fmtfunc64(tmp, number64);
7267
7268 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7269 } else if (hfinfo->strings) {
7270 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7271 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7272 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7273 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7274 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7275 } else {
7276 number_out = hf_try_val64_to_str(number64, hfinfo);
7277
7278 if (!number_out)
7279 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7280
7281 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7282 }
7283 } else {
7284 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7285
7286 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7287 }
7288
7289 break;
7290
7291 case FT_EUI64:
7292 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7293 tmp_str = address_to_display(NULL((void*)0), &addr);
7294 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7295 wmem_free(NULL((void*)0), tmp_str);
7296 break;
7297
7298 case FT_IPv4:
7299 ipv4 = fvalue_get_ipv4(finfo->value);
7300 //XXX: Should we ignore the mask?
7301 set_address_ipv4(&addr, ipv4);
7302 tmp_str = address_to_display(NULL((void*)0), &addr);
7303 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7304 wmem_free(NULL((void*)0), tmp_str);
7305 free_address(&addr);
7306 break;
7307
7308 case FT_IPv6:
7309 ipv6 = fvalue_get_ipv6(finfo->value);
7310 set_address_ipv6(&addr, ipv6);
7311 tmp_str = address_to_display(NULL((void*)0), &addr);
7312 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7313 wmem_free(NULL((void*)0), tmp_str);
7314 free_address(&addr);
7315 break;
7316
7317 case FT_FCWWN:
7318 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7319 tmp_str = address_to_display(NULL((void*)0), &addr);
7320 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7321 wmem_free(NULL((void*)0), tmp_str);
7322 break;
7323
7324 case FT_ETHER:
7325 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7326 tmp_str = address_to_display(NULL((void*)0), &addr);
7327 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7328 wmem_free(NULL((void*)0), tmp_str);
7329 break;
7330
7331 case FT_GUID:
7332 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7333 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7334 wmem_free(NULL((void*)0), tmp_str);
7335 break;
7336
7337 case FT_REL_OID:
7338 bytes = fvalue_get_bytes_data(finfo->value);
7339 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7340 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7341 wmem_free(NULL((void*)0), tmp_str);
7342 break;
7343
7344 case FT_OID:
7345 bytes = fvalue_get_bytes_data(finfo->value);
7346 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7347 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7348 wmem_free(NULL((void*)0), tmp_str);
7349 break;
7350
7351 case FT_SYSTEM_ID:
7352 bytes = fvalue_get_bytes_data(finfo->value);
7353 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7354 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7355 wmem_free(NULL((void*)0), tmp_str);
7356 break;
7357
7358 case FT_FLOAT:
7359 case FT_DOUBLE:
7360 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7361 break;
7362
7363 case FT_IEEE_11073_SFLOAT:
7364 case FT_IEEE_11073_FLOAT:
7365 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7366 break;
7367
7368 case FT_STRING:
7369 case FT_STRINGZ:
7370 case FT_UINT_STRING:
7371 case FT_STRINGZPAD:
7372 case FT_STRINGZTRUNC:
7373 str = fvalue_get_string(finfo->value);
7374 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, str, label_strcat_flags(hfinfo));
7375 if (label_len >= label_str_size) {
7376 /* Truncation occurred. Get the real length
7377 * copied (not including '\0') */
7378 label_len = label_str_size ? label_str_size - 1 : 0;
7379 }
7380 break;
7381
7382 default:
7383 /* First try ftype string representation */
7384 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7385 if (!tmp_str) {
7386 /* Default to show as bytes */
7387 bytes = fvalue_get_bytes_data(finfo->value);
7388 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7389 }
7390 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7391 wmem_free(NULL((void*)0), tmp_str);
7392 break;
7393 }
7394 return label_len;
7395}
7396
7397const char *
7398proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7399 char *result, char *expr, const int size)
7400{
7401 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7402 GPtrArray *finfos;
7403 field_info *finfo = NULL((void*)0);
7404 header_field_info* hfinfo;
7405 const char *abbrev = NULL((void*)0);
7406
7407 char *str;
7408 col_custom_t *field_idx;
7409 int field_id;
7410 int ii = 0;
7411
7412 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7412, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7413 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7414 field_id = field_idx->field_id;
7415 if (field_id == 0) {
7416 GPtrArray *fvals = NULL((void*)0);
7417 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7418 if (fvals != NULL((void*)0)) {
7419
7420 // XXX - Handling occurrences is unusual when more
7421 // than one field is involved, e.g. there's four
7422 // results for tcp.port + tcp.port. We may really
7423 // want to apply it to the operands, not the output.
7424 // Note that occurrences are not quite the same as
7425 // the layer operator (should the grammar support
7426 // both?)
7427 /* Calculate single index or set outer boundaries */
7428 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7429 if (occurrence < 0) {
7430 i = occurrence + len;
7431 last = i;
7432 } else if (occurrence > 0) {
7433 i = occurrence - 1;
7434 last = i;
7435 } else {
7436 i = 0;
7437 last = len - 1;
7438 }
7439 if (i < 0 || i >= len) {
7440 g_ptr_array_unref(fvals);
7441 continue;
7442 }
7443 for (; i <= last; i++) {
7444 /* XXX - We could have a "resolved" result
7445 * for types where the value depends only
7446 * on the type, e.g. FT_IPv4, and not on
7447 * hfinfo->strings. Supporting the latter
7448 * requires knowing which hfinfo matched
7449 * if there are multiple with the same
7450 * abbreviation. In any case, we need to
7451 * know the expected return type of the
7452 * field expression.
7453 */
7454 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7455 if (offset_r && (offset_r < (size - 1)))
7456 result[offset_r++] = ',';
7457 if (offset_e && (offset_e < (size - 1)))
7458 expr[offset_e++] = ',';
7459 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7460 // col_{add,append,set}_* calls ws_label_strcpy
7461 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7462
7463 g_free(str);
7464 }
7465 g_ptr_array_unref(fvals);
7466 } else if (passed) {
7467 // XXX - Occurrence doesn't make sense for a test
7468 // output, it should be applied to the operands.
7469 if (offset_r && (offset_r < (size - 1)))
7470 result[offset_r++] = ',';
7471 if (offset_e && (offset_e < (size - 1)))
7472 expr[offset_e++] = ',';
7473 /* Prevent multiple check marks */
7474 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7475 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7476 } else {
7477 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7478 }
7479 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7480 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7481 } else {
7482 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7483 }
7484 }
7485 continue;
7486 }
7487 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", 7487
, __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", 7487,
"(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", 7487,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7488
7489 /* do we need to rewind ? */
7490 if (!hfinfo)
7491 return "";
7492
7493 if (occurrence < 0) {
7494 /* Search other direction */
7495 while (hfinfo->same_name_prev_id != -1) {
7496 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", 7496
, __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", 7496, "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", 7496,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7497 }
7498 }
7499
7500 prev_len = 0; /* Reset handled occurrences */
7501
7502 while (hfinfo) {
7503 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7504
7505 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7506 if (occurrence < 0) {
7507 hfinfo = hfinfo->same_name_next;
7508 } else {
7509 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7510 }
7511 continue;
7512 }
7513
7514 /* Are there enough occurrences of the field? */
7515 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7516 if (occurrence < 0) {
7517 hfinfo = hfinfo->same_name_next;
7518 } else {
7519 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7520 }
7521 prev_len += len;
7522 continue;
7523 }
7524
7525 /* Calculate single index or set outer boundaries */
7526 if (occurrence < 0) {
7527 i = occurrence + len + prev_len;
7528 last = i;
7529 } else if (occurrence > 0) {
7530 i = occurrence - 1 - prev_len;
7531 last = i;
7532 } else {
7533 i = 0;
7534 last = len - 1;
7535 }
7536
7537 prev_len += len; /* Count handled occurrences */
7538
7539 while (i <= last) {
7540 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7541
7542 if (offset_r && (offset_r < (size - 1)))
7543 result[offset_r++] = ',';
7544
7545 if (display_details) {
7546 char representation[ITEM_LABEL_LENGTH240];
7547 size_t offset = 0;
7548
7549 if (finfo->rep && finfo->rep->value_len) {
7550 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7551 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7552 } else {
7553 proto_item_fill_label(finfo, representation, &offset);
7554 }
7555 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7556 } else {
7557 switch (hfinfo->type) {
7558
7559 case FT_NONE:
7560 case FT_PROTOCOL:
7561 /* Prevent multiple check marks */
7562 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7563 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7564 } else {
7565 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7566 }
7567 break;
7568
7569 default:
7570 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7571 break;
7572 }
7573 }
7574
7575 if (offset_e && (offset_e < (size - 1)))
7576 expr[offset_e++] = ',';
7577
7578 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
))
)) {
7579 const char *hf_str_val;
7580 /* Integer types with BASE_NONE never get the numeric value. */
7581 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7582 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7583 } 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
)
) {
7584 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7585 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7586 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7587 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7588 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7589 }
7590 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7591 offset_e = (int)strlen(expr);
7592 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7593 /* Prevent multiple check marks */
7594 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7595 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7596 } else {
7597 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7598 }
7599 } else {
7600 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7601 // col_{add,append,set}_* calls ws_label_strcpy
7602 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7603 wmem_free(NULL((void*)0), str);
7604 }
7605 i++;
7606 }
7607
7608 /* XXX: Why is only the first abbreviation returned for a multifield
7609 * custom column? */
7610 if (!abbrev) {
7611 /* Store abbrev for return value */
7612 abbrev = hfinfo->abbrev;
7613 }
7614
7615 if (occurrence == 0) {
7616 /* Fetch next hfinfo with same name (abbrev) */
7617 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7618 } else {
7619 hfinfo = NULL((void*)0);
7620 }
7621 }
7622 }
7623
7624 if (offset_r >= (size - 1)) {
7625 mark_truncated(result, 0, size, NULL((void*)0));
7626 }
7627 if (offset_e >= (size - 1)) {
7628 mark_truncated(expr, 0, size, NULL((void*)0));
7629 }
7630 return abbrev ? abbrev : "";
7631}
7632
7633char *
7634proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7635{
7636 int len, prev_len, last, i;
7637 GPtrArray *finfos;
7638 field_info *finfo = NULL((void*)0);
7639 header_field_info* hfinfo;
7640
7641 char *filter = NULL((void*)0);
7642 GPtrArray *filter_array;
7643
7644 col_custom_t *col_custom;
7645 int field_id;
7646
7647 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7647, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7648 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7649 for (GSList *iter = field_ids; iter; iter = iter->next) {
7650 col_custom = (col_custom_t*)iter->data;
7651 field_id = col_custom->field_id;
7652 if (field_id == 0) {
7653 GPtrArray *fvals = NULL((void*)0);
7654 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7655 if (fvals != NULL((void*)0)) {
7656 // XXX - Handling occurrences is unusual when more
7657 // than one field is involved, e.g. there's four
7658 // results for tcp.port + tcp.port. We really
7659 // want to apply it to the operands, not the output.
7660 /* Calculate single index or set outer boundaries */
7661 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7662 if (occurrence < 0) {
7663 i = occurrence + len;
7664 last = i;
7665 } else if (occurrence > 0) {
7666 i = occurrence - 1;
7667 last = i;
7668 } else {
7669 i = 0;
7670 last = len - 1;
7671 }
7672 if (i < 0 || i >= len) {
7673 g_ptr_array_unref(fvals);
7674 continue;
7675 }
7676 for (; i <= last; i++) {
7677 /* XXX - Should multiple values for one
7678 * field use set membership to reduce
7679 * verbosity, here and below? */
7680 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7681 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7682 wmem_free(NULL((void*)0), str);
7683 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7684 g_ptr_array_add(filter_array, filter);
7685 }
7686 }
7687 g_ptr_array_unref(fvals);
7688 } else if (passed) {
7689 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7690 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7691 g_ptr_array_add(filter_array, filter);
7692 }
7693 } else {
7694 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7695 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7696 g_ptr_array_add(filter_array, filter);
7697 }
7698 }
7699 continue;
7700 }
7701
7702 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", 7702
, __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", 7702,
"(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", 7702,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7703
7704 /* do we need to rewind ? */
7705 if (!hfinfo)
7706 return NULL((void*)0);
7707
7708 if (occurrence < 0) {
7709 /* Search other direction */
7710 while (hfinfo->same_name_prev_id != -1) {
7711 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", 7711
, __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", 7711, "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", 7711,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7712 }
7713 }
7714
7715 prev_len = 0; /* Reset handled occurrences */
7716
7717 while (hfinfo) {
7718 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7719
7720 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7721 if (occurrence < 0) {
7722 hfinfo = hfinfo->same_name_next;
7723 } else {
7724 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7725 }
7726 continue;
7727 }
7728
7729 /* Are there enough occurrences of the field? */
7730 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7731 if (occurrence < 0) {
7732 hfinfo = hfinfo->same_name_next;
7733 } else {
7734 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7735 }
7736 prev_len += len;
7737 continue;
7738 }
7739
7740 /* Calculate single index or set outer boundaries */
7741 if (occurrence < 0) {
7742 i = occurrence + len + prev_len;
7743 last = i;
7744 } else if (occurrence > 0) {
7745 i = occurrence - 1 - prev_len;
7746 last = i;
7747 } else {
7748 i = 0;
7749 last = len - 1;
7750 }
7751
7752 prev_len += len; /* Count handled occurrences */
7753
7754 while (i <= last) {
7755 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7756
7757 filter = proto_construct_match_selected_string(finfo, edt);
7758 if (filter) {
7759 /* Only add the same expression once (especially for FT_PROTOCOL).
7760 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7761 */
7762 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7763 g_ptr_array_add(filter_array, filter);
7764 }
7765 }
7766 i++;
7767 }
7768
7769 if (occurrence == 0) {
7770 /* Fetch next hfinfo with same name (abbrev) */
7771 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7772 } else {
7773 hfinfo = NULL((void*)0);
7774 }
7775 }
7776 }
7777
7778 g_ptr_array_add(filter_array, NULL((void*)0));
7779
7780 /* XXX: Should this be || or && ? */
7781 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7782
7783 g_ptr_array_free(filter_array, true1);
7784
7785 return output;
7786}
7787
7788/* Set text of proto_item after having already been created. */
7789void
7790proto_item_set_text(proto_item *pi, const char *format, ...)
7791{
7792 field_info *fi = NULL((void*)0);
7793 va_list ap;
7794
7795 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7796
7797 fi = PITEM_FINFO(pi)((pi)->finfo);
7798 if (fi == NULL((void*)0))
7799 return;
7800
7801 if (fi->rep) {
7802 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7803 fi->rep = NULL((void*)0);
7804 }
7805
7806 va_start(ap, format)__builtin_va_start(ap, format);
7807 proto_tree_set_representation(pi, format, ap);
7808 va_end(ap)__builtin_va_end(ap);
7809}
7810
7811/* Append to text of proto_item after having already been created. */
7812void
7813proto_item_append_text(proto_item *pi, const char *format, ...)
7814{
7815 field_info *fi = NULL((void*)0);
7816 size_t curlen;
7817 char *str;
7818 va_list ap;
7819
7820 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7821
7822 fi = PITEM_FINFO(pi)((pi)->finfo);
7823 if (fi == NULL((void*)0)) {
7824 return;
7825 }
7826
7827 if (!proto_item_is_hidden(pi)) {
7828 /*
7829 * If we don't already have a representation,
7830 * generate the default representation.
7831 */
7832 if (fi->rep == NULL((void*)0)) {
7833 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;
;
7834 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7835 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7836 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7837 (strncmp(format, ": ", 2) == 0)) {
7838 fi->rep->value_pos += 2;
7839 }
7840 }
7841 if (fi->rep) {
7842 curlen = strlen(fi->rep->representation);
7843 /* curlen doesn't include the \0 byte.
7844 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7845 * the representation has already been truncated (of an up
7846 * to 4 byte UTF-8 character) or is just at the maximum length
7847 * unless we search for " [truncated]" (which may not be
7848 * at the start.)
7849 * It's safer to do nothing.
7850 */
7851 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7852 va_start(ap, format)__builtin_va_start(ap, format);
7853 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7854 va_end(ap)__builtin_va_end(ap);
7855 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"
, 7855, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7856 /* Keep fi->rep->value_pos */
7857 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, str, 0);
7858 if (curlen >= ITEM_LABEL_LENGTH240) {
7859 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7860 size_t name_pos = label_find_name_pos(fi->rep);
7861 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7862 }
7863 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7864 }
7865 }
7866 }
7867}
7868
7869/* Prepend to text of proto_item after having already been created. */
7870void
7871proto_item_prepend_text(proto_item *pi, const char *format, ...)
7872{
7873 field_info *fi = NULL((void*)0);
7874 size_t pos;
7875 char representation[ITEM_LABEL_LENGTH240];
7876 char *str;
7877 va_list ap;
7878
7879 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7880
7881 fi = PITEM_FINFO(pi)((pi)->finfo);
7882 if (fi == NULL((void*)0)) {
7883 return;
7884 }
7885
7886 if (!proto_item_is_hidden(pi)) {
7887 /*
7888 * If we don't already have a representation,
7889 * generate the default representation.
7890 */
7891 if (fi->rep == NULL((void*)0)) {
7892 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;
;
7893 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7894 } else
7895 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7896
7897 va_start(ap, format)__builtin_va_start(ap, format);
7898 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7899 va_end(ap)__builtin_va_end(ap);
7900 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"
, 7900, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7901 fi->rep->value_pos += strlen(str);
7902 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7903 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, representation, 0);
7904 /* XXX: As above, if the old representation is close to the label
7905 * length, it might already be marked as truncated. */
7906 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7907 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7908 size_t name_pos = label_find_name_pos(fi->rep);
7909 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7910 }
7911 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7912 }
7913}
7914
7915static void
7916finfo_set_len(field_info *fi, const int length)
7917{
7918 int length_remaining;
7919
7920 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", 7920,
"length >= 0", fi->hfinfo->abbrev))))
;
7921 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7922 if (length > length_remaining)
7923 fi->length = length_remaining;
7924 else
7925 fi->length = length;
7926
7927 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7928 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7929 fvalue_set_protocol_length(fi->value, fi->length);
7930 }
7931
7932 /*
7933 * You cannot just make the "len" field of a GByteArray
7934 * larger, if there's no data to back that length;
7935 * you can only make it smaller.
7936 */
7937 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7938 GBytes *bytes = fvalue_get_bytes(fi->value);
7939 size_t size;
7940 const void *data = g_bytes_get_data(bytes, &size);
7941 if ((size_t)fi->length <= size) {
7942 fvalue_set_bytes_data(fi->value, data, fi->length);
7943 }
7944 g_bytes_unref(bytes);
7945 }
7946}
7947
7948void
7949proto_item_set_len(proto_item *pi, const int length)
7950{
7951 field_info *fi;
7952
7953 if (pi == NULL((void*)0))
7954 return;
7955
7956 fi = PITEM_FINFO(pi)((pi)->finfo);
7957 if (fi == NULL((void*)0))
7958 return;
7959
7960 finfo_set_len(fi, length);
7961}
7962
7963/*
7964 * Sets the length of the item based on its start and on the specified
7965 * offset, which is the offset past the end of the item; as the start
7966 * in the item is relative to the beginning of the data source tvbuff,
7967 * we need to pass in a tvbuff - the end offset is relative to the beginning
7968 * of that tvbuff.
7969 */
7970void
7971proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7972{
7973 field_info *fi;
7974 int length;
7975
7976 if (pi == NULL((void*)0))
7977 return;
7978
7979 fi = PITEM_FINFO(pi)((pi)->finfo);
7980 if (fi == NULL((void*)0))
7981 return;
7982
7983 end += tvb_raw_offset(tvb);
7984 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7984, "end >= fi->start"
))))
;
7985 length = end - fi->start;
7986
7987 finfo_set_len(fi, length);
7988}
7989
7990int
7991proto_item_get_len(const proto_item *pi)
7992{
7993 field_info *fi;
7994
7995 if (!pi)
7996 return -1;
7997 fi = PITEM_FINFO(pi)((pi)->finfo);
7998 return fi ? fi->length : -1;
7999}
8000
8001void
8002proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8003 if (!ti) {
8004 return;
8005 }
8006 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)
;
8007 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)
;
8008}
8009
8010char *
8011proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8012{
8013 field_info *fi;
8014
8015 if (!pi)
8016 return wmem_strdup(scope, "");
8017 fi = PITEM_FINFO(pi)((pi)->finfo);
8018 if (!fi)
8019 return wmem_strdup(scope, "");
8020 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8020, "fi->hfinfo != ((void*)0)"
))))
;
8021 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8022}
8023
8024proto_tree *
8025proto_tree_create_root(packet_info *pinfo)
8026{
8027 proto_node *pnode;
8028
8029 /* Initialize the proto_node */
8030 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
8031 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8032 pnode->parent = NULL((void*)0);
8033 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8034 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
8035
8036 /* Make sure we can access pinfo everywhere */
8037 pnode->tree_data->pinfo = pinfo;
8038
8039 /* Don't initialize the tree_data_t. Wait until we know we need it */
8040 pnode->tree_data->interesting_hfids = NULL((void*)0);
8041
8042 /* Set the default to false so it's easier to
8043 * find errors; if we expect to see the protocol tree
8044 * but for some reason the default 'visible' is not
8045 * changed, then we'll find out very quickly. */
8046 pnode->tree_data->visible = false0;
8047
8048 /* Make sure that we fake protocols (if possible) */
8049 pnode->tree_data->fake_protocols = true1;
8050
8051 /* Keep track of the number of children */
8052 pnode->tree_data->count = 0;
8053
8054 /* Initialize our loop checks */
8055 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8056 pnode->tree_data->max_start = 0;
8057 pnode->tree_data->start_idle_count = 0;
8058
8059 return (proto_tree *)pnode;
8060}
8061
8062
8063/* "prime" a proto_tree with a single hfid that a dfilter
8064 * is interested in. */
8065void
8066proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8067{
8068 header_field_info *hfinfo;
8069
8070 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", 8070, __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", 8070, "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", 8070, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8071 /* this field is referenced by a filter so increase the refcount.
8072 also increase the refcount for the parent, i.e the protocol.
8073 Don't increase the refcount if we're already printing the
8074 type, as that is a superset of direct reference.
8075 */
8076 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8077 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8078 }
8079 /* only increase the refcount if there is a parent.
8080 if this is a protocol and not a field then parent will be -1
8081 and there is no parent to add any refcounting for.
8082 */
8083 if (hfinfo->parent != -1) {
8084 header_field_info *parent_hfinfo;
8085 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", 8085
, __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", 8085,
"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", 8085,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8086
8087 /* Mark parent as indirectly referenced unless it is already directly
8088 * referenced, i.e. the user has specified the parent in a filter.
8089 */
8090 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8091 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8092 }
8093}
8094
8095/* "prime" a proto_tree with a single hfid that a dfilter
8096 * is interested in. */
8097void
8098proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8099{
8100 header_field_info *hfinfo;
8101
8102 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", 8102, __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", 8102, "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", 8102, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8103 /* this field is referenced by an (output) filter so increase the refcount.
8104 also increase the refcount for the parent, i.e the protocol.
8105 */
8106 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8107 /* only increase the refcount if there is a parent.
8108 if this is a protocol and not a field then parent will be -1
8109 and there is no parent to add any refcounting for.
8110 */
8111 if (hfinfo->parent != -1) {
8112 header_field_info *parent_hfinfo;
8113 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", 8113
, __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", 8113,
"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", 8113,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8114
8115 /* Mark parent as indirectly referenced unless it is already directly
8116 * referenced, i.e. the user has specified the parent in a filter.
8117 */
8118 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8119 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8120 }
8121}
8122
8123proto_tree *
8124proto_item_add_subtree(proto_item *pi, const int idx) {
8125 field_info *fi;
8126
8127 if (!pi)
8128 return NULL((void*)0);
8129
8130 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", 8130, "idx >= 0 && idx < num_tree_types"
))))
;
8131
8132 fi = PITEM_FINFO(pi)((pi)->finfo);
8133 if (!fi)
8134 return (proto_tree *)pi;
8135
8136 fi->tree_type = idx;
8137
8138 return (proto_tree *)pi;
8139}
8140
8141proto_tree *
8142proto_item_get_subtree(proto_item *pi) {
8143 field_info *fi;
8144
8145 if (!pi)
8146 return NULL((void*)0);
8147 fi = PITEM_FINFO(pi)((pi)->finfo);
8148 if ( (fi) && (fi->tree_type == -1) )
8149 return NULL((void*)0);
8150 return (proto_tree *)pi;
8151}
8152
8153proto_item *
8154proto_item_get_parent(const proto_item *ti) {
8155 if (!ti)
8156 return NULL((void*)0);
8157 return ti->parent;
8158}
8159
8160proto_item *
8161proto_item_get_parent_nth(proto_item *ti, int gen) {
8162 if (!ti)
8163 return NULL((void*)0);
8164 while (gen--) {
8165 ti = ti->parent;
8166 if (!ti)
8167 return NULL((void*)0);
8168 }
8169 return ti;
8170}
8171
8172
8173proto_item *
8174proto_tree_get_parent(proto_tree *tree) {
8175 if (!tree)
8176 return NULL((void*)0);
8177 return (proto_item *)tree;
8178}
8179
8180proto_tree *
8181proto_tree_get_parent_tree(proto_tree *tree) {
8182 if (!tree)
8183 return NULL((void*)0);
8184
8185 /* we're the root tree, there's no parent
8186 return ourselves so the caller has at least a tree to attach to */
8187 if (!tree->parent)
8188 return tree;
8189
8190 return (proto_tree *)tree->parent;
8191}
8192
8193proto_tree *
8194proto_tree_get_root(proto_tree *tree) {
8195 if (!tree)
8196 return NULL((void*)0);
8197 while (tree->parent) {
8198 tree = tree->parent;
8199 }
8200 return tree;
8201}
8202
8203void
8204proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8205 proto_item *item_to_move)
8206{
8207 /* This function doesn't generate any values. It only reorganizes the prococol tree
8208 * so we can bail out immediately if it isn't visible. */
8209 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8210 return;
8211
8212 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", 8212, "item_to_move->parent == tree"
))))
;
8213 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", 8213, "fixed_item->parent == tree"
))))
;
8214
8215 /*** cut item_to_move out ***/
8216
8217 /* is item_to_move the first? */
8218 if (tree->first_child == item_to_move) {
8219 /* simply change first child to next */
8220 tree->first_child = item_to_move->next;
8221
8222 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", 8222, "tree->last_child != item_to_move"
))))
;
8223 } else {
8224 proto_item *curr_item;
8225 /* find previous and change it's next */
8226 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8227 if (curr_item->next == item_to_move) {
8228 break;
8229 }
8230 }
8231
8232 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8232, "curr_item"
))))
;
8233
8234 curr_item->next = item_to_move->next;
8235
8236 /* fix last_child if required */
8237 if (tree->last_child == item_to_move) {
8238 tree->last_child = curr_item;
8239 }
8240 }
8241
8242 /*** insert to_move after fixed ***/
8243 item_to_move->next = fixed_item->next;
8244 fixed_item->next = item_to_move;
8245 if (tree->last_child == fixed_item) {
8246 tree->last_child = item_to_move;
8247 }
8248}
8249
8250void
8251proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8252 const int length)
8253{
8254 field_info *fi;
8255
8256 if (tree == NULL((void*)0))
8257 return;
8258
8259 fi = PTREE_FINFO(tree)((tree)->finfo);
8260 if (fi == NULL((void*)0))
8261 return;
8262
8263 start += tvb_raw_offset(tvb);
8264 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8264, "start >= 0"
))))
;
8265 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8265, "length >= 0"
))))
;
8266
8267 fi->appendix_start = start;
8268 fi->appendix_length = length;
8269}
8270
8271static void
8272check_protocol_filter_name_or_fail(const char *filter_name)
8273{
8274 /* Require at least two characters. */
8275 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8276 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)
;
8277 }
8278
8279 if (proto_check_field_name(filter_name) != '\0') {
8280 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)
8281 " 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)
8282 " 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)
;
8283 }
8284
8285 /* Check that it doesn't match some very common numeric forms. */
8286 if (filter_name[0] == '0' &&
8287 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8288 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8289 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])
8290 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])
;
8291 }
8292
8293 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8294
8295 /* Check that it contains at least one letter. */
8296 bool_Bool have_letter = false0;
8297 for (const char *s = filter_name; *s != '\0'; s++) {
8298 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8299 have_letter = true1;
8300 break;
8301 }
8302 }
8303 if (!have_letter) {
8304 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)
8305 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8306 }
8307
8308 /* Check for reserved keywords. */
8309 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8310 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)
8311 " 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)
;
8312 }
8313}
8314
8315int
8316proto_register_protocol(const char *name, const char *short_name,
8317 const char *filter_name)
8318{
8319 protocol_t *protocol;
8320 header_field_info *hfinfo;
8321
8322 check_protocol_filter_name_or_fail(filter_name);
8323
8324 /*
8325 * Add this protocol to the list of known protocols;
8326 * the list is sorted by protocol short name.
8327 */
8328 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8329 protocol->name = name;
8330 protocol->short_name = short_name;
8331 protocol->filter_name = filter_name;
8332 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8333 protocol->is_enabled = true1; /* protocol is enabled by default */
8334 protocol->enabled_by_default = true1; /* see previous comment */
8335 protocol->can_toggle = true1;
8336 protocol->parent_proto_id = -1;
8337 protocol->heur_list = NULL((void*)0);
8338
8339 /* List will be sorted later by name, when all protocols completed registering */
8340 protocols = g_list_prepend(protocols, protocol);
8341 /*
8342 * Make sure there's not already a protocol with any of those
8343 * names. Crash if there is, as that's an error in the code
8344 * or an inappropriate plugin.
8345 * This situation has to be fixed to not register more than one
8346 * protocol with the same name.
8347 */
8348 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8349 /* ws_error will terminate the program */
8350 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)
8351 " 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)
;
8352 }
8353 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8354 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)
8355 " 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)
;
8356 }
8357 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8358 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)
8359 " 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)
;
8360 }
8361
8362 /* Here we allocate a new header_field_info struct */
8363 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8364 hfinfo->name = name;
8365 hfinfo->abbrev = filter_name;
8366 hfinfo->type = FT_PROTOCOL;
8367 hfinfo->display = BASE_NONE;
8368 hfinfo->strings = protocol;
8369 hfinfo->bitmask = 0;
8370 hfinfo->ref_type = HF_REF_TYPE_NONE;
8371 hfinfo->blurb = NULL((void*)0);
8372 hfinfo->parent = -1; /* This field differentiates protos and fields */
8373
8374 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8375 return protocol->proto_id;
8376}
8377
8378int
8379proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8380{
8381 protocol_t *protocol;
8382 header_field_info *hfinfo;
8383
8384 /*
8385 * Helper protocols don't need the strict rules as a "regular" protocol
8386 * Just register it in a list and make a hf_ field from it
8387 */
8388 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8389 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)
;
8390 }
8391
8392 if (parent_proto <= 0) {
8393 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)
8394 " 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)
;
8395 }
8396
8397 check_protocol_filter_name_or_fail(filter_name);
8398
8399 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8400 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8401 protocol->name = name;
8402 protocol->short_name = short_name;
8403 protocol->filter_name = filter_name;
8404 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8405
8406 /* Enabling and toggling is really determined by parent protocol,
8407 but provide default values here */
8408 protocol->is_enabled = true1;
8409 protocol->enabled_by_default = true1;
8410 protocol->can_toggle = true1;
8411
8412 protocol->parent_proto_id = parent_proto;
8413 protocol->heur_list = NULL((void*)0);
8414
8415 /* List will be sorted later by name, when all protocols completed registering */
8416 protocols = g_list_prepend(protocols, protocol);
8417
8418 /* Here we allocate a new header_field_info struct */
8419 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8420 hfinfo->name = name;
8421 hfinfo->abbrev = filter_name;
8422 hfinfo->type = field_type;
8423 hfinfo->display = BASE_NONE;
8424 if (field_type == FT_BYTES) {
8425 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8426 }
8427 hfinfo->strings = protocol;
8428 hfinfo->bitmask = 0;
8429 hfinfo->ref_type = HF_REF_TYPE_NONE;
8430 hfinfo->blurb = NULL((void*)0);
8431 hfinfo->parent = -1; /* This field differentiates protos and fields */
8432
8433 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8434 return protocol->proto_id;
8435}
8436
8437bool_Bool
8438proto_deregister_protocol(const char *short_name)
8439{
8440 protocol_t *protocol;
8441 header_field_info *hfinfo;
8442 int proto_id;
8443 unsigned i;
8444
8445 proto_id = proto_get_id_by_short_name(short_name);
8446 protocol = find_protocol_by_id(proto_id);
8447 if (protocol == NULL((void*)0))
8448 return false0;
8449
8450 g_hash_table_remove(proto_names, protocol->name);
8451 g_hash_table_remove(proto_short_names, (void *)short_name);
8452 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8453
8454 if (protocol->fields) {
8455 for (i = 0; i < protocol->fields->len; i++) {
8456 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8457 hfinfo_remove_from_gpa_name_map(hfinfo);
8458 expert_deregister_expertinfo(hfinfo->abbrev);
8459 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8460 }
8461 g_ptr_array_free(protocol->fields, true1);
8462 protocol->fields = NULL((void*)0);
8463 }
8464
8465 g_list_free(protocol->heur_list);
8466
8467 /* Remove this protocol from the list of known protocols */
8468 protocols = g_list_remove(protocols, protocol);
8469
8470 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8471 wmem_map_remove(gpa_name_map, protocol->filter_name);
8472
8473 g_free(last_field_name);
8474 last_field_name = NULL((void*)0);
8475
8476 return true1;
8477}
8478
8479void
8480proto_register_alias(const int proto_id, const char *alias_name)
8481{
8482 protocol_t *protocol;
8483
8484 protocol = find_protocol_by_id(proto_id);
8485 if (alias_name && protocol) {
8486 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8487 }
8488}
8489
8490/*
8491 * Routines to use to iterate over the protocols.
8492 * The argument passed to the iterator routines is an opaque cookie to
8493 * their callers; it's the GList pointer for the current element in
8494 * the list.
8495 * The ID of the protocol is returned, or -1 if there is no protocol.
8496 */
8497int
8498proto_get_first_protocol(void **cookie)
8499{
8500 protocol_t *protocol;
8501
8502 if (protocols == NULL((void*)0))
8503 return -1;
8504 *cookie = protocols;
8505 protocol = (protocol_t *)protocols->data;
8506 return protocol->proto_id;
8507}
8508
8509int
8510proto_get_data_protocol(void *cookie)
8511{
8512 GList *list_item = (GList *)cookie;
8513
8514 protocol_t *protocol = (protocol_t *)list_item->data;
8515 return protocol->proto_id;
8516}
8517
8518int
8519proto_get_next_protocol(void **cookie)
8520{
8521 GList *list_item = (GList *)*cookie;
8522 protocol_t *protocol;
8523
8524 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8525 if (list_item == NULL((void*)0))
8526 return -1;
8527 *cookie = list_item;
8528 protocol = (protocol_t *)list_item->data;
8529 return protocol->proto_id;
8530}
8531
8532header_field_info *
8533proto_get_first_protocol_field(const int proto_id, void **cookie)
8534{
8535 protocol_t *protocol = find_protocol_by_id(proto_id);
8536
8537 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8538 return NULL((void*)0);
8539
8540 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8541 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8542}
8543
8544header_field_info *
8545proto_get_next_protocol_field(const int proto_id, void **cookie)
8546{
8547 protocol_t *protocol = find_protocol_by_id(proto_id);
8548 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8549
8550 i++;
8551
8552 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8553 return NULL((void*)0);
8554
8555 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8556 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8557}
8558
8559protocol_t *
8560find_protocol_by_id(const int proto_id)
8561{
8562 header_field_info *hfinfo;
8563
8564 if (proto_id <= 0)
8565 return NULL((void*)0);
8566
8567 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", 8567, __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", 8567,
"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", 8567, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8568 if (hfinfo->type != FT_PROTOCOL) {
8569 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", 8569, "hfinfo->display & 0x00004000"
))))
;
8570 }
8571 return (protocol_t *)hfinfo->strings;
8572}
8573
8574int
8575proto_get_id(const protocol_t *protocol)
8576{
8577 return protocol->proto_id;
8578}
8579
8580bool_Bool
8581proto_name_already_registered(const char *name)
8582{
8583 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8583, "name", "No name present"))))
;
8584
8585 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8586 return true1;
8587 return false0;
8588}
8589
8590int
8591proto_get_id_by_filter_name(const char *filter_name)
8592{
8593 const protocol_t *protocol = NULL((void*)0);
8594
8595 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", 8595,
"filter_name", "No filter name present"))))
;
8596
8597 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8598
8599 if (protocol == NULL((void*)0))
8600 return -1;
8601 return protocol->proto_id;
8602}
8603
8604int
8605proto_get_id_by_short_name(const char *short_name)
8606{
8607 const protocol_t *protocol = NULL((void*)0);
8608
8609 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", 8609,
"short_name", "No short name present"))))
;
8610
8611 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8612
8613 if (protocol == NULL((void*)0))
8614 return -1;
8615 return protocol->proto_id;
8616}
8617
8618const char *
8619proto_get_protocol_name(const int proto_id)
8620{
8621 protocol_t *protocol;
8622
8623 protocol = find_protocol_by_id(proto_id);
8624
8625 if (protocol == NULL((void*)0))
8626 return NULL((void*)0);
8627 return protocol->name;
8628}
8629
8630const char *
8631proto_get_protocol_short_name(const protocol_t *protocol)
8632{
8633 if (protocol == NULL((void*)0))
8634 return "(none)";
8635 return protocol->short_name;
8636}
8637
8638const char *
8639proto_get_protocol_long_name(const protocol_t *protocol)
8640{
8641 if (protocol == NULL((void*)0))
8642 return "(none)";
8643 return protocol->name;
8644}
8645
8646const char *
8647proto_get_protocol_filter_name(const int proto_id)
8648{
8649 protocol_t *protocol;
8650
8651 protocol = find_protocol_by_id(proto_id);
8652 if (protocol == NULL((void*)0))
8653 return "(none)";
8654 return protocol->filter_name;
8655}
8656
8657void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8658{
8659 heur_dtbl_entry_t* heuristic_dissector;
8660
8661 if (protocol == NULL((void*)0))
8662 return;
8663
8664 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8665 if (heuristic_dissector != NULL((void*)0))
8666 {
8667 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8668 }
8669}
8670
8671void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8672{
8673 if (protocol == NULL((void*)0))
8674 return;
8675
8676 g_list_foreach(protocol->heur_list, func, user_data);
8677}
8678
8679void
8680proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8681 bool_Bool *is_tcp, bool_Bool *is_udp,
8682 bool_Bool *is_sctp, bool_Bool *is_tls,
8683 bool_Bool *is_rtp,
8684 bool_Bool *is_lte_rlc)
8685{
8686 wmem_list_frame_t *protos = wmem_list_head(layers);
8687 int proto_id;
8688 const char *proto_name;
8689
8690 /* Walk the list of a available protocols in the packet and
8691 attempt to find "major" ones. */
8692 /* It might make more sense to assemble and return a bitfield. */
8693 while (protos != NULL((void*)0))
8694 {
8695 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8696 proto_name = proto_get_protocol_filter_name(proto_id);
8697
8698 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8699 (!strcmp(proto_name, "ipv6")))) {
8700 *is_ip = true1;
8701 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8702 *is_tcp = true1;
8703 } else if (is_udp && !strcmp(proto_name, "udp")) {
8704 *is_udp = true1;
8705 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8706 *is_sctp = true1;
8707 } else if (is_tls && !strcmp(proto_name, "tls")) {
8708 *is_tls = true1;
8709 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8710 *is_rtp = true1;
8711 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8712 *is_lte_rlc = true1;
8713 }
8714
8715 protos = wmem_list_frame_next(protos);
8716 }
8717}
8718
8719bool_Bool
8720proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8721{
8722 wmem_list_frame_t *protos = wmem_list_head(layers);
8723 int proto_id;
8724 const char *name;
8725
8726 /* Walk the list of a available protocols in the packet and
8727 attempt to find the specified protocol. */
8728 while (protos != NULL((void*)0))
8729 {
8730 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8731 name = proto_get_protocol_filter_name(proto_id);
8732
8733 if (!strcmp(name, proto_name))
8734 {
8735 return true1;
8736 }
8737
8738 protos = wmem_list_frame_next(protos);
8739 }
8740
8741 return false0;
8742}
8743
8744char *
8745proto_list_layers(const packet_info *pinfo)
8746{
8747 wmem_strbuf_t *buf;
8748 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8749
8750 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8751
8752 /* Walk the list of layers in the packet and
8753 return a string of all entries. */
8754 while (layers != NULL((void*)0))
8755 {
8756 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8757
8758 layers = wmem_list_frame_next(layers);
8759 if (layers != NULL((void*)0)) {
8760 wmem_strbuf_append_c(buf, ':');
8761 }
8762 }
8763
8764 return wmem_strbuf_finalize(buf);
8765}
8766
8767uint8_t
8768proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8769{
8770 int *proto_layer_num_ptr;
8771
8772 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8773 if (proto_layer_num_ptr == NULL((void*)0)) {
8774 return 0;
8775 }
8776
8777 return (uint8_t)*proto_layer_num_ptr;
8778}
8779
8780bool_Bool
8781proto_is_pino(const protocol_t *protocol)
8782{
8783 return (protocol->parent_proto_id != -1);
8784}
8785
8786bool_Bool
8787// NOLINTNEXTLINE(misc-no-recursion)
8788proto_is_protocol_enabled(const protocol_t *protocol)
8789{
8790 if (protocol == NULL((void*)0))
8791 return false0;
8792
8793 //parent protocol determines enable/disable for helper dissectors
8794 if (proto_is_pino(protocol))
8795 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8796
8797 return protocol->is_enabled;
8798}
8799
8800bool_Bool
8801// NOLINTNEXTLINE(misc-no-recursion)
8802proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8803{
8804 //parent protocol determines enable/disable for helper dissectors
8805 if (proto_is_pino(protocol))
8806 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8807
8808 return protocol->enabled_by_default;
8809}
8810
8811bool_Bool
8812// NOLINTNEXTLINE(misc-no-recursion)
8813proto_can_toggle_protocol(const int proto_id)
8814{
8815 protocol_t *protocol;
8816
8817 protocol = find_protocol_by_id(proto_id);
8818 //parent protocol determines toggling for helper dissectors
8819 if (proto_is_pino(protocol))
8820 return proto_can_toggle_protocol(protocol->parent_proto_id);
8821
8822 return protocol->can_toggle;
8823}
8824
8825void
8826proto_disable_by_default(const int proto_id)
8827{
8828 protocol_t *protocol;
8829
8830 protocol = find_protocol_by_id(proto_id);
8831 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8831, "protocol->can_toggle"
))))
;
8832 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", 8832, "proto_is_pino(protocol) == 0"
))))
;
8833 protocol->is_enabled = false0;
8834 protocol->enabled_by_default = false0;
8835}
8836
8837void
8838proto_set_decoding(const int proto_id, const bool_Bool enabled)
8839{
8840 protocol_t *protocol;
8841
8842 protocol = find_protocol_by_id(proto_id);
8843 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8843, "protocol->can_toggle"
))))
;
8844 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", 8844, "proto_is_pino(protocol) == 0"
))))
;
8845 protocol->is_enabled = enabled;
8846}
8847
8848void
8849proto_disable_all(void)
8850{
8851 /* This doesn't explicitly disable heuristic protocols,
8852 * but the heuristic doesn't get called if the parent
8853 * protocol isn't enabled.
8854 */
8855 protocol_t *protocol;
8856 GList *list_item = protocols;
8857
8858 if (protocols == NULL((void*)0))
8859 return;
8860
8861 while (list_item) {
8862 protocol = (protocol_t *)list_item->data;
8863 if (protocol->can_toggle) {
8864 protocol->is_enabled = false0;
8865 }
8866 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8867 }
8868}
8869
8870static void
8871heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8872{
8873 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8874
8875 heur->enabled = heur->enabled_by_default;
8876}
8877
8878void
8879proto_reenable_all(void)
8880{
8881 protocol_t *protocol;
8882 GList *list_item = protocols;
8883
8884 if (protocols == NULL((void*)0))
8885 return;
8886
8887 while (list_item) {
8888 protocol = (protocol_t *)list_item->data;
8889 if (protocol->can_toggle)
8890 protocol->is_enabled = protocol->enabled_by_default;
8891 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8892 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8893 }
8894}
8895
8896void
8897proto_set_cant_toggle(const int proto_id)
8898{
8899 protocol_t *protocol;
8900
8901 protocol = find_protocol_by_id(proto_id);
8902 protocol->can_toggle = false0;
8903}
8904
8905static int
8906proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8907{
8908 g_ptr_array_add(proto->fields, hfi);
8909
8910 return proto_register_field_init(hfi, parent);
8911}
8912
8913/* for use with static arrays only, since we don't allocate our own copies
8914of the header_field_info struct contained within the hf_register_info struct */
8915void
8916proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8917{
8918 hf_register_info *ptr = hf;
8919 protocol_t *proto;
8920 int i;
8921
8922 proto = find_protocol_by_id(parent);
8923
8924 /* if (proto == NULL) - error or return? */
8925
8926 if (proto->fields == NULL((void*)0)) {
8927 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
8928 * GLib introduced g_ptr_array_new_from_array, which might have
8929 * given a reason to actually use it. (#17774)
8930 */
8931 proto->fields = g_ptr_array_sized_new(num_records);
8932 }
8933
8934 for (i = 0; i < num_records; i++, ptr++) {
8935 /*
8936 * Make sure we haven't registered this yet.
8937 * Most fields have variables associated with them that
8938 * are initialized to 0; some are initialized to -1 (which
8939 * was the standard before 4.4).
8940 *
8941 * XXX - Since this is called almost 300000 times at startup,
8942 * it might be nice to compare to only 0 and require
8943 * dissectors to pass in zero for unregistered fields.
8944 */
8945 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8946 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8947 "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)
8948 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8949 return;
8950 }
8951
8952 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8953 }
8954}
8955
8956/* deregister already registered fields */
8957void
8958proto_deregister_field (const int parent, int hf_id)
8959{
8960 header_field_info *hfi;
8961 protocol_t *proto;
8962 unsigned i;
8963
8964 g_free(last_field_name);
8965 last_field_name = NULL((void*)0);
8966
8967 if (hf_id == -1 || hf_id == 0)
8968 return;
8969
8970 proto = find_protocol_by_id (parent);
8971 if (!proto || proto->fields == NULL((void*)0)) {
8972 return;
8973 }
8974
8975 for (i = 0; i < proto->fields->len; i++) {
8976 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8977 if (hfi->id == hf_id) {
8978 /* Found the hf_id in this protocol */
8979 wmem_map_remove(gpa_name_map, hfi->abbrev);
8980 g_ptr_array_remove_index_fast(proto->fields, i);
8981 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8982 return;
8983 }
8984 }
8985}
8986
8987/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
8988void
8989proto_deregister_all_fields_with_prefix(const int parent, const gchar *prefix)
8990{
8991 header_field_info *hfinfo;
8992 protocol_t *proto;
8993
8994 g_free(last_field_name);
8995 last_field_name = NULL((void*)0);
8996
8997 proto = find_protocol_by_id(parent);
8998 if (proto && proto->fields && proto->fields->len > 0) {
8999 guint i = proto->fields->len;
9000 do {
9001 i--;
9002
9003 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9004 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) )
) {
9005 hfinfo_remove_from_gpa_name_map(hfinfo);
9006 expert_deregister_expertinfo(hfinfo->abbrev);
9007 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9008 g_ptr_array_remove_index_fast(proto->fields, i);
9009 }
9010 } while (i > 0);
9011 }
9012}
9013
9014void
9015proto_add_deregistered_data (void *data)
9016{
9017 g_ptr_array_add(deregistered_data, data);
9018}
9019
9020void
9021proto_add_deregistered_slice (size_t block_size, void *mem_block)
9022{
9023 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
)))
;
9024
9025 slice_data->block_size = block_size;
9026 slice_data->mem_block = mem_block;
9027
9028 g_ptr_array_add(deregistered_slice, slice_data);
9029}
9030
9031void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9032{
9033 if (field_strings == NULL((void*)0)) {
9034 return;
9035 }
9036
9037 switch (field_type) {
9038 case FT_FRAMENUM:
9039 /* This is just an integer represented as a pointer */
9040 break;
9041 case FT_PROTOCOL: {
9042 protocol_t *protocol = (protocol_t *)field_strings;
9043 g_free((char *)protocol->short_name);
9044 break;
9045 }
9046 case FT_BOOLEAN: {
9047 true_false_string *tf = (true_false_string *)field_strings;
9048 g_free((char *)tf->true_string);
9049 g_free((char *)tf->false_string);
9050 break;
9051 }
9052 case FT_UINT40:
9053 case FT_INT40:
9054 case FT_UINT48:
9055 case FT_INT48:
9056 case FT_UINT56:
9057 case FT_INT56:
9058 case FT_UINT64:
9059 case FT_INT64: {
9060 if (field_display & BASE_UNIT_STRING0x00001000) {
9061 unit_name_string *unit = (unit_name_string *)field_strings;
9062 g_free((char *)unit->singular);
9063 g_free((char *)unit->plural);
9064 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9065 range_string *rs = (range_string *)field_strings;
9066 while (rs->strptr) {
9067 g_free((char *)rs->strptr);
9068 rs++;
9069 }
9070 } else if (field_display & BASE_EXT_STRING0x00000200) {
9071 val64_string_ext *vse = (val64_string_ext *)field_strings;
9072 val64_string *vs = (val64_string *)vse->_vs_p;
9073 while (vs->strptr) {
9074 g_free((char *)vs->strptr);
9075 vs++;
9076 }
9077 val64_string_ext_free(vse);
9078 field_strings = NULL((void*)0);
9079 } else if (field_display == BASE_CUSTOM) {
9080 /* this will be a pointer to a function, don't free that */
9081 field_strings = NULL((void*)0);
9082 } else {
9083 val64_string *vs64 = (val64_string *)field_strings;
9084 while (vs64->strptr) {
9085 g_free((char *)vs64->strptr);
9086 vs64++;
9087 }
9088 }
9089 break;
9090 }
9091 case FT_CHAR:
9092 case FT_UINT8:
9093 case FT_INT8:
9094 case FT_UINT16:
9095 case FT_INT16:
9096 case FT_UINT24:
9097 case FT_INT24:
9098 case FT_UINT32:
9099 case FT_INT32:
9100 case FT_FLOAT:
9101 case FT_DOUBLE: {
9102 if (field_display & BASE_UNIT_STRING0x00001000) {
9103 unit_name_string *unit = (unit_name_string *)field_strings;
9104 g_free((char *)unit->singular);
9105 g_free((char *)unit->plural);
9106 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9107 range_string *rs = (range_string *)field_strings;
9108 while (rs->strptr) {
9109 g_free((char *)rs->strptr);
9110 rs++;
9111 }
9112 } else if (field_display & BASE_EXT_STRING0x00000200) {
9113 value_string_ext *vse = (value_string_ext *)field_strings;
9114 value_string *vs = (value_string *)vse->_vs_p;
9115 while (vs->strptr) {
9116 g_free((char *)vs->strptr);
9117 vs++;
9118 }
9119 value_string_ext_free(vse);
9120 field_strings = NULL((void*)0);
9121 } else if (field_display == BASE_CUSTOM) {
9122 /* this will be a pointer to a function, don't free that */
9123 field_strings = NULL((void*)0);
9124 } else {
9125 value_string *vs = (value_string *)field_strings;
9126 while (vs->strptr) {
9127 g_free((char *)vs->strptr);
9128 vs++;
9129 }
9130 }
9131 break;
9132 default:
9133 break;
9134 }
9135 }
9136
9137 if (field_type != FT_FRAMENUM) {
9138 g_free((void *)field_strings);
9139 }
9140}
9141
9142static void
9143free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9144{
9145 header_field_info *hfi = (header_field_info *) data;
9146 int hf_id = hfi->id;
9147
9148 g_free((char *)hfi->name);
9149 g_free((char *)hfi->abbrev);
9150 g_free((char *)hfi->blurb);
9151
9152 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9153
9154 if (hfi->parent == -1)
9155 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)
;
9156
9157 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9158}
9159
9160static void
9161free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9162{
9163 g_free (data);
9164}
9165
9166static void
9167free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9168{
9169 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9170
9171 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9172 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)
;
9173}
9174
9175/* free deregistered fields and data */
9176void
9177proto_free_deregistered_fields (void)
9178{
9179 expert_free_deregistered_expertinfos();
9180
9181 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9182 g_ptr_array_free(deregistered_fields, true1);
9183 deregistered_fields = g_ptr_array_new();
9184
9185 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9186 g_ptr_array_free(deregistered_data, true1);
9187 deregistered_data = g_ptr_array_new();
9188
9189 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9190 g_ptr_array_free(deregistered_slice, true1);
9191 deregistered_slice = g_ptr_array_new();
9192}
9193
9194static const value_string hf_display[] = {
9195 { BASE_NONE, "BASE_NONE" },
9196 { BASE_DEC, "BASE_DEC" },
9197 { BASE_HEX, "BASE_HEX" },
9198 { BASE_OCT, "BASE_OCT" },
9199 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9200 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9201 { BASE_CUSTOM, "BASE_CUSTOM" },
9202 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9203 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9204 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9205 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9206 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9207 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9208 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9209 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9210 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9211 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9212 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9213 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9214 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9215 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9216 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9217 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9218 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9219 { BASE_PT_UDP, "BASE_PT_UDP" },
9220 { BASE_PT_TCP, "BASE_PT_TCP" },
9221 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9222 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9223 { BASE_OUI, "BASE_OUI" },
9224 { 0, NULL((void*)0) } };
9225
9226const char* proto_field_display_to_string(int field_display)
9227{
9228 return val_to_str_const(field_display, hf_display, "Unknown");
9229}
9230
9231static inline port_type
9232display_to_port_type(field_display_e e)
9233{
9234 switch (e) {
9235 case BASE_PT_UDP:
9236 return PT_UDP;
9237 case BASE_PT_TCP:
9238 return PT_TCP;
9239 case BASE_PT_DCCP:
9240 return PT_DCCP;
9241 case BASE_PT_SCTP:
9242 return PT_SCTP;
9243 default:
9244 break;
9245 }
9246 return PT_NONE;
9247}
9248
9249/* temporary function containing assert part for easier profiling */
9250static void
9251tmp_fld_check_assert(header_field_info *hfinfo)
9252{
9253 char* tmp_str;
9254
9255 /* The field must have a name (with length > 0) */
9256 if (!hfinfo->name || !hfinfo->name[0]) {
9257 if (hfinfo->abbrev)
9258 /* Try to identify the field */
9259 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)
9260 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9261 else
9262 /* Hum, no luck */
9263 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)"
)
;
9264 }
9265
9266 /* fields with an empty string for an abbreviation aren't filterable */
9267 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9268 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)
;
9269
9270 /* These types of fields are allowed to have value_strings,
9271 * true_false_strings or a protocol_t struct
9272 */
9273 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9274 switch (hfinfo->type) {
9275
9276 /*
9277 * These types are allowed to support display value_strings,
9278 * value64_strings, the extended versions of the previous
9279 * two, range strings, or unit strings.
9280 */
9281 case FT_CHAR:
9282 case FT_UINT8:
9283 case FT_UINT16:
9284 case FT_UINT24:
9285 case FT_UINT32:
9286 case FT_UINT40:
9287 case FT_UINT48:
9288 case FT_UINT56:
9289 case FT_UINT64:
9290 case FT_INT8:
9291 case FT_INT16:
9292 case FT_INT24:
9293 case FT_INT32:
9294 case FT_INT40:
9295 case FT_INT48:
9296 case FT_INT56:
9297 case FT_INT64:
9298 case FT_BOOLEAN:
9299 case FT_PROTOCOL:
9300 break;
9301
9302 /*
9303 * This is allowed to have a value of type
9304 * enum ft_framenum_type to indicate what relationship
9305 * the frame in question has to the frame in which
9306 * the field is put.
9307 */
9308 case FT_FRAMENUM:
9309 break;
9310
9311 /*
9312 * These types are allowed to support only unit strings.
9313 */
9314 case FT_FLOAT:
9315 case FT_DOUBLE:
9316 case FT_IEEE_11073_SFLOAT:
9317 case FT_IEEE_11073_FLOAT:
9318 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9319 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))
9320 " (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))
9321 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))
;
9322 }
9323 break;
9324
9325 /*
9326 * These types are allowed to support display
9327 * time_value_strings.
9328 */
9329 case FT_ABSOLUTE_TIME:
9330 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9331 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9332 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9333 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9334 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))
9335 " (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))
9336 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))
;
9337 }
9338 break;
9339
9340 /*
9341 * This type is only allowed to support a string if it's
9342 * a protocol (for pinos).
9343 */
9344 case FT_BYTES:
9345 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9346 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))
9347 " (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))
9348 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))
;
9349 }
9350 break;
9351
9352 default:
9353 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))
9354 " (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))
9355 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))
;
9356 }
9357 }
9358
9359 /* TODO: This check may slow down startup, and output quite a few warnings.
9360 It would be good to be able to enable this (and possibly other checks?)
9361 in non-release builds. */
9362#ifdef ENABLE_CHECK_FILTER
9363 /* Check for duplicate value_string values.
9364 There are lots that have the same value *and* string, so for now only
9365 report those that have same value but different string. */
9366 if ((hfinfo->strings != NULL((void*)0)) &&
9367 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9368 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9369 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9370 (
9371 (hfinfo->type == FT_CHAR) ||
9372 (hfinfo->type == FT_UINT8) ||
9373 (hfinfo->type == FT_UINT16) ||
9374 (hfinfo->type == FT_UINT24) ||
9375 (hfinfo->type == FT_UINT32) ||
9376 (hfinfo->type == FT_INT8) ||
9377 (hfinfo->type == FT_INT16) ||
9378 (hfinfo->type == FT_INT24) ||
9379 (hfinfo->type == FT_INT32) )) {
9380
9381 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9382 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9383 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9384 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9385 } else {
9386 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9387 CHECK_HF_VALUE(value_string, "u", start_values);
9388 }
9389 } else {
9390 const value_string *start_values = (const value_string*)hfinfo->strings;
9391 CHECK_HF_VALUE(value_string, "u", start_values);
9392 }
9393 }
9394
9395 if (hfinfo->type == FT_BOOLEAN) {
9396 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9397 if (tfs) {
9398 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9399 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"
, 9401, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9400 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9401, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9401 tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9401, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
;
9402 }
9403 }
9404 }
9405
9406 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9407 const range_string *rs = (const range_string*)(hfinfo->strings);
9408 if (rs) {
9409 const range_string *this_it = rs;
9410
9411 do {
9412 if (this_it->value_max < this_it->value_min) {
9413 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"
, 9417, __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)
9414 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9417, __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)
9415 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9417, __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)
9416 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9417, __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)
9417 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9417, __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)
;
9418 ++this_it;
9419 continue;
9420 }
9421
9422 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9423 /* Not OK if this one is completely hidden by an earlier one! */
9424 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9425 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"
, 9431, __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)
9426 "(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"
, 9431, __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)
9427 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9431, __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)
9428 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9431, __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)
9429 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9431, __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)
9430 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9431, __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)
9431 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9431, __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)
;
9432 }
9433 }
9434 ++this_it;
9435 } while (this_it->strptr);
9436 }
9437 }
9438#endif
9439
9440 switch (hfinfo->type) {
9441
9442 case FT_CHAR:
9443 /* Require the char type to have BASE_HEX, BASE_OCT,
9444 * BASE_CUSTOM, or BASE_NONE as its base.
9445 *
9446 * If the display value is BASE_NONE and there is a
9447 * strings conversion then the dissector writer is
9448 * telling us that the field's numerical value is
9449 * meaningless; we'll avoid showing the value to the
9450 * user.
9451 */
9452 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9453 case BASE_HEX:
9454 case BASE_OCT:
9455 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9456 break;
9457 case BASE_NONE:
9458 if (hfinfo->strings == NULL((void*)0))
9459 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
))
9460 " 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
))
9461 " 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
))
9462 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
))
9463 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
))
;
9464 break;
9465 default:
9466 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9467 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)
9468 " 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)
9469 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)
9470 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)
;
9471 //wmem_free(NULL, tmp_str);
9472 }
9473 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9474 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
))
9475 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
))
9476 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
))
;
9477 }
9478 break;
9479 case FT_INT8:
9480 case FT_INT16:
9481 case FT_INT24:
9482 case FT_INT32:
9483 case FT_INT40:
9484 case FT_INT48:
9485 case FT_INT56:
9486 case FT_INT64:
9487 /* Hexadecimal and octal are, in printf() and everywhere
9488 * else, unsigned so don't allow dissectors to register a
9489 * signed field to be displayed unsigned. (Else how would
9490 * we display negative values?)
9491 */
9492 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9493 case BASE_HEX:
9494 case BASE_OCT:
9495 case BASE_DEC_HEX:
9496 case BASE_HEX_DEC:
9497 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9498 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)
9499 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)
9500 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)
;
9501 //wmem_free(NULL, tmp_str);
9502 }
9503 /* FALL THROUGH */
9504 case FT_UINT8:
9505 case FT_UINT16:
9506 case FT_UINT24:
9507 case FT_UINT32:
9508 case FT_UINT40:
9509 case FT_UINT48:
9510 case FT_UINT56:
9511 case FT_UINT64:
9512 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
))
) {
9513 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9514 if (hfinfo->type != FT_UINT16) {
9515 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))
9516 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))
9517 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))
;
9518 }
9519 if (hfinfo->strings != NULL((void*)0)) {
9520 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)
9521 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)
9522 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)
;
9523 }
9524 if (hfinfo->bitmask != 0) {
9525 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)
9526 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)
9527 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)
;
9528 }
9529 wmem_free(NULL((void*)0), tmp_str);
9530 break;
9531 }
9532
9533 if (hfinfo->display == BASE_OUI) {
9534 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9535 if (hfinfo->type != FT_UINT24) {
9536 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))
9537 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))
9538 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))
;
9539 }
9540 if (hfinfo->strings != NULL((void*)0)) {
9541 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)
9542 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)
9543 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)
;
9544 }
9545 if (hfinfo->bitmask != 0) {
9546 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)
9547 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)
9548 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)
;
9549 }
9550 wmem_free(NULL((void*)0), tmp_str);
9551 break;
9552 }
9553
9554 /* Require integral types (other than frame number,
9555 * which is always displayed in decimal) to have a
9556 * number base.
9557 *
9558 * If the display value is BASE_NONE and there is a
9559 * strings conversion then the dissector writer is
9560 * telling us that the field's numerical value is
9561 * meaningless; we'll avoid showing the value to the
9562 * user.
9563 */
9564 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9565 case BASE_DEC:
9566 case BASE_HEX:
9567 case BASE_OCT:
9568 case BASE_DEC_HEX:
9569 case BASE_HEX_DEC:
9570 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9571 break;
9572 case BASE_NONE:
9573 if (hfinfo->strings == NULL((void*)0)) {
9574 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
))
9575 " 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
))
9576 " 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
))
9577 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
))
9578 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
))
;
9579 }
9580 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9581 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
))
9582 " 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
))
9583 " 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
))
9584 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
))
9585 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
))
;
9586 }
9587 break;
9588
9589 default:
9590 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9591 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)
9592 " 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)
9593 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)
9594 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)
;
9595 //wmem_free(NULL, tmp_str);
9596 }
9597 break;
9598 case FT_BYTES:
9599 case FT_UINT_BYTES:
9600 /* Require bytes to have a "display type" that could
9601 * add a character between displayed bytes.
9602 */
9603 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9604 case BASE_NONE:
9605 case SEP_DOT:
9606 case SEP_DASH:
9607 case SEP_COLON:
9608 case SEP_SPACE:
9609 break;
9610 default:
9611 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9612 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)
9613 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)
;
9614 //wmem_free(NULL, tmp_str);
9615 }
9616 if (hfinfo->bitmask != 0)
9617 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
))
9618 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
))
9619 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
))
;
9620 //allowed to support string if its a protocol (for pinos)
9621 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9622 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
))
9623 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
))
9624 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
))
;
9625 break;
9626
9627 case FT_PROTOCOL:
9628 case FT_FRAMENUM:
9629 if (hfinfo->display != BASE_NONE) {
9630 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9631 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)
9632 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)
9633 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)
;
9634 //wmem_free(NULL, tmp_str);
9635 }
9636 if (hfinfo->bitmask != 0)
9637 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
))
9638 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
))
9639 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
))
;
9640 break;
9641
9642 case FT_BOOLEAN:
9643 break;
9644
9645 case FT_ABSOLUTE_TIME:
9646 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9647 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9648 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)
9649 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)
;
9650 //wmem_free(NULL, tmp_str);
9651 }
9652 if (hfinfo->bitmask != 0)
9653 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
))
9654 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
))
9655 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
))
;
9656 break;
9657
9658 case FT_STRING:
9659 case FT_STRINGZ:
9660 case FT_UINT_STRING:
9661 case FT_STRINGZPAD:
9662 case FT_STRINGZTRUNC:
9663 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9664 case BASE_NONE:
9665 case BASE_STR_WSP:
9666 break;
9667
9668 default:
9669 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9670 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)
9671 " 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)
9672 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)
9673 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)
;
9674 //wmem_free(NULL, tmp_str);
9675 }
9676
9677 if (hfinfo->bitmask != 0)
9678 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9679 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9680 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9681 if (hfinfo->strings != NULL((void*)0))
9682 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9683 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9684 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9685 break;
9686
9687 case FT_IPv4:
9688 switch (hfinfo->display) {
9689 case BASE_NONE:
9690 case BASE_NETMASK:
9691 break;
9692
9693 default:
9694 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9695 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)
9696 " 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)
9697 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)
9698 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)
;
9699 //wmem_free(NULL, tmp_str);
9700 break;
9701 }
9702 break;
9703 case FT_FLOAT:
9704 case FT_DOUBLE:
9705 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9706 case BASE_NONE:
9707 case BASE_DEC:
9708 case BASE_HEX:
9709 case BASE_EXP:
9710 case BASE_CUSTOM:
9711 break;
9712 default:
9713 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9714 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)
9715 " 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)
9716 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)
9717 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)
;
9718 //wmem_free(NULL, tmp_str);
9719 }
9720 if (hfinfo->bitmask != 0)
9721 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
))
9722 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
))
9723 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
))
;
9724 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9725 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
))
9726 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
))
9727 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
))
;
9728 break;
9729 case FT_IEEE_11073_SFLOAT:
9730 case FT_IEEE_11073_FLOAT:
9731 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9732 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9733 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)
9734 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)
9735 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)
9736 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)
;
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 ((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 default:
9749 if (hfinfo->display != BASE_NONE) {
9750 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9751 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)
9752 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)
9753 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)
9754 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)
;
9755 //wmem_free(NULL, tmp_str);
9756 }
9757 if (hfinfo->bitmask != 0)
9758 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
))
9759 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
))
9760 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
))
;
9761 if (hfinfo->strings != NULL((void*)0))
9762 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
))
9763 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
))
9764 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
))
;
9765 break;
9766 }
9767}
9768
9769static void
9770register_type_length_mismatch(void)
9771{
9772 static ei_register_info ei[] = {
9773 { &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)}}
}},
9774 { &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)}}
}},
9775 };
9776
9777 expert_module_t* expert_type_length_mismatch;
9778
9779 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9780
9781 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9782 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9783
9784 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9785 disabling them makes no sense. */
9786 proto_set_cant_toggle(proto_type_length_mismatch);
9787}
9788
9789static void
9790register_byte_array_string_decodinws_error(void)
9791{
9792 static ei_register_info ei[] = {
9793 { &ei_byte_array_string_decoding_failed_error,
9794 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9795 "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)}}
9796 }
9797 },
9798 };
9799
9800 expert_module_t* expert_byte_array_string_decoding_error;
9801
9802 proto_byte_array_string_decoding_error =
9803 proto_register_protocol("Byte Array-String Decoding Error",
9804 "Byte Array-string decoding error",
9805 "_ws.byte_array_string.decoding_error");
9806
9807 expert_byte_array_string_decoding_error =
9808 expert_register_protocol(proto_byte_array_string_decoding_error);
9809 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9810
9811 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9812 disabling them makes no sense. */
9813 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9814}
9815
9816static void
9817register_date_time_string_decodinws_error(void)
9818{
9819 static ei_register_info ei[] = {
9820 { &ei_date_time_string_decoding_failed_error,
9821 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9822 "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)}}
9823 }
9824 },
9825 };
9826
9827 expert_module_t* expert_date_time_string_decoding_error;
9828
9829 proto_date_time_string_decoding_error =
9830 proto_register_protocol("Date and Time-String Decoding Error",
9831 "Date and Time-string decoding error",
9832 "_ws.date_time_string.decoding_error");
9833
9834 expert_date_time_string_decoding_error =
9835 expert_register_protocol(proto_date_time_string_decoding_error);
9836 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9837
9838 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9839 disabling them makes no sense. */
9840 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9841}
9842
9843static void
9844register_string_errors(void)
9845{
9846 static ei_register_info ei[] = {
9847 { &ei_string_trailing_characters,
9848 { "_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)}}
}
9849 },
9850 };
9851
9852 expert_module_t* expert_string_errors;
9853
9854 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9855
9856 expert_string_errors = expert_register_protocol(proto_string_errors);
9857 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9858
9859 /* "String Errors" isn't really a protocol, it's an error indication;
9860 disabling them makes no sense. */
9861 proto_set_cant_toggle(proto_string_errors);
9862}
9863
9864static int
9865proto_register_field_init(header_field_info *hfinfo, const int parent)
9866{
9867
9868 tmp_fld_check_assert(hfinfo);
9869
9870 hfinfo->parent = parent;
9871 hfinfo->same_name_next = NULL((void*)0);
9872 hfinfo->same_name_prev_id = -1;
9873
9874 /* if we always add and never delete, then id == len - 1 is correct */
9875 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9876 if (!gpa_hfinfo.hfi) {
9877 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9878 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9879 /* The entry with index 0 is not used. */
9880 gpa_hfinfo.hfi[0] = NULL((void*)0);
9881 gpa_hfinfo.len = 1;
9882 } else {
9883 gpa_hfinfo.allocated_len += 1000;
9884 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9885 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9886 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9887 }
9888 }
9889 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9890 gpa_hfinfo.len++;
9891 hfinfo->id = gpa_hfinfo.len - 1;
9892
9893 /* if we have real names, enter this field in the name tree */
9894 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
9895
9896 header_field_info *same_name_next_hfinfo;
9897 unsigned char c;
9898
9899 /* Check that the filter name (abbreviation) is legal;
9900 * it must contain only alphanumerics, '-', "_", and ".". */
9901 c = proto_check_field_name(hfinfo->abbrev);
9902 if (c) {
9903 if (c == '.') {
9904 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)
;
9905 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9906 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)
;
9907 } else {
9908 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)
;
9909 }
9910 }
9911
9912 /* We allow multiple hfinfo's to be registered under the same
9913 * abbreviation. This was done for X.25, as, depending
9914 * on whether it's modulo-8 or modulo-128 operation,
9915 * some bitfield fields may be in different bits of
9916 * a byte, and we want to be able to refer to that field
9917 * with one name regardless of whether the packets
9918 * are modulo-8 or modulo-128 packets. */
9919
9920 /* wmem_map_insert - if key is already present the previous
9921 * hfinfo with the same key/name is returned, otherwise NULL */
9922 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9923 if (same_name_hfinfo) {
9924 /* There's already a field with this name.
9925 * Put the current field *before* that field
9926 * in the list of fields with this name, Thus,
9927 * we end up with an effectively
9928 * doubly-linked-list of same-named hfinfo's,
9929 * with the head of the list (stored in the
9930 * hash) being the last seen hfinfo.
9931 */
9932 same_name_next_hfinfo =
9933 same_name_hfinfo->same_name_next;
9934
9935 hfinfo->same_name_next = same_name_next_hfinfo;
9936 if (same_name_next_hfinfo)
9937 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9938
9939 same_name_hfinfo->same_name_next = hfinfo;
9940 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9941#ifdef ENABLE_CHECK_FILTER
9942 while (same_name_hfinfo) {
9943 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9944 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"
, 9944, __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)
;
9945 same_name_hfinfo = same_name_hfinfo->same_name_next;
9946 }
9947#endif
9948 }
9949 }
9950
9951 return hfinfo->id;
9952}
9953
9954void
9955proto_register_subtree_array(int * const *indices, const int num_indices)
9956{
9957 int i;
9958 int *const *ptr = indices;
9959
9960 /*
9961 * If we've already allocated the array of tree types, expand
9962 * it; this lets plugins such as mate add tree types after
9963 * the initial startup. (If we haven't already allocated it,
9964 * we don't allocate it; on the first pass, we just assign
9965 * ett values and keep track of how many we've assigned, and
9966 * when we're finished registering all dissectors we allocate
9967 * the array, so that we do only one allocation rather than
9968 * wasting CPU time and memory by growing the array for each
9969 * dissector that registers ett values.)
9970 */
9971 if (tree_is_expanded != NULL((void*)0)) {
9972 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9973
9974 /* set new items to 0 */
9975 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9976 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9977 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9978 }
9979
9980 /*
9981 * Assign "num_indices" subtree numbers starting at "num_tree_types",
9982 * returning the indices through the pointers in the array whose
9983 * first element is pointed to by "indices", and update
9984 * "num_tree_types" appropriately.
9985 */
9986 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9987 if (**ptr != -1 && **ptr != 0) {
9988 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.")
9989 " 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.")
9990 " 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.")
9991 " 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.")
;
9992 }
9993 **ptr = num_tree_types;
9994 }
9995}
9996
9997static void
9998mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
9999{
10000 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10001 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10002 char *last_char;
10003
10004 /* ..... field_name: dataaaaaaaaaaaaa
10005 * |
10006 * ^^^^^ name_pos
10007 *
10008 * ..... field_name […]: dataaaaaaaaaaaaa
10009 *
10010 * name_pos==0 means that we have only data or only a field_name
10011 */
10012
10013 ws_assert(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10013, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10014
10015 if (name_pos >= size - trunc_len) {
10016 /* No room for trunc_str after the field_name, put it first. */
10017 name_pos = 0;
10018 }
10019
10020 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10021 if (name_pos == 0) {
10022 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10023 memcpy(label_str, trunc_str + 1, trunc_len);
10024 } else {
10025 memcpy(label_str + name_pos, trunc_str, trunc_len);
10026 }
10027 /* in general, label_str is UTF-8
10028 we can truncate it only at the beginning of a new character
10029 we go backwards from the byte right after our buffer and
10030 find the next starting byte of a UTF-8 character, this is
10031 where we cut
10032 there's no need to use g_utf8_find_prev_char(), the search
10033 will always succeed since we copied trunc_str into the
10034 buffer */
10035 /* g_utf8_prev_char does not deference the memory address
10036 * passed in (until after decrementing it, so it is perfectly
10037 * legal to pass in a pointer one past the last element.
10038 */
10039 last_char = g_utf8_prev_char(label_str + size);
10040 *last_char = '\0';
10041
10042 if (value_pos && *value_pos > 0) {
10043 if (name_pos == 0) {
10044 *value_pos += trunc_len;
10045 } else {
10046 /* Move one back to include trunc_str in the value. */
10047 *value_pos -= 1;
10048 }
10049 }
10050
10051 /* Check if value_pos is past label_str. */
10052 if (value_pos && *value_pos >= size) {
10053 *value_pos = size - 1;
10054 }
10055}
10056
10057static void
10058label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10059{
10060 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10061}
10062
10063static size_t
10064label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10065{
10066 size_t name_pos;
10067
10068 /* "%s: %s", hfinfo->name, text */
10069 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10070 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10071 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10072 if (value_pos) {
10073 *value_pos = pos;
10074 }
10075 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, text ? text : "(null)", label_strcat_flags(hfinfo));
10076 }
10077
10078 if (pos >= ITEM_LABEL_LENGTH240) {
10079 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10080 label_mark_truncated(label_str, name_pos, value_pos);
10081 }
10082
10083 return pos;
10084}
10085
10086static size_t
10087label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10088{
10089 size_t name_pos;
10090
10091 /* "%s: %s (%s)", hfinfo->name, text, descr */
10092 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10093 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10094 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10095 if (value_pos) {
10096 *value_pos = pos;
10097 }
10098 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10099 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10100 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10101 } else {
10102 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10103 pos = label_concat(label_str, pos, " (")ws_label_strcpy(label_str, 240, pos, " (", 0);
10104 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10105 pos = label_concat(label_str, pos, ")")ws_label_strcpy(label_str, 240, pos, ")", 0);
10106 }
10107 }
10108
10109 if (pos >= ITEM_LABEL_LENGTH240) {
10110 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10111 label_mark_truncated(label_str, name_pos, value_pos);
10112 }
10113
10114 return pos;
10115}
10116
10117void
10118proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10119{
10120 const header_field_info *hfinfo;
10121 const char *str;
10122 const uint8_t *bytes;
10123 uint32_t integer;
10124 const ipv4_addr_and_mask *ipv4;
10125 const ipv6_addr_and_prefix *ipv6;
10126 const e_guid_t *guid;
10127 char *name;
10128 address addr;
10129 char *addr_str;
10130 char *tmp;
10131
10132 if (!label_str) {
10133 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10133, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10134 return;
10135 }
10136
10137 label_str[0]= '\0';
10138
10139 if (!fi) {
10140 return;
10141 }
10142
10143 hfinfo = fi->hfinfo;
10144
10145 switch (hfinfo->type) {
10146 case FT_NONE:
10147 case FT_PROTOCOL:
10148 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10149 if (value_pos) {
10150 *value_pos = strlen(hfinfo->name);
10151 }
10152 break;
10153
10154 case FT_BOOLEAN:
10155 fill_label_boolean(fi, label_str, value_pos);
10156 break;
10157
10158 case FT_BYTES:
10159 case FT_UINT_BYTES:
10160 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10161 fvalue_get_bytes_data(fi->value),
10162 (unsigned)fvalue_length2(fi->value));
10163 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10164 wmem_free(NULL((void*)0), tmp);
10165 break;
10166
10167 case FT_CHAR:
10168 if (hfinfo->bitmask) {
10169 fill_label_bitfield_char(fi, label_str, value_pos);
10170 } else {
10171 fill_label_char(fi, label_str, value_pos);
10172 }
10173 break;
10174
10175 /* Four types of integers to take care of:
10176 * Bitfield, with val_string
10177 * Bitfield, w/o val_string
10178 * Non-bitfield, with val_string
10179 * Non-bitfield, w/o val_string
10180 */
10181 case FT_UINT8:
10182 case FT_UINT16:
10183 case FT_UINT24:
10184 case FT_UINT32:
10185 if (hfinfo->bitmask) {
10186 fill_label_bitfield(fi, label_str, value_pos, false0);
10187 } else {
10188 fill_label_number(fi, label_str, value_pos, false0);
10189 }
10190 break;
10191
10192 case FT_FRAMENUM:
10193 fill_label_number(fi, label_str, value_pos, false0);
10194 break;
10195
10196 case FT_UINT40:
10197 case FT_UINT48:
10198 case FT_UINT56:
10199 case FT_UINT64:
10200 if (hfinfo->bitmask) {
10201 fill_label_bitfield64(fi, label_str, value_pos, false0);
10202 } else {
10203 fill_label_number64(fi, label_str, value_pos, false0);
10204 }
10205 break;
10206
10207 case FT_INT8:
10208 case FT_INT16:
10209 case FT_INT24:
10210 case FT_INT32:
10211 if (hfinfo->bitmask) {
10212 fill_label_bitfield(fi, label_str, value_pos, true1);
10213 } else {
10214 fill_label_number(fi, label_str, value_pos, true1);
10215 }
10216 break;
10217
10218 case FT_INT40:
10219 case FT_INT48:
10220 case FT_INT56:
10221 case FT_INT64:
10222 if (hfinfo->bitmask) {
10223 fill_label_bitfield64(fi, label_str, value_pos, true1);
10224 } else {
10225 fill_label_number64(fi, label_str, value_pos, true1);
10226 }
10227 break;
10228
10229 case FT_FLOAT:
10230 case FT_DOUBLE:
10231 fill_label_float(fi, label_str, value_pos);
10232 break;
10233
10234 case FT_ABSOLUTE_TIME:
10235 {
10236 const nstime_t *value = fvalue_get_time(fi->value);
10237 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10238 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10239 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10240 }
10241 if (hfinfo->strings) {
10242 /*
10243 * Table of time valus to be displayed
10244 * specially.
10245 */
10246 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10247 if (time_string != NULL((void*)0)) {
10248 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10249 break;
10250 }
10251 }
10252 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10253 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10254 wmem_free(NULL((void*)0), tmp);
10255 break;
10256 }
10257 case FT_RELATIVE_TIME:
10258 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10259 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10260 wmem_free(NULL((void*)0), tmp);
10261 break;
10262
10263 case FT_IPXNET:
10264 integer = fvalue_get_uinteger(fi->value);
10265 tmp = get_ipxnet_name(NULL((void*)0), integer);
10266 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10267 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10268 wmem_free(NULL((void*)0), tmp);
10269 wmem_free(NULL((void*)0), addr_str);
10270 break;
10271
10272 case FT_VINES:
10273 addr.type = AT_VINES;
10274 addr.len = VINES_ADDR_LEN6;
10275 addr.data = fvalue_get_bytes_data(fi->value);
10276
10277 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10278 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10279 wmem_free(NULL((void*)0), addr_str);
10280 break;
10281
10282 case FT_ETHER:
10283 bytes = fvalue_get_bytes_data(fi->value);
10284
10285 addr.type = AT_ETHER;
10286 addr.len = 6;
10287 addr.data = bytes;
10288
10289 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10290 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10291 wmem_free(NULL((void*)0), addr_str);
10292 break;
10293
10294 case FT_IPv4:
10295 ipv4 = fvalue_get_ipv4(fi->value);
10296 set_address_ipv4(&addr, ipv4);
10297
10298 if (hfinfo->display == BASE_NETMASK) {
10299 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10300 } else {
10301 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10302 }
10303 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10304 wmem_free(NULL((void*)0), addr_str);
10305 free_address(&addr);
10306 break;
10307
10308 case FT_IPv6:
10309 ipv6 = fvalue_get_ipv6(fi->value);
10310 set_address_ipv6(&addr, ipv6);
10311
10312 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10313 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10314 wmem_free(NULL((void*)0), addr_str);
10315 free_address(&addr);
10316 break;
10317
10318 case FT_FCWWN:
10319 bytes = fvalue_get_bytes_data(fi->value);
10320 addr.type = AT_FCWWN;
10321 addr.len = FCWWN_ADDR_LEN8;
10322 addr.data = bytes;
10323
10324 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10325 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10326 wmem_free(NULL((void*)0), addr_str);
10327 break;
10328
10329 case FT_GUID:
10330 guid = fvalue_get_guid(fi->value);
10331 tmp = guid_to_str(NULL((void*)0), guid);
10332 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10333 wmem_free(NULL((void*)0), tmp);
10334 break;
10335
10336 case FT_OID:
10337 bytes = fvalue_get_bytes_data(fi->value);
10338 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10339 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10340 if (name) {
10341 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10342 wmem_free(NULL((void*)0), name);
10343 } else {
10344 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10345 }
10346 wmem_free(NULL((void*)0), tmp);
10347 break;
10348
10349 case FT_REL_OID:
10350 bytes = fvalue_get_bytes_data(fi->value);
10351 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10352 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10353 if (name) {
10354 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10355 wmem_free(NULL((void*)0), name);
10356 } else {
10357 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10358 }
10359 wmem_free(NULL((void*)0), tmp);
10360 break;
10361
10362 case FT_SYSTEM_ID:
10363 bytes = fvalue_get_bytes_data(fi->value);
10364 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10365 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10366 wmem_free(NULL((void*)0), tmp);
10367 break;
10368
10369 case FT_EUI64:
10370 bytes = fvalue_get_bytes_data(fi->value);
10371 addr.type = AT_EUI64;
10372 addr.len = EUI64_ADDR_LEN8;
10373 addr.data = bytes;
10374
10375 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10376 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10377 wmem_free(NULL((void*)0), addr_str);
10378 break;
10379 case FT_STRING:
10380 case FT_STRINGZ:
10381 case FT_UINT_STRING:
10382 case FT_STRINGZPAD:
10383 case FT_STRINGZTRUNC:
10384 case FT_AX25:
10385 str = fvalue_get_string(fi->value);
10386 label_fill(label_str, 0, hfinfo, str, value_pos);
10387 break;
10388
10389 case FT_IEEE_11073_SFLOAT:
10390 case FT_IEEE_11073_FLOAT:
10391 fill_label_ieee_11073_float(fi, label_str, value_pos);
10392 break;
10393
10394 default:
10395 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
))
10396 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
))
10397 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
))
10398 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
))
;
10399 break;
10400 }
10401}
10402
10403static void
10404fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10405{
10406 char *p;
10407 int bitfield_byte_length = 0, bitwidth;
10408 uint64_t unshifted_value;
10409 uint64_t value;
10410
10411 const header_field_info *hfinfo = fi->hfinfo;
10412
10413 value = fvalue_get_uinteger64(fi->value);
10414 if (hfinfo->bitmask) {
10415 /* Figure out the bit width */
10416 bitwidth = hfinfo_container_bitwidth(hfinfo);
10417
10418 /* Un-shift bits */
10419 unshifted_value = value;
10420 unshifted_value <<= hfinfo_bitshift(hfinfo);
10421
10422 /* Create the bitfield first */
10423 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10424 bitfield_byte_length = (int) (p - label_str);
10425 }
10426
10427 /* Fill in the textual info */
10428 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10429}
10430
10431static const char *
10432hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10433{
10434 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10435 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10436
10437 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10438 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10439 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10440 else
10441 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10442 }
10443
10444 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10445 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10446
10447 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10448 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10449
10450 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10451}
10452
10453static const char *
10454hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10455{
10456 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10457 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10458 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10459 else
10460 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10461 }
10462
10463 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10464 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10465
10466 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10467 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10468
10469 /* If this is reached somebody registered a 64-bit field with a 32-bit
10470 * value-string, which isn't right. */
10471 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)
10472 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10473
10474 /* This is necessary to squelch MSVC errors; is there
10475 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10476 never returns? */
10477 return NULL((void*)0);
10478}
10479
10480static const char *
10481hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10482{
10483 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10484 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10485
10486 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)
;
10487
10488 /* This is necessary to squelch MSVC errors; is there
10489 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10490 never returns? */
10491 return NULL((void*)0);
10492}
10493
10494static const char *
10495hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10496{
10497 const char *str = hf_try_val_to_str(value, hfinfo);
10498
10499 return (str) ? str : unknown_str;
10500}
10501
10502static const char *
10503hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10504{
10505 const char *str = hf_try_val64_to_str(value, hfinfo);
10506
10507 return (str) ? str : unknown_str;
10508}
10509
10510/* Fills data for bitfield chars with val_strings */
10511static void
10512fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10513{
10514 char *p;
10515 int bitfield_byte_length, bitwidth;
10516 uint32_t unshifted_value;
10517 uint32_t value;
10518
10519 char buf[32];
10520 const char *out;
10521
10522 const header_field_info *hfinfo = fi->hfinfo;
10523
10524 /* Figure out the bit width */
10525 bitwidth = hfinfo_container_bitwidth(hfinfo);
10526
10527 /* Un-shift bits */
10528 value = fvalue_get_uinteger(fi->value);
10529
10530 unshifted_value = value;
10531 if (hfinfo->bitmask) {
10532 unshifted_value <<= hfinfo_bitshift(hfinfo);
10533 }
10534
10535 /* Create the bitfield first */
10536 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10537 bitfield_byte_length = (int) (p - label_str);
10538
10539 /* Fill in the textual info using stored (shifted) value */
10540 if (hfinfo->display == BASE_CUSTOM) {
10541 char tmp[ITEM_LABEL_LENGTH240];
10542 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10543
10544 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10544, "fmtfunc"))))
;
10545 fmtfunc(tmp, value);
10546 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10547 }
10548 else if (hfinfo->strings) {
10549 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10550
10551 out = hfinfo_char_vals_format(hfinfo, buf, value);
10552 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10553 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10554 else
10555 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10556 }
10557 else {
10558 out = hfinfo_char_value_format(hfinfo, buf, value);
10559
10560 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10561 }
10562}
10563
10564/* Fills data for bitfield ints with val_strings */
10565static void
10566fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10567{
10568 char *p;
10569 int bitfield_byte_length, bitwidth;
10570 uint32_t value, unshifted_value;
10571 char buf[NUMBER_LABEL_LENGTH80];
10572 const char *out;
10573
10574 const header_field_info *hfinfo = fi->hfinfo;
10575
10576 /* Figure out the bit width */
10577 if (fi->flags & FI_VARINT0x00040000)
10578 bitwidth = fi->length*8;
10579 else
10580 bitwidth = hfinfo_container_bitwidth(hfinfo);
10581
10582 /* Un-shift bits */
10583 if (is_signed)
10584 value = fvalue_get_sinteger(fi->value);
10585 else
10586 value = fvalue_get_uinteger(fi->value);
10587
10588 unshifted_value = value;
10589 if (hfinfo->bitmask) {
10590 unshifted_value <<= hfinfo_bitshift(hfinfo);
10591 }
10592
10593 /* Create the bitfield first */
10594 if (fi->flags & FI_VARINT0x00040000)
10595 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10596 else
10597 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10598 bitfield_byte_length = (int) (p - label_str);
10599
10600 /* Fill in the textual info using stored (shifted) value */
10601 if (hfinfo->display == BASE_CUSTOM) {
10602 char tmp[ITEM_LABEL_LENGTH240];
10603 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10604
10605 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10605, "fmtfunc"))))
;
10606 fmtfunc(tmp, value);
10607 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10608 }
10609 else if (hfinfo->strings) {
10610 const char *val_str = hf_try_val_to_str(value, hfinfo);
10611
10612 out = hfinfo_number_vals_format(hfinfo, buf, value);
10613 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10614 /*
10615 * Unique values only display value_string string
10616 * if there is a match. Otherwise it's just a number
10617 */
10618 if (val_str) {
10619 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10620 } else {
10621 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10622 }
10623 } else {
10624 if (val_str == NULL((void*)0))
10625 val_str = "Unknown";
10626
10627 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10628 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10629 else
10630 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10631 }
10632 }
10633 else {
10634 out = hfinfo_number_value_format(hfinfo, buf, value);
10635
10636 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10637 }
10638}
10639
10640static void
10641fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10642{
10643 char *p;
10644 int bitfield_byte_length, bitwidth;
10645 uint64_t value, unshifted_value;
10646 char buf[NUMBER_LABEL_LENGTH80];
10647 const char *out;
10648
10649 const header_field_info *hfinfo = fi->hfinfo;
10650
10651 /* Figure out the bit width */
10652 if (fi->flags & FI_VARINT0x00040000)
10653 bitwidth = fi->length*8;
10654 else
10655 bitwidth = hfinfo_container_bitwidth(hfinfo);
10656
10657 /* Un-shift bits */
10658 if (is_signed)
10659 value = fvalue_get_sinteger64(fi->value);
10660 else
10661 value = fvalue_get_uinteger64(fi->value);
10662
10663 unshifted_value = value;
10664 if (hfinfo->bitmask) {
10665 unshifted_value <<= hfinfo_bitshift(hfinfo);
10666 }
10667
10668 /* Create the bitfield first */
10669 if (fi->flags & FI_VARINT0x00040000)
10670 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10671 else
10672 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10673 bitfield_byte_length = (int) (p - label_str);
10674
10675 /* Fill in the textual info using stored (shifted) value */
10676 if (hfinfo->display == BASE_CUSTOM) {
10677 char tmp[ITEM_LABEL_LENGTH240];
10678 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10679
10680 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10680, "fmtfunc64"
))))
;
10681 fmtfunc64(tmp, value);
10682 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10683 }
10684 else if (hfinfo->strings) {
10685 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10686
10687 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10688 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10689 /*
10690 * Unique values only display value_string string
10691 * if there is a match. Otherwise it's just a number
10692 */
10693 if (val_str) {
10694 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10695 } else {
10696 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10697 }
10698 } else {
10699 if (val_str == NULL((void*)0))
10700 val_str = "Unknown";
10701
10702 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10703 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10704 else
10705 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10706 }
10707 }
10708 else {
10709 out = hfinfo_number_value_format64(hfinfo, buf, value);
10710
10711 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10712 }
10713}
10714
10715static void
10716fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10717{
10718 const header_field_info *hfinfo = fi->hfinfo;
10719 uint32_t value;
10720
10721 char buf[32];
10722 const char *out;
10723
10724 value = fvalue_get_uinteger(fi->value);
10725
10726 /* Fill in the textual info */
10727 if (hfinfo->display == BASE_CUSTOM) {
10728 char tmp[ITEM_LABEL_LENGTH240];
10729 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10730
10731 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10731, "fmtfunc"))))
;
10732 fmtfunc(tmp, value);
10733 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10734 }
10735 else if (hfinfo->strings) {
10736 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10737
10738 out = hfinfo_char_vals_format(hfinfo, buf, value);
10739 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10740 }
10741 else {
10742 out = hfinfo_char_value_format(hfinfo, buf, value);
10743
10744 label_fill(label_str, 0, hfinfo, out, value_pos);
10745 }
10746}
10747
10748static void
10749fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10750{
10751 const header_field_info *hfinfo = fi->hfinfo;
10752 uint32_t value;
10753
10754 char buf[NUMBER_LABEL_LENGTH80];
10755 const char *out;
10756
10757 if (is_signed)
10758 value = fvalue_get_sinteger(fi->value);
10759 else
10760 value = fvalue_get_uinteger(fi->value);
10761
10762 /* Fill in the textual info */
10763 if (hfinfo->display == BASE_CUSTOM) {
10764 char tmp[ITEM_LABEL_LENGTH240];
10765 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10766
10767 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10767, "fmtfunc"))))
;
10768 fmtfunc(tmp, value);
10769 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10770 }
10771 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10772 /*
10773 * It makes no sense to have a value-string table for a
10774 * frame-number field - they're just integers giving
10775 * the ordinal frame number.
10776 */
10777 const char *val_str = hf_try_val_to_str(value, hfinfo);
10778
10779 out = hfinfo_number_vals_format(hfinfo, buf, value);
10780 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10781 /*
10782 * Unique values only display value_string string
10783 * if there is a match. Otherwise it's just a number
10784 */
10785 if (val_str) {
10786 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10787 } else {
10788 label_fill(label_str, 0, hfinfo, out, value_pos);
10789 }
10790 } else {
10791 if (val_str == NULL((void*)0))
10792 val_str = "Unknown";
10793
10794 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10795 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10796 else
10797 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10798 }
10799 }
10800 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
))
) {
10801 char tmp[ITEM_LABEL_LENGTH240];
10802
10803 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10804 display_to_port_type((field_display_e)hfinfo->display), value);
10805 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10806 }
10807 else {
10808 out = hfinfo_number_value_format(hfinfo, buf, value);
10809
10810 label_fill(label_str, 0, hfinfo, out, value_pos);
10811 }
10812}
10813
10814static void
10815fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10816{
10817 const header_field_info *hfinfo = fi->hfinfo;
10818 uint64_t value;
10819
10820 char buf[NUMBER_LABEL_LENGTH80];
10821 const char *out;
10822
10823 if (is_signed)
10824 value = fvalue_get_sinteger64(fi->value);
10825 else
10826 value = fvalue_get_uinteger64(fi->value);
10827
10828 /* Fill in the textual info */
10829 if (hfinfo->display == BASE_CUSTOM) {
10830 char tmp[ITEM_LABEL_LENGTH240];
10831 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10832
10833 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10833, "fmtfunc64"
))))
;
10834 fmtfunc64(tmp, value);
10835 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10836 }
10837 else if (hfinfo->strings) {
10838 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10839
10840 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10841 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10842 /*
10843 * Unique values only display value_string string
10844 * if there is a match. Otherwise it's just a number
10845 */
10846 if (val_str) {
10847 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10848 } else {
10849 label_fill(label_str, 0, hfinfo, out, value_pos);
10850 }
10851 } else {
10852 if (val_str == NULL((void*)0))
10853 val_str = "Unknown";
10854
10855 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10856 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10857 else
10858 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10859 }
10860 }
10861 else {
10862 out = hfinfo_number_value_format64(hfinfo, buf, value);
10863
10864 label_fill(label_str, 0, hfinfo, out, value_pos);
10865 }
10866}
10867
10868static size_t
10869fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10870{
10871 int display;
10872 int n;
10873 double value;
10874
10875 if (label_str_size < 12) {
10876 /* Not enough room to write an entire floating point value. */
10877 return 0;
10878 }
10879
10880 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10881 value = fvalue_get_floating(fi->value);
10882
10883 if (display == BASE_CUSTOM) {
10884 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10885 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10885, "fmtfunc"))))
;
10886 fmtfunc(label_str, value);
10887 return strlen(label_str);
10888 }
10889
10890 switch (display) {
10891 case BASE_NONE:
10892 if (fi->hfinfo->type == FT_FLOAT) {
10893 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10894 } else {
10895 n = (int)strlen(dtoa_g_fmt(label_str, value));
10896 }
10897 break;
10898 case BASE_DEC:
10899 n = snprintf(label_str, label_str_size, "%f", value);
10900 break;
10901 case BASE_HEX:
10902 n = snprintf(label_str, label_str_size, "%a", value);
10903 break;
10904 case BASE_EXP:
10905 n = snprintf(label_str, label_str_size, "%e", value);
10906 break;
10907 default:
10908 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10908
, __func__, "assertion \"not reached\" failed")
;
10909 }
10910 if (n < 0) {
10911 return 0; /* error */
10912 }
10913 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10914 const char *hf_str_val;
10915 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10916 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10917 }
10918 if (n > label_str_size) {
10919 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10919, __func__, "label length too small"); } } while (0)
;
10920 return strlen(label_str);
10921 }
10922
10923 return n;
10924}
10925
10926void
10927fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10928{
10929 char tmp[ITEM_LABEL_LENGTH240];
10930
10931 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10932 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10933}
10934
10935static size_t
10936fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10937{
10938 int display;
10939 size_t pos = 0;
10940 double value;
10941 char* tmp_str;
10942
10943 if (label_str_size < 12) {
10944 /* Not enough room to write an entire floating point value. */
10945 return 0;
10946 }
10947
10948 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10949 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10950 pos = label_concat(label_str, pos, tmp_str)ws_label_strcpy(label_str, 240, pos, tmp_str, 0);
10951 wmem_free(NULL((void*)0), tmp_str);
10952
10953 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10954 const char *hf_str_val;
10955 fvalue_to_double(fi->value, &value);
10956 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10957 pos = label_concat(label_str, pos, hf_str_val)ws_label_strcpy(label_str, 240, pos, hf_str_val, 0);
10958 }
10959 if ((int)pos > label_str_size) {
10960 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10960, __func__, "label length too small"); } } while (0)
;
10961 return strlen(label_str);
10962 }
10963
10964 return pos;
10965}
10966
10967void
10968fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
10969{
10970 char tmp[ITEM_LABEL_LENGTH240];
10971
10972 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
10973 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10974}
10975
10976int
10977hfinfo_bitshift(const header_field_info *hfinfo)
10978{
10979 return ws_ctz(hfinfo->bitmask);
10980}
10981
10982
10983static int
10984hfinfo_bitoffset(const header_field_info *hfinfo)
10985{
10986 if (!hfinfo->bitmask) {
10987 return 0;
10988 }
10989
10990 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
10991 * as the first bit */
10992 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
10993}
10994
10995static int
10996hfinfo_mask_bitwidth(const header_field_info *hfinfo)
10997{
10998 if (!hfinfo->bitmask) {
10999 return 0;
11000 }
11001
11002 /* ilog2 = first set bit, ctz = last set bit */
11003 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11004}
11005
11006static int
11007hfinfo_type_bitwidth(enum ftenum type)
11008{
11009 int bitwidth = 0;
11010
11011 switch (type) {
11012 case FT_CHAR:
11013 case FT_UINT8:
11014 case FT_INT8:
11015 bitwidth = 8;
11016 break;
11017 case FT_UINT16:
11018 case FT_INT16:
11019 bitwidth = 16;
11020 break;
11021 case FT_UINT24:
11022 case FT_INT24:
11023 bitwidth = 24;
11024 break;
11025 case FT_UINT32:
11026 case FT_INT32:
11027 bitwidth = 32;
11028 break;
11029 case FT_UINT40:
11030 case FT_INT40:
11031 bitwidth = 40;
11032 break;
11033 case FT_UINT48:
11034 case FT_INT48:
11035 bitwidth = 48;
11036 break;
11037 case FT_UINT56:
11038 case FT_INT56:
11039 bitwidth = 56;
11040 break;
11041 case FT_UINT64:
11042 case FT_INT64:
11043 bitwidth = 64;
11044 break;
11045 default:
11046 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11046))
;
11047 ;
11048 }
11049 return bitwidth;
11050}
11051
11052
11053static int
11054hfinfo_container_bitwidth(const header_field_info *hfinfo)
11055{
11056 if (!hfinfo->bitmask) {
11057 return 0;
11058 }
11059
11060 if (hfinfo->type == FT_BOOLEAN) {
11061 return hfinfo->display; /* hacky? :) */
11062 }
11063
11064 return hfinfo_type_bitwidth(hfinfo->type);
11065}
11066
11067static int
11068hfinfo_hex_digits(const header_field_info *hfinfo)
11069{
11070 int bitwidth;
11071
11072 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11073 * appropriate to determine the number of hex digits for the field.
11074 * So instead, we compute it from the bitmask.
11075 */
11076 if (hfinfo->bitmask != 0) {
11077 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11078 } else {
11079 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11080 }
11081
11082 /* Divide by 4, rounding up, to get number of hex digits. */
11083 return (bitwidth + 3) / 4;
11084}
11085
11086const char *
11087hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11088{
11089 char *ptr = &buf[6];
11090 static const char hex_digits[16] =
11091 { '0', '1', '2', '3', '4', '5', '6', '7',
11092 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11093
11094 *ptr = '\0';
11095 *(--ptr) = '\'';
11096 /* Properly format value */
11097 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11098 /*
11099 * Printable, so just show the character, and, if it needs
11100 * to be escaped, escape it.
11101 */
11102 *(--ptr) = value;
11103 if (value == '\\' || value == '\'')
11104 *(--ptr) = '\\';
11105 } else {
11106 /*
11107 * Non-printable; show it as an escape sequence.
11108 */
11109 switch (value) {
11110
11111 case '\0':
11112 /*
11113 * Show a NUL with only one digit.
11114 */
11115 *(--ptr) = '0';
11116 break;
11117
11118 case '\a':
11119 case '\b':
11120 case '\f':
11121 case '\n':
11122 case '\r':
11123 case '\t':
11124 case '\v':
11125 *(--ptr) = value - '\a' + 'a';
11126 break;
11127
11128 default:
11129 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11130
11131 case BASE_OCT:
11132 *(--ptr) = (value & 0x7) + '0';
11133 value >>= 3;
11134 *(--ptr) = (value & 0x7) + '0';
11135 value >>= 3;
11136 *(--ptr) = (value & 0x7) + '0';
11137 break;
11138
11139 case BASE_HEX:
11140 *(--ptr) = hex_digits[value & 0x0F];
11141 value >>= 4;
11142 *(--ptr) = hex_digits[value & 0x0F];
11143 *(--ptr) = 'x';
11144 break;
11145
11146 default:
11147 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11148 }
11149 }
11150 *(--ptr) = '\\';
11151 }
11152 *(--ptr) = '\'';
11153 return ptr;
11154}
11155
11156static const char *
11157hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11158{
11159 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11160 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
))
;
11161
11162 *ptr = '\0';
11163 /* Properly format value */
11164 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11165 case BASE_DEC:
11166 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11167
11168 case BASE_DEC_HEX:
11169 *(--ptr) = ')';
11170 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11171 *(--ptr) = '(';
11172 *(--ptr) = ' ';
11173 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11174 return ptr;
11175
11176 case BASE_OCT:
11177 return oct_to_str_back(ptr, value);
11178
11179 case BASE_HEX:
11180 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11181
11182 case BASE_HEX_DEC:
11183 *(--ptr) = ')';
11184 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11185 *(--ptr) = '(';
11186 *(--ptr) = ' ';
11187 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11188 return ptr;
11189
11190 case BASE_PT_UDP:
11191 case BASE_PT_TCP:
11192 case BASE_PT_DCCP:
11193 case BASE_PT_SCTP:
11194 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11195 display_to_port_type((field_display_e)display), value);
11196 return buf;
11197 case BASE_OUI:
11198 {
11199 uint8_t p_oui[3];
11200 const char *manuf_name;
11201
11202 p_oui[0] = value >> 16 & 0xFF;
11203 p_oui[1] = value >> 8 & 0xFF;
11204 p_oui[2] = value & 0xFF;
11205
11206 /* Attempt an OUI lookup. */
11207 manuf_name = uint_get_manuf_name_if_known(value);
11208 if (manuf_name == NULL((void*)0)) {
11209 /* Could not find an OUI. */
11210 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11211 }
11212 else {
11213 /* Found an address string. */
11214 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11215 }
11216 return buf;
11217 }
11218
11219 default:
11220 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11221 }
11222 return ptr;
11223}
11224
11225static const char *
11226hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11227{
11228 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11229 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
))
;
11230
11231 *ptr = '\0';
11232 /* Properly format value */
11233 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11234 case BASE_DEC:
11235 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11236
11237 case BASE_DEC_HEX:
11238 *(--ptr) = ')';
11239 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11240 *(--ptr) = '(';
11241 *(--ptr) = ' ';
11242 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11243 return ptr;
11244
11245 case BASE_OCT:
11246 return oct64_to_str_back(ptr, value);
11247
11248 case BASE_HEX:
11249 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11250
11251 case BASE_HEX_DEC:
11252 *(--ptr) = ')';
11253 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11254 *(--ptr) = '(';
11255 *(--ptr) = ' ';
11256 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11257 return ptr;
11258
11259 default:
11260 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11261 }
11262
11263 return ptr;
11264}
11265
11266static const char *
11267hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11268{
11269 int display = hfinfo->display;
11270
11271 if (hfinfo->type == FT_FRAMENUM) {
11272 /*
11273 * Frame numbers are always displayed in decimal.
11274 */
11275 display = BASE_DEC;
11276 }
11277
11278 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11279}
11280
11281static const char *
11282hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11283{
11284 int display = hfinfo->display;
11285
11286 if (hfinfo->type == FT_FRAMENUM) {
11287 /*
11288 * Frame numbers are always displayed in decimal.
11289 */
11290 display = BASE_DEC;
11291 }
11292
11293 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11294}
11295
11296static const char *
11297hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11298{
11299 /* Get the underlying BASE_ value */
11300 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11301
11302 return hfinfo_char_value_format_display(display, buf, value);
11303}
11304
11305static const char *
11306hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11307{
11308 /* Get the underlying BASE_ value */
11309 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11310
11311 if (hfinfo->type == FT_FRAMENUM) {
11312 /*
11313 * Frame numbers are always displayed in decimal.
11314 */
11315 display = BASE_DEC;
11316 }
11317
11318 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11319 display = BASE_DEC;
11320 } else if (display == BASE_OUI) {
11321 display = BASE_HEX;
11322 }
11323
11324 switch (display) {
11325 case BASE_NONE:
11326 /* case BASE_DEC: */
11327 case BASE_DEC_HEX:
11328 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11329 case BASE_CUSTOM:
11330 display = BASE_DEC;
11331 break;
11332
11333 /* case BASE_HEX: */
11334 case BASE_HEX_DEC:
11335 display = BASE_HEX;
11336 break;
11337 }
11338
11339 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11340}
11341
11342static const char *
11343hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11344{
11345 /* Get the underlying BASE_ value */
11346 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11347
11348 if (hfinfo->type == FT_FRAMENUM) {
11349 /*
11350 * Frame numbers are always displayed in decimal.
11351 */
11352 display = BASE_DEC;
11353 }
11354
11355 switch (display) {
11356 case BASE_NONE:
11357 /* case BASE_DEC: */
11358 case BASE_DEC_HEX:
11359 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11360 case BASE_CUSTOM:
11361 display = BASE_DEC;
11362 break;
11363
11364 /* case BASE_HEX: */
11365 case BASE_HEX_DEC:
11366 display = BASE_HEX;
11367 break;
11368 }
11369
11370 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11371}
11372
11373static const char *
11374hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11375{
11376 /* Get the underlying BASE_ value */
11377 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11378
11379 return hfinfo_char_value_format_display(display, buf, value);
11380}
11381
11382static const char *
11383hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11384{
11385 /* Get the underlying BASE_ value */
11386 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11387
11388 if (display == BASE_NONE)
11389 return NULL((void*)0);
11390
11391 if (display == BASE_DEC_HEX)
11392 display = BASE_DEC;
11393 if (display == BASE_HEX_DEC)
11394 display = BASE_HEX;
11395
11396 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11397}
11398
11399static const char *
11400hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11401{
11402 /* Get the underlying BASE_ value */
11403 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11404
11405 if (display == BASE_NONE)
11406 return NULL((void*)0);
11407
11408 if (display == BASE_DEC_HEX)
11409 display = BASE_DEC;
11410 if (display == BASE_HEX_DEC)
11411 display = BASE_HEX;
11412
11413 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11414}
11415
11416const char *
11417proto_registrar_get_name(const int n)
11418{
11419 header_field_info *hfinfo;
11420
11421 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", 11421
, __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", 11421
, "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", 11421, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11422 return hfinfo->name;
11423}
11424
11425const char *
11426proto_registrar_get_abbrev(const int n)
11427{
11428 header_field_info *hfinfo;
11429
11430 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", 11430
, __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", 11430
, "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", 11430, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11431 return hfinfo->abbrev;
11432}
11433
11434enum ftenum
11435proto_registrar_get_ftype(const int n)
11436{
11437 header_field_info *hfinfo;
11438
11439 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", 11439
, __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", 11439
, "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", 11439, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11440 return hfinfo->type;
11441}
11442
11443int
11444proto_registrar_get_parent(const int n)
11445{
11446 header_field_info *hfinfo;
11447
11448 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", 11448
, __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", 11448
, "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", 11448, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11449 return hfinfo->parent;
11450}
11451
11452bool_Bool
11453proto_registrar_is_protocol(const int n)
11454{
11455 header_field_info *hfinfo;
11456
11457 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", 11457
, __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", 11457
, "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", 11457, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11458 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11459}
11460
11461/* Returns length of field in packet (not necessarily the length
11462 * in our internal representation, as in the case of IPv4).
11463 * 0 means undeterminable at time of registration
11464 * -1 means the field is not registered. */
11465int
11466proto_registrar_get_length(const int n)
11467{
11468 header_field_info *hfinfo;
11469
11470 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", 11470
, __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", 11470
, "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", 11470, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11471 return ftype_wire_size(hfinfo->type);
11472}
11473
11474/* Looks for a protocol or a field in a proto_tree. Returns true if
11475 * it exists anywhere, or false if it exists nowhere. */
11476bool_Bool
11477proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11478{
11479 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11480
11481 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11482 return true1;
11483 }
11484 else {
11485 return false0;
11486 }
11487}
11488
11489/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11490 * This only works if the hfindex was "primed" before the dissection
11491 * took place, as we just pass back the already-created GPtrArray*.
11492 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11493 * handles that. */
11494GPtrArray *
11495proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11496{
11497 if (!tree)
11498 return NULL((void*)0);
11499
11500 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11501 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11502 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11503 else
11504 return NULL((void*)0);
11505}
11506
11507bool_Bool
11508proto_tracking_interesting_fields(const proto_tree *tree)
11509{
11510 GHashTable *interesting_hfids;
11511
11512 if (!tree)
11513 return false0;
11514
11515 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11516
11517 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11518}
11519
11520/* Helper struct for proto_find_info() and proto_all_finfos() */
11521typedef struct {
11522 GPtrArray *array;
11523 int id;
11524} ffdata_t;
11525
11526/* Helper function for proto_find_info() */
11527static bool_Bool
11528find_finfo(proto_node *node, void * data)
11529{
11530 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11531 if (fi && fi->hfinfo) {
11532 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11533 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11534 }
11535 }
11536
11537 /* Don't stop traversing. */
11538 return false0;
11539}
11540
11541/* Helper function for proto_find_first_info() */
11542static bool_Bool
11543find_first_finfo(proto_node *node, void *data)
11544{
11545 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11546 if (fi && fi->hfinfo) {
11547 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11548 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11549
11550 /* Stop traversing. */
11551 return true1;
11552 }
11553 }
11554
11555 /* Continue traversing. */
11556 return false0;
11557}
11558
11559/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11560* This works on any proto_tree, primed or unprimed, but actually searches
11561* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11562* The caller does need to free the returned GPtrArray with
11563* g_ptr_array_free(<array>, true).
11564*/
11565GPtrArray *
11566proto_find_finfo(proto_tree *tree, const int id)
11567{
11568 ffdata_t ffdata;
11569
11570 ffdata.array = g_ptr_array_new();
11571 ffdata.id = id;
11572
11573 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11574
11575 return ffdata.array;
11576}
11577
11578/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11579* This works on any proto_tree, primed or unprimed, but actually searches
11580* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11581* The caller does need to free the returned GPtrArray with
11582* g_ptr_array_free(<array>, true).
11583*/
11584GPtrArray *
11585proto_find_first_finfo(proto_tree *tree, const int id)
11586{
11587 ffdata_t ffdata;
11588
11589 ffdata.array = g_ptr_array_new();
11590 ffdata.id = id;
11591
11592 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11593
11594 return ffdata.array;
11595}
11596
11597/* Helper function for proto_all_finfos() */
11598static bool_Bool
11599every_finfo(proto_node *node, void * data)
11600{
11601 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11602 if (fi && fi->hfinfo) {
11603 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11604 }
11605
11606 /* Don't stop traversing. */
11607 return false0;
11608}
11609
11610/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11611 * The caller does need to free the returned GPtrArray with
11612 * g_ptr_array_free(<array>, true).
11613 */
11614GPtrArray *
11615proto_all_finfos(proto_tree *tree)
11616{
11617 ffdata_t ffdata;
11618
11619 /* Pre allocate enough space to hold all fields in most cases */
11620 ffdata.array = g_ptr_array_sized_new(512);
11621 ffdata.id = 0;
11622
11623 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11624
11625 return ffdata.array;
11626}
11627
11628
11629typedef struct {
11630 unsigned offset;
11631 field_info *finfo;
11632 tvbuff_t *tvb;
11633} offset_search_t;
11634
11635static bool_Bool
11636check_for_offset(proto_node *node, void * data)
11637{
11638 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11639 offset_search_t *offsearch = (offset_search_t *)data;
11640
11641 /* !fi == the top most container node which holds nothing */
11642 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11643 if (offsearch->offset >= (unsigned) fi->start &&
11644 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11645
11646 offsearch->finfo = fi;
11647 return false0; /* keep traversing */
11648 }
11649 }
11650 return false0; /* keep traversing */
11651}
11652
11653/* Search a proto_tree backwards (from leaves to root) looking for the field
11654 * whose start/length occupies 'offset' */
11655/* XXX - I couldn't find an easy way to search backwards, so I search
11656 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11657 * the one I want to return to the user. This algorithm is inefficient
11658 * and could be re-done, but I'd have to handle all the children and
11659 * siblings of each node myself. When I have more time I'll do that.
11660 * (yeah right) */
11661field_info *
11662proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11663{
11664 offset_search_t offsearch;
11665
11666 offsearch.offset = offset;
11667 offsearch.finfo = NULL((void*)0);
11668 offsearch.tvb = tvb;
11669
11670 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11671
11672 return offsearch.finfo;
11673}
11674
11675typedef struct {
11676 int length;
11677 char *buf;
11678} decoded_data_t;
11679
11680static bool_Bool
11681check_for_undecoded(proto_node *node, void * data)
11682{
11683 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11684 decoded_data_t* decoded = (decoded_data_t*)data;
11685 int i;
11686 unsigned byte;
11687 unsigned bit;
11688
11689 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11690 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11691 byte = i / 8;
11692 bit = i % 8;
11693 decoded->buf[byte] |= (1 << bit);
11694 }
11695 }
11696
11697 return false0;
11698}
11699
11700char*
11701proto_find_undecoded_data(proto_tree *tree, unsigned length)
11702{
11703 decoded_data_t decoded;
11704 decoded.length = length;
11705 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11706
11707 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11708 return decoded.buf;
11709}
11710
11711/* Dumps the protocols in the registration database to stdout. An independent
11712 * program can take this output and format it into nice tables or HTML or
11713 * whatever.
11714 *
11715 * There is one record per line. The fields are tab-delimited.
11716 *
11717 * Field 1 = protocol name
11718 * Field 2 = protocol short name
11719 * Field 3 = protocol filter name
11720 * Field 4 = protocol enabled
11721 * Field 5 = protocol enabled by default
11722 * Field 6 = protocol can toggle
11723 */
11724void
11725proto_registrar_dump_protocols(void)
11726{
11727 protocol_t *protocol;
11728 int i;
11729 void *cookie = NULL((void*)0);
11730
11731
11732 i = proto_get_first_protocol(&cookie);
11733 while (i != -1) {
11734 protocol = find_protocol_by_id(i);
11735 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11736 protocol->name,
11737 protocol->short_name,
11738 protocol->filter_name,
11739 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11740 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11741 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11742 i = proto_get_next_protocol(&cookie);
11743 }
11744}
11745
11746/* Dumps the value_strings, extended value string headers, range_strings
11747 * or true/false strings for fields that have them.
11748 * There is one record per line. Fields are tab-delimited.
11749 * There are four types of records: Value String, Extended Value String Header,
11750 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11751 * the type of record.
11752 *
11753 * Note that a record will be generated only if the value_string,... is referenced
11754 * in a registered hfinfo entry.
11755 *
11756 *
11757 * Value Strings
11758 * -------------
11759 * Field 1 = 'V'
11760 * Field 2 = Field abbreviation to which this value string corresponds
11761 * Field 3 = Integer value
11762 * Field 4 = String
11763 *
11764 * Extended Value String Headers
11765 * -----------------------------
11766 * Field 1 = 'E'
11767 * Field 2 = Field abbreviation to which this extended value string header corresponds
11768 * Field 3 = Extended Value String "Name"
11769 * Field 4 = Number of entries in the associated value_string array
11770 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11771 *
11772 * Range Strings
11773 * -------------
11774 * Field 1 = 'R'
11775 * Field 2 = Field abbreviation to which this range string corresponds
11776 * Field 3 = Integer value: lower bound
11777 * Field 4 = Integer value: upper bound
11778 * Field 5 = String
11779 *
11780 * True/False Strings
11781 * ------------------
11782 * Field 1 = 'T'
11783 * Field 2 = Field abbreviation to which this true/false string corresponds
11784 * Field 3 = True String
11785 * Field 4 = False String
11786 */
11787void
11788proto_registrar_dump_values(void)
11789{
11790 header_field_info *hfinfo;
11791 int i, len, vi;
11792 const value_string *vals;
11793 const val64_string *vals64;
11794 const range_string *range;
11795 const true_false_string *tfs;
11796 const unit_name_string *units;
11797
11798 len = gpa_hfinfo.len;
11799 for (i = 0; i < len ; i++) {
11800 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11801 continue; /* This is a deregistered protocol or field */
11802
11803 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", 11803
, __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", 11803
, "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", 11803, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11804
11805 if (hfinfo->id == hf_text_only) {
11806 continue;
11807 }
11808
11809 /* ignore protocols */
11810 if (proto_registrar_is_protocol(i)) {
11811 continue;
11812 }
11813 /* process header fields */
11814#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11815 /*
11816 * If this field isn't at the head of the list of
11817 * fields with this name, skip this field - all
11818 * fields with the same name are really just versions
11819 * of the same field stored in different bits, and
11820 * should have the same type/radix/value list, and
11821 * just differ in their bit masks. (If a field isn't
11822 * a bitfield, but can be, say, 1 or 2 bytes long,
11823 * it can just be made FT_UINT16, meaning the
11824 * *maximum* length is 2 bytes, and be used
11825 * for all lengths.)
11826 */
11827 if (hfinfo->same_name_prev_id != -1)
11828 continue;
11829#endif
11830 vals = NULL((void*)0);
11831 vals64 = NULL((void*)0);
11832 range = NULL((void*)0);
11833 tfs = NULL((void*)0);
11834 units = NULL((void*)0);
11835
11836 if (hfinfo->strings != NULL((void*)0)) {
11837 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11838 (hfinfo->type == FT_CHAR ||
11839 hfinfo->type == FT_UINT8 ||
11840 hfinfo->type == FT_UINT16 ||
11841 hfinfo->type == FT_UINT24 ||
11842 hfinfo->type == FT_UINT32 ||
11843 hfinfo->type == FT_UINT40 ||
11844 hfinfo->type == FT_UINT48 ||
11845 hfinfo->type == FT_UINT56 ||
11846 hfinfo->type == FT_UINT64 ||
11847 hfinfo->type == FT_INT8 ||
11848 hfinfo->type == FT_INT16 ||
11849 hfinfo->type == FT_INT24 ||
11850 hfinfo->type == FT_INT32 ||
11851 hfinfo->type == FT_INT40 ||
11852 hfinfo->type == FT_INT48 ||
11853 hfinfo->type == FT_INT56 ||
11854 hfinfo->type == FT_INT64 ||
11855 hfinfo->type == FT_FLOAT ||
11856 hfinfo->type == FT_DOUBLE)) {
11857
11858 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11859 range = (const range_string *)hfinfo->strings;
11860 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11861 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11862 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11863 } else {
11864 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11865 }
11866 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11867 vals64 = (const val64_string *)hfinfo->strings;
11868 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11869 units = (const unit_name_string *)hfinfo->strings;
11870 } else {
11871 vals = (const value_string *)hfinfo->strings;
11872 }
11873 }
11874 else if (hfinfo->type == FT_BOOLEAN) {
11875 tfs = (const struct true_false_string *)hfinfo->strings;
11876 }
11877 }
11878
11879 /* Print value strings? */
11880 if (vals) {
11881 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11882 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11883 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11884 if (!val64_string_ext_validate(vse_p)) {
11885 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11885, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11886 continue;
11887 }
11888 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11889 printf("E\t%s\t%u\t%s\t%s\n",
11890 hfinfo->abbrev,
11891 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11892 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11893 val64_string_ext_match_type_str(vse_p));
11894 } else {
11895 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11896 if (!value_string_ext_validate(vse_p)) {
11897 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11897, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11898 continue;
11899 }
11900 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11901 printf("E\t%s\t%u\t%s\t%s\n",
11902 hfinfo->abbrev,
11903 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11904 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11905 value_string_ext_match_type_str(vse_p));
11906 }
11907 }
11908 vi = 0;
11909 while (vals[vi].strptr) {
11910 /* Print in the proper base */
11911 if (hfinfo->type == FT_CHAR) {
11912 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11913 printf("V\t%s\t'%c'\t%s\n",
11914 hfinfo->abbrev,
11915 vals[vi].value,
11916 vals[vi].strptr);
11917 } else {
11918 if (hfinfo->display == BASE_HEX) {
11919 printf("V\t%s\t'\\x%02x'\t%s\n",
11920 hfinfo->abbrev,
11921 vals[vi].value,
11922 vals[vi].strptr);
11923 }
11924 else {
11925 printf("V\t%s\t'\\%03o'\t%s\n",
11926 hfinfo->abbrev,
11927 vals[vi].value,
11928 vals[vi].strptr);
11929 }
11930 }
11931 } else {
11932 if (hfinfo->display == BASE_HEX) {
11933 printf("V\t%s\t0x%x\t%s\n",
11934 hfinfo->abbrev,
11935 vals[vi].value,
11936 vals[vi].strptr);
11937 }
11938 else {
11939 printf("V\t%s\t%u\t%s\n",
11940 hfinfo->abbrev,
11941 vals[vi].value,
11942 vals[vi].strptr);
11943 }
11944 }
11945 vi++;
11946 }
11947 }
11948 else if (vals64) {
11949 vi = 0;
11950 while (vals64[vi].strptr) {
11951 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11952 hfinfo->abbrev,
11953 vals64[vi].value,
11954 vals64[vi].strptr);
11955 vi++;
11956 }
11957 }
11958
11959 /* print range strings? */
11960 else if (range) {
11961 vi = 0;
11962 while (range[vi].strptr) {
11963 /* Print in the proper base */
11964 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
11965 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
11966 hfinfo->abbrev,
11967 range[vi].value_min,
11968 range[vi].value_max,
11969 range[vi].strptr);
11970 }
11971 else {
11972 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
11973 hfinfo->abbrev,
11974 range[vi].value_min,
11975 range[vi].value_max,
11976 range[vi].strptr);
11977 }
11978 vi++;
11979 }
11980 }
11981
11982 /* Print true/false strings? */
11983 else if (tfs) {
11984 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
11985 tfs->true_string, tfs->false_string);
11986 }
11987 /* Print unit strings? */
11988 else if (units) {
11989 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
11990 units->singular, units->plural ? units->plural : "(no plural)");
11991 }
11992 }
11993}
11994
11995/* Prints the number of registered fields.
11996 * Useful for determining an appropriate value for
11997 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
11998 *
11999 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12000 * the number of fields, true otherwise.
12001 */
12002bool_Bool
12003proto_registrar_dump_fieldcount(void)
12004{
12005 uint32_t i;
12006 header_field_info *hfinfo;
12007 uint32_t deregistered_count = 0;
12008 uint32_t same_name_count = 0;
12009 uint32_t protocol_count = 0;
12010
12011 for (i = 0; i < gpa_hfinfo.len; i++) {
12012 if (gpa_hfinfo.hfi[i] == NULL((void*)0)) {
12013 deregistered_count++;
12014 continue; /* This is a deregistered protocol or header field */
12015 }
12016
12017 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", 12017
, __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", 12017
, "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", 12017, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12018
12019 if (proto_registrar_is_protocol(i))
12020 protocol_count++;
12021
12022 if (hfinfo->same_name_prev_id != -1)
12023 same_name_count++;
12024 }
12025
12026 printf("There are %u header fields registered, of which:\n"
12027 "\t%u are deregistered\n"
12028 "\t%u are protocols\n"
12029 "\t%u have the same name as another field\n\n",
12030 gpa_hfinfo.len, deregistered_count, protocol_count,
12031 same_name_count);
12032
12033 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12034 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12035 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12036 "\n");
12037
12038 printf("The header field table consumes %u KiB of memory.\n",
12039 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12040 printf("The fields themselves consume %u KiB of memory.\n",
12041 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12042
12043 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12044}
12045
12046static void
12047elastic_add_base_mapping(json_dumper *dumper)
12048{
12049 json_dumper_set_member_name(dumper, "index_patterns");
12050 json_dumper_begin_array(dumper);
12051 // The index names from write_json_index() in print.c
12052 json_dumper_value_string(dumper, "packets-*");
12053 json_dumper_end_array(dumper);
12054
12055 json_dumper_set_member_name(dumper, "settings");
12056 json_dumper_begin_object(dumper);
12057 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12058 json_dumper_value_anyf(dumper, "%d", 1000000);
12059 json_dumper_end_object(dumper);
12060}
12061
12062static char*
12063ws_type_to_elastic(unsigned type)
12064{
12065 switch(type) {
12066 case FT_INT8:
12067 return "byte";
12068 case FT_UINT8:
12069 case FT_INT16:
12070 return "short";
12071 case FT_UINT16:
12072 case FT_INT32:
12073 case FT_UINT24:
12074 case FT_INT24:
12075 return "integer";
12076 case FT_FRAMENUM:
12077 case FT_UINT32:
12078 case FT_UINT40:
12079 case FT_UINT48:
12080 case FT_UINT56:
12081 case FT_INT40:
12082 case FT_INT48:
12083 case FT_INT56:
12084 case FT_INT64:
12085 return "long";
12086 case FT_UINT64:
12087 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12088 case FT_FLOAT:
12089 return "float";
12090 case FT_DOUBLE:
12091 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12092 return "double";
12093 case FT_IPv6:
12094 case FT_IPv4:
12095 return "ip";
12096 case FT_ABSOLUTE_TIME:
12097 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12098 case FT_BOOLEAN:
12099 return "boolean";
12100 default:
12101 return NULL((void*)0);
12102 }
12103}
12104
12105static char*
12106dot_to_underscore(char* str)
12107{
12108 unsigned i;
12109 for (i = 0; i < strlen(str); i++) {
12110 if (str[i] == '.')
12111 str[i] = '_';
12112 }
12113 return str;
12114}
12115
12116/* Dumps a mapping file for ElasticSearch
12117 * This is the v1 (legacy) _template API.
12118 * At some point it may need to be updated with the composable templates
12119 * introduced in Elasticsearch 7.8 (_index_template)
12120 */
12121void
12122proto_registrar_dump_elastic(const char* filter)
12123{
12124 header_field_info *hfinfo;
12125 header_field_info *parent_hfinfo;
12126 unsigned i;
12127 bool_Bool open_object = true1;
12128 const char* prev_proto = NULL((void*)0);
12129 char* str;
12130 char** protos = NULL((void*)0);
12131 char* proto;
12132 bool_Bool found;
12133 unsigned j;
12134 char* type;
12135 char* prev_item = NULL((void*)0);
12136
12137 /* We have filtering protocols. Extract them. */
12138 if (filter) {
12139 protos = g_strsplit(filter, ",", -1);
12140 }
12141
12142 /*
12143 * To help tracking down the json tree, objects have been appended with a comment:
12144 * n.label -> where n is the indentation level and label the name of the object
12145 */
12146
12147 json_dumper dumper = {
12148 .output_file = stdoutstdout,
12149 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12150 };
12151 json_dumper_begin_object(&dumper); // 1.root
12152 elastic_add_base_mapping(&dumper);
12153
12154 json_dumper_set_member_name(&dumper, "mappings");
12155 json_dumper_begin_object(&dumper); // 2.mappings
12156
12157 json_dumper_set_member_name(&dumper, "properties");
12158 json_dumper_begin_object(&dumper); // 3.properties
12159 json_dumper_set_member_name(&dumper, "timestamp");
12160 json_dumper_begin_object(&dumper); // 4.timestamp
12161 json_dumper_set_member_name(&dumper, "type");
12162 json_dumper_value_string(&dumper, "date");
12163 json_dumper_end_object(&dumper); // 4.timestamp
12164
12165 json_dumper_set_member_name(&dumper, "layers");
12166 json_dumper_begin_object(&dumper); // 4.layers
12167 json_dumper_set_member_name(&dumper, "properties");
12168 json_dumper_begin_object(&dumper); // 5.properties
12169
12170 for (i = 0; i < gpa_hfinfo.len; i++) {
12171 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12172 continue; /* This is a deregistered protocol or header field */
12173
12174 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", 12174
, __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", 12174
, "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", 12174, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12175
12176 /*
12177 * Skip the pseudo-field for "proto_tree_add_text()" since
12178 * we don't want it in the list of filterable protocols.
12179 */
12180 if (hfinfo->id == hf_text_only)
12181 continue;
12182
12183 if (!proto_registrar_is_protocol(i)) {
12184 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", 12184
, __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", 12184
, "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", 12184
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12185
12186 /*
12187 * Skip the field if filter protocols have been set and this one's
12188 * parent is not listed.
12189 */
12190 if (protos) {
12191 found = false0;
12192 j = 0;
12193 proto = protos[0];
12194 while(proto) {
12195 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12196 found = true1;
12197 break;
12198 }
12199 j++;
12200 proto = protos[j];
12201 }
12202 if (!found)
12203 continue;
12204 }
12205
12206 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12207 json_dumper_end_object(&dumper); // 7.properties
12208 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12209 open_object = true1;
12210 }
12211
12212 prev_proto = parent_hfinfo->abbrev;
12213
12214 if (open_object) {
12215 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12216 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12217 json_dumper_set_member_name(&dumper, "properties");
12218 json_dumper_begin_object(&dumper); // 7.properties
12219 open_object = false0;
12220 }
12221 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12222 type = ws_type_to_elastic(hfinfo->type);
12223 /* when type is NULL, we have the default mapping: string */
12224 if (type) {
12225 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12226 dot_to_underscore(str);
12227 if (g_strcmp0(prev_item, str)) {
12228 json_dumper_set_member_name(&dumper, str);
12229 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12230 json_dumper_set_member_name(&dumper, "type");
12231 json_dumper_value_string(&dumper, type);
12232 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12233 }
12234 g_free(prev_item);
12235 prev_item = str;
12236 }
12237 }
12238 }
12239 g_free(prev_item);
12240
12241 if (prev_proto) {
12242 json_dumper_end_object(&dumper); // 7.properties
12243 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12244 }
12245
12246 json_dumper_end_object(&dumper); // 5.properties
12247 json_dumper_end_object(&dumper); // 4.layers
12248 json_dumper_end_object(&dumper); // 3.properties
12249 json_dumper_end_object(&dumper); // 2.mappings
12250 json_dumper_end_object(&dumper); // 1.root
12251 bool_Bool ret = json_dumper_finish(&dumper);
12252 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12252, "ret"))))
;
12253
12254 g_strfreev(protos);
12255}
12256
12257/* Dumps the contents of the registration database to stdout. An independent
12258 * program can take this output and format it into nice tables or HTML or
12259 * whatever.
12260 *
12261 * There is one record per line. Each record is either a protocol or a header
12262 * field, differentiated by the first field. The fields are tab-delimited.
12263 *
12264 * Protocols
12265 * ---------
12266 * Field 1 = 'P'
12267 * Field 2 = descriptive protocol name
12268 * Field 3 = protocol abbreviation
12269 *
12270 * Header Fields
12271 * -------------
12272 * Field 1 = 'F'
12273 * Field 2 = descriptive field name
12274 * Field 3 = field abbreviation
12275 * Field 4 = type ( textual representation of the ftenum type )
12276 * Field 5 = parent protocol abbreviation
12277 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12278 * Field 7 = bitmask: format: hex: 0x....
12279 * Field 8 = blurb describing field
12280 */
12281void
12282proto_registrar_dump_fields(void)
12283{
12284 header_field_info *hfinfo, *parent_hfinfo;
12285 int i, len;
12286 const char *enum_name;
12287 const char *base_name;
12288 const char *blurb;
12289 char width[5];
12290
12291 len = gpa_hfinfo.len;
12292 for (i = 0; i < len ; i++) {
12293 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12294 continue; /* This is a deregistered protocol or header field */
12295
12296 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", 12296
, __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", 12296
, "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", 12296, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12297
12298 /*
12299 * Skip the pseudo-field for "proto_tree_add_text()" since
12300 * we don't want it in the list of filterable fields.
12301 */
12302 if (hfinfo->id == hf_text_only)
12303 continue;
12304
12305 /* format for protocols */
12306 if (proto_registrar_is_protocol(i)) {
12307 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12308 }
12309 /* format for header fields */
12310 else {
12311 /*
12312 * If this field isn't at the head of the list of
12313 * fields with this name, skip this field - all
12314 * fields with the same name are really just versions
12315 * of the same field stored in different bits, and
12316 * should have the same type/radix/value list, and
12317 * just differ in their bit masks. (If a field isn't
12318 * a bitfield, but can be, say, 1 or 2 bytes long,
12319 * it can just be made FT_UINT16, meaning the
12320 * *maximum* length is 2 bytes, and be used
12321 * for all lengths.)
12322 */
12323 if (hfinfo->same_name_prev_id != -1)
12324 continue;
12325
12326 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", 12326
, __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", 12326
, "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", 12326
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12327
12328 enum_name = ftype_name(hfinfo->type);
12329 base_name = "";
12330
12331 if (hfinfo->type == FT_CHAR ||
12332 hfinfo->type == FT_UINT8 ||
12333 hfinfo->type == FT_UINT16 ||
12334 hfinfo->type == FT_UINT24 ||
12335 hfinfo->type == FT_UINT32 ||
12336 hfinfo->type == FT_UINT40 ||
12337 hfinfo->type == FT_UINT48 ||
12338 hfinfo->type == FT_UINT56 ||
12339 hfinfo->type == FT_UINT64 ||
12340 hfinfo->type == FT_INT8 ||
12341 hfinfo->type == FT_INT16 ||
12342 hfinfo->type == FT_INT24 ||
12343 hfinfo->type == FT_INT32 ||
12344 hfinfo->type == FT_INT40 ||
12345 hfinfo->type == FT_INT48 ||
12346 hfinfo->type == FT_INT56 ||
12347 hfinfo->type == FT_INT64) {
12348
12349 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12350 case BASE_NONE:
12351 case BASE_DEC:
12352 case BASE_HEX:
12353 case BASE_OCT:
12354 case BASE_DEC_HEX:
12355 case BASE_HEX_DEC:
12356 case BASE_CUSTOM:
12357 case BASE_PT_UDP:
12358 case BASE_PT_TCP:
12359 case BASE_PT_DCCP:
12360 case BASE_PT_SCTP:
12361 case BASE_OUI:
12362 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12363 break;
12364 default:
12365 base_name = "????";
12366 break;
12367 }
12368 } else if (hfinfo->type == FT_BOOLEAN) {
12369 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12370 snprintf(width, sizeof(width), "%d", hfinfo->display);
12371 base_name = width;
12372 }
12373
12374 blurb = hfinfo->blurb;
12375 if (blurb == NULL((void*)0))
12376 blurb = "";
12377 else if (strlen(blurb) == 0)
12378 blurb = "\"\"";
12379
12380 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12381 hfinfo->name, hfinfo->abbrev, enum_name,
12382 parent_hfinfo->abbrev, base_name,
12383 hfinfo->bitmask, blurb);
12384 }
12385 }
12386}
12387
12388/* Dumps all abbreviated field and protocol completions of the given string to
12389 * stdout. An independent program may use this for command-line tab completion
12390 * of fields.
12391 */
12392bool_Bool
12393proto_registrar_dump_field_completions(const char *prefix)
12394{
12395 header_field_info *hfinfo;
12396 int i, len;
12397 size_t prefix_len;
12398 bool_Bool matched = false0;
12399
12400 prefix_len = strlen(prefix);
12401 len = gpa_hfinfo.len;
12402 for (i = 0; i < len ; i++) {
12403 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12404 continue; /* This is a deregistered protocol or header field */
12405
12406 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", 12406
, __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", 12406
, "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", 12406, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12407
12408 /*
12409 * Skip the pseudo-field for "proto_tree_add_text()" since
12410 * we don't want it in the list of filterable fields.
12411 */
12412 if (hfinfo->id == hf_text_only)
12413 continue;
12414
12415 /* format for protocols */
12416 if (proto_registrar_is_protocol(i)) {
12417 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12418 matched = true1;
12419 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12420 }
12421 }
12422 /* format for header fields */
12423 else {
12424 /*
12425 * If this field isn't at the head of the list of
12426 * fields with this name, skip this field - all
12427 * fields with the same name are really just versions
12428 * of the same field stored in different bits, and
12429 * should have the same type/radix/value list, and
12430 * just differ in their bit masks. (If a field isn't
12431 * a bitfield, but can be, say, 1 or 2 bytes long,
12432 * it can just be made FT_UINT16, meaning the
12433 * *maximum* length is 2 bytes, and be used
12434 * for all lengths.)
12435 */
12436 if (hfinfo->same_name_prev_id != -1)
12437 continue;
12438
12439 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12440 matched = true1;
12441 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12442 }
12443 }
12444 }
12445 return matched;
12446}
12447
12448/* Dumps field types and descriptive names to stdout. An independent
12449 * program can take this output and format it into nice tables or HTML or
12450 * whatever.
12451 *
12452 * There is one record per line. The fields are tab-delimited.
12453 *
12454 * Field 1 = field type name, e.g. FT_UINT8
12455 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12456 */
12457void
12458proto_registrar_dump_ftypes(void)
12459{
12460 int fte;
12461
12462 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12463 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12464 }
12465}
12466
12467/* This function indicates whether it's possible to construct a
12468 * "match selected" display filter string for the specified field,
12469 * returns an indication of whether it's possible, and, if it's
12470 * possible and "filter" is non-null, constructs the filter and
12471 * sets "*filter" to point to it.
12472 * You do not need to [g_]free() this string since it will be automatically
12473 * freed once the next packet is dissected.
12474 */
12475static bool_Bool
12476construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12477 char **filter)
12478{
12479 const header_field_info *hfinfo;
12480 char *ptr;
12481 int buf_len;
12482 int i;
12483 int start, length, length_remaining;
12484 uint8_t c;
12485
12486 if (!finfo)
12487 return false0;
12488
12489 hfinfo = finfo->hfinfo;
12490 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12490, "hfinfo"))))
;
12491
12492 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12493 * then "the numeric value ... is not used when preparing
12494 * filters for the field in question." If it's any other
12495 * base, we'll generate the filter normally (which will
12496 * be numeric, even though the human-readable string does
12497 * work for filtering.)
12498 *
12499 * XXX - It might be nice to use fvalue_to_string_repr() in
12500 * "proto_item_fill_label()" as well, although, there, you'd
12501 * have to deal with the base *and* with resolved values for
12502 * addresses.
12503 *
12504 * Perhaps in addition to taking the repr type (DISPLAY
12505 * or DFILTER) and the display (base), fvalue_to_string_repr()
12506 * should have the the "strings" values in the header_field_info
12507 * structure for the field as a parameter, so it can have
12508 * if the field is Boolean or an enumerated integer type,
12509 * the tables used to generate human-readable values.
12510 */
12511 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12512 const char *str = NULL((void*)0);
12513
12514 switch (hfinfo->type) {
12515
12516 case FT_INT8:
12517 case FT_INT16:
12518 case FT_INT24:
12519 case FT_INT32:
12520 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12521 break;
12522
12523 case FT_CHAR:
12524 case FT_UINT8:
12525 case FT_UINT16:
12526 case FT_UINT24:
12527 case FT_UINT32:
12528 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12529 break;
12530
12531 default:
12532 break;
12533 }
12534
12535 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12536 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12537 return true1;
12538 }
12539 }
12540
12541 switch (hfinfo->type) {
12542
12543 case FT_PROTOCOL:
12544 if (filter != NULL((void*)0))
12545 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12546 break;
12547
12548 case FT_NONE:
12549 /*
12550 * If the length is 0, just match the name of the
12551 * field.
12552 *
12553 * (Also check for negative values, just in case,
12554 * as we'll cast it to an unsigned value later.)
12555 */
12556 length = finfo->length;
12557 if (length == 0) {
12558 if (filter != NULL((void*)0))
12559 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12560 break;
12561 }
12562 if (length < 0)
12563 return false0;
12564
12565 /*
12566 * This doesn't have a value, so we'd match
12567 * on the raw bytes at this address.
12568 *
12569 * Should we be allowed to access to the raw bytes?
12570 * If "edt" is NULL, the answer is "no".
12571 */
12572 if (edt == NULL((void*)0))
12573 return false0;
12574
12575 /*
12576 * Is this field part of the raw frame tvbuff?
12577 * If not, we can't use "frame[N:M]" to match
12578 * it.
12579 *
12580 * XXX - should this be frame-relative, or
12581 * protocol-relative?
12582 *
12583 * XXX - does this fallback for non-registered
12584 * fields even make sense?
12585 */
12586 if (finfo->ds_tvb != edt->tvb)
12587 return false0; /* you lose */
12588
12589 /*
12590 * Don't go past the end of that tvbuff.
12591 */
12592 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12593 if (length > length_remaining)
12594 length = length_remaining;
12595 if (length <= 0)
12596 return false0;
12597
12598 if (filter != NULL((void*)0)) {
12599 start = finfo->start;
12600 buf_len = 32 + length * 3;
12601 *filter = (char *)wmem_alloc0(NULL((void*)0), buf_len);
12602 ptr = *filter;
12603
12604 ptr += snprintf(ptr, buf_len-(ptr-*filter),
12605 "frame[%d:%d] == ", finfo->start, length);
12606 for (i=0; i<length; i++) {
12607 c = tvb_get_uint8(finfo->ds_tvb, start);
12608 start++;
12609 if (i == 0 ) {
12610 ptr += snprintf(ptr, buf_len-(ptr-*filter), "%02x", c);
12611 }
12612 else {
12613 ptr += snprintf(ptr, buf_len-(ptr-*filter), ":%02x", c);
12614 }
12615 }
12616 }
12617 break;
12618
12619 /* By default, use the fvalue's "to_string_repr" method. */
12620 default:
12621 if (filter != NULL((void*)0)) {
12622 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12623 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12624 wmem_free(NULL((void*)0), str);
12625 }
12626 break;
12627 }
12628
12629 return true1;
12630}
12631
12632/*
12633 * Returns true if we can do a "match selected" on the field, false
12634 * otherwise.
12635 */
12636bool_Bool
12637proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12638{
12639 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12640}
12641
12642/* This function attempts to construct a "match selected" display filter
12643 * string for the specified field; if it can do so, it returns a pointer
12644 * to the string, otherwise it returns NULL.
12645 *
12646 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12647 */
12648char *
12649proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12650{
12651 char *filter = NULL((void*)0);
12652
12653 if (!construct_match_selected_string(finfo, edt, &filter))
12654 {
12655 wmem_free(NULL((void*)0), filter);
12656 return NULL((void*)0);
12657 }
12658 return filter;
12659}
12660
12661/* This function is common code for all proto_tree_add_bitmask... functions.
12662 */
12663
12664static bool_Bool
12665proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12666 const int len, const int ett, int * const *fields,
12667 const int flags, bool_Bool first,
12668 bool_Bool use_parent_tree,
12669 proto_tree* tree, uint64_t value)
12670{
12671 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12672 uint64_t bitmask = 0;
12673 uint64_t tmpval;
12674 header_field_info *hf;
12675 uint32_t integer32;
12676 int bit_offset;
12677 int no_of_bits;
12678
12679 if (!*fields)
12680 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"
)
;
12681
12682 if (len < 0 || len > 8)
12683 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12684 /**
12685 * packet-frame.c uses len=0 since the value is taken from the packet
12686 * metadata, not the packet bytes. In that case, assume that all bits
12687 * in the provided value are valid.
12688 */
12689 if (len > 0) {
12690 available_bits >>= (8 - (unsigned)len)*8;
12691 }
12692
12693 if (use_parent_tree == false0)
12694 tree = proto_item_add_subtree(item, ett);
12695
12696 while (*fields) {
12697 uint64_t present_bits;
12698 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", 12698, __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", 12698
, "**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", 12698, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12699 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", 12699
, "hf->bitmask != 0", hf->abbrev))))
;
12700
12701 bitmask |= hf->bitmask;
12702
12703 /* Skip fields that aren't fully present */
12704 present_bits = available_bits & hf->bitmask;
12705 if (present_bits != hf->bitmask) {
12706 fields++;
12707 continue;
12708 }
12709
12710 switch (hf->type) {
12711 case FT_CHAR:
12712 case FT_UINT8:
12713 case FT_UINT16:
12714 case FT_UINT24:
12715 case FT_UINT32:
12716 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12717 break;
12718
12719 case FT_INT8:
12720 case FT_INT16:
12721 case FT_INT24:
12722 case FT_INT32:
12723 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12724 break;
12725
12726 case FT_UINT40:
12727 case FT_UINT48:
12728 case FT_UINT56:
12729 case FT_UINT64:
12730 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12731 break;
12732
12733 case FT_INT40:
12734 case FT_INT48:
12735 case FT_INT56:
12736 case FT_INT64:
12737 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12738 break;
12739
12740 case FT_BOOLEAN:
12741 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12742 break;
12743
12744 default:
12745 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))
12746 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))
12747 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))
12748 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))
;
12749 break;
12750 }
12751 if (flags & BMT_NO_APPEND0x01) {
12752 fields++;
12753 continue;
12754 }
12755 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12756
12757 /* XXX: README.developer and the comments have always defined
12758 * BMT_NO_INT as "only boolean flags are added to the title /
12759 * don't add non-boolean (integral) fields", but the
12760 * implementation has always added BASE_CUSTOM and fields with
12761 * value_strings, though not fields with unit_strings.
12762 * Possibly this is because some dissectors use a FT_UINT8
12763 * with a value_string for fields that should be a FT_BOOLEAN.
12764 */
12765 switch (hf->type) {
12766 case FT_CHAR:
12767 if (hf->display == BASE_CUSTOM) {
12768 char lbl[ITEM_LABEL_LENGTH240];
12769 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12770
12771 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12771, "fmtfunc"))))
;
12772 fmtfunc(lbl, (uint32_t) tmpval);
12773 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12774 hf->name, lbl);
12775 first = false0;
12776 }
12777 else if (hf->strings) {
12778 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12779 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12780 first = false0;
12781 }
12782 else if (!(flags & BMT_NO_INT0x02)) {
12783 char buf[32];
12784 const char *out;
12785
12786 if (!first) {
12787 proto_item_append_text(item, ", ");
12788 }
12789
12790 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12791 proto_item_append_text(item, "%s: %s", hf->name, out);
12792 first = false0;
12793 }
12794
12795 break;
12796
12797 case FT_UINT8:
12798 case FT_UINT16:
12799 case FT_UINT24:
12800 case FT_UINT32:
12801 if (hf->display == BASE_CUSTOM) {
12802 char lbl[ITEM_LABEL_LENGTH240];
12803 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12804
12805 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12805, "fmtfunc"))))
;
12806 fmtfunc(lbl, (uint32_t) tmpval);
12807 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12808 hf->name, lbl);
12809 first = false0;
12810 }
12811 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12812 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12813 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12814 first = false0;
12815 }
12816 else if (!(flags & BMT_NO_INT0x02)) {
12817 char buf[NUMBER_LABEL_LENGTH80];
12818 const char *out = NULL((void*)0);
12819
12820 if (!first) {
12821 proto_item_append_text(item, ", ");
12822 }
12823
12824 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12825 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12826 }
12827 if (out == NULL((void*)0)) {
12828 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12829 }
12830 proto_item_append_text(item, "%s: %s", hf->name, out);
12831 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12832 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12833 }
12834 first = false0;
12835 }
12836
12837 break;
12838
12839 case FT_INT8:
12840 case FT_INT16:
12841 case FT_INT24:
12842 case FT_INT32:
12843 integer32 = (uint32_t) tmpval;
12844 if (hf->bitmask) {
12845 no_of_bits = ws_count_ones(hf->bitmask);
12846 integer32 = ws_sign_ext32(integer32, no_of_bits);
12847 }
12848 if (hf->display == BASE_CUSTOM) {
12849 char lbl[ITEM_LABEL_LENGTH240];
12850 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12851
12852 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12852, "fmtfunc"))))
;
12853 fmtfunc(lbl, (int32_t) integer32);
12854 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12855 hf->name, lbl);
12856 first = false0;
12857 }
12858 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12859 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12860 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12861 first = false0;
12862 }
12863 else if (!(flags & BMT_NO_INT0x02)) {
12864 char buf[NUMBER_LABEL_LENGTH80];
12865 const char *out = NULL((void*)0);
12866
12867 if (!first) {
12868 proto_item_append_text(item, ", ");
12869 }
12870
12871 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12872 out = hf_try_val_to_str((int32_t) integer32, hf);
12873 }
12874 if (out == NULL((void*)0)) {
12875 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12876 }
12877 proto_item_append_text(item, "%s: %s", hf->name, out);
12878 if (hf->display & BASE_UNIT_STRING0x00001000) {
12879 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12880 }
12881 first = false0;
12882 }
12883
12884 break;
12885
12886 case FT_UINT40:
12887 case FT_UINT48:
12888 case FT_UINT56:
12889 case FT_UINT64:
12890 if (hf->display == BASE_CUSTOM) {
12891 char lbl[ITEM_LABEL_LENGTH240];
12892 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12893
12894 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12894, "fmtfunc"))))
;
12895 fmtfunc(lbl, tmpval);
12896 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12897 hf->name, lbl);
12898 first = false0;
12899 }
12900 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12901 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12902 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12903 first = false0;
12904 }
12905 else if (!(flags & BMT_NO_INT0x02)) {
12906 char buf[NUMBER_LABEL_LENGTH80];
12907 const char *out = NULL((void*)0);
12908
12909 if (!first) {
12910 proto_item_append_text(item, ", ");
12911 }
12912
12913 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12914 out = hf_try_val64_to_str(tmpval, hf);
12915 }
12916 if (out == NULL((void*)0)) {
12917 out = hfinfo_number_value_format64(hf, buf, tmpval);
12918 }
12919 proto_item_append_text(item, "%s: %s", hf->name, out);
12920 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12921 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12922 }
12923 first = false0;
12924 }
12925
12926 break;
12927
12928 case FT_INT40:
12929 case FT_INT48:
12930 case FT_INT56:
12931 case FT_INT64:
12932 if (hf->bitmask) {
12933 no_of_bits = ws_count_ones(hf->bitmask);
12934 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12935 }
12936 if (hf->display == BASE_CUSTOM) {
12937 char lbl[ITEM_LABEL_LENGTH240];
12938 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12939
12940 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12940, "fmtfunc"))))
;
12941 fmtfunc(lbl, (int64_t) tmpval);
12942 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12943 hf->name, lbl);
12944 first = false0;
12945 }
12946 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12947 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12948 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12949 first = false0;
12950 }
12951 else if (!(flags & BMT_NO_INT0x02)) {
12952 char buf[NUMBER_LABEL_LENGTH80];
12953 const char *out = NULL((void*)0);
12954
12955 if (!first) {
12956 proto_item_append_text(item, ", ");
12957 }
12958
12959 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12960 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12961 }
12962 if (out == NULL((void*)0)) {
12963 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12964 }
12965 proto_item_append_text(item, "%s: %s", hf->name, out);
12966 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12967 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12968 }
12969 first = false0;
12970 }
12971
12972 break;
12973
12974 case FT_BOOLEAN:
12975 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12976 /* If we have true/false strings, emit full - otherwise messages
12977 might look weird */
12978 const struct true_false_string *tfs =
12979 (const struct true_false_string *)hf->strings;
12980
12981 if (tmpval) {
12982 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12983 hf->name, tfs->true_string);
12984 first = false0;
12985 } else if (!(flags & BMT_NO_FALSE0x04)) {
12986 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12987 hf->name, tfs->false_string);
12988 first = false0;
12989 }
12990 } else if (hf->bitmask & value) {
12991 /* If the flag is set, show the name */
12992 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
12993 first = false0;
12994 }
12995 break;
12996 default:
12997 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))
12998 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))
12999 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))
13000 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))
;
13001 break;
13002 }
13003
13004 fields++;
13005 }
13006
13007 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13008 * but then again most dissectors don't set the bitmask field for
13009 * the higher level bitmask hfi, so calculate the bitmask from the
13010 * fields present. */
13011 if (item) {
13012 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13013 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13014 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)
;
13015 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)
;
13016 }
13017 return first;
13018}
13019
13020/* This function will dissect a sequence of bytes that describe a
13021 * bitmask and supply the value of that sequence through a pointer.
13022 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13023 * to be dissected.
13024 * This field will form an expansion under which the individual fields of the
13025 * bitmask is dissected and displayed.
13026 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13027 *
13028 * fields is an array of pointers to int that lists all the fields of the
13029 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13030 * or another integer of the same type/size as hf_hdr with a mask specified.
13031 * This array is terminated by a NULL entry.
13032 *
13033 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13034 * FT_integer fields that have a value_string attached will have the
13035 * matched string displayed on the expansion line.
13036 */
13037proto_item *
13038proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13039 const unsigned offset, const int hf_hdr,
13040 const int ett, int * const *fields,
13041 const unsigned encoding, uint64_t *retval)
13042{
13043 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);
13044}
13045
13046/* This function will dissect a sequence of bytes that describe a
13047 * bitmask.
13048 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13049 * to be dissected.
13050 * This field will form an expansion under which the individual fields of the
13051 * bitmask is dissected and displayed.
13052 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13053 *
13054 * fields is an array of pointers to int that lists all the fields of the
13055 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13056 * or another integer of the same type/size as hf_hdr with a mask specified.
13057 * This array is terminated by a NULL entry.
13058 *
13059 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13060 * FT_integer fields that have a value_string attached will have the
13061 * matched string displayed on the expansion line.
13062 */
13063proto_item *
13064proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13065 const unsigned offset, const int hf_hdr,
13066 const int ett, int * const *fields,
13067 const unsigned encoding)
13068{
13069 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13070}
13071
13072/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13073 * what data is appended to the header.
13074 */
13075proto_item *
13076proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13077 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13078 uint64_t *retval)
13079{
13080 proto_item *item = NULL((void*)0);
13081 header_field_info *hf;
13082 int len;
13083 uint64_t value;
13084
13085 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", 13085, __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", 13085
, "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", 13085, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13086 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", 13086, (hf)->abbrev)))
;
13087 len = ftype_wire_size(hf->type);
13088 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13089
13090 if (parent_tree) {
13091 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13092 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13093 flags, false0, false0, NULL((void*)0), value);
13094 }
13095
13096 *retval = value;
13097 if (hf->bitmask) {
13098 /* Mask out irrelevant portions */
13099 *retval &= hf->bitmask;
13100 /* Shift bits */
13101 *retval >>= hfinfo_bitshift(hf);
13102 }
13103
13104 return item;
13105}
13106
13107/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13108 * what data is appended to the header.
13109 */
13110proto_item *
13111proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13112 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13113{
13114 proto_item *item = NULL((void*)0);
13115 header_field_info *hf;
13116 int len;
13117 uint64_t value;
13118
13119 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", 13119, __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", 13119
, "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", 13119, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13120 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", 13120, (hf)->abbrev)))
;
13121
13122 if (parent_tree) {
13123 len = ftype_wire_size(hf->type);
13124 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13125 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13126 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13127 flags, false0, false0, NULL((void*)0), value);
13128 }
13129
13130 return item;
13131}
13132
13133/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13134 can't be retrieved directly from tvb) */
13135proto_item *
13136proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13137 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13138{
13139 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13140 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13141}
13142
13143/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13144WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13145proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13146 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13147{
13148 proto_item *item = NULL((void*)0);
13149 header_field_info *hf;
13150 int len;
13151
13152 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", 13152, __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", 13152
, "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", 13152, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13153 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", 13153, (hf)->abbrev)))
;
13154 /* the proto_tree_add_uint/_uint64() calls below
13155 will fail if tvb==NULL and len!=0 */
13156 len = tvb ? ftype_wire_size(hf->type) : 0;
13157
13158 if (parent_tree) {
13159 if (len <= 4)
13160 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13161 else
13162 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13163
13164 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13165 flags, false0, false0, NULL((void*)0), value);
13166 }
13167
13168 return item;
13169}
13170
13171/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13172void
13173proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13174 const int len, int * const *fields, const unsigned encoding)
13175{
13176 uint64_t value;
13177
13178 if (tree) {
13179 value = get_uint64_value(tree, tvb, offset, len, encoding);
13180 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13181 BMT_NO_APPEND0x01, false0, true1, tree, value);
13182 }
13183}
13184
13185WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13186proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13187 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13188{
13189 uint64_t value;
13190
13191 value = get_uint64_value(tree, tvb, offset, len, encoding);
13192 if (tree) {
13193 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13194 BMT_NO_APPEND0x01, false0, true1, tree, value);
13195 }
13196 if (retval) {
13197 *retval = value;
13198 }
13199}
13200
13201WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13202proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13203 const int len, int * const *fields, const uint64_t value)
13204{
13205 if (tree) {
13206 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13207 BMT_NO_APPEND0x01, false0, true1, tree, value);
13208 }
13209}
13210
13211
13212/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13213 * This is intended to support bitmask fields whose lengths can vary, perhaps
13214 * as the underlying standard evolves over time.
13215 * With this API there is the possibility of being called to display more or
13216 * less data than the dissector was coded to support.
13217 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13218 * Thus when presented with "too much" or "too little" data, MSbits will be
13219 * ignored or MSfields sacrificed.
13220 *
13221 * Only fields for which all defined bits are available are displayed.
13222 */
13223proto_item *
13224proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13225 const unsigned offset, const unsigned len, const int hf_hdr,
13226 const int ett, int * const *fields, struct expert_field* exp,
13227 const unsigned encoding)
13228{
13229 proto_item *item = NULL((void*)0);
13230 header_field_info *hf;
13231 unsigned decodable_len;
13232 unsigned decodable_offset;
13233 uint32_t decodable_value;
13234 uint64_t value;
13235
13236 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", 13236, __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", 13236
, "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", 13236, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13237 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", 13237, (hf)->abbrev)))
;
13238
13239 decodable_offset = offset;
13240 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13241
13242 /* If we are ftype_wire_size-limited,
13243 * make sure we decode as many LSBs as possible.
13244 */
13245 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13246 decodable_offset += (len - decodable_len);
13247 }
13248
13249 if (parent_tree) {
13250 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13251 decodable_len, encoding);
13252
13253 /* The root item covers all the bytes even if we can't decode them all */
13254 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13255 decodable_value);
13256 }
13257
13258 if (decodable_len < len) {
13259 /* Dissector likely requires updating for new protocol revision */
13260 expert_add_info_format(NULL((void*)0), item, exp,
13261 "Only least-significant %d of %d bytes decoded",
13262 decodable_len, len);
13263 }
13264
13265 if (item) {
13266 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13267 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13268 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13269 }
13270
13271 return item;
13272}
13273
13274/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13275proto_item *
13276proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13277 const unsigned offset, const unsigned len,
13278 const char *name, const char *fallback,
13279 const int ett, int * const *fields,
13280 const unsigned encoding, const int flags)
13281{
13282 proto_item *item = NULL((void*)0);
13283 uint64_t value;
13284
13285 if (parent_tree) {
13286 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13287 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13288 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13289 flags, true1, false0, NULL((void*)0), value) && fallback) {
13290 /* Still at first item - append 'fallback' text if any */
13291 proto_item_append_text(item, "%s", fallback);
13292 }
13293 }
13294
13295 return item;
13296}
13297
13298proto_item *
13299proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13300 const unsigned bit_offset, const int no_of_bits,
13301 const unsigned encoding)
13302{
13303 header_field_info *hfinfo;
13304 int octet_length;
13305 int octet_offset;
13306
13307 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", 13307, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13307
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13307, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13308
13309 if (no_of_bits < 0) {
13310 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13311 }
13312 octet_length = (no_of_bits + 7) >> 3;
13313 octet_offset = bit_offset >> 3;
13314 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13315
13316 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13317 * but only after doing a bunch more work (which we can, in the common
13318 * case, shortcut here).
13319 */
13320 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13321 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", 13321
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13321, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13321, "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", 13321, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13322
13323 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13324}
13325
13326/*
13327 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13328 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13329 * Offset should be given in bits from the start of the tvb.
13330 */
13331
13332static proto_item *
13333_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13334 const unsigned bit_offset, const int no_of_bits,
13335 uint64_t *return_value, const unsigned encoding)
13336{
13337 int offset;
13338 unsigned length;
13339 uint8_t tot_no_bits;
13340 char *bf_str;
13341 char lbl_str[ITEM_LABEL_LENGTH240];
13342 uint64_t value = 0;
13343 uint8_t *bytes = NULL((void*)0);
13344 size_t bytes_length = 0;
13345
13346 proto_item *pi;
13347 header_field_info *hf_field;
13348
13349 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13350 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", 13350, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13350
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13350, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13351
13352 if (hf_field->bitmask != 0) {
13353 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)
13354 " 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)
13355 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)
;
13356 }
13357
13358 if (no_of_bits < 0) {
13359 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13360 } else if (no_of_bits == 0) {
13361 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)
13362 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)
;
13363 }
13364
13365 /* Byte align offset */
13366 offset = bit_offset>>3;
13367
13368 /*
13369 * Calculate the number of octets used to hold the bits
13370 */
13371 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13372 length = (tot_no_bits + 7) >> 3;
13373
13374 if (no_of_bits < 65) {
13375 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13376 } else if (hf_field->type != FT_BYTES) {
13377 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)
13378 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)
;
13379 return NULL((void*)0);
13380 }
13381
13382 /* Sign extend for signed types */
13383 switch (hf_field->type) {
13384 case FT_INT8:
13385 case FT_INT16:
13386 case FT_INT24:
13387 case FT_INT32:
13388 case FT_INT40:
13389 case FT_INT48:
13390 case FT_INT56:
13391 case FT_INT64:
13392 value = ws_sign_ext64(value, no_of_bits);
13393 break;
13394
13395 default:
13396 break;
13397 }
13398
13399 if (return_value) {
13400 *return_value = value;
13401 }
13402
13403 /* Coast clear. Try and fake it */
13404 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13405 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", 13405
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13405, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13405, "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", 13405, __func__, "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); } } }
;
13406
13407 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13408
13409 switch (hf_field->type) {
13410 case FT_BOOLEAN:
13411 /* Boolean field */
13412 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13413 "%s = %s: %s",
13414 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13415 break;
13416
13417 case FT_CHAR:
13418 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13419 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13420 break;
13421
13422 case FT_UINT8:
13423 case FT_UINT16:
13424 case FT_UINT24:
13425 case FT_UINT32:
13426 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13427 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13428 break;
13429
13430 case FT_INT8:
13431 case FT_INT16:
13432 case FT_INT24:
13433 case FT_INT32:
13434 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13435 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13436 break;
13437
13438 case FT_UINT40:
13439 case FT_UINT48:
13440 case FT_UINT56:
13441 case FT_UINT64:
13442 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13443 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13444 break;
13445
13446 case FT_INT40:
13447 case FT_INT48:
13448 case FT_INT56:
13449 case FT_INT64:
13450 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13451 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13452 break;
13453
13454 case FT_BYTES:
13455 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13456 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13457 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13458 proto_item_set_text(pi, "%s", lbl_str);
13459 return pi;
13460
13461 /* TODO: should handle FT_UINT_BYTES ? */
13462
13463 default:
13464 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))
13465 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))
13466 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))
13467 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))
;
13468 return NULL((void*)0);
13469 }
13470
13471 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13472 return pi;
13473}
13474
13475proto_item *
13476proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13477 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13478 uint64_t *return_value)
13479{
13480 proto_item *pi;
13481 int no_of_bits;
13482 int octet_offset;
13483 unsigned mask_initial_bit_offset;
13484 unsigned mask_greatest_bit_offset;
13485 unsigned octet_length;
13486 uint8_t i;
13487 char bf_str[256];
13488 char lbl_str[ITEM_LABEL_LENGTH240];
13489 uint64_t value;
13490 uint64_t composite_bitmask;
13491 uint64_t composite_bitmap;
13492
13493 header_field_info *hf_field;
13494
13495 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13496 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", 13496, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13496
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13496, "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
13497
13498 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13499 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)
13500 " 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)
13501 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)
;
13502 }
13503
13504 mask_initial_bit_offset = bit_offset % 8;
13505
13506 no_of_bits = 0;
13507 value = 0;
13508 i = 0;
13509 mask_greatest_bit_offset = 0;
13510 composite_bitmask = 0;
13511 composite_bitmap = 0;
13512
13513 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
13514 uint64_t crumb_mask, crumb_value;
13515 uint8_t crumb_end_bit_offset;
13516
13517 crumb_value = tvb_get_bits64(tvb,
13518 bit_offset + crumb_spec[i].crumb_bit_offset,
13519 crumb_spec[i].crumb_bit_length,
13520 ENC_BIG_ENDIAN0x00000000);
13521 value += crumb_value;
13522 no_of_bits += crumb_spec[i].crumb_bit_length;
13523 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", 13523
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13524
13525 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13526 octet containing the initial offset.
13527 If the mask is beyond 32 bits, then give up on bit map display.
13528 This could be improved in future, probably showing a table
13529 of 32 or 64 bits per row */
13530 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13531 crumb_end_bit_offset = mask_initial_bit_offset
13532 + crumb_spec[i].crumb_bit_offset
13533 + crumb_spec[i].crumb_bit_length;
13534 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'
13535
13536 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13537 mask_greatest_bit_offset = crumb_end_bit_offset;
13538 }
13539 /* Currently the bitmap of the crumbs are only shown if
13540 * smaller than 32 bits. Do not bother calculating the
13541 * mask if it is larger than that. */
13542 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13543 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'
13544 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13545 }
13546 }
13547 /* Shift left for the next segment */
13548 value <<= crumb_spec[++i].crumb_bit_length;
13549 }
13550
13551 /* Sign extend for signed types */
13552 switch (hf_field->type) {
13553 case FT_INT8:
13554 case FT_INT16:
13555 case FT_INT24:
13556 case FT_INT32:
13557 case FT_INT40:
13558 case FT_INT48:
13559 case FT_INT56:
13560 case FT_INT64:
13561 value = ws_sign_ext64(value, no_of_bits);
13562 break;
13563 default:
13564 break;
13565 }
13566
13567 if (return_value) {
13568 *return_value = value;
13569 }
13570
13571 /* Coast clear. Try and fake it */
13572 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13573 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", 13573
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13573, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13573, "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", 13573, __func__, "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); } } }
;
13574
13575 /* initialise the format string */
13576 bf_str[0] = '\0';
13577
13578 octet_offset = bit_offset >> 3;
13579
13580 /* Round up mask length to nearest octet */
13581 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13582 mask_greatest_bit_offset = octet_length << 3;
13583
13584 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13585 It would be a useful enhancement to eliminate this restriction. */
13586 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13587 other_decode_bitfield_value(bf_str,
13588 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13589 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13590 mask_greatest_bit_offset);
13591 } else {
13592 /* If the bitmask is too large, try to describe its contents. */
13593 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13594 }
13595
13596 switch (hf_field->type) {
13597 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13598 /* Boolean field */
13599 return proto_tree_add_boolean_format(tree, hfindex,
13600 tvb, octet_offset, octet_length, value,
13601 "%s = %s: %s",
13602 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13603 break;
13604
13605 case FT_CHAR:
13606 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13607 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13608 break;
13609
13610 case FT_UINT8:
13611 case FT_UINT16:
13612 case FT_UINT24:
13613 case FT_UINT32:
13614 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13615 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13616 break;
13617
13618 case FT_INT8:
13619 case FT_INT16:
13620 case FT_INT24:
13621 case FT_INT32:
13622 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13623 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13624 break;
13625
13626 case FT_UINT40:
13627 case FT_UINT48:
13628 case FT_UINT56:
13629 case FT_UINT64:
13630 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13631 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13632 break;
13633
13634 case FT_INT40:
13635 case FT_INT48:
13636 case FT_INT56:
13637 case FT_INT64:
13638 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13639 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13640 break;
13641
13642 default:
13643 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))
13644 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))
13645 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))
13646 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))
;
13647 return NULL((void*)0);
13648 }
13649 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13650 return pi;
13651}
13652
13653void
13654proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13655 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13656{
13657 header_field_info *hfinfo;
13658 int start = bit_offset >> 3;
13659 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13660
13661 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13662 * so that we can use the tree's memory scope in calculating the string */
13663 if (length == -1) {
13664 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13665 } else {
13666 tvb_ensure_bytes_exist(tvb, start, length);
13667 }
13668 if (!tree) return;
13669
13670 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", 13670, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13670
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13670, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13671 proto_tree_add_text_internal(tree, tvb, start, length,
13672 "%s crumb %d of %s (decoded above)",
13673 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13674 tvb_get_bits32(tvb,
13675 bit_offset,
13676 crumb_spec[crumb_index].crumb_bit_length,
13677 ENC_BIG_ENDIAN0x00000000),
13678 ENC_BIG_ENDIAN0x00000000),
13679 crumb_index,
13680 hfinfo->name);
13681}
13682
13683proto_item *
13684proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13685 const unsigned bit_offset, const int no_of_bits,
13686 uint64_t *return_value, const unsigned encoding)
13687{
13688 proto_item *item;
13689
13690 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13691 bit_offset, no_of_bits,
13692 return_value, encoding))) {
13693 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)
;
13694 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)
;
13695 }
13696 return item;
13697}
13698
13699static proto_item *
13700_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13701 tvbuff_t *tvb, const unsigned bit_offset,
13702 const int no_of_bits, void *value_ptr,
13703 const unsigned encoding, char *value_str)
13704{
13705 int offset;
13706 unsigned length;
13707 uint8_t tot_no_bits;
13708 char *str;
13709 uint64_t value = 0;
13710 header_field_info *hf_field;
13711
13712 /* We do not have to return a value, try to fake it as soon as possible */
13713 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13714 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", 13714
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13714, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13714, "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", 13714, __func__, "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); } } }
;
13715
13716 if (hf_field->bitmask != 0) {
13717 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)
13718 " 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)
13719 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)
;
13720 }
13721
13722 if (no_of_bits < 0) {
13723 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13724 } else if (no_of_bits == 0) {
13725 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)
13726 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)
;
13727 }
13728
13729 /* Byte align offset */
13730 offset = bit_offset>>3;
13731
13732 /*
13733 * Calculate the number of octets used to hold the bits
13734 */
13735 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13736 length = tot_no_bits>>3;
13737 /* If we are using part of the next octet, increase length by 1 */
13738 if (tot_no_bits & 0x07)
13739 length++;
13740
13741 if (no_of_bits < 65) {
13742 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13743 } else {
13744 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)
13745 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)
;
13746 return NULL((void*)0);
13747 }
13748
13749 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13750
13751 (void) g_strlcat(str, " = ", 256+64);
13752 (void) g_strlcat(str, hf_field->name, 256+64);
13753
13754 /*
13755 * This function does not receive an actual value but a dimensionless pointer to that value.
13756 * For this reason, the type of the header field is examined in order to determine
13757 * what kind of value we should read from this address.
13758 * The caller of this function must make sure that for the specific header field type the address of
13759 * a compatible value is provided.
13760 */
13761 switch (hf_field->type) {
13762 case FT_BOOLEAN:
13763 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13764 "%s: %s", str, value_str);
13765 break;
13766
13767 case FT_CHAR:
13768 case FT_UINT8:
13769 case FT_UINT16:
13770 case FT_UINT24:
13771 case FT_UINT32:
13772 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13773 "%s: %s", str, value_str);
13774 break;
13775
13776 case FT_UINT40:
13777 case FT_UINT48:
13778 case FT_UINT56:
13779 case FT_UINT64:
13780 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13781 "%s: %s", str, value_str);
13782 break;
13783
13784 case FT_INT8:
13785 case FT_INT16:
13786 case FT_INT24:
13787 case FT_INT32:
13788 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13789 "%s: %s", str, value_str);
13790 break;
13791
13792 case FT_INT40:
13793 case FT_INT48:
13794 case FT_INT56:
13795 case FT_INT64:
13796 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13797 "%s: %s", str, value_str);
13798 break;
13799
13800 case FT_FLOAT:
13801 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13802 "%s: %s", str, value_str);
13803 break;
13804
13805 default:
13806 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))
13807 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))
13808 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))
13809 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))
;
13810 return NULL((void*)0);
13811 }
13812}
13813
13814static proto_item *
13815proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13816 tvbuff_t *tvb, const unsigned bit_offset,
13817 const int no_of_bits, void *value_ptr,
13818 const unsigned encoding, char *value_str)
13819{
13820 proto_item *item;
13821
13822 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13823 tvb, bit_offset, no_of_bits,
13824 value_ptr, encoding, value_str))) {
13825 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)
;
13826 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)
;
13827 }
13828 return item;
13829}
13830
13831#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);
\
13832 va_start(ap, format)__builtin_va_start(ap, format); \
13833 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13834 va_end(ap)__builtin_va_end(ap);
13835
13836proto_item *
13837proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13838 tvbuff_t *tvb, const unsigned bit_offset,
13839 const int no_of_bits, uint32_t value,
13840 const unsigned encoding,
13841 const char *format, ...)
13842{
13843 va_list ap;
13844 char *dst;
13845 header_field_info *hf_field;
13846
13847 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13848
13849 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", 13849
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13849, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13849, "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", 13849, __func__, "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); } } }
;
13850
13851 switch (hf_field->type) {
13852 case FT_UINT8:
13853 case FT_UINT16:
13854 case FT_UINT24:
13855 case FT_UINT32:
13856 break;
13857
13858 default:
13859 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)
13860 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)
;
13861 return NULL((void*)0);
13862 }
13863
13864 CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
;
13865
13866 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13867}
13868
13869proto_item *
13870proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13871 tvbuff_t *tvb, const unsigned bit_offset,
13872 const int no_of_bits, uint64_t value,
13873 const unsigned encoding,
13874 const char *format, ...)
13875{
13876 va_list ap;
13877 char *dst;
13878 header_field_info *hf_field;
13879
13880 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13881
13882 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13882
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13882, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13882, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13882, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13883
13884 switch (hf_field->type) {
13885 case FT_UINT40:
13886 case FT_UINT48:
13887 case FT_UINT56:
13888 case FT_UINT64:
13889 break;
13890
13891 default:
13892 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)
13893 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)
;
13894 return NULL((void*)0);
13895 }
13896
13897 CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
;
13898
13899 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13900}
13901
13902proto_item *
13903proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13904 tvbuff_t *tvb, const unsigned bit_offset,
13905 const int no_of_bits, float value,
13906 const unsigned encoding,
13907 const char *format, ...)
13908{
13909 va_list ap;
13910 char *dst;
13911 header_field_info *hf_field;
13912
13913 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13914
13915 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13915
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13915, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13915, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13915, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13916
13917 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",
13917, ((hf_field))->abbrev))))
;
13918
13919 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);
;
13920
13921 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13922}
13923
13924proto_item *
13925proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13926 tvbuff_t *tvb, const unsigned bit_offset,
13927 const int no_of_bits, int32_t value,
13928 const unsigned encoding,
13929 const char *format, ...)
13930{
13931 va_list ap;
13932 char *dst;
13933 header_field_info *hf_field;
13934
13935 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13936
13937 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", 13937
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13937, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13937, "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", 13937, __func__, "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); } } }
;
13938
13939 switch (hf_field->type) {
13940 case FT_INT8:
13941 case FT_INT16:
13942 case FT_INT24:
13943 case FT_INT32:
13944 break;
13945
13946 default:
13947 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)
13948 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)
;
13949 return NULL((void*)0);
13950 }
13951
13952 CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
;
13953
13954 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13955}
13956
13957proto_item *
13958proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13959 tvbuff_t *tvb, const unsigned bit_offset,
13960 const int no_of_bits, int64_t value,
13961 const unsigned encoding,
13962 const char *format, ...)
13963{
13964 va_list ap;
13965 char *dst;
13966 header_field_info *hf_field;
13967
13968 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13969
13970 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", 13970
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13970, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13970, "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", 13970, __func__, "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); } } }
;
13971
13972 switch (hf_field->type) {
13973 case FT_INT40:
13974 case FT_INT48:
13975 case FT_INT56:
13976 case FT_INT64:
13977 break;
13978
13979 default:
13980 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)
13981 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)
;
13982 return NULL((void*)0);
13983 }
13984
13985 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);
;
13986
13987 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13988}
13989
13990proto_item *
13991proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
13992 tvbuff_t *tvb, const unsigned bit_offset,
13993 const int no_of_bits, uint64_t value,
13994 const unsigned encoding,
13995 const char *format, ...)
13996{
13997 va_list ap;
13998 char *dst;
13999 header_field_info *hf_field;
14000
14001 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14002
14003 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", 14003
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14003, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14003, "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", 14003, __func__, "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); } } }
;
14004
14005 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"
, 14005, ((hf_field))->abbrev))))
;
14006
14007 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);
;
14008
14009 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14010}
14011
14012proto_item *
14013proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14014 const unsigned bit_offset, const int no_of_chars)
14015{
14016 proto_item *pi;
14017 header_field_info *hfinfo;
14018 int byte_length;
14019 int byte_offset;
14020 char *string;
14021
14022 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14023
14024 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", 14024
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14024, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14024, "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", 14024, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14025
14026 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"
, 14026, ((hfinfo))->abbrev))))
;
14027
14028 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14029 byte_offset = bit_offset >> 3;
14030
14031 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14032
14033 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14034 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14034, "byte_length >= 0"
))))
;
14035 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14036
14037 return pi;
14038}
14039
14040proto_item *
14041proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14042 const unsigned bit_offset, const int no_of_chars)
14043{
14044 proto_item *pi;
14045 header_field_info *hfinfo;
14046 int byte_length;
14047 int byte_offset;
14048 char *string;
14049
14050 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14051
14052 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", 14052
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14052, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14052, "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", 14052, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14053
14054 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"
, 14054, ((hfinfo))->abbrev))))
;
14055
14056 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14057 byte_offset = bit_offset >> 3;
14058
14059 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14060
14061 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14062 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14062, "byte_length >= 0"
))))
;
14063 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14064
14065 return pi;
14066}
14067
14068const value_string proto_checksum_vals[] = {
14069 { PROTO_CHECKSUM_E_BAD, "Bad" },
14070 { PROTO_CHECKSUM_E_GOOD, "Good" },
14071 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14072 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14073 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14074
14075 { 0, NULL((void*)0) }
14076};
14077
14078proto_item *
14079proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14080 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14081 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14082{
14083 header_field_info *hfinfo;
14084 uint32_t checksum;
14085 uint32_t len;
14086 proto_item* ti = NULL((void*)0);
14087 proto_item* ti2;
14088 bool_Bool incorrect_checksum = true1;
14089
14090 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", 14090, __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", 14090
, "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", 14090, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14091
14092 switch (hfinfo->type) {
14093 case FT_UINT8:
14094 len = 1;
14095 break;
14096 case FT_UINT16:
14097 len = 2;
14098 break;
14099 case FT_UINT24:
14100 len = 3;
14101 break;
14102 case FT_UINT32:
14103 len = 4;
14104 break;
14105 default:
14106 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)
14107 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14108 }
14109
14110 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14111 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14112 proto_item_set_generated(ti);
14113 if (hf_checksum_status != -1) {
14114 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14115 proto_item_set_generated(ti2);
14116 }
14117 return ti;
14118 }
14119
14120 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14121 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14122 proto_item_set_generated(ti);
14123 } else {
14124 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14125 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14126 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14127 if (computed_checksum == 0) {
14128 proto_item_append_text(ti, " [correct]");
14129 if (hf_checksum_status != -1) {
14130 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14131 proto_item_set_generated(ti2);
14132 }
14133 incorrect_checksum = false0;
14134 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14135 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14136 /* XXX - This can't distinguish between "shouldbe"
14137 * 0x0000 and 0xFFFF unless we know whether there
14138 * were any nonzero bits (other than the checksum).
14139 * Protocols should not use this path if they might
14140 * have an all zero packet.
14141 * Some implementations put the wrong zero; maybe
14142 * we should have a special expert info for that?
14143 */
14144 }
14145 } else {
14146 if (checksum == computed_checksum) {
14147 proto_item_append_text(ti, " [correct]");
14148 if (hf_checksum_status != -1) {
14149 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14150 proto_item_set_generated(ti2);
14151 }
14152 incorrect_checksum = false0;
14153 }
14154 }
14155
14156 if (incorrect_checksum) {
14157 if (hf_checksum_status != -1) {
14158 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14159 proto_item_set_generated(ti2);
14160 }
14161 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14162 proto_item_append_text(ti, " [incorrect]");
14163 if (bad_checksum_expert != NULL((void*)0))
14164 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14165 } else {
14166 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14167 if (bad_checksum_expert != NULL((void*)0))
14168 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);
14169 }
14170 }
14171 } else {
14172 if (hf_checksum_status != -1) {
14173 proto_item_append_text(ti, " [unverified]");
14174 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14175 proto_item_set_generated(ti2);
14176 }
14177 }
14178 }
14179
14180 return ti;
14181}
14182
14183proto_item *
14184proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14185 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14186 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14187{
14188 header_field_info *hfinfo;
14189 uint8_t *checksum = NULL((void*)0);
14190 proto_item* ti = NULL((void*)0);
14191 proto_item* ti2;
14192 bool_Bool incorrect_checksum = true1;
14193
14194 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", 14194, __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", 14194
, "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", 14194, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14195
14196 if (hfinfo->type != FT_BYTES) {
14197 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)
14198 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
14199 }
14200
14201 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14202 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14203 proto_item_set_generated(ti);
14204 if (hf_checksum_status != -1) {
14205 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14206 proto_item_set_generated(ti2);
14207 }
14208 return ti;
14209 }
14210
14211 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14212 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14213 proto_item_set_generated(ti);
14214 } else {
14215 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
))))))
;
14216 tvb_memcpy(tvb, checksum, offset, checksum_len);
14217 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14218 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14219 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14220 if (computed_checksum == 0) {
14221 proto_item_append_text(ti, " [correct]");
14222 if (hf_checksum_status != -1) {
14223 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14224 proto_item_set_generated(ti2);
14225 }
14226 incorrect_checksum = false0;
14227 }
14228 } else {
14229 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14230 proto_item_append_text(ti, " [correct]");
14231 if (hf_checksum_status != -1) {
14232 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14233 proto_item_set_generated(ti2);
14234 }
14235 incorrect_checksum = false0;
14236 }
14237 }
14238
14239 if (incorrect_checksum) {
14240 if (hf_checksum_status != -1) {
14241 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14242 proto_item_set_generated(ti2);
14243 }
14244 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14245 proto_item_append_text(ti, " [incorrect]");
14246 if (bad_checksum_expert != NULL((void*)0))
14247 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14248 } else {
14249 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14250 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))))))
;
14251 for (size_t counter = 0; counter < checksum_len; ++counter) {
14252 snprintf(
14253 /* On ecah iteration inserts two characters */
14254 (char*)&computed_checksum_str[counter << 1],
14255 computed_checksum_str_len - (counter << 1),
14256 "%02x",
14257 computed_checksum[counter]);
14258 }
14259 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14260 if (bad_checksum_expert != NULL((void*)0))
14261 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14262 }
14263 }
14264 } else {
14265 if (hf_checksum_status != -1) {
14266 proto_item_append_text(ti, " [unverified]");
14267 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14268 proto_item_set_generated(ti2);
14269 }
14270 }
14271 }
14272
14273 return ti;
14274}
14275
14276unsigned char
14277proto_check_field_name(const char *field_name)
14278{
14279 return module_check_valid_name(field_name, false0);
14280}
14281
14282unsigned char
14283proto_check_field_name_lower(const char *field_name)
14284{
14285 return module_check_valid_name(field_name, true1);
14286}
14287
14288bool_Bool
14289tree_expanded(int tree_type)
14290{
14291 if (tree_type <= 0) {
14292 return false0;
14293 }
14294 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", 14294, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14295 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14296}
14297
14298void
14299tree_expanded_set(int tree_type, bool_Bool value)
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
14303 if (value)
14304 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14305 else
14306 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14307}
14308
14309/*
14310 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14311 *
14312 * Local variables:
14313 * c-basic-offset: 8
14314 * tab-width: 8
14315 * indent-tabs-mode: t
14316 * End:
14317 *
14318 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14319 * :indentSize=8:tabSize=8:noTabs=false:
14320 */