Bug Summary

File:epan/proto.c
Warning:line 12047, column 2
3rd function call argument is an uninitialized value

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-21/lib/clang/21 -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/mit-krb5 -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-21/lib/clang/21/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-nonliteral -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-12-11-100311-3573-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 <[email protected]>
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#include <ftypes/ftypes-int.h>
37
38#include <epan/packet.h>
39#include "exceptions.h"
40#include "ptvcursor.h"
41#include "strutil.h"
42#include "addr_resolv.h"
43#include "address_types.h"
44#include "oids.h"
45#include "proto.h"
46#include "epan_dissect.h"
47#include "dfilter/dfilter.h"
48#include "tvbuff.h"
49#include "charsets.h"
50#include "column-info.h"
51#include "to_str.h"
52#include "osi-utils.h"
53#include "expert.h"
54#include "show_exception.h"
55#include "in_cksum.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_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "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)
219 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "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)
220 hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "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)
221 current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "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)
; \
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
575void proto_pre_init(void)
576{
577 saved_dir_queue = g_queue_new();
578
579 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
580 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
581 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
582
583 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
584 for (const char** ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
585 /* GHashTable has no key destructor so the cast is safe. */
586 g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
587 }
588
589 gpa_hfinfo.len = 0;
590 gpa_hfinfo.allocated_len = 0;
591 gpa_hfinfo.hfi = NULL((void*)0);
592 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
593 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
594 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
595 deregistered_fields = g_ptr_array_new();
596 deregistered_data = g_ptr_array_new();
597 deregistered_slice = g_ptr_array_new();
598}
599
600/* initialize data structures and register protocols and fields */
601void
602proto_init(GSList *register_all_plugin_protocols_list,
603 GSList *register_all_plugin_handoffs_list,
604 register_entity_func register_func, register_entity_func handoff_func,
605 register_cb cb,
606 void *client_data)
607{
608 /* Initialize the ftype subsystem */
609 ftypes_initialize();
610
611 /* Initialize the address type subsystem */
612 address_types_initialize();
613
614 /* Register one special-case FT_TEXT_ONLY field for use when
615 converting wireshark to new-style proto_tree. These fields
616 are merely strings on the GUI tree; they are not filterable */
617 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
618
619 /* Register the pseudo-protocols used for exceptions. */
620 register_show_exception();
621 register_type_length_mismatch();
622 register_byte_array_string_decodinws_error();
623 register_date_time_string_decodinws_error();
624 register_string_errors();
625 ftypes_register_pseudofields();
626 col_register_protocol();
627
628 /* Have each built-in dissector register its protocols, fields,
629 dissector tables, and dissectors to be called through a
630 handle, and do whatever one-time initialization it needs to
631 do. */
632 if (register_func != NULL((void*)0))
633 register_func(cb, client_data);
634
635 /* Now call the registration routines for all epan plugins. */
636 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
637 ((void (*)(register_cb, void *))l->data)(cb, client_data);
638 }
639
640 /* Now call the registration routines for all dissector plugins. */
641 if (cb)
642 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
643 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
644
645 /* Now call the "handoff registration" routines of all built-in
646 dissectors; those routines register the dissector in other
647 dissectors' handoff tables, and fetch any dissector handles
648 they need. */
649 if (handoff_func != NULL((void*)0))
650 handoff_func(cb, client_data);
651
652 /* Now do the same with epan plugins. */
653 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
654 ((void (*)(register_cb, void *))l->data)(cb, client_data);
655 }
656
657 /* Now do the same with dissector plugins. */
658 if (cb)
659 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
660 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
661
662 /* sort the protocols by protocol name */
663 protocols = g_list_sort(protocols, proto_compare_name);
664
665 /* sort the dissector handles in dissector tables (for -G reports
666 * and -d error messages. The GUI sorts the handles itself.) */
667 packet_all_tables_sort_handles();
668
669 /* We've assigned all the subtree type values; allocate the array
670 for them, and zero it out. */
671 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
)))
;
672}
673
674static void
675proto_cleanup_base(void)
676{
677 protocol_t *protocol;
678 header_field_info *hfinfo;
679
680 /* Free the abbrev/ID hash table */
681 if (gpa_name_map) {
682 // XXX - We don't have a wmem_map_destroy, but
683 // it does get cleaned up when epan scope is
684 // destroyed
685 //g_hash_table_destroy(gpa_name_map);
686 gpa_name_map = NULL((void*)0);
687 }
688 if (gpa_protocol_aliases) {
689 g_hash_table_destroy(gpa_protocol_aliases);
690 gpa_protocol_aliases = NULL((void*)0);
691 }
692 g_free(last_field_name);
693 last_field_name = NULL((void*)0);
694
695 while (protocols) {
696 protocol = (protocol_t *)protocols->data;
697 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", 697
, __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", 697, "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", 697, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
698 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", 698, "protocol->proto_id == hfinfo->id"
))))
;
699
700 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)
;
701 if (protocol->parent_proto_id != -1) {
702 // pino protocol
703 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 703, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
704 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"
, 704, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
705 } else {
706 if (protocol->fields) {
707 g_ptr_array_free(protocol->fields, true1);
708 }
709 g_list_free(protocol->heur_list);
710 }
711 protocols = g_list_remove(protocols, protocol);
712 g_free(protocol);
713 }
714
715 if (proto_names) {
716 g_hash_table_destroy(proto_names);
717 proto_names = NULL((void*)0);
718 }
719
720 if (proto_short_names) {
721 g_hash_table_destroy(proto_short_names);
722 proto_short_names = NULL((void*)0);
723 }
724
725 if (proto_filter_names) {
726 g_hash_table_destroy(proto_filter_names);
727 proto_filter_names = NULL((void*)0);
728 }
729
730 if (proto_reserved_filter_names) {
731 g_hash_table_destroy(proto_reserved_filter_names);
732 proto_reserved_filter_names = NULL((void*)0);
733 }
734
735 if (gpa_hfinfo.allocated_len) {
736 gpa_hfinfo.len = 0;
737 gpa_hfinfo.allocated_len = 0;
738 g_free(gpa_hfinfo.hfi);
739 gpa_hfinfo.hfi = NULL((void*)0);
740 }
741
742 if (deregistered_fields) {
743 g_ptr_array_free(deregistered_fields, true1);
744 deregistered_fields = NULL((void*)0);
745 }
746
747 if (deregistered_data) {
748 g_ptr_array_free(deregistered_data, true1);
749 deregistered_data = NULL((void*)0);
750 }
751
752 if (deregistered_slice) {
753 g_ptr_array_free(deregistered_slice, true1);
754 deregistered_slice = NULL((void*)0);
755 }
756
757 g_free(tree_is_expanded);
758 tree_is_expanded = NULL((void*)0);
759
760 if (prefixes)
761 g_hash_table_destroy(prefixes);
762
763 if (saved_dir_queue != NULL((void*)0)) {
764 g_queue_clear_full(saved_dir_queue, g_free);
765 g_queue_free(saved_dir_queue);
766 saved_dir_queue = NULL((void*)0);
767 }
768}
769
770void
771proto_cleanup(void)
772{
773 proto_free_deregistered_fields();
774 proto_cleanup_base();
775
776 g_slist_free(dissector_plugins);
777 dissector_plugins = NULL((void*)0);
778}
779
780static bool_Bool
781ws_pushd(const char* dir)
782{
783 //Save the current working directory
784 const char* save_wd = get_current_working_dir();
785 if (save_wd != NULL((void*)0))
786 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
787
788 //Change to the new one
789#ifdef _WIN32
790 SetCurrentDirectory(utf_8to16(dir));
791 return true1;
792#else
793 return (chdir(dir) == 0);
794#endif
795}
796
797static bool_Bool
798ws_popd(void)
799{
800 int ret = 0;
801 char* saved_wd = g_queue_pop_head(saved_dir_queue);
802 if (saved_wd == NULL((void*)0))
803 return false0;
804
805 //Restore the previous one
806#ifdef _WIN32
807 SetCurrentDirectory(utf_8to16(saved_wd));
808#else
809 ret = chdir(saved_wd);
810#endif
811 g_free(saved_wd);
812 return (ret == 0);
813}
814
815void
816proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
817{
818 if (ws_pushd(dir))
819 {
820 func(param);
821 ws_popd();
822 }
823}
824
825static bool_Bool
826// NOLINTNEXTLINE(misc-no-recursion)
827proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
828 void *data)
829{
830 proto_node *pnode = tree;
831 proto_node *child;
832 proto_node *current;
833
834 if (func(pnode, data))
835 return true1;
836
837 child = pnode->first_child;
838 while (child != NULL((void*)0)) {
839 /*
840 * The routine we call might modify the child, e.g. by
841 * freeing it, so we get the child's successor before
842 * calling that routine.
843 */
844 current = child;
845 child = current->next;
846 // We recurse here, but we're limited by prefs.gui_max_tree_depth
847 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
848 return true1;
849 }
850
851 return false0;
852}
853
854void
855proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
856 void *data)
857{
858 proto_node *node = tree;
859 proto_node *current;
860
861 if (!node)
862 return;
863
864 node = node->first_child;
865 while (node != NULL((void*)0)) {
866 current = node;
867 node = current->next;
868 func((proto_tree *)current, data);
869 }
870}
871
872static void
873free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
874{
875 GPtrArray *ptrs = (GPtrArray *)value;
876 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
877 header_field_info *hfinfo;
878
879 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", 879, __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", 879, "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", 879, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
880 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
881 /* when a field is referenced by a filter this also
882 affects the refcount for the parent protocol so we need
883 to adjust the refcount for the parent as well
884 */
885 if (hfinfo->parent != -1) {
886 header_field_info *parent_hfinfo;
887 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", 887
, __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", 887, "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", 887, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
888 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
889 }
890 hfinfo->ref_type = HF_REF_TYPE_NONE;
891 }
892
893 g_ptr_array_free(ptrs, true1);
894}
895
896static void
897proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
898{
899 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
900
901 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
902
903 if (finfo) {
904 fvalue_free(finfo->value);
905 finfo->value = NULL((void*)0);
906 }
907}
908
909void
910proto_tree_reset(proto_tree *tree)
911{
912 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
913
914 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
915
916 /* free tree data */
917 if (tree_data->interesting_hfids) {
918 /* Free all the GPtrArray's in the interesting_hfids hash. */
919 g_hash_table_foreach(tree_data->interesting_hfids,
920 free_GPtrArray_value, NULL((void*)0));
921
922 /* And then remove all values. */
923 g_hash_table_remove_all(tree_data->interesting_hfids);
924 }
925
926 /* Reset track of the number of children */
927 tree_data->count = 0;
928
929 /* Reset our loop checks */
930 tree_data->idle_count_ds_tvb = NULL((void*)0);
931 tree_data->max_start = 0;
932 tree_data->start_idle_count = 0;
933
934 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
935}
936
937/* frees the resources that the dissection a proto_tree uses */
938void
939proto_tree_free(proto_tree *tree)
940{
941 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
942
943 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
944
945 /* free tree data */
946 if (tree_data->interesting_hfids) {
947 /* Free all the GPtrArray's in the interesting_hfids hash. */
948 g_hash_table_foreach(tree_data->interesting_hfids,
949 free_GPtrArray_value, NULL((void*)0));
950
951 /* And then destroy the hash. */
952 g_hash_table_destroy(tree_data->interesting_hfids);
953 }
954
955 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)
;
956
957 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
958}
959
960/* Is the parsing being done for a visible proto_tree or an invisible one?
961 * By setting this correctly, the proto_tree creation is sped up by not
962 * having to call vsnprintf and copy strings around.
963 */
964bool_Bool
965proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
966{
967 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
968
969 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
970
971 return old_visible;
972}
973
974void
975proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
976{
977 if (tree)
978 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
979}
980
981/* Assume dissector set only its protocol fields.
982 This function is called by dissectors and allows the speeding up of filtering
983 in wireshark; if this function returns false it is safe to reset tree to NULL
984 and thus skip calling most of the expensive proto_tree_add_...()
985 functions.
986 If the tree is visible we implicitly assume the field is referenced.
987*/
988bool_Bool
989proto_field_is_referenced(proto_tree *tree, int proto_id)
990{
991 register header_field_info *hfinfo;
992
993
994 if (!tree)
995 return false0;
996
997 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
998 return true1;
999
1000 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", 1000, __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", 1000,
"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", 1000, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
1001 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1002 return true1;
1003
1004 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1005 return true1;
1006
1007 return false0;
1008}
1009
1010
1011/* Finds a record in the hfinfo array by id. */
1012header_field_info *
1013proto_registrar_get_nth(unsigned hfindex)
1014{
1015 register header_field_info *hfinfo;
1016
1017 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", 1017, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1017,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1017, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1018 return hfinfo;
1019}
1020
1021
1022/* Prefix initialization
1023 * this allows for a dissector to register a display filter name prefix
1024 * so that it can delay the initialization of the hf array as long as
1025 * possible.
1026 */
1027
1028/* compute a hash for the part before the dot of a display filter */
1029static unsigned
1030prefix_hash (const void *key) {
1031 /* end the string at the dot and compute its hash */
1032 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1033 char* c = copy;
1034 unsigned tmp;
1035
1036 for (; *c; c++) {
1037 if (*c == '.') {
1038 *c = 0;
1039 break;
1040 }
1041 }
1042
1043 tmp = wmem_str_hash(copy);
1044 g_free(copy);
1045 return tmp;
1046}
1047
1048/* are both strings equal up to the end or the dot? */
1049static gboolean
1050prefix_equal (const void *ap, const void *bp) {
1051 const char* a = (const char *)ap;
1052 const char* b = (const char *)bp;
1053
1054 do {
1055 char ac = *a++;
1056 char bc = *b++;
1057
1058 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1059
1060 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1061 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1062
1063 if (ac != bc) return FALSE(0);
1064 } while (1);
1065
1066 return FALSE(0);
1067}
1068
1069/* Register a new prefix for "delayed" initialization of field arrays */
1070void
1071proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1072 if (! prefixes ) {
1073 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1074 }
1075
1076 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1077}
1078
1079/* helper to call all prefix initializers */
1080static gboolean
1081initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1082 ((prefix_initializer_t)v)((const char *)k);
1083 return TRUE(!(0));
1084}
1085
1086/** Initialize every remaining uninitialized prefix. */
1087void
1088proto_initialize_all_prefixes(void) {
1089 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1090}
1091
1092/* Finds a record in the hfinfo array by name.
1093 * If it fails to find it in the already registered fields,
1094 * it tries to find and call an initializer in the prefixes
1095 * table and if so it looks again.
1096 */
1097
1098header_field_info *
1099proto_registrar_get_byname(const char *field_name)
1100{
1101 header_field_info *hfinfo;
1102 prefix_initializer_t pi;
1103
1104 if (!field_name)
1105 return NULL((void*)0);
1106
1107 if (g_strcmp0(field_name, last_field_name) == 0) {
1108 return last_hfinfo;
1109 }
1110
1111 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1112
1113 if (hfinfo) {
1114 g_free(last_field_name);
1115 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1116 last_hfinfo = hfinfo;
1117 return hfinfo;
1118 }
1119
1120 if (!prefixes)
1121 return NULL((void*)0);
1122
1123 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1124 pi(field_name);
1125 g_hash_table_remove(prefixes, field_name);
1126 } else {
1127 return NULL((void*)0);
1128 }
1129
1130 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1131
1132 if (hfinfo) {
1133 g_free(last_field_name);
1134 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1135 last_hfinfo = hfinfo;
1136 }
1137 return hfinfo;
1138}
1139
1140header_field_info*
1141proto_registrar_get_byalias(const char *alias_name)
1142{
1143 if (!alias_name) {
1144 return NULL((void*)0);
1145 }
1146
1147 /* Find our aliased protocol. */
1148 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1149 char *dot = strchr(an_copy, '.');
1150 if (dot) {
1151 *dot = '\0';
1152 }
1153 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1154 if (!proto_pfx) {
1155 g_free(an_copy);
1156 return NULL((void*)0);
1157 }
1158
1159 /* Construct our aliased field and look it up. */
1160 GString *filter_name = g_string_new(proto_pfx);
1161 if (dot) {
1162 g_string_append_printf(filter_name, ".%s", dot+1);
1163 }
1164 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1165 g_free(an_copy);
1166 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)))))
;
1167
1168 return hfinfo;
1169}
1170
1171int
1172proto_registrar_get_id_byname(const char *field_name)
1173{
1174 header_field_info *hfinfo;
1175
1176 hfinfo = proto_registrar_get_byname(field_name);
1177
1178 if (!hfinfo)
1179 return -1;
1180
1181 return hfinfo->id;
1182}
1183
1184static int
1185label_strcat_flags(const header_field_info *hfinfo)
1186{
1187 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1188 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1189
1190 return 0;
1191}
1192
1193static char *
1194format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1195 const uint8_t *bytes, unsigned length, size_t max_str_len)
1196{
1197 char *str = NULL((void*)0);
1198 const uint8_t *p;
1199 bool_Bool is_printable;
1200
1201 if (bytes) {
1202 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1203 /*
1204 * If all bytes are valid and printable UTF-8, show the
1205 * bytes as a string - in quotes to indicate that it's
1206 * a string.
1207 */
1208 if (isprint_utf8_string((const char*)bytes, length)) {
1209 str = wmem_strdup_printf(scope, "\"%.*s\"",
1210 (int)length, bytes);
1211 return str;
1212 }
1213 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1214 /*
1215 * Check whether all bytes are printable.
1216 */
1217 is_printable = true1;
1218 for (p = bytes; p < bytes+length; p++) {
1219 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1220 /* Not printable. */
1221 is_printable = false0;
1222 break;
1223 }
1224 }
1225
1226 /*
1227 * If all bytes are printable ASCII, show the bytes
1228 * as a string - in quotes to indicate that it's
1229 * a string.
1230 */
1231 if (is_printable) {
1232 str = wmem_strdup_printf(scope, "\"%.*s\"",
1233 (int)length, bytes);
1234 return str;
1235 }
1236 }
1237
1238 /*
1239 * Either it's not printable ASCII, or we don't care whether
1240 * it's printable ASCII; show it as hex bytes.
1241 */
1242 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1243 case SEP_DOT:
1244 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1245 break;
1246 case SEP_DASH:
1247 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1248 break;
1249 case SEP_COLON:
1250 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1251 break;
1252 case SEP_SPACE:
1253 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1254 break;
1255 case BASE_NONE:
1256 default:
1257 if (prefs.display_byte_fields_with_spaces) {
1258 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1259 } else {
1260 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1261 }
1262 break;
1263 }
1264 }
1265 else {
1266 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1267 str = wmem_strdup(scope, "<none>");
1268 } else {
1269 str = wmem_strdup(scope, "<MISSING>");
1270 }
1271 }
1272 return str;
1273}
1274
1275static char *
1276format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1277 const uint8_t *bytes, unsigned length)
1278{
1279 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1280}
1281
1282static void
1283ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1284{
1285 subtree_lvl *pushed_tree;
1286
1287 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"
, 1287, "ptvc->pushed_tree_max <= 256-8"))))
;
1288 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1289
1290 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1291 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1291, "pushed_tree != ((void*)0)"
))))
;
1292 ptvc->pushed_tree = pushed_tree;
1293}
1294
1295static void
1296ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1297{
1298 ptvc->pushed_tree = NULL((void*)0);
1299 ptvc->pushed_tree_max = 0;
1300 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", 1300, "ptvc->pushed_tree_index == 0"
))))
;
1301 ptvc->pushed_tree_index = 0;
1302}
1303
1304/* Allocates an initializes a ptvcursor_t with 3 variables:
1305 * proto_tree, tvbuff, and offset. */
1306ptvcursor_t *
1307ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, int offset)
1308{
1309 ptvcursor_t *ptvc;
1310
1311 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1312 ptvc->scope = scope;
1313 ptvc->tree = tree;
1314 ptvc->tvb = tvb;
1315 ptvc->offset = offset;
1316 ptvc->pushed_tree = NULL((void*)0);
1317 ptvc->pushed_tree_max = 0;
1318 ptvc->pushed_tree_index = 0;
1319 return ptvc;
1320}
1321
1322
1323/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1324void
1325ptvcursor_free(ptvcursor_t *ptvc)
1326{
1327 ptvcursor_free_subtree_levels(ptvc);
1328 /*g_free(ptvc);*/
1329}
1330
1331/* Returns tvbuff. */
1332tvbuff_t *
1333ptvcursor_tvbuff(ptvcursor_t *ptvc)
1334{
1335 return ptvc->tvb;
1336}
1337
1338/* Returns current offset. */
1339int
1340ptvcursor_current_offset(ptvcursor_t *ptvc)
1341{
1342 return ptvc->offset;
1343}
1344
1345proto_tree *
1346ptvcursor_tree(ptvcursor_t *ptvc)
1347{
1348 if (!ptvc)
1349 return NULL((void*)0);
1350
1351 return ptvc->tree;
1352}
1353
1354void
1355ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1356{
1357 ptvc->tree = tree;
1358}
1359
1360/* creates a subtree, sets it as the working tree and pushes the old working tree */
1361proto_tree *
1362ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1363{
1364 subtree_lvl *subtree;
1365 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1366 ptvcursor_new_subtree_levels(ptvc);
1367
1368 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1369 subtree->tree = ptvc->tree;
1370 subtree->it= NULL((void*)0);
1371 ptvc->pushed_tree_index++;
1372 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1373}
1374
1375/* pops a subtree */
1376void
1377ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1378{
1379 subtree_lvl *subtree;
1380
1381 if (ptvc->pushed_tree_index <= 0)
1382 return;
1383
1384 ptvc->pushed_tree_index--;
1385 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1386 if (subtree->it != NULL((void*)0))
1387 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1388
1389 ptvc->tree = subtree->tree;
1390}
1391
1392/* saves the current tvb offset and the item in the current subtree level */
1393static void
1394ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1395{
1396 subtree_lvl *subtree;
1397
1398 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", 1398, "ptvc->pushed_tree_index > 0"
))))
;
1399
1400 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1401 subtree->it = it;
1402 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1403}
1404
1405/* Creates a subtree and adds it to the cursor as the working tree but does not
1406 * save the old working tree */
1407proto_tree *
1408ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1409{
1410 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1411 return ptvc->tree;
1412}
1413
1414static proto_tree *
1415ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1416{
1417 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1418 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1419 ptvcursor_subtree_set_item(ptvc, it);
1420 return ptvcursor_tree(ptvc);
1421}
1422
1423/* Add an item to the tree and create a subtree
1424 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1425 * In this case, when the subtree will be closed, the parent item length will
1426 * be equal to the advancement of the cursor since the creation of the subtree.
1427 */
1428proto_tree *
1429ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1430 const unsigned encoding, int ett_subtree)
1431{
1432 proto_item *it;
1433
1434 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1435 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1436}
1437
1438static proto_item *
1439proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1440
1441/* Add a text node to the tree and create a subtree
1442 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1443 * In this case, when the subtree will be closed, the item length will be equal
1444 * to the advancement of the cursor since the creation of the subtree.
1445 */
1446proto_tree *
1447ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1448 int ett_subtree, const char *format, ...)
1449{
1450 proto_item *pi;
1451 va_list ap;
1452 header_field_info *hfinfo;
1453 proto_tree *tree;
1454
1455 tree = ptvcursor_tree(ptvc);
1456
1457 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1458
1459 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", 1459
, __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", 1459, "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", 1459, "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", 1459, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1460
1461 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1462 ptvcursor_current_offset(ptvc), length);
1463
1464 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1464, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1465
1466 va_start(ap, format)__builtin_va_start(ap, format);
1467 proto_tree_set_representation(pi, format, ap);
1468 va_end(ap)__builtin_va_end(ap);
1469
1470 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1471}
1472
1473/* Add a text-only node, leaving it to our caller to fill the text in */
1474static proto_item *
1475proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1476{
1477 proto_item *pi;
1478
1479 if (tree == NULL((void*)0))
1480 return NULL((void*)0);
1481
1482 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1483
1484 return pi;
1485}
1486
1487/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1488proto_item *
1489proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1490 const char *format, ...)
1491{
1492 proto_item *pi;
1493 va_list ap;
1494 header_field_info *hfinfo;
1495
1496 if (length == -1) {
1497 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1498 } else {
1499 tvb_ensure_bytes_exist(tvb, start, length);
1500 }
1501
1502 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1503
1504 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", 1504
, __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", 1504, "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", 1504, "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", 1504, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1505
1506 pi = proto_tree_add_text_node(tree, tvb, start, length);
1507
1508 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1508, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1509
1510 va_start(ap, format)__builtin_va_start(ap, format);
1511 proto_tree_set_representation(pi, format, ap);
1512 va_end(ap)__builtin_va_end(ap);
1513
1514 return pi;
1515}
1516
1517/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1518proto_item *
1519proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1520 int length, const char *format, va_list ap)
1521{
1522 proto_item *pi;
1523 header_field_info *hfinfo;
1524
1525 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1526 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1527 * the length to be what's in the tvbuff if length is -1, and the
1528 * minimum of length and what's in the tvbuff if not.
1529 */
1530
1531 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1532
1533 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", 1533
, __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", 1533, "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", 1533, "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", 1533, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1534
1535 pi = proto_tree_add_text_node(tree, tvb, start, length);
1536
1537 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1537, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1538
1539 proto_tree_set_representation(pi, format, ap);
1540
1541 return pi;
1542}
1543
1544/* Add a text-only node that creates a subtree underneath.
1545 */
1546proto_tree *
1547proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1548{
1549 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1550}
1551
1552/* Add a text-only node that creates a subtree underneath.
1553 */
1554proto_tree *
1555proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1556{
1557 proto_tree *pt;
1558 proto_item *pi;
1559 va_list ap;
1560
1561 va_start(ap, format)__builtin_va_start(ap, format);
1562 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1563 va_end(ap)__builtin_va_end(ap);
1564
1565 if (tree_item != NULL((void*)0))
1566 *tree_item = pi;
1567
1568 pt = proto_item_add_subtree(pi, idx);
1569
1570 return pt;
1571}
1572
1573/* Add a text-only node for debugging purposes. The caller doesn't need
1574 * to worry about tvbuff, start, or length. Debug message gets sent to
1575 * STDOUT, too */
1576proto_item *
1577proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1578{
1579 proto_item *pi;
1580 va_list ap;
1581
1582 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1583
1584 if (pi) {
1585 va_start(ap, format)__builtin_va_start(ap, format);
1586 proto_tree_set_representation(pi, format, ap);
1587 va_end(ap)__builtin_va_end(ap);
1588 }
1589 va_start(ap, format)__builtin_va_start(ap, format);
1590 vprintf(format, ap);
1591 va_end(ap)__builtin_va_end(ap);
1592 printf("\n");
1593
1594 return pi;
1595}
1596
1597proto_item *
1598proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1599{
1600 proto_item *pi;
1601 header_field_info *hfinfo;
1602
1603 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1604
1605 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", 1605
, __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", 1605, "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", 1605, "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", 1605, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1606
1607 pi = proto_tree_add_text_node(tree, tvb, start, length);
1608
1609 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1609, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1610
1611 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1612
1613 return pi;
1614}
1615
1616proto_item *
1617proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1618{
1619 proto_item *pi;
1620 header_field_info *hfinfo;
1621 char *str;
1622
1623 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1624
1625 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", 1625
, __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", 1625, "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", 1625, "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", 1625, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1626
1627 pi = proto_tree_add_text_node(tree, tvb, start, length);
1628
1629 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1629, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1630
1631 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1632 proto_item_set_text(pi, "%s", str);
1633 wmem_free(NULL((void*)0), str);
1634
1635 return pi;
1636}
1637
1638void proto_report_dissector_bug(const char *format, ...)
1639{
1640 va_list args;
1641
1642 if (wireshark_abort_on_dissector_bug) {
1643 /*
1644 * Try to have the error message show up in the crash
1645 * information.
1646 */
1647 va_start(args, format)__builtin_va_start(args, format);
1648 ws_vadd_crash_info(format, args);
1649 va_end(args)__builtin_va_end(args);
1650
1651 /*
1652 * Print the error message.
1653 */
1654 va_start(args, format)__builtin_va_start(args, format);
1655 vfprintf(stderrstderr, format, args);
1656 va_end(args)__builtin_va_end(args);
1657 putc('\n', stderrstderr);
1658
1659 /*
1660 * And crash.
1661 */
1662 abort();
1663 } else {
1664 va_start(args, format)__builtin_va_start(args, format);
1665 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1666 va_end(args)__builtin_va_end(args);
1667 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1667
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1668 }
1669}
1670
1671/* We could probably get away with changing is_error to a minimum length value. */
1672static void
1673report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1674{
1675 if (is_error) {
1676 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1677 } else {
1678 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1679 }
1680
1681 if (is_error) {
1682 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1683 }
1684}
1685
1686static uint32_t
1687get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1688{
1689 uint32_t value;
1690 bool_Bool length_error;
1691
1692 switch (length) {
1693
1694 case 1:
1695 value = tvb_get_uint8(tvb, offset);
1696 if (encoding & ENC_ZIGBEE0x40000000) {
1697 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1698 value = 0;
1699 }
1700 }
1701 break;
1702
1703 case 2:
1704 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1705 : tvb_get_ntohs(tvb, offset);
1706 if (encoding & ENC_ZIGBEE0x40000000) {
1707 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1708 value = 0;
1709 }
1710 }
1711 break;
1712
1713 case 3:
1714 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1715 : tvb_get_ntoh24(tvb, offset);
1716 break;
1717
1718 case 4:
1719 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1720 : tvb_get_ntohl(tvb, offset);
1721 break;
1722
1723 default:
1724 if (length < 1) {
1725 length_error = true1;
1726 value = 0;
1727 } else {
1728 length_error = false0;
1729 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1730 : tvb_get_ntohl(tvb, offset);
1731 }
1732 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1733 break;
1734 }
1735 return value;
1736}
1737
1738static inline uint64_t
1739get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1740{
1741 uint64_t value;
1742
1743 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1744
1745 if (length < 1 || length > 8) {
1746 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1747 }
1748
1749 return value;
1750}
1751
1752static int32_t
1753get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1754{
1755 int32_t value;
1756 bool_Bool length_error;
1757
1758 switch (length) {
1759
1760 case 1:
1761 value = tvb_get_int8(tvb, offset);
1762 break;
1763
1764 case 2:
1765 value = encoding ? tvb_get_letohis(tvb, offset)
1766 : tvb_get_ntohis(tvb, offset);
1767 break;
1768
1769 case 3:
1770 value = encoding ? tvb_get_letohi24(tvb, offset)
1771 : tvb_get_ntohi24(tvb, offset);
1772 break;
1773
1774 case 4:
1775 value = encoding ? tvb_get_letohil(tvb, offset)
1776 : tvb_get_ntohil(tvb, offset);
1777 break;
1778
1779 default:
1780 if (length < 1) {
1781 length_error = true1;
1782 value = 0;
1783 } else {
1784 length_error = false0;
1785 value = encoding ? tvb_get_letohil(tvb, offset)
1786 : tvb_get_ntohil(tvb, offset);
1787 }
1788 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1789 break;
1790 }
1791 return value;
1792}
1793
1794/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1795 * be cast-able as a int64_t. This is weird, but what the code has always done.
1796 */
1797static inline uint64_t
1798get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1799{
1800 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1801
1802 switch (length) {
1803 case 7:
1804 value = ws_sign_ext64(value, 56);
1805 break;
1806 case 6:
1807 value = ws_sign_ext64(value, 48);
1808 break;
1809 case 5:
1810 value = ws_sign_ext64(value, 40);
1811 break;
1812 case 4:
1813 value = ws_sign_ext64(value, 32);
1814 break;
1815 case 3:
1816 value = ws_sign_ext64(value, 24);
1817 break;
1818 case 2:
1819 value = ws_sign_ext64(value, 16);
1820 break;
1821 case 1:
1822 value = ws_sign_ext64(value, 8);
1823 break;
1824 }
1825
1826 return value;
1827}
1828
1829/* For FT_STRING */
1830static inline const uint8_t *
1831get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1832 int length, int *ret_length, const unsigned encoding)
1833{
1834 if (length == -1) {
1835 length = tvb_ensure_captured_length_remaining(tvb, start);
1836 }
1837 *ret_length = length;
1838 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1839}
1840
1841/* For FT_STRINGZ */
1842static inline const uint8_t *
1843get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1844 int start, int length, int *ret_length, const unsigned encoding)
1845{
1846 const uint8_t *value;
1847
1848 if (length < -1) {
1849 report_type_length_mismatch(tree, "a string", length, true1);
1850 }
1851 if (length == -1) {
1852 /* This can throw an exception */
1853 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1854 } else {
1855 /* In this case, length signifies the length of the string.
1856 *
1857 * This could either be a null-padded string, which doesn't
1858 * necessarily have a '\0' at the end, or a null-terminated
1859 * string, with a trailing '\0'. (Yes, there are cases
1860 * where you have a string that's both counted and null-
1861 * terminated.)
1862 *
1863 * In the first case, we must allocate a buffer of length
1864 * "length+1", to make room for a trailing '\0'.
1865 *
1866 * In the second case, we don't assume that there is a
1867 * trailing '\0' there, as the packet might be malformed.
1868 * (XXX - should we throw an exception if there's no
1869 * trailing '\0'?) Therefore, we allocate a buffer of
1870 * length "length+1", and put in a trailing '\0', just to
1871 * be safe.
1872 *
1873 * (XXX - this would change if we made string values counted
1874 * rather than null-terminated.)
1875 */
1876 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1877 }
1878 *ret_length = length;
1879 return value;
1880}
1881
1882/* For FT_UINT_STRING */
1883static inline const uint8_t *
1884get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1885 tvbuff_t *tvb, int start, int length, int *ret_length,
1886 const unsigned encoding)
1887{
1888 uint32_t n;
1889 const uint8_t *value;
1890
1891 /* I believe it's ok if this is called with a NULL tree */
1892 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1893 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1894 length += n;
1895 *ret_length = length;
1896 return value;
1897}
1898
1899/* For FT_STRINGZPAD */
1900static inline const uint8_t *
1901get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1902 int length, int *ret_length, const unsigned encoding)
1903{
1904 /*
1905 * XXX - currently, string values are null-
1906 * terminated, so a "zero-padded" string
1907 * isn't special. If we represent string
1908 * values as something that includes a counted
1909 * array of bytes, we'll need to strip the
1910 * trailing NULs.
1911 */
1912 if (length == -1) {
1913 length = tvb_ensure_captured_length_remaining(tvb, start);
1914 }
1915 *ret_length = length;
1916 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1917}
1918
1919/* For FT_STRINGZTRUNC */
1920static inline const uint8_t *
1921get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1922 int length, int *ret_length, const unsigned encoding)
1923{
1924 /*
1925 * XXX - currently, string values are null-
1926 * terminated, so a "zero-truncated" string
1927 * isn't special. If we represent string
1928 * values as something that includes a counted
1929 * array of bytes, we'll need to strip everything
1930 * starting with the terminating NUL.
1931 */
1932 if (length == -1) {
1933 length = tvb_ensure_captured_length_remaining(tvb, start);
1934 }
1935 *ret_length = length;
1936 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1937}
1938
1939/*
1940 * Deltas between the epochs for various non-UN*X time stamp formats and
1941 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1942 * stamp format.
1943 */
1944
1945/*
1946 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1947 * XXX - if it's OK if this is unsigned, can we just use
1948 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1949 */
1950#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1951
1952/*
1953 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1954 */
1955#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1956
1957/* this can be called when there is no tree, so tree may be null */
1958static void
1959get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1960 const int length, const unsigned encoding, nstime_t *time_stamp,
1961 const bool_Bool is_relative)
1962{
1963 uint32_t tmpsecs;
1964 uint64_t tmp64secs;
1965 uint64_t todusecs;
1966
1967 switch (encoding) {
1968
1969 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1970 /*
1971 * If the length is 16, 8-byte seconds, followed
1972 * by 8-byte fractional time in nanoseconds,
1973 * both big-endian.
1974 *
1975 * If the length is 12, 8-byte seconds, followed
1976 * by 4-byte fractional time in nanoseconds,
1977 * both big-endian.
1978 *
1979 * If the length is 8, 4-byte seconds, followed
1980 * by 4-byte fractional time in nanoseconds,
1981 * both big-endian.
1982 *
1983 * For absolute times, the seconds are seconds
1984 * since the UN*X epoch.
1985 */
1986 if (length == 16) {
1987 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1988 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1989 } else if (length == 12) {
1990 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1991 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1992 } else if (length == 8) {
1993 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1994 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1995 } else if (length == 4) {
1996 /*
1997 * Backwards compatibility.
1998 * ENC_TIME_SECS_NSECS is 0; using
1999 * ENC_BIG_ENDIAN by itself with a 4-byte
2000 * time-in-seconds value was done in the
2001 * past.
2002 */
2003 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2004 time_stamp->nsecs = 0;
2005 } else {
2006 time_stamp->secs = 0;
2007 time_stamp->nsecs = 0;
2008 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2009 }
2010 break;
2011
2012 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2013 /*
2014 * If the length is 16, 8-byte seconds, followed
2015 * by 8-byte fractional time in nanoseconds,
2016 * both little-endian.
2017 *
2018 * If the length is 12, 8-byte seconds, followed
2019 * by 4-byte fractional time in nanoseconds,
2020 * both little-endian.
2021 *
2022 * If the length is 8, 4-byte seconds, followed
2023 * by 4-byte fractional time in nanoseconds,
2024 * both little-endian.
2025 *
2026 * For absolute times, the seconds are seconds
2027 * since the UN*X epoch.
2028 */
2029 if (length == 16) {
2030 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2031 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2032 } else if (length == 12) {
2033 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2034 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2035 } else if (length == 8) {
2036 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2037 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2038 } else if (length == 4) {
2039 /*
2040 * Backwards compatibility.
2041 * ENC_TIME_SECS_NSECS is 0; using
2042 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2043 * time-in-seconds value was done in the
2044 * past.
2045 */
2046 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2047 time_stamp->nsecs = 0;
2048 } else {
2049 time_stamp->secs = 0;
2050 time_stamp->nsecs = 0;
2051 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2052 }
2053 break;
2054
2055 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2056 /*
2057 * NTP time stamp, big-endian.
2058 * Only supported for absolute times.
2059 */
2060 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2060, "!is_relative"
))))
;
2061
2062 /* We need a temporary variable here so the unsigned math
2063 * works correctly (for years > 2036 according to RFC 2030
2064 * chapter 3).
2065 *
2066 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2067 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2068 * If bit 0 is not set, the time is in the range 2036-2104 and
2069 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2070 */
2071 tmpsecs = tvb_get_ntohl(tvb, start);
2072 if ((tmpsecs & 0x80000000) != 0)
2073 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2074 else
2075 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2076
2077 if (length == 8) {
2078 tmp64secs = tvb_get_ntoh64(tvb, start);
2079 if (tmp64secs == 0) {
2080 //This is "NULL" time
2081 time_stamp->secs = 0;
2082 time_stamp->nsecs = 0;
2083 } else {
2084 /*
2085 * Convert 1/2^32s of a second to
2086 * nanoseconds.
2087 */
2088 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2089 }
2090 } else if (length == 4) {
2091 /*
2092 * Backwards compatibility.
2093 */
2094 if (tmpsecs == 0) {
2095 //This is "NULL" time
2096 time_stamp->secs = 0;
2097 }
2098 time_stamp->nsecs = 0;
2099 } else {
2100 time_stamp->secs = 0;
2101 time_stamp->nsecs = 0;
2102 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2103 }
2104 break;
2105
2106 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2107 /*
2108 * NTP time stamp, little-endian.
2109 * Only supported for absolute times.
2110 *
2111 * NTP doesn't use this, because it's an Internet format
2112 * and hence big-endian. Any implementation must decide
2113 * whether the NTP timestamp is a 64-bit unsigned fixed
2114 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2115 * with a 32-bit unsigned seconds field followed by a
2116 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2117 * the previous two).
2118 *
2119 * XXX: We do the latter, but no dissector uses this format.
2120 * OTOH, ERF timestamps do the former, so perhaps we
2121 * should switch the interpretation so that packet-erf.c
2122 * could use this directly?
2123 */
2124 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2124, "!is_relative"
))))
;
2125
2126 /* We need a temporary variable here so the unsigned math
2127 * works correctly (for years > 2036 according to RFC 2030
2128 * chapter 3).
2129 *
2130 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2131 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2132 * If bit 0 is not set, the time is in the range 2036-2104 and
2133 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2134 */
2135 tmpsecs = tvb_get_letohl(tvb, start);
2136 if ((tmpsecs & 0x80000000) != 0)
2137 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2138 else
2139 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2140
2141 if (length == 8) {
2142 tmp64secs = tvb_get_letoh64(tvb, start);
2143 if (tmp64secs == 0) {
2144 //This is "NULL" time
2145 time_stamp->secs = 0;
2146 time_stamp->nsecs = 0;
2147 } else {
2148 /*
2149 * Convert 1/2^32s of a second to
2150 * nanoseconds.
2151 */
2152 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2153 }
2154 } else if (length == 4) {
2155 /*
2156 * Backwards compatibility.
2157 */
2158 if (tmpsecs == 0) {
2159 //This is "NULL" time
2160 time_stamp->secs = 0;
2161 }
2162 time_stamp->nsecs = 0;
2163 } else {
2164 time_stamp->secs = 0;
2165 time_stamp->nsecs = 0;
2166 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2167 }
2168 break;
2169
2170 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2171 /*
2172 * S/3x0 and z/Architecture TOD clock time stamp,
2173 * big-endian. The epoch is January 1, 1900,
2174 * 00:00:00 (proleptic?) UTC.
2175 *
2176 * Only supported for absolute times.
2177 */
2178 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2178, "!is_relative"
))))
;
2179 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2179, "length == 8"
))))
;
2180
2181 if (length == 8) {
2182 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2183 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2184 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2185 } else {
2186 time_stamp->secs = 0;
2187 time_stamp->nsecs = 0;
2188 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2189 }
2190 break;
2191
2192 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2193 /*
2194 * S/3x0 and z/Architecture TOD clock time stamp,
2195 * little-endian. The epoch is January 1, 1900,
2196 * 00:00:00 (proleptic?) UTC.
2197 *
2198 * Only supported for absolute times.
2199 */
2200 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2200, "!is_relative"
))))
;
2201
2202 if (length == 8) {
2203 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2204 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2205 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2206 } else {
2207 time_stamp->secs = 0;
2208 time_stamp->nsecs = 0;
2209 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2210 }
2211 break;
2212
2213 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2214 /*
2215 * Time stamp using the same seconds/fraction format
2216 * as NTP, but with the origin of the time stamp being
2217 * the UNIX epoch rather than the NTP epoch; big-
2218 * endian.
2219 *
2220 * Only supported for absolute times.
2221 */
2222 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2222, "!is_relative"
))))
;
2223
2224 if (length == 8) {
2225 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2226 /*
2227 * Convert 1/2^32s of a second to nanoseconds.
2228 */
2229 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2230 } else {
2231 time_stamp->secs = 0;
2232 time_stamp->nsecs = 0;
2233 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2234 }
2235 break;
2236
2237 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2238 /*
2239 * Time stamp using the same seconds/fraction format
2240 * as NTP, but with the origin of the time stamp being
2241 * the UNIX epoch rather than the NTP epoch; little-
2242 * endian.
2243 *
2244 * Only supported for absolute times.
2245 *
2246 * The RTPS specification explicitly supports Little
2247 * Endian encoding. In one place, it states that its
2248 * Time_t representation "is the one defined by ...
2249 * RFC 1305", but in another explicitly defines it as
2250 * a struct consisting of an 32 bit unsigned seconds
2251 * field and a 32 bit unsigned fraction field, not a 64
2252 * bit fixed point, so we do that here.
2253 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2254 */
2255 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2255, "!is_relative"
))))
;
2256
2257 if (length == 8) {
2258 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2259 /*
2260 * Convert 1/2^32s of a second to nanoseconds.
2261 */
2262 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2263 } else {
2264 time_stamp->secs = 0;
2265 time_stamp->nsecs = 0;
2266 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2267 }
2268 break;
2269
2270 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2271 /*
2272 * MIP6 time stamp, big-endian.
2273 * A 64-bit unsigned integer field containing a timestamp. The
2274 * value indicates the number of seconds since January 1, 1970,
2275 * 00:00 UTC, by using a fixed point format. In this format, the
2276 * integer number of seconds is contained in the first 48 bits of
2277 * the field, and the remaining 16 bits indicate the number of
2278 * 1/65536 fractions of a second.
2279
2280 * Only supported for absolute times.
2281 */
2282 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2282, "!is_relative"
))))
;
2283
2284 if (length == 8) {
2285 /* We need a temporary variable here so the casting and fractions
2286 * of a second work correctly.
2287 */
2288 tmp64secs = tvb_get_ntoh48(tvb, start);
2289 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2290 tmpsecs <<= 16;
2291
2292 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2293 //This is "NULL" time
2294 time_stamp->secs = 0;
2295 time_stamp->nsecs = 0;
2296 } else {
2297 time_stamp->secs = (time_t)tmp64secs;
2298 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2299 }
2300 } else {
2301 time_stamp->secs = 0;
2302 time_stamp->nsecs = 0;
2303 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2304 }
2305 break;
2306
2307 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2308 /*
2309 * If the length is 16, 8-byte seconds, followed
2310 * by 8-byte fractional time in microseconds,
2311 * both big-endian.
2312 *
2313 * If the length is 12, 8-byte seconds, followed
2314 * by 4-byte fractional time in microseconds,
2315 * both big-endian.
2316 *
2317 * If the length is 8, 4-byte seconds, followed
2318 * by 4-byte fractional time in microseconds,
2319 * both big-endian.
2320 *
2321 * For absolute times, the seconds are seconds
2322 * since the UN*X epoch.
2323 */
2324 if (length == 16) {
2325 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2326 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2327 } else if (length == 12) {
2328 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2329 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2330 } else if (length == 8) {
2331 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2332 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2333 } else {
2334 time_stamp->secs = 0;
2335 time_stamp->nsecs = 0;
2336 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2337 }
2338 break;
2339
2340 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2341 /*
2342 * If the length is 16, 8-byte seconds, followed
2343 * by 8-byte fractional time in microseconds,
2344 * both little-endian.
2345 *
2346 * If the length is 12, 8-byte seconds, followed
2347 * by 4-byte fractional time in microseconds,
2348 * both little-endian.
2349 *
2350 * If the length is 8, 4-byte seconds, followed
2351 * by 4-byte fractional time in microseconds,
2352 * both little-endian.
2353 *
2354 * For absolute times, the seconds are seconds
2355 * since the UN*X epoch.
2356 */
2357 if (length == 16) {
2358 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2359 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2360 } else if (length == 12) {
2361 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2362 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2363 } else if (length == 8) {
2364 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2365 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2366 } else {
2367 time_stamp->secs = 0;
2368 time_stamp->nsecs = 0;
2369 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2370 }
2371 break;
2372
2373 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2374 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2375 /*
2376 * Seconds, 1 to 8 bytes.
2377 * For absolute times, it's seconds since the
2378 * UN*X epoch.
2379 */
2380 if (length >= 1 && length <= 8) {
2381 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2382 time_stamp->nsecs = 0;
2383 } else {
2384 time_stamp->secs = 0;
2385 time_stamp->nsecs = 0;
2386 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2387 }
2388 break;
2389
2390 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2391 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2392 /*
2393 * Milliseconds, 1 to 8 bytes.
2394 * For absolute times, it's milliseconds since the
2395 * UN*X epoch.
2396 */
2397 if (length >= 1 && length <= 8) {
2398 uint64_t msecs;
2399
2400 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2401 time_stamp->secs = (time_t)(msecs / 1000);
2402 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2403 } else {
2404 time_stamp->secs = 0;
2405 time_stamp->nsecs = 0;
2406 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2407 }
2408 break;
2409
2410 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2411 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2412 /*
2413 * Microseconds, 1 to 8 bytes.
2414 * For absolute times, it's microseconds since the
2415 * UN*X epoch.
2416 */
2417 if (length >= 1 && length <= 8) {
2418 uint64_t usecs;
2419
2420 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2421 time_stamp->secs = (time_t)(usecs / 1000000);
2422 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2423 } else {
2424 time_stamp->secs = 0;
2425 time_stamp->nsecs = 0;
2426 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2427 }
2428 break;
2429
2430 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2431 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2432 /*
2433 * nanoseconds, 1 to 8 bytes.
2434 * For absolute times, it's nanoseconds since the
2435 * UN*X epoch.
2436 */
2437
2438 if (length >= 1 && length <= 8) {
2439 uint64_t nsecs;
2440
2441 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2442 time_stamp->secs = (time_t)(nsecs / 1000000000);
2443 time_stamp->nsecs = (int)(nsecs % 1000000000);
2444 } else {
2445 time_stamp->secs = 0;
2446 time_stamp->nsecs = 0;
2447 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2448 }
2449 break;
2450
2451 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2452 /*
2453 * 1/64ths of a second since the UN*X epoch,
2454 * big-endian.
2455 *
2456 * Only supported for absolute times.
2457 */
2458 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2458, "!is_relative"
))))
;
2459
2460 if (length == 8) {
2461 /*
2462 * The upper 48 bits are seconds since the
2463 * UN*X epoch.
2464 */
2465 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2466 /*
2467 * The lower 16 bits are 1/2^16s of a second;
2468 * convert them to nanoseconds.
2469 *
2470 * XXX - this may give the impression of higher
2471 * precision than you actually get.
2472 */
2473 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2474 } else {
2475 time_stamp->secs = 0;
2476 time_stamp->nsecs = 0;
2477 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2478 }
2479 break;
2480
2481 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2482 /*
2483 * 1/64ths of a second since the UN*X epoch,
2484 * little-endian.
2485 *
2486 * Only supported for absolute times.
2487 */
2488 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2488, "!is_relative"
))))
;
2489
2490 if (length == 8) {
2491 /*
2492 * XXX - this is assuming that, if anybody
2493 * were ever to use this format - RFC 3971
2494 * doesn't, because that's an Internet
2495 * protocol, and those use network byte
2496 * order, i.e. big-endian - they'd treat it
2497 * as a 64-bit count of 1/2^16s of a second,
2498 * putting the upper 48 bits at the end.
2499 *
2500 * The lower 48 bits are seconds since the
2501 * UN*X epoch.
2502 */
2503 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2504 /*
2505 * The upper 16 bits are 1/2^16s of a second;
2506 * convert them to nanoseconds.
2507 *
2508 * XXX - this may give the impression of higher
2509 * precision than you actually get.
2510 */
2511 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2512 } else {
2513 time_stamp->secs = 0;
2514 time_stamp->nsecs = 0;
2515 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2516 }
2517 break;
2518
2519 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2520 /*
2521 * NTP time stamp, with 1-second resolution (i.e.,
2522 * seconds since the NTP epoch), big-endian.
2523 * Only supported for absolute times.
2524 */
2525 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2525, "!is_relative"
))))
;
2526
2527 if (length == 4) {
2528 /*
2529 * We need a temporary variable here so the unsigned math
2530 * works correctly (for years > 2036 according to RFC 2030
2531 * chapter 3).
2532 *
2533 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2534 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2535 * If bit 0 is not set, the time is in the range 2036-2104 and
2536 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2537 */
2538 tmpsecs = tvb_get_ntohl(tvb, start);
2539 if ((tmpsecs & 0x80000000) != 0)
2540 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2541 else
2542 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2543 time_stamp->nsecs = 0;
2544 } else {
2545 time_stamp->secs = 0;
2546 time_stamp->nsecs = 0;
2547 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2548 }
2549 break;
2550
2551 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2552 /*
2553 * NTP time stamp, with 1-second resolution (i.e.,
2554 * seconds since the NTP epoch), little-endian.
2555 * Only supported for absolute times.
2556 */
2557 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2557, "!is_relative"
))))
;
2558
2559 /*
2560 * We need a temporary variable here so the unsigned math
2561 * works correctly (for years > 2036 according to RFC 2030
2562 * chapter 3).
2563 *
2564 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2565 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2566 * If bit 0 is not set, the time is in the range 2036-2104 and
2567 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2568 */
2569 if (length == 4) {
2570 tmpsecs = tvb_get_letohl(tvb, start);
2571 if ((tmpsecs & 0x80000000) != 0)
2572 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2573 else
2574 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2575 time_stamp->nsecs = 0;
2576 } else {
2577 time_stamp->secs = 0;
2578 time_stamp->nsecs = 0;
2579 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2580 }
2581 break;
2582
2583 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2584 /*
2585 * Milliseconds, 6 to 8 bytes.
2586 * For absolute times, it's milliseconds since the
2587 * NTP epoch.
2588 *
2589 * ETSI TS 129.274 8.119 defines this as:
2590 * "a 48 bit unsigned integer in network order format
2591 * ...encoded as the number of milliseconds since
2592 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2593 * rounded value of 1000 x the value of the 64-bit
2594 * timestamp (Seconds + (Fraction / (1<<32))) defined
2595 * in clause 6 of IETF RFC 5905."
2596 *
2597 * Taken literally, the part after "i.e." would
2598 * mean that the value rolls over before reaching
2599 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2600 * when the 64 bit timestamp rolls over, and we have
2601 * to pick an NTP Era equivalence class to support
2602 * (such as 1968-01-20 to 2104-02-06).
2603 *
2604 * OTOH, the extra room might be used to store Era
2605 * information instead, in which case times until
2606 * 10819-08-03 can be represented with 6 bytes without
2607 * ambiguity. We handle both implementations, and assume
2608 * that times before 1968-01-20 are not represented.
2609 *
2610 * Only 6 bytes or more makes sense as an absolute
2611 * time. 5 bytes or fewer could express a span of
2612 * less than 35 years, either 1900-1934 or 2036-2070.
2613 */
2614 if (length >= 6 && length <= 8) {
2615 uint64_t msecs;
2616
2617 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2618 tmp64secs = (msecs / 1000);
2619 /*
2620 * Assume that times in the first half of NTP
2621 * Era 0 really represent times in the NTP
2622 * Era 1.
2623 */
2624 if (tmp64secs >= 0x80000000)
2625 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2626 else
2627 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2628 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2629 }
2630 else {
2631 time_stamp->secs = 0;
2632 time_stamp->nsecs = 0;
2633 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2634 }
2635 break;
2636
2637 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2638 /*
2639 * MP4 file time stamps, big-endian.
2640 * Only supported for absolute times.
2641 */
2642 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2642, "!is_relative"
))))
;
2643
2644 if (length == 8) {
2645 tmp64secs = tvb_get_ntoh64(tvb, start);
2646 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2647 time_stamp->nsecs = 0;
2648 } else if (length == 4) {
2649 tmpsecs = tvb_get_ntohl(tvb, start);
2650 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2651 time_stamp->nsecs = 0;
2652 } else {
2653 time_stamp->secs = 0;
2654 time_stamp->nsecs = 0;
2655 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2656 }
2657 break;
2658
2659 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2660 /*
2661 * Zigbee ZCL time stamps, big-endian.
2662 * Only supported for absolute times.
2663 */
2664 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2664, "!is_relative"
))))
;
2665
2666 if (length == 8) {
2667 tmp64secs = tvb_get_ntoh64(tvb, start);
2668 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);
2669 time_stamp->nsecs = 0;
2670 } else if (length == 4) {
2671 tmpsecs = tvb_get_ntohl(tvb, start);
2672 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2673 time_stamp->nsecs = 0;
2674 } else {
2675 time_stamp->secs = 0;
2676 time_stamp->nsecs = 0;
2677 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2678 }
2679 break;
2680
2681 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2682 /*
2683 * Zigbee ZCL time stamps, little-endian.
2684 * Only supported for absolute times.
2685 */
2686 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2686, "!is_relative"
))))
;
2687
2688 if (length == 8) {
2689 tmp64secs = tvb_get_letoh64(tvb, start);
2690 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);
2691 time_stamp->nsecs = 0;
2692 } else if (length == 4) {
2693 tmpsecs = tvb_get_letohl(tvb, start);
2694 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2695 time_stamp->nsecs = 0;
2696 } else {
2697 time_stamp->secs = 0;
2698 time_stamp->nsecs = 0;
2699 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2700 }
2701 break;
2702
2703 default:
2704 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2704))
;
2705 break;
2706 }
2707}
2708
2709static void
2710tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2711{
2712 const header_field_info *hfinfo = fi->hfinfo;
2713
2714 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2715 GPtrArray *ptrs = NULL((void*)0);
2716
2717 if (tree_data->interesting_hfids == NULL((void*)0)) {
2718 /* Initialize the hash because we now know that it is needed */
2719 tree_data->interesting_hfids =
2720 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2721 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2722 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2723 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2724 }
2725
2726 if (!ptrs) {
2727 /* First element triggers the creation of pointer array */
2728 ptrs = g_ptr_array_new();
2729 g_hash_table_insert(tree_data->interesting_hfids,
2730 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2731 }
2732
2733 g_ptr_array_add(ptrs, fi);
2734 }
2735}
2736
2737
2738/*
2739 * Validates that field length bytes are available starting from
2740 * start (pos/neg). Throws an exception if they aren't.
2741 */
2742static void
2743test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2744 int start, int length, const unsigned encoding)
2745{
2746 int size = length;
2747
2748 if (!tvb)
2749 return;
2750
2751 if ((hfinfo->type == FT_STRINGZ) ||
2752 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2753 (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
))
))) {
2754 /* If we're fetching until the end of the TVB, only validate
2755 * that the offset is within range.
2756 */
2757 if (length == -1)
2758 size = 0;
2759 }
2760
2761 tvb_ensure_bytes_exist(tvb, start, size);
2762}
2763
2764static void
2765detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2766{
2767 bool_Bool found_stray_character = false0;
2768
2769 if (!string)
2770 return;
2771
2772 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2773 case ENC_ASCII0x00000000:
2774 case ENC_UTF_80x00000002:
2775 for (int i = (int)strlen(string); i < length; i++) {
2776 if (string[i] != '\0') {
2777 found_stray_character = true1;
2778 break;
2779 }
2780 }
2781 break;
2782
2783 default:
2784 break;
2785 }
2786
2787 if (found_stray_character) {
2788 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2789 }
2790}
2791
2792static void
2793free_fvalue_cb(void *data)
2794{
2795 fvalue_t *fv = (fvalue_t*)data;
2796 fvalue_free(fv);
2797}
2798
2799/* Add an item to a proto_tree, using the text label registered to that item;
2800 the item is extracted from the tvbuff handed to it. */
2801static proto_item *
2802proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2803 tvbuff_t *tvb, int start, int length,
2804 unsigned encoding)
2805{
2806 proto_item *pi;
2807 uint32_t value, n;
2808 uint64_t value64;
2809 ws_in4_addr ipv4_value;
2810 float floatval;
2811 double doubleval;
2812 const char *stringval = NULL((void*)0);
2813 nstime_t time_stamp;
2814 bool_Bool length_error;
2815
2816 /* Ensure that the newly created fvalue_t is freed if we throw an
2817 * exception before adding it to the tree. (gcc creates clobbering
2818 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2819 * XXX: Move the new_field_info() call inside here?
2820 */
2821 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))
;
2822
2823 switch (new_fi->hfinfo->type) {
2824 case FT_NONE:
2825 /* no value to set for FT_NONE */
2826 break;
2827
2828 case FT_PROTOCOL:
2829 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2830 break;
2831
2832 case FT_BYTES:
2833 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2834 break;
2835
2836 case FT_UINT_BYTES:
2837 n = get_uint_value(tree, tvb, start, length, encoding);
2838 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2839
2840 /* Instead of calling proto_item_set_len(), since we don't yet
2841 * have a proto_item, we set the field_info's length ourselves. */
2842 new_fi->length = n + length;
2843 break;
2844
2845 case FT_BOOLEAN:
2846 /*
2847 * Map all non-zero values to little-endian for
2848 * backwards compatibility.
2849 */
2850 if (encoding)
2851 encoding = ENC_LITTLE_ENDIAN0x80000000;
2852 proto_tree_set_boolean(new_fi,
2853 get_uint64_value(tree, tvb, start, length, encoding));
2854 break;
2855
2856 case FT_CHAR:
2857 /* XXX - make these just FT_UINT? */
2858 case FT_UINT8:
2859 case FT_UINT16:
2860 case FT_UINT24:
2861 case FT_UINT32:
2862 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2863 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2864 value = (uint32_t)value64;
2865 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2866 new_fi->flags |= FI_VARINT0x00040000;
2867 }
2868 }
2869 else {
2870 /*
2871 * Map all non-zero values to little-endian for
2872 * backwards compatibility.
2873 */
2874 if (encoding)
2875 encoding = ENC_LITTLE_ENDIAN0x80000000;
2876
2877 value = get_uint_value(tree, tvb, start, length, encoding);
2878 }
2879 proto_tree_set_uint(new_fi, value);
2880 break;
2881
2882 case FT_UINT40:
2883 case FT_UINT48:
2884 case FT_UINT56:
2885 case FT_UINT64:
2886 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2887 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2888 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2889 new_fi->flags |= FI_VARINT0x00040000;
2890 }
2891 }
2892 else {
2893 /*
2894 * Map all other non-zero values to little-endian for
2895 * backwards compatibility.
2896 */
2897 if (encoding)
2898 encoding = ENC_LITTLE_ENDIAN0x80000000;
2899
2900 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2901 }
2902 proto_tree_set_uint64(new_fi, value64);
2903 break;
2904
2905 /* XXX - make these just FT_INT? */
2906 case FT_INT8:
2907 case FT_INT16:
2908 case FT_INT24:
2909 case FT_INT32:
2910 /*
2911 * Map all non-zero values to little-endian for
2912 * backwards compatibility.
2913 */
2914 if (encoding)
2915 encoding = ENC_LITTLE_ENDIAN0x80000000;
2916 proto_tree_set_int(new_fi,
2917 get_int_value(tree, tvb, start, length, encoding));
2918 break;
2919
2920 case FT_INT40:
2921 case FT_INT48:
2922 case FT_INT56:
2923 case FT_INT64:
2924 /*
2925 * Map all non-zero values to little-endian for
2926 * backwards compatibility.
2927 */
2928 if (encoding)
2929 encoding = ENC_LITTLE_ENDIAN0x80000000;
2930 proto_tree_set_int64(new_fi,
2931 get_int64_value(tree, tvb, start, length, encoding));
2932 break;
2933
2934 case FT_IPv4:
2935 /*
2936 * Map all non-zero values to little-endian for
2937 * backwards compatibility.
2938 */
2939 if (encoding)
2940 encoding = ENC_LITTLE_ENDIAN0x80000000;
2941 if (length != FT_IPv4_LEN4) {
2942 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2943 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2944 }
2945 ipv4_value = tvb_get_ipv4(tvb, start);
2946 /*
2947 * NOTE: to support code written when
2948 * proto_tree_add_item() took a bool as its
2949 * last argument, with false meaning "big-endian"
2950 * and true meaning "little-endian", we treat any
2951 * non-zero value of "encoding" as meaning
2952 * "little-endian".
2953 */
2954 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);
2955 break;
2956
2957 case FT_IPXNET:
2958 if (length != FT_IPXNET_LEN4) {
2959 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2960 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2961 }
2962 proto_tree_set_ipxnet(new_fi,
2963 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2964 break;
2965
2966 case FT_IPv6:
2967 if (length != FT_IPv6_LEN16) {
2968 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2969 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2970 }
2971 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2972 break;
2973
2974 case FT_FCWWN:
2975 if (length != FT_FCWWN_LEN8) {
2976 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2977 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2978 }
2979 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2980 break;
2981
2982 case FT_AX25:
2983 if (length != 7) {
2984 length_error = length < 7 ? true1 : false0;
2985 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2986 }
2987 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2988 break;
2989
2990 case FT_VINES:
2991 if (length != VINES_ADDR_LEN6) {
2992 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
2993 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2994 }
2995 proto_tree_set_vines_tvb(new_fi, tvb, start);
2996 break;
2997
2998 case FT_ETHER:
2999 if (length != FT_ETHER_LEN6) {
3000 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3001 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3002 }
3003 proto_tree_set_ether_tvb(new_fi, tvb, start);
3004 break;
3005
3006 case FT_EUI64:
3007 /*
3008 * Map all non-zero values to little-endian for
3009 * backwards compatibility.
3010 */
3011 if (encoding)
3012 encoding = ENC_LITTLE_ENDIAN0x80000000;
3013 if (length != FT_EUI64_LEN8) {
3014 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3015 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3016 }
3017 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3018 break;
3019 case FT_GUID:
3020 /*
3021 * Map all non-zero values to little-endian for
3022 * backwards compatibility.
3023 */
3024 if (encoding)
3025 encoding = ENC_LITTLE_ENDIAN0x80000000;
3026 if (length != FT_GUID_LEN16) {
3027 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3028 report_type_length_mismatch(tree, "a GUID", length, length_error);
3029 }
3030 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3031 break;
3032
3033 case FT_OID:
3034 case FT_REL_OID:
3035 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3036 break;
3037
3038 case FT_SYSTEM_ID:
3039 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3040 break;
3041
3042 case FT_FLOAT:
3043 /*
3044 * NOTE: to support code written when
3045 * proto_tree_add_item() took a bool as its
3046 * last argument, with false meaning "big-endian"
3047 * and true meaning "little-endian", we treat any
3048 * non-zero value of "encoding" as meaning
3049 * "little-endian".
3050 *
3051 * At some point in the future, we might
3052 * support non-IEEE-binary floating-point
3053 * formats in the encoding as well
3054 * (IEEE decimal, System/3x0, VAX).
3055 */
3056 if (encoding)
3057 encoding = ENC_LITTLE_ENDIAN0x80000000;
3058 if (length != 4) {
3059 length_error = length < 4 ? true1 : false0;
3060 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3061 }
3062 if (encoding)
3063 floatval = tvb_get_letohieee_float(tvb, start);
3064 else
3065 floatval = tvb_get_ntohieee_float(tvb, start);
3066 proto_tree_set_float(new_fi, floatval);
3067 break;
3068
3069 case FT_DOUBLE:
3070 /*
3071 * NOTE: to support code written when
3072 * proto_tree_add_item() took a bool as its
3073 * last argument, with false meaning "big-endian"
3074 * and true meaning "little-endian", we treat any
3075 * non-zero value of "encoding" as meaning
3076 * "little-endian".
3077 *
3078 * At some point in the future, we might
3079 * support non-IEEE-binary floating-point
3080 * formats in the encoding as well
3081 * (IEEE decimal, System/3x0, VAX).
3082 */
3083 if (encoding == true1)
3084 encoding = ENC_LITTLE_ENDIAN0x80000000;
3085 if (length != 8) {
3086 length_error = length < 8 ? true1 : false0;
3087 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3088 }
3089 if (encoding)
3090 doubleval = tvb_get_letohieee_double(tvb, start);
3091 else
3092 doubleval = tvb_get_ntohieee_double(tvb, start);
3093 proto_tree_set_double(new_fi, doubleval);
3094 break;
3095
3096 case FT_STRING:
3097 stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3098 tvb, start, length, &length, encoding);
3099 proto_tree_set_string(new_fi, stringval);
3100
3101 /* Instead of calling proto_item_set_len(), since we
3102 * don't yet have a proto_item, we set the
3103 * field_info's length ourselves.
3104 *
3105 * XXX - our caller can't use that length to
3106 * advance an offset unless they arrange that
3107 * there always be a protocol tree into which
3108 * we're putting this item.
3109 */
3110 new_fi->length = length;
3111 break;
3112
3113 case FT_STRINGZ:
3114 stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3115 tree, tvb, start, length, &length, encoding);
3116 proto_tree_set_string(new_fi, stringval);
3117
3118 /* Instead of calling proto_item_set_len(),
3119 * since we don't yet have a proto_item, we
3120 * set the field_info's length ourselves.
3121 *
3122 * XXX - our caller can't use that length to
3123 * advance an offset unless they arrange that
3124 * there always be a protocol tree into which
3125 * we're putting this item.
3126 */
3127 new_fi->length = length;
3128 break;
3129
3130 case FT_UINT_STRING:
3131 /*
3132 * NOTE: to support code written when
3133 * proto_tree_add_item() took a bool as its
3134 * last argument, with false meaning "big-endian"
3135 * and true meaning "little-endian", if the
3136 * encoding value is true, treat that as
3137 * ASCII with a little-endian length.
3138 *
3139 * This won't work for code that passes
3140 * arbitrary non-zero values; that code
3141 * will need to be fixed.
3142 */
3143 if (encoding == true1)
3144 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3145 stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3146 tree, tvb, start, length, &length, encoding);
3147 proto_tree_set_string(new_fi, stringval);
3148
3149 /* Instead of calling proto_item_set_len(), since we
3150 * don't yet have a proto_item, we set the
3151 * field_info's length ourselves.
3152 *
3153 * XXX - our caller can't use that length to
3154 * advance an offset unless they arrange that
3155 * there always be a protocol tree into which
3156 * we're putting this item.
3157 */
3158 new_fi->length = length;
3159 break;
3160
3161 case FT_STRINGZPAD:
3162 stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3163 tvb, start, length, &length, encoding);
3164 proto_tree_set_string(new_fi, stringval);
3165
3166 /* Instead of calling proto_item_set_len(), since we
3167 * don't yet have a proto_item, we set the
3168 * field_info's length ourselves.
3169 *
3170 * XXX - our caller can't use that length to
3171 * advance an offset unless they arrange that
3172 * there always be a protocol tree into which
3173 * we're putting this item.
3174 */
3175 new_fi->length = length;
3176 break;
3177
3178 case FT_STRINGZTRUNC:
3179 stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3180 tvb, start, length, &length, encoding);
3181 proto_tree_set_string(new_fi, stringval);
3182
3183 /* Instead of calling proto_item_set_len(), since we
3184 * don't yet have a proto_item, we set the
3185 * field_info's length ourselves.
3186 *
3187 * XXX - our caller can't use that length to
3188 * advance an offset unless they arrange that
3189 * there always be a protocol tree into which
3190 * we're putting this item.
3191 */
3192 new_fi->length = length;
3193 break;
3194
3195 case FT_ABSOLUTE_TIME:
3196 /*
3197 * Absolute times can be in any of a number of
3198 * formats, and they can be big-endian or
3199 * little-endian.
3200 *
3201 * Historically FT_TIMEs were only timespecs;
3202 * the only question was whether they were stored
3203 * in big- or little-endian format.
3204 *
3205 * For backwards compatibility, we interpret an
3206 * encoding of 1 as meaning "little-endian timespec",
3207 * so that passing true is interpreted as that.
3208 */
3209 if (encoding == true1)
3210 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3211
3212 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3213
3214 proto_tree_set_time(new_fi, &time_stamp);
3215 break;
3216
3217 case FT_RELATIVE_TIME:
3218 /*
3219 * Relative times can be in any of a number of
3220 * formats, and they can be big-endian or
3221 * little-endian.
3222 *
3223 * Historically FT_TIMEs were only timespecs;
3224 * the only question was whether they were stored
3225 * in big- or little-endian format.
3226 *
3227 * For backwards compatibility, we interpret an
3228 * encoding of 1 as meaning "little-endian timespec",
3229 * so that passing true is interpreted as that.
3230 */
3231 if (encoding == true1)
3232 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3233
3234 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3235
3236 proto_tree_set_time(new_fi, &time_stamp);
3237 break;
3238 case FT_IEEE_11073_SFLOAT:
3239 if (encoding)
3240 encoding = ENC_LITTLE_ENDIAN0x80000000;
3241 if (length != 2) {
3242 length_error = length < 2 ? true1 : false0;
3243 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3244 }
3245
3246 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3247
3248 break;
3249 case FT_IEEE_11073_FLOAT:
3250 if (encoding)
3251 encoding = ENC_LITTLE_ENDIAN0x80000000;
3252 if (length != 4) {
3253 length_error = length < 4 ? true1 : false0;
3254 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3255 }
3256 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3257
3258 break;
3259 default:
3260 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))
3261 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))
3262 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))
3263 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))
;
3264 break;
3265 }
3266 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)
;
3267
3268 /* Don't add new node to proto_tree until now so that any exceptions
3269 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3270 /* XXX. wouldn't be better to add this item to tree, with some special
3271 * flag (FI_EXCEPTION?) to know which item caused exception? For
3272 * strings and bytes, we would have to set new_fi->value to something
3273 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3274 * could handle NULL values. */
3275 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3276 pi = proto_tree_add_node(tree, new_fi);
3277
3278 switch (new_fi->hfinfo->type) {
3279
3280 case FT_STRING:
3281 /* XXX: trailing stray character detection should be done
3282 * _before_ conversion to UTF-8, because conversion can change
3283 * the length, or else get_string_length should return a value
3284 * for the "length in bytes of the string after conversion
3285 * including internal nulls." (Noting that we do, for other
3286 * reasons, still need the "length in bytes in the field",
3287 * especially for FT_STRINGZ.)
3288 *
3289 * This is true even for ASCII and UTF-8, because
3290 * substituting REPLACEMENT CHARACTERS for illegal characters
3291 * can also do so (and for UTF-8 possibly even make the
3292 * string _shorter_).
3293 */
3294 detect_trailing_stray_characters(encoding, stringval, length, pi);
3295 break;
3296
3297 default:
3298 break;
3299 }
3300
3301 return pi;
3302}
3303
3304proto_item *
3305proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3306 const int start, int length,
3307 const unsigned encoding, int32_t *retval)
3308{
3309 header_field_info *hfinfo;
3310 field_info *new_fi;
3311 int32_t value;
3312
3313 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3313, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3313,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3313, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3314
3315 switch (hfinfo->type) {
3316 case FT_INT8:
3317 case FT_INT16:
3318 case FT_INT24:
3319 case FT_INT32:
3320 break;
3321 case FT_INT64:
3322 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)
3323 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3324 default:
3325 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)
3326 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3327 }
3328
3329 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3330 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3331 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3332 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3333 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3334 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3335 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3336
3337 if (encoding & ENC_STRING0x03000000) {
3338 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3339 }
3340 /* I believe it's ok if this is called with a NULL tree */
3341 value = get_int_value(tree, tvb, start, length, encoding);
3342
3343 if (retval) {
3344 int no_of_bits;
3345 *retval = value;
3346 if (hfinfo->bitmask) {
3347 /* Mask out irrelevant portions */
3348 *retval &= (uint32_t)(hfinfo->bitmask);
3349 /* Shift bits */
3350 *retval >>= hfinfo_bitshift(hfinfo);
3351 }
3352 no_of_bits = ws_count_ones(hfinfo->bitmask);
3353 *retval = ws_sign_ext32(*retval, no_of_bits);
3354 }
3355
3356 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3357
3358 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", 3358
, __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", 3358, "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", 3358, "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", 3358, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3359
3360 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3361
3362 proto_tree_set_int(new_fi, value);
3363
3364 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3365
3366 return proto_tree_add_node(tree, new_fi);
3367}
3368
3369proto_item *
3370proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3371 const int start, int length,
3372 const unsigned encoding, uint32_t *retval)
3373{
3374 header_field_info *hfinfo;
3375 field_info *new_fi;
3376 uint32_t value;
3377
3378 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", 3378, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3378,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3378, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3379
3380 switch (hfinfo->type) {
3381 case FT_CHAR:
3382 case FT_UINT8:
3383 case FT_UINT16:
3384 case FT_UINT24:
3385 case FT_UINT32:
3386 break;
3387 default:
3388 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)
3389 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)
;
3390 }
3391
3392 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3393 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3394 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3395 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3396 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3397 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3398 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3399
3400 if (encoding & ENC_STRING0x03000000) {
3401 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3402 }
3403 /* I believe it's ok if this is called with a NULL tree */
3404 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3405 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3406 uint64_t temp64;
3407 tvb_get_varint(tvb, start, length, &temp64, encoding);
3408 value = (uint32_t)temp64;
3409 } else {
3410 value = get_uint_value(tree, tvb, start, length, encoding);
3411 }
3412
3413 if (retval) {
3414 *retval = value;
3415 if (hfinfo->bitmask) {
3416 /* Mask out irrelevant portions */
3417 *retval &= (uint32_t)(hfinfo->bitmask);
3418 /* Shift bits */
3419 *retval >>= hfinfo_bitshift(hfinfo);
3420 }
3421 }
3422
3423 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3424
3425 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", 3425
, __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", 3425, "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", 3425, "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", 3425, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3426
3427 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3428
3429 proto_tree_set_uint(new_fi, value);
3430
3431 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3432 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3433 new_fi->flags |= FI_VARINT0x00040000;
3434 }
3435 return proto_tree_add_node(tree, new_fi);
3436}
3437
3438/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3439 * and returns proto_item* and uint value retrieved*/
3440proto_item *
3441ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3442 const unsigned encoding, uint32_t *retval)
3443{
3444 field_info *new_fi;
3445 header_field_info *hfinfo;
3446 int item_length;
3447 int offset;
3448 uint32_t value;
3449
3450 offset = ptvc->offset;
3451 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", 3451, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3451,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3451, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3452
3453 switch (hfinfo->type) {
3454 case FT_CHAR:
3455 case FT_UINT8:
3456 case FT_UINT16:
3457 case FT_UINT24:
3458 case FT_UINT32:
3459 break;
3460 default:
3461 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)
3462 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)
;
3463 }
3464
3465 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3466 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3467
3468 /* I believe it's ok if this is called with a NULL tree */
3469 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3470 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3471
3472 if (retval) {
3473 *retval = value;
3474 if (hfinfo->bitmask) {
3475 /* Mask out irrelevant portions */
3476 *retval &= (uint32_t)(hfinfo->bitmask);
3477 /* Shift bits */
3478 *retval >>= hfinfo_bitshift(hfinfo);
3479 }
3480 }
3481
3482 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3483
3484 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3485
3486 /* Coast clear. Try and fake it */
3487 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", 3487
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3487, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3487, "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", 3487, __func__, "Adding %s would put more than %d 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); } } }
;
3488
3489 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3490
3491 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3492 offset, length, encoding);
3493}
3494
3495/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3496 * and returns proto_item* and int value retrieved*/
3497proto_item *
3498ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3499 const unsigned encoding, int32_t *retval)
3500{
3501 field_info *new_fi;
3502 header_field_info *hfinfo;
3503 int item_length;
3504 int offset;
3505 uint32_t value;
3506
3507 offset = ptvc->offset;
3508 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", 3508, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3508,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3508, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3509
3510 switch (hfinfo->type) {
3511 case FT_INT8:
3512 case FT_INT16:
3513 case FT_INT24:
3514 case FT_INT32:
3515 break;
3516 default:
3517 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)
3518 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3519 }
3520
3521 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3522 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3523
3524 /* I believe it's ok if this is called with a NULL tree */
3525 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3526 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3527
3528 if (retval) {
3529 int no_of_bits;
3530 *retval = value;
3531 if (hfinfo->bitmask) {
3532 /* Mask out irrelevant portions */
3533 *retval &= (uint32_t)(hfinfo->bitmask);
3534 /* Shift bits */
3535 *retval >>= hfinfo_bitshift(hfinfo);
3536 }
3537 no_of_bits = ws_count_ones(hfinfo->bitmask);
3538 *retval = ws_sign_ext32(*retval, no_of_bits);
3539 }
3540
3541 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3542
3543 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3544
3545 /* Coast clear. Try and fake it */
3546 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", 3546
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3546, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3546, "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", 3546, __func__, "Adding %s would put more than %d 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); } } }
;
3547
3548 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3549
3550 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3551 offset, length, encoding);
3552}
3553
3554/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3555 * and returns proto_item* and string value retrieved */
3556proto_item*
3557ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3558{
3559 header_field_info *hfinfo;
3560 field_info *new_fi;
3561 const uint8_t *value;
3562 int item_length;
3563 int offset;
3564
3565 offset = ptvc->offset;
3566
3567 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", 3567
, __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", 3567, "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", 3567, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3568
3569 switch (hfinfo->type) {
3570 case FT_STRING:
3571 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3572 break;
3573 case FT_STRINGZ:
3574 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3575 break;
3576 case FT_UINT_STRING:
3577 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3578 break;
3579 case FT_STRINGZPAD:
3580 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3581 break;
3582 case FT_STRINGZTRUNC:
3583 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3584 break;
3585 default:
3586 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)
3587 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)
;
3588 }
3589
3590 if (retval)
3591 *retval = value;
3592
3593 ptvcursor_advance(ptvc, item_length);
3594
3595 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3596
3597 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", 3597, __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", 3597,
"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", 3597, "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", 3597
, __func__, "Adding %s would put more than %d 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); } } }
;
3598
3599 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3600
3601 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3602 offset, length, encoding);
3603}
3604
3605/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3606 * and returns proto_item* and boolean value retrieved */
3607proto_item*
3608ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3609{
3610 header_field_info *hfinfo;
3611 field_info *new_fi;
3612 int item_length;
3613 int offset;
3614 uint64_t value, bitval;
3615
3616 offset = ptvc->offset;
3617 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", 3617, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3617,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3617, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3618
3619 if (hfinfo->type != FT_BOOLEAN) {
3620 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)
3621 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3622 }
3623
3624 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3625 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3626 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3627 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3628 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3629 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3630 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3631
3632 if (encoding & ENC_STRING0x03000000) {
3633 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3634 }
3635
3636 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3637 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3638
3639 /* I believe it's ok if this is called with a NULL tree */
3640 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3641
3642 if (retval) {
3643 bitval = value;
3644 if (hfinfo->bitmask) {
3645 /* Mask out irrelevant portions */
3646 bitval &= hfinfo->bitmask;
3647 }
3648 *retval = (bitval != 0);
3649 }
3650
3651 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3652
3653 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3654
3655 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", 3655, __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", 3655,
"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", 3655, "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", 3655
, __func__, "Adding %s would put more than %d 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); } } }
;
3656
3657 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3658
3659 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3660 offset, length, encoding);
3661}
3662
3663proto_item *
3664proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3665 const int start, int length, const unsigned encoding, uint64_t *retval)
3666{
3667 header_field_info *hfinfo;
3668 field_info *new_fi;
3669 uint64_t value;
3670
3671 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", 3671, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3671,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3671, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3672
3673 switch (hfinfo->type) {
3674 case FT_UINT40:
3675 case FT_UINT48:
3676 case FT_UINT56:
3677 case FT_UINT64:
3678 break;
3679 default:
3680 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)
3681 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3682 }
3683
3684 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,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(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3687 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3688 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3689 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3690 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3691
3692 if (encoding & ENC_STRING0x03000000) {
3693 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3694 }
3695 /* I believe it's ok if this is called with a NULL tree */
3696 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3697 tvb_get_varint(tvb, start, length, &value, encoding);
3698 } else {
3699 value = get_uint64_value(tree, tvb, start, length, encoding);
3700 }
3701
3702 if (retval) {
3703 *retval = value;
3704 if (hfinfo->bitmask) {
3705 /* Mask out irrelevant portions */
3706 *retval &= hfinfo->bitmask;
3707 /* Shift bits */
3708 *retval >>= hfinfo_bitshift(hfinfo);
3709 }
3710 }
3711
3712 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3713
3714 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3714
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3714, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3714, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3714, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3715
3716 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3717
3718 proto_tree_set_uint64(new_fi, value);
3719
3720 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3721 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3722 new_fi->flags |= FI_VARINT0x00040000;
3723 }
3724
3725 return proto_tree_add_node(tree, new_fi);
3726}
3727
3728proto_item *
3729proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3730 const int start, int length, const unsigned encoding, int64_t *retval)
3731{
3732 header_field_info *hfinfo;
3733 field_info *new_fi;
3734 int64_t value;
3735
3736 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3736, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3736,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3736, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3737
3738 switch (hfinfo->type) {
3739 case FT_INT40:
3740 case FT_INT48:
3741 case FT_INT56:
3742 case FT_INT64:
3743 break;
3744 default:
3745 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)
3746 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3747 }
3748
3749 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,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(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3752 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3753 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3754 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3755 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3756
3757 if (encoding & ENC_STRING0x03000000) {
3758 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3759 }
3760 /* I believe it's ok if this is called with a NULL tree */
3761 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3762 tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3763 }
3764 else {
3765 value = get_int64_value(tree, tvb, start, length, encoding);
3766 }
3767
3768 if (retval) {
3769 *retval = value;
3770 }
3771
3772 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3773
3774 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", 3774
, __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", 3774, "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", 3774, "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", 3774, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3775
3776 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3777
3778 proto_tree_set_int64(new_fi, value);
3779
3780 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3781 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3782 new_fi->flags |= FI_VARINT0x00040000;
3783 }
3784
3785 return proto_tree_add_node(tree, new_fi);
3786}
3787
3788proto_item *
3789proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3790 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3791{
3792 header_field_info *hfinfo;
3793 field_info *new_fi;
3794 uint64_t value;
3795
3796 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", 3796, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3796,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3796, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3797
3798 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
))
)) {
3799 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)
3800 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3801 }
3802
3803 /* length validation for native number encoding caught by get_uint64_value() */
3804 /* length has to be -1 or > 0 regardless of encoding */
3805 if (length == 0)
3806 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)
3807 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3808
3809 if (encoding & ENC_STRING0x03000000) {
3810 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3811 }
3812
3813 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3814
3815 if (retval) {
3816 *retval = value;
3817 if (hfinfo->bitmask) {
3818 /* Mask out irrelevant portions */
3819 *retval &= hfinfo->bitmask;
3820 /* Shift bits */
3821 *retval >>= hfinfo_bitshift(hfinfo);
3822 }
3823 }
3824
3825 if (lenretval) {
3826 *lenretval = length;
3827 }
3828
3829 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3830
3831 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", 3831
, __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", 3831, "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", 3831, "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", 3831, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3832
3833 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3834
3835 proto_tree_set_uint64(new_fi, value);
3836
3837 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3838 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3839 new_fi->flags |= FI_VARINT0x00040000;
3840 }
3841
3842 return proto_tree_add_node(tree, new_fi);
3843
3844}
3845
3846proto_item *
3847proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3848 const int start, int length,
3849 const unsigned encoding, bool_Bool *retval)
3850{
3851 header_field_info *hfinfo;
3852 field_info *new_fi;
3853 uint64_t value, bitval;
3854
3855 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", 3855, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3855,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3855, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3856
3857 if (hfinfo->type != FT_BOOLEAN) {
3858 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)
3859 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3860 }
3861
3862 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,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(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3865 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3866 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3867 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3868 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3869
3870 if (encoding & ENC_STRING0x03000000) {
3871 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3872 }
3873 /* I believe it's ok if this is called with a NULL tree */
3874 value = get_uint64_value(tree, tvb, start, length, encoding);
3875
3876 if (retval) {
3877 bitval = value;
3878 if (hfinfo->bitmask) {
3879 /* Mask out irrelevant portions */
3880 bitval &= hfinfo->bitmask;
3881 }
3882 *retval = (bitval != 0);
3883 }
3884
3885 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3886
3887 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", 3887
, __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", 3887, "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", 3887, "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", 3887, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3888
3889 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3890
3891 proto_tree_set_boolean(new_fi, value);
3892
3893 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3894
3895 return proto_tree_add_node(tree, new_fi);
3896}
3897
3898proto_item *
3899proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3900 const int start, int length,
3901 const unsigned encoding, float *retval)
3902{
3903 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3904 field_info *new_fi;
3905 float value;
3906
3907 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", 3907,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3908
3909 if (hfinfo->type != FT_FLOAT) {
3910 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)
;
3911 }
3912
3913 if (length != 4) {
3914 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3915 }
3916
3917 /* treat any nonzero encoding as little endian for backwards compatibility */
3918 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3919 if (retval) {
3920 *retval = value;
3921 }
3922
3923 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3924
3925 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", 3925
, __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", 3925, "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", 3925, "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", 3925, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3926
3927 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3928 if (encoding) {
3929 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3930 }
3931
3932 proto_tree_set_float(new_fi, value);
3933
3934 return proto_tree_add_node(tree, new_fi);
3935}
3936
3937proto_item *
3938proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3939 const int start, int length,
3940 const unsigned encoding, double *retval)
3941{
3942 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3943 field_info *new_fi;
3944 double value;
3945
3946 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", 3946,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3947
3948 if (hfinfo->type != FT_DOUBLE) {
3949 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)
;
3950 }
3951
3952 if (length != 8) {
3953 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3954 }
3955
3956 /* treat any nonzero encoding as little endian for backwards compatibility */
3957 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3958 if (retval) {
3959 *retval = value;
3960 }
3961
3962 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3963
3964 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", 3964
, __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", 3964, "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", 3964, "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", 3964, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3965
3966 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3967 if (encoding) {
3968 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3969 }
3970
3971 proto_tree_set_double(new_fi, value);
3972
3973 return proto_tree_add_node(tree, new_fi);
3974}
3975
3976proto_item *
3977proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3978 const int start, int length,
3979 const unsigned encoding, ws_in4_addr *retval)
3980{
3981 header_field_info *hfinfo;
3982 field_info *new_fi;
3983 ws_in4_addr value;
3984
3985 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", 3985, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3985,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3985, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3986
3987 switch (hfinfo->type) {
3988 case FT_IPv4:
3989 break;
3990 default:
3991 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)
3992 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
3993 }
3994
3995 if (length != FT_IPv4_LEN4)
3996 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)
3997 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
3998
3999 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4000 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4001 }
4002
4003 /*
4004 * NOTE: to support code written when proto_tree_add_item() took
4005 * a bool as its last argument, with false meaning "big-endian"
4006 * and true meaning "little-endian", we treat any non-zero value
4007 * of "encoding" as meaning "little-endian".
4008 */
4009 value = tvb_get_ipv4(tvb, start);
4010 if (encoding)
4011 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))))
;
4012
4013 if (retval) {
4014 *retval = value;
4015 }
4016
4017 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4018
4019 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", 4019
, __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", 4019, "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", 4019, "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", 4019, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4020
4021 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4022
4023 proto_tree_set_ipv4(new_fi, value);
4024
4025 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4026 return proto_tree_add_node(tree, new_fi);
4027}
4028
4029proto_item *
4030proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4031 const int start, int length,
4032 const unsigned encoding, ws_in6_addr *addr)
4033{
4034 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4035 field_info *new_fi;
4036
4037 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", 4037,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4038
4039 switch (hfinfo->type) {
4040 case FT_IPv6:
4041 break;
4042 default:
4043 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)
4044 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4045 }
4046
4047 if (length != FT_IPv6_LEN16)
4048 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)
4049 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4050
4051 if (encoding) {
4052 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"
)
;
4053 }
4054
4055 tvb_get_ipv6(tvb, start, addr);
4056
4057 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4058
4059 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", 4059
, __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", 4059, "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", 4059, "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", 4059, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4060
4061 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4062
4063 proto_tree_set_ipv6(new_fi, addr);
4064
4065 return proto_tree_add_node(tree, new_fi);
4066}
4067
4068proto_item *
4069proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4070 const int start, int length, const unsigned encoding, uint8_t *retval) {
4071
4072 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4073 field_info *new_fi;
4074
4075 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", 4075,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4076
4077 switch (hfinfo->type) {
4078 case FT_ETHER:
4079 break;
4080 default:
4081 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)
4082 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4083 }
4084
4085 if (length != FT_ETHER_LEN6)
4086 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)
4087 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4088
4089 if (encoding) {
4090 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"
)
;
4091 }
4092
4093 tvb_memcpy(tvb, retval, start, length);
4094
4095 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4096
4097 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", 4097
, __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", 4097, "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", 4097, "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", 4097, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4098
4099 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4100
4101 proto_tree_set_ether(new_fi, retval);
4102
4103 return proto_tree_add_node(tree, new_fi);
4104}
4105
4106
4107proto_item *
4108proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4109 tvbuff_t *tvb,
4110 const int start, int length,
4111 const unsigned encoding,
4112 wmem_allocator_t *scope,
4113 const uint8_t **retval,
4114 int *lenretval)
4115{
4116 proto_item *pi;
4117 header_field_info *hfinfo;
4118 field_info *new_fi;
4119 const uint8_t *value;
4120
4121 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", 4121, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4121,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4121, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4122
4123 switch (hfinfo->type) {
4124 case FT_STRING:
4125 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4126 break;
4127 case FT_STRINGZ:
4128 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4129 break;
4130 case FT_UINT_STRING:
4131 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4132 break;
4133 case FT_STRINGZPAD:
4134 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4135 break;
4136 case FT_STRINGZTRUNC:
4137 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4138 break;
4139 default:
4140 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)
4141 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)
;
4142 }
4143
4144 if (retval)
4145 *retval = value;
4146
4147 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4148
4149 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", 4149
, __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", 4149, "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", 4149, "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", 4149, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4150
4151 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4152
4153 proto_tree_set_string(new_fi, (const char*)value);
4154
4155 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4156
4157 pi = proto_tree_add_node(tree, new_fi);
4158
4159 switch (hfinfo->type) {
4160
4161 case FT_STRINGZ:
4162 case FT_STRINGZPAD:
4163 case FT_STRINGZTRUNC:
4164 case FT_UINT_STRING:
4165 break;
4166
4167 case FT_STRING:
4168 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4169 break;
4170
4171 default:
4172 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4172
, __func__, "assertion \"not reached\" failed")
;
4173 }
4174
4175 return pi;
4176}
4177
4178proto_item *
4179proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4180 const int start, int length,
4181 const unsigned encoding, wmem_allocator_t *scope,
4182 const uint8_t **retval)
4183{
4184 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4185 tvb, start, length, encoding, scope, retval, &length);
4186}
4187
4188proto_item *
4189proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4190 tvbuff_t *tvb,
4191 const int start, int length,
4192 const unsigned encoding,
4193 wmem_allocator_t *scope,
4194 char **retval,
4195 int *lenretval)
4196{
4197 proto_item *pi;
4198 header_field_info *hfinfo;
4199 field_info *new_fi;
4200 const uint8_t *value;
4201 uint32_t n = 0;
4202
4203 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", 4203, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4203,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4203, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4204
4205 switch (hfinfo->type) {
4206 case FT_STRING:
4207 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4208 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4209 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4210 break;
4211 case FT_STRINGZ:
4212 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4213 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4214 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4215 break;
4216 case FT_UINT_STRING:
4217 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4218 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4219 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4220 break;
4221 case FT_STRINGZPAD:
4222 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4223 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4224 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4225 break;
4226 case FT_STRINGZTRUNC:
4227 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4228 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4229 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4230 break;
4231 case FT_BYTES:
4232 tvb_ensure_bytes_exist(tvb, start, length);
4233 value = tvb_get_ptr(tvb, start, length);
4234 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4235 *lenretval = length;
4236 break;
4237 case FT_UINT_BYTES:
4238 n = get_uint_value(tree, tvb, start, length, encoding);
4239 tvb_ensure_bytes_exist(tvb, start + length, n);
4240 value = tvb_get_ptr(tvb, start + length, n);
4241 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4242 *lenretval = length + n;
4243 break;
4244 default:
4245 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)
4246 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)
;
4247 }
4248
4249 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4250
4251 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", 4251
, __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", 4251, "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", 4251, "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", 4251, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4252
4253 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4254
4255 switch (hfinfo->type) {
4256
4257 case FT_STRING:
4258 case FT_STRINGZ:
4259 case FT_UINT_STRING:
4260 case FT_STRINGZPAD:
4261 case FT_STRINGZTRUNC:
4262 proto_tree_set_string(new_fi, (const char*)value);
4263 break;
4264
4265 case FT_BYTES:
4266 proto_tree_set_bytes(new_fi, value, length);
4267 break;
4268
4269 case FT_UINT_BYTES:
4270 proto_tree_set_bytes(new_fi, value, n);
4271 break;
4272
4273 default:
4274 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4274
, __func__, "assertion \"not reached\" failed")
;
4275 }
4276
4277 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4278
4279 pi = proto_tree_add_node(tree, new_fi);
4280
4281 switch (hfinfo->type) {
4282
4283 case FT_STRINGZ:
4284 case FT_STRINGZPAD:
4285 case FT_STRINGZTRUNC:
4286 case FT_UINT_STRING:
4287 break;
4288
4289 case FT_STRING:
4290 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4291 break;
4292
4293 case FT_BYTES:
4294 case FT_UINT_BYTES:
4295 break;
4296
4297 default:
4298 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4298
, __func__, "assertion \"not reached\" failed")
;
4299 }
4300
4301 return pi;
4302}
4303
4304proto_item *
4305proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4306 tvbuff_t *tvb,
4307 const int start, int length,
4308 const unsigned encoding,
4309 wmem_allocator_t *scope,
4310 char **retval)
4311{
4312 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4313 tvb, start, length, encoding, scope, retval, &length);
4314}
4315
4316proto_item *
4317proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4318 tvbuff_t *tvb,
4319 const int start, int length, const unsigned encoding,
4320 wmem_allocator_t *scope, char **retval)
4321{
4322 header_field_info *hfinfo;
4323 field_info *new_fi;
4324 nstime_t time_stamp;
4325 int flags;
4326
4327 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", 4327, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4327,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4327, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4328
4329 switch (hfinfo->type) {
4330 case FT_ABSOLUTE_TIME:
4331 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4332 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4333 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4334 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4335 }
4336 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4337 break;
4338 case FT_RELATIVE_TIME:
4339 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4340 *retval = rel_time_to_secs_str(scope, &time_stamp);
4341 break;
4342 default:
4343 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)
4344 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4345 }
4346
4347 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4348
4349 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", 4349
, __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", 4349, "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", 4349, "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", 4349, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4350
4351 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4352
4353 switch (hfinfo->type) {
4354
4355 case FT_ABSOLUTE_TIME:
4356 case FT_RELATIVE_TIME:
4357 proto_tree_set_time(new_fi, &time_stamp);
4358 break;
4359 default:
4360 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4360
, __func__, "assertion \"not reached\" failed")
;
4361 }
4362
4363 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4364
4365 return proto_tree_add_node(tree, new_fi);
4366}
4367
4368/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4369 and returns proto_item* */
4370proto_item *
4371ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4372 const unsigned encoding)
4373{
4374 field_info *new_fi;
4375 header_field_info *hfinfo;
4376 int item_length;
4377 int offset;
4378
4379 offset = ptvc->offset;
4380 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", 4380, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4380,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4380, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4381 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4382 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4383
4384 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4385
4386 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4387
4388 /* Coast clear. Try and fake it */
4389 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", 4389
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4389, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4389, "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", 4389, __func__, "Adding %s would put more than %d 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); } } }
;
4390
4391 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4392
4393 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4394 offset, length, encoding);
4395}
4396
4397/* Add an item to a proto_tree, using the text label registered to that item;
4398 the item is extracted from the tvbuff handed to it. */
4399proto_item *
4400proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4401 const int start, int length, const unsigned encoding)
4402{
4403 field_info *new_fi;
4404 int item_length;
4405
4406 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", 4406,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4407
4408 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4409 test_length(hfinfo, tvb, start, item_length, encoding);
4410
4411 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4412
4413 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", 4413
, __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", 4413, "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", 4413, "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", 4413, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4414
4415 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4416
4417 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4418}
4419
4420proto_item *
4421proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4422 const int start, int length, const unsigned encoding)
4423{
4424 register header_field_info *hfinfo;
4425
4426 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", 4426, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4426,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4426, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4427 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4428}
4429
4430/* Add an item to a proto_tree, using the text label registered to that item;
4431 the item is extracted from the tvbuff handed to it.
4432
4433 Return the length of the item through the pointer. */
4434proto_item *
4435proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4436 tvbuff_t *tvb, const int start,
4437 int length, const unsigned encoding,
4438 int *lenretval)
4439{
4440 field_info *new_fi;
4441 int item_length;
4442 proto_item *item;
4443
4444 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", 4444,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4445
4446 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4447 test_length(hfinfo, tvb, start, item_length, encoding);
4448
4449 if (!tree) {
4450 /*
4451 * We need to get the correct item length here.
4452 * That's normally done by proto_tree_new_item(),
4453 * but we won't be calling it.
4454 */
4455 *lenretval = get_full_length(hfinfo, tvb, start, length,
4456 item_length, encoding);
4457 return NULL((void*)0);
4458 }
4459
4460 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", 4467
, __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", 4467, "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", 4467, "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", 4467
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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", 4467
, __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", 4467, "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", 4467, "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", 4467
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 * 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", 4467
, __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", 4467, "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", 4467, "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", 4467
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 * 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", 4467
, __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", 4467, "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", 4467, "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", 4467
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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", 4467
, __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", 4467, "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", 4467, "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", 4467
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 *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", 4467
, __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", 4467, "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", 4467, "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", 4467
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4466 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", 4467
, __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", 4467, "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", 4467, "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", 4467
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4467 })((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", 4467
, __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", 4467, "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", 4467, "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", 4467
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4468
4469 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4470
4471 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4472 *lenretval = new_fi->length;
4473 return item;
4474}
4475
4476proto_item *
4477proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4478 const int start, int length,
4479 const unsigned encoding, int *lenretval)
4480{
4481 register header_field_info *hfinfo;
4482
4483 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", 4483, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4483,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4483, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4484 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4485}
4486
4487/* which FT_ types can use proto_tree_add_bytes_item() */
4488static inline bool_Bool
4489validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4490{
4491 return (type == FT_BYTES ||
4492 type == FT_UINT_BYTES ||
4493 type == FT_OID ||
4494 type == FT_REL_OID ||
4495 type == FT_SYSTEM_ID );
4496}
4497
4498/* Note: this does no validation that the byte array of an FT_OID or
4499 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4500 so I think it's ok to continue not validating it?
4501 */
4502proto_item *
4503proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4504 const int start, int length, const unsigned encoding,
4505 GByteArray *retval, int *endoff, int *err)
4506{
4507 field_info *new_fi;
4508 GByteArray *bytes = retval;
4509 GByteArray *created_bytes = NULL((void*)0);
4510 bool_Bool failed = false0;
4511 uint32_t n = 0;
4512 header_field_info *hfinfo;
4513 bool_Bool generate = (bytes || tree) ? true1 : false0;
4514
4515 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", 4515, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4515,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4515, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4516
4517 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", 4517,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4518
4519 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", 4520, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4520 "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", 4520, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4521
4522 CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
;
4523
4524 if (encoding & ENC_STR_NUM0x01000000) {
4525 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"
)
;
4526 }
4527
4528 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4529 if (hfinfo->type == FT_UINT_BYTES) {
4530 /* can't decode FT_UINT_BYTES from strings */
4531 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")
4532 "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")
;
4533 }
4534
4535 unsigned hex_encoding = encoding;
4536 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4537 /* If none of the separator values are used,
4538 * assume no separator (the common case). */
4539 hex_encoding |= ENC_SEP_NONE0x00010000;
4540#if 0
4541 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")
4542 "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")
;
4543#endif
4544 }
4545
4546 if (!bytes) {
4547 /* caller doesn't care about return value, but we need it to
4548 call tvb_get_string_bytes() and set the tree later */
4549 bytes = created_bytes = g_byte_array_new();
4550 }
4551
4552 /*
4553 * bytes might be NULL after this, but can't add expert
4554 * error until later; if it's NULL, just note that
4555 * it failed.
4556 */
4557 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4558 if (bytes == NULL((void*)0))
4559 failed = true1;
4560 }
4561 else if (generate) {
4562 tvb_ensure_bytes_exist(tvb, start, length);
4563
4564 if (hfinfo->type == FT_UINT_BYTES) {
4565 n = length; /* n is now the "header" length */
4566 length = get_uint_value(tree, tvb, start, n, encoding);
4567 /* length is now the value's length; only store the value in the array */
4568 tvb_ensure_bytes_exist(tvb, start + n, length);
4569 if (!bytes) {
4570 /* caller doesn't care about return value, but
4571 * we may need it to set the tree later */
4572 bytes = created_bytes = g_byte_array_new();
4573 }
4574 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4575 }
4576 else if (length > 0) {
4577 if (!bytes) {
4578 /* caller doesn't care about return value, but
4579 * we may need it to set the tree later */
4580 bytes = created_bytes = g_byte_array_new();
4581 }
4582 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4583 }
4584
4585 if (endoff)
4586 *endoff = start + n + length;
4587 }
4588
4589 if (err)
4590 *err = failed ? EINVAL22 : 0;
4591
4592 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); }
4593 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4594 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); }
4595 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); }
4596 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); }
4597 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4598 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4599
4600 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", 4606
, __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", 4606, "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", 4606, "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", 4606
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 {((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", 4606
, __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", 4606, "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", 4606, "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", 4606
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4606
, __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", 4606, "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", 4606, "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", 4606
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4606
, __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", 4606, "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", 4606, "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", 4606
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4606
, __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", 4606, "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", 4606, "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", 4606
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4605 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", 4606
, __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", 4606, "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", 4606, "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", 4606
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4606 } )((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", 4606
, __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", 4606, "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", 4606, "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", 4606
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4607
4608 /* n will be zero except when it's a FT_UINT_BYTES */
4609 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4610
4611 if (encoding & ENC_STRING0x03000000) {
4612 if (failed)
4613 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4614
4615 if (bytes)
4616 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4617 else
4618 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4619
4620 if (created_bytes)
4621 g_byte_array_free(created_bytes, true1);
4622 }
4623 else {
4624 /* n will be zero except when it's a FT_UINT_BYTES */
4625 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4626
4627 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4628 * use the byte array created above in this case.
4629 */
4630 if (created_bytes)
4631 g_byte_array_free(created_bytes, true1);
4632
4633 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4634 (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)
;
4635 }
4636
4637 return proto_tree_add_node(tree, new_fi);
4638}
4639
4640
4641proto_item *
4642proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4643 const int start, int length, const unsigned encoding,
4644 nstime_t *retval, int *endoff, int *err)
4645{
4646 field_info *new_fi;
4647 nstime_t time_stamp;
4648 int saved_err = 0;
4649 header_field_info *hfinfo;
4650
4651 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", 4651, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4651,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4651, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4652
4653 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", 4653,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4654
4655 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4656 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4657 if(retval)if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4658 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4659 nstime_set_zero(retval);if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4660 }if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4661 } )if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
;
4662
4663 nstime_set_zero(&time_stamp);
4664
4665 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4666 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", 4666, ((hfinfo))->abbrev))))
;
4667 /* The only string format that could be a relative time is
4668 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4669 * relative to "now" currently.
4670 */
4671 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4672 saved_err = EINVAL22;
4673 }
4674 else {
4675 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", 4675, ((hfinfo))->abbrev))))
;
4676 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4677
4678 tvb_ensure_bytes_exist(tvb, start, length);
4679 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4680 if (endoff) *endoff = start + length;
4681 }
4682
4683 if (err) *err = saved_err;
4684
4685 if (retval) {
4686 retval->secs = time_stamp.secs;
4687 retval->nsecs = time_stamp.nsecs;
4688 }
4689
4690 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4691
4692 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", 4692
, __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", 4692, "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", 4692, "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", 4692, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4693
4694 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4695
4696 proto_tree_set_time(new_fi, &time_stamp);
4697
4698 if (encoding & ENC_STRING0x03000000) {
4699 if (saved_err)
4700 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4701 }
4702 else {
4703 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4704 (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)
;
4705 }
4706
4707 return proto_tree_add_node(tree, new_fi);
4708}
4709
4710/* Add a FT_NONE to a proto_tree */
4711proto_item *
4712proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4713 const int start, int length, const char *format,
4714 ...)
4715{
4716 proto_item *pi;
4717 va_list ap;
4718 header_field_info *hfinfo;
4719
4720 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4721
4722 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", 4722
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4722, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4722, "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", 4722, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4723
4724 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", 4724
, ((hfinfo))->abbrev))))
;
4725
4726 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4727
4728 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4728, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4729
4730 va_start(ap, format)__builtin_va_start(ap, format);
4731 proto_tree_set_representation(pi, format, ap);
4732 va_end(ap)__builtin_va_end(ap);
4733
4734 /* no value to set for FT_NONE */
4735 return pi;
4736}
4737
4738/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4739 * offset, and returns proto_item* */
4740proto_item *
4741ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4742 const unsigned encoding)
4743{
4744 proto_item *item;
4745
4746 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4747 length, encoding);
4748
4749 return item;
4750}
4751
4752/* Advance the ptvcursor's offset within its tvbuff without
4753 * adding anything to the proto_tree. */
4754void
4755ptvcursor_advance(ptvcursor_t* ptvc, int length)
4756{
4757 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4758 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4759 }
4760}
4761
4762
4763static void
4764proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4765{
4766 fvalue_set_protocol(fi->value, tvb, field_data, length);
4767}
4768
4769/* Add a FT_PROTOCOL to a proto_tree */
4770proto_item *
4771proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4772 int start, int length, const char *format, ...)
4773{
4774 proto_item *pi;
4775 tvbuff_t *protocol_tvb;
4776 va_list ap;
4777 header_field_info *hfinfo;
4778 char* protocol_rep;
4779
4780 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4781
4782 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", 4782
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4782, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4782, "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", 4782, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4783
4784 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"
, 4784, ((hfinfo))->abbrev))))
;
4785
4786 /*
4787 * This can throw an exception, so do it before we allocate anything.
4788 */
4789 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4790
4791 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4792
4793 va_start(ap, format)__builtin_va_start(ap, format);
4794 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4795 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4796 g_free(protocol_rep);
4797 va_end(ap)__builtin_va_end(ap);
4798
4799 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4799, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4800
4801 va_start(ap, format)__builtin_va_start(ap, format);
4802 proto_tree_set_representation(pi, format, ap);
4803 va_end(ap)__builtin_va_end(ap);
4804
4805 return pi;
4806}
4807
4808/* Add a FT_BYTES to a proto_tree */
4809proto_item *
4810proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4811 int length, const uint8_t *start_ptr)
4812{
4813 proto_item *pi;
4814 header_field_info *hfinfo;
4815 int item_length;
4816
4817 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", 4817, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4817,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4817, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4818 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4819 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4820
4821 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4822
4823 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", 4823
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4823, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4823, "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", 4823, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4824
4825 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",
4825, ((hfinfo))->abbrev))))
;
4826
4827 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4828 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4829
4830 return pi;
4831}
4832
4833/* Add a FT_BYTES to a proto_tree */
4834proto_item *
4835proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4836 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4837{
4838 proto_item *pi;
4839 header_field_info *hfinfo;
4840 int item_length;
4841
4842 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", 4842, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4842,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4842, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4843 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4844 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4845
4846 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4847
4848 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", 4848
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4848, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4848, "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", 4848, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4849
4850 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",
4850, ((hfinfo))->abbrev))))
;
4851
4852 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4853 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4854
4855 return pi;
4856}
4857
4858proto_item *
4859proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4860 int start, int length,
4861 const uint8_t *start_ptr,
4862 const char *format, ...)
4863{
4864 proto_item *pi;
4865 va_list ap;
4866
4867 if (start_ptr == NULL((void*)0))
4868 start_ptr = tvb_get_ptr(tvb, start, length);
4869
4870 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4871
4872 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; }
;
4873
4874 va_start(ap, format)__builtin_va_start(ap, format);
4875 proto_tree_set_representation_value(pi, format, ap);
4876 va_end(ap)__builtin_va_end(ap);
4877
4878 return pi;
4879}
4880
4881proto_item *
4882proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4883 int start, int length, const uint8_t *start_ptr,
4884 const char *format, ...)
4885{
4886 proto_item *pi;
4887 va_list ap;
4888
4889 if (start_ptr == NULL((void*)0))
4890 start_ptr = tvb_get_ptr(tvb, start, length);
4891
4892 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4893
4894 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; }
;
4895
4896 va_start(ap, format)__builtin_va_start(ap, format);
4897 proto_tree_set_representation(pi, format, ap);
4898 va_end(ap)__builtin_va_end(ap);
4899
4900 return pi;
4901}
4902
4903static void
4904proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4905{
4906 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4906, "length >= 0"
))))
;
4907 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", 4907, "start_ptr != ((void*)0) || length == 0"
))))
;
4908
4909 fvalue_set_bytes_data(fi->value, start_ptr, length);
4910}
4911
4912
4913static void
4914proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4915{
4916 tvb_ensure_bytes_exist(tvb, offset, length);
4917 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4918}
4919
4920static void
4921proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4922{
4923 GByteArray *bytes;
4924
4925 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4925, "value != ((void*)0)"
))))
;
4926
4927 bytes = byte_array_dup(value);
4928
4929 fvalue_set_byte_array(fi->value, bytes);
4930}
4931
4932/* Add a FT_*TIME to a proto_tree */
4933proto_item *
4934proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4935 int length, const nstime_t *value_ptr)
4936{
4937 proto_item *pi;
4938 header_field_info *hfinfo;
4939
4940 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4941
4942 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", 4942
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4942, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4942, "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", 4942, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4943
4944 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", 4944, ((hfinfo))->abbrev))))
;
4945
4946 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4947 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4948
4949 return pi;
4950}
4951
4952proto_item *
4953proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4954 int start, int length, nstime_t *value_ptr,
4955 const char *format, ...)
4956{
4957 proto_item *pi;
4958 va_list ap;
4959
4960 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4961 if (pi != tree) {
4962 va_start(ap, format)__builtin_va_start(ap, format);
4963 proto_tree_set_representation_value(pi, format, ap);
4964 va_end(ap)__builtin_va_end(ap);
4965 }
4966
4967 return pi;
4968}
4969
4970proto_item *
4971proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4972 int start, int length, nstime_t *value_ptr,
4973 const char *format, ...)
4974{
4975 proto_item *pi;
4976 va_list ap;
4977
4978 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4979 if (pi != tree) {
4980 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4980, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4981
4982 va_start(ap, format)__builtin_va_start(ap, format);
4983 proto_tree_set_representation(pi, format, ap);
4984 va_end(ap)__builtin_va_end(ap);
4985 }
4986
4987 return pi;
4988}
4989
4990/* Set the FT_*TIME value */
4991static void
4992proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4993{
4994 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4994, "value_ptr != ((void*)0)"
))))
;
4995
4996 fvalue_set_time(fi->value, value_ptr);
4997}
4998
4999/* Add a FT_IPXNET to a proto_tree */
5000proto_item *
5001proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5002 int length, uint32_t value)
5003{
5004 proto_item *pi;
5005 header_field_info *hfinfo;
5006
5007 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5008
5009 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", 5009
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5009, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5009, "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", 5009, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5010
5011 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"
, 5011, ((hfinfo))->abbrev))))
;
5012
5013 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5014 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5015
5016 return pi;
5017}
5018
5019proto_item *
5020proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5021 int start, int length, uint32_t value,
5022 const char *format, ...)
5023{
5024 proto_item *pi;
5025 va_list ap;
5026
5027 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5028 if (pi != tree) {
5029 va_start(ap, format)__builtin_va_start(ap, format);
5030 proto_tree_set_representation_value(pi, format, ap);
5031 va_end(ap)__builtin_va_end(ap);
5032 }
5033
5034 return pi;
5035}
5036
5037proto_item *
5038proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5039 int start, int length, uint32_t value,
5040 const char *format, ...)
5041{
5042 proto_item *pi;
5043 va_list ap;
5044
5045 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5046 if (pi != tree) {
5047 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5047, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5048
5049 va_start(ap, format)__builtin_va_start(ap, format);
5050 proto_tree_set_representation(pi, format, ap);
5051 va_end(ap)__builtin_va_end(ap);
5052 }
5053
5054 return pi;
5055}
5056
5057/* Set the FT_IPXNET value */
5058static void
5059proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5060{
5061 fvalue_set_uinteger(fi->value, value);
5062}
5063
5064/* Add a FT_IPv4 to a proto_tree */
5065proto_item *
5066proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5067 int length, ws_in4_addr value)
5068{
5069 proto_item *pi;
5070 header_field_info *hfinfo;
5071
5072 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5073
5074 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", 5074
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5074, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5074, "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", 5074, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5075
5076 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", 5076
, ((hfinfo))->abbrev))))
;
5077
5078 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5079 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5080
5081 return pi;
5082}
5083
5084proto_item *
5085proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5086 int start, int length, ws_in4_addr value,
5087 const char *format, ...)
5088{
5089 proto_item *pi;
5090 va_list ap;
5091
5092 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5093 if (pi != tree) {
5094 va_start(ap, format)__builtin_va_start(ap, format);
5095 proto_tree_set_representation_value(pi, format, ap);
5096 va_end(ap)__builtin_va_end(ap);
5097 }
5098
5099 return pi;
5100}
5101
5102proto_item *
5103proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5104 int start, int length, ws_in4_addr value,
5105 const char *format, ...)
5106{
5107 proto_item *pi;
5108 va_list ap;
5109
5110 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5111 if (pi != tree) {
5112 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5112, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5113
5114 va_start(ap, format)__builtin_va_start(ap, format);
5115 proto_tree_set_representation(pi, format, ap);
5116 va_end(ap)__builtin_va_end(ap);
5117 }
5118
5119 return pi;
5120}
5121
5122/* Set the FT_IPv4 value */
5123static void
5124proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5125{
5126 ipv4_addr_and_mask ipv4;
5127 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5128 fvalue_set_ipv4(fi->value, &ipv4);
5129}
5130
5131/* Add a FT_IPv6 to a proto_tree */
5132proto_item *
5133proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5134 int length, const ws_in6_addr *value)
5135{
5136 proto_item *pi;
5137 header_field_info *hfinfo;
5138
5139 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5140
5141 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", 5141
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5141, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5141, "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", 5141, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5142
5143 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", 5143
, ((hfinfo))->abbrev))))
;
5144
5145 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5146 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5147
5148 return pi;
5149}
5150
5151proto_item *
5152proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5153 int start, int length,
5154 const ws_in6_addr *value_ptr,
5155 const char *format, ...)
5156{
5157 proto_item *pi;
5158 va_list ap;
5159
5160 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5161 if (pi != tree) {
5162 va_start(ap, format)__builtin_va_start(ap, format);
5163 proto_tree_set_representation_value(pi, format, ap);
5164 va_end(ap)__builtin_va_end(ap);
5165 }
5166
5167 return pi;
5168}
5169
5170proto_item *
5171proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5172 int start, int length,
5173 const ws_in6_addr *value_ptr,
5174 const char *format, ...)
5175{
5176 proto_item *pi;
5177 va_list ap;
5178
5179 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5180 if (pi != tree) {
5181 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5181, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5182
5183 va_start(ap, format)__builtin_va_start(ap, format);
5184 proto_tree_set_representation(pi, format, ap);
5185 va_end(ap)__builtin_va_end(ap);
5186 }
5187
5188 return pi;
5189}
5190
5191/* Set the FT_IPv6 value */
5192static void
5193proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5194{
5195 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5195, "value != ((void*)0)"
))))
;
5196 ipv6_addr_and_prefix ipv6;
5197 ipv6.addr = *value;
5198 ipv6.prefix = 128;
5199 fvalue_set_ipv6(fi->value, &ipv6);
5200}
5201
5202static void
5203proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5204{
5205 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5206}
5207
5208/* Set the FT_FCWWN value */
5209static void
5210proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5211{
5212 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5212, "value_ptr != ((void*)0)"
))))
;
5213 fvalue_set_fcwwn(fi->value, value_ptr);
5214}
5215
5216static void
5217proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5218{
5219 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5220}
5221
5222/* Add a FT_GUID to a proto_tree */
5223proto_item *
5224proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5225 int length, const e_guid_t *value_ptr)
5226{
5227 proto_item *pi;
5228 header_field_info *hfinfo;
5229
5230 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5231
5232 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", 5232
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5232, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5232, "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", 5232, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5233
5234 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", 5234
, ((hfinfo))->abbrev))))
;
5235
5236 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5237 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5238
5239 return pi;
5240}
5241
5242proto_item *
5243proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5244 int start, int length,
5245 const e_guid_t *value_ptr,
5246 const char *format, ...)
5247{
5248 proto_item *pi;
5249 va_list ap;
5250
5251 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5252 if (pi != tree) {
5253 va_start(ap, format)__builtin_va_start(ap, format);
5254 proto_tree_set_representation_value(pi, format, ap);
5255 va_end(ap)__builtin_va_end(ap);
5256 }
5257
5258 return pi;
5259}
5260
5261proto_item *
5262proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5263 int start, int length, const e_guid_t *value_ptr,
5264 const char *format, ...)
5265{
5266 proto_item *pi;
5267 va_list ap;
5268
5269 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5270 if (pi != tree) {
5271 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5271, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5272
5273 va_start(ap, format)__builtin_va_start(ap, format);
5274 proto_tree_set_representation(pi, format, ap);
5275 va_end(ap)__builtin_va_end(ap);
5276 }
5277
5278 return pi;
5279}
5280
5281/* Set the FT_GUID value */
5282static void
5283proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5284{
5285 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5285, "value_ptr != ((void*)0)"
))))
;
5286 fvalue_set_guid(fi->value, value_ptr);
5287}
5288
5289static void
5290proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5291 const unsigned encoding)
5292{
5293 e_guid_t guid;
5294
5295 tvb_get_guid(tvb, start, &guid, encoding);
5296 proto_tree_set_guid(fi, &guid);
5297}
5298
5299/* Add a FT_OID to a proto_tree */
5300proto_item *
5301proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5302 int length, const uint8_t* value_ptr)
5303{
5304 proto_item *pi;
5305 header_field_info *hfinfo;
5306
5307 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5308
5309 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", 5309
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5309, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5309, "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", 5309, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5310
5311 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", 5311
, ((hfinfo))->abbrev))))
;
5312
5313 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5314 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5315
5316 return pi;
5317}
5318
5319proto_item *
5320proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5321 int start, int length,
5322 const uint8_t* value_ptr,
5323 const char *format, ...)
5324{
5325 proto_item *pi;
5326 va_list ap;
5327
5328 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5329 if (pi != tree) {
5330 va_start(ap, format)__builtin_va_start(ap, format);
5331 proto_tree_set_representation_value(pi, format, ap);
5332 va_end(ap)__builtin_va_end(ap);
5333 }
5334
5335 return pi;
5336}
5337
5338proto_item *
5339proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5340 int start, int length, const uint8_t* value_ptr,
5341 const char *format, ...)
5342{
5343 proto_item *pi;
5344 va_list ap;
5345
5346 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5347 if (pi != tree) {
5348 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5348, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5349
5350 va_start(ap, format)__builtin_va_start(ap, format);
5351 proto_tree_set_representation(pi, format, ap);
5352 va_end(ap)__builtin_va_end(ap);
5353 }
5354
5355 return pi;
5356}
5357
5358/* Set the FT_OID value */
5359static void
5360proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5361{
5362 GByteArray *bytes;
5363
5364 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", 5364, "value_ptr != ((void*)0) || length == 0"
))))
;
5365
5366 bytes = g_byte_array_new();
5367 if (length > 0) {
5368 g_byte_array_append(bytes, value_ptr, length);
5369 }
5370 fvalue_set_byte_array(fi->value, bytes);
5371}
5372
5373static void
5374proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5375{
5376 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5377}
5378
5379/* Set the FT_SYSTEM_ID value */
5380static void
5381proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5382{
5383 GByteArray *bytes;
5384
5385 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", 5385, "value_ptr != ((void*)0) || length == 0"
))))
;
5386
5387 bytes = g_byte_array_new();
5388 if (length > 0) {
5389 g_byte_array_append(bytes, value_ptr, length);
5390 }
5391 fvalue_set_byte_array(fi->value, bytes);
5392}
5393
5394static void
5395proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5396{
5397 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5398}
5399
5400/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5401 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5402 * is destroyed. */
5403proto_item *
5404proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5405 int length, const char* value)
5406{
5407 proto_item *pi;
5408 header_field_info *hfinfo;
5409 int item_length;
5410
5411 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", 5411, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5411,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5411, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5412 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5413 /*
5414 * Special case - if the length is 0, skip the test, so that
5415 * we can have an empty string right after the end of the
5416 * packet. (This handles URL-encoded forms where the last field
5417 * has no value so the form ends right after the =.)
5418 */
5419 if (item_length != 0)
5420 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5421
5422 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5423
5424 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", 5424
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5424, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5424, "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", 5424, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5425
5426 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", 5426, ((hfinfo))->abbrev))))
;
5427
5428 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5429 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5429, "length >= 0"
))))
;
5430
5431 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", 5431, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5432 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5433
5434 return pi;
5435}
5436
5437proto_item *
5438proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5439 int start, int length, const char* value,
5440 const char *format,
5441 ...)
5442{
5443 proto_item *pi;
5444 va_list ap;
5445
5446 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5447 if (pi != tree) {
5448 va_start(ap, format)__builtin_va_start(ap, format);
5449 proto_tree_set_representation_value(pi, format, ap);
5450 va_end(ap)__builtin_va_end(ap);
5451 }
5452
5453 return pi;
5454}
5455
5456proto_item *
5457proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5458 int start, int length, const char* value,
5459 const char *format, ...)
5460{
5461 proto_item *pi;
5462 va_list ap;
5463
5464 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5465 if (pi != tree) {
5466 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5466, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5467
5468 va_start(ap, format)__builtin_va_start(ap, format);
5469 proto_tree_set_representation(pi, format, ap);
5470 va_end(ap)__builtin_va_end(ap);
5471 }
5472
5473 return pi;
5474}
5475
5476/* Set the FT_STRING value */
5477static void
5478proto_tree_set_string(field_info *fi, const char* value)
5479{
5480 if (value) {
5481 fvalue_set_string(fi->value, value);
5482 } else {
5483 /*
5484 * XXX - why is a null value for a string field
5485 * considered valid?
5486 */
5487 fvalue_set_string(fi->value, "[ Null ]");
5488 }
5489}
5490
5491/* Set the FT_AX25 value */
5492static void
5493proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5494{
5495 fvalue_set_ax25(fi->value, value);
5496}
5497
5498static void
5499proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5500{
5501 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5502}
5503
5504/* Set the FT_VINES value */
5505static void
5506proto_tree_set_vines(field_info *fi, const uint8_t* value)
5507{
5508 fvalue_set_vines(fi->value, value);
5509}
5510
5511static void
5512proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5513{
5514 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5515}
5516
5517/* Add a FT_ETHER to a proto_tree */
5518proto_item *
5519proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5520 int length, const uint8_t* value)
5521{
5522 proto_item *pi;
5523 header_field_info *hfinfo;
5524
5525 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5526
5527 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", 5527
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5527, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5527, "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", 5527, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5528
5529 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",
5529, ((hfinfo))->abbrev))))
;
5530
5531 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5532 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5533
5534 return pi;
5535}
5536
5537proto_item *
5538proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5539 int start, int length, const uint8_t* value,
5540 const char *format, ...)
5541{
5542 proto_item *pi;
5543 va_list ap;
5544
5545 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5546 if (pi != tree) {
5547 va_start(ap, format)__builtin_va_start(ap, format);
5548 proto_tree_set_representation_value(pi, format, ap);
5549 va_end(ap)__builtin_va_end(ap);
5550 }
5551
5552 return pi;
5553}
5554
5555proto_item *
5556proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5557 int start, int length, const uint8_t* value,
5558 const char *format, ...)
5559{
5560 proto_item *pi;
5561 va_list ap;
5562
5563 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5564 if (pi != tree) {
5565 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5565, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5566
5567 va_start(ap, format)__builtin_va_start(ap, format);
5568 proto_tree_set_representation(pi, format, ap);
5569 va_end(ap)__builtin_va_end(ap);
5570 }
5571
5572 return pi;
5573}
5574
5575/* Set the FT_ETHER value */
5576static void
5577proto_tree_set_ether(field_info *fi, const uint8_t* value)
5578{
5579 fvalue_set_ether(fi->value, value);
5580}
5581
5582static void
5583proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5584{
5585 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5586}
5587
5588/* Add a FT_BOOLEAN to a proto_tree */
5589proto_item *
5590proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5591 int length, uint64_t value)
5592{
5593 proto_item *pi;
5594 header_field_info *hfinfo;
5595
5596 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5597
5598 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", 5598
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5598, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5598, "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", 5598, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5599
5600 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"
, 5600, ((hfinfo))->abbrev))))
;
5601
5602 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5603 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5604
5605 return pi;
5606}
5607
5608proto_item *
5609proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5610 tvbuff_t *tvb, int start, int length,
5611 uint64_t value, const char *format, ...)
5612{
5613 proto_item *pi;
5614 va_list ap;
5615
5616 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5617 if (pi != tree) {
5618 va_start(ap, format)__builtin_va_start(ap, format);
5619 proto_tree_set_representation_value(pi, format, ap);
5620 va_end(ap)__builtin_va_end(ap);
5621 }
5622
5623 return pi;
5624}
5625
5626proto_item *
5627proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5628 int start, int length, uint64_t value,
5629 const char *format, ...)
5630{
5631 proto_item *pi;
5632 va_list ap;
5633
5634 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5635 if (pi != tree) {
5636 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5636, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5637
5638 va_start(ap, format)__builtin_va_start(ap, format);
5639 proto_tree_set_representation(pi, format, ap);
5640 va_end(ap)__builtin_va_end(ap);
5641 }
5642
5643 return pi;
5644}
5645
5646/* Set the FT_BOOLEAN value */
5647static void
5648proto_tree_set_boolean(field_info *fi, uint64_t value)
5649{
5650 proto_tree_set_uint64(fi, value);
5651}
5652
5653/* Generate, into "buf", a string showing the bits of a bitfield.
5654 Return a pointer to the character after that string. */
5655static char *
5656other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5657{
5658 int i = 0;
5659 uint64_t bit;
5660 char *p;
5661
5662 p = buf;
5663
5664 /* This is a devel error. It is safer to stop here. */
5665 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5665, "width >= 1"
))))
;
5666
5667 bit = UINT64_C(1)1UL << (width - 1);
5668 for (;;) {
5669 if (mask & bit) {
5670 /* This bit is part of the field. Show its value. */
5671 if (val & bit)
5672 *p++ = '1';
5673 else
5674 *p++ = '0';
5675 } else {
5676 /* This bit is not part of the field. */
5677 *p++ = '.';
5678 }
5679 bit >>= 1;
5680 i++;
5681 if (i >= width)
5682 break;
5683 if (i % 4 == 0)
5684 *p++ = ' ';
5685 }
5686 *p = '\0';
5687 return p;
5688}
5689
5690static char *
5691decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5692{
5693 char *p;
5694
5695 p = other_decode_bitfield_value(buf, val, mask, width);
5696 p = g_stpcpy(p, " = ");
5697
5698 return p;
5699}
5700
5701static char *
5702other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5703{
5704 int i = 0;
5705 uint64_t bit;
5706 char *p;
5707
5708 p = buf;
5709
5710 /* This is a devel error. It is safer to stop here. */
5711 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5711, "width >= 1"
))))
;
5712
5713 bit = UINT64_C(1)1UL << (width - 1);
5714 for (;;) {
5715 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5716 (mask & bit)) {
5717 /* This bit is part of the field. Show its value. */
5718 if (val & bit)
5719 *p++ = '1';
5720 else
5721 *p++ = '0';
5722 } else {
5723 /* This bit is not part of the field. */
5724 *p++ = '.';
5725 }
5726 bit >>= 1;
5727 i++;
5728 if (i >= width)
5729 break;
5730 if (i % 4 == 0)
5731 *p++ = ' ';
5732 }
5733
5734 *p = '\0';
5735 return p;
5736}
5737
5738static char *
5739decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5740{
5741 char *p;
5742
5743 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5744 p = g_stpcpy(p, " = ");
5745
5746 return p;
5747}
5748
5749/* Add a FT_FLOAT to a proto_tree */
5750proto_item *
5751proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5752 int length, float value)
5753{
5754 proto_item *pi;
5755 header_field_info *hfinfo;
5756
5757 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5758
5759 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", 5759
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5759, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5759, "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", 5759, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5760
5761 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",
5761, ((hfinfo))->abbrev))))
;
5762
5763 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5764 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5765
5766 return pi;
5767}
5768
5769proto_item *
5770proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5771 int start, int length, float value,
5772 const char *format, ...)
5773{
5774 proto_item *pi;
5775 va_list ap;
5776
5777 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5778 if (pi != tree) {
5779 va_start(ap, format)__builtin_va_start(ap, format);
5780 proto_tree_set_representation_value(pi, format, ap);
5781 va_end(ap)__builtin_va_end(ap);
5782 }
5783
5784 return pi;
5785}
5786
5787proto_item *
5788proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5789 int start, int length, float value,
5790 const char *format, ...)
5791{
5792 proto_item *pi;
5793 va_list ap;
5794
5795 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5796 if (pi != tree) {
5797 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5797, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5798
5799 va_start(ap, format)__builtin_va_start(ap, format);
5800 proto_tree_set_representation(pi, format, ap);
5801 va_end(ap)__builtin_va_end(ap);
5802 }
5803
5804 return pi;
5805}
5806
5807/* Set the FT_FLOAT value */
5808static void
5809proto_tree_set_float(field_info *fi, float value)
5810{
5811 fvalue_set_floating(fi->value, value);
5812}
5813
5814/* Add a FT_DOUBLE to a proto_tree */
5815proto_item *
5816proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5817 int length, double value)
5818{
5819 proto_item *pi;
5820 header_field_info *hfinfo;
5821
5822 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5823
5824 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", 5824
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5824, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5824, "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", 5824, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5825
5826 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"
, 5826, ((hfinfo))->abbrev))))
;
5827
5828 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5829 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5830
5831 return pi;
5832}
5833
5834proto_item *
5835proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5836 int start, int length, double value,
5837 const char *format, ...)
5838{
5839 proto_item *pi;
5840 va_list ap;
5841
5842 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5843 if (pi != tree) {
5844 va_start(ap, format)__builtin_va_start(ap, format);
5845 proto_tree_set_representation_value(pi, format, ap);
5846 va_end(ap)__builtin_va_end(ap);
5847 }
5848
5849 return pi;
5850}
5851
5852proto_item *
5853proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5854 int start, int length, double value,
5855 const char *format, ...)
5856{
5857 proto_item *pi;
5858 va_list ap;
5859
5860 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5861 if (pi != tree) {
5862 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5862, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5863
5864 va_start(ap, format)__builtin_va_start(ap, format);
5865 proto_tree_set_representation(pi, format, ap);
5866 va_end(ap)__builtin_va_end(ap);
5867 }
5868
5869 return pi;
5870}
5871
5872/* Set the FT_DOUBLE value */
5873static void
5874proto_tree_set_double(field_info *fi, double value)
5875{
5876 fvalue_set_floating(fi->value, value);
5877}
5878
5879/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5880proto_item *
5881proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5882 int length, uint32_t value)
5883{
5884 proto_item *pi = NULL((void*)0);
5885 header_field_info *hfinfo;
5886
5887 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5888
5889 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", 5889
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5889, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5889, "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", 5889, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5890
5891 switch (hfinfo->type) {
5892 case FT_CHAR:
5893 case FT_UINT8:
5894 case FT_UINT16:
5895 case FT_UINT24:
5896 case FT_UINT32:
5897 case FT_FRAMENUM:
5898 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5899 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5900 break;
5901
5902 default:
5903 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)
5904 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)
;
5905 }
5906
5907 return pi;
5908}
5909
5910proto_item *
5911proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5912 int start, int length, uint32_t value,
5913 const char *format, ...)
5914{
5915 proto_item *pi;
5916 va_list ap;
5917
5918 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5919 if (pi != tree) {
5920 va_start(ap, format)__builtin_va_start(ap, format);
5921 proto_tree_set_representation_value(pi, format, ap);
5922 va_end(ap)__builtin_va_end(ap);
5923 }
5924
5925 return pi;
5926}
5927
5928proto_item *
5929proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5930 int start, int length, uint32_t value,
5931 const char *format, ...)
5932{
5933 proto_item *pi;
5934 va_list ap;
5935
5936 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5937 if (pi != tree) {
5938 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5938, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5939
5940 va_start(ap, format)__builtin_va_start(ap, format);
5941 proto_tree_set_representation(pi, format, ap);
5942 va_end(ap)__builtin_va_end(ap);
5943 }
5944
5945 return pi;
5946}
5947
5948/* Set the FT_UINT{8,16,24,32} value */
5949static void
5950proto_tree_set_uint(field_info *fi, uint32_t value)
5951{
5952 const header_field_info *hfinfo;
5953 uint32_t integer;
5954
5955 hfinfo = fi->hfinfo;
5956 integer = value;
5957
5958 if (hfinfo->bitmask) {
5959 /* Mask out irrelevant portions */
5960 integer &= (uint32_t)(hfinfo->bitmask);
5961
5962 /* Shift bits */
5963 integer >>= hfinfo_bitshift(hfinfo);
5964
5965 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5966 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)
;
5967 }
5968
5969 fvalue_set_uinteger(fi->value, integer);
5970}
5971
5972/* Add FT_UINT{40,48,56,64} to a proto_tree */
5973proto_item *
5974proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5975 int length, uint64_t value)
5976{
5977 proto_item *pi = NULL((void*)0);
5978 header_field_info *hfinfo;
5979
5980 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5981
5982 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", 5982
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5982, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5982, "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", 5982, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5983
5984 switch (hfinfo->type) {
5985 case FT_UINT40:
5986 case FT_UINT48:
5987 case FT_UINT56:
5988 case FT_UINT64:
5989 case FT_FRAMENUM:
5990 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5991 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
5992 break;
5993
5994 default:
5995 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)
5996 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)
;
5997 }
5998
5999 return pi;
6000}
6001
6002proto_item *
6003proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6004 int start, int length, uint64_t value,
6005 const char *format, ...)
6006{
6007 proto_item *pi;
6008 va_list ap;
6009
6010 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6011 if (pi != tree) {
6012 va_start(ap, format)__builtin_va_start(ap, format);
6013 proto_tree_set_representation_value(pi, format, ap);
6014 va_end(ap)__builtin_va_end(ap);
6015 }
6016
6017 return pi;
6018}
6019
6020proto_item *
6021proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6022 int start, int length, uint64_t value,
6023 const char *format, ...)
6024{
6025 proto_item *pi;
6026 va_list ap;
6027
6028 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6029 if (pi != tree) {
6030 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6030, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6031
6032 va_start(ap, format)__builtin_va_start(ap, format);
6033 proto_tree_set_representation(pi, format, ap);
6034 va_end(ap)__builtin_va_end(ap);
6035 }
6036
6037 return pi;
6038}
6039
6040/* Set the FT_UINT{40,48,56,64} value */
6041static void
6042proto_tree_set_uint64(field_info *fi, uint64_t value)
6043{
6044 const header_field_info *hfinfo;
6045 uint64_t integer;
6046
6047 hfinfo = fi->hfinfo;
6048 integer = value;
6049
6050 if (hfinfo->bitmask) {
6051 /* Mask out irrelevant portions */
6052 integer &= hfinfo->bitmask;
6053
6054 /* Shift bits */
6055 integer >>= hfinfo_bitshift(hfinfo);
6056
6057 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6058 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)
;
6059 }
6060
6061 fvalue_set_uinteger64(fi->value, integer);
6062}
6063
6064/* Add FT_INT{8,16,24,32} to a proto_tree */
6065proto_item *
6066proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6067 int length, int32_t value)
6068{
6069 proto_item *pi = NULL((void*)0);
6070 header_field_info *hfinfo;
6071
6072 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6073
6074 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", 6074
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6074, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6074, "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", 6074, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6075
6076 switch (hfinfo->type) {
6077 case FT_INT8:
6078 case FT_INT16:
6079 case FT_INT24:
6080 case FT_INT32:
6081 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6082 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6083 break;
6084
6085 default:
6086 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)
6087 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6088 }
6089
6090 return pi;
6091}
6092
6093proto_item *
6094proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6095 int start, int length, int32_t value,
6096 const char *format, ...)
6097{
6098 proto_item *pi;
6099 va_list ap;
6100
6101 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6102 if (pi != tree) {
6103 va_start(ap, format)__builtin_va_start(ap, format);
6104 proto_tree_set_representation_value(pi, format, ap);
6105 va_end(ap)__builtin_va_end(ap);
6106 }
6107
6108 return pi;
6109}
6110
6111proto_item *
6112proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6113 int start, int length, int32_t value,
6114 const char *format, ...)
6115{
6116 proto_item *pi;
6117 va_list ap;
6118
6119 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6120 if (pi != tree) {
6121 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6121, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6122
6123 va_start(ap, format)__builtin_va_start(ap, format);
6124 proto_tree_set_representation(pi, format, ap);
6125 va_end(ap)__builtin_va_end(ap);
6126 }
6127
6128 return pi;
6129}
6130
6131/* Set the FT_INT{8,16,24,32} value */
6132static void
6133proto_tree_set_int(field_info *fi, int32_t value)
6134{
6135 const header_field_info *hfinfo;
6136 uint32_t integer;
6137 int no_of_bits;
6138
6139 hfinfo = fi->hfinfo;
6140 integer = (uint32_t) value;
6141
6142 if (hfinfo->bitmask) {
6143 /* Mask out irrelevant portions */
6144 integer &= (uint32_t)(hfinfo->bitmask);
6145
6146 /* Shift bits */
6147 integer >>= hfinfo_bitshift(hfinfo);
6148
6149 no_of_bits = ws_count_ones(hfinfo->bitmask);
6150 integer = ws_sign_ext32(integer, no_of_bits);
6151
6152 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6153 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)
;
6154 }
6155
6156 fvalue_set_sinteger(fi->value, integer);
6157}
6158
6159/* Add FT_INT{40,48,56,64} to a proto_tree */
6160proto_item *
6161proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6162 int length, int64_t value)
6163{
6164 proto_item *pi = NULL((void*)0);
6165 header_field_info *hfinfo;
6166
6167 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6168
6169 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", 6169
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6169, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6169, "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", 6169, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6170
6171 switch (hfinfo->type) {
6172 case FT_INT40:
6173 case FT_INT48:
6174 case FT_INT56:
6175 case FT_INT64:
6176 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6177 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6178 break;
6179
6180 default:
6181 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)
6182 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6183 }
6184
6185 return pi;
6186}
6187
6188proto_item *
6189proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6190 int start, int length, int64_t value,
6191 const char *format, ...)
6192{
6193 proto_item *pi;
6194 va_list ap;
6195
6196 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6197 if (pi != tree) {
6198 va_start(ap, format)__builtin_va_start(ap, format);
6199 proto_tree_set_representation_value(pi, format, ap);
6200 va_end(ap)__builtin_va_end(ap);
6201 }
6202
6203 return pi;
6204}
6205
6206/* Set the FT_INT{40,48,56,64} value */
6207static void
6208proto_tree_set_int64(field_info *fi, int64_t value)
6209{
6210 const header_field_info *hfinfo;
6211 uint64_t integer;
6212 int no_of_bits;
6213
6214 hfinfo = fi->hfinfo;
6215 integer = value;
6216
6217 if (hfinfo->bitmask) {
6218 /* Mask out irrelevant portions */
6219 integer &= hfinfo->bitmask;
6220
6221 /* Shift bits */
6222 integer >>= hfinfo_bitshift(hfinfo);
6223
6224 no_of_bits = ws_count_ones(hfinfo->bitmask);
6225 integer = ws_sign_ext64(integer, no_of_bits);
6226
6227 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6228 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)
;
6229 }
6230
6231 fvalue_set_sinteger64(fi->value, integer);
6232}
6233
6234proto_item *
6235proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6236 int start, int length, int64_t value,
6237 const char *format, ...)
6238{
6239 proto_item *pi;
6240 va_list ap;
6241
6242 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6243 if (pi != tree) {
6244 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6244, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6245
6246 va_start(ap, format)__builtin_va_start(ap, format);
6247 proto_tree_set_representation(pi, format, ap);
6248 va_end(ap)__builtin_va_end(ap);
6249 }
6250
6251 return pi;
6252}
6253
6254/* Add a FT_EUI64 to a proto_tree */
6255proto_item *
6256proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6257 int length, const uint64_t value)
6258{
6259 proto_item *pi;
6260 header_field_info *hfinfo;
6261
6262 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6263
6264 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", 6264
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6264, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6264, "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", 6264, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6265
6266 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",
6266, ((hfinfo))->abbrev))))
;
6267
6268 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6269 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6270
6271 return pi;
6272}
6273
6274proto_item *
6275proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6276 int start, int length, const uint64_t value,
6277 const char *format, ...)
6278{
6279 proto_item *pi;
6280 va_list ap;
6281
6282 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6283 if (pi != tree) {
6284 va_start(ap, format)__builtin_va_start(ap, format);
6285 proto_tree_set_representation_value(pi, format, ap);
6286 va_end(ap)__builtin_va_end(ap);
6287 }
6288
6289 return pi;
6290}
6291
6292proto_item *
6293proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6294 int start, int length, const uint64_t value,
6295 const char *format, ...)
6296{
6297 proto_item *pi;
6298 va_list ap;
6299
6300 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6301 if (pi != tree) {
6302 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6302, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6303
6304 va_start(ap, format)__builtin_va_start(ap, format);
6305 proto_tree_set_representation(pi, format, ap);
6306 va_end(ap)__builtin_va_end(ap);
6307 }
6308
6309 return pi;
6310}
6311
6312/* Set the FT_EUI64 value */
6313static void
6314proto_tree_set_eui64(field_info *fi, const uint64_t value)
6315{
6316 uint8_t v[FT_EUI64_LEN8];
6317 phtonu64(v, value);
6318 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6319}
6320
6321static void
6322proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6323{
6324 if (encoding)
6325 {
6326 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6327 } else {
6328 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6329 }
6330}
6331
6332proto_item *
6333proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6334 const mac_hf_list_t *list_generic,
6335 int idx, tvbuff_t *tvb,
6336 proto_tree *tree, int offset)
6337{
6338 uint8_t addr[6];
6339 const char *addr_name = NULL((void*)0);
6340 const char *oui_name = NULL((void*)0);
6341 proto_item *addr_item = NULL((void*)0);
6342 proto_tree *addr_tree = NULL((void*)0);
6343 proto_item *ret_val = NULL((void*)0);
6344
6345 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6346 return NULL((void*)0);
6347 }
6348
6349 /* Resolve what we can of the address */
6350 tvb_memcpy(tvb, addr, offset, sizeof addr);
6351 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6352 addr_name = get_ether_name(addr);
6353 }
6354 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6355 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6356 }
6357
6358 /* Add the item for the specific address type */
6359 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6360 if (idx >= 0) {
6361 addr_tree = proto_item_add_subtree(ret_val, idx);
6362 }
6363 else {
6364 addr_tree = tree;
6365 }
6366
6367 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6368 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6369 tvb, offset, 6, addr_name);
6370 proto_item_set_generated(addr_item);
6371 proto_item_set_hidden(addr_item);
6372 }
6373
6374 if (list_specific->hf_oui != NULL((void*)0)) {
6375 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6376 proto_item_set_generated(addr_item);
6377 proto_item_set_hidden(addr_item);
6378
6379 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6380 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6381 proto_item_set_generated(addr_item);
6382 proto_item_set_hidden(addr_item);
6383 }
6384 }
6385
6386 if (list_specific->hf_lg != NULL((void*)0)) {
6387 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6388 }
6389 if (list_specific->hf_ig != NULL((void*)0)) {
6390 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6391 }
6392
6393 /* Were we given a list for generic address fields? If not, stop here */
6394 if (list_generic == NULL((void*)0)) {
6395 return ret_val;
6396 }
6397
6398 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6399 proto_item_set_hidden(addr_item);
6400
6401 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6402 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6403 tvb, offset, 6, addr_name);
6404 proto_item_set_generated(addr_item);
6405 proto_item_set_hidden(addr_item);
6406 }
6407
6408 if (list_generic->hf_oui != NULL((void*)0)) {
6409 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6410 proto_item_set_generated(addr_item);
6411 proto_item_set_hidden(addr_item);
6412
6413 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6414 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6415 proto_item_set_generated(addr_item);
6416 proto_item_set_hidden(addr_item);
6417 }
6418 }
6419
6420 if (list_generic->hf_lg != NULL((void*)0)) {
6421 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6422 proto_item_set_hidden(addr_item);
6423 }
6424 if (list_generic->hf_ig != NULL((void*)0)) {
6425 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6426 proto_item_set_hidden(addr_item);
6427 }
6428 return ret_val;
6429}
6430
6431static proto_item *
6432proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6433{
6434 proto_node *pnode, *tnode, *sibling;
6435 field_info *tfi;
6436 unsigned depth = 1;
6437
6438 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6438, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6439
6440 /*
6441 * Restrict our depth. proto_tree_traverse_pre_order and
6442 * proto_tree_traverse_post_order (and possibly others) are recursive
6443 * so we need to be mindful of our stack size.
6444 */
6445 if (tree->first_child == NULL((void*)0)) {
6446 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6447 depth++;
6448 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6449 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__)), 6452)))
6450 "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__)), 6452)))
6451 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__)), 6452)))
6452 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__)), 6452)))
;
6453 }
6454 }
6455 }
6456
6457 /*
6458 * Make sure "tree" is ready to have subtrees under it, by
6459 * checking whether it's been given an ett_ value.
6460 *
6461 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6462 * node of the protocol tree. That node is not displayed,
6463 * so it doesn't need an ett_ value to remember whether it
6464 * was expanded.
6465 */
6466 tnode = tree;
6467 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6468 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6469 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"
, 6470)
6470 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"
, 6470)
;
6471 /* XXX - is it safe to continue here? */
6472 }
6473
6474 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6475 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6476 pnode->parent = tnode;
6477 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6478 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6479 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6480
6481 if (tnode->last_child != NULL((void*)0)) {
6482 sibling = tnode->last_child;
6483 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6483, "sibling->next == ((void*)0)"
))))
;
6484 sibling->next = pnode;
6485 } else
6486 tnode->first_child = pnode;
6487 tnode->last_child = pnode;
6488
6489 /* We should not be adding a fake node for an interesting field */
6490 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", 6490, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6491
6492 /* XXX - Should the proto_item have a header_field_info member, at least
6493 * for faked items, to know what hfi was faked? (Some dissectors look at
6494 * the tree items directly.)
6495 */
6496 return (proto_item *)pnode;
6497}
6498
6499/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6500static proto_item *
6501proto_tree_add_node(proto_tree *tree, field_info *fi)
6502{
6503 proto_node *pnode, *tnode, *sibling;
6504 field_info *tfi;
6505 unsigned depth = 1;
6506
6507 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6507, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6508
6509 /*
6510 * Restrict our depth. proto_tree_traverse_pre_order and
6511 * proto_tree_traverse_post_order (and possibly others) are recursive
6512 * so we need to be mindful of our stack size.
6513 */
6514 if (tree->first_child == NULL((void*)0)) {
6515 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6516 depth++;
6517 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6518 fvalue_free(fi->value);
6519 fi->value = NULL((void*)0);
6520 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__)), 6523)))
6521 "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__)), 6523)))
6522 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__)), 6523)))
6523 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__)), 6523)))
;
6524 }
6525 }
6526 }
6527
6528 /*
6529 * Make sure "tree" is ready to have subtrees under it, by
6530 * checking whether it's been given an ett_ value.
6531 *
6532 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6533 * node of the protocol tree. That node is not displayed,
6534 * so it doesn't need an ett_ value to remember whether it
6535 * was expanded.
6536 */
6537 tnode = tree;
6538 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6539 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6540 /* Since we are not adding fi to a node, its fvalue won't get
6541 * freed by proto_tree_free_node(), so free it now.
6542 */
6543 fvalue_free(fi->value);
6544 fi->value = NULL((void*)0);
6545 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", 6546)
6546 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", 6546)
;
6547 /* XXX - is it safe to continue here? */
6548 }
6549
6550 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6551 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6552 pnode->parent = tnode;
6553 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6554 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6555 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6556
6557 if (tnode->last_child != NULL((void*)0)) {
6558 sibling = tnode->last_child;
6559 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6559, "sibling->next == ((void*)0)"
))))
;
6560 sibling->next = pnode;
6561 } else
6562 tnode->first_child = pnode;
6563 tnode->last_child = pnode;
6564
6565 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6566
6567 return (proto_item *)pnode;
6568}
6569
6570
6571/* Generic way to allocate field_info and add to proto_tree.
6572 * Sets *pfi to address of newly-allocated field_info struct */
6573static proto_item *
6574proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6575 int *length)
6576{
6577 proto_item *pi;
6578 field_info *fi;
6579 int item_length;
6580
6581 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6582 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6583 pi = proto_tree_add_node(tree, fi);
6584
6585 return pi;
6586}
6587
6588
6589static void
6590get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6591 int *item_length, const unsigned encoding)
6592{
6593 int length_remaining;
6594
6595 /*
6596 * We only allow a null tvbuff if the item has a zero length,
6597 * i.e. if there's no data backing it.
6598 */
6599 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", 6599, "tvb != ((void*)0) || *length == 0"
))))
;
6600
6601 /*
6602 * XXX - in some protocols, there are 32-bit unsigned length
6603 * fields, so lengths in protocol tree and tvbuff routines
6604 * should really be unsigned. We should have, for those
6605 * field types for which "to the end of the tvbuff" makes sense,
6606 * additional routines that take no length argument and
6607 * add fields that run to the end of the tvbuff.
6608 */
6609 if (*length == -1) {
6610 /*
6611 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6612 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6613 * of -1 means "set the length to what remains in the
6614 * tvbuff".
6615 *
6616 * The assumption is either that
6617 *
6618 * 1) the length of the item can only be determined
6619 * by dissection (typically true of items with
6620 * subitems, which are probably FT_NONE or
6621 * FT_PROTOCOL)
6622 *
6623 * or
6624 *
6625 * 2) if the tvbuff is "short" (either due to a short
6626 * snapshot length or due to lack of reassembly of
6627 * fragments/segments/whatever), we want to display
6628 * what's available in the field (probably FT_BYTES
6629 * or FT_STRING) and then throw an exception later
6630 *
6631 * or
6632 *
6633 * 3) the field is defined to be "what's left in the
6634 * packet"
6635 *
6636 * so we set the length to what remains in the tvbuff so
6637 * that, if we throw an exception while dissecting, it
6638 * has what is probably the right value.
6639 *
6640 * For FT_STRINGZ, it means "the string is null-terminated,
6641 * not null-padded; set the length to the actual length
6642 * of the string", and if the tvbuff if short, we just
6643 * throw an exception.
6644 *
6645 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6646 * it means "find the end of the string",
6647 * and if the tvbuff if short, we just throw an exception.
6648 *
6649 * It's not valid for any other type of field. For those
6650 * fields, we treat -1 the same way we treat other
6651 * negative values - we assume the length is a Really
6652 * Big Positive Number, and throw a ReportedBoundsError
6653 * exception, under the assumption that the Really Big
6654 * Length would run past the end of the packet.
6655 */
6656 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
))
)) {
6657 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6658 /*
6659 * Leave the length as -1, so our caller knows
6660 * it was -1.
6661 */
6662 *item_length = *length;
6663 return;
6664 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6665 switch (tvb_get_uint8(tvb, start) >> 6)
6666 {
6667 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6668 *item_length = 1;
6669 break;
6670 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6671 *item_length = 2;
6672 break;
6673 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6674 *item_length = 4;
6675 break;
6676 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6677 *item_length = 8;
6678 break;
6679 }
6680 }
6681 }
6682
6683 switch (hfinfo->type) {
6684
6685 case FT_PROTOCOL:
6686 case FT_NONE:
6687 case FT_BYTES:
6688 case FT_STRING:
6689 case FT_STRINGZPAD:
6690 case FT_STRINGZTRUNC:
6691 /*
6692 * We allow FT_PROTOCOLs to be zero-length -
6693 * for example, an ONC RPC NULL procedure has
6694 * neither arguments nor reply, so the
6695 * payload for that protocol is empty.
6696 *
6697 * We also allow the others to be zero-length -
6698 * because that's the way the code has been for a
6699 * long, long time.
6700 *
6701 * However, we want to ensure that the start
6702 * offset is not *past* the byte past the end
6703 * of the tvbuff: we throw an exception in that
6704 * case.
6705 */
6706 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6707 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6707, "*length >= 0"
))))
;
6708 break;
6709
6710 case FT_STRINGZ:
6711 /*
6712 * Leave the length as -1, so our caller knows
6713 * it was -1.
6714 */
6715 break;
6716
6717 default:
6718 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6719 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6719))
;
6720 }
6721 *item_length = *length;
6722 } else {
6723 *item_length = *length;
6724 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6725 /*
6726 * These types are for interior nodes of the
6727 * tree, and don't have data associated with
6728 * them; if the length is negative (XXX - see
6729 * above) or goes past the end of the tvbuff,
6730 * cut it short at the end of the tvbuff.
6731 * That way, if this field is selected in
6732 * Wireshark, we don't highlight stuff past
6733 * the end of the data.
6734 */
6735 /* XXX - what to do, if we don't have a tvb? */
6736 if (tvb) {
6737 length_remaining = tvb_captured_length_remaining(tvb, start);
6738 if (*item_length < 0 ||
6739 (*item_length > 0 &&
6740 (length_remaining < *item_length)))
6741 *item_length = length_remaining;
6742 }
6743 }
6744 if (*item_length < 0) {
6745 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6746 }
6747 }
6748}
6749
6750static int
6751get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6752 int length, unsigned item_length, const int encoding)
6753{
6754 uint32_t n;
6755
6756 /*
6757 * We need to get the correct item length here.
6758 * That's normally done by proto_tree_new_item(),
6759 * but we won't be calling it.
6760 */
6761 switch (hfinfo->type) {
6762
6763 case FT_NONE:
6764 case FT_PROTOCOL:
6765 case FT_BYTES:
6766 /*
6767 * The length is the specified length.
6768 */
6769 break;
6770
6771 case FT_UINT_BYTES:
6772 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6773 item_length += n;
6774 if ((int)item_length < length) {
6775 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6776 }
6777 break;
6778
6779 /* XXX - make these just FT_UINT? */
6780 case FT_UINT8:
6781 case FT_UINT16:
6782 case FT_UINT24:
6783 case FT_UINT32:
6784 case FT_UINT40:
6785 case FT_UINT48:
6786 case FT_UINT56:
6787 case FT_UINT64:
6788 /* XXX - make these just FT_INT? */
6789 case FT_INT8:
6790 case FT_INT16:
6791 case FT_INT24:
6792 case FT_INT32:
6793 case FT_INT40:
6794 case FT_INT48:
6795 case FT_INT56:
6796 case FT_INT64:
6797 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6798 if (length < -1) {
6799 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6800 }
6801 if (length == -1) {
6802 uint64_t dummy;
6803 /* This can throw an exception */
6804 /* XXX - do this without fetching the varint? */
6805 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6806 if (length == 0) {
6807 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6808 }
6809 }
6810 item_length = length;
6811 break;
6812 }
6813
6814 /*
6815 * The length is the specified length.
6816 */
6817 break;
6818
6819 case FT_BOOLEAN:
6820 case FT_CHAR:
6821 case FT_IPv4:
6822 case FT_IPXNET:
6823 case FT_IPv6:
6824 case FT_FCWWN:
6825 case FT_AX25:
6826 case FT_VINES:
6827 case FT_ETHER:
6828 case FT_EUI64:
6829 case FT_GUID:
6830 case FT_OID:
6831 case FT_REL_OID:
6832 case FT_SYSTEM_ID:
6833 case FT_FLOAT:
6834 case FT_DOUBLE:
6835 case FT_STRING:
6836 /*
6837 * The length is the specified length.
6838 */
6839 break;
6840
6841 case FT_STRINGZ:
6842 if (length < -1) {
6843 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6844 }
6845 if (length == -1) {
6846 /* This can throw an exception */
6847 /* XXX - do this without fetching the string? */
6848 wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, &length, encoding));
6849 }
6850 item_length = length;
6851 break;
6852
6853 case FT_UINT_STRING:
6854 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6855 item_length += n;
6856 if ((int)item_length < length) {
6857 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6858 }
6859 break;
6860
6861 case FT_STRINGZPAD:
6862 case FT_STRINGZTRUNC:
6863 case FT_ABSOLUTE_TIME:
6864 case FT_RELATIVE_TIME:
6865 case FT_IEEE_11073_SFLOAT:
6866 case FT_IEEE_11073_FLOAT:
6867 /*
6868 * The length is the specified length.
6869 */
6870 break;
6871
6872 default:
6873 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
))
6874 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
))
6875 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
))
6876 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
))
;
6877 break;
6878 }
6879 return item_length;
6880}
6881
6882// This was arbitrarily chosen, but if you're adding 50K items to the tree
6883// without advancing the offset you should probably take a long, hard look
6884// at what you're doing.
6885// We *could* make this a configurable option, but I (Gerald) would like to
6886// avoid adding yet another nerd knob.
6887# define PROTO_TREE_MAX_IDLE50000 50000
6888static field_info *
6889new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6890 const int start, const int item_length)
6891{
6892 field_info *fi;
6893
6894 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6895
6896 fi->hfinfo = hfinfo;
6897 fi->start = start;
6898 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6899 /* add the data source tvbuff */
6900 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6901
6902 // If our start offset hasn't advanced after adding many items it probably
6903 // means we're in a large or infinite loop.
6904 if (fi->start > 0) {
6905 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6906 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6907 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", 6907, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6908 } else {
6909 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6910 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6911 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6912 }
6913 }
6914 fi->length = item_length;
6915 fi->tree_type = -1;
6916 fi->flags = 0;
6917 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6918 /* If the tree is not visible, set the item hidden, unless we
6919 * need the representation or length and can't fake them.
6920 */
6921 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6922 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6923 }
6924 }
6925 fi->value = fvalue_new(fi->hfinfo->type);
6926 fi->rep = NULL((void*)0);
6927
6928 fi->appendix_start = 0;
6929 fi->appendix_length = 0;
6930
6931 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6932 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6933
6934 return fi;
6935}
6936
6937static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6938{
6939 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6940 return 0;
6941 }
6942
6943 /* Search for field name */
6944 char *ptr = strstr(representation, hfinfo->name);
6945 if (!ptr) {
6946 return 0;
6947 }
6948
6949 /* Check if field name ends with the ": " delimiter */
6950 ptr += strlen(hfinfo->name);
6951 if (strncmp(ptr, ": ", 2) == 0) {
6952 ptr += 2;
6953 }
6954
6955 /* Return offset to after field name */
6956 return ptr - representation;
6957}
6958
6959static size_t label_find_name_pos(const item_label_t *rep)
6960{
6961 size_t name_pos = 0;
6962
6963 /* If the value_pos is too small or too large, we can't find the expected format */
6964 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
6965 return 0;
6966 }
6967
6968 /* Check if the format looks like "label: value", then set name_pos before ':'. */
6969 if (rep->representation[rep->value_pos-2] == ':') {
6970 name_pos = rep->value_pos - 2;
6971 }
6972
6973 return name_pos;
6974}
6975
6976/* If the protocol tree is to be visible, set the representation of a
6977 proto_tree entry with the name of the field for the item and with
6978 the value formatted with the supplied printf-style format and
6979 argument list. */
6980static void
6981proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6982{
6983 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6983, __func__, "assertion failed: %s", "pi"
); } while (0)
;
6984
6985 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6986 * items string representation */
6987 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
6988 size_t name_pos, ret = 0;
6989 char *str;
6990 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6991 const header_field_info *hf;
6992
6993 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6993, "fi"))))
;
6994
6995 hf = fi->hfinfo;
6996
6997 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;
;
6998 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))
)) {
6999 uint64_t val;
7000 char *p;
7001
7002 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)
)
7003 val = fvalue_get_uinteger(fi->value);
7004 else
7005 val = fvalue_get_uinteger64(fi->value);
7006
7007 val <<= hfinfo_bitshift(hf);
7008
7009 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7010 ret = (p - fi->rep->representation);
7011 }
7012
7013 /* put in the hf name */
7014 name_pos = ret = label_concat(fi->rep->representation, ret, (const uint8_t*)hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)hf->name, 0)
;
7015
7016 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7017 /* If possible, Put in the value of the string */
7018 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7019 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"
, 7019, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7020 fi->rep->value_pos = ret;
7021 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7022 if (ret >= ITEM_LABEL_LENGTH240) {
7023 /* Uh oh, we don't have enough room. Tell the user
7024 * that the field is truncated.
7025 */
7026 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7027 }
7028 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7029 }
7030}
7031
7032/* If the protocol tree is to be visible, set the representation of a
7033 proto_tree entry with the representation formatted with the supplied
7034 printf-style format and argument list. */
7035static void
7036proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7037{
7038 size_t ret; /*tmp return value */
7039 char *str;
7040 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7041
7042 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7042, "fi"))))
;
7043
7044 if (!proto_item_is_hidden(pi)) {
7045 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;
;
7046
7047 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7048 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"
, 7048, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7049 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7050 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7051 if (ret >= ITEM_LABEL_LENGTH240) {
7052 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7053 size_t name_pos = label_find_name_pos(fi->rep);
7054 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7055 }
7056 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7057 }
7058}
7059
7060static int
7061proto_strlcpy(char *dest, const char *src, size_t dest_size)
7062{
7063 if (dest_size == 0) return 0;
7064
7065 size_t res = g_strlcpy(dest, src, dest_size);
7066
7067 /* At most dest_size - 1 characters will be copied
7068 * (unless dest_size is 0). */
7069 if (res >= dest_size)
7070 res = dest_size - 1;
7071 return (int) res;
7072}
7073
7074static header_field_info *
7075hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7076{
7077 header_field_info *dup_hfinfo;
7078
7079 if (hfinfo->same_name_prev_id == -1)
7080 return NULL((void*)0);
7081 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", 7081
, __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", 7081, "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", 7081,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7082 return dup_hfinfo;
7083}
7084
7085static void
7086hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7087{
7088 g_free(last_field_name);
7089 last_field_name = NULL((void*)0);
7090
7091 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7092 /* No hfinfo with the same name */
7093 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7094 return;
7095 }
7096
7097 if (hfinfo->same_name_next) {
7098 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7099 }
7100
7101 if (hfinfo->same_name_prev_id != -1) {
7102 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7103 same_name_prev->same_name_next = hfinfo->same_name_next;
7104 if (!hfinfo->same_name_next) {
7105 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7106 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7107 }
7108 }
7109}
7110
7111int
7112proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7113{
7114 const header_field_info *hfinfo = finfo->hfinfo;
7115 int label_len = 0;
7116 char *tmp_str;
7117 const char *str;
7118 const uint8_t *bytes;
7119 uint32_t number;
7120 uint64_t number64;
7121 const char *hf_str_val;
7122 char number_buf[NUMBER_LABEL_LENGTH80];
7123 const char *number_out;
7124 address addr;
7125 const ipv4_addr_and_mask *ipv4;
7126 const ipv6_addr_and_prefix *ipv6;
7127
7128 switch (hfinfo->type) {
7129
7130 case FT_NONE:
7131 case FT_PROTOCOL:
7132 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7133
7134 case FT_UINT_BYTES:
7135 case FT_BYTES:
7136 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7137 hfinfo,
7138 fvalue_get_bytes_data(finfo->value),
7139 (unsigned)fvalue_length2(finfo->value),
7140 label_str_size);
7141 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7142 wmem_free(NULL((void*)0), tmp_str);
7143 break;
7144
7145 case FT_ABSOLUTE_TIME:
7146 {
7147 const nstime_t *value = fvalue_get_time(finfo->value);
7148 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7149 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7150 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7151 }
7152 if (hfinfo->strings) {
7153 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7154 if (time_string != NULL((void*)0)) {
7155 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7156 break;
7157 }
7158 }
7159 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7160 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7161 wmem_free(NULL((void*)0), tmp_str);
7162 break;
7163 }
7164
7165 case FT_RELATIVE_TIME:
7166 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7167 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7168 wmem_free(NULL((void*)0), tmp_str);
7169 break;
7170
7171 case FT_BOOLEAN:
7172 number64 = fvalue_get_uinteger64(finfo->value);
7173 label_len = proto_strlcpy(display_label_str,
7174 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7175 break;
7176
7177 case FT_CHAR:
7178 number = fvalue_get_uinteger(finfo->value);
7179
7180 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7181 char tmp[ITEM_LABEL_LENGTH240];
7182 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7183
7184 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7184, "fmtfunc"))))
;
7185 fmtfunc(tmp, number);
7186
7187 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7188
7189 } else if (hfinfo->strings) {
7190 number_out = hf_try_val_to_str(number, hfinfo);
7191
7192 if (!number_out) {
7193 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7194 }
7195
7196 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7197
7198 } else {
7199 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7200
7201 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7202 }
7203
7204 break;
7205
7206 /* XXX - make these just FT_NUMBER? */
7207 case FT_INT8:
7208 case FT_INT16:
7209 case FT_INT24:
7210 case FT_INT32:
7211 case FT_UINT8:
7212 case FT_UINT16:
7213 case FT_UINT24:
7214 case FT_UINT32:
7215 case FT_FRAMENUM:
7216 hf_str_val = NULL((void*)0);
7217 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
))
?
7218 (uint32_t) fvalue_get_sinteger(finfo->value) :
7219 fvalue_get_uinteger(finfo->value);
7220
7221 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7222 char tmp[ITEM_LABEL_LENGTH240];
7223 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7224
7225 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7225, "fmtfunc"))))
;
7226 fmtfunc(tmp, number);
7227
7228 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7229
7230 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7231 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7232 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7233 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7234 hf_str_val = hf_try_val_to_str(number, hfinfo);
7235 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7236 } else {
7237 number_out = hf_try_val_to_str(number, hfinfo);
7238
7239 if (!number_out) {
7240 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7241 }
7242
7243 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7244 }
7245 } else {
7246 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7247
7248 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7249 }
7250
7251 break;
7252
7253 case FT_INT40:
7254 case FT_INT48:
7255 case FT_INT56:
7256 case FT_INT64:
7257 case FT_UINT40:
7258 case FT_UINT48:
7259 case FT_UINT56:
7260 case FT_UINT64:
7261 hf_str_val = NULL((void*)0);
7262 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
))
?
7263 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7264 fvalue_get_uinteger64(finfo->value);
7265
7266 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7267 char tmp[ITEM_LABEL_LENGTH240];
7268 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7269
7270 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7270, "fmtfunc64"
))))
;
7271 fmtfunc64(tmp, number64);
7272
7273 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7274 } else if (hfinfo->strings) {
7275 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7276 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7277 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7278 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7279 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7280 } else {
7281 number_out = hf_try_val64_to_str(number64, hfinfo);
7282
7283 if (!number_out)
7284 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7285
7286 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7287 }
7288 } else {
7289 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7290
7291 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7292 }
7293
7294 break;
7295
7296 case FT_EUI64:
7297 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7298 tmp_str = address_to_display(NULL((void*)0), &addr);
7299 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7300 wmem_free(NULL((void*)0), tmp_str);
7301 break;
7302
7303 case FT_IPv4:
7304 ipv4 = fvalue_get_ipv4(finfo->value);
7305 //XXX: Should we ignore the mask?
7306 set_address_ipv4(&addr, ipv4);
7307 tmp_str = address_to_display(NULL((void*)0), &addr);
7308 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7309 wmem_free(NULL((void*)0), tmp_str);
7310 free_address(&addr);
7311 break;
7312
7313 case FT_IPv6:
7314 ipv6 = fvalue_get_ipv6(finfo->value);
7315 set_address_ipv6(&addr, ipv6);
7316 tmp_str = address_to_display(NULL((void*)0), &addr);
7317 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7318 wmem_free(NULL((void*)0), tmp_str);
7319 free_address(&addr);
7320 break;
7321
7322 case FT_FCWWN:
7323 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7324 tmp_str = address_to_display(NULL((void*)0), &addr);
7325 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7326 wmem_free(NULL((void*)0), tmp_str);
7327 break;
7328
7329 case FT_ETHER:
7330 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7331 tmp_str = address_to_display(NULL((void*)0), &addr);
7332 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7333 wmem_free(NULL((void*)0), tmp_str);
7334 break;
7335
7336 case FT_GUID:
7337 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7338 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7339 wmem_free(NULL((void*)0), tmp_str);
7340 break;
7341
7342 case FT_REL_OID:
7343 bytes = fvalue_get_bytes_data(finfo->value);
7344 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7345 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7346 wmem_free(NULL((void*)0), tmp_str);
7347 break;
7348
7349 case FT_OID:
7350 bytes = fvalue_get_bytes_data(finfo->value);
7351 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7352 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7353 wmem_free(NULL((void*)0), tmp_str);
7354 break;
7355
7356 case FT_SYSTEM_ID:
7357 bytes = fvalue_get_bytes_data(finfo->value);
7358 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7359 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7360 wmem_free(NULL((void*)0), tmp_str);
7361 break;
7362
7363 case FT_FLOAT:
7364 case FT_DOUBLE:
7365 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7366 break;
7367
7368 case FT_IEEE_11073_SFLOAT:
7369 case FT_IEEE_11073_FLOAT:
7370 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7371 break;
7372
7373 case FT_STRING:
7374 case FT_STRINGZ:
7375 case FT_UINT_STRING:
7376 case FT_STRINGZPAD:
7377 case FT_STRINGZTRUNC:
7378 str = fvalue_get_string(finfo->value);
7379 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7380 if (label_len >= label_str_size) {
7381 /* Truncation occurred. Get the real length
7382 * copied (not including '\0') */
7383 label_len = label_str_size ? label_str_size - 1 : 0;
7384 }
7385 break;
7386
7387 default:
7388 /* First try ftype string representation */
7389 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7390 if (!tmp_str) {
7391 /* Default to show as bytes */
7392 bytes = fvalue_get_bytes_data(finfo->value);
7393 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7394 }
7395 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7396 wmem_free(NULL((void*)0), tmp_str);
7397 break;
7398 }
7399 return label_len;
7400}
7401
7402const char *
7403proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7404 char *result, char *expr, const int size)
7405{
7406 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7407 GPtrArray *finfos;
7408 field_info *finfo = NULL((void*)0);
7409 header_field_info* hfinfo;
7410 const char *abbrev = NULL((void*)0);
7411
7412 char *str;
7413 col_custom_t *field_idx;
7414 int field_id;
7415 int ii = 0;
7416
7417 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7417, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7418 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7419 field_id = field_idx->field_id;
7420 if (field_id == 0) {
7421 GPtrArray *fvals = NULL((void*)0);
7422 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7423 if (fvals != NULL((void*)0)) {
7424
7425 // XXX - Handling occurrences is unusual when more
7426 // than one field is involved, e.g. there's four
7427 // results for tcp.port + tcp.port. We may really
7428 // want to apply it to the operands, not the output.
7429 // Note that occurrences are not quite the same as
7430 // the layer operator (should the grammar support
7431 // both?)
7432 /* Calculate single index or set outer boundaries */
7433 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7434 if (occurrence < 0) {
7435 i = occurrence + len;
7436 last = i;
7437 } else if (occurrence > 0) {
7438 i = occurrence - 1;
7439 last = i;
7440 } else {
7441 i = 0;
7442 last = len - 1;
7443 }
7444 if (i < 0 || i >= len) {
7445 g_ptr_array_unref(fvals);
7446 continue;
7447 }
7448 for (; i <= last; i++) {
7449 /* XXX - We could have a "resolved" result
7450 * for types where the value depends only
7451 * on the type, e.g. FT_IPv4, and not on
7452 * hfinfo->strings. Supporting the latter
7453 * requires knowing which hfinfo matched
7454 * if there are multiple with the same
7455 * abbreviation. In any case, we need to
7456 * know the expected return type of the
7457 * field expression.
7458 */
7459 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7460 if (offset_r && (offset_r < (size - 1)))
7461 result[offset_r++] = ',';
7462 if (offset_e && (offset_e < (size - 1)))
7463 expr[offset_e++] = ',';
7464 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7465 // col_{add,append,set}_* calls ws_label_strcpy
7466 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7467
7468 g_free(str);
7469 }
7470 g_ptr_array_unref(fvals);
7471 } else if (passed) {
7472 // XXX - Occurrence doesn't make sense for a test
7473 // output, it should be applied to the operands.
7474 if (offset_r && (offset_r < (size - 1)))
7475 result[offset_r++] = ',';
7476 if (offset_e && (offset_e < (size - 1)))
7477 expr[offset_e++] = ',';
7478 /* Prevent multiple check marks */
7479 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7480 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7481 } else {
7482 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7483 }
7484 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7485 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7486 } else {
7487 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7488 }
7489 }
7490 continue;
7491 }
7492 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", 7492
, __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", 7492,
"(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", 7492,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7493
7494 /* do we need to rewind ? */
7495 if (!hfinfo)
7496 return "";
7497
7498 if (occurrence < 0) {
7499 /* Search other direction */
7500 while (hfinfo->same_name_prev_id != -1) {
7501 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", 7501
, __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", 7501, "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", 7501,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7502 }
7503 }
7504
7505 prev_len = 0; /* Reset handled occurrences */
7506
7507 while (hfinfo) {
7508 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7509
7510 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7511 if (occurrence < 0) {
7512 hfinfo = hfinfo->same_name_next;
7513 } else {
7514 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7515 }
7516 continue;
7517 }
7518
7519 /* Are there enough occurrences of the field? */
7520 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7521 if (occurrence < 0) {
7522 hfinfo = hfinfo->same_name_next;
7523 } else {
7524 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7525 }
7526 prev_len += len;
7527 continue;
7528 }
7529
7530 /* Calculate single index or set outer boundaries */
7531 if (occurrence < 0) {
7532 i = occurrence + len + prev_len;
7533 last = i;
7534 } else if (occurrence > 0) {
7535 i = occurrence - 1 - prev_len;
7536 last = i;
7537 } else {
7538 i = 0;
7539 last = len - 1;
7540 }
7541
7542 prev_len += len; /* Count handled occurrences */
7543
7544 while (i <= last) {
7545 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7546
7547 if (offset_r && (offset_r < (size - 1)))
7548 result[offset_r++] = ',';
7549
7550 if (display_details) {
7551 char representation[ITEM_LABEL_LENGTH240];
7552 size_t offset = 0;
7553
7554 if (finfo->rep && finfo->rep->value_len) {
7555 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7556 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7557 } else {
7558 proto_item_fill_label(finfo, representation, &offset);
7559 }
7560 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7561 } else {
7562 switch (hfinfo->type) {
7563
7564 case FT_NONE:
7565 case FT_PROTOCOL:
7566 /* Prevent multiple check marks */
7567 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7568 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7569 } else {
7570 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7571 }
7572 break;
7573
7574 default:
7575 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7576 break;
7577 }
7578 }
7579
7580 if (offset_e && (offset_e < (size - 1)))
7581 expr[offset_e++] = ',';
7582
7583 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
))
)) {
7584 const char *hf_str_val;
7585 /* Integer types with BASE_NONE never get the numeric value. */
7586 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7587 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7588 } 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
)
) {
7589 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7590 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7591 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7592 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7593 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7594 }
7595 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7596 offset_e = (int)strlen(expr);
7597 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7598 /* Prevent multiple check marks */
7599 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7600 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7601 } else {
7602 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7603 }
7604 } else {
7605 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7606 // col_{add,append,set}_* calls ws_label_strcpy
7607 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7608 wmem_free(NULL((void*)0), str);
7609 }
7610 i++;
7611 }
7612
7613 /* XXX: Why is only the first abbreviation returned for a multifield
7614 * custom column? */
7615 if (!abbrev) {
7616 /* Store abbrev for return value */
7617 abbrev = hfinfo->abbrev;
7618 }
7619
7620 if (occurrence == 0) {
7621 /* Fetch next hfinfo with same name (abbrev) */
7622 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7623 } else {
7624 hfinfo = NULL((void*)0);
7625 }
7626 }
7627 }
7628
7629 if (offset_r >= (size - 1)) {
7630 mark_truncated(result, 0, size, NULL((void*)0));
7631 }
7632 if (offset_e >= (size - 1)) {
7633 mark_truncated(expr, 0, size, NULL((void*)0));
7634 }
7635 return abbrev ? abbrev : "";
7636}
7637
7638char *
7639proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7640{
7641 int len, prev_len, last, i;
7642 GPtrArray *finfos;
7643 field_info *finfo = NULL((void*)0);
7644 header_field_info* hfinfo;
7645
7646 char *filter = NULL((void*)0);
7647 GPtrArray *filter_array;
7648
7649 col_custom_t *col_custom;
7650 int field_id;
7651
7652 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7652, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7653 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7654 for (GSList *iter = field_ids; iter; iter = iter->next) {
7655 col_custom = (col_custom_t*)iter->data;
7656 field_id = col_custom->field_id;
7657 if (field_id == 0) {
7658 GPtrArray *fvals = NULL((void*)0);
7659 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7660 if (fvals != NULL((void*)0)) {
7661 // XXX - Handling occurrences is unusual when more
7662 // than one field is involved, e.g. there's four
7663 // results for tcp.port + tcp.port. We really
7664 // want to apply it to the operands, not the output.
7665 /* Calculate single index or set outer boundaries */
7666 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7667 if (occurrence < 0) {
7668 i = occurrence + len;
7669 last = i;
7670 } else if (occurrence > 0) {
7671 i = occurrence - 1;
7672 last = i;
7673 } else {
7674 i = 0;
7675 last = len - 1;
7676 }
7677 if (i < 0 || i >= len) {
7678 g_ptr_array_unref(fvals);
7679 continue;
7680 }
7681 for (; i <= last; i++) {
7682 /* XXX - Should multiple values for one
7683 * field use set membership to reduce
7684 * verbosity, here and below? */
7685 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7686 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7687 wmem_free(NULL((void*)0), str);
7688 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7689 g_ptr_array_add(filter_array, filter);
7690 }
7691 }
7692 g_ptr_array_unref(fvals);
7693 } else if (passed) {
7694 filter = wmem_strdup(NULL((void*)0), 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 } else {
7699 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7700 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7701 g_ptr_array_add(filter_array, filter);
7702 }
7703 }
7704 continue;
7705 }
7706
7707 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", 7707
, __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", 7707,
"(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", 7707,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7708
7709 /* do we need to rewind ? */
7710 if (!hfinfo)
7711 return NULL((void*)0);
7712
7713 if (occurrence < 0) {
7714 /* Search other direction */
7715 while (hfinfo->same_name_prev_id != -1) {
7716 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", 7716
, __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", 7716, "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", 7716,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7717 }
7718 }
7719
7720 prev_len = 0; /* Reset handled occurrences */
7721
7722 while (hfinfo) {
7723 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7724
7725 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7726 if (occurrence < 0) {
7727 hfinfo = hfinfo->same_name_next;
7728 } else {
7729 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7730 }
7731 continue;
7732 }
7733
7734 /* Are there enough occurrences of the field? */
7735 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7736 if (occurrence < 0) {
7737 hfinfo = hfinfo->same_name_next;
7738 } else {
7739 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7740 }
7741 prev_len += len;
7742 continue;
7743 }
7744
7745 /* Calculate single index or set outer boundaries */
7746 if (occurrence < 0) {
7747 i = occurrence + len + prev_len;
7748 last = i;
7749 } else if (occurrence > 0) {
7750 i = occurrence - 1 - prev_len;
7751 last = i;
7752 } else {
7753 i = 0;
7754 last = len - 1;
7755 }
7756
7757 prev_len += len; /* Count handled occurrences */
7758
7759 while (i <= last) {
7760 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7761
7762 filter = proto_construct_match_selected_string(finfo, edt);
7763 if (filter) {
7764 /* Only add the same expression once (especially for FT_PROTOCOL).
7765 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7766 */
7767 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7768 g_ptr_array_add(filter_array, filter);
7769 }
7770 }
7771 i++;
7772 }
7773
7774 if (occurrence == 0) {
7775 /* Fetch next hfinfo with same name (abbrev) */
7776 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7777 } else {
7778 hfinfo = NULL((void*)0);
7779 }
7780 }
7781 }
7782
7783 g_ptr_array_add(filter_array, NULL((void*)0));
7784
7785 /* XXX: Should this be || or && ? */
7786 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7787
7788 g_ptr_array_free(filter_array, true1);
7789
7790 return output;
7791}
7792
7793/* Set text of proto_item after having already been created. */
7794void
7795proto_item_set_text(proto_item *pi, const char *format, ...)
7796{
7797 field_info *fi = NULL((void*)0);
7798 va_list ap;
7799
7800 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7801
7802 fi = PITEM_FINFO(pi)((pi)->finfo);
7803 if (fi == NULL((void*)0))
7804 return;
7805
7806 if (fi->rep) {
7807 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7808 fi->rep = NULL((void*)0);
7809 }
7810
7811 va_start(ap, format)__builtin_va_start(ap, format);
7812 proto_tree_set_representation(pi, format, ap);
7813 va_end(ap)__builtin_va_end(ap);
7814}
7815
7816/* Append to text of proto_item after having already been created. */
7817void
7818proto_item_append_text(proto_item *pi, const char *format, ...)
7819{
7820 field_info *fi = NULL((void*)0);
7821 size_t curlen;
7822 char *str;
7823 va_list ap;
7824
7825 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7826
7827 fi = PITEM_FINFO(pi)((pi)->finfo);
7828 if (fi == NULL((void*)0)) {
7829 return;
7830 }
7831
7832 if (!proto_item_is_hidden(pi)) {
7833 /*
7834 * If we don't already have a representation,
7835 * generate the default representation.
7836 */
7837 if (fi->rep == NULL((void*)0)) {
7838 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;
;
7839 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7840 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7841 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7842 (strncmp(format, ": ", 2) == 0)) {
7843 fi->rep->value_pos += 2;
7844 }
7845 }
7846 if (fi->rep) {
7847 curlen = strlen(fi->rep->representation);
7848 /* curlen doesn't include the \0 byte.
7849 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7850 * the representation has already been truncated (of an up
7851 * to 4 byte UTF-8 character) or is just at the maximum length
7852 * unless we search for " [truncated]" (which may not be
7853 * at the start.)
7854 * It's safer to do nothing.
7855 */
7856 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7857 va_start(ap, format)__builtin_va_start(ap, format);
7858 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7859 va_end(ap)__builtin_va_end(ap);
7860 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"
, 7860, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7861 /* Keep fi->rep->value_pos */
7862 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
7863 if (curlen >= ITEM_LABEL_LENGTH240) {
7864 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7865 size_t name_pos = label_find_name_pos(fi->rep);
7866 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7867 }
7868 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7869 }
7870 }
7871 }
7872}
7873
7874/* Prepend to text of proto_item after having already been created. */
7875void
7876proto_item_prepend_text(proto_item *pi, const char *format, ...)
7877{
7878 field_info *fi = NULL((void*)0);
7879 size_t pos;
7880 char representation[ITEM_LABEL_LENGTH240];
7881 char *str;
7882 va_list ap;
7883
7884 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7885
7886 fi = PITEM_FINFO(pi)((pi)->finfo);
7887 if (fi == NULL((void*)0)) {
7888 return;
7889 }
7890
7891 if (!proto_item_is_hidden(pi)) {
7892 /*
7893 * If we don't already have a representation,
7894 * generate the default representation.
7895 */
7896 if (fi->rep == NULL((void*)0)) {
7897 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;
;
7898 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7899 } else
7900 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7901
7902 va_start(ap, format)__builtin_va_start(ap, format);
7903 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7904 va_end(ap)__builtin_va_end(ap);
7905 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"
, 7905, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7906 fi->rep->value_pos += strlen(str);
7907 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7908 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
7909 /* XXX: As above, if the old representation is close to the label
7910 * length, it might already be marked as truncated. */
7911 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7912 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7913 size_t name_pos = label_find_name_pos(fi->rep);
7914 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7915 }
7916 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7917 }
7918}
7919
7920static void
7921finfo_set_len(field_info *fi, const int length)
7922{
7923 int length_remaining;
7924
7925 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", 7925,
"length >= 0", fi->hfinfo->abbrev))))
;
7926 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7927 if (length > length_remaining)
7928 fi->length = length_remaining;
7929 else
7930 fi->length = length;
7931
7932 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7933 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7934 fvalue_set_protocol_length(fi->value, fi->length);
7935 }
7936
7937 /*
7938 * You cannot just make the "len" field of a GByteArray
7939 * larger, if there's no data to back that length;
7940 * you can only make it smaller.
7941 */
7942 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7943 GBytes *bytes = fvalue_get_bytes(fi->value);
7944 size_t size;
7945 const void *data = g_bytes_get_data(bytes, &size);
7946 if ((size_t)fi->length <= size) {
7947 fvalue_set_bytes_data(fi->value, data, fi->length);
7948 }
7949 g_bytes_unref(bytes);
7950 }
7951}
7952
7953void
7954proto_item_set_len(proto_item *pi, const int length)
7955{
7956 field_info *fi;
7957
7958 if (pi == NULL((void*)0))
7959 return;
7960
7961 fi = PITEM_FINFO(pi)((pi)->finfo);
7962 if (fi == NULL((void*)0))
7963 return;
7964
7965 finfo_set_len(fi, length);
7966}
7967
7968/*
7969 * Sets the length of the item based on its start and on the specified
7970 * offset, which is the offset past the end of the item; as the start
7971 * in the item is relative to the beginning of the data source tvbuff,
7972 * we need to pass in a tvbuff - the end offset is relative to the beginning
7973 * of that tvbuff.
7974 */
7975void
7976proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7977{
7978 field_info *fi;
7979 int length;
7980
7981 if (pi == NULL((void*)0))
7982 return;
7983
7984 fi = PITEM_FINFO(pi)((pi)->finfo);
7985 if (fi == NULL((void*)0))
7986 return;
7987
7988 end += tvb_raw_offset(tvb);
7989 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7989, "end >= fi->start"
))))
;
7990 length = end - fi->start;
7991
7992 finfo_set_len(fi, length);
7993}
7994
7995int
7996proto_item_get_len(const proto_item *pi)
7997{
7998 field_info *fi;
7999
8000 if (!pi)
8001 return -1;
8002 fi = PITEM_FINFO(pi)((pi)->finfo);
8003 return fi ? fi->length : -1;
8004}
8005
8006void
8007proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8008 if (!ti) {
8009 return;
8010 }
8011 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)
;
8012 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)
;
8013}
8014
8015char *
8016proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8017{
8018 field_info *fi;
8019
8020 if (!pi)
8021 return wmem_strdup(scope, "");
8022 fi = PITEM_FINFO(pi)((pi)->finfo);
8023 if (!fi)
8024 return wmem_strdup(scope, "");
8025 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8025, "fi->hfinfo != ((void*)0)"
))))
;
8026 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8027}
8028
8029proto_tree *
8030proto_tree_create_root(packet_info *pinfo)
8031{
8032 proto_node *pnode;
8033
8034 /* Initialize the proto_node */
8035 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
8036 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8037 pnode->parent = NULL((void*)0);
8038 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8039 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
8040
8041 /* Make sure we can access pinfo everywhere */
8042 pnode->tree_data->pinfo = pinfo;
8043
8044 /* Don't initialize the tree_data_t. Wait until we know we need it */
8045 pnode->tree_data->interesting_hfids = NULL((void*)0);
8046
8047 /* Set the default to false so it's easier to
8048 * find errors; if we expect to see the protocol tree
8049 * but for some reason the default 'visible' is not
8050 * changed, then we'll find out very quickly. */
8051 pnode->tree_data->visible = false0;
8052
8053 /* Make sure that we fake protocols (if possible) */
8054 pnode->tree_data->fake_protocols = true1;
8055
8056 /* Keep track of the number of children */
8057 pnode->tree_data->count = 0;
8058
8059 /* Initialize our loop checks */
8060 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8061 pnode->tree_data->max_start = 0;
8062 pnode->tree_data->start_idle_count = 0;
8063
8064 return (proto_tree *)pnode;
8065}
8066
8067
8068/* "prime" a proto_tree with a single hfid that a dfilter
8069 * is interested in. */
8070void
8071proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8072{
8073 header_field_info *hfinfo;
8074
8075 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", 8075, __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", 8075, "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", 8075, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8076 /* this field is referenced by a filter so increase the refcount.
8077 also increase the refcount for the parent, i.e the protocol.
8078 Don't increase the refcount if we're already printing the
8079 type, as that is a superset of direct reference.
8080 */
8081 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8082 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8083 }
8084 /* only increase the refcount if there is a parent.
8085 if this is a protocol and not a field then parent will be -1
8086 and there is no parent to add any refcounting for.
8087 */
8088 if (hfinfo->parent != -1) {
8089 header_field_info *parent_hfinfo;
8090 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", 8090
, __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", 8090,
"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", 8090,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8091
8092 /* Mark parent as indirectly referenced unless it is already directly
8093 * referenced, i.e. the user has specified the parent in a filter.
8094 */
8095 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8096 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8097 }
8098}
8099
8100/* "prime" a proto_tree with a single hfid that a dfilter
8101 * is interested in. */
8102void
8103proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8104{
8105 header_field_info *hfinfo;
8106
8107 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", 8107, __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", 8107, "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", 8107, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8108 /* this field is referenced by an (output) filter so increase the refcount.
8109 also increase the refcount for the parent, i.e the protocol.
8110 */
8111 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8112 /* only increase the refcount if there is a parent.
8113 if this is a protocol and not a field then parent will be -1
8114 and there is no parent to add any refcounting for.
8115 */
8116 if (hfinfo->parent != -1) {
8117 header_field_info *parent_hfinfo;
8118 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", 8118
, __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", 8118,
"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", 8118,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8119
8120 /* Mark parent as indirectly referenced unless it is already directly
8121 * referenced, i.e. the user has specified the parent in a filter.
8122 */
8123 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8124 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8125 }
8126}
8127
8128proto_tree *
8129proto_item_add_subtree(proto_item *pi, const int idx) {
8130 field_info *fi;
8131
8132 if (!pi)
8133 return NULL((void*)0);
8134
8135 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", 8135, "idx >= 0 && idx < num_tree_types"
))))
;
8136
8137 fi = PITEM_FINFO(pi)((pi)->finfo);
8138 if (!fi)
8139 return (proto_tree *)pi;
8140
8141 fi->tree_type = idx;
8142
8143 return (proto_tree *)pi;
8144}
8145
8146proto_tree *
8147proto_item_get_subtree(proto_item *pi) {
8148 field_info *fi;
8149
8150 if (!pi)
8151 return NULL((void*)0);
8152 fi = PITEM_FINFO(pi)((pi)->finfo);
8153 if ( (fi) && (fi->tree_type == -1) )
8154 return NULL((void*)0);
8155 return (proto_tree *)pi;
8156}
8157
8158proto_item *
8159proto_item_get_parent(const proto_item *ti) {
8160 if (!ti)
8161 return NULL((void*)0);
8162 return ti->parent;
8163}
8164
8165proto_item *
8166proto_item_get_parent_nth(proto_item *ti, int gen) {
8167 if (!ti)
8168 return NULL((void*)0);
8169 while (gen--) {
8170 ti = ti->parent;
8171 if (!ti)
8172 return NULL((void*)0);
8173 }
8174 return ti;
8175}
8176
8177
8178proto_item *
8179proto_tree_get_parent(proto_tree *tree) {
8180 if (!tree)
8181 return NULL((void*)0);
8182 return (proto_item *)tree;
8183}
8184
8185proto_tree *
8186proto_tree_get_parent_tree(proto_tree *tree) {
8187 if (!tree)
8188 return NULL((void*)0);
8189
8190 /* we're the root tree, there's no parent
8191 return ourselves so the caller has at least a tree to attach to */
8192 if (!tree->parent)
8193 return tree;
8194
8195 return (proto_tree *)tree->parent;
8196}
8197
8198proto_tree *
8199proto_tree_get_root(proto_tree *tree) {
8200 if (!tree)
8201 return NULL((void*)0);
8202 while (tree->parent) {
8203 tree = tree->parent;
8204 }
8205 return tree;
8206}
8207
8208void
8209proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8210 proto_item *item_to_move)
8211{
8212 /* This function doesn't generate any values. It only reorganizes the protocol tree
8213 * so we can bail out immediately if it isn't visible. */
8214 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8215 return;
8216
8217 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", 8217, "item_to_move->parent == tree"
))))
;
8218 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", 8218, "fixed_item->parent == tree"
))))
;
8219
8220 /*** cut item_to_move out ***/
8221
8222 /* is item_to_move the first? */
8223 if (tree->first_child == item_to_move) {
8224 /* simply change first child to next */
8225 tree->first_child = item_to_move->next;
8226
8227 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", 8227, "tree->last_child != item_to_move"
))))
;
8228 } else {
8229 proto_item *curr_item;
8230 /* find previous and change it's next */
8231 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8232 if (curr_item->next == item_to_move) {
8233 break;
8234 }
8235 }
8236
8237 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8237, "curr_item"
))))
;
8238
8239 curr_item->next = item_to_move->next;
8240
8241 /* fix last_child if required */
8242 if (tree->last_child == item_to_move) {
8243 tree->last_child = curr_item;
8244 }
8245 }
8246
8247 /*** insert to_move after fixed ***/
8248 item_to_move->next = fixed_item->next;
8249 fixed_item->next = item_to_move;
8250 if (tree->last_child == fixed_item) {
8251 tree->last_child = item_to_move;
8252 }
8253}
8254
8255void
8256proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8257 const int length)
8258{
8259 field_info *fi;
8260
8261 if (tree == NULL((void*)0))
8262 return;
8263
8264 fi = PTREE_FINFO(tree)((tree)->finfo);
8265 if (fi == NULL((void*)0))
8266 return;
8267
8268 start += tvb_raw_offset(tvb);
8269 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8269, "start >= 0"
))))
;
8270 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8270, "length >= 0"
))))
;
8271
8272 fi->appendix_start = start;
8273 fi->appendix_length = length;
8274}
8275
8276static void
8277check_protocol_filter_name_or_fail(const char *filter_name)
8278{
8279 /* Require at least two characters. */
8280 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8281 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)
;
8282 }
8283
8284 if (proto_check_field_name(filter_name) != '\0') {
8285 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)
8286 " 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)
8287 " 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)
;
8288 }
8289
8290 /* Check that it doesn't match some very common numeric forms. */
8291 if (filter_name[0] == '0' &&
8292 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8293 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8294 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])
8295 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])
;
8296 }
8297
8298 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8299
8300 /* Check that it contains at least one letter. */
8301 bool_Bool have_letter = false0;
8302 for (const char *s = filter_name; *s != '\0'; s++) {
8303 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8304 have_letter = true1;
8305 break;
8306 }
8307 }
8308 if (!have_letter) {
8309 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)
8310 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8311 }
8312
8313 /* Check for reserved keywords. */
8314 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8315 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)
8316 " 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)
;
8317 }
8318}
8319
8320int
8321proto_register_protocol(const char *name, const char *short_name,
8322 const char *filter_name)
8323{
8324 protocol_t *protocol;
8325 header_field_info *hfinfo;
8326
8327 check_protocol_filter_name_or_fail(filter_name);
8328
8329 /*
8330 * Add this protocol to the list of known protocols;
8331 * the list is sorted by protocol short name.
8332 */
8333 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8334 protocol->name = name;
8335 protocol->short_name = short_name;
8336 protocol->filter_name = filter_name;
8337 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8338 protocol->is_enabled = true1; /* protocol is enabled by default */
8339 protocol->enabled_by_default = true1; /* see previous comment */
8340 protocol->can_toggle = true1;
8341 protocol->parent_proto_id = -1;
8342 protocol->heur_list = NULL((void*)0);
8343
8344 /* List will be sorted later by name, when all protocols completed registering */
8345 protocols = g_list_prepend(protocols, protocol);
8346 /*
8347 * Make sure there's not already a protocol with any of those
8348 * names. Crash if there is, as that's an error in the code
8349 * or an inappropriate plugin.
8350 * This situation has to be fixed to not register more than one
8351 * protocol with the same name.
8352 */
8353 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8354 /* ws_error will terminate the program */
8355 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)
8356 " 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)
;
8357 }
8358 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8359 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)
8360 " 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)
;
8361 }
8362 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8363 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)
8364 " 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)
;
8365 }
8366
8367 /* Here we allocate a new header_field_info struct */
8368 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8369 hfinfo->name = name;
8370 hfinfo->abbrev = filter_name;
8371 hfinfo->type = FT_PROTOCOL;
8372 hfinfo->display = BASE_NONE;
8373 hfinfo->strings = protocol;
8374 hfinfo->bitmask = 0;
8375 hfinfo->ref_type = HF_REF_TYPE_NONE;
8376 hfinfo->blurb = NULL((void*)0);
8377 hfinfo->parent = -1; /* This field differentiates protos and fields */
8378
8379 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8380 return protocol->proto_id;
8381}
8382
8383int
8384proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8385{
8386 protocol_t *protocol;
8387 header_field_info *hfinfo;
8388
8389 /*
8390 * Helper protocols don't need the strict rules as a "regular" protocol
8391 * Just register it in a list and make a hf_ field from it
8392 */
8393 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8394 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)
;
8395 }
8396
8397 if (parent_proto <= 0) {
8398 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)
8399 " 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)
;
8400 }
8401
8402 check_protocol_filter_name_or_fail(filter_name);
8403
8404 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8405 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8406 protocol->name = name;
8407 protocol->short_name = short_name;
8408 protocol->filter_name = filter_name;
8409 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8410
8411 /* Enabling and toggling is really determined by parent protocol,
8412 but provide default values here */
8413 protocol->is_enabled = true1;
8414 protocol->enabled_by_default = true1;
8415 protocol->can_toggle = true1;
8416
8417 protocol->parent_proto_id = parent_proto;
8418 protocol->heur_list = NULL((void*)0);
8419
8420 /* List will be sorted later by name, when all protocols completed registering */
8421 protocols = g_list_prepend(protocols, protocol);
8422
8423 /* Here we allocate a new header_field_info struct */
8424 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8425 hfinfo->name = name;
8426 hfinfo->abbrev = filter_name;
8427 hfinfo->type = field_type;
8428 hfinfo->display = BASE_NONE;
8429 if (field_type == FT_BYTES) {
8430 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8431 }
8432 hfinfo->strings = protocol;
8433 hfinfo->bitmask = 0;
8434 hfinfo->ref_type = HF_REF_TYPE_NONE;
8435 hfinfo->blurb = NULL((void*)0);
8436 hfinfo->parent = -1; /* This field differentiates protos and fields */
8437
8438 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8439 return protocol->proto_id;
8440}
8441
8442bool_Bool
8443proto_deregister_protocol(const char *short_name)
8444{
8445 protocol_t *protocol;
8446 header_field_info *hfinfo;
8447 int proto_id;
8448 unsigned i;
8449
8450 proto_id = proto_get_id_by_short_name(short_name);
8451 protocol = find_protocol_by_id(proto_id);
8452 if (protocol == NULL((void*)0))
8453 return false0;
8454
8455 g_hash_table_remove(proto_names, protocol->name);
8456 g_hash_table_remove(proto_short_names, (void *)short_name);
8457 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8458
8459 if (protocol->fields) {
8460 for (i = 0; i < protocol->fields->len; i++) {
8461 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8462 hfinfo_remove_from_gpa_name_map(hfinfo);
8463 expert_deregister_expertinfo(hfinfo->abbrev);
8464 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8465 }
8466 g_ptr_array_free(protocol->fields, true1);
8467 protocol->fields = NULL((void*)0);
8468 }
8469
8470 g_list_free(protocol->heur_list);
8471
8472 /* Remove this protocol from the list of known protocols */
8473 protocols = g_list_remove(protocols, protocol);
8474
8475 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8476 wmem_map_remove(gpa_name_map, protocol->filter_name);
8477
8478 g_free(last_field_name);
8479 last_field_name = NULL((void*)0);
8480
8481 return true1;
8482}
8483
8484void
8485proto_register_alias(const int proto_id, const char *alias_name)
8486{
8487 protocol_t *protocol;
8488
8489 protocol = find_protocol_by_id(proto_id);
8490 if (alias_name && protocol) {
8491 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8492 }
8493}
8494
8495/*
8496 * Routines to use to iterate over the protocols.
8497 * The argument passed to the iterator routines is an opaque cookie to
8498 * their callers; it's the GList pointer for the current element in
8499 * the list.
8500 * The ID of the protocol is returned, or -1 if there is no protocol.
8501 */
8502int
8503proto_get_first_protocol(void **cookie)
8504{
8505 protocol_t *protocol;
8506
8507 if (protocols == NULL((void*)0))
8508 return -1;
8509 *cookie = protocols;
8510 protocol = (protocol_t *)protocols->data;
8511 return protocol->proto_id;
8512}
8513
8514int
8515proto_get_data_protocol(void *cookie)
8516{
8517 GList *list_item = (GList *)cookie;
8518
8519 protocol_t *protocol = (protocol_t *)list_item->data;
8520 return protocol->proto_id;
8521}
8522
8523int
8524proto_get_next_protocol(void **cookie)
8525{
8526 GList *list_item = (GList *)*cookie;
8527 protocol_t *protocol;
8528
8529 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8530 if (list_item == NULL((void*)0))
8531 return -1;
8532 *cookie = list_item;
8533 protocol = (protocol_t *)list_item->data;
8534 return protocol->proto_id;
8535}
8536
8537header_field_info *
8538proto_get_first_protocol_field(const int proto_id, void **cookie)
8539{
8540 protocol_t *protocol = find_protocol_by_id(proto_id);
8541
8542 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8543 return NULL((void*)0);
8544
8545 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8546 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8547}
8548
8549header_field_info *
8550proto_get_next_protocol_field(const int proto_id, void **cookie)
8551{
8552 protocol_t *protocol = find_protocol_by_id(proto_id);
8553 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8554
8555 i++;
8556
8557 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8558 return NULL((void*)0);
8559
8560 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8561 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8562}
8563
8564protocol_t *
8565find_protocol_by_id(const int proto_id)
8566{
8567 header_field_info *hfinfo;
8568
8569 if (proto_id <= 0)
8570 return NULL((void*)0);
8571
8572 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", 8572, __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", 8572,
"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", 8572, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8573 if (hfinfo->type != FT_PROTOCOL) {
8574 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", 8574, "hfinfo->display & 0x00004000"
))))
;
8575 }
8576 return (protocol_t *)hfinfo->strings;
8577}
8578
8579int
8580proto_get_id(const protocol_t *protocol)
8581{
8582 return protocol->proto_id;
8583}
8584
8585bool_Bool
8586proto_name_already_registered(const char *name)
8587{
8588 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8588, "name", "No name present"))))
;
8589
8590 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8591 return true1;
8592 return false0;
8593}
8594
8595int
8596proto_get_id_by_filter_name(const char *filter_name)
8597{
8598 const protocol_t *protocol = NULL((void*)0);
8599
8600 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", 8600,
"filter_name", "No filter name present"))))
;
8601
8602 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8603
8604 if (protocol == NULL((void*)0))
8605 return -1;
8606 return protocol->proto_id;
8607}
8608
8609int
8610proto_get_id_by_short_name(const char *short_name)
8611{
8612 const protocol_t *protocol = NULL((void*)0);
8613
8614 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", 8614,
"short_name", "No short name present"))))
;
8615
8616 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8617
8618 if (protocol == NULL((void*)0))
8619 return -1;
8620 return protocol->proto_id;
8621}
8622
8623const char *
8624proto_get_protocol_name(const int proto_id)
8625{
8626 protocol_t *protocol;
8627
8628 protocol = find_protocol_by_id(proto_id);
8629
8630 if (protocol == NULL((void*)0))
8631 return NULL((void*)0);
8632 return protocol->name;
8633}
8634
8635const char *
8636proto_get_protocol_short_name(const protocol_t *protocol)
8637{
8638 if (protocol == NULL((void*)0))
8639 return "(none)";
8640 return protocol->short_name;
8641}
8642
8643const char *
8644proto_get_protocol_long_name(const protocol_t *protocol)
8645{
8646 if (protocol == NULL((void*)0))
8647 return "(none)";
8648 return protocol->name;
8649}
8650
8651const char *
8652proto_get_protocol_filter_name(const int proto_id)
8653{
8654 protocol_t *protocol;
8655
8656 protocol = find_protocol_by_id(proto_id);
8657 if (protocol == NULL((void*)0))
8658 return "(none)";
8659 return protocol->filter_name;
8660}
8661
8662void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8663{
8664 heur_dtbl_entry_t* heuristic_dissector;
8665
8666 if (protocol == NULL((void*)0))
8667 return;
8668
8669 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8670 if (heuristic_dissector != NULL((void*)0))
8671 {
8672 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8673 }
8674}
8675
8676void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8677{
8678 if (protocol == NULL((void*)0))
8679 return;
8680
8681 g_list_foreach(protocol->heur_list, func, user_data);
8682}
8683
8684void
8685proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8686 bool_Bool *is_tcp, bool_Bool *is_udp,
8687 bool_Bool *is_sctp, bool_Bool *is_tls,
8688 bool_Bool *is_rtp,
8689 bool_Bool *is_lte_rlc)
8690{
8691 wmem_list_frame_t *protos = wmem_list_head(layers);
8692 int proto_id;
8693 const char *proto_name;
8694
8695 /* Walk the list of a available protocols in the packet and
8696 attempt to find "major" ones. */
8697 /* It might make more sense to assemble and return a bitfield. */
8698 while (protos != NULL((void*)0))
8699 {
8700 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8701 proto_name = proto_get_protocol_filter_name(proto_id);
8702
8703 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8704 (!strcmp(proto_name, "ipv6")))) {
8705 *is_ip = true1;
8706 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8707 *is_tcp = true1;
8708 } else if (is_udp && !strcmp(proto_name, "udp")) {
8709 *is_udp = true1;
8710 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8711 *is_sctp = true1;
8712 } else if (is_tls && !strcmp(proto_name, "tls")) {
8713 *is_tls = true1;
8714 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8715 *is_rtp = true1;
8716 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8717 *is_lte_rlc = true1;
8718 }
8719
8720 protos = wmem_list_frame_next(protos);
8721 }
8722}
8723
8724bool_Bool
8725proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8726{
8727 wmem_list_frame_t *protos = wmem_list_head(layers);
8728 int proto_id;
8729 const char *name;
8730
8731 /* Walk the list of a available protocols in the packet and
8732 attempt to find the specified protocol. */
8733 while (protos != NULL((void*)0))
8734 {
8735 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8736 name = proto_get_protocol_filter_name(proto_id);
8737
8738 if (!strcmp(name, proto_name))
8739 {
8740 return true1;
8741 }
8742
8743 protos = wmem_list_frame_next(protos);
8744 }
8745
8746 return false0;
8747}
8748
8749char *
8750proto_list_layers(const packet_info *pinfo)
8751{
8752 wmem_strbuf_t *buf;
8753 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8754
8755 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8756
8757 /* Walk the list of layers in the packet and
8758 return a string of all entries. */
8759 while (layers != NULL((void*)0))
8760 {
8761 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8762
8763 layers = wmem_list_frame_next(layers);
8764 if (layers != NULL((void*)0)) {
8765 wmem_strbuf_append_c(buf, ':');
8766 }
8767 }
8768
8769 return wmem_strbuf_finalize(buf);
8770}
8771
8772uint8_t
8773proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8774{
8775 int *proto_layer_num_ptr;
8776
8777 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8778 if (proto_layer_num_ptr == NULL((void*)0)) {
8779 return 0;
8780 }
8781
8782 return (uint8_t)*proto_layer_num_ptr;
8783}
8784
8785bool_Bool
8786proto_is_pino(const protocol_t *protocol)
8787{
8788 return (protocol->parent_proto_id != -1);
8789}
8790
8791bool_Bool
8792// NOLINTNEXTLINE(misc-no-recursion)
8793proto_is_protocol_enabled(const protocol_t *protocol)
8794{
8795 if (protocol == NULL((void*)0))
8796 return false0;
8797
8798 //parent protocol determines enable/disable for helper dissectors
8799 if (proto_is_pino(protocol))
8800 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8801
8802 return protocol->is_enabled;
8803}
8804
8805bool_Bool
8806// NOLINTNEXTLINE(misc-no-recursion)
8807proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8808{
8809 //parent protocol determines enable/disable for helper dissectors
8810 if (proto_is_pino(protocol))
8811 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8812
8813 return protocol->enabled_by_default;
8814}
8815
8816bool_Bool
8817// NOLINTNEXTLINE(misc-no-recursion)
8818proto_can_toggle_protocol(const int proto_id)
8819{
8820 protocol_t *protocol;
8821
8822 protocol = find_protocol_by_id(proto_id);
8823 //parent protocol determines toggling for helper dissectors
8824 if (proto_is_pino(protocol))
8825 return proto_can_toggle_protocol(protocol->parent_proto_id);
8826
8827 return protocol->can_toggle;
8828}
8829
8830void
8831proto_disable_by_default(const int proto_id)
8832{
8833 protocol_t *protocol;
8834
8835 protocol = find_protocol_by_id(proto_id);
8836 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8836, "protocol->can_toggle"
))))
;
8837 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", 8837, "proto_is_pino(protocol) == 0"
))))
;
8838 protocol->is_enabled = false0;
8839 protocol->enabled_by_default = false0;
8840}
8841
8842void
8843proto_set_decoding(const int proto_id, const bool_Bool enabled)
8844{
8845 protocol_t *protocol;
8846
8847 protocol = find_protocol_by_id(proto_id);
8848 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8848, "protocol->can_toggle"
))))
;
8849 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", 8849, "proto_is_pino(protocol) == 0"
))))
;
8850 protocol->is_enabled = enabled;
8851}
8852
8853void
8854proto_disable_all(void)
8855{
8856 /* This doesn't explicitly disable heuristic protocols,
8857 * but the heuristic doesn't get called if the parent
8858 * protocol isn't enabled.
8859 */
8860 protocol_t *protocol;
8861 GList *list_item = protocols;
8862
8863 if (protocols == NULL((void*)0))
8864 return;
8865
8866 while (list_item) {
8867 protocol = (protocol_t *)list_item->data;
8868 if (protocol->can_toggle) {
8869 protocol->is_enabled = false0;
8870 }
8871 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8872 }
8873}
8874
8875static void
8876heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8877{
8878 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8879
8880 heur->enabled = heur->enabled_by_default;
8881}
8882
8883void
8884proto_reenable_all(void)
8885{
8886 protocol_t *protocol;
8887 GList *list_item = protocols;
8888
8889 if (protocols == NULL((void*)0))
8890 return;
8891
8892 while (list_item) {
8893 protocol = (protocol_t *)list_item->data;
8894 if (protocol->can_toggle)
8895 protocol->is_enabled = protocol->enabled_by_default;
8896 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8897 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8898 }
8899}
8900
8901void
8902proto_set_cant_toggle(const int proto_id)
8903{
8904 protocol_t *protocol;
8905
8906 protocol = find_protocol_by_id(proto_id);
8907 protocol->can_toggle = false0;
8908}
8909
8910static int
8911proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8912{
8913 g_ptr_array_add(proto->fields, hfi);
8914
8915 return proto_register_field_init(hfi, parent);
8916}
8917
8918/* for use with static arrays only, since we don't allocate our own copies
8919of the header_field_info struct contained within the hf_register_info struct */
8920void
8921proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8922{
8923 hf_register_info *ptr = hf;
8924 protocol_t *proto;
8925 int i;
8926
8927 proto = find_protocol_by_id(parent);
8928
8929 /* if (proto == NULL) - error or return? */
8930
8931 if (proto->fields == NULL((void*)0)) {
8932 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
8933 * GLib introduced g_ptr_array_new_from_array, which might have
8934 * given a reason to actually use it. (#17774)
8935 */
8936 proto->fields = g_ptr_array_sized_new(num_records);
8937 }
8938
8939 for (i = 0; i < num_records; i++, ptr++) {
8940 /*
8941 * Make sure we haven't registered this yet.
8942 * Most fields have variables associated with them that
8943 * are initialized to 0; some are initialized to -1 (which
8944 * was the standard before 4.4).
8945 *
8946 * XXX - Since this is called almost 300000 times at startup,
8947 * it might be nice to compare to only 0 and require
8948 * dissectors to pass in zero for unregistered fields.
8949 */
8950 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8951 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8952 "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)
8953 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8954 return;
8955 }
8956
8957 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8958 }
8959}
8960
8961/* deregister already registered fields */
8962void
8963proto_deregister_field (const int parent, int hf_id)
8964{
8965 header_field_info *hfi;
8966 protocol_t *proto;
8967 unsigned i;
8968
8969 g_free(last_field_name);
8970 last_field_name = NULL((void*)0);
8971
8972 if (hf_id == -1 || hf_id == 0)
8973 return;
8974
8975 proto = find_protocol_by_id (parent);
8976 if (!proto || proto->fields == NULL((void*)0)) {
8977 return;
8978 }
8979
8980 for (i = 0; i < proto->fields->len; i++) {
8981 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8982 if (hfi->id == hf_id) {
8983 /* Found the hf_id in this protocol */
8984 wmem_map_remove(gpa_name_map, hfi->abbrev);
8985 g_ptr_array_remove_index_fast(proto->fields, i);
8986 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8987 return;
8988 }
8989 }
8990}
8991
8992/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
8993void
8994proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
8995{
8996 header_field_info *hfinfo;
8997 protocol_t *proto;
8998
8999 g_free(last_field_name);
9000 last_field_name = NULL((void*)0);
9001
9002 proto = find_protocol_by_id(parent);
9003 if (proto && proto->fields && proto->fields->len > 0) {
9004 unsigned i = proto->fields->len;
9005 do {
9006 i--;
9007
9008 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9009 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) )
) {
9010 hfinfo_remove_from_gpa_name_map(hfinfo);
9011 expert_deregister_expertinfo(hfinfo->abbrev);
9012 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9013 g_ptr_array_remove_index_fast(proto->fields, i);
9014 }
9015 } while (i > 0);
9016 }
9017}
9018
9019void
9020proto_add_deregistered_data (void *data)
9021{
9022 g_ptr_array_add(deregistered_data, data);
9023}
9024
9025void
9026proto_add_deregistered_slice (size_t block_size, void *mem_block)
9027{
9028 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
)))
;
9029
9030 slice_data->block_size = block_size;
9031 slice_data->mem_block = mem_block;
9032
9033 g_ptr_array_add(deregistered_slice, slice_data);
9034}
9035
9036void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9037{
9038 if (field_strings == NULL((void*)0)) {
9039 return;
9040 }
9041
9042 switch (field_type) {
9043 case FT_FRAMENUM:
9044 /* This is just an integer represented as a pointer */
9045 break;
9046 case FT_PROTOCOL: {
9047 protocol_t *protocol = (protocol_t *)field_strings;
9048 g_free((char *)protocol->short_name);
9049 break;
9050 }
9051 case FT_BOOLEAN: {
9052 true_false_string *tf = (true_false_string *)field_strings;
9053 g_free((char *)tf->true_string);
9054 g_free((char *)tf->false_string);
9055 break;
9056 }
9057 case FT_UINT40:
9058 case FT_INT40:
9059 case FT_UINT48:
9060 case FT_INT48:
9061 case FT_UINT56:
9062 case FT_INT56:
9063 case FT_UINT64:
9064 case FT_INT64: {
9065 if (field_display & BASE_UNIT_STRING0x00001000) {
9066 unit_name_string *unit = (unit_name_string *)field_strings;
9067 g_free((char *)unit->singular);
9068 g_free((char *)unit->plural);
9069 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9070 range_string *rs = (range_string *)field_strings;
9071 while (rs->strptr) {
9072 g_free((char *)rs->strptr);
9073 rs++;
9074 }
9075 } else if (field_display & BASE_EXT_STRING0x00000200) {
9076 val64_string_ext *vse = (val64_string_ext *)field_strings;
9077 val64_string *vs = (val64_string *)vse->_vs_p;
9078 while (vs->strptr) {
9079 g_free((char *)vs->strptr);
9080 vs++;
9081 }
9082 val64_string_ext_free(vse);
9083 field_strings = NULL((void*)0);
9084 } else if (field_display == BASE_CUSTOM) {
9085 /* this will be a pointer to a function, don't free that */
9086 field_strings = NULL((void*)0);
9087 } else {
9088 val64_string *vs64 = (val64_string *)field_strings;
9089 while (vs64->strptr) {
9090 g_free((char *)vs64->strptr);
9091 vs64++;
9092 }
9093 }
9094 break;
9095 }
9096 case FT_CHAR:
9097 case FT_UINT8:
9098 case FT_INT8:
9099 case FT_UINT16:
9100 case FT_INT16:
9101 case FT_UINT24:
9102 case FT_INT24:
9103 case FT_UINT32:
9104 case FT_INT32:
9105 case FT_FLOAT:
9106 case FT_DOUBLE: {
9107 if (field_display & BASE_UNIT_STRING0x00001000) {
9108 unit_name_string *unit = (unit_name_string *)field_strings;
9109 g_free((char *)unit->singular);
9110 g_free((char *)unit->plural);
9111 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9112 range_string *rs = (range_string *)field_strings;
9113 while (rs->strptr) {
9114 g_free((char *)rs->strptr);
9115 rs++;
9116 }
9117 } else if (field_display & BASE_EXT_STRING0x00000200) {
9118 value_string_ext *vse = (value_string_ext *)field_strings;
9119 value_string *vs = (value_string *)vse->_vs_p;
9120 while (vs->strptr) {
9121 g_free((char *)vs->strptr);
9122 vs++;
9123 }
9124 value_string_ext_free(vse);
9125 field_strings = NULL((void*)0);
9126 } else if (field_display == BASE_CUSTOM) {
9127 /* this will be a pointer to a function, don't free that */
9128 field_strings = NULL((void*)0);
9129 } else {
9130 value_string *vs = (value_string *)field_strings;
9131 while (vs->strptr) {
9132 g_free((char *)vs->strptr);
9133 vs++;
9134 }
9135 }
9136 break;
9137 default:
9138 break;
9139 }
9140 }
9141
9142 if (field_type != FT_FRAMENUM) {
9143 g_free((void *)field_strings);
9144 }
9145}
9146
9147static void
9148free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9149{
9150 header_field_info *hfi = (header_field_info *) data;
9151 int hf_id = hfi->id;
9152
9153 g_free((char *)hfi->name);
9154 g_free((char *)hfi->abbrev);
9155 g_free((char *)hfi->blurb);
9156
9157 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9158
9159 if (hfi->parent == -1)
9160 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)
;
9161
9162 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9163}
9164
9165static void
9166free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9167{
9168 g_free (data);
9169}
9170
9171static void
9172free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9173{
9174 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9175
9176 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9177 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)
;
9178}
9179
9180/* free deregistered fields and data */
9181void
9182proto_free_deregistered_fields (void)
9183{
9184 expert_free_deregistered_expertinfos();
9185
9186 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9187 g_ptr_array_free(deregistered_fields, true1);
9188 deregistered_fields = g_ptr_array_new();
9189
9190 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9191 g_ptr_array_free(deregistered_data, true1);
9192 deregistered_data = g_ptr_array_new();
9193
9194 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9195 g_ptr_array_free(deregistered_slice, true1);
9196 deregistered_slice = g_ptr_array_new();
9197}
9198
9199static const value_string hf_display[] = {
9200 { BASE_NONE, "BASE_NONE" },
9201 { BASE_DEC, "BASE_DEC" },
9202 { BASE_HEX, "BASE_HEX" },
9203 { BASE_OCT, "BASE_OCT" },
9204 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9205 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9206 { BASE_CUSTOM, "BASE_CUSTOM" },
9207 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9208 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9209 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9210 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9211 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9212 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9213 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9214 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9215 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9216 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9217 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9218 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9219 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9220 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9221 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9222 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9223 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9224 { BASE_PT_UDP, "BASE_PT_UDP" },
9225 { BASE_PT_TCP, "BASE_PT_TCP" },
9226 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9227 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9228 { BASE_OUI, "BASE_OUI" },
9229 { 0, NULL((void*)0) } };
9230
9231const char* proto_field_display_to_string(int field_display)
9232{
9233 return val_to_str_const(field_display, hf_display, "Unknown");
9234}
9235
9236static inline port_type
9237display_to_port_type(field_display_e e)
9238{
9239 switch (e) {
9240 case BASE_PT_UDP:
9241 return PT_UDP;
9242 case BASE_PT_TCP:
9243 return PT_TCP;
9244 case BASE_PT_DCCP:
9245 return PT_DCCP;
9246 case BASE_PT_SCTP:
9247 return PT_SCTP;
9248 default:
9249 break;
9250 }
9251 return PT_NONE;
9252}
9253
9254/* temporary function containing assert part for easier profiling */
9255static void
9256tmp_fld_check_assert(header_field_info *hfinfo)
9257{
9258 char* tmp_str;
9259
9260 /* The field must have a name (with length > 0) */
9261 if (!hfinfo->name || !hfinfo->name[0]) {
9262 if (hfinfo->abbrev)
9263 /* Try to identify the field */
9264 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)
9265 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9266 else
9267 /* Hum, no luck */
9268 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)"
)
;
9269 }
9270
9271 /* fields with an empty string for an abbreviation aren't filterable */
9272 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9273 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)
;
9274
9275 /* TODO: This check is a significant percentage of startup time (~10%),
9276 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9277 It might be nice to have a way to disable this check when, e.g.,
9278 running TShark many times with the same configuration. */
9279 /* Check that the filter name (abbreviation) is legal;
9280 * it must contain only alphanumerics, '-', "_", and ".". */
9281 unsigned char c;
9282 c = module_check_valid_name(hfinfo->abbrev, false0);
9283 if (c) {
9284 if (c == '.') {
9285 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)
;
9286 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9287 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)
;
9288 } else {
9289 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)
;
9290 }
9291 }
9292
9293 /* These types of fields are allowed to have value_strings,
9294 * true_false_strings or a protocol_t struct
9295 */
9296 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9297 switch (hfinfo->type) {
9298
9299 /*
9300 * These types are allowed to support display value_strings,
9301 * value64_strings, the extended versions of the previous
9302 * two, range strings, or unit strings.
9303 */
9304 case FT_CHAR:
9305 case FT_UINT8:
9306 case FT_UINT16:
9307 case FT_UINT24:
9308 case FT_UINT32:
9309 case FT_UINT40:
9310 case FT_UINT48:
9311 case FT_UINT56:
9312 case FT_UINT64:
9313 case FT_INT8:
9314 case FT_INT16:
9315 case FT_INT24:
9316 case FT_INT32:
9317 case FT_INT40:
9318 case FT_INT48:
9319 case FT_INT56:
9320 case FT_INT64:
9321 case FT_BOOLEAN:
9322 case FT_PROTOCOL:
9323 break;
9324
9325 /*
9326 * This is allowed to have a value of type
9327 * enum ft_framenum_type to indicate what relationship
9328 * the frame in question has to the frame in which
9329 * the field is put.
9330 */
9331 case FT_FRAMENUM:
9332 break;
9333
9334 /*
9335 * These types are allowed to support only unit strings.
9336 */
9337 case FT_FLOAT:
9338 case FT_DOUBLE:
9339 case FT_IEEE_11073_SFLOAT:
9340 case FT_IEEE_11073_FLOAT:
9341 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9342 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))
9343 " (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))
9344 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))
;
9345 }
9346 break;
9347
9348 /*
9349 * These types are allowed to support display
9350 * time_value_strings.
9351 */
9352 case FT_ABSOLUTE_TIME:
9353 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9354 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9355 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9356 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9357 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))
9358 " (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))
9359 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))
;
9360 }
9361 break;
9362
9363 /*
9364 * This type is only allowed to support a string if it's
9365 * a protocol (for pinos).
9366 */
9367 case FT_BYTES:
9368 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9369 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))
9370 " (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))
9371 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))
;
9372 }
9373 break;
9374
9375 default:
9376 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))
9377 " (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))
9378 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))
;
9379 }
9380 }
9381
9382 /* TODO: This check may slow down startup, and output quite a few warnings.
9383 It would be good to be able to enable this (and possibly other checks?)
9384 in non-release builds. */
9385#ifdef ENABLE_CHECK_FILTER
9386 /* Check for duplicate value_string values.
9387 There are lots that have the same value *and* string, so for now only
9388 report those that have same value but different string. */
9389 if ((hfinfo->strings != NULL((void*)0)) &&
9390 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9391 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9392 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9393 (
9394 (hfinfo->type == FT_CHAR) ||
9395 (hfinfo->type == FT_UINT8) ||
9396 (hfinfo->type == FT_UINT16) ||
9397 (hfinfo->type == FT_UINT24) ||
9398 (hfinfo->type == FT_UINT32) ||
9399 (hfinfo->type == FT_INT8) ||
9400 (hfinfo->type == FT_INT16) ||
9401 (hfinfo->type == FT_INT24) ||
9402 (hfinfo->type == FT_INT32) )) {
9403
9404 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9405 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9406 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9407 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9408 } else {
9409 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9410 CHECK_HF_VALUE(value_string, "u", start_values);
9411 }
9412 } else {
9413 const value_string *start_values = (const value_string*)hfinfo->strings;
9414 CHECK_HF_VALUE(value_string, "u", start_values);
9415 }
9416 }
9417
9418 if (hfinfo->type == FT_BOOLEAN) {
9419 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9420 if (tfs) {
9421 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9422 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"
, 9424, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9423 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9424, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9424 tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9424, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
;
9425 }
9426 }
9427 }
9428
9429 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9430 const range_string *rs = (const range_string*)(hfinfo->strings);
9431 if (rs) {
9432 const range_string *this_it = rs;
9433
9434 do {
9435 if (this_it->value_max < this_it->value_min) {
9436 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"
, 9440, __func__, "value_range_string error: %s (%s) entry for \"%s\" - max(%"
"l" "u"" 0x%""l" "x"") is less than min(%""l" "u"" 0x%""l" "x"
")", hfinfo->name, hfinfo->abbrev, this_it->strptr, this_it
->value_max, this_it->value_max, this_it->value_min,
this_it->value_min); } } while (0)
9437 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9440, __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)
9438 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9440, __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)
9439 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9440, __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)
9440 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9440, __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)
;
9441 ++this_it;
9442 continue;
9443 }
9444
9445 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9446 /* Not OK if this one is completely hidden by an earlier one! */
9447 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9448 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"
, 9454, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9449 "(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"
, 9454, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9450 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9454, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9451 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9454, __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)
9452 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9454, __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)
9453 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9454, __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)
9454 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9454, __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)
;
9455 }
9456 }
9457 ++this_it;
9458 } while (this_it->strptr);
9459 }
9460 }
9461#endif
9462
9463 switch (hfinfo->type) {
9464
9465 case FT_CHAR:
9466 /* Require the char type to have BASE_HEX, BASE_OCT,
9467 * BASE_CUSTOM, or BASE_NONE as its base.
9468 *
9469 * If the display value is BASE_NONE and there is a
9470 * strings conversion then the dissector writer is
9471 * telling us that the field's numerical value is
9472 * meaningless; we'll avoid showing the value to the
9473 * user.
9474 */
9475 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9476 case BASE_HEX:
9477 case BASE_OCT:
9478 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9479 break;
9480 case BASE_NONE:
9481 if (hfinfo->strings == NULL((void*)0))
9482 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
))
9483 " 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
))
9484 " 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
))
9485 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
))
9486 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
))
;
9487 break;
9488 default:
9489 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9490 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)
9491 " 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)
9492 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)
9493 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)
;
9494 //wmem_free(NULL, tmp_str);
9495 }
9496 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9497 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
))
9498 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
))
9499 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
))
;
9500 }
9501 break;
9502 case FT_INT8:
9503 case FT_INT16:
9504 case FT_INT24:
9505 case FT_INT32:
9506 case FT_INT40:
9507 case FT_INT48:
9508 case FT_INT56:
9509 case FT_INT64:
9510 /* Hexadecimal and octal are, in printf() and everywhere
9511 * else, unsigned so don't allow dissectors to register a
9512 * signed field to be displayed unsigned. (Else how would
9513 * we display negative values?)
9514 */
9515 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9516 case BASE_HEX:
9517 case BASE_OCT:
9518 case BASE_DEC_HEX:
9519 case BASE_HEX_DEC:
9520 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9521 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)
9522 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)
9523 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)
;
9524 //wmem_free(NULL, tmp_str);
9525 }
9526 /* FALL THROUGH */
9527 case FT_UINT8:
9528 case FT_UINT16:
9529 case FT_UINT24:
9530 case FT_UINT32:
9531 case FT_UINT40:
9532 case FT_UINT48:
9533 case FT_UINT56:
9534 case FT_UINT64:
9535 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
))
) {
9536 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9537 if (hfinfo->type != FT_UINT16) {
9538 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))
9539 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))
9540 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))
;
9541 }
9542 if (hfinfo->strings != NULL((void*)0)) {
9543 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)
9544 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)
9545 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)
;
9546 }
9547 if (hfinfo->bitmask != 0) {
9548 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)
9549 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)
9550 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)
;
9551 }
9552 wmem_free(NULL((void*)0), tmp_str);
9553 break;
9554 }
9555
9556 if (hfinfo->display == BASE_OUI) {
9557 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9558 if (hfinfo->type != FT_UINT24) {
9559 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))
9560 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))
9561 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))
;
9562 }
9563 if (hfinfo->strings != NULL((void*)0)) {
9564 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)
9565 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)
9566 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)
;
9567 }
9568 if (hfinfo->bitmask != 0) {
9569 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)
9570 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)
9571 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)
;
9572 }
9573 wmem_free(NULL((void*)0), tmp_str);
9574 break;
9575 }
9576
9577 /* Require integral types (other than frame number,
9578 * which is always displayed in decimal) to have a
9579 * number base.
9580 *
9581 * If the display value is BASE_NONE and there is a
9582 * strings conversion then the dissector writer is
9583 * telling us that the field's numerical value is
9584 * meaningless; we'll avoid showing the value to the
9585 * user.
9586 */
9587 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9588 case BASE_DEC:
9589 case BASE_HEX:
9590 case BASE_OCT:
9591 case BASE_DEC_HEX:
9592 case BASE_HEX_DEC:
9593 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9594 break;
9595 case BASE_NONE:
9596 if (hfinfo->strings == NULL((void*)0)) {
9597 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
))
9598 " 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
))
9599 " 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
))
9600 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
))
9601 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
))
;
9602 }
9603 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9604 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
))
9605 " 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
))
9606 " 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
))
9607 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
))
9608 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
))
;
9609 }
9610 break;
9611
9612 default:
9613 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9614 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)
9615 " 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)
9616 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)
9617 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)
;
9618 //wmem_free(NULL, tmp_str);
9619 }
9620 break;
9621 case FT_BYTES:
9622 case FT_UINT_BYTES:
9623 /* Require bytes to have a "display type" that could
9624 * add a character between displayed bytes.
9625 */
9626 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9627 case BASE_NONE:
9628 case SEP_DOT:
9629 case SEP_DASH:
9630 case SEP_COLON:
9631 case SEP_SPACE:
9632 break;
9633 default:
9634 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9635 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)
9636 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)
;
9637 //wmem_free(NULL, tmp_str);
9638 }
9639 if (hfinfo->bitmask != 0)
9640 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
))
9641 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
))
9642 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
))
;
9643 //allowed to support string if its a protocol (for pinos)
9644 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9645 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
))
9646 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
))
9647 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
))
;
9648 break;
9649
9650 case FT_PROTOCOL:
9651 case FT_FRAMENUM:
9652 if (hfinfo->display != BASE_NONE) {
9653 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9654 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)
9655 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)
9656 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)
;
9657 //wmem_free(NULL, tmp_str);
9658 }
9659 if (hfinfo->bitmask != 0)
9660 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
))
9661 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
))
9662 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
))
;
9663 break;
9664
9665 case FT_BOOLEAN:
9666 break;
9667
9668 case FT_ABSOLUTE_TIME:
9669 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9670 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9671 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)
9672 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)
;
9673 //wmem_free(NULL, tmp_str);
9674 }
9675 if (hfinfo->bitmask != 0)
9676 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9677 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9678 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9679 break;
9680
9681 case FT_STRING:
9682 case FT_STRINGZ:
9683 case FT_UINT_STRING:
9684 case FT_STRINGZPAD:
9685 case FT_STRINGZTRUNC:
9686 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9687 case BASE_NONE:
9688 case BASE_STR_WSP:
9689 break;
9690
9691 default:
9692 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9693 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)
9694 " 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)
9695 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)
9696 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)
;
9697 //wmem_free(NULL, tmp_str);
9698 }
9699
9700 if (hfinfo->bitmask != 0)
9701 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9702 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9703 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9704 if (hfinfo->strings != NULL((void*)0))
9705 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9706 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9707 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9708 break;
9709
9710 case FT_IPv4:
9711 switch (hfinfo->display) {
9712 case BASE_NONE:
9713 case BASE_NETMASK:
9714 break;
9715
9716 default:
9717 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9718 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)
9719 " 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)
9720 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)
9721 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)
;
9722 //wmem_free(NULL, tmp_str);
9723 break;
9724 }
9725 break;
9726 case FT_FLOAT:
9727 case FT_DOUBLE:
9728 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9729 case BASE_NONE:
9730 case BASE_DEC:
9731 case BASE_HEX:
9732 case BASE_EXP:
9733 case BASE_CUSTOM:
9734 break;
9735 default:
9736 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9737 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)
9738 " 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)
9739 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)
9740 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)
;
9741 //wmem_free(NULL, tmp_str);
9742 }
9743 if (hfinfo->bitmask != 0)
9744 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
))
9745 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
))
9746 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
))
;
9747 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9748 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
))
9749 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
))
9750 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
))
;
9751 break;
9752 case FT_IEEE_11073_SFLOAT:
9753 case FT_IEEE_11073_FLOAT:
9754 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9755 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9756 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)
9757 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)
9758 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)
9759 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)
;
9760 //wmem_free(NULL, tmp_str);
9761 }
9762 if (hfinfo->bitmask != 0)
9763 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
))
9764 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
))
9765 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
))
;
9766 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9767 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
))
9768 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
))
9769 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
))
;
9770 break;
9771 default:
9772 if (hfinfo->display != BASE_NONE) {
9773 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9774 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)
9775 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)
9776 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)
9777 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)
;
9778 //wmem_free(NULL, tmp_str);
9779 }
9780 if (hfinfo->bitmask != 0)
9781 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
))
9782 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
))
9783 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
))
;
9784 if (hfinfo->strings != NULL((void*)0))
9785 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
))
9786 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
))
9787 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
))
;
9788 break;
9789 }
9790}
9791
9792static void
9793register_type_length_mismatch(void)
9794{
9795 static ei_register_info ei[] = {
9796 { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Trying to fetch X with length Y", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
9797 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch_warn", PI_MALFORMED0x07000000, PI_WARN0x00600000, "Trying to fetch X with length Y", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
9798 };
9799
9800 expert_module_t* expert_type_length_mismatch;
9801
9802 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9803
9804 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9805 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9806
9807 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9808 disabling them makes no sense. */
9809 proto_set_cant_toggle(proto_type_length_mismatch);
9810}
9811
9812static void
9813register_byte_array_string_decodinws_error(void)
9814{
9815 static ei_register_info ei[] = {
9816 { &ei_byte_array_string_decoding_failed_error,
9817 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9818 "Failed to decode byte array from string", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
9819 }
9820 },
9821 };
9822
9823 expert_module_t* expert_byte_array_string_decoding_error;
9824
9825 proto_byte_array_string_decoding_error =
9826 proto_register_protocol("Byte Array-String Decoding Error",
9827 "Byte Array-string decoding error",
9828 "_ws.byte_array_string.decoding_error");
9829
9830 expert_byte_array_string_decoding_error =
9831 expert_register_protocol(proto_byte_array_string_decoding_error);
9832 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9833
9834 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9835 disabling them makes no sense. */
9836 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9837}
9838
9839static void
9840register_date_time_string_decodinws_error(void)
9841{
9842 static ei_register_info ei[] = {
9843 { &ei_date_time_string_decoding_failed_error,
9844 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9845 "Failed to decode date and time from string", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
9846 }
9847 },
9848 };
9849
9850 expert_module_t* expert_date_time_string_decoding_error;
9851
9852 proto_date_time_string_decoding_error =
9853 proto_register_protocol("Date and Time-String Decoding Error",
9854 "Date and Time-string decoding error",
9855 "_ws.date_time_string.decoding_error");
9856
9857 expert_date_time_string_decoding_error =
9858 expert_register_protocol(proto_date_time_string_decoding_error);
9859 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9860
9861 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9862 disabling them makes no sense. */
9863 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9864}
9865
9866static void
9867register_string_errors(void)
9868{
9869 static ei_register_info ei[] = {
9870 { &ei_string_trailing_characters,
9871 { "_ws.string.trailing_stray_characters", PI_UNDECODED0x05000000, PI_WARN0x00600000, "Trailing stray characters", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}
9872 },
9873 };
9874
9875 expert_module_t* expert_string_errors;
9876
9877 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9878
9879 expert_string_errors = expert_register_protocol(proto_string_errors);
9880 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9881
9882 /* "String Errors" isn't really a protocol, it's an error indication;
9883 disabling them makes no sense. */
9884 proto_set_cant_toggle(proto_string_errors);
9885}
9886
9887static int
9888proto_register_field_init(header_field_info *hfinfo, const int parent)
9889{
9890
9891 tmp_fld_check_assert(hfinfo);
9892
9893 hfinfo->parent = parent;
9894 hfinfo->same_name_next = NULL((void*)0);
9895 hfinfo->same_name_prev_id = -1;
9896
9897 /* if we always add and never delete, then id == len - 1 is correct */
9898 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9899 if (!gpa_hfinfo.hfi) {
9900 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9901 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9902 /* The entry with index 0 is not used. */
9903 gpa_hfinfo.hfi[0] = NULL((void*)0);
9904 gpa_hfinfo.len = 1;
9905 } else {
9906 gpa_hfinfo.allocated_len += 1000;
9907 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9908 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9909 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9910 }
9911 }
9912 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9913 gpa_hfinfo.len++;
9914 hfinfo->id = gpa_hfinfo.len - 1;
9915
9916 /* if we have real names, enter this field in the name tree */
9917 /* Already checked in tmp_fld_check_assert */
9918 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
9919 {
9920
9921 header_field_info *same_name_next_hfinfo;
9922
9923 /* We allow multiple hfinfo's to be registered under the same
9924 * abbreviation. This was done for X.25, as, depending
9925 * on whether it's modulo-8 or modulo-128 operation,
9926 * some bitfield fields may be in different bits of
9927 * a byte, and we want to be able to refer to that field
9928 * with one name regardless of whether the packets
9929 * are modulo-8 or modulo-128 packets. */
9930
9931 /* wmem_map_insert - if key is already present the previous
9932 * hfinfo with the same key/name is returned, otherwise NULL */
9933 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9934 if (same_name_hfinfo) {
9935 /* There's already a field with this name.
9936 * Put the current field *before* that field
9937 * in the list of fields with this name, Thus,
9938 * we end up with an effectively
9939 * doubly-linked-list of same-named hfinfo's,
9940 * with the head of the list (stored in the
9941 * hash) being the last seen hfinfo.
9942 */
9943 same_name_next_hfinfo =
9944 same_name_hfinfo->same_name_next;
9945
9946 hfinfo->same_name_next = same_name_next_hfinfo;
9947 if (same_name_next_hfinfo)
9948 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9949
9950 same_name_hfinfo->same_name_next = hfinfo;
9951 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9952#ifdef ENABLE_CHECK_FILTER
9953 while (same_name_hfinfo) {
9954 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9955 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"
, 9955, __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)
;
9956 same_name_hfinfo = same_name_hfinfo->same_name_next;
9957 }
9958#endif
9959 }
9960 }
9961
9962 return hfinfo->id;
9963}
9964
9965void
9966proto_register_subtree_array(int * const *indices, const int num_indices)
9967{
9968 int i;
9969 int *const *ptr = indices;
9970
9971 /*
9972 * If we've already allocated the array of tree types, expand
9973 * it; this lets plugins such as mate add tree types after
9974 * the initial startup. (If we haven't already allocated it,
9975 * we don't allocate it; on the first pass, we just assign
9976 * ett values and keep track of how many we've assigned, and
9977 * when we're finished registering all dissectors we allocate
9978 * the array, so that we do only one allocation rather than
9979 * wasting CPU time and memory by growing the array for each
9980 * dissector that registers ett values.)
9981 */
9982 if (tree_is_expanded != NULL((void*)0)) {
9983 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9984
9985 /* set new items to 0 */
9986 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9987 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9988 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9989 }
9990
9991 /*
9992 * Assign "num_indices" subtree numbers starting at "num_tree_types",
9993 * returning the indices through the pointers in the array whose
9994 * first element is pointed to by "indices", and update
9995 * "num_tree_types" appropriately.
9996 */
9997 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9998 if (**ptr != -1 && **ptr != 0) {
9999 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.")
10000 " 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.")
10001 " 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.")
10002 " 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.")
;
10003 }
10004 **ptr = num_tree_types;
10005 }
10006}
10007
10008static void
10009mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10010{
10011 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10012 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10013 char *last_char;
10014
10015 /* ..... field_name: dataaaaaaaaaaaaa
10016 * |
10017 * ^^^^^ name_pos
10018 *
10019 * ..... field_name […]: dataaaaaaaaaaaaa
10020 *
10021 * name_pos==0 means that we have only data or only a field_name
10022 */
10023
10024 ws_assert(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10024, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10025
10026 if (name_pos >= size - trunc_len) {
10027 /* No room for trunc_str after the field_name, put it first. */
10028 name_pos = 0;
10029 }
10030
10031 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10032 if (name_pos == 0) {
10033 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10034 memcpy(label_str, trunc_str + 1, trunc_len);
10035 } else {
10036 memcpy(label_str + name_pos, trunc_str, trunc_len);
10037 }
10038 /* in general, label_str is UTF-8
10039 we can truncate it only at the beginning of a new character
10040 we go backwards from the byte right after our buffer and
10041 find the next starting byte of a UTF-8 character, this is
10042 where we cut
10043 there's no need to use g_utf8_find_prev_char(), the search
10044 will always succeed since we copied trunc_str into the
10045 buffer */
10046 /* g_utf8_prev_char does not deference the memory address
10047 * passed in (until after decrementing it, so it is perfectly
10048 * legal to pass in a pointer one past the last element.
10049 */
10050 last_char = g_utf8_prev_char(label_str + size);
10051 *last_char = '\0';
10052
10053 if (value_pos && *value_pos > 0) {
10054 if (name_pos == 0) {
10055 *value_pos += trunc_len;
10056 } else {
10057 /* Move one back to include trunc_str in the value. */
10058 *value_pos -= 1;
10059 }
10060 }
10061
10062 /* Check if value_pos is past label_str. */
10063 if (value_pos && *value_pos >= size) {
10064 *value_pos = size - 1;
10065 }
10066}
10067
10068static void
10069label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10070{
10071 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10072}
10073
10074static size_t
10075label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10076{
10077 size_t name_pos;
10078
10079 /* "%s: %s", hfinfo->name, text */
10080 name_pos = pos = label_concat(label_str, pos, (const uint8_t*)hfinfo->name)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)hfinfo->
name, 0)
;
10081 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10082 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10083 if (value_pos) {
10084 *value_pos = pos;
10085 }
10086 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10087 }
10088
10089 if (pos >= ITEM_LABEL_LENGTH240) {
10090 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10091 label_mark_truncated(label_str, name_pos, value_pos);
10092 }
10093
10094 return pos;
10095}
10096
10097static size_t
10098label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10099{
10100 size_t name_pos;
10101
10102 /* "%s: %s (%s)", hfinfo->name, text, descr */
10103 name_pos = pos = label_concat(label_str, pos, (const uint8_t*)hfinfo->name)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)hfinfo->
name, 0)
;
10104 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10105 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10106 if (value_pos) {
10107 *value_pos = pos;
10108 }
10109 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10110 pos = label_concat(label_str, pos, (const uint8_t*)(descr ? descr : "(null)"))ws_label_strcpy(label_str, 240, pos, (const uint8_t*)(descr ?
descr : "(null)"), 0)
;
10111 pos = label_concat(label_str, pos, (const uint8_t*)(text ? text : "(null)"))ws_label_strcpy(label_str, 240, pos, (const uint8_t*)(text ? text
: "(null)"), 0)
;
10112 } else {
10113 pos = label_concat(label_str, pos, (const uint8_t*)(text ? text : "(null)"))ws_label_strcpy(label_str, 240, pos, (const uint8_t*)(text ? text
: "(null)"), 0)
;
10114 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10115 pos = label_concat(label_str, pos, (const uint8_t*)(descr ? descr : "(null)"))ws_label_strcpy(label_str, 240, pos, (const uint8_t*)(descr ?
descr : "(null)"), 0)
;
10116 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10117 }
10118 }
10119
10120 if (pos >= ITEM_LABEL_LENGTH240) {
10121 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10122 label_mark_truncated(label_str, name_pos, value_pos);
10123 }
10124
10125 return pos;
10126}
10127
10128void
10129proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10130{
10131 const header_field_info *hfinfo;
10132 const char *str;
10133 const uint8_t *bytes;
10134 uint32_t integer;
10135 const ipv4_addr_and_mask *ipv4;
10136 const ipv6_addr_and_prefix *ipv6;
10137 const e_guid_t *guid;
10138 char *name;
10139 address addr;
10140 char *addr_str;
10141 char *tmp;
10142
10143 if (!label_str) {
10144 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10144, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10145 return;
10146 }
10147
10148 label_str[0]= '\0';
10149
10150 if (!fi) {
10151 return;
10152 }
10153
10154 hfinfo = fi->hfinfo;
10155
10156 switch (hfinfo->type) {
10157 case FT_NONE:
10158 case FT_PROTOCOL:
10159 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10160 if (value_pos) {
10161 *value_pos = strlen(hfinfo->name);
10162 }
10163 break;
10164
10165 case FT_BOOLEAN:
10166 fill_label_boolean(fi, label_str, value_pos);
10167 break;
10168
10169 case FT_BYTES:
10170 case FT_UINT_BYTES:
10171 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10172 fvalue_get_bytes_data(fi->value),
10173 (unsigned)fvalue_length2(fi->value));
10174 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10175 wmem_free(NULL((void*)0), tmp);
10176 break;
10177
10178 case FT_CHAR:
10179 if (hfinfo->bitmask) {
10180 fill_label_bitfield_char(fi, label_str, value_pos);
10181 } else {
10182 fill_label_char(fi, label_str, value_pos);
10183 }
10184 break;
10185
10186 /* Four types of integers to take care of:
10187 * Bitfield, with val_string
10188 * Bitfield, w/o val_string
10189 * Non-bitfield, with val_string
10190 * Non-bitfield, w/o val_string
10191 */
10192 case FT_UINT8:
10193 case FT_UINT16:
10194 case FT_UINT24:
10195 case FT_UINT32:
10196 if (hfinfo->bitmask) {
10197 fill_label_bitfield(fi, label_str, value_pos, false0);
10198 } else {
10199 fill_label_number(fi, label_str, value_pos, false0);
10200 }
10201 break;
10202
10203 case FT_FRAMENUM:
10204 fill_label_number(fi, label_str, value_pos, false0);
10205 break;
10206
10207 case FT_UINT40:
10208 case FT_UINT48:
10209 case FT_UINT56:
10210 case FT_UINT64:
10211 if (hfinfo->bitmask) {
10212 fill_label_bitfield64(fi, label_str, value_pos, false0);
10213 } else {
10214 fill_label_number64(fi, label_str, value_pos, false0);
10215 }
10216 break;
10217
10218 case FT_INT8:
10219 case FT_INT16:
10220 case FT_INT24:
10221 case FT_INT32:
10222 if (hfinfo->bitmask) {
10223 fill_label_bitfield(fi, label_str, value_pos, true1);
10224 } else {
10225 fill_label_number(fi, label_str, value_pos, true1);
10226 }
10227 break;
10228
10229 case FT_INT40:
10230 case FT_INT48:
10231 case FT_INT56:
10232 case FT_INT64:
10233 if (hfinfo->bitmask) {
10234 fill_label_bitfield64(fi, label_str, value_pos, true1);
10235 } else {
10236 fill_label_number64(fi, label_str, value_pos, true1);
10237 }
10238 break;
10239
10240 case FT_FLOAT:
10241 case FT_DOUBLE:
10242 fill_label_float(fi, label_str, value_pos);
10243 break;
10244
10245 case FT_ABSOLUTE_TIME:
10246 {
10247 const nstime_t *value = fvalue_get_time(fi->value);
10248 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10249 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10250 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10251 }
10252 if (hfinfo->strings) {
10253 /*
10254 * Table of time valus to be displayed
10255 * specially.
10256 */
10257 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10258 if (time_string != NULL((void*)0)) {
10259 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10260 break;
10261 }
10262 }
10263 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10264 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10265 wmem_free(NULL((void*)0), tmp);
10266 break;
10267 }
10268 case FT_RELATIVE_TIME:
10269 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10270 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10271 wmem_free(NULL((void*)0), tmp);
10272 break;
10273
10274 case FT_IPXNET:
10275 integer = fvalue_get_uinteger(fi->value);
10276 tmp = get_ipxnet_name(NULL((void*)0), integer);
10277 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10278 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10279 wmem_free(NULL((void*)0), tmp);
10280 wmem_free(NULL((void*)0), addr_str);
10281 break;
10282
10283 case FT_VINES:
10284 addr.type = AT_VINES;
10285 addr.len = VINES_ADDR_LEN6;
10286 addr.data = fvalue_get_bytes_data(fi->value);
10287
10288 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10289 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10290 wmem_free(NULL((void*)0), addr_str);
10291 break;
10292
10293 case FT_ETHER:
10294 bytes = fvalue_get_bytes_data(fi->value);
10295
10296 addr.type = AT_ETHER;
10297 addr.len = 6;
10298 addr.data = bytes;
10299
10300 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10301 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10302 wmem_free(NULL((void*)0), addr_str);
10303 break;
10304
10305 case FT_IPv4:
10306 ipv4 = fvalue_get_ipv4(fi->value);
10307 set_address_ipv4(&addr, ipv4);
10308
10309 if (hfinfo->display == BASE_NETMASK) {
10310 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10311 } else {
10312 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10313 }
10314 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10315 wmem_free(NULL((void*)0), addr_str);
10316 free_address(&addr);
10317 break;
10318
10319 case FT_IPv6:
10320 ipv6 = fvalue_get_ipv6(fi->value);
10321 set_address_ipv6(&addr, ipv6);
10322
10323 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10324 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10325 wmem_free(NULL((void*)0), addr_str);
10326 free_address(&addr);
10327 break;
10328
10329 case FT_FCWWN:
10330 bytes = fvalue_get_bytes_data(fi->value);
10331 addr.type = AT_FCWWN;
10332 addr.len = FCWWN_ADDR_LEN8;
10333 addr.data = bytes;
10334
10335 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10336 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10337 wmem_free(NULL((void*)0), addr_str);
10338 break;
10339
10340 case FT_GUID:
10341 guid = fvalue_get_guid(fi->value);
10342 tmp = guid_to_str(NULL((void*)0), guid);
10343 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10344 wmem_free(NULL((void*)0), tmp);
10345 break;
10346
10347 case FT_OID:
10348 bytes = fvalue_get_bytes_data(fi->value);
10349 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10350 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10351 if (name) {
10352 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10353 wmem_free(NULL((void*)0), name);
10354 } else {
10355 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10356 }
10357 wmem_free(NULL((void*)0), tmp);
10358 break;
10359
10360 case FT_REL_OID:
10361 bytes = fvalue_get_bytes_data(fi->value);
10362 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10363 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10364 if (name) {
10365 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10366 wmem_free(NULL((void*)0), name);
10367 } else {
10368 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10369 }
10370 wmem_free(NULL((void*)0), tmp);
10371 break;
10372
10373 case FT_SYSTEM_ID:
10374 bytes = fvalue_get_bytes_data(fi->value);
10375 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10376 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10377 wmem_free(NULL((void*)0), tmp);
10378 break;
10379
10380 case FT_EUI64:
10381 bytes = fvalue_get_bytes_data(fi->value);
10382 addr.type = AT_EUI64;
10383 addr.len = EUI64_ADDR_LEN8;
10384 addr.data = bytes;
10385
10386 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10387 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10388 wmem_free(NULL((void*)0), addr_str);
10389 break;
10390 case FT_STRING:
10391 case FT_STRINGZ:
10392 case FT_UINT_STRING:
10393 case FT_STRINGZPAD:
10394 case FT_STRINGZTRUNC:
10395 case FT_AX25:
10396 str = fvalue_get_string(fi->value);
10397 label_fill(label_str, 0, hfinfo, str, value_pos);
10398 break;
10399
10400 case FT_IEEE_11073_SFLOAT:
10401 case FT_IEEE_11073_FLOAT:
10402 fill_label_ieee_11073_float(fi, label_str, value_pos);
10403 break;
10404
10405 default:
10406 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
))
10407 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
))
10408 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
))
10409 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
))
;
10410 break;
10411 }
10412}
10413
10414static void
10415fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10416{
10417 char *p;
10418 int bitfield_byte_length = 0, bitwidth;
10419 uint64_t unshifted_value;
10420 uint64_t value;
10421
10422 const header_field_info *hfinfo = fi->hfinfo;
10423
10424 value = fvalue_get_uinteger64(fi->value);
10425 if (hfinfo->bitmask) {
10426 /* Figure out the bit width */
10427 bitwidth = hfinfo_container_bitwidth(hfinfo);
10428
10429 /* Un-shift bits */
10430 unshifted_value = value;
10431 unshifted_value <<= hfinfo_bitshift(hfinfo);
10432
10433 /* Create the bitfield first */
10434 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10435 bitfield_byte_length = (int) (p - label_str);
10436 }
10437
10438 /* Fill in the textual info */
10439 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10440}
10441
10442static const char *
10443hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10444{
10445 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10446 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10447
10448 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10449 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10450 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10451 else
10452 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10453 }
10454
10455 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10456 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10457
10458 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10459 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10460
10461 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10462}
10463
10464static const char *
10465hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10466{
10467 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10468 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10469 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10470 else
10471 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10472 }
10473
10474 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10475 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10476
10477 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10478 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10479
10480 /* If this is reached somebody registered a 64-bit field with a 32-bit
10481 * value-string, which isn't right. */
10482 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)
10483 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10484
10485 /* This is necessary to squelch MSVC errors; is there
10486 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10487 never returns? */
10488 return NULL((void*)0);
10489}
10490
10491static const char *
10492hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10493{
10494 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10495 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10496
10497 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)
;
10498
10499 /* This is necessary to squelch MSVC errors; is there
10500 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10501 never returns? */
10502 return NULL((void*)0);
10503}
10504
10505static const char *
10506hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10507{
10508 const char *str = hf_try_val_to_str(value, hfinfo);
10509
10510 return (str) ? str : unknown_str;
10511}
10512
10513static const char *
10514hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10515{
10516 const char *str = hf_try_val64_to_str(value, hfinfo);
10517
10518 return (str) ? str : unknown_str;
10519}
10520
10521/* Fills data for bitfield chars with val_strings */
10522static void
10523fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10524{
10525 char *p;
10526 int bitfield_byte_length, bitwidth;
10527 uint32_t unshifted_value;
10528 uint32_t value;
10529
10530 char buf[32];
10531 const char *out;
10532
10533 const header_field_info *hfinfo = fi->hfinfo;
10534
10535 /* Figure out the bit width */
10536 bitwidth = hfinfo_container_bitwidth(hfinfo);
10537
10538 /* Un-shift bits */
10539 value = fvalue_get_uinteger(fi->value);
10540
10541 unshifted_value = value;
10542 if (hfinfo->bitmask) {
10543 unshifted_value <<= hfinfo_bitshift(hfinfo);
10544 }
10545
10546 /* Create the bitfield first */
10547 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10548 bitfield_byte_length = (int) (p - label_str);
10549
10550 /* Fill in the textual info using stored (shifted) value */
10551 if (hfinfo->display == BASE_CUSTOM) {
10552 char tmp[ITEM_LABEL_LENGTH240];
10553 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10554
10555 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10555, "fmtfunc"))))
;
10556 fmtfunc(tmp, value);
10557 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10558 }
10559 else if (hfinfo->strings) {
10560 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10561
10562 out = hfinfo_char_vals_format(hfinfo, buf, value);
10563 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10564 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10565 else
10566 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10567 }
10568 else {
10569 out = hfinfo_char_value_format(hfinfo, buf, value);
10570
10571 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10572 }
10573}
10574
10575/* Fills data for bitfield ints with val_strings */
10576static void
10577fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10578{
10579 char *p;
10580 int bitfield_byte_length, bitwidth;
10581 uint32_t value, unshifted_value;
10582 char buf[NUMBER_LABEL_LENGTH80];
10583 const char *out;
10584
10585 const header_field_info *hfinfo = fi->hfinfo;
10586
10587 /* Figure out the bit width */
10588 if (fi->flags & FI_VARINT0x00040000)
10589 bitwidth = fi->length*8;
10590 else
10591 bitwidth = hfinfo_container_bitwidth(hfinfo);
10592
10593 /* Un-shift bits */
10594 if (is_signed)
10595 value = fvalue_get_sinteger(fi->value);
10596 else
10597 value = fvalue_get_uinteger(fi->value);
10598
10599 unshifted_value = value;
10600 if (hfinfo->bitmask) {
10601 unshifted_value <<= hfinfo_bitshift(hfinfo);
10602 }
10603
10604 /* Create the bitfield first */
10605 if (fi->flags & FI_VARINT0x00040000)
10606 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10607 else
10608 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10609 bitfield_byte_length = (int) (p - label_str);
10610
10611 /* Fill in the textual info using stored (shifted) value */
10612 if (hfinfo->display == BASE_CUSTOM) {
10613 char tmp[ITEM_LABEL_LENGTH240];
10614 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10615
10616 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10616, "fmtfunc"))))
;
10617 fmtfunc(tmp, value);
10618 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10619 }
10620 else if (hfinfo->strings) {
10621 const char *val_str = hf_try_val_to_str(value, hfinfo);
10622
10623 out = hfinfo_number_vals_format(hfinfo, buf, value);
10624 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10625 /*
10626 * Unique values only display value_string string
10627 * if there is a match. Otherwise it's just a number
10628 */
10629 if (val_str) {
10630 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10631 } else {
10632 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10633 }
10634 } else {
10635 if (val_str == NULL((void*)0))
10636 val_str = "Unknown";
10637
10638 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10639 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10640 else
10641 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10642 }
10643 }
10644 else {
10645 out = hfinfo_number_value_format(hfinfo, buf, value);
10646
10647 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10648 }
10649}
10650
10651static void
10652fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10653{
10654 char *p;
10655 int bitfield_byte_length, bitwidth;
10656 uint64_t value, unshifted_value;
10657 char buf[NUMBER_LABEL_LENGTH80];
10658 const char *out;
10659
10660 const header_field_info *hfinfo = fi->hfinfo;
10661
10662 /* Figure out the bit width */
10663 if (fi->flags & FI_VARINT0x00040000)
10664 bitwidth = fi->length*8;
10665 else
10666 bitwidth = hfinfo_container_bitwidth(hfinfo);
10667
10668 /* Un-shift bits */
10669 if (is_signed)
10670 value = fvalue_get_sinteger64(fi->value);
10671 else
10672 value = fvalue_get_uinteger64(fi->value);
10673
10674 unshifted_value = value;
10675 if (hfinfo->bitmask) {
10676 unshifted_value <<= hfinfo_bitshift(hfinfo);
10677 }
10678
10679 /* Create the bitfield first */
10680 if (fi->flags & FI_VARINT0x00040000)
10681 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10682 else
10683 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10684 bitfield_byte_length = (int) (p - label_str);
10685
10686 /* Fill in the textual info using stored (shifted) value */
10687 if (hfinfo->display == BASE_CUSTOM) {
10688 char tmp[ITEM_LABEL_LENGTH240];
10689 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10690
10691 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10691, "fmtfunc64"
))))
;
10692 fmtfunc64(tmp, value);
10693 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10694 }
10695 else if (hfinfo->strings) {
10696 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10697
10698 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10699 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10700 /*
10701 * Unique values only display value_string string
10702 * if there is a match. Otherwise it's just a number
10703 */
10704 if (val_str) {
10705 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10706 } else {
10707 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10708 }
10709 } else {
10710 if (val_str == NULL((void*)0))
10711 val_str = "Unknown";
10712
10713 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10714 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10715 else
10716 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10717 }
10718 }
10719 else {
10720 out = hfinfo_number_value_format64(hfinfo, buf, value);
10721
10722 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10723 }
10724}
10725
10726static void
10727fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10728{
10729 const header_field_info *hfinfo = fi->hfinfo;
10730 uint32_t value;
10731
10732 char buf[32];
10733 const char *out;
10734
10735 value = fvalue_get_uinteger(fi->value);
10736
10737 /* Fill in the textual info */
10738 if (hfinfo->display == BASE_CUSTOM) {
10739 char tmp[ITEM_LABEL_LENGTH240];
10740 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10741
10742 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10742, "fmtfunc"))))
;
10743 fmtfunc(tmp, value);
10744 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10745 }
10746 else if (hfinfo->strings) {
10747 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10748
10749 out = hfinfo_char_vals_format(hfinfo, buf, value);
10750 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10751 }
10752 else {
10753 out = hfinfo_char_value_format(hfinfo, buf, value);
10754
10755 label_fill(label_str, 0, hfinfo, out, value_pos);
10756 }
10757}
10758
10759static void
10760fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10761{
10762 const header_field_info *hfinfo = fi->hfinfo;
10763 uint32_t value;
10764
10765 char buf[NUMBER_LABEL_LENGTH80];
10766 const char *out;
10767
10768 if (is_signed)
10769 value = fvalue_get_sinteger(fi->value);
10770 else
10771 value = fvalue_get_uinteger(fi->value);
10772
10773 /* Fill in the textual info */
10774 if (hfinfo->display == BASE_CUSTOM) {
10775 char tmp[ITEM_LABEL_LENGTH240];
10776 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10777
10778 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10778, "fmtfunc"))))
;
10779 fmtfunc(tmp, value);
10780 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10781 }
10782 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10783 /*
10784 * It makes no sense to have a value-string table for a
10785 * frame-number field - they're just integers giving
10786 * the ordinal frame number.
10787 */
10788 const char *val_str = hf_try_val_to_str(value, hfinfo);
10789
10790 out = hfinfo_number_vals_format(hfinfo, buf, value);
10791 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10792 /*
10793 * Unique values only display value_string string
10794 * if there is a match. Otherwise it's just a number
10795 */
10796 if (val_str) {
10797 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10798 } else {
10799 label_fill(label_str, 0, hfinfo, out, value_pos);
10800 }
10801 } else {
10802 if (val_str == NULL((void*)0))
10803 val_str = "Unknown";
10804
10805 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10806 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10807 else
10808 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10809 }
10810 }
10811 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
))
) {
10812 char tmp[ITEM_LABEL_LENGTH240];
10813
10814 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10815 display_to_port_type((field_display_e)hfinfo->display), value);
10816 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10817 }
10818 else {
10819 out = hfinfo_number_value_format(hfinfo, buf, value);
10820
10821 label_fill(label_str, 0, hfinfo, out, value_pos);
10822 }
10823}
10824
10825static void
10826fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10827{
10828 const header_field_info *hfinfo = fi->hfinfo;
10829 uint64_t value;
10830
10831 char buf[NUMBER_LABEL_LENGTH80];
10832 const char *out;
10833
10834 if (is_signed)
10835 value = fvalue_get_sinteger64(fi->value);
10836 else
10837 value = fvalue_get_uinteger64(fi->value);
10838
10839 /* Fill in the textual info */
10840 if (hfinfo->display == BASE_CUSTOM) {
10841 char tmp[ITEM_LABEL_LENGTH240];
10842 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10843
10844 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10844, "fmtfunc64"
))))
;
10845 fmtfunc64(tmp, value);
10846 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10847 }
10848 else if (hfinfo->strings) {
10849 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10850
10851 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10852 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10853 /*
10854 * Unique values only display value_string string
10855 * if there is a match. Otherwise it's just a number
10856 */
10857 if (val_str) {
10858 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10859 } else {
10860 label_fill(label_str, 0, hfinfo, out, value_pos);
10861 }
10862 } else {
10863 if (val_str == NULL((void*)0))
10864 val_str = "Unknown";
10865
10866 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10867 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10868 else
10869 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10870 }
10871 }
10872 else {
10873 out = hfinfo_number_value_format64(hfinfo, buf, value);
10874
10875 label_fill(label_str, 0, hfinfo, out, value_pos);
10876 }
10877}
10878
10879static size_t
10880fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10881{
10882 int display;
10883 int n;
10884 double value;
10885
10886 if (label_str_size < 12) {
10887 /* Not enough room to write an entire floating point value. */
10888 return 0;
10889 }
10890
10891 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10892 value = fvalue_get_floating(fi->value);
10893
10894 if (display == BASE_CUSTOM) {
10895 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10896 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10896, "fmtfunc"))))
;
10897 fmtfunc(label_str, value);
10898 return strlen(label_str);
10899 }
10900
10901 switch (display) {
10902 case BASE_NONE:
10903 if (fi->hfinfo->type == FT_FLOAT) {
10904 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10905 } else {
10906 n = (int)strlen(dtoa_g_fmt(label_str, value));
10907 }
10908 break;
10909 case BASE_DEC:
10910 n = snprintf(label_str, label_str_size, "%f", value);
10911 break;
10912 case BASE_HEX:
10913 n = snprintf(label_str, label_str_size, "%a", value);
10914 break;
10915 case BASE_EXP:
10916 n = snprintf(label_str, label_str_size, "%e", value);
10917 break;
10918 default:
10919 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10919
, __func__, "assertion \"not reached\" failed")
;
10920 }
10921 if (n < 0) {
10922 return 0; /* error */
10923 }
10924 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10925 const char *hf_str_val;
10926 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10927 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10928 }
10929 if (n > label_str_size) {
10930 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10930, __func__, "label length too small"); } } while (0)
;
10931 return strlen(label_str);
10932 }
10933
10934 return n;
10935}
10936
10937void
10938fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10939{
10940 char tmp[ITEM_LABEL_LENGTH240];
10941
10942 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10943 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10944}
10945
10946static size_t
10947fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10948{
10949 int display;
10950 size_t pos = 0;
10951 double value;
10952 char* tmp_str;
10953
10954 if (label_str_size < 12) {
10955 /* Not enough room to write an entire floating point value. */
10956 return 0;
10957 }
10958
10959 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10960 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10961 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
10962 wmem_free(NULL((void*)0), tmp_str);
10963
10964 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10965 const char *hf_str_val;
10966 fvalue_to_double(fi->value, &value);
10967 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10968 pos = label_concat(label_str, pos, (const uint8_t*)hf_str_val)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)hf_str_val
, 0)
;
10969 }
10970 if ((int)pos > label_str_size) {
10971 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10971, __func__, "label length too small"); } } while (0)
;
10972 return strlen(label_str);
10973 }
10974
10975 return pos;
10976}
10977
10978void
10979fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
10980{
10981 char tmp[ITEM_LABEL_LENGTH240];
10982
10983 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
10984 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10985}
10986
10987int
10988hfinfo_bitshift(const header_field_info *hfinfo)
10989{
10990 return ws_ctz(hfinfo->bitmask);
10991}
10992
10993
10994static int
10995hfinfo_bitoffset(const header_field_info *hfinfo)
10996{
10997 if (!hfinfo->bitmask) {
10998 return 0;
10999 }
11000
11001 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11002 * as the first bit */
11003 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11004}
11005
11006static int
11007hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11008{
11009 if (!hfinfo->bitmask) {
11010 return 0;
11011 }
11012
11013 /* ilog2 = first set bit, ctz = last set bit */
11014 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11015}
11016
11017static int
11018hfinfo_type_bitwidth(enum ftenum type)
11019{
11020 int bitwidth = 0;
11021
11022 switch (type) {
11023 case FT_CHAR:
11024 case FT_UINT8:
11025 case FT_INT8:
11026 bitwidth = 8;
11027 break;
11028 case FT_UINT16:
11029 case FT_INT16:
11030 bitwidth = 16;
11031 break;
11032 case FT_UINT24:
11033 case FT_INT24:
11034 bitwidth = 24;
11035 break;
11036 case FT_UINT32:
11037 case FT_INT32:
11038 bitwidth = 32;
11039 break;
11040 case FT_UINT40:
11041 case FT_INT40:
11042 bitwidth = 40;
11043 break;
11044 case FT_UINT48:
11045 case FT_INT48:
11046 bitwidth = 48;
11047 break;
11048 case FT_UINT56:
11049 case FT_INT56:
11050 bitwidth = 56;
11051 break;
11052 case FT_UINT64:
11053 case FT_INT64:
11054 bitwidth = 64;
11055 break;
11056 default:
11057 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11057))
;
11058 ;
11059 }
11060 return bitwidth;
11061}
11062
11063
11064static int
11065hfinfo_container_bitwidth(const header_field_info *hfinfo)
11066{
11067 if (!hfinfo->bitmask) {
11068 return 0;
11069 }
11070
11071 if (hfinfo->type == FT_BOOLEAN) {
11072 return hfinfo->display; /* hacky? :) */
11073 }
11074
11075 return hfinfo_type_bitwidth(hfinfo->type);
11076}
11077
11078static int
11079hfinfo_hex_digits(const header_field_info *hfinfo)
11080{
11081 int bitwidth;
11082
11083 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11084 * appropriate to determine the number of hex digits for the field.
11085 * So instead, we compute it from the bitmask.
11086 */
11087 if (hfinfo->bitmask != 0) {
11088 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11089 } else {
11090 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11091 }
11092
11093 /* Divide by 4, rounding up, to get number of hex digits. */
11094 return (bitwidth + 3) / 4;
11095}
11096
11097const char *
11098hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11099{
11100 char *ptr = &buf[6];
11101 static const char hex_digits[16] =
11102 { '0', '1', '2', '3', '4', '5', '6', '7',
11103 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11104
11105 *ptr = '\0';
11106 *(--ptr) = '\'';
11107 /* Properly format value */
11108 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11109 /*
11110 * Printable, so just show the character, and, if it needs
11111 * to be escaped, escape it.
11112 */
11113 *(--ptr) = value;
11114 if (value == '\\' || value == '\'')
11115 *(--ptr) = '\\';
11116 } else {
11117 /*
11118 * Non-printable; show it as an escape sequence.
11119 */
11120 switch (value) {
11121
11122 case '\0':
11123 /*
11124 * Show a NUL with only one digit.
11125 */
11126 *(--ptr) = '0';
11127 break;
11128
11129 case '\a':
11130 case '\b':
11131 case '\f':
11132 case '\n':
11133 case '\r':
11134 case '\t':
11135 case '\v':
11136 *(--ptr) = value - '\a' + 'a';
11137 break;
11138
11139 default:
11140 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11141
11142 case BASE_OCT:
11143 *(--ptr) = (value & 0x7) + '0';
11144 value >>= 3;
11145 *(--ptr) = (value & 0x7) + '0';
11146 value >>= 3;
11147 *(--ptr) = (value & 0x7) + '0';
11148 break;
11149
11150 case BASE_HEX:
11151 *(--ptr) = hex_digits[value & 0x0F];
11152 value >>= 4;
11153 *(--ptr) = hex_digits[value & 0x0F];
11154 *(--ptr) = 'x';
11155 break;
11156
11157 default:
11158 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11159 }
11160 }
11161 *(--ptr) = '\\';
11162 }
11163 *(--ptr) = '\'';
11164 return ptr;
11165}
11166
11167static const char *
11168hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11169{
11170 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11171 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
))
;
11172
11173 *ptr = '\0';
11174 /* Properly format value */
11175 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11176 case BASE_DEC:
11177 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11178
11179 case BASE_DEC_HEX:
11180 *(--ptr) = ')';
11181 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11182 *(--ptr) = '(';
11183 *(--ptr) = ' ';
11184 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11185 return ptr;
11186
11187 case BASE_OCT:
11188 return oct_to_str_back(ptr, value);
11189
11190 case BASE_HEX:
11191 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11192
11193 case BASE_HEX_DEC:
11194 *(--ptr) = ')';
11195 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11196 *(--ptr) = '(';
11197 *(--ptr) = ' ';
11198 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11199 return ptr;
11200
11201 case BASE_PT_UDP:
11202 case BASE_PT_TCP:
11203 case BASE_PT_DCCP:
11204 case BASE_PT_SCTP:
11205 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11206 display_to_port_type((field_display_e)display), value);
11207 return buf;
11208 case BASE_OUI:
11209 {
11210 uint8_t p_oui[3];
11211 const char *manuf_name;
11212
11213 p_oui[0] = value >> 16 & 0xFF;
11214 p_oui[1] = value >> 8 & 0xFF;
11215 p_oui[2] = value & 0xFF;
11216
11217 /* Attempt an OUI lookup. */
11218 manuf_name = uint_get_manuf_name_if_known(value);
11219 if (manuf_name == NULL((void*)0)) {
11220 /* Could not find an OUI. */
11221 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11222 }
11223 else {
11224 /* Found an address string. */
11225 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11226 }
11227 return buf;
11228 }
11229
11230 default:
11231 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11232 }
11233 return ptr;
11234}
11235
11236static const char *
11237hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11238{
11239 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11240 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
))
;
11241
11242 *ptr = '\0';
11243 /* Properly format value */
11244 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11245 case BASE_DEC:
11246 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11247
11248 case BASE_DEC_HEX:
11249 *(--ptr) = ')';
11250 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11251 *(--ptr) = '(';
11252 *(--ptr) = ' ';
11253 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11254 return ptr;
11255
11256 case BASE_OCT:
11257 return oct64_to_str_back(ptr, value);
11258
11259 case BASE_HEX:
11260 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11261
11262 case BASE_HEX_DEC:
11263 *(--ptr) = ')';
11264 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11265 *(--ptr) = '(';
11266 *(--ptr) = ' ';
11267 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11268 return ptr;
11269
11270 default:
11271 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11272 }
11273
11274 return ptr;
11275}
11276
11277static const char *
11278hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11279{
11280 int display = hfinfo->display;
11281
11282 if (hfinfo->type == FT_FRAMENUM) {
11283 /*
11284 * Frame numbers are always displayed in decimal.
11285 */
11286 display = BASE_DEC;
11287 }
11288
11289 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11290}
11291
11292static const char *
11293hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11294{
11295 int display = hfinfo->display;
11296
11297 if (hfinfo->type == FT_FRAMENUM) {
11298 /*
11299 * Frame numbers are always displayed in decimal.
11300 */
11301 display = BASE_DEC;
11302 }
11303
11304 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11305}
11306
11307static const char *
11308hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11309{
11310 /* Get the underlying BASE_ value */
11311 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11312
11313 return hfinfo_char_value_format_display(display, buf, value);
11314}
11315
11316static const char *
11317hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11318{
11319 /* Get the underlying BASE_ value */
11320 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11321
11322 if (hfinfo->type == FT_FRAMENUM) {
11323 /*
11324 * Frame numbers are always displayed in decimal.
11325 */
11326 display = BASE_DEC;
11327 }
11328
11329 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11330 display = BASE_DEC;
11331 } else if (display == BASE_OUI) {
11332 display = BASE_HEX;
11333 }
11334
11335 switch (display) {
11336 case BASE_NONE:
11337 /* case BASE_DEC: */
11338 case BASE_DEC_HEX:
11339 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11340 case BASE_CUSTOM:
11341 display = BASE_DEC;
11342 break;
11343
11344 /* case BASE_HEX: */
11345 case BASE_HEX_DEC:
11346 display = BASE_HEX;
11347 break;
11348 }
11349
11350 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11351}
11352
11353static const char *
11354hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11355{
11356 /* Get the underlying BASE_ value */
11357 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11358
11359 if (hfinfo->type == FT_FRAMENUM) {
11360 /*
11361 * Frame numbers are always displayed in decimal.
11362 */
11363 display = BASE_DEC;
11364 }
11365
11366 switch (display) {
11367 case BASE_NONE:
11368 /* case BASE_DEC: */
11369 case BASE_DEC_HEX:
11370 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11371 case BASE_CUSTOM:
11372 display = BASE_DEC;
11373 break;
11374
11375 /* case BASE_HEX: */
11376 case BASE_HEX_DEC:
11377 display = BASE_HEX;
11378 break;
11379 }
11380
11381 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11382}
11383
11384static const char *
11385hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11386{
11387 /* Get the underlying BASE_ value */
11388 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11389
11390 return hfinfo_char_value_format_display(display, buf, value);
11391}
11392
11393static const char *
11394hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11395{
11396 /* Get the underlying BASE_ value */
11397 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11398
11399 if (display == BASE_NONE)
11400 return NULL((void*)0);
11401
11402 if (display == BASE_DEC_HEX)
11403 display = BASE_DEC;
11404 if (display == BASE_HEX_DEC)
11405 display = BASE_HEX;
11406
11407 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11408}
11409
11410static const char *
11411hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11412{
11413 /* Get the underlying BASE_ value */
11414 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11415
11416 if (display == BASE_NONE)
11417 return NULL((void*)0);
11418
11419 if (display == BASE_DEC_HEX)
11420 display = BASE_DEC;
11421 if (display == BASE_HEX_DEC)
11422 display = BASE_HEX;
11423
11424 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11425}
11426
11427const char *
11428proto_registrar_get_name(const int n)
11429{
11430 header_field_info *hfinfo;
11431
11432 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", 11432
, __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", 11432
, "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", 11432, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11433 return hfinfo->name;
11434}
11435
11436const char *
11437proto_registrar_get_abbrev(const int n)
11438{
11439 header_field_info *hfinfo;
11440
11441 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", 11441
, __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", 11441
, "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", 11441, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11442 return hfinfo->abbrev;
11443}
11444
11445enum ftenum
11446proto_registrar_get_ftype(const int n)
11447{
11448 header_field_info *hfinfo;
11449
11450 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", 11450
, __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", 11450
, "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", 11450, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11451 return hfinfo->type;
11452}
11453
11454int
11455proto_registrar_get_parent(const int n)
11456{
11457 header_field_info *hfinfo;
11458
11459 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", 11459
, __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", 11459
, "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", 11459, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11460 return hfinfo->parent;
11461}
11462
11463bool_Bool
11464proto_registrar_is_protocol(const int n)
11465{
11466 header_field_info *hfinfo;
11467
11468 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", 11468
, __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", 11468
, "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", 11468, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11469 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11470}
11471
11472/* Returns length of field in packet (not necessarily the length
11473 * in our internal representation, as in the case of IPv4).
11474 * 0 means undeterminable at time of registration
11475 * -1 means the field is not registered. */
11476int
11477proto_registrar_get_length(const int n)
11478{
11479 header_field_info *hfinfo;
11480
11481 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", 11481
, __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", 11481
, "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", 11481, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11482 return ftype_wire_size(hfinfo->type);
11483}
11484
11485size_t
11486proto_registrar_get_count(struct proto_registrar_stats *stats)
11487{
11488 header_field_info *hfinfo;
11489
11490 // Index zero is not used. We have to skip it.
11491 size_t total_count = gpa_hfinfo.len - 1;
11492 if (stats
1.1
'stats' is not equal to NULL
== NULL((void*)0)) {
2
Taking false branch
11493 return total_count;
11494 }
11495 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
3
Assuming 'id' is >= field 'len'
4
Loop condition is false. Execution continues on line 11510
11496 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11497 stats->deregistered_count++;
11498 continue; /* This is a deregistered protocol or header field */
11499 }
11500
11501 PROTO_REGISTRAR_GET_NTH(id, hfinfo)if((id == 0 || (unsigned)id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11501
, __func__, "Unregistered hf! index=%d", id); ((void) ((id >
0 && (unsigned)id < gpa_hfinfo.len) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11501, "id > 0 && (unsigned)id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[id] != ((
void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11501, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11502
11503 if (proto_registrar_is_protocol(id))
11504 stats->protocol_count++;
11505
11506 if (hfinfo->same_name_prev_id != -1)
11507 stats->same_name_count++;
11508 }
11509
11510 return total_count;
5
Returning without writing to 'stats->deregistered_count'
11511}
11512
11513/* Looks for a protocol or a field in a proto_tree. Returns true if
11514 * it exists anywhere, or false if it exists nowhere. */
11515bool_Bool
11516proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11517{
11518 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11519
11520 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11521 return true1;
11522 }
11523 else {
11524 return false0;
11525 }
11526}
11527
11528/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11529 * This only works if the hfindex was "primed" before the dissection
11530 * took place, as we just pass back the already-created GPtrArray*.
11531 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11532 * handles that. */
11533GPtrArray *
11534proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11535{
11536 if (!tree)
11537 return NULL((void*)0);
11538
11539 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11540 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11541 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11542 else
11543 return NULL((void*)0);
11544}
11545
11546bool_Bool
11547proto_tracking_interesting_fields(const proto_tree *tree)
11548{
11549 GHashTable *interesting_hfids;
11550
11551 if (!tree)
11552 return false0;
11553
11554 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11555
11556 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11557}
11558
11559/* Helper struct for proto_find_info() and proto_all_finfos() */
11560typedef struct {
11561 GPtrArray *array;
11562 int id;
11563} ffdata_t;
11564
11565/* Helper function for proto_find_info() */
11566static bool_Bool
11567find_finfo(proto_node *node, void * data)
11568{
11569 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11570 if (fi && fi->hfinfo) {
11571 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11572 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11573 }
11574 }
11575
11576 /* Don't stop traversing. */
11577 return false0;
11578}
11579
11580/* Helper function for proto_find_first_info() */
11581static bool_Bool
11582find_first_finfo(proto_node *node, void *data)
11583{
11584 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11585 if (fi && fi->hfinfo) {
11586 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11587 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11588
11589 /* Stop traversing. */
11590 return true1;
11591 }
11592 }
11593
11594 /* Continue traversing. */
11595 return false0;
11596}
11597
11598/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11599* This works on any proto_tree, primed or unprimed, but actually searches
11600* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11601* The caller does need to free the returned GPtrArray with
11602* g_ptr_array_free(<array>, true).
11603*/
11604GPtrArray *
11605proto_find_finfo(proto_tree *tree, const int id)
11606{
11607 ffdata_t ffdata;
11608
11609 ffdata.array = g_ptr_array_new();
11610 ffdata.id = id;
11611
11612 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11613
11614 return ffdata.array;
11615}
11616
11617/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11618* This works on any proto_tree, primed or unprimed, but actually searches
11619* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11620* The caller does need to free the returned GPtrArray with
11621* g_ptr_array_free(<array>, true).
11622*/
11623GPtrArray *
11624proto_find_first_finfo(proto_tree *tree, const int id)
11625{
11626 ffdata_t ffdata;
11627
11628 ffdata.array = g_ptr_array_new();
11629 ffdata.id = id;
11630
11631 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11632
11633 return ffdata.array;
11634}
11635
11636/* Helper function for proto_all_finfos() */
11637static bool_Bool
11638every_finfo(proto_node *node, void * data)
11639{
11640 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11641 if (fi && fi->hfinfo) {
11642 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11643 }
11644
11645 /* Don't stop traversing. */
11646 return false0;
11647}
11648
11649/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11650 * The caller does need to free the returned GPtrArray with
11651 * g_ptr_array_free(<array>, true).
11652 */
11653GPtrArray *
11654proto_all_finfos(proto_tree *tree)
11655{
11656 ffdata_t ffdata;
11657
11658 /* Pre allocate enough space to hold all fields in most cases */
11659 ffdata.array = g_ptr_array_sized_new(512);
11660 ffdata.id = 0;
11661
11662 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11663
11664 return ffdata.array;
11665}
11666
11667
11668typedef struct {
11669 unsigned offset;
11670 field_info *finfo;
11671 tvbuff_t *tvb;
11672} offset_search_t;
11673
11674static bool_Bool
11675check_for_offset(proto_node *node, void * data)
11676{
11677 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11678 offset_search_t *offsearch = (offset_search_t *)data;
11679
11680 /* !fi == the top most container node which holds nothing */
11681 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11682 if (offsearch->offset >= (unsigned) fi->start &&
11683 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11684
11685 offsearch->finfo = fi;
11686 return false0; /* keep traversing */
11687 }
11688 }
11689 return false0; /* keep traversing */
11690}
11691
11692/* Search a proto_tree backwards (from leaves to root) looking for the field
11693 * whose start/length occupies 'offset' */
11694/* XXX - I couldn't find an easy way to search backwards, so I search
11695 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11696 * the one I want to return to the user. This algorithm is inefficient
11697 * and could be re-done, but I'd have to handle all the children and
11698 * siblings of each node myself. When I have more time I'll do that.
11699 * (yeah right) */
11700field_info *
11701proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11702{
11703 offset_search_t offsearch;
11704
11705 offsearch.offset = offset;
11706 offsearch.finfo = NULL((void*)0);
11707 offsearch.tvb = tvb;
11708
11709 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11710
11711 return offsearch.finfo;
11712}
11713
11714typedef struct {
11715 int length;
11716 char *buf;
11717} decoded_data_t;
11718
11719static bool_Bool
11720check_for_undecoded(proto_node *node, void * data)
11721{
11722 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11723 decoded_data_t* decoded = (decoded_data_t*)data;
11724 int i;
11725 unsigned byte;
11726 unsigned bit;
11727
11728 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11729 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11730 byte = i / 8;
11731 bit = i % 8;
11732 decoded->buf[byte] |= (1 << bit);
11733 }
11734 }
11735
11736 return false0;
11737}
11738
11739char*
11740proto_find_undecoded_data(proto_tree *tree, unsigned length)
11741{
11742 decoded_data_t decoded;
11743 decoded.length = length;
11744 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11745
11746 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11747 return decoded.buf;
11748}
11749
11750/* Dumps the protocols in the registration database to stdout. An independent
11751 * program can take this output and format it into nice tables or HTML or
11752 * whatever.
11753 *
11754 * There is one record per line. The fields are tab-delimited.
11755 *
11756 * Field 1 = protocol name
11757 * Field 2 = protocol short name
11758 * Field 3 = protocol filter name
11759 * Field 4 = protocol enabled
11760 * Field 5 = protocol enabled by default
11761 * Field 6 = protocol can toggle
11762 */
11763void
11764proto_registrar_dump_protocols(void)
11765{
11766 protocol_t *protocol;
11767 int i;
11768 void *cookie = NULL((void*)0);
11769
11770
11771 i = proto_get_first_protocol(&cookie);
11772 while (i != -1) {
11773 protocol = find_protocol_by_id(i);
11774 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11775 protocol->name,
11776 protocol->short_name,
11777 protocol->filter_name,
11778 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11779 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11780 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11781 i = proto_get_next_protocol(&cookie);
11782 }
11783}
11784
11785/* Dumps the value_strings, extended value string headers, range_strings
11786 * or true/false strings for fields that have them.
11787 * There is one record per line. Fields are tab-delimited.
11788 * There are four types of records: Value String, Extended Value String Header,
11789 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11790 * the type of record.
11791 *
11792 * Note that a record will be generated only if the value_string,... is referenced
11793 * in a registered hfinfo entry.
11794 *
11795 *
11796 * Value Strings
11797 * -------------
11798 * Field 1 = 'V'
11799 * Field 2 = Field abbreviation to which this value string corresponds
11800 * Field 3 = Integer value
11801 * Field 4 = String
11802 *
11803 * Extended Value String Headers
11804 * -----------------------------
11805 * Field 1 = 'E'
11806 * Field 2 = Field abbreviation to which this extended value string header corresponds
11807 * Field 3 = Extended Value String "Name"
11808 * Field 4 = Number of entries in the associated value_string array
11809 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11810 *
11811 * Range Strings
11812 * -------------
11813 * Field 1 = 'R'
11814 * Field 2 = Field abbreviation to which this range string corresponds
11815 * Field 3 = Integer value: lower bound
11816 * Field 4 = Integer value: upper bound
11817 * Field 5 = String
11818 *
11819 * True/False Strings
11820 * ------------------
11821 * Field 1 = 'T'
11822 * Field 2 = Field abbreviation to which this true/false string corresponds
11823 * Field 3 = True String
11824 * Field 4 = False String
11825 */
11826void
11827proto_registrar_dump_values(void)
11828{
11829 header_field_info *hfinfo;
11830 int i, len, vi;
11831 const value_string *vals;
11832 const val64_string *vals64;
11833 const range_string *range;
11834 const true_false_string *tfs;
11835 const unit_name_string *units;
11836
11837 len = gpa_hfinfo.len;
11838 for (i = 1; i < len ; i++) {
11839 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11840 continue; /* This is a deregistered protocol or field */
11841
11842 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", 11842
, __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", 11842
, "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", 11842, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11843
11844 if (hfinfo->id == hf_text_only) {
11845 continue;
11846 }
11847
11848 /* ignore protocols */
11849 if (proto_registrar_is_protocol(i)) {
11850 continue;
11851 }
11852 /* process header fields */
11853#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11854 /*
11855 * If this field isn't at the head of the list of
11856 * fields with this name, skip this field - all
11857 * fields with the same name are really just versions
11858 * of the same field stored in different bits, and
11859 * should have the same type/radix/value list, and
11860 * just differ in their bit masks. (If a field isn't
11861 * a bitfield, but can be, say, 1 or 2 bytes long,
11862 * it can just be made FT_UINT16, meaning the
11863 * *maximum* length is 2 bytes, and be used
11864 * for all lengths.)
11865 */
11866 if (hfinfo->same_name_prev_id != -1)
11867 continue;
11868#endif
11869 vals = NULL((void*)0);
11870 vals64 = NULL((void*)0);
11871 range = NULL((void*)0);
11872 tfs = NULL((void*)0);
11873 units = NULL((void*)0);
11874
11875 if (hfinfo->strings != NULL((void*)0)) {
11876 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11877 (hfinfo->type == FT_CHAR ||
11878 hfinfo->type == FT_UINT8 ||
11879 hfinfo->type == FT_UINT16 ||
11880 hfinfo->type == FT_UINT24 ||
11881 hfinfo->type == FT_UINT32 ||
11882 hfinfo->type == FT_UINT40 ||
11883 hfinfo->type == FT_UINT48 ||
11884 hfinfo->type == FT_UINT56 ||
11885 hfinfo->type == FT_UINT64 ||
11886 hfinfo->type == FT_INT8 ||
11887 hfinfo->type == FT_INT16 ||
11888 hfinfo->type == FT_INT24 ||
11889 hfinfo->type == FT_INT32 ||
11890 hfinfo->type == FT_INT40 ||
11891 hfinfo->type == FT_INT48 ||
11892 hfinfo->type == FT_INT56 ||
11893 hfinfo->type == FT_INT64 ||
11894 hfinfo->type == FT_FLOAT ||
11895 hfinfo->type == FT_DOUBLE)) {
11896
11897 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11898 range = (const range_string *)hfinfo->strings;
11899 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11900 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11901 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11902 } else {
11903 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11904 }
11905 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11906 vals64 = (const val64_string *)hfinfo->strings;
11907 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11908 units = (const unit_name_string *)hfinfo->strings;
11909 } else {
11910 vals = (const value_string *)hfinfo->strings;
11911 }
11912 }
11913 else if (hfinfo->type == FT_BOOLEAN) {
11914 tfs = (const struct true_false_string *)hfinfo->strings;
11915 }
11916 }
11917
11918 /* Print value strings? */
11919 if (vals) {
11920 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11921 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11922 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11923 if (!val64_string_ext_validate(vse_p)) {
11924 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11924, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11925 continue;
11926 }
11927 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11928 printf("E\t%s\t%u\t%s\t%s\n",
11929 hfinfo->abbrev,
11930 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11931 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11932 val64_string_ext_match_type_str(vse_p));
11933 } else {
11934 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11935 if (!value_string_ext_validate(vse_p)) {
11936 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11936, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11937 continue;
11938 }
11939 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11940 printf("E\t%s\t%u\t%s\t%s\n",
11941 hfinfo->abbrev,
11942 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11943 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11944 value_string_ext_match_type_str(vse_p));
11945 }
11946 }
11947 vi = 0;
11948 while (vals[vi].strptr) {
11949 /* Print in the proper base */
11950 if (hfinfo->type == FT_CHAR) {
11951 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11952 printf("V\t%s\t'%c'\t%s\n",
11953 hfinfo->abbrev,
11954 vals[vi].value,
11955 vals[vi].strptr);
11956 } else {
11957 if (hfinfo->display == BASE_HEX) {
11958 printf("V\t%s\t'\\x%02x'\t%s\n",
11959 hfinfo->abbrev,
11960 vals[vi].value,
11961 vals[vi].strptr);
11962 }
11963 else {
11964 printf("V\t%s\t'\\%03o'\t%s\n",
11965 hfinfo->abbrev,
11966 vals[vi].value,
11967 vals[vi].strptr);
11968 }
11969 }
11970 } else {
11971 if (hfinfo->display == BASE_HEX) {
11972 printf("V\t%s\t0x%x\t%s\n",
11973 hfinfo->abbrev,
11974 vals[vi].value,
11975 vals[vi].strptr);
11976 }
11977 else {
11978 printf("V\t%s\t%u\t%s\n",
11979 hfinfo->abbrev,
11980 vals[vi].value,
11981 vals[vi].strptr);
11982 }
11983 }
11984 vi++;
11985 }
11986 }
11987 else if (vals64) {
11988 vi = 0;
11989 while (vals64[vi].strptr) {
11990 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11991 hfinfo->abbrev,
11992 vals64[vi].value,
11993 vals64[vi].strptr);
11994 vi++;
11995 }
11996 }
11997
11998 /* print range strings? */
11999 else if (range) {
12000 vi = 0;
12001 while (range[vi].strptr) {
12002 /* Print in the proper base */
12003 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12004 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12005 hfinfo->abbrev,
12006 range[vi].value_min,
12007 range[vi].value_max,
12008 range[vi].strptr);
12009 }
12010 else {
12011 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12012 hfinfo->abbrev,
12013 range[vi].value_min,
12014 range[vi].value_max,
12015 range[vi].strptr);
12016 }
12017 vi++;
12018 }
12019 }
12020
12021 /* Print true/false strings? */
12022 else if (tfs) {
12023 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12024 tfs->true_string, tfs->false_string);
12025 }
12026 /* Print unit strings? */
12027 else if (units) {
12028 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12029 units->singular, units->plural ? units->plural : "(no plural)");
12030 }
12031 }
12032}
12033
12034/* Prints the number of registered fields.
12035 * Useful for determining an appropriate value for
12036 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12037 *
12038 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12039 * the number of fields, true otherwise.
12040 */
12041bool_Bool
12042proto_registrar_dump_fieldcount(void)
12043{
12044 struct proto_registrar_stats stats;
12045 size_t total_count = proto_registrar_get_count(&stats);
1
Calling 'proto_registrar_get_count'
6
Returning from 'proto_registrar_get_count'
12046
12047 printf("There are %zu header fields registered, of which:\n"
7
3rd function call argument is an uninitialized value
12048 "\t%zu are deregistered\n"
12049 "\t%zu are protocols\n"
12050 "\t%zu have the same name as another field\n\n",
12051 total_count, stats.deregistered_count, stats.protocol_count,
12052 stats.same_name_count);
12053
12054 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12055 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12056 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12057 "\n");
12058
12059 printf("The header field table consumes %u KiB of memory.\n",
12060 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12061 printf("The fields themselves consume %u KiB of memory.\n",
12062 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12063
12064 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12065}
12066
12067static void
12068elastic_add_base_mapping(json_dumper *dumper)
12069{
12070 json_dumper_set_member_name(dumper, "index_patterns");
12071 json_dumper_begin_array(dumper);
12072 // The index names from write_json_index() in print.c
12073 json_dumper_value_string(dumper, "packets-*");
12074 json_dumper_end_array(dumper);
12075
12076 json_dumper_set_member_name(dumper, "settings");
12077 json_dumper_begin_object(dumper);
12078 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12079 json_dumper_value_anyf(dumper, "%d", 1000000);
12080 json_dumper_end_object(dumper);
12081}
12082
12083static char*
12084ws_type_to_elastic(unsigned type)
12085{
12086 switch(type) {
12087 case FT_INT8:
12088 return "byte";
12089 case FT_UINT8:
12090 case FT_INT16:
12091 return "short";
12092 case FT_UINT16:
12093 case FT_INT32:
12094 case FT_UINT24:
12095 case FT_INT24:
12096 return "integer";
12097 case FT_FRAMENUM:
12098 case FT_UINT32:
12099 case FT_UINT40:
12100 case FT_UINT48:
12101 case FT_UINT56:
12102 case FT_INT40:
12103 case FT_INT48:
12104 case FT_INT56:
12105 case FT_INT64:
12106 return "long";
12107 case FT_UINT64:
12108 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12109 case FT_FLOAT:
12110 return "float";
12111 case FT_DOUBLE:
12112 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12113 return "double";
12114 case FT_IPv6:
12115 case FT_IPv4:
12116 return "ip";
12117 case FT_ABSOLUTE_TIME:
12118 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12119 case FT_BOOLEAN:
12120 return "boolean";
12121 default:
12122 return NULL((void*)0);
12123 }
12124}
12125
12126static char*
12127dot_to_underscore(char* str)
12128{
12129 unsigned i;
12130 for (i = 0; i < strlen(str); i++) {
12131 if (str[i] == '.')
12132 str[i] = '_';
12133 }
12134 return str;
12135}
12136
12137/* Dumps a mapping file for ElasticSearch
12138 * This is the v1 (legacy) _template API.
12139 * At some point it may need to be updated with the composable templates
12140 * introduced in Elasticsearch 7.8 (_index_template)
12141 */
12142void
12143proto_registrar_dump_elastic(const char* filter)
12144{
12145 header_field_info *hfinfo;
12146 header_field_info *parent_hfinfo;
12147 unsigned i;
12148 bool_Bool open_object = true1;
12149 const char* prev_proto = NULL((void*)0);
12150 char* str;
12151 char** protos = NULL((void*)0);
12152 char* proto;
12153 bool_Bool found;
12154 unsigned j;
12155 char* type;
12156 char* prev_item = NULL((void*)0);
12157
12158 /* We have filtering protocols. Extract them. */
12159 if (filter) {
12160 protos = g_strsplit(filter, ",", -1);
12161 }
12162
12163 /*
12164 * To help tracking down the json tree, objects have been appended with a comment:
12165 * n.label -> where n is the indentation level and label the name of the object
12166 */
12167
12168 json_dumper dumper = {
12169 .output_file = stdoutstdout,
12170 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12171 };
12172 json_dumper_begin_object(&dumper); // 1.root
12173 elastic_add_base_mapping(&dumper);
12174
12175 json_dumper_set_member_name(&dumper, "mappings");
12176 json_dumper_begin_object(&dumper); // 2.mappings
12177
12178 json_dumper_set_member_name(&dumper, "properties");
12179 json_dumper_begin_object(&dumper); // 3.properties
12180 json_dumper_set_member_name(&dumper, "timestamp");
12181 json_dumper_begin_object(&dumper); // 4.timestamp
12182 json_dumper_set_member_name(&dumper, "type");
12183 json_dumper_value_string(&dumper, "date");
12184 json_dumper_end_object(&dumper); // 4.timestamp
12185
12186 json_dumper_set_member_name(&dumper, "layers");
12187 json_dumper_begin_object(&dumper); // 4.layers
12188 json_dumper_set_member_name(&dumper, "properties");
12189 json_dumper_begin_object(&dumper); // 5.properties
12190
12191 for (i = 1; i < gpa_hfinfo.len; i++) {
12192 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12193 continue; /* This is a deregistered protocol or header field */
12194
12195 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", 12195
, __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", 12195
, "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", 12195, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12196
12197 /*
12198 * Skip the pseudo-field for "proto_tree_add_text()" since
12199 * we don't want it in the list of filterable protocols.
12200 */
12201 if (hfinfo->id == hf_text_only)
12202 continue;
12203
12204 if (!proto_registrar_is_protocol(i)) {
12205 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", 12205
, __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", 12205
, "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", 12205
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12206
12207 /*
12208 * Skip the field if filter protocols have been set and this one's
12209 * parent is not listed.
12210 */
12211 if (protos) {
12212 found = false0;
12213 j = 0;
12214 proto = protos[0];
12215 while(proto) {
12216 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12217 found = true1;
12218 break;
12219 }
12220 j++;
12221 proto = protos[j];
12222 }
12223 if (!found)
12224 continue;
12225 }
12226
12227 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12228 json_dumper_end_object(&dumper); // 7.properties
12229 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12230 open_object = true1;
12231 }
12232
12233 prev_proto = parent_hfinfo->abbrev;
12234
12235 if (open_object) {
12236 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12237 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12238 json_dumper_set_member_name(&dumper, "properties");
12239 json_dumper_begin_object(&dumper); // 7.properties
12240 open_object = false0;
12241 }
12242 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12243 type = ws_type_to_elastic(hfinfo->type);
12244 /* when type is NULL, we have the default mapping: string */
12245 if (type) {
12246 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12247 dot_to_underscore(str);
12248 if (g_strcmp0(prev_item, str)) {
12249 json_dumper_set_member_name(&dumper, str);
12250 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12251 json_dumper_set_member_name(&dumper, "type");
12252 json_dumper_value_string(&dumper, type);
12253 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12254 }
12255 g_free(prev_item);
12256 prev_item = str;
12257 }
12258 }
12259 }
12260 g_free(prev_item);
12261
12262 if (prev_proto) {
12263 json_dumper_end_object(&dumper); // 7.properties
12264 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12265 }
12266
12267 json_dumper_end_object(&dumper); // 5.properties
12268 json_dumper_end_object(&dumper); // 4.layers
12269 json_dumper_end_object(&dumper); // 3.properties
12270 json_dumper_end_object(&dumper); // 2.mappings
12271 json_dumper_end_object(&dumper); // 1.root
12272 bool_Bool ret = json_dumper_finish(&dumper);
12273 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12273, "ret"))))
;
12274
12275 g_strfreev(protos);
12276}
12277
12278/* Dumps the contents of the registration database to stdout. An independent
12279 * program can take this output and format it into nice tables or HTML or
12280 * whatever.
12281 *
12282 * There is one record per line. Each record is either a protocol or a header
12283 * field, differentiated by the first field. The fields are tab-delimited.
12284 *
12285 * Protocols
12286 * ---------
12287 * Field 1 = 'P'
12288 * Field 2 = descriptive protocol name
12289 * Field 3 = protocol abbreviation
12290 *
12291 * Header Fields
12292 * -------------
12293 * Field 1 = 'F'
12294 * Field 2 = descriptive field name
12295 * Field 3 = field abbreviation
12296 * Field 4 = type ( textual representation of the ftenum type )
12297 * Field 5 = parent protocol abbreviation
12298 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12299 * Field 7 = bitmask: format: hex: 0x....
12300 * Field 8 = blurb describing field
12301 */
12302void
12303proto_registrar_dump_fields(void)
12304{
12305 header_field_info *hfinfo, *parent_hfinfo;
12306 int i, len;
12307 const char *enum_name;
12308 const char *base_name;
12309 const char *blurb;
12310 char width[5];
12311
12312 len = gpa_hfinfo.len;
12313 for (i = 1; i < len ; i++) {
12314 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12315 continue; /* This is a deregistered protocol or header field */
12316
12317 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", 12317
, __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", 12317
, "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", 12317, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12318
12319 /*
12320 * Skip the pseudo-field for "proto_tree_add_text()" since
12321 * we don't want it in the list of filterable fields.
12322 */
12323 if (hfinfo->id == hf_text_only)
12324 continue;
12325
12326 /* format for protocols */
12327 if (proto_registrar_is_protocol(i)) {
12328 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12329 }
12330 /* format for header fields */
12331 else {
12332 /*
12333 * If this field isn't at the head of the list of
12334 * fields with this name, skip this field - all
12335 * fields with the same name are really just versions
12336 * of the same field stored in different bits, and
12337 * should have the same type/radix/value list, and
12338 * just differ in their bit masks. (If a field isn't
12339 * a bitfield, but can be, say, 1 or 2 bytes long,
12340 * it can just be made FT_UINT16, meaning the
12341 * *maximum* length is 2 bytes, and be used
12342 * for all lengths.)
12343 */
12344 if (hfinfo->same_name_prev_id != -1)
12345 continue;
12346
12347 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", 12347
, __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", 12347
, "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", 12347
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12348
12349 enum_name = ftype_name(hfinfo->type);
12350 base_name = "";
12351
12352 if (hfinfo->type == FT_CHAR ||
12353 hfinfo->type == FT_UINT8 ||
12354 hfinfo->type == FT_UINT16 ||
12355 hfinfo->type == FT_UINT24 ||
12356 hfinfo->type == FT_UINT32 ||
12357 hfinfo->type == FT_UINT40 ||
12358 hfinfo->type == FT_UINT48 ||
12359 hfinfo->type == FT_UINT56 ||
12360 hfinfo->type == FT_UINT64 ||
12361 hfinfo->type == FT_INT8 ||
12362 hfinfo->type == FT_INT16 ||
12363 hfinfo->type == FT_INT24 ||
12364 hfinfo->type == FT_INT32 ||
12365 hfinfo->type == FT_INT40 ||
12366 hfinfo->type == FT_INT48 ||
12367 hfinfo->type == FT_INT56 ||
12368 hfinfo->type == FT_INT64) {
12369
12370 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12371 case BASE_NONE:
12372 case BASE_DEC:
12373 case BASE_HEX:
12374 case BASE_OCT:
12375 case BASE_DEC_HEX:
12376 case BASE_HEX_DEC:
12377 case BASE_CUSTOM:
12378 case BASE_PT_UDP:
12379 case BASE_PT_TCP:
12380 case BASE_PT_DCCP:
12381 case BASE_PT_SCTP:
12382 case BASE_OUI:
12383 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12384 break;
12385 default:
12386 base_name = "????";
12387 break;
12388 }
12389 } else if (hfinfo->type == FT_BOOLEAN) {
12390 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12391 snprintf(width, sizeof(width), "%d", hfinfo->display);
12392 base_name = width;
12393 }
12394
12395 blurb = hfinfo->blurb;
12396 if (blurb == NULL((void*)0))
12397 blurb = "";
12398 else if (strlen(blurb) == 0)
12399 blurb = "\"\"";
12400
12401 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12402 hfinfo->name, hfinfo->abbrev, enum_name,
12403 parent_hfinfo->abbrev, base_name,
12404 hfinfo->bitmask, blurb);
12405 }
12406 }
12407}
12408
12409/* Dumps all abbreviated field and protocol completions of the given string to
12410 * stdout. An independent program may use this for command-line tab completion
12411 * of fields.
12412 */
12413bool_Bool
12414proto_registrar_dump_field_completions(const char *prefix)
12415{
12416 header_field_info *hfinfo;
12417 int i, len;
12418 size_t prefix_len;
12419 bool_Bool matched = false0;
12420
12421 prefix_len = strlen(prefix);
12422 len = gpa_hfinfo.len;
12423 for (i = 1; i < len ; i++) {
12424 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12425 continue; /* This is a deregistered protocol or header field */
12426
12427 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", 12427
, __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", 12427
, "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", 12427, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12428
12429 /*
12430 * Skip the pseudo-field for "proto_tree_add_text()" since
12431 * we don't want it in the list of filterable fields.
12432 */
12433 if (hfinfo->id == hf_text_only)
12434 continue;
12435
12436 /* format for protocols */
12437 if (proto_registrar_is_protocol(i)) {
12438 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12439 matched = true1;
12440 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12441 }
12442 }
12443 /* format for header fields */
12444 else {
12445 /*
12446 * If this field isn't at the head of the list of
12447 * fields with this name, skip this field - all
12448 * fields with the same name are really just versions
12449 * of the same field stored in different bits, and
12450 * should have the same type/radix/value list, and
12451 * just differ in their bit masks. (If a field isn't
12452 * a bitfield, but can be, say, 1 or 2 bytes long,
12453 * it can just be made FT_UINT16, meaning the
12454 * *maximum* length is 2 bytes, and be used
12455 * for all lengths.)
12456 */
12457 if (hfinfo->same_name_prev_id != -1)
12458 continue;
12459
12460 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12461 matched = true1;
12462 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12463 }
12464 }
12465 }
12466 return matched;
12467}
12468
12469/* Dumps field types and descriptive names to stdout. An independent
12470 * program can take this output and format it into nice tables or HTML or
12471 * whatever.
12472 *
12473 * There is one record per line. The fields are tab-delimited.
12474 *
12475 * Field 1 = field type name, e.g. FT_UINT8
12476 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12477 */
12478void
12479proto_registrar_dump_ftypes(void)
12480{
12481 int fte;
12482
12483 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12484 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12485 }
12486}
12487
12488/* This function indicates whether it's possible to construct a
12489 * "match selected" display filter string for the specified field,
12490 * returns an indication of whether it's possible, and, if it's
12491 * possible and "filter" is non-null, constructs the filter and
12492 * sets "*filter" to point to it.
12493 * You do not need to [g_]free() this string since it will be automatically
12494 * freed once the next packet is dissected.
12495 */
12496static bool_Bool
12497construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12498 char **filter)
12499{
12500 const header_field_info *hfinfo;
12501 int start, length, length_remaining;
12502
12503 if (!finfo)
12504 return false0;
12505
12506 hfinfo = finfo->hfinfo;
12507 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12507, "hfinfo"))))
;
12508
12509 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12510 * then "the numeric value ... is not used when preparing
12511 * filters for the field in question." If it's any other
12512 * base, we'll generate the filter normally (which will
12513 * be numeric, even though the human-readable string does
12514 * work for filtering.)
12515 *
12516 * XXX - It might be nice to use fvalue_to_string_repr() in
12517 * "proto_item_fill_label()" as well, although, there, you'd
12518 * have to deal with the base *and* with resolved values for
12519 * addresses.
12520 *
12521 * Perhaps in addition to taking the repr type (DISPLAY
12522 * or DFILTER) and the display (base), fvalue_to_string_repr()
12523 * should have the the "strings" values in the header_field_info
12524 * structure for the field as a parameter, so it can have
12525 * if the field is Boolean or an enumerated integer type,
12526 * the tables used to generate human-readable values.
12527 */
12528 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12529 const char *str = NULL((void*)0);
12530
12531 switch (hfinfo->type) {
12532
12533 case FT_INT8:
12534 case FT_INT16:
12535 case FT_INT24:
12536 case FT_INT32:
12537 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12538 break;
12539
12540 case FT_CHAR:
12541 case FT_UINT8:
12542 case FT_UINT16:
12543 case FT_UINT24:
12544 case FT_UINT32:
12545 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12546 break;
12547
12548 default:
12549 break;
12550 }
12551
12552 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12553 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12554 return true1;
12555 }
12556 }
12557
12558 switch (hfinfo->type) {
12559
12560 case FT_PROTOCOL:
12561 if (filter != NULL((void*)0))
12562 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12563 break;
12564
12565 case FT_NONE:
12566 /*
12567 * If the length is 0, just match the name of the
12568 * field.
12569 *
12570 * (Also check for negative values, just in case,
12571 * as we'll cast it to an unsigned value later.)
12572 */
12573 length = finfo->length;
12574 if (length == 0) {
12575 if (filter != NULL((void*)0))
12576 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12577 break;
12578 }
12579 if (length < 0)
12580 return false0;
12581
12582 /*
12583 * This doesn't have a value, so we'd match
12584 * on the raw bytes at this address.
12585 *
12586 * Should we be allowed to access to the raw bytes?
12587 * If "edt" is NULL, the answer is "no".
12588 */
12589 if (edt == NULL((void*)0))
12590 return false0;
12591
12592 /*
12593 * Is this field part of the raw frame tvbuff?
12594 * If not, we can't use "frame[N:M]" to match
12595 * it.
12596 *
12597 * XXX - should this be frame-relative, or
12598 * protocol-relative?
12599 *
12600 * XXX - does this fallback for non-registered
12601 * fields even make sense?
12602 */
12603 if (finfo->ds_tvb != edt->tvb)
12604 return false0; /* you lose */
12605
12606 /*
12607 * Don't go past the end of that tvbuff.
12608 */
12609 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12610 if (length > length_remaining)
12611 length = length_remaining;
12612 if (length <= 0)
12613 return false0;
12614
12615 if (filter != NULL((void*)0)) {
12616 start = finfo->start;
12617 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12618 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12619 wmem_free(NULL((void*)0), str);
12620 }
12621 break;
12622
12623 /* By default, use the fvalue's "to_string_repr" method. */
12624 default:
12625 if (filter != NULL((void*)0)) {
12626 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12627 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12628 wmem_free(NULL((void*)0), str);
12629 }
12630 break;
12631 }
12632
12633 return true1;
12634}
12635
12636/*
12637 * Returns true if we can do a "match selected" on the field, false
12638 * otherwise.
12639 */
12640bool_Bool
12641proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12642{
12643 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12644}
12645
12646/* This function attempts to construct a "match selected" display filter
12647 * string for the specified field; if it can do so, it returns a pointer
12648 * to the string, otherwise it returns NULL.
12649 *
12650 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12651 */
12652char *
12653proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12654{
12655 char *filter = NULL((void*)0);
12656
12657 if (!construct_match_selected_string(finfo, edt, &filter))
12658 {
12659 wmem_free(NULL((void*)0), filter);
12660 return NULL((void*)0);
12661 }
12662 return filter;
12663}
12664
12665/* This function is common code for all proto_tree_add_bitmask... functions.
12666 */
12667
12668static bool_Bool
12669proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12670 const int len, const int ett, int * const *fields,
12671 const int flags, bool_Bool first,
12672 bool_Bool use_parent_tree,
12673 proto_tree* tree, uint64_t value)
12674{
12675 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12676 uint64_t bitmask = 0;
12677 uint64_t tmpval;
12678 header_field_info *hf;
12679 uint32_t integer32;
12680 int bit_offset;
12681 int no_of_bits;
12682
12683 if (!*fields)
12684 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"
)
;
12685
12686 if (len < 0 || len > 8)
12687 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12688 /**
12689 * packet-frame.c uses len=0 since the value is taken from the packet
12690 * metadata, not the packet bytes. In that case, assume that all bits
12691 * in the provided value are valid.
12692 */
12693 if (len > 0) {
12694 available_bits >>= (8 - (unsigned)len)*8;
12695 }
12696
12697 if (use_parent_tree == false0)
12698 tree = proto_item_add_subtree(item, ett);
12699
12700 while (*fields) {
12701 uint64_t present_bits;
12702 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", 12702, __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", 12702
, "**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", 12702, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12703 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", 12703
, "hf->bitmask != 0", hf->abbrev))))
;
12704
12705 bitmask |= hf->bitmask;
12706
12707 /* Skip fields that aren't fully present */
12708 present_bits = available_bits & hf->bitmask;
12709 if (present_bits != hf->bitmask) {
12710 fields++;
12711 continue;
12712 }
12713
12714 switch (hf->type) {
12715 case FT_CHAR:
12716 case FT_UINT8:
12717 case FT_UINT16:
12718 case FT_UINT24:
12719 case FT_UINT32:
12720 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12721 break;
12722
12723 case FT_INT8:
12724 case FT_INT16:
12725 case FT_INT24:
12726 case FT_INT32:
12727 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12728 break;
12729
12730 case FT_UINT40:
12731 case FT_UINT48:
12732 case FT_UINT56:
12733 case FT_UINT64:
12734 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12735 break;
12736
12737 case FT_INT40:
12738 case FT_INT48:
12739 case FT_INT56:
12740 case FT_INT64:
12741 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12742 break;
12743
12744 case FT_BOOLEAN:
12745 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12746 break;
12747
12748 default:
12749 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))
12750 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))
12751 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))
12752 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))
;
12753 break;
12754 }
12755 if (flags & BMT_NO_APPEND0x01) {
12756 fields++;
12757 continue;
12758 }
12759 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12760
12761 /* XXX: README.developer and the comments have always defined
12762 * BMT_NO_INT as "only boolean flags are added to the title /
12763 * don't add non-boolean (integral) fields", but the
12764 * implementation has always added BASE_CUSTOM and fields with
12765 * value_strings, though not fields with unit_strings.
12766 * Possibly this is because some dissectors use a FT_UINT8
12767 * with a value_string for fields that should be a FT_BOOLEAN.
12768 */
12769 switch (hf->type) {
12770 case FT_CHAR:
12771 if (hf->display == BASE_CUSTOM) {
12772 char lbl[ITEM_LABEL_LENGTH240];
12773 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12774
12775 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12775, "fmtfunc"))))
;
12776 fmtfunc(lbl, (uint32_t) tmpval);
12777 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12778 hf->name, lbl);
12779 first = false0;
12780 }
12781 else if (hf->strings) {
12782 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12783 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12784 first = false0;
12785 }
12786 else if (!(flags & BMT_NO_INT0x02)) {
12787 char buf[32];
12788 const char *out;
12789
12790 if (!first) {
12791 proto_item_append_text(item, ", ");
12792 }
12793
12794 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12795 proto_item_append_text(item, "%s: %s", hf->name, out);
12796 first = false0;
12797 }
12798
12799 break;
12800
12801 case FT_UINT8:
12802 case FT_UINT16:
12803 case FT_UINT24:
12804 case FT_UINT32:
12805 if (hf->display == BASE_CUSTOM) {
12806 char lbl[ITEM_LABEL_LENGTH240];
12807 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12808
12809 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12809, "fmtfunc"))))
;
12810 fmtfunc(lbl, (uint32_t) tmpval);
12811 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12812 hf->name, lbl);
12813 first = false0;
12814 }
12815 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12816 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12817 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12818 first = false0;
12819 }
12820 else if (!(flags & BMT_NO_INT0x02)) {
12821 char buf[NUMBER_LABEL_LENGTH80];
12822 const char *out = NULL((void*)0);
12823
12824 if (!first) {
12825 proto_item_append_text(item, ", ");
12826 }
12827
12828 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12829 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12830 }
12831 if (out == NULL((void*)0)) {
12832 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12833 }
12834 proto_item_append_text(item, "%s: %s", hf->name, out);
12835 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12836 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12837 }
12838 first = false0;
12839 }
12840
12841 break;
12842
12843 case FT_INT8:
12844 case FT_INT16:
12845 case FT_INT24:
12846 case FT_INT32:
12847 integer32 = (uint32_t) tmpval;
12848 if (hf->bitmask) {
12849 no_of_bits = ws_count_ones(hf->bitmask);
12850 integer32 = ws_sign_ext32(integer32, no_of_bits);
12851 }
12852 if (hf->display == BASE_CUSTOM) {
12853 char lbl[ITEM_LABEL_LENGTH240];
12854 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12855
12856 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12856, "fmtfunc"))))
;
12857 fmtfunc(lbl, (int32_t) integer32);
12858 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12859 hf->name, lbl);
12860 first = false0;
12861 }
12862 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12863 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12864 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12865 first = false0;
12866 }
12867 else if (!(flags & BMT_NO_INT0x02)) {
12868 char buf[NUMBER_LABEL_LENGTH80];
12869 const char *out = NULL((void*)0);
12870
12871 if (!first) {
12872 proto_item_append_text(item, ", ");
12873 }
12874
12875 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12876 out = hf_try_val_to_str((int32_t) integer32, hf);
12877 }
12878 if (out == NULL((void*)0)) {
12879 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12880 }
12881 proto_item_append_text(item, "%s: %s", hf->name, out);
12882 if (hf->display & BASE_UNIT_STRING0x00001000) {
12883 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12884 }
12885 first = false0;
12886 }
12887
12888 break;
12889
12890 case FT_UINT40:
12891 case FT_UINT48:
12892 case FT_UINT56:
12893 case FT_UINT64:
12894 if (hf->display == BASE_CUSTOM) {
12895 char lbl[ITEM_LABEL_LENGTH240];
12896 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12897
12898 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12898, "fmtfunc"))))
;
12899 fmtfunc(lbl, tmpval);
12900 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12901 hf->name, lbl);
12902 first = false0;
12903 }
12904 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12905 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12906 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12907 first = false0;
12908 }
12909 else if (!(flags & BMT_NO_INT0x02)) {
12910 char buf[NUMBER_LABEL_LENGTH80];
12911 const char *out = NULL((void*)0);
12912
12913 if (!first) {
12914 proto_item_append_text(item, ", ");
12915 }
12916
12917 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12918 out = hf_try_val64_to_str(tmpval, hf);
12919 }
12920 if (out == NULL((void*)0)) {
12921 out = hfinfo_number_value_format64(hf, buf, tmpval);
12922 }
12923 proto_item_append_text(item, "%s: %s", hf->name, out);
12924 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12925 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12926 }
12927 first = false0;
12928 }
12929
12930 break;
12931
12932 case FT_INT40:
12933 case FT_INT48:
12934 case FT_INT56:
12935 case FT_INT64:
12936 if (hf->bitmask) {
12937 no_of_bits = ws_count_ones(hf->bitmask);
12938 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12939 }
12940 if (hf->display == BASE_CUSTOM) {
12941 char lbl[ITEM_LABEL_LENGTH240];
12942 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12943
12944 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12944, "fmtfunc"))))
;
12945 fmtfunc(lbl, (int64_t) tmpval);
12946 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12947 hf->name, lbl);
12948 first = false0;
12949 }
12950 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12951 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12952 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12953 first = false0;
12954 }
12955 else if (!(flags & BMT_NO_INT0x02)) {
12956 char buf[NUMBER_LABEL_LENGTH80];
12957 const char *out = NULL((void*)0);
12958
12959 if (!first) {
12960 proto_item_append_text(item, ", ");
12961 }
12962
12963 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12964 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12965 }
12966 if (out == NULL((void*)0)) {
12967 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12968 }
12969 proto_item_append_text(item, "%s: %s", hf->name, out);
12970 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12971 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12972 }
12973 first = false0;
12974 }
12975
12976 break;
12977
12978 case FT_BOOLEAN:
12979 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12980 /* If we have true/false strings, emit full - otherwise messages
12981 might look weird */
12982 const struct true_false_string *tfs =
12983 (const struct true_false_string *)hf->strings;
12984
12985 if (tmpval) {
12986 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12987 hf->name, tfs->true_string);
12988 first = false0;
12989 } else if (!(flags & BMT_NO_FALSE0x04)) {
12990 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12991 hf->name, tfs->false_string);
12992 first = false0;
12993 }
12994 } else if (hf->bitmask & value) {
12995 /* If the flag is set, show the name */
12996 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
12997 first = false0;
12998 }
12999 break;
13000 default:
13001 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))
13002 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))
13003 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))
13004 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))
;
13005 break;
13006 }
13007
13008 fields++;
13009 }
13010
13011 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13012 * but then again most dissectors don't set the bitmask field for
13013 * the higher level bitmask hfi, so calculate the bitmask from the
13014 * fields present. */
13015 if (item) {
13016 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13017 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13018 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)
;
13019 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)
;
13020 }
13021 return first;
13022}
13023
13024/* This function will dissect a sequence of bytes that describe a
13025 * bitmask and supply the value of that sequence through a pointer.
13026 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13027 * to be dissected.
13028 * This field will form an expansion under which the individual fields of the
13029 * bitmask is dissected and displayed.
13030 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13031 *
13032 * fields is an array of pointers to int that lists all the fields of the
13033 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13034 * or another integer of the same type/size as hf_hdr with a mask specified.
13035 * This array is terminated by a NULL entry.
13036 *
13037 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13038 * FT_integer fields that have a value_string attached will have the
13039 * matched string displayed on the expansion line.
13040 */
13041proto_item *
13042proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13043 const unsigned offset, const int hf_hdr,
13044 const int ett, int * const *fields,
13045 const unsigned encoding, uint64_t *retval)
13046{
13047 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);
13048}
13049
13050/* This function will dissect a sequence of bytes that describe a
13051 * bitmask.
13052 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13053 * to be dissected.
13054 * This field will form an expansion under which the individual fields of the
13055 * bitmask is dissected and displayed.
13056 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13057 *
13058 * fields is an array of pointers to int that lists all the fields of the
13059 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13060 * or another integer of the same type/size as hf_hdr with a mask specified.
13061 * This array is terminated by a NULL entry.
13062 *
13063 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13064 * FT_integer fields that have a value_string attached will have the
13065 * matched string displayed on the expansion line.
13066 */
13067proto_item *
13068proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13069 const unsigned offset, const int hf_hdr,
13070 const int ett, int * const *fields,
13071 const unsigned encoding)
13072{
13073 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13074}
13075
13076/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13077 * what data is appended to the header.
13078 */
13079proto_item *
13080proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13081 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13082 uint64_t *retval)
13083{
13084 proto_item *item = NULL((void*)0);
13085 header_field_info *hf;
13086 int len;
13087 uint64_t value;
13088
13089 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", 13089, __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", 13089
, "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", 13089, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13090 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", 13090, (hf)->abbrev)))
;
13091 len = ftype_wire_size(hf->type);
13092 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13093
13094 if (parent_tree) {
13095 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13096 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13097 flags, false0, false0, NULL((void*)0), value);
13098 }
13099
13100 *retval = value;
13101 if (hf->bitmask) {
13102 /* Mask out irrelevant portions */
13103 *retval &= hf->bitmask;
13104 /* Shift bits */
13105 *retval >>= hfinfo_bitshift(hf);
13106 }
13107
13108 return item;
13109}
13110
13111/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13112 * what data is appended to the header.
13113 */
13114proto_item *
13115proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13116 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13117{
13118 proto_item *item = NULL((void*)0);
13119 header_field_info *hf;
13120 int len;
13121 uint64_t value;
13122
13123 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", 13123, __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", 13123
, "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", 13123, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13124 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", 13124, (hf)->abbrev)))
;
13125
13126 if (parent_tree) {
13127 len = ftype_wire_size(hf->type);
13128 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13129 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13130 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13131 flags, false0, false0, NULL((void*)0), value);
13132 }
13133
13134 return item;
13135}
13136
13137/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13138 can't be retrieved directly from tvb) */
13139proto_item *
13140proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13141 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13142{
13143 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13144 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13145}
13146
13147/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13148WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13149proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13150 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13151{
13152 proto_item *item = NULL((void*)0);
13153 header_field_info *hf;
13154 int len;
13155
13156 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", 13156, __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", 13156
, "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", 13156, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13157 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", 13157, (hf)->abbrev)))
;
13158 /* the proto_tree_add_uint/_uint64() calls below
13159 will fail if tvb==NULL and len!=0 */
13160 len = tvb ? ftype_wire_size(hf->type) : 0;
13161
13162 if (parent_tree) {
13163 if (len <= 4)
13164 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13165 else
13166 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13167
13168 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13169 flags, false0, false0, NULL((void*)0), value);
13170 }
13171
13172 return item;
13173}
13174
13175/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13176void
13177proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13178 const int len, int * const *fields, const unsigned encoding)
13179{
13180 uint64_t value;
13181
13182 if (tree) {
13183 value = get_uint64_value(tree, tvb, offset, len, encoding);
13184 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13185 BMT_NO_APPEND0x01, false0, true1, tree, value);
13186 }
13187}
13188
13189WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13190proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13191 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13192{
13193 uint64_t value;
13194
13195 value = get_uint64_value(tree, tvb, offset, len, encoding);
13196 if (tree) {
13197 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13198 BMT_NO_APPEND0x01, false0, true1, tree, value);
13199 }
13200 if (retval) {
13201 *retval = value;
13202 }
13203}
13204
13205WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13206proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13207 const int len, int * const *fields, const uint64_t value)
13208{
13209 if (tree) {
13210 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13211 BMT_NO_APPEND0x01, false0, true1, tree, value);
13212 }
13213}
13214
13215
13216/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13217 * This is intended to support bitmask fields whose lengths can vary, perhaps
13218 * as the underlying standard evolves over time.
13219 * With this API there is the possibility of being called to display more or
13220 * less data than the dissector was coded to support.
13221 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13222 * Thus when presented with "too much" or "too little" data, MSbits will be
13223 * ignored or MSfields sacrificed.
13224 *
13225 * Only fields for which all defined bits are available are displayed.
13226 */
13227proto_item *
13228proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13229 const unsigned offset, const unsigned len, const int hf_hdr,
13230 const int ett, int * const *fields, struct expert_field* exp,
13231 const unsigned encoding)
13232{
13233 proto_item *item = NULL((void*)0);
13234 header_field_info *hf;
13235 unsigned decodable_len;
13236 unsigned decodable_offset;
13237 uint32_t decodable_value;
13238 uint64_t value;
13239
13240 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", 13240, __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", 13240
, "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", 13240, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13241 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", 13241, (hf)->abbrev)))
;
13242
13243 decodable_offset = offset;
13244 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13245
13246 /* If we are ftype_wire_size-limited,
13247 * make sure we decode as many LSBs as possible.
13248 */
13249 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13250 decodable_offset += (len - decodable_len);
13251 }
13252
13253 if (parent_tree) {
13254 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13255 decodable_len, encoding);
13256
13257 /* The root item covers all the bytes even if we can't decode them all */
13258 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13259 decodable_value);
13260 }
13261
13262 if (decodable_len < len) {
13263 /* Dissector likely requires updating for new protocol revision */
13264 expert_add_info_format(NULL((void*)0), item, exp,
13265 "Only least-significant %d of %d bytes decoded",
13266 decodable_len, len);
13267 }
13268
13269 if (item) {
13270 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13271 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13272 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13273 }
13274
13275 return item;
13276}
13277
13278/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13279proto_item *
13280proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13281 const unsigned offset, const unsigned len,
13282 const char *name, const char *fallback,
13283 const int ett, int * const *fields,
13284 const unsigned encoding, const int flags)
13285{
13286 proto_item *item = NULL((void*)0);
13287 uint64_t value;
13288
13289 if (parent_tree) {
13290 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13291 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13292 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13293 flags, true1, false0, NULL((void*)0), value) && fallback) {
13294 /* Still at first item - append 'fallback' text if any */
13295 proto_item_append_text(item, "%s", fallback);
13296 }
13297 }
13298
13299 return item;
13300}
13301
13302proto_item *
13303proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13304 const unsigned bit_offset, const int no_of_bits,
13305 const unsigned encoding)
13306{
13307 header_field_info *hfinfo;
13308 int octet_length;
13309 int octet_offset;
13310
13311 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", 13311, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13311
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13311, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13312
13313 if (no_of_bits < 0) {
13314 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13315 }
13316 octet_length = (no_of_bits + 7) >> 3;
13317 octet_offset = bit_offset >> 3;
13318 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13319
13320 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13321 * but only after doing a bunch more work (which we can, in the common
13322 * case, shortcut here).
13323 */
13324 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13325 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", 13325
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13325, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13325, "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", 13325, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13326
13327 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13328}
13329
13330/*
13331 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13332 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13333 * Offset should be given in bits from the start of the tvb.
13334 */
13335
13336static proto_item *
13337_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13338 const unsigned bit_offset, const int no_of_bits,
13339 uint64_t *return_value, const unsigned encoding)
13340{
13341 int offset;
13342 unsigned length;
13343 uint8_t tot_no_bits;
13344 char *bf_str;
13345 char lbl_str[ITEM_LABEL_LENGTH240];
13346 uint64_t value = 0;
13347 uint8_t *bytes = NULL((void*)0);
13348 size_t bytes_length = 0;
13349
13350 proto_item *pi;
13351 header_field_info *hf_field;
13352
13353 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13354 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", 13354, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13354
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13354, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13355
13356 if (hf_field->bitmask != 0) {
13357 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)
13358 " 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)
13359 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)
;
13360 }
13361
13362 if (no_of_bits < 0) {
13363 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13364 } else if (no_of_bits == 0) {
13365 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)
13366 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)
;
13367 }
13368
13369 /* Byte align offset */
13370 offset = bit_offset>>3;
13371
13372 /*
13373 * Calculate the number of octets used to hold the bits
13374 */
13375 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13376 length = (tot_no_bits + 7) >> 3;
13377
13378 if (no_of_bits < 65) {
13379 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13380 } else if (hf_field->type != FT_BYTES) {
13381 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)
13382 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)
;
13383 return NULL((void*)0);
13384 }
13385
13386 /* Sign extend for signed types */
13387 switch (hf_field->type) {
13388 case FT_INT8:
13389 case FT_INT16:
13390 case FT_INT24:
13391 case FT_INT32:
13392 case FT_INT40:
13393 case FT_INT48:
13394 case FT_INT56:
13395 case FT_INT64:
13396 value = ws_sign_ext64(value, no_of_bits);
13397 break;
13398
13399 default:
13400 break;
13401 }
13402
13403 if (return_value) {
13404 *return_value = value;
13405 }
13406
13407 /* Coast clear. Try and fake it */
13408 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13409 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", 13409
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13409, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13409, "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", 13409, __func__, "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); } } }
;
13410
13411 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13412
13413 switch (hf_field->type) {
13414 case FT_BOOLEAN:
13415 /* Boolean field */
13416 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13417 "%s = %s: %s",
13418 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13419 break;
13420
13421 case FT_CHAR:
13422 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13423 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13424 break;
13425
13426 case FT_UINT8:
13427 case FT_UINT16:
13428 case FT_UINT24:
13429 case FT_UINT32:
13430 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13431 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13432 break;
13433
13434 case FT_INT8:
13435 case FT_INT16:
13436 case FT_INT24:
13437 case FT_INT32:
13438 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13439 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13440 break;
13441
13442 case FT_UINT40:
13443 case FT_UINT48:
13444 case FT_UINT56:
13445 case FT_UINT64:
13446 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13447 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13448 break;
13449
13450 case FT_INT40:
13451 case FT_INT48:
13452 case FT_INT56:
13453 case FT_INT64:
13454 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13455 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13456 break;
13457
13458 case FT_BYTES:
13459 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13460 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13461 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13462 proto_item_set_text(pi, "%s", lbl_str);
13463 return pi;
13464
13465 /* TODO: should handle FT_UINT_BYTES ? */
13466
13467 default:
13468 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))
13469 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))
13470 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))
13471 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))
;
13472 return NULL((void*)0);
13473 }
13474
13475 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13476 return pi;
13477}
13478
13479proto_item *
13480proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13481 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13482 uint64_t *return_value)
13483{
13484 proto_item *pi;
13485 int no_of_bits;
13486 int octet_offset;
13487 unsigned mask_initial_bit_offset;
13488 unsigned mask_greatest_bit_offset;
13489 unsigned octet_length;
13490 uint8_t i;
13491 char bf_str[256];
13492 char lbl_str[ITEM_LABEL_LENGTH240];
13493 uint64_t value;
13494 uint64_t composite_bitmask;
13495 uint64_t composite_bitmap;
13496
13497 header_field_info *hf_field;
13498
13499 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13500 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", 13500, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13500
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13500, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13501
13502 if (hf_field->bitmask != 0) {
13503 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)
13504 " 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)
13505 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)
;
13506 }
13507
13508 mask_initial_bit_offset = bit_offset % 8;
13509
13510 no_of_bits = 0;
13511 value = 0;
13512 i = 0;
13513 mask_greatest_bit_offset = 0;
13514 composite_bitmask = 0;
13515 composite_bitmap = 0;
13516
13517 while (crumb_spec[i].crumb_bit_length != 0) {
13518 uint64_t crumb_mask, crumb_value;
13519 uint8_t crumb_end_bit_offset;
13520
13521 crumb_value = tvb_get_bits64(tvb,
13522 bit_offset + crumb_spec[i].crumb_bit_offset,
13523 crumb_spec[i].crumb_bit_length,
13524 ENC_BIG_ENDIAN0x00000000);
13525 value += crumb_value;
13526 no_of_bits += crumb_spec[i].crumb_bit_length;
13527 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", 13527
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
13528
13529 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13530 octet containing the initial offset.
13531 If the mask is beyond 32 bits, then give up on bit map display.
13532 This could be improved in future, probably showing a table
13533 of 32 or 64 bits per row */
13534 if (mask_greatest_bit_offset < 32) {
13535 crumb_end_bit_offset = mask_initial_bit_offset
13536 + crumb_spec[i].crumb_bit_offset
13537 + crumb_spec[i].crumb_bit_length;
13538 crumb_mask = (UINT64_C(1)1UL << crumb_spec[i].crumb_bit_length) - 1;
13539
13540 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
13541 mask_greatest_bit_offset = crumb_end_bit_offset;
13542 }
13543 /* Currently the bitmap of the crumbs are only shown if
13544 * smaller than 32 bits. Do not bother calculating the
13545 * mask if it is larger than that. */
13546 if (crumb_end_bit_offset <= 32) {
13547 composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
13548 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13549 }
13550 }
13551 /* Shift left for the next segment */
13552 value <<= crumb_spec[++i].crumb_bit_length;
13553 }
13554
13555 /* Sign extend for signed types */
13556 switch (hf_field->type) {
13557 case FT_INT8:
13558 case FT_INT16:
13559 case FT_INT24:
13560 case FT_INT32:
13561 case FT_INT40:
13562 case FT_INT48:
13563 case FT_INT56:
13564 case FT_INT64:
13565 value = ws_sign_ext64(value, no_of_bits);
13566 break;
13567 default:
13568 break;
13569 }
13570
13571 if (return_value) {
13572 *return_value = value;
13573 }
13574
13575 /* Coast clear. Try and fake it */
13576 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13577 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", 13577
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13577, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13577, "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", 13577, __func__, "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); } } }
;
13578
13579 /* initialise the format string */
13580 bf_str[0] = '\0';
13581
13582 octet_offset = bit_offset >> 3;
13583
13584 /* Round up mask length to nearest octet */
13585 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13586 mask_greatest_bit_offset = octet_length << 3;
13587
13588 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13589 It would be a useful enhancement to eliminate this restriction. */
13590 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13591 other_decode_bitfield_value(bf_str,
13592 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13593 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13594 mask_greatest_bit_offset);
13595 } else {
13596 /* If the bitmask is too large, try to describe its contents. */
13597 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13598 }
13599
13600 switch (hf_field->type) {
13601 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13602 /* Boolean field */
13603 return proto_tree_add_boolean_format(tree, hfindex,
13604 tvb, octet_offset, octet_length, value,
13605 "%s = %s: %s",
13606 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13607 break;
13608
13609 case FT_CHAR:
13610 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13611 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13612 break;
13613
13614 case FT_UINT8:
13615 case FT_UINT16:
13616 case FT_UINT24:
13617 case FT_UINT32:
13618 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13619 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13620 break;
13621
13622 case FT_INT8:
13623 case FT_INT16:
13624 case FT_INT24:
13625 case FT_INT32:
13626 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13627 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13628 break;
13629
13630 case FT_UINT40:
13631 case FT_UINT48:
13632 case FT_UINT56:
13633 case FT_UINT64:
13634 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13635 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13636 break;
13637
13638 case FT_INT40:
13639 case FT_INT48:
13640 case FT_INT56:
13641 case FT_INT64:
13642 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13643 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13644 break;
13645
13646 default:
13647 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))
13648 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))
13649 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))
13650 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))
;
13651 return NULL((void*)0);
13652 }
13653 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13654 return pi;
13655}
13656
13657void
13658proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13659 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13660{
13661 header_field_info *hfinfo;
13662 int start = bit_offset >> 3;
13663 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13664
13665 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13666 * so that we can use the tree's memory scope in calculating the string */
13667 if (length == -1) {
13668 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13669 } else {
13670 tvb_ensure_bytes_exist(tvb, start, length);
13671 }
13672 if (!tree) return;
13673
13674 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", 13674, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13674
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13674, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13675 proto_tree_add_text_internal(tree, tvb, start, length,
13676 "%s crumb %d of %s (decoded above)",
13677 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13678 tvb_get_bits32(tvb,
13679 bit_offset,
13680 crumb_spec[crumb_index].crumb_bit_length,
13681 ENC_BIG_ENDIAN0x00000000),
13682 ENC_BIG_ENDIAN0x00000000),
13683 crumb_index,
13684 hfinfo->name);
13685}
13686
13687proto_item *
13688proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13689 const unsigned bit_offset, const int no_of_bits,
13690 uint64_t *return_value, const unsigned encoding)
13691{
13692 proto_item *item;
13693
13694 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13695 bit_offset, no_of_bits,
13696 return_value, encoding))) {
13697 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset&0x7))do { if (((item)->finfo)) (((item)->finfo))->flags =
(((item)->finfo))->flags | ((((bit_offset&0x7) &
63) << 5)); } while(0)
;
13698 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)
;
13699 }
13700 return item;
13701}
13702
13703static proto_item *
13704_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13705 tvbuff_t *tvb, const unsigned bit_offset,
13706 const int no_of_bits, void *value_ptr,
13707 const unsigned encoding, char *value_str)
13708{
13709 int offset;
13710 unsigned length;
13711 uint8_t tot_no_bits;
13712 char *str;
13713 uint64_t value = 0;
13714 header_field_info *hf_field;
13715
13716 /* We do not have to return a value, try to fake it as soon as possible */
13717 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13718 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", 13718
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13718, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13718, "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", 13718, __func__, "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); } } }
;
13719
13720 if (hf_field->bitmask != 0) {
13721 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)
13722 " 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)
13723 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)
;
13724 }
13725
13726 if (no_of_bits < 0) {
13727 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13728 } else if (no_of_bits == 0) {
13729 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)
13730 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)
;
13731 }
13732
13733 /* Byte align offset */
13734 offset = bit_offset>>3;
13735
13736 /*
13737 * Calculate the number of octets used to hold the bits
13738 */
13739 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13740 length = tot_no_bits>>3;
13741 /* If we are using part of the next octet, increase length by 1 */
13742 if (tot_no_bits & 0x07)
13743 length++;
13744
13745 if (no_of_bits < 65) {
13746 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13747 } else {
13748 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)
13749 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)
;
13750 return NULL((void*)0);
13751 }
13752
13753 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13754
13755 (void) g_strlcat(str, " = ", 256+64);
13756 (void) g_strlcat(str, hf_field->name, 256+64);
13757
13758 /*
13759 * This function does not receive an actual value but a dimensionless pointer to that value.
13760 * For this reason, the type of the header field is examined in order to determine
13761 * what kind of value we should read from this address.
13762 * The caller of this function must make sure that for the specific header field type the address of
13763 * a compatible value is provided.
13764 */
13765 switch (hf_field->type) {
13766 case FT_BOOLEAN:
13767 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13768 "%s: %s", str, value_str);
13769 break;
13770
13771 case FT_CHAR:
13772 case FT_UINT8:
13773 case FT_UINT16:
13774 case FT_UINT24:
13775 case FT_UINT32:
13776 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13777 "%s: %s", str, value_str);
13778 break;
13779
13780 case FT_UINT40:
13781 case FT_UINT48:
13782 case FT_UINT56:
13783 case FT_UINT64:
13784 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13785 "%s: %s", str, value_str);
13786 break;
13787
13788 case FT_INT8:
13789 case FT_INT16:
13790 case FT_INT24:
13791 case FT_INT32:
13792 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13793 "%s: %s", str, value_str);
13794 break;
13795
13796 case FT_INT40:
13797 case FT_INT48:
13798 case FT_INT56:
13799 case FT_INT64:
13800 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13801 "%s: %s", str, value_str);
13802 break;
13803
13804 case FT_FLOAT:
13805 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13806 "%s: %s", str, value_str);
13807 break;
13808
13809 default:
13810 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))
13811 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))
13812 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))
13813 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))
;
13814 return NULL((void*)0);
13815 }
13816}
13817
13818static proto_item *
13819proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13820 tvbuff_t *tvb, const unsigned bit_offset,
13821 const int no_of_bits, void *value_ptr,
13822 const unsigned encoding, char *value_str)
13823{
13824 proto_item *item;
13825
13826 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13827 tvb, bit_offset, no_of_bits,
13828 value_ptr, encoding, value_str))) {
13829 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset&0x7))do { if (((item)->finfo)) (((item)->finfo))->flags =
(((item)->finfo))->flags | ((((bit_offset&0x7) &
63) << 5)); } while(0)
;
13830 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)
;
13831 }
13832 return item;
13833}
13834
13835#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);
\
13836 va_start(ap, format)__builtin_va_start(ap, format); \
13837 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13838 va_end(ap)__builtin_va_end(ap);
13839
13840proto_item *
13841proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13842 tvbuff_t *tvb, const unsigned bit_offset,
13843 const int no_of_bits, uint32_t value,
13844 const unsigned encoding,
13845 const char *format, ...)
13846{
13847 va_list ap;
13848 char *dst;
13849 header_field_info *hf_field;
13850
13851 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13852
13853 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13853
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13853, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13853, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13853, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13854
13855 switch (hf_field->type) {
13856 case FT_UINT8:
13857 case FT_UINT16:
13858 case FT_UINT24:
13859 case FT_UINT32:
13860 break;
13861
13862 default:
13863 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)
13864 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)
;
13865 return NULL((void*)0);
13866 }
13867
13868 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);
;
13869
13870 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13871}
13872
13873proto_item *
13874proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13875 tvbuff_t *tvb, const unsigned bit_offset,
13876 const int no_of_bits, uint64_t value,
13877 const unsigned encoding,
13878 const char *format, ...)
13879{
13880 va_list ap;
13881 char *dst;
13882 header_field_info *hf_field;
13883
13884 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13885
13886 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", 13886
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13886, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13886, "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", 13886, __func__, "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); } } }
;
13887
13888 switch (hf_field->type) {
13889 case FT_UINT40:
13890 case FT_UINT48:
13891 case FT_UINT56:
13892 case FT_UINT64:
13893 break;
13894
13895 default:
13896 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)
13897 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)
;
13898 return NULL((void*)0);
13899 }
13900
13901 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);
;
13902
13903 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13904}
13905
13906proto_item *
13907proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13908 tvbuff_t *tvb, const unsigned bit_offset,
13909 const int no_of_bits, float value,
13910 const unsigned encoding,
13911 const char *format, ...)
13912{
13913 va_list ap;
13914 char *dst;
13915 header_field_info *hf_field;
13916
13917 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13918
13919 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", 13919
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13919, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13919, "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", 13919, __func__, "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); } } }
;
13920
13921 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",
13921, ((hf_field))->abbrev))))
;
13922
13923 CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
;
13924
13925 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13926}
13927
13928proto_item *
13929proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13930 tvbuff_t *tvb, const unsigned bit_offset,
13931 const int no_of_bits, int32_t value,
13932 const unsigned encoding,
13933 const char *format, ...)
13934{
13935 va_list ap;
13936 char *dst;
13937 header_field_info *hf_field;
13938
13939 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13940
13941 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13941
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13941, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13941, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13941, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13942
13943 switch (hf_field->type) {
13944 case FT_INT8:
13945 case FT_INT16:
13946 case FT_INT24:
13947 case FT_INT32:
13948 break;
13949
13950 default:
13951 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)
13952 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)
;
13953 return NULL((void*)0);
13954 }
13955
13956 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);
;
13957
13958 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13959}
13960
13961proto_item *
13962proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13963 tvbuff_t *tvb, const unsigned bit_offset,
13964 const int no_of_bits, int64_t value,
13965 const unsigned encoding,
13966 const char *format, ...)
13967{
13968 va_list ap;
13969 char *dst;
13970 header_field_info *hf_field;
13971
13972 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13973
13974 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", 13974
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13974, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13974, "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", 13974, __func__, "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); } } }
;
13975
13976 switch (hf_field->type) {
13977 case FT_INT40:
13978 case FT_INT48:
13979 case FT_INT56:
13980 case FT_INT64:
13981 break;
13982
13983 default:
13984 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)
13985 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)
;
13986 return NULL((void*)0);
13987 }
13988
13989 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);
;
13990
13991 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13992}
13993
13994proto_item *
13995proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
13996 tvbuff_t *tvb, const unsigned bit_offset,
13997 const int no_of_bits, uint64_t value,
13998 const unsigned encoding,
13999 const char *format, ...)
14000{
14001 va_list ap;
14002 char *dst;
14003 header_field_info *hf_field;
14004
14005 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14006
14007 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", 14007
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14007, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14007, "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", 14007, __func__, "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); } } }
;
14008
14009 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"
, 14009, ((hf_field))->abbrev))))
;
14010
14011 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);
;
14012
14013 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14014}
14015
14016proto_item *
14017proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14018 const unsigned bit_offset, const int no_of_chars)
14019{
14020 proto_item *pi;
14021 header_field_info *hfinfo;
14022 int byte_length;
14023 int byte_offset;
14024 char *string;
14025
14026 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14027
14028 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", 14028
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14028, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14028, "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", 14028, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14029
14030 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"
, 14030, ((hfinfo))->abbrev))))
;
14031
14032 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14033 byte_offset = bit_offset >> 3;
14034
14035 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14036
14037 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14038 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14038, "byte_length >= 0"
))))
;
14039 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14040
14041 return pi;
14042}
14043
14044proto_item *
14045proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14046 const unsigned bit_offset, const int no_of_chars)
14047{
14048 proto_item *pi;
14049 header_field_info *hfinfo;
14050 int byte_length;
14051 int byte_offset;
14052 char *string;
14053
14054 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14055
14056 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", 14056
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14056, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14056, "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", 14056, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14057
14058 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"
, 14058, ((hfinfo))->abbrev))))
;
14059
14060 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14061 byte_offset = bit_offset >> 3;
14062
14063 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14064
14065 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14066 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14066, "byte_length >= 0"
))))
;
14067 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14068
14069 return pi;
14070}
14071
14072const value_string proto_checksum_vals[] = {
14073 { PROTO_CHECKSUM_E_BAD, "Bad" },
14074 { PROTO_CHECKSUM_E_GOOD, "Good" },
14075 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14076 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14077 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14078
14079 { 0, NULL((void*)0) }
14080};
14081
14082proto_item *
14083proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14084 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14085 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14086{
14087 header_field_info *hfinfo;
14088 uint32_t checksum;
14089 uint32_t len;
14090 proto_item* ti = NULL((void*)0);
14091 proto_item* ti2;
14092 bool_Bool incorrect_checksum = true1;
14093
14094 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", 14094, __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", 14094
, "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", 14094, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14095
14096 switch (hfinfo->type) {
14097 case FT_UINT8:
14098 len = 1;
14099 break;
14100 case FT_UINT16:
14101 len = 2;
14102 break;
14103 case FT_UINT24:
14104 len = 3;
14105 break;
14106 case FT_UINT32:
14107 len = 4;
14108 break;
14109 default:
14110 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)
14111 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14112 }
14113
14114 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14115 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14116 proto_item_set_generated(ti);
14117 if (hf_checksum_status != -1) {
14118 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14119 proto_item_set_generated(ti2);
14120 }
14121 return ti;
14122 }
14123
14124 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14125 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14126 proto_item_set_generated(ti);
14127 } else {
14128 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14129 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14130 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14131 if (computed_checksum == 0) {
14132 proto_item_append_text(ti, " [correct]");
14133 if (hf_checksum_status != -1) {
14134 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14135 proto_item_set_generated(ti2);
14136 }
14137 incorrect_checksum = false0;
14138 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14139 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14140 /* XXX - This can't distinguish between "shouldbe"
14141 * 0x0000 and 0xFFFF unless we know whether there
14142 * were any nonzero bits (other than the checksum).
14143 * Protocols should not use this path if they might
14144 * have an all zero packet.
14145 * Some implementations put the wrong zero; maybe
14146 * we should have a special expert info for that?
14147 */
14148 }
14149 } else {
14150 if (checksum == computed_checksum) {
14151 proto_item_append_text(ti, " [correct]");
14152 if (hf_checksum_status != -1) {
14153 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14154 proto_item_set_generated(ti2);
14155 }
14156 incorrect_checksum = false0;
14157 }
14158 }
14159
14160 if (incorrect_checksum) {
14161 if (hf_checksum_status != -1) {
14162 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14163 proto_item_set_generated(ti2);
14164 }
14165 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14166 proto_item_append_text(ti, " [incorrect]");
14167 if (bad_checksum_expert != NULL((void*)0))
14168 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14169 } else {
14170 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14171 if (bad_checksum_expert != NULL((void*)0))
14172 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);
14173 }
14174 }
14175 } else {
14176 if (hf_checksum_status != -1) {
14177 proto_item_append_text(ti, " [unverified]");
14178 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14179 proto_item_set_generated(ti2);
14180 }
14181 }
14182 }
14183
14184 return ti;
14185}
14186
14187proto_item *
14188proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14189 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14190 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14191{
14192 header_field_info *hfinfo;
14193 uint8_t *checksum = NULL((void*)0);
14194 proto_item* ti = NULL((void*)0);
14195 proto_item* ti2;
14196 bool_Bool incorrect_checksum = true1;
14197
14198 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", 14198, __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", 14198
, "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", 14198, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14199
14200 if (hfinfo->type != FT_BYTES) {
14201 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)
14202 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
14203 }
14204
14205 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14206 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14207 proto_item_set_generated(ti);
14208 if (hf_checksum_status != -1) {
14209 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14210 proto_item_set_generated(ti2);
14211 }
14212 return ti;
14213 }
14214
14215 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14216 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14217 proto_item_set_generated(ti);
14218 } else {
14219 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
))))))
;
14220 tvb_memcpy(tvb, checksum, offset, checksum_len);
14221 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14222 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14223 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14224 if (computed_checksum == 0) {
14225 proto_item_append_text(ti, " [correct]");
14226 if (hf_checksum_status != -1) {
14227 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14228 proto_item_set_generated(ti2);
14229 }
14230 incorrect_checksum = false0;
14231 }
14232 } else {
14233 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14234 proto_item_append_text(ti, " [correct]");
14235 if (hf_checksum_status != -1) {
14236 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14237 proto_item_set_generated(ti2);
14238 }
14239 incorrect_checksum = false0;
14240 }
14241 }
14242
14243 if (incorrect_checksum) {
14244 if (hf_checksum_status != -1) {
14245 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14246 proto_item_set_generated(ti2);
14247 }
14248 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14249 proto_item_append_text(ti, " [incorrect]");
14250 if (bad_checksum_expert != NULL((void*)0))
14251 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14252 } else {
14253 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14254 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))))))
;
14255 for (size_t counter = 0; counter < checksum_len; ++counter) {
14256 snprintf(
14257 /* On ecah iteration inserts two characters */
14258 (char*)&computed_checksum_str[counter << 1],
14259 computed_checksum_str_len - (counter << 1),
14260 "%02x",
14261 computed_checksum[counter]);
14262 }
14263 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14264 if (bad_checksum_expert != NULL((void*)0))
14265 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14266 }
14267 }
14268 } else {
14269 if (hf_checksum_status != -1) {
14270 proto_item_append_text(ti, " [unverified]");
14271 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14272 proto_item_set_generated(ti2);
14273 }
14274 }
14275 }
14276
14277 return ti;
14278}
14279
14280unsigned char
14281proto_check_field_name(const char *field_name)
14282{
14283 return module_check_valid_name(field_name, false0);
14284}
14285
14286unsigned char
14287proto_check_field_name_lower(const char *field_name)
14288{
14289 return module_check_valid_name(field_name, true1);
14290}
14291
14292bool_Bool
14293tree_expanded(int tree_type)
14294{
14295 if (tree_type <= 0) {
14296 return false0;
14297 }
14298 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", 14298, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14299 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14300}
14301
14302void
14303tree_expanded_set(int tree_type, bool_Bool value)
14304{
14305 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", 14305, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14306
14307 if (value)
14308 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14309 else
14310 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14311}
14312
14313/*
14314 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14315 *
14316 * Local variables:
14317 * c-basic-offset: 8
14318 * tab-width: 8
14319 * indent-tabs-mode: t
14320 * End:
14321 *
14322 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14323 * :indentSize=8:tabSize=8:noTabs=false:
14324 */