Bug Summary

File:epan/proto.c
Warning:line 13567, column 39
The result of left shift is undefined because the right operand '64' is not smaller than 64, the capacity of 'uint64_t'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name proto.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-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/2026-01-14-100352-3603-1 -x c /builds/wireshark/wireshark/epan/proto.c
1/* proto.c
2 * Routines for protocol tree
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include "config.h"
12#define WS_LOG_DOMAIN"Epan" LOG_DOMAIN_EPAN"Epan"
13#include "wireshark.h"
14
15#include <float.h>
16#include <errno(*__errno_location ()).h>
17
18#include <epan/tfs.h>
19#include <epan/unit_strings.h>
20
21#include <wsutil/array.h>
22#include <wsutil/bits_ctz.h>
23#include <wsutil/bits_count_ones.h>
24#include <wsutil/sign_ext.h>
25#include <wsutil/utf8_entities.h>
26#include <wsutil/json_dumper.h>
27#include <wsutil/pint.h>
28#include <wsutil/unicode-utils.h>
29#include <wsutil/dtoa.h>
30#include <wsutil/filesystem.h>
31#ifdef HAVE_UNISTD_H1
32#include <unistd.h>
33#endif
34
35#include <ftypes/ftypes.h>
36#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 * const 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* const * 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
1852 /* XXX - Ideally, every "null-terminated string which fits into a
1853 * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1854 * as appropriate, not a FT_STRINGZ. If so, then we could always call
1855 * tvb_get_stringz_enc here. Failing that, we could treat length 0
1856 * as unknown length as well (since there is a trailing '\0', the real
1857 * length is never zero), allowing switching to unsigned lengths.
1858 */
1859 if (length == -1) {
1860 /* This can throw an exception */
1861 value = tvb_get_stringz_enc(scope, tvb, start, (unsigned*)&length, encoding);
1862 } else {
1863 /* In this case, length signifies the length of the string.
1864 *
1865 * This could either be a null-padded string, which doesn't
1866 * necessarily have a '\0' at the end, or a null-terminated
1867 * string, with a trailing '\0'. (Yes, there are cases
1868 * where you have a string that's both counted and null-
1869 * terminated.)
1870 *
1871 * In the first case, we must allocate a buffer of length
1872 * "length+1", to make room for a trailing '\0'.
1873 *
1874 * In the second case, we don't assume that there is a
1875 * trailing '\0' there, as the packet might be malformed.
1876 * (XXX - should we throw an exception if there's no
1877 * trailing '\0'?) Therefore, we allocate a buffer of
1878 * length "length+1", and put in a trailing '\0', just to
1879 * be safe.
1880 *
1881 * (XXX - this would change if we made string values counted
1882 * rather than null-terminated.)
1883 */
1884 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1885 }
1886 *ret_length = length;
1887 return value;
1888}
1889
1890/* For FT_UINT_STRING */
1891static inline const uint8_t *
1892get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1893 tvbuff_t *tvb, int start, int length, int *ret_length,
1894 const unsigned encoding)
1895{
1896 uint32_t n;
1897 const uint8_t *value;
1898
1899 /* I believe it's ok if this is called with a NULL tree */
1900 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1901 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1902 length += n;
1903 *ret_length = length;
1904 return value;
1905}
1906
1907/* For FT_STRINGZPAD */
1908static inline const uint8_t *
1909get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1910 int length, int *ret_length, const unsigned encoding)
1911{
1912 /*
1913 * XXX - currently, string values are null-
1914 * terminated, so a "zero-padded" string
1915 * isn't special. If we represent string
1916 * values as something that includes a counted
1917 * array of bytes, we'll need to strip the
1918 * trailing NULs.
1919 */
1920 if (length == -1) {
1921 length = tvb_ensure_captured_length_remaining(tvb, start);
1922 }
1923 *ret_length = length;
1924 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1925}
1926
1927/* For FT_STRINGZTRUNC */
1928static inline const uint8_t *
1929get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1930 int length, int *ret_length, const unsigned encoding)
1931{
1932 /*
1933 * XXX - currently, string values are null-
1934 * terminated, so a "zero-truncated" string
1935 * isn't special. If we represent string
1936 * values as something that includes a counted
1937 * array of bytes, we'll need to strip everything
1938 * starting with the terminating NUL.
1939 */
1940 if (length == -1) {
1941 length = tvb_ensure_captured_length_remaining(tvb, start);
1942 }
1943 *ret_length = length;
1944 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1945}
1946
1947/*
1948 * Deltas between the epochs for various non-UN*X time stamp formats and
1949 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1950 * stamp format.
1951 */
1952
1953/*
1954 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1955 * XXX - if it's OK if this is unsigned, can we just use
1956 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1957 */
1958#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1959
1960/*
1961 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1962 */
1963#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1964
1965/* this can be called when there is no tree, so tree may be null */
1966static void
1967get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1968 const int length, const unsigned encoding, nstime_t *time_stamp,
1969 const bool_Bool is_relative)
1970{
1971 uint32_t tmpsecs;
1972 uint64_t tmp64secs;
1973 uint64_t todusecs;
1974
1975 switch (encoding) {
1976
1977 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1978 /*
1979 * If the length is 16, 8-byte seconds, followed
1980 * by 8-byte fractional time in nanoseconds,
1981 * both big-endian.
1982 *
1983 * If the length is 12, 8-byte seconds, followed
1984 * by 4-byte fractional time in nanoseconds,
1985 * both big-endian.
1986 *
1987 * If the length is 8, 4-byte seconds, followed
1988 * by 4-byte fractional time in nanoseconds,
1989 * both big-endian.
1990 *
1991 * For absolute times, the seconds are seconds
1992 * since the UN*X epoch.
1993 */
1994 if (length == 16) {
1995 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1996 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1997 } else if (length == 12) {
1998 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1999 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2000 } else if (length == 8) {
2001 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2002 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2003 } else if (length == 4) {
2004 /*
2005 * Backwards compatibility.
2006 * ENC_TIME_SECS_NSECS is 0; using
2007 * ENC_BIG_ENDIAN by itself with a 4-byte
2008 * time-in-seconds value was done in the
2009 * past.
2010 */
2011 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2012 time_stamp->nsecs = 0;
2013 } else {
2014 time_stamp->secs = 0;
2015 time_stamp->nsecs = 0;
2016 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2017 }
2018 break;
2019
2020 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2021 /*
2022 * If the length is 16, 8-byte seconds, followed
2023 * by 8-byte fractional time in nanoseconds,
2024 * both little-endian.
2025 *
2026 * If the length is 12, 8-byte seconds, followed
2027 * by 4-byte fractional time in nanoseconds,
2028 * both little-endian.
2029 *
2030 * If the length is 8, 4-byte seconds, followed
2031 * by 4-byte fractional time in nanoseconds,
2032 * both little-endian.
2033 *
2034 * For absolute times, the seconds are seconds
2035 * since the UN*X epoch.
2036 */
2037 if (length == 16) {
2038 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2039 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2040 } else if (length == 12) {
2041 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2042 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2043 } else if (length == 8) {
2044 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2045 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2046 } else if (length == 4) {
2047 /*
2048 * Backwards compatibility.
2049 * ENC_TIME_SECS_NSECS is 0; using
2050 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2051 * time-in-seconds value was done in the
2052 * past.
2053 */
2054 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2055 time_stamp->nsecs = 0;
2056 } else {
2057 time_stamp->secs = 0;
2058 time_stamp->nsecs = 0;
2059 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2060 }
2061 break;
2062
2063 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2064 /*
2065 * NTP time stamp, big-endian.
2066 * Only supported for absolute times.
2067 */
2068 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2068, "!is_relative"
))))
;
2069
2070 /* We need a temporary variable here so the unsigned math
2071 * works correctly (for years > 2036 according to RFC 2030
2072 * chapter 3).
2073 *
2074 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2075 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2076 * If bit 0 is not set, the time is in the range 2036-2104 and
2077 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2078 */
2079 tmpsecs = tvb_get_ntohl(tvb, start);
2080 if ((tmpsecs & 0x80000000) != 0)
2081 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2082 else
2083 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2084
2085 if (length == 8) {
2086 tmp64secs = tvb_get_ntoh64(tvb, start);
2087 if (tmp64secs == 0) {
2088 //This is "NULL" time
2089 time_stamp->secs = 0;
2090 time_stamp->nsecs = 0;
2091 } else {
2092 /*
2093 * Convert 1/2^32s of a second to
2094 * nanoseconds.
2095 */
2096 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2097 }
2098 } else if (length == 4) {
2099 /*
2100 * Backwards compatibility.
2101 */
2102 if (tmpsecs == 0) {
2103 //This is "NULL" time
2104 time_stamp->secs = 0;
2105 }
2106 time_stamp->nsecs = 0;
2107 } else {
2108 time_stamp->secs = 0;
2109 time_stamp->nsecs = 0;
2110 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2111 }
2112 break;
2113
2114 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2115 /*
2116 * NTP time stamp, little-endian.
2117 * Only supported for absolute times.
2118 *
2119 * NTP doesn't use this, because it's an Internet format
2120 * and hence big-endian. Any implementation must decide
2121 * whether the NTP timestamp is a 64-bit unsigned fixed
2122 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2123 * with a 32-bit unsigned seconds field followed by a
2124 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2125 * the previous two).
2126 *
2127 * XXX: We do the latter, but no dissector uses this format.
2128 * OTOH, ERF timestamps do the former, so perhaps we
2129 * should switch the interpretation so that packet-erf.c
2130 * could use this directly?
2131 */
2132 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2132, "!is_relative"
))))
;
2133
2134 /* We need a temporary variable here so the unsigned math
2135 * works correctly (for years > 2036 according to RFC 2030
2136 * chapter 3).
2137 *
2138 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2139 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2140 * If bit 0 is not set, the time is in the range 2036-2104 and
2141 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2142 */
2143 tmpsecs = tvb_get_letohl(tvb, start);
2144 if ((tmpsecs & 0x80000000) != 0)
2145 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2146 else
2147 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2148
2149 if (length == 8) {
2150 tmp64secs = tvb_get_letoh64(tvb, start);
2151 if (tmp64secs == 0) {
2152 //This is "NULL" time
2153 time_stamp->secs = 0;
2154 time_stamp->nsecs = 0;
2155 } else {
2156 /*
2157 * Convert 1/2^32s of a second to
2158 * nanoseconds.
2159 */
2160 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2161 }
2162 } else if (length == 4) {
2163 /*
2164 * Backwards compatibility.
2165 */
2166 if (tmpsecs == 0) {
2167 //This is "NULL" time
2168 time_stamp->secs = 0;
2169 }
2170 time_stamp->nsecs = 0;
2171 } else {
2172 time_stamp->secs = 0;
2173 time_stamp->nsecs = 0;
2174 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2175 }
2176 break;
2177
2178 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2179 /*
2180 * S/3x0 and z/Architecture TOD clock time stamp,
2181 * big-endian. The epoch is January 1, 1900,
2182 * 00:00:00 (proleptic?) UTC.
2183 *
2184 * Only supported for absolute times.
2185 */
2186 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2186, "!is_relative"
))))
;
2187 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2187, "length == 8"
))))
;
2188
2189 if (length == 8) {
2190 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2191 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2192 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2193 } else {
2194 time_stamp->secs = 0;
2195 time_stamp->nsecs = 0;
2196 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2197 }
2198 break;
2199
2200 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2201 /*
2202 * S/3x0 and z/Architecture TOD clock time stamp,
2203 * little-endian. The epoch is January 1, 1900,
2204 * 00:00:00 (proleptic?) UTC.
2205 *
2206 * Only supported for absolute times.
2207 */
2208 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2208, "!is_relative"
))))
;
2209
2210 if (length == 8) {
2211 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2212 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2213 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2214 } else {
2215 time_stamp->secs = 0;
2216 time_stamp->nsecs = 0;
2217 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2218 }
2219 break;
2220
2221 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2222 /*
2223 * Time stamp using the same seconds/fraction format
2224 * as NTP, but with the origin of the time stamp being
2225 * the UNIX epoch rather than the NTP epoch; big-
2226 * endian.
2227 *
2228 * Only supported for absolute times.
2229 */
2230 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2230, "!is_relative"
))))
;
2231
2232 if (length == 8) {
2233 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2234 /*
2235 * Convert 1/2^32s of a second to nanoseconds.
2236 */
2237 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2238 } else {
2239 time_stamp->secs = 0;
2240 time_stamp->nsecs = 0;
2241 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2242 }
2243 break;
2244
2245 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2246 /*
2247 * Time stamp using the same seconds/fraction format
2248 * as NTP, but with the origin of the time stamp being
2249 * the UNIX epoch rather than the NTP epoch; little-
2250 * endian.
2251 *
2252 * Only supported for absolute times.
2253 *
2254 * The RTPS specification explicitly supports Little
2255 * Endian encoding. In one place, it states that its
2256 * Time_t representation "is the one defined by ...
2257 * RFC 1305", but in another explicitly defines it as
2258 * a struct consisting of an 32 bit unsigned seconds
2259 * field and a 32 bit unsigned fraction field, not a 64
2260 * bit fixed point, so we do that here.
2261 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2262 */
2263 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2263, "!is_relative"
))))
;
2264
2265 if (length == 8) {
2266 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2267 /*
2268 * Convert 1/2^32s of a second to nanoseconds.
2269 */
2270 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2271 } else {
2272 time_stamp->secs = 0;
2273 time_stamp->nsecs = 0;
2274 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2275 }
2276 break;
2277
2278 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2279 /*
2280 * MIP6 time stamp, big-endian.
2281 * A 64-bit unsigned integer field containing a timestamp. The
2282 * value indicates the number of seconds since January 1, 1970,
2283 * 00:00 UTC, by using a fixed point format. In this format, the
2284 * integer number of seconds is contained in the first 48 bits of
2285 * the field, and the remaining 16 bits indicate the number of
2286 * 1/65536 fractions of a second.
2287
2288 * Only supported for absolute times.
2289 */
2290 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2290, "!is_relative"
))))
;
2291
2292 if (length == 8) {
2293 /* We need a temporary variable here so the casting and fractions
2294 * of a second work correctly.
2295 */
2296 tmp64secs = tvb_get_ntoh48(tvb, start);
2297 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2298 tmpsecs <<= 16;
2299
2300 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2301 //This is "NULL" time
2302 time_stamp->secs = 0;
2303 time_stamp->nsecs = 0;
2304 } else {
2305 time_stamp->secs = (time_t)tmp64secs;
2306 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2307 }
2308 } else {
2309 time_stamp->secs = 0;
2310 time_stamp->nsecs = 0;
2311 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2312 }
2313 break;
2314
2315 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2316 /*
2317 * If the length is 16, 8-byte seconds, followed
2318 * by 8-byte fractional time in microseconds,
2319 * both big-endian.
2320 *
2321 * If the length is 12, 8-byte seconds, followed
2322 * by 4-byte fractional time in microseconds,
2323 * both big-endian.
2324 *
2325 * If the length is 8, 4-byte seconds, followed
2326 * by 4-byte fractional time in microseconds,
2327 * both big-endian.
2328 *
2329 * For absolute times, the seconds are seconds
2330 * since the UN*X epoch.
2331 */
2332 if (length == 16) {
2333 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2334 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2335 } else if (length == 12) {
2336 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2337 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2338 } else if (length == 8) {
2339 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2340 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2341 } else {
2342 time_stamp->secs = 0;
2343 time_stamp->nsecs = 0;
2344 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2345 }
2346 break;
2347
2348 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2349 /*
2350 * If the length is 16, 8-byte seconds, followed
2351 * by 8-byte fractional time in microseconds,
2352 * both little-endian.
2353 *
2354 * If the length is 12, 8-byte seconds, followed
2355 * by 4-byte fractional time in microseconds,
2356 * both little-endian.
2357 *
2358 * If the length is 8, 4-byte seconds, followed
2359 * by 4-byte fractional time in microseconds,
2360 * both little-endian.
2361 *
2362 * For absolute times, the seconds are seconds
2363 * since the UN*X epoch.
2364 */
2365 if (length == 16) {
2366 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2367 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2368 } else if (length == 12) {
2369 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2370 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2371 } else if (length == 8) {
2372 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2373 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2374 } else {
2375 time_stamp->secs = 0;
2376 time_stamp->nsecs = 0;
2377 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2378 }
2379 break;
2380
2381 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2382 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2383 /*
2384 * Seconds, 1 to 8 bytes.
2385 * For absolute times, it's seconds since the
2386 * UN*X epoch.
2387 */
2388 if (length >= 1 && length <= 8) {
2389 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2390 time_stamp->nsecs = 0;
2391 } else {
2392 time_stamp->secs = 0;
2393 time_stamp->nsecs = 0;
2394 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2395 }
2396 break;
2397
2398 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2399 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2400 /*
2401 * Milliseconds, 1 to 8 bytes.
2402 * For absolute times, it's milliseconds since the
2403 * UN*X epoch.
2404 */
2405 if (length >= 1 && length <= 8) {
2406 uint64_t msecs;
2407
2408 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2409 time_stamp->secs = (time_t)(msecs / 1000);
2410 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2411 } else {
2412 time_stamp->secs = 0;
2413 time_stamp->nsecs = 0;
2414 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2415 }
2416 break;
2417
2418 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2419 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2420 /*
2421 * Microseconds, 1 to 8 bytes.
2422 * For absolute times, it's microseconds since the
2423 * UN*X epoch.
2424 */
2425 if (length >= 1 && length <= 8) {
2426 uint64_t usecs;
2427
2428 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2429 time_stamp->secs = (time_t)(usecs / 1000000);
2430 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2431 } else {
2432 time_stamp->secs = 0;
2433 time_stamp->nsecs = 0;
2434 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2435 }
2436 break;
2437
2438 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2439 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2440 /*
2441 * nanoseconds, 1 to 8 bytes.
2442 * For absolute times, it's nanoseconds since the
2443 * UN*X epoch.
2444 */
2445
2446 if (length >= 1 && length <= 8) {
2447 uint64_t nsecs;
2448
2449 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2450 time_stamp->secs = (time_t)(nsecs / 1000000000);
2451 time_stamp->nsecs = (int)(nsecs % 1000000000);
2452 } else {
2453 time_stamp->secs = 0;
2454 time_stamp->nsecs = 0;
2455 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2456 }
2457 break;
2458
2459 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2460 /*
2461 * 1/64ths of a second since the UN*X epoch,
2462 * big-endian.
2463 *
2464 * Only supported for absolute times.
2465 */
2466 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2466, "!is_relative"
))))
;
2467
2468 if (length == 8) {
2469 /*
2470 * The upper 48 bits are seconds since the
2471 * UN*X epoch.
2472 */
2473 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2474 /*
2475 * The lower 16 bits are 1/2^16s of a second;
2476 * convert them to nanoseconds.
2477 *
2478 * XXX - this may give the impression of higher
2479 * precision than you actually get.
2480 */
2481 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2482 } else {
2483 time_stamp->secs = 0;
2484 time_stamp->nsecs = 0;
2485 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2486 }
2487 break;
2488
2489 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2490 /*
2491 * 1/64ths of a second since the UN*X epoch,
2492 * little-endian.
2493 *
2494 * Only supported for absolute times.
2495 */
2496 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2496, "!is_relative"
))))
;
2497
2498 if (length == 8) {
2499 /*
2500 * XXX - this is assuming that, if anybody
2501 * were ever to use this format - RFC 3971
2502 * doesn't, because that's an Internet
2503 * protocol, and those use network byte
2504 * order, i.e. big-endian - they'd treat it
2505 * as a 64-bit count of 1/2^16s of a second,
2506 * putting the upper 48 bits at the end.
2507 *
2508 * The lower 48 bits are seconds since the
2509 * UN*X epoch.
2510 */
2511 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2512 /*
2513 * The upper 16 bits are 1/2^16s of a second;
2514 * convert them to nanoseconds.
2515 *
2516 * XXX - this may give the impression of higher
2517 * precision than you actually get.
2518 */
2519 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2520 } else {
2521 time_stamp->secs = 0;
2522 time_stamp->nsecs = 0;
2523 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2524 }
2525 break;
2526
2527 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2528 /*
2529 * NTP time stamp, with 1-second resolution (i.e.,
2530 * seconds since the NTP epoch), big-endian.
2531 * Only supported for absolute times.
2532 */
2533 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2533, "!is_relative"
))))
;
2534
2535 if (length == 4) {
2536 /*
2537 * We need a temporary variable here so the unsigned math
2538 * works correctly (for years > 2036 according to RFC 2030
2539 * chapter 3).
2540 *
2541 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2542 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2543 * If bit 0 is not set, the time is in the range 2036-2104 and
2544 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2545 */
2546 tmpsecs = tvb_get_ntohl(tvb, start);
2547 if ((tmpsecs & 0x80000000) != 0)
2548 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2549 else
2550 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2551 time_stamp->nsecs = 0;
2552 } else {
2553 time_stamp->secs = 0;
2554 time_stamp->nsecs = 0;
2555 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2556 }
2557 break;
2558
2559 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2560 /*
2561 * NTP time stamp, with 1-second resolution (i.e.,
2562 * seconds since the NTP epoch), little-endian.
2563 * Only supported for absolute times.
2564 */
2565 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2565, "!is_relative"
))))
;
2566
2567 /*
2568 * We need a temporary variable here so the unsigned math
2569 * works correctly (for years > 2036 according to RFC 2030
2570 * chapter 3).
2571 *
2572 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2573 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2574 * If bit 0 is not set, the time is in the range 2036-2104 and
2575 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2576 */
2577 if (length == 4) {
2578 tmpsecs = tvb_get_letohl(tvb, start);
2579 if ((tmpsecs & 0x80000000) != 0)
2580 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2581 else
2582 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2583 time_stamp->nsecs = 0;
2584 } else {
2585 time_stamp->secs = 0;
2586 time_stamp->nsecs = 0;
2587 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2588 }
2589 break;
2590
2591 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2592 /*
2593 * Milliseconds, 6 to 8 bytes.
2594 * For absolute times, it's milliseconds since the
2595 * NTP epoch.
2596 *
2597 * ETSI TS 129.274 8.119 defines this as:
2598 * "a 48 bit unsigned integer in network order format
2599 * ...encoded as the number of milliseconds since
2600 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2601 * rounded value of 1000 x the value of the 64-bit
2602 * timestamp (Seconds + (Fraction / (1<<32))) defined
2603 * in clause 6 of IETF RFC 5905."
2604 *
2605 * Taken literally, the part after "i.e." would
2606 * mean that the value rolls over before reaching
2607 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2608 * when the 64 bit timestamp rolls over, and we have
2609 * to pick an NTP Era equivalence class to support
2610 * (such as 1968-01-20 to 2104-02-06).
2611 *
2612 * OTOH, the extra room might be used to store Era
2613 * information instead, in which case times until
2614 * 10819-08-03 can be represented with 6 bytes without
2615 * ambiguity. We handle both implementations, and assume
2616 * that times before 1968-01-20 are not represented.
2617 *
2618 * Only 6 bytes or more makes sense as an absolute
2619 * time. 5 bytes or fewer could express a span of
2620 * less than 35 years, either 1900-1934 or 2036-2070.
2621 */
2622 if (length >= 6 && length <= 8) {
2623 uint64_t msecs;
2624
2625 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2626 tmp64secs = (msecs / 1000);
2627 /*
2628 * Assume that times in the first half of NTP
2629 * Era 0 really represent times in the NTP
2630 * Era 1.
2631 */
2632 if (tmp64secs >= 0x80000000)
2633 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2634 else
2635 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2636 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2637 }
2638 else {
2639 time_stamp->secs = 0;
2640 time_stamp->nsecs = 0;
2641 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2642 }
2643 break;
2644
2645 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2646 /*
2647 * MP4 file time stamps, big-endian.
2648 * Only supported for absolute times.
2649 */
2650 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2650, "!is_relative"
))))
;
2651
2652 if (length == 8) {
2653 tmp64secs = tvb_get_ntoh64(tvb, start);
2654 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2655 time_stamp->nsecs = 0;
2656 } else if (length == 4) {
2657 tmpsecs = tvb_get_ntohl(tvb, start);
2658 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2659 time_stamp->nsecs = 0;
2660 } else {
2661 time_stamp->secs = 0;
2662 time_stamp->nsecs = 0;
2663 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2664 }
2665 break;
2666
2667 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2668 /*
2669 * Zigbee ZCL time stamps, big-endian.
2670 * Only supported for absolute times.
2671 */
2672 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2672, "!is_relative"
))))
;
2673
2674 if (length == 8) {
2675 tmp64secs = tvb_get_ntoh64(tvb, start);
2676 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);
2677 time_stamp->nsecs = 0;
2678 } else if (length == 4) {
2679 tmpsecs = tvb_get_ntohl(tvb, start);
2680 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2681 time_stamp->nsecs = 0;
2682 } else {
2683 time_stamp->secs = 0;
2684 time_stamp->nsecs = 0;
2685 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2686 }
2687 break;
2688
2689 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2690 /*
2691 * Zigbee ZCL time stamps, little-endian.
2692 * Only supported for absolute times.
2693 */
2694 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2694, "!is_relative"
))))
;
2695
2696 if (length == 8) {
2697 tmp64secs = tvb_get_letoh64(tvb, start);
2698 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);
2699 time_stamp->nsecs = 0;
2700 } else if (length == 4) {
2701 tmpsecs = tvb_get_letohl(tvb, start);
2702 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2703 time_stamp->nsecs = 0;
2704 } else {
2705 time_stamp->secs = 0;
2706 time_stamp->nsecs = 0;
2707 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2708 }
2709 break;
2710
2711 default:
2712 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2712))
;
2713 break;
2714 }
2715}
2716
2717static void
2718tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2719{
2720 const header_field_info *hfinfo = fi->hfinfo;
2721
2722 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2723 GPtrArray *ptrs = NULL((void*)0);
2724
2725 if (tree_data->interesting_hfids == NULL((void*)0)) {
2726 /* Initialize the hash because we now know that it is needed */
2727 tree_data->interesting_hfids =
2728 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2729 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2730 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2731 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2732 }
2733
2734 if (!ptrs) {
2735 /* First element triggers the creation of pointer array */
2736 ptrs = g_ptr_array_new();
2737 g_hash_table_insert(tree_data->interesting_hfids,
2738 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2739 }
2740
2741 g_ptr_array_add(ptrs, fi);
2742 }
2743}
2744
2745
2746/*
2747 * Validates that field length bytes are available starting from
2748 * start (pos/neg). Throws an exception if they aren't.
2749 */
2750static void
2751test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2752 int start, int length, const unsigned encoding)
2753{
2754 int size = length;
2755
2756 if (!tvb)
2757 return;
2758
2759 if ((hfinfo->type == FT_STRINGZ) ||
2760 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2761 (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
))
))) {
2762 /* If we're fetching until the end of the TVB, only validate
2763 * that the offset is within range.
2764 */
2765 if (length == -1)
2766 size = 0;
2767 }
2768
2769 tvb_ensure_bytes_exist(tvb, start, size);
2770}
2771
2772static void
2773detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2774{
2775 bool_Bool found_stray_character = false0;
2776
2777 if (!string)
2778 return;
2779
2780 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2781 case ENC_ASCII0x00000000:
2782 case ENC_UTF_80x00000002:
2783 for (int i = (int)strlen(string); i < length; i++) {
2784 if (string[i] != '\0') {
2785 found_stray_character = true1;
2786 break;
2787 }
2788 }
2789 break;
2790
2791 default:
2792 break;
2793 }
2794
2795 if (found_stray_character) {
2796 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2797 }
2798}
2799
2800static void
2801free_fvalue_cb(void *data)
2802{
2803 fvalue_t *fv = (fvalue_t*)data;
2804 fvalue_free(fv);
2805}
2806
2807/* Add an item to a proto_tree, using the text label registered to that item;
2808 the item is extracted from the tvbuff handed to it. */
2809static proto_item *
2810proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2811 tvbuff_t *tvb, int start, int length,
2812 unsigned encoding)
2813{
2814 proto_item *pi;
2815 uint32_t value, n;
2816 uint64_t value64;
2817 ws_in4_addr ipv4_value;
2818 float floatval;
2819 double doubleval;
2820 const char *stringval = NULL((void*)0);
2821 nstime_t time_stamp;
2822 bool_Bool length_error;
2823
2824 /* Ensure that the newly created fvalue_t is freed if we throw an
2825 * exception before adding it to the tree. (gcc creates clobbering
2826 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2827 * XXX: Move the new_field_info() call inside here?
2828 */
2829 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))
;
2830
2831 switch (new_fi->hfinfo->type) {
2832 case FT_NONE:
2833 /* no value to set for FT_NONE */
2834 break;
2835
2836 case FT_PROTOCOL:
2837 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2838 break;
2839
2840 case FT_BYTES:
2841 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2842 break;
2843
2844 case FT_UINT_BYTES:
2845 n = get_uint_value(tree, tvb, start, length, encoding);
2846 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2847
2848 /* Instead of calling proto_item_set_len(), since we don't yet
2849 * have a proto_item, we set the field_info's length ourselves. */
2850 new_fi->length = n + length;
2851 break;
2852
2853 case FT_BOOLEAN:
2854 /*
2855 * Map all non-zero values to little-endian for
2856 * backwards compatibility.
2857 */
2858 if (encoding)
2859 encoding = ENC_LITTLE_ENDIAN0x80000000;
2860 proto_tree_set_boolean(new_fi,
2861 get_uint64_value(tree, tvb, start, length, encoding));
2862 break;
2863
2864 case FT_CHAR:
2865 /* XXX - make these just FT_UINT? */
2866 case FT_UINT8:
2867 case FT_UINT16:
2868 case FT_UINT24:
2869 case FT_UINT32:
2870 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2871 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2872 value = (uint32_t)value64;
2873 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2874 new_fi->flags |= FI_VARINT0x00040000;
2875 }
2876 }
2877 else {
2878 /*
2879 * Map all non-zero values to little-endian for
2880 * backwards compatibility.
2881 */
2882 if (encoding)
2883 encoding = ENC_LITTLE_ENDIAN0x80000000;
2884
2885 value = get_uint_value(tree, tvb, start, length, encoding);
2886 }
2887 proto_tree_set_uint(new_fi, value);
2888 break;
2889
2890 case FT_UINT40:
2891 case FT_UINT48:
2892 case FT_UINT56:
2893 case FT_UINT64:
2894 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2895 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2896 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2897 new_fi->flags |= FI_VARINT0x00040000;
2898 }
2899 }
2900 else {
2901 /*
2902 * Map all other non-zero values to little-endian for
2903 * backwards compatibility.
2904 */
2905 if (encoding)
2906 encoding = ENC_LITTLE_ENDIAN0x80000000;
2907
2908 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2909 }
2910 proto_tree_set_uint64(new_fi, value64);
2911 break;
2912
2913 /* XXX - make these just FT_INT? */
2914 case FT_INT8:
2915 case FT_INT16:
2916 case FT_INT24:
2917 case FT_INT32:
2918 /*
2919 * Map all non-zero values to little-endian for
2920 * backwards compatibility.
2921 */
2922 if (encoding)
2923 encoding = ENC_LITTLE_ENDIAN0x80000000;
2924 proto_tree_set_int(new_fi,
2925 get_int_value(tree, tvb, start, length, encoding));
2926 break;
2927
2928 case FT_INT40:
2929 case FT_INT48:
2930 case FT_INT56:
2931 case FT_INT64:
2932 /*
2933 * Map all non-zero values to little-endian for
2934 * backwards compatibility.
2935 */
2936 if (encoding)
2937 encoding = ENC_LITTLE_ENDIAN0x80000000;
2938 proto_tree_set_int64(new_fi,
2939 get_int64_value(tree, tvb, start, length, encoding));
2940 break;
2941
2942 case FT_IPv4:
2943 /*
2944 * Map all non-zero values to little-endian for
2945 * backwards compatibility.
2946 */
2947 if (encoding)
2948 encoding = ENC_LITTLE_ENDIAN0x80000000;
2949 if (length != FT_IPv4_LEN4) {
2950 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2951 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2952 }
2953 ipv4_value = tvb_get_ipv4(tvb, start);
2954 /*
2955 * NOTE: to support code written when
2956 * proto_tree_add_item() took a bool as its
2957 * last argument, with false meaning "big-endian"
2958 * and true meaning "little-endian", we treat any
2959 * non-zero value of "encoding" as meaning
2960 * "little-endian".
2961 */
2962 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);
2963 break;
2964
2965 case FT_IPXNET:
2966 if (length != FT_IPXNET_LEN4) {
2967 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2968 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2969 }
2970 proto_tree_set_ipxnet(new_fi,
2971 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2972 break;
2973
2974 case FT_IPv6:
2975 if (length != FT_IPv6_LEN16) {
2976 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2977 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2978 }
2979 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2980 break;
2981
2982 case FT_FCWWN:
2983 if (length != FT_FCWWN_LEN8) {
2984 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2985 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2986 }
2987 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2988 break;
2989
2990 case FT_AX25:
2991 if (length != 7) {
2992 length_error = length < 7 ? true1 : false0;
2993 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2994 }
2995 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2996 break;
2997
2998 case FT_VINES:
2999 if (length != VINES_ADDR_LEN6) {
3000 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3001 report_type_length_mismatch(tree, "a Vines address", length, length_error);
3002 }
3003 proto_tree_set_vines_tvb(new_fi, tvb, start);
3004 break;
3005
3006 case FT_ETHER:
3007 if (length != FT_ETHER_LEN6) {
3008 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3009 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3010 }
3011 proto_tree_set_ether_tvb(new_fi, tvb, start);
3012 break;
3013
3014 case FT_EUI64:
3015 /*
3016 * Map all non-zero values to little-endian for
3017 * backwards compatibility.
3018 */
3019 if (encoding)
3020 encoding = ENC_LITTLE_ENDIAN0x80000000;
3021 if (length != FT_EUI64_LEN8) {
3022 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3023 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3024 }
3025 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3026 break;
3027 case FT_GUID:
3028 /*
3029 * Map all non-zero values to little-endian for
3030 * backwards compatibility.
3031 */
3032 if (encoding)
3033 encoding = ENC_LITTLE_ENDIAN0x80000000;
3034 if (length != FT_GUID_LEN16) {
3035 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3036 report_type_length_mismatch(tree, "a GUID", length, length_error);
3037 }
3038 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3039 break;
3040
3041 case FT_OID:
3042 case FT_REL_OID:
3043 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3044 break;
3045
3046 case FT_SYSTEM_ID:
3047 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3048 break;
3049
3050 case FT_FLOAT:
3051 /*
3052 * NOTE: to support code written when
3053 * proto_tree_add_item() took a bool as its
3054 * last argument, with false meaning "big-endian"
3055 * and true meaning "little-endian", we treat any
3056 * non-zero value of "encoding" as meaning
3057 * "little-endian".
3058 *
3059 * At some point in the future, we might
3060 * support non-IEEE-binary floating-point
3061 * formats in the encoding as well
3062 * (IEEE decimal, System/3x0, VAX).
3063 */
3064 if (encoding)
3065 encoding = ENC_LITTLE_ENDIAN0x80000000;
3066 if (length != 4) {
3067 length_error = length < 4 ? true1 : false0;
3068 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3069 }
3070 if (encoding)
3071 floatval = tvb_get_letohieee_float(tvb, start);
3072 else
3073 floatval = tvb_get_ntohieee_float(tvb, start);
3074 proto_tree_set_float(new_fi, floatval);
3075 break;
3076
3077 case FT_DOUBLE:
3078 /*
3079 * NOTE: to support code written when
3080 * proto_tree_add_item() took a bool as its
3081 * last argument, with false meaning "big-endian"
3082 * and true meaning "little-endian", we treat any
3083 * non-zero value of "encoding" as meaning
3084 * "little-endian".
3085 *
3086 * At some point in the future, we might
3087 * support non-IEEE-binary floating-point
3088 * formats in the encoding as well
3089 * (IEEE decimal, System/3x0, VAX).
3090 */
3091 if (encoding == true1)
3092 encoding = ENC_LITTLE_ENDIAN0x80000000;
3093 if (length != 8) {
3094 length_error = length < 8 ? true1 : false0;
3095 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3096 }
3097 if (encoding)
3098 doubleval = tvb_get_letohieee_double(tvb, start);
3099 else
3100 doubleval = tvb_get_ntohieee_double(tvb, start);
3101 proto_tree_set_double(new_fi, doubleval);
3102 break;
3103
3104 case FT_STRING:
3105 stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3106 tvb, start, length, &length, encoding);
3107 proto_tree_set_string(new_fi, stringval);
3108
3109 /* Instead of calling proto_item_set_len(), since we
3110 * don't yet have a proto_item, we set the
3111 * field_info's length ourselves.
3112 *
3113 * XXX - our caller can't use that length to
3114 * advance an offset unless they arrange that
3115 * there always be a protocol tree into which
3116 * we're putting this item.
3117 */
3118 new_fi->length = length;
3119 break;
3120
3121 case FT_STRINGZ:
3122 stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3123 tree, tvb, start, length, &length, encoding);
3124 proto_tree_set_string(new_fi, stringval);
3125
3126 /* Instead of calling proto_item_set_len(),
3127 * since we don't yet have a proto_item, we
3128 * set the field_info's length ourselves.
3129 *
3130 * XXX - our caller can't use that length to
3131 * advance an offset unless they arrange that
3132 * there always be a protocol tree into which
3133 * we're putting this item.
3134 */
3135 new_fi->length = length;
3136 break;
3137
3138 case FT_UINT_STRING:
3139 /*
3140 * NOTE: to support code written when
3141 * proto_tree_add_item() took a bool as its
3142 * last argument, with false meaning "big-endian"
3143 * and true meaning "little-endian", if the
3144 * encoding value is true, treat that as
3145 * ASCII with a little-endian length.
3146 *
3147 * This won't work for code that passes
3148 * arbitrary non-zero values; that code
3149 * will need to be fixed.
3150 */
3151 if (encoding == true1)
3152 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3153 stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3154 tree, tvb, start, length, &length, encoding);
3155 proto_tree_set_string(new_fi, stringval);
3156
3157 /* Instead of calling proto_item_set_len(), since we
3158 * don't yet have a proto_item, we set the
3159 * field_info's length ourselves.
3160 *
3161 * XXX - our caller can't use that length to
3162 * advance an offset unless they arrange that
3163 * there always be a protocol tree into which
3164 * we're putting this item.
3165 */
3166 new_fi->length = length;
3167 break;
3168
3169 case FT_STRINGZPAD:
3170 stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3171 tvb, start, length, &length, encoding);
3172 proto_tree_set_string(new_fi, stringval);
3173
3174 /* Instead of calling proto_item_set_len(), since we
3175 * don't yet have a proto_item, we set the
3176 * field_info's length ourselves.
3177 *
3178 * XXX - our caller can't use that length to
3179 * advance an offset unless they arrange that
3180 * there always be a protocol tree into which
3181 * we're putting this item.
3182 */
3183 new_fi->length = length;
3184 break;
3185
3186 case FT_STRINGZTRUNC:
3187 stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3188 tvb, start, length, &length, encoding);
3189 proto_tree_set_string(new_fi, stringval);
3190
3191 /* Instead of calling proto_item_set_len(), since we
3192 * don't yet have a proto_item, we set the
3193 * field_info's length ourselves.
3194 *
3195 * XXX - our caller can't use that length to
3196 * advance an offset unless they arrange that
3197 * there always be a protocol tree into which
3198 * we're putting this item.
3199 */
3200 new_fi->length = length;
3201 break;
3202
3203 case FT_ABSOLUTE_TIME:
3204 /*
3205 * Absolute times can be in any of a number of
3206 * formats, and they can be big-endian or
3207 * little-endian.
3208 *
3209 * Historically FT_TIMEs were only timespecs;
3210 * the only question was whether they were stored
3211 * in big- or little-endian format.
3212 *
3213 * For backwards compatibility, we interpret an
3214 * encoding of 1 as meaning "little-endian timespec",
3215 * so that passing true is interpreted as that.
3216 */
3217 if (encoding == true1)
3218 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3219
3220 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3221
3222 proto_tree_set_time(new_fi, &time_stamp);
3223 break;
3224
3225 case FT_RELATIVE_TIME:
3226 /*
3227 * Relative times can be in any of a number of
3228 * formats, and they can be big-endian or
3229 * little-endian.
3230 *
3231 * Historically FT_TIMEs were only timespecs;
3232 * the only question was whether they were stored
3233 * in big- or little-endian format.
3234 *
3235 * For backwards compatibility, we interpret an
3236 * encoding of 1 as meaning "little-endian timespec",
3237 * so that passing true is interpreted as that.
3238 */
3239 if (encoding == true1)
3240 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3241
3242 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3243
3244 proto_tree_set_time(new_fi, &time_stamp);
3245 break;
3246 case FT_IEEE_11073_SFLOAT:
3247 if (encoding)
3248 encoding = ENC_LITTLE_ENDIAN0x80000000;
3249 if (length != 2) {
3250 length_error = length < 2 ? true1 : false0;
3251 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3252 }
3253
3254 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3255
3256 break;
3257 case FT_IEEE_11073_FLOAT:
3258 if (encoding)
3259 encoding = ENC_LITTLE_ENDIAN0x80000000;
3260 if (length != 4) {
3261 length_error = length < 4 ? true1 : false0;
3262 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3263 }
3264 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3265
3266 break;
3267 default:
3268 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))
3269 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))
3270 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))
3271 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))
;
3272 break;
3273 }
3274 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)
;
3275
3276 /* Don't add new node to proto_tree until now so that any exceptions
3277 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3278 /* XXX. wouldn't be better to add this item to tree, with some special
3279 * flag (FI_EXCEPTION?) to know which item caused exception? For
3280 * strings and bytes, we would have to set new_fi->value to something
3281 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3282 * could handle NULL values. */
3283 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3284 pi = proto_tree_add_node(tree, new_fi);
3285
3286 switch (new_fi->hfinfo->type) {
3287
3288 case FT_STRING:
3289 /* XXX: trailing stray character detection should be done
3290 * _before_ conversion to UTF-8, because conversion can change
3291 * the length, or else get_string_length should return a value
3292 * for the "length in bytes of the string after conversion
3293 * including internal nulls." (Noting that we do, for other
3294 * reasons, still need the "length in bytes in the field",
3295 * especially for FT_STRINGZ.)
3296 *
3297 * This is true even for ASCII and UTF-8, because
3298 * substituting REPLACEMENT CHARACTERS for illegal characters
3299 * can also do so (and for UTF-8 possibly even make the
3300 * string _shorter_).
3301 */
3302 detect_trailing_stray_characters(encoding, stringval, length, pi);
3303 break;
3304
3305 default:
3306 break;
3307 }
3308
3309 return pi;
3310}
3311
3312proto_item *
3313proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3314 const int start, int length,
3315 const unsigned encoding, int32_t *retval)
3316{
3317 header_field_info *hfinfo;
3318 field_info *new_fi;
3319 int32_t value;
3320
3321 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", 3321, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3321,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3321, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3322
3323 switch (hfinfo->type) {
3324 case FT_INT8:
3325 case FT_INT16:
3326 case FT_INT24:
3327 case FT_INT32:
3328 break;
3329 case FT_INT64:
3330 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)
3331 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3332 default:
3333 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)
3334 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3335 }
3336
3337 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3338 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3339 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3340 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3341 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3342 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3343 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3344
3345 if (encoding & ENC_STRING0x03000000) {
3346 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3347 }
3348 /* I believe it's ok if this is called with a NULL tree */
3349 value = get_int_value(tree, tvb, start, length, encoding);
3350
3351 if (retval) {
3352 int no_of_bits;
3353 *retval = value;
3354 if (hfinfo->bitmask) {
3355 /* Mask out irrelevant portions */
3356 *retval &= (uint32_t)(hfinfo->bitmask);
3357 /* Shift bits */
3358 *retval >>= hfinfo_bitshift(hfinfo);
3359 }
3360 no_of_bits = ws_count_ones(hfinfo->bitmask);
3361 *retval = ws_sign_ext32(*retval, no_of_bits);
3362 }
3363
3364 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3365
3366 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", 3366
, __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", 3366, "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", 3366, "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", 3366, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3367
3368 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3369
3370 proto_tree_set_int(new_fi, value);
3371
3372 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3373
3374 return proto_tree_add_node(tree, new_fi);
3375}
3376
3377proto_item *
3378proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3379 const int start, int length,
3380 const unsigned encoding, uint32_t *retval)
3381{
3382 header_field_info *hfinfo;
3383 field_info *new_fi;
3384 uint32_t value;
3385
3386 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3386, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3386,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3386, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3387
3388 switch (hfinfo->type) {
3389 case FT_CHAR:
3390 case FT_UINT8:
3391 case FT_UINT16:
3392 case FT_UINT24:
3393 case FT_UINT32:
3394 break;
3395 default:
3396 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",proto_report_dissector_bug("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
3397 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
3398 }
3399
3400 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3401 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3402 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3403 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3404 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3405 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3406 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3407
3408 if (encoding & ENC_STRING0x03000000) {
3409 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3410 }
3411 /* I believe it's ok if this is called with a NULL tree */
3412 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3413 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3414 uint64_t temp64;
3415 tvb_get_varint(tvb, start, length, &temp64, encoding);
3416 value = (uint32_t)temp64;
3417 } else {
3418 value = get_uint_value(tree, tvb, start, length, encoding);
3419 }
3420
3421 if (retval) {
3422 *retval = value;
3423 if (hfinfo->bitmask) {
3424 /* Mask out irrelevant portions */
3425 *retval &= (uint32_t)(hfinfo->bitmask);
3426 /* Shift bits */
3427 *retval >>= hfinfo_bitshift(hfinfo);
3428 }
3429 }
3430
3431 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3432
3433 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", 3433
, __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", 3433, "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", 3433, "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", 3433, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3434
3435 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3436
3437 proto_tree_set_uint(new_fi, value);
3438
3439 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3440 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3441 new_fi->flags |= FI_VARINT0x00040000;
3442 }
3443 return proto_tree_add_node(tree, new_fi);
3444}
3445
3446/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3447 * and returns proto_item* and uint value retrieved*/
3448proto_item *
3449ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3450 const unsigned encoding, uint32_t *retval)
3451{
3452 field_info *new_fi;
3453 header_field_info *hfinfo;
3454 int item_length;
3455 int offset;
3456 uint32_t value;
3457
3458 offset = ptvc->offset;
3459 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", 3459, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3459,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3459, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3460
3461 switch (hfinfo->type) {
3462 case FT_CHAR:
3463 case FT_UINT8:
3464 case FT_UINT16:
3465 case FT_UINT24:
3466 case FT_UINT32:
3467 break;
3468 default:
3469 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)
3470 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)
;
3471 }
3472
3473 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3474 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3475
3476 /* I believe it's ok if this is called with a NULL tree */
3477 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3478 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3479
3480 if (retval) {
3481 *retval = value;
3482 if (hfinfo->bitmask) {
3483 /* Mask out irrelevant portions */
3484 *retval &= (uint32_t)(hfinfo->bitmask);
3485 /* Shift bits */
3486 *retval >>= hfinfo_bitshift(hfinfo);
3487 }
3488 }
3489
3490 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3491
3492 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3493
3494 /* Coast clear. Try and fake it */
3495 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", 3495
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3495, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3495, "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", 3495, __func__, "Adding %s would put more than %d 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); } } }
;
3496
3497 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3498
3499 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3500 offset, length, encoding);
3501}
3502
3503/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3504 * and returns proto_item* and int value retrieved*/
3505proto_item *
3506ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3507 const unsigned encoding, int32_t *retval)
3508{
3509 field_info *new_fi;
3510 header_field_info *hfinfo;
3511 int item_length;
3512 int offset;
3513 uint32_t value;
3514
3515 offset = ptvc->offset;
3516 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", 3516, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3516,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3516, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3517
3518 switch (hfinfo->type) {
3519 case FT_INT8:
3520 case FT_INT16:
3521 case FT_INT24:
3522 case FT_INT32:
3523 break;
3524 default:
3525 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)
3526 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3527 }
3528
3529 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3530 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3531
3532 /* I believe it's ok if this is called with a NULL tree */
3533 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3534 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3535
3536 if (retval) {
3537 int no_of_bits;
3538 *retval = value;
3539 if (hfinfo->bitmask) {
3540 /* Mask out irrelevant portions */
3541 *retval &= (uint32_t)(hfinfo->bitmask);
3542 /* Shift bits */
3543 *retval >>= hfinfo_bitshift(hfinfo);
3544 }
3545 no_of_bits = ws_count_ones(hfinfo->bitmask);
3546 *retval = ws_sign_ext32(*retval, no_of_bits);
3547 }
3548
3549 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3550
3551 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3552
3553 /* Coast clear. Try and fake it */
3554 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", 3554
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3554, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3554, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
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", 3554, __func__, "Adding %s would put more than %d 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); } } }
;
3555
3556 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3557
3558 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3559 offset, length, encoding);
3560}
3561
3562/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3563 * and returns proto_item* and string value retrieved */
3564proto_item*
3565ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3566{
3567 header_field_info *hfinfo;
3568 field_info *new_fi;
3569 const uint8_t *value;
3570 int item_length;
3571 int offset;
3572
3573 offset = ptvc->offset;
3574
3575 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", 3575
, __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", 3575, "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", 3575, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3576
3577 switch (hfinfo->type) {
3578 case FT_STRING:
3579 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3580 break;
3581 case FT_STRINGZ:
3582 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3583 break;
3584 case FT_UINT_STRING:
3585 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3586 break;
3587 case FT_STRINGZPAD:
3588 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3589 break;
3590 case FT_STRINGZTRUNC:
3591 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3592 break;
3593 default:
3594 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)
3595 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)
;
3596 }
3597
3598 if (retval)
3599 *retval = value;
3600
3601 ptvcursor_advance(ptvc, item_length);
3602
3603 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3604
3605 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", 3605, __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", 3605,
"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", 3605, "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", 3605
, __func__, "Adding %s would put more than %d 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); } } }
;
3606
3607 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3608
3609 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3610 offset, length, encoding);
3611}
3612
3613/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3614 * and returns proto_item* and boolean value retrieved */
3615proto_item*
3616ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3617{
3618 header_field_info *hfinfo;
3619 field_info *new_fi;
3620 int item_length;
3621 int offset;
3622 uint64_t value, bitval;
3623
3624 offset = ptvc->offset;
3625 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", 3625, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3625,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3625, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3626
3627 if (hfinfo->type != FT_BOOLEAN) {
3628 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)
3629 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3630 }
3631
3632 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3633 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3634 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3635 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3636 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3637 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3638 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3639
3640 if (encoding & ENC_STRING0x03000000) {
3641 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3642 }
3643
3644 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3645 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3646
3647 /* I believe it's ok if this is called with a NULL tree */
3648 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3649
3650 if (retval) {
3651 bitval = value;
3652 if (hfinfo->bitmask) {
3653 /* Mask out irrelevant portions */
3654 bitval &= hfinfo->bitmask;
3655 }
3656 *retval = (bitval != 0);
3657 }
3658
3659 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3660
3661 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3662
3663 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", 3663, __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", 3663,
"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", 3663, "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", 3663
, __func__, "Adding %s would put more than %d 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); } } }
;
3664
3665 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3666
3667 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3668 offset, length, encoding);
3669}
3670
3671proto_item *
3672proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3673 const int start, int length, const unsigned encoding, uint64_t *retval)
3674{
3675 header_field_info *hfinfo;
3676 field_info *new_fi;
3677 uint64_t value;
3678
3679 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", 3679, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3679,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3679, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3680
3681 switch (hfinfo->type) {
3682 case FT_UINT40:
3683 case FT_UINT48:
3684 case FT_UINT56:
3685 case FT_UINT64:
3686 break;
3687 default:
3688 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)
3689 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3690 }
3691
3692 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3693 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3694 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3695 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3696 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3697 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3698 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3699
3700 if (encoding & ENC_STRING0x03000000) {
3701 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3702 }
3703 /* I believe it's ok if this is called with a NULL tree */
3704 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3705 tvb_get_varint(tvb, start, length, &value, encoding);
3706 } else {
3707 value = get_uint64_value(tree, tvb, start, length, encoding);
3708 }
3709
3710 if (retval) {
3711 *retval = value;
3712 if (hfinfo->bitmask) {
3713 /* Mask out irrelevant portions */
3714 *retval &= hfinfo->bitmask;
3715 /* Shift bits */
3716 *retval >>= hfinfo_bitshift(hfinfo);
3717 }
3718 }
3719
3720 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3721
3722 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", 3722
, __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", 3722, "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", 3722, "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", 3722, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3723
3724 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3725
3726 proto_tree_set_uint64(new_fi, value);
3727
3728 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3729 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3730 new_fi->flags |= FI_VARINT0x00040000;
3731 }
3732
3733 return proto_tree_add_node(tree, new_fi);
3734}
3735
3736proto_item *
3737proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3738 const int start, int length, const unsigned encoding, int64_t *retval)
3739{
3740 header_field_info *hfinfo;
3741 field_info *new_fi;
3742 int64_t value;
3743
3744 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", 3744, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3744,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3744, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3745
3746 switch (hfinfo->type) {
3747 case FT_INT40:
3748 case FT_INT48:
3749 case FT_INT56:
3750 case FT_INT64:
3751 break;
3752 default:
3753 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)
3754 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3755 }
3756
3757 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3758 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3759 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3760 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3761 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3762 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3763 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3764
3765 if (encoding & ENC_STRING0x03000000) {
3766 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3767 }
3768 /* I believe it's ok if this is called with a NULL tree */
3769 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3770 tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3771 }
3772 else {
3773 value = get_int64_value(tree, tvb, start, length, encoding);
3774 }
3775
3776 if (retval) {
3777 *retval = value;
3778 }
3779
3780 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3781
3782 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", 3782
, __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", 3782, "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", 3782, "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", 3782, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3783
3784 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3785
3786 proto_tree_set_int64(new_fi, value);
3787
3788 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3789 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3790 new_fi->flags |= FI_VARINT0x00040000;
3791 }
3792
3793 return proto_tree_add_node(tree, new_fi);
3794}
3795
3796proto_item *
3797proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3798 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3799{
3800 header_field_info *hfinfo;
3801 field_info *new_fi;
3802 uint64_t value;
3803
3804 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", 3804, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3804,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3804, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3805
3806 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
))
)) {
3807 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)
3808 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3809 }
3810
3811 /* length validation for native number encoding caught by get_uint64_value() */
3812 /* length has to be -1 or > 0 regardless of encoding */
3813 if (length == 0)
3814 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)
3815 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3816
3817 if (encoding & ENC_STRING0x03000000) {
3818 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3819 }
3820
3821 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3822
3823 if (retval) {
3824 *retval = value;
3825 if (hfinfo->bitmask) {
3826 /* Mask out irrelevant portions */
3827 *retval &= hfinfo->bitmask;
3828 /* Shift bits */
3829 *retval >>= hfinfo_bitshift(hfinfo);
3830 }
3831 }
3832
3833 if (lenretval) {
3834 *lenretval = length;
3835 }
3836
3837 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3838
3839 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", 3839
, __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", 3839, "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", 3839, "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", 3839, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3840
3841 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3842
3843 proto_tree_set_uint64(new_fi, value);
3844
3845 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3846 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3847 new_fi->flags |= FI_VARINT0x00040000;
3848 }
3849
3850 return proto_tree_add_node(tree, new_fi);
3851
3852}
3853
3854proto_item *
3855proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3856 const int start, int length,
3857 const unsigned encoding, bool_Bool *retval)
3858{
3859 header_field_info *hfinfo;
3860 field_info *new_fi;
3861 uint64_t value, bitval;
3862
3863 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", 3863, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3863,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3863, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3864
3865 if (hfinfo->type != FT_BOOLEAN) {
3866 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)
3867 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3868 }
3869
3870 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3871 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3872 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3873 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3874 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3875 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3876 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3877
3878 if (encoding & ENC_STRING0x03000000) {
3879 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3880 }
3881 /* I believe it's ok if this is called with a NULL tree */
3882 value = get_uint64_value(tree, tvb, start, length, encoding);
3883
3884 if (retval) {
3885 bitval = value;
3886 if (hfinfo->bitmask) {
3887 /* Mask out irrelevant portions */
3888 bitval &= hfinfo->bitmask;
3889 }
3890 *retval = (bitval != 0);
3891 }
3892
3893 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3894
3895 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", 3895
, __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", 3895, "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", 3895, "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", 3895, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3896
3897 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3898
3899 proto_tree_set_boolean(new_fi, value);
3900
3901 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3902
3903 return proto_tree_add_node(tree, new_fi);
3904}
3905
3906proto_item *
3907proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3908 const int start, int length,
3909 const unsigned encoding, float *retval)
3910{
3911 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3912 field_info *new_fi;
3913 float value;
3914
3915 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", 3915,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3916
3917 if (hfinfo->type != FT_FLOAT) {
3918 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)
;
3919 }
3920
3921 if (length != 4) {
3922 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3923 }
3924
3925 /* treat any nonzero encoding as little endian for backwards compatibility */
3926 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3927 if (retval) {
3928 *retval = value;
3929 }
3930
3931 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3932
3933 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", 3933
, __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", 3933, "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", 3933, "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", 3933, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3934
3935 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3936 if (encoding) {
3937 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3938 }
3939
3940 proto_tree_set_float(new_fi, value);
3941
3942 return proto_tree_add_node(tree, new_fi);
3943}
3944
3945proto_item *
3946proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3947 const int start, int length,
3948 const unsigned encoding, double *retval)
3949{
3950 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3951 field_info *new_fi;
3952 double value;
3953
3954 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", 3954,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3955
3956 if (hfinfo->type != FT_DOUBLE) {
3957 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)
;
3958 }
3959
3960 if (length != 8) {
3961 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3962 }
3963
3964 /* treat any nonzero encoding as little endian for backwards compatibility */
3965 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3966 if (retval) {
3967 *retval = value;
3968 }
3969
3970 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3971
3972 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", 3972
, __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", 3972, "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", 3972, "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", 3972, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3973
3974 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3975 if (encoding) {
3976 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3977 }
3978
3979 proto_tree_set_double(new_fi, value);
3980
3981 return proto_tree_add_node(tree, new_fi);
3982}
3983
3984proto_item *
3985proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3986 const int start, int length,
3987 const unsigned encoding, ws_in4_addr *retval)
3988{
3989 header_field_info *hfinfo;
3990 field_info *new_fi;
3991 ws_in4_addr value;
3992
3993 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", 3993, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3993,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3993, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3994
3995 switch (hfinfo->type) {
3996 case FT_IPv4:
3997 break;
3998 default:
3999 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)
4000 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
4001 }
4002
4003 if (length != FT_IPv4_LEN4)
4004 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)
4005 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
4006
4007 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4008 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4009 }
4010
4011 /*
4012 * NOTE: to support code written when proto_tree_add_item() took
4013 * a bool as its last argument, with false meaning "big-endian"
4014 * and true meaning "little-endian", we treat any non-zero value
4015 * of "encoding" as meaning "little-endian".
4016 */
4017 value = tvb_get_ipv4(tvb, start);
4018 if (encoding)
4019 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))))
;
4020
4021 if (retval) {
4022 *retval = value;
4023 }
4024
4025 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4026
4027 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", 4027
, __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", 4027, "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", 4027, "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", 4027, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4028
4029 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4030
4031 proto_tree_set_ipv4(new_fi, value);
4032
4033 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4034 return proto_tree_add_node(tree, new_fi);
4035}
4036
4037proto_item *
4038proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4039 const int start, int length,
4040 const unsigned encoding, ws_in6_addr *addr)
4041{
4042 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4043 field_info *new_fi;
4044
4045 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", 4045,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4046
4047 switch (hfinfo->type) {
4048 case FT_IPv6:
4049 break;
4050 default:
4051 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)
4052 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4053 }
4054
4055 if (length != FT_IPv6_LEN16)
4056 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)
4057 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4058
4059 if (encoding) {
4060 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"
)
;
4061 }
4062
4063 tvb_get_ipv6(tvb, start, addr);
4064
4065 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4066
4067 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", 4067
, __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", 4067, "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", 4067, "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", 4067, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4068
4069 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4070
4071 proto_tree_set_ipv6(new_fi, addr);
4072
4073 return proto_tree_add_node(tree, new_fi);
4074}
4075
4076proto_item *
4077proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4078 const int start, int length, const unsigned encoding, uint8_t *retval) {
4079
4080 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4081 field_info *new_fi;
4082
4083 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", 4083,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4084
4085 switch (hfinfo->type) {
4086 case FT_ETHER:
4087 break;
4088 default:
4089 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)
4090 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4091 }
4092
4093 if (length != FT_ETHER_LEN6)
4094 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)
4095 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4096
4097 if (encoding) {
4098 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"
)
;
4099 }
4100
4101 tvb_memcpy(tvb, retval, start, length);
4102
4103 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4104
4105 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", 4105
, __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", 4105, "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", 4105, "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", 4105, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4106
4107 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4108
4109 proto_tree_set_ether(new_fi, retval);
4110
4111 return proto_tree_add_node(tree, new_fi);
4112}
4113
4114
4115proto_item *
4116proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4117 tvbuff_t *tvb,
4118 const int start, int length,
4119 const unsigned encoding,
4120 wmem_allocator_t *scope,
4121 const uint8_t **retval,
4122 int *lenretval)
4123{
4124 proto_item *pi;
4125 header_field_info *hfinfo;
4126 field_info *new_fi;
4127 const uint8_t *value;
4128
4129 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", 4129, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4129,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4129, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4130
4131 switch (hfinfo->type) {
4132 case FT_STRING:
4133 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4134 break;
4135 case FT_STRINGZ:
4136 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4137 break;
4138 case FT_UINT_STRING:
4139 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4140 break;
4141 case FT_STRINGZPAD:
4142 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4143 break;
4144 case FT_STRINGZTRUNC:
4145 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4146 break;
4147 default:
4148 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)
4149 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)
;
4150 }
4151
4152 if (retval)
4153 *retval = value;
4154
4155 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4156
4157 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", 4157
, __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", 4157, "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", 4157, "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", 4157, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4158
4159 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4160
4161 proto_tree_set_string(new_fi, (const char*)value);
4162
4163 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4164
4165 pi = proto_tree_add_node(tree, new_fi);
4166
4167 switch (hfinfo->type) {
4168
4169 case FT_STRINGZ:
4170 case FT_STRINGZPAD:
4171 case FT_STRINGZTRUNC:
4172 case FT_UINT_STRING:
4173 break;
4174
4175 case FT_STRING:
4176 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4177 break;
4178
4179 default:
4180 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4180
, __func__, "assertion \"not reached\" failed")
;
4181 }
4182
4183 return pi;
4184}
4185
4186proto_item *
4187proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4188 const int start, int length,
4189 const unsigned encoding, wmem_allocator_t *scope,
4190 const uint8_t **retval)
4191{
4192 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4193 tvb, start, length, encoding, scope, retval, &length);
4194}
4195
4196proto_item *
4197proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4198 tvbuff_t *tvb,
4199 const int start, int length,
4200 const unsigned encoding,
4201 wmem_allocator_t *scope,
4202 char **retval,
4203 int *lenretval)
4204{
4205 proto_item *pi;
4206 header_field_info *hfinfo;
4207 field_info *new_fi;
4208 const uint8_t *value;
4209 uint32_t n = 0;
4210
4211 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", 4211, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4211,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4211, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4212
4213 switch (hfinfo->type) {
4214 case FT_STRING:
4215 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4216 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4217 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4218 break;
4219 case FT_STRINGZ:
4220 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4221 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4222 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4223 break;
4224 case FT_UINT_STRING:
4225 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4226 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4227 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4228 break;
4229 case FT_STRINGZPAD:
4230 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4231 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4232 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4233 break;
4234 case FT_STRINGZTRUNC:
4235 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4236 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4237 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4238 break;
4239 case FT_BYTES:
4240 tvb_ensure_bytes_exist(tvb, start, length);
4241 value = tvb_get_ptr(tvb, start, length);
4242 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4243 *lenretval = length;
4244 break;
4245 case FT_UINT_BYTES:
4246 n = get_uint_value(tree, tvb, start, length, encoding);
4247 tvb_ensure_bytes_exist(tvb, start + length, n);
4248 value = tvb_get_ptr(tvb, start + length, n);
4249 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4250 *lenretval = length + n;
4251 break;
4252 default:
4253 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)
4254 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)
;
4255 }
4256
4257 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4258
4259 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", 4259
, __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", 4259, "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", 4259, "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", 4259, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4260
4261 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4262
4263 switch (hfinfo->type) {
4264
4265 case FT_STRING:
4266 case FT_STRINGZ:
4267 case FT_UINT_STRING:
4268 case FT_STRINGZPAD:
4269 case FT_STRINGZTRUNC:
4270 proto_tree_set_string(new_fi, (const char*)value);
4271 break;
4272
4273 case FT_BYTES:
4274 proto_tree_set_bytes(new_fi, value, length);
4275 break;
4276
4277 case FT_UINT_BYTES:
4278 proto_tree_set_bytes(new_fi, value, n);
4279 break;
4280
4281 default:
4282 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4282
, __func__, "assertion \"not reached\" failed")
;
4283 }
4284
4285 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4286
4287 pi = proto_tree_add_node(tree, new_fi);
4288
4289 switch (hfinfo->type) {
4290
4291 case FT_STRINGZ:
4292 case FT_STRINGZPAD:
4293 case FT_STRINGZTRUNC:
4294 case FT_UINT_STRING:
4295 break;
4296
4297 case FT_STRING:
4298 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4299 break;
4300
4301 case FT_BYTES:
4302 case FT_UINT_BYTES:
4303 break;
4304
4305 default:
4306 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4306
, __func__, "assertion \"not reached\" failed")
;
4307 }
4308
4309 return pi;
4310}
4311
4312proto_item *
4313proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4314 tvbuff_t *tvb,
4315 const int start, int length,
4316 const unsigned encoding,
4317 wmem_allocator_t *scope,
4318 char **retval)
4319{
4320 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4321 tvb, start, length, encoding, scope, retval, &length);
4322}
4323
4324proto_item *
4325proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4326 tvbuff_t *tvb,
4327 const int start, int length, const unsigned encoding,
4328 wmem_allocator_t *scope, char **retval)
4329{
4330 header_field_info *hfinfo;
4331 field_info *new_fi;
4332 nstime_t time_stamp;
4333 int flags;
4334
4335 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", 4335, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4335,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4335, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4336
4337 switch (hfinfo->type) {
4338 case FT_ABSOLUTE_TIME:
4339 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4340 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4341 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4342 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4343 }
4344 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4345 break;
4346 case FT_RELATIVE_TIME:
4347 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4348 *retval = rel_time_to_secs_str(scope, &time_stamp);
4349 break;
4350 default:
4351 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)
4352 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4353 }
4354
4355 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4356
4357 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", 4357
, __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", 4357, "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", 4357, "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", 4357, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4358
4359 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4360
4361 switch (hfinfo->type) {
4362
4363 case FT_ABSOLUTE_TIME:
4364 case FT_RELATIVE_TIME:
4365 proto_tree_set_time(new_fi, &time_stamp);
4366 break;
4367 default:
4368 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4368
, __func__, "assertion \"not reached\" failed")
;
4369 }
4370
4371 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4372
4373 return proto_tree_add_node(tree, new_fi);
4374}
4375
4376/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4377 and returns proto_item* */
4378proto_item *
4379ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4380 const unsigned encoding)
4381{
4382 field_info *new_fi;
4383 header_field_info *hfinfo;
4384 int item_length;
4385 int offset;
4386
4387 offset = ptvc->offset;
4388 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", 4388, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4388,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4388, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4389 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4390 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4391
4392 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4393
4394 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4395
4396 /* Coast clear. Try and fake it */
4397 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", 4397
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4397, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4397, "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", 4397, __func__, "Adding %s would put more than %d 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); } } }
;
4398
4399 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4400
4401 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4402 offset, length, encoding);
4403}
4404
4405/* Add an item to a proto_tree, using the text label registered to that item;
4406 the item is extracted from the tvbuff handed to it. */
4407proto_item *
4408proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4409 const int start, int length, const unsigned encoding)
4410{
4411 field_info *new_fi;
4412 int item_length;
4413
4414 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", 4414,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4415
4416 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4417 test_length(hfinfo, tvb, start, item_length, encoding);
4418
4419 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4420
4421 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", 4421
, __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", 4421, "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", 4421, "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", 4421, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4422
4423 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4424
4425 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4426}
4427
4428proto_item *
4429proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4430 const int start, int length, const unsigned encoding)
4431{
4432 register header_field_info *hfinfo;
4433
4434 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", 4434, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4434,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4434, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4435 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4436}
4437
4438/* Add an item to a proto_tree, using the text label registered to that item;
4439 the item is extracted from the tvbuff handed to it.
4440
4441 Return the length of the item through the pointer. */
4442proto_item *
4443proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4444 tvbuff_t *tvb, const int start,
4445 int length, const unsigned encoding,
4446 int *lenretval)
4447{
4448 field_info *new_fi;
4449 int item_length;
4450 proto_item *item;
4451
4452 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", 4452,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4453
4454 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4455 test_length(hfinfo, tvb, start, item_length, encoding);
4456
4457 if (!tree) {
4458 /*
4459 * We need to get the correct item length here.
4460 * That's normally done by proto_tree_new_item(),
4461 * but we won't be calling it.
4462 */
4463 *lenretval = get_full_length(hfinfo, tvb, start, length,
4464 item_length, encoding);
4465 return NULL((void*)0);
4466 }
4467
4468 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", 4475
, __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", 4475, "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", 4475, "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", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4469 /*((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", 4475
, __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", 4475, "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", 4475, "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", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4470 * 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", 4475
, __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", 4475, "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", 4475, "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", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4471 * 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", 4475
, __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", 4475, "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", 4475, "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", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4472 */((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", 4475
, __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", 4475, "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", 4475, "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", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4473 *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", 4475
, __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", 4475, "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", 4475, "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", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4474 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", 4475
, __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", 4475, "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", 4475, "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", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4475 })((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", 4475
, __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", 4475, "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", 4475, "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", 4475
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4476
4477 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4478
4479 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4480 *lenretval = new_fi->length;
4481 return item;
4482}
4483
4484proto_item *
4485proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4486 const int start, int length,
4487 const unsigned encoding, int *lenretval)
4488{
4489 register header_field_info *hfinfo;
4490
4491 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", 4491, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4491,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4491, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4492 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4493}
4494
4495/* which FT_ types can use proto_tree_add_bytes_item() */
4496static inline bool_Bool
4497validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4498{
4499 return (type == FT_BYTES ||
4500 type == FT_UINT_BYTES ||
4501 type == FT_OID ||
4502 type == FT_REL_OID ||
4503 type == FT_SYSTEM_ID );
4504}
4505
4506/* Note: this does no validation that the byte array of an FT_OID or
4507 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4508 so I think it's ok to continue not validating it?
4509 */
4510proto_item *
4511proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4512 const unsigned start, unsigned length,
4513 const unsigned encoding,
4514 GByteArray *retval, unsigned *endoff, int *err)
4515{
4516 field_info *new_fi;
4517 GByteArray *bytes = retval;
4518 GByteArray *created_bytes = NULL((void*)0);
4519 bool_Bool failed = false0;
4520 uint32_t n = 0;
4521 header_field_info *hfinfo;
4522 bool_Bool generate = (bytes || tree) ? true1 : false0;
4523
4524 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", 4524, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4524,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4524, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4525
4526 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", 4526,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4527
4528 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", 4529, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4529 "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", 4529, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4530
4531 if (length == 0) {
4532 return NULL((void*)0);
4533 }
4534
4535 if (encoding & ENC_STR_NUM0x01000000) {
4536 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"
)
;
4537 }
4538
4539 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4540 if (hfinfo->type == FT_UINT_BYTES) {
4541 /* can't decode FT_UINT_BYTES from strings */
4542 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")
4543 "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")
;
4544 }
4545
4546 unsigned hex_encoding = encoding;
4547 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4548 /* If none of the separator values are used,
4549 * assume no separator (the common case). */
4550 hex_encoding |= ENC_SEP_NONE0x00010000;
4551#if 0
4552 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")
4553 "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")
;
4554#endif
4555 }
4556
4557 if (!bytes) {
4558 /* caller doesn't care about return value, but we need it to
4559 call tvb_get_string_bytes() and set the tree later */
4560 bytes = created_bytes = g_byte_array_new();
4561 }
4562
4563 /*
4564 * bytes might be NULL after this, but can't add expert
4565 * error until later; if it's NULL, just note that
4566 * it failed.
4567 */
4568 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4569 if (bytes == NULL((void*)0))
4570 failed = true1;
4571 }
4572 else if (generate) {
4573 tvb_ensure_bytes_exist(tvb, start, length);
4574
4575 if (hfinfo->type == FT_UINT_BYTES) {
4576 n = length; /* n is now the "header" length */
4577 length = get_uint_value(tree, tvb, start, n, encoding);
4578 /* length is now the value's length; only store the value in the array */
4579 tvb_ensure_bytes_exist(tvb, start + n, length);
4580 if (!bytes) {
4581 /* caller doesn't care about return value, but
4582 * we may need it to set the tree later */
4583 bytes = created_bytes = g_byte_array_new();
4584 }
4585 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4586 }
4587 else if (length > 0) {
4588 if (!bytes) {
4589 /* caller doesn't care about return value, but
4590 * we may need it to set the tree later */
4591 bytes = created_bytes = g_byte_array_new();
4592 }
4593 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4594 }
4595
4596 if (endoff)
4597 *endoff = start + n + length;
4598 }
4599
4600 if (err)
4601 *err = failed ? EINVAL22 : 0;
4602
4603 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); }
4604 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4605 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); }
4606 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); }
4607 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); }
4608 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4609 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4610
4611 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", 4617
, __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", 4617, "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", 4617, "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", 4617
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4612 {((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", 4617
, __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", 4617, "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", 4617, "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", 4617
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4613 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", 4617
, __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", 4617, "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", 4617, "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", 4617
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4614 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", 4617
, __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", 4617, "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", 4617, "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", 4617
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4615 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", 4617
, __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", 4617, "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", 4617, "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", 4617
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4616 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", 4617
, __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", 4617, "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", 4617, "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", 4617
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4617 } )((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", 4617
, __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", 4617, "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", 4617, "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", 4617
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4618
4619 /* n will be zero except when it's a FT_UINT_BYTES */
4620 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4621
4622 if (encoding & ENC_STRING0x03000000) {
4623 if (failed)
4624 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4625
4626 if (bytes)
4627 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4628 else
4629 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4630
4631 if (created_bytes)
4632 g_byte_array_free(created_bytes, true1);
4633 }
4634 else {
4635 /* n will be zero except when it's a FT_UINT_BYTES */
4636 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4637
4638 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4639 * use the byte array created above in this case.
4640 */
4641 if (created_bytes)
4642 g_byte_array_free(created_bytes, true1);
4643
4644 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4645 (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)
;
4646 }
4647
4648 return proto_tree_add_node(tree, new_fi);
4649}
4650
4651
4652proto_item *
4653proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4654 const unsigned start, const unsigned length,
4655 const unsigned encoding,
4656 nstime_t *retval, unsigned *endoff, int *err)
4657{
4658 field_info *new_fi;
4659 nstime_t time_stamp;
4660 int saved_err = 0;
4661 header_field_info *hfinfo;
4662
4663 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", 4663, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4663,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4663, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4664
4665 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", 4665,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4666
4667 if (length == 0) {
4668 if(retval) {
4669 nstime_set_zero(retval);
4670 }
4671 return NULL((void*)0);
4672 }
4673
4674 nstime_set_zero(&time_stamp);
4675
4676 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4677 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", 4677, ((hfinfo))->abbrev))))
;
4678 /* The only string format that could be a relative time is
4679 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4680 * relative to "now" currently.
4681 */
4682 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4683 saved_err = EINVAL22;
4684 }
4685 else {
4686 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", 4686, ((hfinfo))->abbrev))))
;
4687 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4688
4689 tvb_ensure_bytes_exist(tvb, start, length);
4690 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4691 if (endoff) *endoff = start + length;
4692 }
4693
4694 if (err) *err = saved_err;
4695
4696 if (retval) {
4697 retval->secs = time_stamp.secs;
4698 retval->nsecs = time_stamp.nsecs;
4699 }
4700
4701 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4702
4703 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", 4703
, __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", 4703, "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", 4703, "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", 4703, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4704
4705 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4706
4707 proto_tree_set_time(new_fi, &time_stamp);
4708
4709 if (encoding & ENC_STRING0x03000000) {
4710 if (saved_err)
4711 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4712 }
4713 else {
4714 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4715 (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)
;
4716 }
4717
4718 return proto_tree_add_node(tree, new_fi);
4719}
4720
4721/* Add a FT_NONE to a proto_tree */
4722proto_item *
4723proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4724 const int start, int length, const char *format,
4725 ...)
4726{
4727 proto_item *pi;
4728 va_list ap;
4729 header_field_info *hfinfo;
4730
4731 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4732
4733 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", 4733
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4733, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4733, "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", 4733, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4734
4735 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", 4735
, ((hfinfo))->abbrev))))
;
4736
4737 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4738
4739 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4739, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4740
4741 va_start(ap, format)__builtin_va_start(ap, format);
4742 proto_tree_set_representation(pi, format, ap);
4743 va_end(ap)__builtin_va_end(ap);
4744
4745 /* no value to set for FT_NONE */
4746 return pi;
4747}
4748
4749/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4750 * offset, and returns proto_item* */
4751proto_item *
4752ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4753 const unsigned encoding)
4754{
4755 proto_item *item;
4756
4757 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4758 length, encoding);
4759
4760 return item;
4761}
4762
4763/* Advance the ptvcursor's offset within its tvbuff without
4764 * adding anything to the proto_tree. */
4765void
4766ptvcursor_advance(ptvcursor_t* ptvc, int length)
4767{
4768 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4769 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4770 }
4771}
4772
4773
4774static void
4775proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4776{
4777 fvalue_set_protocol(fi->value, tvb, field_data, length);
4778}
4779
4780/* Add a FT_PROTOCOL to a proto_tree */
4781proto_item *
4782proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4783 int start, int length, const char *format, ...)
4784{
4785 proto_item *pi;
4786 tvbuff_t *protocol_tvb;
4787 va_list ap;
4788 header_field_info *hfinfo;
4789 char* protocol_rep;
4790
4791 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4792
4793 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", 4793
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4793, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4793, "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", 4793, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4794
4795 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"
, 4795, ((hfinfo))->abbrev))))
;
4796
4797 /*
4798 * This can throw an exception, so do it before we allocate anything.
4799 */
4800 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4801
4802 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4803
4804 va_start(ap, format)__builtin_va_start(ap, format);
4805 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4806 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4807 g_free(protocol_rep);
4808 va_end(ap)__builtin_va_end(ap);
4809
4810 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4810, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4811
4812 va_start(ap, format)__builtin_va_start(ap, format);
4813 proto_tree_set_representation(pi, format, ap);
4814 va_end(ap)__builtin_va_end(ap);
4815
4816 return pi;
4817}
4818
4819/* Add a FT_BYTES to a proto_tree */
4820proto_item *
4821proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4822 int length, const uint8_t *start_ptr)
4823{
4824 proto_item *pi;
4825 header_field_info *hfinfo;
4826 int item_length;
4827
4828 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", 4828, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4828,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4828, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4829 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4830 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4831
4832 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4833
4834 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", 4834
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4834, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4834, "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", 4834, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4835
4836 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",
4836, ((hfinfo))->abbrev))))
;
4837
4838 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4839 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4840
4841 return pi;
4842}
4843
4844/* Add a FT_BYTES to a proto_tree */
4845proto_item *
4846proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4847 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4848{
4849 proto_item *pi;
4850 header_field_info *hfinfo;
4851 int item_length;
4852
4853 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", 4853, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4853,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4853, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4854 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4855 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4856
4857 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4858
4859 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", 4859
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4859, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4859, "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", 4859, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4860
4861 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",
4861, ((hfinfo))->abbrev))))
;
4862
4863 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4864 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4865
4866 return pi;
4867}
4868
4869proto_item *
4870proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4871 int start, int length,
4872 const uint8_t *start_ptr,
4873 const char *format, ...)
4874{
4875 proto_item *pi;
4876 va_list ap;
4877
4878 if (start_ptr == NULL((void*)0))
4879 start_ptr = tvb_get_ptr(tvb, start, length);
4880
4881 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4882
4883 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; }
;
4884
4885 va_start(ap, format)__builtin_va_start(ap, format);
4886 proto_tree_set_representation_value(pi, format, ap);
4887 va_end(ap)__builtin_va_end(ap);
4888
4889 return pi;
4890}
4891
4892proto_item *
4893proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4894 int start, int length, const uint8_t *start_ptr,
4895 const char *format, ...)
4896{
4897 proto_item *pi;
4898 va_list ap;
4899
4900 if (start_ptr == NULL((void*)0))
4901 start_ptr = tvb_get_ptr(tvb, start, length);
4902
4903 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4904
4905 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; }
;
4906
4907 va_start(ap, format)__builtin_va_start(ap, format);
4908 proto_tree_set_representation(pi, format, ap);
4909 va_end(ap)__builtin_va_end(ap);
4910
4911 return pi;
4912}
4913
4914static void
4915proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4916{
4917 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4917, "length >= 0"
))))
;
4918 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", 4918, "start_ptr != ((void*)0) || length == 0"
))))
;
4919
4920 fvalue_set_bytes_data(fi->value, start_ptr, length);
4921}
4922
4923
4924static void
4925proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4926{
4927 tvb_ensure_bytes_exist(tvb, offset, length);
4928 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4929}
4930
4931static void
4932proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4933{
4934 GByteArray *bytes;
4935
4936 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4936, "value != ((void*)0)"
))))
;
4937
4938 bytes = byte_array_dup(value);
4939
4940 fvalue_set_byte_array(fi->value, bytes);
4941}
4942
4943/* Add a FT_*TIME to a proto_tree */
4944proto_item *
4945proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4946 int length, const nstime_t *value_ptr)
4947{
4948 proto_item *pi;
4949 header_field_info *hfinfo;
4950
4951 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4952
4953 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", 4953
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4953, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4953, "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", 4953, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4954
4955 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", 4955, ((hfinfo))->abbrev))))
;
4956
4957 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4958 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4959
4960 return pi;
4961}
4962
4963proto_item *
4964proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4965 int start, int length, nstime_t *value_ptr,
4966 const char *format, ...)
4967{
4968 proto_item *pi;
4969 va_list ap;
4970
4971 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4972 if (pi != tree) {
4973 va_start(ap, format)__builtin_va_start(ap, format);
4974 proto_tree_set_representation_value(pi, format, ap);
4975 va_end(ap)__builtin_va_end(ap);
4976 }
4977
4978 return pi;
4979}
4980
4981proto_item *
4982proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4983 int start, int length, nstime_t *value_ptr,
4984 const char *format, ...)
4985{
4986 proto_item *pi;
4987 va_list ap;
4988
4989 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4990 if (pi != tree) {
4991 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4991, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4992
4993 va_start(ap, format)__builtin_va_start(ap, format);
4994 proto_tree_set_representation(pi, format, ap);
4995 va_end(ap)__builtin_va_end(ap);
4996 }
4997
4998 return pi;
4999}
5000
5001/* Set the FT_*TIME value */
5002static void
5003proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5004{
5005 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5005, "value_ptr != ((void*)0)"
))))
;
5006
5007 fvalue_set_time(fi->value, value_ptr);
5008}
5009
5010/* Add a FT_IPXNET to a proto_tree */
5011proto_item *
5012proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5013 int length, uint32_t value)
5014{
5015 proto_item *pi;
5016 header_field_info *hfinfo;
5017
5018 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5019
5020 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", 5020
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5020, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5020, "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", 5020, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5021
5022 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"
, 5022, ((hfinfo))->abbrev))))
;
5023
5024 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5025 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5026
5027 return pi;
5028}
5029
5030proto_item *
5031proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5032 int start, int length, uint32_t value,
5033 const char *format, ...)
5034{
5035 proto_item *pi;
5036 va_list ap;
5037
5038 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5039 if (pi != tree) {
5040 va_start(ap, format)__builtin_va_start(ap, format);
5041 proto_tree_set_representation_value(pi, format, ap);
5042 va_end(ap)__builtin_va_end(ap);
5043 }
5044
5045 return pi;
5046}
5047
5048proto_item *
5049proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5050 int start, int length, uint32_t value,
5051 const char *format, ...)
5052{
5053 proto_item *pi;
5054 va_list ap;
5055
5056 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5057 if (pi != tree) {
5058 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5058, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5059
5060 va_start(ap, format)__builtin_va_start(ap, format);
5061 proto_tree_set_representation(pi, format, ap);
5062 va_end(ap)__builtin_va_end(ap);
5063 }
5064
5065 return pi;
5066}
5067
5068/* Set the FT_IPXNET value */
5069static void
5070proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5071{
5072 fvalue_set_uinteger(fi->value, value);
5073}
5074
5075/* Add a FT_IPv4 to a proto_tree */
5076proto_item *
5077proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5078 int length, ws_in4_addr value)
5079{
5080 proto_item *pi;
5081 header_field_info *hfinfo;
5082
5083 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5084
5085 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", 5085
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5085, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5085, "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", 5085, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5086
5087 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", 5087
, ((hfinfo))->abbrev))))
;
5088
5089 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5090 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5091
5092 return pi;
5093}
5094
5095proto_item *
5096proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5097 int start, int length, ws_in4_addr value,
5098 const char *format, ...)
5099{
5100 proto_item *pi;
5101 va_list ap;
5102
5103 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5104 if (pi != tree) {
5105 va_start(ap, format)__builtin_va_start(ap, format);
5106 proto_tree_set_representation_value(pi, format, ap);
5107 va_end(ap)__builtin_va_end(ap);
5108 }
5109
5110 return pi;
5111}
5112
5113proto_item *
5114proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5115 int start, int length, ws_in4_addr value,
5116 const char *format, ...)
5117{
5118 proto_item *pi;
5119 va_list ap;
5120
5121 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5122 if (pi != tree) {
5123 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5123, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5124
5125 va_start(ap, format)__builtin_va_start(ap, format);
5126 proto_tree_set_representation(pi, format, ap);
5127 va_end(ap)__builtin_va_end(ap);
5128 }
5129
5130 return pi;
5131}
5132
5133/* Set the FT_IPv4 value */
5134static void
5135proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5136{
5137 ipv4_addr_and_mask ipv4;
5138 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5139 fvalue_set_ipv4(fi->value, &ipv4);
5140}
5141
5142/* Add a FT_IPv6 to a proto_tree */
5143proto_item *
5144proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5145 int length, const ws_in6_addr *value)
5146{
5147 proto_item *pi;
5148 header_field_info *hfinfo;
5149
5150 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5151
5152 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", 5152
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5152, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5152, "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", 5152, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5153
5154 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", 5154
, ((hfinfo))->abbrev))))
;
5155
5156 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5157 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5158
5159 return pi;
5160}
5161
5162proto_item *
5163proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5164 int start, int length,
5165 const ws_in6_addr *value_ptr,
5166 const char *format, ...)
5167{
5168 proto_item *pi;
5169 va_list ap;
5170
5171 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5172 if (pi != tree) {
5173 va_start(ap, format)__builtin_va_start(ap, format);
5174 proto_tree_set_representation_value(pi, format, ap);
5175 va_end(ap)__builtin_va_end(ap);
5176 }
5177
5178 return pi;
5179}
5180
5181proto_item *
5182proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5183 int start, int length,
5184 const ws_in6_addr *value_ptr,
5185 const char *format, ...)
5186{
5187 proto_item *pi;
5188 va_list ap;
5189
5190 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5191 if (pi != tree) {
5192 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5192, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5193
5194 va_start(ap, format)__builtin_va_start(ap, format);
5195 proto_tree_set_representation(pi, format, ap);
5196 va_end(ap)__builtin_va_end(ap);
5197 }
5198
5199 return pi;
5200}
5201
5202/* Set the FT_IPv6 value */
5203static void
5204proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5205{
5206 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5206, "value != ((void*)0)"
))))
;
5207 ipv6_addr_and_prefix ipv6;
5208 ipv6.addr = *value;
5209 ipv6.prefix = 128;
5210 fvalue_set_ipv6(fi->value, &ipv6);
5211}
5212
5213static void
5214proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5215{
5216 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5217}
5218
5219/* Set the FT_FCWWN value */
5220static void
5221proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5222{
5223 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5223, "value_ptr != ((void*)0)"
))))
;
5224 fvalue_set_fcwwn(fi->value, value_ptr);
5225}
5226
5227static void
5228proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5229{
5230 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5231}
5232
5233/* Add a FT_GUID to a proto_tree */
5234proto_item *
5235proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5236 int length, const e_guid_t *value_ptr)
5237{
5238 proto_item *pi;
5239 header_field_info *hfinfo;
5240
5241 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5242
5243 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", 5243
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5243, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5243, "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", 5243, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5244
5245 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", 5245
, ((hfinfo))->abbrev))))
;
5246
5247 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5248 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5249
5250 return pi;
5251}
5252
5253proto_item *
5254proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5255 int start, int length,
5256 const e_guid_t *value_ptr,
5257 const char *format, ...)
5258{
5259 proto_item *pi;
5260 va_list ap;
5261
5262 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5263 if (pi != tree) {
5264 va_start(ap, format)__builtin_va_start(ap, format);
5265 proto_tree_set_representation_value(pi, format, ap);
5266 va_end(ap)__builtin_va_end(ap);
5267 }
5268
5269 return pi;
5270}
5271
5272proto_item *
5273proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5274 int start, int length, const e_guid_t *value_ptr,
5275 const char *format, ...)
5276{
5277 proto_item *pi;
5278 va_list ap;
5279
5280 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5281 if (pi != tree) {
5282 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5282, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5283
5284 va_start(ap, format)__builtin_va_start(ap, format);
5285 proto_tree_set_representation(pi, format, ap);
5286 va_end(ap)__builtin_va_end(ap);
5287 }
5288
5289 return pi;
5290}
5291
5292/* Set the FT_GUID value */
5293static void
5294proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5295{
5296 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5296, "value_ptr != ((void*)0)"
))))
;
5297 fvalue_set_guid(fi->value, value_ptr);
5298}
5299
5300static void
5301proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5302 const unsigned encoding)
5303{
5304 e_guid_t guid;
5305
5306 tvb_get_guid(tvb, start, &guid, encoding);
5307 proto_tree_set_guid(fi, &guid);
5308}
5309
5310/* Add a FT_OID to a proto_tree */
5311proto_item *
5312proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5313 int length, const uint8_t* value_ptr)
5314{
5315 proto_item *pi;
5316 header_field_info *hfinfo;
5317
5318 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5319
5320 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", 5320
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5320, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5320, "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", 5320, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5321
5322 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", 5322
, ((hfinfo))->abbrev))))
;
5323
5324 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5325 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5326
5327 return pi;
5328}
5329
5330proto_item *
5331proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5332 int start, int length,
5333 const uint8_t* value_ptr,
5334 const char *format, ...)
5335{
5336 proto_item *pi;
5337 va_list ap;
5338
5339 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5340 if (pi != tree) {
5341 va_start(ap, format)__builtin_va_start(ap, format);
5342 proto_tree_set_representation_value(pi, format, ap);
5343 va_end(ap)__builtin_va_end(ap);
5344 }
5345
5346 return pi;
5347}
5348
5349proto_item *
5350proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5351 int start, int length, const uint8_t* value_ptr,
5352 const char *format, ...)
5353{
5354 proto_item *pi;
5355 va_list ap;
5356
5357 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5358 if (pi != tree) {
5359 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5359, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5360
5361 va_start(ap, format)__builtin_va_start(ap, format);
5362 proto_tree_set_representation(pi, format, ap);
5363 va_end(ap)__builtin_va_end(ap);
5364 }
5365
5366 return pi;
5367}
5368
5369/* Set the FT_OID value */
5370static void
5371proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5372{
5373 GByteArray *bytes;
5374
5375 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", 5375, "value_ptr != ((void*)0) || length == 0"
))))
;
5376
5377 bytes = g_byte_array_new();
5378 if (length > 0) {
5379 g_byte_array_append(bytes, value_ptr, length);
5380 }
5381 fvalue_set_byte_array(fi->value, bytes);
5382}
5383
5384static void
5385proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5386{
5387 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5388}
5389
5390/* Set the FT_SYSTEM_ID value */
5391static void
5392proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5393{
5394 GByteArray *bytes;
5395
5396 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", 5396, "value_ptr != ((void*)0) || length == 0"
))))
;
5397
5398 bytes = g_byte_array_new();
5399 if (length > 0) {
5400 g_byte_array_append(bytes, value_ptr, length);
5401 }
5402 fvalue_set_byte_array(fi->value, bytes);
5403}
5404
5405static void
5406proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5407{
5408 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5409}
5410
5411/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5412 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5413 * is destroyed. */
5414proto_item *
5415proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5416 int length, const char* value)
5417{
5418 proto_item *pi;
5419 header_field_info *hfinfo;
5420 int item_length;
5421
5422 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", 5422, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5422,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5422, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5423 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5424 /*
5425 * Special case - if the length is 0, skip the test, so that
5426 * we can have an empty string right after the end of the
5427 * packet. (This handles URL-encoded forms where the last field
5428 * has no value so the form ends right after the =.)
5429 *
5430 * XXX - length zero makes sense for FT_STRING, and more or less
5431 * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5432 * for FT_STRINGZ (except that a number of fields that should be
5433 * one of the others are actually registered as FT_STRINGZ.)
5434 */
5435 if (item_length != 0)
5436 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5437
5438 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5439
5440 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", 5440
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5440, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5440, "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", 5440, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5441
5442 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", 5442, ((hfinfo))->abbrev))))
;
5443
5444 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5445 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5445, "length >= 0"
))))
;
5446
5447 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", 5447, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5448 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5449
5450 return pi;
5451}
5452
5453proto_item *
5454proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5455 int start, int length, const char* value,
5456 const char *format,
5457 ...)
5458{
5459 proto_item *pi;
5460 va_list ap;
5461
5462 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5463 if (pi != tree) {
5464 va_start(ap, format)__builtin_va_start(ap, format);
5465 proto_tree_set_representation_value(pi, format, ap);
5466 va_end(ap)__builtin_va_end(ap);
5467 }
5468
5469 return pi;
5470}
5471
5472proto_item *
5473proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5474 int start, int length, const char* value,
5475 const char *format, ...)
5476{
5477 proto_item *pi;
5478 va_list ap;
5479
5480 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5481 if (pi != tree) {
5482 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5482, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5483
5484 va_start(ap, format)__builtin_va_start(ap, format);
5485 proto_tree_set_representation(pi, format, ap);
5486 va_end(ap)__builtin_va_end(ap);
5487 }
5488
5489 return pi;
5490}
5491
5492/* Set the FT_STRING value */
5493static void
5494proto_tree_set_string(field_info *fi, const char* value)
5495{
5496 if (value) {
5497 fvalue_set_string(fi->value, value);
5498 } else {
5499 /*
5500 * XXX - why is a null value for a string field
5501 * considered valid?
5502 */
5503 fvalue_set_string(fi->value, "[ Null ]");
5504 }
5505}
5506
5507/* Set the FT_AX25 value */
5508static void
5509proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5510{
5511 fvalue_set_ax25(fi->value, value);
5512}
5513
5514static void
5515proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5516{
5517 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5518}
5519
5520/* Set the FT_VINES value */
5521static void
5522proto_tree_set_vines(field_info *fi, const uint8_t* value)
5523{
5524 fvalue_set_vines(fi->value, value);
5525}
5526
5527static void
5528proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5529{
5530 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5531}
5532
5533/* Add a FT_ETHER to a proto_tree */
5534proto_item *
5535proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5536 int length, const uint8_t* value)
5537{
5538 proto_item *pi;
5539 header_field_info *hfinfo;
5540
5541 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5542
5543 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", 5543
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5543, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5543, "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", 5543, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5544
5545 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",
5545, ((hfinfo))->abbrev))))
;
5546
5547 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5548 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5549
5550 return pi;
5551}
5552
5553proto_item *
5554proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5555 int start, int length, const uint8_t* value,
5556 const char *format, ...)
5557{
5558 proto_item *pi;
5559 va_list ap;
5560
5561 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5562 if (pi != tree) {
5563 va_start(ap, format)__builtin_va_start(ap, format);
5564 proto_tree_set_representation_value(pi, format, ap);
5565 va_end(ap)__builtin_va_end(ap);
5566 }
5567
5568 return pi;
5569}
5570
5571proto_item *
5572proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5573 int start, int length, const uint8_t* value,
5574 const char *format, ...)
5575{
5576 proto_item *pi;
5577 va_list ap;
5578
5579 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5580 if (pi != tree) {
5581 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5581, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5582
5583 va_start(ap, format)__builtin_va_start(ap, format);
5584 proto_tree_set_representation(pi, format, ap);
5585 va_end(ap)__builtin_va_end(ap);
5586 }
5587
5588 return pi;
5589}
5590
5591/* Set the FT_ETHER value */
5592static void
5593proto_tree_set_ether(field_info *fi, const uint8_t* value)
5594{
5595 fvalue_set_ether(fi->value, value);
5596}
5597
5598static void
5599proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5600{
5601 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5602}
5603
5604/* Add a FT_BOOLEAN to a proto_tree */
5605proto_item *
5606proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5607 int length, uint64_t value)
5608{
5609 proto_item *pi;
5610 header_field_info *hfinfo;
5611
5612 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5613
5614 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", 5614
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5614, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5614, "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", 5614, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5615
5616 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"
, 5616, ((hfinfo))->abbrev))))
;
5617
5618 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5619 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5620
5621 return pi;
5622}
5623
5624proto_item *
5625proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5626 tvbuff_t *tvb, int start, int length,
5627 uint64_t value, const char *format, ...)
5628{
5629 proto_item *pi;
5630 va_list ap;
5631
5632 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5633 if (pi != tree) {
5634 va_start(ap, format)__builtin_va_start(ap, format);
5635 proto_tree_set_representation_value(pi, format, ap);
5636 va_end(ap)__builtin_va_end(ap);
5637 }
5638
5639 return pi;
5640}
5641
5642proto_item *
5643proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5644 int start, int length, uint64_t value,
5645 const char *format, ...)
5646{
5647 proto_item *pi;
5648 va_list ap;
5649
5650 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5651 if (pi != tree) {
5652 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5652, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5653
5654 va_start(ap, format)__builtin_va_start(ap, format);
5655 proto_tree_set_representation(pi, format, ap);
5656 va_end(ap)__builtin_va_end(ap);
5657 }
5658
5659 return pi;
5660}
5661
5662/* Set the FT_BOOLEAN value */
5663static void
5664proto_tree_set_boolean(field_info *fi, uint64_t value)
5665{
5666 proto_tree_set_uint64(fi, value);
5667}
5668
5669/* Generate, into "buf", a string showing the bits of a bitfield.
5670 Return a pointer to the character after that string. */
5671static char *
5672other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5673{
5674 int i = 0;
5675 uint64_t bit;
5676 char *p;
5677
5678 p = buf;
5679
5680 /* This is a devel error. It is safer to stop here. */
5681 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5681, "width >= 1"
))))
;
5682
5683 bit = UINT64_C(1)1UL << (width - 1);
5684 for (;;) {
5685 if (mask & bit) {
5686 /* This bit is part of the field. Show its value. */
5687 if (val & bit)
5688 *p++ = '1';
5689 else
5690 *p++ = '0';
5691 } else {
5692 /* This bit is not part of the field. */
5693 *p++ = '.';
5694 }
5695 bit >>= 1;
5696 i++;
5697 if (i >= width)
5698 break;
5699 if (i % 4 == 0)
5700 *p++ = ' ';
5701 }
5702 *p = '\0';
5703 return p;
5704}
5705
5706static char *
5707decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5708{
5709 char *p;
5710
5711 p = other_decode_bitfield_value(buf, val, mask, width);
5712 p = g_stpcpy(p, " = ");
5713
5714 return p;
5715}
5716
5717static char *
5718other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5719{
5720 int i = 0;
5721 uint64_t bit;
5722 char *p;
5723
5724 p = buf;
5725
5726 /* This is a devel error. It is safer to stop here. */
5727 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5727, "width >= 1"
))))
;
5728
5729 bit = UINT64_C(1)1UL << (width - 1);
5730 for (;;) {
5731 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5732 (mask & bit)) {
5733 /* This bit is part of the field. Show its value. */
5734 if (val & bit)
5735 *p++ = '1';
5736 else
5737 *p++ = '0';
5738 } else {
5739 /* This bit is not part of the field. */
5740 *p++ = '.';
5741 }
5742 bit >>= 1;
5743 i++;
5744 if (i >= width)
5745 break;
5746 if (i % 4 == 0)
5747 *p++ = ' ';
5748 }
5749
5750 *p = '\0';
5751 return p;
5752}
5753
5754static char *
5755decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5756{
5757 char *p;
5758
5759 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5760 p = g_stpcpy(p, " = ");
5761
5762 return p;
5763}
5764
5765/* Add a FT_FLOAT to a proto_tree */
5766proto_item *
5767proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5768 int length, float value)
5769{
5770 proto_item *pi;
5771 header_field_info *hfinfo;
5772
5773 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5774
5775 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", 5775
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5775, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5775, "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", 5775, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5776
5777 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",
5777, ((hfinfo))->abbrev))))
;
5778
5779 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5780 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5781
5782 return pi;
5783}
5784
5785proto_item *
5786proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5787 int start, int length, float value,
5788 const char *format, ...)
5789{
5790 proto_item *pi;
5791 va_list ap;
5792
5793 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5794 if (pi != tree) {
5795 va_start(ap, format)__builtin_va_start(ap, format);
5796 proto_tree_set_representation_value(pi, format, ap);
5797 va_end(ap)__builtin_va_end(ap);
5798 }
5799
5800 return pi;
5801}
5802
5803proto_item *
5804proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5805 int start, int length, float value,
5806 const char *format, ...)
5807{
5808 proto_item *pi;
5809 va_list ap;
5810
5811 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5812 if (pi != tree) {
5813 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5813, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5814
5815 va_start(ap, format)__builtin_va_start(ap, format);
5816 proto_tree_set_representation(pi, format, ap);
5817 va_end(ap)__builtin_va_end(ap);
5818 }
5819
5820 return pi;
5821}
5822
5823/* Set the FT_FLOAT value */
5824static void
5825proto_tree_set_float(field_info *fi, float value)
5826{
5827 fvalue_set_floating(fi->value, value);
5828}
5829
5830/* Add a FT_DOUBLE to a proto_tree */
5831proto_item *
5832proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5833 int length, double value)
5834{
5835 proto_item *pi;
5836 header_field_info *hfinfo;
5837
5838 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5839
5840 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", 5840
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5840, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5840, "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", 5840, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5841
5842 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"
, 5842, ((hfinfo))->abbrev))))
;
5843
5844 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5845 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5846
5847 return pi;
5848}
5849
5850proto_item *
5851proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5852 int start, int length, double value,
5853 const char *format, ...)
5854{
5855 proto_item *pi;
5856 va_list ap;
5857
5858 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5859 if (pi != tree) {
5860 va_start(ap, format)__builtin_va_start(ap, format);
5861 proto_tree_set_representation_value(pi, format, ap);
5862 va_end(ap)__builtin_va_end(ap);
5863 }
5864
5865 return pi;
5866}
5867
5868proto_item *
5869proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5870 int start, int length, double value,
5871 const char *format, ...)
5872{
5873 proto_item *pi;
5874 va_list ap;
5875
5876 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5877 if (pi != tree) {
5878 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5878, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5879
5880 va_start(ap, format)__builtin_va_start(ap, format);
5881 proto_tree_set_representation(pi, format, ap);
5882 va_end(ap)__builtin_va_end(ap);
5883 }
5884
5885 return pi;
5886}
5887
5888/* Set the FT_DOUBLE value */
5889static void
5890proto_tree_set_double(field_info *fi, double value)
5891{
5892 fvalue_set_floating(fi->value, value);
5893}
5894
5895/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5896proto_item *
5897proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5898 int length, uint32_t value)
5899{
5900 proto_item *pi = NULL((void*)0);
5901 header_field_info *hfinfo;
5902
5903 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5904
5905 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", 5905
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5905, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5905, "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", 5905, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5906
5907 switch (hfinfo->type) {
5908 case FT_CHAR:
5909 case FT_UINT8:
5910 case FT_UINT16:
5911 case FT_UINT24:
5912 case FT_UINT32:
5913 case FT_FRAMENUM:
5914 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5915 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5916 break;
5917
5918 default:
5919 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)
5920 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)
;
5921 }
5922
5923 return pi;
5924}
5925
5926proto_item *
5927proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5928 int start, int length, uint32_t value,
5929 const char *format, ...)
5930{
5931 proto_item *pi;
5932 va_list ap;
5933
5934 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5935 if (pi != tree) {
5936 va_start(ap, format)__builtin_va_start(ap, format);
5937 proto_tree_set_representation_value(pi, format, ap);
5938 va_end(ap)__builtin_va_end(ap);
5939 }
5940
5941 return pi;
5942}
5943
5944proto_item *
5945proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5946 int start, int length, uint32_t value,
5947 const char *format, ...)
5948{
5949 proto_item *pi;
5950 va_list ap;
5951
5952 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5953 if (pi != tree) {
5954 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5954, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5955
5956 va_start(ap, format)__builtin_va_start(ap, format);
5957 proto_tree_set_representation(pi, format, ap);
5958 va_end(ap)__builtin_va_end(ap);
5959 }
5960
5961 return pi;
5962}
5963
5964/* Set the FT_UINT{8,16,24,32} value */
5965static void
5966proto_tree_set_uint(field_info *fi, uint32_t value)
5967{
5968 const header_field_info *hfinfo;
5969 uint32_t integer;
5970
5971 hfinfo = fi->hfinfo;
5972 integer = value;
5973
5974 if (hfinfo->bitmask) {
5975 /* Mask out irrelevant portions */
5976 integer &= (uint32_t)(hfinfo->bitmask);
5977
5978 /* Shift bits */
5979 integer >>= hfinfo_bitshift(hfinfo);
5980
5981 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5982 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)
;
5983 }
5984
5985 fvalue_set_uinteger(fi->value, integer);
5986}
5987
5988/* Add FT_UINT{40,48,56,64} to a proto_tree */
5989proto_item *
5990proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5991 int length, uint64_t value)
5992{
5993 proto_item *pi = NULL((void*)0);
5994 header_field_info *hfinfo;
5995
5996 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5997
5998 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", 5998
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5998, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5998, "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", 5998, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5999
6000 switch (hfinfo->type) {
6001 case FT_UINT40:
6002 case FT_UINT48:
6003 case FT_UINT56:
6004 case FT_UINT64:
6005 case FT_FRAMENUM:
6006 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6007 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6008 break;
6009
6010 default:
6011 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)
6012 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)
;
6013 }
6014
6015 return pi;
6016}
6017
6018proto_item *
6019proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6020 int start, int length, uint64_t value,
6021 const char *format, ...)
6022{
6023 proto_item *pi;
6024 va_list ap;
6025
6026 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6027 if (pi != tree) {
6028 va_start(ap, format)__builtin_va_start(ap, format);
6029 proto_tree_set_representation_value(pi, format, ap);
6030 va_end(ap)__builtin_va_end(ap);
6031 }
6032
6033 return pi;
6034}
6035
6036proto_item *
6037proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6038 int start, int length, uint64_t value,
6039 const char *format, ...)
6040{
6041 proto_item *pi;
6042 va_list ap;
6043
6044 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6045 if (pi != tree) {
6046 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6046, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6047
6048 va_start(ap, format)__builtin_va_start(ap, format);
6049 proto_tree_set_representation(pi, format, ap);
6050 va_end(ap)__builtin_va_end(ap);
6051 }
6052
6053 return pi;
6054}
6055
6056/* Set the FT_UINT{40,48,56,64} value */
6057static void
6058proto_tree_set_uint64(field_info *fi, uint64_t value)
6059{
6060 const header_field_info *hfinfo;
6061 uint64_t integer;
6062
6063 hfinfo = fi->hfinfo;
6064 integer = value;
6065
6066 if (hfinfo->bitmask) {
6067 /* Mask out irrelevant portions */
6068 integer &= hfinfo->bitmask;
6069
6070 /* Shift bits */
6071 integer >>= hfinfo_bitshift(hfinfo);
6072
6073 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6074 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)
;
6075 }
6076
6077 fvalue_set_uinteger64(fi->value, integer);
6078}
6079
6080/* Add FT_INT{8,16,24,32} to a proto_tree */
6081proto_item *
6082proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6083 int length, int32_t value)
6084{
6085 proto_item *pi = NULL((void*)0);
6086 header_field_info *hfinfo;
6087
6088 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6089
6090 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", 6090
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6090, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6090, "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", 6090, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6091
6092 switch (hfinfo->type) {
6093 case FT_INT8:
6094 case FT_INT16:
6095 case FT_INT24:
6096 case FT_INT32:
6097 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6098 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6099 break;
6100
6101 default:
6102 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)
6103 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6104 }
6105
6106 return pi;
6107}
6108
6109proto_item *
6110proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6111 int start, int length, int32_t value,
6112 const char *format, ...)
6113{
6114 proto_item *pi;
6115 va_list ap;
6116
6117 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6118 if (pi != tree) {
6119 va_start(ap, format)__builtin_va_start(ap, format);
6120 proto_tree_set_representation_value(pi, format, ap);
6121 va_end(ap)__builtin_va_end(ap);
6122 }
6123
6124 return pi;
6125}
6126
6127proto_item *
6128proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6129 int start, int length, int32_t value,
6130 const char *format, ...)
6131{
6132 proto_item *pi;
6133 va_list ap;
6134
6135 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6136 if (pi != tree) {
6137 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6137, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6138
6139 va_start(ap, format)__builtin_va_start(ap, format);
6140 proto_tree_set_representation(pi, format, ap);
6141 va_end(ap)__builtin_va_end(ap);
6142 }
6143
6144 return pi;
6145}
6146
6147/* Set the FT_INT{8,16,24,32} value */
6148static void
6149proto_tree_set_int(field_info *fi, int32_t value)
6150{
6151 const header_field_info *hfinfo;
6152 uint32_t integer;
6153 int no_of_bits;
6154
6155 hfinfo = fi->hfinfo;
6156 integer = (uint32_t) value;
6157
6158 if (hfinfo->bitmask) {
6159 /* Mask out irrelevant portions */
6160 integer &= (uint32_t)(hfinfo->bitmask);
6161
6162 /* Shift bits */
6163 integer >>= hfinfo_bitshift(hfinfo);
6164
6165 no_of_bits = ws_count_ones(hfinfo->bitmask);
6166 integer = ws_sign_ext32(integer, no_of_bits);
6167
6168 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6169 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)
;
6170 }
6171
6172 fvalue_set_sinteger(fi->value, integer);
6173}
6174
6175/* Add FT_INT{40,48,56,64} to a proto_tree */
6176proto_item *
6177proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6178 int length, int64_t value)
6179{
6180 proto_item *pi = NULL((void*)0);
6181 header_field_info *hfinfo;
6182
6183 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6184
6185 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", 6185
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6185, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6185, "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", 6185, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6186
6187 switch (hfinfo->type) {
6188 case FT_INT40:
6189 case FT_INT48:
6190 case FT_INT56:
6191 case FT_INT64:
6192 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6193 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6194 break;
6195
6196 default:
6197 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)
6198 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6199 }
6200
6201 return pi;
6202}
6203
6204proto_item *
6205proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6206 int start, int length, int64_t value,
6207 const char *format, ...)
6208{
6209 proto_item *pi;
6210 va_list ap;
6211
6212 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6213 if (pi != tree) {
6214 va_start(ap, format)__builtin_va_start(ap, format);
6215 proto_tree_set_representation_value(pi, format, ap);
6216 va_end(ap)__builtin_va_end(ap);
6217 }
6218
6219 return pi;
6220}
6221
6222/* Set the FT_INT{40,48,56,64} value */
6223static void
6224proto_tree_set_int64(field_info *fi, int64_t value)
6225{
6226 const header_field_info *hfinfo;
6227 uint64_t integer;
6228 int no_of_bits;
6229
6230 hfinfo = fi->hfinfo;
6231 integer = value;
6232
6233 if (hfinfo->bitmask) {
6234 /* Mask out irrelevant portions */
6235 integer &= hfinfo->bitmask;
6236
6237 /* Shift bits */
6238 integer >>= hfinfo_bitshift(hfinfo);
6239
6240 no_of_bits = ws_count_ones(hfinfo->bitmask);
6241 integer = ws_sign_ext64(integer, no_of_bits);
6242
6243 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6244 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)
;
6245 }
6246
6247 fvalue_set_sinteger64(fi->value, integer);
6248}
6249
6250proto_item *
6251proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6252 int start, int length, int64_t value,
6253 const char *format, ...)
6254{
6255 proto_item *pi;
6256 va_list ap;
6257
6258 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6259 if (pi != tree) {
6260 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6260, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6261
6262 va_start(ap, format)__builtin_va_start(ap, format);
6263 proto_tree_set_representation(pi, format, ap);
6264 va_end(ap)__builtin_va_end(ap);
6265 }
6266
6267 return pi;
6268}
6269
6270/* Add a FT_EUI64 to a proto_tree */
6271proto_item *
6272proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6273 int length, const uint64_t value)
6274{
6275 proto_item *pi;
6276 header_field_info *hfinfo;
6277
6278 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6279
6280 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", 6280
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6280, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6280, "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", 6280, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6281
6282 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",
6282, ((hfinfo))->abbrev))))
;
6283
6284 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6285 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6286
6287 return pi;
6288}
6289
6290proto_item *
6291proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6292 int start, int length, const uint64_t value,
6293 const char *format, ...)
6294{
6295 proto_item *pi;
6296 va_list ap;
6297
6298 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6299 if (pi != tree) {
6300 va_start(ap, format)__builtin_va_start(ap, format);
6301 proto_tree_set_representation_value(pi, format, ap);
6302 va_end(ap)__builtin_va_end(ap);
6303 }
6304
6305 return pi;
6306}
6307
6308proto_item *
6309proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6310 int start, int length, const uint64_t value,
6311 const char *format, ...)
6312{
6313 proto_item *pi;
6314 va_list ap;
6315
6316 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6317 if (pi != tree) {
6318 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6318, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6319
6320 va_start(ap, format)__builtin_va_start(ap, format);
6321 proto_tree_set_representation(pi, format, ap);
6322 va_end(ap)__builtin_va_end(ap);
6323 }
6324
6325 return pi;
6326}
6327
6328/* Set the FT_EUI64 value */
6329static void
6330proto_tree_set_eui64(field_info *fi, const uint64_t value)
6331{
6332 uint8_t v[FT_EUI64_LEN8];
6333 phtonu64(v, value);
6334 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6335}
6336
6337static void
6338proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6339{
6340 if (encoding)
6341 {
6342 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6343 } else {
6344 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6345 }
6346}
6347
6348proto_item *
6349proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6350 const mac_hf_list_t *list_generic,
6351 int idx, tvbuff_t *tvb,
6352 proto_tree *tree, int offset)
6353{
6354 uint8_t addr[6];
6355 const char *addr_name = NULL((void*)0);
6356 const char *oui_name = NULL((void*)0);
6357 proto_item *addr_item = NULL((void*)0);
6358 proto_tree *addr_tree = NULL((void*)0);
6359 proto_item *ret_val = NULL((void*)0);
6360
6361 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6362 return NULL((void*)0);
6363 }
6364
6365 /* Resolve what we can of the address */
6366 tvb_memcpy(tvb, addr, offset, sizeof addr);
6367 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6368 addr_name = get_ether_name(addr);
6369 }
6370 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6371 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6372 }
6373
6374 /* Add the item for the specific address type */
6375 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6376 if (idx >= 0) {
6377 addr_tree = proto_item_add_subtree(ret_val, idx);
6378 }
6379 else {
6380 addr_tree = tree;
6381 }
6382
6383 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6384 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6385 tvb, offset, 6, addr_name);
6386 proto_item_set_generated(addr_item);
6387 proto_item_set_hidden(addr_item);
6388 }
6389
6390 if (list_specific->hf_oui != NULL((void*)0)) {
6391 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6392 proto_item_set_generated(addr_item);
6393 proto_item_set_hidden(addr_item);
6394
6395 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6396 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6397 proto_item_set_generated(addr_item);
6398 proto_item_set_hidden(addr_item);
6399 }
6400 }
6401
6402 if (list_specific->hf_lg != NULL((void*)0)) {
6403 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6404 }
6405 if (list_specific->hf_ig != NULL((void*)0)) {
6406 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6407 }
6408
6409 /* Were we given a list for generic address fields? If not, stop here */
6410 if (list_generic == NULL((void*)0)) {
6411 return ret_val;
6412 }
6413
6414 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6415 proto_item_set_hidden(addr_item);
6416
6417 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6418 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6419 tvb, offset, 6, addr_name);
6420 proto_item_set_generated(addr_item);
6421 proto_item_set_hidden(addr_item);
6422 }
6423
6424 if (list_generic->hf_oui != NULL((void*)0)) {
6425 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6426 proto_item_set_generated(addr_item);
6427 proto_item_set_hidden(addr_item);
6428
6429 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6430 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6431 proto_item_set_generated(addr_item);
6432 proto_item_set_hidden(addr_item);
6433 }
6434 }
6435
6436 if (list_generic->hf_lg != NULL((void*)0)) {
6437 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6438 proto_item_set_hidden(addr_item);
6439 }
6440 if (list_generic->hf_ig != NULL((void*)0)) {
6441 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6442 proto_item_set_hidden(addr_item);
6443 }
6444 return ret_val;
6445}
6446
6447static proto_item *
6448proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6449{
6450 proto_node *pnode, *tnode, *sibling;
6451 field_info *tfi;
6452 unsigned depth = 1;
6453
6454 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6454, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6455
6456 /*
6457 * Restrict our depth. proto_tree_traverse_pre_order and
6458 * proto_tree_traverse_post_order (and possibly others) are recursive
6459 * so we need to be mindful of our stack size.
6460 */
6461 if (tree->first_child == NULL((void*)0)) {
6462 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6463 depth++;
6464 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6465 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__)), 6468)))
6466 "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__)), 6468)))
6467 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__)), 6468)))
6468 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__)), 6468)))
;
6469 }
6470 }
6471 }
6472
6473 /*
6474 * Make sure "tree" is ready to have subtrees under it, by
6475 * checking whether it's been given an ett_ value.
6476 *
6477 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6478 * node of the protocol tree. That node is not displayed,
6479 * so it doesn't need an ett_ value to remember whether it
6480 * was expanded.
6481 */
6482 tnode = tree;
6483 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6484 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6485 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"
, 6486)
6486 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"
, 6486)
;
6487 /* XXX - is it safe to continue here? */
6488 }
6489
6490 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6491 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6492 pnode->parent = tnode;
6493 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6494 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6495 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6496
6497 if (tnode->last_child != NULL((void*)0)) {
6498 sibling = tnode->last_child;
6499 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6499, "sibling->next == ((void*)0)"
))))
;
6500 sibling->next = pnode;
6501 } else
6502 tnode->first_child = pnode;
6503 tnode->last_child = pnode;
6504
6505 /* We should not be adding a fake node for an interesting field */
6506 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", 6506, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6507
6508 /* XXX - Should the proto_item have a header_field_info member, at least
6509 * for faked items, to know what hfi was faked? (Some dissectors look at
6510 * the tree items directly.)
6511 */
6512 return (proto_item *)pnode;
6513}
6514
6515/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6516static proto_item *
6517proto_tree_add_node(proto_tree *tree, field_info *fi)
6518{
6519 proto_node *pnode, *tnode, *sibling;
6520 field_info *tfi;
6521 unsigned depth = 1;
6522
6523 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6523, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6524
6525 /*
6526 * Restrict our depth. proto_tree_traverse_pre_order and
6527 * proto_tree_traverse_post_order (and possibly others) are recursive
6528 * so we need to be mindful of our stack size.
6529 */
6530 if (tree->first_child == NULL((void*)0)) {
6531 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6532 depth++;
6533 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6534 fvalue_free(fi->value);
6535 fi->value = NULL((void*)0);
6536 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__)), 6539)))
6537 "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__)), 6539)))
6538 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__)), 6539)))
6539 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__)), 6539)))
;
6540 }
6541 }
6542 }
6543
6544 /*
6545 * Make sure "tree" is ready to have subtrees under it, by
6546 * checking whether it's been given an ett_ value.
6547 *
6548 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6549 * node of the protocol tree. That node is not displayed,
6550 * so it doesn't need an ett_ value to remember whether it
6551 * was expanded.
6552 */
6553 tnode = tree;
6554 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6555 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6556 /* Since we are not adding fi to a node, its fvalue won't get
6557 * freed by proto_tree_free_node(), so free it now.
6558 */
6559 fvalue_free(fi->value);
6560 fi->value = NULL((void*)0);
6561 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", 6562)
6562 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", 6562)
;
6563 /* XXX - is it safe to continue here? */
6564 }
6565
6566 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6567 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6568 pnode->parent = tnode;
6569 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6570 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6571 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6572
6573 if (tnode->last_child != NULL((void*)0)) {
6574 sibling = tnode->last_child;
6575 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6575, "sibling->next == ((void*)0)"
))))
;
6576 sibling->next = pnode;
6577 } else
6578 tnode->first_child = pnode;
6579 tnode->last_child = pnode;
6580
6581 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6582
6583 return (proto_item *)pnode;
6584}
6585
6586
6587/* Generic way to allocate field_info and add to proto_tree.
6588 * Sets *pfi to address of newly-allocated field_info struct */
6589static proto_item *
6590proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6591 int *length)
6592{
6593 proto_item *pi;
6594 field_info *fi;
6595 int item_length;
6596
6597 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6598 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6599 pi = proto_tree_add_node(tree, fi);
6600
6601 return pi;
6602}
6603
6604
6605static void
6606get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6607 int *item_length, const unsigned encoding)
6608{
6609 int length_remaining;
6610
6611 /*
6612 * We only allow a null tvbuff if the item has a zero length,
6613 * i.e. if there's no data backing it.
6614 */
6615 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", 6615, "tvb != ((void*)0) || *length == 0"
))))
;
6616
6617 /*
6618 * XXX - in some protocols, there are 32-bit unsigned length
6619 * fields, so lengths in protocol tree and tvbuff routines
6620 * should really be unsigned. We should have, for those
6621 * field types for which "to the end of the tvbuff" makes sense,
6622 * additional routines that take no length argument and
6623 * add fields that run to the end of the tvbuff.
6624 */
6625 if (*length == -1) {
6626 /*
6627 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6628 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6629 * of -1 means "set the length to what remains in the
6630 * tvbuff".
6631 *
6632 * The assumption is either that
6633 *
6634 * 1) the length of the item can only be determined
6635 * by dissection (typically true of items with
6636 * subitems, which are probably FT_NONE or
6637 * FT_PROTOCOL)
6638 *
6639 * or
6640 *
6641 * 2) if the tvbuff is "short" (either due to a short
6642 * snapshot length or due to lack of reassembly of
6643 * fragments/segments/whatever), we want to display
6644 * what's available in the field (probably FT_BYTES
6645 * or FT_STRING) and then throw an exception later
6646 *
6647 * or
6648 *
6649 * 3) the field is defined to be "what's left in the
6650 * packet"
6651 *
6652 * so we set the length to what remains in the tvbuff so
6653 * that, if we throw an exception while dissecting, it
6654 * has what is probably the right value.
6655 *
6656 * For FT_STRINGZ, it means "the string is null-terminated,
6657 * not null-padded; set the length to the actual length
6658 * of the string", and if the tvbuff if short, we just
6659 * throw an exception.
6660 *
6661 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6662 * it means "find the end of the string",
6663 * and if the tvbuff if short, we just throw an exception.
6664 *
6665 * It's not valid for any other type of field. For those
6666 * fields, we treat -1 the same way we treat other
6667 * negative values - we assume the length is a Really
6668 * Big Positive Number, and throw a ReportedBoundsError
6669 * exception, under the assumption that the Really Big
6670 * Length would run past the end of the packet.
6671 */
6672 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
))
)) {
6673 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6674 /*
6675 * Leave the length as -1, so our caller knows
6676 * it was -1.
6677 */
6678 *item_length = *length;
6679 return;
6680 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6681 switch (tvb_get_uint8(tvb, start) >> 6)
6682 {
6683 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6684 *item_length = 1;
6685 break;
6686 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6687 *item_length = 2;
6688 break;
6689 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6690 *item_length = 4;
6691 break;
6692 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6693 *item_length = 8;
6694 break;
6695 }
6696 }
6697 }
6698
6699 switch (hfinfo->type) {
6700
6701 case FT_PROTOCOL:
6702 case FT_NONE:
6703 case FT_BYTES:
6704 case FT_STRING:
6705 case FT_STRINGZPAD:
6706 case FT_STRINGZTRUNC:
6707 /*
6708 * We allow FT_PROTOCOLs to be zero-length -
6709 * for example, an ONC RPC NULL procedure has
6710 * neither arguments nor reply, so the
6711 * payload for that protocol is empty.
6712 *
6713 * We also allow the others to be zero-length -
6714 * because that's the way the code has been for a
6715 * long, long time.
6716 *
6717 * However, we want to ensure that the start
6718 * offset is not *past* the byte past the end
6719 * of the tvbuff: we throw an exception in that
6720 * case.
6721 */
6722 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6723 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6723, "*length >= 0"
))))
;
6724 break;
6725
6726 case FT_STRINGZ:
6727 /*
6728 * Leave the length as -1, so our caller knows
6729 * it was -1.
6730 */
6731 break;
6732
6733 default:
6734 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6735 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6735))
;
6736 }
6737 *item_length = *length;
6738 } else {
6739 *item_length = *length;
6740 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6741 /*
6742 * These types are for interior nodes of the
6743 * tree, and don't have data associated with
6744 * them; if the length is negative (XXX - see
6745 * above) or goes past the end of the tvbuff,
6746 * cut it short at the end of the tvbuff.
6747 * That way, if this field is selected in
6748 * Wireshark, we don't highlight stuff past
6749 * the end of the data.
6750 */
6751 /* XXX - what to do, if we don't have a tvb? */
6752 if (tvb) {
6753 length_remaining = tvb_captured_length_remaining(tvb, start);
6754 if (*item_length < 0 ||
6755 (*item_length > 0 &&
6756 (length_remaining < *item_length)))
6757 *item_length = length_remaining;
6758 }
6759 }
6760 if (*item_length < 0) {
6761 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6762 }
6763 }
6764}
6765
6766static int
6767get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6768 int length, unsigned item_length, const int encoding)
6769{
6770 uint32_t n;
6771
6772 /*
6773 * We need to get the correct item length here.
6774 * That's normally done by proto_tree_new_item(),
6775 * but we won't be calling it.
6776 */
6777 switch (hfinfo->type) {
6778
6779 case FT_NONE:
6780 case FT_PROTOCOL:
6781 case FT_BYTES:
6782 /*
6783 * The length is the specified length.
6784 */
6785 break;
6786
6787 case FT_UINT_BYTES:
6788 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6789 item_length += n;
6790 if ((int)item_length < length) {
6791 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6792 }
6793 break;
6794
6795 /* XXX - make these just FT_UINT? */
6796 case FT_UINT8:
6797 case FT_UINT16:
6798 case FT_UINT24:
6799 case FT_UINT32:
6800 case FT_UINT40:
6801 case FT_UINT48:
6802 case FT_UINT56:
6803 case FT_UINT64:
6804 /* XXX - make these just FT_INT? */
6805 case FT_INT8:
6806 case FT_INT16:
6807 case FT_INT24:
6808 case FT_INT32:
6809 case FT_INT40:
6810 case FT_INT48:
6811 case FT_INT56:
6812 case FT_INT64:
6813 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6814 if (length < -1) {
6815 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6816 }
6817 if (length == -1) {
6818 uint64_t dummy;
6819 /* This can throw an exception */
6820 /* XXX - do this without fetching the varint? */
6821 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6822 if (length == 0) {
6823 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6824 }
6825 }
6826 item_length = length;
6827 break;
6828 }
6829
6830 /*
6831 * The length is the specified length.
6832 */
6833 break;
6834
6835 case FT_BOOLEAN:
6836 case FT_CHAR:
6837 case FT_IPv4:
6838 case FT_IPXNET:
6839 case FT_IPv6:
6840 case FT_FCWWN:
6841 case FT_AX25:
6842 case FT_VINES:
6843 case FT_ETHER:
6844 case FT_EUI64:
6845 case FT_GUID:
6846 case FT_OID:
6847 case FT_REL_OID:
6848 case FT_SYSTEM_ID:
6849 case FT_FLOAT:
6850 case FT_DOUBLE:
6851 case FT_STRING:
6852 /*
6853 * The length is the specified length.
6854 */
6855 break;
6856
6857 case FT_STRINGZ:
6858 if (length < -1) {
6859 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6860 }
6861 if (length == -1) {
6862 /* This can throw an exception */
6863 item_length = tvb_strsize_enc(tvb, start, encoding);
6864 }
6865 break;
6866
6867 case FT_UINT_STRING:
6868 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6869 item_length += n;
6870 if ((int)item_length < length) {
6871 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6872 }
6873 break;
6874
6875 case FT_STRINGZPAD:
6876 case FT_STRINGZTRUNC:
6877 case FT_ABSOLUTE_TIME:
6878 case FT_RELATIVE_TIME:
6879 case FT_IEEE_11073_SFLOAT:
6880 case FT_IEEE_11073_FLOAT:
6881 /*
6882 * The length is the specified length.
6883 */
6884 break;
6885
6886 default:
6887 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
))
6888 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
))
6889 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
))
6890 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
))
;
6891 break;
6892 }
6893 return item_length;
6894}
6895
6896// This was arbitrarily chosen, but if you're adding 50K items to the tree
6897// without advancing the offset you should probably take a long, hard look
6898// at what you're doing.
6899// We *could* make this a configurable option, but I (Gerald) would like to
6900// avoid adding yet another nerd knob.
6901# define PROTO_TREE_MAX_IDLE50000 50000
6902static field_info *
6903new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6904 const int start, const int item_length)
6905{
6906 field_info *fi;
6907
6908 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6909
6910 fi->hfinfo = hfinfo;
6911 fi->start = start;
6912 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6913 /* add the data source tvbuff */
6914 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6915
6916 // If our start offset hasn't advanced after adding many items it probably
6917 // means we're in a large or infinite loop.
6918 if (fi->start > 0) {
6919 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6920 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6921 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", 6921, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6922 } else {
6923 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6924 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6925 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6926 }
6927 }
6928 fi->length = item_length;
6929 fi->tree_type = -1;
6930 fi->flags = 0;
6931 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6932 /* If the tree is not visible, set the item hidden, unless we
6933 * need the representation or length and can't fake them.
6934 */
6935 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6936 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6937 }
6938 }
6939 fi->value = fvalue_new(fi->hfinfo->type);
6940 fi->rep = NULL((void*)0);
6941
6942 fi->appendix_start = 0;
6943 fi->appendix_length = 0;
6944
6945 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6946 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6947
6948 return fi;
6949}
6950
6951static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6952{
6953 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6954 return 0;
6955 }
6956
6957 /* Search for field name */
6958 char *ptr = strstr(representation, hfinfo->name);
6959 if (!ptr) {
6960 return 0;
6961 }
6962
6963 /* Check if field name ends with the ": " delimiter */
6964 ptr += strlen(hfinfo->name);
6965 if (strncmp(ptr, ": ", 2) == 0) {
6966 ptr += 2;
6967 }
6968
6969 /* Return offset to after field name */
6970 return ptr - representation;
6971}
6972
6973static size_t label_find_name_pos(const item_label_t *rep)
6974{
6975 size_t name_pos = 0;
6976
6977 /* If the value_pos is too small or too large, we can't find the expected format */
6978 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
6979 return 0;
6980 }
6981
6982 /* Check if the format looks like "label: value", then set name_pos before ':'. */
6983 if (rep->representation[rep->value_pos-2] == ':') {
6984 name_pos = rep->value_pos - 2;
6985 }
6986
6987 return name_pos;
6988}
6989
6990/* If the protocol tree is to be visible, set the representation of a
6991 proto_tree entry with the name of the field for the item and with
6992 the value formatted with the supplied printf-style format and
6993 argument list. */
6994static void
6995proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6996{
6997 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6997, __func__, "assertion failed: %s", "pi"
); } while (0)
;
6998
6999 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7000 * items string representation */
7001 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7002 size_t name_pos, ret = 0;
7003 char *str;
7004 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7005 const header_field_info *hf;
7006
7007 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7007, "fi"))))
;
7008
7009 hf = fi->hfinfo;
7010
7011 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;
;
7012 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))
)) {
7013 uint64_t val;
7014 char *p;
7015
7016 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)
)
7017 val = fvalue_get_uinteger(fi->value);
7018 else
7019 val = fvalue_get_uinteger64(fi->value);
7020
7021 val <<= hfinfo_bitshift(hf);
7022
7023 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7024 ret = (p - fi->rep->representation);
7025 }
7026
7027 /* put in the hf name */
7028 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)
;
7029
7030 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7031 /* If possible, Put in the value of the string */
7032 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7033 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"
, 7033, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7034 fi->rep->value_pos = ret;
7035 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7036 if (ret >= ITEM_LABEL_LENGTH240) {
7037 /* Uh oh, we don't have enough room. Tell the user
7038 * that the field is truncated.
7039 */
7040 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7041 }
7042 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7043 }
7044}
7045
7046/* If the protocol tree is to be visible, set the representation of a
7047 proto_tree entry with the representation formatted with the supplied
7048 printf-style format and argument list. */
7049static void
7050proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7051{
7052 size_t ret; /*tmp return value */
7053 char *str;
7054 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7055
7056 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7056, "fi"))))
;
7057
7058 if (!proto_item_is_hidden(pi)) {
7059 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;
;
7060
7061 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7062 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"
, 7062, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7063 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7064 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7065 if (ret >= ITEM_LABEL_LENGTH240) {
7066 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7067 size_t name_pos = label_find_name_pos(fi->rep);
7068 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7069 }
7070 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7071 }
7072}
7073
7074static int
7075proto_strlcpy(char *dest, const char *src, size_t dest_size)
7076{
7077 if (dest_size == 0) return 0;
7078
7079 size_t res = g_strlcpy(dest, src, dest_size);
7080
7081 /* At most dest_size - 1 characters will be copied
7082 * (unless dest_size is 0). */
7083 if (res >= dest_size)
7084 res = dest_size - 1;
7085 return (int) res;
7086}
7087
7088static header_field_info *
7089hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7090{
7091 header_field_info *dup_hfinfo;
7092
7093 if (hfinfo->same_name_prev_id == -1)
7094 return NULL((void*)0);
7095 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", 7095
, __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", 7095, "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", 7095,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7096 return dup_hfinfo;
7097}
7098
7099static void
7100hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7101{
7102 g_free(last_field_name);
7103 last_field_name = NULL((void*)0);
7104
7105 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7106 /* No hfinfo with the same name */
7107 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7108 return;
7109 }
7110
7111 if (hfinfo->same_name_next) {
7112 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7113 }
7114
7115 if (hfinfo->same_name_prev_id != -1) {
7116 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7117 same_name_prev->same_name_next = hfinfo->same_name_next;
7118 if (!hfinfo->same_name_next) {
7119 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7120 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7121 }
7122 }
7123}
7124
7125int
7126proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7127{
7128 const header_field_info *hfinfo = finfo->hfinfo;
7129 int label_len = 0;
7130 char *tmp_str;
7131 const char *str;
7132 const uint8_t *bytes;
7133 uint32_t number;
7134 uint64_t number64;
7135 const char *hf_str_val;
7136 char number_buf[NUMBER_LABEL_LENGTH80];
7137 const char *number_out;
7138 address addr;
7139 const ipv4_addr_and_mask *ipv4;
7140 const ipv6_addr_and_prefix *ipv6;
7141
7142 switch (hfinfo->type) {
7143
7144 case FT_NONE:
7145 case FT_PROTOCOL:
7146 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7147
7148 case FT_UINT_BYTES:
7149 case FT_BYTES:
7150 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7151 hfinfo,
7152 fvalue_get_bytes_data(finfo->value),
7153 (unsigned)fvalue_length2(finfo->value),
7154 label_str_size);
7155 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7156 wmem_free(NULL((void*)0), tmp_str);
7157 break;
7158
7159 case FT_ABSOLUTE_TIME:
7160 {
7161 const nstime_t *value = fvalue_get_time(finfo->value);
7162 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7163 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7164 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7165 }
7166 if (hfinfo->strings) {
7167 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7168 if (time_string != NULL((void*)0)) {
7169 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7170 break;
7171 }
7172 }
7173 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7174 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7175 wmem_free(NULL((void*)0), tmp_str);
7176 break;
7177 }
7178
7179 case FT_RELATIVE_TIME:
7180 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7181 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7182 wmem_free(NULL((void*)0), tmp_str);
7183 break;
7184
7185 case FT_BOOLEAN:
7186 number64 = fvalue_get_uinteger64(finfo->value);
7187 label_len = proto_strlcpy(display_label_str,
7188 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7189 break;
7190
7191 case FT_CHAR:
7192 number = fvalue_get_uinteger(finfo->value);
7193
7194 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7195 char tmp[ITEM_LABEL_LENGTH240];
7196 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7197
7198 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7198, "fmtfunc"))))
;
7199 fmtfunc(tmp, number);
7200
7201 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7202
7203 } else if (hfinfo->strings) {
7204 number_out = hf_try_val_to_str(number, hfinfo);
7205
7206 if (!number_out) {
7207 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7208 }
7209
7210 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7211
7212 } else {
7213 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7214
7215 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7216 }
7217
7218 break;
7219
7220 /* XXX - make these just FT_NUMBER? */
7221 case FT_INT8:
7222 case FT_INT16:
7223 case FT_INT24:
7224 case FT_INT32:
7225 case FT_UINT8:
7226 case FT_UINT16:
7227 case FT_UINT24:
7228 case FT_UINT32:
7229 case FT_FRAMENUM:
7230 hf_str_val = NULL((void*)0);
7231 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
))
?
7232 (uint32_t) fvalue_get_sinteger(finfo->value) :
7233 fvalue_get_uinteger(finfo->value);
7234
7235 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7236 char tmp[ITEM_LABEL_LENGTH240];
7237 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7238
7239 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7239, "fmtfunc"))))
;
7240 fmtfunc(tmp, number);
7241
7242 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7243
7244 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7245 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7246 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7247 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7248 hf_str_val = hf_try_val_to_str(number, hfinfo);
7249 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7250 } else {
7251 number_out = hf_try_val_to_str(number, hfinfo);
7252
7253 if (!number_out) {
7254 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7255 }
7256
7257 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7258 }
7259 } else {
7260 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7261
7262 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7263 }
7264
7265 break;
7266
7267 case FT_INT40:
7268 case FT_INT48:
7269 case FT_INT56:
7270 case FT_INT64:
7271 case FT_UINT40:
7272 case FT_UINT48:
7273 case FT_UINT56:
7274 case FT_UINT64:
7275 hf_str_val = NULL((void*)0);
7276 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
))
?
7277 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7278 fvalue_get_uinteger64(finfo->value);
7279
7280 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7281 char tmp[ITEM_LABEL_LENGTH240];
7282 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7283
7284 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7284, "fmtfunc64"
))))
;
7285 fmtfunc64(tmp, number64);
7286
7287 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7288 } else if (hfinfo->strings) {
7289 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7290 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7291 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7292 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7293 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7294 } else {
7295 number_out = hf_try_val64_to_str(number64, hfinfo);
7296
7297 if (!number_out)
7298 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7299
7300 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7301 }
7302 } else {
7303 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7304
7305 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7306 }
7307
7308 break;
7309
7310 case FT_EUI64:
7311 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7312 tmp_str = address_to_display(NULL((void*)0), &addr);
7313 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7314 wmem_free(NULL((void*)0), tmp_str);
7315 break;
7316
7317 case FT_IPv4:
7318 ipv4 = fvalue_get_ipv4(finfo->value);
7319 //XXX: Should we ignore the mask?
7320 set_address_ipv4(&addr, ipv4);
7321 tmp_str = address_to_display(NULL((void*)0), &addr);
7322 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7323 wmem_free(NULL((void*)0), tmp_str);
7324 free_address(&addr);
7325 break;
7326
7327 case FT_IPv6:
7328 ipv6 = fvalue_get_ipv6(finfo->value);
7329 set_address_ipv6(&addr, ipv6);
7330 tmp_str = address_to_display(NULL((void*)0), &addr);
7331 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7332 wmem_free(NULL((void*)0), tmp_str);
7333 free_address(&addr);
7334 break;
7335
7336 case FT_FCWWN:
7337 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7338 tmp_str = address_to_display(NULL((void*)0), &addr);
7339 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7340 wmem_free(NULL((void*)0), tmp_str);
7341 break;
7342
7343 case FT_ETHER:
7344 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7345 tmp_str = address_to_display(NULL((void*)0), &addr);
7346 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7347 wmem_free(NULL((void*)0), tmp_str);
7348 break;
7349
7350 case FT_GUID:
7351 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(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_REL_OID:
7357 bytes = fvalue_get_bytes_data(finfo->value);
7358 tmp_str = rel_oid_resolved_from_encoded(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_OID:
7364 bytes = fvalue_get_bytes_data(finfo->value);
7365 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7366 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7367 wmem_free(NULL((void*)0), tmp_str);
7368 break;
7369
7370 case FT_SYSTEM_ID:
7371 bytes = fvalue_get_bytes_data(finfo->value);
7372 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7373 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7374 wmem_free(NULL((void*)0), tmp_str);
7375 break;
7376
7377 case FT_FLOAT:
7378 case FT_DOUBLE:
7379 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7380 break;
7381
7382 case FT_IEEE_11073_SFLOAT:
7383 case FT_IEEE_11073_FLOAT:
7384 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7385 break;
7386
7387 case FT_STRING:
7388 case FT_STRINGZ:
7389 case FT_UINT_STRING:
7390 case FT_STRINGZPAD:
7391 case FT_STRINGZTRUNC:
7392 str = fvalue_get_string(finfo->value);
7393 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7394 if (label_len >= label_str_size) {
7395 /* Truncation occurred. Get the real length
7396 * copied (not including '\0') */
7397 label_len = label_str_size ? label_str_size - 1 : 0;
7398 }
7399 break;
7400
7401 default:
7402 /* First try ftype string representation */
7403 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7404 if (!tmp_str) {
7405 /* Default to show as bytes */
7406 bytes = fvalue_get_bytes_data(finfo->value);
7407 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7408 }
7409 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7410 wmem_free(NULL((void*)0), tmp_str);
7411 break;
7412 }
7413 return label_len;
7414}
7415
7416const char *
7417proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7418 char *result, char *expr, const int size)
7419{
7420 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7421 GPtrArray *finfos;
7422 field_info *finfo = NULL((void*)0);
7423 header_field_info* hfinfo;
7424 const char *abbrev = NULL((void*)0);
7425
7426 char *str;
7427 col_custom_t *field_idx;
7428 int field_id;
7429 int ii = 0;
7430
7431 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7431, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7432 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7433 field_id = field_idx->field_id;
7434 if (field_id == 0) {
7435 GPtrArray *fvals = NULL((void*)0);
7436 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7437 if (fvals != NULL((void*)0)) {
7438
7439 // XXX - Handling occurrences is unusual when more
7440 // than one field is involved, e.g. there's four
7441 // results for tcp.port + tcp.port. We may really
7442 // want to apply it to the operands, not the output.
7443 // Note that occurrences are not quite the same as
7444 // the layer operator (should the grammar support
7445 // both?)
7446 /* Calculate single index or set outer boundaries */
7447 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7448 if (occurrence < 0) {
7449 i = occurrence + len;
7450 last = i;
7451 } else if (occurrence > 0) {
7452 i = occurrence - 1;
7453 last = i;
7454 } else {
7455 i = 0;
7456 last = len - 1;
7457 }
7458 if (i < 0 || i >= len) {
7459 g_ptr_array_unref(fvals);
7460 continue;
7461 }
7462 for (; i <= last; i++) {
7463 /* XXX - We could have a "resolved" result
7464 * for types where the value depends only
7465 * on the type, e.g. FT_IPv4, and not on
7466 * hfinfo->strings. Supporting the latter
7467 * requires knowing which hfinfo matched
7468 * if there are multiple with the same
7469 * abbreviation. In any case, we need to
7470 * know the expected return type of the
7471 * field expression.
7472 */
7473 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
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 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7479 // col_{add,append,set}_* calls ws_label_strcpy
7480 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7481
7482 g_free(str);
7483 }
7484 g_ptr_array_unref(fvals);
7485 } else if (passed) {
7486 // XXX - Occurrence doesn't make sense for a test
7487 // output, it should be applied to the operands.
7488 if (offset_r && (offset_r < (size - 1)))
7489 result[offset_r++] = ',';
7490 if (offset_e && (offset_e < (size - 1)))
7491 expr[offset_e++] = ',';
7492 /* Prevent multiple check marks */
7493 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7494 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7495 } else {
7496 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7497 }
7498 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7499 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7500 } else {
7501 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7502 }
7503 }
7504 continue;
7505 }
7506 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", 7506
, __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", 7506,
"(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", 7506,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7507
7508 /* do we need to rewind ? */
7509 if (!hfinfo)
7510 return "";
7511
7512 if (occurrence < 0) {
7513 /* Search other direction */
7514 while (hfinfo->same_name_prev_id != -1) {
7515 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", 7515
, __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", 7515, "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", 7515,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7516 }
7517 }
7518
7519 prev_len = 0; /* Reset handled occurrences */
7520
7521 while (hfinfo) {
7522 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7523
7524 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7525 if (occurrence < 0) {
7526 hfinfo = hfinfo->same_name_next;
7527 } else {
7528 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7529 }
7530 continue;
7531 }
7532
7533 /* Are there enough occurrences of the field? */
7534 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7535 if (occurrence < 0) {
7536 hfinfo = hfinfo->same_name_next;
7537 } else {
7538 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7539 }
7540 prev_len += len;
7541 continue;
7542 }
7543
7544 /* Calculate single index or set outer boundaries */
7545 if (occurrence < 0) {
7546 i = occurrence + len + prev_len;
7547 last = i;
7548 } else if (occurrence > 0) {
7549 i = occurrence - 1 - prev_len;
7550 last = i;
7551 } else {
7552 i = 0;
7553 last = len - 1;
7554 }
7555
7556 prev_len += len; /* Count handled occurrences */
7557
7558 while (i <= last) {
7559 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7560
7561 if (offset_r && (offset_r < (size - 1)))
7562 result[offset_r++] = ',';
7563
7564 if (display_details) {
7565 char representation[ITEM_LABEL_LENGTH240];
7566 size_t offset = 0;
7567
7568 if (finfo->rep && finfo->rep->value_len) {
7569 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7570 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7571 } else {
7572 proto_item_fill_label(finfo, representation, &offset);
7573 }
7574 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7575 } else {
7576 switch (hfinfo->type) {
7577
7578 case FT_NONE:
7579 case FT_PROTOCOL:
7580 /* Prevent multiple check marks */
7581 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7582 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7583 } else {
7584 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7585 }
7586 break;
7587
7588 default:
7589 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7590 break;
7591 }
7592 }
7593
7594 if (offset_e && (offset_e < (size - 1)))
7595 expr[offset_e++] = ',';
7596
7597 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
))
)) {
7598 const char *hf_str_val;
7599 /* Integer types with BASE_NONE never get the numeric value. */
7600 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7601 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7602 } 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
)
) {
7603 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7604 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7605 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7606 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7607 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7608 }
7609 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7610 offset_e = (int)strlen(expr);
7611 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7612 /* Prevent multiple check marks */
7613 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7614 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7615 } else {
7616 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7617 }
7618 } else {
7619 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7620 // col_{add,append,set}_* calls ws_label_strcpy
7621 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7622 wmem_free(NULL((void*)0), str);
7623 }
7624 i++;
7625 }
7626
7627 /* XXX: Why is only the first abbreviation returned for a multifield
7628 * custom column? */
7629 if (!abbrev) {
7630 /* Store abbrev for return value */
7631 abbrev = hfinfo->abbrev;
7632 }
7633
7634 if (occurrence == 0) {
7635 /* Fetch next hfinfo with same name (abbrev) */
7636 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7637 } else {
7638 hfinfo = NULL((void*)0);
7639 }
7640 }
7641 }
7642
7643 if (offset_r >= (size - 1)) {
7644 mark_truncated(result, 0, size, NULL((void*)0));
7645 }
7646 if (offset_e >= (size - 1)) {
7647 mark_truncated(expr, 0, size, NULL((void*)0));
7648 }
7649 return abbrev ? abbrev : "";
7650}
7651
7652char *
7653proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7654{
7655 int len, prev_len, last, i;
7656 GPtrArray *finfos;
7657 field_info *finfo = NULL((void*)0);
7658 header_field_info* hfinfo;
7659
7660 char *filter = NULL((void*)0);
7661 GPtrArray *filter_array;
7662
7663 col_custom_t *col_custom;
7664 int field_id;
7665
7666 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7666, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7667 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7668 for (GSList *iter = field_ids; iter; iter = iter->next) {
7669 col_custom = (col_custom_t*)iter->data;
7670 field_id = col_custom->field_id;
7671 if (field_id == 0) {
7672 GPtrArray *fvals = NULL((void*)0);
7673 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7674 if (fvals != NULL((void*)0)) {
7675 // XXX - Handling occurrences is unusual when more
7676 // than one field is involved, e.g. there's four
7677 // results for tcp.port + tcp.port. We really
7678 // want to apply it to the operands, not the output.
7679 /* Calculate single index or set outer boundaries */
7680 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7681 if (occurrence < 0) {
7682 i = occurrence + len;
7683 last = i;
7684 } else if (occurrence > 0) {
7685 i = occurrence - 1;
7686 last = i;
7687 } else {
7688 i = 0;
7689 last = len - 1;
7690 }
7691 if (i < 0 || i >= len) {
7692 g_ptr_array_unref(fvals);
7693 continue;
7694 }
7695 for (; i <= last; i++) {
7696 /* XXX - Should multiple values for one
7697 * field use set membership to reduce
7698 * verbosity, here and below? */
7699 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7700 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7701 wmem_free(NULL((void*)0), str);
7702 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7703 g_ptr_array_add(filter_array, filter);
7704 }
7705 }
7706 g_ptr_array_unref(fvals);
7707 } else if (passed) {
7708 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7709 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7710 g_ptr_array_add(filter_array, filter);
7711 }
7712 } else {
7713 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7714 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7715 g_ptr_array_add(filter_array, filter);
7716 }
7717 }
7718 continue;
7719 }
7720
7721 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", 7721
, __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", 7721,
"(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", 7721,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7722
7723 /* do we need to rewind ? */
7724 if (!hfinfo)
7725 return NULL((void*)0);
7726
7727 if (occurrence < 0) {
7728 /* Search other direction */
7729 while (hfinfo->same_name_prev_id != -1) {
7730 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", 7730
, __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", 7730, "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", 7730,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7731 }
7732 }
7733
7734 prev_len = 0; /* Reset handled occurrences */
7735
7736 while (hfinfo) {
7737 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7738
7739 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7740 if (occurrence < 0) {
7741 hfinfo = hfinfo->same_name_next;
7742 } else {
7743 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7744 }
7745 continue;
7746 }
7747
7748 /* Are there enough occurrences of the field? */
7749 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7750 if (occurrence < 0) {
7751 hfinfo = hfinfo->same_name_next;
7752 } else {
7753 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7754 }
7755 prev_len += len;
7756 continue;
7757 }
7758
7759 /* Calculate single index or set outer boundaries */
7760 if (occurrence < 0) {
7761 i = occurrence + len + prev_len;
7762 last = i;
7763 } else if (occurrence > 0) {
7764 i = occurrence - 1 - prev_len;
7765 last = i;
7766 } else {
7767 i = 0;
7768 last = len - 1;
7769 }
7770
7771 prev_len += len; /* Count handled occurrences */
7772
7773 while (i <= last) {
7774 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7775
7776 filter = proto_construct_match_selected_string(finfo, edt);
7777 if (filter) {
7778 /* Only add the same expression once (especially for FT_PROTOCOL).
7779 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7780 */
7781 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7782 g_ptr_array_add(filter_array, filter);
7783 }
7784 }
7785 i++;
7786 }
7787
7788 if (occurrence == 0) {
7789 /* Fetch next hfinfo with same name (abbrev) */
7790 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7791 } else {
7792 hfinfo = NULL((void*)0);
7793 }
7794 }
7795 }
7796
7797 g_ptr_array_add(filter_array, NULL((void*)0));
7798
7799 /* XXX: Should this be || or && ? */
7800 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7801
7802 g_ptr_array_free(filter_array, true1);
7803
7804 return output;
7805}
7806
7807/* Set text of proto_item after having already been created. */
7808void
7809proto_item_set_text(proto_item *pi, const char *format, ...)
7810{
7811 field_info *fi = NULL((void*)0);
7812 va_list ap;
7813
7814 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7815
7816 fi = PITEM_FINFO(pi)((pi)->finfo);
7817 if (fi == NULL((void*)0))
7818 return;
7819
7820 if (fi->rep) {
7821 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7822 fi->rep = NULL((void*)0);
7823 }
7824
7825 va_start(ap, format)__builtin_va_start(ap, format);
7826 proto_tree_set_representation(pi, format, ap);
7827 va_end(ap)__builtin_va_end(ap);
7828}
7829
7830/* Append to text of proto_item after having already been created. */
7831void
7832proto_item_append_text(proto_item *pi, const char *format, ...)
7833{
7834 field_info *fi = NULL((void*)0);
7835 size_t curlen;
7836 char *str;
7837 va_list ap;
7838
7839 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7840
7841 fi = PITEM_FINFO(pi)((pi)->finfo);
7842 if (fi == NULL((void*)0)) {
7843 return;
7844 }
7845
7846 if (!proto_item_is_hidden(pi)) {
7847 /*
7848 * If we don't already have a representation,
7849 * generate the default representation.
7850 */
7851 if (fi->rep == NULL((void*)0)) {
7852 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;
;
7853 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7854 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7855 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7856 (strncmp(format, ": ", 2) == 0)) {
7857 fi->rep->value_pos += 2;
7858 }
7859 }
7860 if (fi->rep) {
7861 curlen = strlen(fi->rep->representation);
7862 /* curlen doesn't include the \0 byte.
7863 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7864 * the representation has already been truncated (of an up
7865 * to 4 byte UTF-8 character) or is just at the maximum length
7866 * unless we search for " [truncated]" (which may not be
7867 * at the start.)
7868 * It's safer to do nothing.
7869 */
7870 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7871 va_start(ap, format)__builtin_va_start(ap, format);
7872 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7873 va_end(ap)__builtin_va_end(ap);
7874 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"
, 7874, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7875 /* Keep fi->rep->value_pos */
7876 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
7877 if (curlen >= ITEM_LABEL_LENGTH240) {
7878 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7879 size_t name_pos = label_find_name_pos(fi->rep);
7880 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7881 }
7882 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7883 }
7884 }
7885 }
7886}
7887
7888/* Prepend to text of proto_item after having already been created. */
7889void
7890proto_item_prepend_text(proto_item *pi, const char *format, ...)
7891{
7892 field_info *fi = NULL((void*)0);
7893 size_t pos;
7894 char representation[ITEM_LABEL_LENGTH240];
7895 char *str;
7896 va_list ap;
7897
7898 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7899
7900 fi = PITEM_FINFO(pi)((pi)->finfo);
7901 if (fi == NULL((void*)0)) {
7902 return;
7903 }
7904
7905 if (!proto_item_is_hidden(pi)) {
7906 /*
7907 * If we don't already have a representation,
7908 * generate the default representation.
7909 */
7910 if (fi->rep == NULL((void*)0)) {
7911 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;
;
7912 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7913 } else
7914 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7915
7916 va_start(ap, format)__builtin_va_start(ap, format);
7917 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7918 va_end(ap)__builtin_va_end(ap);
7919 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"
, 7919, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7920 fi->rep->value_pos += strlen(str);
7921 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7922 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
7923 /* XXX: As above, if the old representation is close to the label
7924 * length, it might already be marked as truncated. */
7925 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7926 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7927 size_t name_pos = label_find_name_pos(fi->rep);
7928 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7929 }
7930 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7931 }
7932}
7933
7934static void
7935finfo_set_len(field_info *fi, const int length)
7936{
7937 int length_remaining;
7938
7939 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", 7939,
"length >= 0", fi->hfinfo->abbrev))))
;
7940 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7941 if (length > length_remaining)
7942 fi->length = length_remaining;
7943 else
7944 fi->length = length;
7945
7946 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7947 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7948 fvalue_set_protocol_length(fi->value, fi->length);
7949 }
7950
7951 /*
7952 * You cannot just make the "len" field of a GByteArray
7953 * larger, if there's no data to back that length;
7954 * you can only make it smaller.
7955 */
7956 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7957 GBytes *bytes = fvalue_get_bytes(fi->value);
7958 size_t size;
7959 const void *data = g_bytes_get_data(bytes, &size);
7960 if ((size_t)fi->length <= size) {
7961 fvalue_set_bytes_data(fi->value, data, fi->length);
7962 }
7963 g_bytes_unref(bytes);
7964 }
7965}
7966
7967void
7968proto_item_set_len(proto_item *pi, const int length)
7969{
7970 field_info *fi;
7971
7972 if (pi == NULL((void*)0))
7973 return;
7974
7975 fi = PITEM_FINFO(pi)((pi)->finfo);
7976 if (fi == NULL((void*)0))
7977 return;
7978
7979 finfo_set_len(fi, length);
7980}
7981
7982/*
7983 * Sets the length of the item based on its start and on the specified
7984 * offset, which is the offset past the end of the item; as the start
7985 * in the item is relative to the beginning of the data source tvbuff,
7986 * we need to pass in a tvbuff - the end offset is relative to the beginning
7987 * of that tvbuff.
7988 */
7989void
7990proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
7991{
7992 field_info *fi;
7993 int length;
7994
7995 if (pi == NULL((void*)0))
7996 return;
7997
7998 fi = PITEM_FINFO(pi)((pi)->finfo);
7999 if (fi == NULL((void*)0))
8000 return;
8001
8002 end += tvb_raw_offset(tvb);
8003 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8003, "end >= fi->start"
))))
;
8004 length = end - fi->start;
8005
8006 finfo_set_len(fi, length);
8007}
8008
8009int
8010proto_item_get_len(const proto_item *pi)
8011{
8012 field_info *fi;
8013
8014 if (!pi)
8015 return -1;
8016 fi = PITEM_FINFO(pi)((pi)->finfo);
8017 if (fi) {
8018 return fi->length;
8019 }
8020 return -1;
8021}
8022
8023void
8024proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8025 if (!ti) {
8026 return;
8027 }
8028 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)
;
8029 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)
;
8030}
8031
8032char *
8033proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8034{
8035 field_info *fi;
8036
8037 if (!pi)
8038 return wmem_strdup(scope, "");
8039 fi = PITEM_FINFO(pi)((pi)->finfo);
8040 if (!fi)
8041 return wmem_strdup(scope, "");
8042 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8042, "fi->hfinfo != ((void*)0)"
))))
;
8043 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8044}
8045
8046proto_tree *
8047proto_tree_create_root(packet_info *pinfo)
8048{
8049 proto_node *pnode;
8050
8051 /* Initialize the proto_node */
8052 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
8053 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8054 pnode->parent = NULL((void*)0);
8055 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8056 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
8057
8058 /* Make sure we can access pinfo everywhere */
8059 pnode->tree_data->pinfo = pinfo;
8060
8061 /* Don't initialize the tree_data_t. Wait until we know we need it */
8062 pnode->tree_data->interesting_hfids = NULL((void*)0);
8063
8064 /* Set the default to false so it's easier to
8065 * find errors; if we expect to see the protocol tree
8066 * but for some reason the default 'visible' is not
8067 * changed, then we'll find out very quickly. */
8068 pnode->tree_data->visible = false0;
8069
8070 /* Make sure that we fake protocols (if possible) */
8071 pnode->tree_data->fake_protocols = true1;
8072
8073 /* Keep track of the number of children */
8074 pnode->tree_data->count = 0;
8075
8076 /* Initialize our loop checks */
8077 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8078 pnode->tree_data->max_start = 0;
8079 pnode->tree_data->start_idle_count = 0;
8080
8081 return (proto_tree *)pnode;
8082}
8083
8084
8085/* "prime" a proto_tree with a single hfid that a dfilter
8086 * is interested in. */
8087void
8088proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8089{
8090 header_field_info *hfinfo;
8091
8092 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", 8092, __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", 8092, "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", 8092, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8093 /* this field is referenced by a filter so increase the refcount.
8094 also increase the refcount for the parent, i.e the protocol.
8095 Don't increase the refcount if we're already printing the
8096 type, as that is a superset of direct reference.
8097 */
8098 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8099 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8100 }
8101 /* only increase the refcount if there is a parent.
8102 if this is a protocol and not a field then parent will be -1
8103 and there is no parent to add any refcounting for.
8104 */
8105 if (hfinfo->parent != -1) {
8106 header_field_info *parent_hfinfo;
8107 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", 8107
, __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", 8107,
"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", 8107,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8108
8109 /* Mark parent as indirectly referenced unless it is already directly
8110 * referenced, i.e. the user has specified the parent in a filter.
8111 */
8112 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8113 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8114 }
8115}
8116
8117/* "prime" a proto_tree with a single hfid that a dfilter
8118 * is interested in. */
8119void
8120proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8121{
8122 header_field_info *hfinfo;
8123
8124 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", 8124, __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", 8124, "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", 8124, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8125 /* this field is referenced by an (output) filter so increase the refcount.
8126 also increase the refcount for the parent, i.e the protocol.
8127 */
8128 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8129 /* only increase the refcount if there is a parent.
8130 if this is a protocol and not a field then parent will be -1
8131 and there is no parent to add any refcounting for.
8132 */
8133 if (hfinfo->parent != -1) {
8134 header_field_info *parent_hfinfo;
8135 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", 8135
, __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", 8135,
"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", 8135,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8136
8137 /* Mark parent as indirectly referenced unless it is already directly
8138 * referenced, i.e. the user has specified the parent in a filter.
8139 */
8140 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8141 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8142 }
8143}
8144
8145proto_tree *
8146proto_item_add_subtree(proto_item *pi, const int idx) {
8147 field_info *fi;
8148
8149 if (!pi)
8150 return NULL((void*)0);
8151
8152 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", 8152, "idx >= 0 && idx < num_tree_types"
))))
;
8153
8154 fi = PITEM_FINFO(pi)((pi)->finfo);
8155 if (!fi)
8156 return (proto_tree *)pi;
8157
8158 fi->tree_type = idx;
8159
8160 return (proto_tree *)pi;
8161}
8162
8163proto_tree *
8164proto_item_get_subtree(proto_item *pi) {
8165 field_info *fi;
8166
8167 if (!pi)
8168 return NULL((void*)0);
8169 fi = PITEM_FINFO(pi)((pi)->finfo);
8170 if ( (fi) && (fi->tree_type == -1) )
8171 return NULL((void*)0);
8172 return (proto_tree *)pi;
8173}
8174
8175proto_item *
8176proto_item_get_parent(const proto_item *ti) {
8177 if (!ti)
8178 return NULL((void*)0);
8179 return ti->parent;
8180}
8181
8182proto_item *
8183proto_item_get_parent_nth(proto_item *ti, int gen) {
8184 if (!ti)
8185 return NULL((void*)0);
8186 while (gen--) {
8187 ti = ti->parent;
8188 if (!ti)
8189 return NULL((void*)0);
8190 }
8191 return ti;
8192}
8193
8194
8195proto_item *
8196proto_tree_get_parent(proto_tree *tree) {
8197 if (!tree)
8198 return NULL((void*)0);
8199 return (proto_item *)tree;
8200}
8201
8202proto_tree *
8203proto_tree_get_parent_tree(proto_tree *tree) {
8204 if (!tree)
8205 return NULL((void*)0);
8206
8207 /* we're the root tree, there's no parent
8208 return ourselves so the caller has at least a tree to attach to */
8209 if (!tree->parent)
8210 return tree;
8211
8212 return (proto_tree *)tree->parent;
8213}
8214
8215proto_tree *
8216proto_tree_get_root(proto_tree *tree) {
8217 if (!tree)
8218 return NULL((void*)0);
8219 while (tree->parent) {
8220 tree = tree->parent;
8221 }
8222 return tree;
8223}
8224
8225void
8226proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8227 proto_item *item_to_move)
8228{
8229 /* This function doesn't generate any values. It only reorganizes the protocol tree
8230 * so we can bail out immediately if it isn't visible. */
8231 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8232 return;
8233
8234 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", 8234, "item_to_move->parent == tree"
))))
;
8235 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", 8235, "fixed_item->parent == tree"
))))
;
8236
8237 /*** cut item_to_move out ***/
8238
8239 /* is item_to_move the first? */
8240 if (tree->first_child == item_to_move) {
8241 /* simply change first child to next */
8242 tree->first_child = item_to_move->next;
8243
8244 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", 8244, "tree->last_child != item_to_move"
))))
;
8245 } else {
8246 proto_item *curr_item;
8247 /* find previous and change it's next */
8248 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8249 if (curr_item->next == item_to_move) {
8250 break;
8251 }
8252 }
8253
8254 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8254, "curr_item"
))))
;
8255
8256 curr_item->next = item_to_move->next;
8257
8258 /* fix last_child if required */
8259 if (tree->last_child == item_to_move) {
8260 tree->last_child = curr_item;
8261 }
8262 }
8263
8264 /*** insert to_move after fixed ***/
8265 item_to_move->next = fixed_item->next;
8266 fixed_item->next = item_to_move;
8267 if (tree->last_child == fixed_item) {
8268 tree->last_child = item_to_move;
8269 }
8270}
8271
8272void
8273proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8274 const int length)
8275{
8276 field_info *fi;
8277
8278 if (tree == NULL((void*)0))
8279 return;
8280
8281 fi = PTREE_FINFO(tree)((tree)->finfo);
8282 if (fi == NULL((void*)0))
8283 return;
8284
8285 start += tvb_raw_offset(tvb);
8286 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8286, "start >= 0"
))))
;
8287 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8287, "length >= 0"
))))
;
8288
8289 fi->appendix_start = start;
8290 fi->appendix_length = length;
8291}
8292
8293static void
8294check_protocol_filter_name_or_fail(const char *filter_name)
8295{
8296 /* Require at least two characters. */
8297 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8298 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)
;
8299 }
8300
8301 if (proto_check_field_name(filter_name) != '\0') {
8302 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)
8303 " 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)
8304 " 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)
;
8305 }
8306
8307 /* Check that it doesn't match some very common numeric forms. */
8308 if (filter_name[0] == '0' &&
8309 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8310 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8311 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])
8312 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])
;
8313 }
8314
8315 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8316
8317 /* Check that it contains at least one letter. */
8318 bool_Bool have_letter = false0;
8319 for (const char *s = filter_name; *s != '\0'; s++) {
8320 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8321 have_letter = true1;
8322 break;
8323 }
8324 }
8325 if (!have_letter) {
8326 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)
8327 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8328 }
8329
8330 /* Check for reserved keywords. */
8331 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8332 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)
8333 " 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)
;
8334 }
8335}
8336
8337int
8338proto_register_protocol(const char *name, const char *short_name,
8339 const char *filter_name)
8340{
8341 protocol_t *protocol;
8342 header_field_info *hfinfo;
8343
8344 check_protocol_filter_name_or_fail(filter_name);
8345
8346 /*
8347 * Add this protocol to the list of known protocols;
8348 * the list is sorted by protocol short name.
8349 */
8350 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8351 protocol->name = name;
8352 protocol->short_name = short_name;
8353 protocol->filter_name = filter_name;
8354 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8355 protocol->is_enabled = true1; /* protocol is enabled by default */
8356 protocol->enabled_by_default = true1; /* see previous comment */
8357 protocol->can_toggle = true1;
8358 protocol->parent_proto_id = -1;
8359 protocol->heur_list = NULL((void*)0);
8360
8361 /* List will be sorted later by name, when all protocols completed registering */
8362 protocols = g_list_prepend(protocols, protocol);
8363 /*
8364 * Make sure there's not already a protocol with any of those
8365 * names. Crash if there is, as that's an error in the code
8366 * or an inappropriate plugin.
8367 * This situation has to be fixed to not register more than one
8368 * protocol with the same name.
8369 */
8370 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8371 /* ws_error will terminate the program */
8372 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)
8373 " 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)
;
8374 }
8375 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8376 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)
8377 " 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)
;
8378 }
8379 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8380 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)
8381 " 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)
;
8382 }
8383
8384 /* Here we allocate a new header_field_info struct */
8385 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8386 hfinfo->name = name;
8387 hfinfo->abbrev = filter_name;
8388 hfinfo->type = FT_PROTOCOL;
8389 hfinfo->display = BASE_NONE;
8390 hfinfo->strings = protocol;
8391 hfinfo->bitmask = 0;
8392 hfinfo->ref_type = HF_REF_TYPE_NONE;
8393 hfinfo->blurb = NULL((void*)0);
8394 hfinfo->parent = -1; /* This field differentiates protos and fields */
8395
8396 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8397 return protocol->proto_id;
8398}
8399
8400int
8401proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8402{
8403 protocol_t *protocol;
8404 header_field_info *hfinfo;
8405
8406 /*
8407 * Helper protocols don't need the strict rules as a "regular" protocol
8408 * Just register it in a list and make a hf_ field from it
8409 */
8410 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8411 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)
;
8412 }
8413
8414 if (parent_proto <= 0) {
8415 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)
8416 " 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)
;
8417 }
8418
8419 check_protocol_filter_name_or_fail(filter_name);
8420
8421 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8422 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8423 protocol->name = name;
8424 protocol->short_name = short_name;
8425 protocol->filter_name = filter_name;
8426 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8427
8428 /* Enabling and toggling is really determined by parent protocol,
8429 but provide default values here */
8430 protocol->is_enabled = true1;
8431 protocol->enabled_by_default = true1;
8432 protocol->can_toggle = true1;
8433
8434 protocol->parent_proto_id = parent_proto;
8435 protocol->heur_list = NULL((void*)0);
8436
8437 /* List will be sorted later by name, when all protocols completed registering */
8438 protocols = g_list_prepend(protocols, protocol);
8439
8440 /* Here we allocate a new header_field_info struct */
8441 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8442 hfinfo->name = name;
8443 hfinfo->abbrev = filter_name;
8444 hfinfo->type = field_type;
8445 hfinfo->display = BASE_NONE;
8446 if (field_type == FT_BYTES) {
8447 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8448 }
8449 hfinfo->strings = protocol;
8450 hfinfo->bitmask = 0;
8451 hfinfo->ref_type = HF_REF_TYPE_NONE;
8452 hfinfo->blurb = NULL((void*)0);
8453 hfinfo->parent = -1; /* This field differentiates protos and fields */
8454
8455 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8456 return protocol->proto_id;
8457}
8458
8459bool_Bool
8460proto_deregister_protocol(const char *short_name)
8461{
8462 protocol_t *protocol;
8463 header_field_info *hfinfo;
8464 int proto_id;
8465 unsigned i;
8466
8467 proto_id = proto_get_id_by_short_name(short_name);
8468 protocol = find_protocol_by_id(proto_id);
8469 if (protocol == NULL((void*)0))
8470 return false0;
8471
8472 g_hash_table_remove(proto_names, protocol->name);
8473 g_hash_table_remove(proto_short_names, (void *)short_name);
8474 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8475
8476 if (protocol->fields) {
8477 for (i = 0; i < protocol->fields->len; i++) {
8478 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8479 hfinfo_remove_from_gpa_name_map(hfinfo);
8480 expert_deregister_expertinfo(hfinfo->abbrev);
8481 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8482 }
8483 g_ptr_array_free(protocol->fields, true1);
8484 protocol->fields = NULL((void*)0);
8485 }
8486
8487 g_list_free(protocol->heur_list);
8488
8489 /* Remove this protocol from the list of known protocols */
8490 protocols = g_list_remove(protocols, protocol);
8491
8492 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8493 wmem_map_remove(gpa_name_map, protocol->filter_name);
8494
8495 g_free(last_field_name);
8496 last_field_name = NULL((void*)0);
8497
8498 return true1;
8499}
8500
8501void
8502proto_register_alias(const int proto_id, const char *alias_name)
8503{
8504 protocol_t *protocol;
8505
8506 protocol = find_protocol_by_id(proto_id);
8507 if (alias_name && protocol) {
8508 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8509 }
8510}
8511
8512/*
8513 * Routines to use to iterate over the protocols.
8514 * The argument passed to the iterator routines is an opaque cookie to
8515 * their callers; it's the GList pointer for the current element in
8516 * the list.
8517 * The ID of the protocol is returned, or -1 if there is no protocol.
8518 */
8519int
8520proto_get_first_protocol(void **cookie)
8521{
8522 protocol_t *protocol;
8523
8524 if (protocols == NULL((void*)0))
8525 return -1;
8526 *cookie = protocols;
8527 protocol = (protocol_t *)protocols->data;
8528 return protocol->proto_id;
8529}
8530
8531int
8532proto_get_data_protocol(void *cookie)
8533{
8534 GList *list_item = (GList *)cookie;
8535
8536 protocol_t *protocol = (protocol_t *)list_item->data;
8537 return protocol->proto_id;
8538}
8539
8540int
8541proto_get_next_protocol(void **cookie)
8542{
8543 GList *list_item = (GList *)*cookie;
8544 protocol_t *protocol;
8545
8546 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8547 if (list_item == NULL((void*)0))
8548 return -1;
8549 *cookie = list_item;
8550 protocol = (protocol_t *)list_item->data;
8551 return protocol->proto_id;
8552}
8553
8554header_field_info *
8555proto_get_first_protocol_field(const int proto_id, void **cookie)
8556{
8557 protocol_t *protocol = find_protocol_by_id(proto_id);
8558
8559 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8560 return NULL((void*)0);
8561
8562 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8563 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8564}
8565
8566header_field_info *
8567proto_get_next_protocol_field(const int proto_id, void **cookie)
8568{
8569 protocol_t *protocol = find_protocol_by_id(proto_id);
8570 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8571
8572 i++;
8573
8574 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8575 return NULL((void*)0);
8576
8577 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8578 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8579}
8580
8581protocol_t *
8582find_protocol_by_id(const int proto_id)
8583{
8584 header_field_info *hfinfo;
8585
8586 if (proto_id <= 0)
8587 return NULL((void*)0);
8588
8589 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", 8589, __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", 8589,
"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", 8589, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8590 if (hfinfo->type != FT_PROTOCOL) {
8591 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", 8591, "hfinfo->display & 0x00004000"
))))
;
8592 }
8593 return (protocol_t *)hfinfo->strings;
8594}
8595
8596int
8597proto_get_id(const protocol_t *protocol)
8598{
8599 return protocol->proto_id;
8600}
8601
8602bool_Bool
8603proto_name_already_registered(const char *name)
8604{
8605 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8605, "name", "No name present"))))
;
8606
8607 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8608 return true1;
8609 return false0;
8610}
8611
8612int
8613proto_get_id_by_filter_name(const char *filter_name)
8614{
8615 const protocol_t *protocol = NULL((void*)0);
8616
8617 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", 8617,
"filter_name", "No filter name present"))))
;
8618
8619 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8620
8621 if (protocol == NULL((void*)0))
8622 return -1;
8623 return protocol->proto_id;
8624}
8625
8626int
8627proto_get_id_by_short_name(const char *short_name)
8628{
8629 const protocol_t *protocol = NULL((void*)0);
8630
8631 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", 8631,
"short_name", "No short name present"))))
;
8632
8633 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8634
8635 if (protocol == NULL((void*)0))
8636 return -1;
8637 return protocol->proto_id;
8638}
8639
8640const char *
8641proto_get_protocol_name(const int proto_id)
8642{
8643 protocol_t *protocol;
8644
8645 protocol = find_protocol_by_id(proto_id);
8646
8647 if (protocol == NULL((void*)0))
8648 return NULL((void*)0);
8649 return protocol->name;
8650}
8651
8652const char *
8653proto_get_protocol_short_name(const protocol_t *protocol)
8654{
8655 if (protocol == NULL((void*)0))
8656 return "(none)";
8657 return protocol->short_name;
8658}
8659
8660const char *
8661proto_get_protocol_long_name(const protocol_t *protocol)
8662{
8663 if (protocol == NULL((void*)0))
8664 return "(none)";
8665 return protocol->name;
8666}
8667
8668const char *
8669proto_get_protocol_filter_name(const int proto_id)
8670{
8671 protocol_t *protocol;
8672
8673 protocol = find_protocol_by_id(proto_id);
8674 if (protocol == NULL((void*)0))
8675 return "(none)";
8676 return protocol->filter_name;
8677}
8678
8679void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8680{
8681 heur_dtbl_entry_t* heuristic_dissector;
8682
8683 if (protocol == NULL((void*)0))
8684 return;
8685
8686 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8687 if (heuristic_dissector != NULL((void*)0))
8688 {
8689 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8690 }
8691}
8692
8693void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8694{
8695 if (protocol == NULL((void*)0))
8696 return;
8697
8698 g_list_foreach(protocol->heur_list, func, user_data);
8699}
8700
8701void
8702proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8703 bool_Bool *is_tcp, bool_Bool *is_udp,
8704 bool_Bool *is_sctp, bool_Bool *is_tls,
8705 bool_Bool *is_rtp,
8706 bool_Bool *is_lte_rlc)
8707{
8708 wmem_list_frame_t *protos = wmem_list_head(layers);
8709 int proto_id;
8710 const char *proto_name;
8711
8712 /* Walk the list of a available protocols in the packet and
8713 attempt to find "major" ones. */
8714 /* It might make more sense to assemble and return a bitfield. */
8715 while (protos != NULL((void*)0))
8716 {
8717 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8718 proto_name = proto_get_protocol_filter_name(proto_id);
8719
8720 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8721 (!strcmp(proto_name, "ipv6")))) {
8722 *is_ip = true1;
8723 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8724 *is_tcp = true1;
8725 } else if (is_udp && !strcmp(proto_name, "udp")) {
8726 *is_udp = true1;
8727 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8728 *is_sctp = true1;
8729 } else if (is_tls && !strcmp(proto_name, "tls")) {
8730 *is_tls = true1;
8731 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8732 *is_rtp = true1;
8733 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8734 *is_lte_rlc = true1;
8735 }
8736
8737 protos = wmem_list_frame_next(protos);
8738 }
8739}
8740
8741bool_Bool
8742proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8743{
8744 wmem_list_frame_t *protos = wmem_list_head(layers);
8745 int proto_id;
8746 const char *name;
8747
8748 /* Walk the list of a available protocols in the packet and
8749 attempt to find the specified protocol. */
8750 while (protos != NULL((void*)0))
8751 {
8752 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8753 name = proto_get_protocol_filter_name(proto_id);
8754
8755 if (!strcmp(name, proto_name))
8756 {
8757 return true1;
8758 }
8759
8760 protos = wmem_list_frame_next(protos);
8761 }
8762
8763 return false0;
8764}
8765
8766char *
8767proto_list_layers(const packet_info *pinfo)
8768{
8769 wmem_strbuf_t *buf;
8770 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8771
8772 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8773
8774 /* Walk the list of layers in the packet and
8775 return a string of all entries. */
8776 while (layers != NULL((void*)0))
8777 {
8778 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8779
8780 layers = wmem_list_frame_next(layers);
8781 if (layers != NULL((void*)0)) {
8782 wmem_strbuf_append_c(buf, ':');
8783 }
8784 }
8785
8786 return wmem_strbuf_finalize(buf);
8787}
8788
8789uint8_t
8790proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8791{
8792 int *proto_layer_num_ptr;
8793
8794 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8795 if (proto_layer_num_ptr == NULL((void*)0)) {
8796 return 0;
8797 }
8798
8799 return (uint8_t)*proto_layer_num_ptr;
8800}
8801
8802bool_Bool
8803proto_is_pino(const protocol_t *protocol)
8804{
8805 return (protocol->parent_proto_id != -1);
8806}
8807
8808bool_Bool
8809// NOLINTNEXTLINE(misc-no-recursion)
8810proto_is_protocol_enabled(const protocol_t *protocol)
8811{
8812 if (protocol == NULL((void*)0))
8813 return false0;
8814
8815 //parent protocol determines enable/disable for helper dissectors
8816 if (proto_is_pino(protocol))
8817 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8818
8819 return protocol->is_enabled;
8820}
8821
8822bool_Bool
8823// NOLINTNEXTLINE(misc-no-recursion)
8824proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8825{
8826 //parent protocol determines enable/disable for helper dissectors
8827 if (proto_is_pino(protocol))
8828 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8829
8830 return protocol->enabled_by_default;
8831}
8832
8833bool_Bool
8834// NOLINTNEXTLINE(misc-no-recursion)
8835proto_can_toggle_protocol(const int proto_id)
8836{
8837 protocol_t *protocol;
8838
8839 protocol = find_protocol_by_id(proto_id);
8840 //parent protocol determines toggling for helper dissectors
8841 if (proto_is_pino(protocol))
8842 return proto_can_toggle_protocol(protocol->parent_proto_id);
8843
8844 return protocol->can_toggle;
8845}
8846
8847void
8848proto_disable_by_default(const int proto_id)
8849{
8850 protocol_t *protocol;
8851
8852 protocol = find_protocol_by_id(proto_id);
8853 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8853, "protocol->can_toggle"
))))
;
8854 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", 8854, "proto_is_pino(protocol) == 0"
))))
;
8855 protocol->is_enabled = false0;
8856 protocol->enabled_by_default = false0;
8857}
8858
8859void
8860proto_set_decoding(const int proto_id, const bool_Bool enabled)
8861{
8862 protocol_t *protocol;
8863
8864 protocol = find_protocol_by_id(proto_id);
8865 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8865, "protocol->can_toggle"
))))
;
8866 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", 8866, "proto_is_pino(protocol) == 0"
))))
;
8867 protocol->is_enabled = enabled;
8868}
8869
8870void
8871proto_disable_all(void)
8872{
8873 /* This doesn't explicitly disable heuristic protocols,
8874 * but the heuristic doesn't get called if the parent
8875 * protocol isn't enabled.
8876 */
8877 protocol_t *protocol;
8878 GList *list_item = protocols;
8879
8880 if (protocols == NULL((void*)0))
8881 return;
8882
8883 while (list_item) {
8884 protocol = (protocol_t *)list_item->data;
8885 if (protocol->can_toggle) {
8886 protocol->is_enabled = false0;
8887 }
8888 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8889 }
8890}
8891
8892static void
8893heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8894{
8895 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8896
8897 heur->enabled = heur->enabled_by_default;
8898}
8899
8900void
8901proto_reenable_all(void)
8902{
8903 protocol_t *protocol;
8904 GList *list_item = protocols;
8905
8906 if (protocols == NULL((void*)0))
8907 return;
8908
8909 while (list_item) {
8910 protocol = (protocol_t *)list_item->data;
8911 if (protocol->can_toggle)
8912 protocol->is_enabled = protocol->enabled_by_default;
8913 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8914 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8915 }
8916}
8917
8918void
8919proto_set_cant_toggle(const int proto_id)
8920{
8921 protocol_t *protocol;
8922
8923 protocol = find_protocol_by_id(proto_id);
8924 protocol->can_toggle = false0;
8925}
8926
8927static int
8928proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8929{
8930 g_ptr_array_add(proto->fields, hfi);
8931
8932 return proto_register_field_init(hfi, parent);
8933}
8934
8935/* for use with static arrays only, since we don't allocate our own copies
8936of the header_field_info struct contained within the hf_register_info struct */
8937void
8938proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8939{
8940 hf_register_info *ptr = hf;
8941 protocol_t *proto;
8942 int i;
8943
8944 proto = find_protocol_by_id(parent);
8945
8946 /* if (proto == NULL) - error or return? */
8947
8948 if (proto->fields == NULL((void*)0)) {
8949 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
8950 * GLib introduced g_ptr_array_new_from_array, which might have
8951 * given a reason to actually use it. (#17774)
8952 */
8953 proto->fields = g_ptr_array_sized_new(num_records);
8954 }
8955
8956 for (i = 0; i < num_records; i++, ptr++) {
8957 /*
8958 * Make sure we haven't registered this yet.
8959 * Most fields have variables associated with them that
8960 * are initialized to 0; some are initialized to -1 (which
8961 * was the standard before 4.4).
8962 *
8963 * XXX - Since this is called almost 300000 times at startup,
8964 * it might be nice to compare to only 0 and require
8965 * dissectors to pass in zero for unregistered fields.
8966 */
8967 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8968 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8969 "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)
8970 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8971 return;
8972 }
8973
8974 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8975 }
8976}
8977
8978/* deregister already registered fields */
8979void
8980proto_deregister_field (const int parent, int hf_id)
8981{
8982 header_field_info *hfi;
8983 protocol_t *proto;
8984 unsigned i;
8985
8986 g_free(last_field_name);
8987 last_field_name = NULL((void*)0);
8988
8989 if (hf_id == -1 || hf_id == 0)
8990 return;
8991
8992 proto = find_protocol_by_id (parent);
8993 if (!proto || proto->fields == NULL((void*)0)) {
8994 return;
8995 }
8996
8997 for (i = 0; i < proto->fields->len; i++) {
8998 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8999 if (hfi->id == hf_id) {
9000 /* Found the hf_id in this protocol */
9001 wmem_map_remove(gpa_name_map, hfi->abbrev);
9002 g_ptr_array_remove_index_fast(proto->fields, i);
9003 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9004 return;
9005 }
9006 }
9007}
9008
9009/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9010void
9011proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9012{
9013 header_field_info *hfinfo;
9014 protocol_t *proto;
9015
9016 g_free(last_field_name);
9017 last_field_name = NULL((void*)0);
9018
9019 proto = find_protocol_by_id(parent);
9020 if (proto && proto->fields && proto->fields->len > 0) {
9021 unsigned i = proto->fields->len;
9022 do {
9023 i--;
9024
9025 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9026 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) )
) {
9027 hfinfo_remove_from_gpa_name_map(hfinfo);
9028 expert_deregister_expertinfo(hfinfo->abbrev);
9029 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9030 g_ptr_array_remove_index_fast(proto->fields, i);
9031 }
9032 } while (i > 0);
9033 }
9034}
9035
9036void
9037proto_add_deregistered_data (void *data)
9038{
9039 g_ptr_array_add(deregistered_data, data);
9040}
9041
9042void
9043proto_add_deregistered_slice (size_t block_size, void *mem_block)
9044{
9045 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
)))
;
9046
9047 slice_data->block_size = block_size;
9048 slice_data->mem_block = mem_block;
9049
9050 g_ptr_array_add(deregistered_slice, slice_data);
9051}
9052
9053void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9054{
9055 if (field_strings == NULL((void*)0)) {
9056 return;
9057 }
9058
9059 switch (field_type) {
9060 case FT_FRAMENUM:
9061 /* This is just an integer represented as a pointer */
9062 break;
9063 case FT_PROTOCOL: {
9064 protocol_t *protocol = (protocol_t *)field_strings;
9065 g_free((char *)protocol->short_name);
9066 break;
9067 }
9068 case FT_BOOLEAN: {
9069 true_false_string *tf = (true_false_string *)field_strings;
9070 g_free((char *)tf->true_string);
9071 g_free((char *)tf->false_string);
9072 break;
9073 }
9074 case FT_UINT40:
9075 case FT_INT40:
9076 case FT_UINT48:
9077 case FT_INT48:
9078 case FT_UINT56:
9079 case FT_INT56:
9080 case FT_UINT64:
9081 case FT_INT64: {
9082 if (field_display & BASE_UNIT_STRING0x00001000) {
9083 unit_name_string *unit = (unit_name_string *)field_strings;
9084 g_free((char *)unit->singular);
9085 g_free((char *)unit->plural);
9086 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9087 range_string *rs = (range_string *)field_strings;
9088 while (rs->strptr) {
9089 g_free((char *)rs->strptr);
9090 rs++;
9091 }
9092 } else if (field_display & BASE_EXT_STRING0x00000200) {
9093 val64_string_ext *vse = (val64_string_ext *)field_strings;
9094 val64_string *vs = (val64_string *)vse->_vs_p;
9095 while (vs->strptr) {
9096 g_free((char *)vs->strptr);
9097 vs++;
9098 }
9099 val64_string_ext_free(vse);
9100 field_strings = NULL((void*)0);
9101 } else if (field_display == BASE_CUSTOM) {
9102 /* this will be a pointer to a function, don't free that */
9103 field_strings = NULL((void*)0);
9104 } else {
9105 val64_string *vs64 = (val64_string *)field_strings;
9106 while (vs64->strptr) {
9107 g_free((char *)vs64->strptr);
9108 vs64++;
9109 }
9110 }
9111 break;
9112 }
9113 case FT_CHAR:
9114 case FT_UINT8:
9115 case FT_INT8:
9116 case FT_UINT16:
9117 case FT_INT16:
9118 case FT_UINT24:
9119 case FT_INT24:
9120 case FT_UINT32:
9121 case FT_INT32:
9122 case FT_FLOAT:
9123 case FT_DOUBLE: {
9124 if (field_display & BASE_UNIT_STRING0x00001000) {
9125 unit_name_string *unit = (unit_name_string *)field_strings;
9126 g_free((char *)unit->singular);
9127 g_free((char *)unit->plural);
9128 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9129 range_string *rs = (range_string *)field_strings;
9130 while (rs->strptr) {
9131 g_free((char *)rs->strptr);
9132 rs++;
9133 }
9134 } else if (field_display & BASE_EXT_STRING0x00000200) {
9135 value_string_ext *vse = (value_string_ext *)field_strings;
9136 value_string *vs = (value_string *)vse->_vs_p;
9137 while (vs->strptr) {
9138 g_free((char *)vs->strptr);
9139 vs++;
9140 }
9141 value_string_ext_free(vse);
9142 field_strings = NULL((void*)0);
9143 } else if (field_display == BASE_CUSTOM) {
9144 /* this will be a pointer to a function, don't free that */
9145 field_strings = NULL((void*)0);
9146 } else {
9147 value_string *vs = (value_string *)field_strings;
9148 while (vs->strptr) {
9149 g_free((char *)vs->strptr);
9150 vs++;
9151 }
9152 }
9153 break;
9154 default:
9155 break;
9156 }
9157 }
9158
9159 if (field_type != FT_FRAMENUM) {
9160 g_free((void *)field_strings);
9161 }
9162}
9163
9164static void
9165free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9166{
9167 header_field_info *hfi = (header_field_info *) data;
9168 int hf_id = hfi->id;
9169
9170 g_free((char *)hfi->name);
9171 g_free((char *)hfi->abbrev);
9172 g_free((char *)hfi->blurb);
9173
9174 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9175
9176 if (hfi->parent == -1)
9177 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)
;
9178
9179 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9180}
9181
9182static void
9183free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9184{
9185 g_free (data);
9186}
9187
9188static void
9189free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9190{
9191 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9192
9193 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9194 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)
;
9195}
9196
9197/* free deregistered fields and data */
9198void
9199proto_free_deregistered_fields (void)
9200{
9201 expert_free_deregistered_expertinfos();
9202
9203 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9204 g_ptr_array_free(deregistered_fields, true1);
9205 deregistered_fields = g_ptr_array_new();
9206
9207 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9208 g_ptr_array_free(deregistered_data, true1);
9209 deregistered_data = g_ptr_array_new();
9210
9211 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9212 g_ptr_array_free(deregistered_slice, true1);
9213 deregistered_slice = g_ptr_array_new();
9214}
9215
9216static const value_string hf_display[] = {
9217 { BASE_NONE, "BASE_NONE" },
9218 { BASE_DEC, "BASE_DEC" },
9219 { BASE_HEX, "BASE_HEX" },
9220 { BASE_OCT, "BASE_OCT" },
9221 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9222 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9223 { BASE_CUSTOM, "BASE_CUSTOM" },
9224 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9225 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9226 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9227 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9228 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9229 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9230 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9231 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9232 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9233 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9234 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9235 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9236 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9237 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9238 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9239 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9240 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9241 { BASE_PT_UDP, "BASE_PT_UDP" },
9242 { BASE_PT_TCP, "BASE_PT_TCP" },
9243 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9244 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9245 { BASE_OUI, "BASE_OUI" },
9246 { 0, NULL((void*)0) } };
9247
9248const char* proto_field_display_to_string(int field_display)
9249{
9250 return val_to_str_const(field_display, hf_display, "Unknown");
9251}
9252
9253static inline port_type
9254display_to_port_type(field_display_e e)
9255{
9256 switch (e) {
9257 case BASE_PT_UDP:
9258 return PT_UDP;
9259 case BASE_PT_TCP:
9260 return PT_TCP;
9261 case BASE_PT_DCCP:
9262 return PT_DCCP;
9263 case BASE_PT_SCTP:
9264 return PT_SCTP;
9265 default:
9266 break;
9267 }
9268 return PT_NONE;
9269}
9270
9271/* temporary function containing assert part for easier profiling */
9272static void
9273tmp_fld_check_assert(header_field_info *hfinfo)
9274{
9275 char* tmp_str;
9276
9277 /* The field must have a name (with length > 0) */
9278 if (!hfinfo->name || !hfinfo->name[0]) {
9279 if (hfinfo->abbrev)
9280 /* Try to identify the field */
9281 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)
9282 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9283 else
9284 /* Hum, no luck */
9285 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)"
)
;
9286 }
9287
9288 /* fields with an empty string for an abbreviation aren't filterable */
9289 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9290 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)
;
9291
9292 /* TODO: This check is a significant percentage of startup time (~10%),
9293 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9294 It might be nice to have a way to disable this check when, e.g.,
9295 running TShark many times with the same configuration. */
9296 /* Check that the filter name (abbreviation) is legal;
9297 * it must contain only alphanumerics, '-', "_", and ".". */
9298 unsigned char c;
9299 c = module_check_valid_name(hfinfo->abbrev, false0);
9300 if (c) {
9301 if (c == '.') {
9302 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)
;
9303 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9304 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)
;
9305 } else {
9306 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)
;
9307 }
9308 }
9309
9310 /* These types of fields are allowed to have value_strings,
9311 * true_false_strings or a protocol_t struct
9312 */
9313 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9314 switch (hfinfo->type) {
9315
9316 /*
9317 * These types are allowed to support display value_strings,
9318 * value64_strings, the extended versions of the previous
9319 * two, range strings, or unit strings.
9320 */
9321 case FT_CHAR:
9322 case FT_UINT8:
9323 case FT_UINT16:
9324 case FT_UINT24:
9325 case FT_UINT32:
9326 case FT_UINT40:
9327 case FT_UINT48:
9328 case FT_UINT56:
9329 case FT_UINT64:
9330 case FT_INT8:
9331 case FT_INT16:
9332 case FT_INT24:
9333 case FT_INT32:
9334 case FT_INT40:
9335 case FT_INT48:
9336 case FT_INT56:
9337 case FT_INT64:
9338 case FT_BOOLEAN:
9339 case FT_PROTOCOL:
9340 break;
9341
9342 /*
9343 * This is allowed to have a value of type
9344 * enum ft_framenum_type to indicate what relationship
9345 * the frame in question has to the frame in which
9346 * the field is put.
9347 */
9348 case FT_FRAMENUM:
9349 break;
9350
9351 /*
9352 * These types are allowed to support only unit strings.
9353 */
9354 case FT_FLOAT:
9355 case FT_DOUBLE:
9356 case FT_IEEE_11073_SFLOAT:
9357 case FT_IEEE_11073_FLOAT:
9358 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9359 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))
9360 " (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))
9361 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))
;
9362 }
9363 break;
9364
9365 /*
9366 * These types are allowed to support display
9367 * time_value_strings.
9368 */
9369 case FT_ABSOLUTE_TIME:
9370 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9371 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9372 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9373 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9374 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))
9375 " (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))
9376 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))
;
9377 }
9378 break;
9379
9380 /*
9381 * This type is only allowed to support a string if it's
9382 * a protocol (for pinos).
9383 */
9384 case FT_BYTES:
9385 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9386 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))
9387 " (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))
9388 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))
;
9389 }
9390 break;
9391
9392 default:
9393 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))
9394 " (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))
9395 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))
;
9396 }
9397 }
9398
9399 /* TODO: This check may slow down startup, and output quite a few warnings.
9400 It would be good to be able to enable this (and possibly other checks?)
9401 in non-release builds. */
9402#ifdef ENABLE_CHECK_FILTER
9403 /* Check for duplicate value_string values.
9404 There are lots that have the same value *and* string, so for now only
9405 report those that have same value but different string. */
9406 if ((hfinfo->strings != NULL((void*)0)) &&
9407 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9408 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9409 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9410 (
9411 (hfinfo->type == FT_CHAR) ||
9412 (hfinfo->type == FT_UINT8) ||
9413 (hfinfo->type == FT_UINT16) ||
9414 (hfinfo->type == FT_UINT24) ||
9415 (hfinfo->type == FT_UINT32) ||
9416 (hfinfo->type == FT_INT8) ||
9417 (hfinfo->type == FT_INT16) ||
9418 (hfinfo->type == FT_INT24) ||
9419 (hfinfo->type == FT_INT32) )) {
9420
9421 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9422 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9423 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9424 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9425 } else {
9426 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9427 CHECK_HF_VALUE(value_string, "u", start_values);
9428 }
9429 } else {
9430 const value_string *start_values = (const value_string*)hfinfo->strings;
9431 CHECK_HF_VALUE(value_string, "u", start_values);
9432 }
9433 }
9434
9435 if (hfinfo->type == FT_BOOLEAN) {
9436 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9437 if (tfs) {
9438 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9439 ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9441
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9440 hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9441
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9441 tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9441
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
;
9442 }
9443 }
9444 }
9445
9446 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9447 const range_string *rs = (const range_string*)(hfinfo->strings);
9448 if (rs) {
9449 const range_string *this_it = rs;
9450
9451 do {
9452 if (this_it->value_max < this_it->value_min) {
9453 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"
, 9457, __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)
9454 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9457, __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)
9455 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9457, __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)
9456 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9457, __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)
9457 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9457, __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)
;
9458 ++this_it;
9459 continue;
9460 }
9461
9462 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9463 /* Not OK if this one is completely hidden by an earlier one! */
9464 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9465 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"
, 9471, __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)
9466 "(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"
, 9471, __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)
9467 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9471, __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)
9468 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9471, __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)
9469 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9471, __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)
9470 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9471, __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)
9471 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9471, __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)
;
9472 }
9473 }
9474 ++this_it;
9475 } while (this_it->strptr);
9476 }
9477 }
9478#endif
9479
9480 switch (hfinfo->type) {
9481
9482 case FT_CHAR:
9483 /* Require the char type to have BASE_HEX, BASE_OCT,
9484 * BASE_CUSTOM, or BASE_NONE as its base.
9485 *
9486 * If the display value is BASE_NONE and there is a
9487 * strings conversion then the dissector writer is
9488 * telling us that the field's numerical value is
9489 * meaningless; we'll avoid showing the value to the
9490 * user.
9491 */
9492 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9493 case BASE_HEX:
9494 case BASE_OCT:
9495 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9496 break;
9497 case BASE_NONE:
9498 if (hfinfo->strings == NULL((void*)0))
9499 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
))
9500 " 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
))
9501 " 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
))
9502 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
))
9503 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
))
;
9504 break;
9505 default:
9506 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9507 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)
9508 " 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)
9509 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)
9510 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)
;
9511 //wmem_free(NULL, tmp_str);
9512 }
9513 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9514 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
))
9515 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
))
9516 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
))
;
9517 }
9518 break;
9519 case FT_INT8:
9520 case FT_INT16:
9521 case FT_INT24:
9522 case FT_INT32:
9523 case FT_INT40:
9524 case FT_INT48:
9525 case FT_INT56:
9526 case FT_INT64:
9527 /* Hexadecimal and octal are, in printf() and everywhere
9528 * else, unsigned so don't allow dissectors to register a
9529 * signed field to be displayed unsigned. (Else how would
9530 * we display negative values?)
9531 */
9532 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9533 case BASE_HEX:
9534 case BASE_OCT:
9535 case BASE_DEC_HEX:
9536 case BASE_HEX_DEC:
9537 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9538 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)
9539 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)
9540 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)
;
9541 //wmem_free(NULL, tmp_str);
9542 }
9543 /* FALL THROUGH */
9544 case FT_UINT8:
9545 case FT_UINT16:
9546 case FT_UINT24:
9547 case FT_UINT32:
9548 case FT_UINT40:
9549 case FT_UINT48:
9550 case FT_UINT56:
9551 case FT_UINT64:
9552 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
))
) {
9553 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9554 if (hfinfo->type != FT_UINT16) {
9555 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))
9556 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))
9557 tmp_str, ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s"
, hfinfo->name, hfinfo->abbrev, tmp_str, ftype_name(hfinfo
->type))
;
9558 }
9559 if (hfinfo->strings != NULL((void*)0)) {
9560 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s (%s) but has a strings value",proto_report_dissector_bug("Field '%s' (%s) is an %s (%s) but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9561 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s (%s) but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9562 ftype_name(hfinfo->type), tmp_str)proto_report_dissector_bug("Field '%s' (%s) is an %s (%s) but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
;
9563 }
9564 if (hfinfo->bitmask != 0) {
9565 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s (%s) but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s (%s) but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9566 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s (%s) but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
9567 ftype_name(hfinfo->type), tmp_str)proto_report_dissector_bug("Field '%s' (%s) is an %s (%s) but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
), tmp_str)
;
9568 }
9569 wmem_free(NULL((void*)0), tmp_str);
9570 break;
9571 }
9572
9573 if (hfinfo->display == BASE_OUI) {
9574 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9575 if (hfinfo->type != FT_UINT24) {
9576 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))
9577 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))
9578 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))
;
9579 }
9580 if (hfinfo->strings != NULL((void*)0)) {
9581 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)
9582 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)
9583 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)
;
9584 }
9585 if (hfinfo->bitmask != 0) {
9586 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)
9587 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)
9588 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)
;
9589 }
9590 wmem_free(NULL((void*)0), tmp_str);
9591 break;
9592 }
9593
9594 /* Require integral types (other than frame number,
9595 * which is always displayed in decimal) to have a
9596 * number base.
9597 *
9598 * If the display value is BASE_NONE and there is a
9599 * strings conversion then the dissector writer is
9600 * telling us that the field's numerical value is
9601 * meaningless; we'll avoid showing the value to the
9602 * user.
9603 */
9604 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9605 case BASE_DEC:
9606 case BASE_HEX:
9607 case BASE_OCT:
9608 case BASE_DEC_HEX:
9609 case BASE_HEX_DEC:
9610 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9611 break;
9612 case BASE_NONE:
9613 if (hfinfo->strings == NULL((void*)0)) {
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 BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9615 " 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
))
9616 " 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
))
9617 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
))
9618 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
))
;
9619 }
9620 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9621 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
))
9622 " 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
))
9623 " 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
))
9624 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
))
9625 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
))
;
9626 }
9627 break;
9628
9629 default:
9630 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9631 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)
9632 " 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)
9633 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)
9634 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)
;
9635 //wmem_free(NULL, tmp_str);
9636 }
9637 break;
9638 case FT_BYTES:
9639 case FT_UINT_BYTES:
9640 /* Require bytes to have a "display type" that could
9641 * add a character between displayed bytes.
9642 */
9643 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9644 case BASE_NONE:
9645 case SEP_DOT:
9646 case SEP_DASH:
9647 case SEP_COLON:
9648 case SEP_SPACE:
9649 break;
9650 default:
9651 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9652 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)
9653 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)
;
9654 //wmem_free(NULL, tmp_str);
9655 }
9656 if (hfinfo->bitmask != 0)
9657 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9658 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9659 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9660 //allowed to support string if its a protocol (for pinos)
9661 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9662 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
))
9663 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
))
9664 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
))
;
9665 break;
9666
9667 case FT_PROTOCOL:
9668 case FT_FRAMENUM:
9669 if (hfinfo->display != BASE_NONE) {
9670 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9671 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)
9672 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)
9673 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)
;
9674 //wmem_free(NULL, tmp_str);
9675 }
9676 if (hfinfo->bitmask != 0)
9677 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
))
9678 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
))
9679 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
))
;
9680 break;
9681
9682 case FT_BOOLEAN:
9683 break;
9684
9685 case FT_ABSOLUTE_TIME:
9686 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9687 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9688 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)
9689 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)
;
9690 //wmem_free(NULL, tmp_str);
9691 }
9692 if (hfinfo->bitmask != 0)
9693 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
))
9694 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
))
9695 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
))
;
9696 break;
9697
9698 case FT_STRING:
9699 case FT_STRINGZ:
9700 case FT_UINT_STRING:
9701 case FT_STRINGZPAD:
9702 case FT_STRINGZTRUNC:
9703 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9704 case BASE_NONE:
9705 case BASE_STR_WSP:
9706 break;
9707
9708 default:
9709 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9710 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)
9711 " 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)
9712 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)
9713 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)
;
9714 //wmem_free(NULL, tmp_str);
9715 }
9716
9717 if (hfinfo->bitmask != 0)
9718 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
))
9719 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
))
9720 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
))
;
9721 if (hfinfo->strings != NULL((void*)0))
9722 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
))
9723 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
))
9724 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
))
;
9725 break;
9726
9727 case FT_IPv4:
9728 switch (hfinfo->display) {
9729 case BASE_NONE:
9730 case BASE_NETMASK:
9731 break;
9732
9733 default:
9734 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9735 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)
9736 " 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)
9737 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)
9738 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)
;
9739 //wmem_free(NULL, tmp_str);
9740 break;
9741 }
9742 break;
9743 case FT_FLOAT:
9744 case FT_DOUBLE:
9745 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9746 case BASE_NONE:
9747 case BASE_DEC:
9748 case BASE_HEX:
9749 case BASE_EXP:
9750 case BASE_CUSTOM:
9751 break;
9752 default:
9753 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9754 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)
9755 " 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)
9756 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)
9757 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)
;
9758 //wmem_free(NULL, tmp_str);
9759 }
9760 if (hfinfo->bitmask != 0)
9761 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
))
9762 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
))
9763 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
))
;
9764 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9765 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
))
9766 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
))
9767 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
))
;
9768 break;
9769 case FT_IEEE_11073_SFLOAT:
9770 case FT_IEEE_11073_FLOAT:
9771 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9772 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9773 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)
9774 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)
9775 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)
9776 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)
;
9777 //wmem_free(NULL, tmp_str);
9778 }
9779 if (hfinfo->bitmask != 0)
9780 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
))
9781 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
))
9782 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
))
;
9783 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9784 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
))
9785 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
))
9786 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
))
;
9787 break;
9788 default:
9789 if (hfinfo->display != BASE_NONE) {
9790 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9791 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)
9792 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)
9793 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)
9794 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)
;
9795 //wmem_free(NULL, tmp_str);
9796 }
9797 if (hfinfo->bitmask != 0)
9798 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
))
9799 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
))
9800 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
))
;
9801 if (hfinfo->strings != NULL((void*)0))
9802 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
))
9803 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
))
9804 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
))
;
9805 break;
9806 }
9807}
9808
9809static void
9810register_type_length_mismatch(void)
9811{
9812 static ei_register_info ei[] = {
9813 { &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)}}
}},
9814 { &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)}}
}},
9815 };
9816
9817 expert_module_t* expert_type_length_mismatch;
9818
9819 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9820
9821 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9822 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9823
9824 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9825 disabling them makes no sense. */
9826 proto_set_cant_toggle(proto_type_length_mismatch);
9827}
9828
9829static void
9830register_byte_array_string_decodinws_error(void)
9831{
9832 static ei_register_info ei[] = {
9833 { &ei_byte_array_string_decoding_failed_error,
9834 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9835 "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)}}
9836 }
9837 },
9838 };
9839
9840 expert_module_t* expert_byte_array_string_decoding_error;
9841
9842 proto_byte_array_string_decoding_error =
9843 proto_register_protocol("Byte Array-String Decoding Error",
9844 "Byte Array-string decoding error",
9845 "_ws.byte_array_string.decoding_error");
9846
9847 expert_byte_array_string_decoding_error =
9848 expert_register_protocol(proto_byte_array_string_decoding_error);
9849 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9850
9851 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9852 disabling them makes no sense. */
9853 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9854}
9855
9856static void
9857register_date_time_string_decodinws_error(void)
9858{
9859 static ei_register_info ei[] = {
9860 { &ei_date_time_string_decoding_failed_error,
9861 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9862 "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)}}
9863 }
9864 },
9865 };
9866
9867 expert_module_t* expert_date_time_string_decoding_error;
9868
9869 proto_date_time_string_decoding_error =
9870 proto_register_protocol("Date and Time-String Decoding Error",
9871 "Date and Time-string decoding error",
9872 "_ws.date_time_string.decoding_error");
9873
9874 expert_date_time_string_decoding_error =
9875 expert_register_protocol(proto_date_time_string_decoding_error);
9876 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9877
9878 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9879 disabling them makes no sense. */
9880 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9881}
9882
9883static void
9884register_string_errors(void)
9885{
9886 static ei_register_info ei[] = {
9887 { &ei_string_trailing_characters,
9888 { "_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)}}
}
9889 },
9890 };
9891
9892 expert_module_t* expert_string_errors;
9893
9894 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9895
9896 expert_string_errors = expert_register_protocol(proto_string_errors);
9897 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9898
9899 /* "String Errors" isn't really a protocol, it's an error indication;
9900 disabling them makes no sense. */
9901 proto_set_cant_toggle(proto_string_errors);
9902}
9903
9904static int
9905proto_register_field_init(header_field_info *hfinfo, const int parent)
9906{
9907
9908 tmp_fld_check_assert(hfinfo);
9909
9910 hfinfo->parent = parent;
9911 hfinfo->same_name_next = NULL((void*)0);
9912 hfinfo->same_name_prev_id = -1;
9913
9914 /* if we always add and never delete, then id == len - 1 is correct */
9915 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9916 if (!gpa_hfinfo.hfi) {
9917 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9918 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9919 /* The entry with index 0 is not used. */
9920 gpa_hfinfo.hfi[0] = NULL((void*)0);
9921 gpa_hfinfo.len = 1;
9922 } else {
9923 gpa_hfinfo.allocated_len += 1000;
9924 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9925 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9926 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9927 }
9928 }
9929 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9930 gpa_hfinfo.len++;
9931 hfinfo->id = gpa_hfinfo.len - 1;
9932
9933 /* if we have real names, enter this field in the name tree */
9934 /* Already checked in tmp_fld_check_assert */
9935 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
9936 {
9937
9938 header_field_info *same_name_next_hfinfo;
9939
9940 /* We allow multiple hfinfo's to be registered under the same
9941 * abbreviation. This was done for X.25, as, depending
9942 * on whether it's modulo-8 or modulo-128 operation,
9943 * some bitfield fields may be in different bits of
9944 * a byte, and we want to be able to refer to that field
9945 * with one name regardless of whether the packets
9946 * are modulo-8 or modulo-128 packets. */
9947
9948 /* wmem_map_insert - if key is already present the previous
9949 * hfinfo with the same key/name is returned, otherwise NULL */
9950 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9951 if (same_name_hfinfo) {
9952 /* There's already a field with this name.
9953 * Put the current field *before* that field
9954 * in the list of fields with this name, Thus,
9955 * we end up with an effectively
9956 * doubly-linked-list of same-named hfinfo's,
9957 * with the head of the list (stored in the
9958 * hash) being the last seen hfinfo.
9959 */
9960 same_name_next_hfinfo =
9961 same_name_hfinfo->same_name_next;
9962
9963 hfinfo->same_name_next = same_name_next_hfinfo;
9964 if (same_name_next_hfinfo)
9965 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9966
9967 same_name_hfinfo->same_name_next = hfinfo;
9968 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9969#ifdef ENABLE_CHECK_FILTER
9970 while (same_name_hfinfo) {
9971 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9972 ws_error("'%s' exists multiple times with incompatible types: %s and %s", hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(same_name_hfinfo->type))ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9972
, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type))
;
9973 same_name_hfinfo = same_name_hfinfo->same_name_next;
9974 }
9975#endif
9976 }
9977 }
9978
9979 return hfinfo->id;
9980}
9981
9982void
9983proto_register_subtree_array(int * const *indices, const int num_indices)
9984{
9985 int i;
9986 int *const *ptr = indices;
9987
9988 /*
9989 * If we've already allocated the array of tree types, expand
9990 * it; this lets plugins such as mate add tree types after
9991 * the initial startup. (If we haven't already allocated it,
9992 * we don't allocate it; on the first pass, we just assign
9993 * ett values and keep track of how many we've assigned, and
9994 * when we're finished registering all dissectors we allocate
9995 * the array, so that we do only one allocation rather than
9996 * wasting CPU time and memory by growing the array for each
9997 * dissector that registers ett values.)
9998 */
9999 if (tree_is_expanded != NULL((void*)0)) {
10000 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10001
10002 /* set new items to 0 */
10003 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10004 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10005 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10006 }
10007
10008 /*
10009 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10010 * returning the indices through the pointers in the array whose
10011 * first element is pointed to by "indices", and update
10012 * "num_tree_types" appropriately.
10013 */
10014 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10015 if (**ptr != -1 && **ptr != 0) {
10016 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.")
10017 " 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.")
10018 " 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.")
10019 " 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.")
;
10020 }
10021 **ptr = num_tree_types;
10022 }
10023}
10024
10025static void
10026mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10027{
10028 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10029 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10030 char *last_char;
10031
10032 /* ..... field_name: dataaaaaaaaaaaaa
10033 * |
10034 * ^^^^^ name_pos
10035 *
10036 * ..... field_name […]: dataaaaaaaaaaaaa
10037 *
10038 * name_pos==0 means that we have only data or only a field_name
10039 */
10040
10041 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10041, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10042
10043 if (name_pos >= size - trunc_len) {
10044 /* No room for trunc_str after the field_name, put it first. */
10045 name_pos = 0;
10046 }
10047
10048 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10049 if (name_pos == 0) {
10050 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10051 memcpy(label_str, trunc_str + 1, trunc_len);
10052 } else {
10053 memcpy(label_str + name_pos, trunc_str, trunc_len);
10054 }
10055 /* in general, label_str is UTF-8
10056 we can truncate it only at the beginning of a new character
10057 we go backwards from the byte right after our buffer and
10058 find the next starting byte of a UTF-8 character, this is
10059 where we cut
10060 there's no need to use g_utf8_find_prev_char(), the search
10061 will always succeed since we copied trunc_str into the
10062 buffer */
10063 /* g_utf8_prev_char does not deference the memory address
10064 * passed in (until after decrementing it, so it is perfectly
10065 * legal to pass in a pointer one past the last element.
10066 */
10067 last_char = g_utf8_prev_char(label_str + size);
10068 *last_char = '\0';
10069 /* This is unnecessary (above always terminates), but try to
10070 * convince Coverity to avoid dozens of false positives. */
10071 label_str[size - 1] = '\0';
10072
10073 if (value_pos && *value_pos > 0) {
10074 if (name_pos == 0) {
10075 *value_pos += trunc_len;
10076 } else {
10077 /* Move one back to include trunc_str in the value. */
10078 *value_pos -= 1;
10079 }
10080 }
10081
10082 /* Check if value_pos is past label_str. */
10083 if (value_pos && *value_pos >= size) {
10084 *value_pos = size - 1;
10085 }
10086}
10087
10088static void
10089label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10090{
10091 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10092}
10093
10094static size_t
10095label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10096{
10097 size_t name_pos;
10098
10099 /* "%s: %s", hfinfo->name, text */
10100 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)
;
10101 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10102 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10103 if (value_pos) {
10104 *value_pos = pos;
10105 }
10106 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10107 }
10108
10109 if (pos >= ITEM_LABEL_LENGTH240) {
10110 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10111 label_mark_truncated(label_str, name_pos, value_pos);
10112 }
10113
10114 return pos;
10115}
10116
10117static size_t
10118label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10119{
10120 size_t name_pos;
10121
10122 /* "%s: %s (%s)", hfinfo->name, text, descr */
10123 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)
;
10124 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10125 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10126 if (value_pos) {
10127 *value_pos = pos;
10128 }
10129 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10130 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)
;
10131 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)
;
10132 } else {
10133 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)
;
10134 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10135 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)
;
10136 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10137 }
10138 }
10139
10140 if (pos >= ITEM_LABEL_LENGTH240) {
10141 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10142 label_mark_truncated(label_str, name_pos, value_pos);
10143 }
10144
10145 return pos;
10146}
10147
10148void
10149proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10150{
10151 const header_field_info *hfinfo;
10152 const char *str;
10153 const uint8_t *bytes;
10154 uint32_t integer;
10155 const ipv4_addr_and_mask *ipv4;
10156 const ipv6_addr_and_prefix *ipv6;
10157 const e_guid_t *guid;
10158 char *name;
10159 address addr;
10160 char *addr_str;
10161 char *tmp;
10162
10163 if (!label_str) {
10164 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10164, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10165 return;
10166 }
10167
10168 label_str[0]= '\0';
10169
10170 if (!fi) {
10171 return;
10172 }
10173
10174 hfinfo = fi->hfinfo;
10175
10176 switch (hfinfo->type) {
10177 case FT_NONE:
10178 case FT_PROTOCOL:
10179 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10180 if (value_pos) {
10181 *value_pos = strlen(hfinfo->name);
10182 }
10183 break;
10184
10185 case FT_BOOLEAN:
10186 fill_label_boolean(fi, label_str, value_pos);
10187 break;
10188
10189 case FT_BYTES:
10190 case FT_UINT_BYTES:
10191 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10192 fvalue_get_bytes_data(fi->value),
10193 (unsigned)fvalue_length2(fi->value));
10194 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10195 wmem_free(NULL((void*)0), tmp);
10196 break;
10197
10198 case FT_CHAR:
10199 if (hfinfo->bitmask) {
10200 fill_label_bitfield_char(fi, label_str, value_pos);
10201 } else {
10202 fill_label_char(fi, label_str, value_pos);
10203 }
10204 break;
10205
10206 /* Four types of integers to take care of:
10207 * Bitfield, with val_string
10208 * Bitfield, w/o val_string
10209 * Non-bitfield, with val_string
10210 * Non-bitfield, w/o val_string
10211 */
10212 case FT_UINT8:
10213 case FT_UINT16:
10214 case FT_UINT24:
10215 case FT_UINT32:
10216 if (hfinfo->bitmask) {
10217 fill_label_bitfield(fi, label_str, value_pos, false0);
10218 } else {
10219 fill_label_number(fi, label_str, value_pos, false0);
10220 }
10221 break;
10222
10223 case FT_FRAMENUM:
10224 fill_label_number(fi, label_str, value_pos, false0);
10225 break;
10226
10227 case FT_UINT40:
10228 case FT_UINT48:
10229 case FT_UINT56:
10230 case FT_UINT64:
10231 if (hfinfo->bitmask) {
10232 fill_label_bitfield64(fi, label_str, value_pos, false0);
10233 } else {
10234 fill_label_number64(fi, label_str, value_pos, false0);
10235 }
10236 break;
10237
10238 case FT_INT8:
10239 case FT_INT16:
10240 case FT_INT24:
10241 case FT_INT32:
10242 if (hfinfo->bitmask) {
10243 fill_label_bitfield(fi, label_str, value_pos, true1);
10244 } else {
10245 fill_label_number(fi, label_str, value_pos, true1);
10246 }
10247 break;
10248
10249 case FT_INT40:
10250 case FT_INT48:
10251 case FT_INT56:
10252 case FT_INT64:
10253 if (hfinfo->bitmask) {
10254 fill_label_bitfield64(fi, label_str, value_pos, true1);
10255 } else {
10256 fill_label_number64(fi, label_str, value_pos, true1);
10257 }
10258 break;
10259
10260 case FT_FLOAT:
10261 case FT_DOUBLE:
10262 fill_label_float(fi, label_str, value_pos);
10263 break;
10264
10265 case FT_ABSOLUTE_TIME:
10266 {
10267 const nstime_t *value = fvalue_get_time(fi->value);
10268 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10269 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10270 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10271 }
10272 if (hfinfo->strings) {
10273 /*
10274 * Table of time valus to be displayed
10275 * specially.
10276 */
10277 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10278 if (time_string != NULL((void*)0)) {
10279 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10280 break;
10281 }
10282 }
10283 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10284 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10285 wmem_free(NULL((void*)0), tmp);
10286 break;
10287 }
10288 case FT_RELATIVE_TIME:
10289 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10290 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10291 wmem_free(NULL((void*)0), tmp);
10292 break;
10293
10294 case FT_IPXNET:
10295 integer = fvalue_get_uinteger(fi->value);
10296 tmp = get_ipxnet_name(NULL((void*)0), integer);
10297 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10298 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10299 wmem_free(NULL((void*)0), tmp);
10300 wmem_free(NULL((void*)0), addr_str);
10301 break;
10302
10303 case FT_VINES:
10304 addr.type = AT_VINES;
10305 addr.len = VINES_ADDR_LEN6;
10306 addr.data = fvalue_get_bytes_data(fi->value);
10307
10308 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10309 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10310 wmem_free(NULL((void*)0), addr_str);
10311 break;
10312
10313 case FT_ETHER:
10314 bytes = fvalue_get_bytes_data(fi->value);
10315
10316 addr.type = AT_ETHER;
10317 addr.len = 6;
10318 addr.data = bytes;
10319
10320 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10321 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10322 wmem_free(NULL((void*)0), addr_str);
10323 break;
10324
10325 case FT_IPv4:
10326 ipv4 = fvalue_get_ipv4(fi->value);
10327 set_address_ipv4(&addr, ipv4);
10328
10329 if (hfinfo->display == BASE_NETMASK) {
10330 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10331 } else {
10332 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10333 }
10334 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10335 wmem_free(NULL((void*)0), addr_str);
10336 free_address(&addr);
10337 break;
10338
10339 case FT_IPv6:
10340 ipv6 = fvalue_get_ipv6(fi->value);
10341 set_address_ipv6(&addr, ipv6);
10342
10343 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10344 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10345 wmem_free(NULL((void*)0), addr_str);
10346 free_address(&addr);
10347 break;
10348
10349 case FT_FCWWN:
10350 bytes = fvalue_get_bytes_data(fi->value);
10351 addr.type = AT_FCWWN;
10352 addr.len = FCWWN_ADDR_LEN8;
10353 addr.data = bytes;
10354
10355 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10356 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10357 wmem_free(NULL((void*)0), addr_str);
10358 break;
10359
10360 case FT_GUID:
10361 guid = fvalue_get_guid(fi->value);
10362 tmp = guid_to_str(NULL((void*)0), guid);
10363 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10364 wmem_free(NULL((void*)0), tmp);
10365 break;
10366
10367 case FT_OID:
10368 bytes = fvalue_get_bytes_data(fi->value);
10369 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10370 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10371 if (name) {
10372 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10373 wmem_free(NULL((void*)0), name);
10374 } else {
10375 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10376 }
10377 wmem_free(NULL((void*)0), tmp);
10378 break;
10379
10380 case FT_REL_OID:
10381 bytes = fvalue_get_bytes_data(fi->value);
10382 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10383 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10384 if (name) {
10385 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10386 wmem_free(NULL((void*)0), name);
10387 } else {
10388 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10389 }
10390 wmem_free(NULL((void*)0), tmp);
10391 break;
10392
10393 case FT_SYSTEM_ID:
10394 bytes = fvalue_get_bytes_data(fi->value);
10395 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10396 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10397 wmem_free(NULL((void*)0), tmp);
10398 break;
10399
10400 case FT_EUI64:
10401 bytes = fvalue_get_bytes_data(fi->value);
10402 addr.type = AT_EUI64;
10403 addr.len = EUI64_ADDR_LEN8;
10404 addr.data = bytes;
10405
10406 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10407 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10408 wmem_free(NULL((void*)0), addr_str);
10409 break;
10410 case FT_STRING:
10411 case FT_STRINGZ:
10412 case FT_UINT_STRING:
10413 case FT_STRINGZPAD:
10414 case FT_STRINGZTRUNC:
10415 case FT_AX25:
10416 str = fvalue_get_string(fi->value);
10417 label_fill(label_str, 0, hfinfo, str, value_pos);
10418 break;
10419
10420 case FT_IEEE_11073_SFLOAT:
10421 case FT_IEEE_11073_FLOAT:
10422 fill_label_ieee_11073_float(fi, label_str, value_pos);
10423 break;
10424
10425 default:
10426 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
))
10427 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
))
10428 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
))
10429 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
))
;
10430 break;
10431 }
10432}
10433
10434static void
10435fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10436{
10437 char *p;
10438 int bitfield_byte_length = 0, bitwidth;
10439 uint64_t unshifted_value;
10440 uint64_t value;
10441
10442 const header_field_info *hfinfo = fi->hfinfo;
10443
10444 value = fvalue_get_uinteger64(fi->value);
10445 if (hfinfo->bitmask) {
10446 /* Figure out the bit width */
10447 bitwidth = hfinfo_container_bitwidth(hfinfo);
10448
10449 /* Un-shift bits */
10450 unshifted_value = value;
10451 unshifted_value <<= hfinfo_bitshift(hfinfo);
10452
10453 /* Create the bitfield first */
10454 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10455 bitfield_byte_length = (int) (p - label_str);
10456 }
10457
10458 /* Fill in the textual info */
10459 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10460}
10461
10462static const char *
10463hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10464{
10465 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10466 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10467
10468 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10469 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10470 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10471 else
10472 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10473 }
10474
10475 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10476 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10477
10478 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10479 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10480
10481 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10482}
10483
10484static const char *
10485hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10486{
10487 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10488 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10489 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10490 else
10491 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10492 }
10493
10494 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10495 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10496
10497 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10498 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10499
10500 /* If this is reached somebody registered a 64-bit field with a 32-bit
10501 * value-string, which isn't right. */
10502 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)
10503 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10504
10505 /* This is necessary to squelch MSVC errors; is there
10506 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10507 never returns? */
10508 return NULL((void*)0);
10509}
10510
10511static const char *
10512hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10513{
10514 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10515 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10516
10517 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)
;
10518
10519 /* This is necessary to squelch MSVC errors; is there
10520 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10521 never returns? */
10522 return NULL((void*)0);
10523}
10524
10525static const char *
10526hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10527{
10528 const char *str = hf_try_val_to_str(value, hfinfo);
10529
10530 return (str) ? str : unknown_str;
10531}
10532
10533static const char *
10534hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10535{
10536 const char *str = hf_try_val64_to_str(value, hfinfo);
10537
10538 return (str) ? str : unknown_str;
10539}
10540
10541/* Fills data for bitfield chars with val_strings */
10542static void
10543fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10544{
10545 char *p;
10546 int bitfield_byte_length, bitwidth;
10547 uint32_t unshifted_value;
10548 uint32_t value;
10549
10550 char buf[32];
10551 const char *out;
10552
10553 const header_field_info *hfinfo = fi->hfinfo;
10554
10555 /* Figure out the bit width */
10556 bitwidth = hfinfo_container_bitwidth(hfinfo);
10557
10558 /* Un-shift bits */
10559 value = fvalue_get_uinteger(fi->value);
10560
10561 unshifted_value = value;
10562 if (hfinfo->bitmask) {
10563 unshifted_value <<= hfinfo_bitshift(hfinfo);
10564 }
10565
10566 /* Create the bitfield first */
10567 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10568 bitfield_byte_length = (int) (p - label_str);
10569
10570 /* Fill in the textual info using stored (shifted) value */
10571 if (hfinfo->display == BASE_CUSTOM) {
10572 char tmp[ITEM_LABEL_LENGTH240];
10573 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10574
10575 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10575, "fmtfunc"))))
;
10576 fmtfunc(tmp, value);
10577 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10578 }
10579 else if (hfinfo->strings) {
10580 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10581
10582 out = hfinfo_char_vals_format(hfinfo, buf, value);
10583 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10584 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10585 else
10586 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10587 }
10588 else {
10589 out = hfinfo_char_value_format(hfinfo, buf, value);
10590
10591 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10592 }
10593}
10594
10595/* Fills data for bitfield ints with val_strings */
10596static void
10597fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10598{
10599 char *p;
10600 int bitfield_byte_length, bitwidth;
10601 uint32_t value, unshifted_value;
10602 char buf[NUMBER_LABEL_LENGTH80];
10603 const char *out;
10604
10605 const header_field_info *hfinfo = fi->hfinfo;
10606
10607 /* Figure out the bit width */
10608 if (fi->flags & FI_VARINT0x00040000)
10609 bitwidth = fi->length*8;
10610 else
10611 bitwidth = hfinfo_container_bitwidth(hfinfo);
10612
10613 /* Un-shift bits */
10614 if (is_signed)
10615 value = fvalue_get_sinteger(fi->value);
10616 else
10617 value = fvalue_get_uinteger(fi->value);
10618
10619 unshifted_value = value;
10620 if (hfinfo->bitmask) {
10621 unshifted_value <<= hfinfo_bitshift(hfinfo);
10622 }
10623
10624 /* Create the bitfield first */
10625 if (fi->flags & FI_VARINT0x00040000)
10626 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10627 else
10628 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10629 bitfield_byte_length = (int) (p - label_str);
10630
10631 /* Fill in the textual info using stored (shifted) value */
10632 if (hfinfo->display == BASE_CUSTOM) {
10633 char tmp[ITEM_LABEL_LENGTH240];
10634 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10635
10636 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10636, "fmtfunc"))))
;
10637 fmtfunc(tmp, value);
10638 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10639 }
10640 else if (hfinfo->strings) {
10641 const char *val_str = hf_try_val_to_str(value, hfinfo);
10642
10643 out = hfinfo_number_vals_format(hfinfo, buf, value);
10644 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10645 /*
10646 * Unique values only display value_string string
10647 * if there is a match. Otherwise it's just a number
10648 */
10649 if (val_str) {
10650 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10651 } else {
10652 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10653 }
10654 } else {
10655 if (val_str == NULL((void*)0))
10656 val_str = "Unknown";
10657
10658 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10659 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10660 else
10661 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10662 }
10663 }
10664 else {
10665 out = hfinfo_number_value_format(hfinfo, buf, value);
10666
10667 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10668 }
10669}
10670
10671static void
10672fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10673{
10674 char *p;
10675 int bitfield_byte_length, bitwidth;
10676 uint64_t value, unshifted_value;
10677 char buf[NUMBER_LABEL_LENGTH80];
10678 const char *out;
10679
10680 const header_field_info *hfinfo = fi->hfinfo;
10681
10682 /* Figure out the bit width */
10683 if (fi->flags & FI_VARINT0x00040000)
10684 bitwidth = fi->length*8;
10685 else
10686 bitwidth = hfinfo_container_bitwidth(hfinfo);
10687
10688 /* Un-shift bits */
10689 if (is_signed)
10690 value = fvalue_get_sinteger64(fi->value);
10691 else
10692 value = fvalue_get_uinteger64(fi->value);
10693
10694 unshifted_value = value;
10695 if (hfinfo->bitmask) {
10696 unshifted_value <<= hfinfo_bitshift(hfinfo);
10697 }
10698
10699 /* Create the bitfield first */
10700 if (fi->flags & FI_VARINT0x00040000)
10701 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10702 else
10703 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10704 bitfield_byte_length = (int) (p - label_str);
10705
10706 /* Fill in the textual info using stored (shifted) value */
10707 if (hfinfo->display == BASE_CUSTOM) {
10708 char tmp[ITEM_LABEL_LENGTH240];
10709 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10710
10711 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10711, "fmtfunc64"
))))
;
10712 fmtfunc64(tmp, value);
10713 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10714 }
10715 else if (hfinfo->strings) {
10716 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10717
10718 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10719 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10720 /*
10721 * Unique values only display value_string string
10722 * if there is a match. Otherwise it's just a number
10723 */
10724 if (val_str) {
10725 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10726 } else {
10727 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10728 }
10729 } else {
10730 if (val_str == NULL((void*)0))
10731 val_str = "Unknown";
10732
10733 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10734 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10735 else
10736 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10737 }
10738 }
10739 else {
10740 out = hfinfo_number_value_format64(hfinfo, buf, value);
10741
10742 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10743 }
10744}
10745
10746static void
10747fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10748{
10749 const header_field_info *hfinfo = fi->hfinfo;
10750 uint32_t value;
10751
10752 char buf[32];
10753 const char *out;
10754
10755 value = fvalue_get_uinteger(fi->value);
10756
10757 /* Fill in the textual info */
10758 if (hfinfo->display == BASE_CUSTOM) {
10759 char tmp[ITEM_LABEL_LENGTH240];
10760 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10761
10762 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10762, "fmtfunc"))))
;
10763 fmtfunc(tmp, value);
10764 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10765 }
10766 else if (hfinfo->strings) {
10767 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10768
10769 out = hfinfo_char_vals_format(hfinfo, buf, value);
10770 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10771 }
10772 else {
10773 out = hfinfo_char_value_format(hfinfo, buf, value);
10774
10775 label_fill(label_str, 0, hfinfo, out, value_pos);
10776 }
10777}
10778
10779static void
10780fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10781{
10782 const header_field_info *hfinfo = fi->hfinfo;
10783 uint32_t value;
10784
10785 char buf[NUMBER_LABEL_LENGTH80];
10786 const char *out;
10787
10788 if (is_signed)
10789 value = fvalue_get_sinteger(fi->value);
10790 else
10791 value = fvalue_get_uinteger(fi->value);
10792
10793 /* Fill in the textual info */
10794 if (hfinfo->display == BASE_CUSTOM) {
10795 char tmp[ITEM_LABEL_LENGTH240];
10796 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10797
10798 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10798, "fmtfunc"))))
;
10799 fmtfunc(tmp, value);
10800 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10801 }
10802 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10803 /*
10804 * It makes no sense to have a value-string table for a
10805 * frame-number field - they're just integers giving
10806 * the ordinal frame number.
10807 */
10808 const char *val_str = hf_try_val_to_str(value, hfinfo);
10809
10810 out = hfinfo_number_vals_format(hfinfo, buf, value);
10811 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10812 /*
10813 * Unique values only display value_string string
10814 * if there is a match. Otherwise it's just a number
10815 */
10816 if (val_str) {
10817 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10818 } else {
10819 label_fill(label_str, 0, hfinfo, out, value_pos);
10820 }
10821 } else {
10822 if (val_str == NULL((void*)0))
10823 val_str = "Unknown";
10824
10825 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10826 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10827 else
10828 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10829 }
10830 }
10831 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
))
) {
10832 char tmp[ITEM_LABEL_LENGTH240];
10833
10834 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10835 display_to_port_type((field_display_e)hfinfo->display), value);
10836 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10837 }
10838 else {
10839 out = hfinfo_number_value_format(hfinfo, buf, value);
10840
10841 label_fill(label_str, 0, hfinfo, out, value_pos);
10842 }
10843}
10844
10845static void
10846fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10847{
10848 const header_field_info *hfinfo = fi->hfinfo;
10849 uint64_t value;
10850
10851 char buf[NUMBER_LABEL_LENGTH80];
10852 const char *out;
10853
10854 if (is_signed)
10855 value = fvalue_get_sinteger64(fi->value);
10856 else
10857 value = fvalue_get_uinteger64(fi->value);
10858
10859 /* Fill in the textual info */
10860 if (hfinfo->display == BASE_CUSTOM) {
10861 char tmp[ITEM_LABEL_LENGTH240];
10862 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10863
10864 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10864, "fmtfunc64"
))))
;
10865 fmtfunc64(tmp, value);
10866 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10867 }
10868 else if (hfinfo->strings) {
10869 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10870
10871 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10872 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10873 /*
10874 * Unique values only display value_string string
10875 * if there is a match. Otherwise it's just a number
10876 */
10877 if (val_str) {
10878 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10879 } else {
10880 label_fill(label_str, 0, hfinfo, out, value_pos);
10881 }
10882 } else {
10883 if (val_str == NULL((void*)0))
10884 val_str = "Unknown";
10885
10886 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10887 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10888 else
10889 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10890 }
10891 }
10892 else {
10893 out = hfinfo_number_value_format64(hfinfo, buf, value);
10894
10895 label_fill(label_str, 0, hfinfo, out, value_pos);
10896 }
10897}
10898
10899static size_t
10900fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10901{
10902 int display;
10903 int n;
10904 double value;
10905
10906 if (label_str_size < 12) {
10907 /* Not enough room to write an entire floating point value. */
10908 return 0;
10909 }
10910
10911 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10912 value = fvalue_get_floating(fi->value);
10913
10914 if (display == BASE_CUSTOM) {
10915 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10916 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10916, "fmtfunc"))))
;
10917 fmtfunc(label_str, value);
10918 return strlen(label_str);
10919 }
10920
10921 switch (display) {
10922 case BASE_NONE:
10923 if (fi->hfinfo->type == FT_FLOAT) {
10924 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10925 } else {
10926 n = (int)strlen(dtoa_g_fmt(label_str, value));
10927 }
10928 break;
10929 case BASE_DEC:
10930 n = snprintf(label_str, label_str_size, "%f", value);
10931 break;
10932 case BASE_HEX:
10933 n = snprintf(label_str, label_str_size, "%a", value);
10934 break;
10935 case BASE_EXP:
10936 n = snprintf(label_str, label_str_size, "%e", value);
10937 break;
10938 default:
10939 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10939
, __func__, "assertion \"not reached\" failed")
;
10940 }
10941 if (n < 0) {
10942 return 0; /* error */
10943 }
10944 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10945 const char *hf_str_val;
10946 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10947 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10948 }
10949 if (n > label_str_size) {
10950 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10950, __func__, "label length too small"); } } while (0)
;
10951 return strlen(label_str);
10952 }
10953
10954 return n;
10955}
10956
10957void
10958fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10959{
10960 char tmp[ITEM_LABEL_LENGTH240];
10961
10962 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10963 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10964}
10965
10966static size_t
10967fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10968{
10969 int display;
10970 size_t pos = 0;
10971 double value;
10972 char* tmp_str;
10973
10974 if (label_str_size < 12) {
10975 /* Not enough room to write an entire floating point value. */
10976 return 0;
10977 }
10978
10979 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10980 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10981 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
10982 wmem_free(NULL((void*)0), tmp_str);
10983
10984 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10985 const char *hf_str_val;
10986 fvalue_to_double(fi->value, &value);
10987 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10988 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)
;
10989 }
10990 if ((int)pos > label_str_size) {
10991 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10991, __func__, "label length too small"); } } while (0)
;
10992 return strlen(label_str);
10993 }
10994
10995 return pos;
10996}
10997
10998void
10999fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11000{
11001 char tmp[ITEM_LABEL_LENGTH240];
11002
11003 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11004 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11005}
11006
11007int
11008hfinfo_bitshift(const header_field_info *hfinfo)
11009{
11010 return ws_ctz(hfinfo->bitmask);
11011}
11012
11013
11014static int
11015hfinfo_bitoffset(const header_field_info *hfinfo)
11016{
11017 if (!hfinfo->bitmask) {
11018 return 0;
11019 }
11020
11021 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11022 * as the first bit */
11023 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11024}
11025
11026static int
11027hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11028{
11029 if (!hfinfo->bitmask) {
11030 return 0;
11031 }
11032
11033 /* ilog2 = first set bit, ctz = last set bit */
11034 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11035}
11036
11037static int
11038hfinfo_type_bitwidth(enum ftenum type)
11039{
11040 int bitwidth = 0;
11041
11042 switch (type) {
11043 case FT_CHAR:
11044 case FT_UINT8:
11045 case FT_INT8:
11046 bitwidth = 8;
11047 break;
11048 case FT_UINT16:
11049 case FT_INT16:
11050 bitwidth = 16;
11051 break;
11052 case FT_UINT24:
11053 case FT_INT24:
11054 bitwidth = 24;
11055 break;
11056 case FT_UINT32:
11057 case FT_INT32:
11058 bitwidth = 32;
11059 break;
11060 case FT_UINT40:
11061 case FT_INT40:
11062 bitwidth = 40;
11063 break;
11064 case FT_UINT48:
11065 case FT_INT48:
11066 bitwidth = 48;
11067 break;
11068 case FT_UINT56:
11069 case FT_INT56:
11070 bitwidth = 56;
11071 break;
11072 case FT_UINT64:
11073 case FT_INT64:
11074 bitwidth = 64;
11075 break;
11076 default:
11077 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11077))
;
11078 ;
11079 }
11080 return bitwidth;
11081}
11082
11083
11084static int
11085hfinfo_container_bitwidth(const header_field_info *hfinfo)
11086{
11087 if (!hfinfo->bitmask) {
11088 return 0;
11089 }
11090
11091 if (hfinfo->type == FT_BOOLEAN) {
11092 return hfinfo->display; /* hacky? :) */
11093 }
11094
11095 return hfinfo_type_bitwidth(hfinfo->type);
11096}
11097
11098static int
11099hfinfo_hex_digits(const header_field_info *hfinfo)
11100{
11101 int bitwidth;
11102
11103 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11104 * appropriate to determine the number of hex digits for the field.
11105 * So instead, we compute it from the bitmask.
11106 */
11107 if (hfinfo->bitmask != 0) {
11108 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11109 } else {
11110 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11111 }
11112
11113 /* Divide by 4, rounding up, to get number of hex digits. */
11114 return (bitwidth + 3) / 4;
11115}
11116
11117const char *
11118hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11119{
11120 char *ptr = &buf[6];
11121 static const char hex_digits[16] =
11122 { '0', '1', '2', '3', '4', '5', '6', '7',
11123 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11124
11125 *ptr = '\0';
11126 *(--ptr) = '\'';
11127 /* Properly format value */
11128 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11129 /*
11130 * Printable, so just show the character, and, if it needs
11131 * to be escaped, escape it.
11132 */
11133 *(--ptr) = value;
11134 if (value == '\\' || value == '\'')
11135 *(--ptr) = '\\';
11136 } else {
11137 /*
11138 * Non-printable; show it as an escape sequence.
11139 */
11140 switch (value) {
11141
11142 case '\0':
11143 /*
11144 * Show a NUL with only one digit.
11145 */
11146 *(--ptr) = '0';
11147 break;
11148
11149 case '\a':
11150 case '\b':
11151 case '\f':
11152 case '\n':
11153 case '\r':
11154 case '\t':
11155 case '\v':
11156 *(--ptr) = value - '\a' + 'a';
11157 break;
11158
11159 default:
11160 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11161
11162 case BASE_OCT:
11163 *(--ptr) = (value & 0x7) + '0';
11164 value >>= 3;
11165 *(--ptr) = (value & 0x7) + '0';
11166 value >>= 3;
11167 *(--ptr) = (value & 0x7) + '0';
11168 break;
11169
11170 case BASE_HEX:
11171 *(--ptr) = hex_digits[value & 0x0F];
11172 value >>= 4;
11173 *(--ptr) = hex_digits[value & 0x0F];
11174 *(--ptr) = 'x';
11175 break;
11176
11177 default:
11178 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11179 }
11180 }
11181 *(--ptr) = '\\';
11182 }
11183 *(--ptr) = '\'';
11184 return ptr;
11185}
11186
11187static const char *
11188hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11189{
11190 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11191 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
))
;
11192
11193 *ptr = '\0';
11194 /* Properly format value */
11195 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11196 case BASE_DEC:
11197 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11198
11199 case BASE_DEC_HEX:
11200 *(--ptr) = ')';
11201 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11202 *(--ptr) = '(';
11203 *(--ptr) = ' ';
11204 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11205 return ptr;
11206
11207 case BASE_OCT:
11208 return oct_to_str_back(ptr, value);
11209
11210 case BASE_HEX:
11211 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11212
11213 case BASE_HEX_DEC:
11214 *(--ptr) = ')';
11215 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11216 *(--ptr) = '(';
11217 *(--ptr) = ' ';
11218 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11219 return ptr;
11220
11221 case BASE_PT_UDP:
11222 case BASE_PT_TCP:
11223 case BASE_PT_DCCP:
11224 case BASE_PT_SCTP:
11225 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11226 display_to_port_type((field_display_e)display), value);
11227 return buf;
11228 case BASE_OUI:
11229 {
11230 uint8_t p_oui[3];
11231 const char *manuf_name;
11232
11233 p_oui[0] = value >> 16 & 0xFF;
11234 p_oui[1] = value >> 8 & 0xFF;
11235 p_oui[2] = value & 0xFF;
11236
11237 /* Attempt an OUI lookup. */
11238 manuf_name = uint_get_manuf_name_if_known(value);
11239 if (manuf_name == NULL((void*)0)) {
11240 /* Could not find an OUI. */
11241 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11242 }
11243 else {
11244 /* Found an address string. */
11245 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11246 }
11247 return buf;
11248 }
11249
11250 default:
11251 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11252 }
11253 return ptr;
11254}
11255
11256static const char *
11257hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11258{
11259 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11260 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
))
;
11261
11262 *ptr = '\0';
11263 /* Properly format value */
11264 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11265 case BASE_DEC:
11266 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11267
11268 case BASE_DEC_HEX:
11269 *(--ptr) = ')';
11270 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11271 *(--ptr) = '(';
11272 *(--ptr) = ' ';
11273 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11274 return ptr;
11275
11276 case BASE_OCT:
11277 return oct64_to_str_back(ptr, value);
11278
11279 case BASE_HEX:
11280 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11281
11282 case BASE_HEX_DEC:
11283 *(--ptr) = ')';
11284 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11285 *(--ptr) = '(';
11286 *(--ptr) = ' ';
11287 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11288 return ptr;
11289
11290 default:
11291 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11292 }
11293
11294 return ptr;
11295}
11296
11297static const char *
11298hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11299{
11300 int display = hfinfo->display;
11301
11302 if (hfinfo->type == FT_FRAMENUM) {
11303 /*
11304 * Frame numbers are always displayed in decimal.
11305 */
11306 display = BASE_DEC;
11307 }
11308
11309 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11310}
11311
11312static const char *
11313hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11314{
11315 int display = hfinfo->display;
11316
11317 if (hfinfo->type == FT_FRAMENUM) {
11318 /*
11319 * Frame numbers are always displayed in decimal.
11320 */
11321 display = BASE_DEC;
11322 }
11323
11324 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11325}
11326
11327static const char *
11328hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11329{
11330 /* Get the underlying BASE_ value */
11331 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11332
11333 return hfinfo_char_value_format_display(display, buf, value);
11334}
11335
11336static const char *
11337hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11338{
11339 /* Get the underlying BASE_ value */
11340 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11341
11342 if (hfinfo->type == FT_FRAMENUM) {
11343 /*
11344 * Frame numbers are always displayed in decimal.
11345 */
11346 display = BASE_DEC;
11347 }
11348
11349 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11350 display = BASE_DEC;
11351 } else if (display == BASE_OUI) {
11352 display = BASE_HEX;
11353 }
11354
11355 switch (display) {
11356 case BASE_NONE:
11357 /* case BASE_DEC: */
11358 case BASE_DEC_HEX:
11359 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11360 case BASE_CUSTOM:
11361 display = BASE_DEC;
11362 break;
11363
11364 /* case BASE_HEX: */
11365 case BASE_HEX_DEC:
11366 display = BASE_HEX;
11367 break;
11368 }
11369
11370 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11371}
11372
11373static const char *
11374hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11375{
11376 /* Get the underlying BASE_ value */
11377 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11378
11379 if (hfinfo->type == FT_FRAMENUM) {
11380 /*
11381 * Frame numbers are always displayed in decimal.
11382 */
11383 display = BASE_DEC;
11384 }
11385
11386 switch (display) {
11387 case BASE_NONE:
11388 /* case BASE_DEC: */
11389 case BASE_DEC_HEX:
11390 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11391 case BASE_CUSTOM:
11392 display = BASE_DEC;
11393 break;
11394
11395 /* case BASE_HEX: */
11396 case BASE_HEX_DEC:
11397 display = BASE_HEX;
11398 break;
11399 }
11400
11401 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11402}
11403
11404static const char *
11405hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11406{
11407 /* Get the underlying BASE_ value */
11408 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11409
11410 return hfinfo_char_value_format_display(display, buf, value);
11411}
11412
11413static const char *
11414hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11415{
11416 /* Get the underlying BASE_ value */
11417 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11418
11419 if (display == BASE_NONE)
11420 return NULL((void*)0);
11421
11422 if (display == BASE_DEC_HEX)
11423 display = BASE_DEC;
11424 if (display == BASE_HEX_DEC)
11425 display = BASE_HEX;
11426
11427 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11428}
11429
11430static const char *
11431hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11432{
11433 /* Get the underlying BASE_ value */
11434 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11435
11436 if (display == BASE_NONE)
11437 return NULL((void*)0);
11438
11439 if (display == BASE_DEC_HEX)
11440 display = BASE_DEC;
11441 if (display == BASE_HEX_DEC)
11442 display = BASE_HEX;
11443
11444 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11445}
11446
11447const char *
11448proto_registrar_get_name(const int n)
11449{
11450 header_field_info *hfinfo;
11451
11452 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", 11452
, __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", 11452
, "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", 11452, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11453 return hfinfo->name;
11454}
11455
11456const char *
11457proto_registrar_get_abbrev(const int n)
11458{
11459 header_field_info *hfinfo;
11460
11461 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", 11461
, __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", 11461
, "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", 11461, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11462 return hfinfo->abbrev;
11463}
11464
11465enum ftenum
11466proto_registrar_get_ftype(const int n)
11467{
11468 header_field_info *hfinfo;
11469
11470 PROTO_REGISTRAR_GET_NTH(n, hfinfo)if((n == 0 || (unsigned)n > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11470
, __func__, "Unregistered hf! index=%d", n); ((void) ((n >
0 && (unsigned)n < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11470
, "n > 0 && (unsigned)n < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[n] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11470, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11471 return hfinfo->type;
11472}
11473
11474int
11475proto_registrar_get_parent(const int n)
11476{
11477 header_field_info *hfinfo;
11478
11479 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", 11479
, __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", 11479
, "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", 11479, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11480 return hfinfo->parent;
11481}
11482
11483bool_Bool
11484proto_registrar_is_protocol(const int n)
11485{
11486 header_field_info *hfinfo;
11487
11488 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", 11488
, __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", 11488
, "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", 11488, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11489 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11490}
11491
11492/* Returns length of field in packet (not necessarily the length
11493 * in our internal representation, as in the case of IPv4).
11494 * 0 means undeterminable at time of registration
11495 * -1 means the field is not registered. */
11496int
11497proto_registrar_get_length(const int n)
11498{
11499 header_field_info *hfinfo;
11500
11501 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", 11501
, __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", 11501
, "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", 11501, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11502 return ftype_wire_size(hfinfo->type);
11503}
11504
11505size_t
11506proto_registrar_get_count(struct proto_registrar_stats *stats)
11507{
11508 header_field_info *hfinfo;
11509
11510 // Index zero is not used. We have to skip it.
11511 size_t total_count = gpa_hfinfo.len - 1;
11512 if (stats == NULL((void*)0)) {
11513 return total_count;
11514 }
11515 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11516 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11517 stats->deregistered_count++;
11518 continue; /* This is a deregistered protocol or header field */
11519 }
11520
11521 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", 11521
, __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", 11521, "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", 11521, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11522
11523 if (proto_registrar_is_protocol(id))
11524 stats->protocol_count++;
11525
11526 if (hfinfo->same_name_prev_id != -1)
11527 stats->same_name_count++;
11528 }
11529
11530 return total_count;
11531}
11532
11533/* Looks for a protocol or a field in a proto_tree. Returns true if
11534 * it exists anywhere, or false if it exists nowhere. */
11535bool_Bool
11536proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11537{
11538 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11539
11540 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11541 return true1;
11542 }
11543 else {
11544 return false0;
11545 }
11546}
11547
11548/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11549 * This only works if the hfindex was "primed" before the dissection
11550 * took place, as we just pass back the already-created GPtrArray*.
11551 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11552 * handles that. */
11553GPtrArray *
11554proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11555{
11556 if (!tree)
11557 return NULL((void*)0);
11558
11559 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11560 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11561 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11562 else
11563 return NULL((void*)0);
11564}
11565
11566bool_Bool
11567proto_tracking_interesting_fields(const proto_tree *tree)
11568{
11569 GHashTable *interesting_hfids;
11570
11571 if (!tree)
11572 return false0;
11573
11574 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11575
11576 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11577}
11578
11579/* Helper struct for proto_find_info() and proto_all_finfos() */
11580typedef struct {
11581 GPtrArray *array;
11582 int id;
11583} ffdata_t;
11584
11585/* Helper function for proto_find_info() */
11586static bool_Bool
11587find_finfo(proto_node *node, void * data)
11588{
11589 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11590 if (fi && fi->hfinfo) {
11591 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11592 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11593 }
11594 }
11595
11596 /* Don't stop traversing. */
11597 return false0;
11598}
11599
11600/* Helper function for proto_find_first_info() */
11601static bool_Bool
11602find_first_finfo(proto_node *node, void *data)
11603{
11604 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11605 if (fi && fi->hfinfo) {
11606 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11607 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11608
11609 /* Stop traversing. */
11610 return true1;
11611 }
11612 }
11613
11614 /* Continue traversing. */
11615 return false0;
11616}
11617
11618/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11619* This works on any proto_tree, primed or unprimed, but actually searches
11620* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11621* The caller does need to free the returned GPtrArray with
11622* g_ptr_array_free(<array>, true).
11623*/
11624GPtrArray *
11625proto_find_finfo(proto_tree *tree, const int id)
11626{
11627 ffdata_t ffdata;
11628
11629 ffdata.array = g_ptr_array_new();
11630 ffdata.id = id;
11631
11632 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11633
11634 return ffdata.array;
11635}
11636
11637/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11638* This works on any proto_tree, primed or unprimed, but actually searches
11639* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11640* The caller does need to free the returned GPtrArray with
11641* g_ptr_array_free(<array>, true).
11642*/
11643GPtrArray *
11644proto_find_first_finfo(proto_tree *tree, const int id)
11645{
11646 ffdata_t ffdata;
11647
11648 ffdata.array = g_ptr_array_new();
11649 ffdata.id = id;
11650
11651 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11652
11653 return ffdata.array;
11654}
11655
11656/* Helper function for proto_all_finfos() */
11657static bool_Bool
11658every_finfo(proto_node *node, void * data)
11659{
11660 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11661 if (fi && fi->hfinfo) {
11662 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11663 }
11664
11665 /* Don't stop traversing. */
11666 return false0;
11667}
11668
11669/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11670 * The caller does need to free the returned GPtrArray with
11671 * g_ptr_array_free(<array>, true).
11672 */
11673GPtrArray *
11674proto_all_finfos(proto_tree *tree)
11675{
11676 ffdata_t ffdata;
11677
11678 /* Pre allocate enough space to hold all fields in most cases */
11679 ffdata.array = g_ptr_array_sized_new(512);
11680 ffdata.id = 0;
11681
11682 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11683
11684 return ffdata.array;
11685}
11686
11687
11688typedef struct {
11689 unsigned offset;
11690 field_info *finfo;
11691 tvbuff_t *tvb;
11692} offset_search_t;
11693
11694static bool_Bool
11695check_for_offset(proto_node *node, void * data)
11696{
11697 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11698 offset_search_t *offsearch = (offset_search_t *)data;
11699
11700 /* !fi == the top most container node which holds nothing */
11701 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11702 if (offsearch->offset >= (unsigned) fi->start &&
11703 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11704
11705 offsearch->finfo = fi;
11706 return false0; /* keep traversing */
11707 }
11708 }
11709 return false0; /* keep traversing */
11710}
11711
11712/* Search a proto_tree backwards (from leaves to root) looking for the field
11713 * whose start/length occupies 'offset' */
11714/* XXX - I couldn't find an easy way to search backwards, so I search
11715 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11716 * the one I want to return to the user. This algorithm is inefficient
11717 * and could be re-done, but I'd have to handle all the children and
11718 * siblings of each node myself. When I have more time I'll do that.
11719 * (yeah right) */
11720field_info *
11721proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11722{
11723 offset_search_t offsearch;
11724
11725 offsearch.offset = offset;
11726 offsearch.finfo = NULL((void*)0);
11727 offsearch.tvb = tvb;
11728
11729 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11730
11731 return offsearch.finfo;
11732}
11733
11734typedef struct {
11735 unsigned length;
11736 char *buf;
11737} decoded_data_t;
11738
11739static bool_Bool
11740check_for_undecoded(proto_node *node, void * data)
11741{
11742 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11743 decoded_data_t* decoded = (decoded_data_t*)data;
11744 unsigned i;
11745 unsigned byte;
11746 unsigned bit;
11747
11748 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11749 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11750 byte = i / 8;
11751 bit = i % 8;
11752 decoded->buf[byte] |= (1 << bit);
11753 }
11754 }
11755
11756 return false0;
11757}
11758
11759char*
11760proto_find_undecoded_data(proto_tree *tree, unsigned length)
11761{
11762 decoded_data_t decoded;
11763 decoded.length = length;
11764 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11765
11766 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11767 return decoded.buf;
11768}
11769
11770/* Dumps the protocols in the registration database to stdout. An independent
11771 * program can take this output and format it into nice tables or HTML or
11772 * whatever.
11773 *
11774 * There is one record per line. The fields are tab-delimited.
11775 *
11776 * Field 1 = protocol name
11777 * Field 2 = protocol short name
11778 * Field 3 = protocol filter name
11779 * Field 4 = protocol enabled
11780 * Field 5 = protocol enabled by default
11781 * Field 6 = protocol can toggle
11782 */
11783void
11784proto_registrar_dump_protocols(void)
11785{
11786 protocol_t *protocol;
11787 int i;
11788 void *cookie = NULL((void*)0);
11789
11790
11791 i = proto_get_first_protocol(&cookie);
11792 while (i != -1) {
11793 protocol = find_protocol_by_id(i);
11794 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11795 protocol->name,
11796 protocol->short_name,
11797 protocol->filter_name,
11798 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11799 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11800 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11801 i = proto_get_next_protocol(&cookie);
11802 }
11803}
11804
11805/* Dumps the value_strings, extended value string headers, range_strings
11806 * or true/false strings for fields that have them.
11807 * There is one record per line. Fields are tab-delimited.
11808 * There are four types of records: Value String, Extended Value String Header,
11809 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11810 * the type of record.
11811 *
11812 * Note that a record will be generated only if the value_string,... is referenced
11813 * in a registered hfinfo entry.
11814 *
11815 *
11816 * Value Strings
11817 * -------------
11818 * Field 1 = 'V'
11819 * Field 2 = Field abbreviation to which this value string corresponds
11820 * Field 3 = Integer value
11821 * Field 4 = String
11822 *
11823 * Extended Value String Headers
11824 * -----------------------------
11825 * Field 1 = 'E'
11826 * Field 2 = Field abbreviation to which this extended value string header corresponds
11827 * Field 3 = Extended Value String "Name"
11828 * Field 4 = Number of entries in the associated value_string array
11829 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11830 *
11831 * Range Strings
11832 * -------------
11833 * Field 1 = 'R'
11834 * Field 2 = Field abbreviation to which this range string corresponds
11835 * Field 3 = Integer value: lower bound
11836 * Field 4 = Integer value: upper bound
11837 * Field 5 = String
11838 *
11839 * True/False Strings
11840 * ------------------
11841 * Field 1 = 'T'
11842 * Field 2 = Field abbreviation to which this true/false string corresponds
11843 * Field 3 = True String
11844 * Field 4 = False String
11845 */
11846void
11847proto_registrar_dump_values(void)
11848{
11849 header_field_info *hfinfo;
11850 int i, len, vi;
11851 const value_string *vals;
11852 const val64_string *vals64;
11853 const range_string *range;
11854 const true_false_string *tfs;
11855 const unit_name_string *units;
11856
11857 len = gpa_hfinfo.len;
11858 for (i = 1; i < len ; i++) {
11859 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11860 continue; /* This is a deregistered protocol or field */
11861
11862 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", 11862
, __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", 11862
, "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", 11862, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11863
11864 if (hfinfo->id == hf_text_only) {
11865 continue;
11866 }
11867
11868 /* ignore protocols */
11869 if (proto_registrar_is_protocol(i)) {
11870 continue;
11871 }
11872 /* process header fields */
11873#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11874 /*
11875 * If this field isn't at the head of the list of
11876 * fields with this name, skip this field - all
11877 * fields with the same name are really just versions
11878 * of the same field stored in different bits, and
11879 * should have the same type/radix/value list, and
11880 * just differ in their bit masks. (If a field isn't
11881 * a bitfield, but can be, say, 1 or 2 bytes long,
11882 * it can just be made FT_UINT16, meaning the
11883 * *maximum* length is 2 bytes, and be used
11884 * for all lengths.)
11885 */
11886 if (hfinfo->same_name_prev_id != -1)
11887 continue;
11888#endif
11889 vals = NULL((void*)0);
11890 vals64 = NULL((void*)0);
11891 range = NULL((void*)0);
11892 tfs = NULL((void*)0);
11893 units = NULL((void*)0);
11894
11895 if (hfinfo->strings != NULL((void*)0)) {
11896 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11897 (hfinfo->type == FT_CHAR ||
11898 hfinfo->type == FT_UINT8 ||
11899 hfinfo->type == FT_UINT16 ||
11900 hfinfo->type == FT_UINT24 ||
11901 hfinfo->type == FT_UINT32 ||
11902 hfinfo->type == FT_UINT40 ||
11903 hfinfo->type == FT_UINT48 ||
11904 hfinfo->type == FT_UINT56 ||
11905 hfinfo->type == FT_UINT64 ||
11906 hfinfo->type == FT_INT8 ||
11907 hfinfo->type == FT_INT16 ||
11908 hfinfo->type == FT_INT24 ||
11909 hfinfo->type == FT_INT32 ||
11910 hfinfo->type == FT_INT40 ||
11911 hfinfo->type == FT_INT48 ||
11912 hfinfo->type == FT_INT56 ||
11913 hfinfo->type == FT_INT64 ||
11914 hfinfo->type == FT_FLOAT ||
11915 hfinfo->type == FT_DOUBLE)) {
11916
11917 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11918 range = (const range_string *)hfinfo->strings;
11919 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11920 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11921 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11922 } else {
11923 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11924 }
11925 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11926 vals64 = (const val64_string *)hfinfo->strings;
11927 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11928 units = (const unit_name_string *)hfinfo->strings;
11929 } else {
11930 vals = (const value_string *)hfinfo->strings;
11931 }
11932 }
11933 else if (hfinfo->type == FT_BOOLEAN) {
11934 tfs = (const struct true_false_string *)hfinfo->strings;
11935 }
11936 }
11937
11938 /* Print value strings? */
11939 if (vals) {
11940 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11941 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11942 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11943 if (!val64_string_ext_validate(vse_p)) {
11944 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11944, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11945 continue;
11946 }
11947 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11948 printf("E\t%s\t%u\t%s\t%s\n",
11949 hfinfo->abbrev,
11950 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11951 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11952 val64_string_ext_match_type_str(vse_p));
11953 } else {
11954 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11955 if (!value_string_ext_validate(vse_p)) {
11956 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11956, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11957 continue;
11958 }
11959 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11960 printf("E\t%s\t%u\t%s\t%s\n",
11961 hfinfo->abbrev,
11962 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11963 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11964 value_string_ext_match_type_str(vse_p));
11965 }
11966 }
11967 vi = 0;
11968 while (vals[vi].strptr) {
11969 /* Print in the proper base */
11970 if (hfinfo->type == FT_CHAR) {
11971 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11972 printf("V\t%s\t'%c'\t%s\n",
11973 hfinfo->abbrev,
11974 vals[vi].value,
11975 vals[vi].strptr);
11976 } else {
11977 if (hfinfo->display == BASE_HEX) {
11978 printf("V\t%s\t'\\x%02x'\t%s\n",
11979 hfinfo->abbrev,
11980 vals[vi].value,
11981 vals[vi].strptr);
11982 }
11983 else {
11984 printf("V\t%s\t'\\%03o'\t%s\n",
11985 hfinfo->abbrev,
11986 vals[vi].value,
11987 vals[vi].strptr);
11988 }
11989 }
11990 } else {
11991 if (hfinfo->display == BASE_HEX) {
11992 printf("V\t%s\t0x%x\t%s\n",
11993 hfinfo->abbrev,
11994 vals[vi].value,
11995 vals[vi].strptr);
11996 }
11997 else {
11998 printf("V\t%s\t%u\t%s\n",
11999 hfinfo->abbrev,
12000 vals[vi].value,
12001 vals[vi].strptr);
12002 }
12003 }
12004 vi++;
12005 }
12006 }
12007 else if (vals64) {
12008 vi = 0;
12009 while (vals64[vi].strptr) {
12010 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12011 hfinfo->abbrev,
12012 vals64[vi].value,
12013 vals64[vi].strptr);
12014 vi++;
12015 }
12016 }
12017
12018 /* print range strings? */
12019 else if (range) {
12020 vi = 0;
12021 while (range[vi].strptr) {
12022 /* Print in the proper base */
12023 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12024 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12025 hfinfo->abbrev,
12026 range[vi].value_min,
12027 range[vi].value_max,
12028 range[vi].strptr);
12029 }
12030 else {
12031 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12032 hfinfo->abbrev,
12033 range[vi].value_min,
12034 range[vi].value_max,
12035 range[vi].strptr);
12036 }
12037 vi++;
12038 }
12039 }
12040
12041 /* Print true/false strings? */
12042 else if (tfs) {
12043 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12044 tfs->true_string, tfs->false_string);
12045 }
12046 /* Print unit strings? */
12047 else if (units) {
12048 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12049 units->singular, units->plural ? units->plural : "(no plural)");
12050 }
12051 }
12052}
12053
12054/* Prints the number of registered fields.
12055 * Useful for determining an appropriate value for
12056 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12057 *
12058 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12059 * the number of fields, true otherwise.
12060 */
12061bool_Bool
12062proto_registrar_dump_fieldcount(void)
12063{
12064 struct proto_registrar_stats stats = {0, 0, 0};
12065 size_t total_count = proto_registrar_get_count(&stats);
12066
12067 printf("There are %zu header fields registered, of which:\n"
12068 "\t%zu are deregistered\n"
12069 "\t%zu are protocols\n"
12070 "\t%zu have the same name as another field\n\n",
12071 total_count, stats.deregistered_count, stats.protocol_count,
12072 stats.same_name_count);
12073
12074 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12075 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12076 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12077 "\n");
12078
12079 printf("The header field table consumes %u KiB of memory.\n",
12080 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12081 printf("The fields themselves consume %u KiB of memory.\n",
12082 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12083
12084 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12085}
12086
12087static void
12088elastic_add_base_mapping(json_dumper *dumper)
12089{
12090 json_dumper_set_member_name(dumper, "index_patterns");
12091 json_dumper_begin_array(dumper);
12092 // The index names from write_json_index() in print.c
12093 json_dumper_value_string(dumper, "packets-*");
12094 json_dumper_end_array(dumper);
12095
12096 json_dumper_set_member_name(dumper, "settings");
12097 json_dumper_begin_object(dumper);
12098 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12099 json_dumper_value_anyf(dumper, "%d", 1000000);
12100 json_dumper_end_object(dumper);
12101}
12102
12103static char*
12104ws_type_to_elastic(unsigned type)
12105{
12106 switch(type) {
12107 case FT_INT8:
12108 return "byte";
12109 case FT_UINT8:
12110 case FT_INT16:
12111 return "short";
12112 case FT_UINT16:
12113 case FT_INT32:
12114 case FT_UINT24:
12115 case FT_INT24:
12116 return "integer";
12117 case FT_FRAMENUM:
12118 case FT_UINT32:
12119 case FT_UINT40:
12120 case FT_UINT48:
12121 case FT_UINT56:
12122 case FT_INT40:
12123 case FT_INT48:
12124 case FT_INT56:
12125 case FT_INT64:
12126 return "long";
12127 case FT_UINT64:
12128 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12129 case FT_FLOAT:
12130 return "float";
12131 case FT_DOUBLE:
12132 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12133 return "double";
12134 case FT_IPv6:
12135 case FT_IPv4:
12136 return "ip";
12137 case FT_ABSOLUTE_TIME:
12138 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12139 case FT_BOOLEAN:
12140 return "boolean";
12141 default:
12142 return NULL((void*)0);
12143 }
12144}
12145
12146static char*
12147dot_to_underscore(char* str)
12148{
12149 unsigned i;
12150 for (i = 0; i < strlen(str); i++) {
12151 if (str[i] == '.')
12152 str[i] = '_';
12153 }
12154 return str;
12155}
12156
12157/* Dumps a mapping file for ElasticSearch
12158 * This is the v1 (legacy) _template API.
12159 * At some point it may need to be updated with the composable templates
12160 * introduced in Elasticsearch 7.8 (_index_template)
12161 */
12162void
12163proto_registrar_dump_elastic(const char* filter)
12164{
12165 header_field_info *hfinfo;
12166 header_field_info *parent_hfinfo;
12167 unsigned i;
12168 bool_Bool open_object = true1;
12169 const char* prev_proto = NULL((void*)0);
12170 char* str;
12171 char** protos = NULL((void*)0);
12172 char* proto;
12173 bool_Bool found;
12174 unsigned j;
12175 char* type;
12176 char* prev_item = NULL((void*)0);
12177
12178 /* We have filtering protocols. Extract them. */
12179 if (filter) {
12180 protos = g_strsplit(filter, ",", -1);
12181 }
12182
12183 /*
12184 * To help tracking down the json tree, objects have been appended with a comment:
12185 * n.label -> where n is the indentation level and label the name of the object
12186 */
12187
12188 json_dumper dumper = {
12189 .output_file = stdoutstdout,
12190 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12191 };
12192 json_dumper_begin_object(&dumper); // 1.root
12193 elastic_add_base_mapping(&dumper);
12194
12195 json_dumper_set_member_name(&dumper, "mappings");
12196 json_dumper_begin_object(&dumper); // 2.mappings
12197
12198 json_dumper_set_member_name(&dumper, "properties");
12199 json_dumper_begin_object(&dumper); // 3.properties
12200 json_dumper_set_member_name(&dumper, "timestamp");
12201 json_dumper_begin_object(&dumper); // 4.timestamp
12202 json_dumper_set_member_name(&dumper, "type");
12203 json_dumper_value_string(&dumper, "date");
12204 json_dumper_end_object(&dumper); // 4.timestamp
12205
12206 json_dumper_set_member_name(&dumper, "layers");
12207 json_dumper_begin_object(&dumper); // 4.layers
12208 json_dumper_set_member_name(&dumper, "properties");
12209 json_dumper_begin_object(&dumper); // 5.properties
12210
12211 for (i = 1; i < gpa_hfinfo.len; i++) {
12212 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12213 continue; /* This is a deregistered protocol or header field */
12214
12215 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", 12215
, __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", 12215
, "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", 12215, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12216
12217 /*
12218 * Skip the pseudo-field for "proto_tree_add_text()" since
12219 * we don't want it in the list of filterable protocols.
12220 */
12221 if (hfinfo->id == hf_text_only)
12222 continue;
12223
12224 if (!proto_registrar_is_protocol(i)) {
12225 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", 12225
, __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", 12225
, "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", 12225
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12226
12227 /*
12228 * Skip the field if filter protocols have been set and this one's
12229 * parent is not listed.
12230 */
12231 if (protos) {
12232 found = false0;
12233 j = 0;
12234 proto = protos[0];
12235 while(proto) {
12236 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12237 found = true1;
12238 break;
12239 }
12240 j++;
12241 proto = protos[j];
12242 }
12243 if (!found)
12244 continue;
12245 }
12246
12247 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12248 json_dumper_end_object(&dumper); // 7.properties
12249 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12250 open_object = true1;
12251 }
12252
12253 prev_proto = parent_hfinfo->abbrev;
12254
12255 if (open_object) {
12256 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12257 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12258 json_dumper_set_member_name(&dumper, "properties");
12259 json_dumper_begin_object(&dumper); // 7.properties
12260 open_object = false0;
12261 }
12262 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12263 type = ws_type_to_elastic(hfinfo->type);
12264 /* when type is NULL, we have the default mapping: string */
12265 if (type) {
12266 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12267 dot_to_underscore(str);
12268 if (g_strcmp0(prev_item, str)) {
12269 json_dumper_set_member_name(&dumper, str);
12270 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12271 json_dumper_set_member_name(&dumper, "type");
12272 json_dumper_value_string(&dumper, type);
12273 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12274 }
12275 g_free(prev_item);
12276 prev_item = str;
12277 }
12278 }
12279 }
12280 g_free(prev_item);
12281
12282 if (prev_proto) {
12283 json_dumper_end_object(&dumper); // 7.properties
12284 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12285 }
12286
12287 json_dumper_end_object(&dumper); // 5.properties
12288 json_dumper_end_object(&dumper); // 4.layers
12289 json_dumper_end_object(&dumper); // 3.properties
12290 json_dumper_end_object(&dumper); // 2.mappings
12291 json_dumper_end_object(&dumper); // 1.root
12292 bool_Bool ret = json_dumper_finish(&dumper);
12293 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12293, "ret"))))
;
12294
12295 g_strfreev(protos);
12296}
12297
12298/* Dumps the contents of the registration database to stdout. An independent
12299 * program can take this output and format it into nice tables or HTML or
12300 * whatever.
12301 *
12302 * There is one record per line. Each record is either a protocol or a header
12303 * field, differentiated by the first field. The fields are tab-delimited.
12304 *
12305 * Protocols
12306 * ---------
12307 * Field 1 = 'P'
12308 * Field 2 = descriptive protocol name
12309 * Field 3 = protocol abbreviation
12310 *
12311 * Header Fields
12312 * -------------
12313 * Field 1 = 'F'
12314 * Field 2 = descriptive field name
12315 * Field 3 = field abbreviation
12316 * Field 4 = type ( textual representation of the ftenum type )
12317 * Field 5 = parent protocol abbreviation
12318 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12319 * Field 7 = bitmask: format: hex: 0x....
12320 * Field 8 = blurb describing field
12321 */
12322void
12323proto_registrar_dump_fields(void)
12324{
12325 header_field_info *hfinfo, *parent_hfinfo;
12326 int i, len;
12327 const char *enum_name;
12328 const char *base_name;
12329 const char *blurb;
12330 char width[5];
12331
12332 len = gpa_hfinfo.len;
12333 for (i = 1; i < len ; i++) {
12334 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12335 continue; /* This is a deregistered protocol or header field */
12336
12337 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", 12337
, __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", 12337
, "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", 12337, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12338
12339 /*
12340 * Skip the pseudo-field for "proto_tree_add_text()" since
12341 * we don't want it in the list of filterable fields.
12342 */
12343 if (hfinfo->id == hf_text_only)
12344 continue;
12345
12346 /* format for protocols */
12347 if (proto_registrar_is_protocol(i)) {
12348 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12349 }
12350 /* format for header fields */
12351 else {
12352 /*
12353 * If this field isn't at the head of the list of
12354 * fields with this name, skip this field - all
12355 * fields with the same name are really just versions
12356 * of the same field stored in different bits, and
12357 * should have the same type/radix/value list, and
12358 * just differ in their bit masks. (If a field isn't
12359 * a bitfield, but can be, say, 1 or 2 bytes long,
12360 * it can just be made FT_UINT16, meaning the
12361 * *maximum* length is 2 bytes, and be used
12362 * for all lengths.)
12363 */
12364 if (hfinfo->same_name_prev_id != -1)
12365 continue;
12366
12367 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", 12367
, __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", 12367
, "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", 12367
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12368
12369 enum_name = ftype_name(hfinfo->type);
12370 base_name = "";
12371
12372 if (hfinfo->type == FT_CHAR ||
12373 hfinfo->type == FT_UINT8 ||
12374 hfinfo->type == FT_UINT16 ||
12375 hfinfo->type == FT_UINT24 ||
12376 hfinfo->type == FT_UINT32 ||
12377 hfinfo->type == FT_UINT40 ||
12378 hfinfo->type == FT_UINT48 ||
12379 hfinfo->type == FT_UINT56 ||
12380 hfinfo->type == FT_UINT64 ||
12381 hfinfo->type == FT_INT8 ||
12382 hfinfo->type == FT_INT16 ||
12383 hfinfo->type == FT_INT24 ||
12384 hfinfo->type == FT_INT32 ||
12385 hfinfo->type == FT_INT40 ||
12386 hfinfo->type == FT_INT48 ||
12387 hfinfo->type == FT_INT56 ||
12388 hfinfo->type == FT_INT64) {
12389
12390 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12391 case BASE_NONE:
12392 case BASE_DEC:
12393 case BASE_HEX:
12394 case BASE_OCT:
12395 case BASE_DEC_HEX:
12396 case BASE_HEX_DEC:
12397 case BASE_CUSTOM:
12398 case BASE_PT_UDP:
12399 case BASE_PT_TCP:
12400 case BASE_PT_DCCP:
12401 case BASE_PT_SCTP:
12402 case BASE_OUI:
12403 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12404 break;
12405 default:
12406 base_name = "????";
12407 break;
12408 }
12409 } else if (hfinfo->type == FT_BOOLEAN) {
12410 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12411 snprintf(width, sizeof(width), "%d", hfinfo->display);
12412 base_name = width;
12413 }
12414
12415 blurb = hfinfo->blurb;
12416 if (blurb == NULL((void*)0))
12417 blurb = "";
12418 else if (strlen(blurb) == 0)
12419 blurb = "\"\"";
12420
12421 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12422 hfinfo->name, hfinfo->abbrev, enum_name,
12423 parent_hfinfo->abbrev, base_name,
12424 hfinfo->bitmask, blurb);
12425 }
12426 }
12427}
12428
12429/* Dumps all abbreviated field and protocol completions of the given string to
12430 * stdout. An independent program may use this for command-line tab completion
12431 * of fields.
12432 */
12433bool_Bool
12434proto_registrar_dump_field_completions(const char *prefix)
12435{
12436 header_field_info *hfinfo;
12437 int i, len;
12438 size_t prefix_len;
12439 bool_Bool matched = false0;
12440
12441 prefix_len = strlen(prefix);
12442 len = gpa_hfinfo.len;
12443 for (i = 1; i < len ; i++) {
12444 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12445 continue; /* This is a deregistered protocol or header field */
12446
12447 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", 12447
, __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", 12447
, "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", 12447, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12448
12449 /*
12450 * Skip the pseudo-field for "proto_tree_add_text()" since
12451 * we don't want it in the list of filterable fields.
12452 */
12453 if (hfinfo->id == hf_text_only)
12454 continue;
12455
12456 /* format for protocols */
12457 if (proto_registrar_is_protocol(i)) {
12458 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12459 matched = true1;
12460 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12461 }
12462 }
12463 /* format for header fields */
12464 else {
12465 /*
12466 * If this field isn't at the head of the list of
12467 * fields with this name, skip this field - all
12468 * fields with the same name are really just versions
12469 * of the same field stored in different bits, and
12470 * should have the same type/radix/value list, and
12471 * just differ in their bit masks. (If a field isn't
12472 * a bitfield, but can be, say, 1 or 2 bytes long,
12473 * it can just be made FT_UINT16, meaning the
12474 * *maximum* length is 2 bytes, and be used
12475 * for all lengths.)
12476 */
12477 if (hfinfo->same_name_prev_id != -1)
12478 continue;
12479
12480 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12481 matched = true1;
12482 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12483 }
12484 }
12485 }
12486 return matched;
12487}
12488
12489/* Dumps field types and descriptive names to stdout. An independent
12490 * program can take this output and format it into nice tables or HTML or
12491 * whatever.
12492 *
12493 * There is one record per line. The fields are tab-delimited.
12494 *
12495 * Field 1 = field type name, e.g. FT_UINT8
12496 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12497 */
12498void
12499proto_registrar_dump_ftypes(void)
12500{
12501 int fte;
12502
12503 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12504 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12505 }
12506}
12507
12508/* This function indicates whether it's possible to construct a
12509 * "match selected" display filter string for the specified field,
12510 * returns an indication of whether it's possible, and, if it's
12511 * possible and "filter" is non-null, constructs the filter and
12512 * sets "*filter" to point to it.
12513 * You do not need to [g_]free() this string since it will be automatically
12514 * freed once the next packet is dissected.
12515 */
12516static bool_Bool
12517construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12518 char **filter)
12519{
12520 const header_field_info *hfinfo;
12521 int start, length, length_remaining;
12522
12523 if (!finfo)
12524 return false0;
12525
12526 hfinfo = finfo->hfinfo;
12527 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12527, "hfinfo"))))
;
12528
12529 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12530 * then "the numeric value ... is not used when preparing
12531 * filters for the field in question." If it's any other
12532 * base, we'll generate the filter normally (which will
12533 * be numeric, even though the human-readable string does
12534 * work for filtering.)
12535 *
12536 * XXX - It might be nice to use fvalue_to_string_repr() in
12537 * "proto_item_fill_label()" as well, although, there, you'd
12538 * have to deal with the base *and* with resolved values for
12539 * addresses.
12540 *
12541 * Perhaps in addition to taking the repr type (DISPLAY
12542 * or DFILTER) and the display (base), fvalue_to_string_repr()
12543 * should have the the "strings" values in the header_field_info
12544 * structure for the field as a parameter, so it can have
12545 * if the field is Boolean or an enumerated integer type,
12546 * the tables used to generate human-readable values.
12547 */
12548 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12549 const char *str = NULL((void*)0);
12550
12551 switch (hfinfo->type) {
12552
12553 case FT_INT8:
12554 case FT_INT16:
12555 case FT_INT24:
12556 case FT_INT32:
12557 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12558 break;
12559
12560 case FT_CHAR:
12561 case FT_UINT8:
12562 case FT_UINT16:
12563 case FT_UINT24:
12564 case FT_UINT32:
12565 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12566 break;
12567
12568 default:
12569 break;
12570 }
12571
12572 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12573 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12574 return true1;
12575 }
12576 }
12577
12578 switch (hfinfo->type) {
12579
12580 case FT_PROTOCOL:
12581 if (filter != NULL((void*)0))
12582 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12583 break;
12584
12585 case FT_NONE:
12586 /*
12587 * If the length is 0, just match the name of the
12588 * field.
12589 *
12590 * (Also check for negative values, just in case,
12591 * as we'll cast it to an unsigned value later.)
12592 */
12593 length = finfo->length;
12594 if (length == 0) {
12595 if (filter != NULL((void*)0))
12596 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12597 break;
12598 }
12599 if (length < 0)
12600 return false0;
12601
12602 /*
12603 * This doesn't have a value, so we'd match
12604 * on the raw bytes at this address.
12605 *
12606 * Should we be allowed to access to the raw bytes?
12607 * If "edt" is NULL, the answer is "no".
12608 */
12609 if (edt == NULL((void*)0))
12610 return false0;
12611
12612 /*
12613 * Is this field part of the raw frame tvbuff?
12614 * If not, we can't use "frame[N:M]" to match
12615 * it.
12616 *
12617 * XXX - should this be frame-relative, or
12618 * protocol-relative?
12619 *
12620 * XXX - does this fallback for non-registered
12621 * fields even make sense?
12622 */
12623 if (finfo->ds_tvb != edt->tvb)
12624 return false0; /* you lose */
12625
12626 /*
12627 * Don't go past the end of that tvbuff.
12628 */
12629 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12630 if (length > length_remaining)
12631 length = length_remaining;
12632 if (length <= 0)
12633 return false0;
12634
12635 if (filter != NULL((void*)0)) {
12636 start = finfo->start;
12637 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12638 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12639 wmem_free(NULL((void*)0), str);
12640 }
12641 break;
12642
12643 /* By default, use the fvalue's "to_string_repr" method. */
12644 default:
12645 if (filter != NULL((void*)0)) {
12646 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12647 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12648 wmem_free(NULL((void*)0), str);
12649 }
12650 break;
12651 }
12652
12653 return true1;
12654}
12655
12656/*
12657 * Returns true if we can do a "match selected" on the field, false
12658 * otherwise.
12659 */
12660bool_Bool
12661proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12662{
12663 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12664}
12665
12666/* This function attempts to construct a "match selected" display filter
12667 * string for the specified field; if it can do so, it returns a pointer
12668 * to the string, otherwise it returns NULL.
12669 *
12670 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12671 */
12672char *
12673proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12674{
12675 char *filter = NULL((void*)0);
12676
12677 if (!construct_match_selected_string(finfo, edt, &filter))
12678 {
12679 wmem_free(NULL((void*)0), filter);
12680 return NULL((void*)0);
12681 }
12682 return filter;
12683}
12684
12685/* This function is common code for all proto_tree_add_bitmask... functions.
12686 */
12687
12688static bool_Bool
12689proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12690 const int len, const int ett, int * const *fields,
12691 const int flags, bool_Bool first,
12692 bool_Bool use_parent_tree,
12693 proto_tree* tree, uint64_t value)
12694{
12695 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12696 uint64_t bitmask = 0;
12697 uint64_t tmpval;
12698 header_field_info *hf;
12699 uint32_t integer32;
12700 int bit_offset;
12701 int no_of_bits;
12702
12703 if (!*fields)
12704 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"
)
;
12705
12706 if (len < 0 || len > 8)
12707 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12708 /**
12709 * packet-frame.c uses len=0 since the value is taken from the packet
12710 * metadata, not the packet bytes. In that case, assume that all bits
12711 * in the provided value are valid.
12712 */
12713 if (len > 0) {
12714 available_bits >>= (8 - (unsigned)len)*8;
12715 }
12716
12717 if (use_parent_tree == false0)
12718 tree = proto_item_add_subtree(item, ett);
12719
12720 while (*fields) {
12721 uint64_t present_bits;
12722 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", 12722, __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", 12722
, "**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", 12722, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12723 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", 12723
, "hf->bitmask != 0", hf->abbrev))))
;
12724
12725 bitmask |= hf->bitmask;
12726
12727 /* Skip fields that aren't fully present */
12728 present_bits = available_bits & hf->bitmask;
12729 if (present_bits != hf->bitmask) {
12730 fields++;
12731 continue;
12732 }
12733
12734 switch (hf->type) {
12735 case FT_CHAR:
12736 case FT_UINT8:
12737 case FT_UINT16:
12738 case FT_UINT24:
12739 case FT_UINT32:
12740 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12741 break;
12742
12743 case FT_INT8:
12744 case FT_INT16:
12745 case FT_INT24:
12746 case FT_INT32:
12747 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12748 break;
12749
12750 case FT_UINT40:
12751 case FT_UINT48:
12752 case FT_UINT56:
12753 case FT_UINT64:
12754 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12755 break;
12756
12757 case FT_INT40:
12758 case FT_INT48:
12759 case FT_INT56:
12760 case FT_INT64:
12761 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12762 break;
12763
12764 case FT_BOOLEAN:
12765 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12766 break;
12767
12768 default:
12769 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))
12770 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))
12771 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))
12772 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))
;
12773 break;
12774 }
12775 if (flags & BMT_NO_APPEND0x01) {
12776 fields++;
12777 continue;
12778 }
12779 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12780
12781 /* XXX: README.developer and the comments have always defined
12782 * BMT_NO_INT as "only boolean flags are added to the title /
12783 * don't add non-boolean (integral) fields", but the
12784 * implementation has always added BASE_CUSTOM and fields with
12785 * value_strings, though not fields with unit_strings.
12786 * Possibly this is because some dissectors use a FT_UINT8
12787 * with a value_string for fields that should be a FT_BOOLEAN.
12788 */
12789 switch (hf->type) {
12790 case FT_CHAR:
12791 if (hf->display == BASE_CUSTOM) {
12792 char lbl[ITEM_LABEL_LENGTH240];
12793 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12794
12795 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12795, "fmtfunc"))))
;
12796 fmtfunc(lbl, (uint32_t) tmpval);
12797 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12798 hf->name, lbl);
12799 first = false0;
12800 }
12801 else if (hf->strings) {
12802 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12803 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12804 first = false0;
12805 }
12806 else if (!(flags & BMT_NO_INT0x02)) {
12807 char buf[32];
12808 const char *out;
12809
12810 if (!first) {
12811 proto_item_append_text(item, ", ");
12812 }
12813
12814 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12815 proto_item_append_text(item, "%s: %s", hf->name, out);
12816 first = false0;
12817 }
12818
12819 break;
12820
12821 case FT_UINT8:
12822 case FT_UINT16:
12823 case FT_UINT24:
12824 case FT_UINT32:
12825 if (hf->display == BASE_CUSTOM) {
12826 char lbl[ITEM_LABEL_LENGTH240];
12827 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12828
12829 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12829, "fmtfunc"))))
;
12830 fmtfunc(lbl, (uint32_t) tmpval);
12831 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12832 hf->name, lbl);
12833 first = false0;
12834 }
12835 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12836 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12837 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12838 first = false0;
12839 }
12840 else if (!(flags & BMT_NO_INT0x02)) {
12841 char buf[NUMBER_LABEL_LENGTH80];
12842 const char *out = NULL((void*)0);
12843
12844 if (!first) {
12845 proto_item_append_text(item, ", ");
12846 }
12847
12848 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12849 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12850 }
12851 if (out == NULL((void*)0)) {
12852 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12853 }
12854 proto_item_append_text(item, "%s: %s", hf->name, out);
12855 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12856 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12857 }
12858 first = false0;
12859 }
12860
12861 break;
12862
12863 case FT_INT8:
12864 case FT_INT16:
12865 case FT_INT24:
12866 case FT_INT32:
12867 integer32 = (uint32_t) tmpval;
12868 if (hf->bitmask) {
12869 no_of_bits = ws_count_ones(hf->bitmask);
12870 integer32 = ws_sign_ext32(integer32, no_of_bits);
12871 }
12872 if (hf->display == BASE_CUSTOM) {
12873 char lbl[ITEM_LABEL_LENGTH240];
12874 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12875
12876 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12876, "fmtfunc"))))
;
12877 fmtfunc(lbl, (int32_t) integer32);
12878 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12879 hf->name, lbl);
12880 first = false0;
12881 }
12882 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12883 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12884 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12885 first = false0;
12886 }
12887 else if (!(flags & BMT_NO_INT0x02)) {
12888 char buf[NUMBER_LABEL_LENGTH80];
12889 const char *out = NULL((void*)0);
12890
12891 if (!first) {
12892 proto_item_append_text(item, ", ");
12893 }
12894
12895 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12896 out = hf_try_val_to_str((int32_t) integer32, hf);
12897 }
12898 if (out == NULL((void*)0)) {
12899 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12900 }
12901 proto_item_append_text(item, "%s: %s", hf->name, out);
12902 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12903 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12904 }
12905 first = false0;
12906 }
12907
12908 break;
12909
12910 case FT_UINT40:
12911 case FT_UINT48:
12912 case FT_UINT56:
12913 case FT_UINT64:
12914 if (hf->display == BASE_CUSTOM) {
12915 char lbl[ITEM_LABEL_LENGTH240];
12916 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12917
12918 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12918, "fmtfunc"))))
;
12919 fmtfunc(lbl, tmpval);
12920 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12921 hf->name, lbl);
12922 first = false0;
12923 }
12924 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12925 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12926 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12927 first = false0;
12928 }
12929 else if (!(flags & BMT_NO_INT0x02)) {
12930 char buf[NUMBER_LABEL_LENGTH80];
12931 const char *out = NULL((void*)0);
12932
12933 if (!first) {
12934 proto_item_append_text(item, ", ");
12935 }
12936
12937 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12938 out = hf_try_val64_to_str(tmpval, hf);
12939 }
12940 if (out == NULL((void*)0)) {
12941 out = hfinfo_number_value_format64(hf, buf, tmpval);
12942 }
12943 proto_item_append_text(item, "%s: %s", hf->name, out);
12944 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12945 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12946 }
12947 first = false0;
12948 }
12949
12950 break;
12951
12952 case FT_INT40:
12953 case FT_INT48:
12954 case FT_INT56:
12955 case FT_INT64:
12956 if (hf->bitmask) {
12957 no_of_bits = ws_count_ones(hf->bitmask);
12958 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12959 }
12960 if (hf->display == BASE_CUSTOM) {
12961 char lbl[ITEM_LABEL_LENGTH240];
12962 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12963
12964 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12964, "fmtfunc"))))
;
12965 fmtfunc(lbl, (int64_t) tmpval);
12966 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12967 hf->name, lbl);
12968 first = false0;
12969 }
12970 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12971 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12972 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12973 first = false0;
12974 }
12975 else if (!(flags & BMT_NO_INT0x02)) {
12976 char buf[NUMBER_LABEL_LENGTH80];
12977 const char *out = NULL((void*)0);
12978
12979 if (!first) {
12980 proto_item_append_text(item, ", ");
12981 }
12982
12983 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12984 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12985 }
12986 if (out == NULL((void*)0)) {
12987 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12988 }
12989 proto_item_append_text(item, "%s: %s", hf->name, out);
12990 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12991 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12992 }
12993 first = false0;
12994 }
12995
12996 break;
12997
12998 case FT_BOOLEAN:
12999 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13000 /* If we have true/false strings, emit full - otherwise messages
13001 might look weird */
13002 const struct true_false_string *tfs =
13003 (const struct true_false_string *)hf->strings;
13004
13005 if (tmpval) {
13006 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13007 hf->name, tfs->true_string);
13008 first = false0;
13009 } else if (!(flags & BMT_NO_FALSE0x04)) {
13010 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13011 hf->name, tfs->false_string);
13012 first = false0;
13013 }
13014 } else if (hf->bitmask & value) {
13015 /* If the flag is set, show the name */
13016 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13017 first = false0;
13018 }
13019 break;
13020 default:
13021 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))
13022 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))
13023 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))
13024 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))
;
13025 break;
13026 }
13027
13028 fields++;
13029 }
13030
13031 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13032 * but then again most dissectors don't set the bitmask field for
13033 * the higher level bitmask hfi, so calculate the bitmask from the
13034 * fields present. */
13035 if (item) {
13036 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13037 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13038 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)
;
13039 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)
;
13040 }
13041 return first;
13042}
13043
13044/* This function will dissect a sequence of bytes that describe a
13045 * bitmask and supply the value of that sequence through a pointer.
13046 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13047 * to be dissected.
13048 * This field will form an expansion under which the individual fields of the
13049 * bitmask is dissected and displayed.
13050 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13051 *
13052 * fields is an array of pointers to int that lists all the fields of the
13053 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13054 * or another integer of the same type/size as hf_hdr with a mask specified.
13055 * This array is terminated by a NULL entry.
13056 *
13057 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13058 * FT_integer fields that have a value_string attached will have the
13059 * matched string displayed on the expansion line.
13060 */
13061proto_item *
13062proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13063 const unsigned offset, const int hf_hdr,
13064 const int ett, int * const *fields,
13065 const unsigned encoding, uint64_t *retval)
13066{
13067 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);
13068}
13069
13070/* This function will dissect a sequence of bytes that describe a
13071 * bitmask.
13072 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13073 * to be dissected.
13074 * This field will form an expansion under which the individual fields of the
13075 * bitmask is dissected and displayed.
13076 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13077 *
13078 * fields is an array of pointers to int that lists all the fields of the
13079 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13080 * or another integer of the same type/size as hf_hdr with a mask specified.
13081 * This array is terminated by a NULL entry.
13082 *
13083 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13084 * FT_integer fields that have a value_string attached will have the
13085 * matched string displayed on the expansion line.
13086 */
13087proto_item *
13088proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13089 const unsigned offset, const int hf_hdr,
13090 const int ett, int * const *fields,
13091 const unsigned encoding)
13092{
13093 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13094}
13095
13096/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13097 * what data is appended to the header.
13098 */
13099proto_item *
13100proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13101 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13102 uint64_t *retval)
13103{
13104 proto_item *item = NULL((void*)0);
13105 header_field_info *hf;
13106 int len;
13107 uint64_t value;
13108
13109 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", 13109, __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", 13109
, "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", 13109, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13110 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", 13110, (hf)->abbrev)))
;
13111 len = ftype_wire_size(hf->type);
13112 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13113
13114 if (parent_tree) {
13115 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13116 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13117 flags, false0, false0, NULL((void*)0), value);
13118 }
13119
13120 *retval = value;
13121 if (hf->bitmask) {
13122 /* Mask out irrelevant portions */
13123 *retval &= hf->bitmask;
13124 /* Shift bits */
13125 *retval >>= hfinfo_bitshift(hf);
13126 }
13127
13128 return item;
13129}
13130
13131/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13132 * what data is appended to the header.
13133 */
13134proto_item *
13135proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13136 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13137{
13138 proto_item *item = NULL((void*)0);
13139 header_field_info *hf;
13140 int len;
13141 uint64_t value;
13142
13143 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", 13143, __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", 13143
, "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", 13143, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13144 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", 13144, (hf)->abbrev)))
;
13145
13146 if (parent_tree) {
13147 len = ftype_wire_size(hf->type);
13148 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13149 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13150 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13151 flags, false0, false0, NULL((void*)0), value);
13152 }
13153
13154 return item;
13155}
13156
13157/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13158 can't be retrieved directly from tvb) */
13159proto_item *
13160proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13161 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13162{
13163 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13164 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13165}
13166
13167/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13168WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13169proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13170 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13171{
13172 proto_item *item = NULL((void*)0);
13173 header_field_info *hf;
13174 int len;
13175
13176 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf)if((hf_hdr == 0 || (unsigned)hf_hdr > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 13176, __func__, "Unregistered hf! index=%d"
, hf_hdr); ((void) ((hf_hdr > 0 && (unsigned)hf_hdr
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13176
, "hf_hdr > 0 && (unsigned)hf_hdr < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_hdr] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13176, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13177 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf)((void) (((((((hf)->type) == FT_INT8 || ((hf)->type) ==
FT_INT16 || ((hf)->type) == FT_INT24 || ((hf)->type) ==
FT_INT32) || (((hf)->type) == FT_INT40 || ((hf)->type)
== FT_INT48 || ((hf)->type) == FT_INT56 || ((hf)->type
) == FT_INT64)) || ((((hf)->type) == FT_CHAR || ((hf)->
type) == FT_UINT8 || ((hf)->type) == FT_UINT16 || ((hf)->
type) == FT_UINT24 || ((hf)->type) == FT_UINT32 || ((hf)->
type) == FT_FRAMENUM) || (((hf)->type) == FT_UINT40 || ((hf
)->type) == FT_UINT48 || ((hf)->type) == FT_UINT56 || (
(hf)->type) == FT_UINT64)))) ? (void)0 : proto_report_dissector_bug
("%s:%u: field %s is not of type FT_CHAR or an FT_{U}INTn type"
, "epan/proto.c", 13177, (hf)->abbrev)))
;
13178 /* the proto_tree_add_uint/_uint64() calls below
13179 will fail if tvb==NULL and len!=0 */
13180 len = tvb ? ftype_wire_size(hf->type) : 0;
13181
13182 if (parent_tree) {
13183 if (len <= 4)
13184 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13185 else
13186 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13187
13188 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13189 flags, false0, false0, NULL((void*)0), value);
13190 }
13191
13192 return item;
13193}
13194
13195/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13196void
13197proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13198 const int len, int * const *fields, const unsigned encoding)
13199{
13200 uint64_t value;
13201
13202 if (tree) {
13203 value = get_uint64_value(tree, tvb, offset, len, encoding);
13204 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13205 BMT_NO_APPEND0x01, false0, true1, tree, value);
13206 }
13207}
13208
13209WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13210proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13211 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13212{
13213 uint64_t value;
13214
13215 value = get_uint64_value(tree, tvb, offset, len, encoding);
13216 if (tree) {
13217 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13218 BMT_NO_APPEND0x01, false0, true1, tree, value);
13219 }
13220 if (retval) {
13221 *retval = value;
13222 }
13223}
13224
13225WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13226proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13227 const int len, int * const *fields, const uint64_t value)
13228{
13229 if (tree) {
13230 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13231 BMT_NO_APPEND0x01, false0, true1, tree, value);
13232 }
13233}
13234
13235
13236/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13237 * This is intended to support bitmask fields whose lengths can vary, perhaps
13238 * as the underlying standard evolves over time.
13239 * With this API there is the possibility of being called to display more or
13240 * less data than the dissector was coded to support.
13241 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13242 * Thus when presented with "too much" or "too little" data, MSbits will be
13243 * ignored or MSfields sacrificed.
13244 *
13245 * Only fields for which all defined bits are available are displayed.
13246 */
13247proto_item *
13248proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13249 const unsigned offset, const unsigned len, const int hf_hdr,
13250 const int ett, int * const *fields, struct expert_field* exp,
13251 const unsigned encoding)
13252{
13253 proto_item *item = NULL((void*)0);
13254 header_field_info *hf;
13255 unsigned decodable_len;
13256 unsigned decodable_offset;
13257 uint32_t decodable_value;
13258 uint64_t value;
13259
13260 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", 13260, __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", 13260
, "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", 13260, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13261 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", 13261, (hf)->abbrev)))
;
13262
13263 decodable_offset = offset;
13264 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13265
13266 /* If we are ftype_wire_size-limited,
13267 * make sure we decode as many LSBs as possible.
13268 */
13269 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13270 decodable_offset += (len - decodable_len);
13271 }
13272
13273 if (parent_tree) {
13274 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13275 decodable_len, encoding);
13276
13277 /* The root item covers all the bytes even if we can't decode them all */
13278 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13279 decodable_value);
13280 }
13281
13282 if (decodable_len < len) {
13283 /* Dissector likely requires updating for new protocol revision */
13284 expert_add_info_format(NULL((void*)0), item, exp,
13285 "Only least-significant %d of %d bytes decoded",
13286 decodable_len, len);
13287 }
13288
13289 if (item) {
13290 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13291 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13292 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13293 }
13294
13295 return item;
13296}
13297
13298/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13299proto_item *
13300proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13301 const unsigned offset, const unsigned len,
13302 const char *name, const char *fallback,
13303 const int ett, int * const *fields,
13304 const unsigned encoding, const int flags)
13305{
13306 proto_item *item = NULL((void*)0);
13307 uint64_t value;
13308
13309 if (parent_tree) {
13310 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13311 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13312 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13313 flags, true1, false0, NULL((void*)0), value) && fallback) {
13314 /* Still at first item - append 'fallback' text if any */
13315 proto_item_append_text(item, "%s", fallback);
13316 }
13317 }
13318
13319 return item;
13320}
13321
13322proto_item *
13323proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13324 const unsigned bit_offset, const int no_of_bits,
13325 const unsigned encoding)
13326{
13327 header_field_info *hfinfo;
13328 int octet_length;
13329 int octet_offset;
13330
13331 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", 13331, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13331
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13331, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13332
13333 if (no_of_bits < 0) {
13334 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13335 }
13336 octet_length = (no_of_bits + 7) >> 3;
13337 octet_offset = bit_offset >> 3;
13338 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13339
13340 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13341 * but only after doing a bunch more work (which we can, in the common
13342 * case, shortcut here).
13343 */
13344 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13345 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", 13345
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13345, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13345, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; 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", 13345, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13346
13347 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13348}
13349
13350/*
13351 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13352 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13353 * Offset should be given in bits from the start of the tvb.
13354 */
13355
13356static proto_item *
13357_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13358 const unsigned bit_offset, const int no_of_bits,
13359 uint64_t *return_value, const unsigned encoding)
13360{
13361 int offset;
13362 unsigned length;
13363 uint8_t tot_no_bits;
13364 char *bf_str;
13365 char lbl_str[ITEM_LABEL_LENGTH240];
13366 uint64_t value = 0;
13367 uint8_t *bytes = NULL((void*)0);
13368 size_t bytes_length = 0;
13369
13370 proto_item *pi;
13371 header_field_info *hf_field;
13372
13373 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13374 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", 13374, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13374
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13374, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13375
13376 if (hf_field->bitmask != 0) {
13377 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)
13378 " 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)
13379 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)
;
13380 }
13381
13382 if (no_of_bits < 0) {
13383 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13384 } else if (no_of_bits == 0) {
13385 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)
13386 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)
;
13387 }
13388
13389 /* Byte align offset */
13390 offset = bit_offset>>3;
13391
13392 /*
13393 * Calculate the number of octets used to hold the bits
13394 */
13395 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13396 length = (tot_no_bits + 7) >> 3;
13397
13398 if (no_of_bits < 65) {
13399 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13400 } else if (hf_field->type != FT_BYTES) {
13401 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)
13402 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)
;
13403 return NULL((void*)0);
13404 }
13405
13406 /* Sign extend for signed types */
13407 switch (hf_field->type) {
13408 case FT_INT8:
13409 case FT_INT16:
13410 case FT_INT24:
13411 case FT_INT32:
13412 case FT_INT40:
13413 case FT_INT48:
13414 case FT_INT56:
13415 case FT_INT64:
13416 value = ws_sign_ext64(value, no_of_bits);
13417 break;
13418
13419 default:
13420 break;
13421 }
13422
13423 if (return_value) {
13424 *return_value = value;
13425 }
13426
13427 /* Coast clear. Try and fake it */
13428 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13429 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", 13429
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13429, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13429, "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", 13429, __func__, "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); } } }
;
13430
13431 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13432
13433 switch (hf_field->type) {
13434 case FT_BOOLEAN:
13435 /* Boolean field */
13436 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13437 "%s = %s: %s",
13438 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13439 break;
13440
13441 case FT_CHAR:
13442 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13443 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13444 break;
13445
13446 case FT_UINT8:
13447 case FT_UINT16:
13448 case FT_UINT24:
13449 case FT_UINT32:
13450 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13451 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13452 break;
13453
13454 case FT_INT8:
13455 case FT_INT16:
13456 case FT_INT24:
13457 case FT_INT32:
13458 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13459 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13460 break;
13461
13462 case FT_UINT40:
13463 case FT_UINT48:
13464 case FT_UINT56:
13465 case FT_UINT64:
13466 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13467 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13468 break;
13469
13470 case FT_INT40:
13471 case FT_INT48:
13472 case FT_INT56:
13473 case FT_INT64:
13474 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13475 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13476 break;
13477
13478 case FT_BYTES:
13479 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13480 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13481 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13482 proto_item_set_text(pi, "%s", lbl_str);
13483 return pi;
13484
13485 /* TODO: should handle FT_UINT_BYTES ? */
13486
13487 default:
13488 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))
13489 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))
13490 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))
13491 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))
;
13492 return NULL((void*)0);
13493 }
13494
13495 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13496 return pi;
13497}
13498
13499proto_item *
13500proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13501 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13502 uint64_t *return_value)
13503{
13504 proto_item *pi;
13505 int no_of_bits;
13506 int octet_offset;
13507 unsigned mask_initial_bit_offset;
13508 unsigned mask_greatest_bit_offset;
13509 unsigned octet_length;
13510 uint8_t i;
13511 char bf_str[256];
13512 char lbl_str[ITEM_LABEL_LENGTH240];
13513 uint64_t value;
13514 uint64_t composite_bitmask;
13515 uint64_t composite_bitmap;
13516
13517 header_field_info *hf_field;
13518
13519 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13520 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", 13520, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13520
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13520, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
1
Assuming 'hfindex' is not equal to 0
2
Assuming 'hfindex' is <= field 'len'
3
Assuming 'hfindex' is > 0
4
Assuming 'hfindex' is < field 'len'
5
'?' condition is true
6
Assuming the condition is true
7
'?' condition is true
13521
13522 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13523 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)
13524 " 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)
13525 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)
;
13526 }
13527
13528 mask_initial_bit_offset = bit_offset % 8;
13529
13530 no_of_bits = 0;
13531 value = 0;
13532 i = 0;
13533 mask_greatest_bit_offset = 0;
13534 composite_bitmask = 0;
13535 composite_bitmap = 0;
13536
13537 while (crumb_spec[i].crumb_bit_length != 0) {
10
Assuming field 'crumb_bit_length' is not equal to 0
11
Loop condition is true. Entering loop body
13538 uint64_t crumb_mask, crumb_value;
13539 uint8_t crumb_end_bit_offset;
13540
13541 crumb_value = tvb_get_bits64(tvb,
13542 bit_offset + crumb_spec[i].crumb_bit_offset,
13543 crumb_spec[i].crumb_bit_length,
13544 ENC_BIG_ENDIAN0x00000000);
13545 value += crumb_value;
13546 no_of_bits += crumb_spec[i].crumb_bit_length;
13547 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", 13547
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13548
13549 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13550 octet containing the initial offset.
13551 If the mask is beyond 32 bits, then give up on bit map display.
13552 This could be improved in future, probably showing a table
13553 of 32 or 64 bits per row */
13554 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13555 crumb_end_bit_offset = mask_initial_bit_offset
13556 + crumb_spec[i].crumb_bit_offset
13557 + crumb_spec[i].crumb_bit_length;
13558 crumb_mask = (UINT64_C(1)1UL << crumb_spec[i].crumb_bit_length) - 1;
15
Assuming right operand of bit shift is less than 64
16
Value assigned to 'crumb_mask'
13559
13560 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13561 mask_greatest_bit_offset = crumb_end_bit_offset;
13562 }
13563 /* Currently the bitmap of the crumbs are only shown if
13564 * smaller than 32 bits. Do not bother calculating the
13565 * mask if it is larger than that. */
13566 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13567 composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
20
The result of left shift is undefined because the right operand '64' is not smaller than 64, the capacity of 'uint64_t'
13568 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13569 }
13570 }
13571 /* Shift left for the next segment */
13572 value <<= crumb_spec[++i].crumb_bit_length;
13573 }
13574
13575 /* Sign extend for signed types */
13576 switch (hf_field->type) {
13577 case FT_INT8:
13578 case FT_INT16:
13579 case FT_INT24:
13580 case FT_INT32:
13581 case FT_INT40:
13582 case FT_INT48:
13583 case FT_INT56:
13584 case FT_INT64:
13585 value = ws_sign_ext64(value, no_of_bits);
13586 break;
13587 default:
13588 break;
13589 }
13590
13591 if (return_value) {
13592 *return_value = value;
13593 }
13594
13595 /* Coast clear. Try and fake it */
13596 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13597 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", 13597
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13597, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13597, "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", 13597, __func__, "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); } } }
;
13598
13599 /* initialise the format string */
13600 bf_str[0] = '\0';
13601
13602 octet_offset = bit_offset >> 3;
13603
13604 /* Round up mask length to nearest octet */
13605 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13606 mask_greatest_bit_offset = octet_length << 3;
13607
13608 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13609 It would be a useful enhancement to eliminate this restriction. */
13610 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13611 other_decode_bitfield_value(bf_str,
13612 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13613 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13614 mask_greatest_bit_offset);
13615 } else {
13616 /* If the bitmask is too large, try to describe its contents. */
13617 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13618 }
13619
13620 switch (hf_field->type) {
13621 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13622 /* Boolean field */
13623 return proto_tree_add_boolean_format(tree, hfindex,
13624 tvb, octet_offset, octet_length, value,
13625 "%s = %s: %s",
13626 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13627 break;
13628
13629 case FT_CHAR:
13630 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13631 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13632 break;
13633
13634 case FT_UINT8:
13635 case FT_UINT16:
13636 case FT_UINT24:
13637 case FT_UINT32:
13638 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13639 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13640 break;
13641
13642 case FT_INT8:
13643 case FT_INT16:
13644 case FT_INT24:
13645 case FT_INT32:
13646 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13647 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13648 break;
13649
13650 case FT_UINT40:
13651 case FT_UINT48:
13652 case FT_UINT56:
13653 case FT_UINT64:
13654 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13655 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13656 break;
13657
13658 case FT_INT40:
13659 case FT_INT48:
13660 case FT_INT56:
13661 case FT_INT64:
13662 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13663 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13664 break;
13665
13666 default:
13667 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))
13668 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))
13669 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))
13670 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))
;
13671 return NULL((void*)0);
13672 }
13673 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13674 return pi;
13675}
13676
13677void
13678proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13679 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13680{
13681 header_field_info *hfinfo;
13682 int start = bit_offset >> 3;
13683 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13684
13685 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13686 * so that we can use the tree's memory scope in calculating the string */
13687 if (length == -1) {
13688 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13689 } else {
13690 tvb_ensure_bytes_exist(tvb, start, length);
13691 }
13692 if (!tree) return;
13693
13694 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", 13694, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13694
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13694, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13695 proto_tree_add_text_internal(tree, tvb, start, length,
13696 "%s crumb %d of %s (decoded above)",
13697 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13698 tvb_get_bits32(tvb,
13699 bit_offset,
13700 crumb_spec[crumb_index].crumb_bit_length,
13701 ENC_BIG_ENDIAN0x00000000),
13702 ENC_BIG_ENDIAN0x00000000),
13703 crumb_index,
13704 hfinfo->name);
13705}
13706
13707proto_item *
13708proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13709 const unsigned bit_offset, const int no_of_bits,
13710 uint64_t *return_value, const unsigned encoding)
13711{
13712 proto_item *item;
13713
13714 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13715 bit_offset, no_of_bits,
13716 return_value, encoding))) {
13717 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)
;
13718 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)
;
13719 }
13720 return item;
13721}
13722
13723static proto_item *
13724_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13725 tvbuff_t *tvb, const unsigned bit_offset,
13726 const int no_of_bits, void *value_ptr,
13727 const unsigned encoding, char *value_str)
13728{
13729 int offset;
13730 unsigned length;
13731 uint8_t tot_no_bits;
13732 char *str;
13733 uint64_t value = 0;
13734 header_field_info *hf_field;
13735
13736 /* We do not have to return a value, try to fake it as soon as possible */
13737 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13738 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", 13738
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13738, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13738, "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", 13738, __func__, "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); } } }
;
13739
13740 if (hf_field->bitmask != 0) {
13741 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)
13742 " 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)
13743 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)
;
13744 }
13745
13746 if (no_of_bits < 0) {
13747 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13748 } else if (no_of_bits == 0) {
13749 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)
13750 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)
;
13751 }
13752
13753 /* Byte align offset */
13754 offset = bit_offset>>3;
13755
13756 /*
13757 * Calculate the number of octets used to hold the bits
13758 */
13759 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13760 length = tot_no_bits>>3;
13761 /* If we are using part of the next octet, increase length by 1 */
13762 if (tot_no_bits & 0x07)
13763 length++;
13764
13765 if (no_of_bits < 65) {
13766 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13767 } else {
13768 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)
13769 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)
;
13770 return NULL((void*)0);
13771 }
13772
13773 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13774
13775 (void) g_strlcat(str, " = ", 256+64);
13776 (void) g_strlcat(str, hf_field->name, 256+64);
13777
13778 /*
13779 * This function does not receive an actual value but a dimensionless pointer to that value.
13780 * For this reason, the type of the header field is examined in order to determine
13781 * what kind of value we should read from this address.
13782 * The caller of this function must make sure that for the specific header field type the address of
13783 * a compatible value is provided.
13784 */
13785 switch (hf_field->type) {
13786 case FT_BOOLEAN:
13787 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13788 "%s: %s", str, value_str);
13789 break;
13790
13791 case FT_CHAR:
13792 case FT_UINT8:
13793 case FT_UINT16:
13794 case FT_UINT24:
13795 case FT_UINT32:
13796 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13797 "%s: %s", str, value_str);
13798 break;
13799
13800 case FT_UINT40:
13801 case FT_UINT48:
13802 case FT_UINT56:
13803 case FT_UINT64:
13804 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13805 "%s: %s", str, value_str);
13806 break;
13807
13808 case FT_INT8:
13809 case FT_INT16:
13810 case FT_INT24:
13811 case FT_INT32:
13812 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13813 "%s: %s", str, value_str);
13814 break;
13815
13816 case FT_INT40:
13817 case FT_INT48:
13818 case FT_INT56:
13819 case FT_INT64:
13820 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13821 "%s: %s", str, value_str);
13822 break;
13823
13824 case FT_FLOAT:
13825 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13826 "%s: %s", str, value_str);
13827 break;
13828
13829 default:
13830 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))
13831 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))
13832 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))
13833 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))
;
13834 return NULL((void*)0);
13835 }
13836}
13837
13838static proto_item *
13839proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13840 tvbuff_t *tvb, const unsigned bit_offset,
13841 const int no_of_bits, void *value_ptr,
13842 const unsigned encoding, char *value_str)
13843{
13844 proto_item *item;
13845
13846 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13847 tvb, bit_offset, no_of_bits,
13848 value_ptr, encoding, value_str))) {
13849 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)
;
13850 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)
;
13851 }
13852 return item;
13853}
13854
13855#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);
\
13856 va_start(ap, format)__builtin_va_start(ap, format); \
13857 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13858 va_end(ap)__builtin_va_end(ap);
13859
13860proto_item *
13861proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13862 tvbuff_t *tvb, const unsigned bit_offset,
13863 const int no_of_bits, uint32_t value,
13864 const unsigned encoding,
13865 const char *format, ...)
13866{
13867 va_list ap;
13868 char *dst;
13869 header_field_info *hf_field;
13870
13871 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13872
13873 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", 13873
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13873, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13873, "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", 13873, __func__, "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); } } }
;
13874
13875 switch (hf_field->type) {
13876 case FT_UINT8:
13877 case FT_UINT16:
13878 case FT_UINT24:
13879 case FT_UINT32:
13880 break;
13881
13882 default:
13883 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)
13884 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)
;
13885 return NULL((void*)0);
13886 }
13887
13888 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);
;
13889
13890 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13891}
13892
13893proto_item *
13894proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13895 tvbuff_t *tvb, const unsigned bit_offset,
13896 const int no_of_bits, uint64_t value,
13897 const unsigned encoding,
13898 const char *format, ...)
13899{
13900 va_list ap;
13901 char *dst;
13902 header_field_info *hf_field;
13903
13904 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13905
13906 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", 13906
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13906, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13906, "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", 13906, __func__, "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); } } }
;
13907
13908 switch (hf_field->type) {
13909 case FT_UINT40:
13910 case FT_UINT48:
13911 case FT_UINT56:
13912 case FT_UINT64:
13913 break;
13914
13915 default:
13916 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)
13917 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)
;
13918 return NULL((void*)0);
13919 }
13920
13921 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);
;
13922
13923 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13924}
13925
13926proto_item *
13927proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13928 tvbuff_t *tvb, const unsigned bit_offset,
13929 const int no_of_bits, float value,
13930 const unsigned encoding,
13931 const char *format, ...)
13932{
13933 va_list ap;
13934 char *dst;
13935 header_field_info *hf_field;
13936
13937 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13938
13939 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", 13939
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13939, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13939, "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", 13939, __func__, "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); } } }
;
13940
13941 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",
13941, ((hf_field))->abbrev))))
;
13942
13943 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);
;
13944
13945 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13946}
13947
13948proto_item *
13949proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13950 tvbuff_t *tvb, const unsigned bit_offset,
13951 const int no_of_bits, int32_t value,
13952 const unsigned encoding,
13953 const char *format, ...)
13954{
13955 va_list ap;
13956 char *dst;
13957 header_field_info *hf_field;
13958
13959 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13960
13961 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", 13961
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13961, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13961, "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", 13961, __func__, "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); } } }
;
13962
13963 switch (hf_field->type) {
13964 case FT_INT8:
13965 case FT_INT16:
13966 case FT_INT24:
13967 case FT_INT32:
13968 break;
13969
13970 default:
13971 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)
13972 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)
;
13973 return NULL((void*)0);
13974 }
13975
13976 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);
;
13977
13978 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13979}
13980
13981proto_item *
13982proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13983 tvbuff_t *tvb, const unsigned bit_offset,
13984 const int no_of_bits, int64_t value,
13985 const unsigned encoding,
13986 const char *format, ...)
13987{
13988 va_list ap;
13989 char *dst;
13990 header_field_info *hf_field;
13991
13992 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13993
13994 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", 13994
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13994, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13994, "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", 13994, __func__, "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); } } }
;
13995
13996 switch (hf_field->type) {
13997 case FT_INT40:
13998 case FT_INT48:
13999 case FT_INT56:
14000 case FT_INT64:
14001 break;
14002
14003 default:
14004 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)
14005 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)
;
14006 return NULL((void*)0);
14007 }
14008
14009 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);
;
14010
14011 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14012}
14013
14014proto_item *
14015proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14016 tvbuff_t *tvb, const unsigned bit_offset,
14017 const int no_of_bits, uint64_t value,
14018 const unsigned encoding,
14019 const char *format, ...)
14020{
14021 va_list ap;
14022 char *dst;
14023 header_field_info *hf_field;
14024
14025 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14026
14027 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", 14027
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14027, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14027, "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", 14027, __func__, "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); } } }
;
14028
14029 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"
, 14029, ((hf_field))->abbrev))))
;
14030
14031 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);
;
14032
14033 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14034}
14035
14036proto_item *
14037proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14038 const unsigned bit_offset, const int no_of_chars)
14039{
14040 proto_item *pi;
14041 header_field_info *hfinfo;
14042 int byte_length;
14043 int byte_offset;
14044 char *string;
14045
14046 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14047
14048 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", 14048
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14048, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14048, "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", 14048, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14049
14050 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"
, 14050, ((hfinfo))->abbrev))))
;
14051
14052 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14053 byte_offset = bit_offset >> 3;
14054
14055 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14056
14057 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14058 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14058, "byte_length >= 0"
))))
;
14059 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14060
14061 return pi;
14062}
14063
14064proto_item *
14065proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14066 const unsigned bit_offset, const int no_of_chars)
14067{
14068 proto_item *pi;
14069 header_field_info *hfinfo;
14070 int byte_length;
14071 int byte_offset;
14072 char *string;
14073
14074 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14075
14076 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", 14076
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14076, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14076, "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", 14076, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14077
14078 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"
, 14078, ((hfinfo))->abbrev))))
;
14079
14080 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14081 byte_offset = bit_offset >> 3;
14082
14083 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14084
14085 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14086 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14086, "byte_length >= 0"
))))
;
14087 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14088
14089 return pi;
14090}
14091
14092const value_string proto_checksum_vals[] = {
14093 { PROTO_CHECKSUM_E_BAD, "Bad" },
14094 { PROTO_CHECKSUM_E_GOOD, "Good" },
14095 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14096 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14097 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14098
14099 { 0, NULL((void*)0) }
14100};
14101
14102proto_item *
14103proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14104 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14105 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14106{
14107 header_field_info *hfinfo;
14108 uint32_t checksum;
14109 uint32_t len;
14110 proto_item* ti = NULL((void*)0);
14111 proto_item* ti2;
14112 bool_Bool incorrect_checksum = true1;
14113
14114 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", 14114, __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", 14114
, "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", 14114, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14115
14116 switch (hfinfo->type) {
14117 case FT_UINT8:
14118 len = 1;
14119 break;
14120 case FT_UINT16:
14121 len = 2;
14122 break;
14123 case FT_UINT24:
14124 len = 3;
14125 break;
14126 case FT_UINT32:
14127 len = 4;
14128 break;
14129 default:
14130 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)
14131 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14132 }
14133
14134 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14135 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14136 proto_item_set_generated(ti);
14137 if (hf_checksum_status != -1) {
14138 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14139 proto_item_set_generated(ti2);
14140 }
14141 return ti;
14142 }
14143
14144 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14145 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14146 proto_item_set_generated(ti);
14147 } else {
14148 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14149 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14150 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14151 if (computed_checksum == 0) {
14152 proto_item_append_text(ti, " [correct]");
14153 if (hf_checksum_status != -1) {
14154 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14155 proto_item_set_generated(ti2);
14156 }
14157 incorrect_checksum = false0;
14158 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14159 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14160 /* XXX - This can't distinguish between "shouldbe"
14161 * 0x0000 and 0xFFFF unless we know whether there
14162 * were any nonzero bits (other than the checksum).
14163 * Protocols should not use this path if they might
14164 * have an all zero packet.
14165 * Some implementations put the wrong zero; maybe
14166 * we should have a special expert info for that?
14167 */
14168 }
14169 } else {
14170 if (checksum == computed_checksum) {
14171 proto_item_append_text(ti, " [correct]");
14172 if (hf_checksum_status != -1) {
14173 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14174 proto_item_set_generated(ti2);
14175 }
14176 incorrect_checksum = false0;
14177 }
14178 }
14179
14180 if (incorrect_checksum) {
14181 if (hf_checksum_status != -1) {
14182 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14183 proto_item_set_generated(ti2);
14184 }
14185 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14186 proto_item_append_text(ti, " [incorrect]");
14187 if (bad_checksum_expert != NULL((void*)0))
14188 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14189 } else {
14190 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14191 if (bad_checksum_expert != NULL((void*)0))
14192 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);
14193 }
14194 }
14195 } else {
14196 if (hf_checksum_status != -1) {
14197 proto_item_append_text(ti, " [unverified]");
14198 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14199 proto_item_set_generated(ti2);
14200 }
14201 }
14202 }
14203
14204 return ti;
14205}
14206
14207proto_item *
14208proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14209 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14210 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14211{
14212 header_field_info *hfinfo;
14213 uint8_t *checksum = NULL((void*)0);
14214 proto_item* ti = NULL((void*)0);
14215 proto_item* ti2;
14216 bool_Bool incorrect_checksum = true1;
14217
14218 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", 14218, __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", 14218
, "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", 14218, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14219
14220 if (hfinfo->type != FT_BYTES) {
14221 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)
14222 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
14223 }
14224
14225 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14226 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14227 proto_item_set_generated(ti);
14228 if (hf_checksum_status != -1) {
14229 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14230 proto_item_set_generated(ti2);
14231 }
14232 return ti;
14233 }
14234
14235 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14236 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14237 proto_item_set_generated(ti);
14238 } else {
14239 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
))))))
;
14240 tvb_memcpy(tvb, checksum, offset, checksum_len);
14241 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14242 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14243 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14244 if (computed_checksum == 0) {
14245 proto_item_append_text(ti, " [correct]");
14246 if (hf_checksum_status != -1) {
14247 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14248 proto_item_set_generated(ti2);
14249 }
14250 incorrect_checksum = false0;
14251 }
14252 } else {
14253 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14254 proto_item_append_text(ti, " [correct]");
14255 if (hf_checksum_status != -1) {
14256 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14257 proto_item_set_generated(ti2);
14258 }
14259 incorrect_checksum = false0;
14260 }
14261 }
14262
14263 if (incorrect_checksum) {
14264 if (hf_checksum_status != -1) {
14265 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14266 proto_item_set_generated(ti2);
14267 }
14268 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14269 proto_item_append_text(ti, " [incorrect]");
14270 if (bad_checksum_expert != NULL((void*)0))
14271 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14272 } else {
14273 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14274 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))))))
;
14275 for (size_t counter = 0; counter < checksum_len; ++counter) {
14276 snprintf(
14277 /* On ecah iteration inserts two characters */
14278 (char*)&computed_checksum_str[counter << 1],
14279 computed_checksum_str_len - (counter << 1),
14280 "%02x",
14281 computed_checksum[counter]);
14282 }
14283 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14284 if (bad_checksum_expert != NULL((void*)0))
14285 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14286 }
14287 }
14288 } else {
14289 if (hf_checksum_status != -1) {
14290 proto_item_append_text(ti, " [unverified]");
14291 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14292 proto_item_set_generated(ti2);
14293 }
14294 }
14295 }
14296
14297 return ti;
14298}
14299
14300unsigned char
14301proto_check_field_name(const char *field_name)
14302{
14303 return module_check_valid_name(field_name, false0);
14304}
14305
14306unsigned char
14307proto_check_field_name_lower(const char *field_name)
14308{
14309 return module_check_valid_name(field_name, true1);
14310}
14311
14312bool_Bool
14313tree_expanded(int tree_type)
14314{
14315 if (tree_type <= 0) {
14316 return false0;
14317 }
14318 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", 14318, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14319 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14320}
14321
14322void
14323tree_expanded_set(int tree_type, bool_Bool value)
14324{
14325 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", 14325, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14326
14327 if (value)
14328 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14329 else
14330 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14331}
14332
14333/*
14334 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14335 *
14336 * Local variables:
14337 * c-basic-offset: 8
14338 * tab-width: 8
14339 * indent-tabs-mode: t
14340 * End:
14341 *
14342 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14343 * :indentSize=8:tabSize=8:noTabs=false:
14344 */